Index: annotate.c =================================================================== RCS file: /afs/andrew/system/cvs/src/cyrus/imap/annotate.c,v retrieving revision 1.36 diff -u -r1.36 annotate.c --- annotate.c 15 Aug 2007 17:20:55 -0000 1.36 +++ annotate.c 1 Sep 2007 18:00:26 -0000 @@ -869,20 +869,20 @@ output_entryatt(ext_mboxname, entry, "", &attrib, fdata); } -static void annotation_get_condstore(const char *int_mboxname, - const char *ext_mboxname, - const char *entry, - struct fetchdata *fdata, - struct mailbox_annotation_rock *mbrock, - void *rock __attribute__((unused))) +static void annotation_get_mailboxopt(const char *int_mboxname, + const char *ext_mboxname, + const char *entry, + struct fetchdata *fdata, + struct mailbox_annotation_rock *mbrock, + void *rock __attribute__((unused))) { struct mailbox mailbox; - int r = 0; + int flag, r = 0; char value[40]; struct annotation_data attrib; - if(!int_mboxname || !ext_mboxname || !fdata || !mbrock) - fatal("annotation_get_condstore called with bad parameters", + if(!int_mboxname || !ext_mboxname || !entry || !fdata || !mbrock) + fatal("annotation_get_mailboxopt called with bad parameters", EC_TEMPFAIL); get_mb_data(int_mboxname, mbrock); @@ -890,6 +890,15 @@ /* 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 { + return; + } + /* Check ACL */ if(!fdata->isadmin && (!mbrock->acl || @@ -906,7 +915,7 @@ } if (!r) { - if (mailbox.options & OPT_IMAP_CONDSTORE) { + if (mailbox.options & flag) { strcpy(value, "true"); } else { strcpy(value, "false"); @@ -1017,7 +1026,9 @@ { "/vendor/cmu/cyrus-imapd/lastpop", BACKEND_ONLY, annotation_get_lastpop, NULL }, { "/vendor/cmu/cyrus-imapd/condstore", BACKEND_ONLY, - annotation_get_condstore, NULL }, + annotation_get_mailboxopt, NULL }, + { "/vendor/cmu/cyrus-imapd/sharedseen", BACKEND_ONLY, + annotation_get_mailboxopt, NULL }, { NULL, ANNOTATION_PROXY_T_INVALID, NULL, NULL } }; @@ -1694,14 +1705,23 @@ return r; } -static int annotation_set_condstore(const char *int_mboxname, - struct annotate_st_entry_list *entry, - struct storedata *sdata, - struct mailbox_annotation_rock *mbrock, - void *rock __attribute__((unused))) +static int annotation_set_mailboxopt(const char *int_mboxname, + struct annotate_st_entry_list *entry, + struct storedata *sdata, + struct mailbox_annotation_rock *mbrock, + void *rock __attribute__((unused))) { struct mailbox mailbox; - int r = 0; + int flag, r = 0; + + /* 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 { + return IMAP_PERMISSION_DENIED; + } /* Check ACL */ if(!sdata->isadmin && @@ -1717,9 +1737,9 @@ if (!r) { if (!strcmp(entry->shared.value, "true")) { - mailbox.options |= OPT_IMAP_CONDSTORE; + mailbox.options |= flag; } else { - mailbox.options &= ~OPT_IMAP_CONDSTORE; + mailbox.options &= ~flag; } r = mailbox_write_index_header(&mailbox); @@ -1793,7 +1813,10 @@ ACL_ADMIN, annotation_set_todb, NULL }, { "/vendor/cmu/cyrus-imapd/condstore", ATTRIB_TYPE_BOOLEAN, BACKEND_ONLY, ATTRIB_VALUE_SHARED | ATTRIB_CONTENTTYPE_SHARED, - ACL_ADMIN, annotation_set_condstore, NULL }, + ACL_ADMIN, annotation_set_mailboxopt, NULL }, + { "/vendor/cmu/cyrus-imapd/sharedseen", ATTRIB_TYPE_BOOLEAN, BACKEND_ONLY, + ATTRIB_VALUE_SHARED | ATTRIB_CONTENTTYPE_SHARED, + ACL_ADMIN, annotation_set_mailboxopt, NULL }, { NULL, 0, ANNOTATION_PROXY_T_INVALID, 0, 0, NULL, NULL } }; Index: append.c =================================================================== RCS file: /afs/andrew/system/cvs/src/cyrus/imap/append.c,v retrieving revision 1.110 diff -u -r1.110 append.c --- append.c 5 Feb 2007 18:41:45 -0000 1.110 +++ append.c 1 Sep 2007 18:00:26 -0000 @@ -1091,7 +1091,9 @@ /* what's the first uid in our new list? */ start = atoi(msgrange); - r = seen_open(mailbox, userid, SEEN_CREATE, &seendb); + r = seen_open(mailbox, + (mailbox->options & OPT_IMAP_SHAREDSEEN) ? "anyone" : userid, + SEEN_CREATE, &seendb); if (r) return r; r = seen_lockread(seendb, &last_read, &last_uid, &last_change, &seenuids); Index: index.c =================================================================== RCS file: /afs/andrew/system/cvs/src/cyrus/imap/index.c,v retrieving revision 1.226 diff -u -r1.226 index.c --- index.c 2 Aug 2007 14:18:52 -0000 1.226 +++ index.c 1 Sep 2007 18:00:26 -0000 @@ -367,7 +367,10 @@ /* If opening mailbox, get \Recent info */ if (oldexists == -1 && mailbox->keepingseen) { - r = seen_open(mailbox, imapd_userid, SEEN_CREATE, &seendb); + r = seen_open(mailbox, + (mailbox->options & OPT_IMAP_SHAREDSEEN) ? "anyone" : + imapd_userid, + SEEN_CREATE, &seendb); if (!r) { free(seenuids); seenuids = NULL; @@ -1481,7 +1484,10 @@ if (mailbox->exists != 0 && (statusitems & (STATUS_RECENT | STATUS_UNSEEN))) { - r = seen_open(mailbox, imapd_userid, SEEN_CREATE, &status_seendb); + r = seen_open(mailbox, + (mailbox->options & OPT_IMAP_SHAREDSEEN) ? "anyone" : + imapd_userid, + SEEN_CREATE, &status_seendb); if (r) return r; r = seen_lockread(status_seendb, &last_read, &last_uid, Index: mailbox.h =================================================================== RCS file: /afs/andrew/system/cvs/src/cyrus/imap/mailbox.h,v retrieving revision 1.83 diff -u -r1.83 mailbox.h --- mailbox.h 30 Aug 2007 14:25:08 -0000 1.83 +++ mailbox.h 1 Sep 2007 18:00:27 -0000 @@ -255,6 +255,7 @@ #define OPT_POP3_NEW_UIDL (1<<0) /* added for Outlook stupidity */ #define OPT_IMAP_CONDSTORE (1<<1) /* added for CONDSTORE extension */ +#define OPT_IMAP_SHAREDSEEN (1<<2) /* added for shared \Seen state */ struct mailbox_header_cache {