dovecot-2.0: config: If master module requests configuration, re...
dovecot at dovecot.org
dovecot at dovecot.org
Sat Aug 15 01:14:57 EEST 2009
details: http://hg.dovecot.org/dovecot-2.0/rev/d7ccdbb58a03
changeset: 9793:d7ccdbb58a03
user: Timo Sirainen <tss at iki.fi>
date: Fri Aug 14 18:13:35 2009 -0400
description:
config: If master module requests configuration, reread it before replying.
If new configuration is invalid, send an ERROR reply back.
diffstat:
9 files changed, 106 insertions(+), 47 deletions(-)
src/config/all-settings.h | 8 ---
src/config/config-connection.c | 25 ++++++++---
src/config/config-filter.c | 1
src/config/config-filter.h | 1
src/config/config-parser.c | 90 +++++++++++++++++++++++++++-------------
src/config/config-parser.h | 12 ++++-
src/config/doveconf.c | 4 +
src/config/main.c | 6 ++
src/config/settings-get.pl | 6 +-
diffs (truncated from 383 to 300 lines):
diff -r 0287c38ba6bf -r d7ccdbb58a03 src/config/all-settings.h
--- a/src/config/all-settings.h Fri Aug 14 17:36:27 2009 -0400
+++ b/src/config/all-settings.h Fri Aug 14 18:13:35 2009 -0400
@@ -1,14 +1,10 @@
#ifndef ALL_SETTINGS_H
#define ALL_SETTINGS_H
-struct config_setting_parser_list {
+struct all_settings_root {
const char *module_name;
struct setting_parser_info *root;
- struct setting_parser_context *parser;
- void *settings;
};
-ARRAY_DEFINE_TYPE(config_setting_parsers, struct config_setting_parser_list *);
-
-extern struct config_setting_parser_list config_setting_parsers[];
+extern const struct all_settings_root all_roots[];
#endif
diff -r 0287c38ba6bf -r d7ccdbb58a03 src/config/config-connection.c
--- a/src/config/config-connection.c Fri Aug 14 17:36:27 2009 -0400
+++ b/src/config/config-connection.c Fri Aug 14 18:13:35 2009 -0400
@@ -7,6 +7,7 @@
#include "settings-parser.h"
#include "master-service.h"
#include "config-request.h"
+#include "config-parser.h"
#include "config-connection.h"
#include <stdlib.h>
@@ -61,11 +62,11 @@ config_request_output(const char *key, c
o_stream_send_str(output, "\n");
}
-static void config_connection_request(struct config_connection *conn,
- const char *const *args)
+static int config_connection_request(struct config_connection *conn,
+ const char *const *args)
{
struct config_filter filter;
- const char *module = "";
+ const char *path, *error, *module = "";
/* [<args>] */
memset(&filter, 0, sizeof(filter));
@@ -89,11 +90,23 @@ static void config_connection_request(st
}
}
+ if (strcmp(module, "master") == 0) {
+ /* master reads configuration only when reloading settings */
+ path = master_service_get_config_path(master_service);
+ if (config_parse_file(path, TRUE, &error) < 0) {
+ o_stream_send_str(conn->output,
+ t_strconcat("ERROR ", error, "\n", NULL));
+ config_connection_destroy(conn);
+ return -1;
+ }
+ }
+
o_stream_cork(conn->output);
config_request_handle(&filter, module, 0, config_request_output,
conn->output);
o_stream_send_str(conn->output, "\n");
o_stream_uncork(conn->output);
+ return 0;
}
static void config_connection_input(void *context)
@@ -130,8 +143,10 @@ static void config_connection_input(void
while ((args = config_connection_next_line(conn)) != NULL) {
if (args[0] == NULL)
continue;
- if (strcmp(args[0], "REQ") == 0)
- config_connection_request(conn, args + 1);
+ if (strcmp(args[0], "REQ") == 0) {
+ if (config_connection_request(conn, args + 1) < 0)
+ break;
+ }
}
}
diff -r 0287c38ba6bf -r d7ccdbb58a03 src/config/config-filter.c
--- a/src/config/config-filter.c Fri Aug 14 17:36:27 2009 -0400
+++ b/src/config/config-filter.c Fri Aug 14 18:13:35 2009 -0400
@@ -2,6 +2,7 @@
#include "lib.h"
#include "array.h"
+#include "config-parser.h"
#include "config-filter.h"
struct config_filter_context {
diff -r 0287c38ba6bf -r d7ccdbb58a03 src/config/config-filter.h
--- a/src/config/config-filter.h Fri Aug 14 17:36:27 2009 -0400
+++ b/src/config/config-filter.h Fri Aug 14 18:13:35 2009 -0400
@@ -2,7 +2,6 @@
#define CONFIG_FILTER_H
#include "network.h"
-#include "all-settings.h"
struct config_filter {
const char *service;
diff -r 0287c38ba6bf -r d7ccdbb58a03 src/config/config-parser.c
--- a/src/config/config-parser.c Fri Aug 14 17:36:27 2009 -0400
+++ b/src/config/config-parser.c Fri Aug 14 18:13:35 2009 -0400
@@ -7,6 +7,7 @@
#include "strescape.h"
#include "istream.h"
#include "settings-parser.h"
+#include "all-settings.h"
#include "config-filter.h"
#include "config-parser.h"
@@ -43,12 +44,14 @@ struct parser_context {
ARRAY_DEFINE(all_parsers, struct config_filter_parser_list *);
/* parsers matching cur_filter */
ARRAY_TYPE(config_setting_parsers) cur_parsers;
+ struct config_setting_parser_list *root_parsers;
struct config_filter_stack *cur_filter;
struct input_stack *cur_input;
struct config_filter_context *filter;
};
+struct config_setting_parser_list *config_setting_parsers;
struct config_filter_context *config_filter;
static const char *info_type_name_find(const struct setting_parser_info *info)
@@ -171,7 +174,7 @@ config_add_new_parser(struct parser_cont
cur_parsers = array_get(&ctx->cur_parsers, &count);
if (count == 0) {
/* first one */
- parser->parser_list = config_setting_parsers;
+ parser->parser_list = ctx->root_parsers;
} else {
/* duplicate the first settings list */
parser->parser_list =
@@ -223,30 +226,38 @@ config_update_cur_parsers(struct parser_
return array_idx(&ctx->cur_parsers, 0);
}
-static void
+static int
config_filter_parser_list_check(struct parser_context *ctx,
- struct config_filter_parser_list *parser)
+ struct config_filter_parser_list *parser,
+ const char **error_r)
{
struct config_setting_parser_list *l = parser->parser_list;
const char *errormsg;
for (; l->module_name != NULL; l++) {
if (!settings_parser_check(l->parser, ctx->pool, &errormsg)) {
- i_fatal("Error in configuration file %s: %s",
+ *error_r = t_strdup_printf(
+ "Error in configuration file %s: %s",
ctx->path, errormsg);
- }
- }
-}
-
-static void
-config_all_parsers_check(struct parser_context *ctx)
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int
+config_all_parsers_check(struct parser_context *ctx, const char **error_r)
{
struct config_filter_parser_list *const *parsers;
unsigned int i, count;
parsers = array_get(&ctx->all_parsers, &count);
- for (i = 0; i < count; i++)
- config_filter_parser_list_check(ctx, parsers[i]);
+ for (i = 0; i < count; i++) {
+ if (config_filter_parser_list_check(ctx, parsers[i],
+ error_r) < 0)
+ return -1;
+ }
+ return 0;
}
static void
@@ -345,37 +356,45 @@ settings_include(struct parser_context *
#endif
}
-void config_parse_file(const char *path, bool expand_files)
+int config_parse_file(const char *path, bool expand_files,
+ const char **error_r)
{
enum settings_parser_flags parser_flags =
SETTINGS_PARSER_FLAG_IGNORE_UNKNOWN_KEYS;
struct input_stack root;
ARRAY_TYPE(const_string) auth_defaults;
- struct config_setting_parser_list *l, *const *parsers;
+ struct config_setting_parser_list *const *parsers;
struct parser_context ctx;
unsigned int pathlen = 0;
- unsigned int counter = 0, auth_counter = 0, cur_counter;
+ unsigned int i, count, counter = 0, auth_counter = 0, cur_counter;
const char *errormsg, *name;
char *line, *key, *p;
- int fd, ret;
+ int fd, ret = 0;
string_t *str, *full_line;
size_t len;
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0) {
+ *error_r = t_strdup_printf("open(%s) failed: %m", path);
+ return -1;
+ }
memset(&ctx, 0, sizeof(ctx));
ctx.pool = pool_alloconly_create("config file parser", 1024*64);
ctx.path = path;
- fd = open(path, O_RDONLY);
- if (fd < 0)
- i_fatal("open(%s) failed: %m", path);
+ for (count = 0; all_roots[count].module_name != NULL; count++) ;
+ ctx.root_parsers =
+ p_new(ctx.pool, struct config_setting_parser_list, count+1);
+ for (i = 0; i < count; i++) {
+ ctx.root_parsers[i].module_name = all_roots[i].module_name;
+ ctx.root_parsers[i].root = all_roots[i].root;
+ ctx.root_parsers[i].parser =
+ settings_parser_init(ctx.pool, all_roots[i].root,
+ parser_flags);
+ }
t_array_init(&auth_defaults, 32);
-
- for (l = config_setting_parsers; l->module_name != NULL; l++) {
- i_assert(l->parser == NULL);
- l->parser = settings_parser_init(ctx.pool, l->root, parser_flags);
- }
-
t_array_init(&ctx.cur_parsers, 128);
p_array_init(&ctx.all_parsers, ctx.pool, 128);
ctx.cur_filter = p_new(ctx.pool, struct config_filter_stack, 1);
@@ -454,7 +473,6 @@ prevfile:
while (IS_WHITE(*line)) line++;
}
- ret = 1;
if (strcmp(key, "!include_try") == 0 ||
strcmp(key, "!include") == 0) {
if (settings_include(&ctx, fix_relative_path(line, ctx.cur_input),
@@ -600,9 +618,11 @@ prevfile:
}
if (errormsg != NULL) {
- i_fatal("Error in configuration file %s line %d: %s",
+ *error_r = t_strdup_printf(
+ "Error in configuration file %s line %d: %s",
ctx.cur_input->path, ctx.cur_input->linenum,
errormsg);
+ ret = -1;
break;
}
str_truncate(full_line, 0);
@@ -613,9 +633,21 @@ prevfile:
if (line == NULL && ctx.cur_input != NULL)
goto prevfile;
- config_all_parsers_check(&ctx);
+ if (ret == 0) {
+ if (config_all_parsers_check(&ctx, error_r) < 0)
+ ret = -1;
+ }
+ if (ret < 0) {
+ pool_unref(&ctx.pool);
+ return -1;
+ }
+
+ if (config_filter != NULL)
+ config_filter_deinit(&config_filter);
+ config_setting_parsers = ctx.root_parsers;
(void)array_append_space(&ctx.all_parsers);
config_filter = config_filter_init(ctx.pool);
config_filter_add_all(config_filter, array_idx(&ctx.all_parsers, 0));
-}
+ return 0;
+}
diff -r 0287c38ba6bf -r d7ccdbb58a03 src/config/config-parser.h
--- a/src/config/config-parser.h Fri Aug 14 17:36:27 2009 -0400
+++ b/src/config/config-parser.h Fri Aug 14 18:13:35 2009 -0400
@@ -1,8 +1,18 @@
#ifndef CONFIG_PARSER_H
#define CONFIG_PARSER_H
More information about the dovecot-cvs
mailing list