14887Schin /*********************************************************************** 24887Schin * * 34887Schin * This software is part of the ast package * 4*12068SRoger.Faulkner@Oracle.COM * Copyright (c) 1982-2010 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" 4610898Sroland.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 5910898Sroland.mainz@nrubsig.org #if SHOPT_BGX 6010898Sroland.mainz@nrubsig.org #define ATTRS 1 6110898Sroland.mainz@nrubsig.org "J" 6210898Sroland.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 7510898Sroland.mainz@nrubsig.org #if SHOPT_REGRESS 7610898Sroland.mainz@nrubsig.org #define ATTRS 1 7710898Sroland.mainz@nrubsig.org "R" 7810898Sroland.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*); 17310898Sroland.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); 20710898Sroland.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]*")) 21610898Sroland.mainz@nrubsig.org newopt=SH_VI; 2174887Schin else if(strmatch(cp,"*gmacs*")) 21810898Sroland.mainz@nrubsig.org newopt=SH_GMACS; 2194887Schin else if(strmatch(cp,"*macs*")) 22010898Sroland.mainz@nrubsig.org newopt=SH_EMACS; 22110898Sroland.mainz@nrubsig.org if(newopt) 22210898Sroland.mainz@nrubsig.org { 22310898Sroland.mainz@nrubsig.org sh_offoption(SH_VI); 22410898Sroland.mainz@nrubsig.org sh_offoption(SH_EMACS); 22510898Sroland.mainz@nrubsig.org sh_offoption(SH_GMACS); 22610898Sroland.mainz@nrubsig.org sh_onoption(newopt); 22710898Sroland.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; 23710898Sroland.mainz@nrubsig.org char *cp; 2388462SApril.Chin@Sun.COM if(val && histopen) 2398462SApril.Chin@Sun.COM { 24010898Sroland.mainz@nrubsig.org if(np==HISTFILE && (cp=nv_getval(np)) && strcmp(val,cp)==0) 2418462SApril.Chin@Sun.COM return; 24210898Sroland.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 35810898Sroland.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; 363*12068SRoger.Faulkner@Oracle.COM char *cp; 3644887Schin char *name = nv_name(np); 3654887Schin if(name==(LCALLNOD)->nvname) 3664887Schin type = LC_ALL; 3674887Schin else if(name==(LCTYPENOD)->nvname) 3684887Schin type = LC_CTYPE; 3694887Schin else if(name==(LCMSGNOD)->nvname) 3704887Schin type = LC_MESSAGES; 3714887Schin else if(name==(LCCOLLNOD)->nvname) 3724887Schin type = LC_COLLATE; 3734887Schin else if(name==(LCNUMNOD)->nvname) 3744887Schin type = LC_NUMERIC; 37510898Sroland.mainz@nrubsig.org #ifdef LC_LANG 37610898Sroland.mainz@nrubsig.org else if(name==(LANGNOD)->nvname) 37710898Sroland.mainz@nrubsig.org type = LC_LANG; 37810898Sroland.mainz@nrubsig.org #else 37910898Sroland.mainz@nrubsig.org #define LC_LANG LC_ALL 380*12068SRoger.Faulkner@Oracle.COM else if(name==(LANGNOD)->nvname && (!(cp=nv_getval(LCALLNOD)) || !*cp)) 38110898Sroland.mainz@nrubsig.org type = LC_LANG; 38210898Sroland.mainz@nrubsig.org #endif 3834887Schin else 3844887Schin type= -1; 385*12068SRoger.Faulkner@Oracle.COM if(!sh_isstate(SH_INIT) && (type>=0 || type==LC_ALL || type==LC_LANG)) 3864887Schin { 387*12068SRoger.Faulkner@Oracle.COM struct lconv* lc; 388*12068SRoger.Faulkner@Oracle.COM char* r; 389*12068SRoger.Faulkner@Oracle.COM #ifdef AST_LC_setenv 390*12068SRoger.Faulkner@Oracle.COM ast.locale.set |= AST_LC_setenv; 391*12068SRoger.Faulkner@Oracle.COM #endif 392*12068SRoger.Faulkner@Oracle.COM r = setlocale(type,val?val:""); 393*12068SRoger.Faulkner@Oracle.COM #ifdef AST_LC_setenv 394*12068SRoger.Faulkner@Oracle.COM ast.locale.set ^= AST_LC_setenv; 395*12068SRoger.Faulkner@Oracle.COM #endif 396*12068SRoger.Faulkner@Oracle.COM if(!r && val) 3974887Schin { 3988462SApril.Chin@Sun.COM if(!sh_isstate(SH_INIT) || shp->login_sh==0) 3994887Schin errormsg(SH_DICT,0,e_badlocale,val); 4004887Schin return; 4014887Schin } 402*12068SRoger.Faulkner@Oracle.COM shp->decomma = (lc=localeconv()) && lc->decimal_point && *lc->decimal_point==','; 4034887Schin } 404*12068SRoger.Faulkner@Oracle.COM nv_putv(np, val, flags, fp); 405*12068SRoger.Faulkner@Oracle.COM if(CC_NATIVE!=CC_ASCII && (type==LC_ALL || type==LC_LANG || type==LC_CTYPE)) 4064887Schin { 4074887Schin if(sh_lexstates[ST_BEGIN]!=sh_lexrstates[ST_BEGIN]) 4084887Schin free((void*)sh_lexstates[ST_BEGIN]); 4094887Schin if(ast.locale.set&(1<<AST_LC_CTYPE)) 4104887Schin { 4114887Schin register int c; 4124887Schin char *state[4]; 4134887Schin sh_lexstates[ST_BEGIN] = state[0] = (char*)malloc(4*(1<<CHAR_BIT)); 4144887Schin memcpy(state[0],sh_lexrstates[ST_BEGIN],(1<<CHAR_BIT)); 4154887Schin sh_lexstates[ST_NAME] = state[1] = state[0] + (1<<CHAR_BIT); 4164887Schin memcpy(state[1],sh_lexrstates[ST_NAME],(1<<CHAR_BIT)); 4174887Schin sh_lexstates[ST_DOL] = state[2] = state[1] + (1<<CHAR_BIT); 4184887Schin memcpy(state[2],sh_lexrstates[ST_DOL],(1<<CHAR_BIT)); 4194887Schin sh_lexstates[ST_BRACE] = state[3] = state[2] + (1<<CHAR_BIT); 4204887Schin memcpy(state[3],sh_lexrstates[ST_BRACE],(1<<CHAR_BIT)); 4214887Schin for(c=0; c<(1<<CHAR_BIT); c++) 4224887Schin { 4234887Schin if(state[0][c]!=S_REG) 4244887Schin continue; 4254887Schin if(state[2][c]!=S_ERR) 4264887Schin continue; 4274887Schin if(isblank(c)) 4284887Schin { 4294887Schin state[0][c]=0; 4304887Schin state[1][c]=S_BREAK; 4314887Schin state[2][c]=S_BREAK; 4324887Schin continue; 4334887Schin } 4344887Schin if(!isalpha(c)) 4354887Schin continue; 4364887Schin state[0][c]=S_NAME; 4374887Schin if(state[1][c]==S_REG) 4384887Schin state[1][c]=0; 4394887Schin state[2][c]=S_ALP; 4404887Schin if(state[3][c]==S_ERR) 4414887Schin state[3][c]=0; 4424887Schin } 4434887Schin } 4444887Schin else 4454887Schin { 4464887Schin sh_lexstates[ST_BEGIN]=(char*)sh_lexrstates[ST_BEGIN]; 4474887Schin sh_lexstates[ST_NAME]=(char*)sh_lexrstates[ST_NAME]; 4484887Schin sh_lexstates[ST_DOL]=(char*)sh_lexrstates[ST_DOL]; 4494887Schin sh_lexstates[ST_BRACE]=(char*)sh_lexrstates[ST_BRACE]; 4504887Schin } 4514887Schin } 4524887Schin #if ERROR_VERSION < 20000101L 4534887Schin if(type==LC_ALL || type==LC_MESSAGES) 4544887Schin error_info.translate = msg_translate; 4554887Schin #endif 4564887Schin } 4574887Schin #endif /* _hdr_locale */ 4584887Schin 4594887Schin /* Trap for IFS assignment and invalidates state table */ 4604887Schin static void put_ifs(register Namval_t* np,const char *val,int flags,Namfun_t *fp) 4614887Schin { 4624887Schin register struct ifs *ip = (struct ifs*)fp; 46310898Sroland.mainz@nrubsig.org Shell_t *shp; 4644887Schin ip->ifsnp = 0; 46510898Sroland.mainz@nrubsig.org if(!val) 46610898Sroland.mainz@nrubsig.org { 46710898Sroland.mainz@nrubsig.org fp = nv_stack(np, NIL(Namfun_t*)); 46810898Sroland.mainz@nrubsig.org if(fp && !fp->nofree) 46910898Sroland.mainz@nrubsig.org free((void*)fp); 47010898Sroland.mainz@nrubsig.org } 4714887Schin if(val != np->nvalue.cp) 4724887Schin nv_putv(np, val, flags, fp); 47310898Sroland.mainz@nrubsig.org if(!val && !(flags&NV_CLONE) && (fp=np->nvfun) && !fp->disc && (shp=(Shell_t*)(fp->last))) 47410898Sroland.mainz@nrubsig.org nv_stack(np,&((Init_t*)shp->init_context)->IFS_init.hdr); 4754887Schin } 4764887Schin 4774887Schin /* 4784887Schin * This is the lookup function for IFS 4794887Schin * It keeps the sh.ifstable up to date 4804887Schin */ 4814887Schin static char* get_ifs(register Namval_t* np, Namfun_t *fp) 4824887Schin { 4834887Schin register struct ifs *ip = (struct ifs*)fp; 4844887Schin register char *cp, *value; 4854887Schin register int c,n; 4868462SApril.Chin@Sun.COM register Shell_t *shp = nv_shell(np); 4874887Schin value = nv_getv(np,fp); 4884887Schin if(np!=ip->ifsnp) 4894887Schin { 4904887Schin ip->ifsnp = np; 4914887Schin memset(shp->ifstable,0,(1<<CHAR_BIT)); 4924887Schin if(cp=value) 4934887Schin { 4944887Schin #if SHOPT_MULTIBYTE 4954887Schin while(n=mbsize(cp),c= *(unsigned char*)cp) 4964887Schin #else 4974887Schin while(c= *(unsigned char*)cp++) 4984887Schin #endif /* SHOPT_MULTIBYTE */ 4994887Schin { 5004887Schin #if SHOPT_MULTIBYTE 5014887Schin cp++; 5024887Schin if(n>1) 5034887Schin { 5044887Schin cp += (n-1); 5054887Schin shp->ifstable[c] = S_MBYTE; 5064887Schin continue; 5074887Schin } 5084887Schin #endif /* SHOPT_MULTIBYTE */ 5094887Schin n = S_DELIM; 5104887Schin if(c== *cp) 5114887Schin cp++; 5124887Schin else if(c=='\n') 5134887Schin n = S_NL; 5144887Schin else if(isspace(c)) 5154887Schin n = S_SPACE; 5164887Schin shp->ifstable[c] = n; 5174887Schin } 5184887Schin } 5194887Schin else 5204887Schin { 5214887Schin shp->ifstable[' '] = shp->ifstable['\t'] = S_SPACE; 5224887Schin shp->ifstable['\n'] = S_NL; 5234887Schin } 5244887Schin } 5254887Schin return(value); 5264887Schin } 5274887Schin 5284887Schin /* 5294887Schin * these functions are used to get and set the SECONDS variable 5304887Schin */ 5314887Schin #ifdef timeofday 5324887Schin # define dtime(tp) ((double)((tp)->tv_sec)+1e-6*((double)((tp)->tv_usec))) 5334887Schin # define tms timeval 5344887Schin #else 5354887Schin # define dtime(tp) (((double)times(tp))/sh.lim.clk_tck) 5364887Schin # define timeofday(a) 5374887Schin #endif 5384887Schin 5394887Schin static void put_seconds(register Namval_t* np,const char *val,int flags,Namfun_t *fp) 5404887Schin { 5414887Schin double d; 5424887Schin struct tms tp; 5434887Schin if(!val) 5444887Schin { 54510898Sroland.mainz@nrubsig.org fp = nv_stack(np, NIL(Namfun_t*)); 54610898Sroland.mainz@nrubsig.org if(fp && !fp->nofree) 54710898Sroland.mainz@nrubsig.org free((void*)fp); 54810898Sroland.mainz@nrubsig.org nv_putv(np, val, flags, fp); 5494887Schin return; 5504887Schin } 5514887Schin if(!np->nvalue.dp) 5524887Schin { 5534887Schin nv_setsize(np,3); 5548462SApril.Chin@Sun.COM nv_onattr(np,NV_DOUBLE); 5554887Schin np->nvalue.dp = new_of(double,0); 5564887Schin } 5574887Schin nv_putv(np, val, flags, fp); 5584887Schin d = *np->nvalue.dp; 5594887Schin timeofday(&tp); 5604887Schin *np->nvalue.dp = dtime(&tp)-d; 5614887Schin } 5624887Schin 5634887Schin static char* get_seconds(register Namval_t* np, Namfun_t *fp) 5644887Schin { 5658462SApril.Chin@Sun.COM Shell_t *shp = nv_shell(np); 5664887Schin register int places = nv_size(np); 5674887Schin struct tms tp; 5684887Schin double d, offset = (np->nvalue.dp?*np->nvalue.dp:0); 5694887Schin NOT_USED(fp); 5704887Schin timeofday(&tp); 5714887Schin d = dtime(&tp)- offset; 5728462SApril.Chin@Sun.COM sfprintf(shp->strbuf,"%.*f",places,d); 5738462SApril.Chin@Sun.COM return(sfstruse(shp->strbuf)); 5744887Schin } 5754887Schin 5764887Schin static Sfdouble_t nget_seconds(register Namval_t* np, Namfun_t *fp) 5774887Schin { 5784887Schin struct tms tp; 5794887Schin double offset = (np->nvalue.dp?*np->nvalue.dp:0); 5804887Schin NOT_USED(fp); 5814887Schin timeofday(&tp); 5824887Schin return(dtime(&tp)- offset); 5834887Schin } 5844887Schin 5854887Schin /* 5864887Schin * These three functions are used to get and set the RANDOM variable 5874887Schin */ 5884887Schin static void put_rand(register Namval_t* np,const char *val,int flags,Namfun_t *fp) 5894887Schin { 5904887Schin struct rand *rp = (struct rand*)fp; 5914887Schin register long n; 5924887Schin if(!val) 5934887Schin { 59410898Sroland.mainz@nrubsig.org fp = nv_stack(np, NIL(Namfun_t*)); 59510898Sroland.mainz@nrubsig.org if(fp && !fp->nofree) 59610898Sroland.mainz@nrubsig.org free((void*)fp); 5974887Schin nv_unset(np); 5984887Schin return; 5994887Schin } 6004887Schin if(flags&NV_INTEGER) 6014887Schin n = *(double*)val; 6024887Schin else 6034887Schin n = sh_arith(val); 6044887Schin srand((int)(n&RANDMASK)); 6054887Schin rp->rand_last = -1; 6064887Schin if(!np->nvalue.lp) 6074887Schin np->nvalue.lp = &rp->rand_last; 6084887Schin } 6094887Schin 6104887Schin /* 6114887Schin * get random number in range of 0 - 2**15 6124887Schin * never pick same number twice in a row 6134887Schin */ 6144887Schin static Sfdouble_t nget_rand(register Namval_t* np, Namfun_t *fp) 6154887Schin { 6164887Schin register long cur, last= *np->nvalue.lp; 6174887Schin NOT_USED(fp); 6184887Schin do 6194887Schin cur = (rand()>>rand_shift)&RANDMASK; 6204887Schin while(cur==last); 6214887Schin *np->nvalue.lp = cur; 6224887Schin return((Sfdouble_t)cur); 6234887Schin } 6244887Schin 6254887Schin static char* get_rand(register Namval_t* np, Namfun_t *fp) 6264887Schin { 6274887Schin register long n = nget_rand(np,fp); 6284887Schin return(fmtbase(n, 10, 0)); 6294887Schin } 6304887Schin 6314887Schin /* 6324887Schin * These three routines are for LINENO 6334887Schin */ 6344887Schin static Sfdouble_t nget_lineno(Namval_t* np, Namfun_t *fp) 6354887Schin { 6364887Schin double d=1; 6374887Schin if(error_info.line >0) 6384887Schin d = error_info.line; 6394887Schin else if(error_info.context && error_info.context->line>0) 6404887Schin d = error_info.context->line; 6414887Schin NOT_USED(np); 6424887Schin NOT_USED(fp); 6434887Schin return(d); 6444887Schin } 6454887Schin 6464887Schin static void put_lineno(Namval_t* np,const char *val,int flags,Namfun_t *fp) 6474887Schin { 6484887Schin register long n; 6498462SApril.Chin@Sun.COM Shell_t *shp = nv_shell(np); 6504887Schin if(!val) 6514887Schin { 65210898Sroland.mainz@nrubsig.org fp = nv_stack(np, NIL(Namfun_t*)); 65310898Sroland.mainz@nrubsig.org if(fp && !fp->nofree) 65410898Sroland.mainz@nrubsig.org free((void*)fp); 6554887Schin nv_unset(np); 6564887Schin return; 6574887Schin } 6584887Schin if(flags&NV_INTEGER) 6594887Schin n = *(double*)val; 6604887Schin else 6614887Schin n = sh_arith(val); 6624887Schin shp->st.firstline += nget_lineno(np,fp)+1-n; 6634887Schin } 6644887Schin 6654887Schin static char* get_lineno(register Namval_t* np, Namfun_t *fp) 6664887Schin { 6674887Schin register long n = nget_lineno(np,fp); 6684887Schin return(fmtbase(n, 10, 0)); 6694887Schin } 6704887Schin 6714887Schin static char* get_lastarg(Namval_t* np, Namfun_t *fp) 6724887Schin { 67310898Sroland.mainz@nrubsig.org Shell_t *shp = nv_shell(np); 67410898Sroland.mainz@nrubsig.org char *cp; 67510898Sroland.mainz@nrubsig.org int pid; 67610898Sroland.mainz@nrubsig.org if(sh_isstate(SH_INIT) && (cp=shp->lastarg) && *cp=='*' && (pid=strtol(cp+1,&cp,10)) && *cp=='*') 67710898Sroland.mainz@nrubsig.org nv_putval(np,(pid==getppid()?cp+1:0),0); 6788462SApril.Chin@Sun.COM return(shp->lastarg); 6794887Schin } 6804887Schin 6814887Schin static void put_lastarg(Namval_t* np,const char *val,int flags,Namfun_t *fp) 6824887Schin { 6838462SApril.Chin@Sun.COM Shell_t *shp = nv_shell(np); 6844887Schin if(flags&NV_INTEGER) 6854887Schin { 6868462SApril.Chin@Sun.COM sfprintf(shp->strbuf,"%.*g",12,*((double*)val)); 6878462SApril.Chin@Sun.COM val = sfstruse(shp->strbuf); 6884887Schin } 68910898Sroland.mainz@nrubsig.org if(val) 69010898Sroland.mainz@nrubsig.org val = strdup(val); 6918462SApril.Chin@Sun.COM if(shp->lastarg && !nv_isattr(np,NV_NOFREE)) 6928462SApril.Chin@Sun.COM free((void*)shp->lastarg); 6934887Schin else 6944887Schin nv_offattr(np,NV_NOFREE); 69510898Sroland.mainz@nrubsig.org shp->lastarg = (char*)val; 69610898Sroland.mainz@nrubsig.org nv_offattr(np,NV_EXPORT); 69710898Sroland.mainz@nrubsig.org np->nvenv = 0; 6984887Schin } 6994887Schin 7004887Schin static int hasgetdisc(register Namfun_t *fp) 7014887Schin { 7024887Schin while(fp && !fp->disc->getnum && !fp->disc->getval) 7034887Schin fp = fp->next; 7044887Schin return(fp!=0); 7054887Schin } 7064887Schin 7074887Schin /* 7084887Schin * store the most recent value for use in .sh.match 7094887Schin */ 7104887Schin void sh_setmatch(const char *v, int vsize, int nmatch, int match[]) 7114887Schin { 7124887Schin struct match *mp = (struct match*)(SH_MATCHNOD->nvfun); 7134887Schin register int i,n; 7144887Schin if(mp->nmatch = nmatch) 7154887Schin { 7164887Schin memcpy(mp->match,match,nmatch*2*sizeof(match[0])); 7174887Schin for(n=match[0],i=1; i < 2*nmatch; i++) 7184887Schin { 7194887Schin if(mp->match[i] < n) 7204887Schin n = mp->match[i]; 7214887Schin } 7224887Schin for(vsize=0,i=0; i < 2*nmatch; i++) 7234887Schin { 7244887Schin if((mp->match[i] -= n) > vsize) 7254887Schin vsize = mp->match[i]; 7264887Schin } 7274887Schin v += n; 7284887Schin if(vsize >= mp->vsize) 7294887Schin { 7304887Schin if(mp->vsize) 7314887Schin mp->val = (char*)realloc(mp->val,vsize+1); 7324887Schin else 7334887Schin mp->val = (char*)malloc(vsize+1); 7344887Schin mp->vsize = vsize; 7354887Schin } 7364887Schin memcpy(mp->val,v,vsize); 7374887Schin mp->val[vsize] = 0; 7388462SApril.Chin@Sun.COM nv_putsub(SH_MATCHNOD, NIL(char*), (nmatch-1)|ARRAY_FILL); 7394887Schin mp->lastsub = -1; 7404887Schin } 7414887Schin } 7424887Schin 7434887Schin #define array_scan(np) ((nv_arrayptr(np)->nelem&ARRAY_SCAN)) 7444887Schin 7454887Schin static char* get_match(register Namval_t* np, Namfun_t *fp) 7464887Schin { 7474887Schin struct match *mp = (struct match*)fp; 7484887Schin int sub,n; 7494887Schin char *val; 7504887Schin sub = nv_aindex(np); 7514887Schin if(sub>=mp->nmatch) 7524887Schin return(0); 7534887Schin if(sub==mp->lastsub) 7544887Schin return(mp->rval); 7554887Schin if(mp->rval) 7564887Schin { 7574887Schin free((void*)mp->rval); 7584887Schin mp->rval = 0; 7594887Schin } 7604887Schin n = mp->match[2*sub+1]-mp->match[2*sub]; 7614887Schin if(n<=0) 7624887Schin return(""); 7634887Schin val = mp->val+mp->match[2*sub]; 7644887Schin if(mp->val[mp->match[2*sub+1]]==0) 7654887Schin return(val); 7664887Schin mp->rval = (char*)malloc(n+1); 7674887Schin mp->lastsub = sub; 7684887Schin memcpy(mp->rval,val,n); 7694887Schin mp->rval[n] = 0; 7704887Schin return(mp->rval); 7714887Schin } 7724887Schin 7738462SApril.Chin@Sun.COM static const Namdisc_t SH_MATCH_disc = { sizeof(struct match), 0, get_match }; 7748462SApril.Chin@Sun.COM 7758462SApril.Chin@Sun.COM static char* get_version(register Namval_t* np, Namfun_t *fp) 7768462SApril.Chin@Sun.COM { 7778462SApril.Chin@Sun.COM return(nv_getv(np,fp)); 7788462SApril.Chin@Sun.COM } 7798462SApril.Chin@Sun.COM 7808462SApril.Chin@Sun.COM static Sfdouble_t nget_version(register Namval_t* np, Namfun_t *fp) 7818462SApril.Chin@Sun.COM { 7828462SApril.Chin@Sun.COM register const char *cp = e_version + strlen(e_version)-10; 7838462SApril.Chin@Sun.COM register int c; 7848462SApril.Chin@Sun.COM Sflong_t t = 0; 7858462SApril.Chin@Sun.COM NOT_USED(fp); 7868462SApril.Chin@Sun.COM 7878462SApril.Chin@Sun.COM while (c = *cp++) 7888462SApril.Chin@Sun.COM if (c >= '0' && c <= '9') 7898462SApril.Chin@Sun.COM { 7908462SApril.Chin@Sun.COM t *= 10; 7918462SApril.Chin@Sun.COM t += c - '0'; 7928462SApril.Chin@Sun.COM } 7938462SApril.Chin@Sun.COM return((Sfdouble_t)t); 7948462SApril.Chin@Sun.COM } 7958462SApril.Chin@Sun.COM 7968462SApril.Chin@Sun.COM static const Namdisc_t SH_VERSION_disc = { 0, 0, get_version, nget_version }; 7974887Schin 7984887Schin #if SHOPT_FS_3D 7994887Schin /* 8004887Schin * set or unset the mappings given a colon separated list of directories 8014887Schin */ 8024887Schin static void vpath_set(char *str, int mode) 8034887Schin { 8044887Schin register char *lastp, *oldp=str, *newp=strchr(oldp,':'); 8054887Schin if(!sh.lim.fs3d) 8064887Schin return; 8074887Schin while(newp) 8084887Schin { 8094887Schin *newp++ = 0; 8104887Schin if(lastp=strchr(newp,':')) 8114887Schin *lastp = 0; 8124887Schin mount((mode?newp:""),oldp,FS3D_VIEW,0); 8134887Schin newp[-1] = ':'; 8144887Schin oldp = newp; 8154887Schin newp=lastp; 8164887Schin } 8174887Schin } 8184887Schin 8194887Schin /* catch vpath assignments */ 8204887Schin static void put_vpath(register Namval_t* np,const char *val,int flags,Namfun_t *fp) 8214887Schin { 8224887Schin register char *cp; 8234887Schin if(cp = nv_getval(np)) 8244887Schin vpath_set(cp,0); 8254887Schin if(val) 8264887Schin vpath_set((char*)val,1); 8274887Schin nv_putv(np,val,flags,fp); 8284887Schin } 8294887Schin static const Namdisc_t VPATH_disc = { 0, put_vpath }; 8304887Schin static Namfun_t VPATH_init = { &VPATH_disc, 1 }; 8314887Schin #endif /* SHOPT_FS_3D */ 8324887Schin 8334887Schin 8344887Schin static const Namdisc_t IFS_disc = { sizeof(struct ifs), put_ifs, get_ifs }; 8358462SApril.Chin@Sun.COM const Namdisc_t RESTRICTED_disc = { sizeof(Namfun_t), put_restricted }; 8368462SApril.Chin@Sun.COM static const Namdisc_t CDPATH_disc = { sizeof(Namfun_t), put_cdpath }; 8378462SApril.Chin@Sun.COM static const Namdisc_t EDITOR_disc = { sizeof(Namfun_t), put_ed }; 8388462SApril.Chin@Sun.COM static const Namdisc_t HISTFILE_disc = { sizeof(Namfun_t), put_history }; 8398462SApril.Chin@Sun.COM static const Namdisc_t OPTINDEX_disc = { sizeof(Namfun_t), put_optindex, 0, nget_optindex, 0, 0, clone_optindex }; 8404887Schin static const Namdisc_t SECONDS_disc = { sizeof(struct seconds), put_seconds, get_seconds, nget_seconds }; 8414887Schin static const Namdisc_t RAND_disc = { sizeof(struct rand), put_rand, get_rand, nget_rand }; 8428462SApril.Chin@Sun.COM static const Namdisc_t LINENO_disc = { sizeof(Namfun_t), put_lineno, get_lineno, nget_lineno }; 8438462SApril.Chin@Sun.COM static const Namdisc_t L_ARG_disc = { sizeof(Namfun_t), put_lastarg, get_lastarg }; 8444887Schin 8454887Schin #if SHOPT_NAMESPACE 8464887Schin static char* get_nspace(Namval_t* np, Namfun_t *fp) 8474887Schin { 8484887Schin if(sh.namespace) 8494887Schin return(nv_name(sh.namespace)); 8504887Schin return((char*)np->nvalue.cp); 8514887Schin } 8524887Schin static const Namdisc_t NSPACE_disc = { 0, 0, get_nspace }; 8534887Schin static Namfun_t NSPACE_init = { &NSPACE_disc, 1}; 8544887Schin #endif /* SHOPT_NAMESPACE */ 8554887Schin 8564887Schin #ifdef _hdr_locale 8578462SApril.Chin@Sun.COM static const Namdisc_t LC_disc = { sizeof(Namfun_t), put_lang }; 8584887Schin #endif /* _hdr_locale */ 8594887Schin 8604887Schin /* 8614887Schin * This function will get called whenever a configuration parameter changes 8624887Schin */ 8634887Schin static int newconf(const char *name, const char *path, const char *value) 8644887Schin { 8654887Schin register char *arg; 8664887Schin if(!name) 8674887Schin setenviron(value); 8684887Schin else if(strcmp(name,"UNIVERSE")==0 && strcmp(astconf(name,0,0),value)) 8694887Schin { 8704887Schin sh.universe = 0; 8714887Schin /* set directory in new universe */ 8724887Schin if(*(arg = path_pwd(0))=='/') 8734887Schin chdir(arg); 8744887Schin /* clear out old tracked alias */ 8754887Schin stakseek(0); 8764887Schin stakputs(nv_getval(PATHNOD)); 8774887Schin stakputc(0); 8784887Schin nv_putval(PATHNOD,stakseek(0),NV_RDONLY); 8794887Schin } 8804887Schin return(1); 8814887Schin } 8824887Schin 8834887Schin #if (CC_NATIVE != CC_ASCII) 8844887Schin static void a2e(char *d, const char *s) 8854887Schin { 8864887Schin register const unsigned char *t; 8874887Schin register int i; 8884887Schin t = CCMAP(CC_ASCII, CC_NATIVE); 8894887Schin for(i=0; i<(1<<CHAR_BIT); i++) 8904887Schin d[t[i]] = s[i]; 8914887Schin } 8924887Schin 8934887Schin static void init_ebcdic(void) 8944887Schin { 8954887Schin int i; 8964887Schin char *cp = (char*)malloc(ST_NONE*(1<<CHAR_BIT)); 8974887Schin for(i=0; i < ST_NONE; i++) 8984887Schin { 8994887Schin a2e(cp,sh_lexrstates[i]); 9004887Schin sh_lexstates[i] = cp; 9014887Schin cp += (1<<CHAR_BIT); 9024887Schin } 9034887Schin } 9044887Schin #endif 9054887Schin 9064887Schin /* 9074887Schin * return SH_TYPE_* bitmask for path 9084887Schin * 0 for "not a shell" 9094887Schin */ 9104887Schin int sh_type(register const char *path) 9114887Schin { 9124887Schin register const char* s; 9134887Schin register int t = 0; 9144887Schin 9154887Schin if (s = (const char*)strrchr(path, '/')) 9164887Schin { 9174887Schin if (*path == '-') 9184887Schin t |= SH_TYPE_LOGIN; 9194887Schin s++; 9204887Schin } 9214887Schin else 9224887Schin s = path; 9234887Schin if (*s == '-') 9244887Schin { 9254887Schin s++; 9264887Schin t |= SH_TYPE_LOGIN; 9274887Schin } 9284887Schin for (;;) 9294887Schin { 9304887Schin if (!(t & (SH_TYPE_KSH|SH_TYPE_BASH))) 9314887Schin { 9324887Schin if (*s == 'k') 9334887Schin { 9344887Schin s++; 9354887Schin t |= SH_TYPE_KSH; 9364887Schin continue; 9374887Schin } 9384887Schin #if SHOPT_BASH 9394887Schin if (*s == 'b' && *(s+1) == 'a') 9404887Schin { 9414887Schin s += 2; 9424887Schin t |= SH_TYPE_BASH; 9434887Schin continue; 9444887Schin } 9454887Schin #endif 9464887Schin } 9474887Schin if (!(t & (SH_TYPE_PROFILE|SH_TYPE_RESTRICTED))) 9484887Schin { 9494887Schin #if SHOPT_PFSH 9504887Schin if (*s == 'p' && *(s+1) == 'f') 9514887Schin { 9524887Schin s += 2; 9534887Schin t |= SH_TYPE_PROFILE; 9544887Schin continue; 9554887Schin } 9564887Schin #endif 9574887Schin if (*s == 'r') 9584887Schin { 9594887Schin s++; 9604887Schin t |= SH_TYPE_RESTRICTED; 9614887Schin continue; 9624887Schin } 9634887Schin } 9644887Schin break; 9654887Schin } 9668462SApril.Chin@Sun.COM if (*s++ == 's' && (*s == 'h' || *s == 'u')) 9678462SApril.Chin@Sun.COM { 9688462SApril.Chin@Sun.COM s++; 9698462SApril.Chin@Sun.COM t |= SH_TYPE_SH; 9708462SApril.Chin@Sun.COM if ((t & SH_TYPE_KSH) && *s == '9' && *(s+1) == '3') 9718462SApril.Chin@Sun.COM s += 2; 9724887Schin #if _WINIX 9738462SApril.Chin@Sun.COM if (*s == '.' && *(s+1) == 'e' && *(s+2) == 'x' && *(s+3) == 'e') 9748462SApril.Chin@Sun.COM s += 4; 9754887Schin #endif 9768462SApril.Chin@Sun.COM if (!isalnum(*s)) 9778462SApril.Chin@Sun.COM return t; 9788462SApril.Chin@Sun.COM } 9798462SApril.Chin@Sun.COM return t & ~(SH_TYPE_BASH|SH_TYPE_KSH|SH_TYPE_PROFILE|SH_TYPE_RESTRICTED); 9808462SApril.Chin@Sun.COM } 9818462SApril.Chin@Sun.COM 9828462SApril.Chin@Sun.COM 9838462SApril.Chin@Sun.COM static char *get_mode(Namval_t* np, Namfun_t* nfp) 9848462SApril.Chin@Sun.COM { 9858462SApril.Chin@Sun.COM mode_t mode = nv_getn(np,nfp); 9868462SApril.Chin@Sun.COM return(fmtperm(mode)); 9874887Schin } 9884887Schin 9898462SApril.Chin@Sun.COM static void put_mode(Namval_t* np, const char* val, int flag, Namfun_t* nfp) 9908462SApril.Chin@Sun.COM { 9918462SApril.Chin@Sun.COM if(val) 9928462SApril.Chin@Sun.COM { 9938462SApril.Chin@Sun.COM mode_t mode; 9948462SApril.Chin@Sun.COM char *last; 9958462SApril.Chin@Sun.COM if(flag&NV_INTEGER) 9968462SApril.Chin@Sun.COM { 9978462SApril.Chin@Sun.COM if(flag&NV_LONG) 9988462SApril.Chin@Sun.COM mode = *(Sfdouble_t*)val; 9998462SApril.Chin@Sun.COM else 10008462SApril.Chin@Sun.COM mode = *(double*)val; 10018462SApril.Chin@Sun.COM } 10028462SApril.Chin@Sun.COM else 10038462SApril.Chin@Sun.COM mode = strperm(val, &last,0); 10048462SApril.Chin@Sun.COM if(*last) 10058462SApril.Chin@Sun.COM errormsg(SH_DICT,ERROR_exit(1),"%s: invalid mode string",val); 10068462SApril.Chin@Sun.COM nv_putv(np,(char*)&mode,NV_INTEGER,nfp); 10078462SApril.Chin@Sun.COM } 10088462SApril.Chin@Sun.COM else 10098462SApril.Chin@Sun.COM nv_putv(np,val,flag,nfp); 10108462SApril.Chin@Sun.COM } 10118462SApril.Chin@Sun.COM 10128462SApril.Chin@Sun.COM static const Namdisc_t modedisc = 10138462SApril.Chin@Sun.COM { 10148462SApril.Chin@Sun.COM 0, 10158462SApril.Chin@Sun.COM put_mode, 10168462SApril.Chin@Sun.COM get_mode, 10178462SApril.Chin@Sun.COM }; 10188462SApril.Chin@Sun.COM 10198462SApril.Chin@Sun.COM 10204887Schin /* 10214887Schin * initialize the shell 10224887Schin */ 10238462SApril.Chin@Sun.COM Shell_t *sh_init(register int argc,register char *argv[], Shinit_f userinit) 10244887Schin { 10258462SApril.Chin@Sun.COM Shell_t *shp = &sh; 10264887Schin register int n; 10274887Schin int type; 1028*12068SRoger.Faulkner@Oracle.COM long v; 10294887Schin static char *login_files[3]; 103010898Sroland.mainz@nrubsig.org memfatal(); 10314887Schin n = strlen(e_version); 10324887Schin if(e_version[n-1]=='$' && e_version[n-2]==' ') 10334887Schin e_version[n-2]=0; 10344887Schin #if (CC_NATIVE == CC_ASCII) 10354887Schin memcpy(sh_lexstates,sh_lexrstates,ST_NONE*sizeof(char*)); 10364887Schin #else 10374887Schin init_ebcdic(); 10384887Schin #endif 10398462SApril.Chin@Sun.COM umask(shp->mask=umask(0)); 10408462SApril.Chin@Sun.COM shp->mac_context = sh_macopen(shp); 10418462SApril.Chin@Sun.COM shp->arg_context = sh_argopen(shp); 10428462SApril.Chin@Sun.COM shp->lex_context = (void*)sh_lexopen(0,shp,1); 10438462SApril.Chin@Sun.COM shp->ed_context = (void*)ed_open(shp); 10448462SApril.Chin@Sun.COM shp->strbuf = sfstropen(); 10458462SApril.Chin@Sun.COM shp->stk = stkstd; 10468462SApril.Chin@Sun.COM sfsetbuf(shp->strbuf,(char*)0,64); 10474887Schin sh_onstate(SH_INIT); 10484887Schin error_info.exit = sh_exit; 10494887Schin error_info.id = path_basename(argv[0]); 10504887Schin #if ERROR_VERSION >= 20000102L 10514887Schin error_info.catalog = e_dict; 10524887Schin #endif 105310898Sroland.mainz@nrubsig.org #if SHOPT_REGRESS 105410898Sroland.mainz@nrubsig.org { 105510898Sroland.mainz@nrubsig.org Opt_t* nopt; 105610898Sroland.mainz@nrubsig.org Opt_t* oopt; 105710898Sroland.mainz@nrubsig.org char* a; 105810898Sroland.mainz@nrubsig.org char** av = argv; 105910898Sroland.mainz@nrubsig.org char* regress[3]; 106010898Sroland.mainz@nrubsig.org 106110898Sroland.mainz@nrubsig.org sh_regress_init(shp); 106210898Sroland.mainz@nrubsig.org regress[0] = "__regress__"; 106310898Sroland.mainz@nrubsig.org regress[2] = 0; 106410898Sroland.mainz@nrubsig.org /* NOTE: only shp is used by __regress__ at this point */ 106510898Sroland.mainz@nrubsig.org shp->bltindata.shp = shp; 106610898Sroland.mainz@nrubsig.org while ((a = *++av) && a[0] == '-' && (a[1] == 'I' || a[1] == '-' && a[2] == 'r')) 106710898Sroland.mainz@nrubsig.org { 106810898Sroland.mainz@nrubsig.org if (a[1] == 'I') 106910898Sroland.mainz@nrubsig.org { 107010898Sroland.mainz@nrubsig.org if (a[2]) 107110898Sroland.mainz@nrubsig.org regress[1] = a + 2; 107210898Sroland.mainz@nrubsig.org else if (!(regress[1] = *++av)) 107310898Sroland.mainz@nrubsig.org break; 107410898Sroland.mainz@nrubsig.org } 107510898Sroland.mainz@nrubsig.org else if (strncmp(a+2, "regress", 7)) 107610898Sroland.mainz@nrubsig.org break; 107710898Sroland.mainz@nrubsig.org else if (a[9] == '=') 107810898Sroland.mainz@nrubsig.org regress[1] = a + 10; 107910898Sroland.mainz@nrubsig.org else if (!(regress[1] = *++av)) 108010898Sroland.mainz@nrubsig.org break; 108110898Sroland.mainz@nrubsig.org nopt = optctx(0, 0); 108210898Sroland.mainz@nrubsig.org oopt = optctx(nopt, 0); 108310898Sroland.mainz@nrubsig.org b___regress__(2, regress, &shp->bltindata); 108410898Sroland.mainz@nrubsig.org optctx(oopt, nopt); 108510898Sroland.mainz@nrubsig.org } 108610898Sroland.mainz@nrubsig.org } 108710898Sroland.mainz@nrubsig.org #endif 10888462SApril.Chin@Sun.COM shp->cpipe[0] = -1; 10898462SApril.Chin@Sun.COM shp->coutpipe = -1; 10908462SApril.Chin@Sun.COM shp->userid=getuid(); 10918462SApril.Chin@Sun.COM shp->euserid=geteuid(); 10928462SApril.Chin@Sun.COM shp->groupid=getgid(); 10938462SApril.Chin@Sun.COM shp->egroupid=getegid(); 10944887Schin for(n=0;n < 10; n++) 10954887Schin { 10964887Schin /* don't use lower bits when rand() generates large numbers */ 10974887Schin if(rand() > RANDMASK) 10984887Schin { 10994887Schin rand_shift = 3; 11004887Schin break; 11014887Schin } 11024887Schin } 11038462SApril.Chin@Sun.COM shp->lim.clk_tck = getconf("CLK_TCK"); 11048462SApril.Chin@Sun.COM shp->lim.arg_max = getconf("ARG_MAX"); 11058462SApril.Chin@Sun.COM shp->lim.open_max = getconf("OPEN_MAX"); 11068462SApril.Chin@Sun.COM shp->lim.child_max = getconf("CHILD_MAX"); 11078462SApril.Chin@Sun.COM shp->lim.ngroups_max = getconf("NGROUPS_MAX"); 11088462SApril.Chin@Sun.COM shp->lim.posix_version = getconf("VERSION"); 11098462SApril.Chin@Sun.COM shp->lim.posix_jobcontrol = getconf("JOB_CONTROL"); 11108462SApril.Chin@Sun.COM if(shp->lim.arg_max <=0) 11118462SApril.Chin@Sun.COM shp->lim.arg_max = ARG_MAX; 11128462SApril.Chin@Sun.COM if(shp->lim.child_max <=0) 11138462SApril.Chin@Sun.COM shp->lim.child_max = CHILD_MAX; 1114*12068SRoger.Faulkner@Oracle.COM if((v = getconf("PID_MAX")) > 0 && shp->lim.child_max > v) 1115*12068SRoger.Faulkner@Oracle.COM shp->lim.child_max = v; 11168462SApril.Chin@Sun.COM if(shp->lim.open_max <0) 11178462SApril.Chin@Sun.COM shp->lim.open_max = OPEN_MAX; 11188462SApril.Chin@Sun.COM if(shp->lim.open_max > (SHRT_MAX-2)) 11198462SApril.Chin@Sun.COM shp->lim.open_max = SHRT_MAX-2; 11208462SApril.Chin@Sun.COM if(shp->lim.clk_tck <=0) 11218462SApril.Chin@Sun.COM shp->lim.clk_tck = CLK_TCK; 11224887Schin #if SHOPT_FS_3D 11234887Schin if(fs3d(FS3D_TEST)) 11248462SApril.Chin@Sun.COM shp->lim.fs3d = 1; 11254887Schin #endif /* SHOPT_FS_3D */ 11268462SApril.Chin@Sun.COM sh_ioinit(shp); 11274887Schin /* initialize signal handling */ 11288462SApril.Chin@Sun.COM sh_siginit(shp); 11294887Schin stakinstall(NIL(Stak_t*),nospace); 11304887Schin /* set up memory for name-value pairs */ 11318462SApril.Chin@Sun.COM shp->init_context = nv_init(shp); 11324887Schin /* read the environment */ 11334887Schin if(argc>0) 11344887Schin { 11354887Schin type = sh_type(*argv); 11364887Schin if(type&SH_TYPE_LOGIN) 11378462SApril.Chin@Sun.COM shp->login_sh = 2; 11384887Schin } 11398462SApril.Chin@Sun.COM env_init(shp); 114010898Sroland.mainz@nrubsig.org if(!ENVNOD->nvalue.cp) 114110898Sroland.mainz@nrubsig.org { 114210898Sroland.mainz@nrubsig.org sfprintf(shp->strbuf,"%s/.kshrc",nv_getval(HOME)); 114310898Sroland.mainz@nrubsig.org nv_putval(ENVNOD,sfstruse(shp->strbuf),NV_RDONLY); 114410898Sroland.mainz@nrubsig.org } 11458462SApril.Chin@Sun.COM *SHLVL->nvalue.ip +=1; 11464887Schin #if SHOPT_SPAWN 11474887Schin { 11484887Schin /* 11494887Schin * try to find the pathname for this interpreter 11504887Schin * try using environment variable _ or argv[0] 11514887Schin */ 115210898Sroland.mainz@nrubsig.org char *cp=nv_getval(L_ARGNOD); 11534887Schin char buff[PATH_MAX+1]; 11548462SApril.Chin@Sun.COM shp->shpath = 0; 115510898Sroland.mainz@nrubsig.org #if _AST_VERSION >= 20090202L 115610898Sroland.mainz@nrubsig.org if((n = pathprog(NiL, buff, sizeof(buff))) > 0 && n <= sizeof(buff)) 115710898Sroland.mainz@nrubsig.org shp->shpath = strdup(buff); 115810898Sroland.mainz@nrubsig.org #else 11598462SApril.Chin@Sun.COM sfprintf(shp->strbuf,"/proc/%d/exe",getpid()); 11608462SApril.Chin@Sun.COM if((n=readlink(sfstruse(shp->strbuf),buff,sizeof(buff)-1))>0) 11614887Schin { 11624887Schin buff[n] = 0; 11638462SApril.Chin@Sun.COM shp->shpath = strdup(buff); 11644887Schin } 116510898Sroland.mainz@nrubsig.org #endif 11664887Schin else if((cp && (sh_type(cp)&SH_TYPE_SH)) || (argc>0 && strchr(cp= *argv,'/'))) 11674887Schin { 11684887Schin if(*cp=='/') 11698462SApril.Chin@Sun.COM shp->shpath = strdup(cp); 11704887Schin else if(cp = nv_getval(PWDNOD)) 11714887Schin { 11724887Schin int offset = staktell(); 11734887Schin stakputs(cp); 11744887Schin stakputc('/'); 11754887Schin stakputs(argv[0]); 11764887Schin pathcanon(stakptr(offset),PATH_DOTDOT); 11778462SApril.Chin@Sun.COM shp->shpath = strdup(stakptr(offset)); 11784887Schin stakseek(offset); 11794887Schin } 11804887Schin } 11814887Schin } 11824887Schin #endif 11834887Schin nv_putval(IFSNOD,(char*)e_sptbnl,NV_RDONLY); 11844887Schin #if SHOPT_FS_3D 11854887Schin nv_stack(VPATHNOD, &VPATH_init); 11864887Schin #endif /* SHOPT_FS_3D */ 11874887Schin astconfdisc(newconf); 11884887Schin #if SHOPT_TIMEOUT 11898462SApril.Chin@Sun.COM shp->st.tmout = SHOPT_TIMEOUT; 11904887Schin #endif /* SHOPT_TIMEOUT */ 11914887Schin /* initialize jobs table */ 11924887Schin job_clear(); 11934887Schin if(argc>0) 11944887Schin { 11954887Schin /* check for restricted shell */ 11964887Schin if(type&SH_TYPE_RESTRICTED) 11974887Schin sh_onoption(SH_RESTRICTED); 11984887Schin #if SHOPT_PFSH 11994887Schin /* check for profile shell */ 12004887Schin else if(type&SH_TYPE_PROFILE) 12014887Schin sh_onoption(SH_PFSH); 12024887Schin #endif 12034887Schin #if SHOPT_BASH 12044887Schin /* check for invocation as bash */ 12054887Schin if(type&SH_TYPE_BASH) 12064887Schin { 12078462SApril.Chin@Sun.COM shp->userinit = userinit = bash_init; 12084887Schin sh_onoption(SH_BASH); 12094887Schin sh_onstate(SH_PREINIT); 12108462SApril.Chin@Sun.COM (*userinit)(shp, 0); 12114887Schin sh_offstate(SH_PREINIT); 12124887Schin } 12134887Schin #endif 12144887Schin /* look for options */ 12158462SApril.Chin@Sun.COM /* shp->st.dolc is $# */ 12168462SApril.Chin@Sun.COM if((shp->st.dolc = sh_argopts(-argc,argv,shp)) < 0) 12174887Schin { 12188462SApril.Chin@Sun.COM shp->exitval = 2; 12198462SApril.Chin@Sun.COM sh_done(shp,0); 12204887Schin } 12214887Schin opt_info.disc = 0; 12228462SApril.Chin@Sun.COM shp->st.dolv=argv+(argc-1)-shp->st.dolc; 12238462SApril.Chin@Sun.COM shp->st.dolv[0] = argv[0]; 12248462SApril.Chin@Sun.COM if(shp->st.dolc < 1) 12254887Schin sh_onoption(SH_SFLAG); 12264887Schin if(!sh_isoption(SH_SFLAG)) 12274887Schin { 12288462SApril.Chin@Sun.COM shp->st.dolc--; 12298462SApril.Chin@Sun.COM shp->st.dolv++; 12304887Schin #if _WINIX 12314887Schin { 12324887Schin char* name; 12338462SApril.Chin@Sun.COM name = shp->st.dolv[0]; 12344887Schin if(name[1]==':' && (name[2]=='/' || name[2]=='\\')) 12354887Schin { 12364887Schin #if _lib_pathposix 12374887Schin char* p; 12384887Schin 12394887Schin if((n = pathposix(name, NIL(char*), 0)) > 0 && (p = (char*)malloc(++n))) 12404887Schin { 12414887Schin pathposix(name, p, n); 12424887Schin name = p; 12434887Schin } 12444887Schin else 12454887Schin #endif 12464887Schin { 12474887Schin name[1] = name[0]; 12484887Schin name[0] = name[2] = '/'; 12494887Schin } 12504887Schin } 12514887Schin } 12524887Schin #endif /* _WINIX */ 12534887Schin } 12544887Schin } 12554887Schin #if SHOPT_PFSH 12564887Schin if (sh_isoption(SH_PFSH)) 12574887Schin { 12588462SApril.Chin@Sun.COM struct passwd *pw = getpwuid(shp->userid); 12594887Schin if(pw) 12608462SApril.Chin@Sun.COM shp->user = strdup(pw->pw_name); 12614887Schin 12624887Schin } 12634887Schin #endif 12644887Schin /* set[ug]id scripts require the -p flag */ 12658462SApril.Chin@Sun.COM if(shp->userid!=shp->euserid || shp->groupid!=shp->egroupid) 12664887Schin { 126710898Sroland.mainz@nrubsig.org #ifdef SHOPT_P_SUID 12684887Schin /* require sh -p to run setuid and/or setgid */ 126910898Sroland.mainz@nrubsig.org if(!sh_isoption(SH_PRIVILEGED) && shp->userid >= SHOPT_P_SUID) 12704887Schin { 12718462SApril.Chin@Sun.COM setuid(shp->euserid=shp->userid); 12728462SApril.Chin@Sun.COM setgid(shp->egroupid=shp->groupid); 12734887Schin } 12744887Schin else 127510898Sroland.mainz@nrubsig.org #endif /* SHOPT_P_SUID */ 12764887Schin sh_onoption(SH_PRIVILEGED); 12774887Schin #ifdef SHELLMAGIC 12784887Schin /* careful of #! setuid scripts with name beginning with - */ 12798462SApril.Chin@Sun.COM if(shp->login_sh && argv[1] && strcmp(argv[0],argv[1])==0) 12804887Schin errormsg(SH_DICT,ERROR_exit(1),e_prohibited); 12814887Schin #endif /*SHELLMAGIC*/ 12824887Schin } 12834887Schin else 12844887Schin sh_offoption(SH_PRIVILEGED); 12854887Schin /* shname for $0 in profiles and . scripts */ 12864887Schin if(strmatch(argv[1],e_devfdNN)) 12878462SApril.Chin@Sun.COM shp->shname = strdup(argv[0]); 12884887Schin else 12898462SApril.Chin@Sun.COM shp->shname = strdup(shp->st.dolv[0]); 12904887Schin /* 12914887Schin * return here for shell script execution 12924887Schin * but not for parenthesis subshells 12934887Schin */ 12948462SApril.Chin@Sun.COM error_info.id = strdup(shp->st.dolv[0]); /* error_info.id is $0 */ 12958462SApril.Chin@Sun.COM shp->jmpbuffer = (void*)&shp->checkbase; 12968462SApril.Chin@Sun.COM sh_pushcontext(&shp->checkbase,SH_JMPSCRIPT); 12978462SApril.Chin@Sun.COM shp->st.self = &shp->global; 12988462SApril.Chin@Sun.COM shp->topscope = (Shscope_t*)shp->st.self; 12994887Schin sh_offstate(SH_INIT); 13004887Schin login_files[0] = (char*)e_profile; 13014887Schin login_files[1] = ".profile"; 13028462SApril.Chin@Sun.COM shp->login_files = login_files; 13038462SApril.Chin@Sun.COM shp->bltindata.version = SH_VERSION; 13048462SApril.Chin@Sun.COM shp->bltindata.shp = shp; 13058462SApril.Chin@Sun.COM shp->bltindata.shrun = sh_run; 13068462SApril.Chin@Sun.COM shp->bltindata.shtrap = sh_trap; 13078462SApril.Chin@Sun.COM shp->bltindata.shexit = sh_exit; 13088462SApril.Chin@Sun.COM shp->bltindata.shbltin = sh_addbuiltin; 13098462SApril.Chin@Sun.COM #if _AST_VERSION >= 20080617L 1310*12068SRoger.Faulkner@Oracle.COM shp->bltindata.shgetenv = sh_getenv; 1311*12068SRoger.Faulkner@Oracle.COM shp->bltindata.shsetenv = sh_setenviron; 13128462SApril.Chin@Sun.COM astintercept(&shp->bltindata,1); 13138462SApril.Chin@Sun.COM #endif 13148462SApril.Chin@Sun.COM #if 0 13158462SApril.Chin@Sun.COM #define NV_MKINTTYPE(x,y,z) nv_mkinttype(#x,sizeof(x),(x)-1<0,(y),(Namdisc_t*)z); 13168462SApril.Chin@Sun.COM NV_MKINTTYPE(pid_t,"process id",0); 13178462SApril.Chin@Sun.COM NV_MKINTTYPE(gid_t,"group id",0); 13188462SApril.Chin@Sun.COM NV_MKINTTYPE(uid_t,"user id",0); 13198462SApril.Chin@Sun.COM NV_MKINTTYPE(size_t,(const char*)0,0); 13208462SApril.Chin@Sun.COM NV_MKINTTYPE(ssize_t,(const char*)0,0); 13218462SApril.Chin@Sun.COM NV_MKINTTYPE(off_t,"offset in bytes",0); 13228462SApril.Chin@Sun.COM NV_MKINTTYPE(ino_t,"\ai-\anode number",0); 13238462SApril.Chin@Sun.COM NV_MKINTTYPE(mode_t,(const char*)0,&modedisc); 13248462SApril.Chin@Sun.COM NV_MKINTTYPE(dev_t,"device id",0); 13258462SApril.Chin@Sun.COM NV_MKINTTYPE(nlink_t,"hard link count",0); 13268462SApril.Chin@Sun.COM NV_MKINTTYPE(blkcnt_t,"block count",0); 13278462SApril.Chin@Sun.COM NV_MKINTTYPE(time_t,"seconds since the epoch",0); 13288462SApril.Chin@Sun.COM nv_mkstat(); 13298462SApril.Chin@Sun.COM #endif 13308462SApril.Chin@Sun.COM if(shp->userinit=userinit) 13318462SApril.Chin@Sun.COM (*userinit)(shp, 0); 13328462SApril.Chin@Sun.COM return(shp); 13334887Schin } 13344887Schin 13354887Schin Shell_t *sh_getinterp(void) 13364887Schin { 13374887Schin return(&sh); 13384887Schin } 13394887Schin 13404887Schin /* 13414887Schin * reinitialize before executing a script 13424887Schin */ 13434887Schin int sh_reinit(char *argv[]) 13444887Schin { 13458462SApril.Chin@Sun.COM Shell_t *shp = &sh; 13464887Schin Shopt_t opt; 13478462SApril.Chin@Sun.COM Namval_t *np,*npnext; 13488462SApril.Chin@Sun.COM Dt_t *dp; 13498462SApril.Chin@Sun.COM for(np=dtfirst(shp->fun_tree);np;np=npnext) 13504887Schin { 13518462SApril.Chin@Sun.COM if((dp=shp->fun_tree)->walk) 13528462SApril.Chin@Sun.COM dp = dp->walk; 13538462SApril.Chin@Sun.COM npnext = (Namval_t*)dtnext(shp->fun_tree,np); 13548462SApril.Chin@Sun.COM if(np>= shp->bltin_cmds && np < &shp->bltin_cmds[nbltins]) 13558462SApril.Chin@Sun.COM continue; 13568462SApril.Chin@Sun.COM if(is_abuiltin(np) && nv_isattr(np,NV_EXPORT)) 13578462SApril.Chin@Sun.COM continue; 13588462SApril.Chin@Sun.COM if(*np->nvname=='/') 13598462SApril.Chin@Sun.COM continue; 13608462SApril.Chin@Sun.COM nv_delete(np,dp,NV_NOFREE); 13618462SApril.Chin@Sun.COM } 13628462SApril.Chin@Sun.COM dtclose(shp->alias_tree); 13638462SApril.Chin@Sun.COM shp->alias_tree = inittree(shp,shtab_aliases); 13648462SApril.Chin@Sun.COM shp->last_root = shp->var_tree; 13658462SApril.Chin@Sun.COM shp->namespace = 0; 13668462SApril.Chin@Sun.COM shp->inuse_bits = 0; 13678462SApril.Chin@Sun.COM if(shp->userinit) 13688462SApril.Chin@Sun.COM (*shp->userinit)(shp, 1); 13698462SApril.Chin@Sun.COM if(shp->heredocs) 13708462SApril.Chin@Sun.COM { 13718462SApril.Chin@Sun.COM sfclose(shp->heredocs); 13728462SApril.Chin@Sun.COM shp->heredocs = 0; 13734887Schin } 13744887Schin /* remove locals */ 13754887Schin sh_onstate(SH_INIT); 13768462SApril.Chin@Sun.COM nv_scan(shp->var_tree,sh_envnolocal,(void*)0,NV_EXPORT,0); 13778462SApril.Chin@Sun.COM nv_scan(shp->var_tree,sh_envnolocal,(void*)0,NV_ARRAY,NV_ARRAY); 13784887Schin sh_offstate(SH_INIT); 13798462SApril.Chin@Sun.COM memset(shp->st.trapcom,0,(shp->st.trapmax+1)*sizeof(char*)); 13804887Schin memset((void*)&opt,0,sizeof(opt)); 13814887Schin if(sh_isoption(SH_TRACKALL)) 13824887Schin on_option(&opt,SH_TRACKALL); 13834887Schin if(sh_isoption(SH_EMACS)) 13844887Schin on_option(&opt,SH_EMACS); 13854887Schin if(sh_isoption(SH_GMACS)) 13864887Schin on_option(&opt,SH_GMACS); 13874887Schin if(sh_isoption(SH_VI)) 13884887Schin on_option(&opt,SH_VI); 13894887Schin if(sh_isoption(SH_VIRAW)) 13904887Schin on_option(&opt,SH_VIRAW); 13918462SApril.Chin@Sun.COM shp->options = opt; 13924887Schin /* set up new args */ 13934887Schin if(argv) 13948462SApril.Chin@Sun.COM shp->arglist = sh_argcreate(argv); 13958462SApril.Chin@Sun.COM if(shp->arglist) 13968462SApril.Chin@Sun.COM sh_argreset(shp,shp->arglist,NIL(struct dolnod*)); 13978462SApril.Chin@Sun.COM shp->envlist=0; 13988462SApril.Chin@Sun.COM shp->curenv = 0; 13998462SApril.Chin@Sun.COM shp->shname = error_info.id = strdup(shp->st.dolv[0]); 14004887Schin sh_offstate(SH_FORKED); 14018462SApril.Chin@Sun.COM shp->fn_depth = shp->dot_depth = 0; 14024887Schin sh_sigreset(0); 140310898Sroland.mainz@nrubsig.org if(!(SHLVL->nvalue.ip)) 140410898Sroland.mainz@nrubsig.org { 140510898Sroland.mainz@nrubsig.org shlvl = 0; 140610898Sroland.mainz@nrubsig.org SHLVL->nvalue.ip = &shlvl; 140710898Sroland.mainz@nrubsig.org nv_onattr(SHLVL,NV_INTEGER|NV_EXPORT|NV_NOFREE); 140810898Sroland.mainz@nrubsig.org } 14098462SApril.Chin@Sun.COM *SHLVL->nvalue.ip +=1; 141010898Sroland.mainz@nrubsig.org shp->st.filename = strdup(shp->lastarg); 14114887Schin return(1); 14124887Schin } 14134887Schin 14144887Schin /* 14154887Schin * set when creating a local variable of this name 14164887Schin */ 14174887Schin Namfun_t *nv_cover(register Namval_t *np) 14184887Schin { 141910898Sroland.mainz@nrubsig.org if(np==IFSNOD || np==PATHNOD || np==SHELLNOD || np==FPATHNOD || np==CDPNOD || np==SECONDS || np==ENVNOD) 14204887Schin return(np->nvfun); 14214887Schin #ifdef _hdr_locale 14224887Schin if(np==LCALLNOD || np==LCTYPENOD || np==LCMSGNOD || np==LCCOLLNOD || np==LCNUMNOD || np==LANGNOD) 14234887Schin return(np->nvfun); 14244887Schin #endif 14254887Schin return(0); 14264887Schin } 14274887Schin 14284887Schin static const char *shdiscnames[] = { "tilde", 0}; 14294887Schin 14308462SApril.Chin@Sun.COM #ifdef SHOPT_STATS 14318462SApril.Chin@Sun.COM struct Stats 14328462SApril.Chin@Sun.COM { 14338462SApril.Chin@Sun.COM Namfun_t hdr; 14348462SApril.Chin@Sun.COM Shell_t *sh; 14358462SApril.Chin@Sun.COM char *nodes; 14368462SApril.Chin@Sun.COM int numnodes; 14378462SApril.Chin@Sun.COM int current; 14388462SApril.Chin@Sun.COM }; 14398462SApril.Chin@Sun.COM 14408462SApril.Chin@Sun.COM static Namval_t *next_stat(register Namval_t* np, Dt_t *root,Namfun_t *fp) 14418462SApril.Chin@Sun.COM { 14428462SApril.Chin@Sun.COM struct Stats *sp = (struct Stats*)fp; 14438462SApril.Chin@Sun.COM if(!root) 14448462SApril.Chin@Sun.COM sp->current = 0; 14458462SApril.Chin@Sun.COM else if(++sp->current>=sp->numnodes) 14468462SApril.Chin@Sun.COM return(0); 14478462SApril.Chin@Sun.COM return(nv_namptr(sp->nodes,sp->current)); 14488462SApril.Chin@Sun.COM } 14498462SApril.Chin@Sun.COM 14508462SApril.Chin@Sun.COM static Namval_t *create_stat(Namval_t *np,const char *name,int flag,Namfun_t *fp) 14518462SApril.Chin@Sun.COM { 14528462SApril.Chin@Sun.COM struct Stats *sp = (struct Stats*)fp; 14538462SApril.Chin@Sun.COM register const char *cp=name; 14548462SApril.Chin@Sun.COM register int i=0,n; 14558462SApril.Chin@Sun.COM Namval_t *nq=0; 14568462SApril.Chin@Sun.COM Shell_t *shp = sp->sh; 14578462SApril.Chin@Sun.COM if(!name) 14588462SApril.Chin@Sun.COM return(SH_STATS); 14598462SApril.Chin@Sun.COM while((i=*cp++) && i != '=' && i != '+' && i!='['); 14608462SApril.Chin@Sun.COM n = (cp-1) -name; 14618462SApril.Chin@Sun.COM for(i=0; i < sp->numnodes; i++) 14628462SApril.Chin@Sun.COM { 14638462SApril.Chin@Sun.COM nq = nv_namptr(sp->nodes,i); 14648462SApril.Chin@Sun.COM if((n==0||memcmp(name,nq->nvname,n)==0) && nq->nvname[n]==0) 14658462SApril.Chin@Sun.COM goto found; 14668462SApril.Chin@Sun.COM } 14678462SApril.Chin@Sun.COM nq = 0; 14688462SApril.Chin@Sun.COM found: 14698462SApril.Chin@Sun.COM if(nq) 14708462SApril.Chin@Sun.COM { 14718462SApril.Chin@Sun.COM fp->last = (char*)&name[n]; 14728462SApril.Chin@Sun.COM shp->last_table = SH_STATS; 14738462SApril.Chin@Sun.COM } 14748462SApril.Chin@Sun.COM else 14758462SApril.Chin@Sun.COM errormsg(SH_DICT,ERROR_exit(1),e_notelem,n,name,nv_name(np)); 14768462SApril.Chin@Sun.COM return(nq); 14778462SApril.Chin@Sun.COM } 14788462SApril.Chin@Sun.COM 14798462SApril.Chin@Sun.COM static const Namdisc_t stat_disc = 14808462SApril.Chin@Sun.COM { 14818462SApril.Chin@Sun.COM 0, 0, 0, 0, 0, 14828462SApril.Chin@Sun.COM create_stat, 14838462SApril.Chin@Sun.COM 0, 0, 14848462SApril.Chin@Sun.COM next_stat 14858462SApril.Chin@Sun.COM }; 14868462SApril.Chin@Sun.COM 14878462SApril.Chin@Sun.COM static char *name_stat(Namval_t *np, Namfun_t *fp) 14888462SApril.Chin@Sun.COM { 14898462SApril.Chin@Sun.COM Shell_t *shp = sh_getinterp(); 14908462SApril.Chin@Sun.COM sfprintf(shp->strbuf,".sh.stats.%s",np->nvname); 14918462SApril.Chin@Sun.COM return(sfstruse(shp->strbuf)); 14928462SApril.Chin@Sun.COM } 14938462SApril.Chin@Sun.COM 14948462SApril.Chin@Sun.COM static const Namdisc_t stat_child_disc = 14958462SApril.Chin@Sun.COM { 14968462SApril.Chin@Sun.COM 0,0,0,0,0,0,0, 14978462SApril.Chin@Sun.COM name_stat 14988462SApril.Chin@Sun.COM }; 14998462SApril.Chin@Sun.COM 15008462SApril.Chin@Sun.COM static Namfun_t stat_child_fun = 15018462SApril.Chin@Sun.COM { 15028462SApril.Chin@Sun.COM &stat_child_disc, 1, 0, sizeof(Namfun_t) 15038462SApril.Chin@Sun.COM }; 15048462SApril.Chin@Sun.COM 15058462SApril.Chin@Sun.COM static void stat_init(Shell_t *shp) 15068462SApril.Chin@Sun.COM { 15078462SApril.Chin@Sun.COM int i,nstat = STAT_SUBSHELL+1; 15088462SApril.Chin@Sun.COM struct Stats *sp = newof(0,struct Stats,1,nstat*NV_MINSZ); 15098462SApril.Chin@Sun.COM Namval_t *np; 15108462SApril.Chin@Sun.COM sp->numnodes = nstat; 15118462SApril.Chin@Sun.COM sp->nodes = (char*)(sp+1); 15128462SApril.Chin@Sun.COM shp->stats = (int*)calloc(sizeof(int*),nstat); 15138462SApril.Chin@Sun.COM sp->sh = shp; 15148462SApril.Chin@Sun.COM for(i=0; i < nstat; i++) 15158462SApril.Chin@Sun.COM { 15168462SApril.Chin@Sun.COM np = nv_namptr(sp->nodes,i); 15178462SApril.Chin@Sun.COM np->nvfun = &stat_child_fun; 15188462SApril.Chin@Sun.COM np->nvname = (char*)shtab_stats[i].sh_name; 15198462SApril.Chin@Sun.COM nv_onattr(np,NV_RDONLY|NV_MINIMAL|NV_NOFREE|NV_INTEGER); 15208462SApril.Chin@Sun.COM nv_setsize(np,10); 15218462SApril.Chin@Sun.COM np->nvalue.ip = &shp->stats[i]; 15228462SApril.Chin@Sun.COM } 15238462SApril.Chin@Sun.COM sp->hdr.dsize = sizeof(struct Stats) + nstat*(sizeof(int)+NV_MINSZ); 15248462SApril.Chin@Sun.COM sp->hdr.disc = &stat_disc; 15258462SApril.Chin@Sun.COM nv_stack(SH_STATS,&sp->hdr); 15268462SApril.Chin@Sun.COM sp->hdr.nofree = 1; 15278462SApril.Chin@Sun.COM nv_setvtree(SH_STATS); 15288462SApril.Chin@Sun.COM } 15298462SApril.Chin@Sun.COM #else 15308462SApril.Chin@Sun.COM # define stat_init(x) 15318462SApril.Chin@Sun.COM #endif /* SHOPT_STATS */ 15328462SApril.Chin@Sun.COM 15334887Schin /* 15344887Schin * Initialize the shell name and alias table 15354887Schin */ 15364887Schin static Init_t *nv_init(Shell_t *shp) 15374887Schin { 15384887Schin Namval_t *np; 15394887Schin register Init_t *ip; 15404887Schin double d=0; 15414887Schin ip = newof(0,Init_t,1,0); 15424887Schin if(!ip) 15434887Schin return(0); 15448462SApril.Chin@Sun.COM shp->nvfun.last = (char*)shp; 15458462SApril.Chin@Sun.COM shp->nvfun.nofree = 1; 15464887Schin ip->sh = shp; 15474887Schin shp->var_base = shp->var_tree = inittree(shp,shtab_variables); 15488462SApril.Chin@Sun.COM SHLVL->nvalue.ip = &shlvl; 15494887Schin ip->IFS_init.hdr.disc = &IFS_disc; 15504887Schin ip->IFS_init.hdr.nofree = 1; 15518462SApril.Chin@Sun.COM ip->PATH_init.disc = &RESTRICTED_disc; 15528462SApril.Chin@Sun.COM ip->PATH_init.nofree = 1; 15538462SApril.Chin@Sun.COM ip->FPATH_init.disc = &RESTRICTED_disc; 15548462SApril.Chin@Sun.COM ip->FPATH_init.nofree = 1; 15558462SApril.Chin@Sun.COM ip->CDPATH_init.disc = &CDPATH_disc; 15568462SApril.Chin@Sun.COM ip->CDPATH_init.nofree = 1; 15578462SApril.Chin@Sun.COM ip->SHELL_init.disc = &RESTRICTED_disc; 15588462SApril.Chin@Sun.COM ip->SHELL_init.nofree = 1; 15598462SApril.Chin@Sun.COM ip->ENV_init.disc = &RESTRICTED_disc; 15608462SApril.Chin@Sun.COM ip->ENV_init.nofree = 1; 15618462SApril.Chin@Sun.COM ip->VISUAL_init.disc = &EDITOR_disc; 15628462SApril.Chin@Sun.COM ip->VISUAL_init.nofree = 1; 15638462SApril.Chin@Sun.COM ip->EDITOR_init.disc = &EDITOR_disc; 15648462SApril.Chin@Sun.COM ip->EDITOR_init.nofree = 1; 15658462SApril.Chin@Sun.COM ip->HISTFILE_init.disc = &HISTFILE_disc; 15668462SApril.Chin@Sun.COM ip->HISTFILE_init.nofree = 1; 15678462SApril.Chin@Sun.COM ip->HISTSIZE_init.disc = &HISTFILE_disc; 15688462SApril.Chin@Sun.COM ip->HISTSIZE_init.nofree = 1; 15698462SApril.Chin@Sun.COM ip->OPTINDEX_init.disc = &OPTINDEX_disc; 15708462SApril.Chin@Sun.COM ip->OPTINDEX_init.nofree = 1; 15714887Schin ip->SECONDS_init.hdr.disc = &SECONDS_disc; 15724887Schin ip->SECONDS_init.hdr.nofree = 1; 15734887Schin ip->RAND_init.hdr.disc = &RAND_disc; 15744887Schin ip->RAND_init.hdr.nofree = 1; 15754887Schin ip->SH_MATCH_init.hdr.disc = &SH_MATCH_disc; 15764887Schin ip->SH_MATCH_init.hdr.nofree = 1; 15778462SApril.Chin@Sun.COM ip->SH_VERSION_init.disc = &SH_VERSION_disc; 15788462SApril.Chin@Sun.COM ip->SH_VERSION_init.nofree = 1; 15798462SApril.Chin@Sun.COM ip->LINENO_init.disc = &LINENO_disc; 15808462SApril.Chin@Sun.COM ip->LINENO_init.nofree = 1; 15818462SApril.Chin@Sun.COM ip->L_ARG_init.disc = &L_ARG_disc; 15828462SApril.Chin@Sun.COM ip->L_ARG_init.nofree = 1; 15834887Schin #ifdef _hdr_locale 15848462SApril.Chin@Sun.COM ip->LC_TYPE_init.disc = &LC_disc; 15858462SApril.Chin@Sun.COM ip->LC_TYPE_init.nofree = 1; 15868462SApril.Chin@Sun.COM ip->LC_NUM_init.disc = &LC_disc; 15878462SApril.Chin@Sun.COM ip->LC_NUM_init.nofree = 1; 15888462SApril.Chin@Sun.COM ip->LC_COLL_init.disc = &LC_disc; 15898462SApril.Chin@Sun.COM ip->LC_COLL_init.nofree = 1; 15908462SApril.Chin@Sun.COM ip->LC_MSG_init.disc = &LC_disc; 15918462SApril.Chin@Sun.COM ip->LC_MSG_init.nofree = 1; 15928462SApril.Chin@Sun.COM ip->LC_ALL_init.disc = &LC_disc; 15938462SApril.Chin@Sun.COM ip->LC_ALL_init.nofree = 1; 15948462SApril.Chin@Sun.COM ip->LANG_init.disc = &LC_disc; 15958462SApril.Chin@Sun.COM ip->LANG_init.nofree = 1; 15964887Schin #endif /* _hdr_locale */ 15974887Schin nv_stack(IFSNOD, &ip->IFS_init.hdr); 15988462SApril.Chin@Sun.COM nv_stack(PATHNOD, &ip->PATH_init); 15998462SApril.Chin@Sun.COM nv_stack(FPATHNOD, &ip->FPATH_init); 16008462SApril.Chin@Sun.COM nv_stack(CDPNOD, &ip->CDPATH_init); 16018462SApril.Chin@Sun.COM nv_stack(SHELLNOD, &ip->SHELL_init); 16028462SApril.Chin@Sun.COM nv_stack(ENVNOD, &ip->ENV_init); 16038462SApril.Chin@Sun.COM nv_stack(VISINOD, &ip->VISUAL_init); 16048462SApril.Chin@Sun.COM nv_stack(EDITNOD, &ip->EDITOR_init); 16058462SApril.Chin@Sun.COM nv_stack(HISTFILE, &ip->HISTFILE_init); 16068462SApril.Chin@Sun.COM nv_stack(HISTSIZE, &ip->HISTSIZE_init); 16078462SApril.Chin@Sun.COM nv_stack(OPTINDNOD, &ip->OPTINDEX_init); 16084887Schin nv_stack(SECONDS, &ip->SECONDS_init.hdr); 16098462SApril.Chin@Sun.COM nv_stack(L_ARGNOD, &ip->L_ARG_init); 16108462SApril.Chin@Sun.COM nv_putval(SECONDS, (char*)&d, NV_DOUBLE); 16114887Schin nv_stack(RANDNOD, &ip->RAND_init.hdr); 16124887Schin d = (shp->pid&RANDMASK); 16138462SApril.Chin@Sun.COM nv_putval(RANDNOD, (char*)&d, NV_DOUBLE); 16148462SApril.Chin@Sun.COM nv_stack(LINENO, &ip->LINENO_init); 16154887Schin nv_putsub(SH_MATCHNOD,(char*)0,10); 16164887Schin nv_onattr(SH_MATCHNOD,NV_RDONLY); 16174887Schin nv_stack(SH_MATCHNOD, &ip->SH_MATCH_init.hdr); 16188462SApril.Chin@Sun.COM nv_stack(SH_VERSIONNOD, &ip->SH_VERSION_init); 16194887Schin #ifdef _hdr_locale 16208462SApril.Chin@Sun.COM nv_stack(LCTYPENOD, &ip->LC_TYPE_init); 16218462SApril.Chin@Sun.COM nv_stack(LCALLNOD, &ip->LC_ALL_init); 16228462SApril.Chin@Sun.COM nv_stack(LCMSGNOD, &ip->LC_MSG_init); 16238462SApril.Chin@Sun.COM nv_stack(LCCOLLNOD, &ip->LC_COLL_init); 16248462SApril.Chin@Sun.COM nv_stack(LCNUMNOD, &ip->LC_NUM_init); 16258462SApril.Chin@Sun.COM nv_stack(LANGNOD, &ip->LANG_init); 16264887Schin #endif /* _hdr_locale */ 16274887Schin (PPIDNOD)->nvalue.lp = (&shp->ppid); 16284887Schin (TMOUTNOD)->nvalue.lp = (&shp->st.tmout); 16294887Schin (MCHKNOD)->nvalue.lp = (&sh_mailchk); 16304887Schin (OPTINDNOD)->nvalue.lp = (&shp->st.optindex); 16314887Schin /* set up the seconds clock */ 16324887Schin shp->alias_tree = inittree(shp,shtab_aliases); 16334887Schin shp->track_tree = dtopen(&_Nvdisc,Dtset); 16344887Schin shp->bltin_tree = inittree(shp,(const struct shtable2*)shtab_builtins); 16354887Schin shp->fun_tree = dtopen(&_Nvdisc,Dtoset); 16364887Schin dtview(shp->fun_tree,shp->bltin_tree); 16374887Schin #if SHOPT_NAMESPACE 16384887Schin if(np = nv_mount(DOTSHNOD, "global", shp->var_tree)) 16394887Schin nv_onattr(np,NV_RDONLY); 16404887Schin np = nv_search("namespace",nv_dict(DOTSHNOD),NV_ADD); 16414887Schin nv_putval(np,".sh.global",NV_RDONLY|NV_NOFREE); 16424887Schin nv_stack(np, &NSPACE_init); 16434887Schin #endif /* SHOPT_NAMESPACE */ 16448462SApril.Chin@Sun.COM np = nv_mount(DOTSHNOD, "type", shp->typedict=dtopen(&_Nvdisc,Dtoset)); 16454887Schin nv_adddisc(DOTSHNOD, shdiscnames, (Namval_t**)0); 16468462SApril.Chin@Sun.COM SH_LINENO->nvalue.ip = &shp->st.lineno; 16478462SApril.Chin@Sun.COM VERSIONNOD->nvalue.nrp = newof(0,struct Namref,1,0); 16488462SApril.Chin@Sun.COM VERSIONNOD->nvalue.nrp->np = SH_VERSIONNOD; 16498462SApril.Chin@Sun.COM VERSIONNOD->nvalue.nrp->root = nv_dict(DOTSHNOD); 16508462SApril.Chin@Sun.COM VERSIONNOD->nvalue.nrp->table = DOTSHNOD; 16518462SApril.Chin@Sun.COM nv_onattr(VERSIONNOD,NV_RDONLY|NV_REF); 16528462SApril.Chin@Sun.COM stat_init(shp); 16534887Schin return(ip); 16544887Schin } 16554887Schin 16564887Schin /* 16574887Schin * initialize name-value pairs 16584887Schin */ 16594887Schin 16604887Schin static Dt_t *inittree(Shell_t *shp,const struct shtable2 *name_vals) 16614887Schin { 16624887Schin register Namval_t *np; 16634887Schin register const struct shtable2 *tp; 16644887Schin register unsigned n = 0; 16654887Schin register Dt_t *treep; 16664887Schin Dt_t *base_treep, *dict; 16674887Schin for(tp=name_vals;*tp->sh_name;tp++) 16684887Schin n++; 16694887Schin np = (Namval_t*)calloc(n,sizeof(Namval_t)); 16704887Schin if(!shp->bltin_nodes) 16718462SApril.Chin@Sun.COM { 16724887Schin shp->bltin_nodes = np; 16738462SApril.Chin@Sun.COM shp->bltin_nnodes = n; 16748462SApril.Chin@Sun.COM } 16754887Schin else if(name_vals==(const struct shtable2*)shtab_builtins) 16768462SApril.Chin@Sun.COM { 16774887Schin shp->bltin_cmds = np; 16788462SApril.Chin@Sun.COM nbltins = n; 16798462SApril.Chin@Sun.COM } 16804887Schin base_treep = treep = dtopen(&_Nvdisc,Dtoset); 16818462SApril.Chin@Sun.COM treep->user = (void*)shp; 16824887Schin for(tp=name_vals;*tp->sh_name;tp++,np++) 16834887Schin { 16844887Schin if((np->nvname = strrchr(tp->sh_name,'.')) && np->nvname!=((char*)tp->sh_name)) 16854887Schin np->nvname++; 16864887Schin else 16874887Schin { 16884887Schin np->nvname = (char*)tp->sh_name; 16894887Schin treep = base_treep; 16904887Schin } 16914887Schin np->nvenv = 0; 16924887Schin if(name_vals==(const struct shtable2*)shtab_builtins) 16934887Schin np->nvalue.bfp = ((struct shtable3*)tp)->sh_value; 16944887Schin else 16958462SApril.Chin@Sun.COM { 16968462SApril.Chin@Sun.COM if(name_vals == shtab_variables) 16978462SApril.Chin@Sun.COM np->nvfun = &sh.nvfun; 16984887Schin np->nvalue.cp = (char*)tp->sh_value; 16998462SApril.Chin@Sun.COM } 17004887Schin nv_setattr(np,tp->sh_number); 17014887Schin if(nv_istable(np)) 17024887Schin nv_mount(np,(const char*)0,dict=dtopen(&_Nvdisc,Dtoset)); 17034887Schin if(nv_isattr(np,NV_INTEGER)) 17044887Schin nv_setsize(np,10); 17054887Schin else 17064887Schin nv_setsize(np,0); 17074887Schin dtinsert(treep,np); 17084887Schin if(nv_istable(np)) 17094887Schin treep = dict; 17104887Schin } 17114887Schin return(treep); 17124887Schin } 17134887Schin 17144887Schin /* 17154887Schin * read in the process environment and set up name-value pairs 17164887Schin * skip over items that are not name-value pairs 17174887Schin */ 17184887Schin 17194887Schin static void env_init(Shell_t *shp) 17204887Schin { 17214887Schin register char *cp; 17224887Schin register Namval_t *np; 17234887Schin register char **ep=environ; 17244887Schin register char *next=0; 17254887Schin #ifdef _ENV_H 17264887Schin shp->env = env_open(environ,3); 17274887Schin env_delete(shp->env,"_"); 17284887Schin #endif 17294887Schin if(ep) 17304887Schin { 17314887Schin while(cp= *ep++) 17324887Schin { 17334887Schin if(*cp=='A' && cp[1]=='_' && cp[2]=='_' && cp[3]=='z' && cp[4]=='=') 17344887Schin next = cp+4; 17354887Schin else if(np=nv_open(cp,shp->var_tree,(NV_EXPORT|NV_IDENT|NV_ASSIGN|NV_NOFAIL))) 17364887Schin { 17374887Schin nv_onattr(np,NV_IMPORT); 17384887Schin np->nvenv = cp; 17394887Schin nv_close(np); 17404887Schin } 1741*12068SRoger.Faulkner@Oracle.COM else /* swap with front */ 17428462SApril.Chin@Sun.COM { 17438462SApril.Chin@Sun.COM ep[-1] = environ[shp->nenv]; 17448462SApril.Chin@Sun.COM environ[shp->nenv++] = cp; 17458462SApril.Chin@Sun.COM } 17464887Schin } 17474887Schin while(cp=next) 17484887Schin { 17494887Schin if(next = strchr(++cp,'=')) 17504887Schin *next = 0; 17514887Schin np = nv_search(cp+2,shp->var_tree,NV_ADD); 1752*12068SRoger.Faulkner@Oracle.COM if(np!=SHLVL && nv_isattr(np,NV_IMPORT|NV_EXPORT)) 17534887Schin { 17544887Schin int flag = *(unsigned char*)cp-' '; 17554887Schin int size = *(unsigned char*)(cp+1)-' '; 17564887Schin if((flag&NV_INTEGER) && size==0) 17574887Schin { 17584887Schin /* check for floating*/ 17594887Schin char *ep,*val = nv_getval(np); 17604887Schin strtol(val,&ep,10); 17614887Schin if(*ep=='.' || *ep=='e' || *ep=='E') 17624887Schin { 17634887Schin char *lp; 17644887Schin flag |= NV_DOUBLE; 17654887Schin if(*ep=='.') 17664887Schin { 17674887Schin strtol(ep+1,&lp,10); 17684887Schin if(*lp) 17694887Schin ep = lp; 17704887Schin } 17714887Schin if(*ep && *ep!='.') 17724887Schin { 17734887Schin flag |= NV_EXPNOTE; 17744887Schin size = ep-val; 17754887Schin } 17764887Schin else 17774887Schin size = strlen(ep); 17784887Schin size--; 17794887Schin } 17804887Schin } 17814887Schin nv_newattr(np,flag|NV_IMPORT|NV_EXPORT,size); 17824887Schin } 1783*12068SRoger.Faulkner@Oracle.COM else 1784*12068SRoger.Faulkner@Oracle.COM cp += 2; 17854887Schin } 17864887Schin } 17874887Schin #ifdef _ENV_H 17888462SApril.Chin@Sun.COM env_delete(shp->env,e_envmarker); 17894887Schin #endif 17904887Schin if(nv_isnull(PWDNOD) || nv_isattr(PWDNOD,NV_TAGGED)) 17914887Schin { 17924887Schin nv_offattr(PWDNOD,NV_TAGGED); 17934887Schin path_pwd(0); 17944887Schin } 17954887Schin if((cp = nv_getval(SHELLNOD)) && (sh_type(cp)&SH_TYPE_RESTRICTED)) 17964887Schin sh_onoption(SH_RESTRICTED); /* restricted shell */ 17974887Schin return; 17984887Schin } 17994887Schin 18004887Schin /* 18014887Schin * terminate shell and free up the space 18024887Schin */ 18034887Schin int sh_term(void) 18044887Schin { 18054887Schin sfdisc(sfstdin,SF_POPDISC); 18064887Schin free((char*)sh.outbuff); 18074887Schin stakset(NIL(char*),0); 18084887Schin return(0); 18094887Schin } 18104887Schin 18114887Schin /* function versions of these */ 18124887Schin 18134887Schin #define DISABLE /* proto workaround */ 18144887Schin 18154887Schin unsigned long sh_isoption DISABLE (int opt) 18164887Schin { 18174887Schin return(sh_isoption(opt)); 18184887Schin } 18194887Schin 18204887Schin unsigned long sh_onoption DISABLE (int opt) 18214887Schin { 18224887Schin return(sh_onoption(opt)); 18234887Schin } 18244887Schin 18254887Schin unsigned long sh_offoption DISABLE (int opt) 18264887Schin { 18274887Schin return(sh_offoption(opt)); 18284887Schin } 18294887Schin 18304887Schin void sh_sigcheck DISABLE (void) 18314887Schin { 18324887Schin sh_sigcheck(); 18334887Schin } 18344887Schin 18354887Schin Dt_t* sh_bltin_tree DISABLE (void) 18364887Schin { 18374887Schin return(sh.bltin_tree); 18384887Schin } 1839