/* vi: set sw=4 ts=4: */
/*
 * test implementation for busybox
 *
 * Copyright (c) by a whole pile of folks:
 *
 *     test(1); version 7-like  --  author Erik Baalbergen
 *     modified by Eric Gisin to be used as built-in.
 *     modified by Arnold Robbins to add SVR3 compatibility
 *     (-x -c -b -p -u -g -k) plus Korn's -L -nt -ot -ef and new -S (socket).
 *     modified by J.T. Conklin for NetBSD.
 *     modified by Herbert Xu to be used as built-in in ash.
 *     modified by Erik Andersen <andersen@codepoet.org> to be used
 *     in busybox.
 *     modified by Bernhard Fischer to be useable (i.e. a bit less bloaty).
 *
 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
 *
 * Original copyright notice states:
 *     "This program is in the Public Domain."
 */

#include "libbb.h"
#include <setjmp.h>

/* This is a NOFORK applet. Be very careful! */

/* test_main() is called from shells, and we need to be extra careful here.
 * This is true regardless of PREFER_APPLETS and STANDALONE_SHELL
 * state. */


/* test(1) accepts the following grammar:
	oexpr	::= aexpr | aexpr "-o" oexpr ;
	aexpr	::= nexpr | nexpr "-a" aexpr ;
	nexpr	::= primary | "!" primary
	primary ::= unary-operator operand
		| operand binary-operator operand
		| operand
		| "(" oexpr ")"
		;
	unary-operator ::= "-r"|"-w"|"-x"|"-f"|"-d"|"-c"|"-b"|"-p"|
		"-u"|"-g"|"-k"|"-s"|"-t"|"-z"|"-n"|"-o"|"-O"|"-G"|"-L"|"-S";

	binary-operator ::= "="|"=="|"!="|"-eq"|"-ne"|"-ge"|"-gt"|"-le"|"-lt"|
			"-nt"|"-ot"|"-ef";
	operand ::= <any legal UNIX file name>
*/

enum token {
	EOI,
	FILRD,
	FILWR,
	FILEX,
	FILEXIST,
	FILREG,
	FILDIR,
	FILCDEV,
	FILBDEV,
	FILFIFO,
	FILSOCK,
	FILSYM,
	FILGZ,
	FILTT,
	FILSUID,
	FILSGID,
	FILSTCK,
	FILNT,
	FILOT,
	FILEQ,
	FILUID,
	FILGID,
	STREZ,
	STRNZ,
	STREQ,
	STRNE,
	STRLT,
	STRGT,
	INTEQ,
	INTNE,
	INTGE,
	INTGT,
	INTLE,
	INTLT,
	UNOT,
	BAND,
	BOR,
	LPAREN,
	RPAREN,
	OPERAND
};
#define is_int_op(a)      (((unsigned char)((a) - INTEQ)) <= 5)
#define is_str_op(a)      (((unsigned char)((a) - STREZ)) <= 5)
#define is_file_op(a)     (((unsigned char)((a) - FILNT)) <= 2)
#define is_file_access(a) (((unsigned char)((a) - FILRD)) <= 2)
#define is_file_type(a)   (((unsigned char)((a) - FILREG)) <= 5)
#define is_file_bit(a)    (((unsigned char)((a) - FILSUID)) <= 2)
enum token_types {
	UNOP,
	BINOP,
	BUNOP,
	BBINOP,
	PAREN
};

static const struct t_op {
	char op_text[4];
	unsigned char op_num, op_type;
} ops[] = {
	{ "-r", FILRD   , UNOP   },
	{ "-w", FILWR   , UNOP   },
	{ "-x", FILEX   , UNOP   },
	{ "-e", FILEXIST, UNOP   },
	{ "-f", FILREG  , UNOP   },
	{ "-d", FILDIR  , UNOP   },
	{ "-c", FILCDEV , UNOP   },
	{ "-b", FILBDEV , UNOP   },
	{ "-p", FILFIFO , UNOP   },
	{ "-u", FILSUID , UNOP   },
	{ "-g", FILSGID , UNOP   },
	{ "-k", FILSTCK , UNOP   },
	{ "-s", FILGZ   , UNOP   },
	{ "-t", FILTT   , UNOP   },
	{ "-z", STREZ   , UNOP   },
	{ "-n", STRNZ   , UNOP   },
	{ "-h", FILSYM  , UNOP   },    /* for backwards compat */

	{ "-O" , FILUID , UNOP   },
	{ "-G" , FILGID , UNOP   },
	{ "-L" , FILSYM , UNOP   },
	{ "-S" , FILSOCK, UNOP   },
	{ "="  , STREQ  , BINOP  },
	{ "==" , STREQ  , BINOP  },
	{ "!=" , STRNE  , BINOP  },
	{ "<"  , STRLT  , BINOP  },
	{ ">"  , STRGT  , BINOP  },
	{ "-eq", INTEQ  , BINOP  },
	{ "-ne", INTNE  , BINOP  },
	{ "-ge", INTGE  , BINOP  },
	{ "-gt", INTGT  , BINOP  },
	{ "-le", INTLE  , BINOP  },
	{ "-lt", INTLT  , BINOP  },
	{ "-nt", FILNT  , BINOP  },
	{ "-ot", FILOT  , BINOP  },
	{ "-ef", FILEQ  , BINOP  },
	{ "!"  , UNOT   , BUNOP  },
	{ "-a" , BAND   , BBINOP },
	{ "-o" , BOR    , BBINOP },
	{ "("  , LPAREN , PAREN  },
	{ ")"  , RPAREN , PAREN  },
};


#if ENABLE_FEATURE_TEST_64
typedef int64_t arith_t;
#else
typedef int arith_t;
#endif


/* We try to minimize both static and stack usage. */
struct statics {
	char **t_wp;
	const struct t_op *t_wp_op;
	gid_t *group_array;
	int ngroups;
	jmp_buf leaving;
};

/* Make it reside in writable memory, yet make compiler understand
 * that it is not going to change. */
static struct statics *const ptr_to_statics __attribute__ ((section (".data")));

#define S (*ptr_to_statics)
#define t_wp            (S.t_wp         )
#define t_wp_op         (S.t_wp_op      )
#define group_array     (S.group_array  )
#define ngroups         (S.ngroups      )
#define leaving         (S.leaving      )

#define INIT_S() do { \
	(*(struct statics**)&ptr_to_statics) = xzalloc(sizeof(S)); \
} while (0)
#define DEINIT_S() do { \
	free(ptr_to_statics); \
} while (0)

static arith_t primary(enum token n);

static void syntax(const char *op, const char *msg) ATTRIBUTE_NORETURN;
static void syntax(const char *op, const char *msg)
{
	if (op && *op) {
		bb_error_msg("%s: %s", op, msg);
	} else {
		bb_error_msg("%s: %s"+4, msg);
	}
	longjmp(leaving, 2);
}

/* atoi with error detection */
//XXX: FIXME: duplicate of existing libbb function?
static arith_t getn(const char *s)
{
	char *p;
#if ENABLE_FEATURE_TEST_64
	long long r;
#else
	long r;
#endif

	errno = 0;
#if ENABLE_FEATURE_TEST_64
	r = strtoll(s, &p, 10);
#else
	r = strtol(s, &p, 10);
#endif

	if (errno != 0)
		syntax(s, "out of range");

	if (*(skip_whitespace(p)))
		syntax(s, "bad number");

	return r;
}

/* UNUSED
static int newerf(const char *f1, const char *f2)
{
	struct stat b1, b2;

	return (stat(f1, &b1) == 0 &&
			stat(f2, &b2) == 0 && b1.st_mtime > b2.st_mtime);
}

static int olderf(const char *f1, const char *f2)
{
	struct stat b1, b2;

	return (stat(f1, &b1) == 0 &&
			stat(f2, &b2) == 0 && b1.st_mtime < b2.st_mtime);
}

static int equalf(const char *f1, const char *f2)
{
	struct stat b1, b2;

	return (stat(f1, &b1) == 0 &&
			stat(f2, &b2) == 0 &&
			b1.st_dev == b2.st_dev && b1.st_ino == b2.st_ino);
}
*/


static enum token t_lex(char *s)
{
	const struct t_op *op;

	t_wp_op = NULL;
	if (s == NULL) {
		return EOI;
	}

	op = ops;
	do {
		if (strcmp(s, op->op_text) == 0) {
			t_wp_op = op;
			return op->op_num;
		}
		op++;
	} while (op < ops + ARRAY_SIZE(ops));

	return OPERAND;
}


static int binop(void)
{
	const char *opnd1, *opnd2;
	struct t_op const *op;
	arith_t val1, val2;

	opnd1 = *t_wp;
	(void) t_lex(*++t_wp);
	op = t_wp_op;

	opnd2 = *++t_wp;
	if (opnd2 == NULL)
		syntax(op->op_text, "argument expected");

	if (is_int_op(op->op_num)) {
		val1 = getn(opnd1);
		val2 = getn(opnd2);
		if (op->op_num == INTEQ)
			return val1 == val2;
		if (op->op_num == INTNE)
			return val1 != val2;
		if (op->op_num == INTGE)
			return val1 >= val2;
		if (op->op_num == INTGT)
			return val1 >  val2;
		if (op->op_num == INTLE)
			return val1 <= val2;
		if (op->op_num == INTLT)
			return val1 <  val2;
	}
	if (is_str_op(op->op_num)) {
		val1 = strcmp(opnd1, opnd2);
		if (op->op_num == STREQ)
			return val1 == 0;
		if (op->op_num == STRNE)
			return val1 != 0;
		if (op->op_num == STRLT)
			return val1 < 0;
		if (op->op_num == STRGT)
			return val1 > 0;
	}
	/* We are sure that these three are by now the only binops we didn't check
	 * yet, so we do not check if the class is correct:
	 */
/*	if (is_file_op(op->op_num)) */
	{
		struct stat b1, b2;

		if (stat(opnd1, &b1) || stat(opnd2, &b2))
			return 0; /* false, since at least one stat failed */
		if (op->op_num == FILNT)
			return b1.st_mtime > b2.st_mtime;
		if (op->op_num == FILOT)
			return b1.st_mtime < b2.st_mtime;
		if (op->op_num == FILEQ)
			return b1.st_dev == b2.st_dev && b1.st_ino == b2.st_ino;
	}
	return 1; /* NOTREACHED */
}


static void initialize_group_array(void)
{
	ngroups = getgroups(0, NULL);
	if (ngroups > 0) {
		/* FIXME: ash tries so hard to not die on OOM,
		 * and we spoil it with just one xrealloc here */
		/* We realloc, because test_main can be entered repeatedly by shell.
		 * Testcase (ash): 'while true; do test -x some_file; done'
		 * and watch top. (some_file must have owner != you) */
		group_array = xrealloc(group_array, ngroups * sizeof(gid_t));
		getgroups(ngroups, group_array);
	}
}


/* Return non-zero if GID is one that we have in our groups list. */
//XXX: FIXME: duplicate of existing libbb function?
// see toplevel TODO file:
// possible code duplication ingroup() and is_a_group_member()
static int is_a_group_member(gid_t gid)
{
	int i;

	/* Short-circuit if possible, maybe saving a call to getgroups(). */
	if (gid == getgid() || gid == getegid())
		return 1;

	if (ngroups == 0)
		initialize_group_array();

	/* Search through the list looking for GID. */
	for (i = 0; i < ngroups; i++)
		if (gid == group_array[i])
			return 1;

	return 0;
}


/* Do the same thing access(2) does, but use the effective uid and gid,
   and don't make the mistake of telling root that any file is
   executable. */
static int test_eaccess(char *path, int mode)
{
	struct stat st;
	unsigned int euid = geteuid();

	if (stat(path, &st) < 0)
		return -1;

	if (euid == 0) {
		/* Root can read or write any file. */
		if (mode != X_OK)
			return 0;

		/* Root can execute any file that has any one of the execute
		   bits set. */
		if (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))
			return 0;
	}

	if (st.st_uid == euid)  /* owner */
		mode <<= 6;
	else if (is_a_group_member(st.st_gid))
		mode <<= 3;

	if (st.st_mode & mode)
		return 0;

	return -1;
}


static int filstat(char *nm, enum token mode)
{
	struct stat s;
	int i = i; /* gcc 3.x thinks it can be used uninitialized */

	if (mode == FILSYM) {
#ifdef S_IFLNK
		if (lstat(nm, &s) == 0) {
			i = S_IFLNK;
			goto filetype;
		}
#endif
		return 0;
	}

	if (stat(nm, &s) != 0)
		return 0;
	if (mode == FILEXIST)
		return 1;
	if (is_file_access(mode)) {
		if (mode == FILRD)
			i = R_OK;
		if (mode == FILWR)
			i = W_OK;
		if (mode == FILEX)
			i = X_OK;
		return test_eaccess(nm, i) == 0;
	}
	if (is_file_type(mode)) {
		if (mode == FILREG)
			i = S_IFREG;
		if (mode == FILDIR)
			i = S_IFDIR;
		if (mode == FILCDEV)
			i = S_IFCHR;
		if (mode == FILBDEV)
			i = S_IFBLK;
		if (mode == FILFIFO) {
#ifdef S_IFIFO
			i = S_IFIFO;
#else
			return 0;
#endif
		}
		if (mode == FILSOCK) {
#ifdef S_IFSOCK
			i = S_IFSOCK;
#else
			return 0;
#endif
		}
 filetype:
		return ((s.st_mode & S_IFMT) == i);
	}
	if (is_file_bit(mode)) {
		if (mode == FILSUID)
			i = S_ISUID;
		if (mode == FILSGID)
			i = S_ISGID;
		if (mode == FILSTCK)
			i = S_ISVTX;
		return ((s.st_mode & i) != 0);
	}
	if (mode == FILGZ)
		return s.st_size > 0L;
	if (mode == FILUID)
		return s.st_uid == geteuid();
	if (mode == FILGID)
		return s.st_gid == getegid();
	return 1; /* NOTREACHED */
}


static arith_t nexpr(enum token n)
{
	if (n == UNOT)
		return !nexpr(t_lex(*++t_wp));
	return primary(n);
}


static arith_t aexpr(enum token n)
{
	arith_t res;

	res = nexpr(n);
	if (t_lex(*++t_wp) == BAND)
		return aexpr(t_lex(*++t_wp)) && res;
	t_wp--;
	return res;
}


static arith_t oexpr(enum token n)
{
	arith_t res;

	res = aexpr(n);
	if (t_lex(*++t_wp) == BOR) {
		return oexpr(t_lex(*++t_wp)) || res;
	}
	t_wp--;
	return res;
}



static arith_t primary(enum token n)
{
	arith_t res;

	if (n == EOI) {
		syntax(NULL, "argument expected");
	}
	if (n == LPAREN) {
		res = oexpr(t_lex(*++t_wp));
		if (t_lex(*++t_wp) != RPAREN)
			syntax(NULL, "closing paren expected");
		return res;
	}
	if (t_wp_op && t_wp_op->op_type == UNOP) {
		/* unary expression */
		if (*++t_wp == NULL)
			syntax(t_wp_op->op_text, "argument expected");
		if (n == STREZ)
			return t_wp[0][0] == '\0';
		if (n == STRNZ)
			return t_wp[0][0] != '\0';
		if (n == FILTT)
			return isatty(getn(*t_wp));
		return filstat(*t_wp, n);
	}

	t_lex(t_wp[1]);
	if (t_wp_op && t_wp_op->op_type == BINOP) {
		return binop();
	}

	return t_wp[0][0] != '\0';
}


int test_main(int argc, char **argv)
{
	int res;
	const char *arg0;
	bool _off;

	arg0 = bb_basename(argv[0]);
	if (arg0[0] == '[') {
		--argc;
		if (!arg0[1]) { /* "[" ? */
			if (NOT_LONE_CHAR(argv[argc], ']')) {
				bb_error_msg("missing ]");
				return 2;
			}
		} else { /* assuming "[[" */
			if (strcmp(argv[argc], "]]") != 0) {
				bb_error_msg("missing ]]");
				return 2;
			}
		}
		argv[argc] = NULL;
	}

	/* We must do DEINIT_S() prior to returning */
	INIT_S();

	res = setjmp(leaving);
	if (res) {
		goto ret;
	}

	/* resetting ngroups is probably unnecessary.  it will
	 * force a new call to getgroups(), which prevents using
	 * group data fetched during a previous call.  but the
	 * only way the group data could be stale is if there's
	 * been an intervening call to setgroups(), and this
	 * isn't likely in the case of a shell.  paranoia
	 * prevails...
	 */
	ngroups = 0;

	/* Implement special cases from POSIX.2, section 4.62.4 */
	if (argc == 1) {
		res = 1;
		goto ret;
	}
	if (argc == 2) {
		res = (*argv[1] == '\0');
		goto ret;
	}

	/* remember if we saw argc==4 which wants *no* '!' test */
	_off = argc - 4;
	if (_off ? (LONE_CHAR(argv[1], '!'))
	         : (argv[1][0] != '!' || argv[1][1] != '\0')
	) {
		if (argc == 3) {
			res = (*argv[2] != '\0');
			goto ret;
		}

		t_lex(argv[2 + _off]);
		if (t_wp_op && t_wp_op->op_type == BINOP) {
			t_wp = &argv[1 + _off];
			res = (binop() == _off);
			goto ret;
		}
	}
	t_wp = &argv[1];
	res = !oexpr(t_lex(*t_wp));

	if (*t_wp != NULL && *++t_wp != NULL) {
		bb_error_msg("%s: unknown operand", *t_wp);
		res = 2;
	}
 ret:
	DEINIT_S();
	return res;
}
