/* * 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); } }
/* * 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); } } }
/* * 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; } }