Exemplo n.º 1
0
Arquivo: set.c Projeto: Open343/bitrig
static void
asx(Char *vp, int subscr, Char *p)
{
    struct varent *v = getvx(vp, subscr);

    free(v->vec[subscr - 1]);
    v->vec[subscr - 1] = globone(p, G_APPEND);
}
Exemplo n.º 2
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);
}
Exemplo n.º 3
0
void
asx(tchar *vp, int subscr, tchar *p)
{
	struct varent *v = getvx(vp, subscr);

#ifdef TRACE
	tprintf("TRACE- asx()\n");
#endif
	xfree(v->vec[subscr - 1]);
	v->vec[subscr - 1] = globone(p);
}
Exemplo n.º 4
0
static void
asx(Char *vp, int subscr, Char *p)
{
    struct varent *v = getvx(vp, subscr);
    Char *prev;

    if (v->v_flags & VAR_READONLY)
	stderror(ERR_READONLY|ERR_NAME, v->v_name);
    prev = v->vec[subscr - 1];
    cleanup_push(prev, xfree);
    v->vec[subscr - 1] = globone(p, G_APPEND);
    cleanup_until(prev);
}
Exemplo n.º 5
0
Arquivo: sh.sem.c Projeto: lukem/tcsh
/*
 * 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]);
}
Exemplo n.º 6
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]);
}
Exemplo n.º 7
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;
}
Exemplo n.º 8
0
/* tw_result():
 *	Return what the completion action should be depending on the
 *	string
 */
static int
tw_result(const Char *act, Char **pat)
{
    int looking;
    static Char* res = NULL;
    Char *p;

    if (res != NULL)
	xfree(res), res = NULL;

    switch (act[0] & ~QUOTE) {
    case 'X':
	looking = TW_COMPLETION;
	break;
    case 'S':
	looking = TW_SIGNAL;
	break;
    case 'a':
	looking = TW_ALIAS;
	break;
    case 'b':
	looking = TW_BINDING;
	break;
    case 'c':
	looking = TW_COMMAND;
	break;
    case 'C':
	looking = TW_PATH | TW_COMMAND;
	break;
    case 'd':
	looking = TW_DIRECTORY;
	break;
    case 'D':
	looking = TW_PATH | TW_DIRECTORY;
	break;
    case 'e':
	looking = TW_ENVVAR;
	break;
    case 'f':
	looking = TW_FILE;
	break;
#ifdef COMPAT
    case 'p':
#endif /* COMPAT */
    case 'F':
	looking = TW_PATH | TW_FILE;
	break;
    case 'g':
	looking = TW_GRPNAME;
	break;
    case 'j':
	looking = TW_JOB;
	break;
    case 'l':
	looking = TW_LIMIT;
	break;
    case 'n':
	looking = TW_NONE;
	break;
    case 's':
	looking = TW_SHELLVAR;
	break;
    case 't':
	looking = TW_TEXT;
	break;
    case 'T':
	looking = TW_PATH | TW_TEXT;
	break;
    case 'v':
	looking = TW_VARIABLE;
	break;
    case 'u':
	looking = TW_USER;
	break;
    case 'x':
	looking = TW_EXPLAIN;
	break;

    case '$':
	*pat = res = Strsave(&act[1]);
	(void) strip(res);
	return(TW_VARLIST);

    case '(':
	*pat = res = Strsave(&act[1]);
	if ((p = Strchr(res, ')')) != NULL)
	    *p = '\0';
	(void) strip(res);
	return TW_WORDLIST;

    case '`':
	res = Strsave(act);
	if ((p = Strchr(&res[1], '`')) != NULL)
	    *++p = '\0';
	
	if (didfds == 0) {
	    /*
	     * Make sure that we have some file descriptors to
	     * play with, so that the processes have at least 0, 1, 2
	     * open
	     */
	    (void) dcopy(SHIN, 0);
	    (void) dcopy(SHOUT, 1);
	    (void) dcopy(SHDIAG, 2);
	}
	if ((p = globone(res, G_APPEND)) != NULL) {
	    xfree(res), res = NULL;
	    *pat = res = Strsave(p);
	    xfree(p);
	    return TW_WORDLIST;
	}
	return TW_ZERO;

    default:
	stderror(ERR_COMPCOM, short2str(act));
	return TW_ZERO;
    }

    switch (act[1] & ~QUOTE) {
    case '\0':
	return looking;

    case ':':
	*pat = res = Strsave(&act[2]);
	(void) strip(res);
	return looking;

    default:
	stderror(ERR_COMPCOM, short2str(act));
	return TW_ZERO;
    }
} /* end tw_result */
Exemplo n.º 9
0
void
doexec(struct command *t)
{
	tchar *sav;
	tchar *dp, **pv, **av;
	struct varent *v;
	bool slash;
	int hashval, hashval1, i;
	tchar *blk[2];
#ifdef TRACE
	tprintf("TRACE- doexec()\n");
#endif

	/*
	 * Glob the command name.  If this does anything, then we
	 * will execute the command only relative to ".".  One special
	 * case: if there is no PATH, then we execute only commands
	 * which start with '/'.
	 */
	dp = globone(t->t_dcom[0]);
	sav = t->t_dcom[0];
	exerr = 0; t->t_dcom[0] = dp;
	setname(dp);
	xfree(sav);
	v = adrof(S_path /* "path" */);
	if (v == 0 && dp[0] != '/') {
		pexerr();
	}
	slash = gflag;

	/*
	 * Glob the argument list, if necessary.
	 * Otherwise trim off the quote bits.
	 */
	gflag = 0; av = &t->t_dcom[1];
	tglob(av);
	if (gflag) {
		av = glob(av);
		if (av == 0)
			error("No match");
	}
	blk[0] = t->t_dcom[0];
	blk[1] = 0;
	av = blkspl(blk, av);
#ifdef VFORK
	Vav = av;
#endif
	trim(av);
	slash |= any('/', av[0]);

	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; SHDIAG = 2; OLDSTD = 0;

	/*
	 * We must do this AFTER any possible forking (like `foo`
	 * in glob) so that this shell can still do subprocesses.
	 */
	(void) sigsetmask(0);

	/*
	 * If no path, no words in path, or a / in the filename
	 * then restrict the command search.
	 */
	if (v == 0 || v->vec[0] == 0 || slash)
		pv = justabs;
	else
		pv = v->vec;
	sav = strspl(S_SLASH /* "/" */, *av); /* / command name for postpending */
#ifdef VFORK
	Vsav = sav;
#endif
	if (havhash)
		hashval = hashname(*av);
	i = 0;
#ifdef VFORK
	hits++;
#endif
	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], S_DOT /* "." */)) { /* don't make ./xxx */
			texec(t, *av, av);
		} else {
			dp = strspl(*pv, sav);
#ifdef VFORK
			Vdp = dp;
#endif
			texec(t, dp, av);
#ifdef VFORK
			Vdp = 0;
#endif
			xfree(dp);
		}
#ifdef VFORK
		misses++;
#endif
cont:
		pv++;
		i++;
	} while (*pv);
#ifdef VFORK
	hits--;
#endif
#ifdef VFORK
	Vsav = 0;
	Vav = 0;
#endif
	xfree(sav);
	xfree((char *)av);
	pexerr();
}
Exemplo n.º 10
0
Arquivo: sh.dir.c Projeto: lukem/tcsh
/*
 * dfollow - change to arg directory; fall back on cdpath if not valid
 */
static Char *
dfollow(Char *cp, int old)
{
    Char *dp;
    struct varent *c;
    int serrno;

    cp = old ? Strsave(cp) : globone(cp, G_ERROR);
    cleanup_push(cp, xfree);
#ifdef apollo
    if (Strchr(cp, '`')) {
	char *dptr;
	if (chdir(dptr = short2str(cp)) < 0) 
	    stderror(ERR_SYSTEM, dptr, strerror(errno));
	dp = agetcwd();
	cleanup_push(dp, xfree);
	if (dp != NULL) {
	    cleanup_until(cp);
	    return dgoto(dp);
	}
	else
	    stderror(ERR_SYSTEM, dptr, strerror(errno));
    }
#endif /* apollo */

    /*
     * if we are ignoring symlinks, try to fix relatives now.
     * if we are expading symlinks, it should be done by now.
     */ 
    dp = dnormalize(cp, symlinks == SYM_IGNORE);
    if (chdir(short2str(dp)) >= 0) {
        cleanup_until(cp);
        return dgoto(dp);
    }
    else {
        xfree(dp);
        if (chdir(short2str(cp)) >= 0) {
	    cleanup_ignore(cp);
	    cleanup_until(cp);
	    return dgoto(cp);
	}
	else if (errno != ENOENT && errno != ENOTDIR) {
	    int err;

	    err = errno;
	    stderror(ERR_SYSTEM, short2str(cp), strerror(err));
	}
	serrno = errno;
    }

    if (cp[0] != '/' && !prefix(STRdotsl, cp) && !prefix(STRdotdotsl, cp)
	&& (c = adrof(STRcdpath)) && c->vec != NULL) {
	struct Strbuf buf = Strbuf_INIT;
	Char  **cdp;

	for (cdp = c->vec; *cdp; cdp++) {
	    size_t len = Strlen(*cdp);
	    buf.len = 0;
	    if (len > 0) {
		Strbuf_append(&buf, *cdp);
		if ((*cdp)[len - 1] != '/')
		    Strbuf_append1(&buf, '/');
	    }
	    Strbuf_append(&buf, cp);
	    Strbuf_terminate(&buf);
	    /*
	     * We always want to fix the directory here
	     * If we are normalizing symlinks
	     */
	    dp = dnormalize(buf.s, symlinks == SYM_IGNORE || 
				   symlinks == SYM_EXPAND);
	    if (chdir(short2str(dp)) >= 0) {
		printd = 1;
		xfree(buf.s);
		cleanup_until(cp);
		return dgoto(dp);
	    }
	    else if (chdir(short2str(cp)) >= 0) {
		printd = 1;
		xfree(dp);
		xfree(buf.s);
		cleanup_ignore(cp);
		cleanup_until(cp);
		return dgoto(cp);
	    }
	}
	xfree(buf.s);
    }
    dp = varval(cp);
    if ((dp[0] == '/' || dp[0] == '.') && chdir(short2str(dp)) >= 0) {
	cleanup_until(cp);
	cp = Strsave(dp);
	printd = 1;
	return dgoto(cp);
    }
    /*
     * on login source of ~/.cshdirs, errors are eaten. the dir stack is all
     * directories we could get to.
     */
    if (!bequiet)
	stderror(ERR_SYSTEM, short2str(cp), strerror(serrno));
    cleanup_until(cp);
    return (NULL);
}
Exemplo n.º 11
0
Arquivo: sh.dir.c Projeto: lukem/tcsh
/*
 * create a file called ~/.cshdirs which has a sequence
 * of pushd commands which will restore the dir stack to
 * its state before exit/logout. remember that the order
 * is reversed in the file because we are pushing.
 * -strike
 */
void
recdirs(Char *fname, int def)
{
    int     fp, ftmp, oldidfds;
    int     cdflag = 0;
    struct directory *dp;
    unsigned int    num;
    Char   *snum;
    struct Strbuf qname = Strbuf_INIT;

    if (fname == NULL && !def) 
	return;

    if (fname == NULL) {
	if ((fname = varval(STRdirsfile)) == STRNULL)
	    fname = Strspl(varval(STRhome), &STRtildotdirs[1]);
	else
	    fname = Strsave(fname);
    }
    else 
	fname = globone(fname, G_ERROR);
    cleanup_push(fname, xfree);

    if ((fp = xcreat(short2str(fname), 0600)) == -1) {
	cleanup_until(fname);
	return;
    }

    if ((snum = varval(STRsavedirs)) == STRNULL || snum[0] == '\0') 
	num = (unsigned int) ~0;
    else
	num = (unsigned int) atoi(short2str(snum));

    oldidfds = didfds;
    didfds = 0;
    ftmp = SHOUT;
    SHOUT = fp;

    cleanup_push(&qname, Strbuf_cleanup);
    dp = dcwd->di_next;
    do {
	if (dp == &dhead)
	    continue;

	if (cdflag == 0) {
	    cdflag = 1;
	    xprintf("cd %S\n", quote_meta(&qname, dp->di_name));
	}
	else
	    xprintf("pushd %S\n", quote_meta(&qname, dp->di_name));

	if (num-- == 0)
	    break;

    } while ((dp = dp->di_next) != dcwd->di_next);

    xclose(fp);
    SHOUT = ftmp;
    didfds = oldidfds;
    cleanup_until(fname);
}
Exemplo n.º 12
0
/*ARGSUSED*/
void
dosetpath(Char **arglist, struct command *c)
{
    extern char *getenv();
    Char  **pathvars, **cmdargs;
    char  **spaths, **cpaths, **cmds;
    char   *tcp;
    unsigned int npaths, ncmds;
    int     i, sysflag;

    pintr_disabled++;
    cleanup_push(&pintr_disabled, disabled_cleanup);

    /*
     * setpath(3) uses stdio and we want 0, 1, 2 to work...
     */
    if (!didfds) {
	(void) dcopy(SHIN, 0);
	(void) dcopy(SHOUT, 1);
	(void) dcopy(SHDIAG, 2);
	didfds = 1;
    }

    for (i = 1; arglist[i] && (arglist[i][0] != '-'); i++);
    npaths = i - 1;

    cmdargs = &arglist[i];
    for (; arglist[i]; i++);
    ncmds = i - npaths - 1;

    if (npaths) {
	sysflag = 0;
	pathvars = &arglist[1];
    }
    else {
	sysflag = 1;
	npaths = (sizeof syspaths / sizeof *syspaths) - 1;
	pathvars = syspaths;
    }

    /* note that npaths != 0 */

    spaths = xmalloc(npaths * sizeof *spaths);
    setzero(spaths, npaths * sizeof *spaths);
    cpaths = xmalloc((npaths + 1) * sizeof *cpaths);
    setzero(cpaths, (npaths + 1) * sizeof *cpaths);
    cmds = xmalloc((ncmds + 1) * sizeof *cmds);
    setzero(cmds, (ncmds + 1) * sizeof *cmds);
    for (i = 0; i < npaths; i++) {
	char   *val = getenv(short2str(pathvars[i]));

	if (val == NULL)
	    val = "";

	spaths[i] = xmalloc((Strlen(pathvars[i]) + strlen(val) + 2) *
			    sizeof **spaths);
	(void) strcpy(spaths[i], short2str(pathvars[i]));
	(void) strcat(spaths[i], "=");
	(void) strcat(spaths[i], val);
	cpaths[i] = spaths[i];
    }

    for (i = 0; i < ncmds; i++) {
	Char   *val = globone(cmdargs[i], G_ERROR);/*FIXRESET*/

	if (val == NULL)
	    goto abortpath;
	cmds[i] = strsave(short2str(val));
    }


    if (setpath(cpaths, cmds, LOCALSYSPATH, sysflag, 1) < 0) {
abortpath:
	if (spaths) {
	    for (i = 0; i < npaths; i++)
		xfree(spaths[i]);
	    xfree(spaths);
	}
	xfree(cpaths);
	if (cmds) {
	    for (i = 0; i < ncmds; i++)
		xfree(cmds[i]);
	    xfree(cmds);
	}

	cleanup_until(&pintr_disabled);
	donefds();
	return;
    }

    for (i = 0; i < npaths; i++) {
	Char	*val, *name;

	name = str2short(cpaths[i]);
	for (val = str2short(cpaths[i]); val && *val && *val != '='; val++);
	if (val && *val == '=') {
	    *val++ = '\0';

	    tsetenv(name, val);/*FIXRESET*/
	    if (Strcmp(name, STRKPATH) == 0) {
		importpath(val);/*FIXRESET*/
		if (havhash)
		    dohash(NULL, NULL);/*FIXRESET*/
	    }
	    *--val = '=';
	}
    }
    cleanup_until(&pintr_disabled);
    donefds();
}