diff options
| -rw-r--r-- | common/env_attr.c | 7 | ||||
| -rw-r--r-- | common/env_flags.c | 75 | ||||
| -rw-r--r-- | include/env_flags.h | 19 | ||||
| -rw-r--r-- | tools/env/Makefile | 3 | ||||
| -rw-r--r-- | tools/env/fw_env.c | 9 | 
5 files changed, 113 insertions, 0 deletions
| diff --git a/common/env_attr.c b/common/env_attr.c index 7d330a58b..210c98dcf 100644 --- a/common/env_attr.c +++ b/common/env_attr.c @@ -21,7 +21,14 @@   * MA 02111-1307 USA   */ +#ifdef USE_HOSTCC /* Eliminate "ANSI does not permit..." warnings */ +#include <stdint.h> +#include <stdio.h> +#include <linux/linux_string.h> +#else  #include <common.h> +#endif +  #include <env_attr.h>  #include <errno.h>  #include <linux/string.h> diff --git a/common/env_flags.c b/common/env_flags.c index a58d614bb..ed0857cf9 100644 --- a/common/env_flags.c +++ b/common/env_flags.c @@ -24,8 +24,17 @@  #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" @@ -179,6 +188,70 @@ static inline int env_flags_lookup(const char *flags_list, const char *name,  	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); +} + +/* + * 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 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. @@ -317,3 +390,5 @@ int env_flags_validate(const ENTRY *item, const char *newval, enum env_op op,  	return 0;  } + +#endif diff --git a/include/env_flags.h b/include/env_flags.h index bf25f2746..33334464d 100644 --- a/include/env_flags.h +++ b/include/env_flags.h @@ -52,6 +52,23 @@ enum env_flags_vartype {   */  enum env_flags_vartype env_flags_parse_vartype(const char *flags); +#ifdef USE_HOSTCC +/* + * Look up the type of a variable directly from the .flags var. + */ +enum env_flags_vartype env_flags_get_type(const char *name); +/* + * Validate the newval for its type to conform with the requirements defined by + * its flags (directly looked at the .flags var). + */ +int env_flags_validate_type(const char *name, const char *newval); +/* + * Validate the parameters passed to "env set" for type compliance + */ +int env_flags_validate_env_set_params(int argc, char * const argv[]); + +#else /* !USE_HOSTCC */ +  #include <search.h>  /* @@ -73,4 +90,6 @@ int env_flags_validate(const ENTRY *item, const char *newval, enum env_op op,  #define ENV_FLAGS_VARTYPE_BIN_MASK	0x00000007  /* The actual variable type values use the enum value (within the mask) */ +#endif /* USE_HOSTCC */ +  #endif /* __ENV_FLAGS_H__ */ diff --git a/tools/env/Makefile b/tools/env/Makefile index ab73c8c74..0e798e094 100644 --- a/tools/env/Makefile +++ b/tools/env/Makefile @@ -24,12 +24,15 @@  include $(TOPDIR)/config.mk  HOSTSRCS := $(SRCTREE)/lib/crc32.c  fw_env.c  fw_env_main.c +HOSTSRCS += $(SRCTREE)/lib/ctype.c $(SRCTREE)/lib/linux_string.c +HOSTSRCS += $(SRCTREE)/common/env_attr.c $(SRCTREE)/common/env_flags.c  HEADERS	:= fw_env.h $(OBJTREE)/include/config.h  # Compile for a hosted environment on the target  HOSTCPPFLAGS  = -idirafter $(SRCTREE)/include \  		-idirafter $(OBJTREE)/include2 \  		-idirafter $(OBJTREE)/include \ +		-idirafter $(SRCTREE)/tools/env \  		-DUSE_HOSTCC \  		-DTEXT_BASE=$(TEXT_BASE) diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index 9b023e807..5be36fc35 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c @@ -25,6 +25,7 @@   */  #include <errno.h> +#include <env_flags.h>  #include <fcntl.h>  #include <linux/stringify.h>  #include <stdio.h> @@ -395,6 +396,9 @@ int fw_setenv(int argc, char *argv[])  	name = argv[1]; +	if (env_flags_validate_env_set_params(argc, argv) < 0) +		return 1; +  	len = 0;  	for (i = 2; i < argc; ++i) {  		char *val = argv[i]; @@ -516,6 +520,11 @@ int fw_parse_script(char *fname)  			name, val ? val : " removed");  #endif +		if (env_flags_validate_type(name, val) < 0) { +			ret = -1; +			break; +		} +  		/*  		 * If there is an error setting a variable,  		 * try to save the environment and returns an error |