xref: /illumos-gate/usr/src/cmd/sh/test.c (revision 355b4669e025ff377602b6fc7caaf30dbc218371)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
28 /*	  All Rights Reserved  	*/
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 /*
33  *      test expression
34  *      [ expression ]
35  */
36 
37 #include	"defs.h"
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 
41 extern	int lstat();
42 
43 int	ap, ac;
44 unsigned char **av;
45 
46 int
47 test(int argn, unsigned char *com[])
48 {
49 	ac = argn;
50 	av = com;
51 	ap = 1;
52 	if (eq(com[0],"["))
53 	{
54 		if (!eq(com[--ac], "]"))
55 			failed((unsigned char *)"test", nobracket);
56 	}
57 	com[ac] = 0;
58 	if (ac <= 1)
59 		return(1);
60 	return(exp() ? 0 : 1);
61 }
62 
63 unsigned char *
64 nxtarg(mt)
65 {
66 	if (ap >= ac)
67 	{
68 		if (mt)
69 		{
70 			ap++;
71 			return(0);
72 		}
73 		failed((unsigned char *)"test", noarg);
74 	}
75 	return(av[ap++]);
76 }
77 
78 int
79 exp(void)
80 {
81 	int	p1;
82 	unsigned char	*p2;
83 
84 	p1 = e1();
85 	p2 = nxtarg(1);
86 	if (p2 != 0)
87 	{
88 		if (eq(p2, "-o"))
89 			return(p1 | exp());
90 
91 		/* if (!eq(p2, ")"))
92 			failed((unsigned char *)"test", synmsg); */
93 	}
94 	ap--;
95 	return(p1);
96 }
97 
98 int
99 e1(void)
100 {
101 	int	p1;
102 	unsigned char	*p2;
103 
104 	p1 = e2();
105 	p2 = nxtarg(1);
106 
107 	if ((p2 != 0) && eq(p2, "-a"))
108 		return(p1 & e1());
109 	ap--;
110 	return(p1);
111 }
112 
113 int
114 e2(void)
115 {
116 	if (eq(nxtarg(0), "!"))
117 		return(!e3());
118 	ap--;
119 	return(e3());
120 }
121 
122 int
123 e3(void)
124 {
125 	int	p1;
126 	unsigned char	*a;
127 	unsigned char	*p2;
128 	longlong_t	ll_1, ll_2;
129 
130 	a = nxtarg(0);
131 	if (eq(a, "("))
132 	{
133 		p1 = exp();
134 		if (!eq(nxtarg(0), ")"))
135 			failed((unsigned char *)"test", noparen);
136 		return(p1);
137 	}
138 	p2 = nxtarg(1);
139 	ap--;
140 	if ((p2 == 0) || (!eq(p2, "=") && !eq(p2, "!=")))
141 	{
142 		if (eq(a, "-r"))
143 			return(chk_access(nxtarg(0), S_IREAD, 0) == 0);
144 		if (eq(a, "-w"))
145 			return(chk_access(nxtarg(0), S_IWRITE, 0) == 0);
146 		if (eq(a, "-x"))
147 			return(chk_access(nxtarg(0), S_IEXEC, 0) == 0);
148 		if (eq(a, "-d"))
149 			return(filtyp(nxtarg(0), S_IFDIR));
150 		if (eq(a, "-c"))
151 			return(filtyp(nxtarg(0), S_IFCHR));
152 		if (eq(a, "-b"))
153 			return(filtyp(nxtarg(0), S_IFBLK));
154 		if (eq(a, "-f"))
155 			if (ucb_builtins) {
156 				struct stat statb;
157 
158 				return(stat((char *)nxtarg(0), &statb) >= 0 &&
159 					(statb.st_mode & S_IFMT) != S_IFDIR);
160 			}
161 			else
162 				return(filtyp(nxtarg(0), S_IFREG));
163 		if (eq(a, "-u"))
164 			return(ftype(nxtarg(0), S_ISUID));
165 		if (eq(a, "-g"))
166 			return(ftype(nxtarg(0), S_ISGID));
167 		if (eq(a, "-k"))
168 			return(ftype(nxtarg(0), S_ISVTX));
169 		if (eq(a, "-p"))
170 			return(filtyp(nxtarg(0), S_IFIFO));
171 		if (eq(a, "-h") || eq(a, "-L"))
172 			return(filtyp(nxtarg(0), S_IFLNK));
173    		if (eq(a, "-s"))
174 			return(fsizep(nxtarg(0)));
175 		if (eq(a, "-t"))
176 		{
177 			if (ap >= ac)		/* no args */
178 				return(isatty(1));
179 			else if (eq((a = nxtarg(0)), "-a") || eq(a, "-o"))
180 			{
181 				ap--;
182 				return(isatty(1));
183 			}
184 			else
185 				return(isatty(atoi((char *)a)));
186 		}
187 		if (eq(a, "-n"))
188 			return(!eq(nxtarg(0), ""));
189 		if (eq(a, "-z"))
190 			return(eq(nxtarg(0), ""));
191 	}
192 
193 	p2 = nxtarg(1);
194 	if (p2 == 0)
195 		return(!eq(a, ""));
196 	if (eq(p2, "-a") || eq(p2, "-o"))
197 	{
198 		ap--;
199 		return(!eq(a, ""));
200 	}
201 	if (eq(p2, "="))
202 		return(eq(nxtarg(0), a));
203 	if (eq(p2, "!="))
204 		return(!eq(nxtarg(0), a));
205 	ll_1 = strtoll((char *)a, NULL, 10);
206 	ll_2 = strtoll((char *)nxtarg(0), NULL, 10);
207 	if (eq(p2, "-eq"))
208 		return (ll_1 == ll_2);
209 	if (eq(p2, "-ne"))
210 		return (ll_1 != ll_2);
211 	if (eq(p2, "-gt"))
212 		return (ll_1 > ll_2);
213 	if (eq(p2, "-lt"))
214 		return (ll_1 < ll_2);
215 	if (eq(p2, "-ge"))
216 		return (ll_1 >= ll_2);
217 	if (eq(p2, "-le"))
218 		return (ll_1 <= ll_2);
219 
220 	bfailed((unsigned char *)btest, badop, p2);
221 /* NOTREACHED */
222 }
223 
224 int
225 ftype(unsigned char *f, int field)
226 {
227 	struct stat statb;
228 
229 	if (stat((char *)f, &statb) < 0)
230 		return(0);
231 	if ((statb.st_mode & field) == field)
232 		return(1);
233 	return(0);
234 }
235 
236 int
237 filtyp(unsigned char *f, int field)
238 {
239 	struct stat statb;
240 	int (*statf)() = (field == S_IFLNK) ? lstat : stat;
241 
242 	if ((*statf)(f, &statb) < 0)
243 		return(0);
244 	if ((statb.st_mode & S_IFMT) == field)
245 		return(1);
246 	else
247 		return(0);
248 }
249 
250 
251 int
252 fsizep(unsigned char *f)
253 {
254 	struct stat statb;
255 
256 	if (stat((char *)f, &statb) < 0)
257 		return(0);
258 	return(statb.st_size > 0);
259 }
260