1 /* $NetBSD: var.c,v 1.75 2019/01/21 13:27:29 kre 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.75 2019/01/21 13:27:29 kre Exp $"); 41 #endif 42 #endif /* not lint */ 43 44 #include <stdio.h> 45 #include <unistd.h> 46 #include <stdlib.h> 47 #include <string.h> 48 #include <paths.h> 49 #include <limits.h> 50 #include <time.h> 51 #include <pwd.h> 52 #include <fcntl.h> 53 #include <inttypes.h> 54 55 /* 56 * Shell variables. 57 */ 58 59 #include "shell.h" 60 #include "output.h" 61 #include "expand.h" 62 #include "nodes.h" /* for other headers */ 63 #include "eval.h" /* defines cmdenviron */ 64 #include "exec.h" 65 #include "syntax.h" 66 #include "options.h" 67 #include "builtins.h" 68 #include "mail.h" 69 #include "var.h" 70 #include "memalloc.h" 71 #include "error.h" 72 #include "mystring.h" 73 #include "parser.h" 74 #include "show.h" 75 #include "machdep.h" 76 #ifndef SMALL 77 #include "myhistedit.h" 78 #endif 79 80 #ifdef SMALL 81 #define VTABSIZE 39 82 #else 83 #define VTABSIZE 517 84 #endif 85 86 87 struct varinit { 88 struct var *var; 89 int flags; 90 const char *text; 91 union var_func_union v_u; 92 }; 93 #define func v_u.set_func 94 #define rfunc v_u.ref_func 95 96 char *get_lineno(struct var *); 97 98 #ifndef SMALL 99 char *get_tod(struct var *); 100 char *get_hostname(struct var *); 101 char *get_seconds(struct var *); 102 char *get_euser(struct var *); 103 char *get_random(struct var *); 104 #endif 105 106 struct localvar *localvars; 107 108 #ifndef SMALL 109 struct var vhistsize; 110 struct var vterm; 111 struct var editrc; 112 struct var ps_lit; 113 #endif 114 struct var vifs; 115 struct var vmail; 116 struct var vmpath; 117 struct var vpath; 118 struct var vps1; 119 struct var vps2; 120 struct var vps4; 121 struct var vvers; 122 struct var voptind; 123 struct var line_num; 124 #ifndef SMALL 125 struct var tod; 126 struct var host_name; 127 struct var seconds; 128 struct var euname; 129 struct var random_num; 130 131 intmax_t sh_start_time; 132 #endif 133 134 struct var line_num; 135 int line_number; 136 int funclinebase = 0; 137 int funclineabs = 0; 138 139 char ifs_default[] = " \t\n"; 140 141 const struct varinit varinit[] = { 142 #ifndef SMALL 143 { &vhistsize, VSTRFIXED|VTEXTFIXED|VUNSET, "HISTSIZE=", 144 { .set_func= sethistsize } }, 145 #endif 146 { &vifs, VSTRFIXED|VTEXTFIXED, "IFS= \t\n", 147 { NULL } }, 148 { &vmail, VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL=", 149 { NULL } }, 150 { &vmpath, VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH=", 151 { NULL } }, 152 { &vvers, VSTRFIXED|VTEXTFIXED|VNOEXPORT, "NETBSD_SHELL=", 153 { NULL } }, 154 { &vpath, VSTRFIXED|VTEXTFIXED, "PATH=" _PATH_DEFPATH, 155 { .set_func= changepath } }, 156 /* 157 * vps1 depends on uid 158 */ 159 { &vps2, VSTRFIXED|VTEXTFIXED, "PS2=> ", 160 { NULL } }, 161 { &vps4, VSTRFIXED|VTEXTFIXED, "PS4=+ ", 162 { NULL } }, 163 #ifndef SMALL 164 { &vterm, VSTRFIXED|VTEXTFIXED|VUNSET, "TERM=", 165 { .set_func= setterm } }, 166 { &editrc, VSTRFIXED|VTEXTFIXED|VUNSET, "EDITRC=", 167 { .set_func= set_editrc } }, 168 { &ps_lit, VSTRFIXED|VTEXTFIXED|VUNSET, "PSlit=", 169 { .set_func= set_prompt_lit } }, 170 #endif 171 { &voptind, VSTRFIXED|VTEXTFIXED|VNOFUNC, "OPTIND=1", 172 { .set_func= getoptsreset } }, 173 { &line_num, VSTRFIXED|VTEXTFIXED|VFUNCREF|VSPECIAL, "LINENO=1", 174 { .ref_func= get_lineno } }, 175 #ifndef SMALL 176 { &tod, VSTRFIXED|VTEXTFIXED|VFUNCREF, "ToD=", 177 { .ref_func= get_tod } }, 178 { &host_name, VSTRFIXED|VTEXTFIXED|VFUNCREF, "HOSTNAME=", 179 { .ref_func= get_hostname } }, 180 { &seconds, VSTRFIXED|VTEXTFIXED|VFUNCREF, "SECONDS=", 181 { .ref_func= get_seconds } }, 182 { &euname, VSTRFIXED|VTEXTFIXED|VFUNCREF, "EUSER=", 183 { .ref_func= get_euser } }, 184 { &random_num, VSTRFIXED|VTEXTFIXED|VFUNCREF|VSPECIAL, "RANDOM=", 185 { .ref_func= get_random } }, 186 #endif 187 { NULL, 0, NULL, 188 { NULL } } 189 }; 190 191 struct var *vartab[VTABSIZE]; 192 193 STATIC int strequal(const char *, const char *); 194 STATIC struct var *find_var(const char *, struct var ***, int *); 195 STATIC void showvar(struct var *, const char *, const char *, int); 196 static void export_usage(const char *) __dead; 197 198 /* 199 * Initialize the varable symbol tables and import the environment 200 */ 201 202 #ifdef mkinit 203 INCLUDE <stdio.h> 204 INCLUDE <unistd.h> 205 INCLUDE <time.h> 206 INCLUDE "var.h" 207 INCLUDE "version.h" 208 MKINIT char **environ; 209 INIT { 210 char **envp; 211 char buf[64]; 212 213 #ifndef SMALL 214 sh_start_time = (intmax_t)time((time_t *)0); 215 #endif 216 /* 217 * Set up our default variables and their values. 218 */ 219 initvar(); 220 221 /* 222 * Import variables from the environment, which will 223 * override anything initialised just previously. 224 */ 225 for (envp = environ ; *envp ; envp++) { 226 if (strchr(*envp, '=')) { 227 setvareq(*envp, VEXPORT|VTEXTFIXED); 228 } 229 } 230 231 /* 232 * Set variables which override anything read from environment. 233 * 234 * PPID is readonly 235 * Always default IFS 236 * POSIX: "Whenever the shell is invoked, OPTIND shall 237 * be initialized to 1." 238 * PSc indicates the root/non-root status of this shell. 239 * START_TIME belongs only to this shell. 240 * NETBSD_SHELL is a constant (readonly), and is never exported 241 * LINENO is simply magic... 242 */ 243 snprintf(buf, sizeof(buf), "%d", (int)getppid()); 244 setvar("PPID", buf, VREADONLY); 245 setvar("IFS", ifs_default, VTEXTFIXED); 246 setvar("OPTIND", "1", VTEXTFIXED); 247 setvar("PSc", (geteuid() == 0 ? "#" : "$"), VTEXTFIXED); 248 249 #ifndef SMALL 250 snprintf(buf, sizeof(buf), "%jd", sh_start_time); 251 setvar("START_TIME", buf, VTEXTFIXED); 252 #endif 253 254 setvar("NETBSD_SHELL", NETBSD_SHELL 255 #ifdef BUILD_DATE 256 " BUILD:" BUILD_DATE 257 #endif 258 #ifdef DEBUG 259 " DEBUG" 260 #endif 261 #if !defined(JOBS) || JOBS == 0 262 " -JOBS" 263 #endif 264 #ifndef DO_SHAREDVFORK 265 " -VFORK" 266 #endif 267 #ifdef SMALL 268 " SMALL" 269 #endif 270 #ifdef TINY 271 " TINY" 272 #endif 273 #ifdef OLD_TTY_DRIVER 274 " OLD_TTY" 275 #endif 276 #ifdef SYSV 277 " SYSV" 278 #endif 279 #ifndef BSD 280 " -BSD" 281 #endif 282 #ifdef BOGUS_NOT_COMMAND 283 " BOGUS_NOT" 284 #endif 285 , VTEXTFIXED|VREADONLY|VNOEXPORT); 286 287 setvar("LINENO", "1", VTEXTFIXED); 288 } 289 #endif 290 291 292 /* 293 * This routine initializes the builtin variables. It is called when the 294 * shell is initialized and again when a shell procedure is spawned. 295 */ 296 297 void 298 initvar(void) 299 { 300 const struct varinit *ip; 301 struct var *vp; 302 struct var **vpp; 303 304 for (ip = varinit ; (vp = ip->var) != NULL ; ip++) { 305 if (find_var(ip->text, &vpp, &vp->name_len) != NULL) 306 continue; 307 vp->next = *vpp; 308 *vpp = vp; 309 vp->text = strdup(ip->text); 310 vp->flags = (ip->flags & ~VTEXTFIXED) | VSTRFIXED; 311 vp->v_u = ip->v_u; 312 } 313 /* 314 * PS1 depends on uid 315 */ 316 if (find_var("PS1", &vpp, &vps1.name_len) == NULL) { 317 vps1.next = *vpp; 318 *vpp = &vps1; 319 vps1.flags = VSTRFIXED; 320 vps1.text = NULL; 321 choose_ps1(); 322 } 323 } 324 325 void 326 choose_ps1(void) 327 { 328 uid_t u = geteuid(); 329 330 if ((vps1.flags & (VTEXTFIXED|VSTACK)) == 0) 331 free(vps1.text); 332 vps1.text = strdup(u != 0 ? "PS1=$ " : "PS1=# "); 333 vps1.flags &= ~(VTEXTFIXED|VSTACK); 334 335 /* 336 * Update PSc whenever we feel the need to update PS1 337 */ 338 setvarsafe("PSc", (u == 0 ? "#" : "$"), 0); 339 } 340 341 /* 342 * Validate a string as a valid variable name 343 * nb: not parameter - special params and such are "invalid" here. 344 * Name terminated by either \0 or the term param (usually '=' or '\0'). 345 * 346 * If not NULL, the length of the (intended) name is returned via len 347 */ 348 349 int 350 validname(const char *name, int term, int *len) 351 { 352 const char *p = name; 353 int ok = 1; 354 355 if (p == NULL || *p == '\0' || *p == term) { 356 if (len != NULL) 357 *len = 0; 358 return 0; 359 } 360 361 if (!is_name(*p)) 362 ok = 0; 363 p++; 364 for (;;) { 365 if (*p == '\0' || *p == term) 366 break; 367 if (!is_in_name(*p)) 368 ok = 0; 369 p++; 370 } 371 if (len != NULL) 372 *len = p - name; 373 374 return ok; 375 } 376 377 /* 378 * Safe version of setvar, returns 1 on success 0 on failure. 379 */ 380 381 int 382 setvarsafe(const char *name, const char *val, int flags) 383 { 384 struct jmploc jmploc; 385 struct jmploc * const savehandler = handler; 386 int volatile err = 0; 387 388 if (setjmp(jmploc.loc)) 389 err = 1; 390 else { 391 handler = &jmploc; 392 setvar(name, val, flags); 393 } 394 handler = savehandler; 395 return err; 396 } 397 398 /* 399 * Set the value of a variable. The flags argument is ored with the 400 * flags of the variable. If val is NULL, the variable is unset. 401 * 402 * This always copies name and val when setting a variable, so 403 * the source strings can be from anywhere, and are no longer needed 404 * after this function returns. The VTEXTFIXED and VSTACK flags should 405 * not be used (but just in case they were, clear them.) 406 */ 407 408 void 409 setvar(const char *name, const char *val, int flags) 410 { 411 const char *p; 412 const char *q; 413 char *d; 414 int len; 415 int namelen; 416 char *nameeq; 417 418 p = name; 419 420 if (!validname(p, '=', &namelen)) 421 error("%.*s: bad variable name", namelen, name); 422 len = namelen + 2; /* 2 is space for '=' and '\0' */ 423 if (val == NULL) { 424 flags |= VUNSET; 425 } else { 426 len += strlen(val); 427 } 428 d = nameeq = ckmalloc(len); 429 q = name; 430 while (--namelen >= 0) 431 *d++ = *q++; 432 *d++ = '='; 433 *d = '\0'; 434 if (val) 435 scopy(val, d); 436 setvareq(nameeq, flags & ~(VTEXTFIXED | VSTACK)); 437 } 438 439 440 441 /* 442 * Same as setvar except that the variable and value are passed in 443 * the first argument as name=value. Since the first argument will 444 * be actually stored in the table, it should not be a string that 445 * will go away. The flags (VTEXTFIXED or VSTACK) can be used to 446 * indicate the source of the string (if neither is set, the string will 447 * eventually be free()d when a replacement value is assigned.) 448 */ 449 450 void 451 setvareq(char *s, int flags) 452 { 453 struct var *vp, **vpp; 454 int nlen; 455 456 VTRACE(DBG_VARS, ("setvareq([%s],%#x) aflag=%d ", s, flags, aflag)); 457 if (aflag && !(flags & VNOEXPORT)) 458 flags |= VEXPORT; 459 vp = find_var(s, &vpp, &nlen); 460 if (vp != NULL) { 461 VTRACE(DBG_VARS, ("was [%s] fl:%#x\n", vp->text, 462 vp->flags)); 463 if (vp->flags & VREADONLY) { 464 if ((flags & (VTEXTFIXED|VSTACK)) == 0) 465 ckfree(s); 466 if (flags & VNOERROR) 467 return; 468 error("%.*s: is read only", vp->name_len, vp->text); 469 } 470 if (flags & VNOSET) { 471 if ((flags & (VTEXTFIXED|VSTACK)) == 0) 472 ckfree(s); 473 return; 474 } 475 476 INTOFF; 477 478 if (vp->func && !(vp->flags & VFUNCREF) && !(flags & VNOFUNC)) 479 (*vp->func)(s + vp->name_len + 1); 480 481 if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0) 482 ckfree(vp->text); 483 484 /* 485 * if we set a magic var, the magic dissipates, 486 * unless it is very special indeed. 487 */ 488 if (vp->rfunc && (vp->flags & (VFUNCREF|VSPECIAL)) == VFUNCREF) 489 vp->rfunc = NULL; 490 491 vp->flags &= ~(VTEXTFIXED|VSTACK|VUNSET); 492 if (flags & VNOEXPORT) 493 vp->flags &= ~VEXPORT; 494 if (flags & VDOEXPORT) 495 vp->flags &= ~VNOEXPORT; 496 if (vp->flags & VNOEXPORT) 497 flags &= ~VEXPORT; 498 vp->flags |= flags & ~(VNOFUNC | VDOEXPORT); 499 vp->text = s; 500 501 /* 502 * We could roll this to a function, to handle it as 503 * a regular variable function callback, but why bother? 504 */ 505 if (vp == &vmpath || (vp == &vmail && ! mpathset())) 506 chkmail(1); 507 508 INTON; 509 return; 510 } 511 /* not found */ 512 if (flags & VNOSET) { 513 VTRACE(DBG_VARS, ("new noset\n")); 514 if ((flags & (VTEXTFIXED|VSTACK)) == 0) 515 ckfree(s); 516 return; 517 } 518 vp = ckmalloc(sizeof (*vp)); 519 vp->flags = flags & ~(VNOFUNC|VFUNCREF|VDOEXPORT); 520 vp->text = s; 521 vp->name_len = nlen; 522 vp->func = NULL; 523 vp->next = *vpp; 524 *vpp = vp; 525 526 VTRACE(DBG_VARS, ("new [%s] (%d) %#x\n", s, nlen, vp->flags)); 527 } 528 529 530 531 /* 532 * Process a linked list of variable assignments. 533 */ 534 535 void 536 listsetvar(struct strlist *list, int flags) 537 { 538 struct strlist *lp; 539 540 INTOFF; 541 for (lp = list ; lp ; lp = lp->next) { 542 setvareq(savestr(lp->text), flags); 543 } 544 INTON; 545 } 546 547 void 548 listmklocal(struct strlist *list, int flags) 549 { 550 struct strlist *lp; 551 552 for (lp = list ; lp ; lp = lp->next) 553 mklocal(lp->text, flags); 554 } 555 556 557 /* 558 * Find the value of a variable. Returns NULL if not set. 559 */ 560 561 char * 562 lookupvar(const char *name) 563 { 564 struct var *v; 565 566 v = find_var(name, NULL, NULL); 567 if (v == NULL || v->flags & VUNSET) 568 return NULL; 569 if (v->rfunc && (v->flags & VFUNCREF) != 0) 570 return (*v->rfunc)(v) + v->name_len + 1; 571 return v->text + v->name_len + 1; 572 } 573 574 575 576 /* 577 * Search the environment of a builtin command. If the second argument 578 * is nonzero, return the value of a variable even if it hasn't been 579 * exported. 580 */ 581 582 char * 583 bltinlookup(const char *name, int doall) 584 { 585 struct strlist *sp; 586 struct var *v; 587 588 for (sp = cmdenviron ; sp ; sp = sp->next) { 589 if (strequal(sp->text, name)) 590 return strchr(sp->text, '=') + 1; 591 } 592 593 v = find_var(name, NULL, NULL); 594 595 if (v == NULL || v->flags & VUNSET || (!doall && !(v->flags & VEXPORT))) 596 return NULL; 597 if (v->rfunc && (v->flags & VFUNCREF) != 0) 598 return (*v->rfunc)(v) + v->name_len + 1; 599 return v->text + v->name_len + 1; 600 } 601 602 603 604 /* 605 * Generate a list of exported variables. This routine is used to construct 606 * the third argument to execve when executing a program. 607 */ 608 609 char ** 610 environment(void) 611 { 612 int nenv; 613 struct var **vpp; 614 struct var *vp; 615 char **env; 616 char **ep; 617 618 nenv = 0; 619 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) { 620 for (vp = *vpp ; vp ; vp = vp->next) 621 if ((vp->flags & (VEXPORT|VUNSET)) == VEXPORT) 622 nenv++; 623 } 624 CTRACE(DBG_VARS, ("environment: %d vars to export\n", nenv)); 625 ep = env = stalloc((nenv + 1) * sizeof *env); 626 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) { 627 for (vp = *vpp ; vp ; vp = vp->next) 628 if ((vp->flags & (VEXPORT|VUNSET)) == VEXPORT) { 629 if (vp->rfunc && (vp->flags & VFUNCREF)) 630 *ep++ = (*vp->rfunc)(vp); 631 else 632 *ep++ = vp->text; 633 VTRACE(DBG_VARS, ("environment: %s\n", ep[-1])); 634 } 635 } 636 *ep = NULL; 637 return env; 638 } 639 640 641 /* 642 * Called when a shell procedure is invoked to clear out nonexported 643 * variables. It is also necessary to reallocate variables of with 644 * VSTACK set since these are currently allocated on the stack. 645 */ 646 647 #ifdef mkinit 648 void shprocvar(void); 649 650 SHELLPROC { 651 shprocvar(); 652 } 653 #endif 654 655 void 656 shprocvar(void) 657 { 658 struct var **vpp; 659 struct var *vp, **prev; 660 661 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) { 662 for (prev = vpp ; (vp = *prev) != NULL ; ) { 663 if ((vp->flags & VEXPORT) == 0) { 664 *prev = vp->next; 665 if ((vp->flags & VTEXTFIXED) == 0) 666 ckfree(vp->text); 667 if ((vp->flags & VSTRFIXED) == 0) 668 ckfree(vp); 669 } else { 670 if (vp->flags & VSTACK) { 671 vp->text = savestr(vp->text); 672 vp->flags &=~ VSTACK; 673 } 674 prev = &vp->next; 675 } 676 } 677 } 678 initvar(); 679 } 680 681 682 683 /* 684 * Command to list all variables which are set. Currently this command 685 * is invoked from the set command when the set command is called without 686 * any variables. 687 */ 688 689 void 690 print_quoted(const char *p) 691 { 692 const char *q; 693 694 if (p[0] == '\0') { 695 out1fmt("''"); 696 return; 697 } 698 if (strcspn(p, "|&;<>()$`\\\"' \t\n*?[]#~=%") == strlen(p)) { 699 out1fmt("%s", p); 700 return; 701 } 702 while (*p) { 703 if (*p == '\'') { 704 out1fmt("\\'"); 705 p++; 706 continue; 707 } 708 q = strchr(p, '\''); 709 if (!q) { 710 out1fmt("'%s'", p ); 711 return; 712 } 713 out1fmt("'%.*s'", (int)(q - p), p ); 714 p = q; 715 } 716 } 717 718 static int 719 sort_var(const void *v_v1, const void *v_v2) 720 { 721 const struct var * const *v1 = v_v1; 722 const struct var * const *v2 = v_v2; 723 char *t1 = (*v1)->text, *t2 = (*v2)->text; 724 725 if (*t1 == *t2) { 726 char *p, *s; 727 728 STARTSTACKSTR(p); 729 730 /* 731 * note: if lengths are equal, strings must be different 732 * so we don't care which string we pick for the \0 in 733 * that case. 734 */ 735 if ((strchr(t1, '=') - t1) <= (strchr(t2, '=') - t2)) { 736 s = t1; 737 t1 = p; 738 } else { 739 s = t2; 740 t2 = p; 741 } 742 743 while (*s && *s != '=') { 744 STPUTC(*s, p); 745 s++; 746 } 747 STPUTC('\0', p); 748 } 749 750 return strcoll(t1, t2); 751 } 752 753 /* 754 * POSIX requires that 'set' (but not export or readonly) output the 755 * variables in lexicographic order - by the locale's collating order (sigh). 756 * Maybe we could keep them in an ordered balanced binary tree 757 * instead of hashed lists. 758 * For now just roll 'em through qsort for printing... 759 */ 760 761 STATIC void 762 showvar(struct var *vp, const char *cmd, const char *xtra, int show_value) 763 { 764 const char *p; 765 766 if (cmd) 767 out1fmt("%s ", cmd); 768 if (xtra) 769 out1fmt("%s ", xtra); 770 p = vp->text; 771 if (vp->rfunc && (vp->flags & VFUNCREF) != 0) { 772 p = (*vp->rfunc)(vp); 773 if (p == NULL) 774 p = vp->text; 775 } 776 for ( ; *p != '=' ; p++) 777 out1c(*p); 778 if (!(vp->flags & VUNSET) && show_value) { 779 out1fmt("="); 780 print_quoted(++p); 781 } 782 out1c('\n'); 783 } 784 785 int 786 showvars(const char *cmd, int flag, int show_value, const char *xtra) 787 { 788 struct var **vpp; 789 struct var *vp; 790 791 static struct var **list; /* static in case we are interrupted */ 792 static int list_len; 793 int count = 0; 794 795 if (!list) { 796 list_len = 32; 797 list = ckmalloc(list_len * sizeof *list); 798 } 799 800 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) { 801 for (vp = *vpp ; vp ; vp = vp->next) { 802 if (flag && !(vp->flags & flag)) 803 continue; 804 if (vp->flags & VUNSET && !(show_value & 2)) 805 continue; 806 if (count >= list_len) { 807 list = ckrealloc(list, 808 (list_len << 1) * sizeof *list); 809 list_len <<= 1; 810 } 811 list[count++] = vp; 812 } 813 } 814 815 qsort(list, count, sizeof *list, sort_var); 816 817 for (vpp = list; count--; vpp++) 818 showvar(*vpp, cmd, xtra, show_value); 819 820 /* no free(list), will be used again next time ... */ 821 822 return 0; 823 } 824 825 826 827 /* 828 * The export and readonly commands. 829 */ 830 831 static void __dead 832 export_usage(const char *cmd) 833 { 834 #ifdef SMALL 835 if (*cmd == 'r') 836 error("Usage: %s [ -p | var[=val]... ]", cmd); 837 else 838 error("Usage: %s [ -p | [-n] var[=val]... ]", cmd); 839 #else 840 if (*cmd == 'r') 841 error("Usage: %s [-p [var...] | -q var... | var[=val]... ]", cmd); 842 else 843 error( 844 "Usage: %s [ -px [var...] | -q[x] var... | [-n|x] var[=val]... ]", 845 cmd); 846 #endif 847 } 848 849 int 850 exportcmd(int argc, char **argv) 851 { 852 struct var *vp; 853 char *name; 854 const char *p = argv[0]; 855 int flag = p[0] == 'r'? VREADONLY : VEXPORT; 856 int pflg = 0; 857 int nflg = 0; 858 #ifndef SMALL 859 int xflg = 0; 860 int qflg = 0; 861 #endif 862 int res; 863 int c; 864 int f; 865 866 #ifdef SMALL 867 #define EXPORT_OPTS "np" 868 #else 869 #define EXPORT_OPTS "npqx" 870 #endif 871 872 while ((c = nextopt(EXPORT_OPTS)) != '\0') { 873 874 #undef EXPORT_OPTS 875 876 switch (c) { 877 case 'n': 878 if (pflg || flag == VREADONLY 879 #ifndef SMALL 880 || qflg || xflg 881 #endif 882 ) 883 export_usage(p); 884 nflg = 1; 885 break; 886 case 'p': 887 if (nflg 888 #ifndef SMALL 889 || qflg 890 #endif 891 ) 892 export_usage(p); 893 pflg = 3; 894 break; 895 #ifndef SMALL 896 case 'q': 897 if (nflg || pflg) 898 export_usage(p); 899 qflg = 1; 900 break; 901 case 'x': 902 if (nflg || flag == VREADONLY) 903 export_usage(p); 904 flag = VNOEXPORT; 905 xflg = 1; 906 break; 907 #endif 908 } 909 } 910 911 if ((nflg 912 #ifndef SMALL 913 || qflg 914 #endif 915 ) && *argptr == NULL) 916 export_usage(p); 917 918 #ifndef SMALL 919 if (pflg && *argptr != NULL) { 920 while ((name = *argptr++) != NULL) { 921 int len; 922 923 vp = find_var(name, NULL, &len); 924 if (name[len] == '=') 925 export_usage(p); 926 if (!goodname(name)) 927 error("%s: bad variable name", name); 928 929 if (vp && vp->flags & flag) 930 showvar(vp, p, xflg ? "-x" : NULL, 1); 931 } 932 return 0; 933 } 934 #endif 935 936 if (pflg || *argptr == NULL) 937 return showvars( pflg ? p : 0, flag, pflg, 938 #ifndef SMALL 939 pflg && xflg ? "-x" : 940 #endif 941 NULL ); 942 943 res = 0; 944 #ifndef SMALL 945 if (qflg) { 946 while ((name = *argptr++) != NULL) { 947 int len; 948 949 vp = find_var(name, NULL, &len); 950 if (name[len] == '=') 951 export_usage(p); 952 if (!goodname(name)) 953 error("%s: bad variable name", name); 954 955 if (vp == NULL || !(vp->flags & flag)) 956 res = 1; 957 } 958 return res; 959 } 960 #endif 961 962 while ((name = *argptr++) != NULL) { 963 int len; 964 965 f = flag; 966 967 vp = find_var(name, NULL, &len); 968 p = name + len; 969 if (*p++ != '=') 970 p = NULL; 971 972 if (vp != NULL) { 973 if (nflg) 974 vp->flags &= ~flag; 975 else if (flag&VEXPORT && vp->flags&VNOEXPORT) { 976 /* note we go ahead and do any assignment */ 977 sh_warnx("%.*s: not available for export", 978 len, name); 979 res = 1; 980 } else { 981 if (flag == VNOEXPORT) 982 vp->flags &= ~VEXPORT; 983 984 /* if not NULL will be done in setvar below */ 985 if (p == NULL) 986 vp->flags |= flag; 987 } 988 if (p == NULL) 989 continue; 990 } else if (nflg && p == NULL && !goodname(name)) 991 error("%s: bad variable name", name); 992 993 if (!nflg || p != NULL) 994 setvar(name, p, f); 995 } 996 return res; 997 } 998 999 1000 /* 1001 * The "local" command. 1002 */ 1003 1004 int 1005 localcmd(int argc, char **argv) 1006 { 1007 char *name; 1008 int c; 1009 int flags = 0; /*XXX perhaps VUNSET from a -o option value */ 1010 1011 if (! in_function()) 1012 error("Not in a function"); 1013 1014 /* upper case options, as bash stole all the good ones ... */ 1015 while ((c = nextopt("INx")) != '\0') 1016 switch (c) { 1017 case 'I': flags &= ~VUNSET; break; 1018 case 'N': flags |= VUNSET; break; 1019 case 'x': flags |= VEXPORT; break; 1020 } 1021 1022 while ((name = *argptr++) != NULL) { 1023 mklocal(name, flags); 1024 } 1025 return 0; 1026 } 1027 1028 1029 /* 1030 * Make a variable a local variable. When a variable is made local, its 1031 * value and flags are saved in a localvar structure. The saved values 1032 * will be restored when the shell function returns. We handle the name 1033 * "-" as a special case. 1034 */ 1035 1036 void 1037 mklocal(const char *name, int flags) 1038 { 1039 struct localvar *lvp; 1040 struct var **vpp; 1041 struct var *vp; 1042 1043 INTOFF; 1044 lvp = ckmalloc(sizeof (struct localvar)); 1045 if (name[0] == '-' && name[1] == '\0') { 1046 char *p; 1047 p = ckmalloc(sizeof_optlist); 1048 lvp->text = memcpy(p, optlist, sizeof_optlist); 1049 lvp->rfunc = NULL; 1050 vp = NULL; 1051 xtrace_clone(0); 1052 } else { 1053 vp = find_var(name, &vpp, NULL); 1054 if (vp == NULL) { 1055 flags &= ~VNOEXPORT; 1056 if (strchr(name, '=')) 1057 setvareq(savestr(name), 1058 VSTRFIXED | (flags & ~VUNSET)); 1059 else 1060 setvar(name, NULL, VSTRFIXED|flags); 1061 vp = *vpp; /* the new variable */ 1062 lvp->text = NULL; 1063 lvp->flags = VUNSET; 1064 lvp->rfunc = NULL; 1065 } else { 1066 lvp->text = vp->text; 1067 lvp->flags = vp->flags; 1068 lvp->v_u = vp->v_u; 1069 vp->flags |= VSTRFIXED|VTEXTFIXED; 1070 if (flags & (VDOEXPORT | VUNSET)) 1071 vp->flags &= ~VNOEXPORT; 1072 if (vp->flags & VNOEXPORT && 1073 (flags & (VEXPORT|VDOEXPORT|VUNSET)) == VEXPORT) 1074 flags &= ~VEXPORT; 1075 if (flags & (VNOEXPORT | VUNSET)) 1076 vp->flags &= ~VEXPORT; 1077 flags &= ~VNOEXPORT; 1078 if (name[vp->name_len] == '=') 1079 setvareq(savestr(name), flags & ~VUNSET); 1080 else if (flags & VUNSET) 1081 unsetvar(name, 0); 1082 else 1083 vp->flags |= flags & (VUNSET|VEXPORT); 1084 1085 if (vp == &line_num) { 1086 if (name[vp->name_len] == '=') 1087 funclinebase = funclineabs -1; 1088 else 1089 funclinebase = 0; 1090 } 1091 } 1092 } 1093 lvp->vp = vp; 1094 lvp->next = localvars; 1095 localvars = lvp; 1096 INTON; 1097 } 1098 1099 1100 /* 1101 * Called after a function returns. 1102 */ 1103 1104 void 1105 poplocalvars(void) 1106 { 1107 struct localvar *lvp; 1108 struct var *vp; 1109 1110 while ((lvp = localvars) != NULL) { 1111 localvars = lvp->next; 1112 vp = lvp->vp; 1113 VTRACE(DBG_VARS, ("poplocalvar %s\n", vp ? vp->text : "-")); 1114 if (vp == NULL) { /* $- saved */ 1115 memcpy(optlist, lvp->text, sizeof_optlist); 1116 ckfree(lvp->text); 1117 xtrace_pop(); 1118 optschanged(); 1119 } else if ((lvp->flags & (VUNSET|VSTRFIXED)) == VUNSET) { 1120 (void)unsetvar(vp->text, 0); 1121 } else { 1122 if (lvp->func && (lvp->flags & (VNOFUNC|VFUNCREF)) == 0) 1123 (*lvp->func)(lvp->text + vp->name_len + 1); 1124 if ((vp->flags & VTEXTFIXED) == 0) 1125 ckfree(vp->text); 1126 vp->flags = lvp->flags; 1127 vp->text = lvp->text; 1128 vp->v_u = lvp->v_u; 1129 } 1130 ckfree(lvp); 1131 } 1132 } 1133 1134 1135 int 1136 setvarcmd(int argc, char **argv) 1137 { 1138 if (argc <= 2) 1139 return unsetcmd(argc, argv); 1140 else if (argc == 3) 1141 setvar(argv[1], argv[2], 0); 1142 else 1143 error("List assignment not implemented"); 1144 return 0; 1145 } 1146 1147 1148 /* 1149 * The unset builtin command. We unset the function before we unset the 1150 * variable to allow a function to be unset when there is a readonly variable 1151 * with the same name. 1152 */ 1153 1154 int 1155 unsetcmd(int argc, char **argv) 1156 { 1157 char **ap; 1158 int i; 1159 int flg_func = 0; 1160 int flg_var = 0; 1161 int flg_x = 0; 1162 int ret = 0; 1163 1164 while ((i = nextopt("efvx")) != '\0') { 1165 switch (i) { 1166 case 'f': 1167 flg_func = 1; 1168 break; 1169 case 'e': 1170 case 'x': 1171 flg_x = (2 >> (i == 'e')); 1172 /* FALLTHROUGH */ 1173 case 'v': 1174 flg_var = 1; 1175 break; 1176 } 1177 } 1178 1179 if (flg_func == 0 && flg_var == 0) 1180 flg_var = 1; 1181 1182 for (ap = argptr; *ap ; ap++) { 1183 if (flg_func) 1184 ret |= unsetfunc(*ap); 1185 if (flg_var) 1186 ret |= unsetvar(*ap, flg_x); 1187 } 1188 return ret; 1189 } 1190 1191 1192 /* 1193 * Unset the specified variable. 1194 */ 1195 1196 int 1197 unsetvar(const char *s, int unexport) 1198 { 1199 struct var **vpp; 1200 struct var *vp; 1201 1202 vp = find_var(s, &vpp, NULL); 1203 if (vp == NULL) 1204 return 0; 1205 1206 if (vp->flags & VREADONLY && !(unexport & 1)) 1207 return 1; 1208 1209 INTOFF; 1210 if (unexport & 1) { 1211 vp->flags &= ~VEXPORT; 1212 } else { 1213 if (vp->text[vp->name_len + 1] != '\0') 1214 setvar(s, nullstr, 0); 1215 if (!(unexport & 2)) 1216 vp->flags &= ~VEXPORT; 1217 vp->flags |= VUNSET; 1218 if ((vp->flags&(VEXPORT|VSTRFIXED|VREADONLY|VNOEXPORT)) == 0) { 1219 if ((vp->flags & VTEXTFIXED) == 0) 1220 ckfree(vp->text); 1221 *vpp = vp->next; 1222 ckfree(vp); 1223 } 1224 } 1225 INTON; 1226 return 0; 1227 } 1228 1229 1230 /* 1231 * Returns true if the two strings specify the same varable. The first 1232 * variable name is terminated by '='; the second may be terminated by 1233 * either '=' or '\0'. 1234 */ 1235 1236 STATIC int 1237 strequal(const char *p, const char *q) 1238 { 1239 while (*p == *q++) { 1240 if (*p++ == '=') 1241 return 1; 1242 } 1243 if (*p == '=' && *(q - 1) == '\0') 1244 return 1; 1245 return 0; 1246 } 1247 1248 /* 1249 * Search for a variable. 1250 * 'name' may be terminated by '=' or a NUL. 1251 * vppp is set to the pointer to vp, or the list head if vp isn't found 1252 * lenp is set to the number of characters in 'name' 1253 */ 1254 1255 STATIC struct var * 1256 find_var(const char *name, struct var ***vppp, int *lenp) 1257 { 1258 unsigned int hashval; 1259 int len; 1260 struct var *vp, **vpp; 1261 const char *p = name; 1262 1263 hashval = 0; 1264 while (*p && *p != '=') 1265 hashval = 2 * hashval + (unsigned char)*p++; 1266 1267 len = p - name; 1268 if (lenp) 1269 *lenp = len; 1270 1271 vpp = &vartab[hashval % VTABSIZE]; 1272 if (vppp) 1273 *vppp = vpp; 1274 1275 for (vp = *vpp ; vp ; vpp = &vp->next, vp = *vpp) { 1276 if (vp->name_len != len) 1277 continue; 1278 if (memcmp(vp->text, name, len) != 0) 1279 continue; 1280 if (vppp) 1281 *vppp = vpp; 1282 return vp; 1283 } 1284 return NULL; 1285 } 1286 1287 /* 1288 * The following are the functions that create the values for 1289 * shell variables that are dynamically produced when needed. 1290 * 1291 * The output strings cannot be malloc'd as there is nothing to 1292 * free them - callers assume these are ordinary variables where 1293 * the value returned is vp->text 1294 * 1295 * Each function needs its own storage space, as the results are 1296 * used to create processes' environment, and (if exported) all 1297 * the values will (might) be needed simultaneously. 1298 * 1299 * It is not a problem if a var is updated while nominally in use 1300 * somewhere, all these are intended to be dynamic, the value they 1301 * return is not guaranteed, an updated vaue is just as good. 1302 * 1303 * So, malloc a single buffer for the result of each function, 1304 * grow, and even shrink, it as needed, but once we have one that 1305 * is a suitable size for the actual usage, simply hold it forever. 1306 * 1307 * For a SMALL shell we implement only LINENO, none of the others, 1308 * and give it just a fixed length static buffer for its result. 1309 */ 1310 1311 #ifndef SMALL 1312 1313 struct space_reserved { /* record of space allocated for results */ 1314 char *b; 1315 int len; 1316 }; 1317 1318 /* rough (over-)estimate of the number of bytes needed to hold a number */ 1319 static int 1320 digits_in(intmax_t number) 1321 { 1322 int res = 0; 1323 1324 if (number & ~((1LL << 62) - 1)) 1325 res = 64; /* enough for 2^200 and a bit more */ 1326 else if (number & ~((1LL << 32) - 1)) 1327 res = 20; /* enough for 2^64 */ 1328 else if (number & ~((1 << 23) - 1)) 1329 res = 10; /* enough for 2^32 */ 1330 else 1331 res = 8; /* enough for 2^23 or smaller */ 1332 1333 return res; 1334 } 1335 1336 static int 1337 make_space(struct space_reserved *m, int bytes) 1338 { 1339 void *p; 1340 1341 if (m->len >= bytes && m->len <= (bytes<<2)) 1342 return 1; 1343 1344 bytes = SHELL_ALIGN(bytes); 1345 /* not ckrealloc() - we want failure, not error() here */ 1346 p = realloc(m->b, bytes); 1347 if (p == NULL) /* what we had should still be there */ 1348 return 0; 1349 1350 m->b = p; 1351 m->len = bytes; 1352 m->b[bytes - 1] = '\0'; 1353 1354 return 1; 1355 } 1356 #endif 1357 1358 char * 1359 get_lineno(struct var *vp) 1360 { 1361 #ifdef SMALL 1362 #define length (8 + 10) /* 10 digits is enough for a 32 bit line num */ 1363 static char result[length]; 1364 #else 1365 static struct space_reserved buf; 1366 #define result buf.b 1367 #define length buf.len 1368 #endif 1369 int ln = line_number; 1370 1371 if (vp->flags & VUNSET) 1372 return NULL; 1373 1374 ln -= funclinebase; 1375 1376 #ifndef SMALL 1377 if (!make_space(&buf, vp->name_len + 2 + digits_in(ln))) 1378 return vp->text; 1379 #endif 1380 1381 snprintf(result, length, "%.*s=%d", vp->name_len, vp->text, ln); 1382 return result; 1383 } 1384 #undef result 1385 #undef length 1386 1387 #ifndef SMALL 1388 1389 char * 1390 get_hostname(struct var *vp) 1391 { 1392 static struct space_reserved buf; 1393 1394 if (vp->flags & VUNSET) 1395 return NULL; 1396 1397 if (!make_space(&buf, vp->name_len + 2 + 256)) 1398 return vp->text; 1399 1400 memcpy(buf.b, vp->text, vp->name_len + 1); /* include '=' */ 1401 (void)gethostname(buf.b + vp->name_len + 1, 1402 buf.len - vp->name_len - 3); 1403 return buf.b; 1404 } 1405 1406 char * 1407 get_tod(struct var *vp) 1408 { 1409 static struct space_reserved buf; /* space for answers */ 1410 static struct space_reserved tzs; /* remember TZ last used */ 1411 static timezone_t last_zone; /* timezone data for tzs zone */ 1412 const char *fmt; 1413 char *tz; 1414 time_t now; 1415 struct tm tm_now, *tmp; 1416 timezone_t zone = NULL; 1417 static char t_err[] = "time error"; 1418 int len; 1419 1420 if (vp->flags & VUNSET) 1421 return NULL; 1422 1423 fmt = lookupvar("ToD_FORMAT"); 1424 if (fmt == NULL) 1425 fmt="%T"; 1426 tz = lookupvar("TZ"); 1427 (void)time(&now); 1428 1429 if (tz != NULL) { 1430 if (tzs.b == NULL || strcmp(tzs.b, tz) != 0) { 1431 if (make_space(&tzs, strlen(tz) + 1)) { 1432 INTOFF; 1433 strcpy(tzs.b, tz); 1434 if (last_zone) 1435 tzfree(last_zone); 1436 last_zone = zone = tzalloc(tz); 1437 INTON; 1438 } else 1439 zone = tzalloc(tz); 1440 } else 1441 zone = last_zone; 1442 1443 tmp = localtime_rz(zone, &now, &tm_now); 1444 } else 1445 tmp = localtime_r(&now, &tm_now); 1446 1447 len = (strlen(fmt) * 4) + vp->name_len + 2; 1448 while (make_space(&buf, len)) { 1449 memcpy(buf.b, vp->text, vp->name_len+1); 1450 if (tmp == NULL) { 1451 if (buf.len >= vp->name_len+2+(int)(sizeof t_err - 1)) { 1452 strcpy(buf.b + vp->name_len + 1, t_err); 1453 if (zone && zone != last_zone) 1454 tzfree(zone); 1455 return buf.b; 1456 } 1457 len = vp->name_len + 4 + sizeof t_err - 1; 1458 continue; 1459 } 1460 if (strftime_z(zone, buf.b + vp->name_len + 1, 1461 buf.len - vp->name_len - 2, fmt, tmp)) { 1462 if (zone && zone != last_zone) 1463 tzfree(zone); 1464 return buf.b; 1465 } 1466 if (len >= 4096) /* Let's be reasonable */ 1467 break; 1468 len <<= 1; 1469 } 1470 if (zone && zone != last_zone) 1471 tzfree(zone); 1472 return vp->text; 1473 } 1474 1475 char * 1476 get_seconds(struct var *vp) 1477 { 1478 static struct space_reserved buf; 1479 intmax_t secs; 1480 1481 if (vp->flags & VUNSET) 1482 return NULL; 1483 1484 secs = (intmax_t)time((time_t *)0) - sh_start_time; 1485 if (!make_space(&buf, vp->name_len + 2 + digits_in(secs))) 1486 return vp->text; 1487 1488 snprintf(buf.b, buf.len, "%.*s=%jd", vp->name_len, vp->text, secs); 1489 return buf.b; 1490 } 1491 1492 char * 1493 get_euser(struct var *vp) 1494 { 1495 static struct space_reserved buf; 1496 static uid_t lastuid = 0; 1497 uid_t euid; 1498 struct passwd *pw; 1499 1500 if (vp->flags & VUNSET) 1501 return NULL; 1502 1503 euid = geteuid(); 1504 if (buf.b != NULL && lastuid == euid) 1505 return buf.b; 1506 1507 pw = getpwuid(euid); 1508 if (pw == NULL) 1509 return vp->text; 1510 1511 if (make_space(&buf, vp->name_len + 2 + strlen(pw->pw_name))) { 1512 lastuid = euid; 1513 snprintf(buf.b, buf.len, "%.*s=%s", vp->name_len, vp->text, 1514 pw->pw_name); 1515 return buf.b; 1516 } 1517 1518 return vp->text; 1519 } 1520 1521 char * 1522 get_random(struct var *vp) 1523 { 1524 static struct space_reserved buf; 1525 static intmax_t random_val = 0; 1526 1527 #ifdef USE_LRAND48 1528 #define random lrand48 1529 #define srandom srand48 1530 #endif 1531 1532 if (vp->flags & VUNSET) 1533 return NULL; 1534 1535 if (vp->text != buf.b) { 1536 /* 1537 * Either initialisation, or a new seed has been set 1538 */ 1539 if (vp->text[vp->name_len + 1] == '\0') { 1540 int fd; 1541 1542 /* 1543 * initialisation (without pre-seeding), 1544 * or explictly requesting a truly random seed. 1545 */ 1546 fd = open("/dev/urandom", 0); 1547 if (fd == -1) { 1548 out2str("RANDOM initialisation failed\n"); 1549 random_val = (getpid()<<3) ^ time((time_t *)0); 1550 } else { 1551 int n; 1552 1553 do { 1554 n = read(fd,&random_val,sizeof random_val); 1555 } while (n != sizeof random_val); 1556 close(fd); 1557 } 1558 } else 1559 /* good enough for today */ 1560 random_val = strtoimax(vp->text+vp->name_len+1,NULL,0); 1561 1562 srandom((long)random_val); 1563 } 1564 1565 #if 0 1566 random_val = (random_val + 1) & 0x7FFF; /* 15 bit "random" numbers */ 1567 #else 1568 random_val = (random() >> 5) & 0x7FFF; 1569 #endif 1570 1571 if (!make_space(&buf, vp->name_len + 2 + digits_in(random_val))) 1572 return vp->text; 1573 1574 snprintf(buf.b, buf.len, "%.*s=%jd", vp->name_len, vp->text, 1575 random_val); 1576 1577 if (buf.b != vp->text && (vp->flags & (VTEXTFIXED|VSTACK)) == 0) 1578 free(vp->text); 1579 vp->flags |= VTEXTFIXED; 1580 vp->text = buf.b; 1581 1582 return vp->text; 1583 #undef random 1584 #undef srandom 1585 } 1586 1587 #endif /* SMALL */ 1588