[prev in list] [next in list] [prev in thread] [next in thread]
List: cyrus-devel
Subject: Re[2]: Need advice: mailbox-based \Seen flag
From: Boris Lytochkin <boris.lytochkin () e-port ! ru>
Date: 2007-09-02 10:07:01
Message-ID: 139325802.20070902140701 () e-port ! ru
[Download RAW message or body]
Ken,
Thanks for patch!
Here it is full patch (with cyradm patch additions) that works OK on
my imapd 2.3.9 setup. I can not check replication process for now.
Here it is some logs:
cyradm:
localhost> info user.rootmail
{user.rootmail}:
condstore: false
lastpop:
lastupdate: 2-Sep-2007 13:57:45 +0400
partition: default
sharedseen: true
size: 18220
localhost> info user.lytochkin
{user.lytochkin}:
condstore: false
lastpop:
lastupdate: 1-Sep-2007 08:11:08 +0400
partition: default
sharedseen: false
size: 61128298
local6.debug:
Sep 2 13:57:45 svr imaps[7810]: seen_db: user anyone opened /var/imap/user/a/anyone.seen
--
Boris Lytochkin
JCS e-port, Moscow
______________________________________
From: Ken Murchison
Sent: 1 сентября 2007 г., 22:05
To: Boris Lytochkin
Subject: Need advice: mailbox-based \Seen flag
I had some time while waiting for paint to dry, so I whipped up this
quick patch for shared seen state, based on our previous discussions.
It uses a "/vendor/cmu/cyrus-imapd/sharedseen" mailbox annotation,
stored as a mailbox option in the index header, to enable/disable shared
seen state, and stores the shared seen state in "anyone.seen". Note
that this patch is completely untested, although it compiles against
CVS. I also didn't consider replication yet.
Feel free to try this and see if it has the intended behavior. Remember
that the 's' ACL right controls whether a person can change the \Seen
flag on a message.
Boris Lytochkin wrote:
> Hello!
>
> I need an advice in implementing per-mailbox \Seen flag (or 'shared'
> \Seen flag in per-user basis).
>
> For now I want to implement it this way:
> 1) add a new mailbox attribute, say 'sharedseen'
> 2) switch path for .seen file in imap/seen_*.c:seen_getpath() if
> 'sharedseen' flag is set on mailbox.
> 3) changes in replication module?
>
> So, setting 'sharedseen' attribute to mailbox will cause using
> per-mailbox seen-file.
>
> What are weak points of this implementation?
> Is there more correct way to make per-mailbox \Seen flag?
>
>
--
Kenneth Murchison
Systems Programmer
Project Cyrus Developer/Maintainer
Carnegie Mellon University
["sharedseen.patch" (application/octet-stream)]
--- 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<sharedseen>
+
+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<sharedseen>
+
+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<renamemailbox> [C<--partition> I<partition>] I<oldname> I<newname>
--- 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 {
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic