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