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