1 /*- 2 * Copyright (c) 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Kenneth Almquist. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * @(#)var.c 8.3 (Berkeley) 5/4/95 37 * $FreeBSD: src/bin/sh/var.c,v 1.15.2.2 2002/08/27 01:36:28 tjr Exp $ 38 * $DragonFly: src/bin/sh/var.c,v 1.3 2003/08/24 16:26:00 drhodus Exp $ 39 */ 40 41 #include <unistd.h> 42 #include <stdlib.h> 43 44 /* 45 * Shell variables. 46 */ 47 48 #include <locale.h> 49 50 #include "shell.h" 51 #include "output.h" 52 #include "expand.h" 53 #include "nodes.h" /* for other headers */ 54 #include "eval.h" /* defines cmdenviron */ 55 #include "exec.h" 56 #include "syntax.h" 57 #include "options.h" 58 #include "mail.h" 59 #include "var.h" 60 #include "memalloc.h" 61 #include "error.h" 62 #include "mystring.h" 63 #include "parser.h" 64 #ifndef NO_HISTORY 65 #include "myhistedit.h" 66 #endif 67 68 69 #define VTABSIZE 39 70 71 72 struct varinit { 73 struct var *var; 74 int flags; 75 char *text; 76 void (*func)(const char *); 77 }; 78 79 80 #if ATTY 81 struct var vatty; 82 #endif 83 #ifndef NO_HISTORY 84 struct var vhistsize; 85 #endif 86 struct var vifs; 87 struct var vmail; 88 struct var vmpath; 89 struct var vpath; 90 struct var vppid; 91 struct var vps1; 92 struct var vps2; 93 struct var vvers; 94 #if ATTY 95 STATIC struct var vterm; 96 #endif 97 STATIC struct var voptind; 98 99 STATIC const struct varinit varinit[] = { 100 #if ATTY 101 { &vatty, VSTRFIXED|VTEXTFIXED|VUNSET, "ATTY=", 102 NULL }, 103 #endif 104 #ifndef NO_HISTORY 105 { &vhistsize, VSTRFIXED|VTEXTFIXED|VUNSET, "HISTSIZE=", 106 sethistsize }, 107 #endif 108 { &vifs, VSTRFIXED|VTEXTFIXED, "IFS= \t\n", 109 NULL }, 110 { &vmail, VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL=", 111 NULL }, 112 { &vmpath, VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH=", 113 NULL }, 114 { &vpath, VSTRFIXED|VTEXTFIXED, "PATH=/bin:/usr/bin", 115 changepath }, 116 { &vppid, VSTRFIXED|VTEXTFIXED|VUNSET, "PPID=", 117 NULL }, 118 /* 119 * vps1 depends on uid 120 */ 121 { &vps2, VSTRFIXED|VTEXTFIXED, "PS2=> ", 122 NULL }, 123 #if ATTY 124 { &vterm, VSTRFIXED|VTEXTFIXED|VUNSET, "TERM=", 125 NULL }, 126 #endif 127 { &voptind, VSTRFIXED|VTEXTFIXED, "OPTIND=1", 128 getoptsreset }, 129 { NULL, 0, NULL, 130 NULL } 131 }; 132 133 STATIC struct var *vartab[VTABSIZE]; 134 135 STATIC struct var **hashvar(char *); 136 STATIC int varequal(char *, char *); 137 STATIC int localevar(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(void) 166 { 167 char ppid[20]; 168 const struct varinit *ip; 169 struct var *vp; 170 struct var **vpp; 171 172 for (ip = varinit ; (vp = ip->var) != NULL ; ip++) { 173 if ((vp->flags & VEXPORT) == 0) { 174 vpp = hashvar(ip->text); 175 vp->next = *vpp; 176 *vpp = vp; 177 vp->text = ip->text; 178 vp->flags = ip->flags; 179 vp->func = ip->func; 180 } 181 } 182 /* 183 * PS1 depends on uid 184 */ 185 if ((vps1.flags & VEXPORT) == 0) { 186 vpp = hashvar("PS1="); 187 vps1.next = *vpp; 188 *vpp = &vps1; 189 vps1.text = geteuid() ? "PS1=$ " : "PS1=# "; 190 vps1.flags = VSTRFIXED|VTEXTFIXED; 191 } 192 if ((vppid.flags & VEXPORT) == 0) { 193 fmtstr(ppid, sizeof(ppid), "%d", (int)getppid()); 194 setvarsafe("PPID", ppid, 0); 195 } 196 } 197 198 /* 199 * Safe version of setvar, returns 1 on success 0 on failure. 200 */ 201 202 int 203 setvarsafe(char *name, char *val, int flags) 204 { 205 struct jmploc jmploc; 206 struct jmploc *volatile savehandler = handler; 207 int err = 0; 208 #if __GNUC__ 209 /* Avoid longjmp clobbering */ 210 (void) &err; 211 #endif 212 213 if (setjmp(jmploc.loc)) 214 err = 1; 215 else { 216 handler = &jmploc; 217 setvar(name, val, flags); 218 } 219 handler = savehandler; 220 return err; 221 } 222 223 /* 224 * Set the value of a variable. The flags argument is tored with the 225 * flags of the variable. If val is NULL, the variable is unset. 226 */ 227 228 void 229 setvar(char *name, char *val, int flags) 230 { 231 char *p, *q; 232 int len; 233 int namelen; 234 char *nameeq; 235 int isbad; 236 237 isbad = 0; 238 p = name; 239 if (! is_name(*p)) 240 isbad = 1; 241 p++; 242 for (;;) { 243 if (! is_in_name(*p)) { 244 if (*p == '\0' || *p == '=') 245 break; 246 isbad = 1; 247 } 248 p++; 249 } 250 namelen = p - name; 251 if (isbad) 252 error("%.*s: bad variable name", namelen, name); 253 len = namelen + 2; /* 2 is space for '=' and '\0' */ 254 if (val == NULL) { 255 flags |= VUNSET; 256 } else { 257 len += strlen(val); 258 } 259 p = nameeq = ckmalloc(len); 260 q = name; 261 while (--namelen >= 0) 262 *p++ = *q++; 263 *p++ = '='; 264 *p = '\0'; 265 if (val) 266 scopy(val, p); 267 setvareq(nameeq, flags); 268 } 269 270 STATIC int 271 localevar(char *s) 272 { 273 static char *lnames[7] = { 274 "ALL", "COLLATE", "CTYPE", "MONETARY", 275 "NUMERIC", "TIME", NULL 276 }; 277 char **ss; 278 279 if (*s != 'L') 280 return 0; 281 if (varequal(s + 1, "ANG")) 282 return 1; 283 if (strncmp(s + 1, "C_", 2) != 0) 284 return 0; 285 for (ss = lnames; *ss ; ss++) 286 if (varequal(s + 3, *ss)) 287 return 1; 288 return 0; 289 } 290 291 /* 292 * Same as setvar except that the variable and value are passed in 293 * the first argument as name=value. Since the first argument will 294 * be actually stored in the table, it should not be a string that 295 * will go away. 296 */ 297 298 void 299 setvareq(char *s, int flags) 300 { 301 struct var *vp, **vpp; 302 int len; 303 304 if (aflag) 305 flags |= VEXPORT; 306 vpp = hashvar(s); 307 for (vp = *vpp ; vp ; vp = vp->next) { 308 if (varequal(s, vp->text)) { 309 if (vp->flags & VREADONLY) { 310 len = strchr(s, '=') - s; 311 error("%.*s: is read only", len, s); 312 } 313 INTOFF; 314 315 if (vp->func && (flags & VNOFUNC) == 0) 316 (*vp->func)(strchr(s, '=') + 1); 317 318 if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0) 319 ckfree(vp->text); 320 321 vp->flags &= ~(VTEXTFIXED|VSTACK|VUNSET); 322 vp->flags |= flags; 323 vp->text = s; 324 325 /* 326 * We could roll this to a function, to handle it as 327 * a regular variable function callback, but why bother? 328 */ 329 if (vp == &vmpath || (vp == &vmail && ! mpathset())) 330 chkmail(1); 331 if ((vp->flags & VEXPORT) && localevar(s)) { 332 putenv(s); 333 (void) setlocale(LC_ALL, ""); 334 } 335 INTON; 336 return; 337 } 338 } 339 /* not found */ 340 vp = ckmalloc(sizeof (*vp)); 341 vp->flags = flags; 342 vp->text = s; 343 vp->next = *vpp; 344 vp->func = NULL; 345 INTOFF; 346 *vpp = vp; 347 if ((vp->flags & VEXPORT) && localevar(s)) { 348 putenv(s); 349 (void) setlocale(LC_ALL, ""); 350 } 351 INTON; 352 } 353 354 355 356 /* 357 * Process a linked list of variable assignments. 358 */ 359 360 void 361 listsetvar(struct strlist *list) 362 { 363 struct strlist *lp; 364 365 INTOFF; 366 for (lp = list ; lp ; lp = lp->next) { 367 setvareq(savestr(lp->text), 0); 368 } 369 INTON; 370 } 371 372 373 374 /* 375 * Find the value of a variable. Returns NULL if not set. 376 */ 377 378 char * 379 lookupvar(char *name) 380 { 381 struct var *v; 382 383 for (v = *hashvar(name) ; v ; v = v->next) { 384 if (varequal(v->text, name)) { 385 if (v->flags & VUNSET) 386 return NULL; 387 return strchr(v->text, '=') + 1; 388 } 389 } 390 return NULL; 391 } 392 393 394 395 /* 396 * Search the environment of a builtin command. If the second argument 397 * is nonzero, return the value of a variable even if it hasn't been 398 * exported. 399 */ 400 401 char * 402 bltinlookup(char *name, int doall) 403 { 404 struct strlist *sp; 405 struct var *v; 406 407 for (sp = cmdenviron ; sp ; sp = sp->next) { 408 if (varequal(sp->text, name)) 409 return strchr(sp->text, '=') + 1; 410 } 411 for (v = *hashvar(name) ; v ; v = v->next) { 412 if (varequal(v->text, name)) { 413 if ((v->flags & VUNSET) 414 || (!doall && (v->flags & VEXPORT) == 0)) 415 return NULL; 416 return strchr(v->text, '=') + 1; 417 } 418 } 419 return NULL; 420 } 421 422 423 424 /* 425 * Generate a list of exported variables. This routine is used to construct 426 * the third argument to execve when executing a program. 427 */ 428 429 char ** 430 environment(void) 431 { 432 int nenv; 433 struct var **vpp; 434 struct var *vp; 435 char **env, **ep; 436 437 nenv = 0; 438 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) { 439 for (vp = *vpp ; vp ; vp = vp->next) 440 if (vp->flags & VEXPORT) 441 nenv++; 442 } 443 ep = env = stalloc((nenv + 1) * sizeof *env); 444 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) { 445 for (vp = *vpp ; vp ; vp = vp->next) 446 if (vp->flags & VEXPORT) 447 *ep++ = vp->text; 448 } 449 *ep = NULL; 450 return env; 451 } 452 453 454 /* 455 * Called when a shell procedure is invoked to clear out nonexported 456 * variables. It is also necessary to reallocate variables of with 457 * VSTACK set since these are currently allocated on the stack. 458 */ 459 460 #ifdef mkinit 461 MKINIT void shprocvar(); 462 463 SHELLPROC { 464 shprocvar(); 465 } 466 #endif 467 468 void 469 shprocvar(void) 470 { 471 struct var **vpp; 472 struct var *vp, **prev; 473 474 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) { 475 for (prev = vpp ; (vp = *prev) != NULL ; ) { 476 if ((vp->flags & VEXPORT) == 0) { 477 *prev = vp->next; 478 if ((vp->flags & VTEXTFIXED) == 0) 479 ckfree(vp->text); 480 if ((vp->flags & VSTRFIXED) == 0) 481 ckfree(vp); 482 } else { 483 if (vp->flags & VSTACK) { 484 vp->text = savestr(vp->text); 485 vp->flags &=~ VSTACK; 486 } 487 prev = &vp->next; 488 } 489 } 490 } 491 initvar(); 492 } 493 494 495 496 /* 497 * Command to list all variables which are set. Currently this command 498 * is invoked from the set command when the set command is called without 499 * any variables. 500 */ 501 502 int 503 showvarscmd(int argc __unused, char **argv __unused) 504 { 505 struct var **vpp; 506 struct var *vp; 507 const char *s; 508 509 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) { 510 for (vp = *vpp ; vp ; vp = vp->next) { 511 if (vp->flags & VUNSET) 512 continue; 513 for (s = vp->text; *s != '='; s++) 514 out1c(*s); 515 out1c('='); 516 out1qstr(s + 1); 517 out1c('\n'); 518 } 519 } 520 return 0; 521 } 522 523 524 525 /* 526 * The export and readonly commands. 527 */ 528 529 int 530 exportcmd(int argc, char **argv) 531 { 532 struct var **vpp; 533 struct var *vp; 534 char *name; 535 char *p; 536 char *cmdname; 537 int ch, values; 538 int flag = argv[0][0] == 'r'? VREADONLY : VEXPORT; 539 540 cmdname = argv[0]; 541 optreset = optind = 1; 542 opterr = 0; 543 values = 0; 544 while ((ch = getopt(argc, argv, "p")) != -1) { 545 switch (ch) { 546 case 'p': 547 values = 1; 548 break; 549 case '?': 550 default: 551 error("unknown option: -%c", optopt); 552 } 553 } 554 argc -= optind; 555 argv += optind; 556 557 listsetvar(cmdenviron); 558 if (argc != 0) { 559 while ((name = *argptr++) != NULL) { 560 if ((p = strchr(name, '=')) != NULL) { 561 p++; 562 } else { 563 vpp = hashvar(name); 564 for (vp = *vpp ; vp ; vp = vp->next) { 565 if (varequal(vp->text, name)) { 566 567 vp->flags |= flag; 568 if ((vp->flags & VEXPORT) && localevar(vp->text)) { 569 putenv(vp->text); 570 (void) setlocale(LC_ALL, ""); 571 } 572 goto found; 573 } 574 } 575 } 576 setvar(name, p, flag); 577 found:; 578 } 579 } else { 580 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) { 581 for (vp = *vpp ; vp ; vp = vp->next) { 582 if (vp->flags & flag) { 583 if (values) { 584 out1str(cmdname); 585 out1c(' '); 586 } 587 for (p = vp->text ; *p != '=' ; p++) 588 out1c(*p); 589 if (values && !(vp->flags & VUNSET)) { 590 out1c('='); 591 out1qstr(p + 1); 592 } 593 out1c('\n'); 594 } 595 } 596 } 597 } 598 return 0; 599 } 600 601 602 /* 603 * The "local" command. 604 */ 605 606 int 607 localcmd(int argc __unused, char **argv __unused) 608 { 609 char *name; 610 611 if (! in_function()) 612 error("Not in a function"); 613 while ((name = *argptr++) != NULL) { 614 mklocal(name); 615 } 616 return 0; 617 } 618 619 620 /* 621 * Make a variable a local variable. When a variable is made local, it's 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(char *name) 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 lvp->text = ckmalloc(sizeof optlist); 638 memcpy(lvp->text, optlist, sizeof optlist); 639 vp = NULL; 640 } else { 641 vpp = hashvar(name); 642 for (vp = *vpp ; vp && ! varequal(vp->text, name) ; vp = vp->next); 643 if (vp == NULL) { 644 if (strchr(name, '=')) 645 setvareq(savestr(name), VSTRFIXED); 646 else 647 setvar(name, NULL, VSTRFIXED); 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 (strchr(name, '=')) 656 setvareq(savestr(name), 0); 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 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); 684 } else { 685 if ((vp->flags & VTEXTFIXED) == 0) 686 ckfree(vp->text); 687 vp->flags = lvp->flags; 688 vp->text = lvp->text; 689 } 690 ckfree(lvp); 691 } 692 } 693 694 695 int 696 setvarcmd(int argc, char **argv) 697 { 698 if (argc <= 2) 699 return unsetcmd(argc, argv); 700 else if (argc == 3) 701 setvar(argv[1], argv[2], 0); 702 else 703 error("List assignment not implemented"); 704 return 0; 705 } 706 707 708 /* 709 * The unset builtin command. We unset the function before we unset the 710 * variable to allow a function to be unset when there is a readonly variable 711 * with the same name. 712 */ 713 714 int 715 unsetcmd(int argc __unused, char **argv __unused) 716 { 717 char **ap; 718 int i; 719 int flg_func = 0; 720 int flg_var = 0; 721 int ret = 0; 722 723 while ((i = nextopt("vf")) != '\0') { 724 if (i == 'f') 725 flg_func = 1; 726 else 727 flg_var = 1; 728 } 729 if (flg_func == 0 && flg_var == 0) 730 flg_var = 1; 731 732 for (ap = argptr; *ap ; ap++) { 733 if (flg_func) 734 ret |= unsetfunc(*ap); 735 if (flg_var) 736 ret |= unsetvar(*ap); 737 } 738 return ret; 739 } 740 741 742 /* 743 * Unset the specified variable. 744 */ 745 746 int 747 unsetvar(char *s) 748 { 749 struct var **vpp; 750 struct var *vp; 751 752 vpp = hashvar(s); 753 for (vp = *vpp ; vp ; vpp = &vp->next, vp = *vpp) { 754 if (varequal(vp->text, s)) { 755 if (vp->flags & VREADONLY) 756 return (1); 757 INTOFF; 758 if (*(strchr(vp->text, '=') + 1) != '\0') 759 setvar(s, nullstr, 0); 760 if ((vp->flags & VEXPORT) && localevar(vp->text)) { 761 unsetenv(s); 762 setlocale(LC_ALL, ""); 763 } 764 vp->flags &= ~VEXPORT; 765 vp->flags |= VUNSET; 766 if ((vp->flags & VSTRFIXED) == 0) { 767 if ((vp->flags & VTEXTFIXED) == 0) 768 ckfree(vp->text); 769 *vpp = vp->next; 770 ckfree(vp); 771 } 772 INTON; 773 return (0); 774 } 775 } 776 777 return (1); 778 } 779 780 781 782 /* 783 * Find the appropriate entry in the hash table from the name. 784 */ 785 786 STATIC struct var ** 787 hashvar(char *p) 788 { 789 unsigned int hashval; 790 791 hashval = ((unsigned char) *p) << 4; 792 while (*p && *p != '=') 793 hashval += (unsigned char) *p++; 794 return &vartab[hashval % VTABSIZE]; 795 } 796 797 798 799 /* 800 * Returns true if the two strings specify the same varable. The first 801 * variable name is terminated by '='; the second may be terminated by 802 * either '=' or '\0'. 803 */ 804 805 STATIC int 806 varequal(char *p, char *q) 807 { 808 while (*p == *q++) { 809 if (*p++ == '=') 810 return 1; 811 } 812 if (*p == '=' && *(q - 1) == '\0') 813 return 1; 814 return 0; 815 } 816