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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 23 /* 24 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 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 void bfailed(unsigned char *, unsigned char *, unsigned char *) __NORETURN; 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", "] missing"); 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", "argument expected"); 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", ") expected"); 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, (unsigned char *)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 261 /* 262 * fake diagnostics to continue to look like original 263 * test(1) diagnostics 264 */ 265 void 266 bfailed(unsigned char *s1, unsigned char *s2, unsigned char *s3) 267 { 268 prp(); 269 prs(s1); 270 if (s2) 271 { 272 prs(colon); 273 prs(s2); 274 prs(s3); 275 } 276 newline(); 277 exitsh(ERROR); 278 } 279