xref: /illumos-gate/usr/src/cmd/sh/test.c (revision ddb365bfc9e868ad24ccdcb0dc91af18b10df082)
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 /*
31  *      test expression
32  *      [ expression ]
33  */
34 
35 #include	"defs.h"
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 
39 extern	int lstat();
40 
41 int	ap, ac;
42 unsigned char **av;
43 
44 int
45 test(int argn, unsigned char *com[])
46 {
47 	ac = argn;
48 	av = com;
49 	ap = 1;
50 	if (eq(com[0],"["))
51 	{
52 		if (!eq(com[--ac], "]"))
53 			failed((unsigned char *)"test", nobracket);
54 	}
55 	com[ac] = 0;
56 	if (ac <= 1)
57 		return(1);
58 	return(exp() ? 0 : 1);
59 }
60 
61 unsigned char *
62 nxtarg(mt)
63 {
64 	if (ap >= ac)
65 	{
66 		if (mt)
67 		{
68 			ap++;
69 			return(0);
70 		}
71 		failed((unsigned char *)"test", noarg);
72 	}
73 	return(av[ap++]);
74 }
75 
76 int
77 exp(void)
78 {
79 	int	p1;
80 	unsigned char	*p2;
81 
82 	p1 = e1();
83 	p2 = nxtarg(1);
84 	if (p2 != 0)
85 	{
86 		if (eq(p2, "-o"))
87 			return(p1 | exp());
88 
89 		/* if (!eq(p2, ")"))
90 			failed((unsigned char *)"test", synmsg); */
91 	}
92 	ap--;
93 	return(p1);
94 }
95 
96 int
97 e1(void)
98 {
99 	int	p1;
100 	unsigned char	*p2;
101 
102 	p1 = e2();
103 	p2 = nxtarg(1);
104 
105 	if ((p2 != 0) && eq(p2, "-a"))
106 		return(p1 & e1());
107 	ap--;
108 	return(p1);
109 }
110 
111 int
112 e2(void)
113 {
114 	if (eq(nxtarg(0), "!"))
115 		return(!e3());
116 	ap--;
117 	return(e3());
118 }
119 
120 int
121 e3(void)
122 {
123 	int	p1;
124 	unsigned char	*a;
125 	unsigned char	*p2;
126 	longlong_t	ll_1, ll_2;
127 
128 	a = nxtarg(0);
129 	if (eq(a, "("))
130 	{
131 		p1 = exp();
132 		if (!eq(nxtarg(0), ")"))
133 			failed((unsigned char *)"test", noparen);
134 		return(p1);
135 	}
136 	p2 = nxtarg(1);
137 	ap--;
138 	if ((p2 == 0) || (!eq(p2, "=") && !eq(p2, "!=")))
139 	{
140 		if (eq(a, "-r"))
141 			return(chk_access(nxtarg(0), S_IREAD, 0) == 0);
142 		if (eq(a, "-w"))
143 			return(chk_access(nxtarg(0), S_IWRITE, 0) == 0);
144 		if (eq(a, "-x"))
145 			return(chk_access(nxtarg(0), S_IEXEC, 0) == 0);
146 		if (eq(a, "-d"))
147 			return(filtyp(nxtarg(0), S_IFDIR));
148 		if (eq(a, "-c"))
149 			return(filtyp(nxtarg(0), S_IFCHR));
150 		if (eq(a, "-b"))
151 			return(filtyp(nxtarg(0), S_IFBLK));
152 		if (eq(a, "-f"))
153 			if (ucb_builtins) {
154 				struct stat statb;
155 
156 				return(stat((char *)nxtarg(0), &statb) >= 0 &&
157 					(statb.st_mode & S_IFMT) != S_IFDIR);
158 			}
159 			else
160 				return(filtyp(nxtarg(0), S_IFREG));
161 		if (eq(a, "-u"))
162 			return(ftype(nxtarg(0), S_ISUID));
163 		if (eq(a, "-g"))
164 			return(ftype(nxtarg(0), S_ISGID));
165 		if (eq(a, "-k"))
166 			return(ftype(nxtarg(0), S_ISVTX));
167 		if (eq(a, "-p"))
168 			return(filtyp(nxtarg(0), S_IFIFO));
169 		if (eq(a, "-h") || eq(a, "-L"))
170 			return(filtyp(nxtarg(0), S_IFLNK));
171    		if (eq(a, "-s"))
172 			return(fsizep(nxtarg(0)));
173 		if (eq(a, "-t"))
174 		{
175 			if (ap >= ac)		/* no args */
176 				return(isatty(1));
177 			else if (eq((a = nxtarg(0)), "-a") || eq(a, "-o"))
178 			{
179 				ap--;
180 				return(isatty(1));
181 			}
182 			else
183 				return(isatty(atoi((char *)a)));
184 		}
185 		if (eq(a, "-n"))
186 			return(!eq(nxtarg(0), ""));
187 		if (eq(a, "-z"))
188 			return(eq(nxtarg(0), ""));
189 	}
190 
191 	p2 = nxtarg(1);
192 	if (p2 == 0)
193 		return(!eq(a, ""));
194 	if (eq(p2, "-a") || eq(p2, "-o"))
195 	{
196 		ap--;
197 		return(!eq(a, ""));
198 	}
199 	if (eq(p2, "="))
200 		return(eq(nxtarg(0), a));
201 	if (eq(p2, "!="))
202 		return(!eq(nxtarg(0), a));
203 	ll_1 = strtoll((char *)a, NULL, 10);
204 	ll_2 = strtoll((char *)nxtarg(0), NULL, 10);
205 	if (eq(p2, "-eq"))
206 		return (ll_1 == ll_2);
207 	if (eq(p2, "-ne"))
208 		return (ll_1 != ll_2);
209 	if (eq(p2, "-gt"))
210 		return (ll_1 > ll_2);
211 	if (eq(p2, "-lt"))
212 		return (ll_1 < ll_2);
213 	if (eq(p2, "-ge"))
214 		return (ll_1 >= ll_2);
215 	if (eq(p2, "-le"))
216 		return (ll_1 <= ll_2);
217 
218 	bfailed((unsigned char *)btest, badop, p2);
219 /* NOTREACHED */
220 }
221 
222 int
223 ftype(unsigned char *f, int field)
224 {
225 	struct stat statb;
226 
227 	if (stat((char *)f, &statb) < 0)
228 		return(0);
229 	if ((statb.st_mode & field) == field)
230 		return(1);
231 	return(0);
232 }
233 
234 int
235 filtyp(unsigned char *f, int field)
236 {
237 	struct stat statb;
238 	int (*statf)() = (field == S_IFLNK) ? lstat : stat;
239 
240 	if ((*statf)(f, &statb) < 0)
241 		return(0);
242 	if ((statb.st_mode & S_IFMT) == field)
243 		return(1);
244 	else
245 		return(0);
246 }
247 
248 
249 int
250 fsizep(unsigned char *f)
251 {
252 	struct stat statb;
253 
254 	if (stat((char *)f, &statb) < 0)
255 		return(0);
256 	return(statb.st_size > 0);
257 }
258