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