From: Tobias Brunner Date: Fri, 12 Nov 2010 16:35:04 +0000 (+0100) Subject: Ensure that sections exist when using load_files_section. X-Git-Tag: 4.5.1~451 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f2649f354df8548a5ef6085c1f4effa9876f1595;p=thirdparty%2Fstrongswan.git Ensure that sections exist when using load_files_section. --- diff --git a/src/libstrongswan/settings.c b/src/libstrongswan/settings.c index ccff84f252..cc24312a7b 100644 --- a/src/libstrongswan/settings.c +++ b/src/libstrongswan/settings.c @@ -105,7 +105,7 @@ static section_t *section_create(char *name) { section_t *this; INIT(this, - .name = name, + .name = name ? strdup(name) : NULL, .sections = linked_list_create(), .kv = linked_list_create(), ); @@ -119,6 +119,7 @@ static void section_destroy(section_t *this) { this->kv->destroy_function(this->kv, free); this->sections->destroy_function(this->sections, (void*)section_destroy); + free(this->name); free(this); } @@ -187,10 +188,12 @@ static bool print_key(char *buf, int len, char *start, char *key, va_list args) } /** - * find a section by a given key, using buffered key, reusable buffer + * Find a section by a given key, using buffered key, reusable buffer. + * If "ensure" is TRUE, the sections are created if they don't exist. */ static section_t *find_section_buffered(section_t *section, - char *start, char *key, va_list args, char *buf, int len) + char *start, char *key, va_list args, char *buf, int len, + bool ensure) { char *pos; section_t *found = NULL; @@ -211,13 +214,18 @@ static section_t *find_section_buffered(section_t *section, } if (section->sections->find_first(section->sections, (linked_list_match_t)section_find, - (void**)&found, buf) == SUCCESS) + (void**)&found, buf) != SUCCESS) { - if (pos) + if (ensure) { - return find_section_buffered(found, start, pos, args, buf, len); + found = section_create(buf); + section->sections->insert_last(section->sections, found); } } + if (found && pos) + { + return find_section_buffered(found, start, pos, args, buf, len, ensure); + } return found; } @@ -236,7 +244,28 @@ static section_t *find_section(private_settings_t *this, section_t *section, } this->lock->read_lock(this->lock); found = find_section_buffered(section, keybuf, keybuf, args, buf, - sizeof(buf)); + sizeof(buf), FALSE); + this->lock->unlock(this->lock); + return found; +} + +/** + * Ensure that the section with the given key exists (thread-safe). + */ +static section_t *ensure_section(private_settings_t *this, section_t *section, + char *key, va_list args) +{ + char buf[128], keybuf[512]; + section_t *found; + + if (snprintf(keybuf, sizeof(keybuf), "%s", key) >= sizeof(keybuf)) + { + return NULL; + } + /* we might have to change the tree */ + this->lock->write_lock(this->lock); + found = find_section_buffered(section, keybuf, keybuf, args, buf, + sizeof(buf), TRUE); this->lock->unlock(this->lock); return found; } @@ -424,7 +453,7 @@ METHOD(settings_t, get_time, u_int32_t, timeval *= 60; break; case 's': /* time in seconds */ - default: + default: break; } return timeval; @@ -920,7 +949,7 @@ METHOD(settings_t, load_files_section, bool, va_list args; va_start(args, key); - section = find_section(this, this->top, key, args); + section = ensure_section(this, this->top, key, args); va_end(args); if (!section) diff --git a/src/libstrongswan/settings.h b/src/libstrongswan/settings.h index ab4f26e757..70aa96fb5b 100644 --- a/src/libstrongswan/settings.h +++ b/src/libstrongswan/settings.h @@ -180,7 +180,7 @@ struct settings_t { * in the loaded files. * * @note If any of the files matching the pattern fails to load, no settings - * are added at all. So it's all or nothing. + * are added at all. So, it's all or nothing. * * @param pattern file pattern * @return TRUE, if settings were loaded successfully @@ -193,15 +193,16 @@ struct settings_t { * Existing sections are extended, existing values replaced, by those found * in the loaded files. * - * All settings are loaded relative to the given section. + * All settings are loaded relative to the given section. The section is + * created, if it does not yet exist. * * @note If any of the files matching the pattern fails to load, no settings - * are added at all. So it's all or nothing. + * are added at all. So, it's all or nothing. * * @param pattern file pattern * @param section section name of parent section, printf style * @param ... argument list for section - * @return TRUE, if section is found and settings were loaded successfully + * @return TRUE, if settings were loaded successfully */ bool (*load_files_section)(settings_t *this, char *pattern, char *section, ...);