[U-Boot] [PATCH 1/2] env: set individual variables to default

Gerlando Falauto gerlando.falauto at keymile.com
Thu Sep 22 17:06:11 CEST 2011


implement command "env default <vars>..." for resetting individual
variables to their default values.

"env default -f" will always keep resetting the whole environment
to default.

Notes:
- The feature is disabled by default; define CONFIG_CMD_DEFAULTENV_VARS
  to enable it.
- An existing variable not defined in the default environemnt
  will be unset.

Signed-off-by: Gerlando Falauto <gerlando.falauto at keymile.com>
Signed-off-by: Holger Brunck <holger.brunck at keymile.com>

---
 README                   |    2 +
 common/cmd_nvedit.c      |   22 +++++++--
 common/env_common.c      |  109 ++++++++++++++++++++++++++++++++++++++++++++++
 include/config_cmd_all.h |    1 +
 include/environment.h    |    5 ++
 5 files changed, 134 insertions(+), 5 deletions(-)

diff --git a/README b/README
index a43da97..4b28854 100644
--- a/README
+++ b/README
@@ -705,6 +705,8 @@ The following options need to be configured:
 		CONFIG_CMD_CONSOLE	  coninfo
 		CONFIG_CMD_CRC32	* crc32
 		CONFIG_CMD_DATE		* support for RTC, date/time...
+		CONFIG_CMD_DEFAULTENV_VARS
+					* Reset individual variables to default
 		CONFIG_CMD_DHCP		* DHCP support
 		CONFIG_CMD_DIAG		* Diagnostics
 		CONFIG_CMD_DS4510	* ds4510 I2C gpio commands
diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c
index e8b116d..ea1db22 100644
--- a/common/cmd_nvedit.c
+++ b/common/cmd_nvedit.c
@@ -581,11 +581,20 @@ int envmatch(uchar *s1, int i2)
 
 static int do_env_default(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-	if ((argc != 2) || (strcmp(argv[1], "-f") != 0))
-		return cmd_usage(cmdtp);
-
-	set_default_env("## Resetting to default environment\n");
-	return 0;
+	if ((argc == 2) && (strcmp(argv[1], "-f")) == 0) {
+		/* Reset the whole environment */
+		set_default_env("## Resetting to default environment\n");
+		return 0;
+	}
+#ifdef CONFIG_CMD_DEFAULTENV_VARS
+	/* Check that we have at least one argument */
+	else if (argc >= 2) {
+		/* Reset individual variables */
+		env_default_vars(argc-1, argv+1);
+		return 0;
+	}
+#endif
+	return cmd_usage(cmdtp);
 }
 
 static int do_env_delete(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
@@ -911,6 +920,9 @@ U_BOOT_CMD(
 	"ask name [message] [size] - ask for environment variable\nenv "
 #endif
 	"default -f - reset default environment\n"
+#if defined(CONFIG_CMD_DEFAULTENV_VARS)
+	"env default var [...] - reset variable(s) to their default value\n"
+#endif
 #if defined(CONFIG_CMD_EDITENV)
 	"env edit name - edit environment variable\n"
 #endif
diff --git a/common/env_common.c b/common/env_common.c
index 19149b5..77cc439 100644
--- a/common/env_common.c
+++ b/common/env_common.c
@@ -196,6 +196,115 @@ void set_default_env(const char *s)
 	gd->flags |= GD_FLG_ENV_READY;
 }
 
+#ifdef CONFIG_CMD_DEFAULTENV_VARS
+/*
+ * import individual variables from an external environment
+ * (e.g. default environment).
+ * Most of this code comes straight from himport_r().
+ */
+static int env_import_vars(const char *env, const size_t size, const char sep,
+			   int nvars, char * const vars[])
+{
+	char *data, *sp, *dp, *name, *value, *thisvalue;
+	int i;
+
+	/* we allocate new space to make sure we can write to the array */
+	data = malloc(size);
+	if (data == NULL) {
+		debug("env_import_vars: can't malloc %d bytes\n", size);
+		__set_errno(ENOMEM);
+		return 0;
+	}
+
+	/* Loop through all passed variables */
+	for (i = 0; i < nvars; i++) {
+		debug("looking for a default value for %s\n", vars[i]);
+
+		memcpy(data, env, size);
+		dp = data;
+
+		/*
+		 * Unless proven otherwise, this variable
+		 * does not exist in the default env
+		 */
+		thisvalue = "";
+		/* Parse environment; allow for '\0' and 'sep' as separators */
+		do {
+			/* skip leading white space */
+			while ((*dp == ' ') || (*dp == '\t'))
+				++dp;
+
+			/* skip comment lines */
+			if (*dp == '#') {
+				while (*dp && (*dp != sep))
+					++dp;
+				++dp;
+				continue;
+			}
+
+			/* parse name */
+			for (name = dp; *dp != '=' && *dp && *dp != sep; ++dp)
+				;
+
+			/* deal with "name" and "name=" entries (delete var) */
+			if (*dp == '\0' || *(dp + 1) == '\0' ||
+				*dp == sep || *(dp + 1) == sep) {
+				if (*dp == '=')
+					*dp++ = '\0';
+				*dp++ = '\0';	/* terminate name */
+
+				/* default is none */
+				value = "";
+			} else {
+				*dp++ = '\0';	/* terminate name */
+				value = dp; /* value starts here */
+				/* parse value; deal with escapes */
+				for (sp = dp; *dp && (*dp != sep); ++dp) {
+					if ((*dp == '\\') && *(dp + 1))
+						++dp;
+					*sp++ = *dp;
+				}
+				*sp++ = '\0';	/* terminate value */
+			}
+
+			if (strcmp(name, vars[i]) == 0) {
+				debug("found variable: %s\n"
+				      "default value: %s\n", name, value);
+				thisvalue = value;
+				/* exit from loop parsing the default env */
+				break;
+			}
+			++dp;
+
+		} while ((dp < data + size) && *dp);
+		/*
+		 * size check needed for text without '\0' termination
+		 * (e.g. default environment)
+		 */
+
+		debug("setting default value: %s=%s\n", vars[i], thisvalue);
+		setenv(vars[i], thisvalue);
+	} /* for-loop over i */
+
+	debug("env_import_vars: free(data = %p)\n", data);
+	free(data);
+	debug("env_import_vars: done\n");
+	return 1;		/* everything OK */
+
+}
+
+/* [re]set individual variables to their value in the default environment */
+int env_default_vars(int nvars, char * const vars[])
+{
+	/* Special use-case: import from default environment
+	   (and use \0 as a separator) */
+	return env_import_vars((const char *)default_environment,
+			       sizeof(default_environment), '\0',
+			       nvars, vars);
+}
+
+#endif /* CONFIG_CMD_DEFAULTENV_VARS */
+
 /*
  * Check if CRC is valid and (if yes) import the environment.
  * Note that "buf" may or may not be aligned.
diff --git a/include/config_cmd_all.h b/include/config_cmd_all.h
index 9716f9c..e728eae 100644
--- a/include/config_cmd_all.h
+++ b/include/config_cmd_all.h
@@ -25,6 +25,7 @@
 #define CONFIG_CMD_CDP		/* Cisco Discovery Protocol	*/
 #define CONFIG_CMD_CONSOLE	/* coninfo			*/
 #define CONFIG_CMD_DATE		/* support for RTC, date/time...*/
+#define CONFIG_CMD_DEFAULTENV_VARS /* default individ variables */
 #define CONFIG_CMD_DHCP		/* DHCP Support			*/
 #define CONFIG_CMD_DIAG		/* Diagnostics			*/
 #define CONFIG_CMD_DISPLAY	/* Display support		*/
diff --git a/include/environment.h b/include/environment.h
index 6394a96..0be92b6 100644
--- a/include/environment.h
+++ b/include/environment.h
@@ -171,6 +171,11 @@ void env_crc_update (void);
 /* [re]set to the default environment */
 void set_default_env(const char *s);
 
+#ifdef CONFIG_CMD_DEFAULTENV_VARS
+/* [re]set individual variables to their value in the default environment */
+int env_default_vars(int nvars, char * const vars[]);
+#endif
+
 /* Import from binary representation into hash table */
 int env_import(const char *buf, int check);
 
-- 
1.7.1



More information about the U-Boot mailing list