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