1 #ifndef lint 2 static char sccsid[] = "@(#)name.c 4.3 03/19/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 n->namenv = n->namval = argscan; 83 ELSE assign(n, argscan); 84 FI 85 return; 86 FI 87 FI 88 failed(argi,notid); 89 } 90 91 replace(a, v) 92 REG STRING *a; 93 STRING v; 94 { 95 free(*a); *a=make(v); 96 } 97 98 dfault(n,v) 99 NAMPTR n; 100 STRING v; 101 { 102 IF n->namval==0 103 THEN assign(n,v) 104 FI 105 } 106 107 assign(n,v) 108 NAMPTR n; 109 STRING v; 110 { 111 IF n->namflg&N_RDONLY 112 THEN failed(n->namid,wtfailed); 113 ELSE replace(&n->namval,v); 114 FI 115 } 116 117 INT readvar(names) 118 STRING *names; 119 { 120 FILEBLK fb; 121 REG FILE f = &fb; 122 REG CHAR c; 123 REG INT rc=0; 124 NAMPTR n=lookup(*names++); /* done now to avoid storage mess */ 125 STKPTR rel=relstak(); 126 127 push(f); initf(dup(0)); 128 IF lseek(0,0L,1)==-1 129 THEN f->fsiz=1; 130 FI 131 132 LOOP c=nextc(0); 133 IF (*names ANDF any(c, ifsnod.namval)) ORF eolchar(c) 134 THEN zerostak(); 135 assign(n,absstak(rel)); setstak(rel); 136 IF *names 137 THEN n=lookup(*names++); 138 ELSE n=0; 139 FI 140 IF eolchar(c) 141 THEN break; 142 FI 143 ELSE pushstak(c); 144 FI 145 POOL 146 WHILE n 147 DO assign(n, nullstr); 148 IF *names THEN n=lookup(*names++); ELSE n=0; FI 149 OD 150 151 IF eof THEN rc=1 FI 152 lseek(0, (long)(f->fnxt-f->fend), 1); 153 pop(); 154 return(rc); 155 } 156 157 assnum(p, i) 158 STRING *p; 159 INT i; 160 { 161 itos(i); replace(p,numbuf); 162 } 163 164 STRING make(v) 165 STRING v; 166 { 167 REG STRING p; 168 169 IF v 170 THEN movstr(v,p=alloc(length(v))); 171 return(p); 172 ELSE return(0); 173 FI 174 } 175 176 177 NAMPTR lookup(nam) 178 REG STRING nam; 179 { 180 REG NAMPTR nscan=namep; 181 REG NAMPTR *prev; 182 INT LR; 183 184 IF !chkid(nam) 185 THEN failed(nam,notid); 186 FI 187 WHILE nscan 188 DO IF (LR=cf(nam,nscan->namid))==0 189 THEN return(nscan); 190 ELIF LR<0 191 THEN prev = &(nscan->namlft); 192 ELSE prev = &(nscan->namrgt); 193 FI 194 nscan = *prev; 195 OD 196 197 /* add name node */ 198 nscan=alloc(sizeof *nscan); 199 nscan->namlft=nscan->namrgt=NIL; 200 nscan->namid=make(nam); 201 nscan->namval=0; nscan->namflg=N_DEFAULT; nscan->namenv=0; 202 return(*prev = nscan); 203 } 204 205 LOCAL BOOL chkid(nam) 206 STRING nam; 207 { 208 REG CHAR * cp=nam; 209 210 IF !letter(*cp) 211 THEN return(FALSE); 212 ELSE WHILE *++cp 213 DO IF !alphanum(*cp) 214 THEN return(FALSE); 215 FI 216 OD 217 FI 218 return(TRUE); 219 } 220 221 LOCAL VOID (*namfn)(); 222 namscan(fn) 223 VOID (*fn)(); 224 { 225 namfn=fn; 226 namwalk(namep); 227 } 228 229 LOCAL VOID namwalk(np) 230 REG NAMPTR np; 231 { 232 IF np 233 THEN namwalk(np->namlft); 234 (*namfn)(np); 235 namwalk(np->namrgt); 236 FI 237 } 238 239 VOID printnam(n) 240 NAMPTR n; 241 { 242 REG STRING s; 243 244 sigchk(); 245 IF s=n->namval 246 THEN prs(n->namid); 247 prc('='); prs(s); 248 newline(); 249 FI 250 } 251 252 LOCAL STRING staknam(n) 253 REG NAMPTR n; 254 { 255 REG STRING p; 256 257 p=movstr(n->namid,staktop); 258 p=movstr("=",p); 259 p=movstr(n->namval,p); 260 return(getstak(p+1-ADR(stakbot))); 261 } 262 263 VOID exname(n) 264 REG NAMPTR n; 265 { 266 IF n->namflg&N_EXPORT 267 THEN free(n->namenv); 268 n->namenv = make(n->namval); 269 ELSE free(n->namval); 270 n->namval = make(n->namenv); 271 FI 272 } 273 274 VOID printflg(n) 275 REG NAMPTR n; 276 { 277 IF n->namflg&N_EXPORT 278 THEN prs(export); blank(); 279 FI 280 IF n->namflg&N_RDONLY 281 THEN prs(readonly); blank(); 282 FI 283 IF n->namflg&(N_EXPORT|N_RDONLY) 284 THEN prs(n->namid); newline(); 285 FI 286 } 287 288 VOID setupenv() 289 { 290 REG STRING *e=environ; 291 292 WHILE *e 293 DO setname(*e++, N_ENVNAM) OD 294 } 295 296 LOCAL INT namec; 297 298 VOID countnam(n) 299 NAMPTR n; 300 { 301 namec++; 302 } 303 304 LOCAL STRING *argnam; 305 306 VOID pushnam(n) 307 NAMPTR n; 308 { 309 IF n->namval 310 THEN *argnam++ = staknam(n); 311 FI 312 } 313 314 STRING *setenv() 315 { 316 REG STRING *er; 317 318 namec=0; 319 namscan(countnam); 320 argnam = er = getstak(namec*BYTESPERWORD+BYTESPERWORD); 321 namscan(pushnam); 322 *argnam++ = 0; 323 return(er); 324 } 325