summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Hershberger <joe.hershberger@ni.com>2012-12-11 22:16:32 -0600
committerTom Rini <trini@ti.com>2012-12-13 11:46:56 -0700
commit30fd4fadb319d7c6d43d949e2d30ffaea46a60cf (patch)
treecedfa8c38a45f3f6afe046a999003e56a609c84d
parent2598090b7e17f8bdca95b22e7f27217054730e02 (diff)
tools/env: Add environment variable flags support
Currently just validates variable types as decimal, hexidecimal, boolean, ip address, and mac address. Call env_acl_validate_setenv_params() from setenv() in fw_env.c. If the entry is not found in the env .flags, then look in the static one. This allows the env to override the static definitions, but prevents the need to have every definition in the environment distracting you. Need to build in _ctype for isdigit for Linux. Signed-off-by: Joe Hershberger <joe.hershberger@ni.com>
-rw-r--r--common/env_attr.c7
-rw-r--r--common/env_flags.c75
-rw-r--r--include/env_flags.h19
-rw-r--r--tools/env/Makefile3
-rw-r--r--tools/env/fw_env.c9
5 files changed, 113 insertions, 0 deletions
diff --git a/common/env_attr.c b/common/env_attr.c
index 7d330a58bb..210c98dcfd 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 a58d614bb3..ed0857cf9e 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 bf25f2746b..33334464d4 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 ab73c8c744..0e798e0940 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 9b023e807b..5be36fc359 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