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
syslook(w,syswds)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
setlist(arg,xp)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
setname(argi,xp)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
replace(a,v)105 replace(a, v)
106 REG STRING *a;
107 STRING v;
108 {
109 free(*a); *a=make(v);
110 }
111
dfault(n,v)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
assign(n,v)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
readvar(names)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
assnum(p,i)171 assnum(p, i)
172 STRING *p;
173 INT i;
174 {
175 itos(i); replace(p,numbuf);
176 }
177
make(v)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
lookup(nam)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
chkid(nam)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
namwalk(np)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
printnam(n)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
staknam(n)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
exname(n)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
printflg(n)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
setupenv()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
countnam(n)312 VOID countnam(n)
313 NAMPTR n;
314 {
315 namec++;
316 }
317
318 LOCAL STRING *argnam;
319
pushnam(n)320 VOID pushnam(n)
321 NAMPTR n;
322 {
323 IF n->namval
324 THEN *argnam++ = staknam(n);
325 FI
326 }
327
setenv()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