imap4d: speed up asynchronous mailbox notifications.
* imap4d/imap4d.h (util_format_attribute_flags): New prototype. * imap4d/sync.c: Rewrite using flag table to keep attribute flags, mu_mailbox_translate to convert uids to message numbers and MU_EVT_MAILBOX_MESSAGE_EXPUNGE event to report expunged messages. * imap4d/util.c (_imap4d_attrlist): Remove \Recent (util_attribute_to_type): Handle \Recent separately. (util_format_attribute_flags): New function. (util_print_flags): Rewrite as an extra entry point to the above. mailboxes: New event MU_EVT_MAILBOX_MESSAGE_EXPUNGE. * include/mailutils/observer.h: Rearrange and partially rename event constants (all uses updated): MU_EVT_MESSAGE_APPEND => MU_EVT_MAILBOX_MESSAGE_APPEND MU_EVT_AUTHORITY_FAILED => MU_EVT_FOLDER_AUTHORITY_FAILED (MU_EVT_MAILBOX_MESSAGE_EXPUNGE): New event. * libproto/mbox/mbox.c: Generate MU_EVT_MAILBOX_MESSAGE_EXPUNGE. * libproto/pop/mbox.c: Likewise. * libmailutils/base/amd.c: Likewise.
Showing
10 changed files
with
141 additions
and
258 deletions
... | @@ -370,6 +370,7 @@ extern char *util_localname (void); | ... | @@ -370,6 +370,7 @@ extern char *util_localname (void); |
370 | 370 | ||
371 | extern int util_wcard_match (const char *string, const char *pattern, | 371 | extern int util_wcard_match (const char *string, const char *pattern, |
372 | const char *delim); | 372 | const char *delim); |
373 | int util_format_attribute_flags (mu_stream_t str, int flags); | ||
373 | void util_print_flags (mu_attribute_t attr); | 374 | void util_print_flags (mu_attribute_t attr); |
374 | int util_attribute_to_type (const char *item, int *type); | 375 | int util_attribute_to_type (const char *item, int *type); |
375 | int util_type_to_attribute (int type, char **attr_str); | 376 | int util_type_to_attribute (int type, char **attr_str); | ... | ... |
... | @@ -21,163 +21,24 @@ | ... | @@ -21,163 +21,24 @@ |
21 | /* | 21 | /* |
22 | 22 | ||
23 | */ | 23 | */ |
24 | struct _uid_table | 24 | static int *attr_table; |
25 | { | 25 | static size_t attr_table_count; |
26 | size_t uid; | 26 | static int attr_table_loaded; |
27 | size_t msgno; | ||
28 | int notify; | ||
29 | mu_attribute_t attr; | ||
30 | }; | ||
31 | |||
32 | static struct _uid_table *uid_table; | ||
33 | static size_t uid_table_count; | ||
34 | static int uid_table_loaded; | ||
35 | |||
36 | static void | ||
37 | add_flag (char **pbuf, const char *f) | ||
38 | { | ||
39 | char *abuf = *pbuf; | ||
40 | abuf = realloc (abuf, strlen (abuf) + strlen (f) + 2); | ||
41 | if (abuf == NULL) | ||
42 | imap4d_bye (ERR_NO_MEM); | ||
43 | if (*abuf) | ||
44 | strcat (abuf, " "); | ||
45 | strcat (abuf, "\\Seen"); | ||
46 | *pbuf = abuf; | ||
47 | } | ||
48 | |||
49 | static void | ||
50 | notify_flag (size_t msgno, mu_attribute_t oattr) | ||
51 | { | ||
52 | mu_message_t msg = NULL; | ||
53 | mu_attribute_t nattr = NULL; | ||
54 | int status ; | ||
55 | mu_mailbox_get_message (mbox, msgno, &msg); | ||
56 | mu_message_get_attribute (msg, &nattr); | ||
57 | status = mu_attribute_is_equal (oattr, nattr); | ||
58 | |||
59 | if (status == 0) | ||
60 | { | ||
61 | char *abuf = malloc (1);; | ||
62 | if (!abuf) | ||
63 | imap4d_bye (ERR_NO_MEM); | ||
64 | *abuf = '\0'; | ||
65 | if (mu_attribute_is_seen (nattr) && mu_attribute_is_read (nattr)) | ||
66 | if (!mu_attribute_is_seen (oattr) && !mu_attribute_is_read (oattr)) | ||
67 | { | ||
68 | mu_attribute_set_seen (oattr); | ||
69 | mu_attribute_set_read (oattr); | ||
70 | add_flag (&abuf, "\\Seen"); | ||
71 | } | ||
72 | if (mu_attribute_is_answered (nattr)) | ||
73 | if (!mu_attribute_is_answered (oattr)) | ||
74 | { | ||
75 | mu_attribute_set_answered (oattr); | ||
76 | add_flag (&abuf, "\\Answered"); | ||
77 | } | ||
78 | if (mu_attribute_is_flagged (nattr)) | ||
79 | if (!mu_attribute_is_flagged (oattr)) | ||
80 | { | ||
81 | mu_attribute_set_flagged (oattr); | ||
82 | add_flag (&abuf, "\\Flagged"); | ||
83 | } | ||
84 | if (mu_attribute_is_deleted (nattr)) | ||
85 | if (!mu_attribute_is_deleted (oattr)) | ||
86 | { | ||
87 | mu_attribute_set_deleted (oattr); | ||
88 | add_flag (&abuf, "\\Deleted"); | ||
89 | } | ||
90 | if (mu_attribute_is_draft (nattr)) | ||
91 | if (!mu_attribute_is_draft (oattr)) | ||
92 | { | ||
93 | mu_attribute_set_draft (oattr); | ||
94 | add_flag (&abuf, "\\Draft"); | ||
95 | } | ||
96 | if (mu_attribute_is_recent (nattr)) | ||
97 | if (!mu_attribute_is_recent (oattr)) | ||
98 | { | ||
99 | mu_attribute_set_recent (oattr); | ||
100 | add_flag (&abuf, "\\Recent"); | ||
101 | } | ||
102 | if (*abuf) | ||
103 | io_untagged_response (RESP_NONE, "%lu FETCH FLAGS (%s)", | ||
104 | (unsigned long) msgno, abuf); | ||
105 | free (abuf); | ||
106 | } | ||
107 | } | ||
108 | |||
109 | /* The EXPUNGE response reports that the specified message sequence | ||
110 | number has been permanently removed from the mailbox. The message | ||
111 | sequence number for each successive message in the mailbox is | ||
112 | immediately decremented by 1, and this decrement is reflected in | ||
113 | message sequence numbers in subsequent responses (including other | ||
114 | untagged EXPUNGE responses). */ | ||
115 | static void | ||
116 | notify_deleted (void) | ||
117 | { | ||
118 | if (uid_table) | ||
119 | { | ||
120 | size_t i; | ||
121 | size_t decr = 0; | ||
122 | for (i = 0; i < uid_table_count; i++) | ||
123 | { | ||
124 | if (!(uid_table[i].notify)) | ||
125 | { | ||
126 | io_untagged_response (RESP_NONE, "%lu EXPUNGED", | ||
127 | (unsigned long) uid_table[i].msgno-decr); | ||
128 | uid_table[i].notify = 1; | ||
129 | decr++; | ||
130 | } | ||
131 | } | ||
132 | } | ||
133 | } | ||
134 | |||
135 | |||
136 | static int | ||
137 | notify_uid (size_t uid) | ||
138 | { | ||
139 | if (uid_table) | ||
140 | { | ||
141 | size_t i; | ||
142 | for (i = 0; i < uid_table_count; i++) | ||
143 | { | ||
144 | if (uid_table[i].uid == uid) | ||
145 | { | ||
146 | notify_flag (uid_table[i].msgno, uid_table[i].attr); | ||
147 | uid_table[i].notify = 1; | ||
148 | return 1; | ||
149 | } | ||
150 | } | ||
151 | } | ||
152 | return 0; | ||
153 | } | ||
154 | 27 | ||
155 | static void | 28 | static void |
156 | free_uids (void) | 29 | free_uids (void) |
157 | { | 30 | { |
158 | if (uid_table) | 31 | if (attr_table) |
159 | { | 32 | { |
160 | size_t i; | 33 | free (attr_table); |
161 | for (i = 0; i < uid_table_count; i++) | 34 | attr_table = NULL; |
162 | mu_attribute_destroy (&(uid_table[i].attr), NULL); | ||
163 | free (uid_table); | ||
164 | uid_table = NULL; | ||
165 | } | 35 | } |
166 | uid_table_count = 0; | 36 | attr_table_count = 0; |
167 | uid_table_loaded = 0; | 37 | attr_table_loaded = 0; |
168 | } | ||
169 | |||
170 | static void | ||
171 | reset_notify (void) | ||
172 | { | ||
173 | size_t i; | ||
174 | |||
175 | for (i = 0; i < uid_table_count; i++) | ||
176 | uid_table[i].notify = 0; | ||
177 | } | 38 | } |
178 | 39 | ||
179 | static void | 40 | static void |
180 | reset_uids (void) | 41 | reread_attributes (void) |
181 | { | 42 | { |
182 | size_t total = 0; | 43 | size_t total = 0; |
183 | size_t i; | 44 | size_t i; |
... | @@ -185,26 +46,24 @@ reset_uids (void) | ... | @@ -185,26 +46,24 @@ reset_uids (void) |
185 | free_uids (); | 46 | free_uids (); |
186 | 47 | ||
187 | mu_mailbox_messages_count (mbox, &total); | 48 | mu_mailbox_messages_count (mbox, &total); |
49 | if (total > attr_table_count) | ||
50 | { | ||
51 | attr_table = realloc (attr_table, sizeof (*attr_table) * total); | ||
52 | if (!attr_table) | ||
53 | imap4d_bye (ERR_NO_MEM); | ||
54 | attr_table_count = total; | ||
55 | } | ||
56 | |||
188 | for (i = 1; i <= total; i++) | 57 | for (i = 1; i <= total; i++) |
189 | { | 58 | { |
190 | mu_message_t msg = NULL; | 59 | mu_message_t msg = NULL; |
191 | mu_attribute_t attr = NULL; | 60 | mu_attribute_t attr = NULL; |
192 | size_t uid = 0; | 61 | |
193 | uid_table = realloc (uid_table, sizeof (*uid_table) * | ||
194 | (uid_table_count + 1)); | ||
195 | if (!uid_table) | ||
196 | imap4d_bye (ERR_NO_MEM); | ||
197 | mu_mailbox_get_message (mbox, i, &msg); | 62 | mu_mailbox_get_message (mbox, i, &msg); |
198 | mu_message_get_attribute (msg, &attr); | 63 | mu_message_get_attribute (msg, &attr); |
199 | mu_message_get_uid (msg, &uid); | 64 | mu_attribute_get_flags (attr, &attr_table[i-1]); |
200 | uid_table[uid_table_count].uid = uid; | ||
201 | uid_table[uid_table_count].msgno = i; | ||
202 | uid_table[uid_table_count].notify = 0; | ||
203 | mu_attribute_create (&(uid_table[uid_table_count].attr), NULL); | ||
204 | mu_attribute_copy (uid_table[uid_table_count].attr, attr); | ||
205 | uid_table_count++; | ||
206 | } | 65 | } |
207 | uid_table_loaded = 1; | 66 | attr_table_loaded = 1; |
208 | } | 67 | } |
209 | 68 | ||
210 | static void | 69 | static void |
... | @@ -216,25 +75,34 @@ notify (void) | ... | @@ -216,25 +75,34 @@ notify (void) |
216 | 75 | ||
217 | mu_mailbox_messages_count (mbox, &total); | 76 | mu_mailbox_messages_count (mbox, &total); |
218 | 77 | ||
219 | if (!uid_table) | 78 | if (!attr_table) |
220 | { | 79 | { |
221 | reset = 1; | 80 | reset = 1; |
222 | reset_uids (); | 81 | reread_attributes (); |
82 | mu_mailbox_messages_recent (mbox, &recent); | ||
223 | } | 83 | } |
224 | 84 | else if (attr_table) | |
225 | if (uid_table) | ||
226 | { | 85 | { |
227 | size_t i; | 86 | size_t i; |
228 | 87 | ||
229 | for (i = 1; i <= total; i++) | 88 | for (i = 1; i <= total; i++) |
230 | { | 89 | { |
231 | mu_message_t msg = NULL; | 90 | mu_message_t msg = NULL; |
232 | size_t uid = 0; | 91 | mu_attribute_t nattr = NULL; |
92 | int nflags; | ||
93 | |||
233 | mu_mailbox_get_message (mbox, i, &msg); | 94 | mu_mailbox_get_message (mbox, i, &msg); |
234 | mu_message_get_uid (msg, &uid); | 95 | mu_message_get_attribute (msg, &nattr); |
235 | notify_uid (uid); | 96 | mu_attribute_get_flags (nattr, &nflags); |
97 | |||
98 | if (nflags != attr_table[i-1]) | ||
99 | { | ||
100 | io_sendf ("* %lu FETCH FLAGS (", (unsigned long) i); | ||
101 | util_format_attribute_flags (iostream, nflags); | ||
102 | io_sendf (")\n"); | ||
103 | attr_table[i-1] = nflags; | ||
104 | } | ||
236 | } | 105 | } |
237 | notify_deleted (); | ||
238 | mu_mailbox_messages_recent (mbox, &recent); | 106 | mu_mailbox_messages_recent (mbox, &recent); |
239 | } | 107 | } |
240 | 108 | ||
... | @@ -242,35 +110,28 @@ notify (void) | ... | @@ -242,35 +110,28 @@ notify (void) |
242 | io_untagged_response (RESP_NONE, "%lu RECENT", (unsigned long) recent); | 110 | io_untagged_response (RESP_NONE, "%lu RECENT", (unsigned long) recent); |
243 | 111 | ||
244 | if (!reset) | 112 | if (!reset) |
245 | reset_uids (); | 113 | reread_attributes (); |
246 | else | ||
247 | reset_notify (); | ||
248 | } | 114 | } |
249 | 115 | ||
250 | size_t | 116 | size_t |
251 | uid_to_msgno (size_t uid) | 117 | uid_to_msgno (size_t uid) |
252 | { | 118 | { |
253 | size_t i; | 119 | size_t msgno; |
254 | for (i = 0; i < uid_table_count; i++) | 120 | mu_mailbox_translate (mbox, MU_MAILBOX_UID_TO_MSGNO, uid, &msgno); |
255 | if (uid_table[i].uid == uid) | 121 | return msgno; |
256 | return uid_table[i].msgno; | ||
257 | return 0; | ||
258 | } | 122 | } |
259 | 123 | ||
260 | int | 124 | int |
261 | imap4d_sync_flags (size_t msgno) | 125 | imap4d_sync_flags (size_t msgno) |
262 | { | 126 | { |
263 | size_t i; | 127 | if (attr_table) |
264 | for (i = 0; i < uid_table_count; i++) | 128 | { |
265 | if (uid_table[i].msgno == msgno) | 129 | mu_message_t msg = NULL; |
266 | { | 130 | mu_attribute_t attr = NULL; |
267 | mu_message_t msg = NULL; | 131 | mu_mailbox_get_message (mbox, msgno, &msg); |
268 | mu_attribute_t attr = NULL; | 132 | mu_message_get_attribute (msg, &attr); |
269 | mu_mailbox_get_message (mbox, msgno, &msg); | 133 | mu_attribute_get_flags (attr, &attr_table[msgno-1]); |
270 | mu_message_get_attribute (msg, &attr); | 134 | } |
271 | mu_attribute_copy (uid_table[i].attr, attr); | ||
272 | break; | ||
273 | } | ||
274 | return 0; | 135 | return 0; |
275 | } | 136 | } |
276 | 137 | ||
... | @@ -288,6 +149,19 @@ action (mu_observer_t observer, size_t type, void *data, void *action_data) | ... | @@ -288,6 +149,19 @@ action (mu_observer_t observer, size_t type, void *data, void *action_data) |
288 | case MU_EVT_MAILBOX_DESTROY: | 149 | case MU_EVT_MAILBOX_DESTROY: |
289 | mailbox_corrupt = 0; | 150 | mailbox_corrupt = 0; |
290 | break; | 151 | break; |
152 | |||
153 | case MU_EVT_MAILBOX_MESSAGE_EXPUNGE: | ||
154 | /* The EXPUNGE response reports that the specified message sequence | ||
155 | number has been permanently removed from the mailbox. The message | ||
156 | sequence number for each successive message in the mailbox is | ||
157 | immediately decremented by 1, and this decrement is reflected in | ||
158 | message sequence numbers in subsequent responses (including other | ||
159 | untagged EXPUNGE responses). */ | ||
160 | { | ||
161 | size_t *exp = data; | ||
162 | io_untagged_response (RESP_NONE, "%lu EXPUNGED", | ||
163 | (unsigned long) (exp[0] - exp[1])); | ||
164 | } | ||
291 | } | 165 | } |
292 | return 0; | 166 | return 0; |
293 | } | 167 | } |
... | @@ -301,8 +175,11 @@ imap4d_set_observer (mu_mailbox_t mbox) | ... | @@ -301,8 +175,11 @@ imap4d_set_observer (mu_mailbox_t mbox) |
301 | mu_observer_create (&observer, mbox); | 175 | mu_observer_create (&observer, mbox); |
302 | mu_observer_set_action (observer, action, mbox); | 176 | mu_observer_set_action (observer, action, mbox); |
303 | mu_mailbox_get_observable (mbox, &observable); | 177 | mu_mailbox_get_observable (mbox, &observable); |
304 | mu_observable_attach (observable, MU_EVT_MAILBOX_CORRUPT|MU_EVT_MAILBOX_DESTROY, | 178 | mu_observable_attach (observable, |
305 | observer); | 179 | MU_EVT_MAILBOX_CORRUPT| |
180 | MU_EVT_MAILBOX_DESTROY| | ||
181 | MU_EVT_MAILBOX_MESSAGE_EXPUNGE, | ||
182 | observer); | ||
306 | mailbox_corrupt = 0; | 183 | mailbox_corrupt = 0; |
307 | } | 184 | } |
308 | 185 | ||
... | @@ -314,7 +191,7 @@ imap4d_sync (void) | ... | @@ -314,7 +191,7 @@ imap4d_sync (void) |
314 | If it was a close we do not send any notification. */ | 191 | If it was a close we do not send any notification. */ |
315 | if (mbox == NULL) | 192 | if (mbox == NULL) |
316 | free_uids (); | 193 | free_uids (); |
317 | else if (!uid_table_loaded || !mu_mailbox_is_updated (mbox)) | 194 | else if (!attr_table_loaded || !mu_mailbox_is_updated (mbox)) |
318 | { | 195 | { |
319 | if (mailbox_corrupt) | 196 | if (mailbox_corrupt) |
320 | { | 197 | { |
... | @@ -338,7 +215,7 @@ imap4d_sync (void) | ... | @@ -338,7 +215,7 @@ imap4d_sync (void) |
338 | { | 215 | { |
339 | size_t count = 0; | 216 | size_t count = 0; |
340 | mu_mailbox_messages_count (mbox, &count); | 217 | mu_mailbox_messages_count (mbox, &count); |
341 | if (count != uid_table_count) | 218 | if (count != attr_table_count) |
342 | notify (); | 219 | notify (); |
343 | } | 220 | } |
344 | return 0; | 221 | return 0; | ... | ... |
... | @@ -402,8 +402,7 @@ _imap4d_attrlist[] = | ... | @@ -402,8 +402,7 @@ _imap4d_attrlist[] = |
402 | { "\\Flagged", MU_ATTRIBUTE_FLAGGED }, | 402 | { "\\Flagged", MU_ATTRIBUTE_FLAGGED }, |
403 | { "\\Deleted", MU_ATTRIBUTE_DELETED }, | 403 | { "\\Deleted", MU_ATTRIBUTE_DELETED }, |
404 | { "\\Draft", MU_ATTRIBUTE_DRAFT }, | 404 | { "\\Draft", MU_ATTRIBUTE_DRAFT }, |
405 | { "\\Seen", MU_ATTRIBUTE_READ }, | 405 | { "\\Seen", MU_ATTRIBUTE_SEEN|MU_ATTRIBUTE_READ }, |
406 | { "\\Recent", MU_ATTRIBUTE_RECENT }, | ||
407 | }; | 406 | }; |
408 | 407 | ||
409 | #define NATTR sizeof(_imap4d_attrlist)/sizeof(_imap4d_attrlist[0]) | 408 | #define NATTR sizeof(_imap4d_attrlist)/sizeof(_imap4d_attrlist[0]) |
... | @@ -414,6 +413,13 @@ int | ... | @@ -414,6 +413,13 @@ int |
414 | util_attribute_to_type (const char *item, int *type) | 413 | util_attribute_to_type (const char *item, int *type) |
415 | { | 414 | { |
416 | int i; | 415 | int i; |
416 | |||
417 | if (mu_c_strcasecmp (item, "\\Recent") == 0) | ||
418 | { | ||
419 | *type = MU_ATTRIBUTE_RECENT; | ||
420 | return 0; | ||
421 | } | ||
422 | |||
417 | for (i = 0; i < _imap4d_nattr; i++) | 423 | for (i = 0; i < _imap4d_nattr; i++) |
418 | if (mu_c_strcasecmp (item, _imap4d_attrlist[i].name) == 0) | 424 | if (mu_c_strcasecmp (item, _imap4d_attrlist[i].name) == 0) |
419 | { | 425 | { |
... | @@ -423,68 +429,38 @@ util_attribute_to_type (const char *item, int *type) | ... | @@ -423,68 +429,38 @@ util_attribute_to_type (const char *item, int *type) |
423 | return 1; | 429 | return 1; |
424 | } | 430 | } |
425 | 431 | ||
426 | /* Note: currently unused. Not needed, possibly? */ | ||
427 | int | 432 | int |
428 | util_type_to_attribute (int type, char **attr_str) | 433 | util_format_attribute_flags (mu_stream_t str, int flags) |
429 | { | 434 | { |
430 | char *attr_list[NATTR]; | ||
431 | int nattr = 0; | ||
432 | int i; | 435 | int i; |
433 | size_t len = 0; | 436 | int delim = 0; |
434 | 437 | ||
435 | if (MU_ATTRIBUTE_IS_UNSEEN (type)) | ||
436 | *attr_str = strdup ("\\Recent"); | ||
437 | else | ||
438 | *attr_str = NULL; | ||
439 | |||
440 | for (i = 0; i < _imap4d_nattr; i++) | 438 | for (i = 0; i < _imap4d_nattr; i++) |
441 | if (type & _imap4d_attrlist[i].flag) | 439 | if (flags & _imap4d_attrlist[i].flag) |
442 | { | 440 | { |
443 | attr_list[nattr++] = _imap4d_attrlist[i].name; | 441 | if (delim) |
444 | len += 1 + strlen (_imap4d_attrlist[i].name); | 442 | mu_stream_printf (str, " "); |
443 | mu_stream_printf (str, "%s", _imap4d_attrlist[i].name); | ||
444 | delim = 1; | ||
445 | } | 445 | } |
446 | 446 | ||
447 | *attr_str = malloc (len + 1); | 447 | if (MU_ATTRIBUTE_IS_UNSEEN (flags)) |
448 | (*attr_str)[0] = 0; | ||
449 | if (*attr_str) | ||
450 | { | 448 | { |
451 | for (i = 0; i < nattr; i++) | 449 | if (delim) |
452 | { | 450 | mu_stream_printf (str, " "); |
453 | strcat (*attr_str, attr_list[i]); | 451 | mu_stream_printf (str, "\\Recent"); |
454 | if (i != nattr - 1) | ||
455 | strcat (*attr_str, " "); | ||
456 | } | ||
457 | } | 452 | } |
458 | 453 | ||
459 | if (!*attr_str) | ||
460 | imap4d_bye (ERR_NO_MEM); | ||
461 | return 0; | 454 | return 0; |
462 | } | 455 | } |
463 | 456 | ||
464 | void | 457 | void |
465 | util_print_flags (mu_attribute_t attr) | 458 | util_print_flags (mu_attribute_t attr) |
466 | { | 459 | { |
467 | int i; | ||
468 | int flags = 0; | 460 | int flags = 0; |
469 | int space = 0; | ||
470 | 461 | ||
471 | mu_attribute_get_flags (attr, &flags); | 462 | mu_attribute_get_flags (attr, &flags); |
472 | for (i = 0; i < _imap4d_nattr; i++) | 463 | util_format_attribute_flags (iostream, flags); |
473 | if (flags & _imap4d_attrlist[i].flag) | ||
474 | { | ||
475 | if (space) | ||
476 | io_sendf (" "); | ||
477 | else | ||
478 | space = 1; | ||
479 | io_sendf (_imap4d_attrlist[i].name); | ||
480 | } | ||
481 | |||
482 | if (MU_ATTRIBUTE_IS_UNSEEN (flags)) | ||
483 | { | ||
484 | if (space) | ||
485 | io_sendf (" "); | ||
486 | io_sendf ("\\Recent"); | ||
487 | } | ||
488 | } | 464 | } |
489 | 465 | ||
490 | int | 466 | int | ... | ... |
... | @@ -24,17 +24,26 @@ | ... | @@ -24,17 +24,26 @@ |
24 | #ifdef __cplusplus | 24 | #ifdef __cplusplus |
25 | extern "C" { | 25 | extern "C" { |
26 | #endif | 26 | #endif |
27 | /* Call data type: */ | 27 | /* Mailbox events */ |
28 | #define MU_EVT_MAILBOX_DESTROY 0x001 /* mu_mailbox_t */ | 28 | /* Call data type: */ |
29 | #define MU_EVT_FOLDER_DESTROY 0x002 /* mu_folder_t */ | 29 | #define MU_EVT_MAILBOX_DESTROY 0x001 /* mu_mailbox_t */ |
30 | #define MU_EVT_MAILER_DESTROY 0x004 /* mu_mailer_t */ | 30 | #define MU_EVT_MAILBOX_PROGRESS 0x002 /* NULL: FIXME? */ |
31 | #define MU_EVT_MESSAGE_DESTROY 0x008 /* mu_message_t */ | 31 | #define MU_EVT_MAILBOX_CORRUPT 0x004 /* mu_mailbox_t */ |
32 | #define MU_EVT_MESSAGE_ADD 0x010 /* size_t *: FIXME */ | 32 | #define MU_EVT_MAILBOX_MESSAGE_APPEND 0x008 /* mu_message_qid_t: FIXME */ |
33 | #define MU_EVT_MAILBOX_PROGRESS 0x020 /* NULL: FIXME? */ | 33 | #define MU_EVT_MAILBOX_MESSAGE_EXPUNGE 0x010 /* size_t [2] |
34 | #define MU_EVT_AUTHORITY_FAILED 0x030 /* NULL */ | 34 | (message number/number of |
35 | #define MU_EVT_MAILBOX_CORRUPT 0x040 /* mu_mailbox_t */ | 35 | messages removed so far) */ |
36 | #define MU_EVT_MAILER_MESSAGE_SENT 0x080 /* mu_message_t */ | 36 | /* Folder events */ |
37 | #define MU_EVT_MESSAGE_APPEND 0x100 /* mu_message_qid_t: FIXME */ | 37 | #define MU_EVT_FOLDER_DESTROY 0x020 /* mu_folder_t */ |
38 | #define MU_EVT_FOLDER_AUTHORITY_FAILED 0x040 /* NULL */ | ||
39 | |||
40 | /* Message events */ | ||
41 | #define MU_EVT_MESSAGE_DESTROY 0x080 /* mu_message_t */ | ||
42 | #define MU_EVT_MESSAGE_ADD 0x100 /* size_t *: FIXME */ | ||
43 | |||
44 | /* Mailer events */ | ||
45 | #define MU_EVT_MAILER_DESTROY 0x200 /* mu_mailer_t */ | ||
46 | #define MU_EVT_MAILER_MESSAGE_SENT 0x400 /* mu_message_t */ | ||
38 | 47 | ||
39 | #define MU_OBSERVER_NO_CHECK 1 | 48 | #define MU_OBSERVER_NO_CHECK 1 |
40 | 49 | ... | ... |
... | @@ -900,7 +900,8 @@ amd_append_message (mu_mailbox_t mailbox, mu_message_t msg) | ... | @@ -900,7 +900,8 @@ amd_append_message (mu_mailbox_t mailbox, mu_message_t msg) |
900 | char *qid; | 900 | char *qid; |
901 | if (amd->cur_msg_file_name (mhm, &qid) == 0) | 901 | if (amd->cur_msg_file_name (mhm, &qid) == 0) |
902 | { | 902 | { |
903 | mu_observable_notify (mailbox->observable, MU_EVT_MESSAGE_APPEND, | 903 | mu_observable_notify (mailbox->observable, |
904 | MU_EVT_MAILBOX_MESSAGE_APPEND, | ||
904 | qid); | 905 | qid); |
905 | free (qid); | 906 | free (qid); |
906 | } | 907 | } |
... | @@ -1148,6 +1149,7 @@ amd_expunge (mu_mailbox_t mailbox) | ... | @@ -1148,6 +1149,7 @@ amd_expunge (mu_mailbox_t mailbox) |
1148 | struct _amd_message *mhm; | 1149 | struct _amd_message *mhm; |
1149 | size_t i; | 1150 | size_t i; |
1150 | int updated = amd->has_new_msg; | 1151 | int updated = amd->has_new_msg; |
1152 | size_t expcount = 0; | ||
1151 | 1153 | ||
1152 | if (amd == NULL) | 1154 | if (amd == NULL) |
1153 | return EINVAL; | 1155 | return EINVAL; |
... | @@ -1175,9 +1177,15 @@ amd_expunge (mu_mailbox_t mailbox) | ... | @@ -1175,9 +1177,15 @@ amd_expunge (mu_mailbox_t mailbox) |
1175 | 1177 | ||
1176 | if (amd->delete_msg) | 1178 | if (amd->delete_msg) |
1177 | { | 1179 | { |
1180 | size_t expevt[2] = { i + 1, expcount }; | ||
1178 | rc = amd->delete_msg (amd, mhm); | 1181 | rc = amd->delete_msg (amd, mhm); |
1179 | if (rc) | 1182 | if (rc) |
1180 | return rc; | 1183 | return rc; |
1184 | |||
1185 | mu_observable_notify (mailbox->observable, | ||
1186 | MU_EVT_MAILBOX_MESSAGE_EXPUNGE, | ||
1187 | expevt); | ||
1188 | ++expcount; | ||
1181 | } | 1189 | } |
1182 | else | 1190 | else |
1183 | { | 1191 | { | ... | ... |
... | @@ -534,9 +534,7 @@ mu_message_destroy (mu_message_t *pmsg, void *owner) | ... | @@ -534,9 +534,7 @@ mu_message_destroy (mu_message_t *pmsg, void *owner) |
534 | is very unfortunate. | 534 | is very unfortunate. |
535 | 535 | ||
536 | The `owner' stuff is a leftover from older mailutils versions. | 536 | The `owner' stuff is a leftover from older mailutils versions. |
537 | There is an ongoing attempt to remove it in the stream-cleanup | 537 | We are heading to removing it altogether. */ |
538 | branch. When it is ready, it will be merged to the HEAD and this | ||
539 | will finally resolve this issue. */ | ||
540 | if (msg->ref > 0) | 538 | if (msg->ref > 0) |
541 | msg->ref--; | 539 | msg->ref--; |
542 | if ((msg->owner && msg->owner == owner) | 540 | if ((msg->owner && msg->owner == owner) | ... | ... |
... | @@ -2589,7 +2589,7 @@ imap_parse (f_imap_t f_imap) | ... | @@ -2589,7 +2589,7 @@ imap_parse (f_imap_t f_imap) |
2589 | { | 2589 | { |
2590 | mu_observable_t observable = NULL; | 2590 | mu_observable_t observable = NULL; |
2591 | mu_folder_get_observable (f_imap->folder, &observable); | 2591 | mu_folder_get_observable (f_imap->folder, &observable); |
2592 | mu_observable_notify (observable, MU_EVT_AUTHORITY_FAILED, | 2592 | mu_observable_notify (observable, MU_EVT_FOLDER_AUTHORITY_FAILED, |
2593 | NULL); | 2593 | NULL); |
2594 | status = MU_ERR_AUTH_FAILURE; | 2594 | status = MU_ERR_AUTH_FAILURE; |
2595 | } | 2595 | } | ... | ... |
... | @@ -1143,7 +1143,8 @@ mbox_append_message (mu_mailbox_t mailbox, mu_message_t msg) | ... | @@ -1143,7 +1143,8 @@ mbox_append_message (mu_mailbox_t mailbox, mu_message_t msg) |
1143 | { | 1143 | { |
1144 | char *buf = NULL; | 1144 | char *buf = NULL; |
1145 | mu_asprintf (&buf, "%lu", (unsigned long) size); | 1145 | mu_asprintf (&buf, "%lu", (unsigned long) size); |
1146 | mu_observable_notify (mailbox->observable, MU_EVT_MESSAGE_APPEND, buf); | 1146 | mu_observable_notify (mailbox->observable, |
1147 | MU_EVT_MAILBOX_MESSAGE_APPEND, buf); | ||
1147 | free (buf); | 1148 | free (buf); |
1148 | } | 1149 | } |
1149 | 1150 | ||
... | @@ -1184,7 +1185,8 @@ mbox_expunge_unlocked (mu_mailbox_t mailbox, size_t dirty, int remove_deleted, | ... | @@ -1184,7 +1185,8 @@ mbox_expunge_unlocked (mu_mailbox_t mailbox, size_t dirty, int remove_deleted, |
1184 | size_t save_imapbase = 0; /* uidvalidity is save in the first message. */ | 1185 | size_t save_imapbase = 0; /* uidvalidity is save in the first message. */ |
1185 | mu_off_t start_off; | 1186 | mu_off_t start_off; |
1186 | mu_off_t size; | 1187 | mu_off_t size; |
1187 | 1188 | size_t expcount = 0; | |
1189 | |||
1188 | /* Set the marker position. */ | 1190 | /* Set the marker position. */ |
1189 | start_off = mud->umessages[dirty]->envel_from; | 1191 | start_off = mud->umessages[dirty]->envel_from; |
1190 | 1192 | ||
... | @@ -1194,6 +1196,11 @@ mbox_expunge_unlocked (mu_mailbox_t mailbox, size_t dirty, int remove_deleted, | ... | @@ -1194,6 +1196,11 @@ mbox_expunge_unlocked (mu_mailbox_t mailbox, size_t dirty, int remove_deleted, |
1194 | 1196 | ||
1195 | if (remove_deleted && ATTRIBUTE_IS_DELETED (mum->attr_flags)) | 1197 | if (remove_deleted && ATTRIBUTE_IS_DELETED (mum->attr_flags)) |
1196 | { | 1198 | { |
1199 | size_t expevt[2] = { i + 1, expcount }; | ||
1200 | mu_observable_notify (mailbox->observable, | ||
1201 | MU_EVT_MAILBOX_MESSAGE_EXPUNGE, | ||
1202 | expevt); | ||
1203 | expcount++; | ||
1197 | mu_message_destroy (&mum->message, mum); | 1204 | mu_message_destroy (&mum->message, mum); |
1198 | /* We save the uidvalidity in the first message, if it is being | 1205 | /* We save the uidvalidity in the first message, if it is being |
1199 | deleted we need to move the uidvalidity to the first available | 1206 | deleted we need to move the uidvalidity to the first available | ... | ... |
... | @@ -864,6 +864,7 @@ pop_expunge (mu_mailbox_t mbox) | ... | @@ -864,6 +864,7 @@ pop_expunge (mu_mailbox_t mbox) |
864 | struct _pop3_mailbox *mpd = mbox->data; | 864 | struct _pop3_mailbox *mpd = mbox->data; |
865 | int status = 0; | 865 | int status = 0; |
866 | size_t i; | 866 | size_t i; |
867 | size_t expcount = 0; | ||
867 | 868 | ||
868 | if (mpd == NULL) | 869 | if (mpd == NULL) |
869 | return EINVAL; | 870 | return EINVAL; |
... | @@ -879,9 +880,14 @@ pop_expunge (mu_mailbox_t mbox) | ... | @@ -879,9 +880,14 @@ pop_expunge (mu_mailbox_t mbox) |
879 | (mpm->flags & _POP3_MSG_ATTRSET) && | 880 | (mpm->flags & _POP3_MSG_ATTRSET) && |
880 | (mpm->attr_flags & MU_ATTRIBUTE_DELETED)) | 881 | (mpm->attr_flags & MU_ATTRIBUTE_DELETED)) |
881 | { | 882 | { |
883 | size_t expevt[2] = { i + 1, expcount }; | ||
882 | status = mu_pop3_dele (mpd->pop3, mpm->num); | 884 | status = mu_pop3_dele (mpd->pop3, mpm->num); |
883 | if (status) | 885 | if (status) |
884 | break; | 886 | break; |
887 | mu_observable_notify (mbox->observable, | ||
888 | MU_EVT_MAILBOX_MESSAGE_EXPUNGE, | ||
889 | &expevt); | ||
890 | ++expcount; | ||
885 | } | 891 | } |
886 | } | 892 | } |
887 | return 0; | 893 | return 0; | ... | ... |
... | @@ -132,7 +132,7 @@ static const char *biff_user_name; | ... | @@ -132,7 +132,7 @@ static const char *biff_user_name; |
132 | static int | 132 | static int |
133 | notify_action (mu_observer_t obs, size_t type, void *data, void *action_data) | 133 | notify_action (mu_observer_t obs, size_t type, void *data, void *action_data) |
134 | { | 134 | { |
135 | if (type == MU_EVT_MESSAGE_APPEND && biff_user_name) | 135 | if (type == MU_EVT_MAILBOX_MESSAGE_APPEND && biff_user_name) |
136 | { | 136 | { |
137 | mu_message_qid_t qid = data; | 137 | mu_message_qid_t qid = data; |
138 | mu_mailbox_t mbox = mu_observer_get_owner (obs); | 138 | mu_mailbox_t mbox = mu_observer_get_owner (obs); |
... | @@ -183,7 +183,8 @@ attach_notify (mu_mailbox_t mbox) | ... | @@ -183,7 +183,8 @@ attach_notify (mu_mailbox_t mbox) |
183 | mu_observer_create (&observer, mbox); | 183 | mu_observer_create (&observer, mbox); |
184 | mu_observer_set_action (observer, notify_action, mbox); | 184 | mu_observer_set_action (observer, notify_action, mbox); |
185 | mu_mailbox_get_observable (mbox, &observable); | 185 | mu_mailbox_get_observable (mbox, &observable); |
186 | mu_observable_attach (observable, MU_EVT_MESSAGE_APPEND, observer); | 186 | mu_observable_attach (observable, MU_EVT_MAILBOX_MESSAGE_APPEND, |
187 | observer); | ||
187 | } | 188 | } |
188 | } | 189 | } |
189 | 190 | ... | ... |
-
Please register or sign in to post a comment