xref: /freebsd/bin/sh/var.c (revision 952d112864d8008aa87278a30a539d888a8493cd)
1 /*-
2  * Copyright (c) 1991, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Kenneth Almquist.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *	This product includes software developed by the University of
19  *	California, Berkeley and its contributors.
20  * 4. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  *	$Id$
37  */
38 
39 #ifndef lint
40 static char const sccsid[] = "@(#)var.c	8.3 (Berkeley) 5/4/95";
41 #endif /* not lint */
42 
43 #include <unistd.h>
44 #include <stdlib.h>
45 
46 /*
47  * Shell variables.
48  */
49 
50 #include <locale.h>
51 
52 #include "shell.h"
53 #include "output.h"
54 #include "expand.h"
55 #include "nodes.h"	/* for other headers */
56 #include "eval.h"	/* defines cmdenviron */
57 #include "exec.h"
58 #include "syntax.h"
59 #include "options.h"
60 #include "mail.h"
61 #include "var.h"
62 #include "memalloc.h"
63 #include "error.h"
64 #include "mystring.h"
65 #include "parser.h"
66 #ifndef NO_HISTORY
67 #include "myhistedit.h"
68 #endif
69 
70 
71 #define VTABSIZE 39
72 
73 
74 struct varinit {
75 	struct var *var;
76 	int flags;
77 	char *text;
78 	void (*func) __P((const char *));
79 };
80 
81 
82 #if ATTY
83 struct var vatty;
84 #endif
85 #ifndef NO_HISTORY
86 struct var vhistsize;
87 #endif
88 struct var vifs;
89 struct var vmail;
90 struct var vmpath;
91 struct var vpath;
92 struct var vps1;
93 struct var vps2;
94 struct var vvers;
95 #if ATTY
96 struct var vterm;
97 #endif
98 struct var voptind;
99 
100 const struct varinit varinit[] = {
101 #if ATTY
102 	{ &vatty,	VSTRFIXED|VTEXTFIXED|VUNSET,	"ATTY=",
103 	  NULL },
104 #endif
105 #ifndef NO_HISTORY
106 	{ &vhistsize,	VSTRFIXED|VTEXTFIXED|VUNSET,	"HISTSIZE=",
107 	  sethistsize },
108 #endif
109 	{ &vifs,	VSTRFIXED|VTEXTFIXED,		"IFS= \t\n",
110 	  NULL },
111 	{ &vmail,	VSTRFIXED|VTEXTFIXED|VUNSET,	"MAIL=",
112 	  NULL },
113 	{ &vmpath,	VSTRFIXED|VTEXTFIXED|VUNSET,	"MAILPATH=",
114 	  NULL },
115 	{ &vpath,	VSTRFIXED|VTEXTFIXED,		"PATH=/bin:/usr/bin",
116 	  changepath },
117 	/*
118 	 * vps1 depends on uid
119 	 */
120 	{ &vps2,	VSTRFIXED|VTEXTFIXED,		"PS2=> ",
121 	  NULL },
122 #if ATTY
123 	{ &vterm,	VSTRFIXED|VTEXTFIXED|VUNSET,	"TERM=",
124 	  NULL },
125 #endif
126 	{ &voptind,	VSTRFIXED|VTEXTFIXED,		"OPTIND=1",
127 	  getoptsreset },
128 	{ NULL,	0,				NULL,
129 	  NULL }
130 };
131 
132 struct var *vartab[VTABSIZE];
133 
134 STATIC struct var **hashvar __P((char *));
135 STATIC int varequal __P((char *, char *));
136 STATIC int localevar __P((char *));
137 
138 /*
139  * Initialize the varable symbol tables and import the environment
140  */
141 
142 #ifdef mkinit
143 INCLUDE "var.h"
144 INIT {
145 	char **envp;
146 	extern char **environ;
147 
148 	initvar();
149 	for (envp = environ ; *envp ; envp++) {
150 		if (strchr(*envp, '=')) {
151 			setvareq(*envp, VEXPORT|VTEXTFIXED);
152 		}
153 	}
154 }
155 #endif
156 
157 
158 /*
159  * This routine initializes the builtin variables.  It is called when the
160  * shell is initialized and again when a shell procedure is spawned.
161  */
162 
163 void
164 initvar() {
165 	const struct varinit *ip;
166 	struct var *vp;
167 	struct var **vpp;
168 
169 	for (ip = varinit ; (vp = ip->var) != NULL ; ip++) {
170 		if ((vp->flags & VEXPORT) == 0) {
171 			vpp = hashvar(ip->text);
172 			vp->next = *vpp;
173 			*vpp = vp;
174 			vp->text = ip->text;
175 			vp->flags = ip->flags;
176 			vp->func = ip->func;
177 		}
178 	}
179 	/*
180 	 * PS1 depends on uid
181 	 */
182 	if ((vps1.flags & VEXPORT) == 0) {
183 		vpp = hashvar("PS1=");
184 		vps1.next = *vpp;
185 		*vpp = &vps1;
186 		vps1.text = geteuid() ? "PS1=$ " : "PS1=# ";
187 		vps1.flags = VSTRFIXED|VTEXTFIXED;
188 	}
189 }
190 
191 /*
192  * Safe version of setvar, returns 1 on success 0 on failure.
193  */
194 
195 int
196 setvarsafe(name, val, flags)
197 	char *name, *val;
198 	int flags;
199 {
200 	struct jmploc jmploc;
201 	struct jmploc *volatile savehandler = handler;
202 	int err = 0;
203 #if __GNUC__
204 	/* Avoid longjmp clobbering */
205 	(void) &err;
206 #endif
207 
208 	if (setjmp(jmploc.loc))
209 		err = 1;
210 	else {
211 		handler = &jmploc;
212 		setvar(name, val, flags);
213 	}
214 	handler = savehandler;
215 	return err;
216 }
217 
218 /*
219  * Set the value of a variable.  The flags argument is ored with the
220  * flags of the variable.  If val is NULL, the variable is unset.
221  */
222 
223 void
224 setvar(name, val, flags)
225 	char *name, *val;
226 	int flags;
227 {
228 	char *p, *q;
229 	int len;
230 	int namelen;
231 	char *nameeq;
232 	int isbad;
233 
234 	isbad = 0;
235 	p = name;
236 	if (! is_name(*p))
237 		isbad = 1;
238 	p++;
239 	for (;;) {
240 		if (! is_in_name(*p)) {
241 			if (*p == '\0' || *p == '=')
242 				break;
243 			isbad = 1;
244 		}
245 		p++;
246 	}
247 	namelen = p - name;
248 	if (isbad)
249 		error("%.*s: bad variable name", namelen, name);
250 	len = namelen + 2;		/* 2 is space for '=' and '\0' */
251 	if (val == NULL) {
252 		flags |= VUNSET;
253 	} else {
254 		len += strlen(val);
255 	}
256 	p = nameeq = ckmalloc(len);
257 	q = name;
258 	while (--namelen >= 0)
259 		*p++ = *q++;
260 	*p++ = '=';
261 	*p = '\0';
262 	if (val)
263 		scopy(val, p);
264 	setvareq(nameeq, flags);
265 }
266 
267 STATIC int
268 localevar(s)
269 	char *s;
270 	{
271 	static char *lnames[7] = {
272 		"ALL", "COLLATE", "CTYPE", "MONETARY",
273 		"NUMERIC", "TIME", NULL
274 	};
275 	char **ss;
276 
277 	if (*s != 'L')
278 		return 0;
279 	if (varequal(s + 1, "ANG"))
280 		return 1;
281 	if (strncmp(s + 1, "C_", 2) != 0)
282 		return 0;
283 	for (ss = lnames; *ss ; ss++)
284 		if (varequal(s + 3, *ss))
285 			return 1;
286 	return 0;
287 }
288 
289 /*
290  * Same as setvar except that the variable and value are passed in
291  * the first argument as name=value.  Since the first argument will
292  * be actually stored in the table, it should not be a string that
293  * will go away.
294  */
295 
296 void
297 setvareq(s, flags)
298 	char *s;
299 	int flags;
300 {
301 	struct var *vp, **vpp;
302 
303 	vpp = hashvar(s);
304 	for (vp = *vpp ; vp ; vp = vp->next) {
305 		if (varequal(s, vp->text)) {
306 			if (vp->flags & VREADONLY) {
307 				size_t len = strchr(s, '=') - s;
308 				error("%.*s: is read only", len, s);
309 			}
310 			INTOFF;
311 
312 			if (vp->func && (flags & VNOFUNC) == 0)
313 				(*vp->func)(strchr(s, '=') + 1);
314 
315 			if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0)
316 				ckfree(vp->text);
317 
318 			vp->flags &= ~(VTEXTFIXED|VSTACK|VUNSET);
319 			vp->flags |= flags;
320 			vp->text = s;
321 
322 			/*
323 			 * We could roll this to a function, to handle it as
324 			 * a regular variable function callback, but why bother?
325 			 */
326 			if (vp == &vmpath || (vp == &vmail && ! mpathset()))
327 				chkmail(1);
328 			if ((vp->flags & VEXPORT) && localevar(s)) {
329 				putenv(s);
330 				(void) setlocale(LC_ALL, "");
331 			}
332 			INTON;
333 			return;
334 		}
335 	}
336 	/* not found */
337 	vp = ckmalloc(sizeof (*vp));
338 	vp->flags = flags;
339 	vp->text = s;
340 	vp->next = *vpp;
341 	vp->func = NULL;
342 	INTOFF;
343 	*vpp = vp;
344 	if ((vp->flags & VEXPORT) && localevar(s)) {
345 		putenv(s);
346 		(void) setlocale(LC_ALL, "");
347 	}
348 	INTON;
349 }
350 
351 
352 
353 /*
354  * Process a linked list of variable assignments.
355  */
356 
357 void
358 listsetvar(list)
359 	struct strlist *list;
360 	{
361 	struct strlist *lp;
362 
363 	INTOFF;
364 	for (lp = list ; lp ; lp = lp->next) {
365 		setvareq(savestr(lp->text), 0);
366 	}
367 	INTON;
368 }
369 
370 
371 
372 /*
373  * Find the value of a variable.  Returns NULL if not set.
374  */
375 
376 char *
377 lookupvar(name)
378 	char *name;
379 	{
380 	struct var *v;
381 
382 	for (v = *hashvar(name) ; v ; v = v->next) {
383 		if (varequal(v->text, name)) {
384 			if (v->flags & VUNSET)
385 				return NULL;
386 			return strchr(v->text, '=') + 1;
387 		}
388 	}
389 	return NULL;
390 }
391 
392 
393 
394 /*
395  * Search the environment of a builtin command.  If the second argument
396  * is nonzero, return the value of a variable even if it hasn't been
397  * exported.
398  */
399 
400 char *
401 bltinlookup(name, doall)
402 	char *name;
403 	int doall;
404 {
405 	struct strlist *sp;
406 	struct var *v;
407 
408 	for (sp = cmdenviron ; sp ; sp = sp->next) {
409 		if (varequal(sp->text, name))
410 			return strchr(sp->text, '=') + 1;
411 	}
412 	for (v = *hashvar(name) ; v ; v = v->next) {
413 		if (varequal(v->text, name)) {
414 			if ((v->flags & VUNSET)
415 			 || (!doall && (v->flags & VEXPORT) == 0))
416 				return NULL;
417 			return strchr(v->text, '=') + 1;
418 		}
419 	}
420 	return NULL;
421 }
422 
423 
424 
425 /*
426  * Generate a list of exported variables.  This routine is used to construct
427  * the third argument to execve when executing a program.
428  */
429 
430 char **
431 environment() {
432 	int nenv;
433 	struct var **vpp;
434 	struct var *vp;
435 	char **env, **ep;
436 
437 	nenv = 0;
438 	for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
439 		for (vp = *vpp ; vp ; vp = vp->next)
440 			if (vp->flags & VEXPORT)
441 				nenv++;
442 	}
443 	ep = env = stalloc((nenv + 1) * sizeof *env);
444 	for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
445 		for (vp = *vpp ; vp ; vp = vp->next)
446 			if (vp->flags & VEXPORT)
447 				*ep++ = vp->text;
448 	}
449 	*ep = NULL;
450 	return env;
451 }
452 
453 
454 /*
455  * Called when a shell procedure is invoked to clear out nonexported
456  * variables.  It is also necessary to reallocate variables of with
457  * VSTACK set since these are currently allocated on the stack.
458  */
459 
460 #ifdef mkinit
461 MKINIT void shprocvar();
462 
463 SHELLPROC {
464 	shprocvar();
465 }
466 #endif
467 
468 void
469 shprocvar() {
470 	struct var **vpp;
471 	struct var *vp, **prev;
472 
473 	for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
474 		for (prev = vpp ; (vp = *prev) != NULL ; ) {
475 			if ((vp->flags & VEXPORT) == 0) {
476 				*prev = vp->next;
477 				if ((vp->flags & VTEXTFIXED) == 0)
478 					ckfree(vp->text);
479 				if ((vp->flags & VSTRFIXED) == 0)
480 					ckfree(vp);
481 			} else {
482 				if (vp->flags & VSTACK) {
483 					vp->text = savestr(vp->text);
484 					vp->flags &=~ VSTACK;
485 				}
486 				prev = &vp->next;
487 			}
488 		}
489 	}
490 	initvar();
491 }
492 
493 
494 
495 /*
496  * Command to list all variables which are set.  Currently this command
497  * is invoked from the set command when the set command is called without
498  * any variables.
499  */
500 
501 int
502 showvarscmd(argc, argv)
503 	int argc;
504 	char **argv;
505 {
506 	struct var **vpp;
507 	struct var *vp;
508 
509 	for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
510 		for (vp = *vpp ; vp ; vp = vp->next) {
511 			if ((vp->flags & VUNSET) == 0)
512 				out1fmt("%s\n", vp->text);
513 		}
514 	}
515 	return 0;
516 }
517 
518 
519 
520 /*
521  * The export and readonly commands.
522  */
523 
524 int
525 exportcmd(argc, argv)
526 	int argc;
527 	char **argv;
528 {
529 	struct var **vpp;
530 	struct var *vp;
531 	char *name;
532 	char *p;
533 	int flag = argv[0][0] == 'r'? VREADONLY : VEXPORT;
534 
535 	listsetvar(cmdenviron);
536 	if (argc > 1) {
537 		while ((name = *argptr++) != NULL) {
538 			if ((p = strchr(name, '=')) != NULL) {
539 				p++;
540 			} else {
541 				vpp = hashvar(name);
542 				for (vp = *vpp ; vp ; vp = vp->next) {
543 					if (varequal(vp->text, name)) {
544 						vp->flags |= flag;
545 						if ((vp->flags & VEXPORT) && localevar(vp->text)) {
546 							putenv(vp->text);
547 							(void) setlocale(LC_ALL, "");
548 						}
549 						goto found;
550 					}
551 				}
552 			}
553 			setvar(name, p, flag);
554 found:;
555 		}
556 	} else {
557 		for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
558 			for (vp = *vpp ; vp ; vp = vp->next) {
559 				if (vp->flags & flag) {
560 					for (p = vp->text ; *p != '=' ; p++)
561 						out1c(*p);
562 					out1c('\n');
563 				}
564 			}
565 		}
566 	}
567 	return 0;
568 }
569 
570 
571 /*
572  * The "local" command.
573  */
574 
575 int
576 localcmd(argc, argv)
577 	int argc;
578 	char **argv;
579 {
580 	char *name;
581 
582 	if (! in_function())
583 		error("Not in a function");
584 	while ((name = *argptr++) != NULL) {
585 		mklocal(name);
586 	}
587 	return 0;
588 }
589 
590 
591 /*
592  * Make a variable a local variable.  When a variable is made local, it's
593  * value and flags are saved in a localvar structure.  The saved values
594  * will be restored when the shell function returns.  We handle the name
595  * "-" as a special case.
596  */
597 
598 void
599 mklocal(name)
600 	char *name;
601 	{
602 	struct localvar *lvp;
603 	struct var **vpp;
604 	struct var *vp;
605 
606 	INTOFF;
607 	lvp = ckmalloc(sizeof (struct localvar));
608 	if (name[0] == '-' && name[1] == '\0') {
609 		lvp->text = ckmalloc(sizeof optlist);
610 		memcpy(lvp->text, optlist, sizeof optlist);
611 		vp = NULL;
612 	} else {
613 		vpp = hashvar(name);
614 		for (vp = *vpp ; vp && ! varequal(vp->text, name) ; vp = vp->next);
615 		if (vp == NULL) {
616 			if (strchr(name, '='))
617 				setvareq(savestr(name), VSTRFIXED);
618 			else
619 				setvar(name, NULL, VSTRFIXED);
620 			vp = *vpp;	/* the new variable */
621 			lvp->text = NULL;
622 			lvp->flags = VUNSET;
623 		} else {
624 			lvp->text = vp->text;
625 			lvp->flags = vp->flags;
626 			vp->flags |= VSTRFIXED|VTEXTFIXED;
627 			if (strchr(name, '='))
628 				setvareq(savestr(name), 0);
629 		}
630 	}
631 	lvp->vp = vp;
632 	lvp->next = localvars;
633 	localvars = lvp;
634 	INTON;
635 }
636 
637 
638 /*
639  * Called after a function returns.
640  */
641 
642 void
643 poplocalvars() {
644 	struct localvar *lvp;
645 	struct var *vp;
646 
647 	while ((lvp = localvars) != NULL) {
648 		localvars = lvp->next;
649 		vp = lvp->vp;
650 		if (vp == NULL) {	/* $- saved */
651 			memcpy(optlist, lvp->text, sizeof optlist);
652 			ckfree(lvp->text);
653 		} else if ((lvp->flags & (VUNSET|VSTRFIXED)) == VUNSET) {
654 			(void)unsetvar(vp->text);
655 		} else {
656 			if ((vp->flags & VTEXTFIXED) == 0)
657 				ckfree(vp->text);
658 			vp->flags = lvp->flags;
659 			vp->text = lvp->text;
660 		}
661 		ckfree(lvp);
662 	}
663 }
664 
665 
666 int
667 setvarcmd(argc, argv)
668 	int argc;
669 	char **argv;
670 {
671 	if (argc <= 2)
672 		return unsetcmd(argc, argv);
673 	else if (argc == 3)
674 		setvar(argv[1], argv[2], 0);
675 	else
676 		error("List assignment not implemented");
677 	return 0;
678 }
679 
680 
681 /*
682  * The unset builtin command.  We unset the function before we unset the
683  * variable to allow a function to be unset when there is a readonly variable
684  * with the same name.
685  */
686 
687 int
688 unsetcmd(argc, argv)
689 	int argc;
690 	char **argv;
691 {
692 	char **ap;
693 	int i;
694 	int flg_func = 0;
695 	int flg_var = 0;
696 	int ret = 0;
697 
698 	while ((i = nextopt("vf")) != '\0') {
699 		if (i == 'f')
700 			flg_func = 1;
701 		else
702 			flg_var = 1;
703 	}
704 	if (flg_func == 0 && flg_var == 0)
705 		flg_var = 1;
706 
707 	for (ap = argptr; *ap ; ap++) {
708 		if (flg_func)
709 			ret |= unsetfunc(*ap);
710 		if (flg_var)
711 			ret |= unsetvar(*ap);
712 	}
713 	return ret;
714 }
715 
716 
717 /*
718  * Unset the specified variable.
719  */
720 
721 int
722 unsetvar(s)
723 	char *s;
724 	{
725 	struct var **vpp;
726 	struct var *vp;
727 
728 	vpp = hashvar(s);
729 	for (vp = *vpp ; vp ; vpp = &vp->next, vp = *vpp) {
730 		if (varequal(vp->text, s)) {
731 			if (vp->flags & VREADONLY)
732 				return (1);
733 			INTOFF;
734 			if (*(strchr(vp->text, '=') + 1) != '\0')
735 				setvar(s, nullstr, 0);
736 			if ((vp->flags & VEXPORT) && localevar(vp->text)) {
737 				unsetenv(s);
738 				setlocale(LC_ALL, "");
739 			}
740 			vp->flags &= ~VEXPORT;
741 			vp->flags |= VUNSET;
742 			if ((vp->flags & VSTRFIXED) == 0) {
743 				if ((vp->flags & VTEXTFIXED) == 0)
744 					ckfree(vp->text);
745 				*vpp = vp->next;
746 				ckfree(vp);
747 			}
748 			INTON;
749 			return (0);
750 		}
751 	}
752 
753 	return (1);
754 }
755 
756 
757 
758 /*
759  * Find the appropriate entry in the hash table from the name.
760  */
761 
762 STATIC struct var **
763 hashvar(p)
764 	register char *p;
765 	{
766 	unsigned int hashval;
767 
768 	hashval = ((unsigned char) *p) << 4;
769 	while (*p && *p != '=')
770 		hashval += (unsigned char) *p++;
771 	return &vartab[hashval % VTABSIZE];
772 }
773 
774 
775 
776 /*
777  * Returns true if the two strings specify the same varable.  The first
778  * variable name is terminated by '='; the second may be terminated by
779  * either '=' or '\0'.
780  */
781 
782 STATIC int
783 varequal(p, q)
784 	register char *p, *q;
785 	{
786 	while (*p == *q++) {
787 		if (*p++ == '=')
788 			return 1;
789 	}
790 	if (*p == '=' && *(q - 1) == '\0')
791 		return 1;
792 	return 0;
793 }
794