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