home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / UNIX / Shells / zsh-3.0.5-MIHS / src / Src / cond.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-06-03  |  5.3 KB  |  232 lines

  1. /*
  2.  * $Id: cond.c,v 2.6 1996/10/15 20:16:35 hzoli Exp $
  3.  *
  4.  * cond.c - evaluate conditional expressions
  5.  *
  6.  * This file is part of zsh, the Z shell.
  7.  *
  8.  * Copyright (c) 1992-1996 Paul Falstad
  9.  * All rights reserved.
  10.  *
  11.  * Permission is hereby granted, without written agreement and without
  12.  * license or royalty fees, to use, copy, modify, and distribute this
  13.  * software and to distribute modified versions of this software for any
  14.  * purpose, provided that the above copyright notice and the following
  15.  * two paragraphs appear in all copies of this software.
  16.  *
  17.  * In no event shall Paul Falstad or the Zsh Development Group be liable
  18.  * to any party for direct, indirect, special, incidental, or consequential
  19.  * damages arising out of the use of this software and its documentation,
  20.  * even if Paul Falstad and the Zsh Development Group have been advised of
  21.  * the possibility of such damage.
  22.  *
  23.  * Paul Falstad and the Zsh Development Group specifically disclaim any
  24.  * warranties, including, but not limited to, the implied warranties of
  25.  * merchantability and fitness for a particular purpose.  The software
  26.  * provided hereunder is on an "as is" basis, and Paul Falstad and the
  27.  * Zsh Development Group have no obligation to provide maintenance,
  28.  * support, updates, enhancements, or modifications.
  29.  *
  30.  */
  31.  
  32. #include "zsh.h"
  33.  
  34. /**/
  35. int
  36. evalcond(Cond c)
  37. {
  38.     struct stat *st;
  39.  
  40.     switch (c->type) {
  41.     case COND_NOT:
  42.     return !evalcond(c->left);
  43.     case COND_AND:
  44.     return evalcond(c->left) && evalcond(c->right);
  45.     case COND_OR:
  46.     return evalcond(c->left) || evalcond(c->right);
  47.     }
  48.     singsub((char **)&c->left);
  49.     untokenize(c->left);
  50.     if (c->right) {
  51.     singsub((char **)&c->right);
  52.     if (c->type != COND_STREQ && c->type != COND_STRNEQ)
  53.         untokenize(c->right);
  54.     }
  55.     switch (c->type) {
  56.     case COND_STREQ:
  57.     return matchpat(c->left, c->right);
  58.     case COND_STRNEQ:
  59.     return !matchpat(c->left, c->right);
  60.     case COND_STRLT:
  61.     return strcmp(c->left, c->right) < 0;
  62.     case COND_STRGTR:
  63.     return strcmp(c->left, c->right) > 0;
  64.     case 'e':
  65.     case 'a':
  66.     return (doaccess(c->left, F_OK));
  67.     case 'b':
  68.     return (S_ISBLK(dostat(c->left)));
  69.     case 'c':
  70.     return (S_ISCHR(dostat(c->left)));
  71.     case 'd':
  72.     return (S_ISDIR(dostat(c->left)));
  73.     case 'f':
  74.     return (S_ISREG(dostat(c->left)));
  75.     case 'g':
  76.     return (!!(dostat(c->left) & S_ISGID));
  77.     case 'k':
  78.     return (!!(dostat(c->left) & S_ISVTX));
  79.     case 'n':
  80.     return (!!strlen(c->left));
  81.     case 'o':
  82.     return (optison(c->left));
  83.     case 'p':
  84.     return (S_ISFIFO(dostat(c->left)));
  85.     case 'r':
  86.     return (doaccess(c->left, R_OK));
  87.     case 's':
  88.     return ((st = getstat(c->left)) && !!(st->st_size));
  89.     case 'S':
  90. #ifdef S_ISSOCK
  91.     return (S_ISSOCK(dostat(c->left)));
  92. #else
  93.     return 0;   /* some versions of SCO are missing S_ISSOCK */
  94. #endif
  95.     case 'u':
  96.     return (!!(dostat(c->left) & S_ISUID));
  97.     case 'w':
  98.     return (doaccess(c->left, W_OK));
  99.     case 'x':
  100.     if (!geteuid()) {
  101.         unsigned short mode = dostat(c->left);
  102.         return (mode & 0111) || S_ISDIR(mode);
  103.     }
  104.     return doaccess(c->left, X_OK);
  105.     case 'z':
  106.     return (!strlen(c->left));
  107.     case 'h':
  108.     case 'L':
  109.     return (S_ISLNK(dolstat(c->left)));
  110.     case 'O':
  111.     return ((st = getstat(c->left)) && st->st_uid == geteuid());
  112.     case 'G':
  113.     return ((st = getstat(c->left)) && st->st_gid == getegid());
  114.     case 'N':
  115.     return ((st = getstat(c->left)) && st->st_atime <= st->st_mtime);
  116.     case 't':
  117.     return isatty(matheval(c->left));
  118.     case COND_EQ:
  119.     return matheval(c->left) == matheval(c->right);
  120.     case COND_NE:
  121.     return matheval(c->left) != matheval(c->right);
  122.     case COND_LT:
  123.     return matheval(c->left) < matheval(c->right);
  124.     case COND_GT:
  125.     return matheval(c->left) > matheval(c->right);
  126.     case COND_LE:
  127.     return matheval(c->left) <= matheval(c->right);
  128.     case COND_GE:
  129.     return matheval(c->left) >= matheval(c->right);
  130.     case COND_NT:
  131.     case COND_OT:
  132.     {
  133.         time_t a;
  134.  
  135.         if (!(st = getstat(c->left)))
  136.         return 0;
  137.         a = st->st_mtime;
  138.         if (!(st = getstat(c->right)))
  139.         return 0;
  140.         return (c->type == COND_NT) ? a > st->st_mtime : a < st->st_mtime;
  141.     }
  142.     case COND_EF:
  143.     {
  144.         dev_t d;
  145.         ino_t i;
  146.  
  147.         if (!(st = getstat(c->left)))
  148.         return 0;
  149.         d = st->st_dev;
  150.         i = st->st_ino;
  151.         if (!(st = getstat(c->right)))
  152.         return 0;
  153.         return d == st->st_dev && i == st->st_ino;
  154.     }
  155.     default:
  156.     zerr("bad cond structure", NULL, 0);
  157.     }
  158.     return 0;
  159. }
  160.  
  161.  
  162. /**/
  163. int
  164. doaccess(char *s, int c)
  165. {
  166.     return !access(unmeta(s), c);
  167. }
  168.  
  169.  
  170. static struct stat st;
  171.  
  172. /**/
  173. struct stat *
  174. getstat(char *s)
  175. {
  176. /* /dev/fd/n refers to the open file descriptor n.  We always use fstat *
  177.  * in this case since on Solaris /dev/fd/n is a device special file     */
  178.     if (!strncmp(s, "/dev/fd/", 8)) {
  179.     if (fstat(atoi(s + 8), &st))
  180.         return NULL;
  181.         return &st;
  182.     }
  183.  
  184.     if (stat(unmeta(s), &st))
  185.     return NULL;
  186.     return &st;
  187. }
  188.  
  189.  
  190. /**/
  191. unsigned short
  192. dostat(char *s)
  193. {
  194.     struct stat *statp;
  195.  
  196.     if (!(statp = getstat(s)))
  197.     return 0;
  198.     return statp->st_mode;
  199. }
  200.  
  201.  
  202. /* pem@aaii.oz; needed since dostat now uses "stat" */
  203.  
  204. /**/
  205. unsigned short
  206. dolstat(char *s)
  207. {
  208.     if (lstat(unmeta(s), &st) < 0)
  209.     return 0;
  210.     return st.st_mode;
  211. }
  212.  
  213.  
  214. /**/
  215. int
  216. optison(char *s)
  217. {
  218.     int i;
  219.  
  220.     if (strlen(s) == 1)
  221.     i = optlookupc(*s);
  222.     else
  223.     i = optlookup(s);
  224.     if (!i) {
  225.     zerr("no such option: %s", s, 0);
  226.     return 0;
  227.     } else if(i < 0)
  228.     return unset(-i);
  229.     else
  230.     return isset(i);
  231. }
  232.