xref: /onnv-gate/usr/src/ucbcmd/test/test.c (revision 319:f5718580cc5e)
1216Sakaplan /*
2216Sakaplan  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
3216Sakaplan  * Use is subject to license terms.
4216Sakaplan  */
5216Sakaplan 
60Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
70Sstevel@tonic-gate /*	  All Rights Reserved  	*/
80Sstevel@tonic-gate 
9*319Sgbrunett /*
10*319Sgbrunett  * Copyright (c) 1980 Regents of the University of California.
110Sstevel@tonic-gate  * All rights reserved. The Berkeley software License Agreement
120Sstevel@tonic-gate  * specifies the terms and conditions for redistribution.
130Sstevel@tonic-gate  */
140Sstevel@tonic-gate 
15216Sakaplan #pragma ident	"%Z%%M%	%I%	%E% SMI"
160Sstevel@tonic-gate 
170Sstevel@tonic-gate /*
180Sstevel@tonic-gate  * test expression
190Sstevel@tonic-gate  * [ expression ]
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate 
220Sstevel@tonic-gate #include <stdio.h>
23*319Sgbrunett #include <stdlib.h>
24*319Sgbrunett #include <unistd.h>
250Sstevel@tonic-gate #include <sys/types.h>
260Sstevel@tonic-gate #include <sys/stat.h>
27*319Sgbrunett #include <string.h>
280Sstevel@tonic-gate 
29*319Sgbrunett #define	EQ(a, b)	((strcmp(a, b) == 0))
300Sstevel@tonic-gate 
31*319Sgbrunett static char *nxtarg(int mt);
32*319Sgbrunett static int exp(void);
33*319Sgbrunett static int e1(void);
34*319Sgbrunett static int e2(void);
35*319Sgbrunett static int e3(void);
36*319Sgbrunett static int tio(char *a, int f);
37*319Sgbrunett static int ftype(char *f, int field);
38*319Sgbrunett static int filtyp(char *f, int field);
39*319Sgbrunett static int fsizep(char *f);
40*319Sgbrunett static void synbad(char *s1, char *s2);
41*319Sgbrunett 
42*319Sgbrunett static int	ap;
43*319Sgbrunett static int	ac;
44*319Sgbrunett static char	**av;
450Sstevel@tonic-gate 
46216Sakaplan int
main(int argc,char * argv[])47216Sakaplan main(int argc, char *argv[])
480Sstevel@tonic-gate {
490Sstevel@tonic-gate 	int status;
500Sstevel@tonic-gate 
510Sstevel@tonic-gate 	ac = argc; av = argv; ap = 1;
52*319Sgbrunett 	if (EQ(argv[0], "[")) {
53*319Sgbrunett 		if (!EQ(argv[--ac], "]"))
54*319Sgbrunett 			synbad("] missing", "");
550Sstevel@tonic-gate 	}
560Sstevel@tonic-gate 	argv[ac] = 0;
57*319Sgbrunett 	if (ac <= 1)
58*319Sgbrunett 		exit(1);
59*319Sgbrunett 	status = (exp() ? 0 : 1);
60*319Sgbrunett 	if (nxtarg(1) != 0)
61*319Sgbrunett 		synbad("too many arguments", "");
62216Sakaplan 	return (status);
630Sstevel@tonic-gate }
640Sstevel@tonic-gate 
65*319Sgbrunett static char *
nxtarg(int mt)66216Sakaplan nxtarg(int mt)
67216Sakaplan {
68*319Sgbrunett 	if (ap >= ac) {
69*319Sgbrunett 		if (mt) {
700Sstevel@tonic-gate 			ap++;
71*319Sgbrunett 			return (0);
720Sstevel@tonic-gate 		}
73*319Sgbrunett 		synbad("argument expected", "");
740Sstevel@tonic-gate 	}
75*319Sgbrunett 	return (av[ap++]);
760Sstevel@tonic-gate }
770Sstevel@tonic-gate 
78*319Sgbrunett static int
exp(void)79216Sakaplan exp(void)
80216Sakaplan {
810Sstevel@tonic-gate 	int p1;
820Sstevel@tonic-gate 	char *p2;
830Sstevel@tonic-gate 
840Sstevel@tonic-gate 	p1 = e1();
850Sstevel@tonic-gate 	p2 = nxtarg(1);
860Sstevel@tonic-gate 	if (p2 != 0) {
870Sstevel@tonic-gate 		if (EQ(p2, "-o"))
88*319Sgbrunett 			return (p1 | exp());
890Sstevel@tonic-gate 		if (EQ(p2, "]"))
90*319Sgbrunett 			synbad("syntax error", "");
910Sstevel@tonic-gate 	}
920Sstevel@tonic-gate 	ap--;
93*319Sgbrunett 	return (p1);
940Sstevel@tonic-gate }
950Sstevel@tonic-gate 
96*319Sgbrunett static int
e1(void)97216Sakaplan e1(void)
98216Sakaplan {
990Sstevel@tonic-gate 	int p1;
1000Sstevel@tonic-gate 	char *p2;
1010Sstevel@tonic-gate 
1020Sstevel@tonic-gate 	p1 = e2();
1030Sstevel@tonic-gate 	p2 = nxtarg(1);
1040Sstevel@tonic-gate 	if ((p2 != 0) && EQ(p2, "-a"))
105*319Sgbrunett 		return (p1 & e1());
1060Sstevel@tonic-gate 	ap--;
107*319Sgbrunett 	return (p1);
1080Sstevel@tonic-gate }
1090Sstevel@tonic-gate 
110*319Sgbrunett static int
e2(void)111216Sakaplan e2(void)
112216Sakaplan {
1130Sstevel@tonic-gate 	if (EQ(nxtarg(0), "!"))
114*319Sgbrunett 		return (!e3());
1150Sstevel@tonic-gate 	ap--;
116*319Sgbrunett 	return (e3());
1170Sstevel@tonic-gate }
1180Sstevel@tonic-gate 
119*319Sgbrunett static int
e3(void)120216Sakaplan e3(void)
121216Sakaplan {
1220Sstevel@tonic-gate 	int p1;
123216Sakaplan 	char *a;
1240Sstevel@tonic-gate 	char *p2;
1250Sstevel@tonic-gate 	int int1, int2;
1260Sstevel@tonic-gate 
127*319Sgbrunett 	a = nxtarg(0);
128*319Sgbrunett 	if (EQ(a, "(")) {
1290Sstevel@tonic-gate 		p1 = exp();
130*319Sgbrunett 		if (!EQ(nxtarg(0), ")")) synbad(") expected", "");
131*319Sgbrunett 		return (p1);
1320Sstevel@tonic-gate 	}
1330Sstevel@tonic-gate 	p2 = nxtarg(1);
1340Sstevel@tonic-gate 	ap--;
1350Sstevel@tonic-gate 	if ((p2 == 0) || (!EQ(p2, "=") && !EQ(p2, "!="))) {
136*319Sgbrunett 		if (EQ(a, "-r"))
137*319Sgbrunett 			return (tio(nxtarg(0), 4));
1380Sstevel@tonic-gate 
139*319Sgbrunett 		if (EQ(a, "-w"))
140*319Sgbrunett 			return (tio(nxtarg(0), 2));
1410Sstevel@tonic-gate 
142*319Sgbrunett 		if (EQ(a, "-x"))
143*319Sgbrunett 			return (tio(nxtarg(0), 1));
1440Sstevel@tonic-gate 
145*319Sgbrunett 		if (EQ(a, "-d"))
146*319Sgbrunett 			return (filtyp(nxtarg(0), S_IFDIR));
1470Sstevel@tonic-gate 
148*319Sgbrunett 		if (EQ(a, "-c"))
149*319Sgbrunett 			return (filtyp(nxtarg(0), S_IFCHR));
1500Sstevel@tonic-gate 
151*319Sgbrunett 		if (EQ(a, "-b"))
152*319Sgbrunett 			return (filtyp(nxtarg(0), S_IFBLK));
1530Sstevel@tonic-gate 
154*319Sgbrunett 		if (EQ(a, "-f")) {
1550Sstevel@tonic-gate 			struct stat statb;
1560Sstevel@tonic-gate 
157*319Sgbrunett 			return (stat(nxtarg(0), &statb) >= 0 &&
1580Sstevel@tonic-gate 			    (statb.st_mode & S_IFMT) != S_IFDIR);
1590Sstevel@tonic-gate 		}
1600Sstevel@tonic-gate 
161*319Sgbrunett 		if (EQ(a, "-h"))
162*319Sgbrunett 			return (filtyp(nxtarg(0), S_IFLNK));
1630Sstevel@tonic-gate 
164*319Sgbrunett 		if (EQ(a, "-u"))
165*319Sgbrunett 			return (ftype(nxtarg(0), S_ISUID));
1660Sstevel@tonic-gate 
167*319Sgbrunett 		if (EQ(a, "-g"))
168*319Sgbrunett 			return (ftype(nxtarg(0), S_ISGID));
1690Sstevel@tonic-gate 
170*319Sgbrunett 		if (EQ(a, "-k"))
171*319Sgbrunett 			return (ftype(nxtarg(0), S_ISVTX));
1720Sstevel@tonic-gate 
173*319Sgbrunett 		if (EQ(a, "-p"))
1740Sstevel@tonic-gate #ifdef S_IFIFO
175*319Sgbrunett 			return (filtyp(nxtarg(0), S_IFIFO));
1760Sstevel@tonic-gate #else
177*319Sgbrunett 			return (nxtarg(0), 0);
1780Sstevel@tonic-gate #endif
1790Sstevel@tonic-gate 
180*319Sgbrunett 		if (EQ(a, "-s"))
181*319Sgbrunett 			return (fsizep(nxtarg(0)));
1820Sstevel@tonic-gate 
183*319Sgbrunett 		if (EQ(a, "-t"))
184*319Sgbrunett 			if (ap >= ac)
185*319Sgbrunett 				return (isatty(1));
1860Sstevel@tonic-gate 			else if (EQ((a = nxtarg(0)), "-a") || EQ(a, "-o")) {
1870Sstevel@tonic-gate 				ap--;
188*319Sgbrunett 				return (isatty(1));
1890Sstevel@tonic-gate 			} else
190*319Sgbrunett 				return (isatty(atoi(a)));
1910Sstevel@tonic-gate 
192*319Sgbrunett 		if (EQ(a, "-n"))
193*319Sgbrunett 			return (!EQ(nxtarg(0), ""));
194*319Sgbrunett 		if (EQ(a, "-z"))
195*319Sgbrunett 			return (EQ(nxtarg(0), ""));
1960Sstevel@tonic-gate 	}
1970Sstevel@tonic-gate 
1980Sstevel@tonic-gate 	p2 = nxtarg(1);
199*319Sgbrunett 	if (p2 == 0)
200*319Sgbrunett 		return (!EQ(a, ""));
2010Sstevel@tonic-gate 	if (EQ(p2, "-a") || EQ(p2, "-o")) {
2020Sstevel@tonic-gate 		ap--;
203*319Sgbrunett 		return (!EQ(a, ""));
2040Sstevel@tonic-gate 	}
205*319Sgbrunett 	if (EQ(p2, "="))
206*319Sgbrunett 		return (EQ(nxtarg(0), a));
2070Sstevel@tonic-gate 
208*319Sgbrunett 	if (EQ(p2, "!="))
209*319Sgbrunett 		return (!EQ(nxtarg(0), a));
2100Sstevel@tonic-gate 
2110Sstevel@tonic-gate 	int1 = atoi(a);
2120Sstevel@tonic-gate 	int2 = atoi(nxtarg(0));
213*319Sgbrunett 	if (EQ(p2, "-eq"))
214*319Sgbrunett 		return (int1 == int2);
215*319Sgbrunett 	if (EQ(p2, "-ne"))
216*319Sgbrunett 		return (int1 != int2);
217*319Sgbrunett 	if (EQ(p2, "-gt"))
218*319Sgbrunett 		return (int1 > int2);
219*319Sgbrunett 	if (EQ(p2, "-lt"))
220*319Sgbrunett 		return (int1 < int2);
221*319Sgbrunett 	if (EQ(p2, "-ge"))
222*319Sgbrunett 		return (int1 >= int2);
223*319Sgbrunett 	if (EQ(p2, "-le"))
224*319Sgbrunett 		return (int1 <= int2);
2250Sstevel@tonic-gate 
226*319Sgbrunett 	synbad("unknown operator ", p2);
2270Sstevel@tonic-gate 	/* NOTREACHED */
228216Sakaplan 	return (0);
2290Sstevel@tonic-gate }
2300Sstevel@tonic-gate 
231*319Sgbrunett static int
tio(char * a,int f)232216Sakaplan tio(char *a, int f)
2330Sstevel@tonic-gate {
2340Sstevel@tonic-gate 	if (access(a, f) == 0)
235*319Sgbrunett 		return (1);
2360Sstevel@tonic-gate 	else
237*319Sgbrunett 		return (0);
2380Sstevel@tonic-gate }
2390Sstevel@tonic-gate 
240*319Sgbrunett static int
ftype(char * f,int field)241216Sakaplan ftype(char *f, int field)
2420Sstevel@tonic-gate {
2430Sstevel@tonic-gate 	struct stat statb;
2440Sstevel@tonic-gate 
245*319Sgbrunett 	if (stat(f, &statb) < 0)
246*319Sgbrunett 		return (0);
247*319Sgbrunett 	if ((statb.st_mode & field) == field)
248*319Sgbrunett 		return (1);
249*319Sgbrunett 	return (0);
2500Sstevel@tonic-gate }
2510Sstevel@tonic-gate 
252*319Sgbrunett static int
filtyp(char * f,int field)253216Sakaplan filtyp(char *f, int field)
2540Sstevel@tonic-gate {
2550Sstevel@tonic-gate 	struct stat statb;
2560Sstevel@tonic-gate 
2570Sstevel@tonic-gate 	if (field == S_IFLNK) {
258*319Sgbrunett 		if (lstat(f, &statb) < 0)
259*319Sgbrunett 			return (0);
2600Sstevel@tonic-gate 	} else {
261*319Sgbrunett 		if (stat(f, &statb) < 0)
262*319Sgbrunett 			return (0);
2630Sstevel@tonic-gate 	}
264*319Sgbrunett 	if ((statb.st_mode & S_IFMT) == field)
265*319Sgbrunett 		return (1);
2660Sstevel@tonic-gate 	else
267*319Sgbrunett 		return (0);
2680Sstevel@tonic-gate }
2690Sstevel@tonic-gate 
270*319Sgbrunett static int
fsizep(char * f)271216Sakaplan fsizep(char *f)
2720Sstevel@tonic-gate {
2730Sstevel@tonic-gate 	struct stat statb;
2740Sstevel@tonic-gate 
275*319Sgbrunett 	if (stat(f, &statb) < 0)
276*319Sgbrunett 		return (0);
277*319Sgbrunett 	return (statb.st_size > 0);
2780Sstevel@tonic-gate }
2790Sstevel@tonic-gate 
280*319Sgbrunett static void
synbad(char * s1,char * s2)281216Sakaplan synbad(char *s1, char *s2)
2820Sstevel@tonic-gate {
2830Sstevel@tonic-gate 	(void) write(2, "test: ", 6);
2840Sstevel@tonic-gate 	(void) write(2, s1, strlen(s1));
2850Sstevel@tonic-gate 	(void) write(2, s2, strlen(s2));
2860Sstevel@tonic-gate 	(void) write(2, "\n", 1);
2870Sstevel@tonic-gate 	exit(255);
2880Sstevel@tonic-gate }
289