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