/*
 * (C) Copyright 2012
 * Joe Hershberger, National Instruments, joe.hershberger@ni.com
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <linux/string.h>
#include <linux/ctype.h>

#ifdef USE_HOSTCC /* Eliminate "ANSI does not permit..." warnings */
#include <stdint.h>
#include <stdio.h>
#include "fw_env.h"
#include <env_attr.h>
#include <env_flags.h>
#define getenv fw_getenv
#else
#include <common.h>
#include <environment.h>
#endif

#ifdef CONFIG_CMD_NET
#define ENV_FLAGS_NET_VARTYPE_REPS "im"
#else
#define ENV_FLAGS_NET_VARTYPE_REPS ""
#endif

static const char env_flags_vartype_rep[] = "sdxb" ENV_FLAGS_NET_VARTYPE_REPS;
static const char env_flags_varaccess_rep[] = "aroc";
static const int env_flags_varaccess_mask[] = {
	0,
	ENV_FLAGS_VARACCESS_PREVENT_DELETE |
		ENV_FLAGS_VARACCESS_PREVENT_CREATE |
		ENV_FLAGS_VARACCESS_PREVENT_OVERWR,
	ENV_FLAGS_VARACCESS_PREVENT_DELETE |
		ENV_FLAGS_VARACCESS_PREVENT_OVERWR,
	ENV_FLAGS_VARACCESS_PREVENT_DELETE |
		ENV_FLAGS_VARACCESS_PREVENT_NONDEF_OVERWR};

#ifdef CONFIG_CMD_ENV_FLAGS
static const char * const env_flags_vartype_names[] = {
	"string",
	"decimal",
	"hexadecimal",
	"boolean",
#ifdef CONFIG_CMD_NET
	"IP address",
	"MAC address",
#endif
};
static const char * const env_flags_varaccess_names[] = {
	"any",
	"read-only",
	"write-once",
	"change-default",
};

/*
 * Print the whole list of available type flags.
 */
void env_flags_print_vartypes(void)
{
	enum env_flags_vartype curtype = (enum env_flags_vartype)0;

	while (curtype != env_flags_vartype_end) {
		printf("\t%c   -\t%s\n", env_flags_vartype_rep[curtype],
			env_flags_vartype_names[curtype]);
		curtype++;
	}
}

/*
 * Print the whole list of available access flags.
 */
void env_flags_print_varaccess(void)
{
	enum env_flags_varaccess curaccess = (enum env_flags_varaccess)0;

	while (curaccess != env_flags_varaccess_end) {
		printf("\t%c   -\t%s\n", env_flags_varaccess_rep[curaccess],
			env_flags_varaccess_names[curaccess]);
		curaccess++;
	}
}

/*
 * Return the name of the type.
 */
const char *env_flags_get_vartype_name(enum env_flags_vartype type)
{
	return env_flags_vartype_names[type];
}

/*
 * Return the name of the access.
 */
const char *env_flags_get_varaccess_name(enum env_flags_varaccess access)
{
	return env_flags_varaccess_names[access];
}
#endif /* CONFIG_CMD_ENV_FLAGS */

/*
 * Parse the flags string from a .flags attribute list into the vartype enum.
 */
enum env_flags_vartype env_flags_parse_vartype(const char *flags)
{
	char *type;

	if (strlen(flags) <= ENV_FLAGS_VARTYPE_LOC)
		return env_flags_vartype_string;

	type = strchr(env_flags_vartype_rep,
		flags[ENV_FLAGS_VARTYPE_LOC]);

	if (type != NULL)
		return (enum env_flags_vartype)
			(type - &env_flags_vartype_rep[0]);

	printf("## Warning: Unknown environment variable type '%c'\n",
		flags[ENV_FLAGS_VARTYPE_LOC]);
	return env_flags_vartype_string;
}

/*
 * Parse the flags string from a .flags attribute list into the varaccess enum.
 */
enum env_flags_varaccess env_flags_parse_varaccess(const char *flags)
{
	char *access;

	if (strlen(flags) <= ENV_FLAGS_VARACCESS_LOC)
		return env_flags_varaccess_any;

	access = strchr(env_flags_varaccess_rep,
		flags[ENV_FLAGS_VARACCESS_LOC]);

	if (access != NULL)
		return (enum env_flags_varaccess)
			(access - &env_flags_varaccess_rep[0]);

	printf("## Warning: Unknown environment variable access method '%c'\n",
		flags[ENV_FLAGS_VARACCESS_LOC]);
	return env_flags_varaccess_any;
}

/*
 * Parse the binary flags from a hash table entry into the varaccess enum.
 */
enum env_flags_varaccess env_flags_parse_varaccess_from_binflags(int binflags)
{
	int i;

	for (i = 0; i < sizeof(env_flags_varaccess_mask); i++)
		if (env_flags_varaccess_mask[i] ==
		    (binflags & ENV_FLAGS_VARACCESS_BIN_MASK))
			return (enum env_flags_varaccess)i;

	printf("Warning: Non-standard access flags. (0x%x)\n",
		binflags & ENV_FLAGS_VARACCESS_BIN_MASK);

	return env_flags_varaccess_any;
}

static inline int is_hex_prefix(const char *value)
{
	return value[0] == '0' && (value[1] == 'x' || value[1] == 'X');
}

static void skip_num(int hex, const char *value, const char **end,
	int max_digits)
{
	int i;

	if (hex && is_hex_prefix(value))
		value += 2;

	for (i = max_digits; i != 0; i--) {
		if (hex && !isxdigit(*value))
			break;
		if (!hex && !isdigit(*value))
			break;
		value++;
	}
	if (end != NULL)
		*end = value;
}

/*
 * Based on the declared type enum, validate that the value string complies
 * with that format
 */
static int _env_flags_validate_type(const char *value,
	enum env_flags_vartype type)
{
	const char *end;
#ifdef CONFIG_CMD_NET
	const char *cur;
	int i;
#endif

	switch (type) {
	case env_flags_vartype_string:
		break;
	case env_flags_vartype_decimal:
		skip_num(0, value, &end, -1);
		if (*end != '\0')
			return -1;
		break;
	case env_flags_vartype_hex:
		skip_num(1, value, &end, -1);
		if (*end != '\0')
			return -1;
		if (value + 2 == end && is_hex_prefix(value))
			return -1;
		break;
	case env_flags_vartype_bool:
		if (value[0] != '1' && value[0] != 'y' && value[0] != 't' &&
		    value[0] != 'Y' && value[0] != 'T' &&
		    value[0] != '0' && value[0] != 'n' && value[0] != 'f' &&
		    value[0] != 'N' && value[0] != 'F')
			return -1;
		if (value[1] != '\0')
			return -1;
		break;
#ifdef CONFIG_CMD_NET
	case env_flags_vartype_ipaddr:
		cur = value;
		for (i = 0; i < 4; i++) {
			skip_num(0, cur, &end, 3);
			if (cur == end)
				return -1;
			if (i != 3 && *end != '.')
				return -1;
			if (i == 3 && *end != '\0')
				return -1;
			cur = end + 1;
		}
		break;
	case env_flags_vartype_macaddr:
		cur = value;
		for (i = 0; i < 6; i++) {
			skip_num(1, cur, &end, 2);
			if (cur == end)
				return -1;
			if (cur + 2 == end && is_hex_prefix(cur))
				return -1;
			if (i != 5 && *end != ':')
				return -1;
			if (i == 5 && *end != '\0')
				return -1;
			cur = end + 1;
		}
		break;
#endif
	case env_flags_vartype_end:
		return -1;
	}

	/* OK */
	return 0;
}

/*
 * Look for flags in a provided list and failing that the static list
 */
static inline int env_flags_lookup(const char *flags_list, const char *name,
	char *flags)
{
	int ret = 1;

	if (!flags)
		/* bad parameter */
		return -1;

	/* try the env first */
	if (flags_list)
		ret = env_attr_lookup(flags_list, name, flags);

	if (ret != 0)
		/* if not found in the env, look in the static list */
		ret = env_attr_lookup(ENV_FLAGS_LIST_STATIC, name, flags);

	return ret;
}

#ifdef USE_HOSTCC /* Functions only used from tools/env */
/*
 * Look up any flags directly from the .flags variable and the static list
 * and convert them to the vartype enum.
 */
enum env_flags_vartype env_flags_get_type(const char *name)
{
	const char *flags_list = getenv(ENV_FLAGS_VAR);
	char flags[ENV_FLAGS_ATTR_MAX_LEN + 1];

	if (env_flags_lookup(flags_list, name, flags))
		return env_flags_vartype_string;

	if (strlen(flags) <= ENV_FLAGS_VARTYPE_LOC)
		return env_flags_vartype_string;

	return env_flags_parse_vartype(flags);
}

/*
 * Look up the access of a variable directly from the .flags var.
 */
enum env_flags_varaccess env_flags_get_varaccess(const char *name)
{
	const char *flags_list = getenv(ENV_FLAGS_VAR);
	char flags[ENV_FLAGS_ATTR_MAX_LEN + 1];

	if (env_flags_lookup(flags_list, name, flags))
		return env_flags_varaccess_any;

	if (strlen(flags) <= ENV_FLAGS_VARACCESS_LOC)
		return env_flags_varaccess_any;

	return env_flags_parse_varaccess(flags);
}

/*
 * Validate that the proposed new value for "name" is valid according to the
 * defined flags for that variable, if any.
 */
int env_flags_validate_type(const char *name, const char *value)
{
	enum env_flags_vartype type;

	if (value == NULL)
		return 0;
	type = env_flags_get_type(name);
	if (_env_flags_validate_type(value, type) < 0) {
		printf("## Error: flags type check failure for "
			"\"%s\" <= \"%s\" (type: %c)\n",
			name, value, env_flags_vartype_rep[type]);
		return -1;
	}
	return 0;
}

/*
 * Validate that the proposed access to variable "name" is valid according to
 * the defined flags for that variable, if any.
 */
int env_flags_validate_varaccess(const char *name, int check_mask)
{
	enum env_flags_varaccess access;
	int access_mask;

	access = env_flags_get_varaccess(name);
	access_mask = env_flags_varaccess_mask[access];

	return (check_mask & access_mask) != 0;
}

/*
 * Validate the parameters to "env set" directly
 */
int env_flags_validate_env_set_params(int argc, char * const argv[])
{
	if ((argc >= 3) && argv[2] != NULL) {
		enum env_flags_vartype type = env_flags_get_type(argv[1]);

		/*
		 * we don't currently check types that need more than
		 * one argument
		 */
		if (type != env_flags_vartype_string && argc > 3) {
			printf("## Error: too many parameters for setting "
				"\"%s\"\n", argv[1]);
			return -1;
		}
		return env_flags_validate_type(argv[1], argv[2]);
	}
	/* ok */
	return 0;
}

#else /* !USE_HOSTCC - Functions only used from lib/hashtable.c */

/*
 * Parse the flag charachters from the .flags attribute list into the binary
 * form to be stored in the environment entry->flags field.
 */
static int env_parse_flags_to_bin(const char *flags)
{
	int binflags;

	binflags = env_flags_parse_vartype(flags) & ENV_FLAGS_VARTYPE_BIN_MASK;
	binflags |= env_flags_varaccess_mask[env_flags_parse_varaccess(flags)];

	return binflags;
}

/*
 * Look for possible flags for a newly added variable
 * This is called specifically when the variable did not exist in the hash
 * previously, so the blanket update did not find this variable.
 */
void env_flags_init(ENTRY *var_entry)
{
	const char *var_name = var_entry->key;
	const char *flags_list = getenv(ENV_FLAGS_VAR);
	char flags[ENV_FLAGS_ATTR_MAX_LEN + 1] = "";
	int ret = 1;

	/* look in the ".flags" and static for a reference to this variable */
	ret = env_flags_lookup(flags_list, var_name, flags);

	/* if any flags were found, set the binary form to the entry */
	if (!ret && strlen(flags))
		var_entry->flags = env_parse_flags_to_bin(flags);
}

/*
 * Called on each existing env var prior to the blanket update since removing
 * a flag in the flag list should remove its flags.
 */
static int clear_flags(ENTRY *entry)
{
	entry->flags = 0;

	return 0;
}

/*
 * Call for each element in the list that defines flags for a variable
 */
static int set_flags(const char *name, const char *value)
{
	ENTRY e, *ep;

	e.key	= name;
	e.data	= NULL;
	hsearch_r(e, FIND, &ep, &env_htab, 0);

	/* does the env variable actually exist? */
	if (ep != NULL) {
		/* the flag list is empty, so clear the flags */
		if (value == NULL || strlen(value) == 0)
			ep->flags = 0;
		else
			/* assign the requested flags */
			ep->flags = env_parse_flags_to_bin(value);
	}

	return 0;
}

static int on_flags(const char *name, const char *value, enum env_op op,
	int flags)
{
	/* remove all flags */
	hwalk_r(&env_htab, clear_flags);

	/* configure any static flags */
	env_attr_walk(ENV_FLAGS_LIST_STATIC, set_flags);
	/* configure any dynamic flags */
	env_attr_walk(value, set_flags);

	return 0;
}
U_BOOT_ENV_CALLBACK(flags, on_flags);

/*
 * Perform consistency checking before creating, overwriting, or deleting an
 * environment variable. Called as a callback function by hsearch_r() and
 * hdelete_r(). Returns 0 in case of success, 1 in case of failure.
 * When (flag & H_FORCE) is set, do not print out any error message and force
 * overwriting of write-once variables.
 */

int env_flags_validate(const ENTRY *item, const char *newval, enum env_op op,
	int flag)
{
	const char *name;
	const char *oldval = NULL;

	if (op != env_op_create)
		oldval = item->data;

	name = item->key;

	/* Default value for NULL to protect string-manipulating functions */
	newval = newval ? : "";

	/* validate the value to match the variable type */
	if (op != env_op_delete) {
		enum env_flags_vartype type = (enum env_flags_vartype)
			(ENV_FLAGS_VARTYPE_BIN_MASK & item->flags);

		if (_env_flags_validate_type(newval, type) < 0) {
			printf("## Error: flags type check failure for "
				"\"%s\" <= \"%s\" (type: %c)\n",
				name, newval, env_flags_vartype_rep[type]);
			return -1;
		}
	}

	/* check for access permission */
#ifndef CONFIG_ENV_ACCESS_IGNORE_FORCE
	if (flag & H_FORCE)
		return 0;
#endif
	switch (op) {
	case env_op_delete:
		if (item->flags & ENV_FLAGS_VARACCESS_PREVENT_DELETE) {
			printf("## Error: Can't delete \"%s\"\n", name);
			return 1;
		}
		break;
	case env_op_overwrite:
		if (item->flags & ENV_FLAGS_VARACCESS_PREVENT_OVERWR) {
			printf("## Error: Can't overwrite \"%s\"\n", name);
			return 1;
		} else if (item->flags &
		    ENV_FLAGS_VARACCESS_PREVENT_NONDEF_OVERWR) {
			const char *defval = getenv_default(name);

			if (defval == NULL)
				defval = "";
			printf("oldval: %s  defval: %s\n", oldval, defval);
			if (strcmp(oldval, defval) != 0) {
				printf("## Error: Can't overwrite \"%s\"\n",
					name);
				return 1;
			}
		}
		break;
	case env_op_create:
		if (item->flags & ENV_FLAGS_VARACCESS_PREVENT_CREATE) {
			printf("## Error: Can't create \"%s\"\n", name);
			return 1;
		}
		break;
	}

	return 0;
}

#endif
