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 * David Korn
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Labs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define RW_ALL (S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR|S_IWGRP|S_IWOTH)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int canexecute(char*,int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int path_chkpaths(Pathcomp_t*,Pathcomp_t*,Pathcomp_t*,int);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzstatic void path_checkdup(register Pathcomp_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic pid_t path_pfexecve(const char *path, char *argv[],char *const envp[],int spawn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* Solaris implements realpath(3C) using the resolvepath(2) */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* system call so we can save us to call access(2) first */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* we can exec the command directly instead of via pfexec(1) if */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* there is a matching entry without attributes in exec_attr(4) */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pf=getexecuser(sh.user, KV_COMMAND, resolvedpath, GET_ONE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic pid_t _spawnveg(const char *path, char* const argv[], char* const envp[], pid_t pgid)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * used with command -x to run the command in multiple passes
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * spawn is non-zero when invoked via spawn
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the exitval is set to the maximum for each execution
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic pid_t path_xargs(const char *path, char *argv[],char *const envp[], int spawn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* leave at least two for last */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = nlast*sizeof(char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * make sure PWD is set up correctly
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Return the present working directory
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Invokes getcwd() if flag==0 and if necessary
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Sets the PWD variable to this value
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* try from lowest to highest */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(strcmp(pp->name,"/bin")==0 || memcmp(pp->name,np->nvname,pp->len) || np->nvname[pp->len]!='/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * delete current Pathcomp_t structure
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* SHOPT_DYNAMIC */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * returns library variable from .paths
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The value might be returned on the stack overwriting path
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int r;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(pp->ino==statb.st_ino && pp->dev==statb.st_dev && pp->mtime==statb.st_mtime)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy((void*)save, (void*)stakptr(PATH_OFFSET+pcomp.len),sizeof(save));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(path_chkpaths((Pathcomp_t*)0,(Pathcomp_t*)0,&pcomp,PATH_OFFSET))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy((void*)stakptr(PATH_OFFSET+pcomp.len),(void*)save,sizeof(save));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr,"pp=%x dev=%d ino=%d len=%d flags=%o name=%.*s\n",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp,pp->dev,pp->ino,pp->len,pp->flags,pp->len,pp->name);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * check for duplicate directories on PATH
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzstatic void path_checkdup(register Pathcomp_t *pp)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(stat(name,&statb)<0 || !S_ISDIR(statb.st_mode))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz first = (pp->flags&PATH_CDPATH)?pp->shp->cdpathlist:path_get("");
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz for(oldpp=first; oldpp && oldpp!=pp; oldpp=oldpp->next)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(pp->ino==oldpp->ino && pp->dev==oldpp->dev && pp->mtime==oldpp->mtime)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(((pp->flags&(PATH_PATH|PATH_SKIP))==PATH_PATH))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * write the next path to search on the current stack
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if last is given, all paths that come before <last> are skipped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the next pathcomp is returned.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinPathcomp_t *path_nextcomp(register Pathcomp_t *pp, const char *name, Pathcomp_t *last)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((Pathcomp_t*)0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Pathcomp_t *pp = (void*)path_addpath((Pathcomp_t*)0,(std_path),PATH_PATH);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!std_path && !(std_path=astconf("PATH",NIL(char*),NIL(char*))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = (void*)path_addpath((Pathcomp_t*)shp->pathlist,val,PATH_PATH);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = (void*)path_addpath((Pathcomp_t*)shp->pathlist,val,PATH_FPATH);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * returns that pathlist to search
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!pp && (!(PATHNOD)->nvalue.cp) || sh_isstate(SH_DEFPATH))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * open file corresponding to name using path give by <pp>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int path_opentype(const char *name, register Pathcomp_t *pp, int fun)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((fd = sh_open(path_relative(stakptr(PATH_OFFSET)),O_RDONLY,0)) >= 0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz close(0x10001); /* this results in a /var/log/uwin message with "0x10001" for debugging */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * open file corresponding to name using path give by <pp>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint path_open(const char *name, register Pathcomp_t *pp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * given a pathname return the base name
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((*name++ == '/') && *name) /* don't trim trailing / */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return ((char*)start);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * load functions from file <fno>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void funload(Shell_t *shp,int fno, const char *name)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *pname,*oldname=shp->st.filename, buff[IOBSIZE+1];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int savestates = sh_getstate(), oldload=shp->funload;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->fpathdict && (rp = dtmatch(shp->fpathdict,(void*)pname)))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if((np = dtsearch(funtree,rp->np)) && is_afunction(np))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while((rp=dtnext(shp->fpathdict,rp)) && strcmp(pname,rp->fname)==0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sh_eval(sfnew(NIL(Sfio_t*),buff,IOBSIZE,fno,SF_READ),SH_FUNEVAL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * do a path search and track alias if requested
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if flag is 0, or if name not found, then try autoloading function
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * if flag==2 or 3, returns 1 if name found on FPATH
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * if flag==3 no tracked alias will be set
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * returns 1, if function was autoloaded.
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * If oldpp is not NULL, it will contain a pointer to the path component
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * where it was found.
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinint path_search(register const char *name,Pathcomp_t **oldpp, int flag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if((np=nv_search(name,shp->track_tree,0)) && !nv_isattr(np,NV_NOALIAS) && (pp=(Pathcomp_t*)np->nvalue.cp))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin pp = path_absolute(name,oldpp?*oldpp:NIL(Pathcomp_t*));
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(!pp && (np=nv_search(name,shp->fun_tree,HASH_NOSCOPE))&&np->nvalue.ip)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp=sh_isstate(SH_DEFPATH)?shp->defpathlist:shp->pathlist;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pp && strmatch(name,e_alphanum) && (fno=path_opentype(name,pp,1))>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(pp && !sh_isstate(SH_DEFPATH) && *name!='/' && flag<3)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * do a path search and find the full pathname of file name
7c2fbfb345896881c631598ee3852ce9ce33fb07April ChinPathcomp_t *path_absolute(register const char *name, Pathcomp_t *pp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(*stakptr(PATH_OFFSET)=='/' && nv_search(stakptr(PATH_OFFSET),sh.bltin_tree,0))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if((libcmd = !strcmp(cp,LIBCMD)) && (addr=(Fptr_t)dlllook((void*)0,stakptr(n))))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((np = sh_addbuiltin(stakptr(PATH_OFFSET),addr,NiL)) && nv_isattr(np,NV_BLTINOPT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (oldpp->bltin_lib = dllplug(SH_ID, oldpp->blib, NiL, RTLD_LAZY, NiL, 0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (oldpp->bltin_lib = dllfind(oldpp->blib, NiL, RTLD_LAZY, NiL, 0))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * this detects the 2007-05-11 builtin context change and also
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * the 2008-03-30 opt_info.num change that hit libcmd::b_head
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (libcmd && !dlllook(oldpp->bltin_lib, "b_pids"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((addr=(Fptr_t)dlllook(oldpp->bltin_lib,stakptr(n))) &&
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (!(np = sh_addbuiltin(stakptr(PATH_OFFSET),NiL,NiL)) || np->nvalue.bfp!=addr) &&
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* SHOPT_DYNAMIC */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(isfun && f>=0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nv_onattr(nv_open(name,sh_subfuntree(1),NV_NOARRAY|NV_IDENT|NV_NOSCOPE),NV_LTOU|NV_FUNCTION);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = sh_addbuiltin(stakptr(PATH_OFFSET),np->nvalue.bfp,nv_context(np));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!pp || f>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * returns 0 if path can execute
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * sets exec_err if file is found but can't be executable
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /*S_EXEC */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* S_IXUSR */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for .exe or .bat suffix */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(errno==ENOENT && (!(cp=strrchr(path,'.')) || strlen(cp)>4 || strchr(cp,'/')))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* _WINIX */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if((statb.st_mode&S_IXALL)==S_IXALL || sh_access(path,X_OK)>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Return path relative to present working directory
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* can't relpath when sh.pwd not set */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((char*)fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((char*)e_dot);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((char*)fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((char*)e_dot);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((char*)file);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid path_exec(register const char *arg0,register char *argv[],struct argnod *local)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nv_setlist(local,NV_EXPORT|NV_IDENT|NV_ASSIGN,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* name containing / not allowed for restricted shell */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* find first path that has a library component */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* force an exit */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(ERROR_NOENT),e_found,arg0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_system(ERROR_NOEXEC),e_exec,arg0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinpid_t path_spawn(const char *opath,register char **argv, char **envp, Pathcomp_t *libpath, int spawn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char **xp=0, *xval, *libenv = (libpath?libpath->lib:0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *s, *v;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* leave room for inserting _= pathname in environment */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* save original pathname */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz pidsize = sfprintf(stkstd,"*%d*",spawn?getpid():getppid());
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for symlink and use symlink name */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(buff[0]=='.' && buff[1]=='.' && (r = strlen(path) + 1) <= PATH_MAX)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (s = *xp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The following code because execv(foo,) and execv(./foo,)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * may not yield the same results
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHELLMAGIC */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin pid = path_pfexecve(opath, &argv[0] ,envp,spawn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHELLMAGIC */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * On apollo's execve will fail with eacces when
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * file has execute but not read permissions. So,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * for now we will pretend that EACCES and ENOEXEC
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * mean the same thing.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* apollo */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* some systems return EPERM if setuid bit is on */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((struct checkpt*)shp->jmplist)->mode = SH_JMPEXIT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* FALL THROUGH */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* !apollo */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* ENAMETOOLONG */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* EMLINK */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_system(ERROR_NOEXEC),e_exec,path);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * File is executable but not machine code.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Assume file is a Shell script and execute it.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void exscript(Shell_t *shp,register char *path,register char *argv[],char **envp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* clean up any cooperating processes */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check if file cannot open for read or script is setuid/setgid */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* move <n> if n=0,1,2 */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fstat(n,&statb)>=0 && !(statb.st_mode&(S_ISUID|S_ISGID)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strncpy(name+9,fmtbase((long)getpid(),10,0),sizeof(name)-10);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* create a suid open file with owner equal effective uid */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((n=open(name,O_CREAT|O_TRUNC|O_WRONLY,S_ISUID|S_IXUSR)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* make sure that file has right owner */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The following code is just for compatibility
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin errormsg(SH_DICT,ERROR_system(ERROR_NOEXEC),e_exec,path);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin errormsg(SH_DICT,ERROR_system(ERROR_NOEXEC),e_exec,path);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_ACCT */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* save name of calling command */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* close history file if name has changed */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(shp->hist_ptr && (path=nv_getval(HISTFILE)) && strcmp(path,shp->hist_ptr->histname))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static char *SHACCT; /* set to value of SHACCT environment variable */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static shaccton; /* non-zero causes accounting record to be written */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * initialize accounting, i.e., see if SHACCT variable set
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * suspend accounting until turned on by sh_accbegin()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* AEXPAND */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * begin an accounting record by recording start time
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * terminate an accounting record and append to accounting file
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sabuf.ac_utime = compress(buffer.tms_utime + buffer.tms_cutime);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sabuf.ac_stime = compress(buffer.tms_stime + buffer.tms_cstime);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd = open( SHACCT , O_WRONLY | O_APPEND | O_CREAT,RW_ALL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Produce a pseudo-floating point representation
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * with 3 bits base-8 exponent, 13 bits fraction.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (t >= 8192)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (t >= 8192)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_ACCT */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * add a pathcomponent to the path search list and eliminate duplicates
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * and non-existing absolute paths.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Pathcomp_t *path_addcomp(Pathcomp_t *first, Pathcomp_t *old,const char *name, int flag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(memcmp(name,pp->name,len)==0 && (pp->name[len]==':' || pp->name[len]==0))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz for(pp=first, oldpp=0; pp; oldpp=pp, pp=pp->next);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(old && ((flag&(PATH_PATH|PATH_SKIP))==PATH_PATH))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This function checks for the .paths file in directory in <pp>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * it assumes that the directory is on the stack at <offset>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int path_chkpaths(Pathcomp_t *first, Pathcomp_t* old,Pathcomp_t *pp, int offset)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(m==0 || m==6 && memcmp((void*)sp,(void*)"FPATH=",6)==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path_addcomp(first,old,stakptr(offset),PATH_FPATH|PATH_BFPATH);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(m==12 && memcmp((void*)sp,(void*)"BUILTIN_LIB=",12)==0)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(!(pp->flags & PATH_BUILTIN_LIB) || strchr(ep,'-'))
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if ((pp->flags & (PATH_BUILTIN_LIB|PATH_STD_DIR)) == PATH_BUILTIN_LIB)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(m)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinPathcomp_t *path_addpath(Pathcomp_t *first, register const char *path,int type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin first = (void*)path_addpath((Pathcomp_t*)first,cp,PATH_FPATH);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * duplicate the path give by <first> by incremented reference counts
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * called whenever the directory is changed
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* delete .paths component */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* try to insert .paths component */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for(rp=(struct Ufunction*)dtfirst(shp->fpathdict);rp;rp=rpnext)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin rpnext = (struct Ufunction*)dtnext(shp->fpathdict,rp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinPathcomp_t *path_dirfind(Pathcomp_t *first,const char *name,int c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(memcmp(name,pp->name,pp->len)==0 && name[pp->len]==c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * get discipline for tracked alias
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void talias_put(register Namval_t* np,const char *val,int flags,Namfun_t *fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const Namdisc_t talias_disc = { 0, talias_put, talias_get };
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * set tracked alias node <np> to value <pp>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid path_alias(register Namval_t *np,register Pathcomp_t *pp)