From: Timo Sirainen Date: Mon, 8 May 2023 13:44:20 +0000 (+0300) Subject: config: Add support for changing the default settings internally X-Git-Tag: 2.4.0~2036 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e413bc509f279bc21f3bac774f05c91c829be001;p=thirdparty%2Fdovecot%2Fcore.git config: Add support for changing the default settings internally 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. --- diff --git a/src/config/config-dump-full.c b/src/config/config-dump-full.c index 390ec267e0..29b8dd9aa3 100644 --- a/src/config/config-dump-full.c +++ b/src/config/config-dump-full.c @@ -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); diff --git a/src/config/config-parser.c b/src/config/config-parser.c index aba5ad6234..fa79e30e10 100644 --- a/src/config/config-parser.c +++ b/src/config/config-parser.c @@ -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 diff --git a/src/config/config-parser.h b/src/config/config-parser.h index 252cb600bb..6772537e08 100644 --- a/src/config/config-parser.h +++ b/src/config/config-parser.h @@ -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 { diff --git a/src/config/config-request.c b/src/config/config-request.c index 043adbdb39..0b96f33dfc 100644 --- a/src/config/config-request.c +++ b/src/config/config-request.c @@ -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; } diff --git a/src/config/config-request.h b/src/config/config-request.h index 44d1380e17..98bdbe275e 100644 --- a/src/config/config-request.h +++ b/src/config/config-request.h @@ -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 }; diff --git a/src/config/doveconf.c b/src/config/doveconf.c index 4946824bc3..c972011ad0 100644 --- a/src/config/doveconf.c +++ b/src/config/doveconf.c @@ -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,