Mercurial > dovecot > core-2.2
changeset 12883:0dec197d1bb7
imapc: Fixes to handling expunges.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 04 Apr 2011 15:27:33 +0300 |
parents | dc0d02efe64b |
children | f051c326463e |
files | src/lib-storage/index/imapc/imapc-mail-fetch.c src/lib-storage/index/imapc/imapc-mail.c src/lib-storage/index/imapc/imapc-mailbox.c |
diffstat | 3 files changed, 37 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/index/imapc/imapc-mail-fetch.c Mon Apr 04 15:08:50 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-mail-fetch.c Mon Apr 04 15:27:33 2011 +0300 @@ -51,7 +51,9 @@ { struct imapc_mail *mail = (struct imapc_mail *)_mail; struct imapc_mailbox *mbox = (struct imapc_mailbox *)_mail->box; + struct mail_index_view *view; string_t *str; + uint32_t seq; if (_mail->lookup_abort != MAIL_LOOKUP_ABORT_NEVER) return -1; @@ -61,6 +63,16 @@ if (fields == 0) return 0; + /* if we already know that the mail is expunged, + don't try to FETCH it */ + view = mbox->delayed_sync_view != NULL ? + mbox->delayed_sync_view : mbox->box.view; + if (!mail_index_lookup_seq(view, _mail->uid, &seq) || + mail_index_is_expunged(view, seq)) { + mail_set_expunged(_mail); + return -1; + } + if ((fields & MAIL_FETCH_STREAM_BODY) != 0) fields |= MAIL_FETCH_STREAM_HEADER;
--- a/src/lib-storage/index/imapc/imapc-mail.c Mon Apr 04 15:08:50 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-mail.c Mon Apr 04 15:27:33 2011 +0300 @@ -98,6 +98,25 @@ return 0; } +static bool imapc_mail_is_expunged(struct mail *_mail) +{ + struct imapc_mailbox *mbox = (struct imapc_mailbox *)_mail->box; + struct imapc_seqmap *seqmap; + uint32_t lseq; + + /* first we'll need to convert the mail's sequence to sync_view's + sequence. if there's no sync_view, then no mails have been + expunged. */ + if (mbox->sync_view == NULL) + return FALSE; + + if (!mail_index_lookup_seq(mbox->sync_view, _mail->uid, &lseq)) + return TRUE; + + seqmap = imapc_client_mailbox_get_seqmap(mbox->client_box); + return imapc_seqmap_lseq_to_rseq(seqmap, lseq) == 0; +} + static int imapc_mail_get_stream(struct mail *_mail, struct message_size *hdr_size, struct message_size *body_size, struct istream **stream_r) @@ -118,14 +137,9 @@ return -1; if (data->stream == NULL) { - struct imapc_mailbox *mbox = - (struct imapc_mailbox *)_mail->box; - struct imapc_seqmap *seqmap; - - seqmap = imapc_client_mailbox_get_seqmap(mbox->client_box); - if (imapc_seqmap_lseq_to_rseq(seqmap, _mail->seq) == 0) + if (_mail->expunged || imapc_mail_is_expunged(_mail)) mail_set_expunged(_mail); - else if (!_mail->expunged) { + else { mail_storage_set_critical(_mail->box->storage, "imapc: Remote server didn't send BODY[]"); }
--- a/src/lib-storage/index/imapc/imapc-mailbox.c Mon Apr 04 15:08:50 2011 +0300 +++ b/src/lib-storage/index/imapc/imapc-mailbox.c Mon Apr 04 15:27:33 2011 +0300 @@ -202,13 +202,14 @@ seqmap = imapc_client_mailbox_get_seqmap(mbox->client_box); lseq = imapc_seqmap_rseq_to_lseq(seqmap, rseq); + /* fetch_mails' view is different from sync_view, so we can't compare + their sequences directly. that is why this code supports only + UID FETCH commands which are guaranteed to have UID in the reply. */ array_foreach(&mbox->fetch_mails, mailp) { struct imapc_mail *mail = *mailp; - if (mail->imail.mail.mail.seq == lseq) { - i_assert(uid == 0 || mail->imail.mail.mail.uid == uid); + if (mail->imail.mail.mail.uid == uid) imapc_mail_fetch_update(mail, reply, list); - } } imapc_mailbox_init_delayed_trans(mbox);