OpenSolaris_b135/ucbcmd/test/test.c

Compare this file to the similar file:
Show the results in this format:

/*
 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
/*	  All Rights Reserved  	*/

/*
 * Copyright (c) 1980 Regents of the University of California.
 * All rights reserved. The Berkeley software License Agreement
 * specifies the terms and conditions for redistribution.
 */

#pragma ident	"%Z%%M%	%I%	%E% SMI"

/*
 * test expression
 * [ expression ]
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>

#define	EQ(a, b)	((strcmp(a, b) == 0))

static char *nxtarg(int mt);
static int exp(void);
static int e1(void);
static int e2(void);
static int e3(void);
static int tio(char *a, int f);
static int ftype(char *f, int field);
static int filtyp(char *f, int field);
static int fsizep(char *f);
static void synbad(char *s1, char *s2);

static int	ap;
static int	ac;
static char	**av;

int
main(int argc, char *argv[])
{
	int status;

	ac = argc; av = argv; ap = 1;
	if (EQ(argv[0], "[")) {
		if (!EQ(argv[--ac], "]"))
			synbad("] missing", "");
	}
	argv[ac] = 0;
	if (ac <= 1)
		exit(1);
	status = (exp() ? 0 : 1);
	if (nxtarg(1) != 0)
		synbad("too many arguments", "");
	return (status);
}

static char *
nxtarg(int mt)
{
	if (ap >= ac) {
		if (mt) {
			ap++;
			return (0);
		}
		synbad("argument expected", "");
	}
	return (av[ap++]);
}

static int
exp(void)
{
	int p1;
	char *p2;

	p1 = e1();
	p2 = nxtarg(1);
	if (p2 != 0) {
		if (EQ(p2, "-o"))
			return (p1 | exp());
		if (EQ(p2, "]"))
			synbad("syntax error", "");
	}
	ap--;
	return (p1);
}

static int
e1(void)
{
	int p1;
	char *p2;

	p1 = e2();
	p2 = nxtarg(1);
	if ((p2 != 0) && EQ(p2, "-a"))
		return (p1 & e1());
	ap--;
	return (p1);
}

static int
e2(void)
{
	if (EQ(nxtarg(0), "!"))
		return (!e3());
	ap--;
	return (e3());
}

static int
e3(void)
{
	int p1;
	char *a;
	char *p2;
	int int1, int2;

	a = nxtarg(0);
	if (EQ(a, "(")) {
		p1 = exp();
		if (!EQ(nxtarg(0), ")")) synbad(") expected", "");
		return (p1);
	}
	p2 = nxtarg(1);
	ap--;
	if ((p2 == 0) || (!EQ(p2, "=") && !EQ(p2, "!="))) {
		if (EQ(a, "-r"))
			return (tio(nxtarg(0), 4));

		if (EQ(a, "-w"))
			return (tio(nxtarg(0), 2));

		if (EQ(a, "-x"))
			return (tio(nxtarg(0), 1));

		if (EQ(a, "-d"))
			return (filtyp(nxtarg(0), S_IFDIR));

		if (EQ(a, "-c"))
			return (filtyp(nxtarg(0), S_IFCHR));

		if (EQ(a, "-b"))
			return (filtyp(nxtarg(0), S_IFBLK));

		if (EQ(a, "-f")) {
			struct stat statb;

			return (stat(nxtarg(0), &statb) >= 0 &&
			    (statb.st_mode & S_IFMT) != S_IFDIR);
		}

		if (EQ(a, "-h"))
			return (filtyp(nxtarg(0), S_IFLNK));

		if (EQ(a, "-u"))
			return (ftype(nxtarg(0), S_ISUID));

		if (EQ(a, "-g"))
			return (ftype(nxtarg(0), S_ISGID));

		if (EQ(a, "-k"))
			return (ftype(nxtarg(0), S_ISVTX));

		if (EQ(a, "-p"))
#ifdef S_IFIFO
			return (filtyp(nxtarg(0), S_IFIFO));
#else
			return (nxtarg(0), 0);
#endif

		if (EQ(a, "-s"))
			return (fsizep(nxtarg(0)));

		if (EQ(a, "-t"))
			if (ap >= ac)
				return (isatty(1));
			else if (EQ((a = nxtarg(0)), "-a") || EQ(a, "-o")) {
				ap--;
				return (isatty(1));
			} else
				return (isatty(atoi(a)));

		if (EQ(a, "-n"))
			return (!EQ(nxtarg(0), ""));
		if (EQ(a, "-z"))
			return (EQ(nxtarg(0), ""));
	}

	p2 = nxtarg(1);
	if (p2 == 0)
		return (!EQ(a, ""));
	if (EQ(p2, "-a") || EQ(p2, "-o")) {
		ap--;
		return (!EQ(a, ""));
	}
	if (EQ(p2, "="))
		return (EQ(nxtarg(0), a));

	if (EQ(p2, "!="))
		return (!EQ(nxtarg(0), a));

	int1 = atoi(a);
	int2 = atoi(nxtarg(0));
	if (EQ(p2, "-eq"))
		return (int1 == int2);
	if (EQ(p2, "-ne"))
		return (int1 != int2);
	if (EQ(p2, "-gt"))
		return (int1 > int2);
	if (EQ(p2, "-lt"))
		return (int1 < int2);
	if (EQ(p2, "-ge"))
		return (int1 >= int2);
	if (EQ(p2, "-le"))
		return (int1 <= int2);

	synbad("unknown operator ", p2);
	/* NOTREACHED */
	return (0);
}

static int
tio(char *a, int f)
{
	if (access(a, f) == 0)
		return (1);
	else
		return (0);
}

static int
ftype(char *f, int field)
{
	struct stat statb;

	if (stat(f, &statb) < 0)
		return (0);
	if ((statb.st_mode & field) == field)
		return (1);
	return (0);
}

static int
filtyp(char *f, int field)
{
	struct stat statb;

	if (field == S_IFLNK) {
		if (lstat(f, &statb) < 0)
			return (0);
	} else {
		if (stat(f, &statb) < 0)
			return (0);
	}
	if ((statb.st_mode & S_IFMT) == field)
		return (1);
	else
		return (0);
}

static int
fsizep(char *f)
{
	struct stat statb;

	if (stat(f, &statb) < 0)
		return (0);
	return (statb.st_size > 0);
}

static void
synbad(char *s1, char *s2)
{
	(void) write(2, "test: ", 6);
	(void) write(2, s1, strlen(s1));
	(void) write(2, s2, strlen(s2));
	(void) write(2, "\n", 1);
	exit(255);
}