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