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