Annotation of coherent/a/usr/bob/korn/c_test.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * test(1); version 7-like  --  author Erik Baalbergen
        !             3:  * modified by Eric Gisin to be used as built-in.
        !             4:  * modified by Arnold Robbins to add SVR3 compatibility
        !             5:  * (-x -c -b -p -u -g -k) plus Korn's -L -nt -ot -ef and new -S (socket).
        !             6:  */
        !             7: 
        !             8: static char *RCSid = "$Header: c_test.c,v 3.1 88/11/03 09:14:43 egisin Exp $";
        !             9: 
        !            10: #include <stddef.h>
        !            11: #include <stdlib.h>
        !            12: #include <string.h>
        !            13: #include <signal.h>
        !            14: #include <errno.h>
        !            15: #include <setjmp.h>
        !            16: #include <sys/types.h>
        !            17: #include <sys/stat.h>
        !            18: #include "sh.h"
        !            19: 
        !            20: /* test(1) accepts the following grammar:
        !            21:        expr    ::= bexpr | bexpr "-o" expr ;
        !            22:        bexpr   ::= primary | primary "-a" bexpr ;
        !            23:        primary ::= unary-operator operand
        !            24:                | operand binary-operator operand
        !            25:                | operand
        !            26:                | "(" expr ")"
        !            27:                | "!" expr
        !            28:                ;
        !            29:        unary-operator ::= "-r"|"-w"|"-x"|"-f"|"-d"|"-c"|"-b"|"-p"|
        !            30:                "-u"|"-g"|"-k"|"-s"|"-t"|"-z"|"-n"|"-o"|"-O"|"-G"|"-L"|"-S";
        !            31: 
        !            32:        binary-operator ::= "="|"!="|"-eq"|"-ne"|"-ge"|"-gt"|"-le"|"-lt"|
        !            33:                        "-nt"|"-ot"|"-ef";
        !            34:        operand ::= <any legal UNIX file name>
        !            35: */
        !            36: 
        !            37: #define EOI    0
        !            38: #define FILRD  1
        !            39: #define FILWR  2
        !            40: #define FILREG 3
        !            41: #define FILID  4
        !            42: #define FILGZ  5
        !            43: #define FILTT  6
        !            44: #define STZER  7
        !            45: #define STNZE  8
        !            46: #define STEQL  9
        !            47: #define STNEQ  10
        !            48: #define INTEQ  11
        !            49: #define INTNE  12
        !            50: #define INTGE  13
        !            51: #define INTGT  14
        !            52: #define INTLE  15
        !            53: #define INTLT  16
        !            54: #define UNEGN  17
        !            55: #define BAND   18
        !            56: #define BOR    19
        !            57: #define LPAREN 20
        !            58: #define RPAREN 21
        !            59: #define OPERAND        22
        !            60: #define FILEX  23
        !            61: #define FILCDEV        24
        !            62: #define FILBDEV        25
        !            63: #define FILFIFO        26
        !            64: #define FILSETU        27
        !            65: #define FILSETG        28
        !            66: #define FILSTCK        29
        !            67: #define FILSYM 30
        !            68: #define FILNT  31
        !            69: #define FILOT  32
        !            70: #define FILEQ  33
        !            71: #define FILSOCK        34
        !            72: #define        FILUID  35
        !            73: #define        FILGID  36
        !            74: #define        OPTION  37
        !            75: 
        !            76: #define UNOP   1
        !            77: #define BINOP  2
        !            78: #define BUNOP  3
        !            79: #define BBINOP 4
        !            80: #define PAREN  5
        !            81: 
        !            82: struct t_op {
        !            83:        char *op_text;
        !            84:        short op_num, op_type;
        !            85: } Const ops [] = {
        !            86:        {"-r",  FILRD,  UNOP},
        !            87:        {"-w",  FILWR,  UNOP},
        !            88:        {"-x",  FILEX,  UNOP},
        !            89:        {"-f",  FILREG, UNOP},
        !            90:        {"-d",  FILID,  UNOP},
        !            91:        {"-c",  FILCDEV,UNOP},
        !            92:        {"-b",  FILBDEV,UNOP},
        !            93:        {"-p",  FILFIFO,UNOP},
        !            94:        {"-u",  FILSETU,UNOP},
        !            95:        {"-g",  FILSETG,UNOP},
        !            96:        {"-k",  FILSTCK,UNOP},
        !            97:        {"-s",  FILGZ,  UNOP},
        !            98:        {"-t",  FILTT,  UNOP},
        !            99:        {"-z",  STZER,  UNOP},
        !           100:        {"-n",  STNZE,  UNOP},
        !           101: #if 0                          /* conficts with binary -o */
        !           102:        {"-o",  OPTION, UNOP},
        !           103: #endif
        !           104:        {"-U",  FILUID, UNOP},
        !           105:        {"-G",  FILGID, UNOP},
        !           106:        {"-L",  FILSYM, UNOP},
        !           107:        {"-S",  FILSOCK,UNOP},
        !           108:        {"=",   STEQL,  BINOP},
        !           109:        {"!=",  STNEQ,  BINOP},
        !           110:        {"-eq", INTEQ,  BINOP},
        !           111:        {"-ne", INTNE,  BINOP},
        !           112:        {"-ge", INTGE,  BINOP},
        !           113:        {"-gt", INTGT,  BINOP},
        !           114:        {"-le", INTLE,  BINOP},
        !           115:        {"-lt", INTLT,  BINOP},
        !           116:        {"-nt", FILNT,  BINOP},
        !           117:        {"-ot", FILOT,  BINOP},
        !           118:        {"-ef", FILEQ,  BINOP},
        !           119:        {"!",   UNEGN,  BUNOP},
        !           120:        {"-a",  BAND,   BBINOP},
        !           121:        {"-o",  BOR,    BBINOP},
        !           122:        {"(",   LPAREN, PAREN},
        !           123:        {")",   RPAREN, PAREN},
        !           124:        {0,     0,      0}
        !           125: };
        !           126: 
        !           127: char **t_wp;
        !           128: struct t_op Const *t_wp_op;
        !           129: 
        !           130: int
        !           131: c_test(wp)
        !           132:        char **wp;
        !           133: {
        !           134:        t_wp = wp+1;
        !           135:        if (strcmp(wp[0], "[") == 0) {
        !           136:                while (*wp != NULL)
        !           137:                        wp++;
        !           138:                if (strcmp(*--wp, "]") != 0)
        !           139:                        errorf("[: missing ]\n");
        !           140:                *wp = NULL;
        !           141:        }
        !           142: #if 0
        !           143:        if (*t_wp == NULL)
        !           144:                mypr("*t_wp == NULL\n");
        !           145:        else if (!expr(t_lex(*t_wp)))
        !           146:                mypr("expr returned 0\n");
        !           147: #endif
        !           148:        return *t_wp == NULL || !expr(t_lex(*t_wp));
        !           149: }
        !           150: 
        !           151: static
        !           152: syntax()
        !           153: {
        !           154:        errorf("test: syntax error\n");
        !           155: }
        !           156: 
        !           157: expr(n)
        !           158: {
        !           159:        int res;
        !           160: 
        !           161:        if (n == EOI)
        !           162:                syntax();
        !           163:        res = bexpr(n);
        !           164:        if (t_lex(*++t_wp) == BOR)
        !           165:                return expr(t_lex(*++t_wp)) || res;
        !           166:        t_wp--;
        !           167:        return res;
        !           168: }
        !           169: 
        !           170: bexpr(n)
        !           171: {
        !           172:        int res;
        !           173: 
        !           174:        if (n == EOI)
        !           175:                syntax();
        !           176:        res = primary(n);
        !           177:        if (t_lex(*++t_wp) == BAND)
        !           178:                return bexpr(t_lex(*++t_wp)) && res;
        !           179:        t_wp--;
        !           180:        return res;
        !           181: }
        !           182: 
        !           183: primary(n)
        !           184:        int n;                  /* token */
        !           185: {
        !           186:        register char *opnd1, *opnd2;
        !           187:        int res;
        !           188: 
        !           189:        if (n == EOI)
        !           190:                syntax();
        !           191:        if (n == UNEGN)
        !           192:                return !expr(t_lex(*++t_wp));
        !           193:        if (n == LPAREN) {
        !           194:                res = expr(t_lex(*++t_wp));
        !           195:                if (t_lex(*++t_wp) != RPAREN)
        !           196:                        syntax();
        !           197:                return res;
        !           198:        }
        !           199:        if (n == OPERAND) {
        !           200:                opnd1 = *t_wp;
        !           201:                (void) t_lex(*++t_wp);
        !           202:                if (t_wp_op && t_wp_op->op_type == BINOP) {
        !           203:                        struct t_op Const *op = t_wp_op;
        !           204: 
        !           205:                        if ((opnd2 = *++t_wp) == (char *)0)
        !           206:                                syntax();
        !           207:                        
        !           208:                        switch (op->op_num) {
        !           209:                        case STEQL:
        !           210:                                return strcmp(opnd1, opnd2) == 0;
        !           211:                        case STNEQ:
        !           212:                                return strcmp(opnd1, opnd2) != 0;
        !           213:                        case INTEQ:
        !           214:                                return evaluate(opnd1) == evaluate(opnd2);
        !           215:                        case INTNE:
        !           216:                                return evaluate(opnd1) != evaluate(opnd2);
        !           217:                        case INTGE:
        !           218:                                return evaluate(opnd1) >= evaluate(opnd2);
        !           219:                        case INTGT:
        !           220:                                return evaluate(opnd1) > evaluate(opnd2);
        !           221:                        case INTLE:
        !           222:                                return evaluate(opnd1) <= evaluate(opnd2);
        !           223:                        case INTLT:
        !           224:                                return evaluate(opnd1) < evaluate(opnd2);
        !           225:                        case FILNT:
        !           226:                                return newerf (opnd1, opnd2);
        !           227:                        case FILOT:
        !           228:                                return olderf (opnd1, opnd2);
        !           229:                        case FILEQ:
        !           230:                                return equalf (opnd1, opnd2);
        !           231:                        }
        !           232:                }
        !           233:                t_wp--;
        !           234:                return strlen(opnd1) > 0;
        !           235:        }
        !           236:        if (t_wp_op->op_type == UNOP) {
        !           237:                /* unary expression */
        !           238:                if (*++t_wp == NULL && n != FILTT)
        !           239:                        syntax();
        !           240:                switch (n) {
        !           241:                  case OPTION:
        !           242:                        return flag[option(*t_wp)];
        !           243:                  case STZER:
        !           244:                        return strlen(*t_wp) == 0;
        !           245:                  case STNZE:
        !           246:                        return strlen(*t_wp) != 0;
        !           247:                  case FILTT:
        !           248:                        if (!digit(**t_wp))
        !           249:                                return filstat("0", n);
        !           250:                  default:      /* all other FIL* */
        !           251:                        return filstat(*t_wp, n);
        !           252:                }
        !           253:        }
        !           254:        syntax();
        !           255: }
        !           256: 
        !           257: filstat(nm, mode)
        !           258:        char *nm;
        !           259: {
        !           260:        struct stat s;
        !           261:        
        !           262:        switch (mode) {
        !           263:        case FILRD:
        !           264:                return access(nm, 4) == 0;
        !           265:        case FILWR:
        !           266:                return access(nm, 2) == 0;
        !           267:        case FILEX:
        !           268:                return access(nm, 1) == 0;
        !           269:        case FILREG:
        !           270:                return stat(nm, &s) == 0 && (s.st_mode & S_IFMT) == S_IFREG;
        !           271:        case FILID:
        !           272:                return stat(nm, &s) == 0 && (s.st_mode & S_IFMT) == S_IFDIR;
        !           273:        case FILCDEV:
        !           274:                return stat(nm, &s) == 0 && (s.st_mode & S_IFMT) == S_IFCHR;
        !           275:        case FILBDEV:
        !           276:                return stat(nm, &s) == 0 && (s.st_mode & S_IFMT) == S_IFBLK;
        !           277:        case FILFIFO:
        !           278: #ifdef S_IFIFO
        !           279:                return stat(nm, &s) == 0 && (s.st_mode & S_IFMT) == S_IFIFO;
        !           280: #else
        !           281:                return 0;
        !           282: #endif
        !           283:        case FILSETU:
        !           284:                return stat(nm, &s) == 0 && (s.st_mode & S_ISUID) == S_ISUID;
        !           285:        case FILSETG:
        !           286:                return stat(nm, &s) == 0 && (s.st_mode & S_ISGID) == S_ISGID;
        !           287:        case FILSTCK:
        !           288:                return stat(nm, &s) == 0 && (s.st_mode & S_ISVTX) == S_ISVTX;
        !           289:        case FILGZ:
        !           290:                return stat(nm, &s) == 0 && s.st_size > 0L;
        !           291:        case FILTT:
        !           292:                return isatty(getn(nm));
        !           293:          case FILUID:
        !           294:                return stat(nm, &s) == 0 && s.st_uid == geteuid();
        !           295:          case FILGID:
        !           296:                return stat(nm, &s) == 0 && s.st_gid == getegid();
        !           297: #ifdef S_IFLNK
        !           298:        case FILSYM:
        !           299:                return lstat(nm, &s) == 0 && (s.st_mode & S_IFMT) == S_IFLNK;
        !           300: #endif
        !           301: #ifdef S_IFSOCK
        !           302:        case FILSOCK:
        !           303:                return stat(nm, &s) == 0 && (s.st_mode & S_IFMT) == S_IFSOCK;
        !           304: #endif
        !           305:          default:
        !           306:                return 1;
        !           307:        }
        !           308: }
        !           309: 
        !           310: int
        !           311: t_lex(s)
        !           312:        register char *s;
        !           313: {
        !           314:        register struct t_op Const *op = ops;
        !           315: 
        !           316:        if (s == 0)
        !           317:                return EOI;
        !           318:        while (op->op_text) {
        !           319:                if (strcmp(s, op->op_text) == 0) {
        !           320:                        t_wp_op = op;
        !           321:                        return op->op_num;
        !           322:                }
        !           323:                op++;
        !           324:        }
        !           325:        t_wp_op = (struct t_op *)0;
        !           326:        return OPERAND;
        !           327: }
        !           328: 
        !           329: newerf (f1, f2)
        !           330: char *f1, *f2;
        !           331: {
        !           332:        struct stat b1, b2;
        !           333: 
        !           334:        return (stat (f1, &b1) == 0 &&
        !           335:                stat (f2, &b2) == 0 &&
        !           336:                b1.st_mtime > b2.st_mtime);
        !           337: }
        !           338: 
        !           339: olderf (f1, f2)
        !           340: char *f1, *f2;
        !           341: {
        !           342:        struct stat b1, b2;
        !           343: 
        !           344:        return (stat (f1, &b1) == 0 &&
        !           345:                stat (f2, &b2) == 0 &&
        !           346:                b1.st_mtime < b2.st_mtime);
        !           347: }
        !           348: 
        !           349: equalf (f1, f2)
        !           350: char *f1, *f2;
        !           351: {
        !           352:        struct stat b1, b2;
        !           353: 
        !           354:        return (stat (f1, &b1) == 0 &&
        !           355:                stat (f2, &b2) == 0 &&
        !           356:                b1.st_dev == b2.st_dev &&
        !           357:                b1.st_ino == b2.st_ino);
        !           358: }
        !           359: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.