]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
dsync: Support multiple -n parameters.
authorTimo Sirainen <tss@iki.fi>
Tue, 25 Mar 2014 17:59:24 +0000 (19:59 +0200)
committerTimo Sirainen <tss@iki.fi>
Tue, 25 Mar 2014 17:59:24 +0000 (19:59 +0200)
src/doveadm/dsync/doveadm-dsync.c
src/doveadm/dsync/dsync-brain-mailbox-tree.c
src/doveadm/dsync/dsync-brain-mailbox.c
src/doveadm/dsync/dsync-brain-private.h
src/doveadm/dsync/dsync-brain.c
src/doveadm/dsync/dsync-brain.h
src/doveadm/dsync/dsync-ibc-pipe.c
src/doveadm/dsync/dsync-ibc-stream.c
src/doveadm/dsync/dsync-ibc.h

index ee311aaf9d900389b01c4130b75be1070dd245bd..e70ca291578f1e62e22ad61385bf6427a72bf56e 100644 (file)
@@ -54,10 +54,11 @@ enum dsync_run_type {
 struct dsync_cmd_context {
        struct doveadm_mail_cmd_context ctx;
        enum dsync_brain_sync_type sync_type;
-       const char *mailbox, *namespace_prefix;
+       const char *mailbox;
        guid_128_t mailbox_guid;
        const char *state_input, *rawlog_path;
        ARRAY_TYPE(const_string) exclude_mailboxes;
+       ARRAY_TYPE(const_string) namespace_prefixes;
 
        const char *remote_name;
        const char *local_location;
@@ -510,6 +511,8 @@ cmd_dsync_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user)
        struct dsync_ibc *ibc, *ibc2 = NULL;
        struct dsync_brain *brain;
        struct dsync_brain_settings set;
+       struct mail_namespace *ns;
+       const char *const *strp;
        enum dsync_brain_flags brain_flags;
        bool remote_errors_logged = FALSE;
        bool changes_during_sync = FALSE;
@@ -526,9 +529,15 @@ cmd_dsync_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user)
        }
        doveadm_user_init_dsync(user);
 
-       if (ctx->namespace_prefix != NULL) {
-               set.sync_ns = mail_namespace_find(user->namespaces,
-                                                 ctx->namespace_prefix);
+       t_array_init(&set.sync_namespaces, array_count(&ctx->namespace_prefixes));
+       array_foreach(&ctx->namespace_prefixes, strp) {
+               ns = mail_namespace_find(user->namespaces, *strp);
+               if (ns == NULL) {
+                       i_error("Namespace not found: '%s'", *strp);
+                       ctx->ctx.exit_code = EX_USAGE;
+                       return -1;
+               }
+               array_append(&set.sync_namespaces, &ns, 1);
        }
 
        if (ctx->run_type == DSYNC_RUN_TYPE_LOCAL)
@@ -903,7 +912,8 @@ cmd_mailbox_dsync_parse_arg(struct doveadm_mail_cmd_context *_ctx, int c)
                array_append(&ctx->exclude_mailboxes, &str, 1);
                break;
        case 'n':
-               ctx->namespace_prefix = optarg;
+               str = optarg;
+               array_append(&ctx->namespace_prefixes, &str, 1);
                break;
        case 'N':
                ctx->sync_visible_namespaces = TRUE;
@@ -948,6 +958,7 @@ static struct doveadm_mail_cmd_context *cmd_dsync_alloc(void)
        doveadm_print_header("state", "state",
                             DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE);
        p_array_init(&ctx->exclude_mailboxes, ctx->ctx.pool, 4);
+       p_array_init(&ctx->namespace_prefixes, ctx->ctx.pool, 4);
        return &ctx->ctx;
 }
 
index f9bcc7f9140585bd2a2d64e5c236e744db109e45..08489105bdcb98abce90df71c86c69e2c0b1627c 100644 (file)
@@ -17,11 +17,6 @@ static void dsync_brain_check_namespaces(struct dsync_brain *brain)
 
        i_assert(brain->hierarchy_sep == '\0');
 
-       if (brain->sync_ns != NULL) {
-               brain->hierarchy_sep = mail_namespace_get_sep(brain->sync_ns);
-               return;
-       }
-
        for (ns = brain->user->namespaces; ns != NULL; ns = ns->next) {
                if (!dsync_brain_want_namespace(brain, ns))
                        continue;
index 835ed09aef03806cad655bc5c3dcf9efce847cf0..6288e333dc02797b10695eb1b87537f8d554b6bd 100644 (file)
@@ -47,12 +47,6 @@ int dsync_brain_mailbox_alloc(struct dsync_brain *brain, const guid_128_t guid,
        int ret;
 
        *box_r = NULL;
-       if (brain->sync_ns != NULL) {
-               ret = ns_mailbox_try_alloc(brain->sync_ns, guid, box_r, error_r);
-               if (ret < 0)
-                       brain->failed = TRUE;
-               return ret;
-       }
 
        for (ns = brain->user->namespaces; ns != NULL; ns = ns->next) {
                if (!dsync_brain_want_namespace(brain, ns))
index ae565010fab6849f95c49cdda87679ce6a6c8ba3..27a6a1b59c05fe1eb73b8cafab027ebf3dd41bdb 100644 (file)
@@ -49,7 +49,7 @@ struct dsync_brain {
        pool_t pool;
        struct mail_user *user;
        struct dsync_ibc *ibc;
-       struct mail_namespace *sync_ns;
+       ARRAY(struct mail_namespace *) sync_namespaces;
        const char *sync_box;
        guid_128_t sync_box_guid;
        const char *const *exclude_mailboxes;
index 33ac143157b97d6519d3d56c5218318638ebb35d..c061d0ebec3a3eb0d0c0fd65f97fc6ca00534f91 100644 (file)
@@ -143,6 +143,8 @@ dsync_brain_master_init(struct mail_user *user, struct dsync_ibc *ibc,
 {
        struct dsync_ibc_settings ibc_set;
        struct dsync_brain *brain;
+       struct mail_namespace *const *nsp;
+       string_t *sync_ns_str = NULL;
        const char *error;
 
        i_assert(sync_type != DSYNC_BRAIN_SYNC_TYPE_UNKNOWN);
@@ -152,8 +154,17 @@ dsync_brain_master_init(struct mail_user *user, struct dsync_ibc *ibc,
 
        brain = dsync_brain_common_init(user, ibc);
        brain->sync_type = sync_type;
-       if (set->sync_ns != NULL)
-               brain->sync_ns = set->sync_ns;
+       if (array_count(&set->sync_namespaces) > 0) {
+               sync_ns_str = t_str_new(128);
+               p_array_init(&brain->sync_namespaces, brain->pool,
+                            array_count(&set->sync_namespaces));
+               array_foreach(&set->sync_namespaces, nsp) {
+                       if (str_len(sync_ns_str) > 0)
+                               str_append_c(sync_ns_str, '\n');
+                       str_append(sync_ns_str, (*nsp)->prefix);
+                       array_append(&brain->sync_namespaces, nsp, 1);
+               }
+       }
        brain->sync_box = p_strdup(brain->pool, set->sync_box);
        brain->exclude_mailboxes = set->exclude_mailboxes == NULL ? NULL :
                p_strarray_dup(brain->pool, set->exclude_mailboxes);
@@ -175,8 +186,8 @@ dsync_brain_master_init(struct mail_user *user, struct dsync_ibc *ibc,
 
        memset(&ibc_set, 0, sizeof(ibc_set));
        ibc_set.hostname = my_hostdomain();
-       ibc_set.sync_ns_prefix = set->sync_ns == NULL ? NULL :
-               set->sync_ns->prefix;
+       ibc_set.sync_ns_prefixes = sync_ns_str == NULL ?
+               NULL : str_c(sync_ns_str);
        ibc_set.sync_box = set->sync_box;
        ibc_set.exclude_mailboxes = set->exclude_mailboxes;
        memcpy(ibc_set.sync_box_guid, set->sync_box_guid,
@@ -380,6 +391,8 @@ static bool dsync_brain_master_recv_handshake(struct dsync_brain *brain)
 static bool dsync_brain_slave_recv_handshake(struct dsync_brain *brain)
 {
        const struct dsync_ibc_settings *ibc_set;
+       struct mail_namespace *ns;
+       const char *const *prefixes;
 
        i_assert(!brain->master_brain);
 
@@ -394,9 +407,19 @@ static bool dsync_brain_slave_recv_handshake(struct dsync_brain *brain)
                }
        }
 
-       if (ibc_set->sync_ns_prefix != NULL) {
-               brain->sync_ns = mail_namespace_find(brain->user->namespaces,
-                                                    ibc_set->sync_ns_prefix);
+       if (ibc_set->sync_ns_prefixes != NULL) {
+               p_array_init(&brain->sync_namespaces, brain->pool, 4);
+               prefixes = t_strsplit(ibc_set->sync_ns_prefixes, "\n");
+               for (; *prefixes != NULL; prefixes++) {
+                       ns = mail_namespace_find(brain->user->namespaces,
+                                                *prefixes);
+                       if (ns == NULL) {
+                               i_error("Namespace not found: '%s'", *prefixes);
+                               brain->failed = TRUE;
+                               return FALSE;
+                       }
+                       array_append(&brain->sync_namespaces, &ns, 1);
+               }
        }
        brain->sync_box = p_strdup(brain->pool, ibc_set->sync_box);
        brain->exclude_mailboxes = ibc_set->exclude_mailboxes == NULL ? NULL :
@@ -619,8 +642,15 @@ bool dsync_brain_has_unexpected_changes(struct dsync_brain *brain)
 bool dsync_brain_want_namespace(struct dsync_brain *brain,
                                struct mail_namespace *ns)
 {
-       if (brain->sync_ns != NULL)
-               return brain->sync_ns == ns;
+       struct mail_namespace *const *nsp;
+
+       if (array_is_created(&brain->sync_namespaces)) {
+               array_foreach(&brain->sync_namespaces, nsp) {
+                       if (ns == *nsp)
+                               return TRUE;
+               }
+               return FALSE;
+       }
        if (ns->alias_for != NULL) {
                /* always skip aliases */
                return FALSE;
index 5f3360c0d998884033d27bc38cc3964468913e82..c88427c46ba0dd0e8b4cc50637a9bc4ff0236d20 100644 (file)
@@ -38,8 +38,8 @@ enum dsync_brain_sync_type {
 };
 
 struct dsync_brain_settings {
-       /* Sync only this namespace */
-       struct mail_namespace *sync_ns;
+       /* Sync only these namespaces */
+       ARRAY(struct mail_namespace *) sync_namespaces;
        /* Sync only this mailbox name */
        const char *sync_box;
        /* Sync only this mailbox GUID */
index 0eddb9cc0117c7df3784884d96478c01dd8c5a9a..280ffd35f93224e54891947881e0fed0d3d46ae4 100644 (file)
@@ -164,7 +164,8 @@ dsync_ibc_pipe_send_handshake(struct dsync_ibc *ibc,
 
        item = dsync_ibc_pipe_push_item(pipe->remote, ITEM_HANDSHAKE);
        item->u.set = *set;
-       item->u.set.sync_ns_prefix = p_strdup(item->pool, set->sync_ns_prefix);
+       item->u.set.sync_ns_prefixes =
+               p_strdup(item->pool, set->sync_ns_prefixes);
        item->u.set.sync_box = p_strdup(item->pool, set->sync_box);
        item->u.set.exclude_mailboxes = set->exclude_mailboxes == NULL ? NULL :
                p_strarray_dup(item->pool, set->exclude_mailboxes);
index e8625f53e72fe0fd076a48cdb2cfbaa3cffca8c6..627f18f95838ba87e8c544976f8e9e9f978e48bc 100644 (file)
@@ -604,9 +604,9 @@ dsync_ibc_stream_send_handshake(struct dsync_ibc *_ibc,
        str_append_c(str, items[ITEM_HANDSHAKE].chr);
        encoder = dsync_serializer_encode_begin(ibc->serializers[ITEM_HANDSHAKE]);
        dsync_serializer_encode_add(encoder, "hostname", set->hostname);
-       if (set->sync_ns_prefix != NULL) {
+       if (set->sync_ns_prefixes != NULL) {
                dsync_serializer_encode_add(encoder, "sync_ns_prefix",
-                                           set->sync_ns_prefix);
+                                           set->sync_ns_prefixes);
        }
        if (set->sync_box != NULL)
                dsync_serializer_encode_add(encoder, "sync_box", set->sync_box);
@@ -700,7 +700,7 @@ dsync_ibc_stream_recv_handshake(struct dsync_ibc *_ibc,
        ibc->name = i_strdup(set->hostname);
 
        if (dsync_deserializer_decode_try(decoder, "sync_ns_prefix", &value))
-               set->sync_ns_prefix = p_strdup(pool, value);
+               set->sync_ns_prefixes = p_strdup(pool, value);
        if (dsync_deserializer_decode_try(decoder, "sync_box", &value))
                set->sync_box = p_strdup(pool, value);
        if (dsync_deserializer_decode_try(decoder, "sync_box_guid", &value) &&
index 6700dfb70fb4fdbc7d76606b5b434afe50d33a05..587754aabb6aa1db78a224bc38e19fb7d155071b 100644 (file)
@@ -43,8 +43,8 @@ struct dsync_ibc_settings {
        /* Server hostname. Used for determining which server does the
           locking. */
        const char *hostname;
-       /* if non-NULL, sync only this namespace */
-       const char *sync_ns_prefix;
+       /* if non-NULL, sync only these namespaces (LF-separated) */
+       const char *sync_ns_prefixes;
        /* if non-NULL, sync only this mailbox name */
        const char *sync_box;
        /* if non-empty, sync only this mailbox GUID */