From 8c9e48cd6de80da0fa32b9c0dee003472c9a7c0d Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Sun, 25 May 2008 01:45:31 +0300 Subject: [PATCH] Maildir: If dovecot-uidlist has wrong cached virtual size, remove it when we detect it. If maildir filename has wrong W value, log a clear error about it. --HG-- branch : HEAD --- src/lib-storage/index/maildir/maildir-mail.c | 30 ++++++++++++++++++- .../index/maildir/maildir-uidlist.c | 6 ++-- .../index/maildir/maildir-uidlist.h | 1 + 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/lib-storage/index/maildir/maildir-mail.c b/src/lib-storage/index/maildir/maildir-mail.c index 55a7277b33..288b3ce3dc 100644 --- a/src/lib-storage/index/maildir/maildir-mail.c +++ b/src/lib-storage/index/maildir/maildir-mail.c @@ -462,6 +462,34 @@ static int maildir_mail_get_stream(struct mail *_mail, return index_mail_init_stream(mail, hdr_size, body_size, stream_r); } +static void maildir_mail_set_cache_corrupted(struct mail *_mail, + enum mail_fetch_field field) +{ + struct index_mail *mail = (struct index_mail *)_mail; + struct maildir_mailbox *mbox = (struct maildir_mailbox *)mail->ibox; + enum maildir_uidlist_rec_flag flags; + const char *fname; + uoff_t size; + + if (field == MAIL_FETCH_VIRTUAL_SIZE) { + /* make sure it gets removed from uidlist. + if it's in file name, we can't really do more than log it. */ + fname = maildir_uidlist_lookup(mbox->uidlist, + _mail->uid, &flags); + if (maildir_filename_get_size(fname, MAILDIR_EXTRA_VIRTUAL_SIZE, + &size)) { + i_error("Maildir filename has wrong W value: %s/%s", + mbox->path, fname); + } else if (maildir_uidlist_lookup_ext(mbox->uidlist, _mail->uid, + MAILDIR_UIDLIST_REC_EXT_VSIZE) != NULL) { + maildir_uidlist_set_ext(mbox->uidlist, _mail->uid, + MAILDIR_UIDLIST_REC_EXT_VSIZE, + NULL); + } + } + index_mail_set_cache_corrupted(_mail, field); +} + struct mail_vfuncs maildir_mail_vfuncs = { index_mail_close, index_mail_free, @@ -485,6 +513,6 @@ struct mail_vfuncs maildir_mail_vfuncs = { index_mail_update_flags, index_mail_update_keywords, index_mail_expunge, - index_mail_set_cache_corrupted, + maildir_mail_set_cache_corrupted, index_mail_get_index_mail }; diff --git a/src/lib-storage/index/maildir/maildir-uidlist.c b/src/lib-storage/index/maildir/maildir-uidlist.c index c46095e7ba..1e31e7ae3d 100644 --- a/src/lib-storage/index/maildir/maildir-uidlist.c +++ b/src/lib-storage/index/maildir/maildir-uidlist.c @@ -935,8 +935,10 @@ maildir_uidlist_set_ext_real(struct maildir_uidlist *uidlist, uint32_t uid, p += len; } } - buffer_append_c(buf, key); - buffer_append(buf, value, strlen(value) + 1); + if (value != NULL) { + buffer_append_c(buf, key); + buffer_append(buf, value, strlen(value) + 1); + } buffer_append_c(buf, '\0'); rec->extensions = p_malloc(uidlist->record_pool, buf->used); diff --git a/src/lib-storage/index/maildir/maildir-uidlist.h b/src/lib-storage/index/maildir/maildir-uidlist.h index 95d6231472..f9c96ec475 100644 --- a/src/lib-storage/index/maildir/maildir-uidlist.h +++ b/src/lib-storage/index/maildir/maildir-uidlist.h @@ -80,6 +80,7 @@ void maildir_uidlist_set_uid_validity(struct maildir_uidlist *uidlist, void maildir_uidlist_set_next_uid(struct maildir_uidlist *uidlist, uint32_t next_uid, bool force); +/* Update extended record. value=NULL removes the key. */ void maildir_uidlist_set_ext(struct maildir_uidlist *uidlist, uint32_t uid, enum maildir_uidlist_rec_ext_key key, const char *value); -- 2.47.3