|
|
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: if (n->namval.flg & N_FUNCTN)
398: pushstr(strf(n));
399: else
400: {
401: pushstr(n->namid);
402: pushstak('=');
403: pushstr(n->namval.val);
404: }
405: return(getstak(staktop + 1 - (char *)(stakbot)));
406: }
407:
408: static int namec;
409:
410: exname(n)
411: register struct namnod *n;
412: {
413: register int flg = n->namflg;
414:
415: if (!(flg & N_ENVNAM))
416: {
417: n->namflg |= N_ENVNAM;
418:
419: if (flg & N_EXPORT)
420: {
421: free_val(&n->namenv);
422: n->namenv = n->namval;
423: }
424: else
425: {
426: free_val(&n->namval);
427: n->namval = n->namenv;
428: }
429: }
430:
431:
432: n->namflg &= N_ENVNAM;
433:
434: if (n->namval.val)
435: namec++;
436: }
437:
438: printexp(n)
439: register struct namnod *n;
440: {
441: if (n->namflg & N_EXPORT)
442: {
443: prs_buff(export);
444: prc_buff(SP);
445: prs_buff(n->namid);
446: prc_buff(NL);
447: }
448: }
449:
450: setup_env()
451: {
452: register char **e = environ;
453: int onoexec = flags&noexec;
454:
455: flags |= noexec;
456: while (*e)
457: setname(*e++, N_ENVNAM);
458: if(!onoexec)
459: flags &= ~noexec;
460: }
461:
462: killenvfn(n)
463: struct namnod *n;
464: {
465: if ((n->namflg & N_ENVNAM) && (n->namval.flg & N_FUNCTN))
466: {
467: freefunc(n->namval.val);
468: n->namval.val = N_VAR;
469: n->namval.flg = 0;
470: }
471: }
472:
473: prot_env()
474: {
475: namscan(killenvfn);
476: if (ifsnod.namval.val)
477: shfree(ifsnod.namval.val);
478: ifsnod.namval.val = 0;
479: dfault(&ifsnod, sptbnl);
480: }
481:
482: static char **argnam;
483:
484: pushnam(n)
485: struct namnod *n;
486: {
487: if (n->namval.val || (n->namval.flg & N_FUNCTN))
488: *argnam++ = staknam(n);
489: }
490:
491: char **
492: setenv()
493: {
494: register char **er;
495:
496: namec = 0;
497: namscan(exname);
498:
499: argnam = er = (char **)getstak(namec * BYTESPERWORD + BYTESPERWORD);
500: namscan(pushnam);
501: *argnam++ = 0;
502: return(er);
503: }
504:
505: struct namnod *
506: findnam(nam)
507: register char *nam;
508: {
509: register struct namnod *nscan = namep;
510: int LR;
511:
512: if (!chkid(nam))
513: return(0);
514: while (nscan)
515: {
516: if ((LR = cf(nam, nscan->namid)) == 0)
517: return(nscan);
518: else if (LR < 0)
519: nscan = nscan->namlft;
520: else
521: nscan = nscan->namrgt;
522: }
523: return(0);
524: }
525:
526:
527: special(s)
528: char *s;
529: {
530: return !cf(s, "builtin") || !cf(s, ifsname) || !cf(s, pathname) || !cf(s, ps1name) || !cf(s, ps2name);
531: }
532:
533: unset_name(name)
534: register char *name;
535: {
536: register struct namnod *n;
537:
538: if (n = findnam(name))
539: {
540: if (special(name))
541: failed(name, badunset, 0);
542:
543: if (!(n->namflg & N_ENVNAM))
544: {
545: if (n->namval.flg & N_FUNCTN)
546: freefunc(n->namval.val);
547: else
548: shfree(n->namval.val);
549: }
550:
551: if (n->namenv.flg & N_FUNCTN)
552: freefunc(n->namenv.val);
553: else
554: shfree(n->namenv.val);
555:
556: n->namval.val = N_VAR;
557: n->namval.flg = 0;
558: n->namenv = n->namval;
559: n->namflg = N_DEFAULT;
560:
561: if (flags & prompt)
562: {
563: if (n == &mailnod)
564: setmail((char *)0);
565: }
566: }
567: }
568:
569: free_val(nx)
570: struct namx *nx;
571: {
572: if (nx->flg & N_FUNCTN)
573: freefunc(nx->val);
574: else
575: shfree(nx->val);
576: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.