]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
doveconf -N dumps only settings that have been explicitly set.
authorTimo Sirainen <tss@iki.fi>
Wed, 2 Sep 2009 20:21:41 +0000 (16:21 -0400)
committerTimo Sirainen <tss@iki.fi>
Wed, 2 Sep 2009 20:21:41 +0000 (16:21 -0400)
--HG--
branch : HEAD

src/config/config-request.c
src/config/config-request.h
src/config/doveconf.c

index 5815addd926d54e9942dcff74ea1dccacae342c7..1837f7ad64b821002dcd45893a9fc0a39ea037ae 100644 (file)
@@ -16,7 +16,7 @@ struct settings_export_context {
        string_t *value;
        string_t *prefix;
        struct hash_table *keys;
-       bool export_defaults;
+       enum config_dump_scope scope;
 
        config_request_callback_t *callback;
        void *context;
@@ -72,20 +72,32 @@ config_setting_parser_is_in_service(const struct config_setting_parser_list *lis
 
 static void settings_export(struct settings_export_context *ctx,
                            const struct setting_parser_info *info,
-                           const void *set)
+                           const void *set, const void *change_set)
 {
        const struct setting_define *def;
-       const void *value, *default_value;
-       void *const *children = NULL;
-       unsigned int i, count, prefix_len;
+       const void *value, *default_value, *change_value;
+       void *const *children = NULL, *const *change_children = NULL;
+       unsigned int i, count, count2, prefix_len;
        const char *str;
        char *key;
-       bool dump;
+       bool dump, dump_default = FALSE;
 
        for (def = info->defines; def->key != NULL; def++) {
                value = CONST_PTR_OFFSET(set, def->offset);
                default_value = info->defaults == NULL ? NULL :
                        CONST_PTR_OFFSET(info->defaults, def->offset);
+               change_value = CONST_PTR_OFFSET(change_set, def->offset);
+               switch (ctx->scope) {
+               case CONFIG_DUMP_SCOPE_ALL:
+                       dump_default = TRUE;
+                       break;
+               case CONFIG_DUMP_SCOPE_SET:
+                       dump_default = *((const char *)change_value) != 0;
+                       break;
+               case CONFIG_DUMP_SCOPE_CHANGED:
+                       dump_default = FALSE;
+                       break;
+               }
 
                dump = FALSE;
                count = 0;
@@ -93,8 +105,7 @@ static void settings_export(struct settings_export_context *ctx,
                switch (def->type) {
                case SET_BOOL: {
                        const bool *val = value, *dval = default_value;
-                       if (ctx->export_defaults ||
-                           dval == NULL || *val != *dval) {
+                       if (dump_default || dval == NULL || *val != *dval) {
                                str_append(ctx->value,
                                           *val ? "yes" : "no");
                        }
@@ -102,8 +113,7 @@ static void settings_export(struct settings_export_context *ctx,
                }
                case SET_UINT: {
                        const unsigned int *val = value, *dval = default_value;
-                       if (ctx->export_defaults ||
-                           dval == NULL || *val != *dval)
+                       if (dump_default || dval == NULL || *val != *dval)
                                str_printfa(ctx->value, "%u", *val);
                        break;
                }
@@ -116,8 +126,8 @@ static void settings_export(struct settings_export_context *ctx,
                                 **val == SETTING_STRVAR_UNEXPANDED[0]);
 
                        sval = *val == NULL ? NULL : (*val + 1);
-                       if ((ctx->export_defaults ||
-                            null_strcmp(sval, dval) != 0) && sval != NULL) {
+                       if ((dump_default || null_strcmp(sval, dval) != 0) &&
+                           sval != NULL) {
                                str_append(ctx->value, sval);
                                dump = TRUE;
                        }
@@ -128,8 +138,8 @@ static void settings_export(struct settings_export_context *ctx,
                        const char *const *_dval = default_value;
                        const char *dval = _dval == NULL ? NULL : *_dval;
 
-                       if ((ctx->export_defaults ||
-                            null_strcmp(*val, dval) != 0) && *val != NULL) {
+                       if ((dump_default || null_strcmp(*val, dval) != 0) &&
+                           *val != NULL) {
                                str_append(ctx->value, *val);
                                dump = TRUE;
                        }
@@ -141,14 +151,14 @@ static void settings_export(struct settings_export_context *ctx,
                        const char *dval = _dval == NULL ? NULL : *_dval;
                        unsigned int len = strlen(*val);
 
-                       if (ctx->export_defaults ||
-                           strncmp(*val, dval, len) != 0 ||
+                       if (dump_default || strncmp(*val, dval, len) != 0 ||
                            ((*val)[len] != ':' && (*val)[len] != '\0'))
                                str_append(ctx->value, *val);
                        break;
                }
                case SET_DEFLIST: {
                        const ARRAY_TYPE(void_array) *val = value;
+                       const ARRAY_TYPE(void_array) *change_val = change_value;
 
                        if (!array_is_created(val))
                                break;
@@ -159,6 +169,8 @@ static void settings_export(struct settings_export_context *ctx,
                                        str_append_c(ctx->value, ' ');
                                str_printfa(ctx->value, "%u", i);
                        }
+                       change_children = array_get(change_val, &count2);
+                       i_assert(count == count2);
                        break;
                }
                case SET_STRLIST: {
@@ -211,7 +223,8 @@ static void settings_export(struct settings_export_context *ctx,
                        str_append_c(ctx->prefix, SETTINGS_SEPARATOR);
                        str_printfa(ctx->prefix, "%u", i);
                        str_append_c(ctx->prefix, SETTINGS_SEPARATOR);
-                       settings_export(ctx, def->list_info, children[i]);
+                       settings_export(ctx, def->list_info, children[i],
+                                       change_children[i]);
 
                        str_truncate(ctx->prefix, prefix_len);
                }
@@ -219,7 +232,7 @@ static void settings_export(struct settings_export_context *ctx,
 }
 
 void config_request_handle(const struct config_filter *filter,
-                          const char *module, enum config_dump_flags flags,
+                          const char *module, enum config_dump_scope scope,
                           config_request_callback_t *callback, void *context)
 {
        const struct config_setting_parser_list *l;
@@ -229,7 +242,7 @@ void config_request_handle(const struct config_filter *filter,
        ctx.pool = pool_alloconly_create("config request", 10240);
        ctx.callback = callback;
        ctx.context = context;
-       ctx.export_defaults = (flags & CONFIG_DUMP_FLAG_DEFAULTS) != 0;
+       ctx.scope = scope;
        ctx.value = t_str_new(256);
        ctx.prefix = t_str_new(64);
        ctx.keys = hash_table_create(default_pool, ctx.pool, 0,
@@ -240,7 +253,8 @@ void config_request_handle(const struct config_filter *filter,
                if (*module == '\0' ||
                    config_setting_parser_is_in_service(l, module)) {
                        settings_export(&ctx, l->root,
-                                       settings_parser_get(l->parser));
+                                       settings_parser_get(l->parser),
+                                       settings_parser_get_changes(l->parser));
                }
        }
        hash_table_destroy(&ctx.keys);
index 6e7a0e62ab8d99f43ec4b8009b3b6b4aaf79b783..b2b4b854f750fd0940366bd0f94a7002ae7175ad 100644 (file)
@@ -3,15 +3,20 @@
 
 #include "config-filter.h"
 
-enum config_dump_flags {
-       CONFIG_DUMP_FLAG_DEFAULTS       = 0x01
+enum config_dump_scope {
+       /* Dump all settings */
+       CONFIG_DUMP_SCOPE_ALL,
+       /* Dump all that have explicitly been set */
+       CONFIG_DUMP_SCOPE_SET,
+       /* Dump only settings that differ from defaults */
+       CONFIG_DUMP_SCOPE_CHANGED
 };
 
 typedef void config_request_callback_t(const char *key, const char *value,
                                       bool list, void *context);
 
 void config_request_handle(const struct config_filter *filter,
-                          const char *module, enum config_dump_flags flags,
+                          const char *module, enum config_dump_scope scope,
                           config_request_callback_t *callback, void *context);
 
 #endif
index 8afc7b476097f8b14131c6dd4adc81a95dfb16c8..94ed834f4a65537bb7b6d7be15f0599a54648c06 100644 (file)
@@ -64,7 +64,7 @@ static unsigned int prefix_stack_pop(ARRAY_TYPE(uint) *stack)
 static void config_connection_request_human(struct ostream *output,
                                            const struct config_filter *filter,
                                            const char *module,
-                                           enum config_dump_flags flags)
+                                           enum config_dump_scope scope)
 {
        static const char *ident_str = "               ";
        ARRAY_TYPE(const_string) prefixes_arr;
@@ -77,7 +77,7 @@ static void config_connection_request_human(struct ostream *output,
 
        ctx.pool = pool_alloconly_create("config human strings", 10240);
        i_array_init(&ctx.strings, 256);
-       config_request_handle(filter, module, flags,
+       config_request_handle(filter, module, scope,
                              config_request_get_strings, &ctx);
 
        array_sort(&ctx.strings, config_string_cmp);
@@ -159,13 +159,13 @@ static void config_connection_request_human(struct ostream *output,
 
 static void config_dump_human(const struct config_filter *filter,
                              const char *module,
-                             enum config_dump_flags flags)
+                             enum config_dump_scope scope)
 {
        struct ostream *output;
 
        output = o_stream_create_fd(STDOUT_FILENO, 0, FALSE);
        o_stream_cork(output);
-       config_connection_request_human(output, filter, module, flags);
+       config_connection_request_human(output, filter, module, scope);
        o_stream_uncork(output);
 }
 
@@ -202,7 +202,7 @@ static const char *get_mail_location(void)
 
 int main(int argc, char *argv[])
 {
-       enum config_dump_flags flags = CONFIG_DUMP_FLAG_DEFAULTS;
+       enum config_dump_scope scope = CONFIG_DUMP_SCOPE_ALL;
        const char *getopt_str, *config_path, *module = "";
        struct config_filter filter;
        const char *error;
@@ -214,7 +214,8 @@ int main(int argc, char *argv[])
                                             MASTER_SERVICE_FLAG_STANDALONE,
                                             argc, argv);
        i_set_failure_prefix("doveconf: ");
-       getopt_str = t_strconcat("am:np:e", master_service_getopt_string(), NULL);
+       getopt_str = t_strconcat("am:nNp:e",
+                                master_service_getopt_string(), NULL);
        while ((c = getopt(argc, argv, getopt_str)) > 0) {
                if (c == 'e')
                        break;
@@ -225,7 +226,10 @@ int main(int argc, char *argv[])
                        module = optarg;
                        break;
                case 'n':
-                       flags &= ~CONFIG_DUMP_FLAG_DEFAULTS;
+                       scope = CONFIG_DUMP_SCOPE_CHANGED;
+                       break;
+               case 'N':
+                       scope = CONFIG_DUMP_SCOPE_SET;
                        break;
                case 'p':
                        filter.service = optarg;
@@ -261,7 +265,7 @@ int main(int argc, char *argv[])
                if (*info != '\0')
                        printf("# %s\n", info);
                fflush(stdout);
-               config_dump_human(&filter, module, flags);
+               config_dump_human(&filter, module, scope);
        } else {
                env_put("DOVECONF_ENV=1");
                config_request_handle(&filter, module, 0,