|
|
1.1 ! root 1: /* @(#)name.c 1.5 */ ! 2: /* ! 3: * UNIX shell ! 4: * ! 5: * Bell Telephone Laboratories ! 6: * ! 7: */ ! 8: ! 9: #include "defs.h" ! 10: #include "sym.h" ! 11: ! 12: extern BOOL chkid(); ! 13: extern char *simple(); ! 14: ! 15: struct namnod ps2nod = ! 16: { ! 17: (struct namnod *)NIL, ! 18: &acctnod, ! 19: ps2name ! 20: }; ! 21: struct namnod cdpnod = ! 22: { ! 23: (struct namnod *)NIL, ! 24: (struct namnod *)NIL, ! 25: cdpname ! 26: }; ! 27: struct namnod ifsnod = ! 28: { ! 29: (struct namnod *)NIL, ! 30: (struct namnod *)NIL, ! 31: ifsname ! 32: }; ! 33: struct namnod ps1nod = ! 34: { ! 35: &pathnod, ! 36: &ps2nod, ! 37: ps1name ! 38: }; ! 39: struct namnod histnod = ! 40: { ! 41: &cdpnod, ! 42: (struct namnod *)NIL, ! 43: histname ! 44: }; ! 45: struct namnod homenod = ! 46: { ! 47: &histnod, ! 48: &ifsnod, ! 49: homename ! 50: }; ! 51: struct namnod pathnod = ! 52: { ! 53: (struct namnod *)NIL, ! 54: (struct namnod *)NIL, ! 55: pathname ! 56: }; ! 57: struct namnod mailnod = ! 58: { ! 59: &homenod, ! 60: &ps1nod, ! 61: mailname ! 62: }; ! 63: struct namnod acctnod = ! 64: { ! 65: (struct namnod *)NIL, ! 66: (struct namnod *)NIL, ! 67: acctname ! 68: }; ! 69: struct namnod *namep = &mailnod; ! 70: ! 71: /* ======== variable and string handling ======== */ ! 72: ! 73: syslook(w, syswds, n) ! 74: register char *w; ! 75: register struct sysnod syswds[]; ! 76: int n; ! 77: { ! 78: int low; ! 79: int high; ! 80: int mid; ! 81: register int cond; ! 82: ! 83: if (w == 0 || *w == 0) ! 84: return(0); ! 85: ! 86: low = 0; ! 87: high = n - 1; ! 88: ! 89: while (low <= high) ! 90: { ! 91: mid = (low + high) / 2; ! 92: ! 93: if ((cond = cf(w, syswds[mid].sysnam)) < 0) ! 94: high = mid - 1; ! 95: else if (cond > 0) ! 96: low = mid + 1; ! 97: else ! 98: return(syswds[mid].sysval); ! 99: } ! 100: return(0); ! 101: } ! 102: ! 103: setlist(arg, xp) ! 104: register struct argnod *arg; ! 105: int xp; ! 106: { ! 107: if (flags & exportflg) ! 108: xp |= N_EXPORT; ! 109: ! 110: while (arg) ! 111: { ! 112: register char *s = mactrim(arg->argval); ! 113: setname(s, xp); ! 114: arg = arg->argnxt; ! 115: if (flags & execpr) ! 116: { ! 117: prs(s); ! 118: if (arg) ! 119: blank(); ! 120: else ! 121: newline(); ! 122: } ! 123: } ! 124: } ! 125: ! 126: ! 127: setname(argi, xp) /* does parameter assignments */ ! 128: char *argi; ! 129: int xp; ! 130: { ! 131: register char *argscan = argi; ! 132: register struct namnod *n; ! 133: ! 134: while(!ctrlchar(*argscan)) ! 135: { ! 136: if (*argscan == '=') ! 137: { ! 138: *argscan = 0; /* make name a cohesive string */ ! 139: ! 140: n = lookup(argi); ! 141: *argscan++ = '='; ! 142: attrib(n, xp); ! 143: if (xp & N_ENVNAM) ! 144: n->namenv.val = n->namval.val = argscan; ! 145: else ! 146: assign(n, argscan); ! 147: return; ! 148: } ! 149: if ((xp & N_ENVNAM) && *argscan == '(') ! 150: { ! 151: /* ! 152: * flags==0 when we are called, so flags&ttyflg==0, so ! 153: * if there's an error we will exit ! 154: */ ! 155: execexp(argi, 0); ! 156: *argscan = 0; ! 157: n = lookup(argi); ! 158: attrib(n, xp); ! 159: return; ! 160: } ! 161: argscan++; ! 162: } ! 163: failed(argi, notid); ! 164: } ! 165: ! 166: replace(a, v) ! 167: register char **a; ! 168: char *v; ! 169: { ! 170: free(*a); ! 171: *a = make(v); ! 172: } ! 173: ! 174: dfault(n, v) ! 175: struct namnod *n; ! 176: char *v; ! 177: { ! 178: if (n->namval.val == 0) ! 179: assign(n, v); ! 180: } ! 181: ! 182: assign(n, v) ! 183: struct namnod *n; ! 184: char *v; ! 185: { ! 186: if (!(n->namflg & N_ENVNAM)) ! 187: free_val(&n->namval); ! 188: else ! 189: n->namflg &= ~N_ENVNAM; ! 190: ! 191: n->namval.val = make(v); ! 192: n->namval.flg = N_VAR; ! 193: ! 194: if (flags & prompt) ! 195: if (n == &mailnod) ! 196: setmail(n->namval.val); ! 197: } ! 198: ! 199: readvar(names) ! 200: char **names; ! 201: { ! 202: struct fileblk fb; ! 203: register struct fileblk *f = &fb; ! 204: register char c; ! 205: register int rc = 0; ! 206: struct namnod *n = lookup(*names++); /* done now to avoid storage mess */ ! 207: char *rel = (char *)relstak(); ! 208: ! 209: push(f); ! 210: initf(dup(0)); ! 211: ! 212: if (lseek(0, 0L, 1) == -1) ! 213: f->fsiz = 1; ! 214: ! 215: /* ! 216: * strip leading IFS characters ! 217: */ ! 218: while ((any((c = nextc(0)), ifsnod.namval.val)) && !(eolchar(c))) ! 219: ; ! 220: for (;;) ! 221: { ! 222: if ((*names && any(c, ifsnod.namval.val)) || eolchar(c)) ! 223: { ! 224: zerostak(); ! 225: assign(n, absstak(rel)); ! 226: setstak(rel); ! 227: if (*names) ! 228: n = lookup(*names++); ! 229: else ! 230: n = 0; ! 231: if (eolchar(c)) ! 232: { ! 233: break; ! 234: } ! 235: else /* strip imbedded IFS characters */ ! 236: { ! 237: while ((any((c = nextc(0)), ifsnod.namval.val)) && ! 238: !(eolchar(c))) ! 239: ; ! 240: } ! 241: } ! 242: else ! 243: { ! 244: pushstak(c); ! 245: c = nextc(0); ! 246: ! 247: if (eolchar(c)) ! 248: { ! 249: char *top = staktop; ! 250: ! 251: while (any(*(--top), ifsnod.namval.val)) ! 252: ; ! 253: staktop = top + 1; ! 254: } ! 255: ! 256: ! 257: } ! 258: } ! 259: while (n) ! 260: { ! 261: assign(n, nullstr); ! 262: if (*names) ! 263: n = lookup(*names++); ! 264: else ! 265: n = 0; ! 266: } ! 267: ! 268: if (eof) ! 269: rc = 1; ! 270: lseek(0, (long)(f->fnxt - f->fend), 1); ! 271: pop(); ! 272: return(rc); ! 273: } ! 274: ! 275: assnum(p, i) ! 276: char **p; ! 277: int i; ! 278: { ! 279: itos(i); ! 280: replace(p, numbuf); ! 281: } ! 282: ! 283: char * ! 284: make(v) ! 285: char *v; ! 286: { ! 287: register char *p; ! 288: ! 289: if (v) ! 290: { ! 291: movstr(v, p = alloc(length(v))); ! 292: return(p); ! 293: } ! 294: else ! 295: return(0); ! 296: } ! 297: ! 298: ! 299: struct namnod * ! 300: lookup(nam) ! 301: register char *nam; ! 302: { ! 303: register struct namnod *nscan = namep; ! 304: register struct namnod **prev; ! 305: int LR; ! 306: ! 307: if (!chkid(nam)) ! 308: failed(nam, notid); ! 309: while (nscan) ! 310: { ! 311: if ((LR = cf(nam, nscan->namid)) == 0) ! 312: return(nscan); ! 313: ! 314: else if (LR < 0) ! 315: prev = &(nscan->namlft); ! 316: else ! 317: prev = &(nscan->namrgt); ! 318: nscan = *prev; ! 319: } ! 320: /* ! 321: * add name node ! 322: */ ! 323: nscan = (struct namnod *)alloc(sizeof *nscan); ! 324: nscan->namlft = nscan->namrgt = (struct namnod *)NIL; ! 325: nscan->namid = make(nam); ! 326: nscan->namval.val = 0; ! 327: nscan->namval.flg = N_VAR; ! 328: nscan->namenv.val = 0; ! 329: nscan->namenv.flg = N_VAR; ! 330: nscan->namflg = N_DEFAULT; ! 331: ! 332: return(*prev = nscan); ! 333: } ! 334: ! 335: BOOL ! 336: chkid(nam) ! 337: register char *nam; ! 338: { ! 339: while(!ctrlchar(*nam) && (*nam"E)==0 && *nam!='(' && *nam!='=') ! 340: nam++; ! 341: return *nam==0; ! 342: } ! 343: ! 344: static int (*namfn)(); ! 345: namscan(fn) ! 346: int (*fn)(); ! 347: { ! 348: namfn = fn; ! 349: namwalk(namep); ! 350: } ! 351: ! 352: static int ! 353: namwalk(np) ! 354: register struct namnod *np; ! 355: { ! 356: if (np) ! 357: { ! 358: namwalk(np->namlft); ! 359: (*namfn)(np); ! 360: namwalk(np->namrgt); ! 361: } ! 362: } ! 363: ! 364: printnam(n) ! 365: struct namnod *n; ! 366: { ! 367: register char *s; ! 368: ! 369: sigchk(); ! 370: ! 371: if (n->namval.flg & N_FUNCTN) { ! 372: prs_buff(strf(n)); ! 373: prc_buff(NL); ! 374: } ! 375: else if (s = n->namval.val) ! 376: { ! 377: prs_buff(n->namid); ! 378: prc_buff('='); ! 379: prs_buff(quotedstring(s)); ! 380: prc_buff(NL); ! 381: } ! 382: } ! 383: ! 384: static char * ! 385: staknam(n) ! 386: register struct namnod *n; ! 387: { ! 388: register char *p; ! 389: ! 390: if (n->namval.flg & N_FUNCTN) ! 391: p = movstr(strf(n), staktop); /* XXX unnecessary; already at staktop */ ! 392: else ! 393: { ! 394: p = movstr(n->namid, staktop); ! 395: p = movstr("=", p); ! 396: p = movstr(n->namval.val, p); ! 397: } ! 398: return(getstak(p + 1 - (char *)(stakbot))); ! 399: } ! 400: ! 401: static int namec; ! 402: ! 403: exname(n) ! 404: register struct namnod *n; ! 405: { ! 406: register int flg = n->namflg; ! 407: ! 408: if (!(flg & N_ENVNAM)) ! 409: { ! 410: n->namflg |= N_ENVNAM; ! 411: ! 412: if (flg & N_EXPORT) ! 413: { ! 414: free_val(&n->namenv); ! 415: n->namenv = n->namval; ! 416: } ! 417: else ! 418: { ! 419: free_val(&n->namval); ! 420: n->namval = n->namenv; ! 421: } ! 422: } ! 423: ! 424: ! 425: n->namflg &= N_ENVNAM; ! 426: ! 427: if (n->namval.val) ! 428: namec++; ! 429: } ! 430: ! 431: printexp(n) ! 432: register struct namnod *n; ! 433: { ! 434: if (n->namflg & N_EXPORT) ! 435: { ! 436: prs_buff(export); ! 437: prc_buff(SP); ! 438: prs_buff(n->namid); ! 439: prc_buff(NL); ! 440: } ! 441: } ! 442: ! 443: setup_env() ! 444: { ! 445: register char **e = environ; ! 446: ! 447: while (*e) ! 448: setname(*e++, N_ENVNAM); ! 449: } ! 450: ! 451: killenvfn(n) ! 452: struct namnod *n; ! 453: { ! 454: if ((n->namflg & N_ENVNAM) && (n->namval.flg & N_FUNCTN)) ! 455: { ! 456: freefunc(n->namval.val); ! 457: n->namval.val = N_VAR; ! 458: n->namval.flg = 0; ! 459: } ! 460: } ! 461: ! 462: prot_env() ! 463: { ! 464: register struct namnod *n; ! 465: ! 466: namscan(killenvfn); ! 467: if (ifsnod.namval.val) ! 468: free(ifsnod.namval.val); ! 469: ifsnod.namval.val = 0; ! 470: dfault(&ifsnod, sptbnl); ! 471: } ! 472: ! 473: static char **argnam; ! 474: ! 475: pushnam(n) ! 476: struct namnod *n; ! 477: { ! 478: if (n->namval.val || (n->namval.flg & N_FUNCTN)) ! 479: *argnam++ = staknam(n); ! 480: } ! 481: ! 482: char ** ! 483: setenv() ! 484: { ! 485: register char **er; ! 486: ! 487: namec = 0; ! 488: namscan(exname); ! 489: ! 490: argnam = er = (char **)getstak(namec * BYTESPERWORD + BYTESPERWORD); ! 491: namscan(pushnam); ! 492: *argnam++ = 0; ! 493: return(er); ! 494: } ! 495: ! 496: struct namnod * ! 497: findnam(nam) ! 498: register char *nam; ! 499: { ! 500: register struct namnod *nscan = namep; ! 501: int LR; ! 502: ! 503: if (!chkid(nam)) ! 504: return(0); ! 505: while (nscan) ! 506: { ! 507: if ((LR = cf(nam, nscan->namid)) == 0) ! 508: return(nscan); ! 509: else if (LR < 0) ! 510: nscan = nscan->namlft; ! 511: else ! 512: nscan = nscan->namrgt; ! 513: } ! 514: return(0); ! 515: } ! 516: ! 517: ! 518: special(s) ! 519: char *s; ! 520: { ! 521: return !cf(s, "builtin") || !cf(s, ifsname) || !cf(s, pathname) || !cf(s, ps1name) || !cf(s, ps2name); ! 522: } ! 523: ! 524: unset_name(name) ! 525: register char *name; ! 526: { ! 527: register struct namnod *n; ! 528: ! 529: if (n = findnam(name)) ! 530: { ! 531: if (special(name)) ! 532: failed(name, badunset); ! 533: ! 534: if (!(n->namflg & N_ENVNAM)) ! 535: { ! 536: if (n->namval.flg & N_FUNCTN) ! 537: freefunc(n->namval.val); ! 538: else ! 539: free(n->namval.val); ! 540: } ! 541: ! 542: if (n->namenv.flg & N_FUNCTN) ! 543: freefunc(n->namenv.val); ! 544: else ! 545: free(n->namenv.val); ! 546: ! 547: n->namval.val = N_VAR; ! 548: n->namval.flg = 0; ! 549: n->namenv = n->namval; ! 550: n->namflg = N_DEFAULT; ! 551: ! 552: if (flags & prompt) ! 553: { ! 554: if (n == &mailnod) ! 555: setmail(0); ! 556: } ! 557: } ! 558: } ! 559: ! 560: free_val(nx) ! 561: struct namx *nx; ! 562: { ! 563: if (nx->flg & N_FUNCTN) ! 564: freefunc(nx->val); ! 565: else ! 566: free(nx->val); ! 567: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.