dovecot-2.0-sslstream: doveconf: Dump config to stdout even when...

dovecot at dovecot.org dovecot at dovecot.org
Sat Feb 13 02:57:29 EET 2010


details:   http://hg.dovecot.org/dovecot-2.0-sslstream/rev/b01b9eff1f15
changeset: 10570:b01b9eff1f15
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Jan 22 18:14:31 2010 +0200
description:
doveconf: Dump config to stdout even when there are errors, just show them afterwards.

diffstat:

4 files changed, 61 insertions(+), 29 deletions(-)
src/config/config-parser.c  |   14 +++-------
src/config/config-request.c |   11 ++++++--
src/config/config-request.h |    8 ++++--
src/config/doveconf.c       |   57 +++++++++++++++++++++++++++++++------------

diffs (226 lines):

diff -r f1a0f9a66164 -r b01b9eff1f15 src/config/config-parser.c
--- a/src/config/config-parser.c	Fri Jan 22 17:46:54 2010 +0200
+++ b/src/config/config-parser.c	Fri Jan 22 18:14:31 2010 +0200
@@ -589,22 +589,22 @@ static int config_parse_finish(struct pa
 {
 	struct config_filter_context *new_filter;
 	const char *error;
+	int ret;
 
 	new_filter = config_filter_init(ctx->pool);
 	(void)array_append_space(&ctx->all_parsers);
 	config_filter_add_all(new_filter, array_idx(&ctx->all_parsers, 0));
 
-	if (config_all_parsers_check(ctx, new_filter, &error) < 0) {
+	if ((ret = config_all_parsers_check(ctx, new_filter, &error)) < 0) {
 		*error_r = t_strdup_printf("Error in configuration file %s: %s",
 					   ctx->path, error);
-		return -1;
 	}
 
 	if (config_filter != NULL)
 		config_filter_deinit(&config_filter);
 	config_module_parsers = ctx->root_parsers;
 	config_filter = new_filter;
-	return 0;
+	return ret;
 }
 
 int config_parse_file(const char *path, bool expand_files,
@@ -735,7 +735,7 @@ prevfile:
 				"Error in configuration file %s line %d: %s",
 				ctx.cur_input->path, ctx.cur_input->linenum,
 				errormsg);
-			ret = -1;
+			ret = -2;
 			break;
 		}
 		str_truncate(full_line, 0);
@@ -748,11 +748,7 @@ prevfile:
 
 	if (ret == 0)
 		ret = config_parse_finish(&ctx, error_r);
-	if (ret < 0) {
-		pool_unref(&ctx.pool);
-		return -1;
-	}
-	return 1;
+	return ret;
 }
 
 void config_parse_load_modules(void)
diff -r f1a0f9a66164 -r b01b9eff1f15 src/config/config-request.c
--- a/src/config/config-request.c	Fri Jan 22 17:46:54 2010 +0200
+++ b/src/config/config-request.c	Fri Jan 22 18:14:31 2010 +0200
@@ -325,9 +325,14 @@ int config_request_handle(const struct c
 			settings_parse_var_skip(parser->parser);
 			if (!settings_parser_check(parser->parser, ctx.pool,
 						   &error)) {
-				i_error("%s", error);
-				ret = -1;
-				break;
+				if ((flags & CONFIG_DUMP_FLAG_CALLBACK_ERRORS) != 0) {
+					callback(NULL, error, CONFIG_KEY_ERROR,
+						 context);
+				} else {
+					i_error("%s", error);
+					ret = -1;
+					break;
+				}
 			}
 		}
 	}
diff -r f1a0f9a66164 -r b01b9eff1f15 src/config/config-request.h
--- a/src/config/config-request.h	Fri Jan 22 17:46:54 2010 +0200
+++ b/src/config/config-request.h	Fri Jan 22 18:14:31 2010 +0200
@@ -14,13 +14,17 @@ enum config_dump_scope {
 
 enum config_dump_flags {
 	CONFIG_DUMP_FLAG_CHECK_SETTINGS		= 0x01,
-	CONFIG_DUMP_FLAG_HIDE_LIST_DEFAULTS	= 0x02
+	CONFIG_DUMP_FLAG_HIDE_LIST_DEFAULTS	= 0x02,
+	/* Errors are reported using callback and they don't stop handling */
+	CONFIG_DUMP_FLAG_CALLBACK_ERRORS	= 0x04
 };
 
 enum config_key_type {
 	CONFIG_KEY_NORMAL,
 	CONFIG_KEY_LIST,
-	CONFIG_KEY_UNIQUE_KEY
+	CONFIG_KEY_UNIQUE_KEY,
+	/* error message is in value */
+	CONFIG_KEY_ERROR
 };
 
 typedef void config_request_callback_t(const char *key, const char *value,
diff -r f1a0f9a66164 -r b01b9eff1f15 src/config/doveconf.c
--- a/src/config/doveconf.c	Fri Jan 22 17:46:54 2010 +0200
+++ b/src/config/doveconf.c	Fri Jan 22 18:14:31 2010 +0200
@@ -25,6 +25,7 @@ struct config_request_get_string_ctx {
 struct config_request_get_string_ctx {
 	pool_t pool;
 	ARRAY_TYPE(const_string) strings;
+	ARRAY_TYPE(const_string) errors;
 };
 
 #define LIST_KEY_PREFIX "\001"
@@ -51,6 +52,10 @@ config_request_get_strings(const char *k
 		value = p_strdup_printf(ctx->pool, "%s/"UNIQUE_KEY_SUFFIX"%s=%s",
 					t_strdup_until(key, p), p + 1, value);
 		break;
+	case CONFIG_KEY_ERROR:
+		value = p_strdup(ctx->pool, value);
+		array_append(&ctx->errors, &value, 1);
+		return;
 	}
 	array_append(&ctx->strings, &value, 1);
 }
@@ -100,10 +105,10 @@ static void prefix_stack_reset_str(ARRAY
 		s->str_pos = -1U;
 }
 
-static void config_connection_request_human(struct ostream *output,
-					    const struct config_filter *filter,
-					    const char *module,
-					    enum config_dump_scope scope)
+static int config_connection_request_human(struct ostream *output,
+					   const struct config_filter *filter,
+					   const char *module,
+					   enum config_dump_scope scope)
 {
 	static const char *indent_str = "               ";
 	ARRAY_TYPE(const_string) prefixes_arr;
@@ -116,14 +121,17 @@ static void config_connection_request_hu
 	unsigned int indent = 0, prefix_idx = -1U;
 	string_t *list_prefix;
 	bool unique_key;
+	int ret = 0;
 
 	ctx.pool = pool_alloconly_create("config human strings", 10240);
 	i_array_init(&ctx.strings, 256);
+	i_array_init(&ctx.errors, 256);
 	if (config_request_handle(filter, module, scope,
 				  CONFIG_DUMP_FLAG_CHECK_SETTINGS |
-				  CONFIG_DUMP_FLAG_HIDE_LIST_DEFAULTS,
+				  CONFIG_DUMP_FLAG_HIDE_LIST_DEFAULTS |
+				  CONFIG_DUMP_FLAG_CALLBACK_ERRORS,
 				  config_request_get_strings, &ctx) < 0)
-		return;
+		return -1;
 
 	array_sort(&ctx.strings, config_string_cmp);
 	strings = array_get(&ctx.strings, &count);
@@ -231,21 +239,32 @@ static void config_connection_request_hu
 		o_stream_send_str(output, "}\n");
 	}
 
+	/* flush output before writing errors */
+	o_stream_uncork(output);
+	array_foreach(&ctx.errors, strings) {
+		i_error("%s", *strings);
+		ret = -1;
+	}
+
 	array_free(&ctx.strings);
+	array_free(&ctx.errors);
 	pool_unref(&ctx.pool);
-}
-
-static void config_dump_human(const struct config_filter *filter,
-			      const char *module,
-			      enum config_dump_scope scope)
+	return ret;
+}
+
+static int config_dump_human(const struct config_filter *filter,
+			     const char *module,
+			     enum config_dump_scope scope)
 {
 	struct ostream *output;
+	int ret;
 
 	output = o_stream_create_fd(STDOUT_FILENO, 0, FALSE);
 	o_stream_cork(output);
-	config_connection_request_human(output, filter, module, scope);
+	ret = config_connection_request_human(output, filter, module, scope);
 	o_stream_uncork(output);
 	o_stream_unref(&output);
+	return ret;
 }
 
 static void config_request_putenv(const char *key, const char *value,
@@ -309,7 +328,7 @@ int main(int argc, char *argv[])
 	struct config_filter filter;
 	const char *error;
 	char **exec_args = NULL;
-	int c, ret;
+	int c, ret, ret2;
 
 	memset(&filter, 0, sizeof(filter));
 	master_service = master_service_init("config",
@@ -358,7 +377,8 @@ int main(int argc, char *argv[])
 		i_fatal("%s (copy example configs from "EXAMPLE_CONFIG_DIR"/)",
 			error);
 	}
-	if (ret <= 0)
+
+	if (ret <= 0 && (exec_args != NULL || ret == -2))
 		i_fatal("%s", error);
 
 	if (exec_args == NULL) {
@@ -368,7 +388,14 @@ int main(int argc, char *argv[])
 		if (*info != '\0')
 			printf("# %s\n", info);
 		fflush(stdout);
-		config_dump_human(&filter, module, scope);
+		ret2 = config_dump_human(&filter, module, scope);
+
+		if (ret < 0) {
+			/* delayed error */
+			i_fatal("%s", error);
+		}
+		if (ret2 < 0)
+			i_fatal("Errors in configuration");
 	} else {
 		env_put("DOVECONF_ENV=1");
 		if (config_request_handle(&filter, module,


More information about the dovecot-cvs mailing list