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 } 337