示例#1
0
/*
 * Fill up caching arrays for path and cdpath
 */
void
dohash(char cachearray[])
{
	struct stat stb;
	DIR *dirp;
	struct dirent *dp;
	int cnt;
	int i = 0;
	struct varent *v;
	tchar **pv;
	int hashval;
	tchar curdir_[MAXNAMLEN+1];

#ifdef TRACE
	tprintf("TRACE- dohash()\n");
#endif
	/* Caching $path */
	if (cachearray == xhash) {
		havhash = 1;
		v = adrof(S_path /* "path" */);
	} else {    /* Caching $cdpath */
		havhash2 = 1;
		v = adrof(S_cdpath /* "cdpath" */);
	}

	for (cnt = 0; cnt < (HSHSIZ / 8); cnt++)
		cachearray[cnt] = 0;
	if (v == 0)
		{
		return;
		}
	for (pv = v->vec; *pv; pv++, i++) {
		if (pv[0][0] != '/')
			continue;
		dirp = opendir_(*pv);
		if (dirp == NULL)
			continue;
		if (fstat(dirp->dd_fd, &stb) < 0 || !isdir(stb)) {
			unsetfd(dirp->dd_fd);
			closedir_(dirp);
			continue;
		}
		while ((dp = readdir(dirp)) != NULL) {
			if (dp->d_ino == 0)
				continue;
			if (dp->d_name[0] == '.' &&
			    (dp->d_name[1] == '\0' ||
			    dp->d_name[1] == '.' && dp->d_name[2] == '\0'))
				continue;
			hashval = hash(hashname(strtots(curdir_, dp->d_name)), i);
			bis(cachearray, hashval);
		}
		unsetfd(dirp->dd_fd);
		closedir_(dirp);
	}
}
示例#2
0
/*
 * Execute command f, arg list t.
 * Record error message if not found.
 * Also do shell scripts here.
 */
void
texec(struct command *cmd, tchar *f, tchar **t)
{
	int	pfstatus = 0;
	struct	varent *v;
	tchar	**vp;
	tchar		*lastsh[2];

#ifdef TRACE
	tprintf("TRACE- texec()\n");
#endif
	/* convert cfname and cargs from tchar to char */
	tconvert(cmd, f, t);

	if (pfcshflag == 1) {
		pfstatus = secpolicy_pfexec((const char *)(cmd->cfname),
		    cmd->cargs, (const char **)NULL);
		if (pfstatus != NOATTRS) {
			errno = pfstatus;
		}
	}
	if ((pfcshflag == 0) || (pfstatus == NOATTRS)) {
		execv(cmd->cfname, cmd->cargs);
	}

	/*
	 * exec returned, free up allocations from above
	 * tconvert(), zero cfname and cargs to prevent
	 * duplicate free() in freesyn()
	 */
	xfree(cmd->cfname);
	chr_blkfree(cmd->cargs);
	cmd->cfname = (char *)0;
	cmd->cargs = (char **)0;

	switch (errno) {
	case ENOEXEC:
		/* check that this is not a binary file */
		{
			int ff = open_(f, 0);
			tchar ch[MB_LEN_MAX];

			if (ff != -1 && read_(ff, ch, 1) == 1 &&
			    !isprint(ch[0]) && !isspace(ch[0])) {
				printf("Cannot execute binary file.\n");
				Perror(f);
				(void) close(ff);
				unsetfd(ff);
				return;
			}
			(void) close(ff);
			unsetfd(ff);
		}
		/*
		 * If there is an alias for shell, then
		 * put the words of the alias in front of the
		 * argument list replacing the command name.
		 * Note no interpretation of the words at this point.
		 */
		v = adrof1(S_shell /* "shell" */, &aliases);
		if (v == 0) {
#ifdef OTHERSH
			int ff = open_(f, 0);
			tchar ch[MB_LEN_MAX];
#endif

			vp = lastsh;
			vp[0] = adrof(S_shell /* "shell" */) ? value(S_shell /* "shell" */) : S_SHELLPATH /* SHELLPATH */;
			vp[1] =  (tchar *) NULL;
#ifdef OTHERSH
			if (ff != -1 && read_(ff, ch, 1) == 1 && ch[0] != '#')
				vp[0] = S_OTHERSH /* OTHERSH */;
			(void) close(ff);
			unsetfd(ff);
#endif
		} else
			vp = v->vec;
		t[0] = f;
		t = blkspl(vp, t);		/* Splice up the new arglst */
		f = *t;

		tconvert(cmd, f, t);		/* convert tchar to char */

		/*
		 * now done with tchar arg list t,
		 * free the space calloc'd by above blkspl()
		 */
		xfree((char *)t);

		execv(cmd->cfname, cmd->cargs);	/* exec the command */

		/* exec returned, same free'ing as above */
		xfree(cmd->cfname);
		chr_blkfree(cmd->cargs);
		cmd->cfname = (char *)0;
		cmd->cargs = (char **)0;

		/* The sky is falling, the sky is falling! */

	case ENOMEM:
		Perror(f);

	case ENOENT:
		break;

	default:
		if (exerr == 0) {
			exerr = strerror(errno);
			setname(f);
		}
	}
}
示例#3
0
/*
 * Form a shell temporary file (in unit 0) from the words
 * of the shell input up to a line the same as "term".
 * Unit 0 should have been closed before this call.
 */
void
heredoc(tchar *term)
{
	int c;
	tchar *Dv[2];
	tchar obuf[BUFSIZ], lbuf[BUFSIZ], mbuf[BUFSIZ];
	int ocnt, lcnt, mcnt;
	tchar *lbp, *obp, *mbp;
	tchar **vp;
	bool quoted;
	tchar shtemp[] = {'/', 't', 'm', 'p', '/', 's', 'h', 'X', 'X', 'X',
'X', 'X', 'X', 0};
	int fd1;

#ifdef TRACE
	tprintf("TRACE- heredoc()\n");
#endif
	if ((fd1 = mkstemp_(shtemp)) < 0)
		Perror(shtemp);
	(void) unlink_(shtemp);			/* 0 0 inode! */
	unsetfd(fd1);
	Dv[0] = term; Dv[1] = NOSTR; gflag = 0;
	trim(Dv); rscan(Dv, Dtestq); quoted = gflag;
	ocnt = BUFSIZ; obp = obuf;
	for (;;) {
		/*
		 * Read up a line
		 */
		lbp = lbuf; lcnt = BUFSIZ - 4;
		for (;;) {
			c = readc(1);		/* 1 -> Want EOF returns */
			if (c < 0) {
				setname(term);
				bferr("<< terminator not found");
			}
			if (c == '\n')
				break;
			if (c &= TRIM) {
				*lbp++ = c;
				if (--lcnt < 0) {
					setname(S_LESLES /* "<<" */);
					error("Line overflow");
				}
			}
		}
		*lbp = 0;

		/*
		 * Compare to terminator -- before expansion
		 */
		if (eq(lbuf, term)) {
			(void) write_(0, obuf, BUFSIZ - ocnt);
			(void) lseek(0, (off_t)0, 0);
			return;
		}

		/*
		 * If term was quoted or -n just pass it on
		 */
		if (quoted || noexec) {
			*lbp++ = '\n'; *lbp = 0;
			for (lbp = lbuf; c = *lbp++; ) {
				*obp++ = c;
				if (--ocnt == 0) {
					(void) write_(0, obuf, BUFSIZ);
					obp = obuf; ocnt = BUFSIZ;
				}
			}
			continue;
		}

		/*
		 * Term wasn't quoted so variable and then command
		 * expand the input line
		 */
		Dcp = lbuf; Dvp = Dv + 1; mbp = mbuf; mcnt = BUFSIZ - 4;
		for (;;) {
			c = DgetC(DODOL);
			if (c == DEOF)
				break;
			if ((c &= TRIM) == 0)
				continue;
			/* \ quotes \ $ ` here */
			if (c == '\\') {
				c = DgetC(0);
/*				if (!any(c, "$\\`")) */
				if ((c != '$') && (c != '\\') && (c != '`'))
					unDgetC(c | QUOTE), c = '\\';
				else
					c |= QUOTE;
			}
			*mbp++ = c;
			if (--mcnt == 0) {
				setname(S_LESLES /* "<<" */);
				bferr("Line overflow");
			}
		}
		*mbp++ = 0;

		/*
		 * If any ` in line do command substitution
		 */
		mbp = mbuf;
		if (any('`', mbp)) {
			/*
			 * 1 arg to dobackp causes substitution to be literal.
			 * Words are broken only at newlines so that all blanks
			 * and tabs are preserved.  Blank lines (null words)
			 * are not discarded.
			 */
			vp = dobackp(mbuf, 1);
		} else
			/* Setup trivial vector similar to return of dobackp */
			Dv[0] = mbp, Dv[1] = NOSTR, vp = Dv;

		/*
		 * Resurrect the words from the command substitution
		 * each separated by a newline.  Note that the last
		 * newline of a command substitution will have been
		 * discarded, but we put a newline after the last word
		 * because this represents the newline after the last
		 * input line!
		 */
		for (; *vp; vp++) {
			for (mbp = *vp; *mbp; mbp++) {
				*obp++ = *mbp & TRIM;
				if (--ocnt == 0) {
					(void) write_(0, obuf, BUFSIZ);
					obp = obuf; ocnt = BUFSIZ;
				}
			}
			*obp++ = '\n';
			if (--ocnt == 0) {
				(void) write_(0, obuf, BUFSIZ);
				obp = obuf; ocnt = BUFSIZ;
			}
		}
		if (pargv)
			blkfree(pargv), pargv = 0;
	}
}