dovecot-2.0: doveconf: Dump config to stdout even when there are...
dovecot at dovecot.org
dovecot at dovecot.org
Fri Jan 22 18:14:37 EET 2010
details: http://hg.dovecot.org/dovecot-2.0/rev/b01b9eff1f15
changeset: 10569: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