mbox-mail.c revision 8f017a40470ef2f4b530000d947a8bce44350a5e
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2003-2007 Dovecot authors, see the included COPYING file */
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen#include "lib.h"
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen#include "ioloop.h"
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen#include "istream.h"
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen#include "index-mail.h"
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen#include "mbox-storage.h"
2eccb2637d0153bb7f9ad39a70f254cece74342cTimo Sirainen#include "mbox-file.h"
2eccb2637d0153bb7f9ad39a70f254cece74342cTimo Sirainen#include "mbox-lock.h"
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen#include "mbox-sync-private.h"
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen#include "istream-raw-mbox.h"
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen#include "istream-header-filter.h"
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen#include <fcntl.h>
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen#include <unistd.h>
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen#include <sys/stat.h>
2eccb2637d0153bb7f9ad39a70f254cece74342cTimo Sirainen
86bdb644d147a73df85abce4325254d694217a5fTimo Sirainenstatic void mbox_prepare_resync(struct index_mail *mail)
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen{
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen struct mbox_transaction_context *t =
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen (struct mbox_transaction_context *)mail->trans;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen struct mbox_mailbox *mbox = (struct mbox_mailbox *)mail->ibox;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen if (mbox->mbox_lock_type == F_RDLCK) {
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen if (mbox->mbox_lock_id == t->mbox_lock_id)
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen t->mbox_lock_id = 0;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen (void)mbox_unlock(mbox, mbox->mbox_lock_id);
4e8e7a93628b4ed60aaaa47c6f72c1433f21e81dTimo Sirainen mbox->mbox_lock_id = 0;
a01faca549a403b2eda938cea0b1fb76c3ff44b6Aki Tuomi i_assert(mbox->mbox_lock_type == F_UNLCK);
a01faca549a403b2eda938cea0b1fb76c3ff44b6Aki Tuomi }
86bdb644d147a73df85abce4325254d694217a5fTimo Sirainen}
a01faca549a403b2eda938cea0b1fb76c3ff44b6Aki Tuomi
a01faca549a403b2eda938cea0b1fb76c3ff44b6Aki Tuomistatic int mbox_mail_seek(struct index_mail *mail)
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen{
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen struct mbox_transaction_context *t =
b7324e421e2132cbbf753e6fdbe675bbaecdf929Timo Sirainen (struct mbox_transaction_context *)mail->trans;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen struct mbox_mailbox *mbox = (struct mbox_mailbox *)mail->ibox;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen enum mbox_sync_flags sync_flags = 0;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen int ret, try;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen bool deleted;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen if (mail->mail.mail.expunged || mbox->syncing)
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen return -1;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen for (try = 0; try < 2; try++) {
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen if (mbox->mbox_lock_type == F_UNLCK) {
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen sync_flags |= MBOX_SYNC_LOCK_READING;
2eccb2637d0153bb7f9ad39a70f254cece74342cTimo Sirainen if (mbox_sync(mbox, sync_flags) < 0)
2eccb2637d0153bb7f9ad39a70f254cece74342cTimo Sirainen return -1;
2eccb2637d0153bb7f9ad39a70f254cece74342cTimo Sirainen
2eccb2637d0153bb7f9ad39a70f254cece74342cTimo Sirainen /* refresh index file after mbox has been locked to
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen make sure we get only up-to-date mbox offsets. */
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen if (mail_index_refresh(mbox->ibox.index) < 0) {
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen mail_storage_set_index_error(&mbox->ibox);
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen return -1;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen }
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen i_assert(mbox->mbox_lock_type != F_UNLCK);
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen t->mbox_lock_id = mbox->mbox_lock_id;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen } else if ((sync_flags & MBOX_SYNC_FORCE_SYNC) != 0) {
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen /* dirty offsets are broken and mbox is write-locked.
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen sync it to update offsets. */
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen if (mbox_sync(mbox, sync_flags) < 0)
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen return -1;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen }
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen if (mbox_file_open_stream(mbox) < 0)
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen return -1;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen
4e8e7a93628b4ed60aaaa47c6f72c1433f21e81dTimo Sirainen ret = mbox_file_seek(mbox, mail->trans->trans_view,
4e8e7a93628b4ed60aaaa47c6f72c1433f21e81dTimo Sirainen mail->mail.mail.seq, &deleted);
a01faca549a403b2eda938cea0b1fb76c3ff44b6Aki Tuomi if (ret > 0) {
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen /* success */
a01faca549a403b2eda938cea0b1fb76c3ff44b6Aki Tuomi break;
86bdb644d147a73df85abce4325254d694217a5fTimo Sirainen }
86bdb644d147a73df85abce4325254d694217a5fTimo Sirainen if (ret < 0) {
86bdb644d147a73df85abce4325254d694217a5fTimo Sirainen if (deleted)
86bdb644d147a73df85abce4325254d694217a5fTimo Sirainen mail_set_expunged(&mail->mail.mail);
86bdb644d147a73df85abce4325254d694217a5fTimo Sirainen return -1;
86bdb644d147a73df85abce4325254d694217a5fTimo Sirainen }
86bdb644d147a73df85abce4325254d694217a5fTimo Sirainen
86bdb644d147a73df85abce4325254d694217a5fTimo Sirainen /* we'll need to re-sync it completely */
86bdb644d147a73df85abce4325254d694217a5fTimo Sirainen mbox_prepare_resync(mail);
86bdb644d147a73df85abce4325254d694217a5fTimo Sirainen sync_flags |= MBOX_SYNC_UNDIRTY | MBOX_SYNC_FORCE_SYNC;
86bdb644d147a73df85abce4325254d694217a5fTimo Sirainen }
86bdb644d147a73df85abce4325254d694217a5fTimo Sirainen if (ret == 0) {
86bdb644d147a73df85abce4325254d694217a5fTimo Sirainen mail_storage_set_critical(&mbox->storage->storage,
86bdb644d147a73df85abce4325254d694217a5fTimo Sirainen "Losing sync for mail uid=%u in mbox file %s",
86bdb644d147a73df85abce4325254d694217a5fTimo Sirainen mail->mail.mail.uid, mbox->path);
a01faca549a403b2eda938cea0b1fb76c3ff44b6Aki Tuomi }
a01faca549a403b2eda938cea0b1fb76c3ff44b6Aki Tuomi return 0;
a01faca549a403b2eda938cea0b1fb76c3ff44b6Aki Tuomi}
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainenstatic int mbox_mail_get_received_date(struct mail *_mail, time_t *date_r)
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen{
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen struct index_mail_data *data = &mail->data;
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen struct mbox_mailbox *mbox = (struct mbox_mailbox *)mail->ibox;
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen uint32_t t;
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen (void)index_mail_get_received_date(_mail, date_r);
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen if (*date_r != (time_t)-1)
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen return 0;
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen if (mbox_mail_seek(mail) < 0)
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen return -1;
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen data->received_date =
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen istream_raw_mbox_get_received_time(mbox->mbox_stream);
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen if (data->received_date == (time_t)-1) {
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen /* it's broken and conflicts with our "not found"
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen return value. change it. */
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen data->received_date = 0;
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen }
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen t = data->received_date;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen index_mail_cache_add(mail, MAIL_CACHE_RECEIVED_DATE, &t, sizeof(t));
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen *date_r = data->received_date;
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen return 0;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen}
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainenstatic int mbox_mail_get_save_date(struct mail *_mail, time_t *date_r)
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen{
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen struct index_mail_data *data = &mail->data;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen (void)index_mail_get_save_date(_mail, date_r);
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen if (*date_r != (time_t)-1)
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen return 0;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen /* no way to know this. save the current time into cache and use
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen that from now on. this works only as long as the index files
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen are permanent */
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen data->save_date = ioloop_time;
791fb70b3255a11a91ce0c2dc3ae1460d4cf8459Timo Sirainen index_mail_cache_add(mail, MAIL_CACHE_SAVE_DATE,
a18e2525cb076066784967d6c8118a01dd38ac6bTimo Sirainen &data->save_date, sizeof(data->save_date));
a18e2525cb076066784967d6c8118a01dd38ac6bTimo Sirainen *date_r = data->save_date;
2eccb2637d0153bb7f9ad39a70f254cece74342cTimo Sirainen return 0;
2eccb2637d0153bb7f9ad39a70f254cece74342cTimo Sirainen}
2eccb2637d0153bb7f9ad39a70f254cece74342cTimo Sirainen
a18e2525cb076066784967d6c8118a01dd38ac6bTimo Sirainenstatic int
a18e2525cb076066784967d6c8118a01dd38ac6bTimo Sirainenmbox_mail_get_special(struct mail *_mail, enum mail_fetch_field field,
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen const char **value_r)
2eccb2637d0153bb7f9ad39a70f254cece74342cTimo Sirainen{
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen#define EMPTY_MD5_SUM "00000000000000000000000000000000"
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
202b4674243a4a4826c35ed4d089831985c47256Timo Sirainen struct mbox_mailbox *mbox = (struct mbox_mailbox *)mail->ibox;
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen switch (field) {
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen case MAIL_FETCH_FROM_ENVELOPE:
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen if (mbox_mail_seek(mail) < 0)
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen return -1;
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen *value_r = istream_raw_mbox_get_sender(mbox->mbox_stream);
95f5b08fa73ddd9a9de40a97aa141e9c74e0645eAki Tuomi return 0;
95f5b08fa73ddd9a9de40a97aa141e9c74e0645eAki Tuomi case MAIL_FETCH_HEADER_MD5:
a01faca549a403b2eda938cea0b1fb76c3ff44b6Aki Tuomi if (index_mail_get_special(_mail, field, value_r) < 0)
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen return -1;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen if (**value_r != '\0' && strcmp(*value_r, EMPTY_MD5_SUM) != 0)
95f5b08fa73ddd9a9de40a97aa141e9c74e0645eAki Tuomi return 0;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen /* i guess in theory the EMPTY_MD5_SUM is valid and can happen,
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen but it's almost guaranteed that it means the MD5 sum is
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen missing. recalculate it. */
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen mbox->mbox_save_md5 = TRUE;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen mbox_prepare_resync(mail);
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen if (mbox_sync(mbox, MBOX_SYNC_FORCE_SYNC) < 0)
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen return -1;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen break;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen default:
f6497ac81e6de57870936d538acccb75ce408fc1Timo Sirainen break;
f6497ac81e6de57870936d538acccb75ce408fc1Timo Sirainen }
f6497ac81e6de57870936d538acccb75ce408fc1Timo Sirainen
f6497ac81e6de57870936d538acccb75ce408fc1Timo Sirainen return index_mail_get_special(_mail, field, value_r);
f6497ac81e6de57870936d538acccb75ce408fc1Timo Sirainen}
f6497ac81e6de57870936d538acccb75ce408fc1Timo Sirainen
f6497ac81e6de57870936d538acccb75ce408fc1Timo Sirainenstatic int mbox_mail_get_physical_size(struct mail *_mail, uoff_t *size_r)
f6497ac81e6de57870936d538acccb75ce408fc1Timo Sirainen{
f6497ac81e6de57870936d538acccb75ce408fc1Timo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
f6497ac81e6de57870936d538acccb75ce408fc1Timo Sirainen struct index_mail_data *data = &mail->data;
f6497ac81e6de57870936d538acccb75ce408fc1Timo Sirainen struct mbox_mailbox *mbox = (struct mbox_mailbox *)mail->ibox;
f6497ac81e6de57870936d538acccb75ce408fc1Timo Sirainen struct istream *stream;
f6497ac81e6de57870936d538acccb75ce408fc1Timo Sirainen uoff_t hdr_offset, body_offset, body_size;
f6497ac81e6de57870936d538acccb75ce408fc1Timo Sirainen
f6497ac81e6de57870936d538acccb75ce408fc1Timo Sirainen if (mbox_mail_seek(mail) < 0)
f6497ac81e6de57870936d538acccb75ce408fc1Timo Sirainen return -1;
f6497ac81e6de57870936d538acccb75ce408fc1Timo Sirainen
f6497ac81e6de57870936d538acccb75ce408fc1Timo Sirainen /* our header size varies, so don't do any caching */
f6497ac81e6de57870936d538acccb75ce408fc1Timo Sirainen stream = mbox->mbox_stream;
f6497ac81e6de57870936d538acccb75ce408fc1Timo Sirainen hdr_offset = istream_raw_mbox_get_header_offset(stream);
f6497ac81e6de57870936d538acccb75ce408fc1Timo Sirainen body_offset = istream_raw_mbox_get_body_offset(stream);
f6497ac81e6de57870936d538acccb75ce408fc1Timo Sirainen if (body_offset == (uoff_t)-1) {
f6497ac81e6de57870936d538acccb75ce408fc1Timo Sirainen mail_storage_set_critical(_mail->box->storage,
f6497ac81e6de57870936d538acccb75ce408fc1Timo Sirainen "Couldn't get mbox size");
f6497ac81e6de57870936d538acccb75ce408fc1Timo Sirainen return -1;
f6497ac81e6de57870936d538acccb75ce408fc1Timo Sirainen }
f6497ac81e6de57870936d538acccb75ce408fc1Timo Sirainen body_size = istream_raw_mbox_get_body_size(stream, (uoff_t)-1);
f6497ac81e6de57870936d538acccb75ce408fc1Timo Sirainen
f6ae9ae80a1fcf6c8f45ab759f0074caaa66c9c8Timo Sirainen data->physical_size = (body_offset - hdr_offset) + body_size;
f6ae9ae80a1fcf6c8f45ab759f0074caaa66c9c8Timo Sirainen *size_r = data->physical_size;
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen return 0;
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen}
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainenstatic int mbox_mail_get_stream(struct mail *_mail,
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen struct message_size *hdr_size,
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen struct message_size *body_size,
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen struct istream **stream_r)
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen{
f6ae9ae80a1fcf6c8f45ab759f0074caaa66c9c8Timo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen struct index_mail_data *data = &mail->data;
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen struct mbox_mailbox *mbox = (struct mbox_mailbox *)mail->ibox;
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen struct istream *raw_stream;
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen uoff_t offset;
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen if (data->stream == NULL) {
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen if (mbox_mail_seek(mail) < 0)
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen return -1;
f6ae9ae80a1fcf6c8f45ab759f0074caaa66c9c8Timo Sirainen
f6ae9ae80a1fcf6c8f45ab759f0074caaa66c9c8Timo Sirainen raw_stream = mbox->mbox_stream;
b7324e421e2132cbbf753e6fdbe675bbaecdf929Timo Sirainen offset = istream_raw_mbox_get_header_offset(raw_stream);
a18503d5dc0751a1f9785e48438a219d95c0b9c2Timo Sirainen raw_stream = i_stream_create_limit(raw_stream,
a18503d5dc0751a1f9785e48438a219d95c0b9c2Timo Sirainen offset, (uoff_t)-1);
a18503d5dc0751a1f9785e48438a219d95c0b9c2Timo Sirainen data->stream =
a18503d5dc0751a1f9785e48438a219d95c0b9c2Timo Sirainen i_stream_create_header_filter(raw_stream,
a18503d5dc0751a1f9785e48438a219d95c0b9c2Timo Sirainen HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR,
a18503d5dc0751a1f9785e48438a219d95c0b9c2Timo Sirainen mbox_hide_headers, mbox_hide_headers_count,
a18503d5dc0751a1f9785e48438a219d95c0b9c2Timo Sirainen null_header_filter_callback, NULL);
a18503d5dc0751a1f9785e48438a219d95c0b9c2Timo Sirainen i_stream_unref(&raw_stream);
a18503d5dc0751a1f9785e48438a219d95c0b9c2Timo Sirainen }
a18503d5dc0751a1f9785e48438a219d95c0b9c2Timo Sirainen
a18503d5dc0751a1f9785e48438a219d95c0b9c2Timo Sirainen return index_mail_init_stream(mail, hdr_size, body_size, stream_r);
f6ae9ae80a1fcf6c8f45ab759f0074caaa66c9c8Timo Sirainen}
f6ae9ae80a1fcf6c8f45ab759f0074caaa66c9c8Timo Sirainen
f6ae9ae80a1fcf6c8f45ab759f0074caaa66c9c8Timo Sirainenstruct mail_vfuncs mbox_mail_vfuncs = {
f6ae9ae80a1fcf6c8f45ab759f0074caaa66c9c8Timo Sirainen index_mail_close,
f6ae9ae80a1fcf6c8f45ab759f0074caaa66c9c8Timo Sirainen index_mail_free,
a18503d5dc0751a1f9785e48438a219d95c0b9c2Timo Sirainen index_mail_set_seq,
f6ae9ae80a1fcf6c8f45ab759f0074caaa66c9c8Timo Sirainen index_mail_set_uid,
f6ae9ae80a1fcf6c8f45ab759f0074caaa66c9c8Timo Sirainen
f6ae9ae80a1fcf6c8f45ab759f0074caaa66c9c8Timo Sirainen index_mail_get_flags,
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen index_mail_get_keywords,
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen index_mail_get_parts,
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen index_mail_get_date,
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen mbox_mail_get_received_date,
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen mbox_mail_get_save_date,
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen index_mail_get_virtual_size,
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen mbox_mail_get_physical_size,
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen index_mail_get_first_header,
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen index_mail_get_headers,
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen index_mail_get_header_stream,
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen mbox_mail_get_stream,
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen mbox_mail_get_special,
a01faca549a403b2eda938cea0b1fb76c3ff44b6Aki Tuomi index_mail_update_flags,
a01faca549a403b2eda938cea0b1fb76c3ff44b6Aki Tuomi index_mail_update_keywords,
a01faca549a403b2eda938cea0b1fb76c3ff44b6Aki Tuomi index_mail_expunge
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen};
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen