changeset 20831:0c4e5c2725a3

doveadm-sync: Add end-date support
author Aki Tuomi <aki.tuomi@dovecot.fi>
date Mon, 10 Oct 2016 10:36:52 +0300
parents e070d3f9d63c
children e029c79fa786
files src/doveadm/doveadm-dsync.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 src/doveadm/dsync/dsync-mail.h src/doveadm/dsync/dsync-mailbox-import.c src/doveadm/dsync/dsync-mailbox-import.h
diffstat 11 files changed, 58 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/doveadm/doveadm-dsync.c	Mon Oct 10 10:13:12 2016 +0300
+++ b/src/doveadm/doveadm-dsync.c	Mon Oct 10 10:36:52 2016 +0300
@@ -39,7 +39,7 @@
 #include <ctype.h>
 #include <sys/wait.h>
 
-#define DSYNC_COMMON_GETOPT_ARGS "+1a:dDEfg:I:l:m:n:NO:Pr:Rs:t:T:Ux:"
+#define DSYNC_COMMON_GETOPT_ARGS "+1a:dDEfg:I:l:m:n:NO:Pr:Rs:t:e: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
@@ -67,6 +67,7 @@
 	ARRAY_TYPE(const_string) exclude_mailboxes;
 	ARRAY_TYPE(const_string) namespace_prefixes;
 	time_t sync_since_timestamp;
+	time_t sync_until_timestamp;
 	uoff_t sync_max_size;
 	unsigned int io_timeout_secs;
 
@@ -567,6 +568,13 @@
 			"%s ", net_ip2addr(&_ctx->cur_client_ip));
 	}
 	set.sync_since_timestamp = ctx->sync_since_timestamp;
+	set.sync_until_timestamp = ctx->sync_until_timestamp;
+
+	if (set.sync_since_timestamp > 0 && set.sync_until_timestamp > 0 &&
+	    set.sync_since_timestamp > set.sync_until_timestamp) {
+		i_fatal("start date is later than end date");
+	}
+
 	set.sync_max_size = ctx->sync_max_size;
 	set.sync_box = ctx->mailbox;
 	set.sync_flag = ctx->sync_flags;
@@ -1038,6 +1046,10 @@
 		if (mail_parse_human_timestamp(optarg, &ctx->sync_since_timestamp) < 0)
 			i_fatal("Invalid -t parameter: %s", optarg);
 		break;
+	case 'e':
+		if (mail_parse_human_timestamp(optarg, &ctx->sync_until_timestamp) < 0)
+			i_fatal("Invalid -e parameter: %s", optarg);
+		break;
 	case 'I':
 		if (settings_get_size(optarg, &ctx->sync_max_size, &error) < 0)
 			i_fatal("Invalid -I parameter '%s': %s", optarg, error);
--- a/src/doveadm/dsync/dsync-brain-mailbox.c	Mon Oct 10 10:13:12 2016 +0300
+++ b/src/doveadm/dsync/dsync-brain-mailbox.c	Mon Oct 10 10:36:52 2016 +0300
@@ -233,6 +233,7 @@
 					  remote_dsync_box->highest_modseq,
 					  remote_dsync_box->highest_pvt_modseq,
 					  brain->sync_since_timestamp,
+					  brain->sync_until_timestamp,
 					  brain->sync_max_size,
 					  brain->sync_flag,
 					  import_flags);
@@ -321,7 +322,8 @@
 		exporter_flags |= DSYNC_MAILBOX_EXPORTER_FLAG_MAILS_HAVE_GUIDS;
 	if (brain->no_mail_prefetch)
 		exporter_flags |= DSYNC_MAILBOX_EXPORTER_FLAG_MINIMAL_DMAIL_FILL;
-	if (brain->sync_since_timestamp > 0)
+	if (brain->sync_since_timestamp > 0 ||
+	    brain->sync_until_timestamp > 0)
 		exporter_flags |= DSYNC_MAILBOX_EXPORTER_FLAG_TIMESTAMPS;
 	if (brain->sync_max_size > 0)
 		exporter_flags |= DSYNC_MAILBOX_EXPORTER_FLAG_VSIZES;
--- a/src/doveadm/dsync/dsync-brain-private.h	Mon Oct 10 10:13:12 2016 +0300
+++ b/src/doveadm/dsync/dsync-brain-private.h	Mon Oct 10 10:36:52 2016 +0300
@@ -58,6 +58,7 @@
 	const char *const *exclude_mailboxes;
 	enum dsync_brain_sync_type sync_type;
 	time_t sync_since_timestamp;
+	time_t sync_until_timestamp;
 	uoff_t sync_max_size;
 	const char *sync_flag;
 	char alt_char;
--- a/src/doveadm/dsync/dsync-brain.c	Mon Oct 10 10:13:12 2016 +0300
+++ b/src/doveadm/dsync/dsync-brain.c	Mon Oct 10 10:36:52 2016 +0300
@@ -192,6 +192,7 @@
 	brain->alt_char = set->mailbox_alt_char == '\0' ? '_' :
 		set->mailbox_alt_char;
 	brain->sync_since_timestamp = set->sync_since_timestamp;
+	brain->sync_until_timestamp = set->sync_until_timestamp;
 	brain->sync_max_size = set->sync_max_size;
 	brain->sync_flag = p_strdup(brain->pool, set->sync_flag);
 	brain->sync_box = p_strdup(brain->pool, set->sync_box);
@@ -231,6 +232,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_until_timestamp = set->sync_until_timestamp;
 	ibc_set.sync_max_size = set->sync_max_size;
 	ibc_set.sync_flags = set->sync_flag;
 	memcpy(ibc_set.sync_box_guid, set->sync_box_guid,
@@ -487,6 +489,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_until_timestamp = ibc_set->sync_until_timestamp;
 	brain->sync_max_size = ibc_set->sync_max_size;
 	brain->sync_flag = p_strdup(brain->pool, ibc_set->sync_flags);
 	memcpy(brain->sync_box_guid, ibc_set->sync_box_guid,
--- a/src/doveadm/dsync/dsync-brain.h	Mon Oct 10 10:13:12 2016 +0300
+++ b/src/doveadm/dsync/dsync-brain.h	Mon Oct 10 10:36:52 2016 +0300
@@ -69,6 +69,8 @@
 	char mailbox_alt_char;
 	/* Sync only mails with received timestamp at least this high. */
 	time_t sync_since_timestamp;
+	/* Sync only mails with received timestamp less or equal than this */
+	time_t sync_until_timestamp;
 	/* Don't sync mails larger than this. */
 	uoff_t sync_max_size;
 	/* Sync only mails which contains / doesn't contain this flag.
--- a/src/doveadm/dsync/dsync-ibc-pipe.c	Mon Oct 10 10:13:12 2016 +0300
+++ b/src/doveadm/dsync/dsync-ibc-pipe.c	Mon Oct 10 10:36:52 2016 +0300
@@ -180,6 +180,7 @@
 	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_until_timestamp = set->sync_until_timestamp;
 	item->u.set.sync_max_size = set->sync_max_size;
 	item->u.set.sync_flags = p_strdup(item->pool, set->sync_flags);
 }
--- a/src/doveadm/dsync/dsync-ibc-stream.c	Mon Oct 10 10:13:12 2016 +0300
+++ b/src/doveadm/dsync/dsync-ibc-stream.c	Mon Oct 10 10:36:52 2016 +0300
@@ -77,7 +77,7 @@
 	  	"debug sync_visible_namespaces exclude_mailboxes  "
 	  	"send_mail_requests backup_send backup_recv lock_timeout "
 	  	"no_mail_sync no_mailbox_renames no_backup_overwrite purge_remote "
-		"no_notify sync_since_timestamp sync_max_size sync_flags "
+		"no_notify sync_since_timestamp sync_max_size sync_flags sync_until_timestamp"
 	  	"virtual_all_box"
 	},
 	{ .name = "mailbox_state",
@@ -711,6 +711,10 @@
 		dsync_serializer_encode_add(encoder, "sync_since_timestamp",
 			t_strdup_printf("%ld", (long)set->sync_since_timestamp));
 	}
+	if (set->sync_until_timestamp > 0) {
+		dsync_serializer_encode_add(encoder, "sync_until_timestamp",
+			t_strdup_printf("%ld", (long)set->sync_since_timestamp));
+	}
 	if (set->sync_max_size > 0) {
 		dsync_serializer_encode_add(encoder, "sync_max_size",
 			t_strdup_printf("%llu", (unsigned long long)set->sync_max_size));
@@ -827,6 +831,14 @@
 			return DSYNC_IBC_RECV_RET_TRYAGAIN;
 		}
 	}
+	if (dsync_deserializer_decode_try(decoder, "sync_until_timestamp", &value)) {
+		if (str_to_time(value, &set->sync_until_timestamp) < 0 ||
+		    set->sync_until_timestamp == 0) {
+			dsync_ibc_input_error(ibc, decoder,
+				"Invalid sync_until_timestamp: %s", value);
+			return DSYNC_IBC_RECV_RET_TRYAGAIN;
+		}
+	}
 	if (dsync_deserializer_decode_try(decoder, "sync_max_size", &value)) {
 		if (str_to_uoff(value, &set->sync_max_size) < 0 ||
 		    set->sync_max_size == 0) {
--- a/src/doveadm/dsync/dsync-ibc.h	Mon Oct 10 10:13:12 2016 +0300
+++ b/src/doveadm/dsync/dsync-ibc.h	Mon Oct 10 10:36:52 2016 +0300
@@ -58,6 +58,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 received timestamp less or equal than this */
+	time_t sync_until_timestamp;
 	/* Don't sync mails larger than this. */
 	uoff_t sync_max_size;
 	/* Sync only mails with specified flags. */
--- a/src/doveadm/dsync/dsync-mail.h	Mon Oct 10 10:13:12 2016 +0300
+++ b/src/doveadm/dsync/dsync-mail.h	Mon Oct 10 10:36:52 2016 +0300
@@ -79,7 +79,7 @@
 	/* +add, -remove, =final, &add_and_final. */
 	ARRAY_TYPE(const_string) keyword_changes;
 
-	/* Received timestamp for saves, if brain.sync_since_timestamp is set */
+	/* Received timestamp for saves, if brain.sync_since/until_timestamp is set */
 	time_t received_timestamp;
 	/* Mail's size for saves if brain.sync_max_size is set,
 	   (uoff_t)-1 otherwise. */
--- a/src/doveadm/dsync/dsync-mailbox-import.c	Mon Oct 10 10:13:12 2016 +0300
+++ b/src/doveadm/dsync/dsync-mailbox-import.c	Mon Oct 10 10:36:52 2016 +0300
@@ -62,6 +62,7 @@
 	uint32_t remote_first_recent_uid;
 	uint64_t remote_highest_modseq, remote_highest_pvt_modseq;
 	time_t sync_since_timestamp;
+	time_t sync_until_timestamp;
 	uoff_t sync_max_size;
 	enum mailbox_transaction_flags transaction_flags;
 	unsigned int hdr_hash_version;
@@ -217,7 +218,9 @@
 			  uint32_t remote_first_recent_uid,
 			  uint64_t remote_highest_modseq,
 			  uint64_t remote_highest_pvt_modseq,
-			  time_t sync_since_timestamp, uoff_t sync_max_size,
+			  time_t sync_since_timestamp,
+			  time_t sync_until_timestamp,
+			  uoff_t sync_max_size,
 			  const char *sync_flag,
 			  enum dsync_mailbox_import_flags flags)
 {
@@ -241,6 +244,7 @@
 	importer->remote_highest_modseq = remote_highest_modseq;
 	importer->remote_highest_pvt_modseq = remote_highest_pvt_modseq;
 	importer->sync_since_timestamp = sync_since_timestamp;
+	importer->sync_until_timestamp = sync_until_timestamp;
 	importer->sync_max_size = sync_max_size;
 	importer->stateful_import = importer->last_common_uid_found;
 	if (sync_flag != NULL) {
@@ -1352,6 +1356,14 @@
 			return FALSE;
 		}
 	}
+	if (importer->sync_until_timestamp > 0) {
+		i_assert(change->received_timestamp > 0);
+		if (change->received_timestamp > importer->sync_until_timestamp) {
+			/* mail has too new timestamp - skip it */
+			*result_r = "Ignoring missing local mail with too new timestamp";
+			return FALSE;
+		}
+	}
 	if (importer->sync_max_size > 0) {
 		i_assert(change->virtual_size != (uoff_t)-1);
 		if (change->virtual_size < importer->sync_max_size) {
@@ -1646,7 +1658,9 @@
 	int ret;
 
 	i_assert(change->type == DSYNC_MAIL_CHANGE_TYPE_EXPUNGE ||
-		 ((change->received_timestamp > 0 || importer->sync_since_timestamp == 0) &&
+		 ((change->received_timestamp > 0 ||
+		   (importer->sync_since_timestamp == 0 &&
+		    importer->sync_until_timestamp == 0)) &&
 		  (change->virtual_size != (uoff_t)-1 || importer->sync_max_size == 0)));
 
 	/* try to find the matching local mail */
--- a/src/doveadm/dsync/dsync-mailbox-import.h	Mon Oct 10 10:13:12 2016 +0300
+++ b/src/doveadm/dsync/dsync-mailbox-import.h	Mon Oct 10 10:36:52 2016 +0300
@@ -32,7 +32,9 @@
 			  uint32_t remote_first_recent_uid,
 			  uint64_t remote_highest_modseq,
 			  uint64_t remote_highest_pvt_modseq,
-			  time_t sync_since_timestamp, uoff_t sync_max_size,
+			  time_t sync_since_timestamp,
+			  time_t sync_until_timestamp,
+			  uoff_t sync_max_size,
 			  const char *sync_flag,
 			  enum dsync_mailbox_import_flags flags);
 int dsync_mailbox_import_attribute(struct dsync_mailbox_importer *importer,