/* Authors: Joshua Brindle <jbrindle@tresys.com>
 * 	    Jason Tang <jtang@tresys.com>
 *
 * Copyright (C) 2005-2006 Tresys Technology, LLC
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <assert.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>

#include <sepol/policydb/flask_types.h>
#include <sepol/policydb/policydb.h>
#include <sepol/policydb/util.h>
#include <dso.h>

struct val_to_name {
	unsigned int val;
	char *name;
};

/* Add an unsigned integer to a dynamically reallocated array.  *cnt
 * is a reference pointer to the number of values already within array
 * *a; it will be incremented upon successfully appending i.  If *a is
 * NULL then this function will create a new array (*cnt is reset to
 * 0).  Return 0 on success, -1 on out of memory. */
int add_i_to_a(uint32_t i, uint32_t * cnt, uint32_t ** a)
{
	if (cnt == NULL || a == NULL)
		return -1;

	/* FIX ME: This is not very elegant! We use an array that we
	 * grow as new uint32_t are added to an array.  But rather
	 * than be smart about it, for now we realloc() the array each
	 * time a new uint32_t is added! */
	if (*a != NULL)
		*a = (uint32_t *) realloc(*a, (*cnt + 1) * sizeof(uint32_t));
	else {			/* empty list */

		*cnt = 0;
		*a = (uint32_t *) malloc(sizeof(uint32_t));
	}
	if (*a == NULL) {
		return -1;
	}
	(*a)[*cnt] = i;
	(*cnt)++;
	return 0;
}

static int perm_name(hashtab_key_t key, hashtab_datum_t datum, void *data)
{
	struct val_to_name *v = data;
	perm_datum_t *perdatum;

	perdatum = (perm_datum_t *) datum;

	if (v->val == perdatum->s.value) {
		v->name = key;
		return 1;
	}

	return 0;
}

char *sepol_av_to_string(policydb_t * policydbp, uint32_t tclass,
			 sepol_access_vector_t av)
{
	struct val_to_name v;
	static char avbuf[1024];
	class_datum_t *cladatum;
	char *perm = NULL, *p;
	unsigned int i;
	int rc;
	int avlen = 0, len;

	memset(avbuf, 0, sizeof avbuf);
	cladatum = policydbp->class_val_to_struct[tclass - 1];
	p = avbuf;
	for (i = 0; i < cladatum->permissions.nprim; i++) {
		if (av & (1 << i)) {
			v.val = i + 1;
			rc = hashtab_map(cladatum->permissions.table,
					 perm_name, &v);
			if (!rc && cladatum->comdatum) {
				rc = hashtab_map(cladatum->comdatum->
						 permissions.table, perm_name,
						 &v);
			}
			if (rc)
				perm = v.name;
			if (perm) {
				len =
				    snprintf(p, sizeof(avbuf) - avlen, " %s",
					     perm);
				if (len < 0
				    || (size_t) len >= (sizeof(avbuf) - avlen))
					return NULL;
				p += len;
				avlen += len;
			}
		}
	}

	return avbuf;
}

#define next_bit_in_range(i, p) ((i + 1 < sizeof(p)*8) && xperm_test((i + 1), p))

char *sepol_extended_perms_to_string(avtab_extended_perms_t *xperms)
{
	uint16_t value;
	uint16_t low_bit;
	uint16_t low_value;
	unsigned int bit;
	unsigned int in_range = 0;
	static char xpermsbuf[2048];
	xpermsbuf[0] = '\0';
	char *p;
	int len, xpermslen = 0;
	p = xpermsbuf;

	if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
		&& (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER))
		return NULL;

	len = snprintf(p, sizeof(xpermsbuf) - xpermslen, "ioctl { ");
	p += len;
	xpermslen += len;

	for (bit = 0; bit < sizeof(xperms->perms)*8; bit++) {
		if (!xperm_test(bit, xperms->perms))
			continue;

		if (in_range && next_bit_in_range(bit, xperms->perms)) {
			/* continue until high value found */
			continue;
		} else if (next_bit_in_range(bit, xperms->perms)) {
			/* low value */
			low_bit = bit;
			in_range = 1;
			continue;
		}

		if (xperms->specified & AVTAB_XPERMS_IOCTLFUNCTION) {
			value = xperms->driver<<8 | bit;
			low_value = xperms->driver<<8 | low_bit;
			if (in_range) {
				len = snprintf(p, sizeof(xpermsbuf) - xpermslen, "0x%hx-0x%hx ", low_value, value);
			} else {
				len = snprintf(p, sizeof(xpermsbuf) - xpermslen, "0x%hx ", value);
			}
		} else if (xperms->specified & AVTAB_XPERMS_IOCTLDRIVER) {
			value = bit << 8;
			low_value = low_bit << 8;
			if (in_range) {
				len = snprintf(p, sizeof(xpermsbuf) - xpermslen, "0x%hx-0x%hx ", low_value, (uint16_t) (value|0xff));
			} else {
				len = snprintf(p, sizeof(xpermsbuf) - xpermslen, "0x%hx-0x%hx ", value, (uint16_t) (value|0xff));
			}

		}

		if (len < 0 || (size_t) len >= (sizeof(xpermsbuf) - xpermslen))
			return NULL;

		p += len;
		xpermslen += len;
		if (in_range)
			in_range = 0;
	}

	len = snprintf(p, sizeof(xpermsbuf) - xpermslen, "}");
	if (len < 0 || (size_t) len >= (sizeof(xpermsbuf) - xpermslen))
		return NULL;

	return xpermsbuf;
}

/*
 * The tokenize and tokenize_str functions may be used to
 * replace sscanf to read tokens from buffers.
 */

/* Read a token from a buffer */
static inline int tokenize_str(char delim, char **str, char **ptr, size_t *len)
{
	char *tmp_buf = *ptr;
	*str = NULL;

	while (**ptr != '\0') {
		if (isspace(delim) && isspace(**ptr)) {
			(*ptr)++;
			break;
		} else if (!isspace(delim) && **ptr == delim) {
			(*ptr)++;
			break;
		}

		(*ptr)++;
	}

	*len = *ptr - tmp_buf;
	/* If the end of the string has not been reached, this will ensure the
	 * delimiter is not included when returning the token.
	 */
	if (**ptr != '\0') {
		(*len)--;
	}

	*str = strndup(tmp_buf, *len);
	if (!*str) {
		return -1;
	}

	/* Squash spaces if the delimiter is a whitespace character */
	while (**ptr != '\0' && isspace(delim) && isspace(**ptr)) {
		(*ptr)++;
	}

	return 0;
}

/*
 * line_buf - Buffer containing string to tokenize.
 * delim - The delimiter used to tokenize line_buf. A whitespace delimiter will
 *	    be tokenized using isspace().
 * num_args - The number of parameter entries to process.
 * ...      - A 'char **' for each parameter.
 * returns  - The number of items processed.
 *
 * This function calls tokenize_str() to do the actual string processing. The
 * caller is responsible for calling free() on each additional argument. The
 * function will not tokenize more than num_args and the last argument will
 * contain the remaining content of line_buf. If the delimiter is any whitespace
 * character, then all whitespace will be squashed.
 */
int hidden tokenize(char *line_buf, char delim, int num_args, ...)
{
	char **arg, *buf_p;
	int rc, items;
	size_t arg_len = 0;
	va_list ap;

	buf_p = line_buf;

	/* Process the arguments */
	va_start(ap, num_args);

	for (items = 0; items < num_args && *buf_p != '\0'; items++) {
		arg = va_arg(ap, char **);

		/* Save the remainder of the string in arg */
		if (items == num_args - 1) {
			*arg = strdup(buf_p);
			if (*arg == NULL) {
				goto exit;
			}

			continue;
		}

		rc = tokenize_str(delim, arg, &buf_p, &arg_len);
		if (rc < 0) {
			goto exit;
		}
	}

exit:
	va_end(ap);
	return items;
}
