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