]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Merged dsync into "doveadm dsync".
authorTimo Sirainen <tss@iki.fi>
Thu, 29 Dec 2011 12:43:45 +0000 (14:43 +0200)
committerTimo Sirainen <tss@iki.fi>
Thu, 29 Dec 2011 12:43:45 +0000 (14:43 +0200)
dsync symlink is installed for backwards compatibility.

39 files changed:
.hgignore
configure.in
src/Makefile.am
src/doveadm/Makefile.am
src/doveadm/client-connection.c
src/doveadm/doveadm-mail.c
src/doveadm/doveadm-mail.h
src/doveadm/doveadm-settings.c
src/doveadm/doveadm-settings.h
src/doveadm/doveadm.c
src/doveadm/dsync/Makefile.am [moved from src/dsync/Makefile.am with 81% similarity]
src/doveadm/dsync/doveadm-dsync.c [new file with mode: 0644]
src/doveadm/dsync/doveadm-dsync.h [new file with mode: 0644]
src/doveadm/dsync/dsync-brain-msgs-new.c [moved from src/dsync/dsync-brain-msgs-new.c with 100% similarity]
src/doveadm/dsync/dsync-brain-msgs.c [moved from src/dsync/dsync-brain-msgs.c with 100% similarity]
src/doveadm/dsync/dsync-brain-private.h [moved from src/dsync/dsync-brain-private.h with 100% similarity]
src/doveadm/dsync/dsync-brain.c [moved from src/dsync/dsync-brain.c with 99% similarity]
src/doveadm/dsync/dsync-brain.h [moved from src/dsync/dsync-brain.h with 100% similarity]
src/doveadm/dsync/dsync-data.c [moved from src/dsync/dsync-data.c with 100% similarity]
src/doveadm/dsync/dsync-data.h [moved from src/dsync/dsync-data.h with 100% similarity]
src/doveadm/dsync/dsync-proxy-client.c [moved from src/dsync/dsync-proxy-client.c with 99% similarity]
src/doveadm/dsync/dsync-proxy-server-cmd.c [moved from src/dsync/dsync-proxy-server-cmd.c with 99% similarity]
src/doveadm/dsync/dsync-proxy-server.c [moved from src/dsync/dsync-proxy-server.c with 94% similarity]
src/doveadm/dsync/dsync-proxy-server.h [moved from src/dsync/dsync-proxy-server.h with 100% similarity]
src/doveadm/dsync/dsync-proxy.c [moved from src/dsync/dsync-proxy.c with 100% similarity]
src/doveadm/dsync/dsync-proxy.h [moved from src/dsync/dsync-proxy.h with 100% similarity]
src/doveadm/dsync/dsync-worker-local.c [moved from src/dsync/dsync-worker-local.c with 99% similarity]
src/doveadm/dsync/dsync-worker-private.h [moved from src/dsync/dsync-worker-private.h with 100% similarity]
src/doveadm/dsync/dsync-worker.c [moved from src/dsync/dsync-worker.c with 100% similarity]
src/doveadm/dsync/dsync-worker.h [moved from src/dsync/dsync-worker.h with 100% similarity]
src/doveadm/dsync/test-dsync-brain-msgs.c [moved from src/dsync/test-dsync-brain-msgs.c with 100% similarity]
src/doveadm/dsync/test-dsync-brain.c [moved from src/dsync/test-dsync-brain.c with 99% similarity]
src/doveadm/dsync/test-dsync-common.c [moved from src/dsync/test-dsync-common.c with 100% similarity]
src/doveadm/dsync/test-dsync-common.h [moved from src/dsync/test-dsync-common.h with 100% similarity]
src/doveadm/dsync/test-dsync-proxy-server-cmd.c [moved from src/dsync/test-dsync-proxy-server-cmd.c with 99% similarity]
src/doveadm/dsync/test-dsync-proxy.c [moved from src/dsync/test-dsync-proxy.c with 100% similarity]
src/doveadm/dsync/test-dsync-worker.c [moved from src/dsync/test-dsync-worker.c with 100% similarity]
src/doveadm/dsync/test-dsync-worker.h [moved from src/dsync/test-dsync-worker.h with 100% similarity]
src/dsync/dsync.c [deleted file]

index 77706904f53fa1a3272ac066979fc55a9cfc64b9..71a9fe5ea24c4153906aa14f3fd5c9292dfa4982 100644 (file)
--- a/.hgignore
+++ b/.hgignore
@@ -66,7 +66,6 @@ src/director/director-test
 src/dns/dns-client
 src/doveadm/doveadm
 src/doveadm/doveadm-server
-src/dsync/dsync
 src/imap-login/imap-login
 src/imap/imap
 src/indexer/indexer
index aa01f2ad7f28f7b6533b947a35b894d9d4058948..0d0adbbf58565df69e0541c5c9fac1116c1a72b4 100644 (file)
@@ -2750,7 +2750,7 @@ src/anvil/Makefile
 src/auth/Makefile
 src/config/Makefile
 src/doveadm/Makefile
-src/dsync/Makefile
+src/doveadm/dsync/Makefile
 src/lda/Makefile
 src/log/Makefile
 src/lmtp/Makefile
index c4f0a9a8182bac5676c1f79406f54d8e14755718..aff742660f051332a37b4ad60acc1f557488a860 100644 (file)
@@ -41,7 +41,6 @@ SUBDIRS = \
        director \
        util \
        doveadm \
-       dsync \
        ssl-params \
        stats \
        plugins
index 6e76048be2ad86bc123150ca4cee5fd1084e1042..e7e05d8013171d5f5b9c96ff105017c6b29398d7 100644 (file)
@@ -1,6 +1,8 @@
 doveadm_moduledir = $(moduledir)/doveadm
 pkglibexecdir = $(libexecdir)/dovecot
 
+SUBDIRS = dsync
+
 bin_PROGRAMS = doveadm
 pkglibexec_PROGRAMS = doveadm-server
 
@@ -35,6 +37,7 @@ cmd_pw_libs = \
        ../lib-otp/libotp.a
 
 libs = \
+       dsync/libdsync.a \
        $(LIBDOVECOT_STORAGE) \
        $(unused_objects)
 
@@ -122,3 +125,7 @@ noinst_HEADERS = \
        doveadm-settings.h \
        doveadm-util.h \
        doveadm-who.h
+
+install-exec-local:
+       rm -f $(DESTDIR)$(bindir)/dsync
+       $(LN_S) doveadm $(DESTDIR)$(bindir)/dsync
index b5b3cb3ee5a20c8094eb357486ced6abe1bef997..76b96027d0007a345c6a9c57625bf5ecb454a91f 100644 (file)
@@ -41,9 +41,6 @@ doveadm_mail_cmd_server(const char *cmd_name,
                        const struct mail_storage_service_input *input,
                        int argc, char *argv[])
 {
-       enum mail_storage_service_flags service_flags =
-               MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT |
-               MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP;
        struct doveadm_mail_cmd_context *ctx;
        const struct doveadm_mail_cmd *cmd;
        const char *getopt_args;
@@ -56,12 +53,15 @@ doveadm_mail_cmd_server(const char *cmd_name,
                return FALSE;
        }
 
-       if (doveadm_debug)
-               service_flags |= MAIL_STORAGE_SERVICE_FLAG_DEBUG;
-
        ctx = doveadm_mail_cmd_init(cmd, set);
        ctx->full_args = (const void *)(argv + 1);
 
+       ctx->service_flags |=
+               MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT |
+               MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP;
+       if (doveadm_debug)
+               ctx->service_flags |= MAIL_STORAGE_SERVICE_FLAG_DEBUG;
+
        getopt_args = t_strconcat("AS:u:", ctx->getopt_args, NULL);
        while ((c = getopt(argc, argv, getopt_args)) > 0) {
                switch (c) {
@@ -106,7 +106,10 @@ doveadm_mail_cmd_server(const char *cmd_name,
        }
 
        ctx->args = (const void *)argv;
-       doveadm_mail_single_user(ctx, input, service_flags);
+       if (ctx->v.preinit != NULL)
+               ctx->v.preinit(ctx);
+
+       doveadm_mail_single_user(ctx, input);
        doveadm_mail_server_flush();
        ctx->v.deinit(ctx);
        doveadm_print_flush();
index 00b8c15359f6983d2b392d5c46bb416b72037621..872fe8f10bbd8af4afc0c62816711f1b2a7108f8 100644 (file)
@@ -19,6 +19,7 @@
 #include "doveadm.h"
 #include "doveadm-settings.h"
 #include "doveadm-print.h"
+#include "dsync/doveadm-dsync.h"
 #include "doveadm-mail.h"
 
 #include <stdio.h>
@@ -186,7 +187,6 @@ doveadm_mail_next_user(struct doveadm_mail_cmd_context *ctx,
                       const struct mail_storage_service_input *input,
                       const char **error_r)
 {
-       struct mail_storage_service_user *service_user;
        const char *error;
        int ret;
 
@@ -199,7 +199,7 @@ doveadm_mail_next_user(struct doveadm_mail_cmd_context *ctx,
                return ret;
 
        ret = mail_storage_service_lookup(ctx->storage_service, input,
-                                         &service_user, &error);
+                                         &ctx->cur_service_user, &error);
        if (ret <= 0) {
                if (ret < 0) {
                        *error_r = t_strdup_printf("User lookup failed: %s",
@@ -208,31 +208,32 @@ doveadm_mail_next_user(struct doveadm_mail_cmd_context *ctx,
                return ret;
        }
 
-       ret = mail_storage_service_next(ctx->storage_service, service_user,
+       ret = mail_storage_service_next(ctx->storage_service,
+                                       ctx->cur_service_user,
                                        &ctx->cur_mail_user);
        if (ret < 0) {
                *error_r = "User init failed";
-               mail_storage_service_user_free(&service_user);
+               mail_storage_service_user_free(&ctx->cur_service_user);
                return ret;
        }
 
        ctx->v.run(ctx, ctx->cur_mail_user);
        mail_user_unref(&ctx->cur_mail_user);
-       mail_storage_service_user_free(&service_user);
+       mail_storage_service_user_free(&ctx->cur_service_user);
        return 1;
 }
 
 void doveadm_mail_single_user(struct doveadm_mail_cmd_context *ctx,
-                             const struct mail_storage_service_input *input,
-                             enum mail_storage_service_flags service_flags)
+                             const struct mail_storage_service_input *input)
 {
        const char *error;
        int ret;
 
        i_assert(input->username != NULL);
 
+       ctx->cur_username = input->username;
        ctx->storage_service = mail_storage_service_init(master_service, NULL,
-                                                        service_flags);
+                                                        ctx->service_flags);
        ctx->v.init(ctx, ctx->args);
        if (hook_doveadm_mail_init != NULL)
                hook_doveadm_mail_init(ctx);
@@ -251,21 +252,20 @@ static void sig_die(const siginfo_t *si, void *context ATTR_UNUSED)
 
 static void
 doveadm_mail_all_users(struct doveadm_mail_cmd_context *ctx, char *argv[],
-                      const char *wildcard_user,
-                      enum mail_storage_service_flags service_flags)
+                      const char *wildcard_user)
 {
        struct mail_storage_service_input input;
        unsigned int user_idx, user_count, interval, n;
        const char *user, *error;
        int ret;
 
-       service_flags |= MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP;
+       ctx->service_flags |= MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP;
 
        memset(&input, 0, sizeof(input));
        input.service = "doveadm";
 
        ctx->storage_service = mail_storage_service_init(master_service, NULL,
-                                                        service_flags);
+                                                        ctx->service_flags);
         lib_signals_set_handler(SIGINT, 0, sig_die, NULL);
        lib_signals_set_handler(SIGTERM, 0, sig_die, NULL);
 
@@ -355,20 +355,19 @@ doveadm_mail_cmd_init(const struct doveadm_mail_cmd *cmd,
 static void
 doveadm_mail_cmd(const struct doveadm_mail_cmd *cmd, int argc, char *argv[])
 {
-       enum mail_storage_service_flags service_flags =
-               MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT;
        struct doveadm_mail_cmd_context *ctx;
-       const char *getopt_args, *username, *wildcard_user;
+       const char *getopt_args, *wildcard_user;
        int c;
 
-       if (doveadm_debug)
-               service_flags |= MAIL_STORAGE_SERVICE_FLAG_DEBUG;
-
        ctx = doveadm_mail_cmd_init(cmd, doveadm_settings);
        ctx->full_args = (const void *)(argv + 1);
 
+       ctx->service_flags |= MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT;
+       if (doveadm_debug)
+               ctx->service_flags |= MAIL_STORAGE_SERVICE_FLAG_DEBUG;
+
        getopt_args = t_strconcat("AS:u:", ctx->getopt_args, NULL);
-       username = getenv("USER");
+       ctx->cur_username = getenv("USER");
        wildcard_user = NULL;
        while ((c = getopt(argc, argv, getopt_args)) > 0) {
                switch (c) {
@@ -381,12 +380,14 @@ doveadm_mail_cmd(const struct doveadm_mail_cmd *cmd, int argc, char *argv[])
                                doveadm_settings->doveadm_worker_count = 1;
                        break;
                case 'u':
-                       service_flags |=
+                       ctx->service_flags |=
                                MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP;
-                       username = optarg;
-                       if (strchr(username, '*') != NULL ||
-                           strchr(username, '?') != NULL)
-                               wildcard_user = username;
+                       ctx->cur_username = optarg;
+                       if (strchr(ctx->cur_username, '*') != NULL ||
+                           strchr(ctx->cur_username, '?') != NULL) {
+                               wildcard_user = ctx->cur_username;
+                               ctx->cur_username = NULL;
+                       }
                        break;
                default:
                        if (ctx->v.parse_arg == NULL ||
@@ -400,6 +401,8 @@ doveadm_mail_cmd(const struct doveadm_mail_cmd *cmd, int argc, char *argv[])
                        cmd->name, argv[0]);
        }
        ctx->args = (const void *)argv;
+       if (ctx->v.preinit != NULL)
+               ctx->v.preinit(ctx);
 
        ctx->iterate_single_user =
                !ctx->iterate_all_users && wildcard_user == NULL;
@@ -412,16 +415,16 @@ doveadm_mail_cmd(const struct doveadm_mail_cmd *cmd, int argc, char *argv[])
        if (ctx->iterate_single_user) {
                struct mail_storage_service_input input;
 
-               if (username == NULL)
+               if (ctx->cur_username == NULL)
                        i_fatal("USER environment is missing and -u option not used");
 
                memset(&input, 0, sizeof(input));
                input.service = "doveadm";
-               input.username = username;
-               doveadm_mail_single_user(ctx, &input, service_flags);
+               input.username = ctx->cur_username;
+               doveadm_mail_single_user(ctx, &input);
        } else {
-               service_flags |= MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP;
-               doveadm_mail_all_users(ctx, argv, wildcard_user, service_flags);
+               ctx->service_flags |= MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP;
+               doveadm_mail_all_users(ctx, argv, wildcard_user);
        }
        if (ctx->search_args != NULL)
                mail_search_args_unref(&ctx->search_args);
@@ -432,6 +435,8 @@ doveadm_mail_cmd(const struct doveadm_mail_cmd *cmd, int argc, char *argv[])
        /* service deinit unloads mail plugins, so do it late */
        mail_storage_service_deinit(&ctx->storage_service);
 
+       if (ctx->exit_code != 0)
+               exit(ctx->exit_code);
        if (ctx->failed)
                exit(FATAL_DEFAULT);
        pool_unref(&ctx->pool);
@@ -579,7 +584,10 @@ static struct doveadm_mail_cmd *mail_commands[] = {
        &cmd_mailbox_rename,
        &cmd_mailbox_subscribe,
        &cmd_mailbox_unsubscribe,
-       &cmd_mailbox_status
+       &cmd_mailbox_status,
+       &cmd_dsync_backup,
+       &cmd_dsync_mirror,
+       &cmd_dsync_server
 };
 
 void doveadm_mail_init(void)
index aadea6a02527bb51917dcd7e8980237b36358a1e..adca10667867451b3f395e6ce61d173f79b78825 100644 (file)
@@ -4,17 +4,15 @@
 #include <stdio.h>
 #include "doveadm-util.h"
 #include "module-context.h"
+#include "mail-storage-service.h"
 
-enum mail_storage_service_flags;
 struct mailbox;
 struct mail_user;
-struct mail_storage_service_ctx;
-struct mail_storage_service_input;
-struct mail_storage_service_user;
 struct doveadm_mail_cmd_context;
 
 struct doveadm_mail_cmd_vfuncs {
        bool (*parse_arg)(struct doveadm_mail_cmd_context *ctx,int c);
+       void (*preinit)(struct doveadm_mail_cmd_context *ctx);
        void (*init)(struct doveadm_mail_cmd_context *ctx,
                     const char *const args[]);
        int (*get_next_user)(struct doveadm_mail_cmd_context *ctx,
@@ -42,15 +40,21 @@ struct doveadm_mail_cmd_context {
 
        const char *getopt_args;
        const struct doveadm_settings *set;
+       enum mail_storage_service_flags service_flags;
        struct mail_storage_service_ctx *storage_service;
        /* search args aren't set for all mail commands */
        struct mail_search_args *search_args;
 
+       const char *cur_username;
+       struct mail_storage_service_user *cur_service_user;
        struct mail_user *cur_mail_user;
        struct doveadm_mail_cmd_vfuncs v;
 
        ARRAY_DEFINE(module_contexts, union doveadm_mail_cmd_module_context *);
 
+       /* if non-zero, exit with this code */
+       int exit_code;
+
        /* We're handling only a single user */
        unsigned int iterate_single_user:1;
        /* We're going through all users (not set for wildcard usernames) */
@@ -86,8 +90,7 @@ struct doveadm_mail_cmd_context *
 doveadm_mail_cmd_init(const struct doveadm_mail_cmd *cmd,
                      const struct doveadm_settings *set);
 void doveadm_mail_single_user(struct doveadm_mail_cmd_context *ctx,
-                             const struct mail_storage_service_input *input,
-                             enum mail_storage_service_flags service_flags);
+                             const struct mail_storage_service_input *input);
 int doveadm_mail_server_user(struct doveadm_mail_cmd_context *ctx,
                             const struct mail_storage_service_input *input,
                             const char **error_r);
index ed3f48040c058f3375d5015048b32a7862a3357f..bcab8cd74ea19a7ad6cfd20ed072dc50d7930169 100644 (file)
@@ -60,6 +60,7 @@ static const struct setting_define doveadm_setting_defines[] = {
        DEF(SET_UINT, doveadm_proxy_port),
        DEF(SET_STR, doveadm_password),
        DEF(SET_STR, doveadm_allowed_commands),
+       DEF(SET_STR, dsync_alt_char),
 
        { SET_STRLIST, "plugin", offsetof(struct doveadm_settings, plugin_envs), NULL },
 
@@ -75,6 +76,7 @@ const struct doveadm_settings doveadm_default_settings = {
        .doveadm_proxy_port = 0,
        .doveadm_password = "",
        .doveadm_allowed_commands = "",
+       .dsync_alt_char = "_",
 
        .plugin_envs = ARRAY_INIT
 };
index bc9ef9033da869f5afc076efdde1923eb1451e11..7843d96b36b90e4ed70b81488031c27d8635142e 100644 (file)
@@ -10,6 +10,7 @@ struct doveadm_settings {
        unsigned int doveadm_proxy_port;
        const char *doveadm_password;
        const char *doveadm_allowed_commands;
+       const char *dsync_alt_char;
 
        ARRAY_DEFINE(plugin_envs, const char *);
 };
index 7344e4d47214cce90337c96df3b73de7f8145d37..4206cab038cd35948840da1966409019a440ed71 100644 (file)
@@ -12,6 +12,7 @@
 #include "doveadm-dump.h"
 #include "doveadm-mail.h"
 #include "doveadm-settings.h"
+#include "dsync/doveadm-dsync.h"
 #include "doveadm.h"
 
 #include <stdlib.h>
@@ -274,6 +275,8 @@ int main(int argc, char *argv[])
        bool quick_init = FALSE;
        int c;
 
+       doveadm_dsync_main(&argc, &argv);
+
        /* "+" is GNU extension to stop at the first non-option.
           others just accept -+ option. */
        master_service = master_service_init("doveadm", service_flags,
similarity index 81%
rename from src/dsync/Makefile.am
rename to src/doveadm/dsync/Makefile.am
index 519c392f79757044efd91021c9f2a57266959688..34589f706af193699b9904700f5182eccb2f72ab 100644 (file)
@@ -1,4 +1,4 @@
-bin_PROGRAMS = dsync
+noinst_LIBRARIES = libdsync.a
 
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/lib \
@@ -8,22 +8,14 @@ AM_CPPFLAGS = \
        -I$(top_srcdir)/src/lib-mail \
        -I$(top_srcdir)/src/lib-imap \
        -I$(top_srcdir)/src/lib-index \
-       -I$(top_srcdir)/src/lib-storage
-
-if !BUILD_SHARED_LIBS
-unused_objects = \
-       ../lib/mountpoint.o \
-       ../lib-storage/mail-search-parser-imap.o
-endif
+       -I$(top_srcdir)/src/lib-storage \
+       -I$(top_srcdir)/src/doveadm
 
 libs = \
-       $(LIBDOVECOT_STORAGE) \
-       $(unused_objects)
+       $(LIBDOVECOT_STORAGE)
 
-dsync_LDADD = $(libs) $(LIBDOVECOT) $(MODULE_LIBS)
-dsync_DEPENDENCIES = $(libs) $(LIBDOVECOT_DEPS)
-dsync_SOURCES = \
-       dsync.c \
+libdsync_a_SOURCES = \
+       doveadm-dsync.c \
        dsync-brain.c \
        dsync-brain-msgs.c \
        dsync-brain-msgs-new.c \
@@ -55,11 +47,11 @@ test_programs = \
 noinst_PROGRAMS = $(test_programs)
 
 test_libs = \
-       ../lib-test/libtest.la \
-       ../lib-mail/libmail.la \
-       ../lib-imap/libimap.la \
-       ../lib-charset/libcharset.la \
-       ../lib/liblib.la
+       ../../lib-test/libtest.la \
+       ../../lib-mail/libmail.la \
+       ../../lib-imap/libimap.la \
+       ../../lib-charset/libcharset.la \
+       ../../lib/liblib.la
 
 test_ldadd = \
        $(test_libs) \
diff --git a/src/doveadm/dsync/doveadm-dsync.c b/src/doveadm/dsync/doveadm-dsync.c
new file mode 100644 (file)
index 0000000..8fa2fdb
--- /dev/null
@@ -0,0 +1,494 @@
+/* Copyright (c) 2009-2011 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "lib-signals.h"
+#include "array.h"
+#include "execv-const.h"
+#include "settings-parser.h"
+#include "master-service.h"
+#include "mail-storage-service.h"
+#include "mail-user.h"
+#include "mail-namespace.h"
+#include "doveadm-settings.h"
+#include "doveadm-mail.h"
+#include "dsync-brain.h"
+#include "dsync-worker.h"
+#include "dsync-proxy-server.h"
+#include "doveadm-dsync.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <ctype.h>
+
+struct dsync_cmd_context {
+       struct doveadm_mail_cmd_context ctx;
+       enum dsync_brain_flags brain_flags;
+       const char *mailbox;
+
+       const char *const *remote_cmd_args;
+       const char *local_location;
+
+       int fd_in, fd_out;
+
+       unsigned int reverse_workers:1;
+};
+
+static const char *ssh_cmd = "ssh";
+
+static void run_cmd(const char *const *args, int *fd_in_r, int *fd_out_r)
+{
+       int fd_in[2], fd_out[2];
+
+       if (pipe(fd_in) < 0 || pipe(fd_out) < 0)
+               i_fatal("pipe() failed: %m");
+
+       switch (fork()) {
+       case -1:
+               i_fatal("fork() failed: %m");
+               break;
+       case 0:
+               /* child, which will execute the proxy server. stdin/stdout
+                  goes to pipes which we'll pass to proxy client. */
+               if (dup2(fd_in[0], STDIN_FILENO) < 0 ||
+                   dup2(fd_out[1], STDOUT_FILENO) < 0)
+                       i_fatal("dup2() failed: %m");
+
+               (void)close(fd_in[0]);
+               (void)close(fd_in[1]);
+               (void)close(fd_out[0]);
+               (void)close(fd_out[1]);
+
+               execvp_const(args[0], args);
+               break;
+       default:
+               /* parent */
+               (void)close(fd_in[0]);
+               (void)close(fd_out[1]);
+               *fd_in_r = fd_out[0];
+               *fd_out_r = fd_in[1];
+               break;
+       }
+}
+
+static void
+mirror_get_remote_cmd_line(const char *const *argv,
+                          const char *const **cmd_args_r)
+{
+       ARRAY_TYPE(const_string) cmd_args;
+       unsigned int i;
+       const char *p;
+
+       t_array_init(&cmd_args, 16);
+       for (i = 0; argv[i] != NULL; i++) {
+               p = argv[i];
+               array_append(&cmd_args, &p, 1);
+       }
+
+       p = strchr(argv[0], '/');
+       if (p == NULL) p = argv[0];
+       if (strstr(p, "dsync") == NULL) {
+               /* we're executing doveadm (not dsync) */
+               p = "dsync"; array_append(&cmd_args, &p, 1);
+       }
+       p = "server"; array_append(&cmd_args, &p, 1);
+       (void)array_append_space(&cmd_args);
+       *cmd_args_r = array_idx(&cmd_args, 0);
+}
+
+static bool mirror_get_remote_cmd(const char *const *argv, const char *user,
+                                 const char *const **cmd_args_r)
+{
+       ARRAY_TYPE(const_string) cmd_args;
+       const char *p, *host;
+
+       if (argv[1] != NULL) {
+               /* more than one parameter, so it contains a full command
+                  (e.g. ssh host dsync) */
+               mirror_get_remote_cmd_line(argv, cmd_args_r);
+               return TRUE;
+       }
+
+       /* if it begins with /[a-z0-9]+:/, it's a mail location
+          (e.g. mdbox:~/mail) */
+       for (p = argv[0]; *p != '\0'; p++) {
+               if (!i_isalnum(*p)) {
+                       if (*p == ':')
+                               return FALSE;
+                       break;
+               }
+       }
+
+       if (strchr(argv[0], ' ') != NULL || strchr(argv[0], '/') != NULL) {
+               /* a) the whole command is in one string. this is mainly for
+                     backwards compatibility.
+                  b) script/path */
+               mirror_get_remote_cmd_line(t_strsplit(argv[0], " "),
+                                          cmd_args_r);
+               return TRUE;
+       }
+
+       /* [user@]host */
+       host = strchr(argv[0], '@');
+       if (host != NULL)
+               user = t_strdup_until(argv[0], host++);
+       else
+               host = argv[0];
+
+       /* we'll assume virtual users, so in user@host it really means not to
+          give ssh a username, but to give dsync -u user parameter. */
+       t_array_init(&cmd_args, 8);
+       array_append(&cmd_args, &ssh_cmd, 1);
+       array_append(&cmd_args, &host, 1);
+       p = "doveadm"; array_append(&cmd_args, &p, 1);
+       p = "dsync"; array_append(&cmd_args, &p, 1);
+       p = "server"; array_append(&cmd_args, &p, 1);
+       if (*user != '\0') {
+               p = "-u"; array_append(&cmd_args, &p, 1);
+               array_append(&cmd_args, &user, 1);
+       }
+       (void)array_append_space(&cmd_args);
+       *cmd_args_r = array_idx(&cmd_args, 0);
+       return TRUE;
+}
+
+static struct dsync_worker *
+cmd_dsync_run_local(struct dsync_cmd_context *ctx, struct mail_user *user)
+{
+       struct mail_user *user2;
+       struct dsync_worker *worker2;
+       struct setting_parser_context *set_parser;
+       const char *set_line, *path1, *path2;
+
+       i_assert(ctx->local_location != NULL);
+
+       ctx->brain_flags |= DSYNC_BRAIN_FLAG_LOCAL;
+       i_set_failure_prefix(t_strdup_printf("dsync(%s): ", user->username));
+
+       /* update mail_location and create another user for the
+          second location. */
+       set_parser = mail_storage_service_user_get_settings_parser(ctx->ctx.cur_service_user);
+       set_line = t_strconcat("mail_location=", ctx->local_location, NULL);
+       if (settings_parse_line(set_parser, set_line) < 0)
+               i_unreached();
+       if (mail_storage_service_next(ctx->ctx.storage_service,
+                                     ctx->ctx.cur_service_user, &user2) < 0)
+               i_fatal("User init failed");
+       user2->admin = TRUE;
+
+       if (mail_namespaces_get_root_sep(user->namespaces) !=
+           mail_namespaces_get_root_sep(user2->namespaces)) {
+               i_fatal("Mail locations must use the same "
+                       "virtual mailbox hierarchy separator "
+                       "(specify separator for the default namespace)");
+       }
+       path1 = mailbox_list_get_path(user->namespaces->list, NULL,
+                                     MAILBOX_LIST_PATH_TYPE_MAILBOX);
+       path2 = mailbox_list_get_path(user2->namespaces->list, NULL,
+                                     MAILBOX_LIST_PATH_TYPE_MAILBOX);
+       if (path1 != NULL && path2 != NULL &&
+           strcmp(path1, path2) == 0) {
+               i_fatal("Both source and destination mail_location "
+                       "points to same directory: %s", path1);
+       }
+
+       worker2 = dsync_worker_init_local(user2, *ctx->ctx.set->dsync_alt_char);
+       mail_user_unref(&user2);
+       return worker2;
+}
+
+static struct dsync_worker *
+cmd_dsync_run_remote(struct dsync_cmd_context *ctx, struct mail_user *user)
+{
+       i_set_failure_prefix(t_strdup_printf("dsync-local(%s): ",
+                                            user->username));
+       return dsync_worker_init_proxy_client(ctx->fd_in, ctx->fd_out);
+}
+
+static void
+cmd_dsync_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user)
+{
+       struct dsync_cmd_context *ctx = (struct dsync_cmd_context *)_ctx;
+       struct dsync_worker *worker1, *worker2, *workertmp;
+       struct dsync_brain *brain;
+
+       user->admin = TRUE;
+
+       /* create workers */
+       worker1 = dsync_worker_init_local(user, *_ctx->set->dsync_alt_char);
+       if (ctx->remote_cmd_args == NULL)
+               worker2 = cmd_dsync_run_local(ctx, user);
+       else
+               worker2 = cmd_dsync_run_remote(ctx, user);
+       if (ctx->reverse_workers) {
+               workertmp = worker1;
+               worker1 = worker2;
+               worker2 = workertmp;
+       }
+
+       /* create and run the brain */
+       brain = dsync_brain_init(worker1, worker2, ctx->mailbox,
+                                ctx->brain_flags);
+       if (ctx->remote_cmd_args == NULL)
+               dsync_brain_sync_all(brain);
+       else {
+               dsync_brain_sync(brain);
+               if (!dsync_brain_has_failed(brain))
+                       io_loop_run(current_ioloop);
+       }
+       /* deinit */
+       if (dsync_brain_has_unexpected_changes(brain)) {
+               i_warning("Mailbox changes caused a desync. "
+                         "You may want to run dsync again.");
+               _ctx->exit_code = 2;
+       }
+       if (dsync_brain_deinit(&brain) < 0)
+               _ctx->exit_code = 1;
+
+       dsync_worker_deinit(&worker1);
+       dsync_worker_deinit(&worker2);
+}
+
+static void cmd_dsync_init(struct doveadm_mail_cmd_context *_ctx,
+                          const char *const args[])
+{
+       struct dsync_cmd_context *ctx = (struct dsync_cmd_context *)_ctx;
+       const char *username = "";
+
+       if (args[0] == NULL)
+               doveadm_mail_help_name("dsync");
+
+       lib_signals_ignore(SIGHUP, TRUE);
+
+       if (doveadm_debug || doveadm_verbose)
+               ctx->brain_flags |= DSYNC_BRAIN_FLAG_VERBOSE;
+
+       /* if we're executing remotely, give -u parameter if we also
+          did a userdb lookup. this works only when we're handling a
+          single user */
+       if ((_ctx->service_flags & MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) != 0 &&
+           _ctx->cur_username != NULL)
+               username = _ctx->cur_username;
+       if (!mirror_get_remote_cmd(args, username, &ctx->remote_cmd_args)) {
+               /* it's a mail_location */
+               if (args[1] != NULL)
+                       doveadm_mail_help_name("dsync");
+               ctx->local_location = args[0];
+       }
+
+       if (ctx->remote_cmd_args != NULL) {
+               /* do this before mail_storage_service_next() in case it
+                  drops process privileges */
+               run_cmd(ctx->remote_cmd_args, &ctx->fd_in, &ctx->fd_out);
+       } else {
+               ctx->fd_in = STDIN_FILENO;
+               ctx->fd_out = STDOUT_FILENO;
+       }
+}
+
+static void cmd_dsync_preinit(struct doveadm_mail_cmd_context *ctx)
+{
+       if ((ctx->service_flags & MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) == 0)
+               ctx->service_flags |= MAIL_STORAGE_SERVICE_FLAG_NO_CHDIR;
+}
+
+static bool
+cmd_mailbox_dsync_parse_arg(struct doveadm_mail_cmd_context *_ctx, int c)
+{
+       struct dsync_cmd_context *ctx = (struct dsync_cmd_context *)_ctx;
+
+       switch (c) {
+       case 'f':
+               ctx->brain_flags |= DSYNC_BRAIN_FLAG_FULL_SYNC;
+               break;
+       case 'm':
+               ctx->mailbox = optarg;
+               break;
+       case 'R':
+               ctx->reverse_workers = TRUE;
+               break;
+       default:
+               return FALSE;
+       }
+       return TRUE;
+}
+
+static struct doveadm_mail_cmd_context *cmd_dsync_alloc(void)
+{
+       struct dsync_cmd_context *ctx;
+
+       ctx = doveadm_mail_cmd_alloc(struct dsync_cmd_context);
+       ctx->ctx.getopt_args = "fRm:";
+       ctx->ctx.v.parse_arg = cmd_mailbox_dsync_parse_arg;
+       ctx->ctx.v.preinit = cmd_dsync_preinit;
+       ctx->ctx.v.init = cmd_dsync_init;
+       ctx->ctx.v.run = cmd_dsync_run;
+       return &ctx->ctx;
+}
+
+static struct doveadm_mail_cmd_context *cmd_dsync_backup_alloc(void)
+{
+       struct doveadm_mail_cmd_context *_ctx;
+       struct dsync_cmd_context *ctx;
+
+       _ctx = cmd_dsync_alloc();
+       ctx = (struct dsync_cmd_context *)_ctx;
+       ctx->brain_flags |= DSYNC_BRAIN_FLAG_BACKUP;
+       return _ctx;
+}
+
+static void
+cmd_dsync_server_run(struct doveadm_mail_cmd_context *ctx,
+                    struct mail_user *user)
+{
+       struct dsync_proxy_server *server;
+       struct dsync_worker *worker;
+
+       user->admin = TRUE;
+
+       i_set_failure_prefix(t_strdup_printf("dsync-remote(%s): ",
+                                            user->username));
+       worker = dsync_worker_init_local(user, *ctx->set->dsync_alt_char);
+       server = dsync_proxy_server_init(STDIN_FILENO, STDOUT_FILENO, worker);
+
+       io_loop_run(current_ioloop);
+
+       dsync_proxy_server_deinit(&server);
+       dsync_worker_deinit(&worker);
+}
+
+static struct doveadm_mail_cmd_context *cmd_dsync_server_alloc(void)
+{
+       struct doveadm_mail_cmd_context *ctx;
+
+       ctx = doveadm_mail_cmd_alloc(struct doveadm_mail_cmd_context);
+       ctx->v.run = cmd_dsync_server_run;
+       return ctx;
+}
+
+struct doveadm_mail_cmd cmd_dsync_mirror = {
+       cmd_dsync_alloc, "dsync mirror", "[-fR] [-m <mailbox>] <dest>"
+};
+struct doveadm_mail_cmd cmd_dsync_backup = {
+       cmd_dsync_backup_alloc, "dsync backup",
+       "[-fR] [-m <mailbox>] <dest>"
+};
+struct doveadm_mail_cmd cmd_dsync_server = {
+       cmd_dsync_server_alloc, "dsync server", NULL
+};
+
+void doveadm_dsync_main(int *_argc, char **_argv[])
+{
+       int argc = *_argc;
+       const char *getopt_str;
+       char **argv = *_argv;
+       char **new_argv, *mailbox = NULL, *alt_char = NULL;
+       char *p, *dup, new_flags[5];
+       int max_argc, src, dest, i, j;
+       bool flag_f = FALSE, flag_R = FALSE, flag_m, flag_C, has_arg;
+
+       p = strrchr(argv[0], '/');
+       if (p == NULL) p = argv[0];
+       if (strstr(p, "dsync") == NULL)
+               return;
+
+       /* @UNSAFE: this is called when the "doveadm" binary is called as
+          "dsync" (for backwards compatibility) */
+       max_argc = argc + 5;
+       new_argv = calloc(sizeof(char *), max_argc);
+       new_argv[0] = argv[0];
+       dest = 1;
+       getopt_str = master_service_getopt_string();
+
+       /* add global doveadm flags */
+       for (src = 1; src < argc; src++) {
+               if (argv[src][0] != '-')
+                       break;
+
+               flag_m = FALSE; flag_C = FALSE; has_arg = FALSE;
+               dup = strdup(argv[src]);
+               for (i = j = 1; argv[src][i] != '\0'; i++) {
+                       switch (argv[src][i]) {
+                       case 'C':
+                               flag_C = TRUE;
+                               break;
+                       case 'f':
+                               flag_f = TRUE;
+                               break;
+                       case 'R':
+                               flag_R = TRUE;
+                               break;
+                       case 'm':
+                               flag_m = TRUE;
+                               break;
+                       default:
+                               p = strchr(getopt_str, argv[src][i]);
+                               if (p != NULL && p[1] == ':')
+                                       has_arg = TRUE;
+                               dup[j++] = argv[src][i];
+                               break;
+                       }
+               }
+               if (j > 1) {
+                       dup[j++] = '\0';
+                       new_argv[dest++] = dup;
+                       if (has_arg && src+1 < argc)
+                               new_argv[dest++] = argv[++src];
+               }
+               if (flag_m) {
+                       if (src+1 == argc)
+                               i_fatal("-m missing parameter");
+                       mailbox = argv[++src];
+               }
+               if (flag_C) {
+                       if (src+1 == argc)
+                               i_fatal("-C missing parameter");
+                       alt_char = argv[++src];
+               }
+       }
+       if (alt_char != NULL) {
+               new_argv[dest++] = "-o";
+               new_argv[dest++] =
+                       p_strconcat(pool_datastack_create(),
+                                   "dsync_alt_char=", alt_char, NULL);
+       }
+
+       new_argv[dest++] = "dsync";
+       if (src < argc) {
+               /* mirror|backup|server */
+               if (strcmp(argv[src], "dsync") == 0) {
+                       /* looks like we executed doveconf, which
+                          re-executed ourself with new parameters.
+                          no need to change them anymore. */
+                       return;
+               }
+               new_argv[dest++] = argv[src++];
+       }
+
+       /* dsync flags */
+       new_flags[0] = '-'; i = 1;
+       if (flag_f)
+               new_flags[i++] = 'f';
+       if (flag_R)
+               new_flags[i++] = 'R';
+       if (mailbox != NULL)
+               new_flags[i++] = 'm';
+       i_assert((unsigned int)i < sizeof(new_flags));
+       new_flags[i] = '\0';
+
+       if (i > 1) {
+               new_argv[dest++] = strdup(new_flags);
+               if (mailbox != NULL)
+                       new_argv[dest++] = mailbox;
+       }
+
+       /* rest of the parameters */
+       for (; src < argc; src++)
+               new_argv[dest++] = argv[src];
+       i_assert(dest < max_argc);
+       new_argv[dest] = NULL;
+
+       *_argc = dest;
+       *_argv = new_argv;
+       optind = 1;
+}
diff --git a/src/doveadm/dsync/doveadm-dsync.h b/src/doveadm/dsync/doveadm-dsync.h
new file mode 100644 (file)
index 0000000..9ebb3f2
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef DOVEADM_DSYNC_H
+#define DOVEADM_DSYNC_H
+
+extern struct doveadm_mail_cmd cmd_dsync_mirror;
+extern struct doveadm_mail_cmd cmd_dsync_backup;
+extern struct doveadm_mail_cmd cmd_dsync_server;
+
+void doveadm_dsync_main(int *_argc, char **_argv[]);
+
+#endif
similarity index 99%
rename from src/dsync/dsync-brain.c
rename to src/doveadm/dsync/dsync-brain.c
index 7ad27939f1eb7424acea13fbe4a2c1c1448c2da0..b6508d54f4a4be91ae59d787f61c8a35560a29c6 100644 (file)
@@ -3,7 +3,6 @@
 #include "lib.h"
 #include "array.h"
 #include "hash.h"
-#include "master-service.h"
 #include "dsync-worker.h"
 #include "dsync-brain-private.h"
 
@@ -45,7 +44,7 @@ dsync_brain_init(struct dsync_worker *src_worker,
 void dsync_brain_fail(struct dsync_brain *brain)
 {
        brain->failed = TRUE;
-       master_service_stop(master_service);
+       io_loop_stop(current_ioloop);
 }
 
 int dsync_brain_deinit(struct dsync_brain **_brain)
@@ -880,7 +879,7 @@ void dsync_brain_sync(struct dsync_brain *brain)
        case DSYNC_STATE_SYNC_FLUSH2:
                break;
        case DSYNC_STATE_SYNC_END:
-               master_service_stop(master_service);
+               io_loop_stop(current_ioloop);
                break;
        default:
                i_unreached();
similarity index 99%
rename from src/dsync/dsync-proxy-client.c
rename to src/doveadm/dsync/dsync-proxy-client.c
index ae32b0a2bb6f87284dfd80b10acdfd1759b6cbc4..9f5c10105568766dd49fef56fa36bd21aaec44f8 100644 (file)
@@ -9,7 +9,6 @@
 #include "ostream.h"
 #include "str.h"
 #include "strescape.h"
-#include "master-service.h"
 #include "imap-util.h"
 #include "dsync-proxy.h"
 #include "dsync-worker-private.h"
@@ -82,7 +81,7 @@ static void proxy_client_fail(struct proxy_client_dsync_worker *worker)
 {
        i_stream_close(worker->input);
        dsync_worker_set_failure(&worker->worker);
-       master_service_stop(master_service);
+       io_loop_stop(current_ioloop);
 }
 
 static int
similarity index 99%
rename from src/dsync/dsync-proxy-server-cmd.c
rename to src/doveadm/dsync/dsync-proxy-server-cmd.c
index d090778796f7eb9eaceadb72c4bbbfd5dc31df04..ed09e7dc5260d4e4192ebab725f673b4fd810511 100644 (file)
@@ -9,7 +9,6 @@
 #include "istream-dot.h"
 #include "ostream.h"
 #include "imap-util.h"
-#include "master-service.h"
 #include "dsync-worker.h"
 #include "dsync-proxy.h"
 #include "dsync-proxy-server.h"
similarity index 94%
rename from src/dsync/dsync-proxy-server.c
rename to src/doveadm/dsync/dsync-proxy-server.c
index 8ba8c1de6141e0767f9c20499c2cf8de7425360d..df8cef859ffd5562cd491728667b30dfc4369a3a 100644 (file)
@@ -5,7 +5,6 @@
 #include "fd-set-nonblock.h"
 #include "istream.h"
 #include "ostream.h"
-#include "master-service.h"
 #include "dsync-worker.h"
 #include "dsync-proxy.h"
 #include "dsync-proxy-server.h"
@@ -21,13 +20,13 @@ proxy_server_read_line(struct dsync_proxy_server *server,
                if (server->input->stream_errno != 0) {
                        errno = server->input->stream_errno;
                        i_error("read() from proxy client failed: %m");
-                       master_service_stop(master_service);
+                       io_loop_stop(current_ioloop);
                        return -1;
                }
                if (server->input->eof) {
                        if (!server->finished)
                                i_error("read() from proxy client failed: EOF");
-                       master_service_stop(master_service);
+                       io_loop_stop(current_ioloop);
                        return -1;
                }
        }
@@ -37,7 +36,7 @@ proxy_server_read_line(struct dsync_proxy_server *server,
        if (!server->handshake_received) {
                if (strcmp(*line_r, DSYNC_PROXY_CLIENT_GREETING_LINE) != 0) {
                        i_error("Invalid client handshake: %s", *line_r);
-                       master_service_stop(master_service);
+                       io_loop_stop(current_ioloop);
                        return -1;
                }
                server->handshake_received = TRUE;
@@ -121,7 +120,7 @@ static void proxy_server_input(struct dsync_proxy_server *server)
                ret = -1;
 
        if (ret < 0)
-               master_service_stop(master_service);
+               io_loop_stop(current_ioloop);
        timeout_reset(server->to);
 }
 
@@ -147,7 +146,7 @@ static int proxy_server_output(struct dsync_proxy_server *server)
                }
        }
        if (output->closed)
-               master_service_stop(master_service);
+               io_loop_stop(current_ioloop);
        timeout_reset(server->to);
        return ret;
 }
@@ -155,7 +154,7 @@ static int proxy_server_output(struct dsync_proxy_server *server)
 static void dsync_proxy_server_timeout(void *context ATTR_UNUSED)
 {
        i_error("proxy server timed out");
-       master_service_stop(master_service);
+       io_loop_stop(current_ioloop);
 }
 
 struct dsync_proxy_server *
similarity index 99%
rename from src/dsync/dsync-worker-local.c
rename to src/doveadm/dsync/dsync-worker-local.c
index 7c642f2dd6b59704f1be4eac76b4135f4ad87b56..b26689547d87ae2ba89c2b1ffbfc643f6b1474d6 100644 (file)
@@ -222,6 +222,8 @@ dsync_worker_init_local(struct mail_user *user, char alt_char)
        i_array_init(&worker->msg_get_queue, 32);
        p_array_init(&worker->subs_namespaces, pool, 8);
        dsync_drop_extra_namespaces(worker);
+
+       mail_user_ref(worker->user);
        return &worker->worker;
 }
 
@@ -238,6 +240,8 @@ static void local_worker_deinit(struct dsync_worker *_worker)
 
        local_worker_msg_box_close(worker);
        local_worker_mailbox_close(worker);
+       mail_user_unref(&worker->user);
+
        hash_table_destroy(&worker->mailbox_hash);
        if (worker->mailbox_changes_hash != NULL)
                hash_table_destroy(&worker->mailbox_changes_hash);
similarity index 99%
rename from src/dsync/test-dsync-brain.c
rename to src/doveadm/dsync/test-dsync-brain.c
index 06fbe579eb2405033a0102275ad79532c06aa774..e2db98a3c06d95cb7d29fd1b96f23b6a29d200a6 100644 (file)
@@ -2,7 +2,6 @@
 
 #include "lib.h"
 #include "array.h"
-#include "master-service.h"
 #include "dsync-brain-private.h"
 #include "test-dsync-worker.h"
 #include "test-dsync-common.h"
@@ -10,10 +9,6 @@
 struct master_service *master_service;
 static struct test_dsync_worker *src_test_worker, *dest_test_worker;
 
-void master_service_stop(struct master_service *master_service ATTR_UNUSED)
-{
-}
-
 struct dsync_brain_mailbox_sync *
 dsync_brain_msg_sync_init(struct dsync_brain *brain,
                          const ARRAY_TYPE(dsync_brain_mailbox) *mailboxes)
similarity index 99%
rename from src/dsync/test-dsync-proxy-server-cmd.c
rename to src/doveadm/dsync/test-dsync-proxy-server-cmd.c
index 9812e66e0ce275c328b8d92d9d68d553555e5205..c010e578221d82e648a9e5386cf86905dc01f351 100644 (file)
@@ -6,7 +6,6 @@
 #include "strescape.h"
 #include "istream.h"
 #include "ostream.h"
-#include "master-service.h"
 #include "test-common.h"
 #include "dsync-proxy-server.h"
 #include "test-dsync-worker.h"
@@ -21,8 +20,6 @@ static struct test_dsync_worker *test_worker;
 static struct dsync_proxy_server_command *cur_cmd;
 static const char *cur_cmd_args[20];
 
-void master_service_stop(struct master_service *service ATTR_UNUSED) {}
-
 static void out_clear(void)
 {
        o_stream_seek(server->output, 0);
diff --git a/src/dsync/dsync.c b/src/dsync/dsync.c
deleted file mode 100644 (file)
index fafa5bf..0000000
+++ /dev/null
@@ -1,364 +0,0 @@
-/* Copyright (c) 2009-2011 Dovecot authors, see the included COPYING file */
-
-#include "lib.h"
-#include "lib-signals.h"
-#include "array.h"
-#include "execv-const.h"
-#include "settings-parser.h"
-#include "master-service.h"
-#include "master-service-settings.h"
-#include "mail-storage-service.h"
-#include "mail-user.h"
-#include "mail-namespace.h"
-#include "dsync-brain.h"
-#include "dsync-worker.h"
-#include "dsync-proxy-server.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <ctype.h>
-
-static const char *ssh_cmd = "ssh";
-static struct dsync_brain *brain;
-static struct dsync_proxy_server *server;
-
-static void run_cmd(const char *const *args, int *fd_in_r, int *fd_out_r)
-{
-       int fd_in[2], fd_out[2];
-
-       if (pipe(fd_in) < 0 || pipe(fd_out) < 0)
-               i_fatal("pipe() failed: %m");
-
-       switch (fork()) {
-       case -1:
-               i_fatal("fork() failed: %m");
-               break;
-       case 0:
-               /* child, which will execute the proxy server. stdin/stdout
-                  goes to pipes which we'll pass to proxy client. */
-               if (dup2(fd_in[0], STDIN_FILENO) < 0 ||
-                   dup2(fd_out[1], STDOUT_FILENO) < 0)
-                       i_fatal("dup2() failed: %m");
-
-               (void)close(fd_in[0]);
-               (void)close(fd_in[1]);
-               (void)close(fd_out[0]);
-               (void)close(fd_out[1]);
-
-               execvp_const(args[0], args);
-               break;
-       default:
-               /* parent */
-               (void)close(fd_in[0]);
-               (void)close(fd_out[1]);
-               *fd_in_r = fd_out[0];
-               *fd_out_r = fd_in[1];
-               break;
-       }
-}
-
-static void
-mirror_get_remote_cmd_line(char **argv, const char *const **cmd_args_r)
-{
-       ARRAY_TYPE(const_string) cmd_args;
-       unsigned int i;
-       const char *p;
-
-       t_array_init(&cmd_args, 16);
-       for (i = 0; argv[i] != NULL; i++) {
-               p = argv[i];
-               array_append(&cmd_args, &p, 1);
-       }
-
-       p = "server"; array_append(&cmd_args, &p, 1);
-       (void)array_append_space(&cmd_args);
-       *cmd_args_r = array_idx(&cmd_args, 0);
-}
-
-static bool mirror_get_remote_cmd(char **argv, const char *const **cmd_args_r)
-{
-       ARRAY_TYPE(const_string) cmd_args;
-       const char *p, *user, *host;
-
-       if (argv[1] != NULL) {
-               /* more than one parameter, so it contains a full command
-                  (e.g. ssh host dsync) */
-               mirror_get_remote_cmd_line(argv, cmd_args_r);
-               return TRUE;
-       }
-
-       /* if it begins with /[a-z0-9]+:/, it's a mail location
-          (e.g. mdbox:~/mail) */
-       for (p = argv[0]; *p != '\0'; p++) {
-               if (!i_isalnum(*p)) {
-                       if (*p == ':')
-                               return FALSE;
-                       break;
-               }
-       }
-
-       if (strchr(argv[0], ' ') != NULL || strchr(argv[0], '/') != NULL) {
-               /* a) the whole command is in one string. this is mainly for
-                     backwards compatibility.
-                  b) script/path */
-               argv = p_strsplit(pool_datastack_create(), argv[0], " ");
-               mirror_get_remote_cmd_line(argv, cmd_args_r);
-               return TRUE;
-       }
-
-       /* [user@]host */
-       host = strchr(argv[0], '@');
-       if (host != NULL)
-               user = t_strdup_until(argv[0], host++);
-       else {
-               user = "";
-               host = argv[0];
-       }
-
-       /* we'll assume virtual users, so in user@host it really means not to
-          give ssh a username, but to give dsync -u user parameter. */
-       t_array_init(&cmd_args, 8);
-       array_append(&cmd_args, &ssh_cmd, 1);
-       array_append(&cmd_args, &host, 1);
-       p = "dsync"; array_append(&cmd_args, &p, 1);
-       if (*user != '\0') {
-               p = "-u"; array_append(&cmd_args, &p, 1);
-               array_append(&cmd_args, &user, 1);
-       }
-       p = "server"; array_append(&cmd_args, &p, 1);
-       (void)array_append_space(&cmd_args);
-       *cmd_args_r = array_idx(&cmd_args, 0);
-       return TRUE;
-}
-
-static void ATTR_NORETURN
-usage(void)
-{
-       fprintf(stderr,
-"usage: dsync [-C <alt char>] [-m <mailbox>] [-u <user>] [-frRv]\n"
-"  mirror <local mail_location> | [<user>@]<host> | <remote dsync command>\n"
-);
-       exit(1);
-}
-
-static void
-dsync_connected(struct master_service_connection *conn ATTR_UNUSED)
-{
-       i_fatal("Running as service not supported currently");
-}
-
-int main(int argc, char *argv[])
-{
-       enum mail_storage_service_flags ssflags =
-               MAIL_STORAGE_SERVICE_FLAG_NO_CHDIR |
-               MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT;
-       enum dsync_brain_flags brain_flags = 0;
-       struct mail_storage_service_ctx *storage_service;
-       struct mail_storage_service_user *service_user;
-       struct mail_storage_service_input input;
-       struct mail_user *mail_user, *mail_user2 = NULL;
-       struct dsync_worker *worker1, *worker2, *workertmp;
-       const char *error, *username, *cmd_name, *mailbox = NULL;
-       const char *local_location = NULL, *const *remote_cmd_args = NULL;
-       const char *path1, *path2;
-       bool dsync_server = FALSE, unexpected_changes = FALSE;
-       bool dsync_debug = FALSE, reverse_workers = FALSE;
-       char alt_char = '_';
-       int c, ret, fd_in = STDIN_FILENO, fd_out = STDOUT_FILENO;
-
-       master_service = master_service_init("dsync",
-                                            MASTER_SERVICE_FLAG_STANDALONE,
-                                            &argc, &argv, "+C:Dfm:Ru:v");
-
-       username = getenv("USER");
-       while ((c = master_getopt(master_service)) > 0) {
-               if (c == '-')
-                       break;
-               switch (c) {
-               case 'C':
-                       alt_char = optarg[0];
-                       break;
-               case 'D':
-                       dsync_debug = TRUE;
-                       brain_flags |= DSYNC_BRAIN_FLAG_VERBOSE;
-                       ssflags |= MAIL_STORAGE_SERVICE_FLAG_DEBUG;
-                       break;
-               case 'm':
-                       mailbox = optarg;
-                       break;
-               case 'R':
-                       reverse_workers = TRUE;
-                       break;
-               case 'f':
-                       brain_flags |= DSYNC_BRAIN_FLAG_FULL_SYNC;
-                       break;
-               case 'u':
-                       username = optarg;
-                       ssflags |= MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP;
-                       ssflags &= ~MAIL_STORAGE_SERVICE_FLAG_NO_CHDIR;
-                       break;
-               case 'v':
-                       brain_flags |= DSYNC_BRAIN_FLAG_VERBOSE;
-                       break;
-               default:
-                       usage();
-               }
-       }
-       if (optind == argc)
-               usage();
-       if (username == NULL)
-               i_fatal("USER environment not set and -u parameter not given");
-       cmd_name = argv[optind++];
-
-       if (strcmp(cmd_name, "mirror") == 0 ||
-           strcmp(cmd_name, "convert") == 0 ||
-           strcmp(cmd_name, "backup") == 0) {
-               if (optind == argc)
-                       usage();
-
-               if (strcmp(cmd_name, "backup") == 0)
-                       brain_flags |= DSYNC_BRAIN_FLAG_BACKUP;
-               if (!mirror_get_remote_cmd(argv+optind, &remote_cmd_args)) {
-                       if (optind+1 != argc)
-                               usage();
-                       local_location = argv[optind];
-               }
-               optind++;
-       } else if (strcmp(cmd_name, "server") == 0) {
-               dsync_server = TRUE;
-       } else {
-               usage();
-       }
-       master_service_init_finish(master_service);
-       lib_signals_ignore(SIGHUP, TRUE);
-
-       if (!dsync_debug) {
-               /* disable debugging unless -D is given */
-               i_set_debug_file("/dev/null");
-       }
-
-       memset(&input, 0, sizeof(input));
-       input.module = "mail";
-       input.service = "dsync";
-       input.username = username;
-
-       storage_service = mail_storage_service_init(master_service, NULL,
-                                                   ssflags);
-       if (mail_storage_service_lookup(storage_service, &input,
-                                       &service_user, &error) <= 0)
-               i_fatal("User lookup failed: %s", error);
-
-       if (remote_cmd_args != NULL) {
-               /* _service_lookup() may exec doveconf, so do our forking
-                  after that. but do it before _service_next() in case it
-                  drops process privileges */
-               run_cmd(remote_cmd_args, &fd_in, &fd_out);
-       }
-
-       if (mail_storage_service_next(storage_service, service_user,
-                                     &mail_user) < 0)
-               i_fatal("User init failed");
-       mail_user->admin = TRUE;
-
-       /* create the first local worker */
-       worker1 = dsync_worker_init_local(mail_user, alt_char);
-       if (local_location != NULL) {
-               /* update mail_location and create another user for the
-                  second location. */
-               struct setting_parser_context *set_parser;
-               const char *set_line =
-                       t_strconcat("mail_location=", local_location, NULL);
-
-               set_parser = mail_storage_service_user_get_settings_parser(service_user);
-               if (settings_parse_line(set_parser, set_line) < 0)
-                       i_unreached();
-               if (mail_storage_service_next(storage_service, service_user,
-                                             &mail_user2) < 0)
-                       i_fatal("User init failed");
-               mail_user2->admin = TRUE;
-
-               if (mail_namespaces_get_root_sep(mail_user->namespaces) !=
-                   mail_namespaces_get_root_sep(mail_user2->namespaces)) {
-                       i_fatal("Mail locations must use the same "
-                               "virtual mailbox hierarchy separator "
-                               "(specify separator for the default namespace)");
-               }
-               path1 = mailbox_list_get_path(mail_user->namespaces->list, NULL,
-                                             MAILBOX_LIST_PATH_TYPE_MAILBOX);
-               path2 = mailbox_list_get_path(mail_user2->namespaces->list, NULL,
-                                             MAILBOX_LIST_PATH_TYPE_MAILBOX);
-               if (path1 != NULL && path2 != NULL &&
-                   strcmp(path1, path2) == 0) {
-                       i_fatal("Both source and destination mail_location "
-                               "points to same directory: %s", path1);
-               }
-
-               worker2 = dsync_worker_init_local(mail_user2, alt_char);
-               if (reverse_workers) {
-                       workertmp = worker1;
-                       worker1 = worker2;
-                       worker2 = workertmp;
-               }
-
-               i_set_failure_prefix(t_strdup_printf("dsync(%s): ", username));
-               brain = dsync_brain_init(worker1, worker2, mailbox,
-                                        brain_flags | DSYNC_BRAIN_FLAG_LOCAL);
-               server = NULL;
-               dsync_brain_sync_all(brain);
-       } else if (dsync_server) {
-               i_set_failure_prefix(t_strdup_printf("dsync-remote(%s): ",
-                                                    username));
-               server = dsync_proxy_server_init(fd_in, fd_out, worker1);
-               worker2 = NULL;
-
-               master_service_run(master_service, dsync_connected);
-       } else {
-               i_assert(remote_cmd_args != NULL);
-               i_set_failure_prefix(t_strdup_printf("dsync-local(%s): ",
-                                                    username));
-
-               worker2 = dsync_worker_init_proxy_client(fd_in, fd_out);
-               if (reverse_workers) {
-                       workertmp = worker1;
-                       worker1 = worker2;
-                       worker2 = workertmp;
-               }
-
-               brain = dsync_brain_init(worker1, worker2,
-                                        mailbox, brain_flags);
-               server = NULL;
-               dsync_brain_sync(brain);
-
-               if (!dsync_brain_has_failed(brain))
-                       master_service_run(master_service, dsync_connected);
-       }
-
-       if (brain == NULL)
-               ret = 0;
-       else {
-               if (dsync_brain_has_unexpected_changes(brain))
-                       unexpected_changes = TRUE;
-               ret = dsync_brain_deinit(&brain);
-       }
-       if (server != NULL)
-               dsync_proxy_server_deinit(&server);
-
-       dsync_worker_deinit(&worker1);
-       if (worker2 != NULL)
-               dsync_worker_deinit(&worker2);
-
-       mail_user_unref(&mail_user);
-       if (mail_user2 != NULL)
-               mail_user_unref(&mail_user2);
-       mail_storage_service_user_free(&service_user);
-
-       if (unexpected_changes) {
-               i_warning("Mailbox changes caused a desync. "
-                         "You may want to run dsync again.");
-       }
-
-       mail_storage_service_deinit(&storage_service);
-       master_service_deinit(&master_service);
-       return ret < 0 ? 1 : (unexpected_changes ? 2 : 0);
-}