summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/cmd_nvedit.c19
-rw-r--r--common/env_common.c6
-rw-r--r--include/search.h3
-rw-r--r--lib/hashtable.c17
4 files changed, 36 insertions, 9 deletions
diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c
index e6c33956e7..855808c3e4 100644
--- a/common/cmd_nvedit.c
+++ b/common/cmd_nvedit.c
@@ -950,11 +950,15 @@ sep_err:
#ifdef CONFIG_CMD_IMPORTENV
/*
- * env import [-d] [-t | -b | -c] addr [size]
+ * env import [-d] [-t [-r] | -b | -c] addr [size]
* -d: delete existing environment before importing;
* otherwise overwrite / append to existion definitions
* -t: assume text format; either "size" must be given or the
* text data must be '\0' terminated
+ * -r: handle CRLF like LF, that means exported variables with
+ * a content which ends with \r won't get imported. Used
+ * to import text files created with editors which are using CRLF
+ * for line endings. Only effective in addition to -t.
* -b: assume binary format ('\0' separated, "\0\0" terminated)
* -c: assume checksum protected environment format
* addr: memory address to read from
@@ -970,6 +974,7 @@ static int do_env_import(cmd_tbl_t *cmdtp, int flag,
int chk = 0;
int fmt = 0;
int del = 0;
+ int crlf_is_lf = 0;
size_t size;
cmd = *argv;
@@ -994,6 +999,9 @@ static int do_env_import(cmd_tbl_t *cmdtp, int flag,
goto sep_err;
sep = '\n';
break;
+ case 'r': /* handle CRLF like LF */
+ crlf_is_lf = 1;
+ break;
case 'd':
del = 1;
break;
@@ -1009,6 +1017,9 @@ static int do_env_import(cmd_tbl_t *cmdtp, int flag,
if (!fmt)
printf("## Warning: defaulting to text format\n");
+ if (sep != '\n' && crlf_is_lf )
+ crlf_is_lf = 0;
+
addr = simple_strtoul(argv[0], NULL, 16);
ptr = map_sysmem(addr, 0);
@@ -1050,8 +1061,8 @@ static int do_env_import(cmd_tbl_t *cmdtp, int flag,
ptr = (char *)ep->data;
}
- if (himport_r(&env_htab, ptr, size, sep, del ? 0 : H_NOCLEAR, 0,
- NULL) == 0) {
+ if (himport_r(&env_htab, ptr, size, sep, del ? 0 : H_NOCLEAR,
+ crlf_is_lf, 0, NULL) == 0) {
error("Environment import failed: errno = %d\n", errno);
return 1;
}
@@ -1180,7 +1191,7 @@ static char env_help_text[] =
#endif
#endif
#if defined(CONFIG_CMD_IMPORTENV)
- "env import [-d] [-t | -b | -c] addr [size] - import environment\n"
+ "env import [-d] [-t [-r] | -b | -c] addr [size] - import environment\n"
#endif
"env print [-a | name ...] - print environment\n"
#if defined(CONFIG_CMD_RUN)
diff --git a/common/env_common.c b/common/env_common.c
index 3b979bcb98..af59c72e1f 100644
--- a/common/env_common.c
+++ b/common/env_common.c
@@ -118,7 +118,7 @@ void set_default_env(const char *s)
}
if (himport_r(&env_htab, (char *)default_environment,
- sizeof(default_environment), '\0', flags,
+ sizeof(default_environment), '\0', flags, 0,
0, NULL) == 0)
error("Environment import failed: errno = %d\n", errno);
@@ -135,7 +135,7 @@ int set_default_vars(int nvars, char * const vars[])
*/
return himport_r(&env_htab, (const char *)default_environment,
sizeof(default_environment), '\0',
- H_NOCLEAR | H_INTERACTIVE, nvars, vars);
+ H_NOCLEAR | H_INTERACTIVE, 0, nvars, vars);
}
#ifdef CONFIG_ENV_AES
@@ -212,7 +212,7 @@ int env_import(const char *buf, int check)
return ret;
}
- if (himport_r(&env_htab, (char *)ep->data, ENV_SIZE, '\0', 0,
+ if (himport_r(&env_htab, (char *)ep->data, ENV_SIZE, '\0', 0, 0,
0, NULL)) {
gd->flags |= GD_FLG_ENV_READY;
return 1;
diff --git a/include/search.h b/include/search.h
index ae3efc43ca..9701efb2df 100644
--- a/include/search.h
+++ b/include/search.h
@@ -102,7 +102,8 @@ extern ssize_t hexport_r(struct hsearch_data *__htab,
*/
extern int himport_r(struct hsearch_data *__htab,
const char *__env, size_t __size, const char __sep,
- int __flag, int nvars, char * const vars[]);
+ int __flag, int __crlf_is_lf, int nvars,
+ char * const vars[]);
/* Walk the whole table calling the callback on each element */
extern int hwalk_r(struct hsearch_data *__htab, int (*callback)(ENTRY *));
diff --git a/lib/hashtable.c b/lib/hashtable.c
index 4356b234ec..18ed5901ec 100644
--- a/lib/hashtable.c
+++ b/lib/hashtable.c
@@ -776,7 +776,7 @@ static int drop_var_from_set(const char *name, int nvars, char * vars[])
int himport_r(struct hsearch_data *htab,
const char *env, size_t size, const char sep, int flag,
- int nvars, char * const vars[])
+ int crlf_is_lf, int nvars, char * const vars[])
{
char *data, *sp, *dp, *name, *value;
char *localvars[nvars];
@@ -841,6 +841,21 @@ int himport_r(struct hsearch_data *htab,
}
}
+ if(!size)
+ return 1; /* everything OK */
+ if(crlf_is_lf) {
+ /* Remove Carriage Returns in front of Line Feeds */
+ unsigned ignored_crs = 0;
+ for(;dp < data + size && *dp; ++dp) {
+ if(*dp == '\r' &&
+ dp < data + size - 1 && *(dp+1) == '\n')
+ ++ignored_crs;
+ else
+ *(dp-ignored_crs) = *dp;
+ }
+ size -= ignored_crs;
+ dp = data;
+ }
/* Parse environment; allow for '\0' and 'sep' as separators */
do {
ENTRY e, *rv;