Esempio n. 1
0
File: files.c Progetto: AMDmi3/zsh
static int
domove(char *nam, MoveFunc movefn, char *p, char *q, int flags)
{
    struct stat st;
    char *pbuf, *qbuf;

    pbuf = ztrdup(unmeta(p));
    qbuf = unmeta(q);
    if(flags & MV_NODIRS) {
	errno = EISDIR;
	if(lstat(pbuf, &st) || S_ISDIR(st.st_mode)) {
	    zwarnnam(nam, "%s: %e", p, errno);
	    zsfree(pbuf);
	    return 1;
	}
    }
    if(!lstat(qbuf, &st)) {
	int doit = flags & MV_FORCE;
	if(S_ISDIR(st.st_mode)) {
	    zwarnnam(nam, "%s: cannot overwrite directory", q);
	    zsfree(pbuf);
	    return 1;
	} else if(flags & MV_INTERACTIVE) {
	    nicezputs(nam, stderr);
	    fputs(": replace `", stderr);
	    nicezputs(q, stderr);
	    fputs("'? ", stderr);
	    fflush(stderr);
	    if(!ask()) {
		zsfree(pbuf);
		return 0;
	    }
	    doit = 1;
	} else if((flags & MV_ASKNW) &&
		!S_ISLNK(st.st_mode) &&
		access(qbuf, W_OK)) {
	    nicezputs(nam, stderr);
	    fputs(": replace `", stderr);
	    nicezputs(q, stderr);
	    fprintf(stderr, "', overriding mode %04o? ",
		mode_to_octal(st.st_mode));
	    fflush(stderr);
	    if(!ask()) {
		zsfree(pbuf);
		return 0;
	    }
	    doit = 1;
	}
	if(doit && !(flags & MV_ATOMIC))
	    unlink(qbuf);
    }
    if(movefn(pbuf, qbuf)) {
	zwarnnam(nam, "%s: %e", p, errno);
	zsfree(pbuf);
	return 1;
    }
    zsfree(pbuf);
    return 0;
}
Esempio n. 2
0
File: compat.c Progetto: AMDmi3/zsh
char *
zgetcwd(void)
{
    char *ret = zgetdir(NULL);
#ifdef HAVE_GETCWD
    if (!ret) {
#ifdef GETCWD_CALLS_MALLOC
	char *cwd = getcwd(NULL, 0);
	if (cwd) {
	    ret = dupstring(cwd);
	    free(cwd);
	}
#else
	char *cwdbuf = zalloc(PATH_MAX);
	ret = getcwd(cwdbuf, PATH_MAX);
	if (ret)
	    ret = dupstring(ret);
	zfree(cwdbuf, PATH_MAX);
#endif /* GETCWD_CALLS_MALLOC */
    }
#endif /* HAVE_GETCWD */
    if (!ret)
	ret = unmeta(pwd);
    if (!ret)
	ret = dupstring(".");
    return ret;
}
Esempio n. 3
0
File: input.c Progetto: netroby/zsh
int
stuff(char *fn)
{
    FILE *in;
    char *buf;
    off_t len;

    if (!(in = fopen(unmeta(fn), "r"))) {
	zerr("can't open %s", fn);
	return 1;
    }
    fseek(in, 0, 2);
    len = ftell(in);
    fseek(in, 0, 0);
    buf = (char *)zalloc(len + 1);
    if (!(fread(buf, len, 1, in))) {
	zerr("read error on %s", fn);
	fclose(in);
	zfree(buf, len + 1);
	return 1;
    }
    fclose(in);
    buf[len] = '\0';
    fwrite(buf, len, 1, stderr);
    fflush(stderr);
    inputsetline(metafy(buf, len, META_REALLOC), INP_FREE);
    return 0;
}
Esempio n. 4
0
File: cond.c Progetto: AMDmi3/zsh
static mode_t
dolstat(char *s)
{
    if (lstat(unmeta(s), &st) < 0)
	return 0;
    return st.st_mode;
}
Esempio n. 5
0
mod_export void
trashzle(void)
{
    if (zleactive && !trashedzle) {
	/* This zrefresh() is just to get the main editor display right and *
	 * get the cursor in the right place.  For that reason, we disable  *
	 * list display (which would otherwise result in infinite           *
	 * recursion [at least, it would if zrefresh() didn't have its      *
	 * extra `inlist' check]).                                          */
	int sl = showinglist;
	showinglist = 0;
	trashedzle = 1;
	zrefresh();
	showinglist = sl;
	moveto(nlnct, 0);
	if (clearflag && tccan(TCCLEAREOD)) {
	    tcout(TCCLEAREOD);
	    clearflag = listshown = 0;
	}
	if (postedit)
	    fprintf(shout, "%s", unmeta(postedit));
	fflush(shout);
	resetneeded = 1;
	if (!(zlereadflags & ZLRF_NOSETTY))
	  settyinfo(&shttyinfo);
    }
    if (errflag)
	kungetct = 0;
}
Esempio n. 6
0
File: cond.c Progetto: AMDmi3/zsh
static int
doaccess(char *s, int c)
{
#ifdef HAVE_FACCESSX
    if (!strncmp(s, "/dev/fd/", 8))
	return !faccessx(atoi(s + 8), c, ACC_SELF);
#endif
    return !access(unmeta(s), c);
}
Esempio n. 7
0
void
hashdir(char **dirp)
{
    Cmdnam cn;
    DIR *dir;
    char *fn;

    if (isrelative(*dirp) || !(dir = opendir(unmeta(*dirp))))
	return;

    while ((fn = zreaddir(dir))) {
	/* Ignore `.' and `..'. */
	if (fn[0] == '.' &&
	    (fn[1] == '\0' ||
	     (fn[1] == '.' && fn[2] == '\0')))
	    continue;
#ifndef WINNT
	if (!cmdnamtab->getnode(cmdnamtab, fn)) {
	    cn = (Cmdnam) zcalloc(sizeof *cn);
	    cn->flags = 0;
	    cn->u.name = dirp;
	    cmdnamtab->addnode(cmdnamtab, ztrdup(fn), cn);
	}
#else
	if (!cmdnamtab->getnode(cmdnamtab, fn)) {
	    char *fext;
	    fext = fn;
	    while(*fext++)
		;

	    while((fext >fn )&& (*fext != '.'))
		fext--;

	    if ( (fext == fn) /*no extension */
		    || is_pathext(fext+1) ) {
		cn = (Cmdnam) zcalloc(sizeof *cn);
		cn->flags = 0;
		cn->u.name = dirp;
		cmdnamtab->addnode(cmdnamtab, ztrdup(fn), cn);

		/*if (fext != fn && !strnicmp(fext+1,"exe",3)) */

		*fext = 0;
		cn = (Cmdnam) zcalloc(sizeof *cn);
		cn->flags = 0;
		cn->u.name = dirp;

		cmdnamtab->addnode(cmdnamtab, ztrdup(fn), cn);
	    }
#ifdef ZSH_HASH_DEBUG
	    printhashtabinfo(cmdnamtab);
#endif /* ZSH_HASH_DEBUG */
	}
#endif /* WINNT */
    }
    closedir(dir);
}
Esempio n. 8
0
int
source(char *s)
{
    int tempfd, fd, cj, oldlineno;
    int oldshst, osubsh, oloops;
    FILE *obshin;
    char *old_scriptname = scriptname;

    if (!s || (tempfd = movefd(open(unmeta(s), O_RDONLY))) == -1) {
	return 1;
    }

    /* save the current shell state */
    fd        = SHIN;            /* store the shell input fd                  */
    obshin    = bshin;          /* store file handle for buffered shell input */
    osubsh    = subsh;           /* store whether we are in a subshell        */
    cj        = thisjob;         /* store our current job number              */
    oldlineno = lineno;          /* store our current lineno                  */
    oloops    = loops;           /* stored the # of nested loops we are in    */
    oldshst   = opts[SHINSTDIN]; /* store current value of this option        */

    SHIN = tempfd;
    bshin = fdopen(SHIN, "r");
    subsh  = 0;
    lineno = 0;
    loops  = 0;
    dosetopt(SHINSTDIN, 0, 1);
    scriptname = s;

    sourcelevel++;
    loop(0);			/* loop through the file to be sourced        */
    sourcelevel--;
    fclose(bshin);
    fdtable[SHIN] = 0;

    /* restore the current shell state */
    SHIN = fd;                       /* the shell input fd                   */
    bshin = obshin;                  /* file handle for buffered shell input */
    subsh = osubsh;                  /* whether we are in a subshell         */
    thisjob = cj;                    /* current job number                   */
    lineno = oldlineno;              /* our current lineno                   */
    loops = oloops;                  /* the # of nested loops we are in      */
    dosetopt(SHINSTDIN, oldshst, 1); /* SHINSTDIN option                     */
    errflag = 0;
    retflag = 0;
    scriptname = old_scriptname;

    return 0;
}
Esempio n. 9
0
File: files.c Progetto: AMDmi3/zsh
static int
bin_rmdir(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
{
    int err = 0;

    for(; *args; args++) {
	char *rpath = unmeta(*args);

	if(!rpath) {
	    zwarnnam(nam, "%s: %e", *args, ENAMETOOLONG);
	    err = 1;
	} else if(rmdir(rpath)) {
	    zwarnnam(nam, "cannot remove directory `%s': %e", *args, errno);
	    err = 1;
	}
    }
    return err;
}
Esempio n. 10
0
File: cond.c Progetto: AMDmi3/zsh
static struct stat *
getstat(char *s)
{
    char *us;

/* /dev/fd/n refers to the open file descriptor n.  We always use fstat *
 * in this case since on Solaris /dev/fd/n is a device special file     */
    if (!strncmp(s, "/dev/fd/", 8)) {
	if (fstat(atoi(s + 8), &st))
	    return NULL;
        return &st;
    }

    if (!(us = unmeta(s)))
        return NULL;
    if (stat(us, &st))
	return NULL;
    return &st;
}
Esempio n. 11
0
File: files.c Progetto: AMDmi3/zsh
static int
domkdir(char *nam, char *path, mode_t mode, int p)
{
    int err;
    mode_t oumask;
    char const *rpath = unmeta(path);

    if(p) {
	struct stat st;

	if(!stat(rpath, &st) && S_ISDIR(st.st_mode))
	    return 0;
    }
    oumask = umask(0);
    err = mkdir(rpath, mode) ? errno : 0;
    umask(oumask);
    if(!err)
	return 0;
    zwarnnam(nam, "cannot make directory `%s': %e", path, err);
    return 1;
}
Esempio n. 12
0
void
hashdir(char **dirp)
{
    Cmdnam cn;
    DIR *dir;
    char *fn;
#if defined(_WIN32) || defined(__CYGWIN__)
    char *exe;
#endif /* _WIN32 || _CYGWIN__ */

    if (isrelative(*dirp) || !(dir = opendir(unmeta(*dirp))))
	return;

    while ((fn = zreaddir(dir, 1))) {
	if (!cmdnamtab->getnode(cmdnamtab, fn)) {
	    cn = (Cmdnam) zshcalloc(sizeof *cn);
	    cn->flags = 0;
	    cn->u.name = dirp;
	    cmdnamtab->addnode(cmdnamtab, ztrdup(fn), cn);
	}
#if defined(_WIN32) || defined(__CYGWIN__)
	/* Hash foo.exe as foo, since when no real foo exists, foo.exe
	   will get executed by DOS automatically.  This quiets
	   spurious corrections when CORRECT or CORRECT_ALL is set. */
	if ((exe = strrchr(fn, '.')) &&
	    (exe[1] == 'E' || exe[1] == 'e') &&
	    (exe[2] == 'X' || exe[2] == 'x') &&
	    (exe[3] == 'E' || exe[3] == 'e') && exe[4] == 0) {
	    *exe = 0;
	    if (!cmdnamtab->getnode(cmdnamtab, fn)) {
		cn = (Cmdnam) zshcalloc(sizeof *cn);
		cn->flags = 0;
		cn->u.name = dirp;
		cmdnamtab->addnode(cmdnamtab, ztrdup(fn), cn);
	    }
	}
#endif /* _WIN32 || __CYGWIN__ */
    }
    closedir(dir);
}
Esempio n. 13
0
void
parseargs(char **argv)
{
    char **x;
    int action, optno;
    LinkList paramlist;
    int bourne = (emulation == EMULATE_KSH || emulation == EMULATE_SH);

    hackzero = argzero = *argv++;
    SHIN = 0;

    /* There's a bit of trickery with opts[INTERACTIVE] here.  It starts *
     * at a value of 2 (instead of 1) or 0.  If it is explicitly set on  *
     * the command line, it goes to 1 or 0.  If input is coming from     *
     * somewhere that normally makes the shell non-interactive, we do    *
     * "opts[INTERACTIVE] &= 1", so that only a *default* on state will  *
     * be changed.  At the end of the function, a value of 2 gets        *
     * changed to 1.                                                     */
    opts[INTERACTIVE] = isatty(0) ? 2 : 0;
    opts[SHINSTDIN] = 0;
    opts[SINGLECOMMAND] = 0;

    /* loop through command line options (begins with "-" or "+") */
    while (*argv && (**argv == '-' || **argv == '+')) {
	action = (**argv == '-');
	if(!argv[0][1])
	    *argv = "--";
	while (*++*argv) {
	    /* The pseudo-option `--' signifies the end of options. *
	     * `-b' does too, csh-style, unless we're emulating a   *
	     * Bourne style shell.                                  */
	    if (**argv == '-' || (!bourne && **argv == 'b')) {
		argv++;
		goto doneoptions;
	    }

	    if (**argv == 'c') {         /* -c command */
		if (!*++argv) {
		    zerr("string expected after -c", NULL, 0);
		    exit(1);
		}
		cmd = *argv++;
		opts[INTERACTIVE] &= 1;
		opts[SHINSTDIN] = 0;
		goto doneoptions;
	    } else if (**argv == 'o') {
		if (!*++*argv)
		    argv++;
		if (!*argv) {
		    zerr("string expected after -o", NULL, 0);
		    exit(1);
		}
		if(!(optno = optlookup(*argv)))
		    zerr("no such option: %s", *argv, 0);
		else
		    dosetopt(optno, action, 1);
		break;
	    } else {
	    	if (!(optno = optlookupc(**argv))) {
		    zerr("bad option: -%c", NULL, **argv);
		    exit(1);
		} else
		    dosetopt(optno, action, 1);
	    }
	}
	argv++;
    }
    doneoptions:
    paramlist = newlinklist();
    if (*argv) {
	if (unset(SHINSTDIN)) {
	    argzero = *argv;
	    if (!cmd)
		SHIN = movefd(open(unmeta(argzero), O_RDONLY));
	    if (SHIN == -1) {
		zerr("can't open input file: %s", argzero, 0);
		exit(1);
	    }
	    opts[INTERACTIVE] &= 1;
	    argv++;
	}
	while (*argv)
	    addlinknode(paramlist, ztrdup(*argv++));
    } else
	opts[SHINSTDIN] = 1;
    if(isset(SINGLECOMMAND))
	opts[INTERACTIVE] &= 1;
    opts[INTERACTIVE] = !!opts[INTERACTIVE];
    pparams = x = (char **) zcalloc((countlinknodes(paramlist) + 1) * sizeof(char *));

    while ((*x++ = (char *)getlinknode(paramlist)));
    free(paramlist);
    argzero = ztrdup(argzero);
}
Esempio n. 14
0
File: system.c Progetto: Jaharmi/zsh
static int
bin_zsystem_flock(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
{
    int cloexec = 1, unlock = 0, readlock = 0;
    time_t timeout = 0;
    char *fdvar = NULL;
#ifdef HAVE_FCNTL_H
    struct flock lck;
    int flock_fd, flags;
#endif

    while (*args && **args == '-') {
	int opt;
	char *optptr = *args + 1, *optarg;
	args++;
	if (!*optptr || !strcmp(optptr, "-"))
	    break;
	while ((opt = *optptr)) {
	    switch (opt) {
	    case 'e':
		/* keep lock on "exec" */
		cloexec = 0;
		break;

	    case 'f':
		/* variable for fd */
		if (optptr[1]) {
		    fdvar = optptr + 1;
		    optptr += strlen(fdvar) - 1;
		} else if (*args) {
		    fdvar = *args++;
		}
		if (fdvar == NULL || !isident(fdvar)) {
		    zwarnnam(nam, "flock: option %c requires a variable name",
			     opt);
		    return 1;
		}
		break;

	    case 'r':
		/* read lock rather than read-write lock */
		readlock = 1;
		break;

	    case 't':
		/* timeout in seconds */
		if (optptr[1]) {
		    optarg = optptr + 1;
		    optptr += strlen(optarg) - 1;
		} else if (!*args) {
		    zwarnnam(nam, "flock: option %c requires a numeric timeout",
			     opt);
		    return 1;
		} else {
		    optarg = *args++;
		}
		timeout = (time_t)mathevali(optarg);
		break;

	    case 'u':
		/* unlock: argument is fd */
		unlock = 1;
		break;

	    default:
		zwarnnam(nam, "flock: unknown option: %c", *optptr);
		return 1;
	    }
	    optptr++;
	}
    }


    if (!args[0]) {
	zwarnnam(nam, "flock: not enough arguments");
	return 1;
    }
    if (args[1]) {
	zwarnnam(nam, "flock: too many arguments");
	return 1;
    }

#ifdef HAVE_FCNTL_H
    if (unlock) {
	flock_fd = (int)mathevali(args[0]);
	if (zcloselockfd(flock_fd) < 0) {
	    zwarnnam(nam, "flock: file descriptor %d not in use for locking",
		     flock_fd);
	    return 1;
	}
	return 0;
    }

    if (readlock)
	flags = O_RDONLY | O_NOCTTY;
    else
	flags = O_RDWR | O_NOCTTY;
    if ((flock_fd = open(unmeta(args[0]), flags)) < 0) {
	zwarnnam(nam, "failed to open %s for writing: %e", args[0], errno);
	return 1;
    }
    flock_fd = movefd(flock_fd);
    if (flock_fd == -1)
	return 1;
#ifdef FD_CLOEXEC
    if (cloexec)
    {
	long fdflags = fcntl(flock_fd, F_GETFD, 0);
	if (fdflags != (long)-1)
	    fcntl(flock_fd, F_SETFD, fdflags | FD_CLOEXEC);
    }
#endif
    addlockfd(flock_fd, cloexec);

    lck.l_type = readlock ? F_RDLCK : F_WRLCK;
    lck.l_whence = SEEK_SET;
    lck.l_start = 0;
    lck.l_len = 0;  /* lock the whole file */

    if (timeout > 0) {
	time_t end = time(NULL) + (time_t)timeout;
	while (fcntl(flock_fd, F_SETLK, &lck) < 0) {
	    if (errflag)
		return 1;
	    if (errno != EINTR && errno != EACCES && errno != EAGAIN) {
		zwarnnam(nam, "failed to lock file %s: %e", args[0], errno);
		return 1;
	    }
	    if (time(NULL) >= end)
		return 2;
	    sleep(1);
	}
    } else {
	while (fcntl(flock_fd, F_SETLKW, &lck) < 0) {
	    if (errflag)
		return 1;
	    if (errno == EINTR)
		continue;
	    zwarnnam(nam, "failed to lock file %s: %e", args[0], errno);
	    return 1;
	}
    }

    if (fdvar)
	setiparam(fdvar, flock_fd);

    return 0;
#else /* HAVE_FCNTL_H */
    zwarnnam(nam, "flock: not implemented on this system");
    return 255;
#endif /* HAVE_FCNTL_H */
}
Esempio n. 15
0
void
hashdir(char **dirp)
{
    Cmdnam cn;
    DIR *dir;
    char *fn, *unmetadir, *pathbuf, *pathptr;
    int dirlen;
#if defined(_WIN32) || defined(__CYGWIN__)
    char *exe;
#endif /* _WIN32 || _CYGWIN__ */

    if (isrelative(*dirp))
	return;
    unmetadir = unmeta(*dirp);
    if (!(dir = opendir(unmetadir)))
	return;

    dirlen = strlen(unmetadir);
    pathbuf = (char *)zalloc(dirlen + PATH_MAX + 2);
    sprintf(pathbuf, "%s/", unmetadir);
    pathptr = pathbuf + dirlen + 1;

    while ((fn = zreaddir(dir, 1))) {
	if (!cmdnamtab->getnode(cmdnamtab, fn)) {
	    char *fname = ztrdup(fn);
	    struct stat statbuf;
	    int add = 0, dummylen;

	    unmetafy(fn, &dummylen);
	    if (strlen(fn) > PATH_MAX) {
		/* Too heavy to do all the allocation */
		add = 1;
	    } else {
		strcpy(pathptr, fn);
		/*
		 * This is the same test as for the glob qualifier for
		 * executable plain files.
		 */
		if (unset(HASHEXECUTABLESONLY) ||
		    (access(pathbuf, X_OK) == 0 &&
		     stat(pathbuf, &statbuf) == 0 &&
		     S_ISREG(statbuf.st_mode) && (statbuf.st_mode & S_IXUGO)))
		    add = 1;
	    }
	    if (add) {
		cn = (Cmdnam) zshcalloc(sizeof *cn);
		cn->node.flags = 0;
		cn->u.name = dirp;
		cmdnamtab->addnode(cmdnamtab, fname, cn);
	    } else
		zsfree(fname);
	}
#if defined(_WIN32) || defined(__CYGWIN__)
	/* Hash foo.exe as foo, since when no real foo exists, foo.exe
	   will get executed by DOS automatically.  This quiets
	   spurious corrections when CORRECT or CORRECT_ALL is set. */
	if ((exe = strrchr(fn, '.')) &&
	    (exe[1] == 'E' || exe[1] == 'e') &&
	    (exe[2] == 'X' || exe[2] == 'x') &&
	    (exe[3] == 'E' || exe[3] == 'e') && exe[4] == 0) {
	    *exe = 0;
	    if (!cmdnamtab->getnode(cmdnamtab, fn)) {
		cn = (Cmdnam) zshcalloc(sizeof *cn);
		cn->node.flags = 0;
		cn->u.name = dirp;
		cmdnamtab->addnode(cmdnamtab, ztrdup(fn), cn);
	    }
	}
#endif /* _WIN32 || __CYGWIN__ */
    }
    closedir(dir);
    zfree(pathbuf, dirlen + PATH_MAX + 2);
}
Esempio n. 16
0
File: stat.c Progetto: zsh-users/zsh
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;
}
Esempio n. 17
0
File: files.c Progetto: AMDmi3/zsh
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;
}