xref: /illumos-gate/usr/src/contrib/ast/src/cmd/ksh93/sh/init.c (revision b30d1939)
1*b30d1939SAndy Fiddaman /***********************************************************************
2*b30d1939SAndy Fiddaman *                                                                      *
3*b30d1939SAndy Fiddaman *               This software is part of the ast package               *
4*b30d1939SAndy Fiddaman *          Copyright (c) 1982-2012 AT&T Intellectual Property          *
5*b30d1939SAndy Fiddaman *                      and is licensed under the                       *
6*b30d1939SAndy Fiddaman *                 Eclipse Public License, Version 1.0                  *
7*b30d1939SAndy Fiddaman *                    by AT&T Intellectual Property                     *
8*b30d1939SAndy Fiddaman *                                                                      *
9*b30d1939SAndy Fiddaman *                A copy of the License is available at                 *
10*b30d1939SAndy Fiddaman *          http://www.eclipse.org/org/documents/epl-v10.html           *
11*b30d1939SAndy Fiddaman *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12*b30d1939SAndy Fiddaman *                                                                      *
13*b30d1939SAndy Fiddaman *              Information and Software Systems Research               *
14*b30d1939SAndy Fiddaman *                            AT&T Research                             *
15*b30d1939SAndy Fiddaman *                           Florham Park NJ                            *
16*b30d1939SAndy Fiddaman *                                                                      *
17*b30d1939SAndy Fiddaman *                  David Korn <dgk@research.att.com>                   *
18*b30d1939SAndy Fiddaman *                                                                      *
19*b30d1939SAndy Fiddaman ***********************************************************************/
20*b30d1939SAndy Fiddaman #pragma prototyped
21*b30d1939SAndy Fiddaman /*
22*b30d1939SAndy Fiddaman  *
23*b30d1939SAndy Fiddaman  * Shell initialization
24*b30d1939SAndy Fiddaman  *
25*b30d1939SAndy Fiddaman  *   David Korn
26*b30d1939SAndy Fiddaman  *   AT&T Labs
27*b30d1939SAndy Fiddaman  *
28*b30d1939SAndy Fiddaman  */
29*b30d1939SAndy Fiddaman 
30*b30d1939SAndy Fiddaman #include        "defs.h"
31*b30d1939SAndy Fiddaman #include        <stak.h>
32*b30d1939SAndy Fiddaman #include        <ccode.h>
33*b30d1939SAndy Fiddaman #include        <pwd.h>
34*b30d1939SAndy Fiddaman #include        <tmx.h>
35*b30d1939SAndy Fiddaman #include        <regex.h>
36*b30d1939SAndy Fiddaman #include        "variables.h"
37*b30d1939SAndy Fiddaman #include        "path.h"
38*b30d1939SAndy Fiddaman #include        "fault.h"
39*b30d1939SAndy Fiddaman #include        "name.h"
40*b30d1939SAndy Fiddaman #include	"edit.h"
41*b30d1939SAndy Fiddaman #include	"jobs.h"
42*b30d1939SAndy Fiddaman #include	"io.h"
43*b30d1939SAndy Fiddaman #include	"shlex.h"
44*b30d1939SAndy Fiddaman #include	"builtins.h"
45*b30d1939SAndy Fiddaman #include	"FEATURE/time"
46*b30d1939SAndy Fiddaman #include	"FEATURE/dynamic"
47*b30d1939SAndy Fiddaman #include	"FEATURE/externs"
48*b30d1939SAndy Fiddaman #include	"lexstates.h"
49*b30d1939SAndy Fiddaman #include	"version.h"
50*b30d1939SAndy Fiddaman 
51*b30d1939SAndy Fiddaman #if _hdr_wctype
52*b30d1939SAndy Fiddaman #include	<ast_wchar.h>
53*b30d1939SAndy Fiddaman #include	<wctype.h>
54*b30d1939SAndy Fiddaman #endif
55*b30d1939SAndy Fiddaman #if !_typ_wctrans_t
56*b30d1939SAndy Fiddaman #undef	wctrans_t
57*b30d1939SAndy Fiddaman #define wctrans_t	sh_wctrans_t
58*b30d1939SAndy Fiddaman typedef long wctrans_t;
59*b30d1939SAndy Fiddaman #endif
60*b30d1939SAndy Fiddaman #if !_lib_wctrans
61*b30d1939SAndy Fiddaman #undef	wctrans
62*b30d1939SAndy Fiddaman #define wctrans		sh_wctrans
wctrans(const char * name)63*b30d1939SAndy Fiddaman static wctrans_t wctrans(const char *name)
64*b30d1939SAndy Fiddaman {
65*b30d1939SAndy Fiddaman 	if(strcmp(name,e_tolower)==0)
66*b30d1939SAndy Fiddaman 		return(1);
67*b30d1939SAndy Fiddaman 	else if(strcmp(name,e_toupper)==0)
68*b30d1939SAndy Fiddaman 		return(2);
69*b30d1939SAndy Fiddaman 	return(0);
70*b30d1939SAndy Fiddaman }
71*b30d1939SAndy Fiddaman #endif
72*b30d1939SAndy Fiddaman #if !_lib_towctrans
73*b30d1939SAndy Fiddaman #undef	towctrans
74*b30d1939SAndy Fiddaman #define towctrans	sh_towctrans
towctrans(int c,wctrans_t t)75*b30d1939SAndy Fiddaman static int towctrans(int c, wctrans_t t)
76*b30d1939SAndy Fiddaman {
77*b30d1939SAndy Fiddaman 	if(t==1 && isupper(c))
78*b30d1939SAndy Fiddaman 		c = tolower(c);
79*b30d1939SAndy Fiddaman 	else if(t==2 && islower(c))
80*b30d1939SAndy Fiddaman 		c = toupper(c);
81*b30d1939SAndy Fiddaman 	return(c);
82*b30d1939SAndy Fiddaman }
83*b30d1939SAndy Fiddaman #endif
84*b30d1939SAndy Fiddaman 
85*b30d1939SAndy Fiddaman char e_version[]	= "\n@(#)$Id: Version "
86*b30d1939SAndy Fiddaman #if SHOPT_AUDIT
87*b30d1939SAndy Fiddaman #define ATTRS		1
88*b30d1939SAndy Fiddaman 			"A"
89*b30d1939SAndy Fiddaman #endif
90*b30d1939SAndy Fiddaman #if SHOPT_BASH
91*b30d1939SAndy Fiddaman #define ATTRS		1
92*b30d1939SAndy Fiddaman 			"B"
93*b30d1939SAndy Fiddaman #endif
94*b30d1939SAndy Fiddaman #if SHOPT_COSHELL
95*b30d1939SAndy Fiddaman #define ATTRS		1
96*b30d1939SAndy Fiddaman 			"J"
97*b30d1939SAndy Fiddaman #else
98*b30d1939SAndy Fiddaman #if SHOPT_BGX
99*b30d1939SAndy Fiddaman #define ATTRS		1
100*b30d1939SAndy Fiddaman 			"j"
101*b30d1939SAndy Fiddaman #endif
102*b30d1939SAndy Fiddaman #endif
103*b30d1939SAndy Fiddaman #if SHOPT_ACCT
104*b30d1939SAndy Fiddaman #define ATTRS		1
105*b30d1939SAndy Fiddaman 			"L"
106*b30d1939SAndy Fiddaman #endif
107*b30d1939SAndy Fiddaman #if SHOPT_MULTIBYTE
108*b30d1939SAndy Fiddaman #define ATTRS		1
109*b30d1939SAndy Fiddaman 			"M"
110*b30d1939SAndy Fiddaman #endif
111*b30d1939SAndy Fiddaman #if SHOPT_PFSH && _hdr_exec_attr
112*b30d1939SAndy Fiddaman #define ATTRS		1
113*b30d1939SAndy Fiddaman 			"P"
114*b30d1939SAndy Fiddaman #endif
115*b30d1939SAndy Fiddaman #if SHOPT_REGRESS
116*b30d1939SAndy Fiddaman #define ATTRS		1
117*b30d1939SAndy Fiddaman 			"R"
118*b30d1939SAndy Fiddaman #endif
119*b30d1939SAndy Fiddaman #if ATTRS
120*b30d1939SAndy Fiddaman 			" "
121*b30d1939SAndy Fiddaman #endif
122*b30d1939SAndy Fiddaman 			SH_RELEASE " $\0\n";
123*b30d1939SAndy Fiddaman 
124*b30d1939SAndy Fiddaman #if SHOPT_BASH
125*b30d1939SAndy Fiddaman     extern void bash_init(Shell_t*,int);
126*b30d1939SAndy Fiddaman #endif
127*b30d1939SAndy Fiddaman 
128*b30d1939SAndy Fiddaman #define RANDMASK	0x7fff
129*b30d1939SAndy Fiddaman 
130*b30d1939SAndy Fiddaman #ifndef ARG_MAX
131*b30d1939SAndy Fiddaman #   define ARG_MAX	(1*1024*1024)
132*b30d1939SAndy Fiddaman #endif
133*b30d1939SAndy Fiddaman #ifndef CHILD_MAX
134*b30d1939SAndy Fiddaman #   define CHILD_MAX	(1*1024)
135*b30d1939SAndy Fiddaman #endif
136*b30d1939SAndy Fiddaman #ifndef CLK_TCK
137*b30d1939SAndy Fiddaman #   define CLK_TCK	60
138*b30d1939SAndy Fiddaman #endif /* CLK_TCK */
139*b30d1939SAndy Fiddaman 
140*b30d1939SAndy Fiddaman #ifndef environ
141*b30d1939SAndy Fiddaman     extern char	**environ;
142*b30d1939SAndy Fiddaman #endif
143*b30d1939SAndy Fiddaman 
144*b30d1939SAndy Fiddaman #undef	getconf
145*b30d1939SAndy Fiddaman #define getconf(x)	strtol(astconf(x,NiL,NiL),NiL,0)
146*b30d1939SAndy Fiddaman 
147*b30d1939SAndy Fiddaman struct seconds
148*b30d1939SAndy Fiddaman {
149*b30d1939SAndy Fiddaman 	Namfun_t	hdr;
150*b30d1939SAndy Fiddaman 	Shell_t		*sh;
151*b30d1939SAndy Fiddaman };
152*b30d1939SAndy Fiddaman 
153*b30d1939SAndy Fiddaman struct rand
154*b30d1939SAndy Fiddaman {
155*b30d1939SAndy Fiddaman 	Namfun_t	hdr;
156*b30d1939SAndy Fiddaman 	Shell_t		*sh;
157*b30d1939SAndy Fiddaman 	int32_t		rand_last;
158*b30d1939SAndy Fiddaman };
159*b30d1939SAndy Fiddaman 
160*b30d1939SAndy Fiddaman struct ifs
161*b30d1939SAndy Fiddaman {
162*b30d1939SAndy Fiddaman 	Namfun_t	hdr;
163*b30d1939SAndy Fiddaman 	Namval_t	*ifsnp;
164*b30d1939SAndy Fiddaman };
165*b30d1939SAndy Fiddaman 
166*b30d1939SAndy Fiddaman struct match
167*b30d1939SAndy Fiddaman {
168*b30d1939SAndy Fiddaman 	Namfun_t	hdr;
169*b30d1939SAndy Fiddaman 	const char	*v;
170*b30d1939SAndy Fiddaman 	char		*val;
171*b30d1939SAndy Fiddaman 	char		*rval[2];
172*b30d1939SAndy Fiddaman 	regoff_t	*match;
173*b30d1939SAndy Fiddaman 	char		node[NV_MINSZ+sizeof(char*)];
174*b30d1939SAndy Fiddaman 	regoff_t	first;
175*b30d1939SAndy Fiddaman 	int		vsize;
176*b30d1939SAndy Fiddaman 	int		nmatch;
177*b30d1939SAndy Fiddaman 	int		index;
178*b30d1939SAndy Fiddaman 	int		lastsub[2];
179*b30d1939SAndy Fiddaman };
180*b30d1939SAndy Fiddaman 
181*b30d1939SAndy Fiddaman typedef struct _init_
182*b30d1939SAndy Fiddaman {
183*b30d1939SAndy Fiddaman 	Shell_t		*sh;
184*b30d1939SAndy Fiddaman #if SHOPT_FS_3D
185*b30d1939SAndy Fiddaman 	Namfun_t	VPATH_init;
186*b30d1939SAndy Fiddaman #endif /* SHOPT_FS_3D */
187*b30d1939SAndy Fiddaman 	struct ifs	IFS_init;
188*b30d1939SAndy Fiddaman 	Namfun_t	PATH_init;
189*b30d1939SAndy Fiddaman 	Namfun_t	FPATH_init;
190*b30d1939SAndy Fiddaman 	Namfun_t	CDPATH_init;
191*b30d1939SAndy Fiddaman 	Namfun_t	SHELL_init;
192*b30d1939SAndy Fiddaman 	Namfun_t	ENV_init;
193*b30d1939SAndy Fiddaman 	Namfun_t	VISUAL_init;
194*b30d1939SAndy Fiddaman 	Namfun_t	EDITOR_init;
195*b30d1939SAndy Fiddaman 	Namfun_t	HISTFILE_init;
196*b30d1939SAndy Fiddaman 	Namfun_t	HISTSIZE_init;
197*b30d1939SAndy Fiddaman 	Namfun_t	OPTINDEX_init;
198*b30d1939SAndy Fiddaman 	struct seconds	SECONDS_init;
199*b30d1939SAndy Fiddaman 	struct rand	RAND_init;
200*b30d1939SAndy Fiddaman 	Namfun_t	LINENO_init;
201*b30d1939SAndy Fiddaman 	Namfun_t	L_ARG_init;
202*b30d1939SAndy Fiddaman 	Namfun_t	SH_VERSION_init;
203*b30d1939SAndy Fiddaman 	struct match	SH_MATCH_init;
204*b30d1939SAndy Fiddaman 	Namfun_t	SH_MATH_init;
205*b30d1939SAndy Fiddaman #if SHOPT_COSHELL
206*b30d1939SAndy Fiddaman 	Namfun_t	SH_JOBPOOL_init;
207*b30d1939SAndy Fiddaman #endif /* SHOPT_COSHELL */
208*b30d1939SAndy Fiddaman #ifdef _hdr_locale
209*b30d1939SAndy Fiddaman 	Namfun_t	LC_TYPE_init;
210*b30d1939SAndy Fiddaman 	Namfun_t	LC_NUM_init;
211*b30d1939SAndy Fiddaman 	Namfun_t	LC_COLL_init;
212*b30d1939SAndy Fiddaman 	Namfun_t	LC_MSG_init;
213*b30d1939SAndy Fiddaman 	Namfun_t	LC_ALL_init;
214*b30d1939SAndy Fiddaman 	Namfun_t	LANG_init;
215*b30d1939SAndy Fiddaman #endif /* _hdr_locale */
216*b30d1939SAndy Fiddaman } Init_t;
217*b30d1939SAndy Fiddaman 
218*b30d1939SAndy Fiddaman static Init_t		*ip;
219*b30d1939SAndy Fiddaman static int		lctype;
220*b30d1939SAndy Fiddaman static int		nbltins;
221*b30d1939SAndy Fiddaman static void		env_init(Shell_t*);
222*b30d1939SAndy Fiddaman static Init_t		*nv_init(Shell_t*);
223*b30d1939SAndy Fiddaman static Dt_t		*inittree(Shell_t*,const struct shtable2*);
224*b30d1939SAndy Fiddaman static int		shlvl;
225*b30d1939SAndy Fiddaman 
226*b30d1939SAndy Fiddaman #ifdef _WINIX
227*b30d1939SAndy Fiddaman #   define EXE	"?(.exe)"
228*b30d1939SAndy Fiddaman #else
229*b30d1939SAndy Fiddaman #   define EXE
230*b30d1939SAndy Fiddaman #endif
231*b30d1939SAndy Fiddaman 
232*b30d1939SAndy Fiddaman static int		rand_shift;
233*b30d1939SAndy Fiddaman 
234*b30d1939SAndy Fiddaman 
235*b30d1939SAndy Fiddaman /*
236*b30d1939SAndy Fiddaman  * Invalidate all path name bindings
237*b30d1939SAndy Fiddaman  */
rehash(register Namval_t * np,void * data)238*b30d1939SAndy Fiddaman static void rehash(register Namval_t *np,void *data)
239*b30d1939SAndy Fiddaman {
240*b30d1939SAndy Fiddaman 	NOT_USED(data);
241*b30d1939SAndy Fiddaman 	nv_onattr(np,NV_NOALIAS);
242*b30d1939SAndy Fiddaman }
243*b30d1939SAndy Fiddaman 
244*b30d1939SAndy Fiddaman /*
245*b30d1939SAndy Fiddaman  * out of memory routine for stak routines
246*b30d1939SAndy Fiddaman  */
nospace(int unused)247*b30d1939SAndy Fiddaman static char *nospace(int unused)
248*b30d1939SAndy Fiddaman {
249*b30d1939SAndy Fiddaman 	NOT_USED(unused);
250*b30d1939SAndy Fiddaman 	errormsg(SH_DICT,ERROR_exit(3),e_nospace);
251*b30d1939SAndy Fiddaman 	return(NIL(char*));
252*b30d1939SAndy Fiddaman }
253*b30d1939SAndy Fiddaman 
254*b30d1939SAndy Fiddaman /* Trap for VISUAL and EDITOR variables */
put_ed(register Namval_t * np,const char * val,int flags,Namfun_t * fp)255*b30d1939SAndy Fiddaman static void put_ed(register Namval_t* np,const char *val,int flags,Namfun_t *fp)
256*b30d1939SAndy Fiddaman {
257*b30d1939SAndy Fiddaman 	register const char *cp, *name=nv_name(np);
258*b30d1939SAndy Fiddaman 	register int	newopt=0;
259*b30d1939SAndy Fiddaman 	Shell_t *shp = nv_shell(np);
260*b30d1939SAndy Fiddaman 	if(*name=='E' && nv_getval(sh_scoped(shp,VISINOD)))
261*b30d1939SAndy Fiddaman 		goto done;
262*b30d1939SAndy Fiddaman 	if(!(cp=val) && (*name=='E' || !(cp=nv_getval(sh_scoped(shp,EDITNOD)))))
263*b30d1939SAndy Fiddaman 		goto done;
264*b30d1939SAndy Fiddaman 	/* turn on vi or emacs option if editor name is either*/
265*b30d1939SAndy Fiddaman 	cp = path_basename(cp);
266*b30d1939SAndy Fiddaman 	if(strmatch(cp,"*[Vv][Ii]*"))
267*b30d1939SAndy Fiddaman 		newopt=SH_VI;
268*b30d1939SAndy Fiddaman 	else if(strmatch(cp,"*gmacs*"))
269*b30d1939SAndy Fiddaman 		newopt=SH_GMACS;
270*b30d1939SAndy Fiddaman 	else if(strmatch(cp,"*macs*"))
271*b30d1939SAndy Fiddaman 		newopt=SH_EMACS;
272*b30d1939SAndy Fiddaman 	if(newopt)
273*b30d1939SAndy Fiddaman 	{
274*b30d1939SAndy Fiddaman 		sh_offoption(SH_VI);
275*b30d1939SAndy Fiddaman 		sh_offoption(SH_EMACS);
276*b30d1939SAndy Fiddaman 		sh_offoption(SH_GMACS);
277*b30d1939SAndy Fiddaman 		sh_onoption(newopt);
278*b30d1939SAndy Fiddaman 	}
279*b30d1939SAndy Fiddaman done:
280*b30d1939SAndy Fiddaman 	nv_putv(np, val, flags, fp);
281*b30d1939SAndy Fiddaman }
282*b30d1939SAndy Fiddaman 
283*b30d1939SAndy Fiddaman /* Trap for HISTFILE and HISTSIZE variables */
put_history(register Namval_t * np,const char * val,int flags,Namfun_t * fp)284*b30d1939SAndy Fiddaman static void put_history(register Namval_t* np,const char *val,int flags,Namfun_t *fp)
285*b30d1939SAndy Fiddaman {
286*b30d1939SAndy Fiddaman 	Shell_t *shp = nv_shell(np);
287*b30d1939SAndy Fiddaman 	void 	*histopen = NULL;
288*b30d1939SAndy Fiddaman 	char	*cp;
289*b30d1939SAndy Fiddaman 	if( shp ) {
290*b30d1939SAndy Fiddaman 	    histopen = shp->gd->hist_ptr;
291*b30d1939SAndy Fiddaman 	}
292*b30d1939SAndy Fiddaman 	if(val && histopen)
293*b30d1939SAndy Fiddaman 	{
294*b30d1939SAndy Fiddaman 		if(np==HISTFILE && (cp=nv_getval(np)) && strcmp(val,cp)==0)
295*b30d1939SAndy Fiddaman 			return;
296*b30d1939SAndy Fiddaman 		if(np==HISTSIZE && sh_arith(shp,val)==nv_getnum(HISTSIZE))
297*b30d1939SAndy Fiddaman 			return;
298*b30d1939SAndy Fiddaman 		hist_close(shp->gd->hist_ptr);
299*b30d1939SAndy Fiddaman 	}
300*b30d1939SAndy Fiddaman 	nv_putv(np, val, flags, fp);
301*b30d1939SAndy Fiddaman 	if(histopen)
302*b30d1939SAndy Fiddaman 	{
303*b30d1939SAndy Fiddaman 		if(val)
304*b30d1939SAndy Fiddaman 			sh_histinit(shp);
305*b30d1939SAndy Fiddaman 		else
306*b30d1939SAndy Fiddaman 			hist_close(histopen);
307*b30d1939SAndy Fiddaman 	}
308*b30d1939SAndy Fiddaman }
309*b30d1939SAndy Fiddaman 
310*b30d1939SAndy Fiddaman /* Trap for OPTINDEX */
put_optindex(Namval_t * np,const char * val,int flags,Namfun_t * fp)311*b30d1939SAndy Fiddaman static void put_optindex(Namval_t* np,const char *val,int flags,Namfun_t *fp)
312*b30d1939SAndy Fiddaman {
313*b30d1939SAndy Fiddaman 	Shell_t *shp = nv_shell(np);
314*b30d1939SAndy Fiddaman 	shp->st.opterror = shp->st.optchar = 0;
315*b30d1939SAndy Fiddaman 	nv_putv(np, val, flags, fp);
316*b30d1939SAndy Fiddaman 	if(!val)
317*b30d1939SAndy Fiddaman 		nv_disc(np,fp,NV_POP);
318*b30d1939SAndy Fiddaman }
319*b30d1939SAndy Fiddaman 
nget_optindex(register Namval_t * np,Namfun_t * fp)320*b30d1939SAndy Fiddaman static Sfdouble_t nget_optindex(register Namval_t* np, Namfun_t *fp)
321*b30d1939SAndy Fiddaman {
322*b30d1939SAndy Fiddaman 	return((Sfdouble_t)*np->nvalue.lp);
323*b30d1939SAndy Fiddaman }
324*b30d1939SAndy Fiddaman 
clone_optindex(Namval_t * np,Namval_t * mp,int flags,Namfun_t * fp)325*b30d1939SAndy Fiddaman static Namfun_t *clone_optindex(Namval_t* np, Namval_t *mp, int flags, Namfun_t *fp)
326*b30d1939SAndy Fiddaman {
327*b30d1939SAndy Fiddaman 	Namfun_t *dp = (Namfun_t*)malloc(sizeof(Namfun_t));
328*b30d1939SAndy Fiddaman 	memcpy((void*)dp,(void*)fp,sizeof(Namfun_t));
329*b30d1939SAndy Fiddaman 	mp->nvalue.lp = np->nvalue.lp;
330*b30d1939SAndy Fiddaman 	dp->nofree = 0;
331*b30d1939SAndy Fiddaman 	return(dp);
332*b30d1939SAndy Fiddaman }
333*b30d1939SAndy Fiddaman 
334*b30d1939SAndy Fiddaman 
335*b30d1939SAndy Fiddaman /* Trap for restricted variables FPATH, PATH, SHELL, ENV */
put_restricted(register Namval_t * np,const char * val,int flags,Namfun_t * fp)336*b30d1939SAndy Fiddaman static void put_restricted(register Namval_t* np,const char *val,int flags,Namfun_t *fp)
337*b30d1939SAndy Fiddaman {
338*b30d1939SAndy Fiddaman 	Shell_t *shp = nv_shell(np);
339*b30d1939SAndy Fiddaman 	int	path_scoped = 0, fpath_scoped=0;
340*b30d1939SAndy Fiddaman 	Pathcomp_t *pp;
341*b30d1939SAndy Fiddaman 	char *name = nv_name(np);
342*b30d1939SAndy Fiddaman 	if(!(flags&NV_RDONLY) && sh_isoption(SH_RESTRICTED))
343*b30d1939SAndy Fiddaman 		errormsg(SH_DICT,ERROR_exit(1),e_restricted,nv_name(np));
344*b30d1939SAndy Fiddaman 	if(np==PATHNOD	|| (path_scoped=(strcmp(name,PATHNOD->nvname)==0)))
345*b30d1939SAndy Fiddaman 	{
346*b30d1939SAndy Fiddaman 		nv_scan(shp->track_tree,rehash,(void*)0,NV_TAGGED,NV_TAGGED);
347*b30d1939SAndy Fiddaman 		if(path_scoped && !val)
348*b30d1939SAndy Fiddaman 			val = PATHNOD->nvalue.cp;
349*b30d1939SAndy Fiddaman 	}
350*b30d1939SAndy Fiddaman 	if(val && !(flags&NV_RDONLY) && np->nvalue.cp && strcmp(val,np->nvalue.cp)==0)
351*b30d1939SAndy Fiddaman 		 return;
352*b30d1939SAndy Fiddaman 	if(np==FPATHNOD	|| (fpath_scoped=(strcmp(name,FPATHNOD->nvname)==0)))
353*b30d1939SAndy Fiddaman 		shp->pathlist = (void*)path_unsetfpath(shp);
354*b30d1939SAndy Fiddaman 	nv_putv(np, val, flags, fp);
355*b30d1939SAndy Fiddaman 	shp->universe = 0;
356*b30d1939SAndy Fiddaman 	if(shp->pathlist)
357*b30d1939SAndy Fiddaman 	{
358*b30d1939SAndy Fiddaman 		val = np->nvalue.cp;
359*b30d1939SAndy Fiddaman 		if(np==PATHNOD || path_scoped)
360*b30d1939SAndy Fiddaman 			pp = (void*)path_addpath(shp,(Pathcomp_t*)shp->pathlist,val,PATH_PATH);
361*b30d1939SAndy Fiddaman 		else if(val && (np==FPATHNOD || fpath_scoped))
362*b30d1939SAndy Fiddaman 			pp = (void*)path_addpath(shp,(Pathcomp_t*)shp->pathlist,val,PATH_FPATH);
363*b30d1939SAndy Fiddaman 		else
364*b30d1939SAndy Fiddaman 			return;
365*b30d1939SAndy Fiddaman 		if(shp->pathlist = (void*)pp)
366*b30d1939SAndy Fiddaman 			pp->shp = shp;
367*b30d1939SAndy Fiddaman 		if(!val && (flags&NV_NOSCOPE))
368*b30d1939SAndy Fiddaman 		{
369*b30d1939SAndy Fiddaman 			Namval_t *mp = dtsearch(shp->var_tree,np);
370*b30d1939SAndy Fiddaman 			if(mp && (val=nv_getval(mp)))
371*b30d1939SAndy Fiddaman 				nv_putval(mp,val,NV_RDONLY);
372*b30d1939SAndy Fiddaman 		}
373*b30d1939SAndy Fiddaman #if 0
374*b30d1939SAndy Fiddaman sfprintf(sfstderr,"%d: name=%s val=%s\n",getpid(),name,val);
375*b30d1939SAndy Fiddaman path_dump((Pathcomp_t*)shp->pathlist);
376*b30d1939SAndy Fiddaman #endif
377*b30d1939SAndy Fiddaman 	}
378*b30d1939SAndy Fiddaman }
379*b30d1939SAndy Fiddaman 
put_cdpath(register Namval_t * np,const char * val,int flags,Namfun_t * fp)380*b30d1939SAndy Fiddaman static void put_cdpath(register Namval_t* np,const char *val,int flags,Namfun_t *fp)
381*b30d1939SAndy Fiddaman {
382*b30d1939SAndy Fiddaman 	Pathcomp_t *pp;
383*b30d1939SAndy Fiddaman 	Shell_t *shp = nv_shell(np);
384*b30d1939SAndy Fiddaman 	nv_putv(np, val, flags, fp);
385*b30d1939SAndy Fiddaman 	if(!shp->cdpathlist)
386*b30d1939SAndy Fiddaman 		return;
387*b30d1939SAndy Fiddaman 	val = np->nvalue.cp;
388*b30d1939SAndy Fiddaman 	pp = (void*)path_addpath(shp,(Pathcomp_t*)shp->cdpathlist,val,PATH_CDPATH);
389*b30d1939SAndy Fiddaman 	if(shp->cdpathlist = (void*)pp)
390*b30d1939SAndy Fiddaman 		pp->shp = shp;
391*b30d1939SAndy Fiddaman }
392*b30d1939SAndy Fiddaman 
393*b30d1939SAndy Fiddaman #ifdef _hdr_locale
394*b30d1939SAndy Fiddaman     /*
395*b30d1939SAndy Fiddaman      * This function needs to be modified to handle international
396*b30d1939SAndy Fiddaman      * error message translations
397*b30d1939SAndy Fiddaman      */
398*b30d1939SAndy Fiddaman #if ERROR_VERSION >= 20000101L
msg_translate(const char * catalog,const char * message)399*b30d1939SAndy Fiddaman     static char* msg_translate(const char* catalog, const char* message)
400*b30d1939SAndy Fiddaman     {
401*b30d1939SAndy Fiddaman 	NOT_USED(catalog);
402*b30d1939SAndy Fiddaman 	return((char*)message);
403*b30d1939SAndy Fiddaman     }
404*b30d1939SAndy Fiddaman #else
msg_translate(const char * message,int type)405*b30d1939SAndy Fiddaman     static char* msg_translate(const char* message, int type)
406*b30d1939SAndy Fiddaman     {
407*b30d1939SAndy Fiddaman 	NOT_USED(type);
408*b30d1939SAndy Fiddaman 	return((char*)message);
409*b30d1939SAndy Fiddaman     }
410*b30d1939SAndy Fiddaman #endif
411*b30d1939SAndy Fiddaman 
412*b30d1939SAndy Fiddaman     /* Trap for LC_ALL, LC_CTYPE, LC_MESSAGES, LC_COLLATE and LANG */
put_lang(Namval_t * np,const char * val,int flags,Namfun_t * fp)413*b30d1939SAndy Fiddaman     static void put_lang(Namval_t* np,const char *val,int flags,Namfun_t *fp)
414*b30d1939SAndy Fiddaman     {
415*b30d1939SAndy Fiddaman 	Shell_t *shp = nv_shell(np);
416*b30d1939SAndy Fiddaman 	int type;
417*b30d1939SAndy Fiddaman 	char *name = nv_name(np);
418*b30d1939SAndy Fiddaman 	if(name==(LCALLNOD)->nvname)
419*b30d1939SAndy Fiddaman 		type = LC_ALL;
420*b30d1939SAndy Fiddaman 	else if(name==(LCTYPENOD)->nvname)
421*b30d1939SAndy Fiddaman 		type = LC_CTYPE;
422*b30d1939SAndy Fiddaman 	else if(name==(LCMSGNOD)->nvname)
423*b30d1939SAndy Fiddaman 		type = LC_MESSAGES;
424*b30d1939SAndy Fiddaman 	else if(name==(LCCOLLNOD)->nvname)
425*b30d1939SAndy Fiddaman 		type = LC_COLLATE;
426*b30d1939SAndy Fiddaman 	else if(name==(LCNUMNOD)->nvname)
427*b30d1939SAndy Fiddaman 		type = LC_NUMERIC;
428*b30d1939SAndy Fiddaman #ifdef LC_LANG
429*b30d1939SAndy Fiddaman 	else if(name==(LANGNOD)->nvname)
430*b30d1939SAndy Fiddaman 		type = LC_LANG;
431*b30d1939SAndy Fiddaman #else
432*b30d1939SAndy Fiddaman #define LC_LANG		LC_ALL
433*b30d1939SAndy Fiddaman 	else if(name==(LANGNOD)->nvname && (!(name=nv_getval(LCALLNOD)) || !*name))
434*b30d1939SAndy Fiddaman 		type = LC_LANG;
435*b30d1939SAndy Fiddaman #endif
436*b30d1939SAndy Fiddaman 	else
437*b30d1939SAndy Fiddaman 		type= -1;
438*b30d1939SAndy Fiddaman 	if(!sh_isstate(SH_INIT) && (type>=0 || type==LC_ALL || type==LC_LANG))
439*b30d1939SAndy Fiddaman 	{
440*b30d1939SAndy Fiddaman 		char*		r;
441*b30d1939SAndy Fiddaman #ifdef AST_LC_setenv
442*b30d1939SAndy Fiddaman 		ast.locale.set |= AST_LC_setenv;
443*b30d1939SAndy Fiddaman #endif
444*b30d1939SAndy Fiddaman 		r = setlocale(type,val?val:"");
445*b30d1939SAndy Fiddaman #ifdef AST_LC_setenv
446*b30d1939SAndy Fiddaman 		ast.locale.set ^= AST_LC_setenv;
447*b30d1939SAndy Fiddaman #endif
448*b30d1939SAndy Fiddaman 		if(!r && val)
449*b30d1939SAndy Fiddaman 		{
450*b30d1939SAndy Fiddaman 			if(!sh_isstate(SH_INIT) || shp->login_sh==0)
451*b30d1939SAndy Fiddaman 				errormsg(SH_DICT,0,e_badlocale,val);
452*b30d1939SAndy Fiddaman 			return;
453*b30d1939SAndy Fiddaman 		}
454*b30d1939SAndy Fiddaman 	}
455*b30d1939SAndy Fiddaman 	nv_putv(np, val, flags, fp);
456*b30d1939SAndy Fiddaman 	if(CC_NATIVE!=CC_ASCII && (type==LC_ALL || type==LC_LANG || type==LC_CTYPE))
457*b30d1939SAndy Fiddaman 	{
458*b30d1939SAndy Fiddaman 		if(sh_lexstates[ST_BEGIN]!=sh_lexrstates[ST_BEGIN])
459*b30d1939SAndy Fiddaman 			free((void*)sh_lexstates[ST_BEGIN]);
460*b30d1939SAndy Fiddaman 		lctype++;
461*b30d1939SAndy Fiddaman 		if(ast.locale.set&(1<<AST_LC_CTYPE))
462*b30d1939SAndy Fiddaman 		{
463*b30d1939SAndy Fiddaman 			register int c;
464*b30d1939SAndy Fiddaman 			char *state[4];
465*b30d1939SAndy Fiddaman 			sh_lexstates[ST_BEGIN] = state[0] = (char*)malloc(4*(1<<CHAR_BIT));
466*b30d1939SAndy Fiddaman 			memcpy(state[0],sh_lexrstates[ST_BEGIN],(1<<CHAR_BIT));
467*b30d1939SAndy Fiddaman 			sh_lexstates[ST_NAME] = state[1] = state[0] + (1<<CHAR_BIT);
468*b30d1939SAndy Fiddaman 			memcpy(state[1],sh_lexrstates[ST_NAME],(1<<CHAR_BIT));
469*b30d1939SAndy Fiddaman 			sh_lexstates[ST_DOL] = state[2] = state[1] + (1<<CHAR_BIT);
470*b30d1939SAndy Fiddaman 			memcpy(state[2],sh_lexrstates[ST_DOL],(1<<CHAR_BIT));
471*b30d1939SAndy Fiddaman 			sh_lexstates[ST_BRACE] = state[3] = state[2] + (1<<CHAR_BIT);
472*b30d1939SAndy Fiddaman 			memcpy(state[3],sh_lexrstates[ST_BRACE],(1<<CHAR_BIT));
473*b30d1939SAndy Fiddaman 			for(c=0; c<(1<<CHAR_BIT); c++)
474*b30d1939SAndy Fiddaman 			{
475*b30d1939SAndy Fiddaman 				if(state[0][c]!=S_REG)
476*b30d1939SAndy Fiddaman 					continue;
477*b30d1939SAndy Fiddaman 				if(state[2][c]!=S_ERR)
478*b30d1939SAndy Fiddaman 					continue;
479*b30d1939SAndy Fiddaman 				if(isblank(c))
480*b30d1939SAndy Fiddaman 				{
481*b30d1939SAndy Fiddaman 					state[0][c]=0;
482*b30d1939SAndy Fiddaman 					state[1][c]=S_BREAK;
483*b30d1939SAndy Fiddaman 					state[2][c]=S_BREAK;
484*b30d1939SAndy Fiddaman 					continue;
485*b30d1939SAndy Fiddaman 				}
486*b30d1939SAndy Fiddaman 				if(!isalpha(c))
487*b30d1939SAndy Fiddaman 					continue;
488*b30d1939SAndy Fiddaman 				state[0][c]=S_NAME;
489*b30d1939SAndy Fiddaman 				if(state[1][c]==S_REG)
490*b30d1939SAndy Fiddaman 					state[1][c]=0;
491*b30d1939SAndy Fiddaman 				state[2][c]=S_ALP;
492*b30d1939SAndy Fiddaman 				if(state[3][c]==S_ERR)
493*b30d1939SAndy Fiddaman 					state[3][c]=0;
494*b30d1939SAndy Fiddaman 			}
495*b30d1939SAndy Fiddaman 		}
496*b30d1939SAndy Fiddaman 		else
497*b30d1939SAndy Fiddaman 		{
498*b30d1939SAndy Fiddaman 			sh_lexstates[ST_BEGIN]=(char*)sh_lexrstates[ST_BEGIN];
499*b30d1939SAndy Fiddaman 			sh_lexstates[ST_NAME]=(char*)sh_lexrstates[ST_NAME];
500*b30d1939SAndy Fiddaman 			sh_lexstates[ST_DOL]=(char*)sh_lexrstates[ST_DOL];
501*b30d1939SAndy Fiddaman 			sh_lexstates[ST_BRACE]=(char*)sh_lexrstates[ST_BRACE];
502*b30d1939SAndy Fiddaman 		}
503*b30d1939SAndy Fiddaman 	}
504*b30d1939SAndy Fiddaman #if ERROR_VERSION < 20000101L
505*b30d1939SAndy Fiddaman 	if(type==LC_ALL || type==LC_MESSAGES)
506*b30d1939SAndy Fiddaman 		error_info.translate = msg_translate;
507*b30d1939SAndy Fiddaman #endif
508*b30d1939SAndy Fiddaman     }
509*b30d1939SAndy Fiddaman #endif /* _hdr_locale */
510*b30d1939SAndy Fiddaman 
511*b30d1939SAndy Fiddaman /* Trap for IFS assignment and invalidates state table */
put_ifs(register Namval_t * np,const char * val,int flags,Namfun_t * fp)512*b30d1939SAndy Fiddaman static void put_ifs(register Namval_t* np,const char *val,int flags,Namfun_t *fp)
513*b30d1939SAndy Fiddaman {
514*b30d1939SAndy Fiddaman 	register struct ifs *ip = (struct ifs*)fp;
515*b30d1939SAndy Fiddaman 	ip->ifsnp = 0;
516*b30d1939SAndy Fiddaman 	if(!val)
517*b30d1939SAndy Fiddaman 	{
518*b30d1939SAndy Fiddaman 		fp = nv_stack(np, NIL(Namfun_t*));
519*b30d1939SAndy Fiddaman 		if(fp && !fp->nofree)
520*b30d1939SAndy Fiddaman 		{
521*b30d1939SAndy Fiddaman 			free((void*)fp);
522*b30d1939SAndy Fiddaman 			fp = 0;
523*b30d1939SAndy Fiddaman 		}
524*b30d1939SAndy Fiddaman 	}
525*b30d1939SAndy Fiddaman 	if(val != np->nvalue.cp)
526*b30d1939SAndy Fiddaman 		nv_putv(np, val, flags, fp);
527*b30d1939SAndy Fiddaman 	if(!val)
528*b30d1939SAndy Fiddaman 	{
529*b30d1939SAndy Fiddaman 		if(fp)
530*b30d1939SAndy Fiddaman 			fp->next = np->nvfun;
531*b30d1939SAndy Fiddaman 		np->nvfun = fp;
532*b30d1939SAndy Fiddaman 	}
533*b30d1939SAndy Fiddaman }
534*b30d1939SAndy Fiddaman 
535*b30d1939SAndy Fiddaman /*
536*b30d1939SAndy Fiddaman  * This is the lookup function for IFS
537*b30d1939SAndy Fiddaman  * It keeps the sh.ifstable up to date
538*b30d1939SAndy Fiddaman  */
get_ifs(register Namval_t * np,Namfun_t * fp)539*b30d1939SAndy Fiddaman static char* get_ifs(register Namval_t* np, Namfun_t *fp)
540*b30d1939SAndy Fiddaman {
541*b30d1939SAndy Fiddaman 	register struct ifs *ip = (struct ifs*)fp;
542*b30d1939SAndy Fiddaman 	register char *cp, *value;
543*b30d1939SAndy Fiddaman 	register int c,n;
544*b30d1939SAndy Fiddaman 	register Shell_t *shp = nv_shell(np);
545*b30d1939SAndy Fiddaman 	value = nv_getv(np,fp);
546*b30d1939SAndy Fiddaman 	if(np!=ip->ifsnp)
547*b30d1939SAndy Fiddaman 	{
548*b30d1939SAndy Fiddaman 		ip->ifsnp = np;
549*b30d1939SAndy Fiddaman 		memset(shp->ifstable,0,(1<<CHAR_BIT));
550*b30d1939SAndy Fiddaman 		if(cp=value)
551*b30d1939SAndy Fiddaman 		{
552*b30d1939SAndy Fiddaman #if SHOPT_MULTIBYTE
553*b30d1939SAndy Fiddaman 			while(n=mbsize(cp),c= *(unsigned char*)cp)
554*b30d1939SAndy Fiddaman #else
555*b30d1939SAndy Fiddaman 			while(c= *(unsigned char*)cp++)
556*b30d1939SAndy Fiddaman #endif /* SHOPT_MULTIBYTE */
557*b30d1939SAndy Fiddaman 			{
558*b30d1939SAndy Fiddaman #if SHOPT_MULTIBYTE
559*b30d1939SAndy Fiddaman 				cp++;
560*b30d1939SAndy Fiddaman 				if(n>1)
561*b30d1939SAndy Fiddaman 				{
562*b30d1939SAndy Fiddaman 					cp += (n-1);
563*b30d1939SAndy Fiddaman 					shp->ifstable[c] = S_MBYTE;
564*b30d1939SAndy Fiddaman 					continue;
565*b30d1939SAndy Fiddaman 				}
566*b30d1939SAndy Fiddaman #endif /* SHOPT_MULTIBYTE */
567*b30d1939SAndy Fiddaman 				n = S_DELIM;
568*b30d1939SAndy Fiddaman 				if(c== *cp)
569*b30d1939SAndy Fiddaman 					cp++;
570*b30d1939SAndy Fiddaman 				else if(c=='\n')
571*b30d1939SAndy Fiddaman 					n = S_NL;
572*b30d1939SAndy Fiddaman 				else if(isspace(c))
573*b30d1939SAndy Fiddaman 					n = S_SPACE;
574*b30d1939SAndy Fiddaman 				shp->ifstable[c] = n;
575*b30d1939SAndy Fiddaman 			}
576*b30d1939SAndy Fiddaman 		}
577*b30d1939SAndy Fiddaman 		else
578*b30d1939SAndy Fiddaman 		{
579*b30d1939SAndy Fiddaman 			shp->ifstable[' '] = shp->ifstable['\t'] = S_SPACE;
580*b30d1939SAndy Fiddaman 			shp->ifstable['\n'] = S_NL;
581*b30d1939SAndy Fiddaman 		}
582*b30d1939SAndy Fiddaman 	}
583*b30d1939SAndy Fiddaman 	return(value);
584*b30d1939SAndy Fiddaman }
585*b30d1939SAndy Fiddaman 
586*b30d1939SAndy Fiddaman /*
587*b30d1939SAndy Fiddaman  * these functions are used to get and set the SECONDS variable
588*b30d1939SAndy Fiddaman  */
589*b30d1939SAndy Fiddaman #ifdef timeofday
590*b30d1939SAndy Fiddaman #   define dtime(tp) ((double)((tp)->tv_sec)+1e-6*((double)((tp)->tv_usec)))
591*b30d1939SAndy Fiddaman #   define tms	timeval
592*b30d1939SAndy Fiddaman #else
593*b30d1939SAndy Fiddaman #   define dtime(tp)	(((double)times(tp))/shgd->lim.clk_tck)
594*b30d1939SAndy Fiddaman #   define timeofday(a)
595*b30d1939SAndy Fiddaman #endif
596*b30d1939SAndy Fiddaman 
put_seconds(register Namval_t * np,const char * val,int flags,Namfun_t * fp)597*b30d1939SAndy Fiddaman static void put_seconds(register Namval_t* np,const char *val,int flags,Namfun_t *fp)
598*b30d1939SAndy Fiddaman {
599*b30d1939SAndy Fiddaman 	double d;
600*b30d1939SAndy Fiddaman 	struct tms tp;
601*b30d1939SAndy Fiddaman 	if(!val)
602*b30d1939SAndy Fiddaman 	{
603*b30d1939SAndy Fiddaman 		nv_putv(np, val, flags, fp);
604*b30d1939SAndy Fiddaman 		fp = nv_stack(np, NIL(Namfun_t*));
605*b30d1939SAndy Fiddaman 		if(fp && !fp->nofree)
606*b30d1939SAndy Fiddaman 			free((void*)fp);
607*b30d1939SAndy Fiddaman 		return;
608*b30d1939SAndy Fiddaman 	}
609*b30d1939SAndy Fiddaman 	if(!np->nvalue.dp)
610*b30d1939SAndy Fiddaman 	{
611*b30d1939SAndy Fiddaman 		nv_setsize(np,3);
612*b30d1939SAndy Fiddaman 		nv_onattr(np,NV_DOUBLE);
613*b30d1939SAndy Fiddaman 		np->nvalue.dp = new_of(double,0);
614*b30d1939SAndy Fiddaman 	}
615*b30d1939SAndy Fiddaman 	nv_putv(np, val, flags, fp);
616*b30d1939SAndy Fiddaman 	d = *np->nvalue.dp;
617*b30d1939SAndy Fiddaman 	timeofday(&tp);
618*b30d1939SAndy Fiddaman 	*np->nvalue.dp = dtime(&tp)-d;
619*b30d1939SAndy Fiddaman }
620*b30d1939SAndy Fiddaman 
get_seconds(register Namval_t * np,Namfun_t * fp)621*b30d1939SAndy Fiddaman static char* get_seconds(register Namval_t* np, Namfun_t *fp)
622*b30d1939SAndy Fiddaman {
623*b30d1939SAndy Fiddaman 	Shell_t *shp = nv_shell(np);
624*b30d1939SAndy Fiddaman 	register int places = nv_size(np);
625*b30d1939SAndy Fiddaman 	struct tms tp;
626*b30d1939SAndy Fiddaman 	double d, offset = (np->nvalue.dp?*np->nvalue.dp:0);
627*b30d1939SAndy Fiddaman 	NOT_USED(fp);
628*b30d1939SAndy Fiddaman 	timeofday(&tp);
629*b30d1939SAndy Fiddaman 	d = dtime(&tp)- offset;
630*b30d1939SAndy Fiddaman 	sfprintf(shp->strbuf,"%.*f",places,d);
631*b30d1939SAndy Fiddaman 	return(sfstruse(shp->strbuf));
632*b30d1939SAndy Fiddaman }
633*b30d1939SAndy Fiddaman 
nget_seconds(register Namval_t * np,Namfun_t * fp)634*b30d1939SAndy Fiddaman static Sfdouble_t nget_seconds(register Namval_t* np, Namfun_t *fp)
635*b30d1939SAndy Fiddaman {
636*b30d1939SAndy Fiddaman 	struct tms tp;
637*b30d1939SAndy Fiddaman 	double offset = (np->nvalue.dp?*np->nvalue.dp:0);
638*b30d1939SAndy Fiddaman 	NOT_USED(fp);
639*b30d1939SAndy Fiddaman 	timeofday(&tp);
640*b30d1939SAndy Fiddaman 	return(dtime(&tp)- offset);
641*b30d1939SAndy Fiddaman }
642*b30d1939SAndy Fiddaman 
643*b30d1939SAndy Fiddaman /*
644*b30d1939SAndy Fiddaman  * These three functions are used to get and set the RANDOM variable
645*b30d1939SAndy Fiddaman  */
put_rand(register Namval_t * np,const char * val,int flags,Namfun_t * fp)646*b30d1939SAndy Fiddaman static void put_rand(register Namval_t* np,const char *val,int flags,Namfun_t *fp)
647*b30d1939SAndy Fiddaman {
648*b30d1939SAndy Fiddaman 	struct rand *rp = (struct rand*)fp;
649*b30d1939SAndy Fiddaman 	register long n;
650*b30d1939SAndy Fiddaman 	if(!val)
651*b30d1939SAndy Fiddaman 	{
652*b30d1939SAndy Fiddaman 		fp = nv_stack(np, NIL(Namfun_t*));
653*b30d1939SAndy Fiddaman 		if(fp && !fp->nofree)
654*b30d1939SAndy Fiddaman 			free((void*)fp);
655*b30d1939SAndy Fiddaman 		_nv_unset(np,0);
656*b30d1939SAndy Fiddaman 		return;
657*b30d1939SAndy Fiddaman 	}
658*b30d1939SAndy Fiddaman 	if(flags&NV_INTEGER)
659*b30d1939SAndy Fiddaman 		n = *(double*)val;
660*b30d1939SAndy Fiddaman 	else
661*b30d1939SAndy Fiddaman 		n = sh_arith(rp->sh,val);
662*b30d1939SAndy Fiddaman 	srand((int)(n&RANDMASK));
663*b30d1939SAndy Fiddaman 	rp->rand_last = -1;
664*b30d1939SAndy Fiddaman 	if(!np->nvalue.lp)
665*b30d1939SAndy Fiddaman 		np->nvalue.lp = &rp->rand_last;
666*b30d1939SAndy Fiddaman }
667*b30d1939SAndy Fiddaman 
668*b30d1939SAndy Fiddaman /*
669*b30d1939SAndy Fiddaman  * get random number in range of 0 - 2**15
670*b30d1939SAndy Fiddaman  * never pick same number twice in a row
671*b30d1939SAndy Fiddaman  */
nget_rand(register Namval_t * np,Namfun_t * fp)672*b30d1939SAndy Fiddaman static Sfdouble_t nget_rand(register Namval_t* np, Namfun_t *fp)
673*b30d1939SAndy Fiddaman {
674*b30d1939SAndy Fiddaman 	register long cur, last= *np->nvalue.lp;
675*b30d1939SAndy Fiddaman 	NOT_USED(fp);
676*b30d1939SAndy Fiddaman 	do
677*b30d1939SAndy Fiddaman 		cur = (rand()>>rand_shift)&RANDMASK;
678*b30d1939SAndy Fiddaman 	while(cur==last);
679*b30d1939SAndy Fiddaman 	*np->nvalue.lp = cur;
680*b30d1939SAndy Fiddaman 	return((Sfdouble_t)cur);
681*b30d1939SAndy Fiddaman }
682*b30d1939SAndy Fiddaman 
get_rand(register Namval_t * np,Namfun_t * fp)683*b30d1939SAndy Fiddaman static char* get_rand(register Namval_t* np, Namfun_t *fp)
684*b30d1939SAndy Fiddaman {
685*b30d1939SAndy Fiddaman 	register long n = nget_rand(np,fp);
686*b30d1939SAndy Fiddaman 	return(fmtbase(n, 10, 0));
687*b30d1939SAndy Fiddaman }
688*b30d1939SAndy Fiddaman 
689*b30d1939SAndy Fiddaman /*
690*b30d1939SAndy Fiddaman  * These three routines are for LINENO
691*b30d1939SAndy Fiddaman  */
nget_lineno(Namval_t * np,Namfun_t * fp)692*b30d1939SAndy Fiddaman static Sfdouble_t nget_lineno(Namval_t* np, Namfun_t *fp)
693*b30d1939SAndy Fiddaman {
694*b30d1939SAndy Fiddaman 	double d=1;
695*b30d1939SAndy Fiddaman 	if(error_info.line >0)
696*b30d1939SAndy Fiddaman 		d = error_info.line;
697*b30d1939SAndy Fiddaman 	else if(error_info.context && error_info.context->line>0)
698*b30d1939SAndy Fiddaman 		d = error_info.context->line;
699*b30d1939SAndy Fiddaman 	NOT_USED(np);
700*b30d1939SAndy Fiddaman 	NOT_USED(fp);
701*b30d1939SAndy Fiddaman 	return(d);
702*b30d1939SAndy Fiddaman }
703*b30d1939SAndy Fiddaman 
put_lineno(Namval_t * np,const char * val,int flags,Namfun_t * fp)704*b30d1939SAndy Fiddaman static void put_lineno(Namval_t* np,const char *val,int flags,Namfun_t *fp)
705*b30d1939SAndy Fiddaman {
706*b30d1939SAndy Fiddaman 	register long n;
707*b30d1939SAndy Fiddaman 	Shell_t *shp = nv_shell(np);
708*b30d1939SAndy Fiddaman 	if(!val)
709*b30d1939SAndy Fiddaman 	{
710*b30d1939SAndy Fiddaman 		fp = nv_stack(np, NIL(Namfun_t*));
711*b30d1939SAndy Fiddaman 		if(fp && !fp->nofree)
712*b30d1939SAndy Fiddaman 			free((void*)fp);
713*b30d1939SAndy Fiddaman 		_nv_unset(np,0);
714*b30d1939SAndy Fiddaman 		return;
715*b30d1939SAndy Fiddaman 	}
716*b30d1939SAndy Fiddaman 	if(flags&NV_INTEGER)
717*b30d1939SAndy Fiddaman 		n = *(double*)val;
718*b30d1939SAndy Fiddaman 	else
719*b30d1939SAndy Fiddaman 		n = sh_arith(shp,val);
720*b30d1939SAndy Fiddaman 	shp->st.firstline += nget_lineno(np,fp)+1-n;
721*b30d1939SAndy Fiddaman }
722*b30d1939SAndy Fiddaman 
get_lineno(register Namval_t * np,Namfun_t * fp)723*b30d1939SAndy Fiddaman static char* get_lineno(register Namval_t* np, Namfun_t *fp)
724*b30d1939SAndy Fiddaman {
725*b30d1939SAndy Fiddaman 	register long n = nget_lineno(np,fp);
726*b30d1939SAndy Fiddaman 	return(fmtbase(n, 10, 0));
727*b30d1939SAndy Fiddaman }
728*b30d1939SAndy Fiddaman 
get_lastarg(Namval_t * np,Namfun_t * fp)729*b30d1939SAndy Fiddaman static char* get_lastarg(Namval_t* np, Namfun_t *fp)
730*b30d1939SAndy Fiddaman {
731*b30d1939SAndy Fiddaman 	Shell_t	*shp = nv_shell(np);
732*b30d1939SAndy Fiddaman 	char	*cp;
733*b30d1939SAndy Fiddaman 	int	pid;
734*b30d1939SAndy Fiddaman         if(sh_isstate(SH_INIT) && (cp=shp->lastarg) && *cp=='*' && (pid=strtol(cp+1,&cp,10)) && *cp=='*')
735*b30d1939SAndy Fiddaman 		nv_putval(np,cp+1,0);
736*b30d1939SAndy Fiddaman 	return(shp->lastarg);
737*b30d1939SAndy Fiddaman }
738*b30d1939SAndy Fiddaman 
put_lastarg(Namval_t * np,const char * val,int flags,Namfun_t * fp)739*b30d1939SAndy Fiddaman static void put_lastarg(Namval_t* np,const char *val,int flags,Namfun_t *fp)
740*b30d1939SAndy Fiddaman {
741*b30d1939SAndy Fiddaman 	Shell_t *shp = nv_shell(np);
742*b30d1939SAndy Fiddaman 	if(flags&NV_INTEGER)
743*b30d1939SAndy Fiddaman 	{
744*b30d1939SAndy Fiddaman 		sfprintf(shp->strbuf,"%.*g",12,*((double*)val));
745*b30d1939SAndy Fiddaman 		val = sfstruse(shp->strbuf);
746*b30d1939SAndy Fiddaman 	}
747*b30d1939SAndy Fiddaman 	if(val)
748*b30d1939SAndy Fiddaman 		val = strdup(val);
749*b30d1939SAndy Fiddaman 	if(shp->lastarg && !nv_isattr(np,NV_NOFREE))
750*b30d1939SAndy Fiddaman 		free((void*)shp->lastarg);
751*b30d1939SAndy Fiddaman 	else
752*b30d1939SAndy Fiddaman 		nv_offattr(np,NV_NOFREE);
753*b30d1939SAndy Fiddaman 	shp->lastarg = (char*)val;
754*b30d1939SAndy Fiddaman 	nv_offattr(np,NV_EXPORT);
755*b30d1939SAndy Fiddaman 	np->nvenv = 0;
756*b30d1939SAndy Fiddaman }
757*b30d1939SAndy Fiddaman 
hasgetdisc(register Namfun_t * fp)758*b30d1939SAndy Fiddaman static int hasgetdisc(register Namfun_t *fp)
759*b30d1939SAndy Fiddaman {
760*b30d1939SAndy Fiddaman         while(fp && !fp->disc->getnum && !fp->disc->getval)
761*b30d1939SAndy Fiddaman                 fp = fp->next;
762*b30d1939SAndy Fiddaman 	return(fp!=0);
763*b30d1939SAndy Fiddaman }
764*b30d1939SAndy Fiddaman 
765*b30d1939SAndy Fiddaman /*
766*b30d1939SAndy Fiddaman  * store the most recent value for use in .sh.match
767*b30d1939SAndy Fiddaman  * treat .sh.match as a two dimensional array
768*b30d1939SAndy Fiddaman  */
sh_setmatch(Shell_t * shp,const char * v,int vsize,int nmatch,regoff_t match[],int index)769*b30d1939SAndy Fiddaman void sh_setmatch(Shell_t *shp,const char *v, int vsize, int nmatch, regoff_t match[],int index)
770*b30d1939SAndy Fiddaman {
771*b30d1939SAndy Fiddaman 	struct match	*mp = &ip->SH_MATCH_init;
772*b30d1939SAndy Fiddaman 	Namval_t	*np = nv_namptr(mp->node,0);
773*b30d1939SAndy Fiddaman 	register int	i,n,x, savesub=shp->subshell;
774*b30d1939SAndy Fiddaman 	Namarr_t	*ap = nv_arrayptr(SH_MATCHNOD);
775*b30d1939SAndy Fiddaman 	shp->subshell = 0;
776*b30d1939SAndy Fiddaman #ifndef SHOPT_2DMATCH
777*b30d1939SAndy Fiddaman 	index = 0;
778*b30d1939SAndy Fiddaman #else
779*b30d1939SAndy Fiddaman 	if(index==0)
780*b30d1939SAndy Fiddaman #endif /* SHOPT_2DMATCH */
781*b30d1939SAndy Fiddaman 	{
782*b30d1939SAndy Fiddaman 		if(ap->hdr.next != &mp->hdr)
783*b30d1939SAndy Fiddaman 		{
784*b30d1939SAndy Fiddaman 			free((void*)ap);
785*b30d1939SAndy Fiddaman 			ap = nv_arrayptr(np);
786*b30d1939SAndy Fiddaman 			SH_MATCHNOD->nvfun = &ap->hdr;
787*b30d1939SAndy Fiddaman 		}
788*b30d1939SAndy Fiddaman 		if(ap)
789*b30d1939SAndy Fiddaman 		{
790*b30d1939SAndy Fiddaman 			ap->nelem &= ~ARRAY_SCAN;
791*b30d1939SAndy Fiddaman 			i = array_elem(ap);
792*b30d1939SAndy Fiddaman 			ap->nelem++;
793*b30d1939SAndy Fiddaman 			while(--i>= 0)
794*b30d1939SAndy Fiddaman 			{
795*b30d1939SAndy Fiddaman 				nv_putsub(SH_MATCHNOD, (char*)0,i);
796*b30d1939SAndy Fiddaman 				_nv_unset(SH_MATCHNOD,NV_RDONLY);
797*b30d1939SAndy Fiddaman 			}
798*b30d1939SAndy Fiddaman 			ap->nelem--;
799*b30d1939SAndy Fiddaman 		}
800*b30d1939SAndy Fiddaman 		if(!nv_hasdisc(SH_MATCHNOD,mp->hdr.disc))
801*b30d1939SAndy Fiddaman 			nv_disc(SH_MATCHNOD,&mp->hdr,NV_LAST);
802*b30d1939SAndy Fiddaman 		if(nmatch)
803*b30d1939SAndy Fiddaman 			nv_putsub(SH_MATCHNOD, NIL(char*), (nmatch-1)|ARRAY_FILL|ARRAY_SETSUB);
804*b30d1939SAndy Fiddaman 		ap = nv_arrayptr(SH_MATCHNOD);
805*b30d1939SAndy Fiddaman 		ap->nelem = mp->nmatch = nmatch;
806*b30d1939SAndy Fiddaman 		mp->v = v;
807*b30d1939SAndy Fiddaman 		mp->first = match[0];
808*b30d1939SAndy Fiddaman 	}
809*b30d1939SAndy Fiddaman #ifdef SHOPT_2DMATCH
810*b30d1939SAndy Fiddaman 	else
811*b30d1939SAndy Fiddaman 	{
812*b30d1939SAndy Fiddaman 		if(index==1)
813*b30d1939SAndy Fiddaman 		{
814*b30d1939SAndy Fiddaman 			np->nvalue.cp = Empty;
815*b30d1939SAndy Fiddaman 			np->nvfun = SH_MATCHNOD->nvfun;
816*b30d1939SAndy Fiddaman 			nv_onattr(np,NV_NOFREE|NV_ARRAY);
817*b30d1939SAndy Fiddaman 			SH_MATCHNOD->nvfun = 0;
818*b30d1939SAndy Fiddaman 			for(i=0; i < mp->nmatch; i++)
819*b30d1939SAndy Fiddaman 			{
820*b30d1939SAndy Fiddaman 				nv_putsub(SH_MATCHNOD, (char*)0, i);
821*b30d1939SAndy Fiddaman 				nv_arraychild(SH_MATCHNOD, np,0);
822*b30d1939SAndy Fiddaman 			}
823*b30d1939SAndy Fiddaman 			if(ap = nv_arrayptr(SH_MATCHNOD))
824*b30d1939SAndy Fiddaman 				ap->nelem = mp->nmatch;
825*b30d1939SAndy Fiddaman 		}
826*b30d1939SAndy Fiddaman 		ap = nv_arrayptr(np);
827*b30d1939SAndy Fiddaman 		nv_putsub(np, NIL(char*), index|ARRAY_FILL|ARRAY_SETSUB);
828*b30d1939SAndy Fiddaman 	}
829*b30d1939SAndy Fiddaman #endif /* SHOPT_2DMATCH */
830*b30d1939SAndy Fiddaman 	shp->subshell = savesub;
831*b30d1939SAndy Fiddaman 	index *= 2*mp->nmatch;
832*b30d1939SAndy Fiddaman 	if(mp->nmatch)
833*b30d1939SAndy Fiddaman 	{
834*b30d1939SAndy Fiddaman 		for(n=mp->first+(mp->v-v),vsize=0,i=0; i < 2*nmatch; i++)
835*b30d1939SAndy Fiddaman 		{
836*b30d1939SAndy Fiddaman 			if(match[i]>=0 && (match[i] - n) > vsize)
837*b30d1939SAndy Fiddaman 				vsize = match[i] -n;
838*b30d1939SAndy Fiddaman 		}
839*b30d1939SAndy Fiddaman 		i = (index+2*mp->nmatch)*sizeof(match[0]);
840*b30d1939SAndy Fiddaman 		if((i+vsize) >= mp->vsize)
841*b30d1939SAndy Fiddaman 		{
842*b30d1939SAndy Fiddaman 			if(mp->vsize)
843*b30d1939SAndy Fiddaman 				mp->match = (int*)realloc(mp->match,i+vsize+1);
844*b30d1939SAndy Fiddaman 			else
845*b30d1939SAndy Fiddaman 				mp->match = (int*)malloc(i+vsize+1);
846*b30d1939SAndy Fiddaman 			mp->vsize = i+vsize+1;
847*b30d1939SAndy Fiddaman 		}
848*b30d1939SAndy Fiddaman 		mp->val =  ((char*)mp->match)+i;
849*b30d1939SAndy Fiddaman 		memcpy(mp->match+index,match,nmatch*2*sizeof(match[0]));
850*b30d1939SAndy Fiddaman 		for(x=0,i=0; i < 2*nmatch; i++)
851*b30d1939SAndy Fiddaman 		{
852*b30d1939SAndy Fiddaman 			if(match[i]>=0)
853*b30d1939SAndy Fiddaman 				mp->match[index+i] -= n;
854*b30d1939SAndy Fiddaman 			else
855*b30d1939SAndy Fiddaman 				x=1;
856*b30d1939SAndy Fiddaman 
857*b30d1939SAndy Fiddaman 		}
858*b30d1939SAndy Fiddaman 		ap->nelem -= x;
859*b30d1939SAndy Fiddaman 		while(i < 2*mp->nmatch)
860*b30d1939SAndy Fiddaman 			mp->match[index+i++] = -1;
861*b30d1939SAndy Fiddaman 		memcpy(mp->val,v+n,vsize);
862*b30d1939SAndy Fiddaman 		mp->val[vsize] = 0;
863*b30d1939SAndy Fiddaman 		mp->lastsub[0] = mp->lastsub[1] = -1;
864*b30d1939SAndy Fiddaman 	}
865*b30d1939SAndy Fiddaman }
866*b30d1939SAndy Fiddaman 
867*b30d1939SAndy Fiddaman #define array_scan(np)	((nv_arrayptr(np)->nelem&ARRAY_SCAN))
868*b30d1939SAndy Fiddaman 
get_match(register Namval_t * np,Namfun_t * fp)869*b30d1939SAndy Fiddaman static char* get_match(register Namval_t* np, Namfun_t *fp)
870*b30d1939SAndy Fiddaman {
871*b30d1939SAndy Fiddaman 	struct match	*mp = (struct match*)fp;
872*b30d1939SAndy Fiddaman 	int		sub,sub2=0,n,i =!mp->index;
873*b30d1939SAndy Fiddaman 	char		*val;
874*b30d1939SAndy Fiddaman 	sub = nv_aindex(SH_MATCHNOD);
875*b30d1939SAndy Fiddaman 	if(np!=SH_MATCHNOD)
876*b30d1939SAndy Fiddaman 		sub2 = nv_aindex(np);
877*b30d1939SAndy Fiddaman 	if(sub>=mp->nmatch)
878*b30d1939SAndy Fiddaman 		return(0);
879*b30d1939SAndy Fiddaman 	if(sub2>0)
880*b30d1939SAndy Fiddaman 		sub += sub2*mp->nmatch;
881*b30d1939SAndy Fiddaman 	if(sub==mp->lastsub[!i])
882*b30d1939SAndy Fiddaman 		return(mp->rval[!i]);
883*b30d1939SAndy Fiddaman 	else if(sub==mp->lastsub[i])
884*b30d1939SAndy Fiddaman 		return(mp->rval[i]);
885*b30d1939SAndy Fiddaman 	n = mp->match[2*sub+1]-mp->match[2*sub];
886*b30d1939SAndy Fiddaman 	if(n<=0)
887*b30d1939SAndy Fiddaman 		return(mp->match[2*sub]<0?Empty:"");
888*b30d1939SAndy Fiddaman 	val = mp->val+mp->match[2*sub];
889*b30d1939SAndy Fiddaman 	if(mp->val[mp->match[2*sub+1]]==0)
890*b30d1939SAndy Fiddaman 		return(val);
891*b30d1939SAndy Fiddaman 	mp->index = i;
892*b30d1939SAndy Fiddaman 	if(mp->rval[i])
893*b30d1939SAndy Fiddaman 	{
894*b30d1939SAndy Fiddaman 		free((void*)mp->rval[i]);
895*b30d1939SAndy Fiddaman 		mp->rval[i] = 0;
896*b30d1939SAndy Fiddaman 	}
897*b30d1939SAndy Fiddaman 	mp->rval[i] = (char*)malloc(n+1);
898*b30d1939SAndy Fiddaman 	mp->lastsub[i] = sub;
899*b30d1939SAndy Fiddaman 	memcpy(mp->rval[i],val,n);
900*b30d1939SAndy Fiddaman 	mp->rval[i][n] = 0;
901*b30d1939SAndy Fiddaman 	return(mp->rval[i]);
902*b30d1939SAndy Fiddaman }
903*b30d1939SAndy Fiddaman 
904*b30d1939SAndy Fiddaman static const Namdisc_t SH_MATCH_disc  = { sizeof(struct match), 0, get_match };
905*b30d1939SAndy Fiddaman 
get_version(register Namval_t * np,Namfun_t * fp)906*b30d1939SAndy Fiddaman static char* get_version(register Namval_t* np, Namfun_t *fp)
907*b30d1939SAndy Fiddaman {
908*b30d1939SAndy Fiddaman 	return(nv_getv(np,fp));
909*b30d1939SAndy Fiddaman }
910*b30d1939SAndy Fiddaman 
nget_version(register Namval_t * np,Namfun_t * fp)911*b30d1939SAndy Fiddaman static Sfdouble_t nget_version(register Namval_t* np, Namfun_t *fp)
912*b30d1939SAndy Fiddaman {
913*b30d1939SAndy Fiddaman 	register const char	*cp = e_version + strlen(e_version)-10;
914*b30d1939SAndy Fiddaman 	register int		c;
915*b30d1939SAndy Fiddaman 	Sflong_t		t = 0;
916*b30d1939SAndy Fiddaman 	NOT_USED(fp);
917*b30d1939SAndy Fiddaman 
918*b30d1939SAndy Fiddaman 	while (c = *cp++)
919*b30d1939SAndy Fiddaman 		if (c >= '0' && c <= '9')
920*b30d1939SAndy Fiddaman 		{
921*b30d1939SAndy Fiddaman 			t *= 10;
922*b30d1939SAndy Fiddaman 			t += c - '0';
923*b30d1939SAndy Fiddaman 		}
924*b30d1939SAndy Fiddaman 	return((Sfdouble_t)t);
925*b30d1939SAndy Fiddaman }
926*b30d1939SAndy Fiddaman 
927*b30d1939SAndy Fiddaman static const Namdisc_t SH_VERSION_disc	= {  0, 0, get_version, nget_version };
928*b30d1939SAndy Fiddaman 
929*b30d1939SAndy Fiddaman #if SHOPT_FS_3D
930*b30d1939SAndy Fiddaman     /*
931*b30d1939SAndy Fiddaman      * set or unset the mappings given a colon separated list of directories
932*b30d1939SAndy Fiddaman      */
vpath_set(char * str,int mode)933*b30d1939SAndy Fiddaman     static void vpath_set(char *str, int mode)
934*b30d1939SAndy Fiddaman     {
935*b30d1939SAndy Fiddaman 	register char *lastp, *oldp=str, *newp=strchr(oldp,':');
936*b30d1939SAndy Fiddaman 	if(!shgd->lim.fs3d)
937*b30d1939SAndy Fiddaman 		return;
938*b30d1939SAndy Fiddaman 	while(newp)
939*b30d1939SAndy Fiddaman 	{
940*b30d1939SAndy Fiddaman 		*newp++ = 0;
941*b30d1939SAndy Fiddaman 		if(lastp=strchr(newp,':'))
942*b30d1939SAndy Fiddaman 			*lastp = 0;
943*b30d1939SAndy Fiddaman 		mount((mode?newp:""),oldp,FS3D_VIEW,0);
944*b30d1939SAndy Fiddaman 		newp[-1] = ':';
945*b30d1939SAndy Fiddaman 		oldp = newp;
946*b30d1939SAndy Fiddaman 		newp=lastp;
947*b30d1939SAndy Fiddaman 	}
948*b30d1939SAndy Fiddaman     }
949*b30d1939SAndy Fiddaman 
950*b30d1939SAndy Fiddaman     /* catch vpath assignments */
put_vpath(register Namval_t * np,const char * val,int flags,Namfun_t * fp)951*b30d1939SAndy Fiddaman     static void put_vpath(register Namval_t* np,const char *val,int flags,Namfun_t *fp)
952*b30d1939SAndy Fiddaman     {
953*b30d1939SAndy Fiddaman 	register char *cp;
954*b30d1939SAndy Fiddaman 	if(cp = nv_getval(np))
955*b30d1939SAndy Fiddaman 		vpath_set(cp,0);
956*b30d1939SAndy Fiddaman 	if(val)
957*b30d1939SAndy Fiddaman 		vpath_set((char*)val,1);
958*b30d1939SAndy Fiddaman 	nv_putv(np,val,flags,fp);
959*b30d1939SAndy Fiddaman     }
960*b30d1939SAndy Fiddaman     static const Namdisc_t VPATH_disc	= { 0, put_vpath  };
961*b30d1939SAndy Fiddaman     static Namfun_t VPATH_init	= { &VPATH_disc, 1  };
962*b30d1939SAndy Fiddaman #endif /* SHOPT_FS_3D */
963*b30d1939SAndy Fiddaman 
964*b30d1939SAndy Fiddaman 
965*b30d1939SAndy Fiddaman static const Namdisc_t IFS_disc		= {  sizeof(struct ifs), put_ifs, get_ifs };
966*b30d1939SAndy Fiddaman const Namdisc_t RESTRICTED_disc	= {  sizeof(Namfun_t), put_restricted };
967*b30d1939SAndy Fiddaman static const Namdisc_t CDPATH_disc	= {  sizeof(Namfun_t), put_cdpath };
968*b30d1939SAndy Fiddaman static const Namdisc_t EDITOR_disc	= {  sizeof(Namfun_t), put_ed };
969*b30d1939SAndy Fiddaman static const Namdisc_t HISTFILE_disc	= {  sizeof(Namfun_t), put_history };
970*b30d1939SAndy Fiddaman static const Namdisc_t OPTINDEX_disc	= {  sizeof(Namfun_t), put_optindex, 0, nget_optindex, 0, 0, clone_optindex };
971*b30d1939SAndy Fiddaman static const Namdisc_t SECONDS_disc	= {  sizeof(struct seconds), put_seconds, get_seconds, nget_seconds };
972*b30d1939SAndy Fiddaman static const Namdisc_t RAND_disc	= {  sizeof(struct rand), put_rand, get_rand, nget_rand };
973*b30d1939SAndy Fiddaman static const Namdisc_t LINENO_disc	= {  sizeof(Namfun_t), put_lineno, get_lineno, nget_lineno };
974*b30d1939SAndy Fiddaman static const Namdisc_t L_ARG_disc	= {  sizeof(Namfun_t), put_lastarg, get_lastarg };
975*b30d1939SAndy Fiddaman 
976*b30d1939SAndy Fiddaman 
977*b30d1939SAndy Fiddaman #define MAX_MATH_ARGS	3
978*b30d1939SAndy Fiddaman 
name_math(Namval_t * np,Namfun_t * fp)979*b30d1939SAndy Fiddaman static char *name_math(Namval_t *np, Namfun_t *fp)
980*b30d1939SAndy Fiddaman {
981*b30d1939SAndy Fiddaman 	Shell_t		*shp = sh_getinterp();
982*b30d1939SAndy Fiddaman 	sfprintf(shp->strbuf,".sh.math.%s",np->nvname);
983*b30d1939SAndy Fiddaman 	return(sfstruse(shp->strbuf));
984*b30d1939SAndy Fiddaman }
985*b30d1939SAndy Fiddaman 
986*b30d1939SAndy Fiddaman static const Namdisc_t	math_child_disc =
987*b30d1939SAndy Fiddaman {
988*b30d1939SAndy Fiddaman 	0,0,0,0,0,0,0,
989*b30d1939SAndy Fiddaman 	name_math
990*b30d1939SAndy Fiddaman };
991*b30d1939SAndy Fiddaman 
992*b30d1939SAndy Fiddaman static Namfun_t	 math_child_fun =
993*b30d1939SAndy Fiddaman {
994*b30d1939SAndy Fiddaman 	&math_child_disc, 1, 0, sizeof(Namfun_t)
995*b30d1939SAndy Fiddaman };
996*b30d1939SAndy Fiddaman 
math_init(Shell_t * shp)997*b30d1939SAndy Fiddaman static void math_init(Shell_t *shp)
998*b30d1939SAndy Fiddaman {
999*b30d1939SAndy Fiddaman 	Namval_t	*np;
1000*b30d1939SAndy Fiddaman 	char		*name;
1001*b30d1939SAndy Fiddaman 	int		i;
1002*b30d1939SAndy Fiddaman 	shp->mathnodes = (char*)calloc(1,MAX_MATH_ARGS*(NV_MINSZ+5));
1003*b30d1939SAndy Fiddaman 	name = shp->mathnodes+MAX_MATH_ARGS*NV_MINSZ;
1004*b30d1939SAndy Fiddaman 	for(i=0; i < MAX_MATH_ARGS; i++)
1005*b30d1939SAndy Fiddaman 	{
1006*b30d1939SAndy Fiddaman 		np = nv_namptr(shp->mathnodes,i);
1007*b30d1939SAndy Fiddaman 		np->nvfun = &math_child_fun;
1008*b30d1939SAndy Fiddaman 		memcpy(name,"arg",3);
1009*b30d1939SAndy Fiddaman 		name[3] = '1'+i;
1010*b30d1939SAndy Fiddaman 		np->nvname = name;
1011*b30d1939SAndy Fiddaman 		name+=5;
1012*b30d1939SAndy Fiddaman 		nv_onattr(np,NV_MINIMAL|NV_NOFREE|NV_LDOUBLE|NV_RDONLY);
1013*b30d1939SAndy Fiddaman 	}
1014*b30d1939SAndy Fiddaman }
1015*b30d1939SAndy Fiddaman 
create_math(Namval_t * np,const char * name,int flag,Namfun_t * fp)1016*b30d1939SAndy Fiddaman static Namval_t *create_math(Namval_t *np,const char *name,int flag,Namfun_t *fp)
1017*b30d1939SAndy Fiddaman {
1018*b30d1939SAndy Fiddaman 	Shell_t		*shp = nv_shell(np);
1019*b30d1939SAndy Fiddaman 	if(!name)
1020*b30d1939SAndy Fiddaman 		return(SH_MATHNOD);
1021*b30d1939SAndy Fiddaman 	if(name[0]!='a' || name[1]!='r' || name[2]!='g' || name[4] || !isdigit(name[3]) || (name[3]=='0' || (name[3]-'0')>MAX_MATH_ARGS))
1022*b30d1939SAndy Fiddaman 		return(0);
1023*b30d1939SAndy Fiddaman 	fp->last = (char*)&name[4];
1024*b30d1939SAndy Fiddaman 	return(nv_namptr(shp->mathnodes,name[3]-'1'));
1025*b30d1939SAndy Fiddaman }
1026*b30d1939SAndy Fiddaman 
get_math(register Namval_t * np,Namfun_t * fp)1027*b30d1939SAndy Fiddaman static char* get_math(register Namval_t* np, Namfun_t *fp)
1028*b30d1939SAndy Fiddaman {
1029*b30d1939SAndy Fiddaman 	Shell_t		*shp = nv_shell(np);
1030*b30d1939SAndy Fiddaman 	Namval_t	*mp,fake;
1031*b30d1939SAndy Fiddaman 	char		*val;
1032*b30d1939SAndy Fiddaman 	int		first=0;
1033*b30d1939SAndy Fiddaman 	fake.nvname = ".sh.math.";
1034*b30d1939SAndy Fiddaman 	mp = (Namval_t*)dtprev(shp->fun_tree,&fake);
1035*b30d1939SAndy Fiddaman 	while(mp=(Namval_t*)dtnext(shp->fun_tree,mp))
1036*b30d1939SAndy Fiddaman 	{
1037*b30d1939SAndy Fiddaman 		if(memcmp(mp->nvname,".sh.math.",9))
1038*b30d1939SAndy Fiddaman 			break;
1039*b30d1939SAndy Fiddaman 		if(first++)
1040*b30d1939SAndy Fiddaman 			sfputc(shp->strbuf,' ');
1041*b30d1939SAndy Fiddaman 		sfputr(shp->strbuf,mp->nvname+9,-1);
1042*b30d1939SAndy Fiddaman 	}
1043*b30d1939SAndy Fiddaman 	val = sfstruse(shp->strbuf);
1044*b30d1939SAndy Fiddaman 	return(val);
1045*b30d1939SAndy Fiddaman 
1046*b30d1939SAndy Fiddaman }
1047*b30d1939SAndy Fiddaman 
setdisc_any(Namval_t * np,const char * event,Namval_t * action,Namfun_t * fp)1048*b30d1939SAndy Fiddaman static char *setdisc_any(Namval_t *np, const char *event, Namval_t *action, Namfun_t *fp)
1049*b30d1939SAndy Fiddaman {
1050*b30d1939SAndy Fiddaman 	Shell_t		*shp=nv_shell(np);
1051*b30d1939SAndy Fiddaman 	Namval_t	*mp,fake;
1052*b30d1939SAndy Fiddaman 	char		*name;
1053*b30d1939SAndy Fiddaman 	int		getname=0, off=staktell();
1054*b30d1939SAndy Fiddaman 	fake.nvname = nv_name(np);
1055*b30d1939SAndy Fiddaman 	if(!event)
1056*b30d1939SAndy Fiddaman 	{
1057*b30d1939SAndy Fiddaman 		if(!action)
1058*b30d1939SAndy Fiddaman 		{
1059*b30d1939SAndy Fiddaman 			mp = (Namval_t*)dtprev(shp->fun_tree,&fake);
1060*b30d1939SAndy Fiddaman 			return((char*)dtnext(shp->fun_tree,mp));
1061*b30d1939SAndy Fiddaman 		}
1062*b30d1939SAndy Fiddaman 		getname = 1;
1063*b30d1939SAndy Fiddaman 	}
1064*b30d1939SAndy Fiddaman 	stakputs(fake.nvname);
1065*b30d1939SAndy Fiddaman 	stakputc('.');
1066*b30d1939SAndy Fiddaman 	stakputs(event);
1067*b30d1939SAndy Fiddaman 	stakputc(0);
1068*b30d1939SAndy Fiddaman 	name  = stakptr(off);
1069*b30d1939SAndy Fiddaman 	mp = nv_search(name, shp->fun_tree, action?NV_ADD:0);
1070*b30d1939SAndy Fiddaman 	stakseek(off);
1071*b30d1939SAndy Fiddaman 	if(getname)
1072*b30d1939SAndy Fiddaman 		return(mp?(char*)dtnext(shp->fun_tree,mp):0);
1073*b30d1939SAndy Fiddaman 	if(action==np)
1074*b30d1939SAndy Fiddaman 		action = mp;
1075*b30d1939SAndy Fiddaman 	return(action?(char*)action:"");
1076*b30d1939SAndy Fiddaman }
1077*b30d1939SAndy Fiddaman 
1078*b30d1939SAndy Fiddaman static const Namdisc_t SH_MATH_disc  = { 0, 0, get_math, 0, setdisc_any, create_math, };
1079*b30d1939SAndy Fiddaman 
1080*b30d1939SAndy Fiddaman #if SHOPT_COSHELL
1081*b30d1939SAndy Fiddaman static const Namdisc_t SH_JOBPOOL_disc  = { 0, 0, 0, 0, setdisc_any, 0, };
1082*b30d1939SAndy Fiddaman #endif /*  SHOPT_COSHELL */
1083*b30d1939SAndy Fiddaman 
1084*b30d1939SAndy Fiddaman #if SHOPT_NAMESPACE
get_nspace(Namval_t * np,Namfun_t * fp)1085*b30d1939SAndy Fiddaman     static char* get_nspace(Namval_t* np, Namfun_t *fp)
1086*b30d1939SAndy Fiddaman     {
1087*b30d1939SAndy Fiddaman 	if(sh.namespace)
1088*b30d1939SAndy Fiddaman 		return(nv_name(sh.namespace));
1089*b30d1939SAndy Fiddaman 	return((char*)np->nvalue.cp);
1090*b30d1939SAndy Fiddaman     }
1091*b30d1939SAndy Fiddaman     static const Namdisc_t NSPACE_disc	= {  0, 0, get_nspace };
1092*b30d1939SAndy Fiddaman     static Namfun_t NSPACE_init	= {  &NSPACE_disc, 1};
1093*b30d1939SAndy Fiddaman #endif /* SHOPT_NAMESPACE */
1094*b30d1939SAndy Fiddaman 
1095*b30d1939SAndy Fiddaman #ifdef _hdr_locale
1096*b30d1939SAndy Fiddaman     static const Namdisc_t LC_disc	= {  sizeof(Namfun_t), put_lang };
1097*b30d1939SAndy Fiddaman #endif /* _hdr_locale */
1098*b30d1939SAndy Fiddaman 
1099*b30d1939SAndy Fiddaman /*
1100*b30d1939SAndy Fiddaman  * This function will get called whenever a configuration parameter changes
1101*b30d1939SAndy Fiddaman  */
newconf(const char * name,const char * path,const char * value)1102*b30d1939SAndy Fiddaman static int newconf(const char *name, const char *path, const char *value)
1103*b30d1939SAndy Fiddaman {
1104*b30d1939SAndy Fiddaman 	Shell_t	*shp = sh_getinterp();
1105*b30d1939SAndy Fiddaman 	register char *arg;
1106*b30d1939SAndy Fiddaman 	if(!name)
1107*b30d1939SAndy Fiddaman 		setenviron(value);
1108*b30d1939SAndy Fiddaman 	else if(strcmp(name,"UNIVERSE")==0 && strcmp(astconf(name,0,0),value))
1109*b30d1939SAndy Fiddaman 	{
1110*b30d1939SAndy Fiddaman 		shp->universe = 0;
1111*b30d1939SAndy Fiddaman 		/* set directory in new universe */
1112*b30d1939SAndy Fiddaman 		if(*(arg = path_pwd(shp,0))=='/')
1113*b30d1939SAndy Fiddaman 			chdir(arg);
1114*b30d1939SAndy Fiddaman 		/* clear out old tracked alias */
1115*b30d1939SAndy Fiddaman 		stakseek(0);
1116*b30d1939SAndy Fiddaman 		stakputs(nv_getval(PATHNOD));
1117*b30d1939SAndy Fiddaman 		stakputc(0);
1118*b30d1939SAndy Fiddaman 		nv_putval(PATHNOD,stakseek(0),NV_RDONLY);
1119*b30d1939SAndy Fiddaman 	}
1120*b30d1939SAndy Fiddaman 	return(1);
1121*b30d1939SAndy Fiddaman }
1122*b30d1939SAndy Fiddaman 
1123*b30d1939SAndy Fiddaman #if	(CC_NATIVE != CC_ASCII)
a2e(char * d,const char * s)1124*b30d1939SAndy Fiddaman     static void a2e(char *d, const char *s)
1125*b30d1939SAndy Fiddaman     {
1126*b30d1939SAndy Fiddaman 	register const unsigned char *t;
1127*b30d1939SAndy Fiddaman 	register int i;
1128*b30d1939SAndy Fiddaman 	t = CCMAP(CC_ASCII, CC_NATIVE);
1129*b30d1939SAndy Fiddaman 	for(i=0; i<(1<<CHAR_BIT); i++)
1130*b30d1939SAndy Fiddaman 		d[t[i]] = s[i];
1131*b30d1939SAndy Fiddaman     }
1132*b30d1939SAndy Fiddaman 
init_ebcdic(void)1133*b30d1939SAndy Fiddaman     static void init_ebcdic(void)
1134*b30d1939SAndy Fiddaman     {
1135*b30d1939SAndy Fiddaman 	int i;
1136*b30d1939SAndy Fiddaman 	char *cp = (char*)malloc(ST_NONE*(1<<CHAR_BIT));
1137*b30d1939SAndy Fiddaman 	for(i=0; i < ST_NONE; i++)
1138*b30d1939SAndy Fiddaman 	{
1139*b30d1939SAndy Fiddaman 		a2e(cp,sh_lexrstates[i]);
1140*b30d1939SAndy Fiddaman 		sh_lexstates[i] = cp;
1141*b30d1939SAndy Fiddaman 		cp += (1<<CHAR_BIT);
1142*b30d1939SAndy Fiddaman 	}
1143*b30d1939SAndy Fiddaman     }
1144*b30d1939SAndy Fiddaman #endif
1145*b30d1939SAndy Fiddaman 
1146*b30d1939SAndy Fiddaman /*
1147*b30d1939SAndy Fiddaman  * return SH_TYPE_* bitmask for path
1148*b30d1939SAndy Fiddaman  * 0 for "not a shell"
1149*b30d1939SAndy Fiddaman  */
sh_type(register const char * path)1150*b30d1939SAndy Fiddaman int sh_type(register const char *path)
1151*b30d1939SAndy Fiddaman {
1152*b30d1939SAndy Fiddaman 	register const char*	s;
1153*b30d1939SAndy Fiddaman 	register int		t = 0;
1154*b30d1939SAndy Fiddaman 
1155*b30d1939SAndy Fiddaman 	if (s = (const char*)strrchr(path, '/'))
1156*b30d1939SAndy Fiddaman 	{
1157*b30d1939SAndy Fiddaman 		if (*path == '-')
1158*b30d1939SAndy Fiddaman 			t |= SH_TYPE_LOGIN;
1159*b30d1939SAndy Fiddaman 		s++;
1160*b30d1939SAndy Fiddaman 	}
1161*b30d1939SAndy Fiddaman 	else
1162*b30d1939SAndy Fiddaman 		s = path;
1163*b30d1939SAndy Fiddaman 	if (*s == '-')
1164*b30d1939SAndy Fiddaman 	{
1165*b30d1939SAndy Fiddaman 		s++;
1166*b30d1939SAndy Fiddaman 		t |= SH_TYPE_LOGIN;
1167*b30d1939SAndy Fiddaman 	}
1168*b30d1939SAndy Fiddaman 	for (;;)
1169*b30d1939SAndy Fiddaman 	{
1170*b30d1939SAndy Fiddaman 		if (!(t & (SH_TYPE_KSH|SH_TYPE_BASH)))
1171*b30d1939SAndy Fiddaman 		{
1172*b30d1939SAndy Fiddaman 			if (*s == 'k')
1173*b30d1939SAndy Fiddaman 			{
1174*b30d1939SAndy Fiddaman 				s++;
1175*b30d1939SAndy Fiddaman 				t |= SH_TYPE_KSH;
1176*b30d1939SAndy Fiddaman 				continue;
1177*b30d1939SAndy Fiddaman 			}
1178*b30d1939SAndy Fiddaman #if SHOPT_BASH
1179*b30d1939SAndy Fiddaman 			if (*s == 'b' && *(s+1) == 'a')
1180*b30d1939SAndy Fiddaman 			{
1181*b30d1939SAndy Fiddaman 				s += 2;
1182*b30d1939SAndy Fiddaman 				t |= SH_TYPE_BASH;
1183*b30d1939SAndy Fiddaman 				continue;
1184*b30d1939SAndy Fiddaman 			}
1185*b30d1939SAndy Fiddaman #endif
1186*b30d1939SAndy Fiddaman 		}
1187*b30d1939SAndy Fiddaman 		if (!(t & (SH_TYPE_PROFILE|SH_TYPE_RESTRICTED)))
1188*b30d1939SAndy Fiddaman 		{
1189*b30d1939SAndy Fiddaman #if SHOPT_PFSH
1190*b30d1939SAndy Fiddaman 			if (*s == 'p' && *(s+1) == 'f')
1191*b30d1939SAndy Fiddaman 			{
1192*b30d1939SAndy Fiddaman 				s += 2;
1193*b30d1939SAndy Fiddaman 				t |= SH_TYPE_PROFILE;
1194*b30d1939SAndy Fiddaman 				continue;
1195*b30d1939SAndy Fiddaman 			}
1196*b30d1939SAndy Fiddaman #endif
1197*b30d1939SAndy Fiddaman 			if (*s == 'r')
1198*b30d1939SAndy Fiddaman 			{
1199*b30d1939SAndy Fiddaman 				s++;
1200*b30d1939SAndy Fiddaman 				t |= SH_TYPE_RESTRICTED;
1201*b30d1939SAndy Fiddaman 				continue;
1202*b30d1939SAndy Fiddaman 			}
1203*b30d1939SAndy Fiddaman 		}
1204*b30d1939SAndy Fiddaman 		break;
1205*b30d1939SAndy Fiddaman 	}
1206*b30d1939SAndy Fiddaman 	if (*s++ == 's' && (*s == 'h' || *s == 'u'))
1207*b30d1939SAndy Fiddaman 	{
1208*b30d1939SAndy Fiddaman 		s++;
1209*b30d1939SAndy Fiddaman 		t |= SH_TYPE_SH;
1210*b30d1939SAndy Fiddaman 		if ((t & SH_TYPE_KSH) && *s == '9' && *(s+1) == '3')
1211*b30d1939SAndy Fiddaman 			s += 2;
1212*b30d1939SAndy Fiddaman #if _WINIX
1213*b30d1939SAndy Fiddaman 		if (*s == '.' && *(s+1) == 'e' && *(s+2) == 'x' && *(s+3) == 'e')
1214*b30d1939SAndy Fiddaman 			s += 4;
1215*b30d1939SAndy Fiddaman #endif
1216*b30d1939SAndy Fiddaman 		if (!isalnum(*s))
1217*b30d1939SAndy Fiddaman 			return t;
1218*b30d1939SAndy Fiddaman 	}
1219*b30d1939SAndy Fiddaman 	return t & ~(SH_TYPE_BASH|SH_TYPE_KSH|SH_TYPE_PROFILE|SH_TYPE_RESTRICTED);
1220*b30d1939SAndy Fiddaman }
1221*b30d1939SAndy Fiddaman 
1222*b30d1939SAndy Fiddaman 
get_mode(Namval_t * np,Namfun_t * nfp)1223*b30d1939SAndy Fiddaman static char *get_mode(Namval_t* np, Namfun_t* nfp)
1224*b30d1939SAndy Fiddaman {
1225*b30d1939SAndy Fiddaman 	mode_t mode = nv_getn(np,nfp);
1226*b30d1939SAndy Fiddaman 	return(fmtperm(mode));
1227*b30d1939SAndy Fiddaman }
1228*b30d1939SAndy Fiddaman 
put_mode(Namval_t * np,const char * val,int flag,Namfun_t * nfp)1229*b30d1939SAndy Fiddaman static void put_mode(Namval_t* np, const char* val, int flag, Namfun_t* nfp)
1230*b30d1939SAndy Fiddaman {
1231*b30d1939SAndy Fiddaman 	if(val)
1232*b30d1939SAndy Fiddaman 	{
1233*b30d1939SAndy Fiddaman 		mode_t mode;
1234*b30d1939SAndy Fiddaman 		char *last=0;
1235*b30d1939SAndy Fiddaman 		if(flag&NV_INTEGER)
1236*b30d1939SAndy Fiddaman 		{
1237*b30d1939SAndy Fiddaman 			if(flag&NV_LONG)
1238*b30d1939SAndy Fiddaman 				mode = *(Sfdouble_t*)val;
1239*b30d1939SAndy Fiddaman 			else
1240*b30d1939SAndy Fiddaman 				mode = *(double*)val;
1241*b30d1939SAndy Fiddaman 		}
1242*b30d1939SAndy Fiddaman 		else
1243*b30d1939SAndy Fiddaman 			mode = strperm(val, &last,0);
1244*b30d1939SAndy Fiddaman 		if(*last)
1245*b30d1939SAndy Fiddaman 			errormsg(SH_DICT,ERROR_exit(1),"%s: invalid mode string",val);
1246*b30d1939SAndy Fiddaman 		nv_putv(np,(char*)&mode,NV_INTEGER,nfp);
1247*b30d1939SAndy Fiddaman 	}
1248*b30d1939SAndy Fiddaman 	else
1249*b30d1939SAndy Fiddaman 		nv_putv(np,val,flag,nfp);
1250*b30d1939SAndy Fiddaman }
1251*b30d1939SAndy Fiddaman 
1252*b30d1939SAndy Fiddaman static const Namdisc_t modedisc =
1253*b30d1939SAndy Fiddaman {
1254*b30d1939SAndy Fiddaman 	0,
1255*b30d1939SAndy Fiddaman         put_mode,
1256*b30d1939SAndy Fiddaman         get_mode,
1257*b30d1939SAndy Fiddaman };
1258*b30d1939SAndy Fiddaman 
1259*b30d1939SAndy Fiddaman 
1260*b30d1939SAndy Fiddaman /*
1261*b30d1939SAndy Fiddaman  * initialize the shell
1262*b30d1939SAndy Fiddaman  */
sh_init(register int argc,register char * argv[],Shinit_f userinit)1263*b30d1939SAndy Fiddaman Shell_t *sh_init(register int argc,register char *argv[], Shinit_f userinit)
1264*b30d1939SAndy Fiddaman {
1265*b30d1939SAndy Fiddaman 	static int beenhere;
1266*b30d1939SAndy Fiddaman 	Shell_t	*shp;
1267*b30d1939SAndy Fiddaman 	register int n;
1268*b30d1939SAndy Fiddaman 	int type;
1269*b30d1939SAndy Fiddaman 	static char *login_files[3];
1270*b30d1939SAndy Fiddaman 	memfatal();
1271*b30d1939SAndy Fiddaman 	n = strlen(e_version);
1272*b30d1939SAndy Fiddaman 	if(e_version[n-1]=='$' && e_version[n-2]==' ')
1273*b30d1939SAndy Fiddaman 		e_version[n-2]=0;
1274*b30d1939SAndy Fiddaman #if	(CC_NATIVE == CC_ASCII)
1275*b30d1939SAndy Fiddaman 	memcpy(sh_lexstates,sh_lexrstates,ST_NONE*sizeof(char*));
1276*b30d1939SAndy Fiddaman #else
1277*b30d1939SAndy Fiddaman 	init_ebcdic();
1278*b30d1939SAndy Fiddaman #endif
1279*b30d1939SAndy Fiddaman 	if(!beenhere)
1280*b30d1939SAndy Fiddaman 	{
1281*b30d1939SAndy Fiddaman 		beenhere = 1;
1282*b30d1939SAndy Fiddaman 		shp = &sh;
1283*b30d1939SAndy Fiddaman 		shgd = newof(0,struct shared,1,0);
1284*b30d1939SAndy Fiddaman 		shgd->pid = getpid();
1285*b30d1939SAndy Fiddaman 		shgd->ppid = getppid();
1286*b30d1939SAndy Fiddaman 		shgd->userid=getuid();
1287*b30d1939SAndy Fiddaman 		shgd->euserid=geteuid();
1288*b30d1939SAndy Fiddaman 		shgd->groupid=getgid();
1289*b30d1939SAndy Fiddaman 		shgd->egroupid=getegid();
1290*b30d1939SAndy Fiddaman 		shgd->lim.clk_tck = getconf("CLK_TCK");
1291*b30d1939SAndy Fiddaman 		shgd->lim.arg_max = getconf("ARG_MAX");
1292*b30d1939SAndy Fiddaman 		shgd->lim.child_max = getconf("CHILD_MAX");
1293*b30d1939SAndy Fiddaman 		shgd->lim.ngroups_max = getconf("NGROUPS_MAX");
1294*b30d1939SAndy Fiddaman 		shgd->lim.posix_version = getconf("VERSION");
1295*b30d1939SAndy Fiddaman 		shgd->lim.posix_jobcontrol = getconf("JOB_CONTROL");
1296*b30d1939SAndy Fiddaman 		if(shgd->lim.arg_max <=0)
1297*b30d1939SAndy Fiddaman 			shgd->lim.arg_max = ARG_MAX;
1298*b30d1939SAndy Fiddaman 		if(shgd->lim.child_max <=0)
1299*b30d1939SAndy Fiddaman 			shgd->lim.child_max = CHILD_MAX;
1300*b30d1939SAndy Fiddaman 		if(shgd->lim.clk_tck <=0)
1301*b30d1939SAndy Fiddaman 			shgd->lim.clk_tck = CLK_TCK;
1302*b30d1939SAndy Fiddaman #if SHOPT_FS_3D
1303*b30d1939SAndy Fiddaman 		if(fs3d(FS3D_TEST))
1304*b30d1939SAndy Fiddaman 			shgd->lim.fs3d = 1;
1305*b30d1939SAndy Fiddaman #endif /* SHOPT_FS_3D */
1306*b30d1939SAndy Fiddaman 		shgd->ed_context = (void*)ed_open(shp);
1307*b30d1939SAndy Fiddaman 		error_info.exit = sh_exit;
1308*b30d1939SAndy Fiddaman 		error_info.id = path_basename(argv[0]);
1309*b30d1939SAndy Fiddaman 	}
1310*b30d1939SAndy Fiddaman 	else
1311*b30d1939SAndy Fiddaman 		shp = newof(0,Shell_t,1,0);
1312*b30d1939SAndy Fiddaman 	umask(shp->mask=umask(0));
1313*b30d1939SAndy Fiddaman 	shp->gd = shgd;
1314*b30d1939SAndy Fiddaman 	shp->mac_context = sh_macopen(shp);
1315*b30d1939SAndy Fiddaman 	shp->arg_context = sh_argopen(shp);
1316*b30d1939SAndy Fiddaman 	shp->lex_context = (void*)sh_lexopen(0,shp,1);
1317*b30d1939SAndy Fiddaman 	shp->strbuf = sfstropen();
1318*b30d1939SAndy Fiddaman 	shp->stk = stkstd;
1319*b30d1939SAndy Fiddaman 	sfsetbuf(shp->strbuf,(char*)0,64);
1320*b30d1939SAndy Fiddaman 	sh_onstate(SH_INIT);
1321*b30d1939SAndy Fiddaman #if ERROR_VERSION >= 20000102L
1322*b30d1939SAndy Fiddaman 	error_info.catalog = e_dict;
1323*b30d1939SAndy Fiddaman #endif
1324*b30d1939SAndy Fiddaman #if SHOPT_REGRESS
1325*b30d1939SAndy Fiddaman 	{
1326*b30d1939SAndy Fiddaman 		Opt_t*	nopt;
1327*b30d1939SAndy Fiddaman 		Opt_t*	oopt;
1328*b30d1939SAndy Fiddaman 		char*	a;
1329*b30d1939SAndy Fiddaman 		char**	av = argv;
1330*b30d1939SAndy Fiddaman 		char*	regress[3];
1331*b30d1939SAndy Fiddaman 
1332*b30d1939SAndy Fiddaman 		sh_regress_init(shp);
1333*b30d1939SAndy Fiddaman 		regress[0] = "__regress__";
1334*b30d1939SAndy Fiddaman 		regress[2] = 0;
1335*b30d1939SAndy Fiddaman 		/* NOTE: only shp is used by __regress__ at this point */
1336*b30d1939SAndy Fiddaman 		shp->bltindata.shp = shp;
1337*b30d1939SAndy Fiddaman 		while ((a = *++av) && a[0] == '-' && (a[1] == 'I' || a[1] == '-' && a[2] == 'r'))
1338*b30d1939SAndy Fiddaman 		{
1339*b30d1939SAndy Fiddaman 			if (a[1] == 'I')
1340*b30d1939SAndy Fiddaman 			{
1341*b30d1939SAndy Fiddaman 				if (a[2])
1342*b30d1939SAndy Fiddaman 					regress[1] = a + 2;
1343*b30d1939SAndy Fiddaman 				else if (!(regress[1] = *++av))
1344*b30d1939SAndy Fiddaman 					break;
1345*b30d1939SAndy Fiddaman 			}
1346*b30d1939SAndy Fiddaman 			else if (strncmp(a+2, "regress", 7))
1347*b30d1939SAndy Fiddaman 				break;
1348*b30d1939SAndy Fiddaman 			else if (a[9] == '=')
1349*b30d1939SAndy Fiddaman 				regress[1] = a + 10;
1350*b30d1939SAndy Fiddaman 			else if (!(regress[1] = *++av))
1351*b30d1939SAndy Fiddaman 				break;
1352*b30d1939SAndy Fiddaman 			nopt = optctx(0, 0);
1353*b30d1939SAndy Fiddaman 			oopt = optctx(nopt, 0);
1354*b30d1939SAndy Fiddaman 			b___regress__(2, regress, &shp->bltindata);
1355*b30d1939SAndy Fiddaman 			optctx(oopt, nopt);
1356*b30d1939SAndy Fiddaman 		}
1357*b30d1939SAndy Fiddaman 	}
1358*b30d1939SAndy Fiddaman #endif
1359*b30d1939SAndy Fiddaman 	shp->cpipe[0] = -1;
1360*b30d1939SAndy Fiddaman 	shp->coutpipe = -1;
1361*b30d1939SAndy Fiddaman 	for(n=0;n < 10; n++)
1362*b30d1939SAndy Fiddaman 	{
1363*b30d1939SAndy Fiddaman 		/* don't use lower bits when rand() generates large numbers */
1364*b30d1939SAndy Fiddaman 		if(rand() > RANDMASK)
1365*b30d1939SAndy Fiddaman 		{
1366*b30d1939SAndy Fiddaman 			rand_shift = 3;
1367*b30d1939SAndy Fiddaman 			break;
1368*b30d1939SAndy Fiddaman 		}
1369*b30d1939SAndy Fiddaman 	}
1370*b30d1939SAndy Fiddaman 	sh_ioinit(shp);
1371*b30d1939SAndy Fiddaman 	/* initialize signal handling */
1372*b30d1939SAndy Fiddaman 	sh_siginit(shp);
1373*b30d1939SAndy Fiddaman 	stakinstall(NIL(Stak_t*),nospace);
1374*b30d1939SAndy Fiddaman 	/* set up memory for name-value pairs */
1375*b30d1939SAndy Fiddaman 	shp->init_context =  nv_init(shp);
1376*b30d1939SAndy Fiddaman 	/* read the environment */
1377*b30d1939SAndy Fiddaman 	if(argc>0)
1378*b30d1939SAndy Fiddaman 	{
1379*b30d1939SAndy Fiddaman 		type = sh_type(*argv);
1380*b30d1939SAndy Fiddaman 		if(type&SH_TYPE_LOGIN)
1381*b30d1939SAndy Fiddaman 			shp->login_sh = 2;
1382*b30d1939SAndy Fiddaman 	}
1383*b30d1939SAndy Fiddaman 	env_init(shp);
1384*b30d1939SAndy Fiddaman 	if(!ENVNOD->nvalue.cp)
1385*b30d1939SAndy Fiddaman 	{
1386*b30d1939SAndy Fiddaman 		sfprintf(shp->strbuf,"%s/.kshrc",nv_getval(HOME));
1387*b30d1939SAndy Fiddaman 		nv_putval(ENVNOD,sfstruse(shp->strbuf),NV_RDONLY);
1388*b30d1939SAndy Fiddaman 	}
1389*b30d1939SAndy Fiddaman 	*SHLVL->nvalue.ip +=1;
1390*b30d1939SAndy Fiddaman 	nv_offattr(SHLVL,NV_IMPORT);
1391*b30d1939SAndy Fiddaman #if SHOPT_SPAWN
1392*b30d1939SAndy Fiddaman 	{
1393*b30d1939SAndy Fiddaman 		/*
1394*b30d1939SAndy Fiddaman 		 * try to find the pathname for this interpreter
1395*b30d1939SAndy Fiddaman 		 * try using environment variable _ or argv[0]
1396*b30d1939SAndy Fiddaman 		 */
1397*b30d1939SAndy Fiddaman 		char *cp=nv_getval(L_ARGNOD);
1398*b30d1939SAndy Fiddaman 		char buff[PATH_MAX+1];
1399*b30d1939SAndy Fiddaman 		shp->gd->shpath = 0;
1400*b30d1939SAndy Fiddaman #if _AST_VERSION >= 20090202L
1401*b30d1939SAndy Fiddaman 		if((n = pathprog(NiL, buff, sizeof(buff))) > 0 && n <= sizeof(buff))
1402*b30d1939SAndy Fiddaman 			shp->gd->shpath = strdup(buff);
1403*b30d1939SAndy Fiddaman #else
1404*b30d1939SAndy Fiddaman 		sfprintf(shp->strbuf,"/proc/%d/exe",getpid());
1405*b30d1939SAndy Fiddaman 		if((n=readlink(sfstruse(shp->strbuf),buff,sizeof(buff)-1))>0)
1406*b30d1939SAndy Fiddaman 		{
1407*b30d1939SAndy Fiddaman 			buff[n] = 0;
1408*b30d1939SAndy Fiddaman 			shp->gd->shpath = strdup(buff);
1409*b30d1939SAndy Fiddaman 		}
1410*b30d1939SAndy Fiddaman #endif
1411*b30d1939SAndy Fiddaman 		else if((cp && (sh_type(cp)&SH_TYPE_SH)) || (argc>0 && strchr(cp= *argv,'/')))
1412*b30d1939SAndy Fiddaman 		{
1413*b30d1939SAndy Fiddaman 			if(*cp=='/')
1414*b30d1939SAndy Fiddaman 				shp->gd->shpath = strdup(cp);
1415*b30d1939SAndy Fiddaman 			else if(cp = nv_getval(PWDNOD))
1416*b30d1939SAndy Fiddaman 			{
1417*b30d1939SAndy Fiddaman 				int offset = staktell();
1418*b30d1939SAndy Fiddaman 				stakputs(cp);
1419*b30d1939SAndy Fiddaman 				stakputc('/');
1420*b30d1939SAndy Fiddaman 				stakputs(argv[0]);
1421*b30d1939SAndy Fiddaman 				pathcanon(stakptr(offset),PATH_DOTDOT);
1422*b30d1939SAndy Fiddaman 				shp->gd->shpath = strdup(stakptr(offset));
1423*b30d1939SAndy Fiddaman 				stakseek(offset);
1424*b30d1939SAndy Fiddaman 			}
1425*b30d1939SAndy Fiddaman 		}
1426*b30d1939SAndy Fiddaman 	}
1427*b30d1939SAndy Fiddaman #endif
1428*b30d1939SAndy Fiddaman 	nv_putval(IFSNOD,(char*)e_sptbnl,NV_RDONLY);
1429*b30d1939SAndy Fiddaman #if SHOPT_FS_3D
1430*b30d1939SAndy Fiddaman 	nv_stack(VPATHNOD, &VPATH_init);
1431*b30d1939SAndy Fiddaman #endif /* SHOPT_FS_3D */
1432*b30d1939SAndy Fiddaman 	astconfdisc(newconf);
1433*b30d1939SAndy Fiddaman #if SHOPT_TIMEOUT
1434*b30d1939SAndy Fiddaman 	shp->st.tmout = SHOPT_TIMEOUT;
1435*b30d1939SAndy Fiddaman #endif /* SHOPT_TIMEOUT */
1436*b30d1939SAndy Fiddaman 	/* initialize jobs table */
1437*b30d1939SAndy Fiddaman 	job_clear();
1438*b30d1939SAndy Fiddaman 	sh_onoption(SH_MULTILINE);
1439*b30d1939SAndy Fiddaman 	if(argc>0)
1440*b30d1939SAndy Fiddaman 	{
1441*b30d1939SAndy Fiddaman 		int dolv_index = -1;
1442*b30d1939SAndy Fiddaman 		/* check for restricted shell */
1443*b30d1939SAndy Fiddaman 		if(type&SH_TYPE_RESTRICTED)
1444*b30d1939SAndy Fiddaman 			sh_onoption(SH_RESTRICTED);
1445*b30d1939SAndy Fiddaman #if SHOPT_PFSH
1446*b30d1939SAndy Fiddaman 		/* check for profile shell */
1447*b30d1939SAndy Fiddaman 		else if(type&SH_TYPE_PROFILE)
1448*b30d1939SAndy Fiddaman 			sh_onoption(SH_PFSH);
1449*b30d1939SAndy Fiddaman #endif
1450*b30d1939SAndy Fiddaman #if SHOPT_BASH
1451*b30d1939SAndy Fiddaman 		/* check for invocation as bash */
1452*b30d1939SAndy Fiddaman 		if(type&SH_TYPE_BASH)
1453*b30d1939SAndy Fiddaman 		{
1454*b30d1939SAndy Fiddaman 		        shp>userinit = userinit = bash_init;
1455*b30d1939SAndy Fiddaman 			sh_onoption(SH_BASH);
1456*b30d1939SAndy Fiddaman 			sh_onstate(SH_PREINIT);
1457*b30d1939SAndy Fiddaman 			(*userinit)(shp, 0);
1458*b30d1939SAndy Fiddaman 			sh_offstate(SH_PREINIT);
1459*b30d1939SAndy Fiddaman 		}
1460*b30d1939SAndy Fiddaman #endif
1461*b30d1939SAndy Fiddaman 		/* look for options */
1462*b30d1939SAndy Fiddaman 		/* shp->st.dolc is $#	*/
1463*b30d1939SAndy Fiddaman 		if((shp->st.dolc = sh_argopts(-argc,argv,shp)) < 0)
1464*b30d1939SAndy Fiddaman 		{
1465*b30d1939SAndy Fiddaman 			shp->exitval = 2;
1466*b30d1939SAndy Fiddaman 			sh_done(shp,0);
1467*b30d1939SAndy Fiddaman 		}
1468*b30d1939SAndy Fiddaman 		opt_info.disc = 0;
1469*b30d1939SAndy Fiddaman 		dolv_index = (argc-1)-shp->st.dolc;
1470*b30d1939SAndy Fiddaman 		shp->st.dolv=argv+dolv_index;
1471*b30d1939SAndy Fiddaman 		shp->st.repl_index = dolv_index;
1472*b30d1939SAndy Fiddaman 		shp->st.repl_arg = argv[dolv_index];
1473*b30d1939SAndy Fiddaman 		shp->st.dolv[0] = argv[0];
1474*b30d1939SAndy Fiddaman 		if(shp->st.dolc < 1)
1475*b30d1939SAndy Fiddaman 			sh_onoption(SH_SFLAG);
1476*b30d1939SAndy Fiddaman 		if(!sh_isoption(SH_SFLAG))
1477*b30d1939SAndy Fiddaman 		{
1478*b30d1939SAndy Fiddaman 			shp->st.dolc--;
1479*b30d1939SAndy Fiddaman 			shp->st.dolv++;
1480*b30d1939SAndy Fiddaman #if _WINIX
1481*b30d1939SAndy Fiddaman 			{
1482*b30d1939SAndy Fiddaman 				char*	name;
1483*b30d1939SAndy Fiddaman 				name = shp->st.dolv[0];
1484*b30d1939SAndy Fiddaman 				if(name[1]==':' && (name[2]=='/' || name[2]=='\\'))
1485*b30d1939SAndy Fiddaman 				{
1486*b30d1939SAndy Fiddaman #if _lib_pathposix
1487*b30d1939SAndy Fiddaman 					char*	p;
1488*b30d1939SAndy Fiddaman 
1489*b30d1939SAndy Fiddaman 					if((n = pathposix(name, NIL(char*), 0)) > 0 && (p = (char*)malloc(++n)))
1490*b30d1939SAndy Fiddaman 					{
1491*b30d1939SAndy Fiddaman 						pathposix(name, p, n);
1492*b30d1939SAndy Fiddaman 						name = p;
1493*b30d1939SAndy Fiddaman 					}
1494*b30d1939SAndy Fiddaman 					else
1495*b30d1939SAndy Fiddaman #endif
1496*b30d1939SAndy Fiddaman 					{
1497*b30d1939SAndy Fiddaman 						name[1] = name[0];
1498*b30d1939SAndy Fiddaman 						name[0] = name[2] = '/';
1499*b30d1939SAndy Fiddaman 					}
1500*b30d1939SAndy Fiddaman 				}
1501*b30d1939SAndy Fiddaman 			}
1502*b30d1939SAndy Fiddaman #endif /* _WINIX */
1503*b30d1939SAndy Fiddaman 		}
1504*b30d1939SAndy Fiddaman 		if(beenhere==1)
1505*b30d1939SAndy Fiddaman 		{
1506*b30d1939SAndy Fiddaman 			struct lconv*	lc;
1507*b30d1939SAndy Fiddaman 			shp->decomma = (lc=localeconv()) && lc->decimal_point && *lc->decimal_point==',';
1508*b30d1939SAndy Fiddaman 			beenhere = 2;
1509*b30d1939SAndy Fiddaman 		}
1510*b30d1939SAndy Fiddaman 	}
1511*b30d1939SAndy Fiddaman #if SHOPT_PFSH
1512*b30d1939SAndy Fiddaman 	if (sh_isoption(SH_PFSH))
1513*b30d1939SAndy Fiddaman 	{
1514*b30d1939SAndy Fiddaman 		struct passwd *pw = getpwuid(shp->gd->userid);
1515*b30d1939SAndy Fiddaman 		if(pw)
1516*b30d1939SAndy Fiddaman 			shp->gd->user = strdup(pw->pw_name);
1517*b30d1939SAndy Fiddaman 
1518*b30d1939SAndy Fiddaman 	}
1519*b30d1939SAndy Fiddaman #endif
1520*b30d1939SAndy Fiddaman 	/* set[ug]id scripts require the -p flag */
1521*b30d1939SAndy Fiddaman 	if(shp->gd->userid!=shp->gd->euserid || shp->gd->groupid!=shp->gd->egroupid)
1522*b30d1939SAndy Fiddaman 	{
1523*b30d1939SAndy Fiddaman #ifdef SHOPT_P_SUID
1524*b30d1939SAndy Fiddaman 		/* require sh -p to run setuid and/or setgid */
1525*b30d1939SAndy Fiddaman 		if(!sh_isoption(SH_PRIVILEGED) && shp->gd->userid >= SHOPT_P_SUID)
1526*b30d1939SAndy Fiddaman 		{
1527*b30d1939SAndy Fiddaman 			setuid(shp->gd->euserid=shp->gd->userid);
1528*b30d1939SAndy Fiddaman 			setgid(shp->gd->egroupid=shp->gd->groupid);
1529*b30d1939SAndy Fiddaman 		}
1530*b30d1939SAndy Fiddaman 		else
1531*b30d1939SAndy Fiddaman #endif /* SHOPT_P_SUID */
1532*b30d1939SAndy Fiddaman 			sh_onoption(SH_PRIVILEGED);
1533*b30d1939SAndy Fiddaman #ifdef SHELLMAGIC
1534*b30d1939SAndy Fiddaman 		/* careful of #! setuid scripts with name beginning with - */
1535*b30d1939SAndy Fiddaman 		if(shp->login_sh && argv[1] && strcmp(argv[0],argv[1])==0)
1536*b30d1939SAndy Fiddaman 			errormsg(SH_DICT,ERROR_exit(1),e_prohibited);
1537*b30d1939SAndy Fiddaman #endif /*SHELLMAGIC*/
1538*b30d1939SAndy Fiddaman 	}
1539*b30d1939SAndy Fiddaman 	else
1540*b30d1939SAndy Fiddaman 		sh_offoption(SH_PRIVILEGED);
1541*b30d1939SAndy Fiddaman 	/* shname for $0 in profiles and . scripts */
1542*b30d1939SAndy Fiddaman 	if(sh_isdevfd(argv[1]))
1543*b30d1939SAndy Fiddaman 		shp->shname = strdup(argv[0]);
1544*b30d1939SAndy Fiddaman 	else
1545*b30d1939SAndy Fiddaman 		shp->shname = strdup(shp->st.dolv[0]);
1546*b30d1939SAndy Fiddaman 	/*
1547*b30d1939SAndy Fiddaman 	 * return here for shell script execution
1548*b30d1939SAndy Fiddaman 	 * but not for parenthesis subshells
1549*b30d1939SAndy Fiddaman 	 */
1550*b30d1939SAndy Fiddaman 	error_info.id = strdup(shp->st.dolv[0]); /* error_info.id is $0 */
1551*b30d1939SAndy Fiddaman 	shp->jmpbuffer = (void*)&shp->checkbase;
1552*b30d1939SAndy Fiddaman 	sh_pushcontext(shp,&shp->checkbase,SH_JMPSCRIPT);
1553*b30d1939SAndy Fiddaman 	shp->st.self = &shp->global;
1554*b30d1939SAndy Fiddaman         shp->topscope = (Shscope_t*)shp->st.self;
1555*b30d1939SAndy Fiddaman 	sh_offstate(SH_INIT);
1556*b30d1939SAndy Fiddaman 	login_files[0] = (char*)e_profile;
1557*b30d1939SAndy Fiddaman 	login_files[1] = ".profile";
1558*b30d1939SAndy Fiddaman 	shp->gd->login_files = login_files;
1559*b30d1939SAndy Fiddaman 	shp->bltindata.version = SH_VERSION;
1560*b30d1939SAndy Fiddaman 	shp->bltindata.shp = shp;
1561*b30d1939SAndy Fiddaman 	shp->bltindata.shrun = sh_run;
1562*b30d1939SAndy Fiddaman 	shp->bltindata.shtrap = sh_trap;
1563*b30d1939SAndy Fiddaman 	shp->bltindata.shexit = sh_exit;
1564*b30d1939SAndy Fiddaman 	shp->bltindata.shbltin = sh_addbuiltin;
1565*b30d1939SAndy Fiddaman #if _AST_VERSION >= 20080617L
1566*b30d1939SAndy Fiddaman 	shp->bltindata.shgetenv = sh_getenv;
1567*b30d1939SAndy Fiddaman 	shp->bltindata.shsetenv = sh_setenviron;
1568*b30d1939SAndy Fiddaman 	astintercept(&shp->bltindata,1);
1569*b30d1939SAndy Fiddaman #endif
1570*b30d1939SAndy Fiddaman #if 0
1571*b30d1939SAndy Fiddaman #define NV_MKINTTYPE(x,y,z)	nv_mkinttype(#x,sizeof(x),(x)-1<0,(y),(Namdisc_t*)z);
1572*b30d1939SAndy Fiddaman 	NV_MKINTTYPE(pid_t,"process id",0);
1573*b30d1939SAndy Fiddaman 	NV_MKINTTYPE(gid_t,"group id",0);
1574*b30d1939SAndy Fiddaman 	NV_MKINTTYPE(uid_t,"user id",0);
1575*b30d1939SAndy Fiddaman 	NV_MKINTTYPE(size_t,(const char*)0,0);
1576*b30d1939SAndy Fiddaman 	NV_MKINTTYPE(ssize_t,(const char*)0,0);
1577*b30d1939SAndy Fiddaman 	NV_MKINTTYPE(off_t,"offset in bytes",0);
1578*b30d1939SAndy Fiddaman 	NV_MKINTTYPE(ino_t,"\ai-\anode number",0);
1579*b30d1939SAndy Fiddaman 	NV_MKINTTYPE(mode_t,(const char*)0,&modedisc);
1580*b30d1939SAndy Fiddaman 	NV_MKINTTYPE(dev_t,"device id",0);
1581*b30d1939SAndy Fiddaman 	NV_MKINTTYPE(nlink_t,"hard link count",0);
1582*b30d1939SAndy Fiddaman 	NV_MKINTTYPE(blkcnt_t,"block count",0);
1583*b30d1939SAndy Fiddaman 	NV_MKINTTYPE(time_t,"seconds since the epoch",0);
1584*b30d1939SAndy Fiddaman 	nv_mkstat();
1585*b30d1939SAndy Fiddaman #endif
1586*b30d1939SAndy Fiddaman 	if(shp->userinit=userinit)
1587*b30d1939SAndy Fiddaman 		(*userinit)(shp, 0);
1588*b30d1939SAndy Fiddaman 	shp->exittrap = 0;
1589*b30d1939SAndy Fiddaman 	shp->errtrap = 0;
1590*b30d1939SAndy Fiddaman 	shp->end_fn = 0;
1591*b30d1939SAndy Fiddaman 	return(shp);
1592*b30d1939SAndy Fiddaman }
1593*b30d1939SAndy Fiddaman 
sh_getinterp(void)1594*b30d1939SAndy Fiddaman Shell_t *sh_getinterp(void)
1595*b30d1939SAndy Fiddaman {
1596*b30d1939SAndy Fiddaman 	return(&sh);
1597*b30d1939SAndy Fiddaman }
1598*b30d1939SAndy Fiddaman 
1599*b30d1939SAndy Fiddaman /*
1600*b30d1939SAndy Fiddaman  * reinitialize before executing a script
1601*b30d1939SAndy Fiddaman  */
sh_reinit(char * argv[])1602*b30d1939SAndy Fiddaman int sh_reinit(char *argv[])
1603*b30d1939SAndy Fiddaman {
1604*b30d1939SAndy Fiddaman 	Shell_t	*shp = sh_getinterp();
1605*b30d1939SAndy Fiddaman 	Shopt_t opt;
1606*b30d1939SAndy Fiddaman 	Namval_t *np,*npnext;
1607*b30d1939SAndy Fiddaman 	Dt_t	*dp;
1608*b30d1939SAndy Fiddaman 	struct adata
1609*b30d1939SAndy Fiddaman 	{
1610*b30d1939SAndy Fiddaman 		Shell_t		*sh;
1611*b30d1939SAndy Fiddaman 		void		*extra[2];
1612*b30d1939SAndy Fiddaman 	} data;
1613*b30d1939SAndy Fiddaman 	for(np=dtfirst(shp->fun_tree);np;np=npnext)
1614*b30d1939SAndy Fiddaman 	{
1615*b30d1939SAndy Fiddaman 		if((dp=shp->fun_tree)->walk)
1616*b30d1939SAndy Fiddaman 			dp = dp->walk;
1617*b30d1939SAndy Fiddaman 		npnext = (Namval_t*)dtnext(shp->fun_tree,np);
1618*b30d1939SAndy Fiddaman 		if(np>= shgd->bltin_cmds && np < &shgd->bltin_cmds[nbltins])
1619*b30d1939SAndy Fiddaman 			continue;
1620*b30d1939SAndy Fiddaman 		if(is_abuiltin(np) && nv_isattr(np,NV_EXPORT))
1621*b30d1939SAndy Fiddaman 			continue;
1622*b30d1939SAndy Fiddaman 		if(*np->nvname=='/')
1623*b30d1939SAndy Fiddaman 			continue;
1624*b30d1939SAndy Fiddaman 		nv_delete(np,dp,NV_NOFREE);
1625*b30d1939SAndy Fiddaman 	}
1626*b30d1939SAndy Fiddaman 	dtclose(shp->alias_tree);
1627*b30d1939SAndy Fiddaman 	shp->alias_tree = inittree(shp,shtab_aliases);
1628*b30d1939SAndy Fiddaman 	shp->last_root = shp->var_tree;
1629*b30d1939SAndy Fiddaman 	shp->inuse_bits = 0;
1630*b30d1939SAndy Fiddaman 	if(shp->userinit)
1631*b30d1939SAndy Fiddaman 		(*shp->userinit)(shp, 1);
1632*b30d1939SAndy Fiddaman 	if(shp->heredocs)
1633*b30d1939SAndy Fiddaman 	{
1634*b30d1939SAndy Fiddaman 		sfclose(shp->heredocs);
1635*b30d1939SAndy Fiddaman 		shp->heredocs = 0;
1636*b30d1939SAndy Fiddaman 	}
1637*b30d1939SAndy Fiddaman 	/* remove locals */
1638*b30d1939SAndy Fiddaman 	sh_onstate(SH_INIT);
1639*b30d1939SAndy Fiddaman 	memset(&data,0,sizeof(data));
1640*b30d1939SAndy Fiddaman 	data.sh = shp;
1641*b30d1939SAndy Fiddaman 	nv_scan(shp->var_tree,sh_envnolocal,(void*)&data,NV_EXPORT,0);
1642*b30d1939SAndy Fiddaman 	nv_scan(shp->var_tree,sh_envnolocal,(void*)&data,NV_ARRAY,NV_ARRAY);
1643*b30d1939SAndy Fiddaman 	sh_offstate(SH_INIT);
1644*b30d1939SAndy Fiddaman 	memset(shp->st.trapcom,0,(shp->st.trapmax+1)*sizeof(char*));
1645*b30d1939SAndy Fiddaman 	memset((void*)&opt,0,sizeof(opt));
1646*b30d1939SAndy Fiddaman #if SHOPT_NAMESPACE
1647*b30d1939SAndy Fiddaman 	if(shp->namespace)
1648*b30d1939SAndy Fiddaman 	{
1649*b30d1939SAndy Fiddaman 		dp=nv_dict(shp->namespace);
1650*b30d1939SAndy Fiddaman 		if(dp==shp->var_tree)
1651*b30d1939SAndy Fiddaman 			shp->var_tree = dtview(dp,0);
1652*b30d1939SAndy Fiddaman 		_nv_unset(shp->namespace,NV_RDONLY);
1653*b30d1939SAndy Fiddaman 		shp->namespace = 0;
1654*b30d1939SAndy Fiddaman 	}
1655*b30d1939SAndy Fiddaman #endif /* SHOPT_NAMESPACE */
1656*b30d1939SAndy Fiddaman 	if(sh_isoption(SH_TRACKALL))
1657*b30d1939SAndy Fiddaman 		on_option(&opt,SH_TRACKALL);
1658*b30d1939SAndy Fiddaman 	if(sh_isoption(SH_EMACS))
1659*b30d1939SAndy Fiddaman 		on_option(&opt,SH_EMACS);
1660*b30d1939SAndy Fiddaman 	if(sh_isoption(SH_GMACS))
1661*b30d1939SAndy Fiddaman 		on_option(&opt,SH_GMACS);
1662*b30d1939SAndy Fiddaman 	if(sh_isoption(SH_VI))
1663*b30d1939SAndy Fiddaman 		on_option(&opt,SH_VI);
1664*b30d1939SAndy Fiddaman 	if(sh_isoption(SH_VIRAW))
1665*b30d1939SAndy Fiddaman 		on_option(&opt,SH_VIRAW);
1666*b30d1939SAndy Fiddaman 	shp->options = opt;
1667*b30d1939SAndy Fiddaman 	/* set up new args */
1668*b30d1939SAndy Fiddaman 	if(argv)
1669*b30d1939SAndy Fiddaman 		shp->arglist = sh_argcreate(argv);
1670*b30d1939SAndy Fiddaman 	if(shp->arglist)
1671*b30d1939SAndy Fiddaman 		sh_argreset(shp,shp->arglist,NIL(struct dolnod*));
1672*b30d1939SAndy Fiddaman 	shp->envlist=0;
1673*b30d1939SAndy Fiddaman 	shp->curenv = 0;
1674*b30d1939SAndy Fiddaman 	shp->shname = error_info.id = strdup(shp->st.dolv[0]);
1675*b30d1939SAndy Fiddaman 	sh_offstate(SH_FORKED);
1676*b30d1939SAndy Fiddaman 	shp->fn_depth = shp->dot_depth = 0;
1677*b30d1939SAndy Fiddaman 	sh_sigreset(0);
1678*b30d1939SAndy Fiddaman 	if(!(SHLVL->nvalue.ip))
1679*b30d1939SAndy Fiddaman 	{
1680*b30d1939SAndy Fiddaman 		shlvl = 0;
1681*b30d1939SAndy Fiddaman 		SHLVL->nvalue.ip = &shlvl;
1682*b30d1939SAndy Fiddaman 		nv_onattr(SHLVL,NV_INTEGER|NV_EXPORT|NV_NOFREE);
1683*b30d1939SAndy Fiddaman 	}
1684*b30d1939SAndy Fiddaman 	*SHLVL->nvalue.ip +=1;
1685*b30d1939SAndy Fiddaman 	nv_offattr(SHLVL,NV_IMPORT);
1686*b30d1939SAndy Fiddaman 	shp->st.filename = strdup(shp->lastarg);
1687*b30d1939SAndy Fiddaman 	nv_delete((Namval_t*)0, (Dt_t*)0, 0);
1688*b30d1939SAndy Fiddaman 	job.exitval = 0;
1689*b30d1939SAndy Fiddaman 	shp->inpipe = shp->outpipe = 0;
1690*b30d1939SAndy Fiddaman 	job_clear();
1691*b30d1939SAndy Fiddaman 	job.in_critical = 0;
1692*b30d1939SAndy Fiddaman 	shp->exittrap = 0;
1693*b30d1939SAndy Fiddaman 	shp->errtrap = 0;
1694*b30d1939SAndy Fiddaman 	shp->end_fn = 0;
1695*b30d1939SAndy Fiddaman 	return(1);
1696*b30d1939SAndy Fiddaman }
1697*b30d1939SAndy Fiddaman 
1698*b30d1939SAndy Fiddaman /*
1699*b30d1939SAndy Fiddaman  * set when creating a local variable of this name
1700*b30d1939SAndy Fiddaman  */
nv_cover(register Namval_t * np)1701*b30d1939SAndy Fiddaman Namfun_t *nv_cover(register Namval_t *np)
1702*b30d1939SAndy Fiddaman {
1703*b30d1939SAndy Fiddaman 	if(np==IFSNOD || np==PATHNOD || np==SHELLNOD || np==FPATHNOD || np==CDPNOD || np==SECONDS || np==ENVNOD || np==LINENO)
1704*b30d1939SAndy Fiddaman 		return(np->nvfun);
1705*b30d1939SAndy Fiddaman #ifdef _hdr_locale
1706*b30d1939SAndy Fiddaman 	if(np==LCALLNOD || np==LCTYPENOD || np==LCMSGNOD || np==LCCOLLNOD || np==LCNUMNOD || np==LANGNOD)
1707*b30d1939SAndy Fiddaman 		return(np->nvfun);
1708*b30d1939SAndy Fiddaman #endif
1709*b30d1939SAndy Fiddaman 	 return(0);
1710*b30d1939SAndy Fiddaman }
1711*b30d1939SAndy Fiddaman 
1712*b30d1939SAndy Fiddaman static const char *shdiscnames[] = { "tilde", 0};
1713*b30d1939SAndy Fiddaman 
1714*b30d1939SAndy Fiddaman #ifdef SHOPT_STATS
1715*b30d1939SAndy Fiddaman struct Stats
1716*b30d1939SAndy Fiddaman {
1717*b30d1939SAndy Fiddaman 	Namfun_t	hdr;
1718*b30d1939SAndy Fiddaman 	Shell_t		*sh;
1719*b30d1939SAndy Fiddaman 	char		*nodes;
1720*b30d1939SAndy Fiddaman 	int		numnodes;
1721*b30d1939SAndy Fiddaman 	int		current;
1722*b30d1939SAndy Fiddaman };
1723*b30d1939SAndy Fiddaman 
next_stat(register Namval_t * np,Dt_t * root,Namfun_t * fp)1724*b30d1939SAndy Fiddaman static Namval_t *next_stat(register Namval_t* np, Dt_t *root,Namfun_t *fp)
1725*b30d1939SAndy Fiddaman {
1726*b30d1939SAndy Fiddaman 	struct Stats *sp = (struct Stats*)fp;
1727*b30d1939SAndy Fiddaman 	if(!root)
1728*b30d1939SAndy Fiddaman 		sp->current = 0;
1729*b30d1939SAndy Fiddaman 	else if(++sp->current>=sp->numnodes)
1730*b30d1939SAndy Fiddaman 		return(0);
1731*b30d1939SAndy Fiddaman 	return(nv_namptr(sp->nodes,sp->current));
1732*b30d1939SAndy Fiddaman }
1733*b30d1939SAndy Fiddaman 
create_stat(Namval_t * np,const char * name,int flag,Namfun_t * fp)1734*b30d1939SAndy Fiddaman static Namval_t *create_stat(Namval_t *np,const char *name,int flag,Namfun_t *fp)
1735*b30d1939SAndy Fiddaman {
1736*b30d1939SAndy Fiddaman 	struct Stats		*sp = (struct Stats*)fp;
1737*b30d1939SAndy Fiddaman 	register const char	*cp=name;
1738*b30d1939SAndy Fiddaman 	register int		i=0,n;
1739*b30d1939SAndy Fiddaman 	Namval_t		*nq=0;
1740*b30d1939SAndy Fiddaman 	Shell_t			*shp = sp->sh;
1741*b30d1939SAndy Fiddaman 	if(!name)
1742*b30d1939SAndy Fiddaman 		return(SH_STATS);
1743*b30d1939SAndy Fiddaman 	while((i=*cp++) && i != '=' && i != '+' && i!='[');
1744*b30d1939SAndy Fiddaman 	n = (cp-1) -name;
1745*b30d1939SAndy Fiddaman 	for(i=0; i < sp->numnodes; i++)
1746*b30d1939SAndy Fiddaman 	{
1747*b30d1939SAndy Fiddaman 		nq = nv_namptr(sp->nodes,i);
1748*b30d1939SAndy Fiddaman 		if((n==0||memcmp(name,nq->nvname,n)==0) && nq->nvname[n]==0)
1749*b30d1939SAndy Fiddaman 			goto found;
1750*b30d1939SAndy Fiddaman 	}
1751*b30d1939SAndy Fiddaman 	nq = 0;
1752*b30d1939SAndy Fiddaman found:
1753*b30d1939SAndy Fiddaman 	if(nq)
1754*b30d1939SAndy Fiddaman 	{
1755*b30d1939SAndy Fiddaman 		fp->last = (char*)&name[n];
1756*b30d1939SAndy Fiddaman 		shp->last_table = SH_STATS;
1757*b30d1939SAndy Fiddaman 	}
1758*b30d1939SAndy Fiddaman 	else
1759*b30d1939SAndy Fiddaman 		errormsg(SH_DICT,ERROR_exit(1),e_notelem,n,name,nv_name(np));
1760*b30d1939SAndy Fiddaman 	return(nq);
1761*b30d1939SAndy Fiddaman }
1762*b30d1939SAndy Fiddaman 
1763*b30d1939SAndy Fiddaman static const Namdisc_t stat_disc =
1764*b30d1939SAndy Fiddaman {
1765*b30d1939SAndy Fiddaman 	0, 0, 0, 0, 0,
1766*b30d1939SAndy Fiddaman 	create_stat,
1767*b30d1939SAndy Fiddaman 	0, 0,
1768*b30d1939SAndy Fiddaman 	next_stat
1769*b30d1939SAndy Fiddaman };
1770*b30d1939SAndy Fiddaman 
name_stat(Namval_t * np,Namfun_t * fp)1771*b30d1939SAndy Fiddaman static char *name_stat(Namval_t *np, Namfun_t *fp)
1772*b30d1939SAndy Fiddaman {
1773*b30d1939SAndy Fiddaman 	Shell_t	*shp = sh_getinterp();
1774*b30d1939SAndy Fiddaman 	sfprintf(shp->strbuf,".sh.stats.%s",np->nvname);
1775*b30d1939SAndy Fiddaman 	return(sfstruse(shp->strbuf));
1776*b30d1939SAndy Fiddaman }
1777*b30d1939SAndy Fiddaman 
1778*b30d1939SAndy Fiddaman static const Namdisc_t	stat_child_disc =
1779*b30d1939SAndy Fiddaman {
1780*b30d1939SAndy Fiddaman 	0,0,0,0,0,0,0,
1781*b30d1939SAndy Fiddaman 	name_stat
1782*b30d1939SAndy Fiddaman };
1783*b30d1939SAndy Fiddaman 
1784*b30d1939SAndy Fiddaman static Namfun_t	 stat_child_fun =
1785*b30d1939SAndy Fiddaman {
1786*b30d1939SAndy Fiddaman 	&stat_child_disc, 1, 0, sizeof(Namfun_t)
1787*b30d1939SAndy Fiddaman };
1788*b30d1939SAndy Fiddaman 
stat_init(Shell_t * shp)1789*b30d1939SAndy Fiddaman static void stat_init(Shell_t *shp)
1790*b30d1939SAndy Fiddaman {
1791*b30d1939SAndy Fiddaman 	int		i,nstat = STAT_SUBSHELL+1;
1792*b30d1939SAndy Fiddaman 	struct Stats	*sp = newof(0,struct Stats,1,nstat*NV_MINSZ);
1793*b30d1939SAndy Fiddaman 	Namval_t	*np;
1794*b30d1939SAndy Fiddaman 	sp->numnodes = nstat;
1795*b30d1939SAndy Fiddaman 	sp->nodes = (char*)(sp+1);
1796*b30d1939SAndy Fiddaman 	shgd->stats = (int*)calloc(sizeof(int),nstat);
1797*b30d1939SAndy Fiddaman 	sp->sh = shp;
1798*b30d1939SAndy Fiddaman 	for(i=0; i < nstat; i++)
1799*b30d1939SAndy Fiddaman 	{
1800*b30d1939SAndy Fiddaman 		np = nv_namptr(sp->nodes,i);
1801*b30d1939SAndy Fiddaman 		np->nvfun = &stat_child_fun;
1802*b30d1939SAndy Fiddaman 		np->nvname = (char*)shtab_stats[i].sh_name;
1803*b30d1939SAndy Fiddaman 		nv_onattr(np,NV_RDONLY|NV_MINIMAL|NV_NOFREE|NV_INTEGER);
1804*b30d1939SAndy Fiddaman 		nv_setsize(np,10);
1805*b30d1939SAndy Fiddaman 		np->nvalue.ip = &shgd->stats[i];
1806*b30d1939SAndy Fiddaman 	}
1807*b30d1939SAndy Fiddaman 	sp->hdr.dsize = sizeof(struct Stats) + nstat*(sizeof(int)+NV_MINSZ);
1808*b30d1939SAndy Fiddaman 	sp->hdr.disc = &stat_disc;
1809*b30d1939SAndy Fiddaman 	nv_stack(SH_STATS,&sp->hdr);
1810*b30d1939SAndy Fiddaman 	sp->hdr.nofree = 1;
1811*b30d1939SAndy Fiddaman 	nv_setvtree(SH_STATS);
1812*b30d1939SAndy Fiddaman }
1813*b30d1939SAndy Fiddaman #else
1814*b30d1939SAndy Fiddaman #   define stat_init(x)
1815*b30d1939SAndy Fiddaman #endif /* SHOPT_STATS */
1816*b30d1939SAndy Fiddaman 
1817*b30d1939SAndy Fiddaman /*
1818*b30d1939SAndy Fiddaman  * Initialize the shell name and alias table
1819*b30d1939SAndy Fiddaman  */
nv_init(Shell_t * shp)1820*b30d1939SAndy Fiddaman static Init_t *nv_init(Shell_t *shp)
1821*b30d1939SAndy Fiddaman {
1822*b30d1939SAndy Fiddaman 	double d=0;
1823*b30d1939SAndy Fiddaman 	ip = newof(0,Init_t,1,0);
1824*b30d1939SAndy Fiddaman 	if(!ip)
1825*b30d1939SAndy Fiddaman 		return(0);
1826*b30d1939SAndy Fiddaman 	shp->nvfun.last = (char*)shp;
1827*b30d1939SAndy Fiddaman 	shp->nvfun.nofree = 1;
1828*b30d1939SAndy Fiddaman 	ip->sh = shp;
1829*b30d1939SAndy Fiddaman 	shp->var_base = shp->var_tree = inittree(shp,shtab_variables);
1830*b30d1939SAndy Fiddaman 	SHLVL->nvalue.ip = &shlvl;
1831*b30d1939SAndy Fiddaman 	ip->IFS_init.hdr.disc = &IFS_disc;
1832*b30d1939SAndy Fiddaman 	ip->PATH_init.disc = &RESTRICTED_disc;
1833*b30d1939SAndy Fiddaman 	ip->PATH_init.nofree = 1;
1834*b30d1939SAndy Fiddaman 	ip->FPATH_init.disc = &RESTRICTED_disc;
1835*b30d1939SAndy Fiddaman 	ip->FPATH_init.nofree = 1;
1836*b30d1939SAndy Fiddaman 	ip->CDPATH_init.disc = &CDPATH_disc;
1837*b30d1939SAndy Fiddaman 	ip->CDPATH_init.nofree = 1;
1838*b30d1939SAndy Fiddaman 	ip->SHELL_init.disc = &RESTRICTED_disc;
1839*b30d1939SAndy Fiddaman 	ip->SHELL_init.nofree = 1;
1840*b30d1939SAndy Fiddaman 	ip->ENV_init.disc = &RESTRICTED_disc;
1841*b30d1939SAndy Fiddaman 	ip->ENV_init.nofree = 1;
1842*b30d1939SAndy Fiddaman 	ip->VISUAL_init.disc = &EDITOR_disc;
1843*b30d1939SAndy Fiddaman 	ip->VISUAL_init.nofree = 1;
1844*b30d1939SAndy Fiddaman 	ip->EDITOR_init.disc = &EDITOR_disc;
1845*b30d1939SAndy Fiddaman 	ip->EDITOR_init.nofree = 1;
1846*b30d1939SAndy Fiddaman 	ip->HISTFILE_init.disc = &HISTFILE_disc;
1847*b30d1939SAndy Fiddaman 	ip->HISTFILE_init.nofree = 1;
1848*b30d1939SAndy Fiddaman 	ip->HISTSIZE_init.disc = &HISTFILE_disc;
1849*b30d1939SAndy Fiddaman 	ip->HISTSIZE_init.nofree = 1;
1850*b30d1939SAndy Fiddaman 	ip->OPTINDEX_init.disc = &OPTINDEX_disc;
1851*b30d1939SAndy Fiddaman 	ip->OPTINDEX_init.nofree = 1;
1852*b30d1939SAndy Fiddaman 	ip->SECONDS_init.hdr.disc = &SECONDS_disc;
1853*b30d1939SAndy Fiddaman 	ip->SECONDS_init.hdr.nofree = 1;
1854*b30d1939SAndy Fiddaman 	ip->RAND_init.hdr.disc = &RAND_disc;
1855*b30d1939SAndy Fiddaman 	ip->RAND_init.hdr.nofree = 1;
1856*b30d1939SAndy Fiddaman 	ip->RAND_init.sh = shp;
1857*b30d1939SAndy Fiddaman 	ip->SH_MATCH_init.hdr.disc = &SH_MATCH_disc;
1858*b30d1939SAndy Fiddaman 	ip->SH_MATCH_init.hdr.nofree = 1;
1859*b30d1939SAndy Fiddaman 	ip->SH_MATH_init.disc = &SH_MATH_disc;
1860*b30d1939SAndy Fiddaman 	ip->SH_MATH_init.nofree = 1;
1861*b30d1939SAndy Fiddaman #if SHOPT_COSHELL
1862*b30d1939SAndy Fiddaman 	ip->SH_JOBPOOL_init.disc = &SH_JOBPOOL_disc;
1863*b30d1939SAndy Fiddaman 	ip->SH_JOBPOOL_init.nofree = 1;
1864*b30d1939SAndy Fiddaman 	nv_stack(SH_JOBPOOL, &ip->SH_JOBPOOL_init);
1865*b30d1939SAndy Fiddaman #endif /* SHOPT_COSHELL */
1866*b30d1939SAndy Fiddaman 	ip->SH_VERSION_init.disc = &SH_VERSION_disc;
1867*b30d1939SAndy Fiddaman 	ip->SH_VERSION_init.nofree = 1;
1868*b30d1939SAndy Fiddaman 	ip->LINENO_init.disc = &LINENO_disc;
1869*b30d1939SAndy Fiddaman 	ip->LINENO_init.nofree = 1;
1870*b30d1939SAndy Fiddaman 	ip->L_ARG_init.disc = &L_ARG_disc;
1871*b30d1939SAndy Fiddaman 	ip->L_ARG_init.nofree = 1;
1872*b30d1939SAndy Fiddaman #ifdef _hdr_locale
1873*b30d1939SAndy Fiddaman 	ip->LC_TYPE_init.disc = &LC_disc;
1874*b30d1939SAndy Fiddaman 	ip->LC_TYPE_init.nofree = 1;
1875*b30d1939SAndy Fiddaman 	ip->LC_NUM_init.disc = &LC_disc;
1876*b30d1939SAndy Fiddaman 	ip->LC_NUM_init.nofree = 1;
1877*b30d1939SAndy Fiddaman 	ip->LC_COLL_init.disc = &LC_disc;
1878*b30d1939SAndy Fiddaman 	ip->LC_COLL_init.nofree = 1;
1879*b30d1939SAndy Fiddaman 	ip->LC_MSG_init.disc = &LC_disc;
1880*b30d1939SAndy Fiddaman 	ip->LC_MSG_init.nofree = 1;
1881*b30d1939SAndy Fiddaman 	ip->LC_ALL_init.disc = &LC_disc;
1882*b30d1939SAndy Fiddaman 	ip->LC_ALL_init.nofree = 1;
1883*b30d1939SAndy Fiddaman 	ip->LANG_init.disc = &LC_disc;
1884*b30d1939SAndy Fiddaman 	ip->LANG_init.nofree = 1;
1885*b30d1939SAndy Fiddaman #endif /* _hdr_locale */
1886*b30d1939SAndy Fiddaman 	nv_stack(IFSNOD, &ip->IFS_init.hdr);
1887*b30d1939SAndy Fiddaman 	ip->IFS_init.hdr.nofree = 1;
1888*b30d1939SAndy Fiddaman 	nv_stack(PATHNOD, &ip->PATH_init);
1889*b30d1939SAndy Fiddaman 	nv_stack(FPATHNOD, &ip->FPATH_init);
1890*b30d1939SAndy Fiddaman 	nv_stack(CDPNOD, &ip->CDPATH_init);
1891*b30d1939SAndy Fiddaman 	nv_stack(SHELLNOD, &ip->SHELL_init);
1892*b30d1939SAndy Fiddaman 	nv_stack(ENVNOD, &ip->ENV_init);
1893*b30d1939SAndy Fiddaman 	nv_stack(VISINOD, &ip->VISUAL_init);
1894*b30d1939SAndy Fiddaman 	nv_stack(EDITNOD, &ip->EDITOR_init);
1895*b30d1939SAndy Fiddaman 	nv_stack(HISTFILE, &ip->HISTFILE_init);
1896*b30d1939SAndy Fiddaman 	nv_stack(HISTSIZE, &ip->HISTSIZE_init);
1897*b30d1939SAndy Fiddaman 	nv_stack(OPTINDNOD, &ip->OPTINDEX_init);
1898*b30d1939SAndy Fiddaman 	nv_stack(SECONDS, &ip->SECONDS_init.hdr);
1899*b30d1939SAndy Fiddaman 	nv_stack(L_ARGNOD, &ip->L_ARG_init);
1900*b30d1939SAndy Fiddaman 	nv_putval(SECONDS, (char*)&d, NV_DOUBLE);
1901*b30d1939SAndy Fiddaman 	nv_stack(RANDNOD, &ip->RAND_init.hdr);
1902*b30d1939SAndy Fiddaman 	d = (shp->gd->pid&RANDMASK);
1903*b30d1939SAndy Fiddaman 	nv_putval(RANDNOD, (char*)&d, NV_DOUBLE);
1904*b30d1939SAndy Fiddaman 	nv_stack(LINENO, &ip->LINENO_init);
1905*b30d1939SAndy Fiddaman 	SH_MATCHNOD->nvfun =  &ip->SH_MATCH_init.hdr;
1906*b30d1939SAndy Fiddaman 	nv_putsub(SH_MATCHNOD,(char*)0,10);
1907*b30d1939SAndy Fiddaman 	nv_stack(SH_MATHNOD, &ip->SH_MATH_init);
1908*b30d1939SAndy Fiddaman 	nv_stack(SH_VERSIONNOD, &ip->SH_VERSION_init);
1909*b30d1939SAndy Fiddaman #ifdef _hdr_locale
1910*b30d1939SAndy Fiddaman 	nv_stack(LCTYPENOD, &ip->LC_TYPE_init);
1911*b30d1939SAndy Fiddaman 	nv_stack(LCALLNOD, &ip->LC_ALL_init);
1912*b30d1939SAndy Fiddaman 	nv_stack(LCMSGNOD, &ip->LC_MSG_init);
1913*b30d1939SAndy Fiddaman 	nv_stack(LCCOLLNOD, &ip->LC_COLL_init);
1914*b30d1939SAndy Fiddaman 	nv_stack(LCNUMNOD, &ip->LC_NUM_init);
1915*b30d1939SAndy Fiddaman 	nv_stack(LANGNOD, &ip->LANG_init);
1916*b30d1939SAndy Fiddaman #endif /* _hdr_locale */
1917*b30d1939SAndy Fiddaman 	(PPIDNOD)->nvalue.lp = (&shp->gd->ppid);
1918*b30d1939SAndy Fiddaman 	(TMOUTNOD)->nvalue.lp = (&shp->st.tmout);
1919*b30d1939SAndy Fiddaman 	(MCHKNOD)->nvalue.lp = (&sh_mailchk);
1920*b30d1939SAndy Fiddaman 	(OPTINDNOD)->nvalue.lp = (&shp->st.optindex);
1921*b30d1939SAndy Fiddaman 	/* set up the seconds clock */
1922*b30d1939SAndy Fiddaman 	shp->alias_tree = inittree(shp,shtab_aliases);
1923*b30d1939SAndy Fiddaman 	shp->track_tree = dtopen(&_Nvdisc,Dtset);
1924*b30d1939SAndy Fiddaman 	shp->bltin_tree = inittree(shp,(const struct shtable2*)shtab_builtins);
1925*b30d1939SAndy Fiddaman 	shp->fun_tree = dtopen(&_Nvdisc,Dtoset);
1926*b30d1939SAndy Fiddaman 	dtview(shp->fun_tree,shp->bltin_tree);
1927*b30d1939SAndy Fiddaman 	nv_mount(DOTSHNOD, "type", shp->typedict=dtopen(&_Nvdisc,Dtoset));
1928*b30d1939SAndy Fiddaman 	nv_adddisc(DOTSHNOD, shdiscnames, (Namval_t**)0);
1929*b30d1939SAndy Fiddaman 	DOTSHNOD->nvalue.cp = Empty;
1930*b30d1939SAndy Fiddaman 	nv_onattr(DOTSHNOD,NV_RDONLY);
1931*b30d1939SAndy Fiddaman 	SH_LINENO->nvalue.ip = &shp->st.lineno;
1932*b30d1939SAndy Fiddaman 	VERSIONNOD->nvalue.nrp = newof(0,struct Namref,1,0);
1933*b30d1939SAndy Fiddaman         VERSIONNOD->nvalue.nrp->np = SH_VERSIONNOD;
1934*b30d1939SAndy Fiddaman         VERSIONNOD->nvalue.nrp->root = nv_dict(DOTSHNOD);
1935*b30d1939SAndy Fiddaman         VERSIONNOD->nvalue.nrp->table = DOTSHNOD;
1936*b30d1939SAndy Fiddaman 	nv_onattr(VERSIONNOD,NV_REF);
1937*b30d1939SAndy Fiddaman 	math_init(shp);
1938*b30d1939SAndy Fiddaman 	if(!shgd->stats)
1939*b30d1939SAndy Fiddaman 		stat_init(shp);
1940*b30d1939SAndy Fiddaman 	return(ip);
1941*b30d1939SAndy Fiddaman }
1942*b30d1939SAndy Fiddaman 
1943*b30d1939SAndy Fiddaman /*
1944*b30d1939SAndy Fiddaman  * initialize name-value pairs
1945*b30d1939SAndy Fiddaman  */
1946*b30d1939SAndy Fiddaman 
inittree(Shell_t * shp,const struct shtable2 * name_vals)1947*b30d1939SAndy Fiddaman static Dt_t *inittree(Shell_t *shp,const struct shtable2 *name_vals)
1948*b30d1939SAndy Fiddaman {
1949*b30d1939SAndy Fiddaman 	register Namval_t *np;
1950*b30d1939SAndy Fiddaman 	register const struct shtable2 *tp;
1951*b30d1939SAndy Fiddaman 	register unsigned n = 0;
1952*b30d1939SAndy Fiddaman 	register Dt_t *treep;
1953*b30d1939SAndy Fiddaman 	Dt_t *base_treep, *dict;
1954*b30d1939SAndy Fiddaman 	for(tp=name_vals;*tp->sh_name;tp++)
1955*b30d1939SAndy Fiddaman 		n++;
1956*b30d1939SAndy Fiddaman 	np = (Namval_t*)calloc(n,sizeof(Namval_t));
1957*b30d1939SAndy Fiddaman 	if(!shgd->bltin_nodes)
1958*b30d1939SAndy Fiddaman 	{
1959*b30d1939SAndy Fiddaman 		shgd->bltin_nodes = np;
1960*b30d1939SAndy Fiddaman 		shgd->bltin_nnodes = n;
1961*b30d1939SAndy Fiddaman 	}
1962*b30d1939SAndy Fiddaman 	else if(name_vals==(const struct shtable2*)shtab_builtins)
1963*b30d1939SAndy Fiddaman 	{
1964*b30d1939SAndy Fiddaman 		shgd->bltin_cmds = np;
1965*b30d1939SAndy Fiddaman 		nbltins = n;
1966*b30d1939SAndy Fiddaman 	}
1967*b30d1939SAndy Fiddaman 	base_treep = treep = dtopen(&_Nvdisc,Dtoset);
1968*b30d1939SAndy Fiddaman 	treep->user = (void*)shp;
1969*b30d1939SAndy Fiddaman 	for(tp=name_vals;*tp->sh_name;tp++,np++)
1970*b30d1939SAndy Fiddaman 	{
1971*b30d1939SAndy Fiddaman 		if((np->nvname = strrchr(tp->sh_name,'.')) && np->nvname!=((char*)tp->sh_name))
1972*b30d1939SAndy Fiddaman 			np->nvname++;
1973*b30d1939SAndy Fiddaman 		else
1974*b30d1939SAndy Fiddaman 		{
1975*b30d1939SAndy Fiddaman 			np->nvname = (char*)tp->sh_name;
1976*b30d1939SAndy Fiddaman 			treep = base_treep;
1977*b30d1939SAndy Fiddaman 		}
1978*b30d1939SAndy Fiddaman 		np->nvenv = 0;
1979*b30d1939SAndy Fiddaman 		if(name_vals==(const struct shtable2*)shtab_builtins)
1980*b30d1939SAndy Fiddaman 			np->nvalue.bfp = (Nambfp_f)((struct shtable3*)tp)->sh_value;
1981*b30d1939SAndy Fiddaman 		else
1982*b30d1939SAndy Fiddaman 		{
1983*b30d1939SAndy Fiddaman 			if(name_vals == shtab_variables)
1984*b30d1939SAndy Fiddaman 				np->nvfun = &shp->nvfun;
1985*b30d1939SAndy Fiddaman 			np->nvalue.cp = (char*)tp->sh_value;
1986*b30d1939SAndy Fiddaman 		}
1987*b30d1939SAndy Fiddaman 		nv_setattr(np,tp->sh_number);
1988*b30d1939SAndy Fiddaman 		if(nv_isattr(np,NV_TABLE))
1989*b30d1939SAndy Fiddaman 			nv_mount(np,(const char*)0,dict=dtopen(&_Nvdisc,Dtoset));
1990*b30d1939SAndy Fiddaman 		if(nv_isattr(np,NV_INTEGER))
1991*b30d1939SAndy Fiddaman 			nv_setsize(np,10);
1992*b30d1939SAndy Fiddaman 		else
1993*b30d1939SAndy Fiddaman 			nv_setsize(np,0);
1994*b30d1939SAndy Fiddaman 		dtinsert(treep,np);
1995*b30d1939SAndy Fiddaman 		if(nv_istable(np))
1996*b30d1939SAndy Fiddaman 			treep = dict;
1997*b30d1939SAndy Fiddaman 	}
1998*b30d1939SAndy Fiddaman 	return(treep);
1999*b30d1939SAndy Fiddaman }
2000*b30d1939SAndy Fiddaman 
2001*b30d1939SAndy Fiddaman /*
2002*b30d1939SAndy Fiddaman  * read in the process environment and set up name-value pairs
2003*b30d1939SAndy Fiddaman  * skip over items that are not name-value pairs
2004*b30d1939SAndy Fiddaman  */
2005*b30d1939SAndy Fiddaman 
env_init(Shell_t * shp)2006*b30d1939SAndy Fiddaman static void env_init(Shell_t *shp)
2007*b30d1939SAndy Fiddaman {
2008*b30d1939SAndy Fiddaman 	register char		*cp;
2009*b30d1939SAndy Fiddaman 	register Namval_t	*np,*mp;
2010*b30d1939SAndy Fiddaman 	register char		**ep=environ;
2011*b30d1939SAndy Fiddaman 	char			*dp,*next=0;
2012*b30d1939SAndy Fiddaman 	int			nenv=0,k=0,size=0;
2013*b30d1939SAndy Fiddaman 	Namval_t		*np0;
2014*b30d1939SAndy Fiddaman #ifdef _ENV_H
2015*b30d1939SAndy Fiddaman 	shp->env = env_open(environ,3);
2016*b30d1939SAndy Fiddaman 	env_delete(shp->env,"_");
2017*b30d1939SAndy Fiddaman #endif
2018*b30d1939SAndy Fiddaman 	if(!ep)
2019*b30d1939SAndy Fiddaman 		goto skip;
2020*b30d1939SAndy Fiddaman 	while(*ep++)
2021*b30d1939SAndy Fiddaman 		nenv++;
2022*b30d1939SAndy Fiddaman 	np = newof(0,Namval_t,nenv,0);
2023*b30d1939SAndy Fiddaman 	for(np0=np,ep=environ;cp= *ep; ep++)
2024*b30d1939SAndy Fiddaman 	{
2025*b30d1939SAndy Fiddaman 		dp = strchr(cp,'=');
2026*b30d1939SAndy Fiddaman 		if(!dp)
2027*b30d1939SAndy Fiddaman 			continue;
2028*b30d1939SAndy Fiddaman 		*dp++ = 0;
2029*b30d1939SAndy Fiddaman 		if(mp = dtmatch(shp->var_base,cp))
2030*b30d1939SAndy Fiddaman 		{
2031*b30d1939SAndy Fiddaman                         if(strcmp(cp,VERSIONNOD->nvname)==0)
2032*b30d1939SAndy Fiddaman                         {
2033*b30d1939SAndy Fiddaman                                 dp[-1] = '=';
2034*b30d1939SAndy Fiddaman                                 continue;
2035*b30d1939SAndy Fiddaman                         }
2036*b30d1939SAndy Fiddaman 			mp->nvenv = (char*)cp;
2037*b30d1939SAndy Fiddaman 			dp[-1] = '=';
2038*b30d1939SAndy Fiddaman 		}
2039*b30d1939SAndy Fiddaman 		else if(*cp=='A' && cp[1]=='_' && cp[2]=='_' && cp[3]=='z' && cp[4]==0)
2040*b30d1939SAndy Fiddaman 		{
2041*b30d1939SAndy Fiddaman 			dp[-1] = '=';
2042*b30d1939SAndy Fiddaman 			next = cp+4;
2043*b30d1939SAndy Fiddaman 			continue;
2044*b30d1939SAndy Fiddaman 		}
2045*b30d1939SAndy Fiddaman 		else
2046*b30d1939SAndy Fiddaman 		{
2047*b30d1939SAndy Fiddaman 			k++;
2048*b30d1939SAndy Fiddaman 			mp = np++;
2049*b30d1939SAndy Fiddaman 			mp->nvname = cp;
2050*b30d1939SAndy Fiddaman 			size += strlen(cp);
2051*b30d1939SAndy Fiddaman 		}
2052*b30d1939SAndy Fiddaman 			nv_onattr(mp,NV_IMPORT);
2053*b30d1939SAndy Fiddaman 		if(mp->nvfun || nv_isattr(mp,NV_INTEGER))
2054*b30d1939SAndy Fiddaman 			nv_putval(mp,dp,0);
2055*b30d1939SAndy Fiddaman 		else
2056*b30d1939SAndy Fiddaman 		{
2057*b30d1939SAndy Fiddaman 			mp->nvalue.cp = dp;
2058*b30d1939SAndy Fiddaman 			nv_onattr(mp,NV_NOFREE);
2059*b30d1939SAndy Fiddaman 		}
2060*b30d1939SAndy Fiddaman 		nv_onattr(mp,NV_EXPORT|NV_IMPORT);
2061*b30d1939SAndy Fiddaman 	}
2062*b30d1939SAndy Fiddaman 	np =  (Namval_t*)realloc((void*)np0,k*sizeof(Namval_t));
2063*b30d1939SAndy Fiddaman 	dp = (char*)malloc(size+k);
2064*b30d1939SAndy Fiddaman 	while(k-->0)
2065*b30d1939SAndy Fiddaman 	{
2066*b30d1939SAndy Fiddaman 		size = strlen(np->nvname);
2067*b30d1939SAndy Fiddaman 		memcpy(dp,np->nvname,size+1);
2068*b30d1939SAndy Fiddaman 		np->nvname[size] = '=';
2069*b30d1939SAndy Fiddaman 		np->nvenv = np->nvname;
2070*b30d1939SAndy Fiddaman 		np->nvname = dp;
2071*b30d1939SAndy Fiddaman 		dp += size+1;
2072*b30d1939SAndy Fiddaman 		dtinsert(shp->var_base,np++);
2073*b30d1939SAndy Fiddaman 	}
2074*b30d1939SAndy Fiddaman 	while(cp=next)
2075*b30d1939SAndy Fiddaman 	{
2076*b30d1939SAndy Fiddaman 		if(next = strchr(++cp,'='))
2077*b30d1939SAndy Fiddaman 			*next = 0;
2078*b30d1939SAndy Fiddaman 		np = nv_search(cp+2,shp->var_tree,NV_ADD);
2079*b30d1939SAndy Fiddaman 		if(np!=SHLVL && nv_isattr(np,NV_IMPORT|NV_EXPORT))
2080*b30d1939SAndy Fiddaman 		{
2081*b30d1939SAndy Fiddaman 			int flag = *(unsigned char*)cp-' ';
2082*b30d1939SAndy Fiddaman 			int size = *(unsigned char*)(cp+1)-' ';
2083*b30d1939SAndy Fiddaman 			if((flag&NV_INTEGER) && size==0)
2084*b30d1939SAndy Fiddaman 			{
2085*b30d1939SAndy Fiddaman 				/* check for floating*/
2086*b30d1939SAndy Fiddaman 				char *val = nv_getval(np);
2087*b30d1939SAndy Fiddaman 				strtol(val,&dp,10);
2088*b30d1939SAndy Fiddaman 				if(*dp=='.' || *dp=='e' || *dp=='E')
2089*b30d1939SAndy Fiddaman 				{
2090*b30d1939SAndy Fiddaman 					char *lp;
2091*b30d1939SAndy Fiddaman 					flag |= NV_DOUBLE;
2092*b30d1939SAndy Fiddaman 					if(*dp=='.')
2093*b30d1939SAndy Fiddaman 					{
2094*b30d1939SAndy Fiddaman 						strtol(dp+1,&lp,10);
2095*b30d1939SAndy Fiddaman 						if(*lp)
2096*b30d1939SAndy Fiddaman 							dp = lp;
2097*b30d1939SAndy Fiddaman 					}
2098*b30d1939SAndy Fiddaman 					if(*dp && *dp!='.')
2099*b30d1939SAndy Fiddaman 					{
2100*b30d1939SAndy Fiddaman 						flag |= NV_EXPNOTE;
2101*b30d1939SAndy Fiddaman 						size = dp-val;
2102*b30d1939SAndy Fiddaman 					}
2103*b30d1939SAndy Fiddaman 					else
2104*b30d1939SAndy Fiddaman 						size = strlen(dp);
2105*b30d1939SAndy Fiddaman 					size--;
2106*b30d1939SAndy Fiddaman 				}
2107*b30d1939SAndy Fiddaman 			}
2108*b30d1939SAndy Fiddaman 			nv_newattr(np,flag|NV_IMPORT|NV_EXPORT,size);
2109*b30d1939SAndy Fiddaman 			if((flag&(NV_INTEGER|NV_UTOL|NV_LTOU))==(NV_UTOL|NV_LTOU))
2110*b30d1939SAndy Fiddaman 				nv_mapchar(np,(flag&NV_UTOL)?e_tolower:e_toupper);
2111*b30d1939SAndy Fiddaman 		}
2112*b30d1939SAndy Fiddaman 		else
2113*b30d1939SAndy Fiddaman 			cp += 2;
2114*b30d1939SAndy Fiddaman 	}
2115*b30d1939SAndy Fiddaman skip:
2116*b30d1939SAndy Fiddaman #ifdef _ENV_H
2117*b30d1939SAndy Fiddaman 	env_delete(shp->env,e_envmarker);
2118*b30d1939SAndy Fiddaman #endif
2119*b30d1939SAndy Fiddaman 	if(nv_isnull(PWDNOD) || nv_isattr(PWDNOD,NV_TAGGED))
2120*b30d1939SAndy Fiddaman 	{
2121*b30d1939SAndy Fiddaman 		nv_offattr(PWDNOD,NV_TAGGED);
2122*b30d1939SAndy Fiddaman 		path_pwd(shp,0);
2123*b30d1939SAndy Fiddaman 	}
2124*b30d1939SAndy Fiddaman 	if((cp = nv_getval(SHELLNOD)) && (sh_type(cp)&SH_TYPE_RESTRICTED))
2125*b30d1939SAndy Fiddaman 		sh_onoption(SH_RESTRICTED); /* restricted shell */
2126*b30d1939SAndy Fiddaman 	return;
2127*b30d1939SAndy Fiddaman }
2128*b30d1939SAndy Fiddaman 
2129*b30d1939SAndy Fiddaman /*
2130*b30d1939SAndy Fiddaman  * terminate shell and free up the space
2131*b30d1939SAndy Fiddaman  */
sh_term(void)2132*b30d1939SAndy Fiddaman int sh_term(void)
2133*b30d1939SAndy Fiddaman {
2134*b30d1939SAndy Fiddaman 	sfdisc(sfstdin,SF_POPDISC);
2135*b30d1939SAndy Fiddaman 	free((char*)sh.outbuff);
2136*b30d1939SAndy Fiddaman 	stakset(NIL(char*),0);
2137*b30d1939SAndy Fiddaman 	return(0);
2138*b30d1939SAndy Fiddaman }
2139*b30d1939SAndy Fiddaman 
2140*b30d1939SAndy Fiddaman /* function versions of these */
2141*b30d1939SAndy Fiddaman 
2142*b30d1939SAndy Fiddaman #define DISABLE	/* proto workaround */
2143*b30d1939SAndy Fiddaman 
DISABLE(int opt)2144*b30d1939SAndy Fiddaman unsigned long sh_isoption DISABLE (int opt)
2145*b30d1939SAndy Fiddaman {
2146*b30d1939SAndy Fiddaman 	return(sh_isoption(opt));
2147*b30d1939SAndy Fiddaman }
2148*b30d1939SAndy Fiddaman 
DISABLE(int opt)2149*b30d1939SAndy Fiddaman unsigned long sh_onoption DISABLE (int opt)
2150*b30d1939SAndy Fiddaman {
2151*b30d1939SAndy Fiddaman 	return(sh_onoption(opt));
2152*b30d1939SAndy Fiddaman }
2153*b30d1939SAndy Fiddaman 
DISABLE(int opt)2154*b30d1939SAndy Fiddaman unsigned long sh_offoption DISABLE (int opt)
2155*b30d1939SAndy Fiddaman {
2156*b30d1939SAndy Fiddaman 	return(sh_offoption(opt));
2157*b30d1939SAndy Fiddaman }
2158*b30d1939SAndy Fiddaman 
DISABLE(Shell_t * shp)2159*b30d1939SAndy Fiddaman void	sh_sigcheck DISABLE (Shell_t *shp)
2160*b30d1939SAndy Fiddaman {
2161*b30d1939SAndy Fiddaman 	if(!shp)
2162*b30d1939SAndy Fiddaman 		shp = sh_getinterp();
2163*b30d1939SAndy Fiddaman 	sh_sigcheck(shp);
2164*b30d1939SAndy Fiddaman }
2165*b30d1939SAndy Fiddaman 
DISABLE(void)2166*b30d1939SAndy Fiddaman Dt_t*	sh_bltin_tree DISABLE (void)
2167*b30d1939SAndy Fiddaman {
2168*b30d1939SAndy Fiddaman 	return(sh.bltin_tree);
2169*b30d1939SAndy Fiddaman }
2170*b30d1939SAndy Fiddaman 
2171*b30d1939SAndy Fiddaman /*
2172*b30d1939SAndy Fiddaman  * This code is for character mapped variables with wctrans()
2173*b30d1939SAndy Fiddaman  */
2174*b30d1939SAndy Fiddaman struct Mapchar
2175*b30d1939SAndy Fiddaman {
2176*b30d1939SAndy Fiddaman 	Namfun_t	hdr;
2177*b30d1939SAndy Fiddaman 	const char	*name;
2178*b30d1939SAndy Fiddaman 	wctrans_t	trans;
2179*b30d1939SAndy Fiddaman 	int		lctype;
2180*b30d1939SAndy Fiddaman };
2181*b30d1939SAndy Fiddaman 
put_trans(register Namval_t * np,const char * val,int flags,Namfun_t * fp)2182*b30d1939SAndy Fiddaman static void put_trans(register Namval_t* np,const char *val,int flags,Namfun_t *fp)
2183*b30d1939SAndy Fiddaman {
2184*b30d1939SAndy Fiddaman 	struct Mapchar *mp = (struct Mapchar*)fp;
2185*b30d1939SAndy Fiddaman 	int	c,offset = staktell(),off=offset;
2186*b30d1939SAndy Fiddaman 	if(val)
2187*b30d1939SAndy Fiddaman 	{
2188*b30d1939SAndy Fiddaman 		if(mp->lctype!=lctype)
2189*b30d1939SAndy Fiddaman 		{
2190*b30d1939SAndy Fiddaman 			mp->lctype = lctype;
2191*b30d1939SAndy Fiddaman 			mp->trans = wctrans(mp->name);
2192*b30d1939SAndy Fiddaman 		}
2193*b30d1939SAndy Fiddaman 		if(!mp->trans || (flags&NV_INTEGER))
2194*b30d1939SAndy Fiddaman 			goto skip;
2195*b30d1939SAndy Fiddaman 		while(c = mbchar(val))
2196*b30d1939SAndy Fiddaman 		{
2197*b30d1939SAndy Fiddaman 			c = towctrans(c,mp->trans);
2198*b30d1939SAndy Fiddaman 			stakseek(off+c);
2199*b30d1939SAndy Fiddaman 			stakseek(off);
2200*b30d1939SAndy Fiddaman 			c  = mbconv(stakptr(off),c);
2201*b30d1939SAndy Fiddaman 			off += c;
2202*b30d1939SAndy Fiddaman 			stakseek(off);
2203*b30d1939SAndy Fiddaman 		}
2204*b30d1939SAndy Fiddaman 		stakputc(0);
2205*b30d1939SAndy Fiddaman 		val = stakptr(offset);
2206*b30d1939SAndy Fiddaman 	}
2207*b30d1939SAndy Fiddaman 	else
2208*b30d1939SAndy Fiddaman 	{
2209*b30d1939SAndy Fiddaman 		nv_putv(np,val,flags,fp);
2210*b30d1939SAndy Fiddaman 		nv_disc(np,fp,NV_POP);
2211*b30d1939SAndy Fiddaman 		if(!(fp->nofree&1))
2212*b30d1939SAndy Fiddaman 			free((void*)fp);
2213*b30d1939SAndy Fiddaman 		stakseek(offset);
2214*b30d1939SAndy Fiddaman 		return;
2215*b30d1939SAndy Fiddaman 	}
2216*b30d1939SAndy Fiddaman skip:
2217*b30d1939SAndy Fiddaman 	nv_putv(np,val,flags,fp);
2218*b30d1939SAndy Fiddaman 	stakseek(offset);
2219*b30d1939SAndy Fiddaman }
2220*b30d1939SAndy Fiddaman 
2221*b30d1939SAndy Fiddaman static const Namdisc_t TRANS_disc      = {  sizeof(struct Mapchar), put_trans };
2222*b30d1939SAndy Fiddaman 
nv_mapchar(Namval_t * np,const char * name)2223*b30d1939SAndy Fiddaman Namfun_t	*nv_mapchar(Namval_t *np,const char *name)
2224*b30d1939SAndy Fiddaman {
2225*b30d1939SAndy Fiddaman 	wctrans_t	trans = name?wctrans(name):0;
2226*b30d1939SAndy Fiddaman 	struct Mapchar	*mp=0;
2227*b30d1939SAndy Fiddaman 	int		n=0,low;
2228*b30d1939SAndy Fiddaman 	if(np)
2229*b30d1939SAndy Fiddaman 		mp = (struct Mapchar*)nv_hasdisc(np,&TRANS_disc);
2230*b30d1939SAndy Fiddaman 	if(!name)
2231*b30d1939SAndy Fiddaman 		return(mp?(Namfun_t*)mp->name:0);
2232*b30d1939SAndy Fiddaman 	if(!trans)
2233*b30d1939SAndy Fiddaman 		return(0);
2234*b30d1939SAndy Fiddaman 	if(!np)
2235*b30d1939SAndy Fiddaman 		return(((Namfun_t*)0)+1);
2236*b30d1939SAndy Fiddaman 	if((low=strcmp(name,e_tolower)) && strcmp(name,e_toupper))
2237*b30d1939SAndy Fiddaman 		n += strlen(name)+1;
2238*b30d1939SAndy Fiddaman 	if(mp)
2239*b30d1939SAndy Fiddaman 	{
2240*b30d1939SAndy Fiddaman 		if(strcmp(name,mp->name)==0)
2241*b30d1939SAndy Fiddaman 			return(&mp->hdr);
2242*b30d1939SAndy Fiddaman 		nv_disc(np,&mp->hdr,NV_POP);
2243*b30d1939SAndy Fiddaman 		if(!(mp->hdr.nofree&1))
2244*b30d1939SAndy Fiddaman 			free((void*)mp);
2245*b30d1939SAndy Fiddaman 	}
2246*b30d1939SAndy Fiddaman 	mp = newof(0,struct Mapchar,1,n);
2247*b30d1939SAndy Fiddaman 	mp->trans = trans;
2248*b30d1939SAndy Fiddaman 	mp->lctype = lctype;
2249*b30d1939SAndy Fiddaman 	if(low==0)
2250*b30d1939SAndy Fiddaman 		mp->name = e_tolower;
2251*b30d1939SAndy Fiddaman 	else if(n==0)
2252*b30d1939SAndy Fiddaman 		mp->name = e_toupper;
2253*b30d1939SAndy Fiddaman 	else
2254*b30d1939SAndy Fiddaman 	{
2255*b30d1939SAndy Fiddaman 		mp->name = (char*)(mp+1);
2256*b30d1939SAndy Fiddaman 		strcpy((char*)mp->name,name);
2257*b30d1939SAndy Fiddaman 	}
2258*b30d1939SAndy Fiddaman 	mp->hdr.disc =  &TRANS_disc;
2259*b30d1939SAndy Fiddaman 	return(&mp->hdr);
2260*b30d1939SAndy Fiddaman }
2261