Ensure that sections exist when using load_files_section.
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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, ...);
|
||||
|
||||
Reference in New Issue
Block a user