1*0Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 2*0Sstevel@tonic-gate /* All Rights Reserved */ 3*0Sstevel@tonic-gate 4*0Sstevel@tonic-gate 5*0Sstevel@tonic-gate /* Copyright (c) 1980 Regents of the University of California. 6*0Sstevel@tonic-gate * All rights reserved. The Berkeley software License Agreement 7*0Sstevel@tonic-gate * specifies the terms and conditions for redistribution. 8*0Sstevel@tonic-gate */ 9*0Sstevel@tonic-gate 10*0Sstevel@tonic-gate /* 11*0Sstevel@tonic-gate * Copyright (c) 1983, 1984 1985, 1986, 1987, 1988, Sun Microsystems, Inc. 12*0Sstevel@tonic-gate * All Rights Reserved. 13*0Sstevel@tonic-gate */ 14*0Sstevel@tonic-gate 15*0Sstevel@tonic-gate #ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.1 */ 16*0Sstevel@tonic-gate 17*0Sstevel@tonic-gate /* 18*0Sstevel@tonic-gate * test expression 19*0Sstevel@tonic-gate * [ expression ] 20*0Sstevel@tonic-gate */ 21*0Sstevel@tonic-gate 22*0Sstevel@tonic-gate #include <stdio.h> 23*0Sstevel@tonic-gate #include <sys/types.h> 24*0Sstevel@tonic-gate #include <sys/stat.h> 25*0Sstevel@tonic-gate #define EQ(a,b) ((strcmp(a,b)==0)) 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate int ap; 28*0Sstevel@tonic-gate int ac; 29*0Sstevel@tonic-gate char **av; 30*0Sstevel@tonic-gate 31*0Sstevel@tonic-gate char *nxtarg(); 32*0Sstevel@tonic-gate 33*0Sstevel@tonic-gate main(argc, argv) 34*0Sstevel@tonic-gate char *argv[]; 35*0Sstevel@tonic-gate { 36*0Sstevel@tonic-gate int status; 37*0Sstevel@tonic-gate 38*0Sstevel@tonic-gate ac = argc; av = argv; ap = 1; 39*0Sstevel@tonic-gate if(EQ(argv[0],"[")) { 40*0Sstevel@tonic-gate if(!EQ(argv[--ac],"]")) 41*0Sstevel@tonic-gate synbad("] missing",""); 42*0Sstevel@tonic-gate } 43*0Sstevel@tonic-gate argv[ac] = 0; 44*0Sstevel@tonic-gate if (ac<=1) exit(1); 45*0Sstevel@tonic-gate status = (exp()?0:1); 46*0Sstevel@tonic-gate if (nxtarg(1)!=0) 47*0Sstevel@tonic-gate synbad("too many arguments",""); 48*0Sstevel@tonic-gate exit(status); 49*0Sstevel@tonic-gate } 50*0Sstevel@tonic-gate 51*0Sstevel@tonic-gate char *nxtarg(mt) { 52*0Sstevel@tonic-gate 53*0Sstevel@tonic-gate if (ap>=ac) { 54*0Sstevel@tonic-gate if(mt) { 55*0Sstevel@tonic-gate ap++; 56*0Sstevel@tonic-gate return(0); 57*0Sstevel@tonic-gate } 58*0Sstevel@tonic-gate synbad("argument expected",""); 59*0Sstevel@tonic-gate } 60*0Sstevel@tonic-gate return(av[ap++]); 61*0Sstevel@tonic-gate } 62*0Sstevel@tonic-gate 63*0Sstevel@tonic-gate exp() { 64*0Sstevel@tonic-gate int p1; 65*0Sstevel@tonic-gate char *p2; 66*0Sstevel@tonic-gate 67*0Sstevel@tonic-gate p1 = e1(); 68*0Sstevel@tonic-gate p2 = nxtarg(1); 69*0Sstevel@tonic-gate if (p2 != 0) { 70*0Sstevel@tonic-gate if (EQ(p2, "-o")) 71*0Sstevel@tonic-gate return(p1 | exp()); 72*0Sstevel@tonic-gate if (EQ(p2, "]")) 73*0Sstevel@tonic-gate synbad("syntax error",""); 74*0Sstevel@tonic-gate } 75*0Sstevel@tonic-gate ap--; 76*0Sstevel@tonic-gate return(p1); 77*0Sstevel@tonic-gate } 78*0Sstevel@tonic-gate 79*0Sstevel@tonic-gate e1() { 80*0Sstevel@tonic-gate int p1; 81*0Sstevel@tonic-gate char *p2; 82*0Sstevel@tonic-gate 83*0Sstevel@tonic-gate p1 = e2(); 84*0Sstevel@tonic-gate p2 = nxtarg(1); 85*0Sstevel@tonic-gate if ((p2 != 0) && EQ(p2, "-a")) 86*0Sstevel@tonic-gate return(p1 & e1()); 87*0Sstevel@tonic-gate ap--; 88*0Sstevel@tonic-gate return(p1); 89*0Sstevel@tonic-gate } 90*0Sstevel@tonic-gate 91*0Sstevel@tonic-gate e2() { 92*0Sstevel@tonic-gate if (EQ(nxtarg(0), "!")) 93*0Sstevel@tonic-gate return(!e3()); 94*0Sstevel@tonic-gate ap--; 95*0Sstevel@tonic-gate return(e3()); 96*0Sstevel@tonic-gate } 97*0Sstevel@tonic-gate 98*0Sstevel@tonic-gate e3() { 99*0Sstevel@tonic-gate int p1; 100*0Sstevel@tonic-gate register char *a; 101*0Sstevel@tonic-gate char *p2; 102*0Sstevel@tonic-gate int int1, int2; 103*0Sstevel@tonic-gate 104*0Sstevel@tonic-gate a=nxtarg(0); 105*0Sstevel@tonic-gate if(EQ(a, "(")) { 106*0Sstevel@tonic-gate p1 = exp(); 107*0Sstevel@tonic-gate if(!EQ(nxtarg(0), ")")) synbad(") expected",""); 108*0Sstevel@tonic-gate return(p1); 109*0Sstevel@tonic-gate } 110*0Sstevel@tonic-gate p2 = nxtarg(1); 111*0Sstevel@tonic-gate ap--; 112*0Sstevel@tonic-gate if ((p2 == 0) || (!EQ(p2, "=") && !EQ(p2, "!="))) { 113*0Sstevel@tonic-gate if(EQ(a, "-r")) 114*0Sstevel@tonic-gate return(tio(nxtarg(0), 4)); 115*0Sstevel@tonic-gate 116*0Sstevel@tonic-gate if(EQ(a, "-w")) 117*0Sstevel@tonic-gate return(tio(nxtarg(0), 2)); 118*0Sstevel@tonic-gate 119*0Sstevel@tonic-gate if(EQ(a, "-x")) 120*0Sstevel@tonic-gate return(tio(nxtarg(0), 1)); 121*0Sstevel@tonic-gate 122*0Sstevel@tonic-gate if(EQ(a, "-d")) 123*0Sstevel@tonic-gate return(filtyp(nxtarg(0), S_IFDIR)); 124*0Sstevel@tonic-gate 125*0Sstevel@tonic-gate if(EQ(a, "-c")) 126*0Sstevel@tonic-gate return(filtyp(nxtarg(0), S_IFCHR)); 127*0Sstevel@tonic-gate 128*0Sstevel@tonic-gate if(EQ(a, "-b")) 129*0Sstevel@tonic-gate return(filtyp(nxtarg(0), S_IFBLK)); 130*0Sstevel@tonic-gate 131*0Sstevel@tonic-gate if(EQ(a, "-f")) { 132*0Sstevel@tonic-gate struct stat statb; 133*0Sstevel@tonic-gate 134*0Sstevel@tonic-gate return(stat(nxtarg(0), &statb) >= 0 && 135*0Sstevel@tonic-gate (statb.st_mode & S_IFMT) != S_IFDIR); 136*0Sstevel@tonic-gate } 137*0Sstevel@tonic-gate 138*0Sstevel@tonic-gate if(EQ(a, "-h")) 139*0Sstevel@tonic-gate return(filtyp(nxtarg(0), S_IFLNK)); 140*0Sstevel@tonic-gate 141*0Sstevel@tonic-gate if(EQ(a, "-u")) 142*0Sstevel@tonic-gate return(ftype(nxtarg(0), S_ISUID)); 143*0Sstevel@tonic-gate 144*0Sstevel@tonic-gate if(EQ(a, "-g")) 145*0Sstevel@tonic-gate return(ftype(nxtarg(0), S_ISGID)); 146*0Sstevel@tonic-gate 147*0Sstevel@tonic-gate if(EQ(a, "-k")) 148*0Sstevel@tonic-gate return(ftype(nxtarg(0), S_ISVTX)); 149*0Sstevel@tonic-gate 150*0Sstevel@tonic-gate if(EQ(a, "-p")) 151*0Sstevel@tonic-gate #ifdef S_IFIFO 152*0Sstevel@tonic-gate return(filtyp(nxtarg(0), S_IFIFO)); 153*0Sstevel@tonic-gate #else 154*0Sstevel@tonic-gate return(nxtarg(0), 0); 155*0Sstevel@tonic-gate #endif 156*0Sstevel@tonic-gate 157*0Sstevel@tonic-gate if(EQ(a, "-s")) 158*0Sstevel@tonic-gate return(fsizep(nxtarg(0))); 159*0Sstevel@tonic-gate 160*0Sstevel@tonic-gate if(EQ(a, "-t")) 161*0Sstevel@tonic-gate if(ap>=ac) 162*0Sstevel@tonic-gate return(isatty(1)); 163*0Sstevel@tonic-gate else if (EQ((a = nxtarg(0)), "-a") || EQ(a, "-o")) { 164*0Sstevel@tonic-gate ap--; 165*0Sstevel@tonic-gate return(isatty(1)); 166*0Sstevel@tonic-gate } else 167*0Sstevel@tonic-gate return(isatty(atoi(a))); 168*0Sstevel@tonic-gate 169*0Sstevel@tonic-gate if(EQ(a, "-n")) 170*0Sstevel@tonic-gate return(!EQ(nxtarg(0), "")); 171*0Sstevel@tonic-gate if(EQ(a, "-z")) 172*0Sstevel@tonic-gate return(EQ(nxtarg(0), "")); 173*0Sstevel@tonic-gate } 174*0Sstevel@tonic-gate 175*0Sstevel@tonic-gate p2 = nxtarg(1); 176*0Sstevel@tonic-gate if (p2==0) 177*0Sstevel@tonic-gate return(!EQ(a,"")); 178*0Sstevel@tonic-gate if (EQ(p2, "-a") || EQ(p2, "-o")) { 179*0Sstevel@tonic-gate ap--; 180*0Sstevel@tonic-gate return(!EQ(a,"")); 181*0Sstevel@tonic-gate } 182*0Sstevel@tonic-gate if(EQ(p2, "=")) 183*0Sstevel@tonic-gate return(EQ(nxtarg(0), a)); 184*0Sstevel@tonic-gate 185*0Sstevel@tonic-gate if(EQ(p2, "!=")) 186*0Sstevel@tonic-gate return(!EQ(nxtarg(0), a)); 187*0Sstevel@tonic-gate 188*0Sstevel@tonic-gate int1 = atoi(a); 189*0Sstevel@tonic-gate int2 = atoi(nxtarg(0)); 190*0Sstevel@tonic-gate if(EQ(p2, "-eq")) 191*0Sstevel@tonic-gate return(int1==int2); 192*0Sstevel@tonic-gate if(EQ(p2, "-ne")) 193*0Sstevel@tonic-gate return(int1!=int2); 194*0Sstevel@tonic-gate if(EQ(p2, "-gt")) 195*0Sstevel@tonic-gate return(int1>int2); 196*0Sstevel@tonic-gate if(EQ(p2, "-lt")) 197*0Sstevel@tonic-gate return(int1<int2); 198*0Sstevel@tonic-gate if(EQ(p2, "-ge")) 199*0Sstevel@tonic-gate return(int1>=int2); 200*0Sstevel@tonic-gate if(EQ(p2, "-le")) 201*0Sstevel@tonic-gate return(int1<=int2); 202*0Sstevel@tonic-gate 203*0Sstevel@tonic-gate synbad("unknown operator ",p2); 204*0Sstevel@tonic-gate /* NOTREACHED */ 205*0Sstevel@tonic-gate } 206*0Sstevel@tonic-gate 207*0Sstevel@tonic-gate tio(a, f) 208*0Sstevel@tonic-gate char *a; 209*0Sstevel@tonic-gate int f; 210*0Sstevel@tonic-gate { 211*0Sstevel@tonic-gate 212*0Sstevel@tonic-gate if (access(a, f) == 0) 213*0Sstevel@tonic-gate return(1); 214*0Sstevel@tonic-gate else 215*0Sstevel@tonic-gate return(0); 216*0Sstevel@tonic-gate } 217*0Sstevel@tonic-gate 218*0Sstevel@tonic-gate ftype(f, field) 219*0Sstevel@tonic-gate char *f; 220*0Sstevel@tonic-gate int field; 221*0Sstevel@tonic-gate { 222*0Sstevel@tonic-gate struct stat statb; 223*0Sstevel@tonic-gate 224*0Sstevel@tonic-gate if(stat(f,&statb)<0) 225*0Sstevel@tonic-gate return(0); 226*0Sstevel@tonic-gate if((statb.st_mode&field)==field) 227*0Sstevel@tonic-gate return(1); 228*0Sstevel@tonic-gate return(0); 229*0Sstevel@tonic-gate } 230*0Sstevel@tonic-gate 231*0Sstevel@tonic-gate filtyp(f, field) 232*0Sstevel@tonic-gate char *f; 233*0Sstevel@tonic-gate int field; 234*0Sstevel@tonic-gate { 235*0Sstevel@tonic-gate struct stat statb; 236*0Sstevel@tonic-gate 237*0Sstevel@tonic-gate if (field == S_IFLNK) { 238*0Sstevel@tonic-gate if(lstat(f,&statb)<0) 239*0Sstevel@tonic-gate return(0); 240*0Sstevel@tonic-gate } else { 241*0Sstevel@tonic-gate if(stat(f,&statb)<0) 242*0Sstevel@tonic-gate return(0); 243*0Sstevel@tonic-gate } 244*0Sstevel@tonic-gate if((statb.st_mode&S_IFMT)==field) 245*0Sstevel@tonic-gate return(1); 246*0Sstevel@tonic-gate else 247*0Sstevel@tonic-gate return(0); 248*0Sstevel@tonic-gate } 249*0Sstevel@tonic-gate 250*0Sstevel@tonic-gate fsizep(f) 251*0Sstevel@tonic-gate char *f; 252*0Sstevel@tonic-gate { 253*0Sstevel@tonic-gate struct stat statb; 254*0Sstevel@tonic-gate 255*0Sstevel@tonic-gate if(stat(f,&statb)<0) 256*0Sstevel@tonic-gate return(0); 257*0Sstevel@tonic-gate return(statb.st_size>0); 258*0Sstevel@tonic-gate } 259*0Sstevel@tonic-gate 260*0Sstevel@tonic-gate synbad(s1,s2) 261*0Sstevel@tonic-gate char *s1, *s2; 262*0Sstevel@tonic-gate { 263*0Sstevel@tonic-gate (void) write(2, "test: ", 6); 264*0Sstevel@tonic-gate (void) write(2, s1, strlen(s1)); 265*0Sstevel@tonic-gate (void) write(2, s2, strlen(s2)); 266*0Sstevel@tonic-gate (void) write(2, "\n", 1); 267*0Sstevel@tonic-gate exit(255); 268*0Sstevel@tonic-gate } 269*0Sstevel@tonic-gate 270*0Sstevel@tonic-gate length(s) 271*0Sstevel@tonic-gate char *s; 272*0Sstevel@tonic-gate { 273*0Sstevel@tonic-gate char *es=s; 274*0Sstevel@tonic-gate while(*es++); 275*0Sstevel@tonic-gate return(es-s-1); 276*0Sstevel@tonic-gate } 277