[PATCH 09/13] sync all mailbox annotations, not just CONDSTORE

Bron Gondwana brong at fastmail.fm
Tue Jan 27 23:15:36 EST 2009


From: Bron Gondwana <brong at launde.home.brong.net>

Rewrite the mailboxopt annotations to be data driven,
and use the same struct to process ALL annotations on
the mailbox options field during a sync run.  Fixes
duplicatedeliver and sharedseen synchronisation, and
is future-proof.
---
 imap/annotate.c    |   47 ++++++++++++++++++++++++++---------------------
 imap/annotate.h    |    8 ++++++++
 imap/mailbox.h     |    3 ++-
 imap/sync_client.c |   13 +++++++------
 4 files changed, 43 insertions(+), 28 deletions(-)

diff --git a/imap/annotate.c b/imap/annotate.c
index 45db495..1484079 100644
--- a/imap/annotate.c
+++ b/imap/annotate.c
@@ -422,6 +422,17 @@ struct mailbox_annotation_rock
     char *server, *partition, *acl, *path, *mpath;
 };
 
+const struct annotate_info_t annotate_mailbox_flags[] =
+{
+    { "/vendor/cmu/cyrus-imapd/duplicatedeliver",
+      OPT_IMAP_DUPDELIVER },
+    { "/vendor/cmu/cyrus-imapd/sharedseen",
+      OPT_IMAP_SHAREDSEEN },
+    { "/vendor/cmu/cyrus-imapd/condstore",
+      OPT_IMAP_CONDSTORE },
+    { NULL, 0 }
+};
+
 /* To free values in the mailbox_annotation_rock as needed */
 static void cleanup_mbrock(struct mailbox_annotation_rock *mbrock __attribute__((unused))) 
 {
@@ -878,7 +889,7 @@ static void annotation_get_mailboxopt(const char *int_mboxname,
 				      void *rock __attribute__((unused)))
 { 
     struct mailbox mailbox;
-    int flag, r = 0;
+    int flag = 0, r = 0, i;
     char value[40];
     struct annotation_data attrib;
   
@@ -891,16 +902,14 @@ static void annotation_get_mailboxopt(const char *int_mboxname,
     /* Make sure its a local mailbox */
     if (mbrock->server) return;
 
-    /* Check entry */
-    if (!strcmp(entry, "/vendor/cmu/cyrus-imapd/condstore")) {
-	flag = OPT_IMAP_CONDSTORE;
-    } else if (!strcmp(entry, "/vendor/cmu/cyrus-imapd/sharedseen")) {
-	flag = OPT_IMAP_SHAREDSEEN;
-    } else if (!strcmp(entry, "/vendor/cmu/cyrus-imapd/duplicatedeliver")) {
-	flag = OPT_IMAP_DUPDELIVER;
-    } else {
-	return;
+    /* check that this is a mailboxopt annotation */
+    for (i = 0; annotate_mailbox_flags[i].name; i++) {
+	if (!strcmp(entry, annotate_mailbox_flags[i].name)) {
+	    flag = annotate_mailbox_flags[i].flag;
+	    break;
+	}
     }
+    if (!flag) return;
   
     /* Check ACL */
     if(!fdata->isadmin &&
@@ -1717,20 +1726,16 @@ static int annotation_set_mailboxopt(const char *int_mboxname,
 				     void *rock __attribute__((unused)))
 {
     struct mailbox mailbox;
-    int flag, r = 0;
+    int flag = 0, r = 0, i;
 
     /* Check entry */
-    if (!strcmp(entry->entry->name, "/vendor/cmu/cyrus-imapd/condstore")) {
-	flag = OPT_IMAP_CONDSTORE;
-    } else if (!strcmp(entry->entry->name,
-		       "/vendor/cmu/cyrus-imapd/sharedseen")) {
-	flag = OPT_IMAP_SHAREDSEEN;
-    } else if (!strcmp(entry->entry->name,
-		       "/vendor/cmu/cyrus-imapd/duplicatedeliver")) {
-	flag = OPT_IMAP_DUPDELIVER;
-    } else {
-	return IMAP_PERMISSION_DENIED;
+    for (i = 0; annotate_mailbox_flags[i].name; i++) {
+	if (!strcmp(entry->entry->name, annotate_mailbox_flags[i].name)) {
+	    flag = annotate_mailbox_flags[i].flag;
+	    break;
+	}
     }
+    if (!flag) return IMAP_PERMISSION_DENIED;
   
     /* Check ACL */
     if(!sdata->isadmin &&
diff --git a/imap/annotate.h b/imap/annotate.h
index 4482580..5f8d7dc 100644
--- a/imap/annotate.h
+++ b/imap/annotate.h
@@ -119,6 +119,14 @@ struct annotation_data {
     const char *contenttype;
 };
 
+struct annotate_info_t
+{
+    const char *name;
+    int flag;
+};
+
+extern const struct annotate_info_t annotate_mailbox_flags[];
+
 /* lookup a single annotation and return result */
 int annotatemore_lookup(const char *mboxname, const char *entry,
 			const char *userid, struct annotation_data *attrib);
diff --git a/imap/mailbox.h b/imap/mailbox.h
index 066a435..0c6c887 100644
--- a/imap/mailbox.h
+++ b/imap/mailbox.h
@@ -257,11 +257,12 @@ struct index_record {
 #define FLAG_DRAFT (1<<3)
 
 #define OPT_POP3_NEW_UIDL (1<<0)	/* added for Outlook stupidity */
+/* these three are annotations, if you add more, update annotate.c
+ * struct annotate_mailbox_flags */
 #define OPT_IMAP_CONDSTORE (1<<1)	/* added for CONDSTORE extension */
 #define OPT_IMAP_SHAREDSEEN (1<<2)	/* added for shared \Seen flag */
 #define OPT_IMAP_DUPDELIVER (1<<3)	/* added to allow duplicate delivery */
 
-
 struct mailbox_header_cache {
     const char *name; /* Name of header */
     bit32 min_cache_version; /* Cache version it appeared in */
diff --git a/imap/sync_client.c b/imap/sync_client.c
index da6e271..d08f5c4 100644
--- a/imap/sync_client.c
+++ b/imap/sync_client.c
@@ -1828,7 +1828,7 @@ int do_folders(struct sync_folder_list *client_list,
 	       int doing_user)
 {
     struct mailbox m;
-    int r = 0, mailbox_open = 0;
+    int r = 0, mailbox_open = 0, i;
     struct sync_rename_list *rename_list = sync_rename_list_create();
     struct sync_folder   *folder, *folder2;
 
@@ -1978,13 +1978,14 @@ int do_folders(struct sync_folder_list *client_list,
                 if (!r && (m.uidvalidity != folder2->uidvalidity))
                     r = folder_setuidvalidity(folder->name, m.uidvalidity);
 
-                if (!r &&
-                    (folder2->options ^ m.options) & OPT_IMAP_CONDSTORE) {
-                    r = folder_setannotation(m.name,
-					     "/vendor/cmu/cyrus-imapd/condstore",
+		for (i = 0; !r && annotate_mailbox_flags[i].name; i++) {
+		    if ((folder2->options ^ m.options) & annotate_mailbox_flags[i].flag) {
+                    	r = folder_setannotation(m.name,
+					     annotate_mailbox_flags[i].name,
 					     "",
-					     (m.options & OPT_IMAP_CONDSTORE) ?
+					     (m.options & annotate_mailbox_flags[i].flag) ?
 					     "true" : "false");
+		    }
 		}
 
 		if (!r && m.quota.root && !strcmp(m.name, m.quota.root))
-- 
1.5.6.3



More information about the Cyrus-devel mailing list