diff options
Diffstat (limited to 'src/libstrongswan/settings.c')
-rw-r--r-- | src/libstrongswan/settings.c | 128 |
1 files changed, 106 insertions, 22 deletions
diff --git a/src/libstrongswan/settings.c b/src/libstrongswan/settings.c index 610e2b8ea..d85abb1df 100644 --- a/src/libstrongswan/settings.c +++ b/src/libstrongswan/settings.c @@ -88,11 +88,60 @@ struct kv_t { }; /** - * find a section by a given key + * Print a format key, but consume already processed arguments */ -static section_t *find_section(section_t *section, char *key, va_list args) +static bool print_key(char *buf, int len, char *start, char *key, va_list args) { - char name[512], *pos; + va_list copy; + bool res; + char *pos; + + va_copy(copy, args); + while (start < key) + { + pos = strchr(start, '%'); + if (!pos) + { + start += strlen(start) + 1; + continue; + } + pos++; + switch (*pos) + { + case 'd': + va_arg(copy, int); + break; + case 's': + va_arg(copy, char*); + break; + case 'N': + va_arg(copy, enum_name_t*); + va_arg(copy, int); + break; + case '%': + break; + default: + DBG1(DBG_CFG, "settings with %%%c not supported!", *pos); + break; + } + start = pos; + if (*start) + { + start++; + } + } + res = vsnprintf(buf, len, key, copy) < len; + va_end(copy); + return res; +} + +/** + * find a section by a given key, using buffered key, reusable buffer + */ +static section_t *find_section_buffered(section_t *section, + char *start, char *key, va_list args, char *buf, int len) +{ + char *pos; enumerator_t *enumerator; section_t *current, *found = NULL; @@ -100,21 +149,20 @@ static section_t *find_section(section_t *section, char *key, va_list args) { return NULL; } - if (vsnprintf(name, sizeof(name), key, args) >= sizeof(name)) - { - return NULL; - } - - pos = strchr(name, '.'); + pos = strchr(key, '.'); if (pos) { *pos = '\0'; pos++; } + if (!print_key(buf, len, start, key, args)) + { + return NULL; + } enumerator = section->sections->create_enumerator(section->sections); while (enumerator->enumerate(enumerator, ¤t)) { - if (streq(current->name, name)) + if (streq(current->name, buf)) { found = current; break; @@ -123,37 +171,55 @@ static section_t *find_section(section_t *section, char *key, va_list args) enumerator->destroy(enumerator); if (found && pos) { - return find_section(found, pos, args); + return find_section_buffered(found, start, pos, args, buf, len); } return found; } -static char *find_value(section_t *section, char *key, va_list args) +/** + * find a section by a given key + */ +static section_t *find_section(section_t *section, char *key, va_list args) { - char name[512], *pos, *value = NULL; - enumerator_t *enumerator; - kv_t *kv; - section_t *current, *found = NULL; + char buf[128], keybuf[512]; - if (section == NULL) + if (snprintf(keybuf, sizeof(keybuf), "%s", key) >= sizeof(keybuf)) { return NULL; } + return find_section_buffered(section, keybuf, keybuf, args, buf, sizeof(buf)); +} + +/** + * Find the string value for a key, using buffered key, reusable buffer + */ +static char *find_value_buffered(section_t *section, + char *start, char *key, va_list args, char *buf, int len) +{ + char *pos, *value = NULL; + enumerator_t *enumerator; + kv_t *kv; + section_t *current, *found = NULL; - if (vsnprintf(name, sizeof(name), key, args) >= sizeof(name)) + if (section == NULL) { return NULL; } - pos = strchr(name, '.'); + pos = strchr(key, '.'); if (pos) { *pos = '\0'; pos++; + + if (!print_key(buf, len, start, key, args)) + { + return NULL; + } enumerator = section->sections->create_enumerator(section->sections); while (enumerator->enumerate(enumerator, ¤t)) { - if (streq(current->name, name)) + if (streq(current->name, buf)) { found = current; break; @@ -162,15 +228,19 @@ static char *find_value(section_t *section, char *key, va_list args) enumerator->destroy(enumerator); if (found) { - return find_value(found, pos, args); + return find_value_buffered(found, start, pos, args, buf, len); } } else { + if (!print_key(buf, len, start, key, args)) + { + return NULL; + } enumerator = section->kv->create_enumerator(section->kv); while (enumerator->enumerate(enumerator, &kv)) { - if (streq(kv->key, name)) + if (streq(kv->key, buf)) { value = kv->value; break; @@ -182,6 +252,20 @@ static char *find_value(section_t *section, char *key, va_list args) } /** + * Find the string value for a key + */ +static char *find_value(section_t *section, char *key, va_list args) +{ + char buf[128], keybuf[512]; + + if (snprintf(keybuf, sizeof(keybuf), "%s", key) >= sizeof(keybuf)) + { + return NULL; + } + return find_value_buffered(section, keybuf, keybuf, args, buf, sizeof(buf)); +} + +/** * Implementation of settings_t.get. */ static char* get_str(private_settings_t *this, char *key, char *def, ...) |