diff options
author | Tobias Brunner <tobias@strongswan.org> | 2014-04-29 16:04:43 +0200 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2014-05-15 11:28:09 +0200 |
commit | 8b43c9ba349d7370eb82e8340f48a7045d9c5c5e (patch) | |
tree | eea176620dc0eca21843024830ee897f5c7bcc51 | |
parent | 5ac20cbb8713cea802aa2764704201ae84a0d2d8 (diff) | |
download | strongswan-8b43c9ba349d7370eb82e8340f48a7045d9c5c5e.tar.bz2 strongswan-8b43c9ba349d7370eb82e8340f48a7045d9c5c5e.tar.xz |
settings: Adopt the new order of sections and settings when replacing configs
-rw-r--r-- | src/libstrongswan/settings/settings_types.c | 42 | ||||
-rw-r--r-- | src/libstrongswan/tests/suites/test_settings.c | 84 |
2 files changed, 119 insertions, 7 deletions
diff --git a/src/libstrongswan/settings/settings_types.c b/src/libstrongswan/settings/settings_types.c index 253d06808..125676237 100644 --- a/src/libstrongswan/settings/settings_types.c +++ b/src/libstrongswan/settings/settings_types.c @@ -199,10 +199,13 @@ void settings_section_extend(section_t *base, section_t *extension, enumerator_t *enumerator; section_t *section; kv_t *kv; + array_t *sections = NULL, *kvs = NULL; int idx; if (purge) - { /* remove sections and settings in base not found in extension */ + { /* remove sections and settings in base not found in extension, the + * others are removed too (from the _order list) so they can be inserted + * in the order found in extension */ enumerator = array_create_enumerator(base->sections_order); while (enumerator->enumerate(enumerator, (void**)§ion)) { @@ -212,32 +215,49 @@ void settings_section_extend(section_t *base, section_t *extension, idx = array_bsearch(base->sections, section->name, settings_section_find, NULL); if (section_purge(section, contents)) - { + { /* only remove them if we can purge them */ array_remove(base->sections, idx, NULL); array_remove_at(base->sections_order, enumerator); settings_section_destroy(section, contents); } } + else + { + array_remove_at(base->sections_order, enumerator); + array_insert_create(§ions, ARRAY_TAIL, section); + array_sort(sections, settings_section_sort, NULL); + } } enumerator->destroy(enumerator); - enumerator = array_create_enumerator(base->kv_order); - while (enumerator->enumerate(enumerator, (void**)&kv)) + while (array_remove(base->kv_order, 0, &kv)) { if (array_bsearch(extension->kv, kv->key, settings_kv_find, NULL) == -1) { idx = array_bsearch(base->kv, kv->key, settings_kv_find, NULL); array_remove(base->kv, idx, NULL); - array_remove_at(base->kv_order, enumerator); settings_kv_destroy(kv, contents); } + else + { + array_insert_create(&kvs, ARRAY_TAIL, kv); + array_sort(kvs, settings_kv_sort, NULL); + } } - enumerator->destroy(enumerator); } while (array_remove(extension->sections_order, 0, §ion)) { + idx = array_bsearch(sections, section->name, + settings_section_find, NULL); + if (idx != -1) + { + section_t *existing; + + array_remove(sections, idx, &existing); + array_insert(base->sections_order, ARRAY_TAIL, existing); + } idx = array_bsearch(extension->sections, section->name, settings_section_find, NULL); array_remove(extension->sections, idx, NULL); @@ -246,10 +266,20 @@ void settings_section_extend(section_t *base, section_t *extension, while (array_remove(extension->kv_order, 0, &kv)) { + idx = array_bsearch(kvs, kv->key, settings_kv_find, NULL); + if (idx != -1) + { + kv_t *existing; + + array_remove(kvs, idx, &existing); + array_insert(base->kv_order, ARRAY_TAIL, existing); + } idx = array_bsearch(extension->kv, kv->key, settings_kv_find, NULL); array_remove(extension->kv, idx, NULL); settings_kv_add(base, kv, contents); } + array_destroy(sections); + array_destroy(kvs); } /* diff --git a/src/libstrongswan/tests/suites/test_settings.c b/src/libstrongswan/tests/suites/test_settings.c index 77fef12ad..e504b95a1 100644 --- a/src/libstrongswan/tests/suites/test_settings.c +++ b/src/libstrongswan/tests/suites/test_settings.c @@ -694,6 +694,87 @@ START_TEST(test_load_files_section) } END_TEST +START_TEST(test_order_kv) +{ + chunk_t base = chunk_from_str( + "main {\n" + " key1 = val1\n" + " key2 = val2\n" + " key3 = val3\n" + "}"); + chunk_t include = chunk_from_str( + "main {\n" + " key0 = val0\n" + " key3 = val3\n" + " key1 = val1\n" + "}"); + linked_list_t *keys, *values; + + create_settings(base); + ck_assert(chunk_write(include, include1, 0022, TRUE)); + + keys = linked_list_create_with_items("key1", "key2", "key3", NULL); + values = linked_list_create_with_items("val1", "val2", "val3", NULL); + verify_key_values(keys, values, "main"); + + /* the original order is maintained if the settings are merged */ + ck_assert(settings->load_files(settings, include1, TRUE)); + keys = linked_list_create_with_items("key1", "key2", "key3", "key0", NULL); + values = linked_list_create_with_items("val1", "val2", "val3", "val0", NULL); + verify_key_values(keys, values, "main"); + + /* but the new order is adopted if the settings are replaced */ + ck_assert(settings->load_files(settings, include1, FALSE)); + keys = linked_list_create_with_items("key0", "key3", "key1", NULL); + values = linked_list_create_with_items("val0", "val3", "val1", NULL); + verify_key_values(keys, values, "main"); + + unlink(include1); +} +END_TEST + +START_TEST(test_order_section) +{ + chunk_t base = chunk_from_str( + "main {\n" + " sub1 {\n" + " }\n" + " sub2 {\n" + " }\n" + " sub3 {\n" + " }\n" + "}"); + chunk_t include = chunk_from_str( + "main {\n" + " sub0 {\n" + " }\n" + " sub3 {\n" + " }\n" + " sub1 {\n" + " }\n" + "}"); + linked_list_t *sections; + + create_settings(base); + ck_assert(chunk_write(include, include1, 0022, TRUE)); + + sections = linked_list_create_with_items("sub1", "sub2", "sub3", NULL); + verify_sections(sections, "main"); + + /* the original order is maintained if the settings are merged */ + ck_assert(settings->load_files(settings, include1, TRUE)); + sections = linked_list_create_with_items("sub1", "sub2", "sub3", "sub0", NULL); + verify_sections(sections, "main"); + + /* but the new order is adopted if the settings are replaced */ + ck_assert(settings->load_files(settings, include1, FALSE)); + sections = linked_list_create_with_items("sub0", "sub3", "sub1", NULL); + verify_sections(sections, "main"); + + unlink(include1); +} +END_TEST + START_SETUP(setup_fallback_config) { create_settings(chunk_from_str( @@ -811,7 +892,6 @@ START_TEST(test_add_fallback_printf) } END_TEST - START_SETUP(setup_string_config) { create_settings(chunk_from_str( @@ -967,6 +1047,8 @@ Suite *settings_suite_create() tcase_add_test(tc, test_include); tcase_add_test(tc, test_load_files); tcase_add_test(tc, test_load_files_section); + tcase_add_test(tc, test_order_kv); + tcase_add_test(tc, test_order_section); suite_add_tcase(s, tc); tc = tcase_create("fallback"); |