diff options
Diffstat (limited to 'Src/cond.c')
-rw-r--r-- | Src/cond.c | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/Src/cond.c b/Src/cond.c new file mode 100644 index 000000000..79886a720 --- /dev/null +++ b/Src/cond.c @@ -0,0 +1,226 @@ +/* + * cond.c - evaluate conditional expressions + * + * This file is part of zsh, the Z shell. + * + * Copyright (c) 1992-1997 Paul Falstad + * All rights reserved. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and to distribute modified versions of this software for any + * purpose, provided that the above copyright notice and the following + * two paragraphs appear in all copies of this software. + * + * In no event shall Paul Falstad or the Zsh Development Group be liable + * to any party for direct, indirect, special, incidental, or consequential + * damages arising out of the use of this software and its documentation, + * even if Paul Falstad and the Zsh Development Group have been advised of + * the possibility of such damage. + * + * Paul Falstad and the Zsh Development Group specifically disclaim any + * warranties, including, but not limited to, the implied warranties of + * merchantability and fitness for a particular purpose. The software + * provided hereunder is on an "as is" basis, and Paul Falstad and the + * Zsh Development Group have no obligation to provide maintenance, + * support, updates, enhancements, or modifications. + * + */ + +#include "zsh.mdh" +#include "cond.pro" + +/**/ +int +evalcond(Cond c) +{ + struct stat *st; + + switch (c->type) { + case COND_NOT: + return !evalcond(c->left); + case COND_AND: + return evalcond(c->left) && evalcond(c->right); + case COND_OR: + return evalcond(c->left) || evalcond(c->right); + } + singsub((char **)&c->left); + untokenize(c->left); + if (c->right) { + singsub((char **)&c->right); + if (c->type != COND_STREQ && c->type != COND_STRNEQ) + untokenize(c->right); + } + switch (c->type) { + case COND_STREQ: + return matchpat(c->left, c->right); + case COND_STRNEQ: + return !matchpat(c->left, c->right); + case COND_STRLT: + return strcmp(c->left, c->right) < 0; + case COND_STRGTR: + return strcmp(c->left, c->right) > 0; + case 'e': + case 'a': + return (doaccess(c->left, F_OK)); + case 'b': + return (S_ISBLK(dostat(c->left))); + case 'c': + return (S_ISCHR(dostat(c->left))); + case 'd': + return (S_ISDIR(dostat(c->left))); + case 'f': + return (S_ISREG(dostat(c->left))); + case 'g': + return (!!(dostat(c->left) & S_ISGID)); + case 'k': + return (!!(dostat(c->left) & S_ISVTX)); + case 'n': + return (!!strlen(c->left)); + case 'o': + return (optison(c->left)); + case 'p': + return (S_ISFIFO(dostat(c->left))); + case 'r': + return (doaccess(c->left, R_OK)); + case 's': + return ((st = getstat(c->left)) && !!(st->st_size)); + case 'S': + return (S_ISSOCK(dostat(c->left))); + case 'u': + return (!!(dostat(c->left) & S_ISUID)); + case 'w': + return (doaccess(c->left, W_OK)); + case 'x': + if (privasserted()) { + mode_t mode = dostat(c->left); + return (mode & S_IXUGO) || S_ISDIR(mode); + } + return doaccess(c->left, X_OK); + case 'z': + return (!strlen(c->left)); + case 'h': + case 'L': + return (S_ISLNK(dolstat(c->left))); + case 'O': + return ((st = getstat(c->left)) && st->st_uid == geteuid()); + case 'G': + return ((st = getstat(c->left)) && st->st_gid == getegid()); + case 'N': + return ((st = getstat(c->left)) && st->st_atime <= st->st_mtime); + case 't': + return isatty(matheval(c->left)); + case COND_EQ: + return matheval(c->left) == matheval(c->right); + case COND_NE: + return matheval(c->left) != matheval(c->right); + case COND_LT: + return matheval(c->left) < matheval(c->right); + case COND_GT: + return matheval(c->left) > matheval(c->right); + case COND_LE: + return matheval(c->left) <= matheval(c->right); + case COND_GE: + return matheval(c->left) >= matheval(c->right); + case COND_NT: + case COND_OT: + { + time_t a; + + if (!(st = getstat(c->left))) + return 0; + a = st->st_mtime; + if (!(st = getstat(c->right))) + return 0; + return (c->type == COND_NT) ? a > st->st_mtime : a < st->st_mtime; + } + case COND_EF: + { + dev_t d; + ino_t i; + + if (!(st = getstat(c->left))) + return 0; + d = st->st_dev; + i = st->st_ino; + if (!(st = getstat(c->right))) + return 0; + return d == st->st_dev && i == st->st_ino; + } + default: + zerr("bad cond structure", NULL, 0); + } + return 0; +} + + +/**/ +static int +doaccess(char *s, int c) +{ + return !access(unmeta(s), c); +} + + +static struct stat st; + +/**/ +static struct stat * +getstat(char *s) +{ +/* /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 (stat(unmeta(s), &st)) + return NULL; + return &st; +} + + +/**/ +static mode_t +dostat(char *s) +{ + struct stat *statp; + + if (!(statp = getstat(s))) + return 0; + return statp->st_mode; +} + + +/* pem@aaii.oz; needed since dostat now uses "stat" */ + +/**/ +static mode_t +dolstat(char *s) +{ + if (lstat(unmeta(s), &st) < 0) + return 0; + return st.st_mode; +} + + +/**/ +static int +optison(char *s) +{ + int i; + + if (strlen(s) == 1) + i = optlookupc(*s); + else + i = optlookup(s); + if (!i) { + zerr("no such option: %s", s, 0); + return 0; + } else if(i < 0) + return unset(-i); + else + return isset(i); +} |