188f3d729Sakaplan /* 288f3d729Sakaplan * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 388f3d729Sakaplan * Use is subject to license terms. 488f3d729Sakaplan */ 588f3d729Sakaplan 67c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 77c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 87c478bd9Sstevel@tonic-gate 9*f22acdffSgbrunett /* 10*f22acdffSgbrunett * Copyright (c) 1980 Regents of the University of California. 117c478bd9Sstevel@tonic-gate * All rights reserved. The Berkeley software License Agreement 127c478bd9Sstevel@tonic-gate * specifies the terms and conditions for redistribution. 137c478bd9Sstevel@tonic-gate */ 147c478bd9Sstevel@tonic-gate 1588f3d729Sakaplan #pragma ident "%Z%%M% %I% %E% SMI" 167c478bd9Sstevel@tonic-gate 177c478bd9Sstevel@tonic-gate /* 187c478bd9Sstevel@tonic-gate * test expression 197c478bd9Sstevel@tonic-gate * [ expression ] 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate 227c478bd9Sstevel@tonic-gate #include <stdio.h> 23*f22acdffSgbrunett #include <stdlib.h> 24*f22acdffSgbrunett #include <unistd.h> 257c478bd9Sstevel@tonic-gate #include <sys/types.h> 267c478bd9Sstevel@tonic-gate #include <sys/stat.h> 27*f22acdffSgbrunett #include <string.h> 28*f22acdffSgbrunett 297c478bd9Sstevel@tonic-gate #define EQ(a, b) ((strcmp(a, b) == 0)) 307c478bd9Sstevel@tonic-gate 31*f22acdffSgbrunett static char *nxtarg(int mt); 32*f22acdffSgbrunett static int exp(void); 33*f22acdffSgbrunett static int e1(void); 34*f22acdffSgbrunett static int e2(void); 35*f22acdffSgbrunett static int e3(void); 36*f22acdffSgbrunett static int tio(char *a, int f); 37*f22acdffSgbrunett static int ftype(char *f, int field); 38*f22acdffSgbrunett static int filtyp(char *f, int field); 39*f22acdffSgbrunett static int fsizep(char *f); 40*f22acdffSgbrunett static void synbad(char *s1, char *s2); 417c478bd9Sstevel@tonic-gate 42*f22acdffSgbrunett static int ap; 43*f22acdffSgbrunett static int ac; 44*f22acdffSgbrunett static char **av; 457c478bd9Sstevel@tonic-gate 4688f3d729Sakaplan int 4788f3d729Sakaplan main(int argc, char *argv[]) 487c478bd9Sstevel@tonic-gate { 497c478bd9Sstevel@tonic-gate int status; 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gate ac = argc; av = argv; ap = 1; 527c478bd9Sstevel@tonic-gate if (EQ(argv[0], "[")) { 537c478bd9Sstevel@tonic-gate if (!EQ(argv[--ac], "]")) 547c478bd9Sstevel@tonic-gate synbad("] missing", ""); 557c478bd9Sstevel@tonic-gate } 567c478bd9Sstevel@tonic-gate argv[ac] = 0; 57*f22acdffSgbrunett if (ac <= 1) 58*f22acdffSgbrunett exit(1); 597c478bd9Sstevel@tonic-gate status = (exp() ? 0 : 1); 607c478bd9Sstevel@tonic-gate if (nxtarg(1) != 0) 617c478bd9Sstevel@tonic-gate synbad("too many arguments", ""); 6288f3d729Sakaplan return (status); 637c478bd9Sstevel@tonic-gate } 647c478bd9Sstevel@tonic-gate 65*f22acdffSgbrunett static char * 6688f3d729Sakaplan nxtarg(int mt) 6788f3d729Sakaplan { 687c478bd9Sstevel@tonic-gate if (ap >= ac) { 697c478bd9Sstevel@tonic-gate if (mt) { 707c478bd9Sstevel@tonic-gate ap++; 717c478bd9Sstevel@tonic-gate return (0); 727c478bd9Sstevel@tonic-gate } 737c478bd9Sstevel@tonic-gate synbad("argument expected", ""); 747c478bd9Sstevel@tonic-gate } 757c478bd9Sstevel@tonic-gate return (av[ap++]); 767c478bd9Sstevel@tonic-gate } 777c478bd9Sstevel@tonic-gate 78*f22acdffSgbrunett static int 7988f3d729Sakaplan exp(void) 8088f3d729Sakaplan { 817c478bd9Sstevel@tonic-gate int p1; 827c478bd9Sstevel@tonic-gate char *p2; 837c478bd9Sstevel@tonic-gate 847c478bd9Sstevel@tonic-gate p1 = e1(); 857c478bd9Sstevel@tonic-gate p2 = nxtarg(1); 867c478bd9Sstevel@tonic-gate if (p2 != 0) { 877c478bd9Sstevel@tonic-gate if (EQ(p2, "-o")) 887c478bd9Sstevel@tonic-gate return (p1 | exp()); 897c478bd9Sstevel@tonic-gate if (EQ(p2, "]")) 907c478bd9Sstevel@tonic-gate synbad("syntax error", ""); 917c478bd9Sstevel@tonic-gate } 927c478bd9Sstevel@tonic-gate ap--; 937c478bd9Sstevel@tonic-gate return (p1); 947c478bd9Sstevel@tonic-gate } 957c478bd9Sstevel@tonic-gate 96*f22acdffSgbrunett static int 9788f3d729Sakaplan e1(void) 9888f3d729Sakaplan { 997c478bd9Sstevel@tonic-gate int p1; 1007c478bd9Sstevel@tonic-gate char *p2; 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate p1 = e2(); 1037c478bd9Sstevel@tonic-gate p2 = nxtarg(1); 1047c478bd9Sstevel@tonic-gate if ((p2 != 0) && EQ(p2, "-a")) 1057c478bd9Sstevel@tonic-gate return (p1 & e1()); 1067c478bd9Sstevel@tonic-gate ap--; 1077c478bd9Sstevel@tonic-gate return (p1); 1087c478bd9Sstevel@tonic-gate } 1097c478bd9Sstevel@tonic-gate 110*f22acdffSgbrunett static int 11188f3d729Sakaplan e2(void) 11288f3d729Sakaplan { 1137c478bd9Sstevel@tonic-gate if (EQ(nxtarg(0), "!")) 1147c478bd9Sstevel@tonic-gate return (!e3()); 1157c478bd9Sstevel@tonic-gate ap--; 1167c478bd9Sstevel@tonic-gate return (e3()); 1177c478bd9Sstevel@tonic-gate } 1187c478bd9Sstevel@tonic-gate 119*f22acdffSgbrunett static int 12088f3d729Sakaplan e3(void) 12188f3d729Sakaplan { 1227c478bd9Sstevel@tonic-gate int p1; 12388f3d729Sakaplan char *a; 1247c478bd9Sstevel@tonic-gate char *p2; 1257c478bd9Sstevel@tonic-gate int int1, int2; 1267c478bd9Sstevel@tonic-gate 1277c478bd9Sstevel@tonic-gate a = nxtarg(0); 1287c478bd9Sstevel@tonic-gate if (EQ(a, "(")) { 1297c478bd9Sstevel@tonic-gate p1 = exp(); 1307c478bd9Sstevel@tonic-gate if (!EQ(nxtarg(0), ")")) synbad(") expected", ""); 1317c478bd9Sstevel@tonic-gate return (p1); 1327c478bd9Sstevel@tonic-gate } 1337c478bd9Sstevel@tonic-gate p2 = nxtarg(1); 1347c478bd9Sstevel@tonic-gate ap--; 1357c478bd9Sstevel@tonic-gate if ((p2 == 0) || (!EQ(p2, "=") && !EQ(p2, "!="))) { 1367c478bd9Sstevel@tonic-gate if (EQ(a, "-r")) 1377c478bd9Sstevel@tonic-gate return (tio(nxtarg(0), 4)); 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate if (EQ(a, "-w")) 1407c478bd9Sstevel@tonic-gate return (tio(nxtarg(0), 2)); 1417c478bd9Sstevel@tonic-gate 1427c478bd9Sstevel@tonic-gate if (EQ(a, "-x")) 1437c478bd9Sstevel@tonic-gate return (tio(nxtarg(0), 1)); 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate if (EQ(a, "-d")) 1467c478bd9Sstevel@tonic-gate return (filtyp(nxtarg(0), S_IFDIR)); 1477c478bd9Sstevel@tonic-gate 1487c478bd9Sstevel@tonic-gate if (EQ(a, "-c")) 1497c478bd9Sstevel@tonic-gate return (filtyp(nxtarg(0), S_IFCHR)); 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate if (EQ(a, "-b")) 1527c478bd9Sstevel@tonic-gate return (filtyp(nxtarg(0), S_IFBLK)); 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate if (EQ(a, "-f")) { 1557c478bd9Sstevel@tonic-gate struct stat statb; 1567c478bd9Sstevel@tonic-gate 1577c478bd9Sstevel@tonic-gate return (stat(nxtarg(0), &statb) >= 0 && 1587c478bd9Sstevel@tonic-gate (statb.st_mode & S_IFMT) != S_IFDIR); 1597c478bd9Sstevel@tonic-gate } 1607c478bd9Sstevel@tonic-gate 1617c478bd9Sstevel@tonic-gate if (EQ(a, "-h")) 1627c478bd9Sstevel@tonic-gate return (filtyp(nxtarg(0), S_IFLNK)); 1637c478bd9Sstevel@tonic-gate 1647c478bd9Sstevel@tonic-gate if (EQ(a, "-u")) 1657c478bd9Sstevel@tonic-gate return (ftype(nxtarg(0), S_ISUID)); 1667c478bd9Sstevel@tonic-gate 1677c478bd9Sstevel@tonic-gate if (EQ(a, "-g")) 1687c478bd9Sstevel@tonic-gate return (ftype(nxtarg(0), S_ISGID)); 1697c478bd9Sstevel@tonic-gate 1707c478bd9Sstevel@tonic-gate if (EQ(a, "-k")) 1717c478bd9Sstevel@tonic-gate return (ftype(nxtarg(0), S_ISVTX)); 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gate if (EQ(a, "-p")) 1747c478bd9Sstevel@tonic-gate #ifdef S_IFIFO 1757c478bd9Sstevel@tonic-gate return (filtyp(nxtarg(0), S_IFIFO)); 1767c478bd9Sstevel@tonic-gate #else 1777c478bd9Sstevel@tonic-gate return (nxtarg(0), 0); 1787c478bd9Sstevel@tonic-gate #endif 1797c478bd9Sstevel@tonic-gate 1807c478bd9Sstevel@tonic-gate if (EQ(a, "-s")) 1817c478bd9Sstevel@tonic-gate return (fsizep(nxtarg(0))); 1827c478bd9Sstevel@tonic-gate 1837c478bd9Sstevel@tonic-gate if (EQ(a, "-t")) 1847c478bd9Sstevel@tonic-gate if (ap >= ac) 1857c478bd9Sstevel@tonic-gate return (isatty(1)); 1867c478bd9Sstevel@tonic-gate else if (EQ((a = nxtarg(0)), "-a") || EQ(a, "-o")) { 1877c478bd9Sstevel@tonic-gate ap--; 1887c478bd9Sstevel@tonic-gate return (isatty(1)); 1897c478bd9Sstevel@tonic-gate } else 1907c478bd9Sstevel@tonic-gate return (isatty(atoi(a))); 1917c478bd9Sstevel@tonic-gate 1927c478bd9Sstevel@tonic-gate if (EQ(a, "-n")) 1937c478bd9Sstevel@tonic-gate return (!EQ(nxtarg(0), "")); 1947c478bd9Sstevel@tonic-gate if (EQ(a, "-z")) 1957c478bd9Sstevel@tonic-gate return (EQ(nxtarg(0), "")); 1967c478bd9Sstevel@tonic-gate } 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate p2 = nxtarg(1); 1997c478bd9Sstevel@tonic-gate if (p2 == 0) 2007c478bd9Sstevel@tonic-gate return (!EQ(a, "")); 2017c478bd9Sstevel@tonic-gate if (EQ(p2, "-a") || EQ(p2, "-o")) { 2027c478bd9Sstevel@tonic-gate ap--; 2037c478bd9Sstevel@tonic-gate return (!EQ(a, "")); 2047c478bd9Sstevel@tonic-gate } 2057c478bd9Sstevel@tonic-gate if (EQ(p2, "=")) 2067c478bd9Sstevel@tonic-gate return (EQ(nxtarg(0), a)); 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate if (EQ(p2, "!=")) 2097c478bd9Sstevel@tonic-gate return (!EQ(nxtarg(0), a)); 2107c478bd9Sstevel@tonic-gate 2117c478bd9Sstevel@tonic-gate int1 = atoi(a); 2127c478bd9Sstevel@tonic-gate int2 = atoi(nxtarg(0)); 2137c478bd9Sstevel@tonic-gate if (EQ(p2, "-eq")) 2147c478bd9Sstevel@tonic-gate return (int1 == int2); 2157c478bd9Sstevel@tonic-gate if (EQ(p2, "-ne")) 2167c478bd9Sstevel@tonic-gate return (int1 != int2); 2177c478bd9Sstevel@tonic-gate if (EQ(p2, "-gt")) 2187c478bd9Sstevel@tonic-gate return (int1 > int2); 2197c478bd9Sstevel@tonic-gate if (EQ(p2, "-lt")) 2207c478bd9Sstevel@tonic-gate return (int1 < int2); 2217c478bd9Sstevel@tonic-gate if (EQ(p2, "-ge")) 2227c478bd9Sstevel@tonic-gate return (int1 >= int2); 2237c478bd9Sstevel@tonic-gate if (EQ(p2, "-le")) 2247c478bd9Sstevel@tonic-gate return (int1 <= int2); 2257c478bd9Sstevel@tonic-gate 2267c478bd9Sstevel@tonic-gate synbad("unknown operator ", p2); 2277c478bd9Sstevel@tonic-gate /* NOTREACHED */ 22888f3d729Sakaplan return (0); 2297c478bd9Sstevel@tonic-gate } 2307c478bd9Sstevel@tonic-gate 231*f22acdffSgbrunett static int 23288f3d729Sakaplan tio(char *a, int f) 2337c478bd9Sstevel@tonic-gate { 2347c478bd9Sstevel@tonic-gate if (access(a, f) == 0) 2357c478bd9Sstevel@tonic-gate return (1); 2367c478bd9Sstevel@tonic-gate else 2377c478bd9Sstevel@tonic-gate return (0); 2387c478bd9Sstevel@tonic-gate } 2397c478bd9Sstevel@tonic-gate 240*f22acdffSgbrunett static int 24188f3d729Sakaplan ftype(char *f, int field) 2427c478bd9Sstevel@tonic-gate { 2437c478bd9Sstevel@tonic-gate struct stat statb; 2447c478bd9Sstevel@tonic-gate 2457c478bd9Sstevel@tonic-gate if (stat(f, &statb) < 0) 2467c478bd9Sstevel@tonic-gate return (0); 2477c478bd9Sstevel@tonic-gate if ((statb.st_mode & field) == field) 2487c478bd9Sstevel@tonic-gate return (1); 2497c478bd9Sstevel@tonic-gate return (0); 2507c478bd9Sstevel@tonic-gate } 2517c478bd9Sstevel@tonic-gate 252*f22acdffSgbrunett static int 25388f3d729Sakaplan filtyp(char *f, int field) 2547c478bd9Sstevel@tonic-gate { 2557c478bd9Sstevel@tonic-gate struct stat statb; 2567c478bd9Sstevel@tonic-gate 2577c478bd9Sstevel@tonic-gate if (field == S_IFLNK) { 2587c478bd9Sstevel@tonic-gate if (lstat(f, &statb) < 0) 2597c478bd9Sstevel@tonic-gate return (0); 2607c478bd9Sstevel@tonic-gate } else { 2617c478bd9Sstevel@tonic-gate if (stat(f, &statb) < 0) 2627c478bd9Sstevel@tonic-gate return (0); 2637c478bd9Sstevel@tonic-gate } 2647c478bd9Sstevel@tonic-gate if ((statb.st_mode & S_IFMT) == field) 2657c478bd9Sstevel@tonic-gate return (1); 2667c478bd9Sstevel@tonic-gate else 2677c478bd9Sstevel@tonic-gate return (0); 2687c478bd9Sstevel@tonic-gate } 2697c478bd9Sstevel@tonic-gate 270*f22acdffSgbrunett static int 27188f3d729Sakaplan fsizep(char *f) 2727c478bd9Sstevel@tonic-gate { 2737c478bd9Sstevel@tonic-gate struct stat statb; 2747c478bd9Sstevel@tonic-gate 2757c478bd9Sstevel@tonic-gate if (stat(f, &statb) < 0) 2767c478bd9Sstevel@tonic-gate return (0); 2777c478bd9Sstevel@tonic-gate return (statb.st_size > 0); 2787c478bd9Sstevel@tonic-gate } 2797c478bd9Sstevel@tonic-gate 280*f22acdffSgbrunett static void 28188f3d729Sakaplan synbad(char *s1, char *s2) 2827c478bd9Sstevel@tonic-gate { 2837c478bd9Sstevel@tonic-gate (void) write(2, "test: ", 6); 2847c478bd9Sstevel@tonic-gate (void) write(2, s1, strlen(s1)); 2857c478bd9Sstevel@tonic-gate (void) write(2, s2, strlen(s2)); 2867c478bd9Sstevel@tonic-gate (void) write(2, "\n", 1); 2877c478bd9Sstevel@tonic-gate exit(255); 2887c478bd9Sstevel@tonic-gate } 289