Mercurial > dovecot > core-2.2
changeset 15700:067179cbabc2
dsync: Fixed syncing message keywords.
"add" and "final" can't be mixed together always without causing keywords to
be added back unintentionally.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 31 Jan 2013 19:45:33 +0200 |
parents | 9b7d80a8db44 |
children | 61aaf4102761 |
files | src/doveadm/dsync/dsync-mail.h src/doveadm/dsync/dsync-mailbox-export.c src/doveadm/dsync/dsync-mailbox-import.c |
diffstat | 3 files changed, 36 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- 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; };
--- 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); }
--- 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);