]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Split doveconf and libexec/dovecot/config binaries.
authorTimo Sirainen <tss@iki.fi>
Tue, 5 May 2009 19:28:16 +0000 (15:28 -0400)
committerTimo Sirainen <tss@iki.fi>
Tue, 5 May 2009 19:28:16 +0000 (15:28 -0400)
--HG--
branch : HEAD

src/config/Makefile.am
src/config/config-connection.c
src/config/config-connection.h
src/config/config-request.h
src/config/doveconf.c [new file with mode: 0644]
src/config/main.c

index 0aa0686935dc53da3b0e544d4be0b9ac51fa48d9..aab3f6cd7850f5db72ee021482b830b12dcf8a79 100644 (file)
@@ -1,6 +1,7 @@
 pkglibexecdir = $(libexecdir)/dovecot
 
 bin_PROGRAMS = doveconf
+pkglibexec_PROGRAMS = config
 
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/lib \
@@ -12,18 +13,31 @@ AM_CPPFLAGS = \
        -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 \
index 92bc937662bc088a711ad85fbf202ea3bce18e0e..10e10ec2507b2f37021aae82e28c5f3a7ebc9ea6 100644 (file)
@@ -57,149 +57,8 @@ config_request_output(const char *key, const char *value,
        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 @@ static void config_connection_request(struct config_connection *conn,
        }
 
        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 @@ static void config_connection_input(void *context)
                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 @@ void config_connection_destroy(struct config_connection *conn)
        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)
index b20d214682e44bc88d3c94ccf9bd98f73c0ec242..b1771b570ea770edf3ad76a0db9a182da54d40eb 100644 (file)
@@ -8,7 +8,6 @@ void config_connection_destroy(struct config_connection *conn);
 
 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);
 
index 73f4ab1708282dd80d9c19b8b293bd08b63187cd..978fa3a518ba36a9e0063b1807305a9595d21bda 100644 (file)
@@ -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,
diff --git a/src/config/doveconf.c b/src/config/doveconf.c
new file mode 100644 (file)
index 0000000..edee1b1
--- /dev/null
@@ -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;
+}
index 61afd122447fb31e63ea0362ad9b32a261a466d4..6a097da4b5f723e36d9842889b6f0f623259963e 100644 (file)
@@ -26,7 +26,6 @@ static void client_connected(const struct master_service_connection *conn)
 
 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 @@ int main(int argc, char *argv[])
                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 @@ int main(int argc, char *argv[])
        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;