From: Timo Sirainen Date: Tue, 25 Mar 2014 17:59:24 +0000 (+0200) Subject: dsync: Support multiple -n parameters. X-Git-Tag: 2.2.13.rc1~193 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d487aa885845c33fb358d5b3b514eece6791db0e;p=thirdparty%2Fdovecot%2Fcore.git dsync: Support multiple -n parameters. --- diff --git a/src/doveadm/dsync/doveadm-dsync.c b/src/doveadm/dsync/doveadm-dsync.c index ee311aaf9d..e70ca29157 100644 --- a/src/doveadm/dsync/doveadm-dsync.c +++ b/src/doveadm/dsync/doveadm-dsync.c @@ -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; } diff --git a/src/doveadm/dsync/dsync-brain-mailbox-tree.c b/src/doveadm/dsync/dsync-brain-mailbox-tree.c index f9bcc7f914..08489105bd 100644 --- a/src/doveadm/dsync/dsync-brain-mailbox-tree.c +++ b/src/doveadm/dsync/dsync-brain-mailbox-tree.c @@ -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; diff --git a/src/doveadm/dsync/dsync-brain-mailbox.c b/src/doveadm/dsync/dsync-brain-mailbox.c index 835ed09aef..6288e333dc 100644 --- a/src/doveadm/dsync/dsync-brain-mailbox.c +++ b/src/doveadm/dsync/dsync-brain-mailbox.c @@ -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)) diff --git a/src/doveadm/dsync/dsync-brain-private.h b/src/doveadm/dsync/dsync-brain-private.h index ae565010fa..27a6a1b59c 100644 --- a/src/doveadm/dsync/dsync-brain-private.h +++ b/src/doveadm/dsync/dsync-brain-private.h @@ -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; diff --git a/src/doveadm/dsync/dsync-brain.c b/src/doveadm/dsync/dsync-brain.c index 33ac143157..c061d0ebec 100644 --- a/src/doveadm/dsync/dsync-brain.c +++ b/src/doveadm/dsync/dsync-brain.c @@ -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; diff --git a/src/doveadm/dsync/dsync-brain.h b/src/doveadm/dsync/dsync-brain.h index 5f3360c0d9..c88427c46b 100644 --- a/src/doveadm/dsync/dsync-brain.h +++ b/src/doveadm/dsync/dsync-brain.h @@ -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 */ diff --git a/src/doveadm/dsync/dsync-ibc-pipe.c b/src/doveadm/dsync/dsync-ibc-pipe.c index 0eddb9cc01..280ffd35f9 100644 --- a/src/doveadm/dsync/dsync-ibc-pipe.c +++ b/src/doveadm/dsync/dsync-ibc-pipe.c @@ -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); diff --git a/src/doveadm/dsync/dsync-ibc-stream.c b/src/doveadm/dsync/dsync-ibc-stream.c index e8625f53e7..627f18f958 100644 --- a/src/doveadm/dsync/dsync-ibc-stream.c +++ b/src/doveadm/dsync/dsync-ibc-stream.c @@ -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) && diff --git a/src/doveadm/dsync/dsync-ibc.h b/src/doveadm/dsync/dsync-ibc.h index 6700dfb70f..587754aabb 100644 --- a/src/doveadm/dsync/dsync-ibc.h +++ b/src/doveadm/dsync/dsync-ibc.h @@ -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 */