api: Use hashtable function for API_env_enum

The current code can loop undefinitly as it doesn't parse
correctly the env data.
Since the env is an hashtable, use the hashtable function for
the API_ENV_ENUM api call.

Signed-off-by: Emmanuel Vadot <manu@bidouilliste.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Emmanuel Vadot 2016-12-26 18:57:56 +01:00 committed by Tom Rini
parent 6baa692f90
commit 6215bd4c1f
1 changed files with 31 additions and 29 deletions

View File

@ -495,45 +495,47 @@ static int API_env_set(va_list ap)
*/ */
static int API_env_enum(va_list ap) static int API_env_enum(va_list ap)
{ {
int i, n; int i, buflen;
char *last, **next; char *last, **next, *s;
ENTRY *match, search;
static char *var;
last = (char *)va_arg(ap, unsigned long); last = (char *)va_arg(ap, unsigned long);
if ((next = (char **)va_arg(ap, uintptr_t)) == NULL) if ((next = (char **)va_arg(ap, uintptr_t)) == NULL)
return API_EINVAL; return API_EINVAL;
if (last == NULL) if (last == NULL) {
/* start over */ var = NULL;
*next = ((char *)env_get_addr(0)); i = 0;
else { } else {
*next = last; var = strdup(last);
s = strchr(var, '=');
for (i = 0; env_get_char(i) != '\0'; i = n + 1) { if (s != NULL)
for (n = i; env_get_char(n) != '\0'; ++n) { *s = 0;
if (n >= CONFIG_ENV_SIZE) { search.key = var;
/* XXX shouldn't we set *next = NULL?? */ i = hsearch_r(search, FIND, &match, &env_htab, 0);
return 0; if (i == 0) {
} i = API_EINVAL;
} goto done;
if (envmatch((uchar *)last, i) < 0)
continue;
/* try to get next name */
i = n + 1;
if (env_get_char(i) == '\0') {
/* no more left */
*next = NULL;
return 0;
}
*next = ((char *)env_get_addr(i));
return 0;
} }
} }
/* match the next entry after i */
i = hmatch_r("", i, &match, &env_htab);
if (i == 0)
goto done;
buflen = strlen(match->key) + strlen(match->data) + 2;
var = realloc(var, buflen);
snprintf(var, buflen, "%s=%s", match->key, match->data);
*next = var;
return 0; return 0;
done:
free(var);
var = NULL;
*next = NULL;
return i;
} }
/* /*