Mercurial > dovecot > core-2.2
changeset 9227:f155917f1615 HEAD
Split doveconf and libexec/dovecot/config binaries.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 05 May 2009 15:28:16 -0400 |
parents | 0ca7ed260f1e |
children | e91bca10d5a1 |
files | src/config/Makefile.am src/config/config-connection.c src/config/config-connection.h src/config/config-request.h src/config/doveconf.c src/config/main.c |
diffstat | 6 files changed, 246 insertions(+), 200 deletions(-) [+] |
line wrap: on
line diff
--- a/src/config/Makefile.am Tue May 05 14:55:05 2009 -0400 +++ b/src/config/Makefile.am Tue May 05 15:28:16 2009 -0400 @@ -1,6 +1,7 @@ pkglibexecdir = $(libexecdir)/dovecot bin_PROGRAMS = doveconf +pkglibexec_PROGRAMS = config AM_CPPFLAGS = \ -I$(top_srcdir)/src/lib \ @@ -12,18 +13,31 @@ -DMODULEDIR=\""$(moduledir)"\" \ -DSSLDIR=\""$(ssldir)\"" +config_LDADD = \ + $(LIBDOVECOT) \ + $(MODULE_LIBS) \ + $(RAND_LIBS) +config_DEPENDENCIES = $(LIBDOVECOT) + doveconf_LDADD = \ $(LIBDOVECOT) \ $(MODULE_LIBS) \ $(RAND_LIBS) doveconf_DEPENDENCIES = $(LIBDOVECOT) -doveconf_SOURCES = \ +common = \ all-settings.c \ config-connection.c \ config-parser.c \ - config-request.c \ - main.c + config-request.c + +config_SOURCES = \ + main.c \ + $(common) + +doveconf_SOURCES = \ + doveconf.c \ + $(common) noinst_HEADERS = \ all-settings.h \
--- a/src/config/config-connection.c Tue May 05 14:55:05 2009 -0400 +++ b/src/config/config-connection.c Tue May 05 15:28:16 2009 -0400 @@ -57,149 +57,8 @@ o_stream_send_str(output, "\n"); } -struct config_request_get_string_ctx { - pool_t pool; - ARRAY_TYPE(const_string) strings; -}; - -static void -config_request_get_strings(const char *key, const char *value, - bool list, void *context) -{ - struct config_request_get_string_ctx *ctx = context; - - value = p_strdup_printf(ctx->pool, list ? "-%s=%s" : "%s=%s", - key, value); - array_append(&ctx->strings, &value, 1); -} - -static int config_string_cmp(const void *p1, const void *p2) -{ - const char *s1 = *(const char *const *)p1; - const char *s2 = *(const char *const *)p2; - unsigned int i = 0; - - while (s1[i] == s2[i]) { - if (s1[i] == '\0' || s1[i] == '=') - return 0; - i++; - } - - if (s1[i] == '=') - 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]; - array_delete(stack, count-1, 1); - return idx; -} - -static void config_connection_request_human(struct ostream *output, - const char *service, - enum config_dump_flags flags) -{ - static const char *ident_str = " "; - ARRAY_TYPE(const_string) prefixes_arr; - ARRAY_TYPE(uint) prefix_idx_stack; - struct config_request_get_string_ctx ctx; - const char **strings, *const *args, *p, *str, *const *prefixes; - const char *key, *value; - unsigned int i, j, count, len, prefix_count, skip_len; - unsigned int indent = 0, prefix_idx = -1U; - - ctx.pool = pool_alloconly_create("config human strings", 10240); - i_array_init(&ctx.strings, 256); - config_request_handle(service, flags, config_request_get_strings, &ctx); - - strings = array_get_modifiable(&ctx.strings, &count); - qsort(strings, count, sizeof(*strings), config_string_cmp); - - p_array_init(&prefixes_arr, ctx.pool, 32); - for (i = 0; i < count && strings[i][0] == '-'; i++) T_BEGIN { - p = strchr(strings[i], '='); - i_assert(p != NULL); - for (args = t_strsplit(p + 1, " "); *args != NULL; args++) { - str = p_strdup_printf(ctx.pool, "%s/%s/", - t_strcut(strings[i]+1, '='), - *args); - array_append(&prefixes_arr, &str, 1); - } - } T_END; - prefixes = array_get(&prefixes_arr, &prefix_count); - - p_array_init(&prefix_idx_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++; - - 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); - indent--; - o_stream_send(output, ident_str, indent*2); - o_stream_send_str(output, "}\n"); - } else if (strchr(key + len, '/') == NULL) { - /* keep the prefix */ - j = prefix_count; - break; - } else { - /* subprefix */ - break; - } - } - for (; j < prefix_count; j++) { - len = strlen(prefixes[j]); - if (strncmp(prefixes[j], key, len) == 0 && - strchr(key + len, '/') == NULL) { - key += prefix_idx == -1U ? 0 : - strlen(prefixes[prefix_idx]); - o_stream_send(output, ident_str, indent*2); - o_stream_send_str(output, t_strcut(key, '/')); - o_stream_send_str(output, " {\n"); - indent++; - prefix_idx = j; - array_append(&prefix_idx_stack, &prefix_idx, 1); - break; - } - } - skip_len = prefix_idx == -1U ? 0 : strlen(prefixes[prefix_idx]); - i_assert(strncmp(prefixes[prefix_idx], strings[i], skip_len) == 0); - o_stream_send(output, ident_str, indent*2); - key = strings[i] + skip_len; - value = strchr(key, '='); - o_stream_send(output, key, value-key); - o_stream_send_str(output, " = "); - o_stream_send_str(output, value+1); - o_stream_send(output, "\n", 1); - } T_END; - - while (prefix_idx != -1U) { - prefix_idx = prefix_stack_pop(&prefix_idx_stack); - indent--; - o_stream_send(output, ident_str, indent*2); - o_stream_send_str(output, "}\n"); - } - - array_free(&ctx.strings); - pool_unref(&ctx.pool); -} - static void config_connection_request(struct config_connection *conn, - const char *const *args, - enum config_dump_flags flags) + const char *const *args) { const char *service = ""; @@ -210,13 +69,8 @@ } o_stream_cork(conn->output); - if ((flags & CONFIG_DUMP_FLAG_HUMAN) == 0) { - config_request_handle(service, flags, config_request_output, - conn->output); - o_stream_send_str(conn->output, "\n"); - } else { - config_connection_request_human(conn->output, service, flags); - } + config_request_handle(service, 0, config_request_output, conn->output); + o_stream_send_str(conn->output, "\n"); o_stream_uncork(conn->output); } @@ -255,7 +109,7 @@ if (args[0] == NULL) continue; if (strcmp(args[0], "REQ") == 0) - config_connection_request(conn, args + 1, 0); + config_connection_request(conn, args + 1); } } @@ -284,31 +138,6 @@ i_free(conn); } -void config_connection_dump_request(int fd, const char *service, - enum config_dump_flags flags) -{ - struct config_connection *conn; - const char *args[2] = { service, NULL }; - - conn = config_connection_create(fd); - config_connection_request(conn, args, flags); - config_connection_destroy(conn); -} - -static void config_request_putenv(const char *key, const char *value, - bool list ATTR_UNUSED, - void *context ATTR_UNUSED) -{ - T_BEGIN { - env_put(t_strconcat(t_str_ucase(key), "=", value, NULL)); - } T_END; -} - -void config_connection_putenv(const char *service) -{ - config_request_handle(service, 0, config_request_putenv, NULL); -} - void config_connections_destroy_all(void) { while (config_connections != NULL)
--- a/src/config/config-connection.h Tue May 05 14:55:05 2009 -0400 +++ b/src/config/config-connection.h Tue May 05 15:28:16 2009 -0400 @@ -8,7 +8,6 @@ void config_connection_dump_request(int fd, const char *service, enum config_dump_flags flags); -void config_connection_putenv(const char *service); void config_connections_destroy_all(void);
--- a/src/config/config-request.h Tue May 05 14:55:05 2009 -0400 +++ b/src/config/config-request.h Tue May 05 15:28:16 2009 -0400 @@ -2,8 +2,7 @@ #define CONFIG_REQUEST_H enum config_dump_flags { - CONFIG_DUMP_FLAG_HUMAN = 0x01, - CONFIG_DUMP_FLAG_DEFAULTS = 0x02 + CONFIG_DUMP_FLAG_DEFAULTS = 0x01 }; typedef void config_request_callback_t(const char *key, const char *value,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/config/doveconf.c Tue May 05 15:28:16 2009 -0400 @@ -0,0 +1,223 @@ +/* Copyright (C) 2005-2009 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "array.h" +#include "env-util.h" +#include "master-service.h" +#include "ostream.h" +#include "config-connection.h" +#include "config-parser.h" +#include "config-request.h" + +#include <stdlib.h> +#include <unistd.h> + +struct config_request_get_string_ctx { + pool_t pool; + ARRAY_TYPE(const_string) strings; +}; + +static struct master_service *service; + +static void +config_request_get_strings(const char *key, const char *value, + bool list, void *context) +{ + struct config_request_get_string_ctx *ctx = context; + + value = p_strdup_printf(ctx->pool, list ? "-%s=%s" : "%s=%s", + key, value); + array_append(&ctx->strings, &value, 1); +} + +static int config_string_cmp(const void *p1, const void *p2) +{ + const char *s1 = *(const char *const *)p1; + const char *s2 = *(const char *const *)p2; + unsigned int i = 0; + + while (s1[i] == s2[i]) { + if (s1[i] == '\0' || s1[i] == '=') + return 0; + i++; + } + + if (s1[i] == '=') + 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]; + array_delete(stack, count-1, 1); + return idx; +} + +static void config_connection_request_human(struct ostream *output, + const char *service, + enum config_dump_flags flags) +{ + static const char *ident_str = " "; + ARRAY_TYPE(const_string) prefixes_arr; + ARRAY_TYPE(uint) prefix_idx_stack; + struct config_request_get_string_ctx ctx; + const char **strings, *const *args, *p, *str, *const *prefixes; + const char *key, *value; + unsigned int i, j, count, len, prefix_count, skip_len; + unsigned int indent = 0, prefix_idx = -1U; + + ctx.pool = pool_alloconly_create("config human strings", 10240); + i_array_init(&ctx.strings, 256); + config_request_handle(service, flags, config_request_get_strings, &ctx); + + strings = array_get_modifiable(&ctx.strings, &count); + qsort(strings, count, sizeof(*strings), config_string_cmp); + + p_array_init(&prefixes_arr, ctx.pool, 32); + for (i = 0; i < count && strings[i][0] == '-'; i++) T_BEGIN { + p = strchr(strings[i], '='); + i_assert(p != NULL); + for (args = t_strsplit(p + 1, " "); *args != NULL; args++) { + str = p_strdup_printf(ctx.pool, "%s/%s/", + t_strcut(strings[i]+1, '='), + *args); + array_append(&prefixes_arr, &str, 1); + } + } T_END; + prefixes = array_get(&prefixes_arr, &prefix_count); + + p_array_init(&prefix_idx_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++; + + 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); + indent--; + o_stream_send(output, ident_str, indent*2); + o_stream_send_str(output, "}\n"); + } else if (strchr(key + len, '/') == NULL) { + /* keep the prefix */ + j = prefix_count; + break; + } else { + /* subprefix */ + break; + } + } + for (; j < prefix_count; j++) { + len = strlen(prefixes[j]); + if (strncmp(prefixes[j], key, len) == 0 && + strchr(key + len, '/') == NULL) { + key += prefix_idx == -1U ? 0 : + strlen(prefixes[prefix_idx]); + o_stream_send(output, ident_str, indent*2); + o_stream_send_str(output, t_strcut(key, '/')); + o_stream_send_str(output, " {\n"); + indent++; + prefix_idx = j; + array_append(&prefix_idx_stack, &prefix_idx, 1); + break; + } + } + skip_len = prefix_idx == -1U ? 0 : strlen(prefixes[prefix_idx]); + i_assert(strncmp(prefixes[prefix_idx], strings[i], skip_len) == 0); + o_stream_send(output, ident_str, indent*2); + key = strings[i] + skip_len; + value = strchr(key, '='); + o_stream_send(output, key, value-key); + o_stream_send_str(output, " = "); + o_stream_send_str(output, value+1); + o_stream_send(output, "\n", 1); + } T_END; + + while (prefix_idx != -1U) { + prefix_idx = prefix_stack_pop(&prefix_idx_stack); + indent--; + o_stream_send(output, ident_str, indent*2); + o_stream_send_str(output, "}\n"); + } + + array_free(&ctx.strings); + pool_unref(&ctx.pool); +} + +static void config_dump_human(const char *service, enum config_dump_flags flags) +{ + struct ostream *output; + + output = o_stream_create_fd(STDOUT_FILENO, 0, FALSE); + o_stream_cork(output); + config_connection_request_human(output, service, flags); + o_stream_uncork(output); +} + +static void config_request_putenv(const char *key, const char *value, + bool list ATTR_UNUSED, + void *context ATTR_UNUSED) +{ + T_BEGIN { + env_put(t_strconcat(t_str_ucase(key), "=", value, NULL)); + } T_END; +} + +int main(int argc, char *argv[]) +{ + enum config_dump_flags flags = CONFIG_DUMP_FLAG_DEFAULTS; + const char *getopt_str, *service_name = ""; + char **exec_args = NULL; + int c; + + service = master_service_init("config", 0, argc, argv); + + getopt_str = t_strconcat("anp:e", master_service_getopt_string(), NULL); + while ((c = getopt(argc, argv, getopt_str)) > 0) { + if (c == 'e') + break; + switch (c) { + case 'a': + break; + case 'n': + flags &= ~CONFIG_DUMP_FLAG_DEFAULTS; + break; + case 'p': + service_name = optarg; + break; + default: + if (!master_service_parse_option(service, c, optarg)) + exit(FATAL_DEFAULT); + } + } + if (argv[optind] != NULL) + exec_args = &argv[optind]; + + master_service_init_log(service, "doveconf: ", 0); + master_service_init_finish(service); + + config_parse_file(master_service_get_config_path(service), + service_name); + + if (exec_args == NULL) + config_dump_human(service_name, flags); + else { + env_put("DOVECONF_ENV=1"); + config_request_handle(service_name, 0, + config_request_putenv, NULL); + execvp(exec_args[0], exec_args); + i_fatal("execvp(%s) failed: %m", exec_args[0]); + } + master_service_deinit(&service); + return 0; +}
--- a/src/config/main.c Tue May 05 14:55:05 2009 -0400 +++ b/src/config/main.c Tue May 05 15:28:16 2009 -0400 @@ -26,7 +26,6 @@ int main(int argc, char *argv[]) { - enum config_dump_flags flags = 0; const char *getopt_str, *service_name = ""; char **exec_args = NULL; int c; @@ -38,13 +37,6 @@ if (c == 'e') break; switch (c) { - case 'a': - flags |= CONFIG_DUMP_FLAG_HUMAN | - CONFIG_DUMP_FLAG_DEFAULTS; - break; - case 'n': - flags |= CONFIG_DUMP_FLAG_HUMAN; - break; case 'p': service_name = optarg; break; @@ -60,17 +52,7 @@ master_service_init_finish(service); main_init(service_name); - if (master_service_get_socket_count(service) > 0) - master_service_run(service, client_connected); - else if (exec_args == NULL) { - config_connection_dump_request(STDOUT_FILENO, - service_name, flags); - } else { - config_connection_putenv(service_name); - env_put("DOVECONF_ENV=1"); - execvp(exec_args[0], exec_args); - i_fatal("execvp(%s) failed: %m", exec_args[0]); - } + master_service_run(service, client_connected); config_connections_destroy_all(); master_service_deinit(&service); return 0;