]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
config: Add support for changing the default settings internally
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Mon, 8 May 2023 13:44:20 +0000 (16:44 +0300)
committerTimo Sirainen <timo.sirainen@open-xchange.com>
Mon, 20 Nov 2023 12:22:30 +0000 (14:22 +0200)
Currently the default settings can be given only via the defaults struct.
With this change it's possible to separately track whether settings changes
are intended to be defaults or explicit configuration changes.

Only the explicit config changes are visible in e.g. "doveconf -n" output,
while all the changes will be written to the binary config file.

src/config/config-dump-full.c
src/config/config-parser.c
src/config/config-parser.h
src/config/config-request.c
src/config/config-request.h
src/config/doveconf.c

index 390ec267e0fbfe94ce050b18cf79e8f59271319a..29b8dd9aa393efa3d7e8ddf9fb815c01929d074d 100644 (file)
@@ -269,12 +269,12 @@ config_dump_full_sections(struct config_parsed *config,
                dump_ctx.filter_written = FALSE;
                if (dest == CONFIG_DUMP_FULL_DEST_STDOUT) {
                        export_ctx = config_export_init(
-                               CONFIG_DUMP_SCOPE_SET,
+                               CONFIG_DUMP_SCOPE_SET_AND_DEFAULT_OVERRIDES,
                                CONFIG_DUMP_FLAG_HIDE_LIST_DEFAULTS,
                                config_dump_full_stdout_callback, &dump_ctx);
                } else {
                        export_ctx = config_export_init(
-                               CONFIG_DUMP_SCOPE_SET,
+                               CONFIG_DUMP_SCOPE_SET_AND_DEFAULT_OVERRIDES,
                                CONFIG_DUMP_FLAG_HIDE_LIST_DEFAULTS,
                                config_dump_full_callback, &dump_ctx);
                }
@@ -318,12 +318,13 @@ int config_dump_full(struct config_parsed *config,
 
        if (dest == CONFIG_DUMP_FULL_DEST_STDOUT) {
                export_ctx = config_export_init(
-                               CONFIG_DUMP_SCOPE_CHANGED, flags,
-                               config_dump_full_stdout_callback, &dump_ctx);
+                               CONFIG_DUMP_SCOPE_SET_AND_DEFAULT_OVERRIDES,
+                               flags, config_dump_full_stdout_callback,
+                               &dump_ctx);
        } else {
                export_ctx = config_export_init(
-                               CONFIG_DUMP_SCOPE_CHANGED, flags,
-                               config_dump_full_callback, &dump_ctx);
+                               CONFIG_DUMP_SCOPE_SET_AND_DEFAULT_OVERRIDES,
+                               flags, config_dump_full_callback, &dump_ctx);
        }
        struct config_filter_parser *filter_parser =
                config_parsed_get_global_filter_parser(config);
index aba5ad62348cbea973eeb7077e626fd16d70ff2d..fa79e30e10c661dd516af67048af3da4ef08dd95 100644 (file)
@@ -269,6 +269,8 @@ config_module_parsers_init(pool_t pool)
                dest[i].root = all_roots[i];
                dest[i].parser = settings_parser_init(pool, all_roots[i],
                                                      settings_parser_flags);
+               settings_parse_set_change_counter(dest[i].parser,
+                                                 CONFIG_PARSER_CHANGE_EXPLICIT);
        }
        return dest;
 }
@@ -1298,6 +1300,8 @@ int config_parse_file(const char *path, enum config_parse_flags flags,
                ctx.root_module_parsers[i].parser =
                        settings_parser_init(ctx.pool, all_roots[i],
                                             settings_parser_flags);
+               settings_parse_set_change_counter(ctx.root_module_parsers[i].parser,
+                                                 CONFIG_PARSER_CHANGE_EXPLICIT);
                for (unsigned int j = 0; j < i; j++) {
                        if (strcmp(all_roots[j]->name, all_roots[i]->name) == 0) {
                                /* Just fatal - it's difficult to continue
index 252cb600bbc9778451cbf0c55f294be55a36dc33..6772537e08b2b0b3414cdc77afe4b972be31e492 100644 (file)
@@ -5,6 +5,11 @@
 
 #define IS_WHITE(c) ((c) == ' ' || (c) == '\t')
 
+/* change_counter used for default settings created internally */
+#define CONFIG_PARSER_CHANGE_INTERNAL 1
+/* change_counter used for settings changed by configuration file */
+#define CONFIG_PARSER_CHANGE_EXPLICIT 2
+
 struct config_parsed;
 
 enum config_parse_flags {
index 043adbdb3987c6d728ad576dbd1d8025b480432f..0b96f33dfcc8acb98538378af263da43b1288d21 100644 (file)
@@ -241,9 +241,26 @@ settings_export(struct config_export_context *ctx,
                        /* hidden - dump default only if it's explicitly set */
                        /* fall through */
                case CONFIG_DUMP_SCOPE_SET:
+                       if (def->type == SET_DEFLIST ||
+                           def->type == SET_DEFLIST_UNIQUE)
+                               break;
+                       if (*((const uint8_t *)change_value) < CONFIG_PARSER_CHANGE_EXPLICIT) {
+                               /* setting is unchanged in config file */
+                               continue;
+                       }
+                       dump_default = TRUE;
+                       break;
+               case CONFIG_DUMP_SCOPE_SET_AND_DEFAULT_OVERRIDES:
+                       if (def->type == SET_DEFLIST ||
+                           def->type == SET_DEFLIST_UNIQUE)
+                               break;
                        dump_default = *((const char *)change_value) != 0;
                        break;
                case CONFIG_DUMP_SCOPE_CHANGED:
+                       if (*((const uint8_t *)change_value) < CONFIG_PARSER_CHANGE_EXPLICIT) {
+                               /* setting is unchanged in config file */
+                               continue;
+                       }
                        dump_default = FALSE;
                        break;
                }
index 44d1380e1724e078f593ba11d590cb1d01b89a5c..98bdbe275e62a9ea7888e8e80a90f529eee40a03 100644 (file)
@@ -13,6 +13,9 @@ enum config_dump_scope {
        CONFIG_DUMP_SCOPE_ALL_WITHOUT_HIDDEN,
        /* Dump all that have explicitly been set */
        CONFIG_DUMP_SCOPE_SET,
+       /* Same as CONFIG_DUMP_SCOPE_SET, but also dump any defaults overridden
+          via strings (instead of the defaults struct). */
+       CONFIG_DUMP_SCOPE_SET_AND_DEFAULT_OVERRIDES,
        /* Dump only settings that differ from defaults */
        CONFIG_DUMP_SCOPE_CHANGED
 };
index 4946824bc30d1dc07509a7ae788afd5c0ac91ffb..c972011ad03912061b10408ff503466210017ee1 100644 (file)
@@ -735,6 +735,10 @@ config_dump_human(enum config_dump_scope scope,
        const char *const *set_filter_path =
                setting_name_filter == NULL ? empty_str_array :
                t_strsplit(setting_name_filter, "/");
+       if (scope == CONFIG_DUMP_SCOPE_CHANGED)
+               scope = CONFIG_DUMP_SCOPE_SET;
+       else
+               scope = CONFIG_DUMP_SCOPE_SET_AND_DEFAULT_OVERRIDES;
        config_dump_human_filter_path(scope, set_filter_path,
                                      filter_parser->children_head, output, 0,
                                      list_prefix, &list_prefix_sent,