Exemple #1
0
static int
bin_pcre_compile(char *nam, char **args, Options ops, UNUSED(int func))
{
    int pcre_opts = 0, pcre_errptr;
    const char *pcre_error;
    
    if(OPT_ISSET(ops,'a')) pcre_opts |= PCRE_ANCHORED;
    if(OPT_ISSET(ops,'i')) pcre_opts |= PCRE_CASELESS;
    if(OPT_ISSET(ops,'m')) pcre_opts |= PCRE_MULTILINE;
    if(OPT_ISSET(ops,'x')) pcre_opts |= PCRE_EXTENDED;
    if(OPT_ISSET(ops,'s')) pcre_opts |= PCRE_DOTALL;
    
    if (zpcre_utf8_enabled())
	pcre_opts |= PCRE_UTF8;

    pcre_hints = NULL;  /* Is this necessary? */
    
    if (pcre_pattern)
	pcre_free(pcre_pattern);

    pcre_pattern = pcre_compile(*args, pcre_opts, &pcre_error, &pcre_errptr, NULL);
    
    if (pcre_pattern == NULL)
    {
	zwarnnam(nam, "error in regex: %s", pcre_error);
	return 1;
    }
    
    return 0;
}
Exemple #2
0
static int
bin_private(char *nam, char **args, LinkList assigns, Options ops, int func)
{
    int from_typeset = 1;
    makeprivate_error = 0;

    if (!OPT_ISSET(ops, 'P'))
        return bin_typeset(nam, args, assigns, ops, func);
    else if (OPT_ISSET(ops, 'T')) {
        zwarn("bad option: -T");
        return 1;
    }

    if (locallevel == 0) {
        if (isset(WARNCREATEGLOBAL))
            zwarnnam(nam, "invalid local scope, using globals");
        return bin_typeset("private", args, assigns, ops, func);
    }

    ops->ind['g'] = 2;	/* force bin_typeset() to behave as "local" */

    queue_signals();
    fakelevel = locallevel;
    startparamscope();
    from_typeset = bin_typeset("private", args, assigns, ops, func);
    scanhashtable(paramtab, 0, 0, 0, makeprivate, 0);
    endparamscope();
    fakelevel = 0;
    unqueue_signals();

    return makeprivate_error | from_typeset;
}
Exemple #3
0
static int
bin_sysopen(char *nam, char **args, Options ops, UNUSED(int func))
{
    int read = OPT_ISSET(ops, 'r');
    int write = OPT_ISSET(ops, 'w');
    int append = OPT_ISSET(ops, 'a') ? O_APPEND : 0;
    int flags = O_NOCTTY | append | ((append || write) ?
	(read ? O_RDWR : O_WRONLY) : O_RDONLY);
    char *opt, *ptr, *nextopt, *fdvar;
    int o, fd, explicit = -1;
    mode_t perms = 0666;
#if defined(FD_CLOEXEC) && !defined(O_CLOEXEC)
    int fdflags;
#endif

    if (!OPT_ISSET(ops, 'u')) {
	zwarnnam(nam, "file descriptor not specified");
	return 1;
    }

    /* file descriptor, either 0-9 or a variable name */
    fdvar = OPT_ARG(ops, 'u');
    if (idigit(*fdvar) && !fdvar[1]) {
	explicit = atoi(fdvar);
    } else if (!isident(fdvar)) {
Exemple #4
0
static int
bin_strftime(char *nam, char **argv, Options ops, UNUSED(int func))
{
    int bufsize, x;
    char *endptr = NULL, *scalar = NULL, *buffer;
    time_t secs;
    struct tm *t;

    if (OPT_ISSET(ops,'s')) {
	scalar = OPT_ARG(ops, 's');
	if (!isident(scalar)) {
	    zwarnnam(nam, "not an identifier: %s", scalar);
	    return 1;
	}
    }
    if (OPT_ISSET(ops, 'r'))
	return reverse_strftime(nam, argv, scalar, OPT_ISSET(ops, 'q'));

    errno = 0;
    secs = (time_t)strtoul(argv[1], &endptr, 10);
    if (errno != 0) {
	zwarnnam(nam, "%s: %e", argv[1], errno);
	return 1;
    } else if (*endptr != '\0') {
	zwarnnam(nam, "%s: invalid decimal number", argv[1]);
	return 1;
    }

    t = localtime(&secs);
    if (!t) {
	zwarnnam(nam, "%s: unable to convert to time", argv[1]);
	return 1;
    }
    bufsize = strlen(argv[0]) * 8;
    buffer = zalloc(bufsize);

    for (x=0; x < 4; x++) {
        if (ztrftime(buffer, bufsize, argv[0], t) >= 0)
	    break;
	buffer = zrealloc(buffer, bufsize *= 2);
    }

    if (scalar) {
	setsparam(scalar, metafy(buffer, -1, META_DUP));
    } else {
	printf("%s\n", buffer);
    }
    zfree(buffer, bufsize);

    return 0;
}
Exemple #5
0
static int
bin_mkdir(char *nam, char **args, Options ops, UNUSED(int func))
{
    mode_t oumask = umask(0);
    mode_t mode = 0777 & ~oumask;
    int err = 0;

    umask(oumask);
    if(OPT_ISSET(ops,'m')) {
	char *str = OPT_ARG(ops,'m'), *ptr;

	mode = zstrtol(str, &ptr, 8);
	if(!*str || *ptr) {
	    zwarnnam(nam, "invalid mode `%s'", str);
	    return 1;
	}
    }
    for(; *args; args++) {
	char *ptr = strchr(*args, 0);

	while(ptr > *args + (**args == '/') && *--ptr == '/')
	    *ptr = 0;
	if(OPT_ISSET(ops,'p')) {
	    char *ptr = *args;

	    for(;;) {
		while(*ptr == '/')
		    ptr++;
		while(*ptr && *ptr != '/')
		    ptr++;
		if(!*ptr) {
		    err |= domkdir(nam, *args, mode, 1);
		    break;
		} else {
		    int e;

		    *ptr = 0;
		    e = domkdir(nam, *args, mode | 0300, 1);
		    if(e) {
			err = 1;
			break;
		    }
		    *ptr = '/';
		}
	    }
	} else
	    err |= domkdir(nam, *args, mode, 0);
    }
    return err;
}
Exemple #6
0
static int
bin_syserror(char *nam, char **args, Options ops, UNUSED(int func))
{
    int num = 0;
    char *errvar = NULL, *msg, *pfx = "", *str;

    /* variable in which to write error message */
    if (OPT_ISSET(ops, 'e')) {
	errvar = OPT_ARG(ops, 'e');
	if (!isident(errvar)) {
	    zwarnnam(nam, "not an identifier: %s", errvar);
	    return 1;
	}
    }
    /* prefix for error message */
    if (OPT_ISSET(ops, 'p'))
	pfx = OPT_ARG(ops, 'p');

    if (!*args)
	num = errno;
    else {
	char *ptr = *args;
	while (*ptr && idigit(*ptr))
	    ptr++;
	if (!*ptr && ptr > *args)
	    num = atoi(*args);
	else {
	    const char **eptr;
	    for (eptr = sys_errnames; *eptr; eptr++) {
		if (!strcmp(*eptr, *args)) {
		    num = (eptr - sys_errnames) + 1;
		    break;
		}
	    }
	    if (!*eptr)
		return 2;
	}
    }

    msg = strerror(num);
    if (errvar) {
	str = (char *)zalloc(strlen(msg) + strlen(pfx) + 1);
	sprintf(str, "%s%s", pfx, msg);
	setsparam(errvar, str);
    } else {
	fprintf(stderr, "%s%s\n", pfx, msg);
    }

    return 0;
}
Exemple #7
0
static int
bin_getattr(char *nam, char **argv, Options ops, UNUSED(int func))
{
    int ret = 0;
    int val_len = 0, attr_len = 0, slen;
    char *value, *file = argv[0], *attr = argv[1], *param = argv[2];
    int symlink = OPT_ISSET(ops, 'h');

    unmetafy(file, &slen);
    unmetafy(attr, NULL);
    val_len = xgetxattr(file, attr, NULL, 0, symlink);
    if (val_len == 0) {
        if (param)
            unsetparam(param);
        return 0;
    }
    if (val_len > 0) {
        value = (char *)zalloc(val_len+1);
        attr_len = xgetxattr(file, attr, value, val_len, symlink);
        if (attr_len > 0 && attr_len <= val_len) {
            value[attr_len] = '\0';
            if (param)
                setsparam(param, metafy(value, attr_len, META_DUP));
            else
                printf("%s\n", value);
        }
        zfree(value, val_len+1);
    }
    if (val_len < 0 || attr_len < 0 || attr_len > val_len)  {
        zwarnnam(nam, "%s: %e", metafy(file, slen, META_NOALLOC), errno);
        ret = 1 + ((val_len > 0 && attr_len > val_len) || attr_len < 0);
    }
    return ret;
}
Exemple #8
0
static int
bin_zuntie(char *nam, char **args, Options ops, UNUSED(int func))
{
    Param pm;
    char *pmname;
    int ret = 0;

    for (pmname = *args; *args++; pmname = *args) {
	pm = (Param) paramtab->getnode(paramtab, pmname);
	if(!pm) {
	    zwarnnam(nam, "cannot untie %s", pmname);
	    ret = 1;
	    continue;
	}
	if (pm->gsu.h != &gdbm_hash_gsu) {
	    zwarnnam(nam, "not a tied gdbm hash: %s", pmname);
	    ret = 1;
	    continue;
	}

	queue_signals();
	if (OPT_ISSET(ops,'u'))
	    gdbmuntie(pm);	/* clear read-only-ness */
	if (unsetparam_pm(pm, 0, 1)) {
	    /* assume already reported */
	    ret = 1;
	}
	unqueue_signals();
    }

    return ret;
}
Exemple #9
0
static int
bin_rm(char *nam, char **args, Options ops, UNUSED(int func))
{
    struct rmmagic rmm;
    int err;

    rmm.nam = nam;
    rmm.opt_force = OPT_ISSET(ops,'f');
    rmm.opt_interact = OPT_ISSET(ops,'i') && !OPT_ISSET(ops,'f');
    rmm.opt_unlinkdir = OPT_ISSET(ops,'d');
    err = recursivecmd(nam, OPT_ISSET(ops,'f'), 
		       OPT_ISSET(ops,'r') && !OPT_ISSET(ops,'d'),
		       OPT_ISSET(ops,'s'),
	args, recurse_donothing, rm_dirpost, rm_leaf, &rmm);
    return OPT_ISSET(ops,'f') ? 0 : err;
}
Exemple #10
0
static int
bin_syswrite(char *nam, char **args, Options ops, UNUSED(int func))
{
    int outfd = 1, len, count, totcount;
    char *countvar = NULL;

    /* -o: output file descriptor if not stdout */
    if (OPT_ISSET(ops, 'o')) {
	outfd = getposint(OPT_ARG(ops, 'o'), nam);
	if (outfd < 0)
	    return 1;
    }

    /* -c: variable in which to store count of bytes written */
    if (OPT_ISSET(ops, 'c')) {
	countvar = OPT_ARG(ops, 'c');
	if (!isident(countvar)) {
	    zwarnnam(nam, "not an identifier: %s", countvar);
	    return 1;
	}
    }

    totcount = 0;
    unmetafy(*args, &len);
    while (len) {
	while ((count = write(outfd, *args, len)) < 0) {
	    if (errno != EINTR || errflag || retflag || breaks || contflag)
	    {
		if (countvar)
		    setiparam(countvar, totcount);
		return 2;
	    }
	}
	*args += count;
	totcount += count;
	len -= count;
    }
    if (countvar)
	setiparam(countvar, totcount);

    return 0;
}
Exemple #11
0
static int
bin_listattr(char *nam, char **argv, Options ops, UNUSED(int func))
{
    int ret = 0;
    int val_len, list_len = 0, slen;
    char *value, *file = argv[0], *param = argv[1];
    int symlink = OPT_ISSET(ops, 'h');

    unmetafy(file, &slen);
    val_len = xlistxattr(file, NULL, 0, symlink);
    if (val_len == 0) {
        if (param)
            unsetparam(param);
        return 0;
    }
    if (val_len > 0) {
        value = (char *)zalloc(val_len+1);
        list_len = xlistxattr(file, value, val_len, symlink);
        if (list_len > 0 && list_len <= val_len) {
            char *p = value;
            if (param) {
                if (strlen(value) + 1 == list_len)
                    setsparam(param, metafy(value, list_len-1, META_DUP));
                else {
                    int arrlen = 0;
                    char **array = NULL, **arrptr = NULL;

                    while (p < &value[list_len]) {
                        arrlen++;
                        p += strlen(p) + 1;
                    }
                    arrptr = array = (char **)zshcalloc((arrlen+1) * sizeof(char *));
                    p = value;
                    while (p < &value[list_len]) {
                        *arrptr++ = metafy(p, -1, META_DUP);
                        p += strlen(p) + 1;
                    }
                    setaparam(param, array);
                }
            } else while (p < &value[list_len]) {
                printf("%s\n", p);
                p += strlen(p) + 1;
            }
        }
        zfree(value, val_len+1);
    }
    if (val_len < 0 || list_len < 0 || list_len > val_len) {
        zwarnnam(nam, "%s: %e", metafy(file, slen, META_NOALLOC), errno);
        ret = 1 + (list_len > val_len || list_len < 0);
    }
    return ret;
}
Exemple #12
0
static int
bin_setattr(char *nam, char **argv, Options ops, UNUSED(int func))
{
    int ret = 0, slen, vlen;
    int symlink = OPT_ISSET(ops, 'h');
    char *file = argv[0], *attr = argv[1], *value = argv[2];

    unmetafy(file, &slen);
    unmetafy(attr, NULL);
    unmetafy(value, &vlen);
    if (xsetxattr(file, attr, value, vlen, 0, symlink)) {
        zwarnnam(nam, "%s: %e", metafy(file, slen, META_NOALLOC), errno);
        ret = 1;
    }
    return ret;
}
Exemple #13
0
static int
bin_delattr(char *nam, char **argv, Options ops, UNUSED(int func))
{
    int ret = 0, slen;
    int symlink = OPT_ISSET(ops, 'h');
    char *file = argv[0], **attr = argv;

    unmetafy(file, &slen);
    while (*++attr) {
        unmetafy(*attr, NULL);
        if (xremovexattr(file, *attr, symlink)) {
            zwarnnam(nam, "%s: %e", metafy(file, slen, META_NOALLOC), errno);
            ret = 1;
            break;
        }
    }
    return ret;
}
Exemple #14
0
static int
bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func))
{
    int ret, capcount, *ovec, ovecsize;
    char *receptacle = NULL;
    
    if(OPT_ISSET(ops,'a')) {
	receptacle = *args++;
	if(!*args) {
	    zwarnnam(nam, "not enough arguments", NULL, 0);
	    return 1;
	}
    }
    
    if ((ret = pcre_fullinfo(pcre_pattern, pcre_hints, PCRE_INFO_CAPTURECOUNT, &capcount)))
    {
	zwarnnam(nam, "error %d in fullinfo", NULL, ret);
	return 1;
    }
    
    ovecsize = (capcount+1)*3;
    ovec = zalloc(ovecsize*sizeof(int));
    
    ret = pcre_exec(pcre_pattern, pcre_hints, *args, strlen(*args), 0, 0, ovec, ovecsize);
    
    if (ret==0) return 0;
    else if (ret==PCRE_ERROR_NOMATCH) return 1; /* no match */
    else if (ret>0) {
	zpcre_get_substrings(*args, ovec, ret, receptacle);
	return 0;
    }
    else {
	zwarnnam(nam, "error in pcre_exec", NULL, 0);
	return 1;
    }
    
    return 1;
}
Exemple #15
0
static int
bin_ln(char *nam, char **args, Options ops, int func)
{
    MoveFunc movefn;
    int flags, have_dir, err = 0;
    char **a, *ptr, *rp, *buf;
    struct stat st;
    size_t blen;


    if(func == BIN_MV) {
	movefn = (MoveFunc) rename;
	flags = OPT_ISSET(ops,'f') ? 0 : MV_ASKNW;
	flags |= MV_ATOMIC;
    } else {
	flags = OPT_ISSET(ops,'f') ? MV_FORCE : 0;
#ifdef HAVE_LSTAT
	if(OPT_ISSET(ops,'h') || OPT_ISSET(ops,'n'))
	    flags |= MV_NOCHASETARGET;
	if(OPT_ISSET(ops,'s'))
	    movefn = (MoveFunc) symlink;
	else
#endif
	{
	    movefn = (MoveFunc) link;
	    if(!OPT_ISSET(ops,'d'))
		flags |= MV_NODIRS;
	}
    }
    if(OPT_ISSET(ops,'i') && !OPT_ISSET(ops,'f'))
	flags |= MV_INTERACTIVE;
    for(a = args; a[1]; a++) ;
    if(a != args) {
	rp = unmeta(*a);
	if(rp && !stat(rp, &st) && S_ISDIR(st.st_mode)) {
	    have_dir = 1;
	    if((flags & MV_NOCHASETARGET)
	      && !lstat(rp, &st) && S_ISLNK(st.st_mode)) {
		/*
		 * So we have "ln -h" with the target being a symlink pointing
		 * to a directory; if there are multiple sources but the target
		 * is a symlink, then it's an error as we're not following
		 * symlinks; if OTOH there's just one source, then we need to
		 * either fail EEXIST or if "-f" given then remove the target.
		 */
		if(a > args+1) {
		    errno = ENOTDIR;
		    zwarnnam(nam, "%s: %e", *a, errno);
		    return 1;
		}
		if(flags & MV_FORCE) {
		    unlink(rp);
		    have_dir = 0;
		} else {
		    errno = EEXIST;
		    zwarnnam(nam, "%s: %e", *a, errno);
		    return 1;
		}
	    }
	    /* Normal case, target is a directory, chase into it */
	    if (have_dir)
		goto havedir;
	}
    }
    if(a > args+1) {
	zwarnnam(nam, "last of many arguments must be a directory");
	return 1;
    }
    if(!args[1]) {
	ptr = strrchr(args[0], '/');
	if(ptr)
	    args[1] = ptr+1;
	else
	    args[1] = args[0];
    }
    return domove(nam, movefn, args[0], args[1], flags);
 havedir:
    buf = ztrdup(*a);
    *a = NULL;
    buf = appstr(buf, "/");
    blen = strlen(buf);
    for(; *args; args++) {

	ptr = strrchr(*args, '/');
	if(ptr)
	    ptr++;
	else
	    ptr = *args;

	buf[blen] = 0;
	buf = appstr(buf, ptr);
	err |= domove(nam, movefn, *args, buf, flags);
    }
    zsfree(buf);
    return err;
}
Exemple #16
0
Fichier : pcre.c Projet : Lujaw/zsh
static int
bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func))
{
    int ret, capcount, *ovec, ovecsize, c;
    char *matched_portion = NULL;
    char *plaintext = NULL;
    char *receptacle = NULL;
    int return_value = 1;
    /* The subject length and offset start are both int values in pcre_exec */
    int subject_len;
    int offset_start = 0;
    int want_offset_pair = 0;

    if (pcre_pattern == NULL) {
	zwarnnam(nam, "no pattern has been compiled");
	return 1;
    }
    
    if(OPT_HASARG(ops,c='a')) {
	receptacle = OPT_ARG(ops,c);
    }
    if(OPT_HASARG(ops,c='v')) {
	matched_portion = OPT_ARG(ops,c);
    }
    if(OPT_HASARG(ops,c='n')) { /* The offset position to start the search, in bytes. */
	offset_start = getposint(OPT_ARG(ops,c), nam);
    }
    /* For the entire match, 'Return' the offset byte positions instead of the matched string */
    if(OPT_ISSET(ops,'b')) want_offset_pair = 1; 

    if(!*args) {
	zwarnnam(nam, "not enough arguments");
    }
    
    if ((ret = pcre_fullinfo(pcre_pattern, pcre_hints, PCRE_INFO_CAPTURECOUNT, &capcount)))
    {
	zwarnnam(nam, "error %d in fullinfo", ret);
	return 1;
    }

    ovecsize = (capcount+1)*3;
    ovec = zalloc(ovecsize*sizeof(int));

    plaintext = ztrdup(*args);
    unmetafy(plaintext, NULL);
    subject_len = (int)strlen(plaintext);

    if (offset_start < 0 || offset_start >= subject_len)
	ret = PCRE_ERROR_NOMATCH;
    else
	ret = pcre_exec(pcre_pattern, pcre_hints, plaintext, subject_len, offset_start, 0, ovec, ovecsize);

    if (ret==0) return_value = 0;
    else if (ret==PCRE_ERROR_NOMATCH) /* no match */;
    else if (ret>0) {
	zpcre_get_substrings(plaintext, ovec, ret, matched_portion, receptacle,
			     want_offset_pair, 0, 0);
	return_value = 0;
    }
    else {
	zwarnnam(nam, "error in pcre_exec [%d]", ret);
    }
    
    if (ovec)
	zfree(ovec, ovecsize*sizeof(int));

    return return_value;
}
Exemple #17
0
static int
bin_vared(char *name, char **args, Options ops, UNUSED(int func))
{
    char *s, *t, *ova = varedarg;
    struct value vbuf;
    Value v;
    Param pm = 0;
    int ifl;
    int type = PM_SCALAR, obreaks = breaks, haso = 0, oSHTTY = 0;
    char *p1, *p2, *main_keymapname, *vicmd_keymapname, *init, *finish;
    Keymap main_keymapsave = NULL, vicmd_keymapsave = NULL;
    FILE *oshout = NULL;

    if ((interact && unset(USEZLE)) || !strcmp(term, "emacs")) {
	zwarnnam(name, "ZLE not enabled");
	return 1;
    }
    if (zleactive) {
	zwarnnam(name, "ZLE cannot be used recursively (yet)");
	return 1;
    }

    if (OPT_ISSET(ops,'A'))
    {
	if (OPT_ISSET(ops, 'a'))
	{
	    zwarnnam(name, "specify only one of -a and -A");
	    return 1;
	}
	type = PM_HASHED;
    }
    else if (OPT_ISSET(ops,'a'))
	type = PM_ARRAY;
    p1 = OPT_ARG_SAFE(ops,'p');
    p2 = OPT_ARG_SAFE(ops,'r');
    main_keymapname = OPT_ARG_SAFE(ops,'M');
    vicmd_keymapname = OPT_ARG_SAFE(ops,'m');
    init = OPT_ARG_SAFE(ops,'i');
    finish = OPT_ARG_SAFE(ops,'f');

    if (type != PM_SCALAR && !OPT_ISSET(ops,'c')) {
	zwarnnam(name, "-%s ignored", type == PM_ARRAY ? "a" : "A");
    }

    /* handle non-existent parameter */
    s = args[0];
    queue_signals();
    v = fetchvalue(&vbuf, &s, (!OPT_ISSET(ops,'c') || type == PM_SCALAR),
		   SCANPM_WANTKEYS|SCANPM_WANTVALS|SCANPM_MATCHMANY);
    if (!v && !OPT_ISSET(ops,'c')) {
	unqueue_signals();
	zwarnnam(name, "no such variable: %s", args[0]);
	return 1;
    } else if (v) {
	if (*s) {
	    zwarnnam(name, "not an identifier: `%s'", args[0]);
	    return 1;
	}
	if (v->isarr) {
	    /* Array: check for separators and quote them. */
	    char **arr = getarrvalue(v), **aptr, **tmparr, **tptr;
	    tptr = tmparr = (char **)zhalloc(sizeof(char *)*(arrlen(arr)+1));
	    for (aptr = arr; *aptr; aptr++) {
		int sepcount = 0, clen;
		convchar_t c;
		/*
		 * See if this word contains a separator character
		 * or backslash
		 */
		MB_METACHARINIT();
		for (t = *aptr; *t; ) {
		    if (*t == '\\') {
			t++;
			sepcount++;
		    } else {
			t += MB_METACHARLENCONV(t, &c);
			if (WC_ZISTYPE(c, ISEP))
			    sepcount++;
		    }
		}
		if (sepcount) {
		    /* Yes, so allocate enough space to quote it. */
		    char *newstr, *nptr;
		    newstr = zhalloc(strlen(*aptr)+sepcount+1);
		    /* Go through string quoting separators */
		    MB_METACHARINIT();
		    for (t = *aptr, nptr = newstr; *t; ) {
			if (*t == '\\') {
			    *nptr++ = '\\';
			    *nptr++ = *t++;
			} else {
			    clen = MB_METACHARLENCONV(t, &c);
			    if (WC_ZISTYPE(c, ISEP))
				*nptr++ = '\\';
			    while (clen--)
				*nptr++ = *t++;
			}
		    }
		    *nptr = '\0';
		    /* Stick this into the array of words to join up */
		    *tptr++ = newstr;
		} else
		    *tptr++ = *aptr; /* No, keep original array element */
	    }
	    *tptr = NULL;
	    s = sepjoin(tmparr, NULL, 0);
	} else {
	    s = ztrdup(getstrvalue(v));
	}
	unqueue_signals();
    } else if (*s) {
	unqueue_signals();
	zwarnnam(name, "invalid parameter name: %s", args[0]);
	return 1;
    } else {
	unqueue_signals();
	s = ztrdup(s);
    }

    if (SHTTY == -1 || OPT_ISSET(ops,'t')) {
	/* need to open /dev/tty specially */
	oSHTTY = SHTTY;
	if ((SHTTY = open(OPT_ISSET(ops,'t') ? OPT_ARG(ops,'t') : "/dev/tty",
			  O_RDWR|O_NOCTTY)) == -1) {
	    zwarnnam(name, "can't access terminal");
	    zsfree(s);
	    return 1;
	}
	if (!isatty(SHTTY)) {
	    zwarnnam(name, "%s: not a terminal", OPT_ARG(ops,'t'));
	    close(SHTTY);
	    SHTTY = oSHTTY;
	    zsfree(s);
	    return 1;
	}
	oshout = shout;
	init_shout();

	haso = 1;
    }

    /* edit the parameter value */
    zpushnode(bufstack, s);

    if (main_keymapname &&
	savekeymap(name, "main", main_keymapname, &main_keymapsave))
	main_keymapname = NULL;
    if (vicmd_keymapname &&
	savekeymap(name, "vicmd", vicmd_keymapname, &vicmd_keymapsave))
	vicmd_keymapname = NULL;

    varedarg = *args;
    ifl = isfirstln;
    if (OPT_ISSET(ops,'h'))
	hbegin(2);
    isfirstln = OPT_ISSET(ops,'e');

    t = zleread(&p1, &p2, OPT_ISSET(ops,'h') ? ZLRF_HISTORY : 0, ZLCON_VARED,
		init ? init : "zle-line-init",
		finish ? finish : "zle-line-finish");
    if (OPT_ISSET(ops,'h'))
	hend(NULL);
    isfirstln = ifl;
    varedarg = ova;

    restorekeymap(name, "main", main_keymapname, main_keymapsave);
    restorekeymap(name, "vicmd", vicmd_keymapname, vicmd_keymapsave);

    if (haso) {
	fclose(shout);	/* close(SHTTY) */
	shout = oshout;
	SHTTY = oSHTTY;
    }
    if (!t || errflag) {
	/* error in editing */
	errflag &= ~ERRFLAG_ERROR;
	breaks = obreaks;
	if (t)
	    zsfree(t);
	return 1;
    }
    /* strip off trailing newline, if any */
    if (t[strlen(t) - 1] == '\n')
	t[strlen(t) - 1] = '\0';
    /* final assignment of parameter value */
    if (OPT_ISSET(ops,'c')) {
	unsetparam(args[0]);
	createparam(args[0], type);
    }
    queue_signals();
    pm = (Param) paramtab->getnode(paramtab, args[0]);
    if (pm && (PM_TYPE(pm->node.flags) & (PM_ARRAY|PM_HASHED))) {
	char **a;

	/*
	 * Use spacesplit with fourth argument 1: identify quoted separators,
	 * and unquote.  This duplicates the string, so we still need to free.
	 */
	a = spacesplit(t, 1, 0, 1);
	zsfree(t);
	if (PM_TYPE(pm->node.flags) == PM_ARRAY)
	    setaparam(args[0], a);
	else
	    sethparam(args[0], a);
    } else
	setsparam(args[0], t);
    unqueue_signals();
    return 0;
}
Exemple #18
0
static int
bin_sysread(char *nam, char **args, Options ops, UNUSED(int func))
{
    int infd = 0, outfd = -1, bufsize = SYSREAD_BUFSIZE, count;
    char *outvar = NULL, *countvar = NULL, *inbuf;

    /* -i: input file descriptor if not stdin */
    if (OPT_ISSET(ops, 'i')) {
	infd = getposint(OPT_ARG(ops, 'i'), nam);
	if (infd < 0)
	    return 1;
    }

    /* -o: output file descriptor, else store in REPLY */
    if (OPT_ISSET(ops, 'o')) {
	if (*args) {
	    zwarnnam(nam, "no argument allowed with -o");
	    return 1;
	}
	outfd = getposint(OPT_ARG(ops, 'o'), nam);
	if (outfd < 0)
	    return 1;
    }

    /* -s: buffer size if not default SYSREAD_BUFSIZE */
    if (OPT_ISSET(ops, 's')) {
	bufsize = getposint(OPT_ARG(ops, 's'), nam);
	if (bufsize < 0)
	    return 1;
    }

    /* -c: name of variable to store count of transferred bytes */
    if (OPT_ISSET(ops, 'c')) {
	countvar = OPT_ARG(ops, 'c');
	if (!isident(countvar)) {
	    zwarnnam(nam, "not an identifier: %s", countvar);
	    return 1;
	}
    }

    if (*args) {
	/*
	 * Variable in which to store result if doing a plain read.
	 * Default variable if not specified is REPLY.
	 * If writing, only stuff we couldn't write is stored here,
	 * no default in that case (we just discard it if no variable).
	 */
	outvar = *args;
	if (!isident(outvar)) {
	    zwarnnam(nam, "not an identifier: %s", outvar);
	    return 1;
	}
    }

    inbuf = zhalloc(bufsize);

#if defined(HAVE_POLL) || defined(HAVE_SELECT)
    /* -t: timeout */
    if (OPT_ISSET(ops, 't'))
    {
# ifdef HAVE_POLL
	struct pollfd poll_fd;
	mnumber to_mn;
	int to_int, ret;

	poll_fd.fd = infd;
	poll_fd.events = POLLIN;

	to_mn = matheval(OPT_ARG(ops, 't'));
	if (errflag)
	    return 1;
	if (to_mn.type == MN_FLOAT)
	    to_int = (int) (1000 * to_mn.u.d);
	else
	    to_int = 1000 * (int)to_mn.u.l;

	while ((ret = poll(&poll_fd, 1, to_int)) < 0) {
	    if (errno != EINTR || errflag || retflag || breaks || contflag)
		break;
	}
	if (ret <= 0) {
	    /* treat non-timeout error as error on read */
	    return ret ? 2 : 4;
	}
# else
	/* using select */
	struct timeval select_tv;
	fd_set fds;
	mnumber to_mn;
	int ret;

	FD_ZERO(&fds);
	FD_SET(infd, &fds);
	to_mn = matheval(OPT_ARG(ops, 't'));
	if (errflag)
	    return 1;

	if (to_mn.type == MN_FLOAT) {
	    select_tv.tv_sec = (int) to_mn.u.d;
	    select_tv.tv_usec =
		(int) ((to_mn.u.d - select_tv.tv_sec) * 1e6);
	} else {
	    select_tv.tv_sec = (int) to_mn.u.l;
	    select_tv.tv_usec = 0;
	}

	while ((ret = select(infd+1, (SELECT_ARG_2_T) &fds,
			     NULL, NULL,&select_tv)) < 1) {
	    if (errno != EINTR || errflag || retflag || breaks || contflag)
		break;
	}
	if (ret <= 0) {
	    /* treat non-timeout error as error on read */
	    return ret ? 2 : 4;
	}
# endif
    }
#endif

    while ((count = read(infd, inbuf, bufsize)) < 0) {
	if (errno != EINTR || errflag || retflag || breaks || contflag)
	    break;
    }
    if (countvar)
	setiparam(countvar, count);
    if (count < 0)
	return 2;

    if (outfd >= 0) {
	if (!count)
	    return 5;
	while (count > 0) {
	    int ret;

	    ret = write(outfd, inbuf, count);
	    if (ret < 0) {
		if (errno == EINTR && !errflag &&
		    !retflag && !breaks && !contflag)
		    continue;
		if (outvar)
		    setsparam(outvar, metafy(inbuf, count, META_DUP));
		if (countvar)
		    setiparam(countvar, count);
		return 3;
	    }
	    inbuf += ret;
	    count -= ret;
	}
	return 0;
    }

    if (!outvar)
	    outvar = "REPLY";
    /* do this even if we read zero bytes */
    setsparam(outvar, metafy(inbuf, count, META_DUP));

    return count ? 0 : 5;
}
Exemple #19
0
static int
bin_zpty(char *nam, char **args, Options ops, UNUSED(int func))
{
    if ((OPT_ISSET(ops,'r') && OPT_ISSET(ops,'w')) ||
	((OPT_ISSET(ops,'r') || OPT_ISSET(ops,'w')) &&
	 (OPT_ISSET(ops,'d') || OPT_ISSET(ops,'e') ||
	  OPT_ISSET(ops,'b') || OPT_ISSET(ops,'L'))) ||
	(OPT_ISSET(ops,'w') && (OPT_ISSET(ops,'t') || OPT_ISSET(ops,'m'))) ||
	(OPT_ISSET(ops,'n') && (OPT_ISSET(ops,'b') || OPT_ISSET(ops,'e') ||
				OPT_ISSET(ops,'r') || OPT_ISSET(ops,'t') ||
				OPT_ISSET(ops,'d') || OPT_ISSET(ops,'L') ||
				OPT_ISSET(ops,'m'))) ||
	(OPT_ISSET(ops,'d') && (OPT_ISSET(ops,'b') || OPT_ISSET(ops,'e') ||
				OPT_ISSET(ops,'L') || OPT_ISSET(ops,'t') ||
				OPT_ISSET(ops,'m'))) ||
	(OPT_ISSET(ops,'L') && (OPT_ISSET(ops,'b') || OPT_ISSET(ops,'e') ||
				OPT_ISSET(ops,'m')))) {
	zwarnnam(nam, "illegal option combination");
	return 1;
    }
    if (OPT_ISSET(ops,'r') || OPT_ISSET(ops,'w')) {
	Ptycmd p;

	if (!*args) {
	    zwarnnam(nam, "missing pty command name");
	    return 1;
	} else if (!(p = getptycmd(*args))) {
	    zwarnnam(nam, "no such pty command: %s", *args);
	    return 1;
	}
	if (p->fin)
	    return 2;

	return (OPT_ISSET(ops,'r') ?
		ptyread(nam, p, args + 1, OPT_ISSET(ops,'t'),
			OPT_ISSET(ops, 'm')) :
		ptywrite(p, args + 1, OPT_ISSET(ops,'n')));
    } else if (OPT_ISSET(ops,'d')) {
	Ptycmd p;
	int ret = 0;

	if (*args) {
	    while (*args)
		if ((p = getptycmd(*args++)))
		    deleteptycmd(p);
		else {
		    zwarnnam(nam, "no such pty command: %s", args[-1]);
		    ret = 1;
		}
	} else
	    deleteallptycmds();

	return ret;
    } else if (OPT_ISSET(ops,'t')) {
	Ptycmd p;

	if (!*args) {
	    zwarnnam(nam, "missing pty command name");
	    return 1;
	} else if (!(p = getptycmd(*args))) {
	    zwarnnam(nam, "no such pty command: %s", *args);
	    return 1;
	}
	checkptycmd(p);
	return p->fin;
    } else if (*args) {
	if (!args[1]) {
	    zwarnnam(nam, "missing command");
	    return 1;
	}
	if (getptycmd(*args)) {
	    zwarnnam(nam, "pty command name already used: %s", *args);
	    return 1;
	}
	return newptycmd(nam, *args, args + 1, OPT_ISSET(ops,'e'), 
			 OPT_ISSET(ops,'b'));
    } else {
	Ptycmd p;
	char **a;

	for (p = ptycmds; p; p = p->next) {
	    checkptycmd(p);
	    if (OPT_ISSET(ops,'L'))
		printf("%s %s%s%s ", nam, (p->echo ? "-e " : ""),
		       (p->nblock ? "-b " : ""), p->name);
	    else if (p->fin)
		printf("(finished) %s: ", p->name);
	    else
		printf("(%d) %s: ", p->pid, p->name);
	    for (a = p->args; *a; ) {
		quotedzputs(*a++, stdout);
		if (*a)
		    putchar(' ');
	    }
	    putchar('\n');
	}
	return 0;
    }
}
Exemple #20
0
static int
bin_chown(char *nam, char **args, Options ops, int func)
{
    struct chownmagic chm;
    char *uspec = ztrdup(*args), *p = uspec;
    char *end;

    chm.nam = nam;
    if(func == BIN_CHGRP) {
	chm.uid = -1;
	goto dogroup;
    }
    end = strchr(uspec, ':');
    if(!end)
	end = strchr(uspec, '.');
    if(end == uspec) {
	chm.uid = -1;
	p++;
	goto dogroup;
    } else {
	struct passwd *pwd;
	if(end)
	    *end = 0;
	pwd = getpwnam(p);
	if(pwd)
	    chm.uid = pwd->pw_uid;
	else {
	    int err;
	    chm.uid = getnumeric(p, &err);
	    if(err) {
		zwarnnam(nam, "%s: no such user", p);
		free(uspec);
		return 1;
	    }
	}
	if(end) {
	    p = end+1;
	    if(!*p) {
		if(!pwd && !(pwd = getpwuid(chm.uid))) {
		    zwarnnam(nam, "%s: no such user", uspec);
		    free(uspec);
		    return 1;
		}
		chm.gid = pwd->pw_gid;
	    } else if(p[0] == ':' && !p[1]) {
		chm.gid = -1;
	    } else {
		struct group *grp;
		dogroup:
		grp = getgrnam(p);
		if(grp)
		    chm.gid = grp->gr_gid;
		else {
		    int err;
		    chm.gid = getnumeric(p, &err);
		    if(err) {
			zwarnnam(nam, "%s: no such group", p);
			free(uspec);
			return 1;
		    }
		}
	    }
	 } else
	    chm.gid = -1;
    }
    free(uspec);
    return recursivecmd(nam, 0, OPT_ISSET(ops,'R'), OPT_ISSET(ops,'s'),
	args + 1, OPT_ISSET(ops, 'h') ? chown_dolchown : chown_dochown, recurse_donothing,
	OPT_ISSET(ops, 'h') ? chown_dolchown : chown_dochown, &chm);
}
Exemple #21
0
static int
bin_ztie(char *nam, char **args, Options ops, UNUSED(int func))
{
    char *resource_name, *pmname;
    GDBM_FILE dbf = NULL;
    int read_write = GDBM_SYNC, pmflags = PM_REMOVABLE;
    Param tied_param;

    if(!OPT_ISSET(ops,'d')) {
        zwarnnam(nam, "you must pass `-d %s'", backtype);
	return 1;
    }
    if(!OPT_ISSET(ops,'f')) {
        zwarnnam(nam, "you must pass `-f' with a filename", NULL);
	return 1;
    }
    if (OPT_ISSET(ops,'r')) {
	read_write |= GDBM_READER;
	pmflags |= PM_READONLY;
    } else {
	read_write |= GDBM_WRCREAT;
    }

    /* Here should be a lookup of the backend type against
     * a registry.
     */
    if (strcmp(OPT_ARG(ops, 'd'), backtype) != 0) {
        zwarnnam(nam, "unsupported backend type `%s'", OPT_ARG(ops, 'd'));
	return 1;
    }

    resource_name = OPT_ARG(ops, 'f');
    pmname = *args;

    if ((tied_param = (Param)paramtab->getnode(paramtab, pmname)) &&
	!(tied_param->node.flags & PM_UNSET)) {
	/*
	 * Unset any existing parameter.  Note there's no implicit
	 * "local" here, but if the existing parameter is local
	 * that will be reflected in the new one.
	 *
	 * We need to do this before attempting to open the DB
	 * in case this variable is already tied to a DB.
	 *
	 * This can fail if the variable is readonly or restricted.
	 * We could call unsetparam() and check errflag instead
	 * of the return status.
	 */
	if (unsetparam_pm(tied_param, 0, 1))
	    return 1;
    }

    dbf = gdbm_open(resource_name, 0, read_write, 0666, 0);
    if(!dbf) {
	zwarnnam(nam, "error opening database file %s", resource_name);
	return 1;
    }

    if (!(tied_param = createspecialhash(pmname, &getgdbmnode, &scangdbmkeys,
					 pmflags))) {
        zwarnnam(nam, "cannot create the requested parameter %s", pmname);
	gdbm_close(dbf);
	return 1;
    }

    tied_param->gsu.h = &gdbm_hash_gsu;
    tied_param->u.hash->tmpdata = (void *)dbf;

    return 0;
}
Exemple #22
0
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;
}
Exemple #23
0
static int
bin_zprof(UNUSED(char *nam), UNUSED(char **args), Options ops, UNUSED(int func))
{
    if (OPT_ISSET(ops,'c')) {
	freepfuncs(calls);
	calls = NULL;
	ncalls = 0;
	freeparcs(arcs);
	arcs = NULL;
	narcs = 0;
    } else {
	VARARR(Pfunc, fs, (ncalls + 1));
	Pfunc f, *fp;
	VARARR(Parc, as, (narcs + 1));
	Parc a, *ap;
	long i;
	double total;

	for (total = 0.0, f = calls, fp = fs; f; f = f->next, fp++) {
	    *fp = f;
	    total += f->self;
	}
	*fp = NULL;
	for (a = arcs, ap = as; a; a = a->next, ap++)
	    *ap = a;
	*ap = NULL;

	qsort(fs, ncalls, sizeof(f),
	      (int (*) _((const void *, const void *))) cmpsfuncs);
	qsort(as, narcs, sizeof(a),
	      (int (*) _((const void *, const void *))) cmpparcs);

	printf("num  calls                time                       self            name\n-----------------------------------------------------------------------------------\n");
	for (fp = fs, i = 1; *fp; fp++, i++) {
	    printf("%2ld) %4ld       %8.2f %8.2f  %6.2f%%  %8.2f %8.2f  %6.2f%%  %s\n",
		   ((*fp)->num = i),
		   (*fp)->calls,
		   (*fp)->time, (*fp)->time / ((double) (*fp)->calls),
		   ((*fp)->time / total) * 100.0,
		   (*fp)->self, (*fp)->self / ((double) (*fp)->calls),
		   ((*fp)->self / total) * 100.0,
		   (*fp)->name);
	}
	qsort(fs, ncalls, sizeof(f),
	      (int (*) _((const void *, const void *))) cmptfuncs);

	for (fp = fs; *fp; fp++) {
	    printf("\n-----------------------------------------------------------------------------------\n\n");
	    for (ap = as; *ap; ap++)
		if ((*ap)->to == *fp) {
		    printf("    %4ld/%-4ld  %8.2f %8.2f  %6.2f%%  %8.2f %8.2f             %s [%ld]\n",
			   (*ap)->calls, (*fp)->calls,
			   (*ap)->time, (*ap)->time / ((double) (*ap)->calls),
			   ((*ap)->time / total) * 100.0,
			   (*ap)->self, (*ap)->self / ((double) (*ap)->calls),
			   (*ap)->from->name, (*ap)->from->num);
		}
	    printf("%2ld) %4ld       %8.2f %8.2f  %6.2f%%  %8.2f %8.2f  %6.2f%%  %s\n",
		   (*fp)->num, (*fp)->calls,
		   (*fp)->time, (*fp)->time / ((double) (*fp)->calls),
		   ((*fp)->time / total) * 100.0,
		   (*fp)->self, (*fp)->self / ((double) (*fp)->calls),
		   ((*fp)->self / total) * 100.0,
		   (*fp)->name);
	    for (ap = as + narcs - 1; ap >= as; ap--)
		if ((*ap)->from == *fp) {
		    printf("    %4ld/%-4ld  %8.2f %8.2f  %6.2f%%  %8.2f %8.2f             %s [%ld]\n",
			   (*ap)->calls, (*ap)->to->calls,
			   (*ap)->time, (*ap)->time / ((double) (*ap)->calls),
			   ((*ap)->time / total) * 100.0,
			   (*ap)->self, (*ap)->self / ((double) (*ap)->calls),
			   (*ap)->to->name, (*ap)->to->num);
		}
	}
    }
    return 0;
}
Exemple #24
0
static int
bin_stat(char *name, char **args, Options ops, UNUSED(int func))
{
    char **aptr, *arrnam = NULL, **array = NULL, **arrptr = NULL;
    char *hashnam = NULL, **hash = NULL, **hashptr = NULL;
    int len, iwhich = -1, ret = 0, flags = 0, arrsize = 0, fd = 0;
    struct stat statbuf;
    int found = 0, nargs;

    timefmt = "%a %b %e %k:%M:%S %Z %Y";

    for (; *args && (**args == '+' || **args == '-'); args++) {
	char *arg = *args+1;
	if (!*arg || *arg == '-' || *arg == '+') {
	    args++;
	    break;
	}

	if (**args == '+') {
	    if (found)
		break;
	    len = strlen(arg);
	    for (aptr = statelts; *aptr; aptr++)
		if (!strncmp(*aptr, arg, len)) {
		    found++;
		    iwhich = aptr - statelts;
		}
	    if (found > 1) {
		zwarnnam(name, "%s: ambiguous stat element", arg);
		return 1;
	    } else if (found == 0) {
		zwarnnam(name, "%s: no such stat element", arg);
		return 1;
	    }
	    /* if name of link requested, turn on lstat */
	    if (iwhich == ST_READLINK)
		ops->ind['L'] = 1;
	    flags |= STF_PICK;
	} else {
	    for (; *arg; arg++) {
		if (strchr("glLnNorstT", *arg))
		    ops->ind[STOUC(*arg)] = 1;
		else if (*arg == 'A') {
		    if (arg[1]) {
			arrnam = arg+1;
		    } else if (!(arrnam = *++args)) {
			zwarnnam(name, "missing parameter name");
			return 1;
		    }
		    flags |= STF_ARRAY;
		    break;
		} else if (*arg == 'H') {
		    if (arg[1]) {
			hashnam = arg+1;
		    } else if (!(hashnam = *++args)) {
			zwarnnam(name, "missing parameter name");
			return 1;
		    }
		    flags |= STF_HASH;
		    break;
		} else if (*arg == 'f') {
		    char *sfd;
		    ops->ind['f'] = 1;
		    if (arg[1]) {
			sfd = arg+1;
		    } else if (!(sfd = *++args)) {
			zwarnnam(name, "missing file descriptor");
			return 1;
		    }
		    fd = zstrtol(sfd, &sfd, 10);
		    if (*sfd) {
			zwarnnam(name, "bad file descriptor");
			return 1;
		    }
		    break;
		} else if (*arg == 'F') {
		    if (arg[1]) {
			timefmt = arg+1;
		    } else if (!(timefmt = *++args)) {
			zwarnnam(name, "missing time format");
			return 1;
		    }
		    /* force string format in order to use time format */
		    ops->ind['s'] = 1;
		    break;
		} else {
		    zwarnnam(name, "bad option: -%c", *arg);
		    return 1;
		}
	    }
	}
    }

    if ((flags & STF_ARRAY) && (flags & STF_HASH)) {
    	/* We don't implement setting multiple variables at once */
	zwarnnam(name, "both array and hash requested");
	return 1;
	/* Alternate method would be to make -H blank arrnam etc etc *
	 * and so get 'silent loss' of earlier choice, which would   *
	 * be similar to stat -A foo -A bar filename                 */
    }

    if (OPT_ISSET(ops,'l')) {
	/* list types and return:  can also list to array */
	if (arrnam) {
	    arrptr = array = (char **)zalloc((ST_COUNT+1)*sizeof(char *));
	    array[ST_COUNT] = NULL;
	}
	for (aptr = statelts; *aptr; aptr++) {
	    if (arrnam) {
		*arrptr++ = ztrdup(*aptr);
	    } else {
		printf("%s", *aptr);
		if (aptr[1])
		    putchar(' ');
	    }
	}
	if (arrnam) {
	    setaparam(arrnam, array);
	    if (errflag)
		return 1;
	} else
	    putchar('\n');
	return 0;
    }

    if (!*args && !OPT_ISSET(ops,'f')) {
	zwarnnam(name, "no files given");
	return 1;
    } else if (*args && OPT_ISSET(ops,'f')) {
	zwarnnam(name, "no files allowed with -f");
	return 1;
    }

    nargs = 0;
    if (OPT_ISSET(ops,'f'))
	nargs = 1;
    else
	for (aptr = args; *aptr; aptr++)
	    nargs++;

    if (OPT_ISSET(ops,'g')) {
	flags |= STF_GMT;
	ops->ind['s'] = 1;
    }
    if (OPT_ISSET(ops,'s') || OPT_ISSET(ops,'r'))
	flags |= STF_STRING;
    if (OPT_ISSET(ops,'r') || !OPT_ISSET(ops,'s'))
	flags |= STF_RAW;
    if (OPT_ISSET(ops,'n'))
	flags |= STF_FILE;
    if (OPT_ISSET(ops,'o'))
	flags |= STF_OCTAL;
    if (OPT_ISSET(ops,'t'))
	flags |= STF_NAME;

    if (!(arrnam || hashnam)) {
	if (nargs > 1)
	    flags |= STF_FILE;
	if (!(flags & STF_PICK))
	    flags |= STF_NAME;
    }

    if (OPT_ISSET(ops,'N') || OPT_ISSET(ops,'f'))
	flags &= ~STF_FILE;
    if (OPT_ISSET(ops,'T') || OPT_ISSET(ops,'H'))
	flags &= ~STF_NAME;

    if (hashnam) {
    	if (nargs > 1) {
	    zwarnnam(name, "only one file allowed with -H");
	    return 1;
	}
	arrsize = (flags & STF_PICK) ? 1 : ST_COUNT;
	if (flags & STF_FILE)
	    arrsize++;
	hashptr = hash = (char **)zshcalloc((arrsize+1)*2*sizeof(char *));
    }

    if (arrnam) {
	arrsize = (flags & STF_PICK) ? 1 : ST_COUNT;
	if (flags & STF_FILE)
	    arrsize++;
	arrsize *= nargs;
	arrptr = array = (char **)zshcalloc((arrsize+1)*sizeof(char *));
    }

    for (; OPT_ISSET(ops,'f') || *args; args++) {
	char outbuf[PATH_MAX + 9]; /* "link   " + link name + NULL */
	int rval = OPT_ISSET(ops,'f') ? fstat(fd, &statbuf) :
	    OPT_ISSET(ops,'L') ? lstat(unmeta(*args), &statbuf) :
	    stat(unmeta(*args), &statbuf);
	if (rval) {
	    if (OPT_ISSET(ops,'f'))
		sprintf(outbuf, "%d", fd);
	    zwarnnam(name, "%s: %e", OPT_ISSET(ops,'f') ? outbuf : *args,
		     errno);
	    ret = 1;
	    if (OPT_ISSET(ops,'f') || arrnam)
		break;
	    else
		continue;
	}

	if (flags & STF_FILE) {
	    if (arrnam)
		*arrptr++ = ztrdup(*args);
	    else if (hashnam) {
	    	*hashptr++ = ztrdup(HNAMEKEY);
		*hashptr++ = ztrdup(*args);
	    } else
		printf("%s%s", *args, (flags & STF_PICK) ? " " : ":\n");
	}
	if (iwhich > -1) {
	    statprint(&statbuf, outbuf, *args, iwhich, flags);
	    if (arrnam)
		*arrptr++ = metafy(outbuf, -1, META_DUP);
	    else if (hashnam) {
		/* STF_NAME explicitly turned off for ops.ind['H'] above */
	    	*hashptr++ = ztrdup(statelts[iwhich]);
		*hashptr++ = metafy(outbuf, -1, META_DUP);
	    } else
		printf("%s\n", outbuf);
	} else {
	    int i;
	    for (i = 0; i < ST_COUNT; i++) {
		statprint(&statbuf, outbuf, *args, i, flags);
		if (arrnam)
		    *arrptr++= metafy(outbuf, -1, META_DUP);
		else if (hashnam) {
		    /* STF_NAME explicitly turned off for ops.ind['H'] above */
		    *hashptr++ = ztrdup(statelts[i]);
		    *hashptr++ = metafy(outbuf, -1, META_DUP);
		} else
		    printf("%s\n", outbuf);
	    }
	}
	if (OPT_ISSET(ops,'f'))
	    break;

	if (!arrnam && !hashnam && args[1] && !(flags & STF_PICK))
	    putchar('\n');
    }

    if (arrnam) {
	if (ret)
	    freearray(array);
	else {
	    setaparam(arrnam, array);
	    if (errflag)
		return 1;
	}
    }

    if (hashnam) {
    	if (ret)
	    freearray(hash);
	else {
	    sethparam(hashnam, hash);
	    if (errflag)
		return 1;
	}
    }

    return ret;
}