Exemple #1
0
static Char *
handleone(Char *str, Char **vl, int action)
{
    size_t chars;
    Char **t, *p, *strp;

    switch (action) {
    case G_ERROR:
	setname(short2str(str));
	blkfree(vl);
	stderror(ERR_NAME | ERR_AMBIG);
	break;
    case G_APPEND:
	chars = 0;
	for (t = vl; (p = *t++) != NULL; chars++)
	    chars += Strlen(p);
	str = xmalloc(chars * sizeof(Char));
	for (t = vl, strp = str; (p = *t++) != '\0'; chars++) {
	    while (*p)
		 *strp++ = *p++ & TRIM;
	    *strp++ = ' ';
	}
	*--strp = '\0';
	blkfree(vl);
	break;
    case G_IGNORE:
	str = Strsave(strip(*vl));
	blkfree(vl);
	break;
    default:
	break;
    }
    return (str);
}
Exemple #2
0
void vffree(int sig)
{
	register char **v;

	if (v = gargv)
		gargv = 0, blkfree(v);
	if (v = pargv)
		pargv = 0, blkfree(v);
	_exit(1);
}
Exemple #3
0
void
setq(Char *name, Char **vec, struct varent *p)
{
    struct varent *c;
    int f;

    f = 0;			/* tree hangs off the header's left link */
    while ((c = p->v_link[f]) != NULL) {
	if ((f = *name - *c->v_name) == 0 &&
	    (f = Strcmp(name, c->v_name)) == 0) {
	    blkfree(c->vec);
	    goto found;
	}
	p = c;
	f = f > 0;
    }
    p->v_link[f] = c = (struct varent *) xmalloc((size_t) sizeof(struct varent));
    c->v_name = Strsave(name);
    c->v_bal = 0;
    c->v_left = c->v_right = 0;
    c->v_parent = p;
    balance(p, f, 0);
found:
    trim(c->vec = vec);
}
Exemple #4
0
void
setq(const Char *name, Char **vec, struct varent *p, int flags)
{
    struct varent *c;
    int f;

    f = 0;			/* tree hangs off the header's left link */
    while ((c = p->v_link[f]) != 0) {
	if ((f = *name - *c->v_name) == 0 &&
	    (f = Strcmp(name, c->v_name)) == 0) {
	    if (c->v_flags & VAR_READONLY)
		stderror(ERR_READONLY|ERR_NAME, c->v_name);
	    blkfree(c->vec);
	    c->v_flags = flags;
	    trim(c->vec = vec);
	    return;
	}
	p = c;
	f = f > 0;
    }
    p->v_link[f] = c = xmalloc(sizeof(struct varent));
    c->v_name = Strsave(name);
    c->v_flags = flags;
    c->v_bal = 0;
    c->v_left = c->v_right = 0;
    c->v_parent = p;
    balance(p, f, 0);
    trim(c->vec = vec);
}
Exemple #5
0
void
pintr1(int wantnl)
{
    Char **v;
    sigset_t nsigset, osigset;

    sigemptyset(&nsigset);
    (void)sigprocmask(SIG_BLOCK, &nsigset, &osigset);
    if (setintr) {
	nsigset = osigset;
	(void)sigdelset(&nsigset, SIGINT);
	(void)sigprocmask(SIG_SETMASK, &nsigset, NULL);
	if (pjobs) {
	    pjobs = 0;
	    (void)fprintf(cshout, "\n");
	    dojobs(jobargv, NULL);
	    stderror(ERR_NAME | ERR_INTR);
	}
    }
    (void)sigdelset(&osigset, SIGCHLD);
    (void)sigprocmask(SIG_SETMASK, &osigset, NULL);
    (void)fpurge(cshout);
    (void)endpwent();

    /*
     * If we have an active "onintr" then we search for the label. Note that if
     * one does "onintr -" then we shan't be interruptible so we needn't worry
     * about that here.
     */
    if (gointr) {
	gotolab(gointr);
	timflg = 0;
	if ((v = pargv) != NULL)
	    pargv = 0, blkfree(v);
	if ((v = gargv) != NULL)
	    gargv = 0, blkfree(v);
	reset();
    }
    else if (intty && wantnl) {
	(void)fputc('\r', cshout);
	(void)fputc('\n', cshout);
    }
    stderror(ERR_SILENT);
    /* NOTREACHED */
}
Exemple #6
0
void
blk_indirect_cleanup(void *xptr)
{
    Char ***ptr;

    ptr = xptr;
    blkfree(*ptr);
    xfree(ptr);
}
Exemple #7
0
/*
 * $ substitute one word, for i/o redirection
 */
Char   *
Dfix1(Char *cp)
{
    Char *Dv[2], **expanded;

    if (noexec)
	return (0);
    Dv[0] = cp;
    Dv[1] = NULL;
    expanded = Dfix2(Dv);
    if (expanded[0] == NULL || expanded[1] != NULL) {
	blkfree(expanded);
	setname(short2str(cp));
	stderror(ERR_NAME | ERR_AMBIG);
    }
    cp = Strsave(expanded[0]);
    blkfree(expanded);
    return (cp);
}
Exemple #8
0
void
set1(Char *var, Char **vec, struct varent *head)
{
    Char **oldv = vec;

    gflag = 0;
    tglob(oldv);
    if (gflag) {
	vec = globall(oldv);
	if (vec == 0) {
	    blkfree(oldv);
	    stderror(ERR_NAME | ERR_NOMATCH);
	    return;
	}
	blkfree(oldv);
	gargv = 0;
    }
    setq(var, vec, head);
}
static void
globzap(void)
{
	if (globbed) {
		blkfree(globbed);
		free(globbed);
	}
	globbed = NULL;
	globcnt = 0;
}
Exemple #10
0
/*
 * $ substitute one word, for i/o redirection
 */
Char   *
Dfix1(Char *cp)
{
    Char   *Dv[2];

    if (noexec)
	return (0);
    Dv[0] = cp;
    Dv[1] = NULL;
    Dfix2(Dv);
    if (gargc != 1) {
	setname(vis_str(cp));
	stderror(ERR_NAME | ERR_AMBIG);
    }
    cp = Strsave(gargv[0]);
    blkfree(gargv), gargv = 0;
    return (cp);
}
Exemple #11
0
static void
unsetv1(struct varent *p)
{
    struct varent *c, *pp;
    int f;

    /*
     * Free associated memory first to avoid complications.
     */
    blkfree(p->vec);
    xfree(p->v_name);
    /*
     * If p is missing one child, then we can move the other into where p is.
     * Otherwise, we find the predecessor of p, which is guaranteed to have no
     * right child, copy it into p, and move it's left child into it.
     */
    if (p->v_right == 0)
	c = p->v_left;
    else if (p->v_left == 0)
	c = p->v_right;
    else {
	for (c = p->v_left; c->v_right; c = c->v_right)
	    continue;
	p->v_name = c->v_name;
	p->v_flags = c->v_flags;
	p->vec = c->vec;
	p = c;
	c = p->v_left;
    }

    /*
     * Move c into where p is.
     */
    pp = p->v_parent;
    f = pp->v_right == p;
    if ((pp->v_link[f] = c) != 0)
	c->v_parent = pp;
    /*
     * Free the deleted node, and rebalance.
     */
    xfree(p);
    balance(pp, f, 1);
}
Exemple #12
0
/*
 * $ substitute one word, for i/o redirection
 */
tchar *
Dfix1(tchar *cp)
{
	tchar *Dv[2];

#ifdef TRACE
	tprintf("TRACE- Dfix1()\n");
#endif
	if (noexec)
		return (0);
	Dv[0] = cp; Dv[1] = NOSTR;
	Dfix2(Dv);
	if (gargc != 1) {
		setname(cp);
		bferr("Ambiguous");
	}
	cp = savestr(gargv[0]);
	blkfree(gargv), gargv = 0;
	return (cp);
}
Exemple #13
0
/*
 * Fix up the $ expansions and quotations in the
 * argument list to command t.
 */
void
Dfix(struct command *t)
{
    Char **pp;
    Char *p;

    if (noexec)
	return;
    /* Note that t_dcom isn't trimmed thus !...:q's aren't lost */
    for (pp = t->t_dcom; (p = *pp++) != NULL;)
	for (; *p; p++) {
	    if (cmap(*p, _DOL | QUOTES)) {	/* $, \, ', ", ` */
		Dfix2(t->t_dcom);	/* found one */
		blkfree(t->t_dcom);
		t->t_dcom = gargv;
		gargv = 0;
		return;
	    }
	}
}
Exemple #14
0
/*
 * Fix up the $ expansions and quotations in the
 * argument list to command t.
 */
void
Dfix(struct command *t)
{
	tchar **pp;
	tchar *p;

#ifdef TRACE
	tprintf("TRACE- Dfix()\n");
#endif
	if (noexec)
		return;
	/* Note that t_dcom isn't trimmed thus !...:q's aren't lost */
	for (pp = t->t_dcom; p = *pp++; )
		while (*p)
			if (cmap(*p++, _DOL|QUOTES)) {	/* $, \, ', ", ` */
				Dfix2(t->t_dcom);	/* found one */
				blkfree(t->t_dcom);
				t->t_dcom = gargv;
				gargv = 0;
				return;
			}
}
Exemple #15
0
void
set1(const Char *var, Char **vec, struct varent *head, int flags)
{
    Char **oldv = vec;

    if ((flags & VAR_NOGLOB) == 0) {
	int gflag;

	gflag = tglob(oldv);
	if (gflag) {
	    vec = globall(oldv, gflag);
	    if (vec == 0) {
		blkfree(oldv);
		stderror(ERR_NAME | ERR_NOMATCH);
	    }
	    blkfree(oldv);
	}
    }
    /*
     * Uniqueness addition from: Michael Veksler <*****@*****.**>
     */
    if ( flags & (VAR_FIRST | VAR_LAST) ) {
	/*
	 * Code for -f (VAR_FIRST) and -l (VAR_LAST) options.
	 * Method:
	 *  Delete all duplicate words leaving "holes" in the word array (vec).
	 *  Then remove the "holes", keeping the order of the words unchanged.
	 */
	if (vec && vec[0] && vec[1]) { /* more than one word ? */
	    int i, j;
	    int num_items;

	    for (num_items = 0; vec[num_items]; num_items++)
	        continue;
	    if (flags & VAR_FIRST) {
		/* delete duplications, keeping first occurance */
		for (i = 1; i < num_items; i++)
		    for (j = 0; j < i; j++)
			/* If have earlier identical item, remove i'th item */
			if (vec[i] && vec[j] && Strcmp(vec[j], vec[i]) == 0) {
			    xfree(vec[i]);
			    vec[i] = NULL;
			    break;
			}
	    } else if (flags & VAR_LAST) {
	      /* delete duplications, keeping last occurance */
		for (i = 0; i < num_items - 1; i++)
		    for (j = i + 1; j < num_items; j++)
			/* If have later identical item, remove i'th item */
			if (vec[i] && vec[j] && Strcmp(vec[j], vec[i]) == 0) {
			    /* remove identical item (the first) */
			    xfree(vec[i]);
			    vec[i] = NULL;
			}
	    }
	    /* Compress items - remove empty items */
	    for (j = i = 0; i < num_items; i++)
	       if (vec[i]) 
		  vec[j++] = vec[i];

	    /* NULL-fy remaining items */
	    for (; j < num_items; j++)
		 vec[j] = NULL;
	}
	/* don't let the attribute propagate */
	flags &= ~(VAR_FIRST|VAR_LAST);
    } 
    setq(var, vec, head, flags);
}
Exemple #16
0
/*
 * Print the error with the given id.
 *
 * Special ids:
 *	ERR_SILENT: Print nothing.
 *	ERR_OLD: Print the previously set error if one was there.
 *	         otherwise return.
 *	ERR_NAME: If this bit is set, print the name of the function
 *		  in bname
 *
 * This routine always resets or exits.  The flag haderr
 * is set so the routine who catches the unwind can propogate
 * it if they want.
 *
 * Note that any open files at the point of error will eventually
 * be closed in the routine process in sh.c which is the only
 * place error unwinds are ever caught.
 */
void
stderror(int id, ...)
{
    va_list va;
    Char **v;
    int flags;

    flags = id & ERR_FLAGS;
    id &= ~ERR_FLAGS;

    if ((flags & ERR_OLD) && seterr == NULL)
	abort();

    if (id < 0 || id > (int)(sizeof(errorlist) / sizeof(errorlist[0])))
	id = ERR_INVALID;

    (void)fflush(cshout);
    (void)fflush(csherr);
    haderr = 1;			/* Now to diagnostic output */
    timflg = 0;			/* This isn't otherwise reset */


    if (!(flags & ERR_SILENT)) {
	if (flags & ERR_NAME)
	    (void)fprintf(csherr, "%s: ", bname);
	if ((flags & ERR_OLD))
	    /* Old error. */
	    (void)fprintf(csherr, "%s.\n", seterr);
	else {
	    va_start(va, id);
	    (void)vfprintf(csherr, errorlist[id], va);
	    va_end(va);
	    (void)fprintf(csherr, ".\n");
	}
    }

    if (seterr) {
	xfree((ptr_t) seterr);
	seterr = NULL;
    }

    if ((v = pargv) != NULL)
	pargv = 0, blkfree(v);
    if ((v = gargv) != NULL)
	gargv = 0, blkfree(v);

    (void)fflush(cshout);
    (void)fflush(csherr);
    didfds = 0;			/* Forget about 0,1,2 */
    /*
     * Go away if -e or we are a child shell
     */
    if (exiterr || child)
	xexit(1);

    /*
     * Reset the state of the input. This buffered seek to end of file will
     * also clear the while/foreach stack.
     */
    btoeof();

    set(STRstatus, Strsave(STR1));
    if (tpgrp > 0)
	(void)tcsetpgrp(FSHTTY, tpgrp);
    reset();			/* Unwind */
}
Exemple #17
0
void
execute(struct command *t, int wtty, int *pipein, int *pipeout)
{
    static sigset_t csigset, ocsigset; 
    static int nosigchld = 0, onosigchld = 0;
    volatile int wanttty = wtty;
    struct biltins * volatile bifunc;
    int pv[2], pid;
    sigset_t nsigset;
    int forked;

    UNREGISTER(forked);
    UNREGISTER(bifunc);
    UNREGISTER(wanttty);

    forked = 0;
    pid = 0;

    if (t == 0)
	return;

    if (t->t_dflg & F_AMPERSAND)
	wanttty = 0;
    switch (t->t_dtyp) {
    case NODE_COMMAND:
	if ((t->t_dcom[0][0] & (QUOTE | TRIM)) == QUOTE)
	    (void)Strcpy(t->t_dcom[0], t->t_dcom[0] + 1);
	if ((t->t_dflg & F_REPEAT) == 0)
	    Dfix(t);		/* $ " ' \ */
	if (t->t_dcom[0] == 0)
	    return;
	/* FALLTHROUGH */
    case NODE_PAREN:
	if (t->t_dflg & F_PIPEOUT)
	    mypipe(pipeout);
	/*
	 * Must do << early so parent will know where input pointer should be.
	 * If noexec then this is all we do.
	 */
	if (t->t_dflg & F_READ) {
	    (void)close(0);
	    heredoc(t->t_dlef);
	    if (noexec)
		(void)close(0);
	}

	set(STRstatus, Strsave(STR0));

	/*
	 * This mess is the necessary kludge to handle the prefix builtins:
	 * nice, nohup, time.  These commands can also be used by themselves,
	 * and this is not handled here. This will also work when loops are
	 * parsed.
	 */
	while (t->t_dtyp == NODE_COMMAND)
	    if (eq(t->t_dcom[0], STRnice)) {
		if (t->t_dcom[1]) {
		    if (strchr("+-", t->t_dcom[1][0])) {
			if (t->t_dcom[2]) {
			    setname("nice");
			    t->t_nice =
				getn(t->t_dcom[1]);
			    lshift(t->t_dcom, 2);
			    t->t_dflg |= F_NICE;
			}
			else
			    break;
		    } else {
			t->t_nice = 4;
			lshift(t->t_dcom, 1);
			t->t_dflg |= F_NICE;
		    }
		} else
		    break;
	    } else if (eq(t->t_dcom[0], STRnohup)) {
		if (t->t_dcom[1]) {
		    t->t_dflg |= F_NOHUP;
		    lshift(t->t_dcom, 1);
		}
		else
		    break;
	    } else if (eq(t->t_dcom[0], STRtime)) {
		if (t->t_dcom[1]) {
		    t->t_dflg |= F_TIME;
		    lshift(t->t_dcom, 1);
		}
		else
		    break;
	    } else
		break;

	/* is it a command */
	if (t->t_dtyp == NODE_COMMAND) {
	    /*
	     * Check if we have a builtin function and remember which one.
	     */
	    bifunc = isbfunc(t);
 	    if (noexec && bifunc != NULL) {
		/*
		 * Continue for builtins that are part of the scripting language
		 */
		if (bifunc->bfunct != dobreak   && bifunc->bfunct != docontin &&
		    bifunc->bfunct != doelse    && bifunc->bfunct != doend    &&
		    bifunc->bfunct != doforeach && bifunc->bfunct != dogoto   &&
		    bifunc->bfunct != doif      && bifunc->bfunct != dorepeat &&
		    bifunc->bfunct != doswbrk   && bifunc->bfunct != doswitch &&
		    bifunc->bfunct != dowhile   && bifunc->bfunct != dozip)
		    break;
	    }
	}
	else {			/* not a command */
	    bifunc = NULL;
	    if (noexec)
		break;
	}

	/*
	 * We fork only if we are timed, or are not the end of a parenthesized
	 * list and not a simple builtin function. Simple meaning one that is
	 * not pipedout, niced, nohupped, or &'d. It would be nice(?) to not
	 * fork in some of these cases.
	 */
	/*
	 * Prevent forking cd, pushd, popd, chdir cause this will cause the
	 * shell not to change dir!
	 */
	if (bifunc && (bifunc->bfunct == dochngd ||
		       bifunc->bfunct == dopushd ||
		       bifunc->bfunct == dopopd))
	    t->t_dflg &= ~(F_NICE);
	if (((t->t_dflg & F_TIME) || ((t->t_dflg & F_NOFORK) == 0 &&
	     (!bifunc || t->t_dflg &
	      (F_PIPEOUT | F_AMPERSAND | F_NICE | F_NOHUP)))) ||
	/*
	 * We have to fork for eval too.
	 */
	    (bifunc && (t->t_dflg & (F_PIPEIN | F_PIPEOUT)) != 0 &&
	     bifunc->bfunct == doeval)) {
	    if (t->t_dtyp == NODE_PAREN ||
		t->t_dflg & (F_REPEAT | F_AMPERSAND) || bifunc) {
		forked++;
		/*
		 * We need to block SIGCHLD here, so that if the process does
		 * not die before we can set the process group
		 */
		if (wanttty >= 0 && !nosigchld) {
		    sigemptyset(&nsigset);
		    (void)sigaddset(&nsigset, SIGCHLD);
		    (void)sigprocmask(SIG_BLOCK, &nsigset, &csigset);
		    nosigchld = 1;
		}

		pid = pfork(t, wanttty);
		if (pid == 0 && nosigchld) {
		    (void)sigprocmask(SIG_SETMASK, &csigset, NULL);
		    nosigchld = 0;
		}
		else if (pid != 0 && (t->t_dflg & F_AMPERSAND))
		    backpid = pid;

	    }
	    else {
		int ochild, osetintr, ohaderr, odidfds;
		int oSHIN, oSHOUT, oSHERR, oOLDSTD, otpgrp;
		sigset_t osigset;

		/*
		 * Prepare for the vfork by saving everything that the child
		 * corrupts before it exec's. Note that in some signal
		 * implementations which keep the signal info in user space
		 * (e.g. Sun's) it will also be necessary to save and restore
		 * the current sigaction's for the signals the child touches
		 * before it exec's.
		 */
		if (wanttty >= 0 && !nosigchld && !noexec) {
		    sigemptyset(&nsigset);
		    (void)sigaddset(&nsigset, SIGCHLD);
		    (void)sigprocmask(SIG_BLOCK, &nsigset, &csigset);
		    nosigchld = 1;
		}
		sigemptyset(&nsigset);
		(void)sigaddset(&nsigset, SIGCHLD);
		(void)sigaddset(&nsigset, SIGINT);
		(void)sigprocmask(SIG_BLOCK, &nsigset, &osigset);
		ochild = child;
		osetintr = setintr;
		ohaderr = haderr;
		odidfds = didfds;
		oSHIN = SHIN;
		oSHOUT = SHOUT;
		oSHERR = SHERR;
		oOLDSTD = OLDSTD;
		otpgrp = tpgrp;
		ocsigset = csigset;
		onosigchld = nosigchld;
		Vsav = Vdp = 0;
		Vexpath = 0;
		Vt = 0;
		pid = vfork();

		if (pid < 0) {
		    (void)sigprocmask(SIG_SETMASK, &osigset, NULL);
		    stderror(ERR_NOPROC);
		}
		forked++;
		if (pid) {	/* parent */
		    child = ochild;
		    setintr = osetintr;
		    haderr = ohaderr;
		    didfds = odidfds;
		    SHIN = oSHIN;
		    SHOUT = oSHOUT;
		    SHERR = oSHERR;
		    OLDSTD = oOLDSTD;
		    tpgrp = otpgrp;
		    csigset = ocsigset;
		    nosigchld = onosigchld;

		    xfree((ptr_t) Vsav);
		    Vsav = 0;
		    xfree((ptr_t) Vdp);
		    Vdp = 0;
		    xfree((ptr_t) Vexpath);
		    Vexpath = 0;
		    blkfree((Char **) Vt);
		    Vt = 0;
		    /* this is from pfork() */
		    palloc(pid, t);
		    (void)sigprocmask(SIG_SETMASK, &osigset, NULL);
		}
		else {		/* child */
		    /* this is from pfork() */
		    int pgrp;
		    int ignint = 0;

		    if (nosigchld) {
		        (void)sigprocmask(SIG_SETMASK, &csigset, NULL);
			nosigchld = 0;
		    }

		    if (setintr)
			ignint =
			    (tpgrp == -1 &&
			     (t->t_dflg & F_NOINTERRUPT))
			    || (gointr && eq(gointr, STRminus));
		    pgrp = pcurrjob ? pcurrjob->p_jobid : getpid();
		    child++;
		    if (setintr) {
			setintr = 0;
			if (ignint) {
			    (void)signal(SIGINT, SIG_IGN);
			    (void)signal(SIGQUIT, SIG_IGN);
			}
			else {
			    (void)signal(SIGINT, vffree);
			    (void)signal(SIGQUIT, SIG_DFL);
			}

			if (wanttty >= 0) {
			    (void)signal(SIGTSTP, SIG_DFL);
			    (void)signal(SIGTTIN, SIG_DFL);
			    (void)signal(SIGTTOU, SIG_DFL);
			}

			(void)signal(SIGTERM, parterm);
		    }
		    else if (tpgrp == -1 &&
			     (t->t_dflg & F_NOINTERRUPT)) {
			(void)signal(SIGINT, SIG_IGN);
			(void)signal(SIGQUIT, SIG_IGN);
		    }

		    pgetty(wanttty, pgrp);
		    if (t->t_dflg & F_NOHUP)
			(void)signal(SIGHUP, SIG_IGN);
		    if (t->t_dflg & F_NICE)
			(void)setpriority(PRIO_PROCESS, 0, t->t_nice);
		}

	    }
	}
	if (pid != 0) {
	    /*
	     * It would be better if we could wait for the whole job when we
	     * knew the last process had been started.  Pwait, in fact, does
	     * wait for the whole job anyway, but this test doesn't really
	     * express our intentions.
	     */
	    if (didfds == 0 && t->t_dflg & F_PIPEIN) {
		(void)close(pipein[0]);
		(void)close(pipein[1]);
	    }
	    if ((t->t_dflg & F_PIPEOUT) == 0) {
		if (nosigchld) {
		    (void)sigprocmask(SIG_SETMASK, &csigset, NULL);
		    nosigchld = 0;
		}
		if ((t->t_dflg & F_AMPERSAND) == 0)
		    pwait();
	    }
	    break;
	}
	doio(t, pipein, pipeout);
	if (t->t_dflg & F_PIPEOUT) {
	    (void)close(pipeout[0]);
	    (void)close(pipeout[1]);
	}
	/*
	 * Perform a builtin function. If we are not forked, arrange for
	 * possible stopping
	 */
	if (bifunc) {
	    func(t, bifunc);
	    if (forked)
		exitstat();
	    break;
	}
	if (t->t_dtyp != NODE_PAREN)
	    doexec(NULL, t);
	/*
	 * For () commands must put new 0,1,2 in FSH* and recurse
	 */
	(void) ioctl(OLDSTD = dcopy(0, FOLDSTD), FIOCLEX, NULL);
	(void) ioctl(SHOUT = dcopy(1, FSHOUT), FIOCLEX, NULL);
	(void) ioctl(SHERR = dcopy(2, FSHERR), FIOCLEX, NULL);
	(void) close(SHIN);

	SHIN = -1;
	didfds = 0;
	wanttty = -1;
	t->t_dspr->t_dflg |= t->t_dflg & F_NOINTERRUPT;
	execute(t->t_dspr, wanttty, NULL, NULL);
	exitstat();
	/* NOTREACHED */
    case NODE_PIPE:
	t->t_dcar->t_dflg |= F_PIPEOUT |
	    (t->t_dflg & (F_PIPEIN | F_AMPERSAND | F_STDERR | F_NOINTERRUPT));
	execute(t->t_dcar, wanttty, pipein, pv);
	t->t_dcdr->t_dflg |= F_PIPEIN | (t->t_dflg &
			(F_PIPEOUT | F_AMPERSAND | F_NOFORK | F_NOINTERRUPT));
	if (wanttty > 0)
	    wanttty = 0;	/* got tty already */
	execute(t->t_dcdr, wanttty, pv, pipeout);
	break;
    case NODE_LIST:
	if (t->t_dcar) {
	    t->t_dcar->t_dflg |= t->t_dflg & F_NOINTERRUPT;
	    execute(t->t_dcar, wanttty, NULL, NULL);
	    /*
	     * In strange case of A&B make a new job after A
	     */
	    if (t->t_dcar->t_dflg & F_AMPERSAND && t->t_dcdr &&
		(t->t_dcdr->t_dflg & F_AMPERSAND) == 0)
		pendjob();
	}
	if (t->t_dcdr) {
	    t->t_dcdr->t_dflg |= t->t_dflg &
		(F_NOFORK | F_NOINTERRUPT);
	    execute(t->t_dcdr, wanttty, NULL, NULL);
	}
	break;
    case NODE_OR:
    case NODE_AND:
	if (t->t_dcar) {
	    t->t_dcar->t_dflg |= t->t_dflg & F_NOINTERRUPT;
	    execute(t->t_dcar, wanttty, NULL, NULL);
	    if ((getn(value(STRstatus)) == 0) !=
		(t->t_dtyp == NODE_AND))
		return;
	}
	if (t->t_dcdr) {
	    t->t_dcdr->t_dflg |= t->t_dflg &
		(F_NOFORK | F_NOINTERRUPT);
	    execute(t->t_dcdr, wanttty, NULL, NULL);
	}
	break;
    }
    /*
     * Fall through for all breaks from switch
     * 
     * If there will be no more executions of this command, flush all file
     * descriptors. Places that turn on the F_REPEAT bit are responsible for
     * doing donefds after the last re-execution
     */
    if (didfds && !(t->t_dflg & F_REPEAT))
	donefds();
}
Exemple #18
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;
	}
}
Exemple #19
0
void dostart(Char ** vc, struct command *c) {

	char *cmdstr,*cmdend,*ptr;
	char argv0[256];/*FIXBUF*/
	DWORD cmdsize;
	char *currdir=NULL;
	char *savepath;
	char **v = NULL;
	STARTUPINFO si;
	PROCESS_INFORMATION pi;
	DWORD dwCreationFlags=CREATE_NEW_CONSOLE;
	DWORD k,cmdlen,j,jj,ret;


	UNREFERENCED_PARAMETER(c);
	vc++;

	cmdsize = 512;
	cmdstr = heap_alloc(cmdsize);
	cmdend = cmdstr;
	cmdlen = 0;

	memset(&si,0,sizeof(si));
	si.cb = sizeof(si);

	vc = glob_all_or_error(vc);
	v = short2blk(vc);
	if(v == NULL) {
		stderror(ERR_NOMEM);
		return;
	}
	blkfree(vc);
	for (k = 0; v[k] != NULL ; k++){

		if ( v[k][0] == '-' ) {
			/* various options */
			if( (v[k][1] == 'T') || (v[k][1] == 't'))
				si.lpTitle =&( v[k][2]);
			else if ( (v[k][1] == 'D') || (v[k][1] == 'd'))
				currdir =&( v[k][2]);
			else if (!_stricmp(&v[k][1],"MIN") )
				si.wShowWindow = SW_SHOWMINIMIZED;
			else if (!_stricmp(&v[k][1],"MAX") )
				si.wShowWindow = SW_SHOWMAXIMIZED;
			else if (!_stricmp(&v[k][1],"SEPARATE") )
				dwCreationFlags |= CREATE_SEPARATE_WOW_VDM;
			else if (!_stricmp(&v[k][1],"SHARED") )
				dwCreationFlags |= CREATE_SHARED_WOW_VDM;
			else if (!_stricmp(&v[k][1],"LOW") )
				dwCreationFlags |= IDLE_PRIORITY_CLASS;
			else if (!_stricmp(&v[k][1],"NORMAL") )
				dwCreationFlags |= NORMAL_PRIORITY_CLASS;
			else if (!_stricmp(&v[k][1],"HIGH") )
				dwCreationFlags |= HIGH_PRIORITY_CLASS;
			else if (!_stricmp(&v[k][1],"REALTIME") )
				dwCreationFlags |= REALTIME_PRIORITY_CLASS;
			else{
				blkfree((Char **)v);
				stderror(ERR_SYSTEM,start_usage,"See CMD.EXE for more info");/*FIXRESET*/
			}
		}
		else{ // non-option arg
			break;
		}
	}
	/* 
	 * Stop the insanity of requiring start "tcsh -l"
	 * Option processing now stops at first non-option arg
	 * -amol 5/30/96
	 */
	for (jj=k;v[jj] != NULL; jj++) {
		j=(lstrlen(v[jj]) + 2);
		if (j + cmdlen > cmdsize) {
			ptr = cmdstr;
			cmdstr = heap_realloc(cmdstr, max(cmdsize << 1, j+cmdlen) );
			if(!cmdstr)
			{
				heap_free(ptr);
				stderror(ERR_NOMEM,"start");/*FIXRESET*/
			}
			cmdend =  cmdstr + (cmdend - ptr);
			cmdsize <<= 1;
		}
		ptr = v[jj];
		while (*ptr) {
			*cmdend++ = *ptr++;
			cmdlen++;
		}
		*cmdend++ = ' ';
		cmdlen++;
	}
	if (jj == k) {
		blkfree((Char **)v);
		stderror(ERR_SYSTEM,start_usage,"See CMD.EXE for more info");/*FIXRESET*/
		return;
	}
	*cmdend = 0;
	StringCbCopy(argv0,sizeof(argv0),v[k]);


	/* 
	 * strictly speaking, it should do no harm to set the path
	 * back to '\'-delimited even in the parent, but in the
	 * interest of consistency, we save the old value and restore it
	 * later
	 */

	savepath = fix_path_for_child();

	if (! CreateProcess(NULL,
				cmdstr,
				NULL,
				NULL,
				FALSE,
				dwCreationFlags,
				NULL,
				currdir,
				&si,
				&pi) ) {

		restore_path(savepath);

		ret = GetLastError();
		if (ret == ERROR_BAD_EXE_FORMAT || ret == ERROR_ACCESS_DENIED ||
				(ret == ERROR_FILE_NOT_FOUND && 
				 (is_url(v[k]) || is_directory(v[k]))
				) 
		   ) {

			char erbuf[MAX_PATH];

			errno = ENOEXEC;

			try_shell_ex(&v[k],0,FALSE);

			heap_free(cmdstr); /* free !! */

			if (errno) {
				strerror_s(erbuf,sizeof(erbuf),errno);
				stderror(ERR_ARCH,argv0,erbuf);/*FIXRESET*/
			}
		}
		else if (ret == ERROR_INVALID_PARAMETER) {

			errno = ENAMETOOLONG;

			heap_free(cmdstr); /* free !! */

			stderror(ERR_TOOLARGE,argv0);/*FIXRESET*/

		}
		else {
			errno = ENOENT;
			if (
					( (v[k][0] == '\\') ||(v[k][0] == '/') ) &&
					( (v[k][1] == '\\') ||(v[k][1] == '/') ) &&
					(!v[k+1])
			   )
				try_shell_ex(&v[k],0,FALSE);

			heap_free(cmdstr); /* free !! */
			if (errno) {
				stderror(ERR_NOTFOUND,argv0);/*FIXRESET*/
			}
		}
	}
	else {
		CloseHandle(pi.hProcess);
		CloseHandle(pi.hThread);

		heap_free(cmdstr);
		restore_path(savepath);
	}
	blkfree((Char **)v);
	return;
}
Exemple #20
0
The default action is to shutdown without a reboot.\n\"now\" must be \
specified to actually shutdown or reboot\n"};

void doshutdown(Char **vc, struct command *c) {

	unsigned int flags = 0;
	unsigned char reboot,shutdown,logoff,shutdown_ok;
	char **v;
	char *ptr;
	char errbuf[128];
	int k;
	HANDLE hToken;
	TOKEN_PRIVILEGES tp,tpPrevious;
	LUID luid;
	DWORD cbPrevious = sizeof(TOKEN_PRIVILEGES);

	if (gdwPlatform != VER_PLATFORM_WIN32_NT) {
		stderror(ERR_SYSTEM,"shutdown","Sorry,not supported on win95");
	}

	shutdown_ok = reboot = shutdown = logoff = 0;
	gflag = 0;
	tglob(vc);
	if (gflag) {
		vc = globall(vc);
		if (vc == 0)
			stderror(ERR_NAME | ERR_NOMATCH);
	}
	else
		vc = gargv = saveblk(vc);
	trim(vc);
	v = short2blk(vc);
	for (k = 0; v[k] != NULL ; k++){
		if ( v[k][0] == '-' ) {
			ptr = v[k];
			ptr++;
			while( ptr && *ptr) {
				if (*ptr == 'f')
					flags |= EWX_FORCE;
				if (*ptr == 'r')
					reboot =1;
				else if (*ptr == 'l')
					logoff =1;
				else {
					blkfree((Char **)v);
					stderror(ERR_SYSTEM,"Usage",shutdown_usage);
				}
				ptr++;
			}
		}
		else if (!lstrcmpi(v[k],"now")) {
			shutdown_ok = 1;
		}
	}
	if (k == 0) {
		blkfree((Char**)v);
		stderror(ERR_SYSTEM,"Usage",shutdown_usage);
	}
	if (!reboot && !logoff){
		flags |= EWX_SHUTDOWN;
		shutdown = 1;
	}
	if (reboot && logoff ) {
		blkfree((Char **)v);
		stderror(ERR_SYSTEM,"Usage",shutdown_usage);
	}
	if (reboot)
		flags |= EWX_REBOOT;
	if (logoff)
		flags |= EWX_LOGOFF;

	if ((reboot || shutdown) && (!shutdown_ok) ) {
		blkfree((Char **)v);
		stderror(ERR_SYSTEM,"shutdown","Specify \"now\" to really shutdown");
	}


	if (!OpenProcessToken(GetCurrentProcess(),
							TOKEN_ADJUST_PRIVILEGES| TOKEN_QUERY,
							&hToken) ){
		make_err_str(GetLastError(),errbuf,128);
		blkfree((Char **)v);
		stderror(ERR_SYSTEM,"shutdown failed",errbuf);
	}
							

	if (!LookupPrivilegeValue(NULL,SE_SHUTDOWN_NAME,&luid)) {
		make_err_str(GetLastError(),errbuf,128);
		blkfree((Char **)v);
		stderror(ERR_SYSTEM,"shutdown failed",errbuf);
	}
	tp.PrivilegeCount = 1;
	tp.Privileges[0].Luid = luid;
	tp.Privileges[0].Attributes = 0;

	if (!AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(tp),&tpPrevious,
				&cbPrevious)){
		make_err_str(GetLastError(),errbuf,128);
		blkfree((Char **)v);
		stderror(ERR_SYSTEM,"shutdown failed",errbuf);
	}
	tpPrevious.PrivilegeCount = 1;
	tpPrevious.Privileges[0].Luid = luid;
	tpPrevious.Privileges[0].Attributes |= SE_PRIVILEGE_ENABLED;

	if (!AdjustTokenPrivileges(hToken,FALSE,&tpPrevious,cbPrevious,NULL,
				NULL)){
		make_err_str(GetLastError(),errbuf,128);
		blkfree((Char **)v);
		stderror(ERR_SYSTEM,"shutdown failed",errbuf);
	}
	if  (  !ExitWindowsEx(flags,0) ) {
		make_err_str(GetLastError(),errbuf,128);
		blkfree((Char **)v);
		stderror(ERR_SYSTEM,"shutdown failed",errbuf);
	}
}
Exemple #21
0
/*
 * Form a shell temporary file (in unit 0) from the words
 * of the shell input up to EOF or a line the same as "term".
 * Unit 0 should have been closed before this call.
 */
void
heredoc(Char *term)
{
    eChar  c;
    Char   *Dv[2];
    struct Strbuf lbuf = Strbuf_INIT, mbuf = Strbuf_INIT;
    Char    obuf[BUFSIZE + 1];
#define OBUF_END (obuf + sizeof(obuf) / sizeof (*obuf) - 1)
    Char *lbp, *obp, *mbp;
    Char  **vp;
    int    quoted;
#ifdef HAVE_MKSTEMP
    char   *tmp = short2str(shtemp);
    char   *dot = strrchr(tmp, '.');

    if (!dot)
	stderror(ERR_NAME | ERR_NOMATCH);
    strcpy(dot, TMP_TEMPLATE);

    xclose(0);
    if (mkstemp(tmp) == -1)
	stderror(ERR_SYSTEM, tmp, strerror(errno));
#else /* !HAVE_MKSTEMP */
    char   *tmp;
# ifndef WINNT_NATIVE

again:
# endif /* WINNT_NATIVE */
    tmp = short2str(shtemp);
# if O_CREAT == 0
    if (xcreat(tmp, 0600) < 0)
	stderror(ERR_SYSTEM, tmp, strerror(errno));
# endif
    xclose(0);
    if (xopen(tmp, O_RDWR|O_CREAT|O_EXCL|O_TEMPORARY|O_LARGEFILE, 0600) ==
	-1) {
	int oerrno = errno;
# ifndef WINNT_NATIVE
	if (errno == EEXIST) {
	    if (unlink(tmp) == -1) {
		xfree(shtemp);
		mbp = randsuf();
		shtemp = Strspl(STRtmpsh, mbp);
		xfree(mbp);
	    }
	    goto again;
	}
# endif /* WINNT_NATIVE */
	(void) unlink(tmp);
	errno = oerrno;
 	stderror(ERR_SYSTEM, tmp, strerror(errno));
    }
#endif /* HAVE_MKSTEMP */
    (void) unlink(tmp);		/* 0 0 inode! */
    Dv[0] = term;
    Dv[1] = NULL;
    gflag = 0;
    trim(Dv);
    rscan(Dv, Dtestq);
    quoted = gflag;
    obp = obuf;
    obuf[BUFSIZE] = 0;
    inheredoc = 1;
    cleanup_push(&inheredoc, inheredoc_cleanup);
#ifdef WINNT_NATIVE
    __dup_stdin = 1;
#endif /* WINNT_NATIVE */
    cleanup_push(&lbuf, Strbuf_cleanup);
    cleanup_push(&mbuf, Strbuf_cleanup);
    for (;;) {
	Char **words;

	/*
	 * Read up a line
	 */
	lbuf.len = 0;
	for (;;) {
	    c = readc(1);	/* 1 -> Want EOF returns */
	    if (c == CHAR_ERR || c == '\n')
		break;
	    if ((c &= TRIM) != 0)
		Strbuf_append1(&lbuf, (Char) c);
	}
	Strbuf_terminate(&lbuf);

	/* Catch EOF in the middle of a line. */
	if (c == CHAR_ERR && lbuf.len != 0)
	    c = '\n';

	/*
	 * Check for EOF or compare to terminator -- before expansion
	 */
	if (c == CHAR_ERR || eq(lbuf.s, term))
	    break;

	/*
	 * If term was quoted or -n just pass it on
	 */
	if (quoted || noexec) {
	    Strbuf_append1(&lbuf, '\n');
	    Strbuf_terminate(&lbuf);
	    for (lbp = lbuf.s; (c = *lbp++) != 0;) {
		*obp++ = (Char) c;
		if (obp == OBUF_END) {
		    tmp = short2str(obuf);
		    (void) xwrite(0, tmp, strlen (tmp));
		    obp = obuf;
		}
	    }
	    continue;
	}

	/*
	 * Term wasn't quoted so variable and then command expand the input
	 * line
	 */
	Dcp = lbuf.s;
	Dvp = Dv + 1;
	mbuf.len = 0;
	for (;;) {
	    c = DgetC(DODOL);
	    if (c == DEOF)
		break;
	    if ((c &= TRIM) == 0)
		continue;
	    /* \ quotes \ $ ` here */
	    if (c == '\\') {
		c = DgetC(0);
		if (!any("$\\`", c))
		    unDgetC(c | QUOTE), c = '\\';
		else
		    c |= QUOTE;
	    }
	    Strbuf_append1(&mbuf, (Char) c);
	}
	Strbuf_terminate(&mbuf);

	/*
	 * If any ` in line do command substitution
	 */
	mbp = mbuf.s;
	if (Strchr(mbp, '`') != NULL) {
	    /*
	     * 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.
	     */
	    words = dobackp(mbp, 1);
	}
	else
	    /* Setup trivial vector similar to return of dobackp */
	    Dv[0] = mbp, Dv[1] = NULL, words = 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= words; *vp; vp++) {
	    for (mbp = *vp; *mbp; mbp++) {
		*obp++ = *mbp & TRIM;
		if (obp == OBUF_END) {
		    tmp = short2str(obuf);
		    (void) xwrite(0, tmp, strlen (tmp));
		    obp = obuf;
		}
	    }
	    *obp++ = '\n';
	    if (obp == OBUF_END) {
	        tmp = short2str(obuf);
		(void) xwrite(0, tmp, strlen (tmp));
		obp = obuf;
	    }
	}
	if (words != Dv)
	    blkfree(words);
    }
    *obp = 0;
    tmp = short2str(obuf);
    (void) xwrite(0, tmp, strlen (tmp));
    (void) lseek(0, (off_t) 0, L_SET);
    cleanup_until(&inheredoc);
}
Exemple #22
0
/*
 * Form a shell temporary file (in unit 0) from the words
 * of the shell input up to EOF or a line the same as "term".
 * Unit 0 should have been closed before this call.
 */
void
/*ARGSUSED*/
heredoc(Char *term)
{
    int c;
    Char   *Dv[2];
    Char    obuf[BUFSIZ], lbuf[BUFSIZ], mbuf[BUFSIZ];
    int     ocnt, lcnt, mcnt;
    Char *lbp, *obp, *mbp;
    Char  **vp;
    bool    quoted;
    char   tmp[] = "/tmp/sh.XXXXXXXX";

    if (mkstemp(tmp) < 0)
	stderror(ERR_SYSTEM, tmp, strerror(errno));
    (void) unlink(tmp);		/* 0 0 inode! */
    Dv[0] = term;
    Dv[1] = NULL;
    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 || c == '\n')
		break;
	    if ((c &= TRIM) != '\0') {
		*lbp++ = c;
		if (--lcnt < 0) {
		    setname("<<");
		    stderror(ERR_NAME | ERR_OVERFLOW);
		}
	    }
	}
	*lbp = 0;

	/*
	 * Check for EOF or compare to terminator -- before expansion
	 */
	if (c < 0 || eq(lbuf, term)) {
	    (void) write(STDIN_FILENO, short2str(obuf), 
	        (size_t) (BUFSIZ - ocnt));
	    (void) lseek(STDIN_FILENO, (off_t) 0, SEEK_SET);
	    return;
	}

	/*
	 * If term was quoted or -n just pass it on
	 */
	if (quoted || noexec) {
	    *lbp++ = '\n';
	    *lbp = 0;
	    for (lbp = lbuf; (c = *lbp++) != '\0';) {
		*obp++ = c;
		if (--ocnt == 0) {
		    (void) write(STDIN_FILENO, short2str(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))
		    unDgetC(c | QUOTE), c = '\\';
		else
		    c |= QUOTE;
	    }
	    *mbp++ = c;
	    if (--mcnt == 0) {
		setname("<<");
		stderror(ERR_NAME | ERR_OVERFLOW);
	    }
	}
	*mbp++ = 0;

	/*
	 * If any ` in line do command substitution
	 */
	mbp = mbuf;
	if (any(short2str(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] = NULL, 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(STDIN_FILENO, short2str(obuf), BUFSIZ);
		    obp = obuf;
		    ocnt = BUFSIZ;
		}
	    }
	    *obp++ = '\n';
	    if (--ocnt == 0) {
		(void) write(STDIN_FILENO, short2str(obuf), BUFSIZ);
		obp = obuf;
		ocnt = BUFSIZ;
	    }
	}
	if (pargv)
	    blkfree(pargv), pargv = 0;
    }
}
Exemple #23
0
/*ARGSUSED*/
void
dosched(Char **v, struct command *c)
{
    struct sched_event *tp, **pp;
    time_t  cur_time;
    int     count, hours, minutes, dif_hour, dif_min;
    Char   *cp;
    int    relative;		/* time specified as +hh:mm */
    struct tm *ltp;

    USE(c);
/* This is a major kludge because of a gcc linker  */
/* Problem.  It may or may not be needed for you   */
#if defined(_MINIX) && !defined(_MINIX_VMD)
    char kludge[10];
    extern char *sprintf();
    sprintf(kludge, CGETS(24, 1, "kludge"));
#endif /* _MINIX && !_MINIX_VMD */

    v++;
    cp = *v++;
    if (cp == NULL) {
	const Char *fmt;
	if ((fmt = varval(STRsched)) == STRNULL)
	    fmt = str2short("%h\t%T\t%R\n");
	/* print list of scheduled events */
	for (count = 1, tp = sched_ptr; tp; count++, tp = tp->t_next) {
	    Char *buf, *str;

	    buf = blkexpand(tp->t_lex);
	    cleanup_push(buf, xfree);
	    str = tprintf(FMT_SCHED, fmt, short2str(buf), tp->t_when, &count);
	    cleanup_until(buf);
	    cleanup_push(str, xfree);
	    for (cp = str; *cp;)
		xputwchar(*cp++);
	    cleanup_until(str);
	}
	return;
    }

    if (*cp == '-') {
	/* remove item from list */
	if (!sched_ptr)
	    stderror(ERR_NOSCHED);
	if (*v)
	    stderror(ERR_SCHEDUSAGE);
	count = atoi(short2str(++cp));
	if (count <= 0)
	    stderror(ERR_SCHEDUSAGE);
	pp = &sched_ptr;
	tp = sched_ptr;
	while (--count) {
	    if (tp->t_next == 0)
		break;
	    else {
		pp = &tp->t_next;
		tp = tp->t_next;
	    }
	}
	if (count)
	    stderror(ERR_SCHEDEV);
	*pp = tp->t_next;
	blkfree(tp->t_lex);
	xfree(tp);
	return;
    }

    /* else, add an item to the list */
    if (!*v)
	stderror(ERR_SCHEDCOM);
    relative = 0;
    if (!Isdigit(*cp)) {	/* not abs. time */
	if (*cp != '+')
	    stderror(ERR_SCHEDUSAGE);
	cp++, relative++;
    }
    minutes = 0;
    hours = atoi(short2str(cp));
    while (*cp && *cp != ':' && *cp != 'a' && *cp != 'p')
	cp++;
    if (*cp && *cp == ':')
	minutes = atoi(short2str(++cp));
    if ((hours < 0) || (minutes < 0) ||
	(hours > 23) || (minutes > 59))
	stderror(ERR_SCHEDTIME);
    while (*cp && *cp != 'p' && *cp != 'a')
	cp++;
    if (*cp && relative)
	stderror(ERR_SCHEDREL);
    if (*cp == 'p')
	hours += 12;
    (void) time(&cur_time);
    ltp = localtime(&cur_time);
    if (relative) {
	dif_hour = hours;
	dif_min = minutes;
    }
    else {
	if ((dif_hour = hours - ltp->tm_hour) < 0)
	    dif_hour += 24;
	if ((dif_min = minutes - ltp->tm_min) < 0) {
	    dif_min += 60;
	    if ((--dif_hour) < 0)
		dif_hour = 23;
	}
    }
    tp = xcalloc(1, sizeof *tp);
#ifdef _SX
    tp->t_when = cur_time - ltp->tm_sec + dif_hour * 3600 + dif_min * 60;
#else	/* _SX */
    tp->t_when = cur_time - ltp->tm_sec + dif_hour * 3600L + dif_min * 60L;
#endif /* _SX */
    /* use of tm_sec: get to beginning of minute. */
    for (pp = &sched_ptr; *pp != NULL && tp->t_when >= (*pp)->t_when;
	 pp = &(*pp)->t_next)
	;
    tp->t_next = *pp;
    *pp = tp;
    tp->t_lex = saveblk(v);
}
Exemple #24
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 */
}
Exemple #25
0
int nt_try_fast_exec(struct command *t) {
	register Char  **pv, **av;
	register Char *dp,*sav;
	register char **tt;
	register char *f;
	register struct varent *v;
	register int hashval,i;
	register int slash;
	int rc = 0, gflag;
	Char *vp;
	Char   *blk[2];

	vp = varval(STRNTslowexec);
	if (vp != STRNULL)
		return 1;

	blk[0] = t->t_dcom[0];
	blk[1] = 0;

	// don't do backtick
	if(Strchr(t->t_dcom[0],'`') )
		return 1;


	gflag = tglob(blk);
	if (gflag) {
		pv = globall(blk, gflag);
		if (pv == 0) {
			return 1;
		}
	}
	else
		pv = saveblk(blk);

	trim(pv);

	epath = Strsave(pv[0]);
	v = adrof(STRpath);
	if (v == 0 && epath[0] != '/' && epath[0] != '.') {
		blkfree(pv);
		return 1;
	}
	slash = any(short2str(epath),'/');
	/*
	 * Glob the argument list, if necessary. Otherwise trim off the quote bits.
	 */
	av = &t->t_dcom[1];
	gflag = tglob(av);
	if (gflag) {
		av = globall(av, gflag);/*FIXRESET*/
		if (av == 0) {
			blkfree(pv);
			return 1;
		}
	}
	else
		av = saveblk(av);

	blkfree(t->t_dcom);
	t->t_dcom = blkspl(pv, av);
	xfree((ptr_t) pv);
	xfree((ptr_t) av);
	av = t->t_dcom;
	//trim(av);

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

	xechoit(av);/*FIXRESET*/		/* Echo command if -x */
	if (v == 0 || v->vec[0] == 0 || slash)
		pv = abspath;
	else
		pv = v->vec;

	sav = Strspl(STRslash,*av);
	hashval = hashval_extern(*av);

	i = 0;
	do {
#pragma warning(disable:4310)
		if (!slash && ABSOLUTEP(pv[0]) && havhash) {
#pragma warning(default:4310)
			if (!bit_extern(hashval,i)){
				pv++;i++;
				continue;
			}
		}
		if (pv[0][0] == 0 || eq(pv[0],STRdot)) {

			tt = short2blk(av);
			f = short2str(*av);

			rc = nt_texec(f, tt);

			blkfree((Char**)tt);
			if (!rc)
				break;
		}
		else {
			dp = Strspl(*pv,sav);
			tt = short2blk(av);
			f = short2str(dp);

			rc = nt_texec(f, tt);

			blkfree((Char**)tt);
			xfree((ptr_t)dp);
			if (!rc)
				break;
		}
		pv++;
		i++;
	}while(*pv);
	return rc;
}
FILE *
ftpd_popen(char *program, char *type, int closestderr)
{
    register char *cp;
    FILE *iop;
    int argc,
      gargc,
      pdes[2],
      pid;
    char **pop,
     *argv[100],
     *gargv[1000],
     *vv[2];
    extern char **ftpglob(register char *v),
    **copyblk(register char **v),
     *strspl(register char *cp, register char *dp);

    if (*type != 'r' && *type != 'w' || type[1])
        return (NULL);

    if (!pids) {
#ifndef HAVE_GETDTABLESIZE
        struct rlimit rlp;

		rlp.rlim_cur = rlp.rlim_max = RLIM_INFINITY;
		if (getrlimit( RLIMIT_NOFILE, &rlp ) )
			return(NULL);
		fds = rlp.rlim_cur;
#else
        if ((fds = getdtablesize()) <= 0)
            return (NULL);
#endif

        if ((pids = (int *) malloc((u_int) (fds * sizeof(int)))) == NULL)
              return (NULL);
#ifdef USG
        (void) memset((char *)pids, fds * sizeof(int), 0);
#else
        bzero((char *) pids, fds * sizeof(int));
#endif
    }
    if (pipe(pdes) < 0)
        return (NULL);

    /* break up string into pieces */
    for (argc = 0, cp = program;; cp = NULL)
        if (!(argv[argc++] = strtok(cp, " \t\n")))
            break;

    /* glob each piece */
    gargv[0] = argv[0];
    for (gargc = argc = 1; argv[argc]; argc++) {
        if (!(pop = ftpglob(argv[argc]))) { /* globbing failed */
            vv[0] = strspl(argv[argc], "");
            vv[1] = NULL;
            pop = copyblk(vv);
        }
        argv[argc] = (char *) pop;  /* save to free later */
        while (*pop && gargc < 1000)
            gargv[gargc++] = *pop++;
    }
    gargv[gargc] = NULL;

    iop = NULL;
    switch (pid = vfork()) {
    case -1:                    /* error */
        (void) close(pdes[0]);
        (void) close(pdes[1]);
        goto pfree;
        /* NOTREACHED */
    case 0:                 /* child */
        if (*type == 'r') {
            if (pdes[1] != 1) {
                dup2(pdes[1], 1);
                if (closestderr)
                    (void) close(2);
                else 
                    dup2(pdes[1], 2);  /* stderr, too! */
                (void) close(pdes[1]);
            }
            (void) close(pdes[0]);
        } else {
            if (pdes[0] != 0) {
                dup2(pdes[0], 0);
                (void) close(pdes[0]);
            }
            (void) close(pdes[1]);
        }
        execv(gargv[0], gargv);
        _exit(1);
    }
    /* parent; assume fdopen can't fail...  */
    if (*type == 'r') {
        iop = fdopen(pdes[0], type);
        (void) close(pdes[1]);
    } else {
        iop = fdopen(pdes[1], type);
        (void) close(pdes[0]);
    }
    pids[fileno(iop)] = pid;

  pfree:for (argc = 1; argv[argc] != NULL; argc++) {
        blkfree((char **) argv[argc]);
        free((char *) argv[argc]);
    }
    return (iop);
}
Exemple #27
0
void
blk_cleanup(void *ptr)
{
    blkfree(ptr);
}
Exemple #28
0
int 
f_put (char **vec)
{
	int     append;
#ifdef	BRIDGE
	int     result;
	char  *dst;
#else
	int	    sglobbed;
	char  *bp,
			 *dst,
			 **gp,
			 **src;
	char   *freedst = NULL,
			buffer[BUFSIZ];
#endif

	append = strcmp (*vec, "append") == 0;

	if (*++vec == NULL) {
#ifdef	BRIDGE
		return NOTOK;
#else
		if (getftamline ("source: ", buffer) == NOTOK || str2vec (buffer, vec) < 1)
			return OK;
		dst = NULL;
#endif
	} else {
#ifdef	BRIDGE
		dst = *vec;
#else
		char **ap;

		for (ap = vec; *ap; ap++)
			continue;
		if (--ap != vec)
			dst = *ap, *ap = NULL;
		else
			dst = NULL;
#endif
	}
#ifndef	BRIDGE
	if (!(src = xglob (vec, 0)))
		return OK;
	sglobbed = xglobbed;

	if (dst == NULL) {
		if (getftamline ("destination: ", buffer) == NOTOK) {
			blkfree (src);
			return OK;
		}
		switch (str2vec (buffer, vec)) {
		case 0:
			break;

		case 1:
			dst = *vec;
			break;

		default:
			advise (NULLCP, "too many destinations");
			goto out;
		}
	}
	if (dst && !(dst = freedst = xglob1val (dst, 0)))
		goto out;

	if (src[1] == NULL) {
		if (interrupted)
			goto out;

		if (dst == NULL) {
			switch (realstore) {
			case RFS_UNIX:
				if (dst = rindex (*src, '/'))
					dst++;
				if (dst == NULL || *dst == NULL)
					dst = *src;
				break;

			default:
				dst = *src;
				break;
			}
			dst = str2file (dst);

ask_it:
			;
			if (query)
				switch (ask ("%s %s %s", append ? "append" : "put", *src,
							 dst)) {
				case NOTOK:
					goto out;

				case OK:
				default:
					break;

				case DONE:
					goto out;
				}
		} else
			switch (realstore) {
			case RFS_UNIX:
				if (isdir (dst, NULLCP, 1) == NOTOK)
					break;
#ifdef apollo
				if (*dst == '/')
					 sprintf (bp = buffer, "%s", dst);
				else
#endif
					 sprintf (bp = buffer, "%s/", dst);
				bp += strlen (bp);
				if (dst = rindex (*src, '/'))
					dst++;
				if (dst == NULL || *dst == NULL)
					dst = *src;
				 strcpy (bp, dst);
				dst = buffer;
				goto ask_it;

			default:
				break;
			}

		dst = str2file (dst);
		 put (*src, dst, append);
		goto out;
	}

	switch (realstore) {
	case RFS_UNKNOWN:
		advise (NULLCP, "%s", rs_unknown);
		goto out;

	case RFS_UNIX:
		if (dst)
#ifdef apollo
			if (*(bp = str2file (dst)) == '/') {
				 strcpy (buffer, bp);
				bp = buffer;
			} else
#endif
				 sprintf (bp = buffer, "%s/", str2file (dst));
		else if (rcwd)
			 sprintf (bp = buffer, "%s", str2file (""));
		else
			 strcpy (bp = buffer, "./");
		bp += strlen (bp);
		break;

	default:
		advise (NULLCP, "%s", rs_support);
		goto out;
	}

	if (isdir (str2file (buffer), NULLCP, 0) == NOTOK)
		goto out;

	for (gp = src; *gp && !interrupted; gp++) {
		switch (realstore) {
		case RFS_UNIX:
			if (dst = rindex (*gp, '/'))
				dst++;
			if (dst == NULL || *dst == NULL)
				dst = *gp;
			break;

		default:
			dst = *gp;
			break;
		}
		 strcpy (bp, dst);
		dst = str2file (buffer);

		if (sglobbed) {
			if (query)
				switch (ask ("%s %s %s", append ? "append" : "put", *gp, dst)) {
				case NOTOK:
					continue;

				case OK:
				default:
					break;

				case DONE:
					goto out;
				}
			else
				advise (NULLCP, "%s %s %s", append ? "append" : "put", *gp,
						dst);
		}

		 put (*gp, dst, append);

		if (ftamfd == NOTOK)
			break;
	}

out:
	;
	blkfree (src);
	if (freedst)
		free (freedst);

	return OK;
#else
	result = put (dst, append);
	return result;
#endif
}
Exemple #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;
	}
    }
}
Exemple #30
0
/*
 * Execute scheduled events
 */
void
sched_run(void)
{
    time_t   cur_time;
    struct sched_event *tp;
    struct wordent cmd, *nextword, *lastword;
    struct command *t;
    Char  **v, *cp;

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

    (void) time(&cur_time);

    /* bugfix by: Justin Bur at Universite de Montreal */
    /*
     * this test wouldn't be necessary if this routine were not called before
     * each prompt (in sh.c).  But it is, to catch missed alarms.  Someone
     * ought to fix it all up.  -jbb
     */
    if (!(sched_ptr && sched_ptr->t_when < cur_time)) {
	cleanup_until(&pintr_disabled);
	return;
    }

    if (GettingInput)
	(void) Cookedmode();

    while ((tp = sched_ptr) != NULL && tp->t_when < cur_time) {
	if (seterr) {
	    xfree(seterr);
	    seterr = NULL;
	}
	cmd.word = STRNULL;
	lastword = &cmd;
	v = tp->t_lex;
	for (cp = *v; cp; cp = *++v) {
	    nextword = xcalloc(1, sizeof cmd);
	    nextword->word = Strsave(cp);
	    lastword->next = nextword;
	    nextword->prev = lastword;
	    lastword = nextword;
	}
	lastword->next = &cmd;
	cmd.prev = lastword;
	sched_ptr = tp->t_next;	/* looping termination cond: */
	blkfree(tp->t_lex);	/* straighten out in case of */
	xfree(tp);		/* command blow-up. */

	cleanup_push(&cmd, lex_cleanup);
	/* expand aliases like process() does. */
	alias(&cmd);
	/* build a syntax tree for the command. */
	t = syntax(cmd.next, &cmd, 0);
	cleanup_push(t, syntax_cleanup);
	if (seterr)
	    stderror(ERR_OLD);
	/* execute the parse tree. */
	execute(t, -1, NULL, NULL, TRUE);
	/* done. free the lex list and parse tree. */
	cleanup_until(&cmd);
    }
    if (GettingInput && !just_signaled) {	/* PWP */
	(void) Rawmode();
	ClearLines();		/* do a real refresh since something may */
	ClearDisp();		/* have printed to the screen */
	Refresh();
    }
    just_signaled = 0;

    cleanup_until(&pintr_disabled);
}