diff options
author | Emmanuel Vadot <manu@bidouilliste.com> | 2016-12-26 18:57:56 +0100 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2017-01-20 09:15:24 -0500 |
commit | 6215bd4c1fd6bce95072ad123cf1e4af94ab44e2 (patch) | |
tree | 9ce8f69f433d1a41ab71d0ea858f93cacc3e1edb /api | |
parent | 6baa692f90f398ffe334c1f5668e459cd59a5825 (diff) |
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>
Diffstat (limited to 'api')
-rw-r--r-- | api/api.c | 60 |
1 files changed, 31 insertions, 29 deletions
@@ -495,45 +495,47 @@ static int API_env_set(va_list ap) */ static int API_env_enum(va_list ap) { - int i, n; - char *last, **next; + int i, buflen; + char *last, **next, *s; + ENTRY *match, search; + static char *var; last = (char *)va_arg(ap, unsigned long); if ((next = (char **)va_arg(ap, uintptr_t)) == NULL) return API_EINVAL; - if (last == NULL) - /* start over */ - *next = ((char *)env_get_addr(0)); - else { - *next = last; - - for (i = 0; env_get_char(i) != '\0'; i = n + 1) { - for (n = i; env_get_char(n) != '\0'; ++n) { - if (n >= CONFIG_ENV_SIZE) { - /* XXX shouldn't we set *next = NULL?? */ - return 0; - } - } - - 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; + if (last == NULL) { + var = NULL; + i = 0; + } else { + var = strdup(last); + s = strchr(var, '='); + if (s != NULL) + *s = 0; + search.key = var; + i = hsearch_r(search, FIND, &match, &env_htab, 0); + if (i == 0) { + i = API_EINVAL; + goto done; } } + /* 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; + +done: + free(var); + var = NULL; + *next = NULL; + return i; } /* |