--- perl/imap/IMAP/Admin.pm Thu Nov 30 20:11:23 2006 +++ perl/imap/IMAP/Admin.pm Sat Sep 1 11:57:16 2007 @@ -788,6 +788,7 @@ "news2mail" => "/vendor/cmu/cyrus-imapd/news2mail", "expire" => "/vendor/cmu/cyrus-imapd/expire", "sieve" => "/vendor/cmu/cyrus-imapd/sieve", + "sharedseen" => "/vendor/cmu/cyrus-imapd/sharedseen", "squat" => "/vendor/cmu/cyrus-imapd/squat" ); if(!$self->{support_annotatemore}) { --- perl/imap/IMAP/Shell.pm Thu Nov 30 20:11:24 2006 +++ perl/imap/IMAP/Shell.pm Sat Sep 1 11:57:16 2007 @@ -126,7 +126,7 @@ [\&_sc_info, '[mailbox]', 'display mailbox/server metadata'], mboxcfg => - [\&_sc_mboxcfg, 'mailbox [comment|condstore|news2mail|expire|sieve|squat] value', + [\&_sc_mboxcfg, 'mailbox [comment|condstore|news2mail|expire|sieve|sharedseen|squat] value', 'configure mailbox'], mboxconfig => 'mboxcfg', reconstruct => @@ -1424,7 +1424,7 @@ while (defined ($opt = shift(@argv))) { last if $opt eq '--'; if ($opt =~ /^-/) { - die "usage: mboxconfig mailbox [comment|condstore|news2mail|expire|sieve|squat] value\n"; + die "usage: mboxconfig mailbox [comment|condstore|news2mail|expire|sieve|sharedseen|squat] value\n"; } else { push(@nargv, $opt); @@ -1433,7 +1433,7 @@ } push(@nargv, @argv); if (@nargv < 2) { - die "usage: mboxconfig mailbox [comment|condstore|news2mail|expire|sieve|squat] value\n"; + die "usage: mboxconfig mailbox [comment|condstore|news2mail|expire|sieve|sharedseen|squat] value\n"; } if (!$cyrref || !$$cyrref) { die "mboxconfig: no connection to server\n"; @@ -1685,6 +1685,11 @@ Sets an email address to which messages injected into the server via NNTP will be sent. + +=item C + +Indicates that shared seendb must be used for this mailbox instead of per-user. +This enables sharing \Seen flag with all users that have ACLs to use this mailbox. =back --- perl/imap/cyradm.sh Thu Nov 30 20:11:23 2006 +++ perl/imap/cyradm.sh Sat Sep 1 11:57:16 2007 @@ -235,6 +235,11 @@ Sets an email address to which messages injected into the server via NNTP will be sent. +=item C + +Indicates that shared seendb must be used for this mailbox instead of per-user. +This enables sharing \Seen flag with all users that have ACLs to use this mailbox. + =back =item C [C<--partition> I] I I --- imap/annotate.c 15 Aug 2007 17:20:55 -0000 +++ imap/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 } }; --- imap/append.c 5 Feb 2007 18:41:45 -0000 1.110 +++ imap/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); --- imap/index.c 2 Aug 2007 14:18:52 -0000 1.226 +++ imap/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, --- imap/mailbox.h 30 Aug 2007 14:25:08 -0000 1.83 +++ imap/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 {