Hi there,

I ran into an issue yesterday (dovecot 2.0) whereby when we dsync messages from 
a local machine (sdbox) to a remote (Maildir) which have different 
pop3_uidl_formats configured, the uidl format is not preserved. There doesn't 
seem to be any way to force this in the code, although I suspect that Maildir 
sources with saved pop3 uidls would pass them correctly. Attached is a rough 
patch against 2.0.21 dsync which will generate the uidls on the client before 
passing them over to the destination. This only works for %u and %v currently, 
also because dsync doesn't read the whole config file you need to specify -o 
pop3_uidl_format=... to dsync.

Mark
--- dovecot-2.0.21/src/dsync/dsync-worker-local.c	2012-02-12 21:12:34.000000000 +0000
+++ dovecot-2.0.21.new/src/dsync/dsync-worker-local.c	2013-04-11 09:05:05.000000000 +0100
@@ -9,6 +9,7 @@
 #include "istream.h"
 #include "settings-parser.h"
 #include "mailbox-log.h"
+#include "var-expand.h"
 #include "mail-user.h"
 #include "mail-namespace.h"
 #include "mail-storage.h"
@@ -1832,7 +1833,16 @@
 	struct dsync_msg_static_data data;
 	struct mailbox_transaction_context *trans;
 	struct mailbox *box;
+    char uid_valid_str[MAX_INT_STRLEN];
+    char uid_str[MAX_INT_STRLEN];
+    struct mailbox_status status;
+
+    struct var_expand_table tab[] = {
+        { 'v', NULL, "uidvalidity" },
+        { 'u', NULL, "uid" },
+    };
 
+	string_t *str = t_str_new(128);
 	i_assert(!worker->reading_mail);
 
 	if (!dsync_guid_equals(&worker->get_mailbox, &get->mailbox)) {
@@ -1864,7 +1874,19 @@
 			      DSYNC_MSG_GET_RESULT_FAILED, NULL, get->context);
 	} else {
 		worker->reading_mail = TRUE;
+		if( data.pop3_uidl[0] == '\0' ) {
+			mailbox_get_status(worker->get_mail->box, STATUS_UIDVALIDITY, &status);
+			i_snprintf(uid_valid_str, sizeof(uid_valid_str), "%u", status.uidvalidity);
+			tab[0].value = uid_valid_str;
+			i_snprintf(uid_str, sizeof(uid_str), "%u", get->uid);
+			tab[1].value = uid_str;
+			const struct mail_storage_settings *set = mailbox_get_settings( worker->get_mail->box );
+
+			var_expand(str, set->pop3_uidl_format, tab);
+			data.pop3_uidl = str_c( str );
+		} else
 		data.pop3_uidl = t_strdup(data.pop3_uidl);
+
 		data.input = i_stream_create_limit(data.input, (uoff_t)-1);
 		i_stream_set_destroy_callback(data.input,
 					      local_worker_msg_get_done,

Reply via email to