@@ -580,10 +580,17 @@ 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))
+ /* Check that we have at least one argument */
+ if (argc < 2) {
return cmd_usage(cmdtp);
+ } else if ((argc == 2) && (strcmp(argv[1], "-f")) == 0) {
+ /* Reset the whole environment */
+ set_default_env("## Resetting to default environment\n");
+ return 0;
+ }
- set_default_env("## Resetting to default environment\n");
+ /* Reset individual variables */
+ env_default_vars(argc-1, argv+1);
return 0;
}
@@ -910,6 +917,7 @@ U_BOOT_CMD(
"ask name [message] [size] - ask for environment variable\nenv "
#endif
"default -f - reset default environment\n"
+ "env default name [...] - reset variable(s) to their default value\n"
#if defined(CONFIG_CMD_EDITENV)
"env edit name - edit environment variable\n"
#endif
@@ -197,6 +197,112 @@ void set_default_env(const char *s)
}
/*
+ * 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_default_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_default_vars: free(data = %p)\n", data);
+ free(data);
+ debug("env_default_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);
+}
+
+/*
* Check if CRC is valid and (if yes) import the environment.
* Note that "buf" may or may not be aligned.
*/
@@ -169,6 +169,9 @@ void env_crc_update (void);
/* [re]set to the default environment */
void set_default_env(const char *s);
+/* [re]set individual variables to their value in the default environment */
+int env_default_vars(int nvars, char * const vars[]);
+
/* Import from binary representation into hash table */
int env_import(const char *buf, int check);