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