]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/patches/cyrus-imapd-2.2.12-seenstate.patch
Wir kehren zurueck zu Kudzu, da hwinfo noch mehr Aerger macht.
[people/teissler/ipfire-2.x.git] / src / patches / cyrus-imapd-2.2.12-seenstate.patch
1 # Small patch to Cyrus IMAP 2.2.12 which modifies \Seen state handling to
2 # make it compatible with Outlook Express. OE makes two connections to a
3 # given mailfolder: one generates indexes while the other fetches messages.
4 # Unfortunately it gets confused if \Seen updates caused by the message
5 # stream aren't immediately flushed and picked up by the index stream.
6 #
7 # Apparently Mozilla Thunderbird has the same problem.
8 #
9 # This patch is a 2.2.12 port from the patch found here:
10 # http://www-uxsup.csx.cam.ac.uk/~dpc22/cyrus/patches/2.1.16/seenstate.patch
11 #
12 diff -Naur cyrus-imapd-2.2.12.orig/imap/imapd.c cyrus-imapd-2.2.12/imap/imapd.c
13 --- cyrus-imapd-2.2.12.orig/imap/imapd.c 2005-02-14 07:39:55.000000000 +0100
14 +++ cyrus-imapd-2.2.12/imap/imapd.c 2006-01-04 07:41:45.000000000 +0100
15 @@ -3095,6 +3095,10 @@
16 snprintf(mytime, sizeof(mytime), "%2.3f",
17 (clock() - start) / (double) CLOCKS_PER_SEC);
18
19 + /* Checkpoint \Seen immediately after each FETCH completes. Checks for
20 + * changes from other processes at the same time */
21 + index_check_existing(imapd_mailbox, usinguid, 1);
22 +
23 if (r) {
24 prot_printf(imapd_out, "%s NO %s (%s sec)\r\n", tag,
25 error_message(r), mytime);
26 @@ -3219,7 +3223,8 @@
27
28 index_fetch(imapd_mailbox, msgno, 0, &fetchargs, &fetchedsomething);
29
30 - index_check(imapd_mailbox, 0, 0);
31 + /* Vanilla index_check() can generate illegal EXPUNGE events */
32 + index_check_existing(imapd_mailbox, 0, 1);
33
34 if (fetchedsomething) {
35 prot_printf(imapd_out, "%s OK %s\r\n", tag,
36 @@ -3352,7 +3357,9 @@
37 flag, nflags);
38
39 if (usinguid) {
40 - index_check(imapd_mailbox, 1, 0);
41 + index_check(imapd_mailbox, 1, 1); /* Check \Seen too */
42 + } else {
43 + index_check_existing(imapd_mailbox, 0, 1);
44 }
45
46 if (r) {
47 diff -Naur cyrus-imapd-2.2.12.orig/imap/imapd.h cyrus-imapd-2.2.12/imap/imapd.h
48 --- cyrus-imapd-2.2.12.orig/imap/imapd.h 2004-06-22 23:36:18.000000000 +0200
49 +++ cyrus-imapd-2.2.12/imap/imapd.h 2006-01-04 07:41:45.000000000 +0100
50 @@ -232,6 +232,8 @@
51 extern void index_operatemailbox(struct mailbox *mailbox);
52 extern void index_check(struct mailbox *mailbox, int usinguid,
53 int checkseen);
54 +extern void
55 +index_check_existing(struct mailbox *mailbox, int usinguid, int checkseen);
56 extern void index_checkseen(struct mailbox *mailbox, int quiet,
57 int usinguid, int oldexists);
58
59 diff -Naur cyrus-imapd-2.2.12.orig/imap/index.c cyrus-imapd-2.2.12/imap/index.c
60 --- cyrus-imapd-2.2.12.orig/imap/index.c 2005-02-14 17:42:08.000000000 +0100
61 +++ cyrus-imapd-2.2.12/imap/index.c 2006-01-04 08:08:51.000000000 +0100
62 @@ -425,6 +425,53 @@
63 }
64 }
65
66 +/* Nasty hack to report system + user flags updates without checking for
67 + * new mail or expunge (relies on index atomic rewrite+rename for expunge).
68 + *
69 + * Needed to keep Outlook Express happy without breaking IMAP concurrent
70 + * access regime which (quite correctly) prohibits unsolicited EXPUNGE and
71 + * EXIST responses for non-UID versions of FETCH and STORE. Otherwise you
72 + * can end up with hilarous situations such as:
73 + *
74 + * . FETCH 2 fast
75 + * * EXPUNGE 1 <-- from concurrent session.
76 + * . FETCH (data relating to previous message _3_, if it exists)
77 + *
78 + */
79 +
80 +void
81 +index_check_existing(struct mailbox *mailbox, int usinguid, int checkseen)
82 +{
83 + struct stat sbuf;
84 + int msgno, i;
85 + bit32 user_flags[MAX_USER_FLAGS/32];
86 +
87 + if (imapd_exists == -1)
88 + return;
89 +
90 + /* Bail out if the mailbox was rotated under our feet */
91 + if ((index_len > 0) &&
92 + ((stat(FNAME_INDEX+1, &sbuf) != 0) ||
93 + (sbuf.st_ino != mailbox->index_ino) ||
94 + (index_ino != mailbox->index_ino)))
95 + return;
96 +
97 + if (checkseen)
98 + index_checkseen(mailbox, 0, usinguid, imapd_exists);
99 +
100 + for (msgno = 1; msgno <= imapd_exists; msgno++) {
101 + if (flagreport[msgno] < LAST_UPDATED(msgno)) {
102 + for (i = 0; i < VECTOR_SIZE(user_flags); i++) {
103 + user_flags[i] = USER_FLAGS(msgno, i);
104 + }
105 + index_fetchflags(mailbox, msgno, SYSTEM_FLAGS(msgno), user_flags,
106 + LAST_UPDATED(msgno));
107 + if (usinguid) prot_printf(imapd_out, " UID %u", UID(msgno));
108 + prot_printf(imapd_out, ")\r\n");
109 + }
110 + }
111 +}
112 +
113 /*
114 * Checkpoint the user's \Seen state
115 *
116 @@ -458,6 +505,7 @@
117 char *saveseenuids, *save;
118 int savealloced;
119 unsigned start, newallseen, inrange, usecomma;
120 + mailbox_notifyproc_t *updatenotifier;
121
122 if (!keepingseen || !seendb) return;
123 if (imapd_exists == 0) {
124 @@ -731,6 +779,9 @@
125
126 free(newseenuids);
127 seenuids = saveseenuids;
128 +
129 + updatenotifier = mailbox_get_updatenotifier();
130 + if (updatenotifier) updatenotifier(mailbox);
131 }
132
133
134 diff -Naur cyrus-imapd-2.2.12.orig/imap/mailbox.c cyrus-imapd-2.2.12/imap/mailbox.c
135 --- cyrus-imapd-2.2.12.orig/imap/mailbox.c 2005-02-14 07:39:57.000000000 +0100
136 +++ cyrus-imapd-2.2.12/imap/mailbox.c 2006-01-04 07:41:45.000000000 +0100
137 @@ -230,6 +230,14 @@
138 }
139
140 /*
141 + * Get the updatenotifier function
142 + */
143 +mailbox_notifyproc_t *mailbox_get_updatenotifier(void)
144 +{
145 + return updatenotifier;
146 +}
147 +
148 +/*
149 * Create connection to acappush (obsolete)
150 */
151 int mailbox_initialize(void)
152 diff -Naur cyrus-imapd-2.2.12.orig/imap/mailbox.h cyrus-imapd-2.2.12/imap/mailbox.h
153 --- cyrus-imapd-2.2.12.orig/imap/mailbox.h 2004-01-22 22:17:09.000000000 +0100
154 +++ cyrus-imapd-2.2.12/imap/mailbox.h 2006-01-04 07:41:45.000000000 +0100
155 @@ -224,6 +224,8 @@
156
157 extern void mailbox_set_updatenotifier(mailbox_notifyproc_t *notifyproc);
158
159 +extern mailbox_notifyproc_t *mailbox_get_updatenotifier(void);
160 +
161 extern int mailbox_initialize(void);
162
163 extern char *mailbox_message_fname(struct mailbox *mailbox,