dovecot-2.2: dsync: Fixed syncing message keywords.

dovecot at dovecot.org dovecot at dovecot.org
Thu Jan 31 19:45:41 EET 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/067179cbabc2
changeset: 15700:067179cbabc2
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Jan 31 19:45:33 2013 +0200
description:
dsync: Fixed syncing message keywords.
"add" and "final" can't be mixed together always without causing keywords to
be added back unintentionally.

diffstat:

 src/doveadm/dsync/dsync-mail.h           |   4 +-
 src/doveadm/dsync/dsync-mailbox-export.c |  35 +++++++++++++++++++++----------
 src/doveadm/dsync/dsync-mailbox-import.c |  14 +++++++++---
 3 files changed, 36 insertions(+), 17 deletions(-)

diffs (136 lines):

diff -r 9b7d80a8db44 -r 067179cbabc2 src/doveadm/dsync/dsync-mail.h
--- a/src/doveadm/dsync/dsync-mail.h	Thu Jan 31 19:44:28 2013 +0200
+++ b/src/doveadm/dsync/dsync-mail.h	Thu Jan 31 19:45:33 2013 +0200
@@ -40,6 +40,7 @@
 #define KEYWORD_CHANGE_ADD '+'
 #define KEYWORD_CHANGE_REMOVE '-'
 #define KEYWORD_CHANGE_FINAL '='
+#define KEYWORD_CHANGE_ADD_AND_FINAL '&'
 
 struct dsync_mail_change {
 	enum dsync_mail_change_type type;
@@ -71,8 +72,7 @@
 	   old transaction logs, new ones never reset keywords (just explicitly
 	   remove unwanted keywords) */
 	bool keywords_reset;
-	/* +add, -remove, =final. If the flag is both +added and in =final,
-	   it's not not duplicated as =flag to avoid wasting space. */
+	/* +add, -remove, =final, &add_and_final. */
 	ARRAY_TYPE(const_string) keyword_changes;
 };
 
diff -r 9b7d80a8db44 -r 067179cbabc2 src/doveadm/dsync/dsync-mailbox-export.c
--- a/src/doveadm/dsync/dsync-mailbox-export.c	Thu Jan 31 19:44:28 2013 +0200
+++ b/src/doveadm/dsync/dsync-mailbox-export.c	Thu Jan 31 19:45:33 2013 +0200
@@ -68,20 +68,33 @@
 }
 
 static bool
-final_keyword_check(struct dsync_mail_change *change, const char *name)
+final_keyword_check(struct dsync_mail_change *change, const char *name,
+		    char *type_r)
 {
 	const char *const *changes;
 	unsigned int i, count;
 
+	*type_r = KEYWORD_CHANGE_ADD;
+
 	changes = array_get(&change->keyword_changes, &count);
 	for (i = 0; i < count; i++) {
-		if (strcmp(changes[i]+1, name) == 0) {
-			if (changes[i][0] == KEYWORD_CHANGE_REMOVE) {
-				/* a final keyword is marked as removed.
-				   this shouldn't normally happen. */
-				array_delete(&change->keyword_changes, i, 1);
-				break;
-			}
+		if (strcmp(changes[i]+1, name) != 0)
+			continue;
+
+		switch (changes[i][0]) {
+		case KEYWORD_CHANGE_ADD:
+			/* replace with ADD_AND_FINAL */
+			array_delete(&change->keyword_changes, i, 1);
+			*type_r = KEYWORD_CHANGE_ADD_AND_FINAL;
+			return FALSE;
+		case KEYWORD_CHANGE_REMOVE:
+			/* a final keyword is marked as removed.
+			   this shouldn't normally happen. */
+			array_delete(&change->keyword_changes, i, 1);
+			return FALSE;
+		case KEYWORD_CHANGE_ADD_AND_FINAL:
+		case KEYWORD_CHANGE_FINAL:
+			/* no change */
 			return TRUE;
 		}
 	}
@@ -94,6 +107,7 @@
 {
 	const char *const *keywords;
 	unsigned int i;
+	char type;
 
 	i_assert((change->add_flags & change->remove_flags) == 0);
 
@@ -110,11 +124,10 @@
 	for (i = 0; keywords[i] != NULL; i++) {
 		/* add the final keyword if it's not already there
 		   as +keyword */
-		if (!final_keyword_check(change, keywords[i])) {
+		if (!final_keyword_check(change, keywords[i], &type)) {
 			const char *keyword_change =
 				p_strdup_printf(exporter->pool, "%c%s",
-						KEYWORD_CHANGE_ADD,
-						keywords[i]);
+						type, keywords[i]);
 			array_append(&change->keyword_changes,
 				     &keyword_change, 1);
 		}
diff -r 9b7d80a8db44 -r 067179cbabc2 src/doveadm/dsync/dsync-mailbox-import.c
--- a/src/doveadm/dsync/dsync-mailbox-import.c	Thu Jan 31 19:44:28 2013 +0200
+++ b/src/doveadm/dsync/dsync-mailbox-import.c	Thu Jan 31 19:45:33 2013 +0200
@@ -638,12 +638,16 @@
 		switch (changes[i][0]) {
 		case KEYWORD_CHANGE_ADD:
 			remote_add[name_idx/32] |= 1U << (name_idx%32);
-			/* fall through */
+			break;
+		case KEYWORD_CHANGE_REMOVE:
+			remote_remove[name_idx/32] |= 1U << (name_idx%32);
+			break;
 		case KEYWORD_CHANGE_FINAL:
 			remote_final[name_idx/32] |= 1U << (name_idx%32);
 			break;
-		case KEYWORD_CHANGE_REMOVE:
-			remote_remove[name_idx/32] |= 1U << (name_idx%32);
+		case KEYWORD_CHANGE_ADD_AND_FINAL:
+			remote_add[name_idx/32] |= 1U << (name_idx%32);
+			remote_final[name_idx/32] |= 1U << (name_idx%32);
 			break;
 		}
 	}
@@ -664,6 +668,7 @@
 
 		switch (changes[i][0]) {
 		case KEYWORD_CHANGE_ADD:
+		case KEYWORD_CHANGE_ADD_AND_FINAL:
 			local_add[name_idx/32] |= 1U << (name_idx%32);
 			break;
 		case KEYWORD_CHANGE_REMOVE:
@@ -737,6 +742,7 @@
 		switch (changes[i][0]) {
 		case KEYWORD_CHANGE_ADD:
 		case KEYWORD_CHANGE_FINAL:
+		case KEYWORD_CHANGE_ADD_AND_FINAL:
 			name = changes[i]+1;
 			array_append(&keywords, &name, 1);
 			break;
@@ -1245,7 +1251,7 @@
 	t_array_init(&keywords, count);
 	for (i = 0; i < count; i++) {
 		if (changes[i][0] == KEYWORD_CHANGE_ADD ||
-		    changes[i][0] == KEYWORD_CHANGE_FINAL) {
+		    changes[i][0] == KEYWORD_CHANGE_ADD_AND_FINAL) {
 			const char *name = changes[i]+1;
 
 			array_append(&keywords, &name, 1);


More information about the dovecot-cvs mailing list