1*35157Smarc /*
2*35157Smarc
3*35157Smarc * Copyright (c) 1984, 1985, 1986 AT&T
4*35157Smarc * All Rights Reserved
5*35157Smarc
6*35157Smarc * THIS IS UNPUBLISHED PROPRIETARY SOURCE
7*35157Smarc * CODE OF AT&T.
8*35157Smarc * The copyright notice above does not
9*35157Smarc * evidence any actual or intended
10*35157Smarc * publication of such source code.
11*35157Smarc
12*35157Smarc */
13*35157Smarc /*
14*35157Smarc * AT&T Bell Laboratories
15*35157Smarc *
16*35157Smarc */
17*35157Smarc
18*35157Smarc #include "defs.h"
19*35157Smarc #include "io.h"
20*35157Smarc #include "flags.h"
21*35157Smarc #include "name.h"
22*35157Smarc #include "shtype.h"
23*35157Smarc #include "sym.h"
24*35157Smarc #include "stak.h"
25*35157Smarc #include "brkincr.h"
26*35157Smarc #include "builtins.h"
27*35157Smarc #include "history.h"
28*35157Smarc #include "timeout.h"
29*35157Smarc
30*35157Smarc /* This module defines the following routines */
31*35157Smarc NAMPTR checkfor();
32*35157Smarc void do_whence();
33*35157Smarc #ifdef ECHO_N
34*35157Smarc char *echo_mode();
35*35157Smarc #endif /* ECHO_N */
36*35157Smarc #ifdef apollo
37*35157Smarc void ev_$set_var();
38*35157Smarc #endif /* apollo */
39*35157Smarc int genenv();
40*35157Smarc char *heap();
41*35157Smarc void meminit();
42*35157Smarc void mem_scope();
43*35157Smarc void mem_unscope();
44*35157Smarc char *movstr();
45*35157Smarc void name_unscope();
46*35157Smarc char *qvalup();
47*35157Smarc void prinscan();
48*35157Smarc int printnam();
49*35157Smarc void printflg();
50*35157Smarc int readvar();
51*35157Smarc void rmlocal();
52*35157Smarc char **setenv();
53*35157Smarc void setlist();
54*35157Smarc NAMPTR setname();
55*35157Smarc int syslook();
56*35157Smarc
57*35157Smarc /* This module references the following external routines */
58*35157Smarc extern void assign();
59*35157Smarc extern char *bracket_match();
60*35157Smarc extern unsigned chkid();
61*35157Smarc #ifdef ECHO_N
62*35157Smarc extern MSG echo_bin;
63*35157Smarc extern MSG echo_opt;
64*35157Smarc #endif /* ECHO_N */
65*35157Smarc extern char **environ;
66*35157Smarc extern void exitsh();
67*35157Smarc extern void failed();
68*35157Smarc extern void free();
69*35157Smarc extern NAMPTR findnod();
70*35157Smarc extern char *fullname();
71*35157Smarc extern char *getstak();
72*35157Smarc extern struct Amemory *gettree();
73*35157Smarc extern void gsort();
74*35157Smarc extern long hist_list();
75*35157Smarc extern void hist_flush();
76*35157Smarc extern void initf();
77*35157Smarc extern void gscan_all();
78*35157Smarc extern void gscan_some();
79*35157Smarc extern NAMPTR lookup();
80*35157Smarc extern void linknod();
81*35157Smarc extern char *mactrim();
82*35157Smarc extern char *malloc();
83*35157Smarc extern char *movstr();
84*35157Smarc extern unsigned rand();
85*35157Smarc extern void p_num();
86*35157Smarc extern void p_str();
87*35157Smarc extern void p_sub();
88*35157Smarc extern void p_setout();
89*35157Smarc extern void scan_all();
90*35157Smarc extern char *simple();
91*35157Smarc extern int srand();
92*35157Smarc extern char *strchr();
93*35157Smarc extern char *strcpy();
94*35157Smarc extern void rmnval();
95*35157Smarc extern void unassign();
96*35157Smarc extern long time();
97*35157Smarc extern char *utos();
98*35157Smarc extern char *valup();
99*35157Smarc
100*35157Smarc static void countnam();
101*35157Smarc #ifdef ECHO_N
102*35157Smarc static char *echo_arg;
103*35157Smarc #endif /* ECHO_N */
104*35157Smarc static long get_rand();
105*35157Smarc static long get_second();
106*35157Smarc static struct Amemory *inittree();
107*35157Smarc static void no_export();
108*35157Smarc static void pr_name();
109*35157Smarc static void pushnam();
110*35157Smarc static void pushnid();
111*35157Smarc static void rehash();
112*35157Smarc static void rm_node();
113*35157Smarc static int set_second();
114*35157Smarc static int set_rand();
115*35157Smarc static char *staknam();
116*35157Smarc
117*35157Smarc
118*35157Smarc static rsflag; /* used to see if "SHELL" has been set in the environment */
119*35157Smarc static int namec;
120*35157Smarc static char **argnam;
121*35157Smarc static struct Amemory *namebase;
122*35157Smarc
123*35157Smarc struct Bfunction seconds = { get_second, set_second};
124*35157Smarc struct Bfunction randnum = { get_rand, set_rand};
125*35157Smarc
126*35157Smarc
127*35157Smarc
128*35157Smarc /* ======== variable and string handling ======== */
129*35157Smarc
130*35157Smarc /*
131*35157Smarc * Table lookup routine
132*35157Smarc * The table <syswds> is searched for string <w> and corresponding value is returned
133*35157Smarc */
syslook(w,syswds)134*35157Smarc syslook(w,syswds)
135*35157Smarc register char *w;
136*35157Smarc SYSTAB syswds;
137*35157Smarc {
138*35157Smarc register int first;
139*35157Smarc register SYSPTR syscan;
140*35157Smarc register int c;
141*35157Smarc if(w==0 || (first= *w)==0)
142*35157Smarc return(0);
143*35157Smarc syscan=syswds;
144*35157Smarc while((c= *syscan->sysnam) && c <= first)
145*35157Smarc {
146*35157Smarc if(first == c && eq(w,syscan->sysnam))
147*35157Smarc return(syscan->sysval);
148*35157Smarc syscan++;
149*35157Smarc }
150*35157Smarc return(0);
151*35157Smarc }
152*35157Smarc
153*35157Smarc /*
154*35157Smarc * perform parameter assignment on an argument list
155*35157Smarc */
156*35157Smarc
setlist(arg,xp)157*35157Smarc void setlist(arg,xp)
158*35157Smarc register ARGPTR arg;
159*35157Smarc register int xp;
160*35157Smarc {
161*35157Smarc if(is_option(ALLEXP))
162*35157Smarc xp |= N_EXPORT;
163*35157Smarc while(arg)
164*35157Smarc {
165*35157Smarc register char *s;
166*35157Smarc if(arg->argflag&A_MAC)
167*35157Smarc s=mactrim(arg->argval,0);
168*35157Smarc else
169*35157Smarc s = arg->argval;
170*35157Smarc setname(s, xp);
171*35157Smarc arg=arg->argnxt;
172*35157Smarc if(is_option(EXECPR))
173*35157Smarc {
174*35157Smarc p_setout(stderr);
175*35157Smarc p_str(s,arg?SP:NL);
176*35157Smarc }
177*35157Smarc }
178*35157Smarc }
179*35157Smarc
180*35157Smarc /*
181*35157Smarc * Put <arg> into associative memory.
182*35157Smarc * If <xp> & V_FLAG then the alias list is used instead
183*35157Smarc * If <xp> & S_FLAG then use the current scope only
184*35157Smarc */
185*35157Smarc
186*35157Smarc
setname(argi,xp)187*35157Smarc NAMPTR setname(argi, xp)
188*35157Smarc char *argi;
189*35157Smarc int xp;
190*35157Smarc {
191*35157Smarc register char *argscan=argi;
192*35157Smarc register NAMPTR n;
193*35157Smarc register int sep = *argscan;
194*35157Smarc char *sim;
195*35157Smarc if(isalpha(sep) || ((xp&V_FLAG) && !expchar(sep)))
196*35157Smarc {
197*35157Smarc do
198*35157Smarc {
199*35157Smarc sep = *++argscan;
200*35157Smarc }
201*35157Smarc while(isalnum(sep));
202*35157Smarc /* check for subscript*/
203*35157Smarc if(sep=='[')
204*35157Smarc {
205*35157Smarc argscan = bracket_match(argscan)+1;
206*35157Smarc }
207*35157Smarc if((sep = *argscan) && sep!='=')
208*35157Smarc failed(argi,notid);
209*35157Smarc *argscan = 0;
210*35157Smarc if(xp&V_FLAG)
211*35157Smarc {
212*35157Smarc n = findnod(argi,alias,1);
213*35157Smarc if(attest(n,T_FLAG|NO_ALIAS))
214*35157Smarc pattrib(n,~(NO_ALIAS|T_FLAG|N_EXPORT));
215*35157Smarc }
216*35157Smarc else if(xp&S_FLAG)
217*35157Smarc /* scoped name must be in first tree */
218*35157Smarc n = findnod(argi,namep,1);
219*35157Smarc else
220*35157Smarc n = lookup(argi);
221*35157Smarc *argscan++ = sep;
222*35157Smarc if(sep == '=')
223*35157Smarc {
224*35157Smarc if(n==PATHNOD || n==ENVNOD || n==SHELLNOD)
225*35157Smarc {
226*35157Smarc if(is_option(RSHFLG))
227*35157Smarc failed(argi,restricted);
228*35157Smarc if(n==SHELLNOD)
229*35157Smarc {
230*35157Smarc sim = simple(argscan);
231*35157Smarc if(strchr(sim,'r') != NULL)
232*35157Smarc rsflag = 0; /* restricted shell */
233*35157Smarc }
234*35157Smarc }
235*35157Smarc assign (n, argscan);
236*35157Smarc attrib(n, xp&~(S_FLAG|V_FLAG));
237*35157Smarc #ifdef apollo
238*35157Smarc if(attest(n,N_EXPORT) && attest(n,N_IMPORT)==0
239*35157Smarc && (xp&(S_FLAG|V_FLAG))==0)
240*35157Smarc {
241*35157Smarc short namlen,vallen;
242*35157Smarc namlen =strlen(n->namid);
243*35157Smarc vallen = strlen(argscan);
244*35157Smarc ev_$set_var(n->namid,&namlen,argscan,&vallen);
245*35157Smarc }
246*35157Smarc #endif /* apollo */
247*35157Smarc if(n==PATHNOD)
248*35157Smarc {
249*35157Smarc gscan_some(rehash,alias,T_FLAG,T_FLAG);
250*35157Smarc #ifdef ECHO_N
251*35157Smarc echo_arg = NIL;
252*35157Smarc #endif /* ECHO_N */
253*35157Smarc }
254*35157Smarc if(n==VISINOD || ((n==EDITNOD)&&isnull(VISINOD)))
255*35157Smarc {
256*35157Smarc /* turn on vi or emacs option if editor name is either*/
257*35157Smarc argscan = simple(argscan);
258*35157Smarc if(gmatch(argscan,"*vi"))
259*35157Smarc {
260*35157Smarc off_option(EDITVI|EMACS|GMACS);
261*35157Smarc on_option(EDITVI);
262*35157Smarc }
263*35157Smarc if(gmatch(argscan,"*macs"))
264*35157Smarc {
265*35157Smarc off_option(EDITVI|EMACS|GMACS);
266*35157Smarc if(*argscan=='g')
267*35157Smarc on_option(GMACS);
268*35157Smarc else
269*35157Smarc on_option(EMACS);
270*35157Smarc }
271*35157Smarc }
272*35157Smarc }
273*35157Smarc return(n);
274*35157Smarc }
275*35157Smarc failed (argi, notid);
276*35157Smarc /* NOTREACHED */
277*35157Smarc }
278*35157Smarc
279*35157Smarc /*
280*35157Smarc * Mark each node is invalid
281*35157Smarc */
282*35157Smarc
rehash(np)283*35157Smarc static void rehash(np)
284*35157Smarc register NAMPTR np;
285*35157Smarc {
286*35157Smarc attrib(np,NO_ALIAS);
287*35157Smarc }
288*35157Smarc
289*35157Smarc /*
290*35157Smarc * alias each name to full path name
291*35157Smarc * realias returns the pathname or NULL if not found
292*35157Smarc */
293*35157Smarc
realias(np)294*35157Smarc char *realias(np)
295*35157Smarc register NAMPTR np;
296*35157Smarc {
297*35157Smarc register char *sp;
298*35157Smarc register char *vp = np->value.namval.cp;
299*35157Smarc int flag = namflag(np)&(N_EXPORT|NO_ALIAS|T_FLAG);
300*35157Smarc /* turn of T_FLAG to avoid recursion */
301*35157Smarc pattrib(np,~(NO_ALIAS|T_FLAG));
302*35157Smarc sp = fullname(np->namid);
303*35157Smarc if(sp==NIL)
304*35157Smarc {
305*35157Smarc unassign(np);
306*35157Smarc return(NIL);
307*35157Smarc }
308*35157Smarc else if(*sp!= '/')
309*35157Smarc {
310*35157Smarc sattrib(np,flag);
311*35157Smarc return(NIL);
312*35157Smarc }
313*35157Smarc if(vp==0 || strcmp(sp,vp)!=0)
314*35157Smarc assign(np,sp);
315*35157Smarc /* turn T_FLAG back on */
316*35157Smarc attrib(np,T_FLAG|N_EXPORT);
317*35157Smarc return(sp);
318*35157Smarc }
319*35157Smarc
320*35157Smarc
readvar(names,fd,raw)321*35157Smarc int readvar(names,fd,raw)
322*35157Smarc register char **names;
323*35157Smarc FILE *fd;
324*35157Smarc {
325*35157Smarc FILEBLK fb;
326*35157Smarc SHFILE f;
327*35157Smarc register int c;
328*35157Smarc int issep;
329*35157Smarc register NAMPTR n;
330*35157Smarc int checksep = 1; /* set when looking for separators */
331*35157Smarc STKPTR rel;
332*35157Smarc char *seps;
333*35157Smarc char is_eol;
334*35157Smarc FILE *savef;
335*35157Smarc states |= RWAIT;
336*35157Smarc /* save in history file if S_FLAG is set */
337*35157Smarc if((raw&S_FLAG) && fc_fix)
338*35157Smarc states |= FIXFLG;
339*35157Smarc raw &= R_FLAG;
340*35157Smarc f = &fb;
341*35157Smarc if(*names)
342*35157Smarc {
343*35157Smarc if(seps=strchr(*names,'?'))
344*35157Smarc *seps = 0;
345*35157Smarc n = lookup(*names++);
346*35157Smarc if(seps)
347*35157Smarc *seps = '?';
348*35157Smarc }
349*35157Smarc else
350*35157Smarc n = REPLYNOD;
351*35157Smarc rel=(STKPTR)relstak();
352*35157Smarc seps = qvalup(IFSNOD);
353*35157Smarc if(seps==NULL)
354*35157Smarc seps = sptbnl;
355*35157Smarc savef = input;
356*35157Smarc if(fd==NULL)
357*35157Smarc failed(bread,noquery);
358*35157Smarc if(fd != input)
359*35157Smarc {
360*35157Smarc /* buffer the input stream if possible */
361*35157Smarc if(fnobuff(fd) && (fd!=stdin || !ispipe(stdin)))
362*35157Smarc setbuf(fd,malloc((unsigned)BUFSIZ));
363*35157Smarc push(f);
364*35157Smarc initf(fd);
365*35157Smarc }
366*35157Smarc while(1)
367*35157Smarc {
368*35157Smarc c = (raw?readc():nextc());
369*35157Smarc issep = (strchr(seps,c)!=0);
370*35157Smarc is_eol = eolchar(c);
371*35157Smarc if(checksep && issep && !is_eol)
372*35157Smarc {
373*35157Smarc /* visable adjacent separators signify null fields*/
374*35157Smarc if(strchr(sptbnl,c)!=0)
375*35157Smarc continue;
376*35157Smarc }
377*35157Smarc checksep = 0;
378*35157Smarc if((issep && *names) || is_eol) /* from non-separator to separator */
379*35157Smarc {
380*35157Smarc if(*names==NULL && staktop>stakbot)
381*35157Smarc {
382*35157Smarc /* remove trailing separators */
383*35157Smarc while(strchr(seps,*--staktop));
384*35157Smarc staktop++;
385*35157Smarc }
386*35157Smarc zerostak();
387*35157Smarc assign(n,absstak(rel)); setstak(rel);
388*35157Smarc if(is_option(ALLEXP))
389*35157Smarc attrib(n,N_EXPORT);
390*35157Smarc n = (*names?lookup(*names++):0);
391*35157Smarc if(is_eol)
392*35157Smarc break;
393*35157Smarc checksep = 1;
394*35157Smarc }
395*35157Smarc else /* not a separator */
396*35157Smarc pushstak(c);
397*35157Smarc }
398*35157Smarc while(n)
399*35157Smarc {
400*35157Smarc assign(n, nullstr);
401*35157Smarc if(is_option(ALLEXP))
402*35157Smarc attrib(n,N_EXPORT);
403*35157Smarc n = (*names?lookup(*names++):0);
404*35157Smarc }
405*35157Smarc if(savef != fd)
406*35157Smarc pop(1);
407*35157Smarc if(states&FIXFLG)
408*35157Smarc hist_flush();
409*35157Smarc states &= ~(RWAIT|PROMPT);
410*35157Smarc states |= is_option(INTFLG);
411*35157Smarc return;
412*35157Smarc }
413*35157Smarc
414*35157Smarc /*
415*35157Smarc * put string v onto the heap and return the heap pointer
416*35157Smarc */
417*35157Smarc
heap(v)418*35157Smarc char *heap(v)
419*35157Smarc register char *v;
420*35157Smarc {
421*35157Smarc register char *p;
422*35157Smarc if(v)
423*35157Smarc {
424*35157Smarc movstr(v,p=malloc((unsigned)strlen(v)+1));
425*35157Smarc return(p);
426*35157Smarc }
427*35157Smarc else
428*35157Smarc return(0);
429*35157Smarc }
430*35157Smarc
431*35157Smarc
432*35157Smarc /*
433*35157Smarc * print out the name and value of a name-value pair <n>
434*35157Smarc */
435*35157Smarc
printnam(n,flag)436*35157Smarc int printnam(n,flag)
437*35157Smarc register NAMPTR n;
438*35157Smarc register int flag;
439*35157Smarc {
440*35157Smarc register FILE *fd;
441*35157Smarc register char *s;
442*35157Smarc union Namval *up= &n->value.namval;
443*35157Smarc if(trapnote&SIGSET)
444*35157Smarc exitsh(SIGFAIL);
445*35157Smarc fd = output;
446*35157Smarc if(attest(n,NO_ALIAS)==NO_ALIAS)
447*35157Smarc {
448*35157Smarc return(0);
449*35157Smarc }
450*35157Smarc if(is_afunction(n))
451*35157Smarc {
452*35157Smarc fputs(bltfn,fd);
453*35157Smarc fputs(n->namid,fd);
454*35157Smarc if(flag==0 && n->value.namval.rp->hoffset >=0 )
455*35157Smarc {
456*35157Smarc fputs(fn_hdr,fd);
457*35157Smarc hist_list(n->value.namval.rp->hoffset,EOF,"\n");
458*35157Smarc }
459*35157Smarc else
460*35157Smarc putc('\n',fd);
461*35157Smarc return(n->namsz+1);
462*35157Smarc }
463*35157Smarc if(s=valup(n))
464*35157Smarc {
465*35157Smarc char numbuf[30];
466*35157Smarc pr_name(n,0);
467*35157Smarc flag = (flag?NL:'=');
468*35157Smarc if (attest (n, ARRAY))
469*35157Smarc {
470*35157Smarc if(attest(n,INT_GER))
471*35157Smarc {
472*35157Smarc /* copy to a save place */
473*35157Smarc strcpy(numbuf,s);
474*35157Smarc s = numbuf;
475*35157Smarc }
476*35157Smarc p_sub((int)up->aray->adot,flag);
477*35157Smarc }
478*35157Smarc else
479*35157Smarc putc(flag,fd);
480*35157Smarc if(flag != NL)
481*35157Smarc p_str(s,NL);
482*35157Smarc return(1);
483*35157Smarc }
484*35157Smarc return(0);
485*35157Smarc }
486*35157Smarc
487*35157Smarc /*
488*35157Smarc * print the name of a node followed by the character c
489*35157Smarc */
490*35157Smarc
pr_name(n,c)491*35157Smarc static void pr_name(n,c)
492*35157Smarc register NAMPTR n;
493*35157Smarc int c;
494*35157Smarc {
495*35157Smarc register char *cp = strchr(n->namid,'=');
496*35157Smarc if(cp)
497*35157Smarc *cp = 0;
498*35157Smarc p_str(n->namid,c);
499*35157Smarc if(cp)
500*35157Smarc *cp = '=';
501*35157Smarc }
502*35157Smarc
pushnid(np)503*35157Smarc static void pushnid(np)
504*35157Smarc NAMPTR np;
505*35157Smarc {
506*35157Smarc *argnam++ = np->namid;
507*35157Smarc namec++;
508*35157Smarc if(attest(np,ARRAY))
509*35157Smarc arayp(np)->adot = arayp(np)->maxi;
510*35157Smarc }
511*35157Smarc
512*35157Smarc /*
513*35157Smarc * print the nodes in tree <root> which have attributes <flag> set
514*35157Smarc */
515*35157Smarc
prinscan(file,flag,root,option)516*35157Smarc void prinscan(file,flag,root,option)
517*35157Smarc FILE *file;
518*35157Smarc struct Amemory *root;
519*35157Smarc {
520*35157Smarc register char **argv;
521*35157Smarc register NAMPTR np;
522*35157Smarc p_setout(file);
523*35157Smarc argv = argnam = (char**)locstak();
524*35157Smarc namec = 0;
525*35157Smarc if(flag)
526*35157Smarc gscan_some(pushnid,root,flag,flag);
527*35157Smarc else
528*35157Smarc gscan_all(pushnid,root);
529*35157Smarc gsort(argv,namec);
530*35157Smarc while(namec--)
531*35157Smarc {
532*35157Smarc {
533*35157Smarc register char *cp;
534*35157Smarc if(cp = strchr(*argv,'='))
535*35157Smarc *cp = 0;
536*35157Smarc np = checkfor(*argv++,root);
537*35157Smarc if(cp)
538*35157Smarc *cp = '=';
539*35157Smarc }
540*35157Smarc if(np)
541*35157Smarc {
542*35157Smarc if(attest(np,ARRAY))
543*35157Smarc {
544*35157Smarc register struct Namaray *ap = arayp (np);
545*35157Smarc register int i, imax;
546*35157Smarc i = ap->adot = 0;
547*35157Smarc imax = ap->maxi;
548*35157Smarc for (; i <= imax; i++)
549*35157Smarc {
550*35157Smarc ap->adot = i;
551*35157Smarc if (ap->val[i])
552*35157Smarc printnam(np,option);
553*35157Smarc }
554*35157Smarc }
555*35157Smarc else
556*35157Smarc printnam(np,option);
557*35157Smarc }
558*35157Smarc }
559*35157Smarc }
560*35157Smarc
staknam(n,value)561*35157Smarc static char *staknam(n,value)
562*35157Smarc char * value;
563*35157Smarc register NAMPTR n;
564*35157Smarc {
565*35157Smarc register char *p,*q;
566*35157Smarc q = getstak(strlen(n->namid)+strlen(value)+2);
567*35157Smarc p=movstr(n->namid,q);
568*35157Smarc *p++ = '=';
569*35157Smarc strcpy(p,value);
570*35157Smarc return(q);
571*35157Smarc }
572*35157Smarc
573*35157Smarc
printflg(n)574*35157Smarc void printflg(n)
575*35157Smarc register NAMPTR n;
576*35157Smarc {
577*35157Smarc register SYSPTR syscan;
578*35157Smarc register int val;
579*35157Smarc if (namflag(n) != N_DEFAULT)
580*35157Smarc {
581*35157Smarc syscan=attributes;
582*35157Smarc while(*syscan->sysnam)
583*35157Smarc {
584*35157Smarc val = syscan->sysval;
585*35157Smarc if(attest(n,val)==val)
586*35157Smarc {
587*35157Smarc p_str(syscan->sysnam,SP);
588*35157Smarc if (attest (n, L_JUST|R_JUST|Z_FILL))
589*35157Smarc p_num(n->namsz,SP);
590*35157Smarc if(val == (BLT_NOD|INT_GER))
591*35157Smarc break;
592*35157Smarc }
593*35157Smarc if(val == INT_GER && attest(n,INT_GER))
594*35157Smarc {
595*35157Smarc if(n->namsz != 10)
596*35157Smarc {
597*35157Smarc p_str(intbase,SP);
598*35157Smarc p_num(n->namsz,SP);
599*35157Smarc }
600*35157Smarc break;
601*35157Smarc }
602*35157Smarc syscan++;
603*35157Smarc }
604*35157Smarc pr_name(n,NL);
605*35157Smarc }
606*35157Smarc }
607*35157Smarc
genenv()608*35157Smarc int genenv()
609*35157Smarc {
610*35157Smarc register char **e=environ;
611*35157Smarc register NAMPTR n;
612*35157Smarc rsflag = 1;
613*35157Smarc if(e)
614*35157Smarc {
615*35157Smarc while(*e)
616*35157Smarc {
617*35157Smarc n = setname(*e, (N_IMPORT|N_EXPORT));
618*35157Smarc n->namid = *e++;
619*35157Smarc }
620*35157Smarc }
621*35157Smarc return(rsflag);
622*35157Smarc }
623*35157Smarc
624*35157Smarc
countnam()625*35157Smarc static void countnam()
626*35157Smarc {
627*35157Smarc namec++;
628*35157Smarc }
629*35157Smarc
630*35157Smarc
pushnam(n)631*35157Smarc static void pushnam(n)
632*35157Smarc register NAMPTR n;
633*35157Smarc {
634*35157Smarc register char *value;
635*35157Smarc if(attest(n,N_IMPORT))
636*35157Smarc *argnam++ = n->namid;
637*35157Smarc else if(value=valup(n))
638*35157Smarc *argnam++ = staknam(n,value);
639*35157Smarc }
640*35157Smarc
641*35157Smarc /*
642*35157Smarc * Generate the environment list for the child.
643*35157Smarc */
644*35157Smarc
645*35157Smarc
setenv()646*35157Smarc char **setenv()
647*35157Smarc {
648*35157Smarc register char **er;
649*35157Smarc namec = 0;
650*35157Smarc /* L_ARGNOD gets generated automatically as full path name of command */
651*35157Smarc pattrib(L_ARGNOD,~N_EXPORT);
652*35157Smarc gscan_some (countnam,namep, N_EXPORT|N_IMPORT, N_EXPORT);
653*35157Smarc er = (char**)getstak((namec+2)*BYTESPERWORD);
654*35157Smarc argnam = ++er;
655*35157Smarc gscan_some (pushnam, namep, N_EXPORT|N_IMPORT, N_EXPORT);
656*35157Smarc *argnam++ = 0;
657*35157Smarc return(er);
658*35157Smarc }
659*35157Smarc
660*35157Smarc /*
661*35157Smarc * Initialize the shell name and alias table
662*35157Smarc */
663*35157Smarc
meminit()664*35157Smarc void meminit()
665*35157Smarc {
666*35157Smarc register NAMPTR np;
667*35157Smarc bltin_nodes = (NAMPTR)malloc((unsigned)(NNODES*sizeof(struct Namnod)));
668*35157Smarc namebase = namep = inittree(node_names,bltin_nodes,0);
669*35157Smarc /* set up random number generator */
670*35157Smarc #ifdef apollo
671*35157Smarc (PPIDNOD)->value.namval.cp = (char*)(&ppid);
672*35157Smarc (L_ARGNOD)->value.namval.cp = (char*)(&lastarg);
673*35157Smarc (TMOUTNOD)->value.namval.cp = (char*)(&timeout);
674*35157Smarc (SECONDS)->value.namval.cp = (char*)(&seconds);
675*35157Smarc (MCHKNOD)->value.namval.cp = (char*)(&mailchk);
676*35157Smarc (RANDNOD)->value.namval.cp = (char*)(&randnum);
677*35157Smarc #endif /* apollo */
678*35157Smarc namflag(RANDNOD) = N_FREE|INT_GER|BLT_NOD;
679*35157Smarc /* set up the seconds clock */
680*35157Smarc namflag(SECONDS) = N_FREE|INT_GER|BLT_NOD;
681*35157Smarc set_second(0L);
682*35157Smarc namflag(MCHKNOD) = N_FREE|INT_GER;
683*35157Smarc namflag(TMOUTNOD) = INT_GER;
684*35157Smarc namflag(PPIDNOD) = (N_FREE|INT_GER|N_RDONLY);
685*35157Smarc namflag(L_ARGNOD) = N_FREE|IN_DIR;
686*35157Smarc np = (NAMPTR)malloc(NALIAS*sizeof(struct Namnod));
687*35157Smarc alias = inittree(alias_names,np,N_EXPORT);
688*35157Smarc prnames = gettree(MEMSIZE/4);
689*35157Smarc }
690*35157Smarc
691*35157Smarc /*
692*35157Smarc * re-initialize name-value pairs after fork
693*35157Smarc */
694*35157Smarc
695*35157Smarc
inittree(name_vals,nodes,atflag)696*35157Smarc static struct Amemory *inittree(name_vals,nodes,atflag)
697*35157Smarc struct name_value *name_vals;
698*35157Smarc NAMPTR nodes;
699*35157Smarc {
700*35157Smarc register struct Amemory *treep;
701*35157Smarc register NAMPTR np;
702*35157Smarc register struct name_value *nv;
703*35157Smarc int flag;
704*35157Smarc treep = gettree (MEMSIZE);
705*35157Smarc for(np=nodes,nv=name_vals;*nv->nv_name;nv++,np++)
706*35157Smarc {
707*35157Smarc np->namid = nv->nv_name;
708*35157Smarc np->value.namval.cp = nv->nv_value;
709*35157Smarc flag = 0;
710*35157Smarc #ifdef apollo
711*35157Smarc if(*nv->nv_value==0)
712*35157Smarc np->value.namval.cp = 0;
713*35157Smarc else
714*35157Smarc #else
715*35157Smarc if(nv->nv_value)
716*35157Smarc #endif /* apollo */
717*35157Smarc {
718*35157Smarc flag = atflag|N_FREE;
719*35157Smarc if(atflag && *nv->nv_value=='/')
720*35157Smarc flag |= T_FLAG;
721*35157Smarc }
722*35157Smarc sattrib(np,flag);
723*35157Smarc np->namsz = 10;
724*35157Smarc linknod (np, treep);
725*35157Smarc }
726*35157Smarc return(treep);
727*35157Smarc }
728*35157Smarc
729*35157Smarc /*
730*35157Smarc * create a new environment scope
731*35157Smarc */
732*35157Smarc
mem_scope(envlist)733*35157Smarc void mem_scope(envlist)
734*35157Smarc ARGPTR envlist;
735*35157Smarc {
736*35157Smarc register struct Amemory *sav_namep = namep;
737*35157Smarc register struct Amemory *newscope;
738*35157Smarc newscope = gettree(MEMSIZE/8);
739*35157Smarc newscope->nexttree = sav_namep;
740*35157Smarc namep = newscope;
741*35157Smarc setlist(envlist,N_EXPORT|S_FLAG);
742*35157Smarc newscope->nexttree = NULL;
743*35157Smarc namep = sav_namep;
744*35157Smarc scan_all(no_export,newscope);
745*35157Smarc newscope->nexttree = sav_namep;
746*35157Smarc namep = newscope;
747*35157Smarc }
748*35157Smarc
749*35157Smarc /*
750*35157Smarc * Temporarily remove name from export list of previous scopes
751*35157Smarc */
752*35157Smarc
no_export(nnod)753*35157Smarc static void no_export(nnod)
754*35157Smarc register struct Namnod *nnod;
755*35157Smarc {
756*35157Smarc register struct Namnod *np = checkfor(nnod->namid,namep);
757*35157Smarc if(np && attest(np,N_EXPORT))
758*35157Smarc {
759*35157Smarc pattrib(np,~N_EXPORT);
760*35157Smarc attrib(np,E_FLAG);
761*35157Smarc }
762*35157Smarc }
763*35157Smarc
764*35157Smarc /*
765*35157Smarc * free up top environment scope
766*35157Smarc */
767*35157Smarc
mem_unscope()768*35157Smarc void mem_unscope()
769*35157Smarc {
770*35157Smarc register struct Amemory *ap = namep;
771*35157Smarc if((namep = ap->nexttree)==NULL)
772*35157Smarc namep = namebase;
773*35157Smarc scan_all(rm_node,ap);
774*35157Smarc free((char*)ap);
775*35157Smarc }
776*35157Smarc
777*35157Smarc /*
778*35157Smarc * free up all environment scopes except the first
779*35157Smarc */
780*35157Smarc
name_unscope()781*35157Smarc void name_unscope()
782*35157Smarc {
783*35157Smarc while(namep->nexttree)
784*35157Smarc mem_unscope();
785*35157Smarc }
786*35157Smarc
787*35157Smarc /*
788*35157Smarc * Remove a node and free up all the space
789*35157Smarc * Restate export attribute for hidden nodes if necessary
790*35157Smarc */
rm_node(nnod)791*35157Smarc static void rm_node(nnod)
792*35157Smarc register struct Namnod *nnod;
793*35157Smarc {
794*35157Smarc register struct Namnod *np = checkfor(nnod->namid,namep);
795*35157Smarc if(np && attest(np,E_FLAG))
796*35157Smarc {
797*35157Smarc pattrib(np,~E_FLAG);
798*35157Smarc attrib(np,N_EXPORT);
799*35157Smarc }
800*35157Smarc pattrib(nnod,~N_EXPORT);
801*35157Smarc rmlocal(nnod);
802*35157Smarc free((char*)nnod);
803*35157Smarc }
804*35157Smarc
805*35157Smarc /*
806*35157Smarc * Remove freeable local space associated with the namval field
807*35157Smarc * of nnod. This includes any strings representing the value(s) of the
808*35157Smarc * node, as well as its dope vector, if it is an array.
809*35157Smarc */
810*35157Smarc
rmlocal(nnod)811*35157Smarc void rmlocal (nnod)
812*35157Smarc register struct Namnod *nnod;
813*35157Smarc {
814*35157Smarc register int i;
815*35157Smarc register struct Nodval *nv;
816*35157Smarc register struct Namaray *ap;
817*35157Smarc register union Namval *up = &nnod->value.namval;
818*35157Smarc
819*35157Smarc /* return if the node is global or unfreeable */
820*35157Smarc
821*35157Smarc if (attest (nnod, N_EXPORT|N_FREE))
822*35157Smarc return;
823*35157Smarc /*
824*35157Smarc * If the node is a freeable array, then free both the stringspace
825*35157Smarc * associated with it and its dope vector.
826*35157Smarc */
827*35157Smarc
828*35157Smarc else if (attest (nnod, ARRAY))
829*35157Smarc {
830*35157Smarc ap = up->aray;
831*35157Smarc i = ap->maxi;
832*35157Smarc while(i >= 0)
833*35157Smarc {
834*35157Smarc nv = ap->val[i--];
835*35157Smarc if (nv)
836*35157Smarc {
837*35157Smarc if (freeble (nv))
838*35157Smarc rmnval (unmark (nv));
839*35157Smarc else
840*35157Smarc {
841*35157Smarc up = &nv->namval;
842*35157Smarc if ((up->cp) && ((nv->namflg & (N_FREE|N_ALLOC)) == 0))
843*35157Smarc free ((nv->namflg & IN_DIR)?up->up->cp:up->cp);
844*35157Smarc }
845*35157Smarc }
846*35157Smarc }
847*35157Smarc free ((char*)(arayp(nnod)));
848*35157Smarc nnod->value.namval.cp = NULL;
849*35157Smarc }
850*35157Smarc /*
851*35157Smarc * otherwise node is a freeable scalar, so free the string
852*35157Smarc * representing its value.
853*35157Smarc */
854*35157Smarc else
855*35157Smarc {
856*35157Smarc unassign (nnod);
857*35157Smarc }
858*35157Smarc sattrib (nnod, N_DEFAULT);
859*35157Smarc }
860*35157Smarc
861*35157Smarc /*
862*35157Smarc * Get the value of a built-in node
863*35157Smarc * A lookup may not be necessary
864*35157Smarc */
865*35157Smarc
qvalup(n)866*35157Smarc char *qvalup(n)
867*35157Smarc register NAMPTR n;
868*35157Smarc {
869*35157Smarc if(namep->nexttree)
870*35157Smarc n = lookup((node_names+(n-bltin_nodes))->nv_name);
871*35157Smarc return(valup(n));
872*35157Smarc }
873*35157Smarc
874*35157Smarc /*
875*35157Smarc * lookup name in trees root and return Namnod pointer with this name.
876*35157Smarc * If none exists, it will not be created.
877*35157Smarc */
878*35157Smarc
checkfor(name,root)879*35157Smarc NAMPTR checkfor(name,root)
880*35157Smarc char *name;
881*35157Smarc struct Amemory *root;
882*35157Smarc {
883*35157Smarc register struct Namnod *np = NULL;
884*35157Smarc register struct Amemory *app = root;
885*35157Smarc struct Namnod *findnod();
886*35157Smarc while(app && np==NULL)
887*35157Smarc {
888*35157Smarc np = findnod(name,app,0);
889*35157Smarc app = app->nexttree;
890*35157Smarc }
891*35157Smarc return((np==NULL||isnull(np))?NULL:np);
892*35157Smarc }
893*35157Smarc
894*35157Smarc /*
895*35157Smarc * for the whence command
896*35157Smarc */
897*35157Smarc
do_whence(com,flag)898*35157Smarc void do_whence(com,flag)
899*35157Smarc char **com;
900*35157Smarc register int flag;
901*35157Smarc {
902*35157Smarc register char *a1;
903*35157Smarc register struct Namnod *np;
904*35157Smarc register char *cp;
905*35157Smarc struct Namnod *fp;
906*35157Smarc while(a1 = *++com)
907*35157Smarc {
908*35157Smarc if(flag)
909*35157Smarc fputs(a1,output);
910*35157Smarc np = NULL;
911*35157Smarc /* reserved words first */
912*35157Smarc if(syslook(a1,reserved))
913*35157Smarc {
914*35157Smarc if(flag)
915*35157Smarc a1 = is_reserved;
916*35157Smarc }
917*35157Smarc /* non-tracked aliases */
918*35157Smarc else if((np=findnod(a1,alias,CHK_FOR)) && !isnull(np)
919*35157Smarc && attest(np,T_FLAG)==0 && (a1=valup(np)))
920*35157Smarc {
921*35157Smarc if(flag)
922*35157Smarc {
923*35157Smarc if(attest(np,N_EXPORT))
924*35157Smarc cp = is_xalias;
925*35157Smarc else
926*35157Smarc cp = is_alias;
927*35157Smarc fputs(cp,output);
928*35157Smarc }
929*35157Smarc }
930*35157Smarc /* built-in commands next */
931*35157Smarc else if(syslook(a1,commands))
932*35157Smarc {
933*35157Smarc if(flag)
934*35157Smarc a1 = is_builtin;
935*35157Smarc }
936*35157Smarc /* functions next */
937*35157Smarc else if((fp=findnod(a1,prnames,CHK_FOR))&& !isnull(fp))
938*35157Smarc {
939*35157Smarc if(flag)
940*35157Smarc a1=attest(fp,N_EXPORT)?is_xfunction:is_function;
941*35157Smarc }
942*35157Smarc else
943*35157Smarc {
944*35157Smarc /* find full pathname */
945*35157Smarc a1 = fullname(a1);
946*35157Smarc if(a1)
947*35157Smarc {
948*35157Smarc if(flag)
949*35157Smarc {
950*35157Smarc /* tracked aliases next */
951*35157Smarc if(np && attest(np,T_FLAG) && *a1 == '/')
952*35157Smarc fputs(is_talias,output);
953*35157Smarc else
954*35157Smarc fputs(is_,output);
955*35157Smarc }
956*35157Smarc }
957*35157Smarc else
958*35157Smarc {
959*35157Smarc a1 = (flag?notfound:nullstr);
960*35157Smarc exitval |= 1;
961*35157Smarc }
962*35157Smarc }
963*35157Smarc p_str(a1,NL);
964*35157Smarc }
965*35157Smarc }
966*35157Smarc
967*35157Smarc /*
968*35157Smarc * these functions are used to get and set the SECONDS variable
969*35157Smarc */
970*35157Smarc
971*35157Smarc static long sec_offset;
972*35157Smarc
set_second(n)973*35157Smarc static int set_second(n)
974*35157Smarc long n;
975*35157Smarc {
976*35157Smarc sec_offset = time((long*)0) - n ;
977*35157Smarc }
978*35157Smarc
get_second()979*35157Smarc static long get_second()
980*35157Smarc {
981*35157Smarc return(time((long*)0)-sec_offset);
982*35157Smarc }
983*35157Smarc
984*35157Smarc /*
985*35157Smarc * These functions are used to get and set the RANDOM variable
986*35157Smarc */
987*35157Smarc
set_rand(n)988*35157Smarc static int set_rand(n)
989*35157Smarc long n;
990*35157Smarc {
991*35157Smarc srand((int)n);
992*35157Smarc }
993*35157Smarc
get_rand()994*35157Smarc static long get_rand()
995*35157Smarc {
996*35157Smarc return((long)rand());
997*35157Smarc }
998*35157Smarc
999*35157Smarc #ifdef ECHO_N
echo_mode()1000*35157Smarc char *echo_mode()
1001*35157Smarc {
1002*35157Smarc register char *cp;
1003*35157Smarc optflag savopts;
1004*35157Smarc if(echo_arg==0)
1005*35157Smarc {
1006*35157Smarc #ifdef apollo
1007*35157Smarc register NAMPTR np = checkfor("SYSTYPE",namep);
1008*35157Smarc if(np && (cp=valup(np)))
1009*35157Smarc {
1010*35157Smarc echo_arg = (*cp=='b'?echo_opt:minus);
1011*35157Smarc return(echo_arg);
1012*35157Smarc }
1013*35157Smarc #endif /* apollo */
1014*35157Smarc savopts = flags;
1015*35157Smarc off_option(HASHALL);
1016*35157Smarc cp = fullname(echo_bin+5);
1017*35157Smarc flags = savopts;
1018*35157Smarc if(eq(cp,echo_bin))
1019*35157Smarc echo_arg = echo_opt;
1020*35157Smarc else
1021*35157Smarc echo_arg = minus;
1022*35157Smarc }
1023*35157Smarc return(echo_arg);
1024*35157Smarc }
1025*35157Smarc #endif /* ECHO_N */
1026