1: # 2: /* 3: * UNIX shell 4: * 5: * S. R. Bourne 6: * Bell Telephone Laboratories 7: * 8: */ 9: 10: #include "defs.h" 11: 12: PROC BOOL chkid(); 13: 14: 15: NAMNOD ps2nod = { NIL, NIL, ps2name}, 16: fngnod = { NIL, NIL, fngname}, 17: pathnod = { NIL, NIL, pathname}, 18: ifsnod = { NIL, NIL, ifsname}, 19: ps1nod = { &pathnod, &ps2nod, ps1name}, 20: homenod = { &fngnod, &ifsnod, homename}, 21: mailnod = { &homenod, &ps1nod, mailname}; 22: 23: NAMPTR namep = &mailnod; 24: 25: 26: /* ======== variable and string handling ======== */ 27: 28: syslook(w,syswds) 29: STRING w; 30: SYSTAB syswds; 31: { 32: REG CHAR first; 33: REG STRING s; 34: REG SYSPTR syscan; 35: 36: syscan=syswds; first = *w; 37: 38: WHILE s=syscan->sysnam 39: DO IF first == *s 40: ANDF eq(w,s) 41: THEN return(syscan->sysval); 42: FI 43: syscan++; 44: OD 45: return(0); 46: } 47: 48: setlist(arg,xp) 49: REG ARGPTR arg; 50: INT xp; 51: { 52: WHILE arg 53: DO REG STRING s=mactrim(arg->argval); 54: setname(s, xp); 55: arg=arg->argnxt; 56: IF flags&execpr 57: THEN prs(s); 58: IF arg THEN blank(); ELSE newline(); FI 59: FI 60: OD 61: } 62: 63: VOID setname(argi, xp) 64: STRING argi; 65: INT xp; 66: { 67: REG STRING argscan=argi; 68: REG NAMPTR n; 69: 70: IF letter(*argscan) 71: THEN WHILE alphanum(*argscan) DO argscan++ OD 72: IF *argscan=='=' 73: THEN *argscan = 0; 74: n=lookup(argi); 75: *argscan++ = '='; 76: attrib(n, xp); 77: IF xp&N_ENVNAM 78: THEN n->namenv = n->namval = argscan; 79: ELSE assign(n, argscan); 80: FI 81: return; 82: FI 83: FI 84: failed(argi,notid); 85: } 86: 87: replace(a, v) 88: REG STRING *a; 89: STRING v; 90: { 91: free(*a); *a=make(v); 92: } 93: 94: dfault(n,v) 95: NAMPTR n; 96: STRING v; 97: { 98: IF n->namval==0 99: THEN assign(n,v) 100: FI 101: } 102: 103: assign(n,v) 104: NAMPTR n; 105: STRING v; 106: { 107: IF n->namflg&N_RDONLY 108: THEN failed(n->namid,wtfailed); 109: ELSE replace(&n->namval,v); 110: FI 111: } 112: 113: INT readvar(names) 114: STRING *names; 115: { 116: FILEBLK fb; 117: REG FILE f = &fb; 118: REG CHAR c; 119: REG INT rc=0; 120: NAMPTR n=lookup(*names++); /* done now to avoid storage mess */ 121: STKPTR rel=relstak(); 122: 123: push(f); initf(dup(0)); 124: IF lseek(0,0L,1)==-1 125: THEN f->fsiz=1; 126: FI 127: 128: LOOP c=nextc(0); 129: IF (*names ANDF any(c, ifsnod.namval)) ORF eolchar(c) 130: THEN zerostak(); 131: assign(n,absstak(rel)); setstak(rel); 132: IF *names 133: THEN n=lookup(*names++); 134: ELSE n=0; 135: FI 136: IF eolchar(c) 137: THEN break; 138: FI 139: ELSE pushstak(c); 140: FI 141: POOL 142: WHILE n 143: DO assign(n, nullstr); 144: IF *names THEN n=lookup(*names++); ELSE n=0; FI 145: OD 146: 147: IF eof THEN rc=1 FI 148: lseek(0, (long)(f->fnxt-f->fend), 1); 149: pop(); 150: return(rc); 151: } 152: 153: assnum(p, i) 154: STRING *p; 155: INT i; 156: { 157: itos(i); replace(p,numbuf); 158: } 159: 160: STRING make(v) 161: STRING v; 162: { 163: REG STRING p; 164: 165: IF v 166: THEN movstr(v,p=alloc(length(v))); 167: return(p); 168: ELSE return(0); 169: FI 170: } 171: 172: 173: NAMPTR lookup(nam) 174: REG STRING nam; 175: { 176: REG NAMPTR nscan=namep; 177: REG NAMPTR *prev; 178: INT LR; 179: 180: IF !chkid(nam) 181: THEN failed(nam,notid); 182: FI 183: WHILE nscan 184: DO IF (LR=cf(nam,nscan->namid))==0 185: THEN return(nscan); 186: ELIF LR<0 187: THEN prev = &(nscan->namlft); 188: ELSE prev = &(nscan->namrgt); 189: FI 190: nscan = *prev; 191: OD 192: 193: /* add name node */ 194: nscan=alloc(sizeof *nscan); 195: nscan->namlft=nscan->namrgt=NIL; 196: nscan->namid=make(nam); 197: nscan->namval=0; nscan->namflg=N_DEFAULT; nscan->namenv=0; 198: return(*prev = nscan); 199: } 200: 201: LOCAL BOOL chkid(nam) 202: STRING nam; 203: { 204: REG CHAR * cp=nam; 205: 206: IF !letter(*cp) 207: THEN return(FALSE); 208: ELSE WHILE *++cp 209: DO IF !alphanum(*cp) 210: THEN return(FALSE); 211: FI 212: OD 213: FI 214: return(TRUE); 215: } 216: 217: LOCAL VOID (*namfn)(); 218: namscan(fn) 219: VOID (*fn)(); 220: { 221: namfn=fn; 222: namwalk(namep); 223: } 224: 225: LOCAL VOID namwalk(np) 226: REG NAMPTR np; 227: { 228: IF np 229: THEN namwalk(np->namlft); 230: (*namfn)(np); 231: namwalk(np->namrgt); 232: FI 233: } 234: 235: VOID printnam(n) 236: NAMPTR n; 237: { 238: REG STRING s; 239: 240: sigchk(); 241: IF s=n->namval 242: THEN prs(n->namid); 243: prc('='); prs(s); 244: newline(); 245: FI 246: } 247: 248: LOCAL STRING staknam(n) 249: REG NAMPTR n; 250: { 251: REG STRING p; 252: 253: p=movstr(n->namid,staktop); 254: p=movstr("=",p); 255: p=movstr(n->namval,p); 256: return(getstak(p+1-ADR(stakbot))); 257: } 258: 259: VOID exname(n) 260: REG NAMPTR n; 261: { 262: IF n->namflg&N_EXPORT 263: THEN free(n->namenv); 264: n->namenv = make(n->namval); 265: ELSE free(n->namval); 266: n->namval = make(n->namenv); 267: FI 268: } 269: 270: VOID printflg(n) 271: REG NAMPTR n; 272: { 273: IF n->namflg&N_EXPORT 274: THEN prs(export); blank(); 275: FI 276: IF n->namflg&N_RDONLY 277: THEN prs(readonly); blank(); 278: FI 279: IF n->namflg&(N_EXPORT|N_RDONLY) 280: THEN prs(n->namid); newline(); 281: FI 282: } 283: 284: VOID getenv() 285: { 286: REG STRING *e=environ; 287: 288: WHILE *e 289: DO setname(*e++, N_ENVNAM) OD 290: } 291: 292: LOCAL INT namec; 293: 294: VOID countnam(n) 295: NAMPTR n; 296: { 297: namec++; 298: } 299: 300: LOCAL STRING *argnam; 301: 302: VOID pushnam(n) 303: NAMPTR n; 304: { 305: IF n->namval 306: THEN *argnam++ = staknam(n); 307: FI 308: } 309: 310: STRING *setenv() 311: { 312: REG STRING *er; 313: 314: namec=0; 315: namscan(countnam); 316: argnam = er = getstak(namec*BYTESPERWORD+BYTESPERWORD); 317: namscan(pushnam); 318: *argnam++ = 0; 319: return(er); 320: }