dovecot-2.0-sslstream: doveconf -n/-a: Don't dump default servic...

dovecot at dovecot.org dovecot at dovecot.org
Sat Feb 13 02:55:43 EET 2010


details:   http://hg.dovecot.org/dovecot-2.0-sslstream/rev/d647b795da6d
changeset: 10197: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