dovecot-2.2: dsync: Added -F parameter to sync only mails with[o...

dovecot at dovecot.org dovecot at dovecot.org
Tue Jan 20 02:31:45 UTC 2015


details:   http://hg.dovecot.org/dovecot-2.2/rev/35e4a6ae8d85
changeset: 18181:35e4a6ae8d85
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Jan 20 04:07:09 2015 +0200
description:
dsync: Added -F parameter to sync only mails with[out] specific flag.

diffstat:

 src/doveadm/doveadm-dsync.c              |  17 +++++-
 src/doveadm/dsync/dsync-brain-mailbox.c  |   1 +
 src/doveadm/dsync/dsync-brain-private.h  |   1 +
 src/doveadm/dsync/dsync-brain.c          |   3 +
 src/doveadm/dsync/dsync-brain.h          |   3 +
 src/doveadm/dsync/dsync-ibc-pipe.c       |   2 +
 src/doveadm/dsync/dsync-ibc-stream.c     |   8 ++-
 src/doveadm/dsync/dsync-ibc.h            |   2 +
 src/doveadm/dsync/dsync-mailbox-import.c |  98 ++++++++++++++++++++++++++-----
 src/doveadm/dsync/dsync-mailbox-import.h |   2 +-
 10 files changed, 118 insertions(+), 19 deletions(-)

diffs (truncated from 341 to 300 lines):

diff -r 39d00448490f -r 35e4a6ae8d85 src/doveadm/doveadm-dsync.c
--- a/src/doveadm/doveadm-dsync.c	Tue Jan 20 03:23:29 2015 +0200
+++ b/src/doveadm/doveadm-dsync.c	Tue Jan 20 04:07:09 2015 +0200
@@ -14,6 +14,7 @@
 #include "strescape.h"
 #include "var-expand.h"
 #include "settings-parser.h"
+#include "imap-util.h"
 #include "master-service.h"
 #include "master-service-ssl-settings.h"
 #include "mail-storage.h"
@@ -37,7 +38,7 @@
 #include <ctype.h>
 #include <sys/wait.h>
 
-#define DSYNC_COMMON_GETOPT_ARGS "+1a:dEfg:l:m:n:NPr:Rs:t:Ux:"
+#define DSYNC_COMMON_GETOPT_ARGS "+1a:dEfF:g:l:m:n:NPr:Rs:t:Ux:"
 #define DSYNC_REMOTE_CMD_EXIT_WAIT_SECS 30
 /* The broken_char is mainly set to get a proper error message when trying to
    convert a mailbox with a name that can't be used properly translated between
@@ -56,6 +57,7 @@
 	struct doveadm_mail_cmd_context ctx;
 	enum dsync_brain_sync_type sync_type;
 	const char *mailbox;
+	const char *sync_flags;
 	const char *virtual_all_box;
 	guid_128_t mailbox_guid;
 	const char *state_input, *rawlog_path;
@@ -544,6 +546,7 @@
 	}
 	set.sync_since_timestamp = ctx->sync_since_timestamp;
 	set.sync_box = ctx->mailbox;
+	set.sync_flag = ctx->sync_flags;
 	set.virtual_all_box = ctx->virtual_all_box;
 	memcpy(set.sync_box_guid, ctx->mailbox_guid, sizeof(set.sync_box_guid));
 	set.lock_timeout_secs = ctx->lock_timeout;
@@ -924,6 +927,18 @@
 	case 'f':
 		ctx->sync_type = DSYNC_BRAIN_SYNC_TYPE_FULL;
 		break;
+	case 'F': {
+		const char *str = optarg;
+
+		if (strchr(str, ' ') != NULL)
+			i_fatal("-F parameter doesn't support multiple flags currently");
+		if (str[0] == '-')
+			str++;
+		if (str[0] == '\\' && imap_parse_system_flag(str) == 0)
+			i_fatal("Invalid system flag given for -F parameter: '%s'", str);
+		ctx->sync_flags = optarg;
+		break;
+	}
 	case 'g':
 		if (optarg[0] == '\0')
 			ctx->no_mail_sync = TRUE;
diff -r 39d00448490f -r 35e4a6ae8d85 src/doveadm/dsync/dsync-brain-mailbox.c
--- a/src/doveadm/dsync/dsync-brain-mailbox.c	Tue Jan 20 03:23:29 2015 +0200
+++ b/src/doveadm/dsync/dsync-brain-mailbox.c	Tue Jan 20 04:07:09 2015 +0200
@@ -222,6 +222,7 @@
 					  remote_dsync_box->highest_modseq,
 					  remote_dsync_box->highest_pvt_modseq,
 					  brain->sync_since_timestamp,
+					  brain->sync_flag,
 					  import_flags);
 }
 
diff -r 39d00448490f -r 35e4a6ae8d85 src/doveadm/dsync/dsync-brain-private.h
--- a/src/doveadm/dsync/dsync-brain-private.h	Tue Jan 20 03:23:29 2015 +0200
+++ b/src/doveadm/dsync/dsync-brain-private.h	Tue Jan 20 04:07:09 2015 +0200
@@ -57,6 +57,7 @@
 	const char *const *exclude_mailboxes;
 	enum dsync_brain_sync_type sync_type;
 	time_t sync_since_timestamp;
+	const char *sync_flag;
 	char alt_char;
 
 	unsigned int lock_timeout;
diff -r 39d00448490f -r 35e4a6ae8d85 src/doveadm/dsync/dsync-brain.c
--- a/src/doveadm/dsync/dsync-brain.c	Tue Jan 20 03:23:29 2015 +0200
+++ b/src/doveadm/dsync/dsync-brain.c	Tue Jan 20 04:07:09 2015 +0200
@@ -186,6 +186,7 @@
 	brain->alt_char = set->mailbox_alt_char == '\0' ? '_' :
 		set->mailbox_alt_char;
 	brain->sync_since_timestamp = set->sync_since_timestamp;
+	brain->sync_flag = p_strdup(brain->pool, set->sync_flag);
 	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);
@@ -223,6 +224,7 @@
 	ibc_set.virtual_all_box = set->virtual_all_box;
 	ibc_set.exclude_mailboxes = set->exclude_mailboxes;
 	ibc_set.sync_since_timestamp = set->sync_since_timestamp;
+	ibc_set.sync_flags = set->sync_flag;
 	memcpy(ibc_set.sync_box_guid, set->sync_box_guid,
 	       sizeof(ibc_set.sync_box_guid));
 	ibc_set.sync_type = sync_type;
@@ -471,6 +473,7 @@
 	brain->exclude_mailboxes = ibc_set->exclude_mailboxes == NULL ? NULL :
 		p_strarray_dup(brain->pool, ibc_set->exclude_mailboxes);
 	brain->sync_since_timestamp = ibc_set->sync_since_timestamp;
+	brain->sync_flag = p_strdup(brain->pool, ibc_set->sync_flags);
 	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 39d00448490f -r 35e4a6ae8d85 src/doveadm/dsync/dsync-brain.h
--- a/src/doveadm/dsync/dsync-brain.h	Tue Jan 20 03:23:29 2015 +0200
+++ b/src/doveadm/dsync/dsync-brain.h	Tue Jan 20 04:07:09 2015 +0200
@@ -61,6 +61,9 @@
 	char mailbox_alt_char;
 	/* Sync only mails with received timestamp at least this high. */
 	time_t sync_since_timestamp;
+	/* Sync only mails which contains / doesn't contain this flag.
+	   '-' at the beginning means this flag must not exist. */
+	const char *sync_flag;
 
 	/* If non-zero, use dsync lock file for this user */
 	unsigned int lock_timeout_secs;
diff -r 39d00448490f -r 35e4a6ae8d85 src/doveadm/dsync/dsync-ibc-pipe.c
--- a/src/doveadm/dsync/dsync-ibc-pipe.c	Tue Jan 20 03:23:29 2015 +0200
+++ b/src/doveadm/dsync/dsync-ibc-pipe.c	Tue Jan 20 04:07:09 2015 +0200
@@ -172,6 +172,8 @@
 		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));
+	item->u.set.sync_since_timestamp = set->sync_since_timestamp;
+	item->u.set.sync_flags = p_strdup(item->pool, set->sync_flags);
 }
 
 static enum dsync_ibc_recv_ret
diff -r 39d00448490f -r 35e4a6ae8d85 src/doveadm/dsync/dsync-ibc-stream.c
--- a/src/doveadm/dsync/dsync-ibc-stream.c	Tue Jan 20 03:23:29 2015 +0200
+++ b/src/doveadm/dsync/dsync-ibc-stream.c	Tue Jan 20 04:07:09 2015 +0200
@@ -76,7 +76,7 @@
 	  	"debug sync_visible_namespaces exclude_mailboxes  "
 	  	"send_mail_requests backup_send backup_recv lock_timeout "
 	  	"no_mail_sync no_backup_overwrite purge_remote "
-		"sync_since_timestamp virtual_all_box"
+		"sync_since_timestamp sync_flags virtual_all_box"
 	},
 	{ .name = "mailbox_state",
 	  .chr = 'S',
@@ -658,6 +658,10 @@
 		dsync_serializer_encode_add(encoder, "sync_since_timestamp",
 			t_strdup_printf("%ld", (long)set->sync_since_timestamp));
 	}
+	if (set->sync_flags != NULL) {
+		dsync_serializer_encode_add(encoder, "sync_flags",
+					    set->sync_flags);
+	}
 	if ((set->brain_flags & DSYNC_BRAIN_FLAG_SEND_MAIL_REQUESTS) != 0)
 		dsync_serializer_encode_add(encoder, "send_mail_requests", "");
 	if ((set->brain_flags & DSYNC_BRAIN_FLAG_BACKUP_SEND) != 0)
@@ -760,6 +764,8 @@
 			return DSYNC_IBC_RECV_RET_TRYAGAIN;
 		}
 	}
+	if (dsync_deserializer_decode_try(decoder, "sync_flags", &value))
+		set->sync_flags = p_strdup(pool, value);
 	if (dsync_deserializer_decode_try(decoder, "send_mail_requests", &value))
 		set->brain_flags |= DSYNC_BRAIN_FLAG_SEND_MAIL_REQUESTS;
 	if (dsync_deserializer_decode_try(decoder, "backup_send", &value))
diff -r 39d00448490f -r 35e4a6ae8d85 src/doveadm/dsync/dsync-ibc.h
--- a/src/doveadm/dsync/dsync-ibc.h	Tue Jan 20 03:23:29 2015 +0200
+++ b/src/doveadm/dsync/dsync-ibc.h	Tue Jan 20 04:07:09 2015 +0200
@@ -57,6 +57,8 @@
 	const char *const *exclude_mailboxes;
 	/* Sync only mails with received timestamp at least this high. */
 	time_t sync_since_timestamp;
+	/* Sync only mails with specified flags. */
+	const char *sync_flags;
 
 	enum dsync_brain_sync_type sync_type;
 	enum dsync_brain_flags brain_flags;
diff -r 39d00448490f -r 35e4a6ae8d85 src/doveadm/dsync/dsync-mailbox-import.c
--- a/src/doveadm/dsync/dsync-mailbox-import.c	Tue Jan 20 03:23:29 2015 +0200
+++ b/src/doveadm/dsync/dsync-mailbox-import.c	Tue Jan 20 04:07:09 2015 +0200
@@ -63,6 +63,10 @@
 	uint64_t remote_highest_modseq, remote_highest_pvt_modseq;
 	time_t sync_since_timestamp;
 
+	enum mail_flags sync_flag;
+	const char *sync_keyword;
+	bool sync_flag_dontwant;
+
 	struct mailbox_transaction_context *trans, *ext_trans;
 	struct mail_search_context *search_ctx;
 	struct mail *mail, *ext_mail;
@@ -187,7 +191,7 @@
 			  uint32_t remote_first_recent_uid,
 			  uint64_t remote_highest_modseq,
 			  uint64_t remote_highest_pvt_modseq,
-			  time_t sync_since_timestamp,
+			  time_t sync_since_timestamp, const char *sync_flag,
 			  enum dsync_mailbox_import_flags flags)
 {
 	struct dsync_mailbox_importer *importer;
@@ -211,6 +215,16 @@
 	importer->remote_highest_pvt_modseq = remote_highest_pvt_modseq;
 	importer->sync_since_timestamp = sync_since_timestamp;
 	importer->stateful_import = importer->last_common_uid_found;
+	if (sync_flag != NULL) {
+		if (sync_flag[0] == '-') {
+			importer->sync_flag_dontwant = TRUE;
+			sync_flag++;
+		}
+		if (sync_flag[0] == '\\')
+			importer->sync_flag = imap_parse_system_flag(sync_flag);
+		else
+			importer->sync_keyword = p_strdup(pool, sync_flag);
+	}
 
 	hash_table_create(&importer->import_guids, pool, 0, str_hash, strcmp);
 	hash_table_create_direct(&importer->import_uids, pool, 0);
@@ -1226,11 +1240,72 @@
 		mail_update_pvt_modseq(mail, new_modseq);
 }
 
+static bool
+dsync_mail_change_have_keyword(const struct dsync_mail_change *change,
+			       const char *keyword)
+{
+	const char *const *strp;
+
+	array_foreach(&change->keyword_changes, strp) {
+		switch ((*strp)[0]) {
+		case KEYWORD_CHANGE_FINAL:
+		case KEYWORD_CHANGE_ADD_AND_FINAL:
+			if (strcasecmp((*strp)+1, keyword) == 0)
+				return TRUE;
+			break;
+		default:
+			break;
+		}
+	}
+	return FALSE;
+}
+
+static bool
+dsync_mailbox_import_want_change(struct dsync_mailbox_importer *importer,
+				 const struct dsync_mail_change *change,
+				 const char **result_r)
+{
+	if (importer->sync_since_timestamp > 0) {
+		i_assert(change->received_timestamp > 0);
+		if (change->received_timestamp < importer->sync_since_timestamp) {
+			/* mail has too old timestamp - skip it */
+			*result_r = "Ignoring missing local mail with too old timestamp";
+			return FALSE;
+		}
+	}
+	if (importer->sync_flag != 0) {
+		bool have_flag = (change->final_flags & importer->sync_flag) != 0;
+
+		if (have_flag && importer->sync_flag_dontwant) {
+			*result_r = "Ignoring missing local mail that doesn't have wanted flags";
+			return FALSE;
+		}
+		if (!have_flag && !importer->sync_flag_dontwant) {
+			*result_r = "Ignoring missing local mail that has unwanted flags";
+			return FALSE;
+		}
+	}
+	if (importer->sync_keyword != NULL) {
+		bool have_kw = dsync_mail_change_have_keyword(change, importer->sync_keyword);
+
+		if (have_kw && importer->sync_flag_dontwant) {
+			*result_r = "Ignoring missing local mail that doesn't have wanted keywords";
+			return FALSE;
+		}
+		if (!have_kw && !importer->sync_flag_dontwant) {
+			*result_r = "Ignoring missing local mail that has unwanted keywords";
+			return FALSE;
+		}
+	}
+	return TRUE;
+}
+
 static void
 dsync_mailbox_import_save(struct dsync_mailbox_importer *importer,
 			  const struct dsync_mail_change *change)
 {
 	struct dsync_mail_change *save;
+	const char *result;
 
 	i_assert(change->guid != NULL);
 
@@ -1241,13 +1316,8 @@
 		dsync_mailbox_import_flag_change(importer, change);
 		return;
 	}
-	if (importer->sync_since_timestamp > 0) {
-		i_assert(change->received_timestamp > 0);
-		if (change->received_timestamp < importer->sync_since_timestamp) {
-			/* mail has too old timestamp - skip it */
-			return;
-		}
-	}
+	if (!dsync_mailbox_import_want_change(importer, change, &result))
+		return;
 


More information about the dovecot-cvs mailing list