]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-master: When executing standalone, try first to read config from global socket.
authorTimo Sirainen <tss@iki.fi>
Wed, 27 Jan 2010 21:20:05 +0000 (23:20 +0200)
committerTimo Sirainen <tss@iki.fi>
Wed, 27 Jan 2010 21:20:05 +0000 (23:20 +0200)
--HG--
branch : HEAD

src/lib-master/Makefile.am
src/lib-master/master-service-private.h
src/lib-master/master-service-settings.c
src/lib-master/master-service.c

index cd6ee7bfff230eae72bc1f08ce18f490b4d54246..c6b3f3d20aa33dbbb40a57f64d6636e4a0c5d1bf 100644 (file)
@@ -5,6 +5,7 @@ noinst_LTLIBRARIES = libmaster.la
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/lib \
        -I$(top_srcdir)/src/lib-settings \
+       -DPKG_RUNDIR=\""$(rundir)"\" \
        -DSYSCONFDIR=\""$(pkgsysconfdir)"\" \
        -DBINDIR=\""$(bindir)"\"
 
index b09b67ed8d43bcb7fcb75ae396d73f737de57509..e010502aa4df808c82f3008c1be327d22b029f67 100644 (file)
@@ -56,6 +56,7 @@ struct master_service {
        unsigned int die_with_master:1;
        unsigned int call_avail_overflow:1;
        unsigned int delay_status_updates:1;
+       unsigned int config_path_is_default:1;
 };
 
 void master_service_io_listeners_add(struct master_service *service);
index 6c1d8ef48c8483dd9133248d29089f8a74b914e3..014b09edd3367988a6b3313d9dc586c5b65e4bc2 100644 (file)
@@ -17,6 +17,7 @@
 #include <sys/stat.h>
 
 #define DOVECOT_CONFIG_BIN_PATH BINDIR"/doveconf"
+#define DOVECOT_CONFIG_SOCKET_PATH PKG_RUNDIR"/config"
 
 #define CONFIG_READ_TIMEOUT_SECS 10
 #define CONFIG_HANDSHAKE "VERSION\tconfig\t1\t0\n"
@@ -100,33 +101,66 @@ master_service_exec_config(struct master_service *service, bool preserve_home)
 }
 
 static int
-master_service_read_config(struct master_service *service, const char *path,
+master_service_open_config(struct master_service *service,
                           const struct master_service_settings_input *input,
-                          const char **error_r)
+                          const char **path_r, const char **error_r)
 {
+       const char *path;
        struct stat st;
-       int fd, ret;
+       int fd;
+
+       *path_r = path = input->config_path != NULL ? input->config_path :
+               master_service_get_config_path(service);
 
-       if (service->config_fd != -1) {
+       if (service->config_fd != -1 && input->config_path == NULL) {
+               /* use the already opened config socket */
                fd = service->config_fd;
                service->config_fd = -1;
-       } else {
-               fd = net_connect_unix_with_retries(path, 1000);
-               if (fd < 0) {
-                       *error_r = t_strdup_printf(
-                               "net_connect_unix(%s) failed: %m", path);
+               return fd;
+       }
 
-                       if (stat(path, &st) == 0 && 
-                           !S_ISSOCK(st.st_mode) && !S_ISFIFO(st.st_mode)) {
-                               /* it's a file, not a socket/pipe */
-                               master_service_exec_config(service,
-                                                          input->preserve_home);
-                       }
-                       return -1;
+       if (service->config_path_is_default && input->config_path == NULL) {
+               /* first try to connect to the default config socket.
+                  configuration may contain secrets, so in default config
+                  this fails because the socket is 0600. it's useful for
+                  developers though. :) */
+               fd = net_connect_unix(DOVECOT_CONFIG_SOCKET_PATH);
+               if (fd >= 0) {
+                       *path_r = DOVECOT_CONFIG_SOCKET_PATH;
+                       net_set_nonblock(fd, FALSE);
+                       return fd;
                }
-               net_set_nonblock(fd, FALSE);
+               /* fallback to executing doveconf */
        }
 
+       fd = net_connect_unix_with_retries(path, 1000);
+       if (fd < 0) {
+               *error_r = t_strdup_printf("net_connect_unix(%s) failed: %m",
+                                          path);
+
+               if (stat(path, &st) == 0 &&
+                   !S_ISSOCK(st.st_mode) && !S_ISFIFO(st.st_mode)) {
+                       /* it's a file, not a socket/pipe */
+                       master_service_exec_config(service,
+                                                  input->preserve_home);
+               }
+               return -1;
+       }
+       net_set_nonblock(fd, FALSE);
+       return fd;
+}
+
+static int
+master_service_read_config(struct master_service *service,
+                          const struct master_service_settings_input *input,
+                          const char **path_r, const char **error_r)
+{
+       int fd, ret;
+
+       fd = master_service_open_config(service, input, path_r, error_r);
+       if (fd == -1)
+               return -1;
+
        T_BEGIN {
                string_t *str;
 
@@ -154,7 +188,8 @@ master_service_read_config(struct master_service *service, const char *path,
                ret = write_full(fd, str_data(str), str_len(str));
        } T_END;
        if (ret < 0) {
-               *error_r = t_strdup_printf("write_full(%s) failed: %m", path);
+               *error_r = t_strdup_printf("write_full(%s) failed: %m",
+                                          *path_r);
                return -1;
        }
        return fd;
@@ -198,9 +233,7 @@ int master_service_settings_read(struct master_service *service,
 
        if (getenv("DOVECONF_ENV") == NULL &&
            (service->flags & MASTER_SERVICE_FLAG_NO_CONFIG_SETTINGS) == 0) {
-               path = input->config_path != NULL ? input->config_path :
-                       master_service_get_config_path(service);
-               fd = master_service_read_config(service, path, input, error_r);
+               fd = master_service_read_config(service, input, &path, error_r);
                if (fd == -1)
                        return -1;
        }
@@ -259,7 +292,8 @@ int master_service_settings_read(struct master_service *service,
                }
        }
 
-       if ((service->flags & MASTER_SERVICE_FLAG_KEEP_CONFIG_OPEN) != 0)
+       if ((service->flags & MASTER_SERVICE_FLAG_KEEP_CONFIG_OPEN) != 0 &&
+           service->config_fd == -1 && input->config_path == NULL)
                service->config_fd = fd;
        else if (fd != -1)
                (void)close(fd);
index 6960bdfbbddc5b8f63f2448fe848868b23a0f235..77df4731593c3f2801ea195ee0c3e724a7594675 100644 (file)
@@ -134,8 +134,10 @@ master_service_init(const char *name, enum master_service_flags flags,
        service->config_fd = -1;
 
        service->config_path = getenv(MASTER_CONFIG_FILE_ENV);
-       if (service->config_path == NULL)
+       if (service->config_path == NULL) {
                service->config_path = DEFAULT_CONFIG_FILE_PATH;
+               service->config_path_is_default = TRUE;
+       }
 
        if ((flags & MASTER_SERVICE_FLAG_STANDALONE) == 0) {
                service->version_string = getenv(MASTER_DOVECOT_VERSION_ENV);
@@ -245,6 +247,7 @@ bool master_service_parse_option(struct master_service *service,
        switch (opt) {
        case 'c':
                service->config_path = arg;
+               service->config_path_is_default = FALSE;
                break;
        case 'k':
                service->keep_environment = TRUE;