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