|
|
1.1 root 1: /* @(#)name.c 1.5 */
2: /*
3: * UNIX shell
4: *
5: * Bell Telephone Laboratories
6: *
7: */
8:
9: #include "defs.h"
10: #include "sym.h"
11:
12: extern BOOL chkid();
13: extern char *simple();
14:
15: struct namnod ps2nod =
16: {
17: (struct namnod *)NIL,
18: &acctnod,
19: ps2name
20: };
21: struct namnod cdpnod =
22: {
23: (struct namnod *)NIL,
24: (struct namnod *)NIL,
25: cdpname
26: };
27: struct namnod ifsnod =
28: {
29: (struct namnod *)NIL,
30: (struct namnod *)NIL,
31: ifsname
32: };
33: struct namnod ps1nod =
34: {
35: &pathnod,
36: &ps2nod,
37: ps1name
38: };
39: struct namnod histnod =
40: {
41: &cdpnod,
42: (struct namnod *)NIL,
43: histname
44: };
45: struct namnod homenod =
46: {
47: &histnod,
48: &ifsnod,
49: homename
50: };
51: struct namnod pathnod =
52: {
53: (struct namnod *)NIL,
54: (struct namnod *)NIL,
55: pathname
56: };
57: struct namnod mailnod =
58: {
59: &homenod,
60: &ps1nod,
61: mailname
62: };
63: struct namnod acctnod =
64: {
65: (struct namnod *)NIL,
66: (struct namnod *)NIL,
67: acctname
68: };
69: struct namnod *namep = &mailnod;
70:
71: /* ======== variable and string handling ======== */
72:
73: syslook(w, syswds, n)
74: register char *w;
75: register struct sysnod syswds[];
76: int n;
77: {
78: int low;
79: int high;
80: int mid;
81: register int cond;
82:
83: if (w == 0 || *w == 0)
84: return(0);
85:
86: low = 0;
87: high = n - 1;
88:
89: while (low <= high)
90: {
91: mid = (low + high) / 2;
92:
93: if ((cond = cf(w, syswds[mid].sysnam)) < 0)
94: high = mid - 1;
95: else if (cond > 0)
96: low = mid + 1;
97: else
98: return(syswds[mid].sysval);
99: }
100: return(0);
101: }
102:
103: setlist(arg, xp)
104: register struct argnod *arg;
105: int xp;
106: {
107: if (flags & exportflg)
108: xp |= N_EXPORT;
109:
110: while (arg)
111: {
112: register char *s = mactrim(arg->argval);
113: setname(s, xp);
114: arg = arg->argnxt;
115: if (flags & execpr)
116: {
117: prs(s);
118: if (arg)
119: blank();
120: else
121: newline();
122: }
123: }
124: }
125:
126:
127: setname(argi, xp) /* does parameter assignments */
128: char *argi;
129: int xp;
130: {
131: register char *argscan = argi;
132: register struct namnod *n;
133:
134: while(!ctrlchar(*argscan))
135: {
136: if (*argscan == '=')
137: {
138: *argscan = 0; /* make name a cohesive string */
139:
140: n = lookup(argi);
141: *argscan++ = '=';
142: attrib(n, xp);
143: if (xp & N_ENVNAM)
144: n->namenv.val = n->namval.val = argscan;
145: else
146: assign(n, argscan);
147: return;
148: }
149: if ((xp & N_ENVNAM) && *argscan == '(')
150: {
151: /*
152: * flags==0 when we are called, so flags&ttyflg==0, so
153: * if there's an error we will exit
154: */
155: execexp(argi, 0);
156: *argscan = 0;
157: n = lookup(argi);
158: attrib(n, xp);
159: return;
160: }
161: argscan++;
162: }
163: failed(argi, notid);
164: }
165:
166: replace(a, v)
167: register char **a;
168: char *v;
169: {
170: free(*a);
171: *a = make(v);
172: }
173:
174: dfault(n, v)
175: struct namnod *n;
176: char *v;
177: {
178: if (n->namval.val == 0)
179: assign(n, v);
180: }
181:
182: assign(n, v)
183: struct namnod *n;
184: char *v;
185: {
186: if (!(n->namflg & N_ENVNAM))
187: free_val(&n->namval);
188: else
189: n->namflg &= ~N_ENVNAM;
190:
191: n->namval.val = make(v);
192: n->namval.flg = N_VAR;
193:
194: if (flags & prompt)
195: if (n == &mailnod)
196: setmail(n->namval.val);
197: }
198:
199: readvar(names)
200: char **names;
201: {
202: struct fileblk fb;
203: register struct fileblk *f = &fb;
204: register char c;
205: register int rc = 0;
206: struct namnod *n = lookup(*names++); /* done now to avoid storage mess */
207: char *rel = (char *)relstak();
208:
209: push(f);
210: initf(dup(0));
211:
212: if (lseek(0, 0L, 1) == -1)
213: f->fsiz = 1;
214:
215: /*
216: * strip leading IFS characters
217: */
218: while ((any((c = nextc(0)), ifsnod.namval.val)) && !(eolchar(c)))
219: ;
220: for (;;)
221: {
222: if ((*names && any(c, ifsnod.namval.val)) || eolchar(c))
223: {
224: zerostak();
225: assign(n, absstak(rel));
226: setstak(rel);
227: if (*names)
228: n = lookup(*names++);
229: else
230: n = 0;
231: if (eolchar(c))
232: {
233: break;
234: }
235: else /* strip imbedded IFS characters */
236: {
237: while ((any((c = nextc(0)), ifsnod.namval.val)) &&
238: !(eolchar(c)))
239: ;
240: }
241: }
242: else
243: {
244: pushstak(c);
245: c = nextc(0);
246:
247: if (eolchar(c))
248: {
249: char *top = staktop;
250:
251: while (any(*(--top), ifsnod.namval.val))
252: ;
253: staktop = top + 1;
254: }
255:
256:
257: }
258: }
259: while (n)
260: {
261: assign(n, nullstr);
262: if (*names)
263: n = lookup(*names++);
264: else
265: n = 0;
266: }
267:
268: if (eof)
269: rc = 1;
270: lseek(0, (long)(f->fnxt - f->fend), 1);
271: pop();
272: return(rc);
273: }
274:
275: assnum(p, i)
276: char **p;
277: int i;
278: {
279: itos(i);
280: replace(p, numbuf);
281: }
282:
283: char *
284: make(v)
285: char *v;
286: {
287: register char *p;
288:
289: if (v)
290: {
291: movstr(v, p = alloc(length(v)));
292: return(p);
293: }
294: else
295: return(0);
296: }
297:
298:
299: struct namnod *
300: lookup(nam)
301: register char *nam;
302: {
303: register struct namnod *nscan = namep;
304: register struct namnod **prev;
305: int LR;
306:
307: if (!chkid(nam))
308: failed(nam, notid);
309: while (nscan)
310: {
311: if ((LR = cf(nam, nscan->namid)) == 0)
312: return(nscan);
313:
314: else if (LR < 0)
315: prev = &(nscan->namlft);
316: else
317: prev = &(nscan->namrgt);
318: nscan = *prev;
319: }
320: /*
321: * add name node
322: */
323: nscan = (struct namnod *)alloc(sizeof *nscan);
324: nscan->namlft = nscan->namrgt = (struct namnod *)NIL;
325: nscan->namid = make(nam);
326: nscan->namval.val = 0;
327: nscan->namval.flg = N_VAR;
328: nscan->namenv.val = 0;
329: nscan->namenv.flg = N_VAR;
330: nscan->namflg = N_DEFAULT;
331:
332: return(*prev = nscan);
333: }
334:
335: BOOL
336: chkid(nam)
337: register char *nam;
338: {
339: while(!ctrlchar(*nam) && (*nam"E)==0 && *nam!='(' && *nam!='=')
340: nam++;
341: return *nam==0;
342: }
343:
344: static int (*namfn)();
345: namscan(fn)
346: int (*fn)();
347: {
348: namfn = fn;
349: namwalk(namep);
350: }
351:
352: static int
353: namwalk(np)
354: register struct namnod *np;
355: {
356: if (np)
357: {
358: namwalk(np->namlft);
359: (*namfn)(np);
360: namwalk(np->namrgt);
361: }
362: }
363:
364: printnam(n)
365: struct namnod *n;
366: {
367: register char *s;
368:
369: sigchk();
370:
371: if (n->namval.flg & N_FUNCTN) {
372: prs_buff(strf(n));
373: prc_buff(NL);
374: }
375: else if (s = n->namval.val)
376: {
377: prs_buff(n->namid);
378: prc_buff('=');
379: prs_buff(quotedstring(s));
380: prc_buff(NL);
381: }
382: }
383:
384: static char *
385: staknam(n)
386: register struct namnod *n;
387: {
388: register char *p;
389:
390: if (n->namval.flg & N_FUNCTN)
391: p = movstr(strf(n), staktop); /* XXX unnecessary; already at staktop */
392: else
393: {
394: p = movstr(n->namid, staktop);
395: p = movstr("=", p);
396: p = movstr(n->namval.val, p);
397: }
398: return(getstak(p + 1 - (char *)(stakbot)));
399: }
400:
401: static int namec;
402:
403: exname(n)
404: register struct namnod *n;
405: {
406: register int flg = n->namflg;
407:
408: if (!(flg & N_ENVNAM))
409: {
410: n->namflg |= N_ENVNAM;
411:
412: if (flg & N_EXPORT)
413: {
414: free_val(&n->namenv);
415: n->namenv = n->namval;
416: }
417: else
418: {
419: free_val(&n->namval);
420: n->namval = n->namenv;
421: }
422: }
423:
424:
425: n->namflg &= N_ENVNAM;
426:
427: if (n->namval.val)
428: namec++;
429: }
430:
431: printexp(n)
432: register struct namnod *n;
433: {
434: if (n->namflg & N_EXPORT)
435: {
436: prs_buff(export);
437: prc_buff(SP);
438: prs_buff(n->namid);
439: prc_buff(NL);
440: }
441: }
442:
443: setup_env()
444: {
445: register char **e = environ;
446:
447: while (*e)
448: setname(*e++, N_ENVNAM);
449: }
450:
451: killenvfn(n)
452: struct namnod *n;
453: {
454: if ((n->namflg & N_ENVNAM) && (n->namval.flg & N_FUNCTN))
455: {
456: freefunc(n->namval.val);
457: n->namval.val = N_VAR;
458: n->namval.flg = 0;
459: }
460: }
461:
462: prot_env()
463: {
464: register struct namnod *n;
465:
466: namscan(killenvfn);
467: if (ifsnod.namval.val)
468: free(ifsnod.namval.val);
469: ifsnod.namval.val = 0;
470: dfault(&ifsnod, sptbnl);
471: }
472:
473: static char **argnam;
474:
475: pushnam(n)
476: struct namnod *n;
477: {
478: if (n->namval.val || (n->namval.flg & N_FUNCTN))
479: *argnam++ = staknam(n);
480: }
481:
482: char **
483: setenv()
484: {
485: register char **er;
486:
487: namec = 0;
488: namscan(exname);
489:
490: argnam = er = (char **)getstak(namec * BYTESPERWORD + BYTESPERWORD);
491: namscan(pushnam);
492: *argnam++ = 0;
493: return(er);
494: }
495:
496: struct namnod *
497: findnam(nam)
498: register char *nam;
499: {
500: register struct namnod *nscan = namep;
501: int LR;
502:
503: if (!chkid(nam))
504: return(0);
505: while (nscan)
506: {
507: if ((LR = cf(nam, nscan->namid)) == 0)
508: return(nscan);
509: else if (LR < 0)
510: nscan = nscan->namlft;
511: else
512: nscan = nscan->namrgt;
513: }
514: return(0);
515: }
516:
517:
518: special(s)
519: char *s;
520: {
521: return !cf(s, "builtin") || !cf(s, ifsname) || !cf(s, pathname) || !cf(s, ps1name) || !cf(s, ps2name);
522: }
523:
524: unset_name(name)
525: register char *name;
526: {
527: register struct namnod *n;
528:
529: if (n = findnam(name))
530: {
531: if (special(name))
532: failed(name, badunset);
533:
534: if (!(n->namflg & N_ENVNAM))
535: {
536: if (n->namval.flg & N_FUNCTN)
537: freefunc(n->namval.val);
538: else
539: free(n->namval.val);
540: }
541:
542: if (n->namenv.flg & N_FUNCTN)
543: freefunc(n->namenv.val);
544: else
545: free(n->namenv.val);
546:
547: n->namval.val = N_VAR;
548: n->namval.flg = 0;
549: n->namenv = n->namval;
550: n->namflg = N_DEFAULT;
551:
552: if (flags & prompt)
553: {
554: if (n == &mailnod)
555: setmail(0);
556: }
557: }
558: }
559:
560: free_val(nx)
561: struct namx *nx;
562: {
563: if (nx->flg & N_FUNCTN)
564: freefunc(nx->val);
565: else
566: free(nx->val);
567: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.