Esempio n. 1
0
void
semicolon_arrfixenv(char *s, char **t)
{
    char **ep, *u;
    int len_s;
    Param pm;

    MUSTUSEHEAP("semicolon_arrfixenv");
    if (t == path)
	cmdnamtab->emptytable(cmdnamtab);
    u = zjoin(t, ';');
    len_s = strlen(s);
    pm = (Param) paramtab->getnode(paramtab, s);
    for (ep = environ; *ep; ep++)
	if (!strncmp(*ep, s, len_s) && (*ep)[len_s] == '=') {
	    pm->env = replenv(*ep, u);
//		(void)SetEnvironmentVariable(*ep,u);
	    return;
	}
    if (isset(ALLEXPORT))
	pm->flags |= PM_EXPORTED;
    if (pm->flags & PM_EXPORTED) {
		pm->env = addenv(s, u);
		(void)SetEnvironmentVariable(s,u);
	}
}
Esempio n. 2
0
static char *
get_zle_state(UNUSED(Param pm))
{
    char *zle_state = NULL, *ptr = NULL, **arr = NULL;
    int itp, istate, len = 0;

    /*
     * Substrings are sorted at the end, so the user can
     * easily match against this parameter:
     * if [[ $ZLE_STATE == *bar*foo*zonk* ]]; then ...; fi
     */
    for (itp = 0; itp < 2; itp++) {
	char *str;
	for (istate = 0; istate < 2; istate++) {
	    int slen;
	    switch (istate) {
	    case 0:
		if (insmode) {
		    str = "insert";
		} else {
		    str = "overwrite";
		}
		break;
	    case 1:
		if (hist_skip_flags & HIST_FOREIGN) {
		    str = "localhistory";
		} else {
		    str = "globalhistory";
		}
		break;

	    default:
		str = "";
	    }
	    slen = strlen(str);
	    if (itp == 0) {
		/* Accumulating length */
		if (istate)
		    len++;	/* for space */
		len += slen;
	    } else {
		/* Accumulating string */
		if (istate)
		    *ptr++ = ':';
		memcpy(ptr, str, slen);
		ptr += slen;
	    }
	}
	if (itp == 0) {
	    len++;		/* terminating NULL */
	    ptr = zle_state = (char *)zhalloc(len);
	} else {
	    *ptr = '\0';
	}
    }

    arr = colonsplit(zle_state, 0);
    strmetasort(arr, SORTIT_ANYOLDHOW, NULL);
    zle_state = zjoin(arr, ' ', 1);
    freearray(arr);

    return zle_state;
}
Esempio n. 3
0
static int
bin_sched(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
{
    char *s, **argptr;
    time_t t;
    long h, m, sec;
    struct tm *tm;
    struct schedcmd *sch, *sch2, *schl;
    int sn, flags = 0;

    /* If the argument begins with a -, remove the specified item from the
    schedule. */
    for (argptr = argv; *argptr && **argptr == '-'; argptr++) {
	char *arg = *argptr + 1;
	if (idigit(*arg)) {
	    sn = atoi(arg);

	    if (!sn) {
		zwarnnam("sched", "usage for delete: sched -<item#>.");
		return 1;
	    }
	    for (schl = NULL, sch = schedcmds, sn--;
		 sch && sn; sch = (schl = sch)->next, sn--);
	    if (!sch) {
		zwarnnam("sched", "not that many entries");
		return 1;
	    }
	    if (schl)
		schl->next = sch->next;
	    else {
		scheddeltimed();
		schedcmds = sch->next;
		if (schedcmds) {
		    DPUTS(timedfns && firstnode(timedfns), "BUG: already timed fn (2)");
		    schedaddtimed(schedcmds->time);
		}
	    }
	    zsfree(sch->cmd);
	    zfree(sch, sizeof(struct schedcmd));

	    return 0;
	} else if (*arg == '-') {
	    /* end of options */
	    argptr++;
	    break;
	} else if (!strcmp(arg, "o")) {
	    flags |= SCHEDFLAG_TRASH_ZLE;
	} else {
	    if (*arg)
		zwarnnam(nam, "bad option: -%c", *arg);
	    else
		zwarnnam(nam, "option expected");
	    return 1;
	}
    }

    /* given no arguments, display the schedule list */
    if (!*argptr) {
	for (sn = 1, sch = schedcmds; sch; sch = sch->next, sn++) {
	    char tbuf[60], *flagstr, *endstr;
	    time_t t;
	    struct tm *tmp;

	    t = sch->time;
	    tmp = localtime(&t);
	    ztrftime(tbuf, 40, "%a %b %e %k:%M:%S", tmp, 0L);
	    if (sch->flags & SCHEDFLAG_TRASH_ZLE)
		flagstr = "-o ";
	    else
		flagstr = "";
	    if (*sch->cmd == '-')
		endstr = "-- ";
	    else
		endstr = "";
	    printf("%3d %s %s%s%s\n", sn, tbuf, flagstr, endstr, sch->cmd);
	}
	return 0;
    } else if (!argptr[1]) {
	/* other than the two cases above, sched *
	 *requires at least two arguments        */
	zwarnnam("sched", "not enough arguments");
	return 1;
    }

    /* The first argument specifies the time to schedule the command for.  The
    remaining arguments form the command. */
    s = *argptr++;
    if (*s == '+') {
	/*
	 * + introduces a relative time.  The rest of the argument may be an
	 * hour:minute offset from the current time.  Once the hour and minute
	 * numbers have been extracted, and the format verified, the resulting
	 * offset is simply added to the current time.
	 */
	zlong zl = zstrtol(s + 1, &s, 10);
	if (*s == ':') {
	    m = (long)zstrtol(s + 1, &s, 10);
	    if (*s == ':')
		sec = (long)zstrtol(s + 1, &s, 10);
	    else
		sec = 0;
	    if (*s) {
		zwarnnam("sched", "bad time specifier");
		return 1;
	    }
	    t = time(NULL) + (long)zl * 3600 + m * 60 + sec;
	} else if (!*s) {
	    /*
	     * Alternatively, it may simply be a number of seconds.
	     * This is here for consistency with absolute times.
	     */
	    t = time(NULL) + (time_t)zl;
	} else {
	    zwarnnam("sched", "bad time specifier");
	    return 1;
	}
    } else {
	/*
	 * If there is no +, an absolute time must have been given.
	 * This may be in hour:minute format, optionally followed by a string
	 * starting with `a' or `p' (for a.m. or p.m.).  Characters after the
	 * `a' or `p' are ignored.
	 */
	zlong zl = zstrtol(s, &s, 10);
	if (*s == ':') {
	    h = (long)zl;
	    m = (long)zstrtol(s + 1, &s, 10);
	    if (*s == ':')
		sec = (long)zstrtol(s + 1, &s, 10);
	    else
		sec = 0;
	    if (*s && *s != 'a' && *s != 'A' && *s != 'p' && *s != 'P') {
		zwarnnam("sched", "bad time specifier");
		return 1;
	    }
	    t = time(NULL);
	    tm = localtime(&t);
	    t -= tm->tm_sec + tm->tm_min * 60 + tm->tm_hour * 3600;
	    if (*s == 'p' || *s == 'P')
		h += 12;
	    t += h * 3600 + m * 60 + sec;
	    /*
	     * If the specified time is before the current time, it must refer
	     * to tomorrow.
	     */
	    if (t < time(NULL))
		t += 3600 * 24;
	} else if (!*s) {
	    /*
	     * Otherwise, it must be a raw time specifier.
	     */
	    t = (long)zl;
	} else {
	    zwarnnam("sched", "bad time specifier");
	    return 1;
	}
    }
    /* The time has been calculated; now add the new entry to the linked list
    of scheduled commands. */
    sch = (struct schedcmd *) zalloc(sizeof *sch);
    sch->time = t;
    sch->cmd = zjoin(argptr, ' ', 0);
    sch->flags = flags;
    /* Insert into list in time order */
    if (schedcmds) {
	if (sch->time < schedcmds->time) {
	    scheddeltimed();
	    sch->next = schedcmds;
	    schedcmds = sch;
	    DPUTS(timedfns && firstnode(timedfns), "BUG: already timed fn (3)");
	    schedaddtimed(t);
	} else {
	    for (sch2 = schedcmds;
		 sch2->next && sch2->next->time < sch->time;
		 sch2 = sch2->next)
		;
	    sch->next = sch2->next;
	    sch2->next = sch;
	}
    } else {
	sch->next = NULL;
	schedcmds = sch;
	DPUTS(timedfns && firstnode(timedfns), "BUG: already timed fn (4)");
	schedaddtimed(t);
    }
    return 0;
}
Esempio n. 4
0
File: zpty.c Progetto: zsh-users/zsh
static int
newptycmd(char *nam, char *pname, char **args, int echo, int nblock)
{
    Ptycmd p;
    int master, slave, pid, oineval = ineval, ret;
    char *oscriptname = scriptname, syncch;
    Eprog prog;

    /* code borrowed from bin_eval() */
    ineval = !isset(EVALLINENO);
    if (!ineval)
	scriptname = "(zpty)";

    prog = parse_string(zjoin(args, ' ', 1), 0);
    if (!prog) {
	errflag &= ~ERRFLAG_ERROR;
	scriptname = oscriptname;
	ineval = oineval;
	return 1;
    }

    if (get_pty(1, &master)) {
	zwarnnam(nam, "can't open pseudo terminal: %e", errno);
	scriptname = oscriptname;
	ineval = oineval;
	return 1;
    }
    if ((pid = fork()) == -1) {
	zwarnnam(nam, "can't create pty command %s: %e", pname, errno);
	close(master);
	scriptname = oscriptname;
	ineval = oineval;
	return 1;
    } else if (!pid) {
	/* This code copied from the clone module, except for getting *
	 * the descriptor from get_pty() and duplicating it to 0/1/2. */

	deletehookfunc("exit", ptyhook);
	clearjobtab(0);
	ppid = getppid();
	mypid = getpid();
#ifdef HAVE_SETSID
	if (setsid() != mypid) {
	    zwarnnam(nam, "failed to create new session: %e", errno);
#endif
#ifdef TIOCNOTTY
	    if (ioctl(SHTTY, TIOCNOTTY, 0))
		zwarnnam(nam, "%e", errno);
	    setpgrp(0L, mypid);
#endif
#ifdef HAVE_SETSID
	}
#endif

	if (get_pty(0, &slave))
	    exit(1);
	SHTTY = slave;
	attachtty(mypid);
#ifdef TIOCGWINSZ
	/* Set the window size before associating with the terminal *
	 * so that we don't get hit with a SIGWINCH.  I'm paranoid. */
	if (interact) {
	    struct ttyinfo info;

	    if (ioctl(slave, TIOCGWINSZ, (char *) &info.winsize) == 0) {
		info.winsize.ws_row = zterm_lines;
		info.winsize.ws_col = zterm_columns;
		ioctl(slave, TIOCSWINSZ, (char *) &info.winsize);
	    }
	}
#endif /* TIOCGWINSZ */

	if (!echo) {
	    struct ttyinfo info;

	    if (!ptygettyinfo(slave, &info)) {
#ifdef HAVE_TERMIOS_H
		info.tio.c_lflag &= ~ECHO;
#else
#ifdef HAVE_TERMIO_H
		info.tio.c_lflag &= ~ECHO;
#else
		info.tio.lmodes &= ~ECHO; /**** dunno if this is right */
#endif
#endif
		ptysettyinfo(slave, &info);
	    }
	}

#ifdef TIOCSCTTY
	ioctl(slave, TIOCSCTTY, 0);
#endif

	close(0);
	close(1);
	close(2);

	dup2(slave, 0);
	dup2(slave, 1);
	dup2(slave, 2);

	closem(FDT_UNUSED, 0);
	close(slave);
	close(master);
	close(coprocin);
	close(coprocout);
	init_io(NULL);
	setsparam("TTY", ztrdup(ttystrname));

	opts[INTERACTIVE] = 0;

	syncch = 0;
	do {
	    ret = write(1, &syncch, 1);
	} while (ret != 1 && (
#ifdef EWOULDBLOCK
	    errno == EWOULDBLOCK ||
#else
#ifdef EAGAIN
	    errno == EAGAIN ||
#endif
#endif
	    errno == EINTR));

	execode(prog, 1, 0, "zpty");
	stopmsg = 2;
	mypid = 0; /* trick to ensure we _exit() */
	zexit(lastval, 0);
    }
    master = movefd(master);
    if (master == -1) {
	zerrnam(nam, "cannot duplicate fd %d: %e", master, errno);
	scriptname = oscriptname;
	ineval = oineval;
	return 1;
    }

    p = (Ptycmd) zalloc(sizeof(*p));

    p->name = ztrdup(pname);
    p->args = zarrdup(args);
    p->fd = master;
    p->pid = pid;
    p->echo = echo;
    p->nblock = nblock;
    p->fin = 0;
    p->read = -1;
    p->old = NULL;
    p->olen = 0;

    p->next = ptycmds;
    ptycmds = p;

    if (nblock)
	ptynonblock(master);

    scriptname = oscriptname;
    ineval = oineval;

    do {
	ret = read(master, &syncch, 1);
    } while (ret != 1 && (
#ifdef EWOULDBLOCK
	    errno == EWOULDBLOCK ||
#else
#ifdef EAGAIN
	    errno == EAGAIN ||
#endif
#endif
	    errno == EINTR));

    setiparam_no_convert("REPLY", (zlong)master);

    return 0;
}
Esempio n. 5
0
char *
semicolonarrgetfn(Param pm)
{
    return zjoin(*(char ***)pm->data, ';');
}