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