]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
welcome: Use program-client for welcome script
authorAki Tuomi <aki.tuomi@open-xchange.com>
Wed, 19 Jan 2022 09:20:24 +0000 (10:20 +0100)
committerKarl Fleischmann <karl.fleischmann@open-xchange.com>
Tue, 1 Feb 2022 07:35:34 +0000 (08:35 +0100)
Replace manual execution of client script with consolidated
program-client API.

src/plugins/welcome/Makefile.am
src/plugins/welcome/welcome-plugin.c

index 98968f5dc0b9bd7304cfb6b509e268496090c749..b16e669a4de62f547ff71c66bba854883b8e9f2e 100644 (file)
@@ -2,6 +2,7 @@ AM_CPPFLAGS = \
        -I$(top_srcdir)/src/lib \
        -I$(top_srcdir)/src/lib-mail \
        -I$(top_srcdir)/src/lib-index \
+       -I$(top_srcdir)/src/lib-program-client \
        -I$(top_srcdir)/src/lib-storage
 
 NOPLUGIN_LDFLAGS =
index e98d1260454d71f8fb2e3946d00a4cb76b6f9083..bba6fe9c5dcbde7447ad41fcb6ba32b997eec30d 100644 (file)
@@ -2,15 +2,16 @@
 
 #include "lib.h"
 #include "net.h"
+#include "ioloop.h"
+#include "llist.h"
 #include "str.h"
+#include "program-client.h"
 #include "strescape.h"
 #include "eacces-error.h"
 #include "write-full.h"
 #include "module-context.h"
 #include "mail-storage-private.h"
 
-#define WELCOME_SOCKET_TIMEOUT_SECS 30
-
 #define WELCOME_CONTEXT(obj) \
        MODULE_CONTEXT_REQUIRE(obj, welcome_storage_module)
 
@@ -19,15 +20,43 @@ struct welcome_mailbox {
        bool created;
 };
 
+static struct welcome_client_list {
+       struct welcome_client_list *prev, *next;
+       struct program_client *client;
+} *welcome_clients = NULL;
+
 static MODULE_CONTEXT_DEFINE_INIT(welcome_storage_module,
                                  &mail_storage_module_register);
 
+static void welcome_client_destroy(struct welcome_client_list **_wclient) {
+       struct welcome_client_list *wclient = *_wclient;
+
+       *_wclient = NULL;
+
+       program_client_destroy(&wclient->client);
+       i_free(wclient);
+}
+
+static void script_finish(int ret, struct program_client *client ATTR_UNUSED)
+{
+       if (ret < 1)
+               i_error("welcome: Execution failed");
+       io_loop_stop(current_ioloop);
+}
+
 static void script_execute(struct mail_user *user, const char *cmd, bool wait)
 {
-       const char *socket_path, *const *args;
-       string_t *str;
-       char buf[1024];
-       int fd, ret;
+       const char *socket_path, *home, *const *args;
+
+       if (mail_user_get_home(user, &home) < 0)
+               home = NULL;
+
+       struct program_client_settings set = {
+               .client_connect_timeout_msecs = 1000,
+               .event = user->event,
+               .debug = user->mail_debug,
+               .home = home,
+       };
 
        e_debug(user->event, "welcome: Executing %s (wait=%d)", cmd, wait ? 1 : 0);
 
@@ -39,45 +68,19 @@ static void script_execute(struct mail_user *user, const char *cmd, bool wait)
                socket_path = t_strconcat(user->set->base_dir, "/",
                                          socket_path, NULL);
        }
-       if ((fd = net_connect_unix_with_retries(socket_path, 1000)) < 0) {
-               if (errno == EACCES) {
-                       i_error("welcome: %s",
-                               eacces_error_get("net_connect_unix",
-                                                socket_path));
-               } else {
-                       i_error("welcome: net_connect_unix(%s) failed: %m",
-                               socket_path);
-               }
-               return;
-       }
 
-       str = t_str_new(1024);
-       str_append(str, "VERSION\tscript\t4\t0\n");
-       if (!wait)
-               str_append(str, "noreply\n");
-       else
-               str_append(str, "-\n");
-       for (; *args != NULL; args++) {
-               str_append_tabescaped(str, *args);
-               str_append_c(str, '\n');
+       struct welcome_client_list *wclient = i_new(struct welcome_client_list, 1);
+       wclient->client = program_client_unix_create(socket_path, args, &set, TRUE);
+
+       if (wait) {
+               int ret = program_client_run(wclient->client);
+               script_finish(ret, wclient->client);
+               welcome_client_destroy(&wclient);
+       } else {
+               DLLIST_PREPEND(&welcome_clients, wclient);
+               program_client_run_async(wclient->client, script_finish,
+                                        wclient->client);
        }
-       str_append_c(str, '\n');
-
-       alarm(WELCOME_SOCKET_TIMEOUT_SECS);
-       net_set_nonblock(fd, FALSE);
-       if (write_full(fd, str_data(str), str_len(str)) < 0)
-               i_error("write(%s) failed: %m", socket_path);
-       else if (wait) {
-               ret = read(fd, buf, sizeof(buf));
-               if (ret < 0)
-                       i_error("welcome: read(%s) failed: %m", socket_path);
-               else if (ret < 2)
-                       i_error("welcome: %s failed: Only %d bytes read", socket_path, ret);
-               else if (buf[0] != '+')
-                       i_error("welcome: %s failed: Script returned error", socket_path);
-       }
-       if (close(fd) < 0)
-               i_error("close(%s) failed: %m", socket_path);
 }
 
 static int
@@ -140,6 +143,14 @@ void welcome_plugin_init(struct module *module)
 
 void welcome_plugin_deinit(void)
 {
+       while (welcome_clients != NULL) {
+               struct welcome_client_list *next = welcome_clients->next;
+
+               program_client_wait(welcome_clients->client);
+               welcome_client_destroy(&welcome_clients);
+               welcome_clients = next;
+       }
+
        mail_storage_hooks_remove(&welcome_mail_storage_hooks);
 }