da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1982-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Shell initialization
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * David Korn
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Labs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* CLK_TCK */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin extern char **environ;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_FS_3D */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* _hdr_locale */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Invalidate all path name bindings
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * out of memory routine for stak routines
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(NIL(char*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* Trap for VISUAL and EDITOR variables */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void put_ed(register Namval_t* np,const char *val,int flags,Namfun_t *fp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(*name=='E' && nv_getval(sh_scoped(shp,VISINOD)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(cp=val) && (*name=='E' || !(cp=nv_getval(sh_scoped(shp,EDITNOD)))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* turn on vi or emacs option if editor name is either*/
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/* Trap for HISTFILE and HISTSIZE variables */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void put_history(register Namval_t* np,const char *val,int flags,Namfun_t *fp)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(np==HISTFILE && (cp=nv_getval(np)) && strcmp(val,cp)==0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(np==HISTSIZE && sh_arith(val)==nv_getnum(HISTSIZE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* Trap for OPTINDEX */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void put_optindex(Namval_t* np,const char *val,int flags,Namfun_t *fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Sfdouble_t nget_optindex(register Namval_t* np, Namfun_t *fp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Namfun_t *clone_optindex(Namval_t* np, Namval_t *mp, int flags, Namfun_t *fp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Namfun_t *dp = (Namfun_t*)malloc(sizeof(Namfun_t));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* Trap for restricted variables FPATH, PATH, SHELL, ENV */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void put_restricted(register Namval_t* np,const char *val,int flags,Namfun_t *fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),e_restricted,nv_name(np));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np==PATHNOD || (path_scoped=(strcmp(name,PATHNOD->nvname)==0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_scan(shp->track_tree,rehash,(void*)0,NV_TAGGED,NV_TAGGED);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(val && !(flags&NV_RDONLY) && np->nvalue.cp && strcmp(val,np->nvalue.cp)==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->pathlist = (void*)path_unsetfpath((Pathcomp_t*)shp->pathlist);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = (void*)path_addpath((Pathcomp_t*)shp->pathlist,val,PATH_PATH);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = (void*)path_addpath((Pathcomp_t*)shp->pathlist,val,PATH_FPATH);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsfprintf(sfstderr,"%d: name=%s val=%s\n",getpid(),name,val);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void put_cdpath(register Namval_t* np,const char *val,int flags,Namfun_t *fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = (void*)path_addpath((Pathcomp_t*)shp->cdpathlist,val,PATH_CDPATH);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This function needs to be modified to handle international
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * error message translations
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static char* msg_translate(const char* catalog, const char* message)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((char*)message);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static char* msg_translate(const char* message, int type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((char*)message);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /* Trap for LC_ALL, LC_CTYPE, LC_MESSAGES, LC_COLLATE and LANG */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static void put_lang(Namval_t* np,const char *val,int flags,Namfun_t *fp)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else if(name==(LANGNOD)->nvname && (!(cp=nv_getval(LCALLNOD)) || !*cp))
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(!sh_isstate(SH_INIT) && (type>=0 || type==LC_ALL || type==LC_LANG))
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner shp->decomma = (lc=localeconv()) && lc->decimal_point && *lc->decimal_point==',';
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(CC_NATIVE!=CC_ASCII && (type==LC_ALL || type==LC_LANG || type==LC_CTYPE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_lexstates[ST_BEGIN] = state[0] = (char*)malloc(4*(1<<CHAR_BIT));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(state[0],sh_lexrstates[ST_BEGIN],(1<<CHAR_BIT));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_lexstates[ST_NAME] = state[1] = state[0] + (1<<CHAR_BIT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_lexstates[ST_DOL] = state[2] = state[1] + (1<<CHAR_BIT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_lexstates[ST_BRACE] = state[3] = state[2] + (1<<CHAR_BIT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(state[3],sh_lexrstates[ST_BRACE],(1<<CHAR_BIT));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* _hdr_locale */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* Trap for IFS assignment and invalidates state table */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void put_ifs(register Namval_t* np,const char *val,int flags,Namfun_t *fp)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(!val && !(flags&NV_CLONE) && (fp=np->nvfun) && !fp->disc && (shp=(Shell_t*)(fp->last)))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nv_stack(np,&((Init_t*)shp->init_context)->IFS_init.hdr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This is the lookup function for IFS
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * It keeps the sh.ifstable up to date
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char* get_ifs(register Namval_t* np, Namfun_t *fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c,n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(c= *(unsigned char*)cp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c=='\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(isspace(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * these functions are used to get and set the SECONDS variable
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define dtime(tp) ((double)((tp)->tv_sec)+1e-6*((double)((tp)->tv_usec)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void put_seconds(register Namval_t* np,const char *val,int flags,Namfun_t *fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char* get_seconds(register Namval_t* np, Namfun_t *fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Sfdouble_t nget_seconds(register Namval_t* np, Namfun_t *fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * These three functions are used to get and set the RANDOM variable
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void put_rand(register Namval_t* np,const char *val,int flags,Namfun_t *fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register long n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = *(double*)val;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * get random number in range of 0 - 2**15
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * never pick same number twice in a row
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Sfdouble_t nget_rand(register Namval_t* np, Namfun_t *fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char* get_rand(register Namval_t* np, Namfun_t *fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * These three routines are for LINENO
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Sfdouble_t nget_lineno(Namval_t* np, Namfun_t *fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin double d=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(error_info.context && error_info.context->line>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(d);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void put_lineno(Namval_t* np,const char *val,int flags,Namfun_t *fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register long n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = *(double*)val;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char* get_lineno(register Namval_t* np, Namfun_t *fp)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(sh_isstate(SH_INIT) && (cp=shp->lastarg) && *cp=='*' && (pid=strtol(cp+1,&cp,10)) && *cp=='*')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void put_lastarg(Namval_t* np,const char *val,int flags,Namfun_t *fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(fp!=0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * store the most recent value for use in .sh.match
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid sh_setmatch(const char *v, int vsize, int nmatch, int match[])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct match *mp = (struct match*)(SH_MATCHNOD->nvfun);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int i,n;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_putsub(SH_MATCHNOD, NIL(char*), (nmatch-1)|ARRAY_FILL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define array_scan(np) ((nv_arrayptr(np)->nelem&ARRAY_SCAN))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char* get_match(register Namval_t* np, Namfun_t *fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return("");
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic const Namdisc_t SH_MATCH_disc = { sizeof(struct match), 0, get_match };
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic char* get_version(register Namval_t* np, Namfun_t *fp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Sfdouble_t nget_version(register Namval_t* np, Namfun_t *fp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register const char *cp = e_version + strlen(e_version)-10;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while (c = *cp++)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t += c - '0';
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic const Namdisc_t SH_VERSION_disc = { 0, 0, get_version, nget_version };
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * set or unset the mappings given a colon separated list of directories
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *lastp, *oldp=str, *newp=strchr(oldp,':');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* catch vpath assignments */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static void put_vpath(register Namval_t* np,const char *val,int flags,Namfun_t *fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_FS_3D */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const Namdisc_t IFS_disc = { sizeof(struct ifs), put_ifs, get_ifs };
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinconst Namdisc_t RESTRICTED_disc = { sizeof(Namfun_t), put_restricted };
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic const Namdisc_t CDPATH_disc = { sizeof(Namfun_t), put_cdpath };
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic const Namdisc_t EDITOR_disc = { sizeof(Namfun_t), put_ed };
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic const Namdisc_t HISTFILE_disc = { sizeof(Namfun_t), put_history };
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic const Namdisc_t OPTINDEX_disc = { sizeof(Namfun_t), put_optindex, 0, nget_optindex, 0, 0, clone_optindex };
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const Namdisc_t SECONDS_disc = { sizeof(struct seconds), put_seconds, get_seconds, nget_seconds };
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const Namdisc_t RAND_disc = { sizeof(struct rand), put_rand, get_rand, nget_rand };
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic const Namdisc_t LINENO_disc = { sizeof(Namfun_t), put_lineno, get_lineno, nget_lineno };
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic const Namdisc_t L_ARG_disc = { sizeof(Namfun_t), put_lastarg, get_lastarg };
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static const Namdisc_t NSPACE_disc = { 0, 0, get_nspace };
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_NAMESPACE */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin static const Namdisc_t LC_disc = { sizeof(Namfun_t), put_lang };
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* _hdr_locale */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This function will get called whenever a configuration parameter changes
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int newconf(const char *name, const char *path, const char *value)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(strcmp(name,"UNIVERSE")==0 && strcmp(astconf(name,0,0),value))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* set directory in new universe */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* clear out old tracked alias */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const unsigned char *t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin d[t[i]] = s[i];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(i=0; i < ST_NONE; i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return SH_TYPE_* bitmask for path
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * 0 for "not a shell"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int t = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*s == '-')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*s == 'k')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*s == 'r')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if ((t & SH_TYPE_KSH) && *s == '9' && *(s+1) == '3')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (*s == '.' && *(s+1) == 'e' && *(s+2) == 'x' && *(s+3) == 'e')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return t & ~(SH_TYPE_BASH|SH_TYPE_KSH|SH_TYPE_PROFILE|SH_TYPE_RESTRICTED);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic char *get_mode(Namval_t* np, Namfun_t* nfp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void put_mode(Namval_t* np, const char* val, int flag, Namfun_t* nfp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin errormsg(SH_DICT,ERROR_exit(1),"%s: invalid mode string",val);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * initialize the shell
7c2fbfb345896881c631598ee3852ce9ce33fb07April ChinShell_t *sh_init(register int argc,register char *argv[], Shinit_f userinit)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(sh_lexstates,sh_lexrstates,ST_NONE*sizeof(char*));
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /* NOTE: only shp is used by __regress__ at this point */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz while ((a = *++av) && a[0] == '-' && (a[1] == 'I' || a[1] == '-' && a[2] == 'r'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(n=0;n < 10; n++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* don't use lower bits when rand() generates large numbers */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->lim.posix_jobcontrol = getconf("JOB_CONTROL");
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if((v = getconf("PID_MAX")) > 0 && shp->lim.child_max > v)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_FS_3D */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* initialize signal handling */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* set up memory for name-value pairs */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* read the environment */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfprintf(shp->strbuf,"%s/.kshrc",nv_getval(HOME));
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nv_putval(ENVNOD,sfstruse(shp->strbuf),NV_RDONLY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * try to find the pathname for this interpreter
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * try using environment variable _ or argv[0]
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if((n = pathprog(NiL, buff, sizeof(buff))) > 0 && n <= sizeof(buff))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((n=readlink(sfstruse(shp->strbuf),buff,sizeof(buff)-1))>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if((cp && (sh_type(cp)&SH_TYPE_SH)) || (argc>0 && strchr(cp= *argv,'/')))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_FS_3D */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_TIMEOUT */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* initialize jobs table */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for restricted shell */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for profile shell */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for invocation as bash */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* look for options */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* shp->st.dolc is $# */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((shp->st.dolc = sh_argopts(-argc,argv,shp)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((n = pathposix(name, NIL(char*), 0)) > 0 && (p = (char*)malloc(++n)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* _WINIX */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* set[ug]id scripts require the -p flag */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->userid!=shp->euserid || shp->groupid!=shp->egroupid)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* require sh -p to run setuid and/or setgid */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(!sh_isoption(SH_PRIVILEGED) && shp->userid >= SHOPT_P_SUID)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_P_SUID */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* careful of #! setuid scripts with name beginning with - */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->login_sh && argv[1] && strcmp(argv[0],argv[1])==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /*SHELLMAGIC*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* shname for $0 in profiles and . scripts */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return here for shell script execution
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * but not for parenthesis subshells
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin error_info.id = strdup(shp->st.dolv[0]); /* error_info.id is $0 */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define NV_MKINTTYPE(x,y,z) nv_mkinttype(#x,sizeof(x),(x)-1<0,(y),(Namdisc_t*)z);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin NV_MKINTTYPE(time_t,"seconds since the epoch",0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * reinitialize before executing a script
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(np>= shp->bltin_cmds && np < &shp->bltin_cmds[nbltins])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* remove locals */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_scan(shp->var_tree,sh_envnolocal,(void*)0,NV_EXPORT,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_scan(shp->var_tree,sh_envnolocal,(void*)0,NV_ARRAY,NV_ARRAY);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin memset(shp->st.trapcom,0,(shp->st.trapmax+1)*sizeof(char*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* set up new args */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_argreset(shp,shp->arglist,NIL(struct dolnod*));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->shname = error_info.id = strdup(shp->st.dolv[0]);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nv_onattr(SHLVL,NV_INTEGER|NV_EXPORT|NV_NOFREE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * set when creating a local variable of this name
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(np==IFSNOD || np==PATHNOD || np==SHELLNOD || np==FPATHNOD || np==CDPNOD || np==SECONDS || np==ENVNOD)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np==LCALLNOD || np==LCTYPENOD || np==LCMSGNOD || np==LCCOLLNOD || np==LCNUMNOD || np==LANGNOD)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Namval_t *next_stat(register Namval_t* np, Dt_t *root,Namfun_t *fp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Namval_t *create_stat(Namval_t *np,const char *name,int flag,Namfun_t *fp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int i=0,n;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while((i=*cp++) && i != '=' && i != '+' && i!='[');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((n==0||memcmp(name,nq->nvname,n)==0) && nq->nvname[n]==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin errormsg(SH_DICT,ERROR_exit(1),e_notelem,n,name,nv_name(np));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0, 0, 0, 0, 0,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic char *name_stat(Namval_t *np, Namfun_t *fp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 0,0,0,0,0,0,0,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct Stats *sp = newof(0,struct Stats,1,nstat*NV_MINSZ);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for(i=0; i < nstat; i++)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_onattr(np,NV_RDONLY|NV_MINIMAL|NV_NOFREE|NV_INTEGER);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sp->hdr.dsize = sizeof(struct Stats) + nstat*(sizeof(int)+NV_MINSZ);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* SHOPT_STATS */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Initialize the shell name and alias table
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin double d=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->var_base = shp->var_tree = inittree(shp,shtab_variables);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* _hdr_locale */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* _hdr_locale */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* set up the seconds clock */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->bltin_tree = inittree(shp,(const struct shtable2*)shtab_builtins);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_NAMESPACE */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = nv_mount(DOTSHNOD, "type", shp->typedict=dtopen(&_Nvdisc,Dtoset));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin VERSIONNOD->nvalue.nrp = newof(0,struct Namref,1,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin VERSIONNOD->nvalue.nrp->root = nv_dict(DOTSHNOD);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * initialize name-value pairs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Dt_t *inittree(Shell_t *shp,const struct shtable2 *name_vals)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(name_vals==(const struct shtable2*)shtab_builtins)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((np->nvname = strrchr(tp->sh_name,'.')) && np->nvname!=((char*)tp->sh_name))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_mount(np,(const char*)0,dict=dtopen(&_Nvdisc,Dtoset));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * read in the process environment and set up name-value pairs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * skip over items that are not name-value pairs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*cp=='A' && cp[1]=='_' && cp[2]=='_' && cp[3]=='z' && cp[4]=='=')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(np=nv_open(cp,shp->var_tree,(NV_EXPORT|NV_IDENT|NV_ASSIGN|NV_NOFAIL)))
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else /* swap with front */
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(np!=SHLVL && nv_isattr(np,NV_IMPORT|NV_EXPORT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for floating*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((cp = nv_getval(SHELLNOD)) && (sh_type(cp)&SH_TYPE_RESTRICTED))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * terminate shell and free up the space
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* function versions of these */