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