]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
Allow to replace/extend previously defined values/sections in strongswan.conf.
authorTobias Brunner <tobias@strongswan.org>
Thu, 11 Nov 2010 15:02:30 +0000 (16:02 +0100)
committerTobias Brunner <tobias@strongswan.org>
Fri, 3 Dec 2010 16:38:37 +0000 (17:38 +0100)
src/libstrongswan/settings.c

index 034539491fe4a326112d2d32e7733c3e52a873a5..84a86d8675bf99e115422cfe2c6123ec16a393c9 100644 (file)
@@ -473,6 +473,22 @@ static void section_destroy(section_t *this)
        free(this);
 }
 
+/**
+ * callback to find a section by name
+ */
+static bool section_find(section_t *this, char *name)
+{
+       return streq(this->name, name);
+}
+
+/**
+ * callback to find a kv pair by key
+ */
+static bool kv_find(kv_t *this, char *key)
+{
+       return streq(this->key, key);
+}
+
 /**
  * parse text, truncate "skip" chars, delimited by term respecting brackets.
  *
@@ -562,13 +578,27 @@ static bool parse_section(char **text, section_t *section)
                        case '{':
                                if (parse(text, "\t ", "}", "{", &inner))
                                {
-                                       section_t *sub = section_create(key);
-                                       if (parse_section(&inner, sub))
+                                       section_t *sub;
+                                       if (section->sections->find_first(section->sections,
+                                                                                       (linked_list_match_t)section_find,
+                                                                                       (void**)&sub, key) != SUCCESS)
                                        {
-                                               section->sections->insert_last(section->sections, sub);
-                                               continue;
+                                               sub = section_create(key);
+                                               if (parse_section(&inner, sub))
+                                               {
+                                                       section->sections->insert_last(section->sections,
+                                                                                                                  sub);
+                                                       continue;
+                                               }
+                                               section_destroy(sub);
+                                       }
+                                       else
+                                       {       /* extend the existing section */
+                                               if (parse_section(&inner, sub))
+                                               {
+                                                       continue;
+                                               }
                                        }
-                                       section_destroy(sub);
                                        DBG1(DBG_LIB, "parsing subsection '%s' failed", key);
                                        break;
                                }
@@ -577,10 +607,21 @@ static bool parse_section(char **text, section_t *section)
                        case '=':
                                if (parse(text, "\t ", "\n", NULL, &value))
                                {
-                                       kv_t *kv = malloc_thing(kv_t);
-                                       kv->key = key;
-                                       kv->value = value;
-                                       section->kv->insert_last(section->kv, kv);
+                                       kv_t *kv;
+                                       if (section->kv->find_first(section->kv,
+                                                               (linked_list_match_t)kv_find,
+                                                               (void**)&kv, key) != SUCCESS)
+                                       {
+                                               INIT(kv,
+                                                       .key = key,
+                                                       .value = value,
+                                               );
+                                               section->kv->insert_last(section->kv, kv);
+                                       }
+                                       else
+                                       {       /* replace with the most recently read value */
+                                               kv->value = value;
+                                       }
                                        continue;
                                }
                                DBG1(DBG_LIB, "parsing value failed near %s", *text);