dovecot-2.2: dsync: Added -x parameter to exclude mailboxes from...

dovecot at dovecot.org dovecot at dovecot.org
Mon May 27 02:10:39 EEST 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/4883a8e1db13
changeset: 16398:4883a8e1db13
user:      Timo Sirainen <tss at iki.fi>
date:      Sun May 26 21:57:36 2013 +0300
description:
dsync: Added -x parameter to exclude mailboxes from sync.
Multiple -x parameters can be added. Giving \flag as parameter means that
the mailbox with the given SPECIAL-USE \flag is skipped. For example:

doveadm sync -x '\All' -x '\Flagged' -x '\Important' mdbox:~/mdbox

diffstat:

 src/doveadm/dsync/doveadm-dsync.c            |  19 ++++++++++-
 src/doveadm/dsync/dsync-brain-mailbox-tree.c |  20 ++++--------
 src/doveadm/dsync/dsync-brain-private.h      |   1 +
 src/doveadm/dsync/dsync-brain.c              |   5 +++
 src/doveadm/dsync/dsync-brain.h              |   3 +
 src/doveadm/dsync/dsync-ibc-pipe.c           |   2 +
 src/doveadm/dsync/dsync-ibc-stream.c         |  19 +++++++++++-
 src/doveadm/dsync/dsync-ibc.h                |   3 +
 src/doveadm/dsync/dsync-mailbox-tree-fill.c  |  43 ++++++++++++++++++++++++---
 src/doveadm/dsync/dsync-mailbox-tree.h       |   3 +-
 10 files changed, 95 insertions(+), 23 deletions(-)

diffs (truncated from 315 to 300 lines):

diff -r 0b02dc66e9f1 -r 4883a8e1db13 src/doveadm/dsync/doveadm-dsync.c
--- a/src/doveadm/dsync/doveadm-dsync.c	Sun May 26 21:44:50 2013 +0300
+++ b/src/doveadm/dsync/doveadm-dsync.c	Sun May 26 21:57:36 2013 +0300
@@ -36,7 +36,7 @@
 #include <ctype.h>
 #include <sys/wait.h>
 
-#define DSYNC_COMMON_GETOPT_ARGS "+dEfg:l:m:n:Nr:Rs:U"
+#define DSYNC_COMMON_GETOPT_ARGS "+dEfg:l:m:n:Nr:Rs:Ux:"
 #define DSYNC_REMOTE_CMD_EXIT_WAIT_SECS 30
 
 enum dsync_run_type {
@@ -51,6 +51,7 @@
 	const char *mailbox, *namespace_prefix;
 	guid_128_t mailbox_guid;
 	const char *state_input, *rawlog_path;
+	ARRAY_TYPE(const_string) exclude_mailboxes;
 
 	const char *remote_name;
 	const char *local_location;
@@ -496,6 +497,10 @@
 	memcpy(set.sync_box_guid, ctx->mailbox_guid, sizeof(set.sync_box_guid));
 	set.lock_timeout_secs = ctx->lock_timeout;
 	set.state = ctx->state_input;
+	if (array_count(&ctx->exclude_mailboxes) > 0) {
+		/* array is NULL-terminated in init() */
+		set.exclude_mailboxes = array_idx(&ctx->exclude_mailboxes, 0);
+	}
 
 	user->dsyncing = TRUE;
 
@@ -803,6 +808,8 @@
 		if (args[0] == NULL)
 			doveadm_mail_help_name(_ctx->cmd->name);
 	}
+	if (array_count(&ctx->exclude_mailboxes) > 0)
+		array_append_zero(&ctx->exclude_mailboxes);
 
 	lib_signals_ignore(SIGHUP, TRUE);
 }
@@ -817,6 +824,7 @@
 cmd_mailbox_dsync_parse_arg(struct doveadm_mail_cmd_context *_ctx, int c)
 {
 	struct dsync_cmd_context *ctx = (struct dsync_cmd_context *)_ctx;
+	const char *str;
 
 	switch (c) {
 	case 'd':
@@ -847,6 +855,10 @@
 		else
 			ctx->mailbox = optarg;
 		break;
+	case 'x':
+		str = optarg;
+		array_append(&ctx->exclude_mailboxes, &str, 1);
+		break;
 	case 'n':
 		ctx->namespace_prefix = optarg;
 		break;
@@ -891,6 +903,7 @@
 	doveadm_print_init(DOVEADM_PRINT_TYPE_FLOW);
 	doveadm_print_header("state", "state",
 			     DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE);
+	p_array_init(&ctx->exclude_mailboxes, ctx->ctx.pool, 4);
 	return &ctx->ctx;
 }
 
@@ -995,11 +1008,11 @@
 
 struct doveadm_mail_cmd cmd_dsync_mirror = {
 	cmd_dsync_alloc, "sync",
-	"[-dfR] [-l <secs>] [-m <mailbox>] [-n <namespace>] [-s <state>] <dest>"
+	"[-dfR] [-l <secs>] [-m <mailbox>] [-n <namespace>] [-x <exclude>] [-s <state>] <dest>"
 };
 struct doveadm_mail_cmd cmd_dsync_backup = {
 	cmd_dsync_backup_alloc, "backup",
-	"[-dfR] [-l <secs>] [-m <mailbox>] [-n <namespace>] [-s <state>] <dest>"
+	"[-dfR] [-l <secs>] [-m <mailbox>] [-n <namespace>] [-x <exclude>] [-s <state>] <dest>"
 };
 struct doveadm_mail_cmd cmd_dsync_server = {
 	cmd_dsync_server_alloc, "dsync-server", &doveadm_mail_cmd_hide
diff -r 0b02dc66e9f1 -r 4883a8e1db13 src/doveadm/dsync/dsync-brain-mailbox-tree.c
--- a/src/doveadm/dsync/dsync-brain-mailbox-tree.c	Sun May 26 21:44:50 2013 +0300
+++ b/src/doveadm/dsync/dsync-brain-mailbox-tree.c	Sun May 26 21:57:36 2013 +0300
@@ -83,20 +83,14 @@
 					doveadm_settings->dsync_alt_char[0]);
 
 	/* fill the local mailbox tree */
-	if (brain->sync_ns != NULL) {
-		if (dsync_mailbox_tree_fill(brain->local_mailbox_tree,
-					    brain->sync_ns, brain->sync_box,
-					    brain->sync_box_guid) < 0)
+	for (ns = brain->user->namespaces; ns != NULL; ns = ns->next) {
+		if (!dsync_brain_want_namespace(brain, ns))
+			continue;
+		if (dsync_mailbox_tree_fill(brain->local_mailbox_tree, ns,
+					    brain->sync_box,
+					    brain->sync_box_guid,
+					    brain->exclude_mailboxes) < 0)
 			brain->failed = TRUE;
-	} else {
-		for (ns = brain->user->namespaces; ns != NULL; ns = ns->next) {
-			if (!dsync_brain_want_namespace(brain, ns))
-				continue;
-			if (dsync_mailbox_tree_fill(brain->local_mailbox_tree,
-						    ns, brain->sync_box,
-						    brain->sync_box_guid) < 0)
-				brain->failed = TRUE;
-		}
 	}
 
 	brain->local_tree_iter =
diff -r 0b02dc66e9f1 -r 4883a8e1db13 src/doveadm/dsync/dsync-brain-private.h
--- a/src/doveadm/dsync/dsync-brain-private.h	Sun May 26 21:44:50 2013 +0300
+++ b/src/doveadm/dsync/dsync-brain-private.h	Sun May 26 21:57:36 2013 +0300
@@ -52,6 +52,7 @@
 	struct mail_namespace *sync_ns;
 	const char *sync_box;
 	guid_128_t sync_box_guid;
+	const char *const *exclude_mailboxes;
 	enum dsync_brain_sync_type sync_type;
 
 	unsigned int lock_timeout;
diff -r 0b02dc66e9f1 -r 4883a8e1db13 src/doveadm/dsync/dsync-brain.c
--- a/src/doveadm/dsync/dsync-brain.c	Sun May 26 21:44:50 2013 +0300
+++ b/src/doveadm/dsync/dsync-brain.c	Sun May 26 21:57:36 2013 +0300
@@ -103,6 +103,8 @@
 	if (set->sync_ns != NULL)
 		brain->sync_ns = set->sync_ns;
 	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);
 	memcpy(brain->sync_box_guid, set->sync_box_guid,
 	       sizeof(brain->sync_box_guid));
 	brain->lock_timeout = set->lock_timeout_secs;
@@ -124,6 +126,7 @@
 	ibc_set.sync_ns_prefix = set->sync_ns == NULL ? NULL :
 		set->sync_ns->prefix;
 	ibc_set.sync_box = set->sync_box;
+	ibc_set.exclude_mailboxes = set->exclude_mailboxes;
 	memcpy(ibc_set.sync_box_guid, set->sync_box_guid,
 	       sizeof(ibc_set.sync_box_guid));
 	ibc_set.sync_type = sync_type;
@@ -312,6 +315,8 @@
 						     ibc_set->sync_ns_prefix);
 	}
 	brain->sync_box = p_strdup(brain->pool, ibc_set->sync_box);
+	brain->exclude_mailboxes = ibc_set->exclude_mailboxes == NULL ? NULL :
+		p_strarray_dup(brain->pool, ibc_set->exclude_mailboxes);
 	memcpy(brain->sync_box_guid, ibc_set->sync_box_guid,
 	       sizeof(brain->sync_box_guid));
 	i_assert(brain->sync_type == DSYNC_BRAIN_SYNC_TYPE_UNKNOWN);
diff -r 0b02dc66e9f1 -r 4883a8e1db13 src/doveadm/dsync/dsync-brain.h
--- a/src/doveadm/dsync/dsync-brain.h	Sun May 26 21:44:50 2013 +0300
+++ b/src/doveadm/dsync/dsync-brain.h	Sun May 26 21:57:36 2013 +0300
@@ -37,6 +37,9 @@
 	const char *sync_box;
 	/* Sync only this mailbox GUID */
 	guid_128_t sync_box_guid;
+	/* Exclude these mailboxes from the sync. They can contain '*'
+	   wildcards and be \special-use flags. */
+	const char *const *exclude_mailboxes;
 
 	/* If non-zero, use dsync lock file for this user */
 	unsigned int lock_timeout_secs;
diff -r 0b02dc66e9f1 -r 4883a8e1db13 src/doveadm/dsync/dsync-ibc-pipe.c
--- a/src/doveadm/dsync/dsync-ibc-pipe.c	Sun May 26 21:44:50 2013 +0300
+++ b/src/doveadm/dsync/dsync-ibc-pipe.c	Sun May 26 21:57:36 2013 +0300
@@ -161,6 +161,8 @@
 	item->u.set = *set;
 	item->u.set.sync_ns_prefix = p_strdup(item->pool, set->sync_ns_prefix);
 	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);
 	memcpy(item->u.set.sync_box_guid, set->sync_box_guid,
 	       sizeof(item->u.set.sync_box_guid));
 }
diff -r 0b02dc66e9f1 -r 4883a8e1db13 src/doveadm/dsync/dsync-ibc-stream.c
--- a/src/doveadm/dsync/dsync-ibc-stream.c	Sun May 26 21:44:50 2013 +0300
+++ b/src/doveadm/dsync/dsync-ibc-stream.c	Sun May 26 21:57:36 2013 +0300
@@ -73,7 +73,7 @@
 	  .chr = 'H',
 	  .required_keys = "hostname",
 	  .optional_keys = "sync_ns_prefix sync_box sync_box_guid sync_type "
-	  	"debug sync_visible_namespaces "
+	  	"debug sync_visible_namespaces exclude_mailboxes"
 	  	"send_mail_requests backup_send backup_recv lock_timeout"
 	},
 	{ .name = "mailbox_state",
@@ -594,6 +594,18 @@
 	}
 	if (set->sync_box != NULL)
 		dsync_serializer_encode_add(encoder, "sync_box", set->sync_box);
+	if (set->exclude_mailboxes != NULL) {
+		string_t *substr = t_str_new(64);
+		unsigned int i;
+
+		for (i = 0; set->exclude_mailboxes[i] != NULL; i++) {
+			if (i != 0)
+				str_append_c(substr, '\t');
+			str_append_tabescaped(substr, set->exclude_mailboxes[i]);
+		}
+		dsync_serializer_encode_add(encoder, "exclude_mailboxes",
+					    str_c(substr));
+	}
 	if (!guid_128_is_empty(set->sync_box_guid)) {
 		dsync_serializer_encode_add(encoder, "sync_box_guid",
 			guid_128_to_string(set->sync_box_guid));
@@ -670,6 +682,11 @@
 				      "Invalid sync_box_guid: %s", value);
 		return DSYNC_IBC_RECV_RET_TRYAGAIN;
 	}
+	if (dsync_deserializer_decode_try(decoder, "exclude_mailboxes", &value) &&
+	    *value != '\0') {
+		char **boxes = p_strsplit_tabescaped(pool, value);
+		set->exclude_mailboxes = (const void *)boxes;
+	}
 	if (dsync_deserializer_decode_try(decoder, "sync_type", &value)) {
 		switch (value[0]) {
 		case 'f':
diff -r 0b02dc66e9f1 -r 4883a8e1db13 src/doveadm/dsync/dsync-ibc.h
--- a/src/doveadm/dsync/dsync-ibc.h	Sun May 26 21:44:50 2013 +0300
+++ b/src/doveadm/dsync/dsync-ibc.h	Sun May 26 21:57:36 2013 +0300
@@ -49,6 +49,9 @@
 	const char *sync_box;
 	/* if non-empty, sync only this mailbox GUID */
 	guid_128_t sync_box_guid;
+	/* Exclude these mailboxes from the sync. They can contain '*'
+	   wildcards and be \special-use flags. */
+	const char *const *exclude_mailboxes;
 
 	enum dsync_brain_sync_type sync_type;
 	enum dsync_brain_flags brain_flags;
diff -r 0b02dc66e9f1 -r 4883a8e1db13 src/doveadm/dsync/dsync-mailbox-tree-fill.c
--- a/src/doveadm/dsync/dsync-mailbox-tree-fill.c	Sun May 26 21:44:50 2013 +0300
+++ b/src/doveadm/dsync/dsync-mailbox-tree-fill.c	Sun May 26 21:57:36 2013 +0300
@@ -5,6 +5,7 @@
 #include "hash.h"
 #include "guid.h"
 #include "str.h"
+#include "wildcard-match.h"
 #include "mailbox-log.h"
 #include "mail-namespace.h"
 #include "mail-storage.h"
@@ -265,9 +266,39 @@
 	return ret;
 }
 
+static bool
+dsync_mailbox_info_is_excluded(const struct mailbox_info *info,
+			       const char *const *exclude_mailboxes)
+{
+	const char *const *info_specialuses;
+	unsigned int i;
+
+	if (exclude_mailboxes == NULL)
+		return FALSE;
+
+	info_specialuses = info->special_use == NULL ? NULL :
+		t_strsplit(info->special_use, " ");
+	for (i = 0; exclude_mailboxes[i] != NULL; i++) {
+		const char *exclude = exclude_mailboxes[i];
+
+		if (exclude[0] == '\\') {
+			/* special-use */
+			if (info_specialuses != NULL &&
+			    str_array_icase_find(info_specialuses, exclude))
+				return TRUE;
+		} else {
+			/* mailbox with wildcards */
+			if (wildcard_match(info->vname, exclude))
+				return TRUE;
+		}
+	}
+	return FALSE;
+}
+
 int dsync_mailbox_tree_fill(struct dsync_mailbox_tree *tree,
 			    struct mail_namespace *ns, const char *box_name,
-			    const guid_128_t box_guid)
+			    const guid_128_t box_guid,
+			    const char *const *exclude_mailboxes)
 {
 	const enum mailbox_list_iter_flags list_flags =
 		/* FIXME: we'll skip symlinks, because we can't handle them
@@ -298,10 +329,12 @@
 
 	/* first add all of the existing mailboxes */
 	iter = mailbox_list_iter_init(ns->list, list_pattern, list_flags);
-	while ((info = mailbox_list_iter_next(iter)) != NULL) {
-		if (dsync_mailbox_tree_add(tree, info, box_guid) < 0)
-			ret = -1;
-	}
+	while ((info = mailbox_list_iter_next(iter)) != NULL) T_BEGIN {
+		if (!dsync_mailbox_info_is_excluded(info, exclude_mailboxes)) {
+			if (dsync_mailbox_tree_add(tree, info, box_guid) < 0)
+				ret = -1;
+		}
+	} T_END;
 	if (mailbox_list_iter_deinit(&iter) < 0) {


More information about the dovecot-cvs mailing list