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