Пример #1
0
/*
 * dnewcwd - make a new directory in the loop the current one
 */
static void
dnewcwd(struct directory *dp, int dflag)
{
    int print;

    if (adrof(STRdunique)) {
	struct directory *dn;

	for (dn = dhead.di_prev; dn != &dhead; dn = dn->di_prev) 
	    if (dn != dp && Strcmp(dn->di_name, dp->di_name) == 0) {
		dn->di_next->di_prev = dn->di_prev;
		dn->di_prev->di_next = dn->di_next;
		dfree(dn);
		break;
	    }
    }
    dcwd = dp;
    dset(dcwd->di_name);
    dgetstack();
    print = printd;		/* if printd is set, print dirstack... */
    if (adrof(STRpushdsilent))	/* but pushdsilent overrides printd... */
	print = 0;
    if (dflag & DIR_PRINT)	/* but DIR_PRINT overrides pushdsilent... */
	print = 1;
    if (bequiet)		/* and bequiet overrides everything */
	print = 0;
    if (print)
	printdirs(dflag);
    cwd_cmd();			/* PWP: run the defined cwd command */
}
Пример #2
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);
	}
}
Пример #3
0
	void
SoundBeep(void)
{				/* produce a sound */
	beep_cmd ();
	if (adrof(STRnobeep))
		return;

	if (adrof(STRvisiblebell))
		NT_VisibleBell();	/* visible bell */
	else
		MessageBeep(MB_ICONQUESTION);
}
Пример #4
0
void
/*ARGSUSED*/
unset(Char **v, struct command *t)
{
    unset1(v, &shvhed);
    if (adrof(STRfilec) == 0)
	filec = 0;
    if (adrof(STRhistchars) == 0) {
	HIST = '!';
	HISTSUB = '^';
    }
    if (adrof(STRwordchars) == 0)
	word_chars = STR_WORD_CHARS;
}
Пример #5
0
/* set_color_context():
 */
void
set_color_context()
{
    struct varent *vp = adrof(STRcolor);

    if (!vp) {
	color_context_ls = FALSE;
	color_context_lsmF = FALSE;
    }
    else if (!vp->vec[0] || vp->vec[0][0] == '\0') {
	color_context_ls = TRUE;
	color_context_lsmF = TRUE;
    }
    else {
	size_t i;

	color_context_ls = FALSE;
	color_context_lsmF = FALSE;
	for (i = 0; vp->vec[i]; i++)
	    if (Strcmp(vp->vec[i], STRls) == 0)
		color_context_ls = TRUE;
	    else if (Strcmp(vp->vec[i], STRlsmF) == 0)
		color_context_lsmF = TRUE;
    }
}
Пример #6
0
void
dsetstack(void)
{
    Char **cp;
    struct varent *vp;
    struct directory *dn, *dp;

    if ((vp = adrof(STRdirstack)) == NULL || vp->vec == NULL)
	return;

    /* Free the whole stack */
    while ((dn = dhead.di_prev) != &dhead) {
	dn->di_next->di_prev = dn->di_prev;
	dn->di_prev->di_next = dn->di_next;
	if (dn != dcwd)
	    dfree(dn);
    }

    /* thread the current working directory */
    dhead.di_prev = dhead.di_next = dcwd;
    dcwd->di_next = dcwd->di_prev = &dhead;

    /* put back the stack */
    for (cp = vp->vec; cp && *cp && **cp; cp++) {
	dp = xcalloc(sizeof(struct directory), 1);
	dp->di_name = Strsave(*cp);
	dp->di_count = 0;
	dp->di_prev = dcwd;
	dp->di_next = dcwd->di_next;
	dcwd->di_next = dp;
	dp->di_next->di_prev = dp;
    }
    dgetstack();	/* Make $dirstack reflect the current state */
}
Пример #7
0
static Char *
globtilde(Char *s)
{
    Char *name, *u, *home, *res;

    u = s;
    for (s++; *s && *s != '/' && *s != ':'; s++)
	continue;
    name = Strnsave(u + 1, s - (u + 1));
    cleanup_push(name, xfree);
    home = gethdir(name);
    if (home == NULL) {
	if (adrof(STRnonomatch)) {
	    cleanup_until(name);
	    return u;
	}
	if (*name)
	    stderror(ERR_UNKUSER, short2str(name));
	else
	    stderror(ERR_NOHOME);
    }
    cleanup_until(name);
    if (home[0] == '/' && home[1] == '\0' && s[0] == '/')
	res = Strsave(s);
    else
	res = Strspl(home, s);
    xfree(home);
    xfree(u);
    return res;
}
Пример #8
0
/*
 * dnewcwd - make a new directory in the loop the current one
 */
static void
dnewcwd(struct directory *dp)
{
    dcwd = dp;
    dset(dcwd->di_name);
    if (printd && !(adrof(STRpushdsilent)))
	printdirs();
}
Пример #9
0
void
goodbye(void)
{
    rechist();

    if (loginsh) {
	(void) signal(SIGQUIT, SIG_IGN);
	(void) signal(SIGINT, SIG_IGN);
	(void) signal(SIGTERM, SIG_IGN);
	setintr = 0;		/* No interrupts after "logout" */
	if (!(adrof(STRlogout)))
	    set(STRlogout, STRnormal);
	(void) srcfile(_PATH_DOTLOGOUT, 0, 0);
	if (adrof(STRhome))
	    (void) srccat(value(STRhome), STRsldtlogout);
    }
    exitstat();
}
Пример #10
0
void
xechoit(Char **t)
{
    if (adrof(STRecho)) {
	(void) fflush(csherr);
	blkpr(csherr, t);
	(void) fputc('\n', csherr);
    }
}
Пример #11
0
void
rechist(void)
{
    Char    buf[BUFSIZ], hbuf[BUFSIZ], *hfile;
    int     fd, ftmp, oldidfds;
    struct  varent *shist;

    if (!fast) {
	/*
	 * If $savehist is just set, we use the value of $history
	 * else we use the value in $savehist
	 */
	if ((shist = adrof(STRsavehist)) != NULL) {
	    if (shist->vec[0][0] != '\0')
		(void) Strlcpy(hbuf, shist->vec[0], sizeof hbuf/sizeof(Char));
	    else if ((shist = adrof(STRhistory)) && shist->vec[0][0] != '\0')
		(void) Strlcpy(hbuf, shist->vec[0], sizeof hbuf/sizeof(Char));
	    else
		return;
	}
	else
	    return;

	if ((hfile = value(STRhistfile)) == STRNULL) {
	    Strlcpy(buf, value(STRhome), sizeof buf/sizeof(Char));
	    hfile = buf;
	    (void) Strlcat(buf, STRsldthist, sizeof buf/sizeof(Char));
	}

	if ((fd = open(short2str(hfile), O_WRONLY | O_CREAT | O_TRUNC,
	    0600)) == -1)
	    return;

	oldidfds = didfds;
	didfds = 0;
	ftmp = SHOUT;
	SHOUT = fd;
	dumphist[2] = hbuf;
	dohist(dumphist, NULL);
	SHOUT = ftmp;
	(void) close(fd);
	didfds = oldidfds;
    }
}
Пример #12
0
/*
 * dfollow - change to arg directory; fall back on cdpath if not valid
 */
static Char *
dfollow(Char *cp)
{
    Char *dp;
    struct varent *c;
    char    ebuf[PATH_MAX];
    int serrno;

    cp = globone(cp, G_ERROR);
    /*
     * if we are ignoring symlinks, try to fix relatives now.
     */
    dp = dnormalize(cp);
    if (chdir(short2str(dp)) >= 0) {
	free(cp);
	return dgoto(dp);
    }
    else {
	free(dp);
	if (chdir(short2str(cp)) >= 0)
	    return dgoto(cp);
	serrno = errno;
    }

    if (cp[0] != '/' && !prefix(STRdotsl, cp) && !prefix(STRdotdotsl, cp)
	&& (c = adrof(STRcdpath))) {
	Char  **cdp;
	Char *p;
	Char    buf[PATH_MAX];

	for (cdp = c->vec; *cdp; cdp++) {
	    for (dp = buf, p = *cdp; (*dp++ = *p++) != '\0';)
		continue;
	    dp[-1] = '/';
	    for (p = cp; (*dp++ = *p++) != '\0';)
		continue;
	    if (chdir(short2str(buf)) >= 0) {
		printd = 1;
		free(cp);
		cp = Strsave(buf);
		return dgoto(cp);
	    }
	}
    }
    dp = value(cp);
    if ((dp[0] == '/' || dp[0] == '.') && chdir(short2str(dp)) >= 0) {
	free(cp);
	cp = Strsave(dp);
	printd = 1;
	return dgoto(cp);
    }
    (void) strlcpy(ebuf, short2str(cp), sizeof ebuf);
    free(cp);
    stderror(ERR_SYSTEM, ebuf, strerror(serrno));
    return (NULL);
}
Пример #13
0
void
autoset_kanji(void)
{
    char *codeset = nl_langinfo(CODESET);
    
    if (*codeset == '\0') {
	if (adrof(STRnokanji) == NULL)
	    setNS(STRnokanji);
	return;
    }

    if (strcasestr(codeset, "SHIFT_JIS") == (char*)0) {
	if (adrof(STRnokanji) == NULL)
	    setNS(STRnokanji);
	return;
    }

    if (adrof(STRnokanji) != NULL)
	unsetv(STRnokanji);
}
Пример #14
0
static struct varent *
getvx(Char *vp, int subscr)
{
    struct varent *v = adrof(vp);

    if (v == 0)
	udvar(vp);
    if (subscr < 1 || subscr > blklen(v->vec))
	stderror(ERR_NAME | ERR_RANGE);
    return (v);
}
Пример #15
0
Char   *
globone(Char *str, int action)
{
    Char   *v[2], **vl, **vo;
    int gflg, noglob;

    noglob = adrof(STRnoglob) != 0;
    v[0] = str;
    v[1] = 0;
    gflg = tglob(v);
    if (gflg == G_NONE)
	return (strip(Strsave(str)));

    if (gflg & G_CSH) {
	/*
	 * Expand back-quote, tilde and brace
	 */
	vo = globexpand(v, noglob);
	if (noglob || (gflg & G_GLOB) == 0) {
	    vl = vo;
	    goto result;
	}
	cleanup_push(vo, blk_cleanup);
    }
    else if (noglob || (gflg & G_GLOB) == 0)
	return (strip(Strsave(str)));
    else
	vo = v;

    vl = libglob(vo);
    if (gflg & G_CSH) {
    	if (vl != vo)
	    cleanup_until(vo);
	else
	    cleanup_ignore(vo);
    }
    if (vl == NULL) {
	setname(short2str(str));
	stderror(ERR_NAME | ERR_NOMATCH);
    }
 result:
    if (vl && vl[0] == NULL) {
	xfree(vl);
	return (Strsave(STRNULL));
    }
    if (vl && vl[1]) 
	return (handleone(str, vl, action));
    else {
	str = strip(*vl);
	xfree(vl);
	return (str);
    }
}
Пример #16
0
void
setalarm(int lck)
{
    struct varent *vp;
    Char   *cp;
    unsigned alrm_time = 0, logout_time, lock_time;
    time_t cl, nl, sched_dif;

    if ((vp = adrof(STRautologout)) != NULL && vp->vec != NULL) {
	if ((cp = vp->vec[0]) != 0) {
	    if ((logout_time = (unsigned) atoi(short2str(cp)) * 60) > 0) {
#ifdef SOLARIS2
		/*
		 * Solaris alarm(2) uses a timer based in clock ticks
		 * internally so it multiplies our value with CLK_TCK...
		 * Of course that can overflow leading to unexpected
		 * results, so we clip it here. Grr. Where is that
		 * documented folks?
		 */
		if (logout_time >= 0x7fffffff / CLK_TCK)
			logout_time = 0x7fffffff / CLK_TCK;
#endif /* SOLARIS2 */
		alrm_time = logout_time;
		alm_fun = auto_logout;
	    }
	}
	if ((cp = vp->vec[1]) != 0) {
	    if ((lock_time = (unsigned) atoi(short2str(cp)) * 60) > 0) {
		if (lck) {
		    if (alrm_time == 0 || lock_time < alrm_time) {
			alrm_time = lock_time;
			alm_fun = auto_lock;
		    }
		}
		else /* lock_time always < alrm_time */
		    if (alrm_time)
			alrm_time -= lock_time;
	    }
	}
    }
    if ((nl = sched_next()) != -1) {
	(void) time(&cl);
	sched_dif = nl > cl ? nl - cl : 0;
	if ((alrm_time == 0) || ((unsigned) sched_dif < alrm_time)) {
	    alrm_time = ((unsigned) sched_dif) + 1;
	    alm_fun = sched_run;
	}
    }
    alrmcatch_disabled = 0;
    (void) alarm(alrm_time);	/* Autologout ON */
}
Пример #17
0
struct varent *
getvx(tchar *vp, int subscr)
{
	struct varent *v = adrof(vp);

#ifdef TRACE
	tprintf("TRACE- getvx()\n");
#endif
	if (v == 0)
		udvar(vp);
	if (subscr < 1 || subscr > blklen(v->vec))
		bferr("Subscript out of range");
	return (v);
}
Пример #18
0
void
xechoit(Char **t)
{
    if (adrof(STRecho)) {
	int odidfds = didfds;
	(void)fflush(csherr);
	odidfds = didfds;
	didfds = 0;
	blkpr(csherr, t);
	(void)fputc('\n', csherr);
	(void)fflush(csherr);
	didfds = odidfds;
    }
}
Пример #19
0
void
xechoit(tchar **t)
{
#ifdef TRACE
	tprintf("TRACE- xechoit()\n");
#endif

	if (adrof(S_echo /* "echo" */)) {
		flush();
		haderr = 1;
		blkpr(t), Putchar('\n');
		haderr = 0;
	}
}
Пример #20
0
void
prusage(FILE *fp, struct rusage *r0, struct rusage *r1, struct timespec *e,
        struct timespec *b)
{
    struct varent *vp;
    const char *cp;

    vp = adrof(STRtime);

    if (vp && vp->vec[0] && vp->vec[1])
	cp = short2str(vp->vec[1]);
    else
	cp = "%Uu %Ss %E %P %X+%Dk %I+%Oio %Fpf+%Ww";
    prusage1(fp, cp, r0, r1, e, b);
}
Пример #21
0
static int
iscommand(Char *name)
{
    struct varent *v;
    Char **pv, *sav;
    int hashval, hashval1, i;
    int slash;

    hashval = 0;
    slash = any(short2str(name), '/');
    v = adrof(STRpath);
    
    if (v == 0 || v->vec[0] == 0 || slash)
	pv = justabs;
    else
	pv = v->vec;
    sav = Strspl(STRslash, name);	/* / command name for postpending */
    if (havhash)
	hashval = hashname(name);
    i = 0;
    do {
	if (!slash && pv[0][0] == '/' && havhash) {
	    hashval1 = hash(hashval, i);
	    if (!bit(xhash, hashval1))
		goto cont;
	}
	if (pv[0][0] == 0 || eq(pv[0], STRdot)) {	/* don't make ./xxx */
	    if (executable(NULL, name, 0)) {
		free(sav);
		return i + 1;
	    }
	}
	else {
	    if (executable(*pv, sav, 0)) {
		free(sav);
		return i + 1;
	    }
	}
cont:
	pv++;
	i++;
    } while (*pv);
    free(sav);
    return 0;
}
Пример #22
0
void
/*ARGSUSED*/
shift(Char **v, struct command *t)
{
    struct varent *argv;
    Char *name;

    v++;
    name = *v;
    if (name == 0)
	name = STRargv;
    else
	(void) strip(name);
    argv = adrof(name);
    if (argv == 0)
	udvar(name);
    if (argv->vec[0] == 0)
	stderror(ERR_NAME | ERR_NOMORE);
    lshift(argv->vec, 1);
}
Пример #23
0
static void
dgetstack(void)
{
    int i = 0;
    Char **dblk, **dbp;
    struct directory *dn;

    if (adrof(STRdirstack) == NULL) 
    	return;

    for (dn = dhead.di_prev; dn != &dhead; dn = dn->di_prev, i++)
	continue;
    dbp = dblk = xmalloc((i + 1) * sizeof(Char *));
    for (dn = dhead.di_prev; dn != &dhead; dn = dn->di_prev, dbp++)
	 *dbp = Strsave(dn->di_name);
    *dbp = NULL;
    cleanup_push(dblk, blk_cleanup);
    setq(STRdirstack, dblk, &shvhed, VAR_READWRITE);
    cleanup_ignore(dblk);
    cleanup_until(dblk);
}
Пример #24
0
/*ARGSUSED*/
void
shift(Char **v, struct command *c)
{
    struct varent *argv;
    Char *name;

    USE(c);
    v++;
    name = *v;
    if (name == 0)
	name = STRargv;
    else
	(void) strip(name);
    argv = adrof(name);
    if (argv == NULL || argv->vec == NULL)
	udvar(name);
    if (argv->vec[0] == 0)
	stderror(ERR_NAME | ERR_NOMORE);
    lshift(argv->vec, 1);
    update_vars(name);
}
Пример #25
0
/*
 * Expand and glob the words after an i/o redirection.
 * If more than one word is generated, then update the command vector.
 *
 * This is done differently in all the shells:
 * 1. in the bourne shell and ksh globbing is not performed
 * 2. Bash/csh say ambiguous
 * 3. zsh does i/o to/from all the files
 * 4. itcsh concatenates the words.
 *
 * I don't know what is best to do. I think that Ambiguous is better
 * than restructuring the command vector, because the user can get
 * unexpected results. In any case, the command vector restructuring 
 * code is present and the user can choose it by setting noambiguous
 */
static Char *
splicepipe(struct command *t, Char *cp)
{
    Char *blk[2];

    if (adrof(STRnoambiguous)) {
	Char **pv;
	int gflag;

	blk[0] = Dfix1(cp); /* expand $ */
	blk[1] = NULL;

	gflag = tglob(blk);
	if (gflag) {
	    pv = globall(blk, gflag);
	    if (pv == NULL) {
		setname(short2str(blk[0]));
		xfree(blk[0]);
		stderror(ERR_NAME | ERR_NOMATCH);
	    }
	    if (pv[1] != NULL) { /* we need to fix the command vector */
		Char **av = blkspl(t->t_dcom, &pv[1]);
		xfree(t->t_dcom);
		t->t_dcom = av;
	    }
	    xfree(blk[0]);
	    blk[0] = pv[0];
	    xfree(pv);
	}
    }
    else {
	Char *buf;

	buf = Dfix1(cp);
	cleanup_push(buf, xfree);
	blk[0] = globone(buf, G_ERROR);
	cleanup_until(buf);
    }
    return(blk[0]);
}
Пример #26
0
void
/*ARGSUSED*/
dohash(Char **v, struct command *t)
{
    struct dirent *dp;
    struct varent *pathv;
    DIR *dirp;
    Char **pv;
    size_t cnt;
    int hashval, i;

    i = 0;
    havhash = 1;
    pathv = adrof(STRpath);

    for (cnt = 0; cnt < sizeof xhash; cnt++)
	xhash[cnt] = 0;
    if (pathv == 0)
	return;
    for (pv = pathv->vec; *pv; pv++, i++) {
	if (pv[0][0] != '/')
	    continue;
	dirp = opendir(short2str(*pv));
	if (dirp == NULL)
	    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(str2short(dp->d_name)), i);
	    bis(xhash, hashval);
	    /* tw_add_comm_name (dp->d_name); */
	}
	(void) closedir(dirp);
    }
}
Пример #27
0
/*
 * Expand and glob the words after an i/o redirection.
 * If more than one word is generated, then update the command vector.
 *
 * This is done differently in all the shells:
 * 1. in the bourne shell and ksh globbing is not performed
 * 2. Bash/csh say ambiguous
 * 3. zsh does i/o to/from all the files
 * 4. itcsh concatenates the words.
 *
 * I don't know what is best to do. I think that Ambiguous is better
 * than restructuring the command vector, because the user can get
 * unexpected results. In any case, the command vector restructuring 
 * code is present and the user can choose it by setting noambiguous
 */
static Char *
splicepipe(struct command *t, Char *cp /* word after < or > */)
{
    Char *blk[2];

    if (adrof(STRnoambiguous)) {
	Char **pv;

	blk[0] = Dfix1(cp); /* expand $ */
	blk[1] = NULL;

	gflag = 0, tglob(blk);
	if (gflag) {
	    pv = globall(blk);
	    if (pv == NULL) {
		setname(vis_str(blk[0]));
		xfree((ptr_t) blk[0]);
		stderror(ERR_NAME | ERR_NOMATCH);
		/* NOTREACHED */
	    }
	    gargv = NULL;
	    if (pv[1] != NULL) { /* we need to fix the command vector */
		Char **av = blkspl(t->t_dcom, &pv[1]);
		xfree((ptr_t) t->t_dcom);
		t->t_dcom = av;
	    }
	    xfree((ptr_t) blk[0]);
	    blk[0] = pv[0];
	    xfree((ptr_t) pv);
	}
    }
    else {
	blk[0] = globone(blk[1] = Dfix1(cp), G_ERROR);
	xfree((ptr_t) blk[1]);
    }
    return(blk[0]);
}
Пример #28
0
static int
tellmewhat(struct wordent *lexp, Char *str)
{
    struct biltins *bptr;
    struct wordent *sp;
    Char *cmd, *s0, *s1, *s2;
    int i;
    int aliased, found;
    Char qc;

    aliased = 0;
    sp = lexp->next;

    if (adrof1(sp->word, &aliases)) {
	alias(lexp);
	sp = lexp->next;
	aliased = 1;
    }

    s0 = sp->word;		/* to get the memory freeing right... */

    /* handle quoted alias hack */
    if ((*(sp->word) & (QUOTE | TRIM)) == QUOTE)
	(sp->word)++;

    /* do quoting, if it hasn't been done */
    s1 = s2 = sp->word;
    while (*s2)
	switch (*s2) {
	case '\'':
	case '"':
	    qc = *s2++;
	    while (*s2 && *s2 != qc)
		*s1++ = (Char)(*s2++ | QUOTE);
	    if (*s2)
		s2++;
	    break;
	case '\\':
	    if (*++s2)
		*s1++ = (Char)(*s2++ | QUOTE);
	    break;
	default:
	    *s1++ = *s2++;
	}
    *s1 = '\0';

    for (bptr = bfunc; bptr < &bfunc[nbfunc]; bptr++) {
	if (eq(sp->word, str2short(bptr->bname))) {
	    if (str == NULL) {
		if (aliased)
		    prlex(cshout, lexp);
		(void)fprintf(cshout, "%s: shell built-in command.\n", 
			       vis_str(sp->word));
	    }
	    else
		(void)Strcpy(str, sp->word);
	    sp->word = s0;	/* we save and then restore this */
	    return 1;
	}
    }

    sp->word = cmd = globone(sp->word, G_IGNORE);

    if ((i = iscommand(sp->word)) != 0) {
	Char **pv;
	struct varent *v;
	int    slash = any(short2str(sp->word), '/');

	v = adrof(STRpath);
	if (v == 0 || v->vec[0] == 0 || slash)
	    pv = justabs;
	else
	    pv = v->vec;

	while (--i)
	    pv++;
	if (pv[0][0] == 0 || eq(pv[0], STRdot)) {
	    if (!slash) {
		sp->word = Strspl(STRdotsl, sp->word);
		prlex(cshout, lexp);
		free(sp->word);
	    }
	    else
		prlex(cshout, lexp);
	}
	else {
	    s1 = Strspl(*pv, STRslash);
	    sp->word = Strspl(s1, sp->word);
	    free(s1);
	    if (str == NULL)
		prlex(cshout, lexp);
	    else
		(void)Strcpy(str, sp->word);
	    free(sp->word);
	}
	found = 1;
    }
    else {
 	if (str == NULL) {
	    if (aliased)
		prlex(cshout, lexp);
	    (void)fprintf(csherr,
			   "%s: Command not found.\n", vis_str(sp->word));
	}
	else
	    (void)Strcpy(str, sp->word);
	found = 0;
    }
    sp->word = s0;		/* we save and then restore this */
    free(cmd);
    return found;
}
Пример #29
0
/*
 * Execute command f, arg list t.
 * Record error message if not found.
 * Also do shell scripts here.
 */
static void
texec(Char *sf, Char **st)
{
    struct varent *v;
    Char *lastsh[2], **vp, *st0, **ost;
    char *f, **t;
    int fd;
    unsigned char c = '\0';

    /* The order for the conversions is significant */
    t = short2blk(st);
    f = short2str(sf);
    Vt = t;
    errno = 0;			/* don't use a previous error */
    (void)execve(f, t, environ);
    Vt = 0;
    blkfree((Char **)t);
    switch (errno) {

    case ENOEXEC:
	/*
	 * From: [email protected] (Casper H.S. Dik) If we could not execute
	 * it, don't feed it to the shell if it looks like a binary!
	 */
	if ((fd = open(f, O_RDONLY)) != -1) {
	    if (read(fd, (char *)&c, 1) == 1) {
		if (!Isprint(c) && (c != '\n' && c != '\t')) {
		    (void)close(fd);
		    /*
		     * We *know* what ENOEXEC means.
		     */
		    stderror(ERR_ARCH, f, strerror(errno));
		}
	    }
#ifdef _PATH_BSHELL
	    else
		c = '#';
#endif
	    (void)close(fd);
	}
	/*
	 * 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(STRshell, &aliases);
	if (v == 0) {
	    vp = lastsh;
	    vp[0] = adrof(STRshell) ? value(STRshell) : STR_SHELLPATH;
	    vp[1] = NULL;
#ifdef _PATH_BSHELL
	    if (fd != -1 && c != '#')
		vp[0] = STR_BSHELL;
#endif
	}
	else
	    vp = v->vec;
	st0 = st[0];
	st[0] = sf;
	ost = st;
	st = blkspl(vp, st);	/* Splice up the new arglst */
	ost[0] = st0;
	sf = *st;
	/* The order for the conversions is significant */
	t = short2blk(st);
	f = short2str(sf);
	free(st);
	Vt = t;
	(void)execve(f, t, environ);
	Vt = 0;
	blkfree((Char **)t);
	/* FALLTHROUGH */

    case ENOMEM:
	stderror(ERR_SYSTEM, f, strerror(errno));
	/* NOTREACHED */

    case ENOENT:
	break;

    default:
	if (exerr == 0) {
	    exerr = strerror(errno);
	    if (expath)
		free(expath);
	    expath = Strsave(sf);
	    Vexpath = expath;
	}
    }
}
Пример #30
0
void
/*ARGSUSED*/
doexec(Char **v, struct command *t)
{
    struct varent *pathv;
    Char *blk[2], **av, *dp, **pv, *sav;
    int i, hashval, hashval1;
    sigset_t nsigset;
    int slash;

    hashval = 0;
    /*
     * Glob the command name. We will search $path even if this does something,
     * as in sh but not in csh.  One special case: if there is no PATH, then we
     * execute only commands which start with '/'.
     */
    blk[0] = t->t_dcom[0];
    blk[1] = 0;
    gflag = 0, tglob(blk);
    if (gflag) {
	pv = globall(blk);
	if (pv == 0) {
	    setname(vis_str(blk[0]));
	    stderror(ERR_NAME | ERR_NOMATCH);
	}
	gargv = 0;
    }
    else
	pv = saveblk(blk);

    trim(pv);

    exerr = 0;
    expath = Strsave(pv[0]);
    Vexpath = expath;

    pathv = adrof(STRpath);
    if (pathv == 0 && expath[0] != '/') {
	blkfree(pv);
	pexerr();
    }
    slash = any(short2str(expath), '/');

    /*
     * Glob the argument list, if necessary. Otherwise trim off the quote bits.
     */
    gflag = 0;
    av = &t->t_dcom[1];
    tglob(av);
    if (gflag) {
	av = globall(av);
	if (av == 0) {
	    blkfree(pv);
	    setname(vis_str(expath));
	    stderror(ERR_NAME | ERR_NOMATCH);
	}
	gargv = 0;
    }
    else
	av = saveblk(av);

    blkfree(t->t_dcom);
    t->t_dcom = blkspl(pv, av);
    free(pv);
    free(av);
    av = t->t_dcom;
    trim(av);

    if (*av == NULL || **av == '\0')
	pexerr();

    xechoit(av);		/* Echo command if -x */
    /*
     * Since all internal file descriptors are set to close on exec, we don't
     * need to close them explicitly here.  Just reorient ourselves for error
     * messages.
     */
    SHIN = 0;
    SHOUT = 1;
    SHERR = 2;
    OLDSTD = 0;
    /*
     * We must do this AFTER any possible forking (like `foo` in glob) so that
     * this shell can still do subprocesses.
     */
    sigemptyset(&nsigset);
    (void)sigprocmask(SIG_SETMASK, &nsigset, NULL);
    /*
     * If no path, no words in path, or a / in the filename then restrict the
     * command search.
     */
    if (pathv == 0 || pathv->vec[0] == 0 || slash)
	pv = justabs;
    else
	pv = pathv->vec;
    sav = Strspl(STRslash, *av); 	/* / command name for postpending */
    Vsav = sav;
    if (havhash)
	hashval = hashname(*av);
    i = 0;
    hits++;
    do {
	/*
	 * Try to save time by looking at the hash table for where this command
	 * could be.  If we are doing delayed hashing, then we put the names in
	 * one at a time, as the user enters them.  This is kinda like Korn
	 * Shell's "tracked aliases".
	 */
	if (!slash && pv[0][0] == '/' && havhash) {
	    hashval1 = hash(hashval, i);
	    if (!bit(xhash, hashval1))
		goto cont;
	}
	if (pv[0][0] == 0 || eq(pv[0], STRdot))	/* don't make ./xxx */
	    texec(*av, av);
	else {
	    dp = Strspl(*pv, sav);
	    Vdp = dp;
	    texec(dp, av);
	    Vdp = 0;
	    free(dp);
	}
	misses++;
cont:
	pv++;
	i++;
    } while (*pv);
    hits--;
    Vsav = 0;
    free(sav);
    pexerr();
    /* NOTREACHED */
}