aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libstrongswan/settings.c120
-rw-r--r--src/libstrongswan/settings.h50
2 files changed, 136 insertions, 34 deletions
diff --git a/src/libstrongswan/settings.c b/src/libstrongswan/settings.c
index 6f9e40395..a02823ba0 100644
--- a/src/libstrongswan/settings.c
+++ b/src/libstrongswan/settings.c
@@ -88,9 +88,50 @@ struct kv_t {
char *value;
};
-static char *find(section_t *section, char *key)
+/**
+ * find a section by a given key
+ */
+static section_t *find_section(section_t *section, char *key, va_list args)
+{
+ char name[512], *pos;
+ enumerator_t *enumerator;
+ section_t *current, *found = NULL;
+
+ if (section == NULL)
+ {
+ return NULL;
+ }
+ if (vsnprintf(name, sizeof(name), key, args) >= sizeof(name))
+ {
+ return NULL;
+ }
+
+ pos = strchr(name, '.');
+ if (pos)
+ {
+ *pos = '\0';
+ pos++;
+ }
+ enumerator = section->sections->create_enumerator(section->sections);
+ while (enumerator->enumerate(enumerator, &current))
+ {
+ if (streq(current->name, name))
+ {
+ found = current;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ if (found && pos)
+ {
+ return find_section(found, pos, args);
+ }
+ return found;
+}
+
+static char *find_value(section_t *section, char *key, va_list args)
{
- char *name, *pos, *value = NULL;
+ char name[512], *pos, *value = NULL;
enumerator_t *enumerator;
kv_t *kv;
section_t *current, *found = NULL;
@@ -100,7 +141,10 @@ static char *find(section_t *section, char *key)
return NULL;
}
- name = strdupa(key);
+ if (vsnprintf(name, sizeof(name), key, args) >= sizeof(name))
+ {
+ return NULL;
+ }
pos = strchr(name, '.');
if (pos)
@@ -119,7 +163,7 @@ static char *find(section_t *section, char *key)
enumerator->destroy(enumerator);
if (found)
{
- return find(found, pos);
+ return find_value(found, pos, args);
}
}
else
@@ -141,11 +185,14 @@ static char *find(section_t *section, char *key)
/**
* Implementation of settings_t.get.
*/
-static char* get_str(private_settings_t *this, char *key, char *def)
+static char* get_str(private_settings_t *this, char *key, char *def, ...)
{
char *value;
+ va_list args;
- value = find(this->top, key);
+ va_start(args, def);
+ value = find_value(this->top, key, args);
+ va_end(args);
if (value)
{
return value;
@@ -156,11 +203,14 @@ static char* get_str(private_settings_t *this, char *key, char *def)
/**
* Implementation of settings_t.get_bool.
*/
-static bool get_bool(private_settings_t *this, char *key, bool def)
+static bool get_bool(private_settings_t *this, char *key, bool def, ...)
{
char *value;
+ va_list args;
- value = find(this->top, key);
+ va_start(args, def);
+ value = find_value(this->top, key, args);
+ va_end(args);
if (value)
{
if (strcasecmp(value, "true") == 0 ||
@@ -184,12 +234,15 @@ static bool get_bool(private_settings_t *this, char *key, bool def)
/**
* Implementation of settings_t.get_int.
*/
-static int get_int(private_settings_t *this, char *key, int def)
+static int get_int(private_settings_t *this, char *key, int def, ...)
{
char *value;
int intval;
+ va_list args;
- value = find(this->top, key);
+ va_start(args, def);
+ value = find_value(this->top, key, args);
+ va_end(args);
if (value)
{
errno = 0;
@@ -205,12 +258,15 @@ static int get_int(private_settings_t *this, char *key, int def)
/**
* Implementation of settings_t.get_time.
*/
-static u_int32_t get_time(private_settings_t *this, char *key, u_int32_t def)
+static u_int32_t get_time(private_settings_t *this, char *key, u_int32_t def, ...)
{
char *value, *endptr;
u_int32_t timeval;
+ va_list args;
- value = find(this->top, key);
+ va_start(args, def);
+ value = find_value(this->top, key, args);
+ va_end(args);
if (value)
{
errno = 0;
@@ -239,6 +295,37 @@ static u_int32_t get_time(private_settings_t *this, char *key, u_int32_t def)
}
/**
+ * Enumerate section names, not sections
+ */
+static bool section_filter(void *null, section_t **in, char **out)
+{
+ *out = (*in)->name;
+ return TRUE;
+}
+
+/**
+ * Implementation of settings_t.create_section_enumerator
+ */
+static enumerator_t* create_section_enumerator(private_settings_t *this,
+ char *key, ...)
+{
+ section_t *section;
+ va_list args;
+
+ va_start(args, key);
+ section = find_section(this->top, key, args);
+ va_end(args);
+
+ if (!section)
+ {
+ return enumerator_create_empty();
+ }
+ return enumerator_create_filter(
+ section->sections->create_enumerator(section->sections),
+ (void*)section_filter, NULL, NULL);
+}
+
+/**
* destroy a section
*/
static void section_destroy(section_t *this)
@@ -400,10 +487,11 @@ settings_t *settings_create(char *file)
{
private_settings_t *this = malloc_thing(private_settings_t);
- this->public.get_str = (char*(*)(settings_t*, char *key, char* def))get_str;
- this->public.get_int = (int(*)(settings_t*, char *key, int def))get_int;
- this->public.get_time = (u_int32_t(*)(settings_t*, char *key, u_int32_t def))get_time;
- this->public.get_bool = (bool(*)(settings_t*, char *key, bool def))get_bool;
+ this->public.get_str = (char*(*)(settings_t*, char *key, char* def, ...))get_str;
+ this->public.get_int = (int(*)(settings_t*, char *key, int def, ...))get_int;
+ this->public.get_time = (u_int32_t(*)(settings_t*, char *key, u_int32_t def, ...))get_time;
+ this->public.get_bool = (bool(*)(settings_t*, char *key, bool def, ...))get_bool;
+ this->public.create_section_enumerator = (enumerator_t*(*)(settings_t*,char *section, ...))create_section_enumerator;
this->public.destroy = (void(*)(settings_t*))destroy;
this->top = NULL;
diff --git a/src/libstrongswan/settings.h b/src/libstrongswan/settings.h
index 451c2a583..0f41878c5 100644
--- a/src/libstrongswan/settings.h
+++ b/src/libstrongswan/settings.h
@@ -26,11 +26,12 @@
typedef struct settings_t settings_t;
#include <library.h>
+#include <utils/enumerator.h>
/**
* Generic configuration options read from a config file.
*
- * The sytax is quite simple:
+ * The syntax is quite simple:
*
* settings := (section|keyvalue)*
* section := name { settings }
@@ -38,8 +39,8 @@ typedef struct settings_t settings_t;
*
* E.g.:
* @code
- a = b
- section-one {
+ a = b
+ section-one {
somevalue = asdf
subsection {
othervalue = xxx
@@ -58,43 +59,56 @@ struct settings_t {
/**
* Get a settings value as a string.
*
- * @param key key including sections
+ * @param key key including sections, printf style format
* @param def value returned if key not found
+ * @param ... argument list for key
* @return value pointing to internal string
*/
- char* (*get_str)(settings_t *this, char *key, char *def);
+ char* (*get_str)(settings_t *this, char *key, char *def, ...);
/**
* Get a boolean yes|no, true|false value.
*
- * @param jey key including sections
- * @param def default value returned if key not found
+ * @param key key including sections, printf style format
+ * @param def value returned if key not found
+ * @param ... argument list for key
* @return value of the key
*/
- bool (*get_bool)(settings_t *this, char *key, bool def);
+ bool (*get_bool)(settings_t *this, char *key, bool def, ...);
/**
* Get an integer value.
*
- * @param key key including sections
- * @param def default value to return if key not found
+ * @param key key including sections, printf style format
+ * @param def value returned if key not found
+ * @param ... argument list for key
* @return value of the key
*/
- int (*get_int)(settings_t *this, char *key, int def);
+ int (*get_int)(settings_t *this, char *key, int def, ...);
/**
* Get a time value.
*
- * @param key key including sections
- * @param def default value to return if key not found
+ * @param key key including sections, printf style format
+ * @param def value returned if key not found
+ * @param ... argument list for key
* @return value of the key
*/
- u_int32_t (*get_time)(settings_t *this, char *key, u_int32_t def);
-
+ u_int32_t (*get_time)(settings_t *this, char *key, u_int32_t def, ...);
+
/**
- * Destroy a settings instance.
- */
- void (*destroy)(settings_t *this);
+ * Create an enumerator over subsection names of a section.
+ *
+ * @param section section including parents, printf style format
+ * @param ... argument list for key
+ * @return enumerator over subsection names
+ */
+ enumerator_t* (*create_section_enumerator)(settings_t *this,
+ char *section, ...);
+ /**
+ * Destroy a settings instance.
+ */
+ void (*destroy)(settings_t *this);
};
/**