예제 #1
0
파일: compat.c 프로젝트: Web5design/zsh
mod_export char *
output64(zlong val)
{
    static char llbuf[DIGBUFSIZE];
    convbase(llbuf, val, 0);
    return llbuf;
}
예제 #2
0
파일: datetime.c 프로젝트: Lujaw/zsh
static int
reverse_strftime(char *nam, char **argv, char *scalar, int quiet)
{
#if defined(HAVE_STRPTIME) && defined(HAVE_MKTIME)
    struct tm tm;
    zlong mytime;
    char *endp;

    /*
     * Initialise all parameters to zero; there's no floating point
     * so memset() will do the trick.  The exception is that tm_isdst
     * is set to -1 which, if not overridden, will cause mktime()
     * to use the current timezone.  This is probably the best guess;
     * it's the one that will cause dates and times output by strftime
     * without the -r option and without an explicit timezone to be
     * converted back correctly.
     */
    (void)memset(&tm, 0, sizeof(tm));
    tm.tm_isdst = -1;
    endp = strptime(argv[1], argv[0], &tm);

    if (!endp) {
	/* Conversion failed completely. */
	if (!quiet)
	    zwarnnam(nam, "format not matched");
	return 1;
    }

    mytime = (zlong)mktime(&tm);

    if (scalar)
	setiparam(scalar, mytime);
    else {
	char buf[DIGBUFSIZE];
	convbase(buf, mytime, 10);
	printf("%s\n", buf);
    }

    if (*endp && !quiet) {
	/*
	 * Not everything in the input string was converted.
	 * This is probably benign, since the format has been satisfied,
	 * but issue a warning unless the quiet flag is set.
	 */
	zwarnnam(nam, "warning: input string not completely matched");
    }

    return 0;
#else
    if (!quiet)
	zwarnnam(nam, "not implemented on this system");
    return 2;
#endif
}
예제 #3
0
파일: zselect.c 프로젝트: AMDmi3/zsh
static int
bin_zselect(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
{
#ifdef HAVE_SELECT
    int i, fd, fdsetind = 0, fdmax = 0, fdcount;
    fd_set fdset[3];
    const char fdchar[3] = "rwe";
    struct timeval tv, *tvptr = NULL;
    char *outarray = "reply", **outdata, **outptr;
    char *outhash = NULL;
    LinkList fdlist;

    for (i = 0; i < 3; i++)
	FD_ZERO(fdset+i);

    for (; *args; args++) {
	char *argptr = *args, *endptr;
	zlong tempnum;
	if (*argptr == '-') {
	    for (argptr++; *argptr; argptr++) {
		switch (*argptr) {
		    /*
		     * Array name for reply, if not $reply.
		     * This gets set to e.g. `-r 0 -w 1' if 0 is ready
		     * for reading and 1 is ready for writing.
		     */
		case 'a':
		case 'A':
		    i = *argptr;
		    if (argptr[1])
			argptr++;
		    else if (args[1]) {
			argptr = *++args;
		    } else {
			zwarnnam(nam, "argument expected after -%c", *argptr);
			return 1;
		    }
		    if (idigit(*argptr) || !isident(argptr)) {
			zwarnnam(nam, "invalid array name: %s", argptr);
			return 1;
		    }
		    if (i == 'a')
			outarray = argptr;
		    else
			outhash = argptr;
		    /* set argptr to next to last char because of increment */
		    while (argptr[1])
			argptr++;
		    break;

		    /* Following numbers indicate fd's for reading */
		case 'r':
		    fdsetind = 0;
		    break;

		    /* Following numbers indicate fd's for writing */
		case 'w':
		    fdsetind = 1;
		    break;

		    /* Following numbers indicate fd's for errors */
		case 'e':
		    fdsetind = 2;
		    break;

		    /*
		     * Get a timeout value in hundredths of a second
		     * (same units as KEYTIMEOUT).  0 means just poll.
		     * If not given, blocks indefinitely.
		     */
		case 't':
		    if (argptr[1])
			argptr++;
		    else if (args[1]) {
			argptr = *++args;
		    } else {
			zwarnnam(nam, "argument expected after -%c", *argptr);
			return 1;
		    }
		    if (!idigit(*argptr)) {
			zwarnnam(nam, "number expected after -t");
			return 1;
		    }
		    tempnum = zstrtol(argptr, &endptr, 10);
		    if (*endptr) {
			zwarnnam(nam, "garbage after -t argument: %s",
				 endptr);
			return 1;
		    }
		    /* timevalue now active */
		    tvptr = &tv;
		    tv.tv_sec = (long)(tempnum / 100);
		    tv.tv_usec = (long)(tempnum % 100) * 10000L;

		    /* remember argptr is incremented at end of loop */
		    argptr = endptr - 1;
		    break;

		    /* Digits following option without arguments are fd's. */
		default:
		    if (handle_digits(nam, argptr, fdset+fdsetind,
				      &fdmax))
			return 1;
		}
	    }
	} else if (handle_digits(nam, argptr, fdset+fdsetind, &fdmax))
	    return 1;
    }

    errno = 0;
    do {
	i = select(fdmax, (SELECT_ARG_2_T)fdset, (SELECT_ARG_2_T)(fdset+1),
		   (SELECT_ARG_2_T)(fdset+2), tvptr);
    } while (i < 0 && errno == EINTR && !errflag);

    if (i <= 0) {
	if (i < 0)
	    zwarnnam(nam, "error on select: %e", errno);
	/* else no fd's set.  Presumably a timeout. */
	return 1;
    }

    /*
     * Make a linked list of all file descriptors which are ready.
     * These go into an array preceded by -r, -w or -e for read, write,
     * error as appropriate.  Typically there will only be one set
     * so this looks rather like overkill.
     */
    fdlist = znewlinklist();
    for (i = 0; i < 3; i++) {
	int doneit = 0;
	for (fd = 0; fd < fdmax; fd++) {
	    if (FD_ISSET(fd, fdset+i)) {
		char buf[BDIGBUFSIZE];
		if (outhash) {
		    /*
		     * Key/value pairs; keys are fd's (as strings),
		     * value is a (possibly improper) subset of "rwe".
		     */
		    LinkNode nptr;
		    int found = 0;

		    convbase(buf, fd, 10);
		    for (nptr = firstnode(fdlist); nptr; 
			 nptr = nextnode(nextnode(nptr))) {
			if (!strcmp((char *)getdata(nptr), buf)) {
			    /* Already there, add new character. */
			    void **dataptr = getaddrdata(nextnode(nptr));
			    char *data = (char *)*dataptr, *ptr;
			    found = 1;
			    if (!strchr(data, fdchar[i])) {
				strcpy(buf, data);
				for (ptr = buf; *ptr; ptr++)
				    ;
				*ptr++ = fdchar[i];
				*ptr = '\0';
				zsfree(data);
				*dataptr = ztrdup(buf);
			    }
			    break;
			}
		    }
		    if (!found) {
			/* Add new key/value pair. */
			zaddlinknode(fdlist, ztrdup(buf));
			buf[0] = fdchar[i];
			buf[1] = '\0';
			zaddlinknode(fdlist, ztrdup(buf));
		    }
		} else {
		    /* List of fd's preceded by -r, -w, -e. */
		    if (!doneit) {
			buf[0] = '-';
			buf[1] = fdchar[i];
			buf[2] = 0;
			zaddlinknode(fdlist, ztrdup(buf));
			doneit = 1;
		    }
		    convbase(buf, fd, 10);
		    zaddlinknode(fdlist, ztrdup(buf));
		}
	    }
	}
    }

    /* convert list to array */
    fdcount = countlinknodes(fdlist);
    outptr = outdata = (char **)zalloc((fdcount+1)*sizeof(char *));
    while (nonempty(fdlist))
	*outptr++ = getlinknode(fdlist);
    *outptr = NULL;
    /* and store in array parameter */
    if (outhash)
	sethparam(outhash, outdata);
    else
	setaparam(outarray, outdata);
    freelinklist(fdlist, NULL);

    return 0;
#else
    /* TODO: use poll */
    zerrnam(nam, "your system does not implement the select system call.");
    return 2;
#endif
}
예제 #4
0
static int
raw_getbyte(long do_keytmout, char *cptr)
{
    int ret;
    struct ztmout tmout;
#if defined(HAS_TIO) && \
  (defined(sun) || (!defined(HAVE_POLL) && !defined(HAVE_SELECT)))
    struct ttyinfo ti;
#endif
#ifndef HAVE_POLL
# ifdef HAVE_SELECT
    fd_set foofd, errfd;
    FD_ZERO(&errfd);
# endif
#endif

    calc_timeout(&tmout, do_keytmout);

    /*
     * Handle timeouts and watched fd's.  If a watched fd or a function
     * timeout triggers we restart any key timeout.  This is likely to
     * be harmless: the combination is extremely rare and a function
     * is likely to occupy the user for a little while anyway.  We used
     * to make timeouts take precedence, but we can't now that the
     * timeouts may be external, so we may have both a permanent watched
     * fd and a long-term timeout.
     */
    if ((nwatch || tmout.tp != ZTM_NONE)) {
#if defined(HAVE_SELECT) || defined(HAVE_POLL)
	int i, errtry = 0, selret;
# ifdef HAVE_POLL
	int nfds;
	struct pollfd *fds;
# endif
# if defined(HAS_TIO) && defined(sun)
	/*
	 * Yes, I know this is complicated.  Yes, I know we
	 * already have three bits of code to poll the terminal
	 * down below.  No, I don't want to do this either.
	 * However, it turns out on certain OSes, specifically
	 * Solaris, that you can't poll typeahead for love nor
	 * money without actually trying to read it.  But
	 * if we are trying to select (and we need to if we
	 * are watching other fd's) we won't pick that up.
	 * So we just try and read it without blocking in
	 * the time-honoured (i.e. absurdly baroque) termios
	 * fashion.
	 */
	gettyinfo(&ti);
	ti.tio.c_cc[VMIN] = 0;
	settyinfo(&ti);
	winch_unblock();
	ret = read(SHTTY, cptr, 1);
	winch_block();
	ti.tio.c_cc[VMIN] = 1;
	settyinfo(&ti);
	if (ret > 0)
	    return 1;
# endif
# ifdef HAVE_POLL
	nfds = 1 + nwatch;
	/* First pollfd is SHTTY, following are the nwatch fds */
	fds = zalloc(sizeof(struct pollfd) * nfds);
	fds[0].fd = SHTTY;
	/*
	 * POLLIN, POLLIN, POLLIN,
	 * Keep those fd's POLLIN...
	 */
	fds[0].events = POLLIN;
	for (i = 0; i < nwatch; i++) {
	    fds[i+1].fd = watch_fds[i].fd;
	    fds[i+1].events = POLLIN;
	}
# endif
	for (;;) {
# ifdef HAVE_POLL
	    int poll_timeout;

	    if (tmout.tp != ZTM_NONE)
		poll_timeout = tmout.exp100ths * 10;
	    else
		poll_timeout = -1;

	    winch_unblock();
	    selret = poll(fds, errtry ? 1 : nfds, poll_timeout);
	    winch_block();
# else
	    int fdmax = SHTTY;
	    struct timeval *tvptr;
	    struct timeval expire_tv;

	    FD_ZERO(&foofd);
	    FD_SET(SHTTY, &foofd);
	    if (!errtry) {
		for (i = 0; i < nwatch; i++) {
		    int fd = watch_fds[i].fd;
		    if (FD_ISSET(fd, &errfd))
			continue;
		    FD_SET(fd, &foofd);
		    if (fd > fdmax)
			fdmax = fd;
		}
	    }
	    FD_ZERO(&errfd);

	    if (tmout.tp != ZTM_NONE) {
		expire_tv.tv_sec = tmout.exp100ths / 100;
		expire_tv.tv_usec = (tmout.exp100ths % 100) * 10000L;
		tvptr = &expire_tv;
	    }
	    else
		tvptr = NULL;

	    winch_unblock();
	    selret = select(fdmax+1, (SELECT_ARG_2_T) & foofd,
			    NULL, NULL, tvptr);
	    winch_block();
# endif
	    /*
	     * Make sure a user interrupt gets passed on straight away.
	     */
	    if (selret < 0 && (errflag || retflag || breaks || exit_pending))
		break;
	    /*
	     * Try to avoid errors on our special fd's from
	     * messing up reads from the terminal.  Try first
	     * with all fds, then try unsetting the special ones.
	     */
	    if (selret < 0 && !errtry) {
		errtry = 1;
		continue;
	    }
	    if (selret == 0) {
		/*
		 * Nothing ready and no error, so we timed out.
		 */
		switch (tmout.tp) {
		case ZTM_NONE:
		    /* keeps compiler happy if not debugging */
#ifdef DEBUG
		    dputs("BUG: timeout fired with no timeout set.");
#endif
		    /* treat as if a key timeout triggered */
		    /*FALLTHROUGH*/
		case ZTM_KEY:
		    /* Special value -2 signals nothing ready */
		    selret = -2;
		    break;

		case ZTM_FUNC:
		    while (firstnode(timedfns)) {
			Timedfn tfdat = (Timedfn)getdata(firstnode(timedfns));
			/*
			 * It's possible a previous function took
			 * a long time to run (though it can't
			 * call zle recursively), so recalculate
			 * the time on each iteration.
			 */
			time_t now = time(NULL);
			if (tfdat->when > now)
			    break;
			tfdat->func();
		    }
		    /* Function may have messed up the display */
		    if (resetneeded)
			zrefresh();
		    /* We need to recalculate the timeout */
		    /*FALLTHROUGH*/
		case ZTM_MAX:
		    /*
		     * Reached the limit of our range, but not the
		     * actual timeout; recalculate the timeout.
		     * We're cheating with the key timeout here:
		     * if one clashed with a function timeout we
		     * reconsider the key timeout from scratch.
		     * The effect of this is microscopic.
		     */
		    calc_timeout(&tmout, do_keytmout);
		    break;
		}
		/*
		 * If we handled the timeout successfully,
		 * carry on.
		 */
		if (selret == 0)
		    continue;
	    }
	    /* If error or unhandled timeout, give up. */
	    if (selret < 0)
		break;
	    /*
	     * If there's user input handle it straight away.
	     * This improves the user's ability to handle exceptional
	     * conditions like runaway output.
	     */
	    if (
# ifdef HAVE_POLL
		 (fds[0].revents & POLLIN)
# else
		 FD_ISSET(SHTTY, &foofd)
# endif
		 )
		break;
	    if (nwatch && !errtry) {
		/*
		 * Copy the details of the watch fds in case the
		 * user decides to delete one from inside the
		 * handler function.
		 */
		int lnwatch = nwatch;
		Watch_fd lwatch_fds = zalloc(lnwatch*sizeof(struct watch_fd));
		memcpy(lwatch_fds, watch_fds, lnwatch*sizeof(struct watch_fd));
		for (i = 0; i < lnwatch; i++)
		    lwatch_fds[i].func = ztrdup(lwatch_fds[i].func);
		for (i = 0; i < lnwatch; i++) {
		    Watch_fd lwatch_fd = lwatch_fds + i;
		    if (
# ifdef HAVE_POLL
			(fds[i+1].revents & (POLLIN|POLLERR|POLLHUP|POLLNVAL))
# else
			FD_ISSET(lwatch_fd->fd, &foofd) ||
			FD_ISSET(lwatch_fd->fd, &errfd)
# endif
			) {
			/* Handle the fd. */
			char *fdbuf;
			{
			    char buf[BDIGBUFSIZE];
			    convbase(buf, lwatch_fd->fd, 10);
			    fdbuf = ztrdup(buf);
			}

			if (lwatch_fd->widget) {
			    zlecallhook(lwatch_fd->func, fdbuf);
			    zsfree(fdbuf);
			} else {
			    LinkList funcargs = znewlinklist();
			    zaddlinknode(funcargs, ztrdup(lwatch_fd->func));
			    zaddlinknode(funcargs, fdbuf);
# ifdef HAVE_POLL
#  ifdef POLLERR
			    if (fds[i+1].revents & POLLERR)
				zaddlinknode(funcargs, ztrdup("err"));
#  endif
#  ifdef POLLHUP
			    if (fds[i+1].revents & POLLHUP)
				zaddlinknode(funcargs, ztrdup("hup"));
#  endif
#  ifdef POLLNVAL
			    if (fds[i+1].revents & POLLNVAL)
				zaddlinknode(funcargs, ztrdup("nval"));
#  endif
# else
			    if (FD_ISSET(lwatch_fd->fd, &errfd))
				zaddlinknode(funcargs, ztrdup("err"));
# endif
			    callhookfunc(lwatch_fd->func, funcargs, 0, NULL);
			    freelinklist(funcargs, freestr);
			}
			if (errflag) {
			    /* No sensible way of handling errors here */
			    errflag &= ~ERRFLAG_ERROR;
			    /*
			     * Paranoia: don't run the hooks again this
			     * time.
			     */
			    errtry = 1;
			}
		    }
		}
		/* Function may have invalidated the display. */
		if (resetneeded)
		    zrefresh();
		for (i = 0; i < lnwatch; i++)
		    zsfree(lwatch_fds[i].func);
		zfree(lwatch_fds, lnwatch*sizeof(struct watch_fd));

# ifdef HAVE_POLL
		/* Function may have added or removed handlers */
		nfds = 1 + nwatch;
		if (nfds > 1) {
		    fds = zrealloc(fds, sizeof(struct pollfd) * nfds);
		    for (i = 0; i < nwatch; i++) {
			/*
			 * This is imperfect because it assumes fds[] and
			 * watch_fds[] remain in sync, which may be false
			 * if handlers are shuffled.  However, it should
			 * be harmless (e.g., produce one extra pass of
			 * the loop) in the event they fall out of sync.
			 */
			if (fds[i+1].fd == watch_fds[i].fd &&
			    (fds[i+1].revents & (POLLERR|POLLHUP|POLLNVAL))) {
			    fds[i+1].events = 0;	/* Don't poll this */
			} else {
			    fds[i+1].fd = watch_fds[i].fd;
			    fds[i+1].events = POLLIN;
			}
			fds[i+1].revents = 0;
		    }
		}
# endif
	    }
	}
# ifdef HAVE_POLL
	zfree(fds, sizeof(struct pollfd) * nfds);
# endif
	if (selret < 0)
	    return selret;
#else
# ifdef HAS_TIO
	ti = shttyinfo;
	ti.tio.c_lflag &= ~ICANON;
	ti.tio.c_cc[VMIN] = 0;
	ti.tio.c_cc[VTIME] = tmout.exp100ths / 10;
#  ifdef HAVE_TERMIOS_H
	tcsetattr(SHTTY, TCSANOW, &ti.tio);
#  else
	ioctl(SHTTY, TCSETA, &ti.tio);
#  endif
	winch_unblock();
	ret = read(SHTTY, cptr, 1);
	winch_block();
#  ifdef HAVE_TERMIOS_H
	tcsetattr(SHTTY, TCSANOW, &shttyinfo.tio);
#  else
	ioctl(SHTTY, TCSETA, &shttyinfo.tio);
#  endif
	return (ret <= 0) ? ret : *cptr;
# endif
#endif
    }

    winch_unblock();
    ret = read(SHTTY, cptr, 1);
    winch_block();

    return ret;
}
예제 #5
0
파일: pcre.c 프로젝트: Lujaw/zsh
static int
zpcre_get_substrings(char *arg, int *ovec, int ret, char *matchvar,
		     char *substravar, int want_offset_pair, int matchedinarr,
		     int want_begin_end)
{
    char **captures, *match_all, **matches;
    char offset_all[50];
    int capture_start = 1;

    if (matchedinarr)
	capture_start = 0;
    if (matchvar == NULL)
	matchvar = "MATCH";
    if (substravar == NULL)
	substravar = "match";
    
    /* captures[0] will be entire matched string, [1] first substring */
    if (!pcre_get_substring_list(arg, ovec, ret, (const char ***)&captures)) {
	int nelem = arrlen(captures)-1;
	/* Set to the offsets of the complete match */
	if (want_offset_pair) {
	    sprintf(offset_all, "%d %d", ovec[0], ovec[1]);
	    setsparam("ZPCRE_OP", ztrdup(offset_all));
	}
	match_all = metafy(captures[0], -1, META_DUP);
	setsparam(matchvar, match_all);
	/*
	 * If we're setting match, mbegin, mend we only do
	 * so if there were parenthesised matches, for consistency
	 * (c.f. regex.c).
	 */
	if (!want_begin_end || nelem) {
	    char **x, **y;
	    y = &captures[capture_start];
	    matches = x = (char **) zalloc(sizeof(char *) * (arrlen(y) + 1));
	    do {
		if (*y)
		    *x++ = metafy(*y, -1, META_DUP);
		else
		    *x++ = NULL;
	    } while (*y++);
	    setaparam(substravar, matches);
	}

	if (want_begin_end) {
	    char *ptr = arg;
	    zlong offs = 0;

	    /* Count the characters before the match */
	    MB_METACHARINIT();
	    while (ptr < arg + ovec[0]) {
		offs++;
		ptr += MB_METACHARLEN(ptr);
	    }
	    setiparam("MBEGIN", offs + !isset(KSHARRAYS));
	    /* Add on the characters in the match */
	    while (ptr < arg + ovec[1]) {
		offs++;
		ptr += MB_METACHARLEN(ptr);
	    }
	    setiparam("MEND", offs + !isset(KSHARRAYS) - 1);
	    if (nelem) {
		char **mbegin, **mend, **bptr, **eptr;
		int i, *ipair;

		bptr = mbegin = zalloc(sizeof(char*)*(nelem+1));
		eptr = mend = zalloc(sizeof(char*)*(nelem+1));

		for (ipair = ovec + 2, i = 0;
		     i < nelem;
		     ipair += 2, i++, bptr++, eptr++)
		{
		    char buf[DIGBUFSIZE];
		    ptr = arg;
		    offs = 0;
		    /* Find the start offset */
		    MB_METACHARINIT();
		    while (ptr < arg + ipair[0]) {
			offs++;
			ptr += MB_METACHARLEN(ptr);
		    }
		    convbase(buf, offs + !isset(KSHARRAYS), 10);
		    *bptr = ztrdup(buf);
		    /* Continue to the end offset */
		    while (ptr < arg + ipair[1]) {
			offs++;
			ptr += MB_METACHARLEN(ptr);
		    }
		    convbase(buf, offs + !isset(KSHARRAYS) - 1, 10);
		    *eptr = ztrdup(buf);
		}
		*bptr = *eptr = NULL;

		setaparam("mbegin", mbegin);
		setaparam("mend", mend);
	    }
	}

	pcre_free_substring_list((const char **)captures);
    }

    return 0;
}
예제 #6
0
파일: prompt.c 프로젝트: jackleaks/zsh
static int
putpromptchar(int doprint, int endchar, unsigned int *txtchangep)
{
    char *ss, *hostnam;
    int t0, arg, test, sep, j, numjobs;
    struct tm *tm;
    struct timezone dummy_tz;
    struct timeval tv;
    time_t timet;
    Nameddir nd;

    for (; *bv->fm && *bv->fm != endchar; bv->fm++) {
	arg = 0;
	if (*bv->fm == '%' && isset(PROMPTPERCENT)) {
	    int minus = 0;
	    bv->fm++;
	    if (*bv->fm == '-') {
		minus = 1;
		bv->fm++;
	    }
	    if (idigit(*bv->fm)) {
		arg = zstrtol(bv->fm, &bv->fm, 10);
		if (minus)
		    arg *= -1;
	    } else if (minus)
		arg = -1;
	    if (*bv->fm == '(') {
		int tc, otruncwidth;

		if (idigit(*++bv->fm)) {
		    arg = zstrtol(bv->fm, &bv->fm, 10);
		} else if (arg < 0) {
		    /* negative numbers don't make sense here */
		    arg *= -1;
		}
		test = 0;
		ss = pwd;
		switch (tc = *bv->fm) {
		case 'c':
		case '.':
		case '~':
		    if ((nd = finddir(ss))) {
			arg--;
			ss += strlen(nd->dir);
		    } /*FALLTHROUGH*/
		case '/':
		case 'C':
		    /* `/' gives 0, `/any' gives 1, etc. */
		    if (*ss++ == '/' && *ss)
			arg--;
		    for (; *ss; ss++)
			if (*ss == '/')
			    arg--;
		    if (arg <= 0)
			test = 1;
		    break;
		case 't':
		case 'T':
		case 'd':
		case 'D':
		case 'w':
		    timet = time(NULL);
		    tm = localtime(&timet);
		    switch (tc) {
		    case 't':
			test = (arg == tm->tm_min);
			break;
		    case 'T':
			test = (arg == tm->tm_hour);
			break;
		    case 'd':
			test = (arg == tm->tm_mday);
			break;
		    case 'D':
			test = (arg == tm->tm_mon);
			break;
		    case 'w':
			test = (arg == tm->tm_wday);
			break;
		    }
		    break;
		case '?':
		    if (lastval == arg)
			test = 1;
		    break;
		case '#':
		    if (geteuid() == (uid_t)arg)
			test = 1;
		    break;
		case 'g':
		    if (getegid() == (gid_t)arg)
			test = 1;
		    break;
		case 'j':
		    for (numjobs = 0, j = 1; j <= maxjob; j++)
			if (jobtab[j].stat && jobtab[j].procs &&
		    	    !(jobtab[j].stat & STAT_NOPRINT)) numjobs++;
		    if (numjobs >= arg)
		    	test = 1;
		    break;
		case 'l':
		    *bv->bp = '\0';
		    countprompt(bv->bufline, &t0, 0, 0);
		    if (minus)
			t0 = zterm_columns - t0;
		    if (t0 >= arg)
			test = 1;
		    break;
		case 'e':
		    {
			Funcstack fsptr = funcstack;
			test = arg;
			while (fsptr && test > 0) {
			    test--;
			    fsptr = fsptr->prev;
			}
			test = !test;
		    }
		    break;
		case 'L':
		    if (shlvl >= arg)
			test = 1;
		    break;
		case 'S':
		    if (time(NULL) - shtimer.tv_sec >= arg)
			test = 1;
		    break;
		case 'v':
		    if (arrlen(psvar) >= arg)
			test = 1;
		    break;
		case 'V':
		    if (arrlen(psvar) >= arg) {
			if (*psvar[(arg ? arg : 1) - 1])
			    test = 1;
		    }
		    break;
		case '_':
		    test = (cmdsp >= arg);
		    break;
		case '!':
		    test = privasserted();
		    break;
		default:
		    test = -1;
		    break;
		}
		if (!*bv->fm || !(sep = *++bv->fm))
		    return 0;
		bv->fm++;
		/* Don't do the current truncation until we get back */
		otruncwidth = bv->truncwidth;
		bv->truncwidth = 0;
		if (!putpromptchar(test == 1 && doprint, sep,
				   txtchangep) || !*++bv->fm ||
		    !putpromptchar(test == 0 && doprint, ')',
				   txtchangep)) {
		    bv->truncwidth = otruncwidth;
		    return 0;
		}
		bv->truncwidth = otruncwidth;
		continue;
	    }
	    if (!doprint)
		switch(*bv->fm) {
		  case '[':
		    while(idigit(*++bv->fm));
		    while(*++bv->fm != ']');
		    continue;
		  case '<':
		    while(*++bv->fm != '<');
		    continue;
		  case '>':
		    while(*++bv->fm != '>');
		    continue;
		  case 'D':
		    if(bv->fm[1]=='{')
			while(*++bv->fm != '}');
		    continue;
		  default:
		    continue;
		}
	    switch (*bv->fm) {
	    case '~':
		promptpath(pwd, arg, 1);
		break;
	    case 'd':
	    case '/':
		promptpath(pwd, arg, 0);
		break;
	    case 'c':
	    case '.':
		promptpath(pwd, arg ? arg : 1, 1);
		break;
	    case 'C':
		promptpath(pwd, arg ? arg : 1, 0);
		break;
	    case 'N':
		promptpath(scriptname ? scriptname : argzero, arg, 0);
		break;
	    case 'h':
	    case '!':
		addbufspc(DIGBUFSIZE);
		convbase(bv->bp, curhist, 10);
		bv->bp += strlen(bv->bp);
		break;
	    case 'j':
		for (numjobs = 0, j = 1; j <= maxjob; j++)
		    if (jobtab[j].stat && jobtab[j].procs &&
		    	!(jobtab[j].stat & STAT_NOPRINT)) numjobs++;
		addbufspc(DIGBUFSIZE);
		sprintf(bv->bp, "%d", numjobs);
		bv->bp += strlen(bv->bp);
		break;
	    case 'M':
		queue_signals();
		if ((hostnam = getsparam("HOST")))
		    stradd(hostnam);
		unqueue_signals();
		break;
	    case 'm':
		if (!arg)
		    arg++;
		queue_signals();
		if (!(hostnam = getsparam("HOST")))
		    break;
		if (arg < 0) {
		    for (ss = hostnam + strlen(hostnam); ss > hostnam; ss--)
			if (ss[-1] == '.' && !++arg)
			    break;
		    stradd(ss);
		} else {
		    for (ss = hostnam; *ss; ss++)
			if (*ss == '.' && !--arg)
			    break;
		    stradd(*ss ? dupstrpfx(hostnam, ss - hostnam) : hostnam);
		}
		unqueue_signals();
		break;
	    case 'S':
		txtchangeset(txtchangep, TXTSTANDOUT, TXTNOSTANDOUT);
		txtset(TXTSTANDOUT);
		tsetcap(TCSTANDOUTBEG, TSC_PROMPT);
		break;
	    case 's':
		txtchangeset(txtchangep, TXTNOSTANDOUT, TXTSTANDOUT);
		txtunset(TXTSTANDOUT);
		tsetcap(TCSTANDOUTEND, TSC_PROMPT|TSC_DIRTY);
		break;
	    case 'B':
		txtchangeset(txtchangep, TXTBOLDFACE, TXTNOBOLDFACE);
		txtset(TXTBOLDFACE);
		tsetcap(TCBOLDFACEBEG, TSC_PROMPT|TSC_DIRTY);
		break;
	    case 'b':
		txtchangeset(txtchangep, TXTNOBOLDFACE, TXTBOLDFACE);
		txtchangeset(txtchangep, TXTNOSTANDOUT, TXTSTANDOUT);
		txtchangeset(txtchangep, TXTNOUNDERLINE, TXTUNDERLINE);
		txtunset(TXTBOLDFACE);
		tsetcap(TCALLATTRSOFF, TSC_PROMPT|TSC_DIRTY);
		break;
	    case 'U':
		txtchangeset(txtchangep, TXTUNDERLINE, TXTNOUNDERLINE);
		txtset(TXTUNDERLINE);
		tsetcap(TCUNDERLINEBEG, TSC_PROMPT);
		break;
	    case 'u':
		txtchangeset(txtchangep, TXTNOUNDERLINE, TXTUNDERLINE);
		txtunset(TXTUNDERLINE);
		tsetcap(TCUNDERLINEEND, TSC_PROMPT|TSC_DIRTY);
		break;
	    case 'F':
		arg = parsecolorchar(arg, 1);
		if (arg >= 0 && !(arg & TXTNOFGCOLOUR)) {
		    txtchangeset(txtchangep, arg & TXT_ATTR_FG_ON_MASK,
				 TXTNOFGCOLOUR);
		    txtset(arg & TXT_ATTR_FG_ON_MASK);
		    set_colour_attribute(arg, COL_SEQ_FG, TSC_PROMPT);
		    break;
		}
		/* else FALLTHROUGH */
	    case 'f':
		txtchangeset(txtchangep, TXTNOFGCOLOUR, TXT_ATTR_FG_ON_MASK);
		txtunset(TXT_ATTR_FG_ON_MASK);
		set_colour_attribute(TXTNOFGCOLOUR, COL_SEQ_FG, TSC_PROMPT);
		break;
	    case 'K':
		arg = parsecolorchar(arg, 0);
		if (arg >= 0 && !(arg & TXTNOBGCOLOUR)) {
		    txtchangeset(txtchangep, arg & TXT_ATTR_BG_ON_MASK,
				 TXTNOBGCOLOUR);
		    txtset(arg & TXT_ATTR_BG_ON_MASK);
		    set_colour_attribute(arg, COL_SEQ_BG, TSC_PROMPT);
		    break;
		}
		/* else FALLTHROUGH */
	    case 'k':
		txtchangeset(txtchangep, TXTNOBGCOLOUR, TXT_ATTR_BG_ON_MASK);
		txtunset(TXT_ATTR_BG_ON_MASK);
		set_colour_attribute(TXTNOBGCOLOUR, COL_SEQ_BG, TSC_PROMPT);
		break;
	    case '[':
		if (idigit(*++bv->fm))
		    arg = zstrtol(bv->fm, &bv->fm, 10);
		if (!prompttrunc(arg, ']', doprint, endchar, txtchangep))
		    return *bv->fm;
		break;
	    case '<':
	    case '>':
		/* Test (minus) here so -0 means "at the right margin" */
		if (minus) {
		    *bv->bp = '\0';
		    countprompt(bv->bufline, &t0, 0, 0);
		    arg = zterm_columns - t0 + arg;
		    if (arg <= 0)
			arg = 1;
		}
		if (!prompttrunc(arg, *bv->fm, doprint, endchar, txtchangep))
		    return *bv->fm;
		break;
	    case '{': /*}*/
		if (!bv->dontcount++) {
		    addbufspc(1);
		    *bv->bp++ = Inpar;
		}
		if (arg <= 0)
		    break;
		/* else */
		/* FALLTHROUGH */
	    case 'G':
		if (arg > 0) {
		    addbufspc(arg);
		    while (arg--)
			*bv->bp++ = Nularg;
		} else {
		    addbufspc(1);
		    *bv->bp++ = Nularg;
		}
		break;
	    case /*{*/ '}':
		if (bv->trunccount && bv->trunccount >= bv->dontcount)
		    return *bv->fm;
		if (bv->dontcount && !--bv->dontcount) {
		    addbufspc(1);
		    *bv->bp++ = Outpar;
		}
		break;
	    case 't':
	    case '@':
	    case 'T':
	    case '*':
	    case 'w':
	    case 'W':
	    case 'D':
		{
		    char *tmfmt, *dd, *tmbuf = NULL;

		    switch (*bv->fm) {
		    case 'T':
			tmfmt = "%K:%M";
			break;
		    case '*':
			tmfmt = "%K:%M:%S";
			break;
		    case 'w':
			tmfmt = "%a %f";
			break;
		    case 'W':
			tmfmt = "%m/%d/%y";
			break;
		    case 'D':
			if (bv->fm[1] == '{' /*}*/) {
			    for (ss = bv->fm + 2; *ss && *ss != /*{*/ '}'; ss++)
				if(*ss == '\\' && ss[1])
				    ss++;
			    dd = tmfmt = tmbuf = zalloc(ss - bv->fm);
			    for (ss = bv->fm + 2; *ss && *ss != /*{*/ '}';
				 ss++) {
				if(*ss == '\\' && ss[1])
				    ss++;
				*dd++ = *ss;
			    }
			    *dd = 0;
			    bv->fm = ss - !*ss;
			    if (!*tmfmt) {
				free(tmbuf);
				continue;
			    }
			} else
			    tmfmt = "%y-%m-%d";
			break;
		    default:
			tmfmt = "%l:%M%p";
			break;
		    }
		    gettimeofday(&tv, &dummy_tz);
		    tm = localtime(&tv.tv_sec);
		    /*
		     * Hack because strftime won't say how
		     * much space it actually needs.  Try to add it
		     * a few times until it works.  Some formats don't
		     * actually have a length, so we could go on for
		     * ever.
		     */
		    for(j = 0, t0 = strlen(tmfmt)*8; j < 3; j++, t0*=2) {
			addbufspc(t0);
			if (ztrftime(bv->bp, t0, tmfmt, tm, tv.tv_usec) >= 0)
			    break;
		    }
		    /* There is enough room for this because addbufspc(t0)
		     * allocates room for t0 * 2 bytes. */
		    metafy(bv->bp, -1, META_NOALLOC);
		    bv->bp += strlen(bv->bp);
		    zsfree(tmbuf);
		    break;
		}
	    case 'n':
		stradd(get_username());
		break;
	    case 'l':
		if (*ttystrname) {
                   ss = (strncmp(ttystrname, "/dev/tty", 8) ?
                           ttystrname + 5 : ttystrname + 8);
		    stradd(ss);
		} else
		    stradd("()");
		break;
	    case 'y':
		if (*ttystrname) {
		    ss = (strncmp(ttystrname, "/dev/", 5) ?
			    ttystrname : ttystrname + 5);
		    stradd(ss);
		} else
		    stradd("()");
		break;
	    case 'L':
		addbufspc(DIGBUFSIZE);
#if defined(ZLONG_IS_LONG_LONG) && defined(PRINTF_HAS_LLD)
		sprintf(bv->bp, "%lld", shlvl);
#else
		sprintf(bv->bp, "%ld", (long)shlvl);
#endif
		bv->bp += strlen(bv->bp);
		break;
	    case '?':
		addbufspc(DIGBUFSIZE);
#if defined(ZLONG_IS_LONG_LONG) && defined(PRINTF_HAS_LLD)
		sprintf(bv->bp, "%lld", lastval);
#else
		sprintf(bv->bp, "%ld", (long)lastval);
#endif
		bv->bp += strlen(bv->bp);
		break;
	    case '%':
	    case ')':
		addbufspc(1);
		*bv->bp++ = *bv->fm;
		break;
	    case '#':
		addbufspc(1);
		*bv->bp++ = privasserted() ? '#' : '%';
		break;
	    case 'v':
		if (!arg)
		    arg = 1;
		else if (arg < 0)
		    arg += arrlen(psvar) + 1;
		if (arg > 0 && arrlen(psvar) >= arg)
		    stradd(psvar[arg - 1]);
		break;
	    case 'E':
                tsetcap(TCCLEAREOL, TSC_PROMPT);
		break;
	    case '^':
		if (cmdsp) {
		    if (arg >= 0) {
			if (arg > cmdsp || arg == 0)
			    arg = cmdsp;
			for (t0 = cmdsp - 1; arg--; t0--) {
			    stradd(cmdnames[cmdstack[t0]]);
			    if (arg) {
				addbufspc(1);
				*bv->bp++=' ';
			    }
			}
		    } else {
			arg = -arg;
			if (arg > cmdsp)
			    arg = cmdsp;
			for (t0 = arg - 1; arg--; t0--) {
			    stradd(cmdnames[cmdstack[t0]]);
			    if (arg) {
				addbufspc(1);
				*bv->bp++=' ';
			    }
			}
		    }
		}
		break;
	    case '_':
		if (cmdsp) {
		    if (arg >= 0) {
			if (arg > cmdsp || arg == 0)
			    arg = cmdsp;
			for (t0 = cmdsp - arg; arg--; t0++) {
			    stradd(cmdnames[cmdstack[t0]]);
			    if (arg) {
				addbufspc(1);
				*bv->bp++=' ';
			    }
			}
		    } else {
			arg = -arg;
			if (arg > cmdsp)
			    arg = cmdsp;
			for (t0 = 0; arg--; t0++) {
			    stradd(cmdnames[cmdstack[t0]]);
			    if (arg) {
				addbufspc(1);
				*bv->bp++=' ';
			    }
			}
		    }
		}
		break;
	    case 'r':
		if(bv->rstring)
		    stradd(bv->rstring);
		break;
	    case 'R':
		if(bv->Rstring)
		    stradd(bv->Rstring);
		break;
	    case 'e':
	    {
		int depth = 0;
		Funcstack fsptr = funcstack;
		while (fsptr) {
		    depth++;
		    fsptr = fsptr->prev;
		}
		addbufspc(DIGBUFSIZE);
		sprintf(bv->bp, "%d", depth);
		bv->bp += strlen(bv->bp);
		break;
	    }
	    case 'I':
		if (funcstack && funcstack->tp != FS_SOURCE &&
		    !IN_EVAL_TRAP()) {
		    /*
		     * We're in a function or an eval with
		     * EVALLINENO.  Calculate the line number in
		     * the file.
		     */
		    zlong flineno = lineno + funcstack->flineno;
		    /* take account of eval line nos. starting at 1 */
		    if (funcstack->tp == FS_EVAL)
			lineno--;
		    addbufspc(DIGBUFSIZE);
#if defined(ZLONG_IS_LONG_LONG) && defined(PRINTF_HAS_LLD)
		    sprintf(bv->bp, "%lld", flineno);
#else
		    sprintf(bv->bp, "%ld", (long)flineno);
#endif
		    bv->bp += strlen(bv->bp);
		    break;
		}
		/* else we're in a file and lineno is already correct */
		/* FALLTHROUGH */
	    case 'i':
		addbufspc(DIGBUFSIZE);
#if defined(ZLONG_IS_LONG_LONG) && defined(PRINTF_HAS_LLD)
		sprintf(bv->bp, "%lld", lineno);
#else
		sprintf(bv->bp, "%ld", (long)lineno);
#endif
		bv->bp += strlen(bv->bp);
		break;
	    case 'x':
		if (funcstack && funcstack->tp != FS_SOURCE &&
		    !IN_EVAL_TRAP())
		    promptpath(funcstack->filename ? funcstack->filename : "",
			       arg, 0);
		else
		    promptpath(scriptfilename ? scriptfilename : argzero,
			       arg, 0);
		break;
	    case '\0':
		return 0;
	    case Meta:
		bv->fm++;
		break;
	    }
	} else if(*bv->fm == '!' && isset(PROMPTBANG)) {
	    if(doprint) {
		if(bv->fm[1] == '!') {
		    bv->fm++;
		    addbufspc(1);
		    pputc('!');
		} else {
		    addbufspc(DIGBUFSIZE);
		    convbase(bv->bp, curhist, 10);
		    bv->bp += strlen(bv->bp);
		}
	    }
	} else {
	    char c = *bv->fm == Meta ? *++bv->fm ^ 32 : *bv->fm;

	    if (doprint) {
		addbufspc(1);
		pputc(c);
	    }
	}
    }

    return *bv->fm;
}
예제 #7
0
파일: math.c 프로젝트: blueyed/zsh
static mnumber
callmathfunc(char *o)
{
    MathFunc f;
    char *a, *n;
    static mnumber dummy;

    n = a = dupstring(o);

    while (*a != '(')
	a++;
    *a++ = '\0';
    a[strlen(a) - 1] = '\0';

    if ((f = getmathfunc(n, 1))) {
	if (f->flags & MFF_STR) {
	    return f->sfunc(n, a, f->funcid);
	} else {
	    int argc = 0;
	    mnumber *argv = NULL, *q, marg;
	    LinkList l = newlinklist();
	    LinkNode node;

	    if (f->flags & MFF_USERFUNC) {
		/* first argument is function name: always use mathfunc */
		addlinknode(l, n);
	    }

	    while (iblank(*a))
		a++;
	    while (*a) {
		if (*a) {
		    argc++;
		    if (f->flags & MFF_USERFUNC) {
			/* need to pass strings */
			char *str;
			marg = mathevall(a, MPREC_ARG, &a);
			if (marg.type & MN_FLOAT) {
			    /* convfloat is off the heap */
			    str = convfloat(marg.u.d, 0, 0, NULL);
			} else {
			    char buf[BDIGBUFSIZE];
			    convbase(buf, marg.u.l, 10);
			    str = dupstring(buf);
			}
			addlinknode(l, str);
		    } else {
			q = (mnumber *) zhalloc(sizeof(mnumber));
			*q = mathevall(a, MPREC_ARG, &a);
			addlinknode(l, q);
		    }
		    if (errflag || mtok != COMMA)
			break;
		}
	    }
	    if (*a && !errflag)
		zerr("bad math expression: illegal character: %c", *a);
	    if (!errflag) {
		if (argc >= f->minargs && (f->maxargs < 0 ||
					   argc <= f->maxargs)) {
		    if (f->flags & MFF_USERFUNC) {
			char *shfnam = f->module ? f->module : n;
			Shfunc shfunc = getshfunc(shfnam);
			if (!shfunc)
			    zerr("no such function: %s", shfnam);
			else {
			    doshfunc(shfunc, l, 1);
			    return lastmathval;
			}
		    } else {
			if (argc) {
			    q = argv =
				(mnumber *)zhalloc(argc * sizeof(mnumber));
			    for (node = firstnode(l); node; incnode(node))
				*q++ = *(mnumber *)getdata(node);
			}
			return f->nfunc(n, argc, argv, f->funcid);
		    }
		} else
		    zerr("wrong number of arguments: %s", o);
	    }
	}
    } else {
	zerr("unknown function: %s", n);
    }

    dummy.type = MN_INTEGER;
    dummy.u.l = 0;

    return dummy;
}
예제 #8
0
void
printparamnode(HashNode hn, int printflags)
{
#ifdef ZSH_64_BIT_TYPE
    static char llbuf[DIGBUFSIZE];
#endif
    Param p = (Param) hn;
    char *t, **u;

    if (p->flags & PM_UNSET)
	return;

    /* Print the attributes of the parameter */
    if (printflags & PRINT_TYPE) {
	if (p->flags & PM_INTEGER)
	    printf("integer ");
	if (p->flags & PM_ARRAY)
	    printf("array ");
	if (p->flags & PM_LEFT)
	    printf("left justified %d ", p->ct);
	if (p->flags & PM_RIGHT_B)
	    printf("right justified %d ", p->ct);
	if (p->flags & PM_RIGHT_Z)
	    printf("zero filled %d ", p->ct);
	if (p->flags & PM_LOWER)
	    printf("lowercase ");
	if (p->flags & PM_UPPER)
	    printf("uppercase ");
	if (p->flags & PM_READONLY)
	    printf("readonly ");
	if (p->flags & PM_TAGGED)
	    printf("tagged ");
	if (p->flags & PM_EXPORTED)
	    printf("exported ");
    }

    if (printflags & PRINT_NAMEONLY) {
	zputs(p->nam, stdout);
	putchar('\n');
	return;
    }

    /* How the value is displayed depends *
     * on the type of the parameter       */
    quotedzputs(p->nam, stdout);
    putchar('=');
    switch (PM_TYPE(p->flags)) {
    case PM_SCALAR:
	/* string: simple output */
	if (p->gets.cfn && (t = p->gets.cfn(p)))
	    quotedzputs(t, stdout);
	putchar('\n');
	break;
    case PM_INTEGER:
	/* integer */
#ifdef ZSH_64_BIT_TYPE
	convbase(llbuf, p->gets.ifn(p), 0);
	puts(llbuf);
#else
	printf("%ld\n", p->gets.ifn(p));
#endif
	break;
    case PM_ARRAY:
	/* array */
	putchar('(');
	u = p->gets.afn(p);
	if(*u) {
	    quotedzputs(*u++, stdout);
	    while (*u) {
		putchar(' ');
		quotedzputs(*u++, stdout);
	    }
	}
	printf(")\n");
	break;
    }
}
예제 #9
0
파일: regex.c 프로젝트: AMDmi3/zsh
static int
zcond_regex_match(char **a, int id)
{
    regex_t re;
    regmatch_t *m, *matches = NULL;
    size_t matchessz = 0;
    char *lhstr, *lhstr_zshmeta, *rhre, *rhre_zshmeta, *s, **arr, **x;
    int r, n, return_value, rcflags, reflags, nelem, start;

    lhstr_zshmeta = cond_str(a,0,0);
    rhre_zshmeta = cond_str(a,1,0);
    rcflags = reflags = 0;
    return_value = 0; /* 1 => matched successfully */

    lhstr = ztrdup(lhstr_zshmeta);
    unmetafy(lhstr, NULL);
    rhre = ztrdup(rhre_zshmeta);
    unmetafy(rhre, NULL);

    switch(id) {
    case ZREGEX_EXTENDED:
	rcflags |= REG_EXTENDED;
	if (!isset(CASEMATCH))
	    rcflags |= REG_ICASE;
	r = regcomp(&re, rhre, rcflags);
	if (r) {
	    zregex_regerrwarn(r, &re, "failed to compile regex");
	    break;
	}
	/* re.re_nsub is number of parenthesized groups, we also need
	 * 1 for the 0 offset, which is the entire matched portion
	 */
	if ((int)re.re_nsub < 0) {
	    zwarn("INTERNAL ERROR: regcomp() returned "
		    "negative subpattern count %d", (int)re.re_nsub);
	    break;
	}
	matchessz = (re.re_nsub + 1) * sizeof(regmatch_t);
	matches = zalloc(matchessz);
	r = regexec(&re, lhstr, re.re_nsub+1, matches, reflags);
	if (r == REG_NOMATCH)
	    ; /* We do nothing when we fail to match. */
	else if (r == 0) {
	    return_value = 1;
	    if (isset(BASHREMATCH)) {
		start = 0;
		nelem = re.re_nsub + 1;
	    } else {
		start = 1;
		nelem = re.re_nsub;
	    }
	    arr = NULL; /* bogus gcc warning of used uninitialised */
	    /* entire matched portion + re_nsub substrings + NULL */
	    if (nelem) {
		arr = x = (char **) zalloc(sizeof(char *) * (nelem + 1));
		for (m = matches + start, n = start; n <= (int)re.re_nsub; ++n, ++m, ++x) {
		    *x = metafy(lhstr + m->rm_so, m->rm_eo - m->rm_so, META_DUP);
		}
		*x = NULL;
	    }
	    if (isset(BASHREMATCH)) {
		setaparam("BASH_REMATCH", arr);
	    } else {
		zlong offs;
		char *ptr;
		int clen, leftlen;

		m = matches;
		s = metafy(lhstr + m->rm_so, m->rm_eo - m->rm_so, META_DUP);
		setsparam("MATCH", s);
		/*
		 * Count the characters before the match.
		 */
		ptr = lhstr;
		leftlen = m->rm_so;
		offs = 0;
		MB_CHARINIT();
		while (leftlen) {
		    offs++;
		    clen = MB_CHARLEN(ptr, leftlen);
		    ptr += clen;
		    leftlen -= clen;
		}
		setiparam("MBEGIN", offs + !isset(KSHARRAYS));
		/*
		 * Add on the characters in the match.
		 */
		leftlen = m->rm_eo - m->rm_so;
		while (leftlen) {
		    offs++;
		    clen = MB_CHARLEN(ptr, leftlen);
		    ptr += clen;
		    leftlen -= clen;
		}
		setiparam("MEND", offs + !isset(KSHARRAYS) - 1);
		if (nelem) {
		    char **mbegin, **mend, **bptr, **eptr;
		    bptr = mbegin = (char **)zalloc(sizeof(char *)*(nelem+1));
		    eptr = mend = (char **)zalloc(sizeof(char *)*(nelem+1));

		    for (m = matches + start, n = 0;
			 n < nelem;
			 ++n, ++m, ++bptr, ++eptr)
		    {
			char buf[DIGBUFSIZE];
			if (m->rm_so < 0 || m->rm_eo < 0) {
			    *bptr = ztrdup("-1");
			    *eptr = ztrdup("-1");
			    continue;
			}
			ptr = lhstr;
			leftlen = m->rm_so;
			offs = 0;
			/* Find the start offset */
			MB_CHARINIT();
			while (leftlen) {
			    offs++;
			    clen = MB_CHARLEN(ptr, leftlen);
			    ptr += clen;
			    leftlen -= clen;
			}
			convbase(buf, offs + !isset(KSHARRAYS), 10);
			*bptr = ztrdup(buf);
			/* Continue to the end offset */
			leftlen = m->rm_eo - m->rm_so;
			while (leftlen ) {
			    offs++;
			    clen = MB_CHARLEN(ptr, leftlen);
			    ptr += clen;
			    leftlen -= clen;
			}
			convbase(buf, offs + !isset(KSHARRAYS) - 1, 10);
			*eptr = ztrdup(buf);
		    }
		    *bptr = *eptr = NULL;

		    setaparam("match", arr);
		    setaparam("mbegin", mbegin);
		    setaparam("mend", mend);
		}
	    }
	}
	else
	    zregex_regerrwarn(r, &re, "regex matching error");
	break;
    default:
	DPUTS(1, "bad regex option");
	return_value = 0;
	goto CLEAN_BASEMETA;
    }

    if (matches)
	zfree(matches, matchessz);
    regfree(&re);
CLEAN_BASEMETA:
    free(lhstr);
    free(rhre);
    return return_value;
}
예제 #10
0
파일: tcp.c 프로젝트: zsh-users/zsh
static int
bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func))
{
    int herrno, err=1, destport, force=0, verbose=0, test=0, targetfd=0;
    ZSOCKLEN_T  len;
    char **addrp, *desthost;
    const char *localname, *remotename;
    struct hostent *zthost = NULL, *ztpeer = NULL;
    struct servent *srv;
    Tcp_session sess = NULL;

    if (OPT_ISSET(ops,'f'))
	force = 1;

    if (OPT_ISSET(ops,'v'))
	verbose = 1;

    if (OPT_ISSET(ops,'t'))
        test = 1;

    if (OPT_ISSET(ops,'d')) {
	targetfd = atoi(OPT_ARG(ops,'d'));
	if (!targetfd) {
	    zwarnnam(nam, "%s is an invalid argument to -d", OPT_ARG(ops,'d'));
	    return 1;
	}
    }


    if (OPT_ISSET(ops,'c')) {
	if (!args[0]) {
	    tcp_cleanup();
	}
	else {
	    targetfd = atoi(args[0]);
	    sess = zts_byfd(targetfd);
	    if(!targetfd) {
		zwarnnam(nam, "%s is an invalid argument to -c", args[0]);
		return 1;
	    }

	    if (sess)
	    {
		if ((sess->flags & ZTCP_ZFTP) && !force)
		{
		    zwarnnam(nam, "use -f to force closure of a zftp control connection");
		    return 1;
		}
		tcp_close(sess);
		return 0;
	    }
	    else
	    {
		zwarnnam(nam, "fd %s not found in tcp table", args[0]);
		return 1;
	    }
	}
    }
    else if (OPT_ISSET(ops,'l')) {
	int lport = 0;

	if (!args[0]) {
	    zwarnnam(nam, "-l requires an argument");
	    return 1;
	}

	srv = getservbyname(args[0], "tcp");
	if (srv)
	    lport = srv->s_port;
	else
	    lport = htons(atoi(args[0]));
	if (!lport) { zwarnnam(nam, "bad service name or port number");
	return 1;
	}
	sess = tcp_socket(PF_INET, SOCK_STREAM, 0, ZTCP_LISTEN);

	if (!sess) {
	    zwarnnam(nam, "unable to allocate a TCP session slot");
	    return 1;
	}
#ifdef SO_OOBINLINE
	len = 1;
	setsockopt(sess->fd, SOL_SOCKET, SO_OOBINLINE, (char *)&len, sizeof(len));
#endif
	if (!zsh_inet_aton("0.0.0.0", &(sess->sock.in.sin_addr)))
	{
	    zwarnnam(nam, "bad address: %s", "0.0.0.0");
	    return 1;
	}

	sess->sock.in.sin_family = AF_INET;
	sess->sock.in.sin_port = lport;


	if (bind(sess->fd, (struct sockaddr *)&sess->sock.in, sizeof(struct sockaddr_in)))
	{
	    char buf[DIGBUFSIZE];
	    convbase(buf, (zlong)ntohs(lport), 10);
	    zwarnnam(nam, "could not bind to port %s: %e", buf, errno);
	    tcp_close(sess);
	    return 1;
	}

	if (listen(sess->fd, 1))
	{
	    zwarnnam(nam, "could not listen on socket: %e", errno);
	    tcp_close(sess);
	    return 1;
	}

	if (targetfd) {
	    sess->fd = redup(sess->fd, targetfd);
	}
	else {
	    /* move the fd since no one will want to read from it */
	    sess->fd = movefd(sess->fd);
	}

	if (sess->fd == -1) {
	    zwarnnam(nam, "cannot duplicate fd %d: %e", sess->fd, errno);
	    tcp_close(sess);
	    return 1;
	}

	setiparam_no_convert("REPLY", (zlong)sess->fd);

	if (verbose)
	    printf("%d listener is on fd %d\n", ntohs(sess->sock.in.sin_port), sess->fd);

	return 0;

    }
    else if (OPT_ISSET(ops,'a'))
    {
	int lfd, rfd;

	if (!args[0]) {
	    zwarnnam(nam, "-a requires an argument");
	    return 1;
	}

	lfd = atoi(args[0]);

	if (!lfd) {
	    zwarnnam(nam, "invalid numerical argument");
	    return 1;
	}

	sess = zts_byfd(lfd);
	if (!sess) {
	    zwarnnam(nam, "fd %s is not registered as a tcp connection", args[0]);
	    return 1;
	}

	if (!(sess->flags & ZTCP_LISTEN))
	{
	    zwarnnam(nam, "tcp connection not a listener");
	    return 1;
	}

	if (test) {
#if defined(HAVE_POLL) || defined(HAVE_SELECT)
# ifdef HAVE_POLL
	    struct pollfd pfd;
	    int ret;

	    pfd.fd = lfd;
	    pfd.events = POLLIN;
	    if ((ret = poll(&pfd, 1, 0)) == 0) return 1;
	    else if (ret == -1)
	    {
		zwarnnam(nam, "poll error: %e", errno);
		return 1;
	    }
# else
	    fd_set rfds;
	    struct timeval tv;
	    int ret;
	    
	    FD_ZERO(&rfds);
	    FD_SET(lfd, &rfds);
	    tv.tv_sec = 0;
	    tv.tv_usec = 0;
	    
	    if ((ret = select(lfd+1, &rfds, NULL, NULL, &tv)) == 0) return 1;
	    else if (ret == -1)
	    {
		zwarnnam(nam, "select error: %e", errno);
		return 1;
	    }
	    
# endif
	    
#else
	    zwarnnam(nam, "not currently supported");
	    return 1;
#endif
	}
	sess = zts_alloc(ZTCP_INBOUND);

	len = sizeof(sess->peer.in);
	do {
	    rfd = accept(lfd, (struct sockaddr *)&sess->peer.in, &len);
	} while (rfd < 0 && errno == EINTR && !errflag);

	if (rfd == -1) {
	    zwarnnam(nam, "could not accept connection: %e", errno);
	    tcp_close(sess);
	    return 1;
	}

	/* redup expects fd is already registered */
	addmodulefd(rfd, FDT_MODULE);

	if (targetfd) {
	    sess->fd = redup(rfd, targetfd);
	    if (sess->fd < 0) {
		zerrnam(nam, "could not duplicate socket fd to %d: %e", targetfd, errno);
		return 1;
	    }
	}
	else {
	    sess->fd = rfd;
	}

	setiparam_no_convert("REPLY", (zlong)sess->fd);

	if (verbose)
	    printf("%d is on fd %d\n", ntohs(sess->peer.in.sin_port), sess->fd);
    }
    else
    {
	if (!args[0]) {
	    LinkNode node;
	    for(node = firstnode(ztcp_sessions); node; incnode(node))
	    {
		sess = (Tcp_session)getdata(node);

		if (sess->fd != -1)
		{
		    zthost = gethostbyaddr((const void *)&(sess->sock.in.sin_addr), sizeof(sess->sock.in.sin_addr), AF_INET);
		    if (zthost)
			localname = zthost->h_name;
		    else
			localname = inet_ntoa(sess->sock.in.sin_addr);
		    ztpeer = gethostbyaddr((const void *)&(sess->peer.in.sin_addr), sizeof(sess->peer.in.sin_addr), AF_INET);
		    if (ztpeer)
			remotename = ztpeer->h_name;
		    else
			remotename = inet_ntoa(sess->peer.in.sin_addr);
		    if (OPT_ISSET(ops,'L')) {
			int schar;
			if (sess->flags & ZTCP_ZFTP)
			    schar = 'Z';
			else if (sess->flags & ZTCP_LISTEN)
			    schar = 'L';
			else if (sess->flags & ZTCP_INBOUND)
			    schar = 'I';
			else
			    schar = 'O';
			printf("%d %c %s %d %s %d\n",
			       sess->fd, schar,
			       localname, ntohs(sess->sock.in.sin_port),
			       remotename, ntohs(sess->peer.in.sin_port));
		    } else {
			printf("%s:%d %s %s:%d is on fd %d%s\n",
			       localname, ntohs(sess->sock.in.sin_port),
			       ((sess->flags & ZTCP_LISTEN) ? "-<" :
				((sess->flags & ZTCP_INBOUND) ? "<-" : "->")),
			       remotename, ntohs(sess->peer.in.sin_port),
			       sess->fd,
			       (sess->flags & ZTCP_ZFTP) ? " ZFTP" : "");
		    }
		}
	    }
	    return 0;
	}
	else if (!args[1]) {
	    destport = htons(23);
	}
	else {

	    srv = getservbyname(args[1],"tcp");
	    if (srv)
		destport = srv->s_port;
	    else
		destport = htons(atoi(args[1]));
	}
	
	desthost = ztrdup(args[0]);
	
	zthost = zsh_getipnodebyname(desthost, AF_INET, 0, &herrno);
	if (!zthost || errflag) {
	    zwarnnam(nam, "host resolution failure: %s", desthost);
	    zsfree(desthost);
	    return 1;
	}
	
	sess = tcp_socket(PF_INET, SOCK_STREAM, 0, 0);

	if (!sess) {
	    zwarnnam(nam, "unable to allocate a TCP session slot");
	    zsfree(desthost);
	    return 1;
	}

#ifdef SO_OOBINLINE
	len = 1;
	setsockopt(sess->fd, SOL_SOCKET, SO_OOBINLINE, (char *)&len, sizeof(len));
#endif

	if (sess->fd < 0) {
	    zwarnnam(nam, "socket creation failed: %e", errno);
	    zsfree(desthost);
	    zts_delete(sess);
	    return 1;
	}
	
	for (addrp = zthost->h_addr_list; err && *addrp; addrp++) {
	    if (zthost->h_length != 4)
		zwarnnam(nam, "address length mismatch");
	    do {
		err = tcp_connect(sess, *addrp, zthost, destport);
	    } while (err && errno == EINTR && !errflag);
	}
	
	if (err) {
	    zwarnnam(nam, "connection failed: %e", errno);
	    tcp_close(sess);
	    zsfree(desthost);
	    return 1;
	}
	else
	{
	    if (targetfd) {
		sess->fd = redup(sess->fd, targetfd);
		if (sess->fd < 0) {
		    zerrnam(nam, "could not duplicate socket fd to %d: %e", targetfd, errno);
		    zsfree(desthost);
		    tcp_close(sess);
		    return 1;
		}
	    }

	    setiparam_no_convert("REPLY", (zlong)sess->fd);

	    if (verbose)
		printf("%s:%d is now on fd %d\n",
			desthost, destport, sess->fd);
	}
	
	zsfree(desthost);
    }

    return 0;
}
예제 #11
0
파일: stat.c 프로젝트: zsh-users/zsh
static void
statprint(struct stat *sbuf, char *outbuf, char *fname, int iwhich, int flags)
{
    char *optr = outbuf;

    if (flags & STF_NAME) {
	sprintf(outbuf, (flags & (STF_PICK|STF_ARRAY)) ?
		"%s " : "%-8s", statelts[iwhich]);
	optr += strlen(outbuf);
    }
    *optr = '\0';

    /* cast values to unsigned long as safest bet */
    switch (iwhich) {
    case ST_DEV:
	statulprint((unsigned long)sbuf->st_dev, optr);
	break;

    case ST_INO:
#ifdef INO_T_IS_64_BIT
	convbase(optr, sbuf->st_ino, 0);
#else
	DPUTS(sizeof(sbuf->st_ino) > sizeof(unsigned long),
	      "Shell compiled with wrong ino_t size");
	statulprint((unsigned long)sbuf->st_ino, optr);
#endif
	break;

    case ST_MODE:
	statmodeprint(sbuf->st_mode, optr, flags);
	break;

    case ST_NLINK:
	statulprint((unsigned long)sbuf->st_nlink, optr);
	break;

    case ST_UID:
	statuidprint(sbuf->st_uid, optr, flags);
	break;

    case ST_GID:
	statgidprint(sbuf->st_gid, optr, flags);
	break;

    case ST_RDEV:
	statulprint((unsigned long)sbuf->st_rdev, optr);
	break;

    case ST_SIZE:
#ifdef OFF_T_IS_64_BIT
	convbase(optr, sbuf->st_size, 0);
#else
	DPUTS(sizeof(sbuf->st_size) > sizeof(unsigned long),
	      "Shell compiled with wrong off_t size");
	statulprint((unsigned long)sbuf->st_size, optr);
#endif
	break;

    case ST_ATIM:
#ifdef GET_ST_ATIME_NSEC
	stattimeprint(sbuf->st_atime, GET_ST_ATIME_NSEC(*sbuf), optr, flags);
#else
	stattimeprint(sbuf->st_atime, 0L, optr, flags);
#endif
	break;

    case ST_MTIM:
#ifdef GET_ST_MTIME_NSEC
	stattimeprint(sbuf->st_mtime, GET_ST_MTIME_NSEC(*sbuf), optr, flags);
#else
	stattimeprint(sbuf->st_mtime, 0L, optr, flags);
#endif
	break;

    case ST_CTIM:
#ifdef GET_ST_CTIME_NSEC
	stattimeprint(sbuf->st_ctime, GET_ST_CTIME_NSEC(*sbuf), optr, flags);
#else
	stattimeprint(sbuf->st_ctime, 0L, optr, flags);
#endif
	break;

    case ST_BLKSIZE:
	statulprint((unsigned long)sbuf->st_blksize, optr);
	break;

    case ST_BLOCKS:
	statulprint((unsigned long)sbuf->st_blocks, optr);
	break;

    case ST_READLINK:
	statlinkprint(sbuf, optr, fname);
	break;

    case ST_COUNT:			/* keep some compilers happy */
	break;
    }
}
예제 #12
0
파일: typeuid2.c 프로젝트: spchamp/ilu
char *FigureTypeUID (Type t)
{
  struct buffer_s buffer;
  unsigned char hash[20];
  SHS_CTX ctx;
  static boolean initialized = FALSE;
  Type t2;

  if (! initialized)
    {
      verbose = (getenv ("ILU_TYPE_UID_VERBOSE") != NULL);
      initialized = TRUE;
    }


  if (type_uid(t) != NULL)
    return (type_uid(t));

  assert((t->importInterfaceName == NULL) || (type_kind(t) == alias_Type));

  if (type_kind(t) == alias_Type || t->importInterfaceName != NULL)
    return (type_uid(t) = ilu_strdup(FigureTypeUID(under_type(t))));

  if (type_kind(t) == object_Type &&
      class_object(t) != NULL &&
      class_object(t)->corba_rep_id != NULL)
    return (type_uid(t) = class_object(t)->corba_rep_id);

  if (verbose && !t->builtIn)
    fprintf(stderr,
	  "figuring 'ilut:' uid for <%s> (addr %p, ifc addr %p) from %s\n",
	    full_type_name(t), t, t->interface,
	    ((t->importInterfaceName != NULL)
	     ? t->importInterfaceName
	     : "(current ifc)"));
  buffer.data = (unsigned char *) iluparser_Malloc(buffer.size = 1024);
  buffer.used = 0;
  form_typedesc (t, &buffer);
  buffer.data[buffer.used] = '\0';

  if (verbose && ! t->builtIn)
    fprintf (stderr, "  buffer is <%*.*s>\n", buffer.used, buffer.used, buffer.data);

  SHSInit(&ctx);
  SHSUpdate (&ctx, buffer.data, buffer.used);
  SHSFinal (hash, &ctx);

/*
  {
    int i;

    fprintf (stderr, "  hash is ");
    for (i = 0;  i < 20;  i += 1)
      fprintf (stderr, "%u ", hash[i]);
    fprintf (stderr, "\n");
  }
*/

  type_uid(t) = (char *) iluparser_Malloc(40);
  strcpy (type_uid(t), "ilut:");
  /* convert to base 64 */
  convbase(hash,20,type_uid(t) + strlen(type_uid(t)));
  iluparser_Free(buffer.data);

  if (verbose && !t->builtIn)
    fprintf (stderr, "  uid for %s is %s\n", type_name(t), type_uid(t));

  if (iluparser_CString_Type == NULL &&
      t->importInterfaceName == NULL &&
      type_interface(t) != NULL &&
      strcmp(interface_name(type_interface(t)), "ilu") == 0 &&
      strcmp(type_name(t), "CString") == 0)
    iluparser_CString_Type = t;

  return (type_uid(t));
}