[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