14887Schin /*********************************************************************** 24887Schin * * 34887Schin * This software is part of the ast package * 4*10898Sroland.mainz@nrubsig.org * Copyright (c) 1982-2009 AT&T Intellectual Property * 54887Schin * and is licensed under the * 64887Schin * Common Public License, Version 1.0 * 78462SApril.Chin@Sun.COM * by AT&T Intellectual Property * 84887Schin * * 94887Schin * A copy of the License is available at * 104887Schin * http://www.opensource.org/licenses/cpl1.0.txt * 114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 124887Schin * * 134887Schin * Information and Software Systems Research * 144887Schin * AT&T Research * 154887Schin * Florham Park NJ * 164887Schin * * 174887Schin * David Korn <dgk@research.att.com> * 184887Schin * * 194887Schin ***********************************************************************/ 204887Schin #pragma prototyped 214887Schin /* 224887Schin * 234887Schin * Shell initialization 244887Schin * 254887Schin * David Korn 264887Schin * AT&T Labs 274887Schin * 284887Schin */ 294887Schin 304887Schin #include "defs.h" 314887Schin #include <stak.h> 324887Schin #include <ccode.h> 334887Schin #include <pwd.h> 348462SApril.Chin@Sun.COM #include <tmx.h> 354887Schin #include "variables.h" 364887Schin #include "path.h" 374887Schin #include "fault.h" 384887Schin #include "name.h" 394887Schin #include "edit.h" 404887Schin #include "jobs.h" 414887Schin #include "io.h" 424887Schin #include "shlex.h" 434887Schin #include "builtins.h" 444887Schin #include "FEATURE/time" 454887Schin #include "FEATURE/dynamic" 46*10898Sroland.mainz@nrubsig.org #include "FEATURE/externs" 474887Schin #include "lexstates.h" 484887Schin #include "version.h" 494887Schin 508462SApril.Chin@Sun.COM char e_version[] = "\n@(#)$Id: Version " 518462SApril.Chin@Sun.COM #if SHOPT_AUDIT 528462SApril.Chin@Sun.COM #define ATTRS 1 538462SApril.Chin@Sun.COM "A" 548462SApril.Chin@Sun.COM #endif 558462SApril.Chin@Sun.COM #if SHOPT_BASH 568462SApril.Chin@Sun.COM #define ATTRS 1 578462SApril.Chin@Sun.COM "B" 588462SApril.Chin@Sun.COM #endif 59*10898Sroland.mainz@nrubsig.org #if SHOPT_BGX 60*10898Sroland.mainz@nrubsig.org #define ATTRS 1 61*10898Sroland.mainz@nrubsig.org "J" 62*10898Sroland.mainz@nrubsig.org #endif 638462SApril.Chin@Sun.COM #if SHOPT_ACCT 648462SApril.Chin@Sun.COM #define ATTRS 1 658462SApril.Chin@Sun.COM "L" 668462SApril.Chin@Sun.COM #endif 674887Schin #if SHOPT_MULTIBYTE 688462SApril.Chin@Sun.COM #define ATTRS 1 698462SApril.Chin@Sun.COM "M" 708462SApril.Chin@Sun.COM #endif 718462SApril.Chin@Sun.COM #if SHOPT_PFSH && _hdr_exec_attr 728462SApril.Chin@Sun.COM #define ATTRS 1 738462SApril.Chin@Sun.COM "P" 748462SApril.Chin@Sun.COM #endif 75*10898Sroland.mainz@nrubsig.org #if SHOPT_REGRESS 76*10898Sroland.mainz@nrubsig.org #define ATTRS 1 77*10898Sroland.mainz@nrubsig.org "R" 78*10898Sroland.mainz@nrubsig.org #endif 798462SApril.Chin@Sun.COM #if ATTRS 808462SApril.Chin@Sun.COM " " 818462SApril.Chin@Sun.COM #endif 828462SApril.Chin@Sun.COM SH_RELEASE " $\0\n"; 834887Schin 844887Schin #if SHOPT_BASH 858462SApril.Chin@Sun.COM extern void bash_init(Shell_t*,int); 864887Schin #endif 874887Schin 884887Schin #define RANDMASK 0x7fff 898462SApril.Chin@Sun.COM 908462SApril.Chin@Sun.COM #ifndef ARG_MAX 918462SApril.Chin@Sun.COM # define ARG_MAX (1*1024*1024) 928462SApril.Chin@Sun.COM #endif 938462SApril.Chin@Sun.COM #ifndef CHILD_MAX 948462SApril.Chin@Sun.COM # define CHILD_MAX (1*1024) 958462SApril.Chin@Sun.COM #endif 964887Schin #ifndef CLK_TCK 974887Schin # define CLK_TCK 60 984887Schin #endif /* CLK_TCK */ 994887Schin 1004887Schin #ifndef environ 1014887Schin extern char **environ; 1024887Schin #endif 1034887Schin 1044887Schin #undef getconf 1054887Schin #define getconf(x) strtol(astconf(x,NiL,NiL),NiL,0) 1064887Schin 1074887Schin struct seconds 1084887Schin { 1094887Schin Namfun_t hdr; 1104887Schin Shell_t *sh; 1114887Schin }; 1124887Schin 1134887Schin struct rand 1144887Schin { 1154887Schin Namfun_t hdr; 1164887Schin int32_t rand_last; 1174887Schin }; 1184887Schin 1194887Schin struct ifs 1204887Schin { 1214887Schin Namfun_t hdr; 1224887Schin Namval_t *ifsnp; 1234887Schin }; 1244887Schin 1254887Schin struct match 1264887Schin { 1274887Schin Namfun_t hdr; 1284887Schin char *val; 1294887Schin char *rval; 1304887Schin int vsize; 1314887Schin int nmatch; 1324887Schin int lastsub; 1334887Schin int match[2*(MATCH_MAX+1)]; 1344887Schin }; 1354887Schin 1364887Schin typedef struct _init_ 1374887Schin { 1384887Schin Shell_t *sh; 1394887Schin #if SHOPT_FS_3D 1404887Schin Namfun_t VPATH_init; 1414887Schin #endif /* SHOPT_FS_3D */ 1424887Schin struct ifs IFS_init; 1438462SApril.Chin@Sun.COM Namfun_t PATH_init; 1448462SApril.Chin@Sun.COM Namfun_t FPATH_init; 1458462SApril.Chin@Sun.COM Namfun_t CDPATH_init; 1468462SApril.Chin@Sun.COM Namfun_t SHELL_init; 1478462SApril.Chin@Sun.COM Namfun_t ENV_init; 1488462SApril.Chin@Sun.COM Namfun_t VISUAL_init; 1498462SApril.Chin@Sun.COM Namfun_t EDITOR_init; 1508462SApril.Chin@Sun.COM Namfun_t HISTFILE_init; 1518462SApril.Chin@Sun.COM Namfun_t HISTSIZE_init; 1528462SApril.Chin@Sun.COM Namfun_t OPTINDEX_init; 1534887Schin struct seconds SECONDS_init; 1544887Schin struct rand RAND_init; 1558462SApril.Chin@Sun.COM Namfun_t LINENO_init; 1568462SApril.Chin@Sun.COM Namfun_t L_ARG_init; 1578462SApril.Chin@Sun.COM Namfun_t SH_VERSION_init; 1584887Schin struct match SH_MATCH_init; 1594887Schin #ifdef _hdr_locale 1608462SApril.Chin@Sun.COM Namfun_t LC_TYPE_init; 1618462SApril.Chin@Sun.COM Namfun_t LC_NUM_init; 1628462SApril.Chin@Sun.COM Namfun_t LC_COLL_init; 1638462SApril.Chin@Sun.COM Namfun_t LC_MSG_init; 1648462SApril.Chin@Sun.COM Namfun_t LC_ALL_init; 1658462SApril.Chin@Sun.COM Namfun_t LANG_init; 1664887Schin #endif /* _hdr_locale */ 1674887Schin } Init_t; 1684887Schin 1698462SApril.Chin@Sun.COM static int nbltins; 1704887Schin static void env_init(Shell_t*); 1714887Schin static Init_t *nv_init(Shell_t*); 1724887Schin static Dt_t *inittree(Shell_t*,const struct shtable2*); 173*10898Sroland.mainz@nrubsig.org static int shlvl; 1744887Schin 1754887Schin #ifdef _WINIX 1764887Schin # define EXE "?(.exe)" 1774887Schin #else 1784887Schin # define EXE 1794887Schin #endif 1804887Schin 1814887Schin static int rand_shift; 1824887Schin 1834887Schin 1844887Schin /* 1854887Schin * Invalidate all path name bindings 1864887Schin */ 1874887Schin static void rehash(register Namval_t *np,void *data) 1884887Schin { 1894887Schin NOT_USED(data); 1904887Schin nv_onattr(np,NV_NOALIAS); 1914887Schin } 1924887Schin 1934887Schin /* 1944887Schin * out of memory routine for stak routines 1954887Schin */ 1964887Schin static char *nospace(int unused) 1974887Schin { 1984887Schin NOT_USED(unused); 1994887Schin errormsg(SH_DICT,ERROR_exit(3),e_nospace); 2004887Schin return(NIL(char*)); 2014887Schin } 2024887Schin 2034887Schin /* Trap for VISUAL and EDITOR variables */ 2044887Schin static void put_ed(register Namval_t* np,const char *val,int flags,Namfun_t *fp) 2054887Schin { 2064887Schin register const char *cp, *name=nv_name(np); 207*10898Sroland.mainz@nrubsig.org register int newopt=0; 2088462SApril.Chin@Sun.COM Shell_t *shp = nv_shell(np); 2098462SApril.Chin@Sun.COM if(*name=='E' && nv_getval(sh_scoped(shp,VISINOD))) 2104887Schin goto done; 2118462SApril.Chin@Sun.COM if(!(cp=val) && (*name=='E' || !(cp=nv_getval(sh_scoped(shp,EDITNOD))))) 2124887Schin goto done; 2134887Schin /* turn on vi or emacs option if editor name is either*/ 2144887Schin cp = path_basename(cp); 2154887Schin if(strmatch(cp,"*[Vv][Ii]*")) 216*10898Sroland.mainz@nrubsig.org newopt=SH_VI; 2174887Schin else if(strmatch(cp,"*gmacs*")) 218*10898Sroland.mainz@nrubsig.org newopt=SH_GMACS; 2194887Schin else if(strmatch(cp,"*macs*")) 220*10898Sroland.mainz@nrubsig.org newopt=SH_EMACS; 221*10898Sroland.mainz@nrubsig.org if(newopt) 222*10898Sroland.mainz@nrubsig.org { 223*10898Sroland.mainz@nrubsig.org sh_offoption(SH_VI); 224*10898Sroland.mainz@nrubsig.org sh_offoption(SH_EMACS); 225*10898Sroland.mainz@nrubsig.org sh_offoption(SH_GMACS); 226*10898Sroland.mainz@nrubsig.org sh_onoption(newopt); 227*10898Sroland.mainz@nrubsig.org } 2284887Schin done: 2294887Schin nv_putv(np, val, flags, fp); 2304887Schin } 2314887Schin 2328462SApril.Chin@Sun.COM /* Trap for HISTFILE and HISTSIZE variables */ 2338462SApril.Chin@Sun.COM static void put_history(register Namval_t* np,const char *val,int flags,Namfun_t *fp) 2348462SApril.Chin@Sun.COM { 2358462SApril.Chin@Sun.COM Shell_t *shp = nv_shell(np); 2368462SApril.Chin@Sun.COM void *histopen = shp->hist_ptr; 237*10898Sroland.mainz@nrubsig.org char *cp; 2388462SApril.Chin@Sun.COM if(val && histopen) 2398462SApril.Chin@Sun.COM { 240*10898Sroland.mainz@nrubsig.org if(np==HISTFILE && (cp=nv_getval(np)) && strcmp(val,cp)==0) 2418462SApril.Chin@Sun.COM return; 242*10898Sroland.mainz@nrubsig.org if(np==HISTSIZE && sh_arith(val)==nv_getnum(HISTSIZE)) 2438462SApril.Chin@Sun.COM return; 2448462SApril.Chin@Sun.COM hist_close(shp->hist_ptr); 2458462SApril.Chin@Sun.COM } 2468462SApril.Chin@Sun.COM nv_putv(np, val, flags, fp); 2478462SApril.Chin@Sun.COM if(histopen) 2488462SApril.Chin@Sun.COM { 2498462SApril.Chin@Sun.COM if(val) 2508462SApril.Chin@Sun.COM sh_histinit(shp); 2518462SApril.Chin@Sun.COM else 2528462SApril.Chin@Sun.COM hist_close(histopen); 2538462SApril.Chin@Sun.COM } 2548462SApril.Chin@Sun.COM } 2558462SApril.Chin@Sun.COM 2564887Schin /* Trap for OPTINDEX */ 2574887Schin static void put_optindex(Namval_t* np,const char *val,int flags,Namfun_t *fp) 2584887Schin { 2598462SApril.Chin@Sun.COM Shell_t *shp = nv_shell(np); 2604887Schin shp->st.opterror = shp->st.optchar = 0; 2614887Schin nv_putv(np, val, flags, fp); 2628462SApril.Chin@Sun.COM if(!val) 2638462SApril.Chin@Sun.COM nv_disc(np,fp,NV_POP); 2644887Schin } 2654887Schin 2664887Schin static Sfdouble_t nget_optindex(register Namval_t* np, Namfun_t *fp) 2674887Schin { 2684887Schin return((Sfdouble_t)*np->nvalue.lp); 2694887Schin } 2704887Schin 2718462SApril.Chin@Sun.COM static Namfun_t *clone_optindex(Namval_t* np, Namval_t *mp, int flags, Namfun_t *fp) 2728462SApril.Chin@Sun.COM { 2738462SApril.Chin@Sun.COM Namfun_t *dp = (Namfun_t*)malloc(sizeof(Namfun_t)); 2748462SApril.Chin@Sun.COM memcpy((void*)dp,(void*)fp,sizeof(Namfun_t)); 2758462SApril.Chin@Sun.COM mp->nvalue.lp = np->nvalue.lp; 2768462SApril.Chin@Sun.COM dp->nofree = 0; 2778462SApril.Chin@Sun.COM return(dp); 2788462SApril.Chin@Sun.COM } 2798462SApril.Chin@Sun.COM 2808462SApril.Chin@Sun.COM 2814887Schin /* Trap for restricted variables FPATH, PATH, SHELL, ENV */ 2824887Schin static void put_restricted(register Namval_t* np,const char *val,int flags,Namfun_t *fp) 2834887Schin { 2848462SApril.Chin@Sun.COM Shell_t *shp = nv_shell(np); 2858462SApril.Chin@Sun.COM int path_scoped = 0; 2864887Schin Pathcomp_t *pp; 2874887Schin char *name = nv_name(np); 2884887Schin if(!(flags&NV_RDONLY) && sh_isoption(SH_RESTRICTED)) 2894887Schin errormsg(SH_DICT,ERROR_exit(1),e_restricted,nv_name(np)); 2904887Schin if(np==PATHNOD || (path_scoped=(strcmp(name,PATHNOD->nvname)==0))) 2914887Schin { 2924887Schin nv_scan(shp->track_tree,rehash,(void*)0,NV_TAGGED,NV_TAGGED); 2934887Schin if(path_scoped && !val) 2944887Schin val = PATHNOD->nvalue.cp; 2954887Schin } 2964887Schin if(val && !(flags&NV_RDONLY) && np->nvalue.cp && strcmp(val,np->nvalue.cp)==0) 2974887Schin return; 2988462SApril.Chin@Sun.COM if(np==FPATHNOD) 2994887Schin shp->pathlist = (void*)path_unsetfpath((Pathcomp_t*)shp->pathlist); 3004887Schin nv_putv(np, val, flags, fp); 3018462SApril.Chin@Sun.COM shp->universe = 0; 3024887Schin if(shp->pathlist) 3034887Schin { 3044887Schin val = np->nvalue.cp; 3054887Schin if(np==PATHNOD || path_scoped) 3064887Schin pp = (void*)path_addpath((Pathcomp_t*)shp->pathlist,val,PATH_PATH); 3074887Schin else if(val && np==FPATHNOD) 3084887Schin pp = (void*)path_addpath((Pathcomp_t*)shp->pathlist,val,PATH_FPATH); 3094887Schin else 3104887Schin return; 3114887Schin if(shp->pathlist = (void*)pp) 3124887Schin pp->shp = shp; 3134887Schin if(!val && (flags&NV_NOSCOPE)) 3144887Schin { 3154887Schin Namval_t *mp = dtsearch(shp->var_tree,np); 3164887Schin if(mp && (val=nv_getval(mp))) 3174887Schin nv_putval(mp,val,NV_RDONLY); 3184887Schin } 3194887Schin #if 0 3204887Schin sfprintf(sfstderr,"%d: name=%s val=%s\n",getpid(),name,val); 3214887Schin path_dump((Pathcomp_t*)shp->pathlist); 3224887Schin #endif 3234887Schin } 3244887Schin } 3254887Schin 3264887Schin static void put_cdpath(register Namval_t* np,const char *val,int flags,Namfun_t *fp) 3274887Schin { 3284887Schin Pathcomp_t *pp; 3298462SApril.Chin@Sun.COM Shell_t *shp = nv_shell(np); 3304887Schin nv_putv(np, val, flags, fp); 3314887Schin if(!shp->cdpathlist) 3324887Schin return; 3334887Schin val = np->nvalue.cp; 3344887Schin pp = (void*)path_addpath((Pathcomp_t*)shp->cdpathlist,val,PATH_CDPATH); 3354887Schin if(shp->cdpathlist = (void*)pp) 3364887Schin pp->shp = shp; 3374887Schin } 3384887Schin 3394887Schin #ifdef _hdr_locale 3404887Schin /* 3414887Schin * This function needs to be modified to handle international 3424887Schin * error message translations 3434887Schin */ 3444887Schin #if ERROR_VERSION >= 20000101L 3454887Schin static char* msg_translate(const char* catalog, const char* message) 3464887Schin { 3474887Schin NOT_USED(catalog); 3484887Schin return((char*)message); 3494887Schin } 3504887Schin #else 3514887Schin static char* msg_translate(const char* message, int type) 3524887Schin { 3534887Schin NOT_USED(type); 3544887Schin return((char*)message); 3554887Schin } 3564887Schin #endif 3574887Schin 358*10898Sroland.mainz@nrubsig.org /* Trap for LC_ALL, LC_CTYPE, LC_MESSAGES, LC_COLLATE and LANG */ 3594887Schin static void put_lang(Namval_t* np,const char *val,int flags,Namfun_t *fp) 3604887Schin { 3618462SApril.Chin@Sun.COM Shell_t *shp = nv_shell(np); 3624887Schin int type; 3634887Schin char *lc_all = nv_getval(LCALLNOD); 3644887Schin char *name = nv_name(np); 365*10898Sroland.mainz@nrubsig.org if((shp->test&1) && !val && !nv_getval(np)) 366*10898Sroland.mainz@nrubsig.org return; 367*10898Sroland.mainz@nrubsig.org if(shp->test&2) 368*10898Sroland.mainz@nrubsig.org nv_putv(np, val, flags, fp); 3694887Schin if(name==(LCALLNOD)->nvname) 3704887Schin type = LC_ALL; 3714887Schin else if(name==(LCTYPENOD)->nvname) 3724887Schin type = LC_CTYPE; 3734887Schin else if(name==(LCMSGNOD)->nvname) 3744887Schin type = LC_MESSAGES; 3754887Schin else if(name==(LCCOLLNOD)->nvname) 3764887Schin type = LC_COLLATE; 3774887Schin else if(name==(LCNUMNOD)->nvname) 3784887Schin type = LC_NUMERIC; 379*10898Sroland.mainz@nrubsig.org #ifdef LC_LANG 380*10898Sroland.mainz@nrubsig.org else if(name==(LANGNOD)->nvname) 381*10898Sroland.mainz@nrubsig.org type = LC_LANG; 382*10898Sroland.mainz@nrubsig.org #else 383*10898Sroland.mainz@nrubsig.org #define LC_LANG LC_ALL 384*10898Sroland.mainz@nrubsig.org else if(name==(LANGNOD)->nvname && (!lc_all || !*lc_all)) 385*10898Sroland.mainz@nrubsig.org type = LC_LANG; 386*10898Sroland.mainz@nrubsig.org #endif 3874887Schin else 3884887Schin type= -1; 3894887Schin if(sh_isstate(SH_INIT) && type>=0 && type!=LC_ALL && lc_all && *lc_all) 3904887Schin type= -1; 391*10898Sroland.mainz@nrubsig.org if(type>=0 || type==LC_ALL || type==LC_LANG) 3924887Schin { 393*10898Sroland.mainz@nrubsig.org if(!setlocale(type,val?val:"-") && val) 3944887Schin { 3958462SApril.Chin@Sun.COM if(!sh_isstate(SH_INIT) || shp->login_sh==0) 3964887Schin errormsg(SH_DICT,0,e_badlocale,val); 3974887Schin return; 3984887Schin } 3994887Schin } 400*10898Sroland.mainz@nrubsig.org if(!(shp->test&2)) 401*10898Sroland.mainz@nrubsig.org nv_putv(np, val, flags, fp); 402*10898Sroland.mainz@nrubsig.org if(CC_NATIVE==CC_ASCII && (type==LC_ALL || type==LC_LANG || type==LC_CTYPE)) 4034887Schin { 4044887Schin if(sh_lexstates[ST_BEGIN]!=sh_lexrstates[ST_BEGIN]) 4054887Schin free((void*)sh_lexstates[ST_BEGIN]); 4064887Schin if(ast.locale.set&(1<<AST_LC_CTYPE)) 4074887Schin { 4084887Schin register int c; 4094887Schin char *state[4]; 4104887Schin sh_lexstates[ST_BEGIN] = state[0] = (char*)malloc(4*(1<<CHAR_BIT)); 4114887Schin memcpy(state[0],sh_lexrstates[ST_BEGIN],(1<<CHAR_BIT)); 4124887Schin sh_lexstates[ST_NAME] = state[1] = state[0] + (1<<CHAR_BIT); 4134887Schin memcpy(state[1],sh_lexrstates[ST_NAME],(1<<CHAR_BIT)); 4144887Schin sh_lexstates[ST_DOL] = state[2] = state[1] + (1<<CHAR_BIT); 4154887Schin memcpy(state[2],sh_lexrstates[ST_DOL],(1<<CHAR_BIT)); 4164887Schin sh_lexstates[ST_BRACE] = state[3] = state[2] + (1<<CHAR_BIT); 4174887Schin memcpy(state[3],sh_lexrstates[ST_BRACE],(1<<CHAR_BIT)); 4184887Schin for(c=0; c<(1<<CHAR_BIT); c++) 4194887Schin { 4204887Schin if(state[0][c]!=S_REG) 4214887Schin continue; 4224887Schin if(state[2][c]!=S_ERR) 4234887Schin continue; 4244887Schin if(isblank(c)) 4254887Schin { 4264887Schin state[0][c]=0; 4274887Schin state[1][c]=S_BREAK; 4284887Schin state[2][c]=S_BREAK; 4294887Schin continue; 4304887Schin } 4314887Schin if(!isalpha(c)) 4324887Schin continue; 4334887Schin state[0][c]=S_NAME; 4344887Schin if(state[1][c]==S_REG) 4354887Schin state[1][c]=0; 4364887Schin state[2][c]=S_ALP; 4374887Schin if(state[3][c]==S_ERR) 4384887Schin state[3][c]=0; 4394887Schin } 4404887Schin } 4414887Schin else 4424887Schin { 4434887Schin sh_lexstates[ST_BEGIN]=(char*)sh_lexrstates[ST_BEGIN]; 4444887Schin sh_lexstates[ST_NAME]=(char*)sh_lexrstates[ST_NAME]; 4454887Schin sh_lexstates[ST_DOL]=(char*)sh_lexrstates[ST_DOL]; 4464887Schin sh_lexstates[ST_BRACE]=(char*)sh_lexrstates[ST_BRACE]; 4474887Schin } 4484887Schin } 4494887Schin #if ERROR_VERSION < 20000101L 4504887Schin if(type==LC_ALL || type==LC_MESSAGES) 4514887Schin error_info.translate = msg_translate; 4524887Schin #endif 4534887Schin } 4544887Schin #endif /* _hdr_locale */ 4554887Schin 4564887Schin /* Trap for IFS assignment and invalidates state table */ 4574887Schin static void put_ifs(register Namval_t* np,const char *val,int flags,Namfun_t *fp) 4584887Schin { 4594887Schin register struct ifs *ip = (struct ifs*)fp; 460*10898Sroland.mainz@nrubsig.org Shell_t *shp; 4614887Schin ip->ifsnp = 0; 462*10898Sroland.mainz@nrubsig.org if(!val) 463*10898Sroland.mainz@nrubsig.org { 464*10898Sroland.mainz@nrubsig.org fp = nv_stack(np, NIL(Namfun_t*)); 465*10898Sroland.mainz@nrubsig.org if(fp && !fp->nofree) 466*10898Sroland.mainz@nrubsig.org free((void*)fp); 467*10898Sroland.mainz@nrubsig.org } 4684887Schin if(val != np->nvalue.cp) 4694887Schin nv_putv(np, val, flags, fp); 470*10898Sroland.mainz@nrubsig.org if(!val && !(flags&NV_CLONE) && (fp=np->nvfun) && !fp->disc && (shp=(Shell_t*)(fp->last))) 471*10898Sroland.mainz@nrubsig.org nv_stack(np,&((Init_t*)shp->init_context)->IFS_init.hdr); 4724887Schin } 4734887Schin 4744887Schin /* 4754887Schin * This is the lookup function for IFS 4764887Schin * It keeps the sh.ifstable up to date 4774887Schin */ 4784887Schin static char* get_ifs(register Namval_t* np, Namfun_t *fp) 4794887Schin { 4804887Schin register struct ifs *ip = (struct ifs*)fp; 4814887Schin register char *cp, *value; 4824887Schin register int c,n; 4838462SApril.Chin@Sun.COM register Shell_t *shp = nv_shell(np); 4844887Schin value = nv_getv(np,fp); 4854887Schin if(np!=ip->ifsnp) 4864887Schin { 4874887Schin ip->ifsnp = np; 4884887Schin memset(shp->ifstable,0,(1<<CHAR_BIT)); 4894887Schin if(cp=value) 4904887Schin { 4914887Schin #if SHOPT_MULTIBYTE 4924887Schin while(n=mbsize(cp),c= *(unsigned char*)cp) 4934887Schin #else 4944887Schin while(c= *(unsigned char*)cp++) 4954887Schin #endif /* SHOPT_MULTIBYTE */ 4964887Schin { 4974887Schin #if SHOPT_MULTIBYTE 4984887Schin cp++; 4994887Schin if(n>1) 5004887Schin { 5014887Schin cp += (n-1); 5024887Schin shp->ifstable[c] = S_MBYTE; 5034887Schin continue; 5044887Schin } 5054887Schin #endif /* SHOPT_MULTIBYTE */ 5064887Schin n = S_DELIM; 5074887Schin if(c== *cp) 5084887Schin cp++; 5094887Schin else if(c=='\n') 5104887Schin n = S_NL; 5114887Schin else if(isspace(c)) 5124887Schin n = S_SPACE; 5134887Schin shp->ifstable[c] = n; 5144887Schin } 5154887Schin } 5164887Schin else 5174887Schin { 5184887Schin shp->ifstable[' '] = shp->ifstable['\t'] = S_SPACE; 5194887Schin shp->ifstable['\n'] = S_NL; 5204887Schin } 5214887Schin } 5224887Schin return(value); 5234887Schin } 5244887Schin 5254887Schin /* 5264887Schin * these functions are used to get and set the SECONDS variable 5274887Schin */ 5284887Schin #ifdef timeofday 5294887Schin # define dtime(tp) ((double)((tp)->tv_sec)+1e-6*((double)((tp)->tv_usec))) 5304887Schin # define tms timeval 5314887Schin #else 5324887Schin # define dtime(tp) (((double)times(tp))/sh.lim.clk_tck) 5334887Schin # define timeofday(a) 5344887Schin #endif 5354887Schin 5364887Schin static void put_seconds(register Namval_t* np,const char *val,int flags,Namfun_t *fp) 5374887Schin { 5384887Schin double d; 5394887Schin struct tms tp; 5404887Schin if(!val) 5414887Schin { 542*10898Sroland.mainz@nrubsig.org fp = nv_stack(np, NIL(Namfun_t*)); 543*10898Sroland.mainz@nrubsig.org if(fp && !fp->nofree) 544*10898Sroland.mainz@nrubsig.org free((void*)fp); 545*10898Sroland.mainz@nrubsig.org nv_putv(np, val, flags, fp); 5464887Schin return; 5474887Schin } 5484887Schin if(!np->nvalue.dp) 5494887Schin { 5504887Schin nv_setsize(np,3); 5518462SApril.Chin@Sun.COM nv_onattr(np,NV_DOUBLE); 5524887Schin np->nvalue.dp = new_of(double,0); 5534887Schin } 5544887Schin nv_putv(np, val, flags, fp); 5554887Schin d = *np->nvalue.dp; 5564887Schin timeofday(&tp); 5574887Schin *np->nvalue.dp = dtime(&tp)-d; 5584887Schin } 5594887Schin 5604887Schin static char* get_seconds(register Namval_t* np, Namfun_t *fp) 5614887Schin { 5628462SApril.Chin@Sun.COM Shell_t *shp = nv_shell(np); 5634887Schin register int places = nv_size(np); 5644887Schin struct tms tp; 5654887Schin double d, offset = (np->nvalue.dp?*np->nvalue.dp:0); 5664887Schin NOT_USED(fp); 5674887Schin timeofday(&tp); 5684887Schin d = dtime(&tp)- offset; 5698462SApril.Chin@Sun.COM sfprintf(shp->strbuf,"%.*f",places,d); 5708462SApril.Chin@Sun.COM return(sfstruse(shp->strbuf)); 5714887Schin } 5724887Schin 5734887Schin static Sfdouble_t nget_seconds(register Namval_t* np, Namfun_t *fp) 5744887Schin { 5754887Schin struct tms tp; 5764887Schin double offset = (np->nvalue.dp?*np->nvalue.dp:0); 5774887Schin NOT_USED(fp); 5784887Schin timeofday(&tp); 5794887Schin return(dtime(&tp)- offset); 5804887Schin } 5814887Schin 5824887Schin /* 5834887Schin * These three functions are used to get and set the RANDOM variable 5844887Schin */ 5854887Schin static void put_rand(register Namval_t* np,const char *val,int flags,Namfun_t *fp) 5864887Schin { 5874887Schin struct rand *rp = (struct rand*)fp; 5884887Schin register long n; 5894887Schin if(!val) 5904887Schin { 591*10898Sroland.mainz@nrubsig.org fp = nv_stack(np, NIL(Namfun_t*)); 592*10898Sroland.mainz@nrubsig.org if(fp && !fp->nofree) 593*10898Sroland.mainz@nrubsig.org free((void*)fp); 5944887Schin nv_unset(np); 5954887Schin return; 5964887Schin } 5974887Schin if(flags&NV_INTEGER) 5984887Schin n = *(double*)val; 5994887Schin else 6004887Schin n = sh_arith(val); 6014887Schin srand((int)(n&RANDMASK)); 6024887Schin rp->rand_last = -1; 6034887Schin if(!np->nvalue.lp) 6044887Schin np->nvalue.lp = &rp->rand_last; 6054887Schin } 6064887Schin 6074887Schin /* 6084887Schin * get random number in range of 0 - 2**15 6094887Schin * never pick same number twice in a row 6104887Schin */ 6114887Schin static Sfdouble_t nget_rand(register Namval_t* np, Namfun_t *fp) 6124887Schin { 6134887Schin register long cur, last= *np->nvalue.lp; 6144887Schin NOT_USED(fp); 6154887Schin do 6164887Schin cur = (rand()>>rand_shift)&RANDMASK; 6174887Schin while(cur==last); 6184887Schin *np->nvalue.lp = cur; 6194887Schin return((Sfdouble_t)cur); 6204887Schin } 6214887Schin 6224887Schin static char* get_rand(register Namval_t* np, Namfun_t *fp) 6234887Schin { 6244887Schin register long n = nget_rand(np,fp); 6254887Schin return(fmtbase(n, 10, 0)); 6264887Schin } 6274887Schin 6284887Schin /* 6294887Schin * These three routines are for LINENO 6304887Schin */ 6314887Schin static Sfdouble_t nget_lineno(Namval_t* np, Namfun_t *fp) 6324887Schin { 6334887Schin double d=1; 6344887Schin if(error_info.line >0) 6354887Schin d = error_info.line; 6364887Schin else if(error_info.context && error_info.context->line>0) 6374887Schin d = error_info.context->line; 6384887Schin NOT_USED(np); 6394887Schin NOT_USED(fp); 6404887Schin return(d); 6414887Schin } 6424887Schin 6434887Schin static void put_lineno(Namval_t* np,const char *val,int flags,Namfun_t *fp) 6444887Schin { 6454887Schin register long n; 6468462SApril.Chin@Sun.COM Shell_t *shp = nv_shell(np); 6474887Schin if(!val) 6484887Schin { 649*10898Sroland.mainz@nrubsig.org fp = nv_stack(np, NIL(Namfun_t*)); 650*10898Sroland.mainz@nrubsig.org if(fp && !fp->nofree) 651*10898Sroland.mainz@nrubsig.org free((void*)fp); 6524887Schin nv_unset(np); 6534887Schin return; 6544887Schin } 6554887Schin if(flags&NV_INTEGER) 6564887Schin n = *(double*)val; 6574887Schin else 6584887Schin n = sh_arith(val); 6594887Schin shp->st.firstline += nget_lineno(np,fp)+1-n; 6604887Schin } 6614887Schin 6624887Schin static char* get_lineno(register Namval_t* np, Namfun_t *fp) 6634887Schin { 6644887Schin register long n = nget_lineno(np,fp); 6654887Schin return(fmtbase(n, 10, 0)); 6664887Schin } 6674887Schin 6684887Schin static char* get_lastarg(Namval_t* np, Namfun_t *fp) 6694887Schin { 670*10898Sroland.mainz@nrubsig.org Shell_t *shp = nv_shell(np); 671*10898Sroland.mainz@nrubsig.org char *cp; 672*10898Sroland.mainz@nrubsig.org int pid; 673*10898Sroland.mainz@nrubsig.org if(sh_isstate(SH_INIT) && (cp=shp->lastarg) && *cp=='*' && (pid=strtol(cp+1,&cp,10)) && *cp=='*') 674*10898Sroland.mainz@nrubsig.org nv_putval(np,(pid==getppid()?cp+1:0),0); 6758462SApril.Chin@Sun.COM return(shp->lastarg); 6764887Schin } 6774887Schin 6784887Schin static void put_lastarg(Namval_t* np,const char *val,int flags,Namfun_t *fp) 6794887Schin { 6808462SApril.Chin@Sun.COM Shell_t *shp = nv_shell(np); 6814887Schin if(flags&NV_INTEGER) 6824887Schin { 6838462SApril.Chin@Sun.COM sfprintf(shp->strbuf,"%.*g",12,*((double*)val)); 6848462SApril.Chin@Sun.COM val = sfstruse(shp->strbuf); 6854887Schin } 686*10898Sroland.mainz@nrubsig.org if(val) 687*10898Sroland.mainz@nrubsig.org val = strdup(val); 6888462SApril.Chin@Sun.COM if(shp->lastarg && !nv_isattr(np,NV_NOFREE)) 6898462SApril.Chin@Sun.COM free((void*)shp->lastarg); 6904887Schin else 6914887Schin nv_offattr(np,NV_NOFREE); 692*10898Sroland.mainz@nrubsig.org shp->lastarg = (char*)val; 693*10898Sroland.mainz@nrubsig.org nv_offattr(np,NV_EXPORT); 694*10898Sroland.mainz@nrubsig.org np->nvenv = 0; 6954887Schin } 6964887Schin 6974887Schin static int hasgetdisc(register Namfun_t *fp) 6984887Schin { 6994887Schin while(fp && !fp->disc->getnum && !fp->disc->getval) 7004887Schin fp = fp->next; 7014887Schin return(fp!=0); 7024887Schin } 7034887Schin 7044887Schin /* 7054887Schin * store the most recent value for use in .sh.match 7064887Schin */ 7074887Schin void sh_setmatch(const char *v, int vsize, int nmatch, int match[]) 7084887Schin { 7094887Schin struct match *mp = (struct match*)(SH_MATCHNOD->nvfun); 7104887Schin register int i,n; 7114887Schin if(mp->nmatch = nmatch) 7124887Schin { 7134887Schin memcpy(mp->match,match,nmatch*2*sizeof(match[0])); 7144887Schin for(n=match[0],i=1; i < 2*nmatch; i++) 7154887Schin { 7164887Schin if(mp->match[i] < n) 7174887Schin n = mp->match[i]; 7184887Schin } 7194887Schin for(vsize=0,i=0; i < 2*nmatch; i++) 7204887Schin { 7214887Schin if((mp->match[i] -= n) > vsize) 7224887Schin vsize = mp->match[i]; 7234887Schin } 7244887Schin v += n; 7254887Schin if(vsize >= mp->vsize) 7264887Schin { 7274887Schin if(mp->vsize) 7284887Schin mp->val = (char*)realloc(mp->val,vsize+1); 7294887Schin else 7304887Schin mp->val = (char*)malloc(vsize+1); 7314887Schin mp->vsize = vsize; 7324887Schin } 7334887Schin memcpy(mp->val,v,vsize); 7344887Schin mp->val[vsize] = 0; 7358462SApril.Chin@Sun.COM nv_putsub(SH_MATCHNOD, NIL(char*), (nmatch-1)|ARRAY_FILL); 7364887Schin mp->lastsub = -1; 7374887Schin } 7384887Schin } 7394887Schin 7404887Schin #define array_scan(np) ((nv_arrayptr(np)->nelem&ARRAY_SCAN)) 7414887Schin 7424887Schin static char* get_match(register Namval_t* np, Namfun_t *fp) 7434887Schin { 7444887Schin struct match *mp = (struct match*)fp; 7454887Schin int sub,n; 7464887Schin char *val; 7474887Schin sub = nv_aindex(np); 7484887Schin if(sub>=mp->nmatch) 7494887Schin return(0); 7504887Schin if(sub==mp->lastsub) 7514887Schin return(mp->rval); 7524887Schin if(mp->rval) 7534887Schin { 7544887Schin free((void*)mp->rval); 7554887Schin mp->rval = 0; 7564887Schin } 7574887Schin n = mp->match[2*sub+1]-mp->match[2*sub]; 7584887Schin if(n<=0) 7594887Schin return(""); 7604887Schin val = mp->val+mp->match[2*sub]; 7614887Schin if(mp->val[mp->match[2*sub+1]]==0) 7624887Schin return(val); 7634887Schin mp->rval = (char*)malloc(n+1); 7644887Schin mp->lastsub = sub; 7654887Schin memcpy(mp->rval,val,n); 7664887Schin mp->rval[n] = 0; 7674887Schin return(mp->rval); 7684887Schin } 7694887Schin 7708462SApril.Chin@Sun.COM static const Namdisc_t SH_MATCH_disc = { sizeof(struct match), 0, get_match }; 7718462SApril.Chin@Sun.COM 7728462SApril.Chin@Sun.COM static char* get_version(register Namval_t* np, Namfun_t *fp) 7738462SApril.Chin@Sun.COM { 7748462SApril.Chin@Sun.COM return(nv_getv(np,fp)); 7758462SApril.Chin@Sun.COM } 7768462SApril.Chin@Sun.COM 7778462SApril.Chin@Sun.COM static Sfdouble_t nget_version(register Namval_t* np, Namfun_t *fp) 7788462SApril.Chin@Sun.COM { 7798462SApril.Chin@Sun.COM register const char *cp = e_version + strlen(e_version)-10; 7808462SApril.Chin@Sun.COM register int c; 7818462SApril.Chin@Sun.COM Sflong_t t = 0; 7828462SApril.Chin@Sun.COM NOT_USED(fp); 7838462SApril.Chin@Sun.COM 7848462SApril.Chin@Sun.COM while (c = *cp++) 7858462SApril.Chin@Sun.COM if (c >= '0' && c <= '9') 7868462SApril.Chin@Sun.COM { 7878462SApril.Chin@Sun.COM t *= 10; 7888462SApril.Chin@Sun.COM t += c - '0'; 7898462SApril.Chin@Sun.COM } 7908462SApril.Chin@Sun.COM return((Sfdouble_t)t); 7918462SApril.Chin@Sun.COM } 7928462SApril.Chin@Sun.COM 7938462SApril.Chin@Sun.COM static const Namdisc_t SH_VERSION_disc = { 0, 0, get_version, nget_version }; 7944887Schin 7954887Schin #if SHOPT_FS_3D 7964887Schin /* 7974887Schin * set or unset the mappings given a colon separated list of directories 7984887Schin */ 7994887Schin static void vpath_set(char *str, int mode) 8004887Schin { 8014887Schin register char *lastp, *oldp=str, *newp=strchr(oldp,':'); 8024887Schin if(!sh.lim.fs3d) 8034887Schin return; 8044887Schin while(newp) 8054887Schin { 8064887Schin *newp++ = 0; 8074887Schin if(lastp=strchr(newp,':')) 8084887Schin *lastp = 0; 8094887Schin mount((mode?newp:""),oldp,FS3D_VIEW,0); 8104887Schin newp[-1] = ':'; 8114887Schin oldp = newp; 8124887Schin newp=lastp; 8134887Schin } 8144887Schin } 8154887Schin 8164887Schin /* catch vpath assignments */ 8174887Schin static void put_vpath(register Namval_t* np,const char *val,int flags,Namfun_t *fp) 8184887Schin { 8194887Schin register char *cp; 8204887Schin if(cp = nv_getval(np)) 8214887Schin vpath_set(cp,0); 8224887Schin if(val) 8234887Schin vpath_set((char*)val,1); 8244887Schin nv_putv(np,val,flags,fp); 8254887Schin } 8264887Schin static const Namdisc_t VPATH_disc = { 0, put_vpath }; 8274887Schin static Namfun_t VPATH_init = { &VPATH_disc, 1 }; 8284887Schin #endif /* SHOPT_FS_3D */ 8294887Schin 8304887Schin 8314887Schin static const Namdisc_t IFS_disc = { sizeof(struct ifs), put_ifs, get_ifs }; 8328462SApril.Chin@Sun.COM const Namdisc_t RESTRICTED_disc = { sizeof(Namfun_t), put_restricted }; 8338462SApril.Chin@Sun.COM static const Namdisc_t CDPATH_disc = { sizeof(Namfun_t), put_cdpath }; 8348462SApril.Chin@Sun.COM static const Namdisc_t EDITOR_disc = { sizeof(Namfun_t), put_ed }; 8358462SApril.Chin@Sun.COM static const Namdisc_t HISTFILE_disc = { sizeof(Namfun_t), put_history }; 8368462SApril.Chin@Sun.COM static const Namdisc_t OPTINDEX_disc = { sizeof(Namfun_t), put_optindex, 0, nget_optindex, 0, 0, clone_optindex }; 8374887Schin static const Namdisc_t SECONDS_disc = { sizeof(struct seconds), put_seconds, get_seconds, nget_seconds }; 8384887Schin static const Namdisc_t RAND_disc = { sizeof(struct rand), put_rand, get_rand, nget_rand }; 8398462SApril.Chin@Sun.COM static const Namdisc_t LINENO_disc = { sizeof(Namfun_t), put_lineno, get_lineno, nget_lineno }; 8408462SApril.Chin@Sun.COM static const Namdisc_t L_ARG_disc = { sizeof(Namfun_t), put_lastarg, get_lastarg }; 8414887Schin 8424887Schin #if SHOPT_NAMESPACE 8434887Schin static char* get_nspace(Namval_t* np, Namfun_t *fp) 8444887Schin { 8454887Schin if(sh.namespace) 8464887Schin return(nv_name(sh.namespace)); 8474887Schin return((char*)np->nvalue.cp); 8484887Schin } 8494887Schin static const Namdisc_t NSPACE_disc = { 0, 0, get_nspace }; 8504887Schin static Namfun_t NSPACE_init = { &NSPACE_disc, 1}; 8514887Schin #endif /* SHOPT_NAMESPACE */ 8524887Schin 8534887Schin #ifdef _hdr_locale 8548462SApril.Chin@Sun.COM static const Namdisc_t LC_disc = { sizeof(Namfun_t), put_lang }; 8554887Schin #endif /* _hdr_locale */ 8564887Schin 8574887Schin /* 8584887Schin * This function will get called whenever a configuration parameter changes 8594887Schin */ 8604887Schin static int newconf(const char *name, const char *path, const char *value) 8614887Schin { 8624887Schin register char *arg; 8634887Schin if(!name) 8644887Schin setenviron(value); 8654887Schin else if(strcmp(name,"UNIVERSE")==0 && strcmp(astconf(name,0,0),value)) 8664887Schin { 8674887Schin sh.universe = 0; 8684887Schin /* set directory in new universe */ 8694887Schin if(*(arg = path_pwd(0))=='/') 8704887Schin chdir(arg); 8714887Schin /* clear out old tracked alias */ 8724887Schin stakseek(0); 8734887Schin stakputs(nv_getval(PATHNOD)); 8744887Schin stakputc(0); 8754887Schin nv_putval(PATHNOD,stakseek(0),NV_RDONLY); 8764887Schin } 8774887Schin return(1); 8784887Schin } 8794887Schin 8804887Schin #if (CC_NATIVE != CC_ASCII) 8814887Schin static void a2e(char *d, const char *s) 8824887Schin { 8834887Schin register const unsigned char *t; 8844887Schin register int i; 8854887Schin t = CCMAP(CC_ASCII, CC_NATIVE); 8864887Schin for(i=0; i<(1<<CHAR_BIT); i++) 8874887Schin d[t[i]] = s[i]; 8884887Schin } 8894887Schin 8904887Schin static void init_ebcdic(void) 8914887Schin { 8924887Schin int i; 8934887Schin char *cp = (char*)malloc(ST_NONE*(1<<CHAR_BIT)); 8944887Schin for(i=0; i < ST_NONE; i++) 8954887Schin { 8964887Schin a2e(cp,sh_lexrstates[i]); 8974887Schin sh_lexstates[i] = cp; 8984887Schin cp += (1<<CHAR_BIT); 8994887Schin } 9004887Schin } 9014887Schin #endif 9024887Schin 9034887Schin /* 9044887Schin * return SH_TYPE_* bitmask for path 9054887Schin * 0 for "not a shell" 9064887Schin */ 9074887Schin int sh_type(register const char *path) 9084887Schin { 9094887Schin register const char* s; 9104887Schin register int t = 0; 9114887Schin 9124887Schin if (s = (const char*)strrchr(path, '/')) 9134887Schin { 9144887Schin if (*path == '-') 9154887Schin t |= SH_TYPE_LOGIN; 9164887Schin s++; 9174887Schin } 9184887Schin else 9194887Schin s = path; 9204887Schin if (*s == '-') 9214887Schin { 9224887Schin s++; 9234887Schin t |= SH_TYPE_LOGIN; 9244887Schin } 9254887Schin for (;;) 9264887Schin { 9274887Schin if (!(t & (SH_TYPE_KSH|SH_TYPE_BASH))) 9284887Schin { 9294887Schin if (*s == 'k') 9304887Schin { 9314887Schin s++; 9324887Schin t |= SH_TYPE_KSH; 9334887Schin continue; 9344887Schin } 9354887Schin #if SHOPT_BASH 9364887Schin if (*s == 'b' && *(s+1) == 'a') 9374887Schin { 9384887Schin s += 2; 9394887Schin t |= SH_TYPE_BASH; 9404887Schin continue; 9414887Schin } 9424887Schin #endif 9434887Schin } 9444887Schin if (!(t & (SH_TYPE_PROFILE|SH_TYPE_RESTRICTED))) 9454887Schin { 9464887Schin #if SHOPT_PFSH 9474887Schin if (*s == 'p' && *(s+1) == 'f') 9484887Schin { 9494887Schin s += 2; 9504887Schin t |= SH_TYPE_PROFILE; 9514887Schin continue; 9524887Schin } 9534887Schin #endif 9544887Schin if (*s == 'r') 9554887Schin { 9564887Schin s++; 9574887Schin t |= SH_TYPE_RESTRICTED; 9584887Schin continue; 9594887Schin } 9604887Schin } 9614887Schin break; 9624887Schin } 9638462SApril.Chin@Sun.COM if (*s++ == 's' && (*s == 'h' || *s == 'u')) 9648462SApril.Chin@Sun.COM { 9658462SApril.Chin@Sun.COM s++; 9668462SApril.Chin@Sun.COM t |= SH_TYPE_SH; 9678462SApril.Chin@Sun.COM if ((t & SH_TYPE_KSH) && *s == '9' && *(s+1) == '3') 9688462SApril.Chin@Sun.COM s += 2; 9694887Schin #if _WINIX 9708462SApril.Chin@Sun.COM if (*s == '.' && *(s+1) == 'e' && *(s+2) == 'x' && *(s+3) == 'e') 9718462SApril.Chin@Sun.COM s += 4; 9724887Schin #endif 9738462SApril.Chin@Sun.COM if (!isalnum(*s)) 9748462SApril.Chin@Sun.COM return t; 9758462SApril.Chin@Sun.COM } 9768462SApril.Chin@Sun.COM return t & ~(SH_TYPE_BASH|SH_TYPE_KSH|SH_TYPE_PROFILE|SH_TYPE_RESTRICTED); 9778462SApril.Chin@Sun.COM } 9788462SApril.Chin@Sun.COM 9798462SApril.Chin@Sun.COM 9808462SApril.Chin@Sun.COM static char *get_mode(Namval_t* np, Namfun_t* nfp) 9818462SApril.Chin@Sun.COM { 9828462SApril.Chin@Sun.COM mode_t mode = nv_getn(np,nfp); 9838462SApril.Chin@Sun.COM return(fmtperm(mode)); 9844887Schin } 9854887Schin 9868462SApril.Chin@Sun.COM static void put_mode(Namval_t* np, const char* val, int flag, Namfun_t* nfp) 9878462SApril.Chin@Sun.COM { 9888462SApril.Chin@Sun.COM if(val) 9898462SApril.Chin@Sun.COM { 9908462SApril.Chin@Sun.COM mode_t mode; 9918462SApril.Chin@Sun.COM char *last; 9928462SApril.Chin@Sun.COM if(flag&NV_INTEGER) 9938462SApril.Chin@Sun.COM { 9948462SApril.Chin@Sun.COM if(flag&NV_LONG) 9958462SApril.Chin@Sun.COM mode = *(Sfdouble_t*)val; 9968462SApril.Chin@Sun.COM else 9978462SApril.Chin@Sun.COM mode = *(double*)val; 9988462SApril.Chin@Sun.COM } 9998462SApril.Chin@Sun.COM else 10008462SApril.Chin@Sun.COM mode = strperm(val, &last,0); 10018462SApril.Chin@Sun.COM if(*last) 10028462SApril.Chin@Sun.COM errormsg(SH_DICT,ERROR_exit(1),"%s: invalid mode string",val); 10038462SApril.Chin@Sun.COM nv_putv(np,(char*)&mode,NV_INTEGER,nfp); 10048462SApril.Chin@Sun.COM } 10058462SApril.Chin@Sun.COM else 10068462SApril.Chin@Sun.COM nv_putv(np,val,flag,nfp); 10078462SApril.Chin@Sun.COM } 10088462SApril.Chin@Sun.COM 10098462SApril.Chin@Sun.COM static const Namdisc_t modedisc = 10108462SApril.Chin@Sun.COM { 10118462SApril.Chin@Sun.COM 0, 10128462SApril.Chin@Sun.COM put_mode, 10138462SApril.Chin@Sun.COM get_mode, 10148462SApril.Chin@Sun.COM }; 10158462SApril.Chin@Sun.COM 10168462SApril.Chin@Sun.COM 10174887Schin /* 10184887Schin * initialize the shell 10194887Schin */ 10208462SApril.Chin@Sun.COM Shell_t *sh_init(register int argc,register char *argv[], Shinit_f userinit) 10214887Schin { 10228462SApril.Chin@Sun.COM Shell_t *shp = &sh; 10234887Schin register int n; 10244887Schin int type; 10254887Schin static char *login_files[3]; 1026*10898Sroland.mainz@nrubsig.org memfatal(); 10274887Schin n = strlen(e_version); 10284887Schin if(e_version[n-1]=='$' && e_version[n-2]==' ') 10294887Schin e_version[n-2]=0; 10304887Schin #if (CC_NATIVE == CC_ASCII) 10314887Schin memcpy(sh_lexstates,sh_lexrstates,ST_NONE*sizeof(char*)); 10324887Schin #else 10334887Schin init_ebcdic(); 10344887Schin #endif 10358462SApril.Chin@Sun.COM umask(shp->mask=umask(0)); 10368462SApril.Chin@Sun.COM shp->mac_context = sh_macopen(shp); 10378462SApril.Chin@Sun.COM shp->arg_context = sh_argopen(shp); 10388462SApril.Chin@Sun.COM shp->lex_context = (void*)sh_lexopen(0,shp,1); 10398462SApril.Chin@Sun.COM shp->ed_context = (void*)ed_open(shp); 10408462SApril.Chin@Sun.COM shp->strbuf = sfstropen(); 10418462SApril.Chin@Sun.COM shp->stk = stkstd; 10428462SApril.Chin@Sun.COM sfsetbuf(shp->strbuf,(char*)0,64); 10434887Schin sh_onstate(SH_INIT); 10444887Schin error_info.exit = sh_exit; 10454887Schin error_info.id = path_basename(argv[0]); 10464887Schin #if ERROR_VERSION >= 20000102L 10474887Schin error_info.catalog = e_dict; 10484887Schin #endif 1049*10898Sroland.mainz@nrubsig.org #if SHOPT_REGRESS 1050*10898Sroland.mainz@nrubsig.org { 1051*10898Sroland.mainz@nrubsig.org Opt_t* nopt; 1052*10898Sroland.mainz@nrubsig.org Opt_t* oopt; 1053*10898Sroland.mainz@nrubsig.org char* a; 1054*10898Sroland.mainz@nrubsig.org char** av = argv; 1055*10898Sroland.mainz@nrubsig.org char* regress[3]; 1056*10898Sroland.mainz@nrubsig.org 1057*10898Sroland.mainz@nrubsig.org sh_regress_init(shp); 1058*10898Sroland.mainz@nrubsig.org regress[0] = "__regress__"; 1059*10898Sroland.mainz@nrubsig.org regress[2] = 0; 1060*10898Sroland.mainz@nrubsig.org /* NOTE: only shp is used by __regress__ at this point */ 1061*10898Sroland.mainz@nrubsig.org shp->bltindata.shp = shp; 1062*10898Sroland.mainz@nrubsig.org while ((a = *++av) && a[0] == '-' && (a[1] == 'I' || a[1] == '-' && a[2] == 'r')) 1063*10898Sroland.mainz@nrubsig.org { 1064*10898Sroland.mainz@nrubsig.org if (a[1] == 'I') 1065*10898Sroland.mainz@nrubsig.org { 1066*10898Sroland.mainz@nrubsig.org if (a[2]) 1067*10898Sroland.mainz@nrubsig.org regress[1] = a + 2; 1068*10898Sroland.mainz@nrubsig.org else if (!(regress[1] = *++av)) 1069*10898Sroland.mainz@nrubsig.org break; 1070*10898Sroland.mainz@nrubsig.org } 1071*10898Sroland.mainz@nrubsig.org else if (strncmp(a+2, "regress", 7)) 1072*10898Sroland.mainz@nrubsig.org break; 1073*10898Sroland.mainz@nrubsig.org else if (a[9] == '=') 1074*10898Sroland.mainz@nrubsig.org regress[1] = a + 10; 1075*10898Sroland.mainz@nrubsig.org else if (!(regress[1] = *++av)) 1076*10898Sroland.mainz@nrubsig.org break; 1077*10898Sroland.mainz@nrubsig.org nopt = optctx(0, 0); 1078*10898Sroland.mainz@nrubsig.org oopt = optctx(nopt, 0); 1079*10898Sroland.mainz@nrubsig.org b___regress__(2, regress, &shp->bltindata); 1080*10898Sroland.mainz@nrubsig.org optctx(oopt, nopt); 1081*10898Sroland.mainz@nrubsig.org } 1082*10898Sroland.mainz@nrubsig.org } 1083*10898Sroland.mainz@nrubsig.org #endif 10848462SApril.Chin@Sun.COM shp->cpipe[0] = -1; 10858462SApril.Chin@Sun.COM shp->coutpipe = -1; 10868462SApril.Chin@Sun.COM shp->userid=getuid(); 10878462SApril.Chin@Sun.COM shp->euserid=geteuid(); 10888462SApril.Chin@Sun.COM shp->groupid=getgid(); 10898462SApril.Chin@Sun.COM shp->egroupid=getegid(); 10904887Schin for(n=0;n < 10; n++) 10914887Schin { 10924887Schin /* don't use lower bits when rand() generates large numbers */ 10934887Schin if(rand() > RANDMASK) 10944887Schin { 10954887Schin rand_shift = 3; 10964887Schin break; 10974887Schin } 10984887Schin } 10998462SApril.Chin@Sun.COM shp->lim.clk_tck = getconf("CLK_TCK"); 11008462SApril.Chin@Sun.COM shp->lim.arg_max = getconf("ARG_MAX"); 11018462SApril.Chin@Sun.COM shp->lim.open_max = getconf("OPEN_MAX"); 11028462SApril.Chin@Sun.COM shp->lim.child_max = getconf("CHILD_MAX"); 11038462SApril.Chin@Sun.COM shp->lim.ngroups_max = getconf("NGROUPS_MAX"); 11048462SApril.Chin@Sun.COM shp->lim.posix_version = getconf("VERSION"); 11058462SApril.Chin@Sun.COM shp->lim.posix_jobcontrol = getconf("JOB_CONTROL"); 11068462SApril.Chin@Sun.COM if(shp->lim.arg_max <=0) 11078462SApril.Chin@Sun.COM shp->lim.arg_max = ARG_MAX; 11088462SApril.Chin@Sun.COM if(shp->lim.child_max <=0) 11098462SApril.Chin@Sun.COM shp->lim.child_max = CHILD_MAX; 11108462SApril.Chin@Sun.COM if(shp->lim.open_max <0) 11118462SApril.Chin@Sun.COM shp->lim.open_max = OPEN_MAX; 11128462SApril.Chin@Sun.COM if(shp->lim.open_max > (SHRT_MAX-2)) 11138462SApril.Chin@Sun.COM shp->lim.open_max = SHRT_MAX-2; 11148462SApril.Chin@Sun.COM if(shp->lim.clk_tck <=0) 11158462SApril.Chin@Sun.COM shp->lim.clk_tck = CLK_TCK; 11164887Schin #if SHOPT_FS_3D 11174887Schin if(fs3d(FS3D_TEST)) 11188462SApril.Chin@Sun.COM shp->lim.fs3d = 1; 11194887Schin #endif /* SHOPT_FS_3D */ 11208462SApril.Chin@Sun.COM sh_ioinit(shp); 11214887Schin /* initialize signal handling */ 11228462SApril.Chin@Sun.COM sh_siginit(shp); 11234887Schin stakinstall(NIL(Stak_t*),nospace); 11244887Schin /* set up memory for name-value pairs */ 11258462SApril.Chin@Sun.COM shp->init_context = nv_init(shp); 11264887Schin /* read the environment */ 11274887Schin if(argc>0) 11284887Schin { 11294887Schin type = sh_type(*argv); 11304887Schin if(type&SH_TYPE_LOGIN) 11318462SApril.Chin@Sun.COM shp->login_sh = 2; 11324887Schin } 11338462SApril.Chin@Sun.COM env_init(shp); 1134*10898Sroland.mainz@nrubsig.org if(!ENVNOD->nvalue.cp) 1135*10898Sroland.mainz@nrubsig.org { 1136*10898Sroland.mainz@nrubsig.org sfprintf(shp->strbuf,"%s/.kshrc",nv_getval(HOME)); 1137*10898Sroland.mainz@nrubsig.org nv_putval(ENVNOD,sfstruse(shp->strbuf),NV_RDONLY); 1138*10898Sroland.mainz@nrubsig.org } 11398462SApril.Chin@Sun.COM *SHLVL->nvalue.ip +=1; 11404887Schin #if SHOPT_SPAWN 11414887Schin { 11424887Schin /* 11434887Schin * try to find the pathname for this interpreter 11444887Schin * try using environment variable _ or argv[0] 11454887Schin */ 1146*10898Sroland.mainz@nrubsig.org char *cp=nv_getval(L_ARGNOD); 11474887Schin char buff[PATH_MAX+1]; 11488462SApril.Chin@Sun.COM shp->shpath = 0; 1149*10898Sroland.mainz@nrubsig.org #if _AST_VERSION >= 20090202L 1150*10898Sroland.mainz@nrubsig.org if((n = pathprog(NiL, buff, sizeof(buff))) > 0 && n <= sizeof(buff)) 1151*10898Sroland.mainz@nrubsig.org shp->shpath = strdup(buff); 1152*10898Sroland.mainz@nrubsig.org #else 11538462SApril.Chin@Sun.COM sfprintf(shp->strbuf,"/proc/%d/exe",getpid()); 11548462SApril.Chin@Sun.COM if((n=readlink(sfstruse(shp->strbuf),buff,sizeof(buff)-1))>0) 11554887Schin { 11564887Schin buff[n] = 0; 11578462SApril.Chin@Sun.COM shp->shpath = strdup(buff); 11584887Schin } 1159*10898Sroland.mainz@nrubsig.org #endif 11604887Schin else if((cp && (sh_type(cp)&SH_TYPE_SH)) || (argc>0 && strchr(cp= *argv,'/'))) 11614887Schin { 11624887Schin if(*cp=='/') 11638462SApril.Chin@Sun.COM shp->shpath = strdup(cp); 11644887Schin else if(cp = nv_getval(PWDNOD)) 11654887Schin { 11664887Schin int offset = staktell(); 11674887Schin stakputs(cp); 11684887Schin stakputc('/'); 11694887Schin stakputs(argv[0]); 11704887Schin pathcanon(stakptr(offset),PATH_DOTDOT); 11718462SApril.Chin@Sun.COM shp->shpath = strdup(stakptr(offset)); 11724887Schin stakseek(offset); 11734887Schin } 11744887Schin } 11754887Schin } 11764887Schin #endif 11774887Schin nv_putval(IFSNOD,(char*)e_sptbnl,NV_RDONLY); 11784887Schin #if SHOPT_FS_3D 11794887Schin nv_stack(VPATHNOD, &VPATH_init); 11804887Schin #endif /* SHOPT_FS_3D */ 11814887Schin astconfdisc(newconf); 11824887Schin #if SHOPT_TIMEOUT 11838462SApril.Chin@Sun.COM shp->st.tmout = SHOPT_TIMEOUT; 11844887Schin #endif /* SHOPT_TIMEOUT */ 11854887Schin /* initialize jobs table */ 11864887Schin job_clear(); 11874887Schin if(argc>0) 11884887Schin { 11894887Schin /* check for restricted shell */ 11904887Schin if(type&SH_TYPE_RESTRICTED) 11914887Schin sh_onoption(SH_RESTRICTED); 11924887Schin #if SHOPT_PFSH 11934887Schin /* check for profile shell */ 11944887Schin else if(type&SH_TYPE_PROFILE) 11954887Schin sh_onoption(SH_PFSH); 11964887Schin #endif 11974887Schin #if SHOPT_BASH 11984887Schin /* check for invocation as bash */ 11994887Schin if(type&SH_TYPE_BASH) 12004887Schin { 12018462SApril.Chin@Sun.COM shp->userinit = userinit = bash_init; 12024887Schin sh_onoption(SH_BASH); 12034887Schin sh_onstate(SH_PREINIT); 12048462SApril.Chin@Sun.COM (*userinit)(shp, 0); 12054887Schin sh_offstate(SH_PREINIT); 12064887Schin } 12074887Schin #endif 12084887Schin /* look for options */ 12098462SApril.Chin@Sun.COM /* shp->st.dolc is $# */ 12108462SApril.Chin@Sun.COM if((shp->st.dolc = sh_argopts(-argc,argv,shp)) < 0) 12114887Schin { 12128462SApril.Chin@Sun.COM shp->exitval = 2; 12138462SApril.Chin@Sun.COM sh_done(shp,0); 12144887Schin } 12154887Schin opt_info.disc = 0; 12168462SApril.Chin@Sun.COM shp->st.dolv=argv+(argc-1)-shp->st.dolc; 12178462SApril.Chin@Sun.COM shp->st.dolv[0] = argv[0]; 12188462SApril.Chin@Sun.COM if(shp->st.dolc < 1) 12194887Schin sh_onoption(SH_SFLAG); 12204887Schin if(!sh_isoption(SH_SFLAG)) 12214887Schin { 12228462SApril.Chin@Sun.COM shp->st.dolc--; 12238462SApril.Chin@Sun.COM shp->st.dolv++; 12244887Schin #if _WINIX 12254887Schin { 12264887Schin char* name; 12278462SApril.Chin@Sun.COM name = shp->st.dolv[0]; 12284887Schin if(name[1]==':' && (name[2]=='/' || name[2]=='\\')) 12294887Schin { 12304887Schin #if _lib_pathposix 12314887Schin char* p; 12324887Schin 12334887Schin if((n = pathposix(name, NIL(char*), 0)) > 0 && (p = (char*)malloc(++n))) 12344887Schin { 12354887Schin pathposix(name, p, n); 12364887Schin name = p; 12374887Schin } 12384887Schin else 12394887Schin #endif 12404887Schin { 12414887Schin name[1] = name[0]; 12424887Schin name[0] = name[2] = '/'; 12434887Schin } 12444887Schin } 12454887Schin } 12464887Schin #endif /* _WINIX */ 12474887Schin } 12484887Schin } 12494887Schin #if SHOPT_PFSH 12504887Schin if (sh_isoption(SH_PFSH)) 12514887Schin { 12528462SApril.Chin@Sun.COM struct passwd *pw = getpwuid(shp->userid); 12534887Schin if(pw) 12548462SApril.Chin@Sun.COM shp->user = strdup(pw->pw_name); 12554887Schin 12564887Schin } 12574887Schin #endif 12584887Schin /* set[ug]id scripts require the -p flag */ 12598462SApril.Chin@Sun.COM if(shp->userid!=shp->euserid || shp->groupid!=shp->egroupid) 12604887Schin { 1261*10898Sroland.mainz@nrubsig.org #ifdef SHOPT_P_SUID 12624887Schin /* require sh -p to run setuid and/or setgid */ 1263*10898Sroland.mainz@nrubsig.org if(!sh_isoption(SH_PRIVILEGED) && shp->userid >= SHOPT_P_SUID) 12644887Schin { 12658462SApril.Chin@Sun.COM setuid(shp->euserid=shp->userid); 12668462SApril.Chin@Sun.COM setgid(shp->egroupid=shp->groupid); 12674887Schin } 12684887Schin else 1269*10898Sroland.mainz@nrubsig.org #endif /* SHOPT_P_SUID */ 12704887Schin sh_onoption(SH_PRIVILEGED); 12714887Schin #ifdef SHELLMAGIC 12724887Schin /* careful of #! setuid scripts with name beginning with - */ 12738462SApril.Chin@Sun.COM if(shp->login_sh && argv[1] && strcmp(argv[0],argv[1])==0) 12744887Schin errormsg(SH_DICT,ERROR_exit(1),e_prohibited); 12754887Schin #endif /*SHELLMAGIC*/ 12764887Schin } 12774887Schin else 12784887Schin sh_offoption(SH_PRIVILEGED); 12794887Schin /* shname for $0 in profiles and . scripts */ 12804887Schin if(strmatch(argv[1],e_devfdNN)) 12818462SApril.Chin@Sun.COM shp->shname = strdup(argv[0]); 12824887Schin else 12838462SApril.Chin@Sun.COM shp->shname = strdup(shp->st.dolv[0]); 12844887Schin /* 12854887Schin * return here for shell script execution 12864887Schin * but not for parenthesis subshells 12874887Schin */ 12888462SApril.Chin@Sun.COM error_info.id = strdup(shp->st.dolv[0]); /* error_info.id is $0 */ 12898462SApril.Chin@Sun.COM shp->jmpbuffer = (void*)&shp->checkbase; 12908462SApril.Chin@Sun.COM sh_pushcontext(&shp->checkbase,SH_JMPSCRIPT); 12918462SApril.Chin@Sun.COM shp->st.self = &shp->global; 12928462SApril.Chin@Sun.COM shp->topscope = (Shscope_t*)shp->st.self; 12934887Schin sh_offstate(SH_INIT); 12944887Schin login_files[0] = (char*)e_profile; 12954887Schin login_files[1] = ".profile"; 12968462SApril.Chin@Sun.COM shp->login_files = login_files; 12978462SApril.Chin@Sun.COM shp->bltindata.version = SH_VERSION; 12988462SApril.Chin@Sun.COM shp->bltindata.shp = shp; 12998462SApril.Chin@Sun.COM shp->bltindata.shrun = sh_run; 13008462SApril.Chin@Sun.COM shp->bltindata.shtrap = sh_trap; 13018462SApril.Chin@Sun.COM shp->bltindata.shexit = sh_exit; 13028462SApril.Chin@Sun.COM shp->bltindata.shbltin = sh_addbuiltin; 13038462SApril.Chin@Sun.COM #if _AST_VERSION >= 20080617L 13048462SApril.Chin@Sun.COM shp->bltindata.shgetenv = getenv; 13058462SApril.Chin@Sun.COM shp->bltindata.shsetenv = setenviron; 13068462SApril.Chin@Sun.COM astintercept(&shp->bltindata,1); 13078462SApril.Chin@Sun.COM #endif 13088462SApril.Chin@Sun.COM #if 0 13098462SApril.Chin@Sun.COM #define NV_MKINTTYPE(x,y,z) nv_mkinttype(#x,sizeof(x),(x)-1<0,(y),(Namdisc_t*)z); 13108462SApril.Chin@Sun.COM NV_MKINTTYPE(pid_t,"process id",0); 13118462SApril.Chin@Sun.COM NV_MKINTTYPE(gid_t,"group id",0); 13128462SApril.Chin@Sun.COM NV_MKINTTYPE(uid_t,"user id",0); 13138462SApril.Chin@Sun.COM NV_MKINTTYPE(size_t,(const char*)0,0); 13148462SApril.Chin@Sun.COM NV_MKINTTYPE(ssize_t,(const char*)0,0); 13158462SApril.Chin@Sun.COM NV_MKINTTYPE(off_t,"offset in bytes",0); 13168462SApril.Chin@Sun.COM NV_MKINTTYPE(ino_t,"\ai-\anode number",0); 13178462SApril.Chin@Sun.COM NV_MKINTTYPE(mode_t,(const char*)0,&modedisc); 13188462SApril.Chin@Sun.COM NV_MKINTTYPE(dev_t,"device id",0); 13198462SApril.Chin@Sun.COM NV_MKINTTYPE(nlink_t,"hard link count",0); 13208462SApril.Chin@Sun.COM NV_MKINTTYPE(blkcnt_t,"block count",0); 13218462SApril.Chin@Sun.COM NV_MKINTTYPE(time_t,"seconds since the epoch",0); 13228462SApril.Chin@Sun.COM nv_mkstat(); 13238462SApril.Chin@Sun.COM #endif 13248462SApril.Chin@Sun.COM if(shp->userinit=userinit) 13258462SApril.Chin@Sun.COM (*userinit)(shp, 0); 13268462SApril.Chin@Sun.COM return(shp); 13274887Schin } 13284887Schin 13294887Schin Shell_t *sh_getinterp(void) 13304887Schin { 13314887Schin return(&sh); 13324887Schin } 13334887Schin 13344887Schin /* 13354887Schin * reinitialize before executing a script 13364887Schin */ 13374887Schin int sh_reinit(char *argv[]) 13384887Schin { 13398462SApril.Chin@Sun.COM Shell_t *shp = &sh; 13404887Schin Shopt_t opt; 13418462SApril.Chin@Sun.COM Namval_t *np,*npnext; 13428462SApril.Chin@Sun.COM Dt_t *dp; 13438462SApril.Chin@Sun.COM for(np=dtfirst(shp->fun_tree);np;np=npnext) 13444887Schin { 13458462SApril.Chin@Sun.COM if((dp=shp->fun_tree)->walk) 13468462SApril.Chin@Sun.COM dp = dp->walk; 13478462SApril.Chin@Sun.COM npnext = (Namval_t*)dtnext(shp->fun_tree,np); 13488462SApril.Chin@Sun.COM if(np>= shp->bltin_cmds && np < &shp->bltin_cmds[nbltins]) 13498462SApril.Chin@Sun.COM continue; 13508462SApril.Chin@Sun.COM if(is_abuiltin(np) && nv_isattr(np,NV_EXPORT)) 13518462SApril.Chin@Sun.COM continue; 13528462SApril.Chin@Sun.COM if(*np->nvname=='/') 13538462SApril.Chin@Sun.COM continue; 13548462SApril.Chin@Sun.COM nv_delete(np,dp,NV_NOFREE); 13558462SApril.Chin@Sun.COM } 13568462SApril.Chin@Sun.COM dtclose(shp->alias_tree); 13578462SApril.Chin@Sun.COM shp->alias_tree = inittree(shp,shtab_aliases); 13588462SApril.Chin@Sun.COM shp->last_root = shp->var_tree; 13598462SApril.Chin@Sun.COM shp->namespace = 0; 13608462SApril.Chin@Sun.COM shp->inuse_bits = 0; 13618462SApril.Chin@Sun.COM if(shp->userinit) 13628462SApril.Chin@Sun.COM (*shp->userinit)(shp, 1); 13638462SApril.Chin@Sun.COM if(shp->heredocs) 13648462SApril.Chin@Sun.COM { 13658462SApril.Chin@Sun.COM sfclose(shp->heredocs); 13668462SApril.Chin@Sun.COM shp->heredocs = 0; 13674887Schin } 13684887Schin /* remove locals */ 13694887Schin sh_onstate(SH_INIT); 13708462SApril.Chin@Sun.COM nv_scan(shp->var_tree,sh_envnolocal,(void*)0,NV_EXPORT,0); 13718462SApril.Chin@Sun.COM nv_scan(shp->var_tree,sh_envnolocal,(void*)0,NV_ARRAY,NV_ARRAY); 13724887Schin sh_offstate(SH_INIT); 13738462SApril.Chin@Sun.COM memset(shp->st.trapcom,0,(shp->st.trapmax+1)*sizeof(char*)); 13744887Schin memset((void*)&opt,0,sizeof(opt)); 13754887Schin if(sh_isoption(SH_TRACKALL)) 13764887Schin on_option(&opt,SH_TRACKALL); 13774887Schin if(sh_isoption(SH_EMACS)) 13784887Schin on_option(&opt,SH_EMACS); 13794887Schin if(sh_isoption(SH_GMACS)) 13804887Schin on_option(&opt,SH_GMACS); 13814887Schin if(sh_isoption(SH_VI)) 13824887Schin on_option(&opt,SH_VI); 13834887Schin if(sh_isoption(SH_VIRAW)) 13844887Schin on_option(&opt,SH_VIRAW); 13858462SApril.Chin@Sun.COM shp->options = opt; 13864887Schin /* set up new args */ 13874887Schin if(argv) 13888462SApril.Chin@Sun.COM shp->arglist = sh_argcreate(argv); 13898462SApril.Chin@Sun.COM if(shp->arglist) 13908462SApril.Chin@Sun.COM sh_argreset(shp,shp->arglist,NIL(struct dolnod*)); 13918462SApril.Chin@Sun.COM shp->envlist=0; 13928462SApril.Chin@Sun.COM shp->curenv = 0; 13938462SApril.Chin@Sun.COM shp->shname = error_info.id = strdup(shp->st.dolv[0]); 13944887Schin sh_offstate(SH_FORKED); 13958462SApril.Chin@Sun.COM shp->fn_depth = shp->dot_depth = 0; 13964887Schin sh_sigreset(0); 1397*10898Sroland.mainz@nrubsig.org if(!(SHLVL->nvalue.ip)) 1398*10898Sroland.mainz@nrubsig.org { 1399*10898Sroland.mainz@nrubsig.org shlvl = 0; 1400*10898Sroland.mainz@nrubsig.org SHLVL->nvalue.ip = &shlvl; 1401*10898Sroland.mainz@nrubsig.org nv_onattr(SHLVL,NV_INTEGER|NV_EXPORT|NV_NOFREE); 1402*10898Sroland.mainz@nrubsig.org } 14038462SApril.Chin@Sun.COM *SHLVL->nvalue.ip +=1; 1404*10898Sroland.mainz@nrubsig.org shp->st.filename = strdup(shp->lastarg); 14054887Schin return(1); 14064887Schin } 14074887Schin 14084887Schin /* 14094887Schin * set when creating a local variable of this name 14104887Schin */ 14114887Schin Namfun_t *nv_cover(register Namval_t *np) 14124887Schin { 1413*10898Sroland.mainz@nrubsig.org if(np==IFSNOD || np==PATHNOD || np==SHELLNOD || np==FPATHNOD || np==CDPNOD || np==SECONDS || np==ENVNOD) 14144887Schin return(np->nvfun); 14154887Schin #ifdef _hdr_locale 14164887Schin if(np==LCALLNOD || np==LCTYPENOD || np==LCMSGNOD || np==LCCOLLNOD || np==LCNUMNOD || np==LANGNOD) 14174887Schin return(np->nvfun); 14184887Schin #endif 14194887Schin return(0); 14204887Schin } 14214887Schin 14224887Schin static const char *shdiscnames[] = { "tilde", 0}; 14234887Schin 14248462SApril.Chin@Sun.COM #ifdef SHOPT_STATS 14258462SApril.Chin@Sun.COM struct Stats 14268462SApril.Chin@Sun.COM { 14278462SApril.Chin@Sun.COM Namfun_t hdr; 14288462SApril.Chin@Sun.COM Shell_t *sh; 14298462SApril.Chin@Sun.COM char *nodes; 14308462SApril.Chin@Sun.COM int numnodes; 14318462SApril.Chin@Sun.COM int current; 14328462SApril.Chin@Sun.COM }; 14338462SApril.Chin@Sun.COM 14348462SApril.Chin@Sun.COM static Namval_t *next_stat(register Namval_t* np, Dt_t *root,Namfun_t *fp) 14358462SApril.Chin@Sun.COM { 14368462SApril.Chin@Sun.COM struct Stats *sp = (struct Stats*)fp; 14378462SApril.Chin@Sun.COM if(!root) 14388462SApril.Chin@Sun.COM sp->current = 0; 14398462SApril.Chin@Sun.COM else if(++sp->current>=sp->numnodes) 14408462SApril.Chin@Sun.COM return(0); 14418462SApril.Chin@Sun.COM return(nv_namptr(sp->nodes,sp->current)); 14428462SApril.Chin@Sun.COM } 14438462SApril.Chin@Sun.COM 14448462SApril.Chin@Sun.COM static Namval_t *create_stat(Namval_t *np,const char *name,int flag,Namfun_t *fp) 14458462SApril.Chin@Sun.COM { 14468462SApril.Chin@Sun.COM struct Stats *sp = (struct Stats*)fp; 14478462SApril.Chin@Sun.COM register const char *cp=name; 14488462SApril.Chin@Sun.COM register int i=0,n; 14498462SApril.Chin@Sun.COM Namval_t *nq=0; 14508462SApril.Chin@Sun.COM Shell_t *shp = sp->sh; 14518462SApril.Chin@Sun.COM if(!name) 14528462SApril.Chin@Sun.COM return(SH_STATS); 14538462SApril.Chin@Sun.COM while((i=*cp++) && i != '=' && i != '+' && i!='['); 14548462SApril.Chin@Sun.COM n = (cp-1) -name; 14558462SApril.Chin@Sun.COM for(i=0; i < sp->numnodes; i++) 14568462SApril.Chin@Sun.COM { 14578462SApril.Chin@Sun.COM nq = nv_namptr(sp->nodes,i); 14588462SApril.Chin@Sun.COM if((n==0||memcmp(name,nq->nvname,n)==0) && nq->nvname[n]==0) 14598462SApril.Chin@Sun.COM goto found; 14608462SApril.Chin@Sun.COM } 14618462SApril.Chin@Sun.COM nq = 0; 14628462SApril.Chin@Sun.COM found: 14638462SApril.Chin@Sun.COM if(nq) 14648462SApril.Chin@Sun.COM { 14658462SApril.Chin@Sun.COM fp->last = (char*)&name[n]; 14668462SApril.Chin@Sun.COM shp->last_table = SH_STATS; 14678462SApril.Chin@Sun.COM } 14688462SApril.Chin@Sun.COM else 14698462SApril.Chin@Sun.COM errormsg(SH_DICT,ERROR_exit(1),e_notelem,n,name,nv_name(np)); 14708462SApril.Chin@Sun.COM return(nq); 14718462SApril.Chin@Sun.COM } 14728462SApril.Chin@Sun.COM 14738462SApril.Chin@Sun.COM static const Namdisc_t stat_disc = 14748462SApril.Chin@Sun.COM { 14758462SApril.Chin@Sun.COM 0, 0, 0, 0, 0, 14768462SApril.Chin@Sun.COM create_stat, 14778462SApril.Chin@Sun.COM 0, 0, 14788462SApril.Chin@Sun.COM next_stat 14798462SApril.Chin@Sun.COM }; 14808462SApril.Chin@Sun.COM 14818462SApril.Chin@Sun.COM static char *name_stat(Namval_t *np, Namfun_t *fp) 14828462SApril.Chin@Sun.COM { 14838462SApril.Chin@Sun.COM Shell_t *shp = sh_getinterp(); 14848462SApril.Chin@Sun.COM sfprintf(shp->strbuf,".sh.stats.%s",np->nvname); 14858462SApril.Chin@Sun.COM return(sfstruse(shp->strbuf)); 14868462SApril.Chin@Sun.COM } 14878462SApril.Chin@Sun.COM 14888462SApril.Chin@Sun.COM static const Namdisc_t stat_child_disc = 14898462SApril.Chin@Sun.COM { 14908462SApril.Chin@Sun.COM 0,0,0,0,0,0,0, 14918462SApril.Chin@Sun.COM name_stat 14928462SApril.Chin@Sun.COM }; 14938462SApril.Chin@Sun.COM 14948462SApril.Chin@Sun.COM static Namfun_t stat_child_fun = 14958462SApril.Chin@Sun.COM { 14968462SApril.Chin@Sun.COM &stat_child_disc, 1, 0, sizeof(Namfun_t) 14978462SApril.Chin@Sun.COM }; 14988462SApril.Chin@Sun.COM 14998462SApril.Chin@Sun.COM static void stat_init(Shell_t *shp) 15008462SApril.Chin@Sun.COM { 15018462SApril.Chin@Sun.COM int i,nstat = STAT_SUBSHELL+1; 15028462SApril.Chin@Sun.COM struct Stats *sp = newof(0,struct Stats,1,nstat*NV_MINSZ); 15038462SApril.Chin@Sun.COM Namval_t *np; 15048462SApril.Chin@Sun.COM sp->numnodes = nstat; 15058462SApril.Chin@Sun.COM sp->nodes = (char*)(sp+1); 15068462SApril.Chin@Sun.COM shp->stats = (int*)calloc(sizeof(int*),nstat); 15078462SApril.Chin@Sun.COM sp->sh = shp; 15088462SApril.Chin@Sun.COM for(i=0; i < nstat; i++) 15098462SApril.Chin@Sun.COM { 15108462SApril.Chin@Sun.COM np = nv_namptr(sp->nodes,i); 15118462SApril.Chin@Sun.COM np->nvfun = &stat_child_fun; 15128462SApril.Chin@Sun.COM np->nvname = (char*)shtab_stats[i].sh_name; 15138462SApril.Chin@Sun.COM nv_onattr(np,NV_RDONLY|NV_MINIMAL|NV_NOFREE|NV_INTEGER); 15148462SApril.Chin@Sun.COM nv_setsize(np,10); 15158462SApril.Chin@Sun.COM np->nvalue.ip = &shp->stats[i]; 15168462SApril.Chin@Sun.COM } 15178462SApril.Chin@Sun.COM sp->hdr.dsize = sizeof(struct Stats) + nstat*(sizeof(int)+NV_MINSZ); 15188462SApril.Chin@Sun.COM sp->hdr.disc = &stat_disc; 15198462SApril.Chin@Sun.COM nv_stack(SH_STATS,&sp->hdr); 15208462SApril.Chin@Sun.COM sp->hdr.nofree = 1; 15218462SApril.Chin@Sun.COM nv_setvtree(SH_STATS); 15228462SApril.Chin@Sun.COM } 15238462SApril.Chin@Sun.COM #else 15248462SApril.Chin@Sun.COM # define stat_init(x) 15258462SApril.Chin@Sun.COM #endif /* SHOPT_STATS */ 15268462SApril.Chin@Sun.COM 15274887Schin /* 15284887Schin * Initialize the shell name and alias table 15294887Schin */ 15304887Schin static Init_t *nv_init(Shell_t *shp) 15314887Schin { 15324887Schin Namval_t *np; 15334887Schin register Init_t *ip; 15344887Schin double d=0; 15354887Schin ip = newof(0,Init_t,1,0); 15364887Schin if(!ip) 15374887Schin return(0); 15388462SApril.Chin@Sun.COM shp->nvfun.last = (char*)shp; 15398462SApril.Chin@Sun.COM shp->nvfun.nofree = 1; 15404887Schin ip->sh = shp; 15414887Schin shp->var_base = shp->var_tree = inittree(shp,shtab_variables); 15428462SApril.Chin@Sun.COM SHLVL->nvalue.ip = &shlvl; 15434887Schin ip->IFS_init.hdr.disc = &IFS_disc; 15444887Schin ip->IFS_init.hdr.nofree = 1; 15458462SApril.Chin@Sun.COM ip->PATH_init.disc = &RESTRICTED_disc; 15468462SApril.Chin@Sun.COM ip->PATH_init.nofree = 1; 15478462SApril.Chin@Sun.COM ip->FPATH_init.disc = &RESTRICTED_disc; 15488462SApril.Chin@Sun.COM ip->FPATH_init.nofree = 1; 15498462SApril.Chin@Sun.COM ip->CDPATH_init.disc = &CDPATH_disc; 15508462SApril.Chin@Sun.COM ip->CDPATH_init.nofree = 1; 15518462SApril.Chin@Sun.COM ip->SHELL_init.disc = &RESTRICTED_disc; 15528462SApril.Chin@Sun.COM ip->SHELL_init.nofree = 1; 15538462SApril.Chin@Sun.COM ip->ENV_init.disc = &RESTRICTED_disc; 15548462SApril.Chin@Sun.COM ip->ENV_init.nofree = 1; 15558462SApril.Chin@Sun.COM ip->VISUAL_init.disc = &EDITOR_disc; 15568462SApril.Chin@Sun.COM ip->VISUAL_init.nofree = 1; 15578462SApril.Chin@Sun.COM ip->EDITOR_init.disc = &EDITOR_disc; 15588462SApril.Chin@Sun.COM ip->EDITOR_init.nofree = 1; 15598462SApril.Chin@Sun.COM ip->HISTFILE_init.disc = &HISTFILE_disc; 15608462SApril.Chin@Sun.COM ip->HISTFILE_init.nofree = 1; 15618462SApril.Chin@Sun.COM ip->HISTSIZE_init.disc = &HISTFILE_disc; 15628462SApril.Chin@Sun.COM ip->HISTSIZE_init.nofree = 1; 15638462SApril.Chin@Sun.COM ip->OPTINDEX_init.disc = &OPTINDEX_disc; 15648462SApril.Chin@Sun.COM ip->OPTINDEX_init.nofree = 1; 15654887Schin ip->SECONDS_init.hdr.disc = &SECONDS_disc; 15664887Schin ip->SECONDS_init.hdr.nofree = 1; 15674887Schin ip->RAND_init.hdr.disc = &RAND_disc; 15684887Schin ip->RAND_init.hdr.nofree = 1; 15694887Schin ip->SH_MATCH_init.hdr.disc = &SH_MATCH_disc; 15704887Schin ip->SH_MATCH_init.hdr.nofree = 1; 15718462SApril.Chin@Sun.COM ip->SH_VERSION_init.disc = &SH_VERSION_disc; 15728462SApril.Chin@Sun.COM ip->SH_VERSION_init.nofree = 1; 15738462SApril.Chin@Sun.COM ip->LINENO_init.disc = &LINENO_disc; 15748462SApril.Chin@Sun.COM ip->LINENO_init.nofree = 1; 15758462SApril.Chin@Sun.COM ip->L_ARG_init.disc = &L_ARG_disc; 15768462SApril.Chin@Sun.COM ip->L_ARG_init.nofree = 1; 15774887Schin #ifdef _hdr_locale 15788462SApril.Chin@Sun.COM ip->LC_TYPE_init.disc = &LC_disc; 15798462SApril.Chin@Sun.COM ip->LC_TYPE_init.nofree = 1; 15808462SApril.Chin@Sun.COM ip->LC_NUM_init.disc = &LC_disc; 15818462SApril.Chin@Sun.COM ip->LC_NUM_init.nofree = 1; 15828462SApril.Chin@Sun.COM ip->LC_COLL_init.disc = &LC_disc; 15838462SApril.Chin@Sun.COM ip->LC_COLL_init.nofree = 1; 15848462SApril.Chin@Sun.COM ip->LC_MSG_init.disc = &LC_disc; 15858462SApril.Chin@Sun.COM ip->LC_MSG_init.nofree = 1; 15868462SApril.Chin@Sun.COM ip->LC_ALL_init.disc = &LC_disc; 15878462SApril.Chin@Sun.COM ip->LC_ALL_init.nofree = 1; 15888462SApril.Chin@Sun.COM ip->LANG_init.disc = &LC_disc; 15898462SApril.Chin@Sun.COM ip->LANG_init.nofree = 1; 15904887Schin #endif /* _hdr_locale */ 15914887Schin nv_stack(IFSNOD, &ip->IFS_init.hdr); 15928462SApril.Chin@Sun.COM nv_stack(PATHNOD, &ip->PATH_init); 15938462SApril.Chin@Sun.COM nv_stack(FPATHNOD, &ip->FPATH_init); 15948462SApril.Chin@Sun.COM nv_stack(CDPNOD, &ip->CDPATH_init); 15958462SApril.Chin@Sun.COM nv_stack(SHELLNOD, &ip->SHELL_init); 15968462SApril.Chin@Sun.COM nv_stack(ENVNOD, &ip->ENV_init); 15978462SApril.Chin@Sun.COM nv_stack(VISINOD, &ip->VISUAL_init); 15988462SApril.Chin@Sun.COM nv_stack(EDITNOD, &ip->EDITOR_init); 15998462SApril.Chin@Sun.COM nv_stack(HISTFILE, &ip->HISTFILE_init); 16008462SApril.Chin@Sun.COM nv_stack(HISTSIZE, &ip->HISTSIZE_init); 16018462SApril.Chin@Sun.COM nv_stack(OPTINDNOD, &ip->OPTINDEX_init); 16024887Schin nv_stack(SECONDS, &ip->SECONDS_init.hdr); 16038462SApril.Chin@Sun.COM nv_stack(L_ARGNOD, &ip->L_ARG_init); 16048462SApril.Chin@Sun.COM nv_putval(SECONDS, (char*)&d, NV_DOUBLE); 16054887Schin nv_stack(RANDNOD, &ip->RAND_init.hdr); 16064887Schin d = (shp->pid&RANDMASK); 16078462SApril.Chin@Sun.COM nv_putval(RANDNOD, (char*)&d, NV_DOUBLE); 16088462SApril.Chin@Sun.COM nv_stack(LINENO, &ip->LINENO_init); 16094887Schin nv_putsub(SH_MATCHNOD,(char*)0,10); 16104887Schin nv_onattr(SH_MATCHNOD,NV_RDONLY); 16114887Schin nv_stack(SH_MATCHNOD, &ip->SH_MATCH_init.hdr); 16128462SApril.Chin@Sun.COM nv_stack(SH_VERSIONNOD, &ip->SH_VERSION_init); 16134887Schin #ifdef _hdr_locale 16148462SApril.Chin@Sun.COM nv_stack(LCTYPENOD, &ip->LC_TYPE_init); 16158462SApril.Chin@Sun.COM nv_stack(LCALLNOD, &ip->LC_ALL_init); 16168462SApril.Chin@Sun.COM nv_stack(LCMSGNOD, &ip->LC_MSG_init); 16178462SApril.Chin@Sun.COM nv_stack(LCCOLLNOD, &ip->LC_COLL_init); 16188462SApril.Chin@Sun.COM nv_stack(LCNUMNOD, &ip->LC_NUM_init); 16198462SApril.Chin@Sun.COM nv_stack(LANGNOD, &ip->LANG_init); 16204887Schin #endif /* _hdr_locale */ 16214887Schin (PPIDNOD)->nvalue.lp = (&shp->ppid); 16224887Schin (TMOUTNOD)->nvalue.lp = (&shp->st.tmout); 16234887Schin (MCHKNOD)->nvalue.lp = (&sh_mailchk); 16244887Schin (OPTINDNOD)->nvalue.lp = (&shp->st.optindex); 16254887Schin /* set up the seconds clock */ 16264887Schin shp->alias_tree = inittree(shp,shtab_aliases); 16274887Schin shp->track_tree = dtopen(&_Nvdisc,Dtset); 16284887Schin shp->bltin_tree = inittree(shp,(const struct shtable2*)shtab_builtins); 16294887Schin shp->fun_tree = dtopen(&_Nvdisc,Dtoset); 16304887Schin dtview(shp->fun_tree,shp->bltin_tree); 16314887Schin #if SHOPT_NAMESPACE 16324887Schin if(np = nv_mount(DOTSHNOD, "global", shp->var_tree)) 16334887Schin nv_onattr(np,NV_RDONLY); 16344887Schin np = nv_search("namespace",nv_dict(DOTSHNOD),NV_ADD); 16354887Schin nv_putval(np,".sh.global",NV_RDONLY|NV_NOFREE); 16364887Schin nv_stack(np, &NSPACE_init); 16374887Schin #endif /* SHOPT_NAMESPACE */ 16388462SApril.Chin@Sun.COM np = nv_mount(DOTSHNOD, "type", shp->typedict=dtopen(&_Nvdisc,Dtoset)); 16394887Schin nv_adddisc(DOTSHNOD, shdiscnames, (Namval_t**)0); 16408462SApril.Chin@Sun.COM SH_LINENO->nvalue.ip = &shp->st.lineno; 16418462SApril.Chin@Sun.COM VERSIONNOD->nvalue.nrp = newof(0,struct Namref,1,0); 16428462SApril.Chin@Sun.COM VERSIONNOD->nvalue.nrp->np = SH_VERSIONNOD; 16438462SApril.Chin@Sun.COM VERSIONNOD->nvalue.nrp->root = nv_dict(DOTSHNOD); 16448462SApril.Chin@Sun.COM VERSIONNOD->nvalue.nrp->table = DOTSHNOD; 16458462SApril.Chin@Sun.COM nv_onattr(VERSIONNOD,NV_RDONLY|NV_REF); 16468462SApril.Chin@Sun.COM stat_init(shp); 16474887Schin return(ip); 16484887Schin } 16494887Schin 16504887Schin /* 16514887Schin * initialize name-value pairs 16524887Schin */ 16534887Schin 16544887Schin static Dt_t *inittree(Shell_t *shp,const struct shtable2 *name_vals) 16554887Schin { 16564887Schin register Namval_t *np; 16574887Schin register const struct shtable2 *tp; 16584887Schin register unsigned n = 0; 16594887Schin register Dt_t *treep; 16604887Schin Dt_t *base_treep, *dict; 16614887Schin for(tp=name_vals;*tp->sh_name;tp++) 16624887Schin n++; 16634887Schin np = (Namval_t*)calloc(n,sizeof(Namval_t)); 16644887Schin if(!shp->bltin_nodes) 16658462SApril.Chin@Sun.COM { 16664887Schin shp->bltin_nodes = np; 16678462SApril.Chin@Sun.COM shp->bltin_nnodes = n; 16688462SApril.Chin@Sun.COM } 16694887Schin else if(name_vals==(const struct shtable2*)shtab_builtins) 16708462SApril.Chin@Sun.COM { 16714887Schin shp->bltin_cmds = np; 16728462SApril.Chin@Sun.COM nbltins = n; 16738462SApril.Chin@Sun.COM } 16744887Schin base_treep = treep = dtopen(&_Nvdisc,Dtoset); 16758462SApril.Chin@Sun.COM treep->user = (void*)shp; 16764887Schin for(tp=name_vals;*tp->sh_name;tp++,np++) 16774887Schin { 16784887Schin if((np->nvname = strrchr(tp->sh_name,'.')) && np->nvname!=((char*)tp->sh_name)) 16794887Schin np->nvname++; 16804887Schin else 16814887Schin { 16824887Schin np->nvname = (char*)tp->sh_name; 16834887Schin treep = base_treep; 16844887Schin } 16854887Schin np->nvenv = 0; 16864887Schin if(name_vals==(const struct shtable2*)shtab_builtins) 16874887Schin np->nvalue.bfp = ((struct shtable3*)tp)->sh_value; 16884887Schin else 16898462SApril.Chin@Sun.COM { 16908462SApril.Chin@Sun.COM if(name_vals == shtab_variables) 16918462SApril.Chin@Sun.COM np->nvfun = &sh.nvfun; 16924887Schin np->nvalue.cp = (char*)tp->sh_value; 16938462SApril.Chin@Sun.COM } 16944887Schin nv_setattr(np,tp->sh_number); 16954887Schin if(nv_istable(np)) 16964887Schin nv_mount(np,(const char*)0,dict=dtopen(&_Nvdisc,Dtoset)); 16974887Schin if(nv_isattr(np,NV_INTEGER)) 16984887Schin nv_setsize(np,10); 16994887Schin else 17004887Schin nv_setsize(np,0); 17014887Schin dtinsert(treep,np); 17024887Schin if(nv_istable(np)) 17034887Schin treep = dict; 17044887Schin } 17054887Schin return(treep); 17064887Schin } 17074887Schin 17084887Schin /* 17094887Schin * read in the process environment and set up name-value pairs 17104887Schin * skip over items that are not name-value pairs 17114887Schin */ 17124887Schin 17134887Schin static void env_init(Shell_t *shp) 17144887Schin { 17154887Schin register char *cp; 17164887Schin register Namval_t *np; 17174887Schin register char **ep=environ; 17184887Schin register char *next=0; 17194887Schin #ifdef _ENV_H 17204887Schin shp->env = env_open(environ,3); 17214887Schin env_delete(shp->env,"_"); 17224887Schin #endif 17234887Schin if(ep) 17244887Schin { 17254887Schin while(cp= *ep++) 17264887Schin { 17274887Schin if(*cp=='A' && cp[1]=='_' && cp[2]=='_' && cp[3]=='z' && cp[4]=='=') 17284887Schin next = cp+4; 17294887Schin else if(np=nv_open(cp,shp->var_tree,(NV_EXPORT|NV_IDENT|NV_ASSIGN|NV_NOFAIL))) 17304887Schin { 17314887Schin nv_onattr(np,NV_IMPORT); 17324887Schin np->nvenv = cp; 17334887Schin nv_close(np); 17344887Schin } 17358462SApril.Chin@Sun.COM else /* swap with fron */ 17368462SApril.Chin@Sun.COM { 17378462SApril.Chin@Sun.COM ep[-1] = environ[shp->nenv]; 17388462SApril.Chin@Sun.COM environ[shp->nenv++] = cp; 17398462SApril.Chin@Sun.COM } 17404887Schin } 17414887Schin while(cp=next) 17424887Schin { 17434887Schin if(next = strchr(++cp,'=')) 17444887Schin *next = 0; 17454887Schin np = nv_search(cp+2,shp->var_tree,NV_ADD); 17464887Schin if(nv_isattr(np,NV_IMPORT|NV_EXPORT)) 17474887Schin { 17484887Schin int flag = *(unsigned char*)cp-' '; 17494887Schin int size = *(unsigned char*)(cp+1)-' '; 17504887Schin if((flag&NV_INTEGER) && size==0) 17514887Schin { 17524887Schin /* check for floating*/ 17534887Schin char *ep,*val = nv_getval(np); 17544887Schin strtol(val,&ep,10); 17554887Schin if(*ep=='.' || *ep=='e' || *ep=='E') 17564887Schin { 17574887Schin char *lp; 17584887Schin flag |= NV_DOUBLE; 17594887Schin if(*ep=='.') 17604887Schin { 17614887Schin strtol(ep+1,&lp,10); 17624887Schin if(*lp) 17634887Schin ep = lp; 17644887Schin } 17654887Schin if(*ep && *ep!='.') 17664887Schin { 17674887Schin flag |= NV_EXPNOTE; 17684887Schin size = ep-val; 17694887Schin } 17704887Schin else 17714887Schin size = strlen(ep); 17724887Schin size--; 17734887Schin } 17744887Schin } 17754887Schin nv_newattr(np,flag|NV_IMPORT|NV_EXPORT,size); 17764887Schin } 17774887Schin } 17784887Schin } 17794887Schin #ifdef _ENV_H 17808462SApril.Chin@Sun.COM env_delete(shp->env,e_envmarker); 17814887Schin #endif 17824887Schin if(nv_isnull(PWDNOD) || nv_isattr(PWDNOD,NV_TAGGED)) 17834887Schin { 17844887Schin nv_offattr(PWDNOD,NV_TAGGED); 17854887Schin path_pwd(0); 17864887Schin } 17874887Schin if((cp = nv_getval(SHELLNOD)) && (sh_type(cp)&SH_TYPE_RESTRICTED)) 17884887Schin sh_onoption(SH_RESTRICTED); /* restricted shell */ 17894887Schin return; 17904887Schin } 17914887Schin 17924887Schin /* 17934887Schin * terminate shell and free up the space 17944887Schin */ 17954887Schin int sh_term(void) 17964887Schin { 17974887Schin sfdisc(sfstdin,SF_POPDISC); 17984887Schin free((char*)sh.outbuff); 17994887Schin stakset(NIL(char*),0); 18004887Schin return(0); 18014887Schin } 18024887Schin 18034887Schin /* function versions of these */ 18044887Schin 18054887Schin #define DISABLE /* proto workaround */ 18064887Schin 18074887Schin unsigned long sh_isoption DISABLE (int opt) 18084887Schin { 18094887Schin return(sh_isoption(opt)); 18104887Schin } 18114887Schin 18124887Schin unsigned long sh_onoption DISABLE (int opt) 18134887Schin { 18144887Schin return(sh_onoption(opt)); 18154887Schin } 18164887Schin 18174887Schin unsigned long sh_offoption DISABLE (int opt) 18184887Schin { 18194887Schin return(sh_offoption(opt)); 18204887Schin } 18214887Schin 18224887Schin void sh_sigcheck DISABLE (void) 18234887Schin { 18244887Schin sh_sigcheck(); 18254887Schin } 18264887Schin 18274887Schin Dt_t* sh_bltin_tree DISABLE (void) 18284887Schin { 18294887Schin return(sh.bltin_tree); 18304887Schin } 1831