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