mbox-mail.c revision bf9402875418faf11825cf11fbe06326b6086e3d
2e37d45867d081db150ab78dad303b9077aea24fTimo Sirainen/* Copyright (c) 2003-2009 Dovecot authors, see the included COPYING file */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenstatic void mbox_prepare_resync(struct index_mail *mail)
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen (struct mbox_transaction_context *)mail->trans;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen struct mbox_mailbox *mbox = (struct mbox_mailbox *)mail->ibox;
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainenstatic int mbox_mail_seek(struct index_mail *mail)
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen (struct mbox_transaction_context *)mail->trans;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen struct mbox_mailbox *mbox = (struct mbox_mailbox *)mail->ibox;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen if (mail->mail.mail.expunged || mbox->syncing)
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen if (mail->mail.mail.lookup_abort != MAIL_LOOKUP_ABORT_NEVER)
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen istream_raw_mbox_is_corrupted(mbox->mbox_stream)) {
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* clear the corruption by forcing a full resync */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen sync_flags |= MBOX_SYNC_UNDIRTY | MBOX_SYNC_FORCE_SYNC;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen if ((sync_flags & MBOX_SYNC_FORCE_SYNC) != 0) {
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen /* dirty offsets are broken. make sure we can sync. */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* refresh index file after mbox has been locked to
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen make sure we get only up-to-date mbox offsets. */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen if (mail_index_refresh(mbox->ibox.index) < 0) {
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen } else if (t->mbox_lock_id == 0) {
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen /* file is already locked by another transaction, but
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen we must keep it locked for the entire transaction,
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen so increase the lock counter. */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen ret = mbox_file_seek(mbox, mail->trans->trans_view,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* success */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* we'll need to re-sync it completely */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen sync_flags |= MBOX_SYNC_UNDIRTY | MBOX_SYNC_FORCE_SYNC;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen mail_storage_set_critical(&mbox->storage->storage,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen "Losing sync for mail uid=%u in mbox file %s",
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenstatic int mbox_mail_get_received_date(struct mail *_mail, time_t *date_r)
67c24901ac5e1521e38a91efc452faeb3e2135a1Timo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen struct mbox_mailbox *mbox = (struct mbox_mailbox *)mail->ibox;
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen if (index_mail_get_received_date(_mail, date_r) == 0)
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen istream_raw_mbox_get_received_time(mbox->mbox_stream);
67c24901ac5e1521e38a91efc452faeb3e2135a1Timo Sirainen /* it's broken and conflicts with our "not found"
67c24901ac5e1521e38a91efc452faeb3e2135a1Timo Sirainen return value. change it. */
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainenstatic int mbox_mail_get_save_date(struct mail *_mail, time_t *date_r)
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen if (index_mail_get_save_date(_mail, date_r) == 0)
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* no way to know this. save the current time into cache and use
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen that from now on. this works only as long as the index files
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen are permanent */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenmbox_mail_get_md5_header(struct index_mail *mail, const char **value_r)
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen struct mbox_mailbox *mbox = (struct mbox_mailbox *)mail->ibox;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen mail_index_lookup_ext(mail->trans->trans_view, mail->mail.mail.seq,
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen if (ext_data != NULL && memcmp(ext_data, empty_md5, 16) != 0) {
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainenmbox_mail_get_special(struct mail *_mail, enum mail_fetch_field field,
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen const char **value_r)
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen struct mbox_mailbox *mbox = (struct mbox_mailbox *)mail->ibox;
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen *value_r = istream_raw_mbox_get_sender(mbox->mbox_stream);
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen /* i guess in theory the empty_md5 is valid and can happen,
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen but it's almost guaranteed that it means the MD5 sum is
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen missing. recalculate it. */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen if (mbox_sync(mbox, MBOX_SYNC_FORCE_SYNC) < 0)
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen if (!mbox_mail_get_md5_header(mail, value_r)) {
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen i_error("mbox resyncing didn't save header MD5 values");
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen return index_mail_get_special(_mail, field, value_r);
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainenmbox_mail_get_next_offset(struct index_mail *mail, uoff_t *next_offset_r)
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen struct mbox_mailbox *mbox = (struct mbox_mailbox *)mail->ibox;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen hdr = mail_index_get_header(mail->trans->trans_view);
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen if (mail->mail.mail.seq > hdr->messages_count) {
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* we're appending a new message */
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen /* We can't really trust trans_view. The next message may already be
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen expunged from it. Also hdr.messages_count may be incorrect there.
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen So refresh the index to get the latest changes and get the next
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen message's offset using a new view. */
9511a40d933181045343110c8101b75887062aaeTimo Sirainen view = mail_index_view_open(mail->ibox->index);
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen if (!mail_index_lookup_seq(view, mail->mail.mail.uid, &seq))
411d6baa37f31d90730e90c4a28c43e1974bbe58Timo Sirainen i_panic("Message unexpectedly expunged from index");
next_offset_r) <= 0)
return ret;
int ret;
if (ret < 0) {
if (ret < 0) {
if (ret <= 0)
bool ret;
return ret;
NULL,