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
41extern	int lstat();
42
43int	ap, ac;
44unsigned char **av;
45
46int
47test(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
63unsigned char *
64nxtarg(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
78int
79exp(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
98int
99e1(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
113int
114e2(void)
115{
116	if (eq(nxtarg(0), "!"))
117		return(!e3());
118	ap--;
119	return(e3());
120}
121
122int
123e3(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
224int
225ftype(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
236int
237filtyp(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
251int
252fsizep(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