/* 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;
			if (in_range) {
				low_value = xperms->driver<<8 | low_bit;
				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;
			if (in_range) {
				low_value = low_bit << 8;
				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;
}
