xref: /illumos-gate/usr/src/cmd/sh/name.c (revision 7c478bd9)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
23*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
24*7c478bd9Sstevel@tonic-gate 
25*7c478bd9Sstevel@tonic-gate 
26*7c478bd9Sstevel@tonic-gate /*
27*7c478bd9Sstevel@tonic-gate  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
28*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
29*7c478bd9Sstevel@tonic-gate  */
30*7c478bd9Sstevel@tonic-gate 
31*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
32*7c478bd9Sstevel@tonic-gate /*
33*7c478bd9Sstevel@tonic-gate  * UNIX shell
34*7c478bd9Sstevel@tonic-gate  */
35*7c478bd9Sstevel@tonic-gate 
36*7c478bd9Sstevel@tonic-gate #include	"defs.h"
37*7c478bd9Sstevel@tonic-gate #include	<stropts.h>
38*7c478bd9Sstevel@tonic-gate 
39*7c478bd9Sstevel@tonic-gate extern BOOL	chkid();
40*7c478bd9Sstevel@tonic-gate extern unsigned char	*simple();
41*7c478bd9Sstevel@tonic-gate extern int	mailchk;
42*7c478bd9Sstevel@tonic-gate static void	namwalk();
43*7c478bd9Sstevel@tonic-gate 
44*7c478bd9Sstevel@tonic-gate static void	set_builtins_path();
45*7c478bd9Sstevel@tonic-gate static int	patheq();
46*7c478bd9Sstevel@tonic-gate static void dolocale();
47*7c478bd9Sstevel@tonic-gate 
48*7c478bd9Sstevel@tonic-gate struct namnod ps2nod =
49*7c478bd9Sstevel@tonic-gate {
50*7c478bd9Sstevel@tonic-gate 	(struct namnod *)NIL,
51*7c478bd9Sstevel@tonic-gate 	&acctnod,
52*7c478bd9Sstevel@tonic-gate 	(unsigned char *)ps2name
53*7c478bd9Sstevel@tonic-gate };
54*7c478bd9Sstevel@tonic-gate struct namnod cdpnod =
55*7c478bd9Sstevel@tonic-gate {
56*7c478bd9Sstevel@tonic-gate 	(struct namnod *)NIL,
57*7c478bd9Sstevel@tonic-gate 	(struct namnod *)NIL,
58*7c478bd9Sstevel@tonic-gate 	(unsigned char *)cdpname
59*7c478bd9Sstevel@tonic-gate };
60*7c478bd9Sstevel@tonic-gate struct namnod pathnod =
61*7c478bd9Sstevel@tonic-gate {
62*7c478bd9Sstevel@tonic-gate 	&mailpnod,
63*7c478bd9Sstevel@tonic-gate 	(struct namnod *)NIL,
64*7c478bd9Sstevel@tonic-gate 	(unsigned char *)pathname
65*7c478bd9Sstevel@tonic-gate };
66*7c478bd9Sstevel@tonic-gate struct namnod ifsnod =
67*7c478bd9Sstevel@tonic-gate {
68*7c478bd9Sstevel@tonic-gate 	&homenod,
69*7c478bd9Sstevel@tonic-gate 	&mailnod,
70*7c478bd9Sstevel@tonic-gate 	(unsigned char *)ifsname
71*7c478bd9Sstevel@tonic-gate };
72*7c478bd9Sstevel@tonic-gate struct namnod ps1nod =
73*7c478bd9Sstevel@tonic-gate {
74*7c478bd9Sstevel@tonic-gate 	&pathnod,
75*7c478bd9Sstevel@tonic-gate 	&ps2nod,
76*7c478bd9Sstevel@tonic-gate 	(unsigned char *)ps1name
77*7c478bd9Sstevel@tonic-gate };
78*7c478bd9Sstevel@tonic-gate struct namnod homenod =
79*7c478bd9Sstevel@tonic-gate {
80*7c478bd9Sstevel@tonic-gate 	&cdpnod,
81*7c478bd9Sstevel@tonic-gate 	(struct namnod *)NIL,
82*7c478bd9Sstevel@tonic-gate 	(unsigned char *)homename
83*7c478bd9Sstevel@tonic-gate };
84*7c478bd9Sstevel@tonic-gate struct namnod mailnod =
85*7c478bd9Sstevel@tonic-gate {
86*7c478bd9Sstevel@tonic-gate 	(struct namnod *)NIL,
87*7c478bd9Sstevel@tonic-gate 	(struct namnod *)NIL,
88*7c478bd9Sstevel@tonic-gate 	(unsigned char *)mailname
89*7c478bd9Sstevel@tonic-gate };
90*7c478bd9Sstevel@tonic-gate struct namnod mchknod =
91*7c478bd9Sstevel@tonic-gate {
92*7c478bd9Sstevel@tonic-gate 	&ifsnod,
93*7c478bd9Sstevel@tonic-gate 	&ps1nod,
94*7c478bd9Sstevel@tonic-gate 	(unsigned char *)mchkname
95*7c478bd9Sstevel@tonic-gate };
96*7c478bd9Sstevel@tonic-gate struct namnod acctnod =
97*7c478bd9Sstevel@tonic-gate {
98*7c478bd9Sstevel@tonic-gate 	(struct namnod *)NIL,
99*7c478bd9Sstevel@tonic-gate 	(struct namnod *)NIL,
100*7c478bd9Sstevel@tonic-gate 	(unsigned char *)acctname
101*7c478bd9Sstevel@tonic-gate };
102*7c478bd9Sstevel@tonic-gate struct namnod mailpnod =
103*7c478bd9Sstevel@tonic-gate {
104*7c478bd9Sstevel@tonic-gate 	(struct namnod *)NIL,
105*7c478bd9Sstevel@tonic-gate 	(struct namnod *)NIL,
106*7c478bd9Sstevel@tonic-gate 	(unsigned char *)mailpname
107*7c478bd9Sstevel@tonic-gate };
108*7c478bd9Sstevel@tonic-gate 
109*7c478bd9Sstevel@tonic-gate 
110*7c478bd9Sstevel@tonic-gate struct namnod *namep = &mchknod;
111*7c478bd9Sstevel@tonic-gate 
112*7c478bd9Sstevel@tonic-gate /* ========	variable and string handling	======== */
113*7c478bd9Sstevel@tonic-gate 
114*7c478bd9Sstevel@tonic-gate syslook(w, syswds, n)
115*7c478bd9Sstevel@tonic-gate 	register unsigned char *w;
116*7c478bd9Sstevel@tonic-gate 	register struct sysnod syswds[];
117*7c478bd9Sstevel@tonic-gate 	int n;
118*7c478bd9Sstevel@tonic-gate {
119*7c478bd9Sstevel@tonic-gate 	int	low;
120*7c478bd9Sstevel@tonic-gate 	int	high;
121*7c478bd9Sstevel@tonic-gate 	int	mid;
122*7c478bd9Sstevel@tonic-gate 	register int cond;
123*7c478bd9Sstevel@tonic-gate 
124*7c478bd9Sstevel@tonic-gate 	if (w == 0 || *w == 0)
125*7c478bd9Sstevel@tonic-gate 		return(0);
126*7c478bd9Sstevel@tonic-gate 
127*7c478bd9Sstevel@tonic-gate 	low = 0;
128*7c478bd9Sstevel@tonic-gate 	high = n - 1;
129*7c478bd9Sstevel@tonic-gate 
130*7c478bd9Sstevel@tonic-gate 	while (low <= high)
131*7c478bd9Sstevel@tonic-gate 	{
132*7c478bd9Sstevel@tonic-gate 		mid = (low + high) / 2;
133*7c478bd9Sstevel@tonic-gate 
134*7c478bd9Sstevel@tonic-gate 		if ((cond = cf(w, syswds[mid].sysnam)) < 0)
135*7c478bd9Sstevel@tonic-gate 			high = mid - 1;
136*7c478bd9Sstevel@tonic-gate 		else if (cond > 0)
137*7c478bd9Sstevel@tonic-gate 			low = mid + 1;
138*7c478bd9Sstevel@tonic-gate 		else
139*7c478bd9Sstevel@tonic-gate 			return(syswds[mid].sysval);
140*7c478bd9Sstevel@tonic-gate 	}
141*7c478bd9Sstevel@tonic-gate 	return(0);
142*7c478bd9Sstevel@tonic-gate }
143*7c478bd9Sstevel@tonic-gate 
144*7c478bd9Sstevel@tonic-gate setlist(arg, xp)
145*7c478bd9Sstevel@tonic-gate register struct argnod *arg;
146*7c478bd9Sstevel@tonic-gate int	xp;
147*7c478bd9Sstevel@tonic-gate {
148*7c478bd9Sstevel@tonic-gate 	if (flags & exportflg)
149*7c478bd9Sstevel@tonic-gate 		xp |= N_EXPORT;
150*7c478bd9Sstevel@tonic-gate 
151*7c478bd9Sstevel@tonic-gate 	while (arg)
152*7c478bd9Sstevel@tonic-gate 	{
153*7c478bd9Sstevel@tonic-gate 		register unsigned char *s = mactrim(arg->argval);
154*7c478bd9Sstevel@tonic-gate 		setname(s, xp);
155*7c478bd9Sstevel@tonic-gate 		arg = arg->argnxt;
156*7c478bd9Sstevel@tonic-gate 		if (flags & execpr)
157*7c478bd9Sstevel@tonic-gate 		{
158*7c478bd9Sstevel@tonic-gate 			prs(s);
159*7c478bd9Sstevel@tonic-gate 			if (arg)
160*7c478bd9Sstevel@tonic-gate 				blank();
161*7c478bd9Sstevel@tonic-gate 			else
162*7c478bd9Sstevel@tonic-gate 				newline();
163*7c478bd9Sstevel@tonic-gate 		}
164*7c478bd9Sstevel@tonic-gate 	}
165*7c478bd9Sstevel@tonic-gate }
166*7c478bd9Sstevel@tonic-gate 
167*7c478bd9Sstevel@tonic-gate 
168*7c478bd9Sstevel@tonic-gate setname(argi, xp)	/* does parameter assignments */
169*7c478bd9Sstevel@tonic-gate unsigned char	*argi;
170*7c478bd9Sstevel@tonic-gate int	xp;
171*7c478bd9Sstevel@tonic-gate {
172*7c478bd9Sstevel@tonic-gate 	register unsigned char *argscan = argi;
173*7c478bd9Sstevel@tonic-gate 	register struct namnod *n;
174*7c478bd9Sstevel@tonic-gate 
175*7c478bd9Sstevel@tonic-gate 	if (letter(*argscan))
176*7c478bd9Sstevel@tonic-gate 	{
177*7c478bd9Sstevel@tonic-gate 		while (alphanum(*argscan))
178*7c478bd9Sstevel@tonic-gate 			argscan++;
179*7c478bd9Sstevel@tonic-gate 
180*7c478bd9Sstevel@tonic-gate 		if (*argscan == '=')
181*7c478bd9Sstevel@tonic-gate 		{
182*7c478bd9Sstevel@tonic-gate 			*argscan = 0;	/* make name a cohesive string */
183*7c478bd9Sstevel@tonic-gate 
184*7c478bd9Sstevel@tonic-gate 			n = lookup(argi);
185*7c478bd9Sstevel@tonic-gate 			*argscan++ = '=';
186*7c478bd9Sstevel@tonic-gate 			attrib(n, xp);
187*7c478bd9Sstevel@tonic-gate 			if (xp & N_ENVNAM)
188*7c478bd9Sstevel@tonic-gate 			{
189*7c478bd9Sstevel@tonic-gate 				n->namenv = n->namval = argscan;
190*7c478bd9Sstevel@tonic-gate 				if (n == &pathnod)
191*7c478bd9Sstevel@tonic-gate 					set_builtins_path();
192*7c478bd9Sstevel@tonic-gate 			}
193*7c478bd9Sstevel@tonic-gate 			else
194*7c478bd9Sstevel@tonic-gate 				assign(n, argscan);
195*7c478bd9Sstevel@tonic-gate 
196*7c478bd9Sstevel@tonic-gate 			dolocale(n->namid);
197*7c478bd9Sstevel@tonic-gate 			return;
198*7c478bd9Sstevel@tonic-gate 		}
199*7c478bd9Sstevel@tonic-gate 	}
200*7c478bd9Sstevel@tonic-gate }
201*7c478bd9Sstevel@tonic-gate 
202*7c478bd9Sstevel@tonic-gate replace(a, v)
203*7c478bd9Sstevel@tonic-gate register unsigned char	**a;
204*7c478bd9Sstevel@tonic-gate unsigned char	*v;
205*7c478bd9Sstevel@tonic-gate {
206*7c478bd9Sstevel@tonic-gate 	free(*a);
207*7c478bd9Sstevel@tonic-gate 	*a = make(v);
208*7c478bd9Sstevel@tonic-gate }
209*7c478bd9Sstevel@tonic-gate 
210*7c478bd9Sstevel@tonic-gate dfault(n, v)
211*7c478bd9Sstevel@tonic-gate struct namnod *n;
212*7c478bd9Sstevel@tonic-gate unsigned char	*v;
213*7c478bd9Sstevel@tonic-gate {
214*7c478bd9Sstevel@tonic-gate 	if (n->namval == 0)
215*7c478bd9Sstevel@tonic-gate 		assign(n, v);
216*7c478bd9Sstevel@tonic-gate }
217*7c478bd9Sstevel@tonic-gate 
218*7c478bd9Sstevel@tonic-gate assign(n, v)
219*7c478bd9Sstevel@tonic-gate struct namnod *n;
220*7c478bd9Sstevel@tonic-gate unsigned char	*v;
221*7c478bd9Sstevel@tonic-gate {
222*7c478bd9Sstevel@tonic-gate 	if (n->namflg & N_RDONLY)
223*7c478bd9Sstevel@tonic-gate 		failed(n->namid, wtfailed);
224*7c478bd9Sstevel@tonic-gate 
225*7c478bd9Sstevel@tonic-gate #ifndef RES
226*7c478bd9Sstevel@tonic-gate 
227*7c478bd9Sstevel@tonic-gate 	else if (flags & rshflg)
228*7c478bd9Sstevel@tonic-gate 	{
229*7c478bd9Sstevel@tonic-gate 		if (n == &pathnod || eq(n->namid,"SHELL"))
230*7c478bd9Sstevel@tonic-gate 			failed(n->namid, restricted);
231*7c478bd9Sstevel@tonic-gate 	}
232*7c478bd9Sstevel@tonic-gate #endif
233*7c478bd9Sstevel@tonic-gate 
234*7c478bd9Sstevel@tonic-gate 	else if (n->namflg & N_FUNCTN)
235*7c478bd9Sstevel@tonic-gate 	{
236*7c478bd9Sstevel@tonic-gate 		func_unhash(n->namid);
237*7c478bd9Sstevel@tonic-gate 		freefunc(n);
238*7c478bd9Sstevel@tonic-gate 
239*7c478bd9Sstevel@tonic-gate 		n->namenv = 0;
240*7c478bd9Sstevel@tonic-gate 		n->namflg = N_DEFAULT;
241*7c478bd9Sstevel@tonic-gate 	}
242*7c478bd9Sstevel@tonic-gate 
243*7c478bd9Sstevel@tonic-gate 	if (n == &mchknod)
244*7c478bd9Sstevel@tonic-gate 	{
245*7c478bd9Sstevel@tonic-gate 		mailchk = stoi(v);
246*7c478bd9Sstevel@tonic-gate 	}
247*7c478bd9Sstevel@tonic-gate 
248*7c478bd9Sstevel@tonic-gate 	replace(&n->namval, v);
249*7c478bd9Sstevel@tonic-gate 	attrib(n, N_ENVCHG);
250*7c478bd9Sstevel@tonic-gate 
251*7c478bd9Sstevel@tonic-gate 	if (n == &pathnod)
252*7c478bd9Sstevel@tonic-gate 	{
253*7c478bd9Sstevel@tonic-gate 		zaphash();
254*7c478bd9Sstevel@tonic-gate 		set_dotpath();
255*7c478bd9Sstevel@tonic-gate 		set_builtins_path();
256*7c478bd9Sstevel@tonic-gate 		return;
257*7c478bd9Sstevel@tonic-gate 	}
258*7c478bd9Sstevel@tonic-gate 
259*7c478bd9Sstevel@tonic-gate 	if (flags & prompt)
260*7c478bd9Sstevel@tonic-gate 	{
261*7c478bd9Sstevel@tonic-gate 		if ((n == &mailpnod) || (n == &mailnod && mailpnod.namflg == N_DEFAULT))
262*7c478bd9Sstevel@tonic-gate 			setmail(n->namval);
263*7c478bd9Sstevel@tonic-gate 	}
264*7c478bd9Sstevel@tonic-gate }
265*7c478bd9Sstevel@tonic-gate 
266*7c478bd9Sstevel@tonic-gate static void
267*7c478bd9Sstevel@tonic-gate set_builtins_path()
268*7c478bd9Sstevel@tonic-gate {
269*7c478bd9Sstevel@tonic-gate         register unsigned char *path;
270*7c478bd9Sstevel@tonic-gate 
271*7c478bd9Sstevel@tonic-gate         ucb_builtins = 0;
272*7c478bd9Sstevel@tonic-gate         path = getpath("");
273*7c478bd9Sstevel@tonic-gate         while (path && *path)
274*7c478bd9Sstevel@tonic-gate         {
275*7c478bd9Sstevel@tonic-gate                 if (patheq(path, "/usr/ucb"))
276*7c478bd9Sstevel@tonic-gate                 {
277*7c478bd9Sstevel@tonic-gate                         ucb_builtins++;
278*7c478bd9Sstevel@tonic-gate                         break;
279*7c478bd9Sstevel@tonic-gate                 }
280*7c478bd9Sstevel@tonic-gate                 else if (patheq(path, "/usr/bin"))
281*7c478bd9Sstevel@tonic-gate                         break;
282*7c478bd9Sstevel@tonic-gate                 else if (patheq(path, "/bin"))
283*7c478bd9Sstevel@tonic-gate                         break;
284*7c478bd9Sstevel@tonic-gate                 else if (patheq(path, "/usr/5bin"))
285*7c478bd9Sstevel@tonic-gate                         break;
286*7c478bd9Sstevel@tonic-gate                 path = nextpath(path);
287*7c478bd9Sstevel@tonic-gate         }
288*7c478bd9Sstevel@tonic-gate }
289*7c478bd9Sstevel@tonic-gate 
290*7c478bd9Sstevel@tonic-gate static int
291*7c478bd9Sstevel@tonic-gate patheq(component, dir)
292*7c478bd9Sstevel@tonic-gate register unsigned char   *component;
293*7c478bd9Sstevel@tonic-gate register char   *dir;
294*7c478bd9Sstevel@tonic-gate {
295*7c478bd9Sstevel@tonic-gate         register unsigned char   c;
296*7c478bd9Sstevel@tonic-gate 
297*7c478bd9Sstevel@tonic-gate         for (;;)
298*7c478bd9Sstevel@tonic-gate         {
299*7c478bd9Sstevel@tonic-gate                 c = *component++;
300*7c478bd9Sstevel@tonic-gate                 if (c == COLON)
301*7c478bd9Sstevel@tonic-gate                         c = '\0';       /* end of component of path */
302*7c478bd9Sstevel@tonic-gate                 if (c != *dir++)
303*7c478bd9Sstevel@tonic-gate                         return(0);
304*7c478bd9Sstevel@tonic-gate                 if (c == '\0')
305*7c478bd9Sstevel@tonic-gate                         return(1);
306*7c478bd9Sstevel@tonic-gate         }
307*7c478bd9Sstevel@tonic-gate }
308*7c478bd9Sstevel@tonic-gate 
309*7c478bd9Sstevel@tonic-gate readvar(names)
310*7c478bd9Sstevel@tonic-gate unsigned char	**names;
311*7c478bd9Sstevel@tonic-gate {
312*7c478bd9Sstevel@tonic-gate 	struct fileblk	fb;
313*7c478bd9Sstevel@tonic-gate 	register struct fileblk *f = &fb;
314*7c478bd9Sstevel@tonic-gate 	unsigned char	c[MULTI_BYTE_MAX+1];
315*7c478bd9Sstevel@tonic-gate 	register int	rc = 0;
316*7c478bd9Sstevel@tonic-gate 	struct namnod *n = lookup(*names++);	/* done now to avoid storage mess */
317*7c478bd9Sstevel@tonic-gate 	unsigned char	*rel = (unsigned char *)relstak();
318*7c478bd9Sstevel@tonic-gate 	unsigned char *oldstak;
319*7c478bd9Sstevel@tonic-gate 	register unsigned char *pc, *rest;
320*7c478bd9Sstevel@tonic-gate 	int		d;
321*7c478bd9Sstevel@tonic-gate 
322*7c478bd9Sstevel@tonic-gate 	push(f);
323*7c478bd9Sstevel@tonic-gate 	initf(dup(0));
324*7c478bd9Sstevel@tonic-gate 
325*7c478bd9Sstevel@tonic-gate 	/*
326*7c478bd9Sstevel@tonic-gate 	 * If stdin is a pipe then this lseek(2) will fail with ESPIPE, so
327*7c478bd9Sstevel@tonic-gate 	 * the read buffer size is set to 1 because we will not be able
328*7c478bd9Sstevel@tonic-gate 	 * lseek(2) back towards the beginning of the file, so we have
329*7c478bd9Sstevel@tonic-gate 	 * to read a byte at a time instead
330*7c478bd9Sstevel@tonic-gate 	 *
331*7c478bd9Sstevel@tonic-gate 	 */
332*7c478bd9Sstevel@tonic-gate 	if (lseek(0, (off_t)0, SEEK_CUR) == -1)
333*7c478bd9Sstevel@tonic-gate 		f->fsiz = 1;
334*7c478bd9Sstevel@tonic-gate 
335*7c478bd9Sstevel@tonic-gate 	/*
336*7c478bd9Sstevel@tonic-gate 	 * If stdin is a socket then this isastream(3C) will return 1, so
337*7c478bd9Sstevel@tonic-gate 	 * the read buffer size is set to 1 because we will not be able
338*7c478bd9Sstevel@tonic-gate 	 * lseek(2) back towards the beginning of the file, so we have
339*7c478bd9Sstevel@tonic-gate 	 * to read a byte at a time instead
340*7c478bd9Sstevel@tonic-gate 	 *
341*7c478bd9Sstevel@tonic-gate 	 */
342*7c478bd9Sstevel@tonic-gate 	if (isastream(0) == 1)
343*7c478bd9Sstevel@tonic-gate 		f->fsiz = 1;
344*7c478bd9Sstevel@tonic-gate 
345*7c478bd9Sstevel@tonic-gate 	/*
346*7c478bd9Sstevel@tonic-gate 	 * strip leading IFS characters
347*7c478bd9Sstevel@tonic-gate 	 */
348*7c478bd9Sstevel@tonic-gate 	for (;;)
349*7c478bd9Sstevel@tonic-gate 	{
350*7c478bd9Sstevel@tonic-gate 		d = nextwc();
351*7c478bd9Sstevel@tonic-gate 		if(eolchar(d))
352*7c478bd9Sstevel@tonic-gate 			break;
353*7c478bd9Sstevel@tonic-gate 		rest = readw(d);
354*7c478bd9Sstevel@tonic-gate 		pc = c;
355*7c478bd9Sstevel@tonic-gate 		while(*pc++ = *rest++);
356*7c478bd9Sstevel@tonic-gate 		if(!anys(c, ifsnod.namval))
357*7c478bd9Sstevel@tonic-gate 			break;
358*7c478bd9Sstevel@tonic-gate 	}
359*7c478bd9Sstevel@tonic-gate 
360*7c478bd9Sstevel@tonic-gate 	oldstak = curstak();
361*7c478bd9Sstevel@tonic-gate 	for (;;)
362*7c478bd9Sstevel@tonic-gate 	{
363*7c478bd9Sstevel@tonic-gate 		if ((*names && anys(c, ifsnod.namval)) || eolchar(d))
364*7c478bd9Sstevel@tonic-gate 		{
365*7c478bd9Sstevel@tonic-gate 			if (staktop >= brkend)
366*7c478bd9Sstevel@tonic-gate 				growstak(staktop);
367*7c478bd9Sstevel@tonic-gate 			zerostak();
368*7c478bd9Sstevel@tonic-gate 			assign(n, absstak(rel));
369*7c478bd9Sstevel@tonic-gate 			setstak(rel);
370*7c478bd9Sstevel@tonic-gate 			if (*names)
371*7c478bd9Sstevel@tonic-gate 				n = lookup(*names++);
372*7c478bd9Sstevel@tonic-gate 			else
373*7c478bd9Sstevel@tonic-gate 				n = 0;
374*7c478bd9Sstevel@tonic-gate 			if (eolchar(d))
375*7c478bd9Sstevel@tonic-gate 			{
376*7c478bd9Sstevel@tonic-gate 				break;
377*7c478bd9Sstevel@tonic-gate 			}
378*7c478bd9Sstevel@tonic-gate 			else		/* strip imbedded IFS characters */
379*7c478bd9Sstevel@tonic-gate 				while(1) {
380*7c478bd9Sstevel@tonic-gate 					d = nextwc();
381*7c478bd9Sstevel@tonic-gate 					if(eolchar(d))
382*7c478bd9Sstevel@tonic-gate 						break;
383*7c478bd9Sstevel@tonic-gate 					rest = readw(d);
384*7c478bd9Sstevel@tonic-gate 					pc = c;
385*7c478bd9Sstevel@tonic-gate 					while(*pc++ = *rest++);
386*7c478bd9Sstevel@tonic-gate 					if(!anys(c, ifsnod.namval))
387*7c478bd9Sstevel@tonic-gate 						break;
388*7c478bd9Sstevel@tonic-gate 				}
389*7c478bd9Sstevel@tonic-gate 		}
390*7c478bd9Sstevel@tonic-gate 		else
391*7c478bd9Sstevel@tonic-gate 		{
392*7c478bd9Sstevel@tonic-gate 			if(d == '\\') {
393*7c478bd9Sstevel@tonic-gate 				d = readwc();
394*7c478bd9Sstevel@tonic-gate 				rest = readw(d);
395*7c478bd9Sstevel@tonic-gate 				while(d = *rest++) {
396*7c478bd9Sstevel@tonic-gate 					if (staktop >= brkend)
397*7c478bd9Sstevel@tonic-gate 						growstak(staktop);
398*7c478bd9Sstevel@tonic-gate 					pushstak(d);
399*7c478bd9Sstevel@tonic-gate 				}
400*7c478bd9Sstevel@tonic-gate 				oldstak = staktop;
401*7c478bd9Sstevel@tonic-gate 			}
402*7c478bd9Sstevel@tonic-gate 			else
403*7c478bd9Sstevel@tonic-gate 			{
404*7c478bd9Sstevel@tonic-gate 				pc = c;
405*7c478bd9Sstevel@tonic-gate 				while(d = *pc++) {
406*7c478bd9Sstevel@tonic-gate 					if (staktop >= brkend)
407*7c478bd9Sstevel@tonic-gate 						growstak(staktop);
408*7c478bd9Sstevel@tonic-gate 					pushstak(d);
409*7c478bd9Sstevel@tonic-gate 				}
410*7c478bd9Sstevel@tonic-gate 				if(!anys(c, ifsnod.namval))
411*7c478bd9Sstevel@tonic-gate 					oldstak = staktop;
412*7c478bd9Sstevel@tonic-gate 			}
413*7c478bd9Sstevel@tonic-gate 			d = nextwc();
414*7c478bd9Sstevel@tonic-gate 
415*7c478bd9Sstevel@tonic-gate 			if (eolchar(d))
416*7c478bd9Sstevel@tonic-gate 				staktop = oldstak;
417*7c478bd9Sstevel@tonic-gate 			else
418*7c478bd9Sstevel@tonic-gate 			{
419*7c478bd9Sstevel@tonic-gate 				rest = readw(d);
420*7c478bd9Sstevel@tonic-gate 				pc = c;
421*7c478bd9Sstevel@tonic-gate 				while(*pc++ = *rest++);
422*7c478bd9Sstevel@tonic-gate 			}
423*7c478bd9Sstevel@tonic-gate 		}
424*7c478bd9Sstevel@tonic-gate 	}
425*7c478bd9Sstevel@tonic-gate 	while (n)
426*7c478bd9Sstevel@tonic-gate 	{
427*7c478bd9Sstevel@tonic-gate 		assign(n, nullstr);
428*7c478bd9Sstevel@tonic-gate 		if (*names)
429*7c478bd9Sstevel@tonic-gate 			n = lookup(*names++);
430*7c478bd9Sstevel@tonic-gate 		else
431*7c478bd9Sstevel@tonic-gate 			n = 0;
432*7c478bd9Sstevel@tonic-gate 	}
433*7c478bd9Sstevel@tonic-gate 
434*7c478bd9Sstevel@tonic-gate 	if (eof)
435*7c478bd9Sstevel@tonic-gate 		rc = 1;
436*7c478bd9Sstevel@tonic-gate 
437*7c478bd9Sstevel@tonic-gate 	if (isastream(0) != 1)
438*7c478bd9Sstevel@tonic-gate 		/*
439*7c478bd9Sstevel@tonic-gate 		 * If we are reading on a stream do not attempt to
440*7c478bd9Sstevel@tonic-gate 		 * lseek(2) back towards the start because this is
441*7c478bd9Sstevel@tonic-gate 		 * logically meaningless, but there is nothing in
442*7c478bd9Sstevel@tonic-gate 		 * the standards to pervent the stream implementation
443*7c478bd9Sstevel@tonic-gate 		 * from attempting it and breaking our code here
444*7c478bd9Sstevel@tonic-gate 		 *
445*7c478bd9Sstevel@tonic-gate 		 */
446*7c478bd9Sstevel@tonic-gate 		lseek(0, (off_t)(f->nxtoff - f->endoff), SEEK_CUR);
447*7c478bd9Sstevel@tonic-gate 
448*7c478bd9Sstevel@tonic-gate 	pop();
449*7c478bd9Sstevel@tonic-gate 	return(rc);
450*7c478bd9Sstevel@tonic-gate }
451*7c478bd9Sstevel@tonic-gate 
452*7c478bd9Sstevel@tonic-gate assnum(p, i)
453*7c478bd9Sstevel@tonic-gate unsigned char	**p;
454*7c478bd9Sstevel@tonic-gate long	i;
455*7c478bd9Sstevel@tonic-gate {
456*7c478bd9Sstevel@tonic-gate 	int j = ltos(i);
457*7c478bd9Sstevel@tonic-gate 	replace(p, &numbuf[j]);
458*7c478bd9Sstevel@tonic-gate }
459*7c478bd9Sstevel@tonic-gate 
460*7c478bd9Sstevel@tonic-gate unsigned char *
461*7c478bd9Sstevel@tonic-gate make(v)
462*7c478bd9Sstevel@tonic-gate unsigned char	*v;
463*7c478bd9Sstevel@tonic-gate {
464*7c478bd9Sstevel@tonic-gate 	register unsigned char	*p;
465*7c478bd9Sstevel@tonic-gate 
466*7c478bd9Sstevel@tonic-gate 	if (v)
467*7c478bd9Sstevel@tonic-gate 	{
468*7c478bd9Sstevel@tonic-gate 		movstr(v, p = (unsigned char *)alloc(length(v)));
469*7c478bd9Sstevel@tonic-gate 		return(p);
470*7c478bd9Sstevel@tonic-gate 	}
471*7c478bd9Sstevel@tonic-gate 	else
472*7c478bd9Sstevel@tonic-gate 		return(0);
473*7c478bd9Sstevel@tonic-gate }
474*7c478bd9Sstevel@tonic-gate 
475*7c478bd9Sstevel@tonic-gate 
476*7c478bd9Sstevel@tonic-gate struct namnod *
477*7c478bd9Sstevel@tonic-gate lookup(nam)
478*7c478bd9Sstevel@tonic-gate 	register unsigned char	*nam;
479*7c478bd9Sstevel@tonic-gate {
480*7c478bd9Sstevel@tonic-gate 	register struct namnod *nscan = namep;
481*7c478bd9Sstevel@tonic-gate 	register struct namnod **prev;
482*7c478bd9Sstevel@tonic-gate 	int		LR;
483*7c478bd9Sstevel@tonic-gate 
484*7c478bd9Sstevel@tonic-gate 	if (!chkid(nam))
485*7c478bd9Sstevel@tonic-gate 		failed(nam, notid);
486*7c478bd9Sstevel@tonic-gate 
487*7c478bd9Sstevel@tonic-gate 	while (nscan)
488*7c478bd9Sstevel@tonic-gate 	{
489*7c478bd9Sstevel@tonic-gate 		if ((LR = cf(nam, nscan->namid)) == 0)
490*7c478bd9Sstevel@tonic-gate 			return(nscan);
491*7c478bd9Sstevel@tonic-gate 
492*7c478bd9Sstevel@tonic-gate 		else if (LR < 0)
493*7c478bd9Sstevel@tonic-gate 			prev = &(nscan->namlft);
494*7c478bd9Sstevel@tonic-gate 		else
495*7c478bd9Sstevel@tonic-gate 			prev = &(nscan->namrgt);
496*7c478bd9Sstevel@tonic-gate 		nscan = *prev;
497*7c478bd9Sstevel@tonic-gate 	}
498*7c478bd9Sstevel@tonic-gate 	/*
499*7c478bd9Sstevel@tonic-gate 	 * add name node
500*7c478bd9Sstevel@tonic-gate 	 */
501*7c478bd9Sstevel@tonic-gate 	nscan = (struct namnod *)alloc(sizeof *nscan);
502*7c478bd9Sstevel@tonic-gate 	nscan->namlft = nscan->namrgt = (struct namnod *)NIL;
503*7c478bd9Sstevel@tonic-gate 	nscan->namid = make(nam);
504*7c478bd9Sstevel@tonic-gate 	nscan->namval = 0;
505*7c478bd9Sstevel@tonic-gate 	nscan->namflg = N_DEFAULT;
506*7c478bd9Sstevel@tonic-gate 	nscan->namenv = 0;
507*7c478bd9Sstevel@tonic-gate 
508*7c478bd9Sstevel@tonic-gate 	return(*prev = nscan);
509*7c478bd9Sstevel@tonic-gate }
510*7c478bd9Sstevel@tonic-gate 
511*7c478bd9Sstevel@tonic-gate BOOL
512*7c478bd9Sstevel@tonic-gate chkid(nam)
513*7c478bd9Sstevel@tonic-gate unsigned char	*nam;
514*7c478bd9Sstevel@tonic-gate {
515*7c478bd9Sstevel@tonic-gate 	register unsigned char *cp = nam;
516*7c478bd9Sstevel@tonic-gate 
517*7c478bd9Sstevel@tonic-gate 	if (!letter(*cp))
518*7c478bd9Sstevel@tonic-gate 		return(FALSE);
519*7c478bd9Sstevel@tonic-gate 	else
520*7c478bd9Sstevel@tonic-gate 	{
521*7c478bd9Sstevel@tonic-gate 		while (*++cp)
522*7c478bd9Sstevel@tonic-gate 		{
523*7c478bd9Sstevel@tonic-gate 			if (!alphanum(*cp))
524*7c478bd9Sstevel@tonic-gate 				return(FALSE);
525*7c478bd9Sstevel@tonic-gate 		}
526*7c478bd9Sstevel@tonic-gate 	}
527*7c478bd9Sstevel@tonic-gate 	return(TRUE);
528*7c478bd9Sstevel@tonic-gate }
529*7c478bd9Sstevel@tonic-gate 
530*7c478bd9Sstevel@tonic-gate static int (*namfn)();
531*7c478bd9Sstevel@tonic-gate namscan(fn)
532*7c478bd9Sstevel@tonic-gate 	int	(*fn)();
533*7c478bd9Sstevel@tonic-gate {
534*7c478bd9Sstevel@tonic-gate 	namfn = fn;
535*7c478bd9Sstevel@tonic-gate 	namwalk(namep);
536*7c478bd9Sstevel@tonic-gate }
537*7c478bd9Sstevel@tonic-gate 
538*7c478bd9Sstevel@tonic-gate static void
539*7c478bd9Sstevel@tonic-gate namwalk(np)
540*7c478bd9Sstevel@tonic-gate register struct namnod *np;
541*7c478bd9Sstevel@tonic-gate {
542*7c478bd9Sstevel@tonic-gate 	if (np)
543*7c478bd9Sstevel@tonic-gate 	{
544*7c478bd9Sstevel@tonic-gate 		namwalk(np->namlft);
545*7c478bd9Sstevel@tonic-gate 		(*namfn)(np);
546*7c478bd9Sstevel@tonic-gate 		namwalk(np->namrgt);
547*7c478bd9Sstevel@tonic-gate 	}
548*7c478bd9Sstevel@tonic-gate }
549*7c478bd9Sstevel@tonic-gate 
550*7c478bd9Sstevel@tonic-gate printnam(n)
551*7c478bd9Sstevel@tonic-gate struct namnod *n;
552*7c478bd9Sstevel@tonic-gate {
553*7c478bd9Sstevel@tonic-gate 	register unsigned char	*s;
554*7c478bd9Sstevel@tonic-gate 
555*7c478bd9Sstevel@tonic-gate 	sigchk();
556*7c478bd9Sstevel@tonic-gate 
557*7c478bd9Sstevel@tonic-gate 	if (n->namflg & N_FUNCTN)
558*7c478bd9Sstevel@tonic-gate 	{
559*7c478bd9Sstevel@tonic-gate 		prs_buff(n->namid);
560*7c478bd9Sstevel@tonic-gate 		prs_buff("(){\n");
561*7c478bd9Sstevel@tonic-gate 		prf(n->namenv);
562*7c478bd9Sstevel@tonic-gate 		prs_buff("\n}\n");
563*7c478bd9Sstevel@tonic-gate 	}
564*7c478bd9Sstevel@tonic-gate 	else if (s = n->namval)
565*7c478bd9Sstevel@tonic-gate 	{
566*7c478bd9Sstevel@tonic-gate 		prs_buff(n->namid);
567*7c478bd9Sstevel@tonic-gate 		prc_buff('=');
568*7c478bd9Sstevel@tonic-gate 		prs_buff(s);
569*7c478bd9Sstevel@tonic-gate 		prc_buff(NL);
570*7c478bd9Sstevel@tonic-gate 	}
571*7c478bd9Sstevel@tonic-gate }
572*7c478bd9Sstevel@tonic-gate 
573*7c478bd9Sstevel@tonic-gate static unsigned char *
574*7c478bd9Sstevel@tonic-gate staknam(n)
575*7c478bd9Sstevel@tonic-gate register struct namnod *n;
576*7c478bd9Sstevel@tonic-gate {
577*7c478bd9Sstevel@tonic-gate 	register unsigned char	*p;
578*7c478bd9Sstevel@tonic-gate 
579*7c478bd9Sstevel@tonic-gate 	p = movstrstak(n->namid, staktop);
580*7c478bd9Sstevel@tonic-gate 	p = movstrstak("=", p);
581*7c478bd9Sstevel@tonic-gate 	p = movstrstak(n->namval, p);
582*7c478bd9Sstevel@tonic-gate 	return(getstak(p + 1 - (unsigned char *)(stakbot)));
583*7c478bd9Sstevel@tonic-gate }
584*7c478bd9Sstevel@tonic-gate 
585*7c478bd9Sstevel@tonic-gate static int namec;
586*7c478bd9Sstevel@tonic-gate 
587*7c478bd9Sstevel@tonic-gate exname(n)
588*7c478bd9Sstevel@tonic-gate 	register struct namnod *n;
589*7c478bd9Sstevel@tonic-gate {
590*7c478bd9Sstevel@tonic-gate 	register int 	flg = n->namflg;
591*7c478bd9Sstevel@tonic-gate 
592*7c478bd9Sstevel@tonic-gate 	if (flg & N_ENVCHG)
593*7c478bd9Sstevel@tonic-gate 	{
594*7c478bd9Sstevel@tonic-gate 
595*7c478bd9Sstevel@tonic-gate 		if (flg & N_EXPORT)
596*7c478bd9Sstevel@tonic-gate 		{
597*7c478bd9Sstevel@tonic-gate 			free(n->namenv);
598*7c478bd9Sstevel@tonic-gate 			n->namenv = make(n->namval);
599*7c478bd9Sstevel@tonic-gate 		}
600*7c478bd9Sstevel@tonic-gate 		else
601*7c478bd9Sstevel@tonic-gate 		{
602*7c478bd9Sstevel@tonic-gate 			free(n->namval);
603*7c478bd9Sstevel@tonic-gate 			n->namval = make(n->namenv);
604*7c478bd9Sstevel@tonic-gate 		}
605*7c478bd9Sstevel@tonic-gate 	}
606*7c478bd9Sstevel@tonic-gate 
607*7c478bd9Sstevel@tonic-gate 
608*7c478bd9Sstevel@tonic-gate 	if (!(flg & N_FUNCTN))
609*7c478bd9Sstevel@tonic-gate 		n->namflg = N_DEFAULT;
610*7c478bd9Sstevel@tonic-gate 
611*7c478bd9Sstevel@tonic-gate 	if (n->namval)
612*7c478bd9Sstevel@tonic-gate 		namec++;
613*7c478bd9Sstevel@tonic-gate 
614*7c478bd9Sstevel@tonic-gate }
615*7c478bd9Sstevel@tonic-gate 
616*7c478bd9Sstevel@tonic-gate printro(n)
617*7c478bd9Sstevel@tonic-gate register struct namnod *n;
618*7c478bd9Sstevel@tonic-gate {
619*7c478bd9Sstevel@tonic-gate 	if (n->namflg & N_RDONLY)
620*7c478bd9Sstevel@tonic-gate 	{
621*7c478bd9Sstevel@tonic-gate 		prs_buff(readonly);
622*7c478bd9Sstevel@tonic-gate 		prc_buff(SPACE);
623*7c478bd9Sstevel@tonic-gate 		prs_buff(n->namid);
624*7c478bd9Sstevel@tonic-gate 		prc_buff(NL);
625*7c478bd9Sstevel@tonic-gate 	}
626*7c478bd9Sstevel@tonic-gate }
627*7c478bd9Sstevel@tonic-gate 
628*7c478bd9Sstevel@tonic-gate printexp(n)
629*7c478bd9Sstevel@tonic-gate register struct namnod *n;
630*7c478bd9Sstevel@tonic-gate {
631*7c478bd9Sstevel@tonic-gate 	if (n->namflg & N_EXPORT)
632*7c478bd9Sstevel@tonic-gate 	{
633*7c478bd9Sstevel@tonic-gate 		prs_buff(export);
634*7c478bd9Sstevel@tonic-gate 		prc_buff(SPACE);
635*7c478bd9Sstevel@tonic-gate 		prs_buff(n->namid);
636*7c478bd9Sstevel@tonic-gate 		prc_buff(NL);
637*7c478bd9Sstevel@tonic-gate 	}
638*7c478bd9Sstevel@tonic-gate }
639*7c478bd9Sstevel@tonic-gate 
640*7c478bd9Sstevel@tonic-gate setup_env()
641*7c478bd9Sstevel@tonic-gate {
642*7c478bd9Sstevel@tonic-gate 	register unsigned char **e = environ;
643*7c478bd9Sstevel@tonic-gate 
644*7c478bd9Sstevel@tonic-gate 	while (*e)
645*7c478bd9Sstevel@tonic-gate 		setname(*e++, N_ENVNAM);
646*7c478bd9Sstevel@tonic-gate }
647*7c478bd9Sstevel@tonic-gate 
648*7c478bd9Sstevel@tonic-gate 
649*7c478bd9Sstevel@tonic-gate static unsigned char **argnam;
650*7c478bd9Sstevel@tonic-gate 
651*7c478bd9Sstevel@tonic-gate static
652*7c478bd9Sstevel@tonic-gate countnam(n)
653*7c478bd9Sstevel@tonic-gate struct namnod *n;
654*7c478bd9Sstevel@tonic-gate {
655*7c478bd9Sstevel@tonic-gate 	if (n->namval)
656*7c478bd9Sstevel@tonic-gate 		namec++;
657*7c478bd9Sstevel@tonic-gate }
658*7c478bd9Sstevel@tonic-gate 
659*7c478bd9Sstevel@tonic-gate static
660*7c478bd9Sstevel@tonic-gate pushnam(n)
661*7c478bd9Sstevel@tonic-gate 	register struct namnod *n;
662*7c478bd9Sstevel@tonic-gate {
663*7c478bd9Sstevel@tonic-gate 	register int 	flg = n->namflg;
664*7c478bd9Sstevel@tonic-gate 	register unsigned char	*p;
665*7c478bd9Sstevel@tonic-gate 	register unsigned char	*namval;
666*7c478bd9Sstevel@tonic-gate 
667*7c478bd9Sstevel@tonic-gate 	if (((flg & N_ENVCHG) && (flg & N_EXPORT)) || (flg & N_FUNCTN))
668*7c478bd9Sstevel@tonic-gate 		namval = n->namval;
669*7c478bd9Sstevel@tonic-gate 	else {
670*7c478bd9Sstevel@tonic-gate 		/* Discard Local variable in child process */
671*7c478bd9Sstevel@tonic-gate 		if (!(flg & ~N_ENVCHG)) {
672*7c478bd9Sstevel@tonic-gate 			n->namflg = 0;
673*7c478bd9Sstevel@tonic-gate 			n->namenv = 0;
674*7c478bd9Sstevel@tonic-gate 			if (n->namval) {
675*7c478bd9Sstevel@tonic-gate 				/* Release for re-use */
676*7c478bd9Sstevel@tonic-gate 				free(n->namval);
677*7c478bd9Sstevel@tonic-gate 				n->namval = (unsigned char *)NIL;
678*7c478bd9Sstevel@tonic-gate 			}
679*7c478bd9Sstevel@tonic-gate 		}
680*7c478bd9Sstevel@tonic-gate 		namval = n->namenv;
681*7c478bd9Sstevel@tonic-gate 	}
682*7c478bd9Sstevel@tonic-gate 
683*7c478bd9Sstevel@tonic-gate 	if (namval)
684*7c478bd9Sstevel@tonic-gate 	{
685*7c478bd9Sstevel@tonic-gate 		p = movstrstak(n->namid, staktop);
686*7c478bd9Sstevel@tonic-gate 		p = movstrstak("=", p);
687*7c478bd9Sstevel@tonic-gate 		p = movstrstak(namval, p);
688*7c478bd9Sstevel@tonic-gate 		*argnam++ = getstak(p + 1 - (unsigned char *)(stakbot));
689*7c478bd9Sstevel@tonic-gate 	}
690*7c478bd9Sstevel@tonic-gate }
691*7c478bd9Sstevel@tonic-gate 
692*7c478bd9Sstevel@tonic-gate unsigned char **
693*7c478bd9Sstevel@tonic-gate local_setenv()
694*7c478bd9Sstevel@tonic-gate {
695*7c478bd9Sstevel@tonic-gate 	register unsigned char	**er;
696*7c478bd9Sstevel@tonic-gate 
697*7c478bd9Sstevel@tonic-gate 	namec = 0;
698*7c478bd9Sstevel@tonic-gate 	namscan(countnam);
699*7c478bd9Sstevel@tonic-gate 
700*7c478bd9Sstevel@tonic-gate 	argnam = er = (unsigned char **)getstak(namec * BYTESPERWORD + BYTESPERWORD);
701*7c478bd9Sstevel@tonic-gate 	namscan(pushnam);
702*7c478bd9Sstevel@tonic-gate 	*argnam++ = 0;
703*7c478bd9Sstevel@tonic-gate 	return(er);
704*7c478bd9Sstevel@tonic-gate }
705*7c478bd9Sstevel@tonic-gate 
706*7c478bd9Sstevel@tonic-gate void
707*7c478bd9Sstevel@tonic-gate setvars()
708*7c478bd9Sstevel@tonic-gate {
709*7c478bd9Sstevel@tonic-gate 	namscan(exname);
710*7c478bd9Sstevel@tonic-gate }
711*7c478bd9Sstevel@tonic-gate 
712*7c478bd9Sstevel@tonic-gate struct namnod *
713*7c478bd9Sstevel@tonic-gate findnam(nam)
714*7c478bd9Sstevel@tonic-gate 	register unsigned char	*nam;
715*7c478bd9Sstevel@tonic-gate {
716*7c478bd9Sstevel@tonic-gate 	register struct namnod *nscan = namep;
717*7c478bd9Sstevel@tonic-gate 	int		LR;
718*7c478bd9Sstevel@tonic-gate 
719*7c478bd9Sstevel@tonic-gate 	if (!chkid(nam))
720*7c478bd9Sstevel@tonic-gate 		return(0);
721*7c478bd9Sstevel@tonic-gate 	while (nscan)
722*7c478bd9Sstevel@tonic-gate 	{
723*7c478bd9Sstevel@tonic-gate 		if ((LR = cf(nam, nscan->namid)) == 0)
724*7c478bd9Sstevel@tonic-gate 			return(nscan);
725*7c478bd9Sstevel@tonic-gate 		else if (LR < 0)
726*7c478bd9Sstevel@tonic-gate 			nscan = nscan->namlft;
727*7c478bd9Sstevel@tonic-gate 		else
728*7c478bd9Sstevel@tonic-gate 			nscan = nscan->namrgt;
729*7c478bd9Sstevel@tonic-gate 	}
730*7c478bd9Sstevel@tonic-gate 	return(0);
731*7c478bd9Sstevel@tonic-gate }
732*7c478bd9Sstevel@tonic-gate 
733*7c478bd9Sstevel@tonic-gate 
734*7c478bd9Sstevel@tonic-gate unset_name(name)
735*7c478bd9Sstevel@tonic-gate 	register unsigned char 	*name;
736*7c478bd9Sstevel@tonic-gate {
737*7c478bd9Sstevel@tonic-gate 	register struct namnod	*n;
738*7c478bd9Sstevel@tonic-gate 	register unsigned char 	call_dolocale = 0;
739*7c478bd9Sstevel@tonic-gate 
740*7c478bd9Sstevel@tonic-gate 	if (n = findnam(name))
741*7c478bd9Sstevel@tonic-gate 	{
742*7c478bd9Sstevel@tonic-gate 		if (n->namflg & N_RDONLY)
743*7c478bd9Sstevel@tonic-gate 			failed(name, wtfailed);
744*7c478bd9Sstevel@tonic-gate 
745*7c478bd9Sstevel@tonic-gate 		if (n == &pathnod ||
746*7c478bd9Sstevel@tonic-gate 		    n == &ifsnod ||
747*7c478bd9Sstevel@tonic-gate 		    n == &ps1nod ||
748*7c478bd9Sstevel@tonic-gate 		    n == &ps2nod ||
749*7c478bd9Sstevel@tonic-gate 		    n == &mchknod)
750*7c478bd9Sstevel@tonic-gate 		{
751*7c478bd9Sstevel@tonic-gate 			failed(name, badunset);
752*7c478bd9Sstevel@tonic-gate 		}
753*7c478bd9Sstevel@tonic-gate 
754*7c478bd9Sstevel@tonic-gate #ifndef RES
755*7c478bd9Sstevel@tonic-gate 
756*7c478bd9Sstevel@tonic-gate 		if ((flags & rshflg) && eq(name, "SHELL"))
757*7c478bd9Sstevel@tonic-gate 			failed(name, restricted);
758*7c478bd9Sstevel@tonic-gate 
759*7c478bd9Sstevel@tonic-gate #endif
760*7c478bd9Sstevel@tonic-gate 
761*7c478bd9Sstevel@tonic-gate 		if (n->namflg & N_FUNCTN)
762*7c478bd9Sstevel@tonic-gate 		{
763*7c478bd9Sstevel@tonic-gate 			func_unhash(name);
764*7c478bd9Sstevel@tonic-gate 			freefunc(n);
765*7c478bd9Sstevel@tonic-gate 		}
766*7c478bd9Sstevel@tonic-gate 		else
767*7c478bd9Sstevel@tonic-gate 		{
768*7c478bd9Sstevel@tonic-gate 			call_dolocale++;
769*7c478bd9Sstevel@tonic-gate 			free(n->namval);
770*7c478bd9Sstevel@tonic-gate 			free(n->namenv);
771*7c478bd9Sstevel@tonic-gate 		}
772*7c478bd9Sstevel@tonic-gate 
773*7c478bd9Sstevel@tonic-gate 		n->namval = n->namenv = 0;
774*7c478bd9Sstevel@tonic-gate 		n->namflg = N_DEFAULT;
775*7c478bd9Sstevel@tonic-gate 
776*7c478bd9Sstevel@tonic-gate 		if (call_dolocale)
777*7c478bd9Sstevel@tonic-gate 			dolocale(name);
778*7c478bd9Sstevel@tonic-gate 
779*7c478bd9Sstevel@tonic-gate 		if (flags & prompt)
780*7c478bd9Sstevel@tonic-gate 		{
781*7c478bd9Sstevel@tonic-gate 			if (n == &mailpnod)
782*7c478bd9Sstevel@tonic-gate 				setmail(mailnod.namval);
783*7c478bd9Sstevel@tonic-gate 			else if (n == &mailnod && mailpnod.namflg == N_DEFAULT)
784*7c478bd9Sstevel@tonic-gate 				setmail(0);
785*7c478bd9Sstevel@tonic-gate 		}
786*7c478bd9Sstevel@tonic-gate 	}
787*7c478bd9Sstevel@tonic-gate }
788*7c478bd9Sstevel@tonic-gate 
789*7c478bd9Sstevel@tonic-gate /*
790*7c478bd9Sstevel@tonic-gate  * The environment variables which affect locale.
791*7c478bd9Sstevel@tonic-gate  * Note: if all names in this list do not begin with 'L',
792*7c478bd9Sstevel@tonic-gate  * you MUST modify dolocale().  Also, be sure that the
793*7c478bd9Sstevel@tonic-gate  * fake_env has the same number of elements as localevar.
794*7c478bd9Sstevel@tonic-gate  */
795*7c478bd9Sstevel@tonic-gate static char *localevar[] = {
796*7c478bd9Sstevel@tonic-gate 	"LC_ALL",
797*7c478bd9Sstevel@tonic-gate 	"LC_CTYPE",
798*7c478bd9Sstevel@tonic-gate 	"LC_MESSAGES",
799*7c478bd9Sstevel@tonic-gate 	"LANG",
800*7c478bd9Sstevel@tonic-gate 	0
801*7c478bd9Sstevel@tonic-gate };
802*7c478bd9Sstevel@tonic-gate 
803*7c478bd9Sstevel@tonic-gate static char *fake_env[] = {
804*7c478bd9Sstevel@tonic-gate 	0,
805*7c478bd9Sstevel@tonic-gate 	0,
806*7c478bd9Sstevel@tonic-gate 	0,
807*7c478bd9Sstevel@tonic-gate 	0,
808*7c478bd9Sstevel@tonic-gate 	0
809*7c478bd9Sstevel@tonic-gate };
810*7c478bd9Sstevel@tonic-gate 
811*7c478bd9Sstevel@tonic-gate /*
812*7c478bd9Sstevel@tonic-gate  * If name is one of several special variables which affect the locale,
813*7c478bd9Sstevel@tonic-gate  * do a setlocale().
814*7c478bd9Sstevel@tonic-gate  */
815*7c478bd9Sstevel@tonic-gate static void
816*7c478bd9Sstevel@tonic-gate dolocale(nm)
817*7c478bd9Sstevel@tonic-gate 	char *nm;
818*7c478bd9Sstevel@tonic-gate {
819*7c478bd9Sstevel@tonic-gate 	char **real_env;
820*7c478bd9Sstevel@tonic-gate 	struct namnod *n;
821*7c478bd9Sstevel@tonic-gate 	int lv, fe;
822*7c478bd9Sstevel@tonic-gate 	int i;
823*7c478bd9Sstevel@tonic-gate 
824*7c478bd9Sstevel@tonic-gate 	/*
825*7c478bd9Sstevel@tonic-gate 	 * Take advantage of fact that names of these vars all start
826*7c478bd9Sstevel@tonic-gate 	 * with 'L' to avoid unnecessary work.
827*7c478bd9Sstevel@tonic-gate 	 * Do locale processing only if /usr is mounted.
828*7c478bd9Sstevel@tonic-gate 	 */
829*7c478bd9Sstevel@tonic-gate 	if ((*nm != 'L') || !localedir_exists ||
830*7c478bd9Sstevel@tonic-gate 	    (!(eq(nm, "LC_ALL") || eq(nm, "LC_CTYPE") ||
831*7c478bd9Sstevel@tonic-gate 	    eq(nm, "LANG") || eq(nm, "LC_MESSAGES"))))
832*7c478bd9Sstevel@tonic-gate 		return;
833*7c478bd9Sstevel@tonic-gate 
834*7c478bd9Sstevel@tonic-gate 	/*
835*7c478bd9Sstevel@tonic-gate 	 * setlocale() has all the smarts built into it, but
836*7c478bd9Sstevel@tonic-gate 	 * it works by examining the environment.  Unfortunately,
837*7c478bd9Sstevel@tonic-gate 	 * when you set an environment variable, the shell does
838*7c478bd9Sstevel@tonic-gate 	 * not modify its own environment; it just remembers that the
839*7c478bd9Sstevel@tonic-gate 	 * variable needs to be exported to any children.  We hack around
840*7c478bd9Sstevel@tonic-gate 	 * this by consing up a fake environment for the use of setlocale()
841*7c478bd9Sstevel@tonic-gate 	 * and substituting it for the real env before calling setlocale().
842*7c478bd9Sstevel@tonic-gate 	 */
843*7c478bd9Sstevel@tonic-gate 
844*7c478bd9Sstevel@tonic-gate 	/*
845*7c478bd9Sstevel@tonic-gate 	 * Build the fake environment.
846*7c478bd9Sstevel@tonic-gate 	 * Look up the value of each of the special environment
847*7c478bd9Sstevel@tonic-gate 	 * variables, and put their value into the fake environment,
848*7c478bd9Sstevel@tonic-gate 	 * if they are exported.
849*7c478bd9Sstevel@tonic-gate 	 */
850*7c478bd9Sstevel@tonic-gate 	for (lv = 0, fe = 0; localevar[lv]; lv++) {
851*7c478bd9Sstevel@tonic-gate 		if ((n = findnam(localevar[lv]))) {
852*7c478bd9Sstevel@tonic-gate 			register char *p, *q;
853*7c478bd9Sstevel@tonic-gate 
854*7c478bd9Sstevel@tonic-gate 			if (!n->namval)
855*7c478bd9Sstevel@tonic-gate 				continue;
856*7c478bd9Sstevel@tonic-gate 
857*7c478bd9Sstevel@tonic-gate 			fake_env[fe++] = p = alloc(length(localevar[lv])
858*7c478bd9Sstevel@tonic-gate 					       + length(n->namval) + 2);
859*7c478bd9Sstevel@tonic-gate 			/* copy name */
860*7c478bd9Sstevel@tonic-gate 			q = localevar[lv];
861*7c478bd9Sstevel@tonic-gate 			while (*q)
862*7c478bd9Sstevel@tonic-gate 				*p++ = *q++;
863*7c478bd9Sstevel@tonic-gate 
864*7c478bd9Sstevel@tonic-gate 			*p++ = '=';
865*7c478bd9Sstevel@tonic-gate 
866*7c478bd9Sstevel@tonic-gate 			/* copy value */
867*7c478bd9Sstevel@tonic-gate 			q = (char*)(n->namval);
868*7c478bd9Sstevel@tonic-gate 			while (*q)
869*7c478bd9Sstevel@tonic-gate 				*p++ = *q++;
870*7c478bd9Sstevel@tonic-gate 			*p++ = '\0';
871*7c478bd9Sstevel@tonic-gate 		}
872*7c478bd9Sstevel@tonic-gate 	}
873*7c478bd9Sstevel@tonic-gate 	fake_env[fe] = (char *)0;
874*7c478bd9Sstevel@tonic-gate 
875*7c478bd9Sstevel@tonic-gate 	/*
876*7c478bd9Sstevel@tonic-gate 	 * Switch fake env for real and call setlocale().
877*7c478bd9Sstevel@tonic-gate 	 */
878*7c478bd9Sstevel@tonic-gate 	real_env = (char **)environ;
879*7c478bd9Sstevel@tonic-gate 	environ = (unsigned char **)fake_env;
880*7c478bd9Sstevel@tonic-gate 
881*7c478bd9Sstevel@tonic-gate 	if (setlocale(LC_ALL, "") == NULL)
882*7c478bd9Sstevel@tonic-gate 		prs("couldn't set locale correctly\n");
883*7c478bd9Sstevel@tonic-gate 
884*7c478bd9Sstevel@tonic-gate 	/*
885*7c478bd9Sstevel@tonic-gate 	 * Switch back and tear down the fake env.
886*7c478bd9Sstevel@tonic-gate 	 */
887*7c478bd9Sstevel@tonic-gate 	environ = (unsigned char **)real_env;
888*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < fe; i++) {
889*7c478bd9Sstevel@tonic-gate 		free(fake_env[i]);
890*7c478bd9Sstevel@tonic-gate 		fake_env[i] = (char *)0;
891*7c478bd9Sstevel@tonic-gate 	}
892*7c478bd9Sstevel@tonic-gate }
893