Commit 83bdd70a 83bdd70aa68dc101b605402325257c4011b0ecaf by Sergey Poznyakoff

(imap4d_set_observer): New function.

(imap4d_sync): Check if the mailbox was shrunk (in libmailbox
terms 'corrupted'). If so, reopen it and issue untagged alert.
1 parent 393014be
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17 17
18 #include "imap4d.h" 18 #include "imap4d.h"
19 #include <mailutils/observer.h>
19 20
20 /* 21 /*
21 22
...@@ -271,6 +272,38 @@ imap4d_sync_flags (size_t msgno) ...@@ -271,6 +272,38 @@ imap4d_sync_flags (size_t msgno)
271 return 0; 272 return 0;
272 } 273 }
273 274
275 static int mailbox_corrupt;
276
277 static int
278 action (observer_t observer, size_t type)
279 {
280 switch (type)
281 {
282 case MU_EVT_MAILBOX_CORRUPT:
283 mailbox_corrupt = 1;
284 break;
285
286 case MU_EVT_MAILBOX_DESTROY:
287 mailbox_corrupt = 0;
288 break;
289 }
290 return 0;
291 }
292
293 void
294 imap4d_set_observer (mailbox_t mbox)
295 {
296 observer_t observer;
297 observable_t observable;
298
299 observer_create (&observer, mbox);
300 observer_set_action (observer, action, mbox);
301 mailbox_get_observable (mbox, &observable);
302 observable_attach (observable, MU_EVT_MAILBOX_CORRUPT|MU_EVT_MAILBOX_DESTROY,
303 observer);
304 mailbox_corrupt = 0;
305 }
306
274 int 307 int
275 imap4d_sync (void) 308 imap4d_sync (void)
276 { 309 {
...@@ -280,7 +313,25 @@ imap4d_sync (void) ...@@ -280,7 +313,25 @@ imap4d_sync (void)
280 if (mbox == NULL) 313 if (mbox == NULL)
281 free_uids (); 314 free_uids ();
282 else if (!uid_table_loaded || !mailbox_is_updated (mbox)) 315 else if (!uid_table_loaded || !mailbox_is_updated (mbox))
283 notify (); 316 {
317 if (mailbox_corrupt)
318 {
319 /* Some messages have been deleted from the mailbox by some other
320 party */
321 int status = mailbox_close (mbox);
322 if (status)
323 imap4d_bye (ERR_MAILBOX_CORRUPTED);
324 status = mailbox_open (mbox, MU_STREAM_RDWR);
325 if (status)
326 imap4d_bye (ERR_MAILBOX_CORRUPTED);
327 imap4d_set_observer (mbox);
328 free_uids ();
329 mailbox_corrupt = 0;
330 util_out (RESP_NONE,
331 "OK [ALERT] Mailbox modified by another program");
332 }
333 notify ();
334 }
284 else 335 else
285 { 336 {
286 size_t count = 0; 337 size_t count = 0;
......