home *** CD-ROM | disk | FTP | other *** search
- /*
- * $Id: cond.c,v 2.6 1996/10/15 20:16:35 hzoli Exp $
- *
- * cond.c - evaluate conditional expressions
- *
- * This file is part of zsh, the Z shell.
- *
- * Copyright (c) 1992-1996 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.h"
-
- /**/
- 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':
- #ifdef S_ISSOCK
- return (S_ISSOCK(dostat(c->left)));
- #else
- return 0; /* some versions of SCO are missing S_ISSOCK */
- #endif
- case 'u':
- return (!!(dostat(c->left) & S_ISUID));
- case 'w':
- return (doaccess(c->left, W_OK));
- case 'x':
- if (!geteuid()) {
- unsigned short mode = dostat(c->left);
- return (mode & 0111) || 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;
- }
-
-
- /**/
- int
- doaccess(char *s, int c)
- {
- return !access(unmeta(s), c);
- }
-
-
- static struct stat st;
-
- /**/
- 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;
- }
-
-
- /**/
- unsigned short
- 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" */
-
- /**/
- unsigned short
- dolstat(char *s)
- {
- if (lstat(unmeta(s), &st) < 0)
- return 0;
- return st.st_mode;
- }
-
-
- /**/
- 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);
- }
-