1*88f3d729Sakaplan /* 2*88f3d729Sakaplan * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 3*88f3d729Sakaplan * Use is subject to license terms. 4*88f3d729Sakaplan */ 5*88f3d729Sakaplan 67c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 77c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 87c478bd9Sstevel@tonic-gate 97c478bd9Sstevel@tonic-gate 107c478bd9Sstevel@tonic-gate /* 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 15*88f3d729Sakaplan #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> 237c478bd9Sstevel@tonic-gate #include <sys/types.h> 247c478bd9Sstevel@tonic-gate #include <sys/stat.h> 257c478bd9Sstevel@tonic-gate #define EQ(a,b) ((strcmp(a,b)==0)) 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate int ap; 287c478bd9Sstevel@tonic-gate int ac; 297c478bd9Sstevel@tonic-gate char **av; 307c478bd9Sstevel@tonic-gate 31*88f3d729Sakaplan void synbad(char *s1, char *s2); 32*88f3d729Sakaplan int tio(char *a, int f); 33*88f3d729Sakaplan int ftype(char *f, int field); 34*88f3d729Sakaplan int filtyp(char *f, int field); 35*88f3d729Sakaplan int fsizep(char *f); 36*88f3d729Sakaplan char *nxtarg(int mt); 377c478bd9Sstevel@tonic-gate 38*88f3d729Sakaplan int 39*88f3d729Sakaplan main(int argc, char *argv[]) 407c478bd9Sstevel@tonic-gate { 417c478bd9Sstevel@tonic-gate int status; 427c478bd9Sstevel@tonic-gate 437c478bd9Sstevel@tonic-gate ac = argc; av = argv; ap = 1; 447c478bd9Sstevel@tonic-gate if(EQ(argv[0],"[")) { 457c478bd9Sstevel@tonic-gate if(!EQ(argv[--ac],"]")) 467c478bd9Sstevel@tonic-gate synbad("] missing",""); 477c478bd9Sstevel@tonic-gate } 487c478bd9Sstevel@tonic-gate argv[ac] = 0; 497c478bd9Sstevel@tonic-gate if (ac<=1) exit(1); 507c478bd9Sstevel@tonic-gate status = (exp()?0:1); 517c478bd9Sstevel@tonic-gate if (nxtarg(1)!=0) 527c478bd9Sstevel@tonic-gate synbad("too many arguments",""); 53*88f3d729Sakaplan return (status); 547c478bd9Sstevel@tonic-gate } 557c478bd9Sstevel@tonic-gate 56*88f3d729Sakaplan char * 57*88f3d729Sakaplan nxtarg(int mt) 58*88f3d729Sakaplan { 597c478bd9Sstevel@tonic-gate 607c478bd9Sstevel@tonic-gate if (ap>=ac) { 617c478bd9Sstevel@tonic-gate if(mt) { 627c478bd9Sstevel@tonic-gate ap++; 637c478bd9Sstevel@tonic-gate return(0); 647c478bd9Sstevel@tonic-gate } 657c478bd9Sstevel@tonic-gate synbad("argument expected",""); 667c478bd9Sstevel@tonic-gate } 677c478bd9Sstevel@tonic-gate return(av[ap++]); 687c478bd9Sstevel@tonic-gate } 697c478bd9Sstevel@tonic-gate 70*88f3d729Sakaplan int 71*88f3d729Sakaplan exp(void) 72*88f3d729Sakaplan { 737c478bd9Sstevel@tonic-gate int p1; 747c478bd9Sstevel@tonic-gate char *p2; 757c478bd9Sstevel@tonic-gate 767c478bd9Sstevel@tonic-gate p1 = e1(); 777c478bd9Sstevel@tonic-gate p2 = nxtarg(1); 787c478bd9Sstevel@tonic-gate if (p2 != 0) { 797c478bd9Sstevel@tonic-gate if (EQ(p2, "-o")) 807c478bd9Sstevel@tonic-gate return(p1 | exp()); 817c478bd9Sstevel@tonic-gate if (EQ(p2, "]")) 827c478bd9Sstevel@tonic-gate synbad("syntax error",""); 837c478bd9Sstevel@tonic-gate } 847c478bd9Sstevel@tonic-gate ap--; 857c478bd9Sstevel@tonic-gate return(p1); 867c478bd9Sstevel@tonic-gate } 877c478bd9Sstevel@tonic-gate 88*88f3d729Sakaplan int 89*88f3d729Sakaplan e1(void) 90*88f3d729Sakaplan { 917c478bd9Sstevel@tonic-gate int p1; 927c478bd9Sstevel@tonic-gate char *p2; 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate p1 = e2(); 957c478bd9Sstevel@tonic-gate p2 = nxtarg(1); 967c478bd9Sstevel@tonic-gate if ((p2 != 0) && EQ(p2, "-a")) 977c478bd9Sstevel@tonic-gate return(p1 & e1()); 987c478bd9Sstevel@tonic-gate ap--; 997c478bd9Sstevel@tonic-gate return(p1); 1007c478bd9Sstevel@tonic-gate } 1017c478bd9Sstevel@tonic-gate 102*88f3d729Sakaplan int 103*88f3d729Sakaplan e2(void) 104*88f3d729Sakaplan { 1057c478bd9Sstevel@tonic-gate if (EQ(nxtarg(0), "!")) 1067c478bd9Sstevel@tonic-gate return(!e3()); 1077c478bd9Sstevel@tonic-gate ap--; 1087c478bd9Sstevel@tonic-gate return(e3()); 1097c478bd9Sstevel@tonic-gate } 1107c478bd9Sstevel@tonic-gate 111*88f3d729Sakaplan int 112*88f3d729Sakaplan e3(void) 113*88f3d729Sakaplan { 1147c478bd9Sstevel@tonic-gate int p1; 115*88f3d729Sakaplan char *a; 1167c478bd9Sstevel@tonic-gate char *p2; 1177c478bd9Sstevel@tonic-gate int int1, int2; 1187c478bd9Sstevel@tonic-gate 1197c478bd9Sstevel@tonic-gate a=nxtarg(0); 1207c478bd9Sstevel@tonic-gate if(EQ(a, "(")) { 1217c478bd9Sstevel@tonic-gate p1 = exp(); 1227c478bd9Sstevel@tonic-gate if(!EQ(nxtarg(0), ")")) synbad(") expected",""); 1237c478bd9Sstevel@tonic-gate return(p1); 1247c478bd9Sstevel@tonic-gate } 1257c478bd9Sstevel@tonic-gate p2 = nxtarg(1); 1267c478bd9Sstevel@tonic-gate ap--; 1277c478bd9Sstevel@tonic-gate if ((p2 == 0) || (!EQ(p2, "=") && !EQ(p2, "!="))) { 1287c478bd9Sstevel@tonic-gate if(EQ(a, "-r")) 1297c478bd9Sstevel@tonic-gate return(tio(nxtarg(0), 4)); 1307c478bd9Sstevel@tonic-gate 1317c478bd9Sstevel@tonic-gate if(EQ(a, "-w")) 1327c478bd9Sstevel@tonic-gate return(tio(nxtarg(0), 2)); 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate if(EQ(a, "-x")) 1357c478bd9Sstevel@tonic-gate return(tio(nxtarg(0), 1)); 1367c478bd9Sstevel@tonic-gate 1377c478bd9Sstevel@tonic-gate if(EQ(a, "-d")) 1387c478bd9Sstevel@tonic-gate return(filtyp(nxtarg(0), S_IFDIR)); 1397c478bd9Sstevel@tonic-gate 1407c478bd9Sstevel@tonic-gate if(EQ(a, "-c")) 1417c478bd9Sstevel@tonic-gate return(filtyp(nxtarg(0), S_IFCHR)); 1427c478bd9Sstevel@tonic-gate 1437c478bd9Sstevel@tonic-gate if(EQ(a, "-b")) 1447c478bd9Sstevel@tonic-gate return(filtyp(nxtarg(0), S_IFBLK)); 1457c478bd9Sstevel@tonic-gate 1467c478bd9Sstevel@tonic-gate if(EQ(a, "-f")) { 1477c478bd9Sstevel@tonic-gate struct stat statb; 1487c478bd9Sstevel@tonic-gate 1497c478bd9Sstevel@tonic-gate return(stat(nxtarg(0), &statb) >= 0 && 1507c478bd9Sstevel@tonic-gate (statb.st_mode & S_IFMT) != S_IFDIR); 1517c478bd9Sstevel@tonic-gate } 1527c478bd9Sstevel@tonic-gate 1537c478bd9Sstevel@tonic-gate if(EQ(a, "-h")) 1547c478bd9Sstevel@tonic-gate return(filtyp(nxtarg(0), S_IFLNK)); 1557c478bd9Sstevel@tonic-gate 1567c478bd9Sstevel@tonic-gate if(EQ(a, "-u")) 1577c478bd9Sstevel@tonic-gate return(ftype(nxtarg(0), S_ISUID)); 1587c478bd9Sstevel@tonic-gate 1597c478bd9Sstevel@tonic-gate if(EQ(a, "-g")) 1607c478bd9Sstevel@tonic-gate return(ftype(nxtarg(0), S_ISGID)); 1617c478bd9Sstevel@tonic-gate 1627c478bd9Sstevel@tonic-gate if(EQ(a, "-k")) 1637c478bd9Sstevel@tonic-gate return(ftype(nxtarg(0), S_ISVTX)); 1647c478bd9Sstevel@tonic-gate 1657c478bd9Sstevel@tonic-gate if(EQ(a, "-p")) 1667c478bd9Sstevel@tonic-gate #ifdef S_IFIFO 1677c478bd9Sstevel@tonic-gate return(filtyp(nxtarg(0), S_IFIFO)); 1687c478bd9Sstevel@tonic-gate #else 1697c478bd9Sstevel@tonic-gate return(nxtarg(0), 0); 1707c478bd9Sstevel@tonic-gate #endif 1717c478bd9Sstevel@tonic-gate 1727c478bd9Sstevel@tonic-gate if(EQ(a, "-s")) 1737c478bd9Sstevel@tonic-gate return(fsizep(nxtarg(0))); 1747c478bd9Sstevel@tonic-gate 1757c478bd9Sstevel@tonic-gate if(EQ(a, "-t")) 1767c478bd9Sstevel@tonic-gate if(ap>=ac) 1777c478bd9Sstevel@tonic-gate return(isatty(1)); 1787c478bd9Sstevel@tonic-gate else if (EQ((a = nxtarg(0)), "-a") || EQ(a, "-o")) { 1797c478bd9Sstevel@tonic-gate ap--; 1807c478bd9Sstevel@tonic-gate return(isatty(1)); 1817c478bd9Sstevel@tonic-gate } else 1827c478bd9Sstevel@tonic-gate return(isatty(atoi(a))); 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate if(EQ(a, "-n")) 1857c478bd9Sstevel@tonic-gate return(!EQ(nxtarg(0), "")); 1867c478bd9Sstevel@tonic-gate if(EQ(a, "-z")) 1877c478bd9Sstevel@tonic-gate return(EQ(nxtarg(0), "")); 1887c478bd9Sstevel@tonic-gate } 1897c478bd9Sstevel@tonic-gate 1907c478bd9Sstevel@tonic-gate p2 = nxtarg(1); 1917c478bd9Sstevel@tonic-gate if (p2==0) 1927c478bd9Sstevel@tonic-gate return(!EQ(a,"")); 1937c478bd9Sstevel@tonic-gate if (EQ(p2, "-a") || EQ(p2, "-o")) { 1947c478bd9Sstevel@tonic-gate ap--; 1957c478bd9Sstevel@tonic-gate return(!EQ(a,"")); 1967c478bd9Sstevel@tonic-gate } 1977c478bd9Sstevel@tonic-gate if(EQ(p2, "=")) 1987c478bd9Sstevel@tonic-gate return(EQ(nxtarg(0), a)); 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate if(EQ(p2, "!=")) 2017c478bd9Sstevel@tonic-gate return(!EQ(nxtarg(0), a)); 2027c478bd9Sstevel@tonic-gate 2037c478bd9Sstevel@tonic-gate int1 = atoi(a); 2047c478bd9Sstevel@tonic-gate int2 = atoi(nxtarg(0)); 2057c478bd9Sstevel@tonic-gate if(EQ(p2, "-eq")) 2067c478bd9Sstevel@tonic-gate return(int1==int2); 2077c478bd9Sstevel@tonic-gate if(EQ(p2, "-ne")) 2087c478bd9Sstevel@tonic-gate return(int1!=int2); 2097c478bd9Sstevel@tonic-gate if(EQ(p2, "-gt")) 2107c478bd9Sstevel@tonic-gate return(int1>int2); 2117c478bd9Sstevel@tonic-gate if(EQ(p2, "-lt")) 2127c478bd9Sstevel@tonic-gate return(int1<int2); 2137c478bd9Sstevel@tonic-gate if(EQ(p2, "-ge")) 2147c478bd9Sstevel@tonic-gate return(int1>=int2); 2157c478bd9Sstevel@tonic-gate if(EQ(p2, "-le")) 2167c478bd9Sstevel@tonic-gate return(int1<=int2); 2177c478bd9Sstevel@tonic-gate 2187c478bd9Sstevel@tonic-gate synbad("unknown operator ",p2); 2197c478bd9Sstevel@tonic-gate /* NOTREACHED */ 220*88f3d729Sakaplan return (0); 2217c478bd9Sstevel@tonic-gate } 2227c478bd9Sstevel@tonic-gate 223*88f3d729Sakaplan int 224*88f3d729Sakaplan tio(char *a, int f) 2257c478bd9Sstevel@tonic-gate { 2267c478bd9Sstevel@tonic-gate 2277c478bd9Sstevel@tonic-gate if (access(a, f) == 0) 2287c478bd9Sstevel@tonic-gate return(1); 2297c478bd9Sstevel@tonic-gate else 2307c478bd9Sstevel@tonic-gate return(0); 2317c478bd9Sstevel@tonic-gate } 2327c478bd9Sstevel@tonic-gate 233*88f3d729Sakaplan int 234*88f3d729Sakaplan ftype(char *f, int field) 2357c478bd9Sstevel@tonic-gate { 2367c478bd9Sstevel@tonic-gate struct stat statb; 2377c478bd9Sstevel@tonic-gate 2387c478bd9Sstevel@tonic-gate if(stat(f,&statb)<0) 2397c478bd9Sstevel@tonic-gate return(0); 2407c478bd9Sstevel@tonic-gate if((statb.st_mode&field)==field) 2417c478bd9Sstevel@tonic-gate return(1); 2427c478bd9Sstevel@tonic-gate return(0); 2437c478bd9Sstevel@tonic-gate } 2447c478bd9Sstevel@tonic-gate 245*88f3d729Sakaplan int 246*88f3d729Sakaplan filtyp(char *f, int field) 2477c478bd9Sstevel@tonic-gate { 2487c478bd9Sstevel@tonic-gate struct stat statb; 2497c478bd9Sstevel@tonic-gate 2507c478bd9Sstevel@tonic-gate if (field == S_IFLNK) { 2517c478bd9Sstevel@tonic-gate if(lstat(f,&statb)<0) 2527c478bd9Sstevel@tonic-gate return(0); 2537c478bd9Sstevel@tonic-gate } else { 2547c478bd9Sstevel@tonic-gate if(stat(f,&statb)<0) 2557c478bd9Sstevel@tonic-gate return(0); 2567c478bd9Sstevel@tonic-gate } 2577c478bd9Sstevel@tonic-gate if((statb.st_mode&S_IFMT)==field) 2587c478bd9Sstevel@tonic-gate return(1); 2597c478bd9Sstevel@tonic-gate else 2607c478bd9Sstevel@tonic-gate return(0); 2617c478bd9Sstevel@tonic-gate } 2627c478bd9Sstevel@tonic-gate 263*88f3d729Sakaplan int 264*88f3d729Sakaplan fsizep(char *f) 2657c478bd9Sstevel@tonic-gate { 2667c478bd9Sstevel@tonic-gate struct stat statb; 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate if(stat(f,&statb)<0) 2697c478bd9Sstevel@tonic-gate return(0); 2707c478bd9Sstevel@tonic-gate return(statb.st_size>0); 2717c478bd9Sstevel@tonic-gate } 2727c478bd9Sstevel@tonic-gate 273*88f3d729Sakaplan void 274*88f3d729Sakaplan synbad(char *s1, char *s2) 2757c478bd9Sstevel@tonic-gate { 2767c478bd9Sstevel@tonic-gate (void) write(2, "test: ", 6); 2777c478bd9Sstevel@tonic-gate (void) write(2, s1, strlen(s1)); 2787c478bd9Sstevel@tonic-gate (void) write(2, s2, strlen(s2)); 2797c478bd9Sstevel@tonic-gate (void) write(2, "\n", 1); 2807c478bd9Sstevel@tonic-gate exit(255); 2817c478bd9Sstevel@tonic-gate } 2827c478bd9Sstevel@tonic-gate 283*88f3d729Sakaplan int 284*88f3d729Sakaplan length(char *s) 2857c478bd9Sstevel@tonic-gate { 2867c478bd9Sstevel@tonic-gate char *es=s; 2877c478bd9Sstevel@tonic-gate while(*es++); 2887c478bd9Sstevel@tonic-gate return(es-s-1); 2897c478bd9Sstevel@tonic-gate } 290