Mercurial > dovecot > core-2.2
changeset 15087:8c003fe6f5a6
config: Support looking up config for multiple modules at the same time.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 19 Sep 2012 15:33:10 +0300 |
parents | 04580a59dc53 |
children | 14df6be0111f |
files | src/config/config-connection.c src/config/config-filter.c src/config/config-filter.h src/config/config-parser-private.h src/config/config-parser.c src/config/config-parser.h src/config/config-request.c src/config/config-request.h src/config/doveconf.c src/config/main.c |
diffstat | 10 files changed, 77 insertions(+), 61 deletions(-) [+] |
line wrap: on
line diff
--- a/src/config/config-connection.c Tue Sep 18 05:12:28 2012 +0300 +++ b/src/config/config-connection.c Wed Sep 19 15:33:10 2012 +0300 @@ -1,6 +1,7 @@ /* Copyright (c) 2005-2012 Dovecot authors, see the included COPYING file */ #include "lib.h" +#include "array.h" #include "llist.h" #include "istream.h" #include "ostream.h" @@ -69,16 +70,22 @@ struct config_export_context *ctx; struct master_service_settings_output output; struct config_filter filter; - const char *path, *error, *module = ""; + const char *path, *error, *module; + ARRAY(const char *) modules; + bool is_master = FALSE; /* [<args>] */ + t_array_init(&modules, 4); memset(&filter, 0, sizeof(filter)); for (; *args != NULL; args++) { if (strncmp(*args, "service=", 8) == 0) filter.service = *args + 8; - else if (strncmp(*args, "module=", 7) == 0) + else if (strncmp(*args, "module=", 7) == 0) { module = *args + 7; - else if (strncmp(*args, "lname=", 6) == 0) + if (strcmp(module, "master") == 0) + is_master = TRUE; + array_append(&modules, &module, 1); + } else if (strncmp(*args, "lname=", 6) == 0) filter.local_name = *args + 6; else if (strncmp(*args, "lip=", 4) == 0) { if (net_addr2ip(*args + 4, &filter.local_net) == 0) { @@ -94,11 +101,12 @@ } } } + array_append_zero(&modules); - if (strcmp(module, "master") == 0) { + if (is_master) { /* master reads configuration only when reloading settings */ path = master_service_get_config_path(master_service); - if (config_parse_file(path, TRUE, "", &error) <= 0) { + if (config_parse_file(path, TRUE, NULL, &error) <= 0) { o_stream_nsend_str(conn->output, t_strconcat("\nERROR ", error, "\n", NULL)); config_connection_destroy(conn); @@ -108,7 +116,8 @@ o_stream_cork(conn->output); - ctx = config_export_init(module, CONFIG_DUMP_SCOPE_SET, 0, + ctx = config_export_init(array_idx(&modules, 0), + CONFIG_DUMP_SCOPE_SET, 0, config_request_output, conn->output); config_export_by_filter(ctx, &filter); config_export_get_output(ctx, &output);
--- a/src/config/config-filter.c Tue Sep 18 05:12:28 2012 +0300 +++ b/src/config/config-filter.c Wed Sep 19 15:33:10 2012 +0300 @@ -164,15 +164,14 @@ } static bool have_changed_settings(const struct config_filter_parser *parser, - const char *module) + const char *const *modules) { const unsigned char *changes; unsigned int i, j, size; for (i = 0; parser->parsers[i].root != NULL; i++) { - if (*module != '\0' && - !config_module_want_parser(config_module_parsers, - module, parser->parsers[i].root)) + if (!config_module_want_parser(config_module_parsers, + modules, parser->parsers[i].root)) continue; changes = settings_parser_get_changes(parser->parsers[i].parser); @@ -186,7 +185,8 @@ } static struct config_filter_parser *const * -config_filter_find_all(struct config_filter_context *ctx, const char *module, +config_filter_find_all(struct config_filter_context *ctx, + const char *const *modules, const struct config_filter *filter, struct master_service_settings_output *output_r) { @@ -203,7 +203,7 @@ if (!config_filter_match_service(mask, filter)) { if (!str_array_contains(&service_names, mask->service) && - have_changed_settings(ctx->parsers[i], module)) + have_changed_settings(ctx->parsers[i], modules)) array_append(&service_names, &mask->service, 1); continue; } @@ -306,7 +306,7 @@ } int config_filter_parsers_get(struct config_filter_context *ctx, pool_t pool, - const char *module, + const char *const *modules, const struct config_filter *filter, struct config_module_parser **parsers_r, struct master_service_settings_output *output_r, @@ -322,7 +322,7 @@ with an error. Merging SET_STRLIST types requires settings_parser_apply_changes() to work a bit unintuitively by letting the destination settings override the source settings. */ - src = config_filter_find_all(ctx, module, filter, output_r); + src = config_filter_find_all(ctx, modules, filter, output_r); /* all of them should have the same number of parsers. duplicate our initial parsers from the first match */
--- a/src/config/config-filter.h Tue Sep 18 05:12:28 2012 +0300 +++ b/src/config/config-filter.h Wed Sep 19 15:33:10 2012 +0300 @@ -33,11 +33,11 @@ /* Build new parsers from all existing ones matching the given filter. */ int config_filter_parsers_get(struct config_filter_context *ctx, pool_t pool, - const char *module, + const char *const *modules, const struct config_filter *filter, struct config_module_parser **parsers_r, struct master_service_settings_output *output_r, - const char **error_r); + const char **error_r) ATTR_NULL(3); void config_filter_parsers_free(struct config_module_parser *parsers); /* Return a list of filters that are a subset of the given filter. */
--- a/src/config/config-parser-private.h Tue Sep 18 05:12:28 2012 +0300 +++ b/src/config/config-parser-private.h Wed Sep 19 15:33:10 2012 +0300 @@ -39,7 +39,7 @@ struct config_parser_context { pool_t pool; const char *path; - const char *module; + const char *const *modules; ARRAY(struct config_filter_parser *) all_parsers; struct config_module_parser *root_parsers;
--- a/src/config/config-parser.c Tue Sep 18 05:12:28 2012 +0300 +++ b/src/config/config-parser.c Wed Sep 19 15:33:10 2012 +0300 @@ -334,9 +334,8 @@ { for (; p->root != NULL; p++) { /* skip checking settings we don't care about */ - if (*ctx->module != '\0' && - !config_module_want_parser(ctx->root_parsers, - ctx->module, p->root)) + if (!config_module_want_parser(ctx->root_parsers, + ctx->modules, p->root)) continue; settings_parse_var_skip(p->parser); @@ -396,7 +395,7 @@ global_ssl_set = get_str_setting(parsers[0], "ssl", ""); for (i = 0; i < count && ret == 0; i++) { - if (config_filter_parsers_get(new_filter, tmp_pool, "", + if (config_filter_parsers_get(new_filter, tmp_pool, NULL, &parsers[i]->filter, &tmp_parsers, &output, error_r) < 0) { @@ -728,12 +727,12 @@ { struct config_module_parser *l; - if (*ctx->module == '\0') + if (ctx->modules == NULL) return TRUE; for (l = ctx->cur_section->parsers; l->root != NULL; l++) { if (config_module_want_parser(ctx->root_parsers, - ctx->module, l->root) && + ctx->modules, l->root) && settings_parse_is_valid_key(l->parser, key)) return TRUE; } @@ -881,8 +880,8 @@ } } -int config_parse_file(const char *path, bool expand_values, const char *module, - const char **error_r) +int config_parse_file(const char *path, bool expand_values, + const char *const *modules, const char **error_r) { struct input_stack root; struct config_parser_context ctx; @@ -924,7 +923,7 @@ root.path = path; ctx.cur_input = &root; ctx.expand_values = expand_values; - ctx.module = module; + ctx.modules = modules; p_array_init(&ctx.all_parsers, ctx.pool, 128); ctx.cur_section = p_new(ctx.pool, struct config_section_stack, 1); @@ -1052,21 +1051,20 @@ } bool config_module_want_parser(struct config_module_parser *parsers, - const char *module, + const char *const *modules, const struct setting_parser_info *root) { struct config_module_parser *l; - if (strcmp(root->module_name, module) == 0) + if (modules == NULL) return TRUE; - if (root == &master_service_setting_parser_info || - root == &master_service_ssl_setting_parser_info) { + if (root == &master_service_setting_parser_info) { /* everyone wants master service settings */ return TRUE; } for (l = parsers; l->root != NULL; l++) { - if (strcmp(l->root->module_name, module) != 0) + if (!str_array_find(modules, l->root->module_name)) continue; /* see if we can find a way to get from the original parser
--- a/src/config/config-parser.h Tue Sep 18 05:12:28 2012 +0300 +++ b/src/config/config-parser.h Wed Sep 19 15:33:10 2012 +0300 @@ -18,13 +18,15 @@ int config_parse_net(const char *value, struct ip_addr *ip_r, unsigned int *bits_r, const char **error_r); -int config_parse_file(const char *path, bool expand_values, const char *module, - const char **error_r); +int config_parse_file(const char *path, bool expand_values, + const char *const *modules, const char **error_r) + ATTR_NULL(3); void config_parse_load_modules(void); bool config_module_want_parser(struct config_module_parser *parsers, - const char *module, - const struct setting_parser_info *root); + const char *const *modules, + const struct setting_parser_info *root) + ATTR_NULL(2); #endif
--- a/src/config/config-request.c Tue Sep 18 05:12:28 2012 +0300 +++ b/src/config/config-request.c Wed Sep 19 15:33:10 2012 +0300 @@ -21,7 +21,7 @@ config_request_callback_t *callback; void *context; - const char *module; + const char *const *modules; enum config_dump_flags flags; const struct config_module_parser *parsers; struct config_module_parser *dup_parsers; @@ -341,20 +341,20 @@ } struct config_export_context * -config_export_init(const char *module, enum config_dump_scope scope, +config_export_init(const char *const *modules, enum config_dump_scope scope, enum config_dump_flags flags, config_request_callback_t *callback, void *context) { struct config_export_context *ctx; pool_t pool; - i_assert(module != NULL); + i_assert(modules != NULL); pool = pool_alloconly_create(MEMPOOL_GROWING"config export", 1024*64); ctx = p_new(pool, struct config_export_context, 1); ctx->pool = pool; - ctx->module = p_strdup(pool, module); + ctx->modules = p_strarray_dup(pool, modules); ctx->flags = flags; ctx->callback = callback; ctx->context = context; @@ -371,7 +371,7 @@ const char *error; if (config_filter_parsers_get(config_filter, ctx->pool, - ctx->module, filter, + ctx->modules, filter, &ctx->dup_parsers, &ctx->output, &error) < 0) { i_error("%s", error); @@ -417,9 +417,8 @@ for (i = 0; ctx->parsers[i].root != NULL; i++) { parser = &ctx->parsers[i]; - if (*ctx->module != '\0' && - !config_module_want_parser(config_module_parsers, - ctx->module, parser->root)) + if (!config_module_want_parser(config_module_parsers, + ctx->modules, parser->root)) continue; settings_export(ctx, parser->root, FALSE,
--- a/src/config/config-request.h Tue Sep 18 05:12:28 2012 +0300 +++ b/src/config/config-request.h Wed Sep 19 15:33:10 2012 +0300 @@ -38,10 +38,10 @@ enum setting_type type, bool dump_default, bool *dump_r) ATTR_NULL(3); struct config_export_context * -config_export_init(const char *module, enum config_dump_scope scope, +config_export_init(const char *const *modules, enum config_dump_scope scope, enum config_dump_flags flags, config_request_callback_t *callback, void *context) - ATTR_NULL(5); + ATTR_NULL(1, 5); void config_export_by_filter(struct config_export_context *ctx, const struct config_filter *filter); void config_export_parsers(struct config_export_context *ctx,
--- a/src/config/doveconf.c Tue Sep 18 05:12:28 2012 +0300 +++ b/src/config/doveconf.c Wed Sep 19 15:33:10 2012 +0300 @@ -118,7 +118,7 @@ } static struct config_dump_human_context * -config_dump_human_init(const char *module, enum config_dump_scope scope, +config_dump_human_init(const char *const *modules, enum config_dump_scope scope, bool check_settings) { struct config_dump_human_context *ctx; @@ -137,7 +137,7 @@ if (check_settings) flags |= CONFIG_DUMP_FLAG_CHECK_SETTINGS; - ctx->export_ctx = config_export_init(module, scope, flags, + ctx->export_ctx = config_export_init(modules, scope, flags, config_request_get_strings, ctx); return ctx; } @@ -390,7 +390,7 @@ static int config_dump_human_sections(struct ostream *output, const struct config_filter *filter, - const char *module) + const char *const *modules) { struct config_filter_parser *const *filters; static struct config_dump_human_context *ctx; @@ -404,7 +404,7 @@ filters++; for (; *filters != NULL; filters++) { - ctx = config_dump_human_init(module, CONFIG_DUMP_SCOPE_SET, + ctx = config_dump_human_init(modules, CONFIG_DUMP_SCOPE_SET, FALSE); indent = config_dump_filter_begin(ctx->list_prefix, &(*filters)->filter); @@ -419,7 +419,7 @@ } static int ATTR_NULL(4) -config_dump_human(const struct config_filter *filter, const char *module, +config_dump_human(const struct config_filter *filter, const char *const *modules, enum config_dump_scope scope, const char *setting_name_filter) { static struct config_dump_human_context *ctx; @@ -430,13 +430,13 @@ o_stream_set_no_error_handling(output, TRUE); o_stream_cork(output); - ctx = config_dump_human_init(module, scope, TRUE); + ctx = config_dump_human_init(modules, scope, TRUE); config_export_by_filter(ctx->export_ctx, filter); ret = config_dump_human_output(ctx, output, 0, setting_name_filter); config_dump_human_deinit(ctx); if (setting_name_filter == NULL) - ret = config_dump_human_sections(output, filter, module); + ret = config_dump_human_sections(output, filter, modules); o_stream_uncork(output); o_stream_destroy(&output); @@ -452,7 +452,7 @@ unsigned int len; bool dump_section = FALSE; - ctx = config_dump_human_init("", scope, FALSE); + ctx = config_dump_human_init(NULL, scope, FALSE); config_export_by_filter(ctx->export_ctx, filter); if (config_export_finish(&ctx->export_ctx) < 0) return -1; @@ -478,7 +478,7 @@ config_dump_human_deinit(ctx); if (dump_section) - (void)config_dump_human(filter, "", scope, setting_name_filter); + (void)config_dump_human(filter, NULL, scope, setting_name_filter); return 0; } @@ -589,7 +589,8 @@ int main(int argc, char *argv[]) { enum config_dump_scope scope = CONFIG_DUMP_SCOPE_ALL; - const char *orig_config_path, *config_path, *module = ""; + const char *orig_config_path, *config_path, *module; + ARRAY(const char *) module_names; struct config_filter filter; const char *error; char **exec_args = NULL, **setting_name_filters = NULL; @@ -611,6 +612,7 @@ orig_config_path = master_service_get_config_path(master_service); i_set_failure_prefix("doveconf: "); + t_array_init(&module_names, 4); while ((c = master_getopt(master_service)) > 0) { if (c == 'e') { expand_vars = TRUE; @@ -629,7 +631,8 @@ hide_key = TRUE; break; case 'm': - module = optarg; + module = t_strdup(optarg); + array_append(&module_names, &module, 1); break; case 'n': scope = CONFIG_DUMP_SCOPE_CHANGED; @@ -650,6 +653,8 @@ return FATAL_DEFAULT; } } + array_append_zero(&module_names); + config_path = master_service_get_config_path(master_service); /* use strcmp() instead of !=, because dovecot -n always gives us -c parameter */ @@ -673,7 +678,8 @@ if ((ret = config_parse_file(dump_defaults ? NULL : config_path, expand_vars, - parse_full_config ? "" : module, + parse_full_config ? NULL : + array_idx(&module_names, 0), &error)) == 0 && access(EXAMPLE_CONFIG_DIR, X_OK) == 0) { i_fatal("%s (copy example configs from "EXAMPLE_CONFIG_DIR"/)", @@ -686,7 +692,7 @@ if (simple_output) { struct config_export_context *ctx; - ctx = config_export_init(module, scope, + ctx = config_export_init(array_idx(&module_names, 0), scope, CONFIG_DUMP_FLAG_CHECK_SETTINGS, config_request_simple_stdout, setting_name_filters); @@ -713,12 +719,14 @@ if (!config_path_specified) check_wrong_config(config_path); fflush(stdout); - ret2 = config_dump_human(&filter, module, scope, NULL); + ret2 = config_dump_human(&filter, array_idx(&module_names, 0), + scope, NULL); } else { struct config_export_context *ctx; env_put("DOVECONF_ENV=1"); - ctx = config_export_init(module, CONFIG_DUMP_SCOPE_SET, + ctx = config_export_init(array_idx(&module_names, 0), + CONFIG_DUMP_SCOPE_SET, CONFIG_DUMP_FLAG_CHECK_SETTINGS, config_request_putenv, NULL); config_export_by_filter(ctx, &filter);
--- a/src/config/main.c Tue Sep 18 05:12:28 2012 +0300 +++ b/src/config/main.c Wed Sep 19 15:33:10 2012 +0300 @@ -30,7 +30,7 @@ config_parse_load_modules(); path = master_service_get_config_path(master_service); - if (config_parse_file(path, TRUE, "", &error) <= 0) + if (config_parse_file(path, TRUE, NULL, &error) <= 0) i_fatal("%s", error); master_service_run(master_service, client_connected);