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;