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