da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
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* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * David Korn
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Labs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "defs.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <fcin.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <ls.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <nval.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "variables.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "path.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "io.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "jobs.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "history.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "test.h"
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#include "FEATURE/dynamic"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "FEATURE/externs"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_PFSH
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifdef _hdr_exec_attr
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# include <exec_attr.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# if _lib_vfork
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# include <ast_vfork.h>
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# define vfork() fork()
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define RW_ALL (S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR|S_IWGRP|S_IWOTH)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define LIBCMD "cmd"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int canexecute(char*,int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void funload(Shell_t*,int,const char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void exscript(Shell_t*,char*, char*[], char**);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int path_chkpaths(Pathcomp_t*,Pathcomp_t*,Pathcomp_t*,int);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzstatic void path_checkdup(register Pathcomp_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const char *std_path;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int onstdpath(const char *name)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const char *cp = std_path, *sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(*cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(sp=name; *sp && (*cp == *sp); sp++,cp++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*sp==0 && (*cp==0 || *cp==':'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(*cp && *cp++!=':');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic pid_t path_pfexecve(const char *path, char *argv[],char *const envp[],int spawn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_PFSH
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin pid_t pid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char resolvedpath[PATH_MAX + 1];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(spawn)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while((pid = vfork()) < 0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin _sh_fork(pid, 0, (int*)0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(pid)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(pid);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!sh_isoption(SH_PFSH))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(execve(path, argv, envp));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* Solaris implements realpath(3C) using the resolvepath(2) */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* system call so we can save us to call access(2) first */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!realpath(path, resolvedpath))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
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 (sh.user && *sh.user)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin execattr_t *pf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pf=getexecuser(sh.user, KV_COMMAND, resolvedpath, GET_ONE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!pf->attr || pf->attr->length == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int r = execve(path, argv, envp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free_execattr(pf);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return r;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free_execattr(pf);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = ENOENT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin --argv;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv[0] = argv[1];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv[1] = resolvedpath;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(execve("/usr/bin/pfexec", argv, envp));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(execve(path, argv, envp));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic pid_t _spawnveg(const char *path, char* const argv[], char* const envp[], pid_t pgid)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int waitsafe = job.waitsafe;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin pid_t pid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job_lock();
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(1)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_stats(STAT_SPAWN);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin pid = spawnveg(path,argv,envp,pgid);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(pid>=0 || errno!=EAGAIN)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin _sh_fork(pid, 0, (int*)0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job.waitsafe = waitsafe;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(pid>0)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner job_fork(pid);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner job_unlock();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(pid);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
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
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic pid_t path_xargs(const char *path, char *argv[],char *const envp[], int spawn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp, **av, **xv;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char **avlast= &argv[sh.xargmax], **saveargs=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *const *ev;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin long size, left;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int nlast=1,n,exitval=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pid_t pid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh.xargmin < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((pid_t)-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = sh.lim.arg_max-1024;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(ev=envp; cp= *ev; ev++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size -= strlen(cp)-1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(av=argv; (cp= *av) && av< &argv[sh.xargmin]; av++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size -= strlen(cp)-1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(av=avlast; cp= *av; av++,nlast++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size -= strlen(cp)-1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin av = &argv[sh.xargmin];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!spawn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job_clear();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.exitval = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(av<avlast)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(xv=av,left=size; left>0 && av<avlast;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin left -= strlen(*av++)+1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* leave at least two for last */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(left<0 && (avlast-av)<2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin av--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(xv==&argv[sh.xargmin])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = nlast*sizeof(char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin saveargs = (char**)malloc(n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy((void*)saveargs, (void*)av, n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy((void*)av,(void*)avlast,n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(n=sh.xargmin; xv < av; xv++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv[n++] = *xv;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(xv=avlast; cp= *xv; xv++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv[n++] = cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv[n] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(saveargs || av<avlast || (exitval && !spawn))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((pid=_spawnveg(path,argv,envp,0)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job_post(pid,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job_wait(pid);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh.exitval>exitval)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin exitval = sh.exitval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(saveargs)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy((void*)av,saveargs,n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)saveargs);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin saveargs = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(spawn && !sh_isoption(SH_PFSH))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.xargexit = exitval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(_spawnveg(path,argv,envp,spawn>>1));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(path_pfexecve(path,argv,envp,spawn));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!spawn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin exit(exitval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((pid_t)-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
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 */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinchar *path_pwd(int flag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *dfault = (char*)e_dot;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int count = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Shell_t *shp = &sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(shp->pwd)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((char*)shp->pwd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* try from lowest to highest */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(count++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = nv_getval(PWDNOD);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 1:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = nv_getval(HOME);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 2:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = "/";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 3:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = (char*)e_crondir;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag) /* skip next case when non-zero flag */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ++count;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 4:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cp=getcwd(NIL(char*),0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_offattr(PWDNOD,NV_NOFREE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_unset(PWDNOD);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PWDNOD->nvalue.cp = cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto skip;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 5:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(dfault);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cp && *cp=='/' && test_inode(cp,e_dot))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(count>1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_offattr(PWDNOD,NV_NOFREE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putval(PWDNOD,cp,NV_RDONLY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinskip:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_onattr(PWDNOD,NV_NOFREE|NV_EXPORT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->pwd = (char*)(PWDNOD->nvalue.cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void free_bltin(Namval_t *np,void *data)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Pathcomp_t *pp= (Pathcomp_t*)data;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pp->flags&PATH_STD_DIR)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int offset=staktell();;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(strcmp(pp->name,"/bin")==0 || memcmp(pp->name,np->nvname,pp->len) || np->nvname[pp->len]!='/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs("/bin");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs(np->nvname+pp->len+1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputc(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_addbuiltin(stakptr(offset),np->nvalue.bfp,NiL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakseek(offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((void*)np->nvenv==pp->bltin_lib)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_delete(np,sh_bltin_tree(),NV_NOFREE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * delete current Pathcomp_t structure
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid path_delete(Pathcomp_t *first)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Pathcomp_t *pp=first, *old=0, *ppnext;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(pp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppnext = pp->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(--pp->refcount<=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pp->lib)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)pp->lib);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pp->blib)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)pp->blib);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pp->bltin_lib || (pp->flags&PATH_STD_DIR))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_scan(sh_bltin_tree(),free_bltin,pp,0,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if SHOPT_DYNAMIC
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pp->bltin_lib)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dlclose(pp->bltin_lib);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* SHOPT_DYNAMIC */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)pp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(old)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin old->next = ppnext;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin old = pp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = ppnext;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * returns library variable from .paths
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The value might be returned on the stack overwriting path
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char *path_lib(Pathcomp_t *pp, char *path)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *last = strrchr(path,'/');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int r;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct stat statb;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(last)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *last = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path = ".";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r = stat(path,&statb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(last)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *last = '/';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(r>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Pathcomp_t pcomp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char save[8];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for( ;pp; pp=pp->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz path_checkdup(pp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(pp->ino==statb.st_ino && pp->dev==statb.st_dev && pp->mtime==statb.st_mtime)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(pp->lib);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pcomp.len = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(last)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pcomp.len = last-path;
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 return(stakfreeze(1));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy((void*)stakptr(PATH_OFFSET+pcomp.len),(void*)save,sizeof(save));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if 0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid path_dump(register Pathcomp_t *pp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr,"dump\n");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(pp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
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);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = pp->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz/*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * check for duplicate directories on PATH
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzstatic void path_checkdup(register Pathcomp_t *pp)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz{
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz register char *name = pp->name;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz register Pathcomp_t *oldpp,*first;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz register int flag=0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz struct stat statb;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(stat(name,&statb)<0 || !S_ISDIR(statb.st_mode))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz pp->flags |= PATH_SKIP;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz pp->dev = *name=='/';
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz pp->mtime = statb.st_mtime;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz pp->ino = statb.st_ino;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz pp->dev = statb.st_dev;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(*name=='/' && onstdpath(name))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz flag = PATH_STD_DIR;
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 {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(pp->ino==oldpp->ino && pp->dev==oldpp->dev && pp->mtime==oldpp->mtime)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz flag |= PATH_SKIP;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz pp->flags |= flag;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(((pp->flags&(PATH_PATH|PATH_SKIP))==PATH_PATH))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int offset = staktell();
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz stakputs(name);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz path_chkpaths(first,0,pp,offset);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz stakseek(offset);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz}
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
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.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinPathcomp_t *path_nextcomp(register Pathcomp_t *pp, const char *name, Pathcomp_t *last)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz Pathcomp_t *ppnext;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakseek(PATH_OFFSET);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*name=='/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz for(;pp && pp!=last;pp=ppnext)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(ppnext=pp->next)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz ppnext->shp = pp->shp;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(!pp->dev && !pp->ino)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz path_checkdup(pp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pp->flags&PATH_SKIP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!last || *pp->name!='/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!pp) /* this should not happen */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = last;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pp && (pp->name[0]!='.' || pp->name[1]))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*pp->name!='/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs(path_pwd(1));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*stakptr(staktell()-1)!='/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputc('/');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakwrite(pp->name,pp->len);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pp->name[pp->len-1]!='/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputc('/');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs(name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputc(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(pp && pp!=last && (pp=pp->next))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(pp->flags&PATH_SKIP))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(pp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((Pathcomp_t*)0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Pathcomp_t* defpath_init(Shell_t *shp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Pathcomp_t *pp = (void*)path_addpath((Pathcomp_t*)0,(std_path),PATH_PATH);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(shp->defpathlist = (void*)pp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->shp = shp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(pp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void path_init(Shell_t *shp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const char *val;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Pathcomp_t *pp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!std_path && !(std_path=astconf("PATH",NIL(char*),NIL(char*))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin std_path = e_defpath;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(val=sh_scoped(shp,(PATHNOD))->nvalue.cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = (void*)path_addpath((Pathcomp_t*)shp->pathlist,val,PATH_PATH);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(shp->pathlist = (void*)pp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->shp = shp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(pp=(Pathcomp_t*)shp->defpathlist))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = defpath_init(shp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->pathlist = (void*)path_dup(pp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(val=sh_scoped(shp,(FPATHNOD))->nvalue.cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = (void*)path_addpath((Pathcomp_t*)shp->pathlist,val,PATH_FPATH);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(shp->pathlist = (void*)pp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->shp = shp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * returns that pathlist to search
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinPathcomp_t *path_get(register const char *name)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Shell_t *shp = &sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Pathcomp_t *pp=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*name && strchr(name,'/'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!sh_isstate(SH_DEFPATH))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!shp->pathlist)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path_init(shp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = (Pathcomp_t*)shp->pathlist;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!pp && (!(PATHNOD)->nvalue.cp) || sh_isstate(SH_DEFPATH))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(pp=(Pathcomp_t*)shp->defpathlist))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = defpath_init(shp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(pp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * open file corresponding to name using path give by <pp>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int path_opentype(const char *name, register Pathcomp_t *pp, int fun)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int fd= -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct stat statb;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Pathcomp_t *oldpp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Shell_t *shp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp = pp->shp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp = sh_getinterp();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!shp->pathlist)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path_init(shp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!fun && strchr(name,'/'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_RESTRICTED))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),e_restricted,name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = path_nextcomp(oldpp=pp,name,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(oldpp && (oldpp->flags&PATH_SKIP))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin oldpp = oldpp->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fun && (!oldpp || !(oldpp->flags&PATH_FPATH)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((fd = sh_open(path_relative(stakptr(PATH_OFFSET)),O_RDONLY,0)) >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fstat(fd,&statb)<0 || S_ISDIR(statb.st_mode))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = EISDIR;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_close(fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while( fd<0 && pp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fd>=0 && (fd = sh_iomovefd(fd)) > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcntl(fd,F_SETFD,FD_CLOEXEC);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(!shp)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz shp = sh_getinterp();
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#if _UWIN
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz close(0x10001); /* this results in a /var/log/uwin message with "0x10001" for debugging */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#endif
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->fdstatus[fd] |= IOCLEX;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * open file corresponding to name using path give by <pp>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint path_open(const char *name, register Pathcomp_t *pp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(path_opentype(name,pp,0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * given a pathname return the base name
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinchar *path_basename(register const char *name)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const char *start = name;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*name)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((*name++ == '/') && *name) /* don't trim trailing / */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin start = name;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return ((char*)start);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinchar *path_fullname(const char *name)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int len=strlen(name)+1,dirlen=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *path,*pwd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*name!='/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pwd = path_pwd(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dirlen = strlen(pwd)+1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path = (char*)malloc(len+dirlen);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dirlen)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy((void*)path,(void*)pwd,dirlen);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path[dirlen-1] = '/';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy((void*)&path[dirlen],(void*)name,len);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pathcanon(path,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(path);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * load functions from file <fno>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void funload(Shell_t *shp,int fno, const char *name)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *pname,*oldname=shp->st.filename, buff[IOBSIZE+1];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Namval_t *np;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct Ufunction *rp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int savestates = sh_getstate(), oldload=shp->funload;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin pname = path_fullname(stakptr(PATH_OFFSET));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->fpathdict && (rp = dtmatch(shp->fpathdict,(void*)pname)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz Dt_t *funtree = sh_subfuntree(1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin do
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if((np = dtsearch(funtree,rp->np)) && is_afunction(np))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(np->nvalue.rp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np->nvalue.rp->fdict = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nv_delete(np,funtree,NV_NOFREE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz dtinsert(funtree,rp->np);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz rp->fdict = funtree;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while((rp=dtnext(shp->fpathdict,rp)) && strcmp(pname,rp->fname)==0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onstate(SH_NOLOG);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onstate(SH_NOALIAS);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->readscript = (char*)name;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.filename = pname;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->funload = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.line = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sh_eval(sfnew(NIL(Sfio_t*),buff,IOBSIZE,fno,SF_READ),SH_FUNEVAL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->readscript = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)shp->st.filename);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->funload = oldload;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->st.filename = oldname;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_setstate(savestates);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
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.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinint path_search(register const char *name,Pathcomp_t **oldpp, int flag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Namval_t *np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int fno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Pathcomp_t *pp=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Shell_t *shp = &sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(name && strchr(name,'/'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakseek(PATH_OFFSET);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs(name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(canexecute(stakptr(PATH_OFFSET),0)<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *stakptr(PATH_OFFSET) = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*name=='/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakseek(PATH_OFFSET);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs(path_pwd(1));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputc('/');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs(name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputc(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isstate(SH_DEFPATH))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!shp->defpathlist)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin defpath_init(shp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(!shp->pathlist)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path_init(shp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if((np=nv_search(name,shp->track_tree,0)) && !nv_isattr(np,NV_NOALIAS) && (pp=(Pathcomp_t*)np->nvalue.cp))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz stakseek(PATH_OFFSET);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz path_nextcomp(pp,name,pp);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz stakputc(0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return(0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin pp = path_absolute(name,oldpp?*oldpp:NIL(Pathcomp_t*));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(oldpp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *oldpp = pp;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(!pp && (np=nv_search(name,shp->fun_tree,HASH_NOSCOPE))&&np->nvalue.ip)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!pp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *stakptr(PATH_OFFSET) = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag==0 || !pp || (pp->flags&PATH_FPATH))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!pp)
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 {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag==2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_close(fno);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin funload(shp,fno,name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *stakptr(PATH_OFFSET) = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(pp && !sh_isstate(SH_DEFPATH) && *name!='/' && flag<3)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np=nv_search(name,shp->track_tree,NV_ADD))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path_alias(np,pp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * do a path search and find the full pathname of file name
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April ChinPathcomp_t *path_absolute(register const char *name, Pathcomp_t *pp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int f,isfun;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int noexec=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Pathcomp_t *oldpp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Shell_t *shp = &sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->path_err = ENOENT;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!pp && !(pp=path_get("")))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->path_err = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_sigcheck();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin isfun = (pp->flags&PATH_FPATH);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(oldpp=pp)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = path_nextcomp(pp,name,0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz while(oldpp->flags&PATH_SKIP)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(!(oldpp=oldpp->next))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz shp->path_err = ENOENT;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return(0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!isfun && !sh_isoption(SH_RESTRICTED))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(*stakptr(PATH_OFFSET)=='/' && nv_search(stakptr(PATH_OFFSET),sh.bltin_tree,0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(oldpp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if SHOPT_DYNAMIC
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(oldpp->blib)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin typedef int (*Fptr_t)(int, char*[], void*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Fptr_t addr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n = staktell();
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int libcmd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs("b_");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs(name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputc(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!oldpp->bltin_lib)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cp = strrchr(oldpp->blib,'/'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = oldpp->blib;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if((libcmd = !strcmp(cp,LIBCMD)) && (addr=(Fptr_t)dlllook((void*)0,stakptr(n))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((np = sh_addbuiltin(stakptr(PATH_OFFSET),addr,NiL)) && nv_isattr(np,NV_BLTINOPT))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(oldpp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if (_AST_VERSION>=20040404)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (oldpp->bltin_lib = dllplug(SH_ID, oldpp->blib, NiL, RTLD_LAZY, NiL, 0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (oldpp->bltin_lib = dllfind(oldpp->blib, NiL, RTLD_LAZY, NiL, 0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*
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 */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (libcmd && !dlllook(oldpp->bltin_lib, "b_pids"))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz dlclose(oldpp->bltin_lib);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz oldpp->bltin_lib = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz oldpp->blib = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sh_addlib(oldpp->bltin_lib);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((addr=(Fptr_t)dlllook(oldpp->bltin_lib,stakptr(n))) &&
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (!(np = sh_addbuiltin(stakptr(PATH_OFFSET),NiL,NiL)) || np->nvalue.bfp!=addr) &&
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (np = sh_addbuiltin(stakptr(PATH_OFFSET),addr,NiL)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvenv = oldpp->bltin_lib;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(oldpp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* SHOPT_DYNAMIC */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_stats(STAT_PATHS);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = canexecute(stakptr(PATH_OFFSET),isfun);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(isfun && f>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nv_onattr(nv_open(name,sh_subfuntree(1),NV_NOARRAY|NV_IDENT|NV_NOSCOPE),NV_LTOU|NV_FUNCTION);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz funload(shp,f,name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin close(f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(f>=0 && (oldpp->flags & PATH_STD_DIR))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int n = staktell();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs("/bin/");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs(name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputc(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = nv_search(stakptr(n),sh.bltin_tree,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stakseek(n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin n = np->nvflag;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = sh_addbuiltin(stakptr(PATH_OFFSET),np->nvalue.bfp,nv_context(np));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np->nvflag = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!pp || f>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(errno!=ENOENT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin noexec = errno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(f<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->path_err = (noexec?noexec:ENOENT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputc(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(oldpp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * returns 0 if path can execute
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * sets exec_err if file is found but can't be executable
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef S_IXALL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef S_IXUSR
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define S_IXALL (S_IXUSR|S_IXGRP|S_IXOTH)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifdef S_IEXEC
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define S_IXALL (S_IEXEC|(S_IEXEC>>3)|(S_IEXEC>>6))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define S_IXALL 0111
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /*S_EXEC */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* S_IXUSR */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int canexecute(register char *path, int isfun)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct stat statb;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int fd=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path = path_relative(path);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(isfun)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((fd=open(path,O_RDONLY,0))<0 || fstat(fd,&statb)<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto err;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(stat(path,&statb) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _WINIX
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for .exe or .bat suffix */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(errno==ENOENT && (!(cp=strrchr(path,'.')) || strlen(cp)>4 || strchr(cp,'/')))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int offset = staktell()-1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakseek(offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs(".bat");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path = stakptr(PATH_OFFSET);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(stat(path,&statb) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(errno!=ENOENT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto err;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(stakptr(offset),".sh",4);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(stat(path,&statb) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto err;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* _WINIX */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto err;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = EPERM;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(S_ISDIR(statb.st_mode))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = EISDIR;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if((statb.st_mode&S_IXALL)==S_IXALL || sh_access(path,X_OK)>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(isfun && fd>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_close(fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinerr:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Return path relative to present working directory
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinchar *path_relative(register const char* file)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const char *pwd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const char *fp = file;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* can't relpath when sh.pwd not set */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(pwd=sh.pwd))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((char*)fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(*pwd==*fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*pwd++==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((char*)e_dot);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*pwd==0 && *fp == '/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(*++fp=='/');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((char*)fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((char*)e_dot);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((char*)file);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid path_exec(register const char *arg0,register char *argv[],struct argnod *local)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char **envp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const char *opath;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Pathcomp_t *libpath, *pp=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Shell_t *shp = &sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int slash=0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nv_setlist(local,NV_EXPORT|NV_IDENT|NV_ASSIGN,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin envp = sh_envgen();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(strchr(arg0,'/'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin slash=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* name containing / not allowed for restricted shell */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_RESTRICTED))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),e_restricted,arg0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp=path_get(arg0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->path_err= ENOENT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsync(NIL(Sfio_t*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin timerdel(NIL(void*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* find first path that has a library component */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz while(pp && (pp->flags&PATH_SKIP))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz pp = pp->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pp || slash) do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_sigcheck();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(libpath=pp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = path_nextcomp(pp,arg0,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin opath = stakfreeze(1)+PATH_OFFSET;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin opath = arg0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path_spawn(opath,argv,envp,libpath,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(pp && (pp->flags&PATH_FPATH))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = path_nextcomp(pp,arg0,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(pp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* force an exit */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ((struct checkpt*)shp->jmplist)->mode = SH_JMPEXIT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((errno=shp->path_err)==ENOENT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(ERROR_NOENT),e_found,arg0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_system(ERROR_NOEXEC),e_exec,arg0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinpid_t path_spawn(const char *opath,register char **argv, char **envp, Pathcomp_t *libpath, int spawn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Shell_t *shp = sh_getinterp();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *path;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char **xp=0, *xval, *libenv = (libpath?libpath->lib:0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t* np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *s, *v;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int r, n, pidsize;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pid_t pid= -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* leave room for inserting _= pathname in environment */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin envp--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _lib_readlink
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* save original pathname */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakseek(PATH_OFFSET);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz pidsize = sfprintf(stkstd,"*%d*",spawn?getpid():getppid());
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs(opath);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz opath = stakfreeze(1)+PATH_OFFSET+pidsize;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np=nv_search(argv[0],shp->track_tree,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(libpath && !libpath->lib)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin libpath=libpath->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(libpath && (!np || nv_size(np)>0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for symlink and use symlink name */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char buff[PATH_MAX+1];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char save[PATH_MAX+1];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakseek(PATH_OFFSET);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs(opath);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path = stakptr(PATH_OFFSET);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while((n=readlink(path,buff,PATH_MAX))>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin buff[n] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = PATH_OFFSET;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((v=strrchr(path,'/')) && *buff!='/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(buff[0]=='.' && buff[1]=='.' && (r = strlen(path) + 1) <= PATH_MAX)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(save, path, r);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n += (v+1-path);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakseek(n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs(buff);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputc(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path = stakptr(PATH_OFFSET);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(v && buff[0]=='.' && buff[1]=='.')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pathcanon(path, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(r && access(path,X_OK))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(path, save, r);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(libenv = path_lib(libpath,path))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakseek(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(libenv && (v = strchr(libenv,'=')))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = v - libenv;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *v = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = nv_open(libenv,shp->var_tree,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *v = '=';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = nv_getval(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs(libenv);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputc(':');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs(s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v = stakfreeze(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin xp = envp + 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (s = *xp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (strneq(s, v, n) && s[n] == '=')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin xval = *--xp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *xp = v;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (r)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *envp-- = v;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin xp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!opath)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin opath = stakptr(PATH_OFFSET);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz envp[0] = (char*)opath-(PATH_OFFSET+pidsize);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin envp[0][0] = '_';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin envp[0][1] = '=';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsync(sfstderr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_sigcheck();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path = path_relative(opath);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef SHELLMAGIC
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*path!='/' && path!=opath)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The following code because execv(foo,) and execv(./foo,)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * may not yield the same results
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *sp = (char*)malloc(strlen(path)+3);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp[0] = '.';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp[1] = '/';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strcpy(sp+2,path);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path = sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHELLMAGIC */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(spawn && !sh_isoption(SH_PFSH))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pid = _spawnveg(opath, &argv[0],envp, spawn>>1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin pid = path_pfexecve(opath, &argv[0] ,envp,spawn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(xp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *xp = xval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef SHELLMAGIC
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*path=='.' && path!=opath)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(path);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path = path_relative(opath);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHELLMAGIC */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pid>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(pid);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinretry:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(sh.path_err = errno)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef apollo
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
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 */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case EACCES:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* apollo */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ENOEXEC:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_SUID_EXEC
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case EPERM:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* some systems return EPERM if setuid bit is on */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = ENOEXEC;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(spawn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef _lib_fork
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh.subshell)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((pid=fork())>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(pid);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(_sh_fork(pid,0,(int*)0) < 0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((struct checkpt*)shp->jmplist)->mode = SH_JMPEXIT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin exscript(shp,path,argv,envp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef apollo
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case EACCES:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct stat statb;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(stat(path,&statb)>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(S_ISDIR(statb.st_mode))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = EISDIR;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef S_ISSOCK
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(S_ISSOCK(statb.st_mode))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin exscript(shp,path,argv,envp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* FALL THROUGH */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* !apollo */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef ENAMETOOLONG
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ENAMETOOLONG:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* ENAMETOOLONG */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if !SHOPT_SUID_EXEC
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case EPERM:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->path_err = errno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ENOTDIR:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ENOENT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case EINTR:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef EMLINK
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case EMLINK:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* EMLINK */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case E2BIG:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh.xargmin)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pid = path_xargs(opath, &argv[0] ,envp,spawn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pid<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto retry;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(pid);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_system(ERROR_NOEXEC),e_exec,path);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * File is executable but not machine code.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Assume file is a Shell script and execute it.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void exscript(Shell_t *shp,register char *path,register char *argv[],char **envp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Sfio_t *sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path = path_relative(path);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->comdiv=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->bckpid = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->st.ioset=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* clean up any cooperating processes */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(shp->cpipe[0]>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_pclose(shp->cpipe);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(shp->cpid && shp->outpipe)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_close(*shp->outpipe);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->cpid = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sp=fcfile())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(sfstack(sp,SF_POPSTACK));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job_clear();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(shp->infd>0 && (shp->fdstatus[shp->infd]&IOCLEX))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_close(shp->infd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_setstate(sh_state(SH_FORKED));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsync(sfstderr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_SUID_EXEC && !SHOPT_PFSH
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check if file cannot open for read or script is setuid/setgid */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static char name[] = "/tmp/euidXXXXXXXXXX";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register uid_t euserid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *savet=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct stat statb;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((n=sh_open(path,O_RDONLY,0)) >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* move <n> if n=0,1,2 */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = sh_iomovefd(n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fstat(n,&statb)>=0 && !(statb.st_mode&(S_ISUID|S_ISGID)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto openok;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_close(n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((euserid=geteuid()) != shp->userid)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
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 goto fail;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unlink(name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* make sure that file has right owner */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fstat(n,&statb)<0 || statb.st_uid != euserid)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto fail;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n!=10)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_close(10);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcntl(n, F_DUPFD, 10);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_close(n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n=10;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin savet = *--argv;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *argv = path;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin path_pfexecve(e_suidexec,argv,envp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fail:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The following code is just for compatibility
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((n=open(path,O_RDONLY,0)) < 0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin errormsg(SH_DICT,ERROR_system(ERROR_NOEXEC),e_exec,path);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(savet)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *argv++ = savet;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin openok:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->infd = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((shp->infd = sh_open(path,O_RDONLY,0)) < 0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin errormsg(SH_DICT,ERROR_system(ERROR_NOEXEC),e_exec,path);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->infd = sh_iomovefd(shp->infd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_ACCT
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_accbegin(path) ; /* reset accounting */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_ACCT */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->arglist = sh_argcreate(argv);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->lastarg = strdup(path);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* save name of calling command */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->readscript = error_info.id;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* close history file if name has changed */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(shp->hist_ptr && (path=nv_getval(HISTFILE)) && strcmp(path,shp->hist_ptr->histname))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin hist_close(shp->hist_ptr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (HISTCUR)->nvalue.lp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offstate(SH_FORKED);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(shp->sigflag[SIGCHLD]==SH_SIGOFF)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz shp->sigflag[SIGCHLD] = SH_SIGFAULT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin siglongjmp(*shp->jmplist,SH_JMPSCRIPT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_ACCT
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# include <sys/acct.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# include "FEATURE/time"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static struct acct sabuf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static struct tms buffer;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static clock_t before;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static char *SHACCT; /* set to value of SHACCT environment variable */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static shaccton; /* non-zero causes accounting record to be written */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static int compress(time_t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * initialize accounting, i.e., see if SHACCT variable set
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin void sh_accinit(void)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin SHACCT = getenv("SHACCT");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * suspend accounting until turned on by sh_accbegin()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin void sh_accsusp(void)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shaccton=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef AEXPAND
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sabuf.ac_flag |= AEXPND;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* AEXPAND */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * begin an accounting record by recording start time
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin void sh_accbegin(const char *cmdname)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(SHACCT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sabuf.ac_btime = time(NIL(time_t *));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin before = times(&buffer);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sabuf.ac_uid = getuid();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sabuf.ac_gid = getgid();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strncpy(sabuf.ac_comm, (char*)path_basename(cmdname),
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sizeof(sabuf.ac_comm));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shaccton = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * terminate an accounting record and append to accounting file
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin void sh_accend(void)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int fd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin clock_t after;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(shaccton)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin after = times(&buffer);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sabuf.ac_utime = compress(buffer.tms_utime + buffer.tms_cutime);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sabuf.ac_stime = compress(buffer.tms_stime + buffer.tms_cstime);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sabuf.ac_etime = compress( (time_t)(after-before));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd = open( SHACCT , O_WRONLY | O_APPEND | O_CREAT,RW_ALL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin write(fd, (const char*)&sabuf, sizeof( sabuf ));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin close( fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Produce a pseudo-floating point representation
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * with 3 bits base-8 exponent, 13 bits fraction.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static int compress(register time_t t)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int exp = 0, rund = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (t >= 8192)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin exp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rund = t&04;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t >>= 3;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (rund)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (t >= 8192)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t >>= 3;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin exp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((exp<<13) + t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_ACCT */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * add a pathcomponent to the path search list and eliminate duplicates
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * and non-existing absolute paths.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Pathcomp_t *path_addcomp(Pathcomp_t *first, Pathcomp_t *old,const char *name, int flag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Pathcomp_t *pp, *oldpp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int len, offset=staktell();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(flag&PATH_BFPATH))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const char *cp = name;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(*cp && *cp!=':')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputc(*cp++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin len = staktell()-offset;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputc(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakseek(offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin name = (const char*)stakptr(offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin len = strlen(name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(pp=first; pp; pp=pp->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(memcmp(name,pp->name,len)==0 && (pp->name[len]==':' || pp->name[len]==0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->flags |= flag;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(first);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz for(pp=first, oldpp=0; pp; oldpp=pp, pp=pp->next);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = newof((Pathcomp_t*)0,Pathcomp_t,1,len+1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->refcount = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy((char*)(pp+1),name,len+1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->name = (char*)(pp+1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->len = len;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(oldpp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin oldpp->next = pp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin first = pp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->flags = flag;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(strcmp(name,SH_CMDLIB_DIR)==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz pp->dev = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->flags |= PATH_BUILTIN_LIB;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->blib = malloc(4);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strcpy(pp->blib,LIBCMD);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(first);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(old && ((flag&(PATH_PATH|PATH_SKIP))==PATH_PATH))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path_chkpaths(first,old,pp,offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(first);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This function checks for the .paths file in directory in <pp>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * it assumes that the directory is on the stack at <offset>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int path_chkpaths(Pathcomp_t *first, Pathcomp_t* old,Pathcomp_t *pp, int offset)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct stat statb;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int k,m,n,fd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *sp,*cp,*ep;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakseek(offset+pp->len);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pp->len==1 && *stakptr(offset)=='/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakseek(offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs("/.paths");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((fd=open(stakptr(offset),O_RDONLY))>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fstat(fd,&statb);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = statb.st_size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakseek(offset+pp->len+n+2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = stakptr(offset+pp->len);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *sp++ = '/';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n=read(fd,cp=sp,n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp[n] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin close(fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(ep=0; n--; cp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*cp=='=')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep = cp+1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(*cp!='\r' && *cp!='\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*sp=='#' || sp==cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = cp+1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *cp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m = ep ? (ep-sp) : 0;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(m==0 || m==6 && memcmp((void*)sp,(void*)"FPATH=",6)==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(first)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *ptr = stakptr(offset+pp->len+1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strcpy(ptr,ep);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path_addcomp(first,old,stakptr(offset),PATH_FPATH|PATH_BFPATH);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(m==12 && memcmp((void*)sp,(void*)"BUILTIN_LIB=",12)==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(!(pp->flags & PATH_BUILTIN_LIB) || strchr(ep,'-'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if ((pp->flags & (PATH_BUILTIN_LIB|PATH_STD_DIR)) == PATH_BUILTIN_LIB)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner free(pp->blib);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner pp->blib = 0;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->flags |= PATH_BUILTIN_LIB;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*ep == '.' && !*(ep + 1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->flags |= PATH_STD_DIR;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin k = strlen(ep)+1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*ep != '/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin k += pp->len+1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->blib = sp = malloc(k);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*ep != '/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strcpy(pp->blib,pp->name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp += pp->len;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *sp++ = '/';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strcpy(sp,ep);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(m)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->lib = (char*)malloc(cp-sp+pp->len+2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy((void*)pp->lib,(void*)sp,m);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy((void*)&pp->lib[m],stakptr(offset),pp->len);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->lib[k=m+pp->len] = '/';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strcpy((void*)&pp->lib[k+1],ep);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pathcanon(&pp->lib[m],0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!first)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakseek(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs(pp->lib);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)pp->lib);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = cp+1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinPathcomp_t *path_addpath(Pathcomp_t *first, register const char *path,int type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const char *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Pathcomp_t *old=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int offset = staktell();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *savptr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!path && type!=PATH_PATH)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(first);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type!=PATH_FPATH)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin old = first;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin first = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(offset)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin savptr = stakfreeze(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(path) while(*(cp=path))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*cp==':')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type!=PATH_FPATH)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin first = path_addcomp(first,old,".",type);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(*++path == ':');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(*path && *path!=':')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *path++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin first = path_addcomp(first,old,cp,type);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*path==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(old)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!first && !path)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Pathcomp_t *pp = (Pathcomp_t*)old->shp->defpathlist;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!pp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = defpath_init(old->shp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin first = path_dup(pp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cp=(FPATHNOD)->nvalue.cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin first = (void*)path_addpath((Pathcomp_t*)first,cp,PATH_FPATH);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path_delete(old);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(offset)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakset(savptr,offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakseek(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(first);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * duplicate the path give by <first> by incremented reference counts
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinPathcomp_t *path_dup(Pathcomp_t *first)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Pathcomp_t *pp=first;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(pp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->refcount++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = pp->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(first);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * called whenever the directory is changed
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid path_newdir(Pathcomp_t *first)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Pathcomp_t *pp=first, *next, *pq;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct stat statb;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(pp=first; pp; pp=pp->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->flags &= ~PATH_SKIP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*pp->name=='/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* delete .paths component */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((next=pp->next) && (next->flags&PATH_BFPATH))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->next = next->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(--next->refcount<=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)next);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(stat(pp->name,&statb)<0 || !S_ISDIR(statb.st_mode))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->dev = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->ino = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->dev = statb.st_dev;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->ino = statb.st_ino;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin pp->mtime = statb.st_mtime;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(pq=first;pq!=pp;pq=pq->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pp->ino==pq->ino && pp->dev==pq->dev)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->flags |= PATH_SKIP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(pq=pp;pq=pq->next;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pp->ino==pq->ino && pp->dev==pq->dev)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pq->flags |= PATH_SKIP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((pp->flags&(PATH_PATH|PATH_SKIP))==PATH_PATH)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* try to insert .paths component */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int offset = staktell();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs(pp->name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakseek(offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin next = pp->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->next = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path_chkpaths(first,(Pathcomp_t*)0,pp,offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pp->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = pp->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->next = next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if 0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path_dump(first);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinPathcomp_t *path_unsetfpath(Pathcomp_t *first)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Pathcomp_t *pp=first, *old=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = &sh;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->fpathdict)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct Ufunction *rp, *rpnext;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for(rp=(struct Ufunction*)dtfirst(shp->fpathdict);rp;rp=rpnext)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin rpnext = (struct Ufunction*)dtnext(shp->fpathdict,rp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(rp->fdict)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_delete(rp->np,rp->fdict,NV_NOFREE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin rp->fdict = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(pp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((pp->flags&PATH_FPATH) && !(pp->flags&PATH_BFPATH))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pp->flags&PATH_PATH)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->flags &= ~PATH_FPATH;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Pathcomp_t *ppsave=pp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(old)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin old->next = pp->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin first = pp->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = pp->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(--ppsave->refcount<=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ppsave->lib)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)ppsave->lib);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)ppsave);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin old = pp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = pp->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(first);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinPathcomp_t *path_dirfind(Pathcomp_t *first,const char *name,int c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Pathcomp_t *pp=first;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(pp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(memcmp(name,pp->name,pp->len)==0 && name[pp->len]==c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(pp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = pp->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * get discipline for tracked alias
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char *talias_get(Namval_t *np, Namfun_t *nvp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Pathcomp_t *pp = (Pathcomp_t*)np->nvalue.cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *ptr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!pp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(NULL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path_nextcomp(pp,nv_name(np),pp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ptr = stakfreeze(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(ptr+PATH_OFFSET);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void talias_put(register Namval_t* np,const char *val,int flags,Namfun_t *fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!val && np->nvalue.cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Pathcomp_t *pp = (Pathcomp_t*)np->nvalue.cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(--pp->refcount<=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)pp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putv(np,val,flags,fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const Namdisc_t talias_disc = { 0, talias_put, talias_get };
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Namfun_t talias_init = { &talias_disc, 1 };
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * set tracked alias node <np> to value <pp>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid path_alias(register Namval_t *np,register Pathcomp_t *pp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct stat statb;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_offattr(np,NV_NOPRINT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_stack(np,&talias_init);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvalue.cp = (char*)pp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->refcount++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_setattr(np,NV_TAGGED|NV_NOFREE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path_nextcomp(pp,nv_name(np),pp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = stakptr(PATH_OFFSET);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sp && lstat(sp,&statb)>=0 && S_ISLNK(statb.st_mode))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_setsize(np,statb.st_size+1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_setsize(np,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_unset(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin