dovecot-2.0: doveconf -n/-a: Don't dump default service settings.
dovecot at dovecot.org
dovecot at dovecot.org
Tue Oct 27 03:44:18 EET 2009
details: http://hg.dovecot.org/dovecot-2.0/rev/d647b795da6d
changeset: 10196:d647b795da6d
user: Timo Sirainen <tss at iki.fi>
date: Mon Oct 26 21:44:10 2009 -0400
description:
doveconf -n/-a: Don't dump default service settings.
This code is just getting uglier and uglier..
diffstat:
4 files changed, 143 insertions(+), 44 deletions(-)
src/config/config-connection.c | 2
src/config/config-request.c | 37 +++++++---
src/config/config-request.h | 8 ++
src/config/doveconf.c | 140 +++++++++++++++++++++++++++++++---------
diffs (truncated from 364 to 300 lines):
diff -r c94ca1acd623 -r d647b795da6d src/config/config-connection.c
--- a/src/config/config-connection.c Mon Oct 26 20:49:10 2009 -0400
+++ b/src/config/config-connection.c Mon Oct 26 21:44:10 2009 -0400
@@ -46,7 +46,7 @@ config_connection_next_line(struct confi
static void
config_request_output(const char *key, const char *value,
- bool list ATTR_UNUSED, void *context)
+ enum config_key_type type ATTR_UNUSED, void *context)
{
struct ostream *output = context;
const char *p;
diff -r c94ca1acd623 -r d647b795da6d src/config/config-request.c
--- a/src/config/config-request.c Mon Oct 26 20:49:10 2009 -0400
+++ b/src/config/config-request.c Mon Oct 26 21:44:10 2009 -0400
@@ -71,9 +71,11 @@ config_module_parser_is_in_service(const
return FALSE;
}
-static void settings_export(struct settings_export_context *ctx,
- const struct setting_parser_info *info,
- const void *set, const void *change_set)
+static void
+settings_export(struct settings_export_context *ctx,
+ const struct setting_parser_info *info,
+ bool parent_unique_deflist,
+ const void *set, const void *change_set)
{
const struct setting_define *def;
const void *value, *default_value, *change_value;
@@ -104,6 +106,10 @@ static void settings_export(struct setti
hasn't changed, it's the default. even if
info->defaults has a different value. */
default_value = value;
+ } else if (parent_unique_deflist) {
+ /* value is set explicitly, but we don't know the
+ default here. assume it's not the default. */
+ dump_default = TRUE;
}
dump = FALSE;
@@ -196,7 +202,7 @@ static void settings_export(struct setti
break;
}
hash_table_insert(ctx->keys, key, key);
- ctx->callback(key, "0", TRUE, ctx->context);
+ ctx->callback(key, "0", CONFIG_KEY_LIST, ctx->context);
strings = array_get(val, &count);
i_assert(count % 2 == 0);
@@ -207,8 +213,8 @@ static void settings_export(struct setti
SETTINGS_SEPARATOR,
SETTINGS_SEPARATOR,
strings[i]);
- ctx->callback(str, strings[i+1], FALSE,
- ctx->context);
+ ctx->callback(str, strings[i+1],
+ CONFIG_KEY_NORMAL, ctx->context);
}
count = 0;
break;
@@ -218,8 +224,16 @@ static void settings_export(struct setti
key = p_strconcat(ctx->pool, str_c(ctx->prefix),
def->key, NULL);
if (hash_table_lookup(ctx->keys, key) == NULL) {
- ctx->callback(key, str_c(ctx->value),
- SETTING_TYPE_IS_DEFLIST(def->type),
+ enum config_key_type type;
+
+ if (def->offset == info->type_offset &&
+ parent_unique_deflist)
+ type = CONFIG_KEY_UNIQUE_KEY;
+ else if (SETTING_TYPE_IS_DEFLIST(def->type))
+ type = CONFIG_KEY_LIST;
+ else
+ type = CONFIG_KEY_NORMAL;
+ ctx->callback(key, str_c(ctx->value), type,
ctx->context);
hash_table_insert(ctx->keys, key, key);
}
@@ -231,8 +245,9 @@ static void settings_export(struct setti
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],
- change_children[i]);
+ settings_export(ctx, def->list_info,
+ def->type == SET_DEFLIST_UNIQUE,
+ children[i], change_children[i]);
str_truncate(ctx->prefix, prefix_len);
}
@@ -274,7 +289,7 @@ int config_request_handle(const struct c
!config_module_parser_is_in_service(parser, module))
continue;
- settings_export(&ctx, parser->root,
+ settings_export(&ctx, parser->root, FALSE,
settings_parser_get(parser->parser),
settings_parser_get_changes(parser->parser));
diff -r c94ca1acd623 -r d647b795da6d src/config/config-request.h
--- a/src/config/config-request.h Mon Oct 26 20:49:10 2009 -0400
+++ b/src/config/config-request.h Mon Oct 26 21:44:10 2009 -0400
@@ -12,8 +12,14 @@ enum config_dump_scope {
CONFIG_DUMP_SCOPE_CHANGED
};
+enum config_key_type {
+ CONFIG_KEY_NORMAL,
+ CONFIG_KEY_LIST,
+ CONFIG_KEY_UNIQUE_KEY
+};
+
typedef void config_request_callback_t(const char *key, const char *value,
- bool list, void *context);
+ enum config_key_type type, void *context);
int config_request_handle(const struct config_filter *filter,
const char *module, enum config_dump_scope scope,
diff -r c94ca1acd623 -r d647b795da6d src/config/doveconf.c
--- a/src/config/doveconf.c Mon Oct 26 20:49:10 2009 -0400
+++ b/src/config/doveconf.c Mon Oct 26 21:44:10 2009 -0400
@@ -4,6 +4,7 @@
#include "array.h"
#include "env-util.h"
#include "ostream.h"
+#include "str.h"
#include "settings-parser.h"
#include "master-service.h"
#include "all-settings.h"
@@ -15,19 +16,42 @@
#include <stdio.h>
#include <unistd.h>
+struct prefix_stack {
+ unsigned int prefix_idx;
+ unsigned int str_pos;
+};
+ARRAY_DEFINE_TYPE(prefix_stack, struct prefix_stack);
+
struct config_request_get_string_ctx {
pool_t pool;
ARRAY_TYPE(const_string) strings;
};
+#define LIST_KEY_PREFIX "\001"
+#define UNIQUE_KEY_SUFFIX "\xff"
+
static void
config_request_get_strings(const char *key, const char *value,
- bool list, void *context)
+ enum config_key_type type, void *context)
{
struct config_request_get_string_ctx *ctx = context;
-
- value = p_strdup_printf(ctx->pool, list ? "-%s=%s" : "%s=%s",
- key, value);
+ const char *p;
+
+ switch (type) {
+ case CONFIG_KEY_NORMAL:
+ value = p_strdup_printf(ctx->pool, "%s=%s", key, value);
+ break;
+ case CONFIG_KEY_LIST:
+ value = p_strdup_printf(ctx->pool, LIST_KEY_PREFIX"%s=%s",
+ key, value);
+ break;
+ case CONFIG_KEY_UNIQUE_KEY:
+ p = strrchr(key, '/');
+ i_assert(p != NULL);
+ value = p_strdup_printf(ctx->pool, "%s/"UNIQUE_KEY_SUFFIX"%s=%s",
+ t_strdup_until(key, p), p + 1, value);
+ break;
+ }
array_append(&ctx->strings, &value, 1);
}
@@ -46,18 +70,34 @@ static int config_string_cmp(const char
return -1;
if (s2[i] == '=')
return 1;
+
return s1[i] - s2[i];
}
-static unsigned int prefix_stack_pop(ARRAY_TYPE(uint) *stack)
-{
- const unsigned int *indexes;
- unsigned int idx, count;
-
- indexes = array_get(stack, &count);
- idx = count <= 1 ? -1U : indexes[count-2];
+static struct prefix_stack prefix_stack_pop(ARRAY_TYPE(prefix_stack) *stack)
+{
+ const struct prefix_stack *s;
+ struct prefix_stack sc;
+ unsigned int count;
+
+ s = array_get(stack, &count);
+ i_assert(count > 0);
+ if (count == 1) {
+ sc.prefix_idx = -1U;
+ } else {
+ sc.prefix_idx = s[count-2].prefix_idx;
+ }
+ sc.str_pos = s[count-1].str_pos;
array_delete(stack, count-1, 1);
- return idx;
+ return sc;
+}
+
+static void prefix_stack_reset_str(ARRAY_TYPE(prefix_stack) *stack)
+{
+ struct prefix_stack *s;
+
+ array_foreach_modifiable(stack, s)
+ s->str_pos = -1U;
}
static void config_connection_request_human(struct ostream *output,
@@ -65,14 +105,17 @@ static void config_connection_request_hu
const char *module,
enum config_dump_scope scope)
{
- static const char *ident_str = " ";
+ static const char *indent_str = " ";
ARRAY_TYPE(const_string) prefixes_arr;
- ARRAY_TYPE(uint) prefix_idx_stack;
+ ARRAY_TYPE(prefix_stack) prefix_stack;
+ struct prefix_stack prefix;
struct config_request_get_string_ctx ctx;
const char *const *strings, *const *args, *p, *str, *const *prefixes;
const char *key, *key2, *value;
unsigned int i, j, count, len, prefix_count, skip_len;
unsigned int indent = 0, prefix_idx = -1U;
+ string_t *list_prefix;
+ bool unique_key;
ctx.pool = pool_alloconly_create("config human strings", 10240);
i_array_init(&ctx.strings, 256);
@@ -84,7 +127,7 @@ static void config_connection_request_hu
strings = array_get(&ctx.strings, &count);
p_array_init(&prefixes_arr, ctx.pool, 32);
- for (i = 0; i < count && strings[i][0] == '-'; i++) T_BEGIN {
+ for (i = 0; i < count && strings[i][0] == LIST_KEY_PREFIX[0]; i++) T_BEGIN {
p = strchr(strings[i], '=');
i_assert(p != NULL);
for (args = t_strsplit(p + 1, " "); *args != NULL; args++) {
@@ -96,22 +139,36 @@ static void config_connection_request_hu
} T_END;
prefixes = array_get(&prefixes_arr, &prefix_count);
- p_array_init(&prefix_idx_stack, ctx.pool, 8);
+ list_prefix = str_new(ctx.pool, 128);
+ p_array_init(&prefix_stack, ctx.pool, 8);
for (; i < count; i++) T_BEGIN {
value = strchr(strings[i], '=');
i_assert(value != NULL);
- key = t_strdup_until(strings[i], value);
- value++;
+
+ key = t_strdup_until(strings[i], value++);
+ unique_key = FALSE;
+
+ p = strrchr(key, '/');
+ if (p != NULL && p[1] == UNIQUE_KEY_SUFFIX[0]) {
+ key = t_strconcat(t_strdup_until(key, p + 1),
+ p + 2, NULL);
+ unique_key = TRUE;
+ }
again:
j = 0;
while (prefix_idx != -1U) {
len = strlen(prefixes[prefix_idx]);
if (strncmp(prefixes[prefix_idx], key, len) != 0) {
- prefix_idx = prefix_stack_pop(&prefix_idx_stack);
+ prefix = prefix_stack_pop(&prefix_stack);
indent--;
- o_stream_send(output, ident_str, indent*2);
- o_stream_send_str(output, "}\n");
+ if (prefix.str_pos != -1U)
+ str_truncate(list_prefix, prefix.str_pos);
+ else {
+ o_stream_send(output, indent_str, indent*2);
+ o_stream_send_str(output, "}\n");
+ }
+ prefix_idx = prefix.prefix_idx;
} else {
/* keep the prefix */
j = prefix_idx + 1;
@@ -123,31 +180,52 @@ static void config_connection_request_hu
if (strncmp(prefixes[j], key, len) == 0) {
key2 = key + (prefix_idx == -1U ? 0 :
strlen(prefixes[prefix_idx]));
- o_stream_send(output, ident_str, indent*2);
- o_stream_send_str(output, t_strcut(key2, '/'));
- o_stream_send_str(output, " {\n");
More information about the dovecot-cvs
mailing list