bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2003-2018 Dovecot authors, see the included COPYING file */
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "lib.h"
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen#include "ioloop.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "istream.h"
ea5f188fc29dfaa0c4071e6413e16e1d04263722Timo Sirainen#include "hex-binary.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "index-mail.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "mbox-storage.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "mbox-file.h"
f1901fd21906911f7be075c965ac882f6a87b4c3Timo Sirainen#include "mbox-lock.h"
63a61b7a739ae0f3f520215137d9c50f94d0f34fTimo Sirainen#include "mbox-sync-private.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "istream-raw-mbox.h"
18565c69efcd7db003dbf27cf625ed822e889fb1Timo Sirainen#include "istream-header-filter.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include <fcntl.h>
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include <unistd.h>
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include <sys/stat.h>
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
d22301419109ed4a38351715e6760011421dadecTimo Sirainenstatic void mbox_prepare_resync(struct mail *mail)
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen{
c150beda11da6fbbb1a936829550945d5e884f68Josef 'Jeff' Sipek struct mbox_transaction_context *t = MBOX_TRANSCTX(mail->transaction);
c150beda11da6fbbb1a936829550945d5e884f68Josef 'Jeff' Sipek struct mbox_mailbox *mbox = MBOX_MAILBOX(mail->box);
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen if (mbox->mbox_lock_type == F_RDLCK) {
86c6b2546b0bbfce326583f14d05f59674a6d861Timo Sirainen if (mbox->mbox_lock_id == t->read_lock_id)
86c6b2546b0bbfce326583f14d05f59674a6d861Timo Sirainen t->read_lock_id = 0;
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainen mbox_unlock(mbox, mbox->mbox_lock_id);
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen i_assert(mbox->mbox_lock_type == F_UNLCK);
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen }
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen}
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenstatic int mbox_mail_seek(struct index_mail *mail)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen{
d22301419109ed4a38351715e6760011421dadecTimo Sirainen struct mail *_mail = &mail->mail.mail;
c150beda11da6fbbb1a936829550945d5e884f68Josef 'Jeff' Sipek struct mbox_transaction_context *t = MBOX_TRANSCTX(_mail->transaction);
c150beda11da6fbbb1a936829550945d5e884f68Josef 'Jeff' Sipek struct mbox_mailbox *mbox = MBOX_MAILBOX(_mail->box);
f1901fd21906911f7be075c965ac882f6a87b4c3Timo Sirainen enum mbox_sync_flags sync_flags = 0;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen int ret, try;
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen bool deleted;
01cbf4ac5d44137ab434791be7f838d98d0fcf3bTimo Sirainen
d22301419109ed4a38351715e6760011421dadecTimo Sirainen if (_mail->expunged || mbox->syncing)
4b41116563110d00330896a568eff1078c382827Timo Sirainen return -1;
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainen
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen if (_mail->lookup_abort != MAIL_LOOKUP_ABORT_NEVER) {
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen mail_set_aborted(_mail);
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen return -1;
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen }
7204b8112e005ff81dcf628f7880ef1feed1effeTimo Sirainen _mail->mail_stream_opened = TRUE;
ebe6df72f1309135f02b6a4d2aef1e81a073f91cTimo Sirainen
b12a6d0e54318273acf0d0fb8b3f4c29f67b62b0Timo Sirainen if (mbox->mbox_stream != NULL &&
b12a6d0e54318273acf0d0fb8b3f4c29f67b62b0Timo Sirainen istream_raw_mbox_is_corrupted(mbox->mbox_stream)) {
b12a6d0e54318273acf0d0fb8b3f4c29f67b62b0Timo Sirainen /* clear the corruption by forcing a full resync */
b12a6d0e54318273acf0d0fb8b3f4c29f67b62b0Timo Sirainen sync_flags |= MBOX_SYNC_UNDIRTY | MBOX_SYNC_FORCE_SYNC;
b12a6d0e54318273acf0d0fb8b3f4c29f67b62b0Timo Sirainen }
b12a6d0e54318273acf0d0fb8b3f4c29f67b62b0Timo Sirainen
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen for (try = 0; try < 2; try++) {
73247459cf41eb1e5ae5bc61354db46d3b05ee75Timo Sirainen if ((sync_flags & MBOX_SYNC_FORCE_SYNC) != 0) {
73247459cf41eb1e5ae5bc61354db46d3b05ee75Timo Sirainen /* dirty offsets are broken. make sure we can sync. */
d22301419109ed4a38351715e6760011421dadecTimo Sirainen mbox_prepare_resync(_mail);
73247459cf41eb1e5ae5bc61354db46d3b05ee75Timo Sirainen }
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen if (mbox->mbox_lock_type == F_UNLCK) {
86c6b2546b0bbfce326583f14d05f59674a6d861Timo Sirainen i_assert(t->read_lock_id == 0);
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen sync_flags |= MBOX_SYNC_LOCK_READING;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen if (mbox_sync(mbox, sync_flags) < 0)
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen return -1;
86c6b2546b0bbfce326583f14d05f59674a6d861Timo Sirainen t->read_lock_id = mbox_get_cur_lock_id(mbox);
86c6b2546b0bbfce326583f14d05f59674a6d861Timo Sirainen i_assert(t->read_lock_id != 0);
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen /* refresh index file after mbox has been locked to
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen make sure we get only up-to-date mbox offsets. */
d22301419109ed4a38351715e6760011421dadecTimo Sirainen if (mail_index_refresh(mbox->box.index) < 0) {
1f1ee8db68d9ae1604350801cd8dc33ebe29fe8aTimo Sirainen mailbox_set_index_error(&mbox->box);
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen return -1;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen }
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen i_assert(mbox->mbox_lock_type != F_UNLCK);
86c6b2546b0bbfce326583f14d05f59674a6d861Timo Sirainen } else if (t->read_lock_id == 0) {
73247459cf41eb1e5ae5bc61354db46d3b05ee75Timo Sirainen /* file is already locked by another transaction, but
73247459cf41eb1e5ae5bc61354db46d3b05ee75Timo Sirainen we must keep it locked for the entire transaction,
73247459cf41eb1e5ae5bc61354db46d3b05ee75Timo Sirainen so increase the lock counter. */
73247459cf41eb1e5ae5bc61354db46d3b05ee75Timo Sirainen if (mbox_lock(mbox, mbox->mbox_lock_type,
86c6b2546b0bbfce326583f14d05f59674a6d861Timo Sirainen &t->read_lock_id) < 0)
73247459cf41eb1e5ae5bc61354db46d3b05ee75Timo Sirainen i_unreached();
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen }
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen if (mbox_file_open_stream(mbox) < 0)
597dce34068d603fb759b4dff404b34049213e51Timo Sirainen return -1;
63a61b7a739ae0f3f520215137d9c50f94d0f34fTimo Sirainen
cd83124e5d070a016c590bb0b1096d7828c7b6adTimo Sirainen ret = mbox_file_seek(mbox, _mail->transaction->view,
d22301419109ed4a38351715e6760011421dadecTimo Sirainen _mail->seq, &deleted);
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen if (ret > 0) {
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen /* success */
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen break;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen }
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen if (ret < 0) {
4b41116563110d00330896a568eff1078c382827Timo Sirainen if (deleted)
d22301419109ed4a38351715e6760011421dadecTimo Sirainen mail_set_expunged(_mail);
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen return -1;
f1901fd21906911f7be075c965ac882f6a87b4c3Timo Sirainen }
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
f1901fd21906911f7be075c965ac882f6a87b4c3Timo Sirainen /* we'll need to re-sync it completely */
6060b7c8edf8fce73470d0df6a2479b69b01c537Timo Sirainen sync_flags |= MBOX_SYNC_UNDIRTY | MBOX_SYNC_FORCE_SYNC;
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen }
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen if (ret == 0) {
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi mail_set_critical(_mail, "mbox: Losing sync");
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen }
4b41116563110d00330896a568eff1078c382827Timo Sirainen return 0;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen}
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenstatic int mbox_mail_get_received_date(struct mail *_mail, time_t *date_r)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen{
87490012895b4f371635ded00add04c9107dcfefJosef 'Jeff' Sipek struct index_mail *mail = INDEX_MAIL(_mail);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen struct index_mail_data *data = &mail->data;
c150beda11da6fbbb1a936829550945d5e884f68Josef 'Jeff' Sipek struct mbox_mailbox *mbox = MBOX_MAILBOX(_mail->box);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen if (index_mail_get_received_date(_mail, date_r) == 0)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return 0;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
4b41116563110d00330896a568eff1078c382827Timo Sirainen if (mbox_mail_seek(mail) < 0)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return -1;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen data->received_date =
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen istream_raw_mbox_get_received_time(mbox->mbox_stream);
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen if (data->received_date == (time_t)-1) {
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen /* it's broken and conflicts with our "not found"
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen return value. change it. */
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen data->received_date = 0;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen }
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen *date_r = data->received_date;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return 0;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen}
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenstatic int mbox_mail_get_save_date(struct mail *_mail, time_t *date_r)
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen{
87490012895b4f371635ded00add04c9107dcfefJosef 'Jeff' Sipek struct index_mail *mail = INDEX_MAIL(_mail);
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen struct index_mail_data *data = &mail->data;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen if (index_mail_get_save_date(_mail, date_r) == 0)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return 0;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen /* no way to know this. save the current time into cache and use
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen that from now on. this works only as long as the index files
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen are permanent */
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen data->save_date = ioloop_time;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen *date_r = data->save_date;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return 0;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen}
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen
915bb1572a406d30013ed3ee83fba7082a6d1baePhil Carmodystatic int
5daa12cc1c862eec4f63df42227812d3514da2ccTimo Sirainenmbox_mail_get_md5_header(struct index_mail *mail, const char **value_r)
5daa12cc1c862eec4f63df42227812d3514da2ccTimo Sirainen{
fc22ecbb03396eda9270472446a6065a986a43e0Timo Sirainen struct mail *_mail = &mail->mail.mail;
5daa12cc1c862eec4f63df42227812d3514da2ccTimo Sirainen static uint8_t empty_md5[16] =
5daa12cc1c862eec4f63df42227812d3514da2ccTimo Sirainen { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
c150beda11da6fbbb1a936829550945d5e884f68Josef 'Jeff' Sipek struct mbox_mailbox *mbox = MBOX_MAILBOX(_mail->box);
5daa12cc1c862eec4f63df42227812d3514da2ccTimo Sirainen const void *ext_data;
5daa12cc1c862eec4f63df42227812d3514da2ccTimo Sirainen
e6aa82aeb50948cb47a45a1b61a9c16d6a162388Timo Sirainen if (mail->data.guid != NULL) {
e6aa82aeb50948cb47a45a1b61a9c16d6a162388Timo Sirainen *value_r = mail->data.guid;
fc22ecbb03396eda9270472446a6065a986a43e0Timo Sirainen return 1;
e6aa82aeb50948cb47a45a1b61a9c16d6a162388Timo Sirainen }
bf9402875418faf11825cf11fbe06326b6086e3dTimo Sirainen
fc22ecbb03396eda9270472446a6065a986a43e0Timo Sirainen mail_index_lookup_ext(_mail->transaction->view, _mail->seq,
fc22ecbb03396eda9270472446a6065a986a43e0Timo Sirainen mbox->md5hdr_ext_idx, &ext_data, NULL);
5daa12cc1c862eec4f63df42227812d3514da2ccTimo Sirainen if (ext_data != NULL && memcmp(ext_data, empty_md5, 16) != 0) {
5f44975ec6c5755dd74bcd4c47a123a7242ecab3Timo Sirainen mail->data.guid = p_strdup(mail->mail.data_pool,
bf9402875418faf11825cf11fbe06326b6086e3dTimo Sirainen binary_to_hex(ext_data, 16));
bf9402875418faf11825cf11fbe06326b6086e3dTimo Sirainen *value_r = mail->data.guid;
fc22ecbb03396eda9270472446a6065a986a43e0Timo Sirainen return 1;
fc22ecbb03396eda9270472446a6065a986a43e0Timo Sirainen } else if (mail_index_is_expunged(_mail->transaction->view, _mail->seq)) {
fc22ecbb03396eda9270472446a6065a986a43e0Timo Sirainen mail_set_expunged(_mail);
fc22ecbb03396eda9270472446a6065a986a43e0Timo Sirainen return -1;
5daa12cc1c862eec4f63df42227812d3514da2ccTimo Sirainen } else {
fc22ecbb03396eda9270472446a6065a986a43e0Timo Sirainen return 0;
5daa12cc1c862eec4f63df42227812d3514da2ccTimo Sirainen }
5daa12cc1c862eec4f63df42227812d3514da2ccTimo Sirainen}
5daa12cc1c862eec4f63df42227812d3514da2ccTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenstatic int
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenmbox_mail_get_special(struct mail *_mail, enum mail_fetch_field field,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen const char **value_r)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen{
87490012895b4f371635ded00add04c9107dcfefJosef 'Jeff' Sipek struct index_mail *mail = INDEX_MAIL(_mail);
c150beda11da6fbbb1a936829550945d5e884f68Josef 'Jeff' Sipek struct mbox_mailbox *mbox = MBOX_MAILBOX(_mail->box);
f140f88a5ab3e2194f214c11f9f418559e949c83Timo Sirainen uoff_t offset;
36f4f01d56ec9156ab75bc2047a8388192df3178Timo Sirainen bool move_offset;
fc22ecbb03396eda9270472446a6065a986a43e0Timo Sirainen int ret;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen switch (field) {
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen case MAIL_FETCH_FROM_ENVELOPE:
4b41116563110d00330896a568eff1078c382827Timo Sirainen if (mbox_mail_seek(mail) < 0)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return -1;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen *value_r = istream_raw_mbox_get_sender(mbox->mbox_stream);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return 0;
ee3e01f75b1db691bf20dd4e2558965421b8f937Timo Sirainen case MAIL_FETCH_GUID:
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen case MAIL_FETCH_HEADER_MD5:
fc22ecbb03396eda9270472446a6065a986a43e0Timo Sirainen if ((ret = mbox_mail_get_md5_header(mail, value_r)) != 0)
fc22ecbb03396eda9270472446a6065a986a43e0Timo Sirainen return ret < 0 ? -1 : 0;
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen
ea5f188fc29dfaa0c4071e6413e16e1d04263722Timo Sirainen /* i guess in theory the empty_md5 is valid and can happen,
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen but it's almost guaranteed that it means the MD5 sum is
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen missing. recalculate it. */
36f4f01d56ec9156ab75bc2047a8388192df3178Timo Sirainen if (mbox->mbox_lock_type == F_UNLCK ||
36f4f01d56ec9156ab75bc2047a8388192df3178Timo Sirainen mbox->mbox_stream == NULL) {
36f4f01d56ec9156ab75bc2047a8388192df3178Timo Sirainen offset = 0;
36f4f01d56ec9156ab75bc2047a8388192df3178Timo Sirainen move_offset = FALSE;
36f4f01d56ec9156ab75bc2047a8388192df3178Timo Sirainen } else {
36f4f01d56ec9156ab75bc2047a8388192df3178Timo Sirainen offset = istream_raw_mbox_get_start_offset(mbox->mbox_stream);
36f4f01d56ec9156ab75bc2047a8388192df3178Timo Sirainen move_offset = TRUE;
36f4f01d56ec9156ab75bc2047a8388192df3178Timo Sirainen }
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen mbox->mbox_save_md5 = TRUE;
f140f88a5ab3e2194f214c11f9f418559e949c83Timo Sirainen if (mbox_sync(mbox, MBOX_SYNC_FORCE_SYNC |
f140f88a5ab3e2194f214c11f9f418559e949c83Timo Sirainen MBOX_SYNC_READONLY) < 0)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return -1;
36f4f01d56ec9156ab75bc2047a8388192df3178Timo Sirainen if (move_offset) {
cbcde6379f1b0b27bdefc4b11eec93ad69e459d4Timo Sirainen if (istream_raw_mbox_seek(mbox->mbox_stream,
cbcde6379f1b0b27bdefc4b11eec93ad69e459d4Timo Sirainen offset) < 0) {
cbcde6379f1b0b27bdefc4b11eec93ad69e459d4Timo Sirainen i_error("mbox %s sync lost during MD5 syncing",
cbcde6379f1b0b27bdefc4b11eec93ad69e459d4Timo Sirainen _mail->box->name);
cbcde6379f1b0b27bdefc4b11eec93ad69e459d4Timo Sirainen return -1;
cbcde6379f1b0b27bdefc4b11eec93ad69e459d4Timo Sirainen }
f140f88a5ab3e2194f214c11f9f418559e949c83Timo Sirainen }
5daa12cc1c862eec4f63df42227812d3514da2ccTimo Sirainen
fc22ecbb03396eda9270472446a6065a986a43e0Timo Sirainen if ((ret = mbox_mail_get_md5_header(mail, value_r)) == 0) {
e48c10b9db945fd72e2315e3ec343174fa55c7c7Timo Sirainen i_error("mbox %s resyncing didn't save header MD5 values",
e48c10b9db945fd72e2315e3ec343174fa55c7c7Timo Sirainen _mail->box->name);
5daa12cc1c862eec4f63df42227812d3514da2ccTimo Sirainen return -1;
5daa12cc1c862eec4f63df42227812d3514da2ccTimo Sirainen }
fc22ecbb03396eda9270472446a6065a986a43e0Timo Sirainen return ret < 0 ? -1 : 0;
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen default:
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen break;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen }
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return index_mail_get_special(_mail, field, value_r);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen}
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
915bb1572a406d30013ed3ee83fba7082a6d1baePhil Carmodystatic int
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainenmbox_mail_get_next_offset(struct index_mail *mail, uoff_t *next_offset_r)
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen{
c150beda11da6fbbb1a936829550945d5e884f68Josef 'Jeff' Sipek struct mbox_mailbox *mbox = MBOX_MAILBOX(mail->mail.mail.box);
54d42552005111841ab45ec9ca7559075fabd5dfTimo Sirainen struct mail_index_view *view;
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen const struct mail_index_header *hdr;
54d42552005111841ab45ec9ca7559075fabd5dfTimo Sirainen uint32_t seq;
54d42552005111841ab45ec9ca7559075fabd5dfTimo Sirainen int trailer_size;
5abb33fdc94c081ccd3213bf7d0fa9d0367b4bfdTimo Sirainen int ret = 1;
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen
7bd301fdbfefe7cef3576d19ece29c75ebe53bafTimo Sirainen *next_offset_r = (uoff_t)-1;
7bd301fdbfefe7cef3576d19ece29c75ebe53bafTimo Sirainen
cd83124e5d070a016c590bb0b1096d7828c7b6adTimo Sirainen hdr = mail_index_get_header(mail->mail.mail.transaction->view);
54d42552005111841ab45ec9ca7559075fabd5dfTimo Sirainen if (mail->mail.mail.seq > hdr->messages_count) {
54d42552005111841ab45ec9ca7559075fabd5dfTimo Sirainen /* we're appending a new message */
5abb33fdc94c081ccd3213bf7d0fa9d0367b4bfdTimo Sirainen return 0;
54d42552005111841ab45ec9ca7559075fabd5dfTimo Sirainen }
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen
54d42552005111841ab45ec9ca7559075fabd5dfTimo Sirainen /* We can't really trust trans_view. The next message may already be
8ed8c821ba8aab0b4ed0375f87d48737ef0e0d8eTimo Sirainen expunged from it. Also hdr.messages_count may be incorrect there.
690bafa70767e3f6e98bbfd62ad4a26be2387ea9Timo Sirainen So refresh the index to get the latest changes and get the next
690bafa70767e3f6e98bbfd62ad4a26be2387ea9Timo Sirainen message's offset using a new view. */
8ed8c821ba8aab0b4ed0375f87d48737ef0e0d8eTimo Sirainen i_assert(mbox->mbox_lock_type != F_UNLCK);
690bafa70767e3f6e98bbfd62ad4a26be2387ea9Timo Sirainen if (mbox_sync_header_refresh(mbox) < 0)
690bafa70767e3f6e98bbfd62ad4a26be2387ea9Timo Sirainen return -1;
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen
d22301419109ed4a38351715e6760011421dadecTimo Sirainen view = mail_index_view_open(mail->mail.mail.box->index);
54d42552005111841ab45ec9ca7559075fabd5dfTimo Sirainen hdr = mail_index_get_header(view);
54d42552005111841ab45ec9ca7559075fabd5dfTimo Sirainen if (!mail_index_lookup_seq(view, mail->mail.mail.uid, &seq))
54d42552005111841ab45ec9ca7559075fabd5dfTimo Sirainen i_panic("Message unexpectedly expunged from index");
54d42552005111841ab45ec9ca7559075fabd5dfTimo Sirainen
767cd7e92a46ca7c0dc4823936750b2bf2eb99e3Timo Sirainen if (seq < hdr->messages_count) {
767cd7e92a46ca7c0dc4823936750b2bf2eb99e3Timo Sirainen if (mbox_file_lookup_offset(mbox, view, seq + 1,
767cd7e92a46ca7c0dc4823936750b2bf2eb99e3Timo Sirainen next_offset_r) <= 0)
767cd7e92a46ca7c0dc4823936750b2bf2eb99e3Timo Sirainen ret = -1;
767cd7e92a46ca7c0dc4823936750b2bf2eb99e3Timo Sirainen } else if (mail->mail.mail.box->input != NULL) {
767cd7e92a46ca7c0dc4823936750b2bf2eb99e3Timo Sirainen /* opened the mailbox as input stream. we can't trust the
767cd7e92a46ca7c0dc4823936750b2bf2eb99e3Timo Sirainen sync_size, since it's wrong with compressed mailboxes */
767cd7e92a46ca7c0dc4823936750b2bf2eb99e3Timo Sirainen ret = 0;
767cd7e92a46ca7c0dc4823936750b2bf2eb99e3Timo Sirainen } else {
54d42552005111841ab45ec9ca7559075fabd5dfTimo Sirainen /* last message, use the synced mbox size */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen trailer_size =
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen mbox->storage->storage.set->mail_save_crlf ? 2 : 1;
690bafa70767e3f6e98bbfd62ad4a26be2387ea9Timo Sirainen *next_offset_r = mbox->mbox_hdr.sync_size - trailer_size;
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen }
54d42552005111841ab45ec9ca7559075fabd5dfTimo Sirainen mail_index_view_close(&view);
54d42552005111841ab45ec9ca7559075fabd5dfTimo Sirainen return ret;
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen}
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenstatic int mbox_mail_get_physical_size(struct mail *_mail, uoff_t *size_r)
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen{
87490012895b4f371635ded00add04c9107dcfefJosef 'Jeff' Sipek struct index_mail *mail = INDEX_MAIL(_mail);
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen struct index_mail_data *data = &mail->data;
c150beda11da6fbbb1a936829550945d5e884f68Josef 'Jeff' Sipek struct mbox_mailbox *mbox = MBOX_MAILBOX(_mail->box);
aa215ab623706463cea1d047f975ffe51d3f0c05Timo Sirainen struct istream *input;
aa215ab623706463cea1d047f975ffe51d3f0c05Timo Sirainen struct message_size hdr_size;
a5c8dc283ef673fcdae158513b8032e74b45f59aTimo Sirainen uoff_t old_offset, body_offset, body_size, next_offset;
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen
aa215ab623706463cea1d047f975ffe51d3f0c05Timo Sirainen if (index_mail_get_physical_size(_mail, size_r) == 0)
aa215ab623706463cea1d047f975ffe51d3f0c05Timo Sirainen return 0;
aa215ab623706463cea1d047f975ffe51d3f0c05Timo Sirainen
aa215ab623706463cea1d047f975ffe51d3f0c05Timo Sirainen /* we want to return the header size as seen by mail_get_stream(). */
a5c8dc283ef673fcdae158513b8032e74b45f59aTimo Sirainen old_offset = data->stream == NULL ? 0 : data->stream->v_offset;
aa215ab623706463cea1d047f975ffe51d3f0c05Timo Sirainen if (mail_get_stream(_mail, &hdr_size, NULL, &input) < 0)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return -1;
a1808be0774cbcb28fec45341aabf803ec44bae5Timo Sirainen
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen /* our header size varies, so don't do any caching */
3063bd8ff05d3d8cd33156f4366b36890e501436Timo Sirainen if (istream_raw_mbox_get_body_offset(mbox->mbox_stream, &body_offset) < 0) {
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi mail_set_critical(_mail, "mbox: Couldn't get body offset");
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return -1;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen }
1b5366b2234892f8930a29351da06b193e385150Timo Sirainen
1b5366b2234892f8930a29351da06b193e385150Timo Sirainen /* use the next message's offset to avoid reading through the entire
1b5366b2234892f8930a29351da06b193e385150Timo Sirainen message body to find out its size */
5abb33fdc94c081ccd3213bf7d0fa9d0367b4bfdTimo Sirainen if (mbox_mail_get_next_offset(mail, &next_offset) > 0)
1b5366b2234892f8930a29351da06b193e385150Timo Sirainen body_size = next_offset - body_offset;
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen else
1b5366b2234892f8930a29351da06b193e385150Timo Sirainen body_size = (uoff_t)-1;
1b5366b2234892f8930a29351da06b193e385150Timo Sirainen
1b5366b2234892f8930a29351da06b193e385150Timo Sirainen /* verify that the calculated body size is correct */
3063bd8ff05d3d8cd33156f4366b36890e501436Timo Sirainen if (istream_raw_mbox_get_body_size(mbox->mbox_stream,
3063bd8ff05d3d8cd33156f4366b36890e501436Timo Sirainen body_size, &body_size) < 0) {
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi mail_set_critical(_mail, "mbox: Couldn't get body size");
3063bd8ff05d3d8cd33156f4366b36890e501436Timo Sirainen return -1;
3063bd8ff05d3d8cd33156f4366b36890e501436Timo Sirainen }
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen
aa215ab623706463cea1d047f975ffe51d3f0c05Timo Sirainen data->physical_size = hdr_size.physical_size + body_size;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen *size_r = data->physical_size;
a5c8dc283ef673fcdae158513b8032e74b45f59aTimo Sirainen
a5c8dc283ef673fcdae158513b8032e74b45f59aTimo Sirainen i_stream_seek(input, old_offset);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return 0;
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen}
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainenstatic int mbox_mail_init_stream(struct index_mail *mail)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen{
c150beda11da6fbbb1a936829550945d5e884f68Josef 'Jeff' Sipek struct mbox_mailbox *mbox = MBOX_MAILBOX(mail->mail.mail.box);
b2ecd50bb98c44816cb07c17aa17fae2b425f941Timo Sirainen struct istream *raw_stream;
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen uoff_t hdr_offset, next_offset;
5abb33fdc94c081ccd3213bf7d0fa9d0367b4bfdTimo Sirainen int ret;
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen if (mbox_mail_seek(mail) < 0)
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen return -1;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
5abb33fdc94c081ccd3213bf7d0fa9d0367b4bfdTimo Sirainen ret = mbox_mail_get_next_offset(mail, &next_offset);
5abb33fdc94c081ccd3213bf7d0fa9d0367b4bfdTimo Sirainen if (ret < 0) {
4b41116563110d00330896a568eff1078c382827Timo Sirainen if (mbox_mail_seek(mail) < 0)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return -1;
5abb33fdc94c081ccd3213bf7d0fa9d0367b4bfdTimo Sirainen ret = mbox_mail_get_next_offset(mail, &next_offset);
5abb33fdc94c081ccd3213bf7d0fa9d0367b4bfdTimo Sirainen if (ret < 0) {
f480b30abdddf6f1beb8a2c5b1ce4bf8999400dbTimo Sirainen i_warning("mbox %s: Can't find next message offset "
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen "for uid=%u", mailbox_get_path(&mbox->box),
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen mail->mail.mail.uid);
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen }
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen }
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen raw_stream = mbox->mbox_stream;
3063bd8ff05d3d8cd33156f4366b36890e501436Timo Sirainen if (istream_raw_mbox_get_header_offset(raw_stream, &hdr_offset) < 0) {
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi mail_set_critical(&mail->mail.mail,
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi "mbox: Couldn't get header offset");
3063bd8ff05d3d8cd33156f4366b36890e501436Timo Sirainen return -1;
3063bd8ff05d3d8cd33156f4366b36890e501436Timo Sirainen }
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen i_stream_seek(raw_stream, hdr_offset);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen if (next_offset != (uoff_t)-1)
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen istream_raw_mbox_set_next_offset(raw_stream, next_offset);
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen raw_stream = i_stream_create_limit(raw_stream, (uoff_t)-1);
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen mail->data.stream =
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen i_stream_create_header_filter(raw_stream,
8f017a40470ef2f4b530000d947a8bce44350a5eTimo Sirainen HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR,
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen mbox_hide_headers, mbox_hide_headers_count,
677b75f90d81eafe742896d6570a2f63ce501d05Josef 'Jeff' Sipek *null_header_filter_callback, NULL);
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen i_stream_unref(&raw_stream);
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen return 0;
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen}
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen
6df0ab0c1ab91f06b6418cb30eff44405a1b8f02Timo Sirainenstatic int mbox_mail_get_stream(struct mail *_mail, bool get_body ATTR_UNUSED,
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen struct message_size *hdr_size,
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen struct message_size *body_size,
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen struct istream **stream_r)
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen{
87490012895b4f371635ded00add04c9107dcfefJosef 'Jeff' Sipek struct index_mail *mail = INDEX_MAIL(_mail);
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen if (mail->data.stream == NULL) {
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen if (mbox_mail_init_stream(mail) < 0)
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen return -1;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen }
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return index_mail_init_stream(mail, hdr_size, body_size, stream_r);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen}
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
7631f16156aca373004953fe6b01a7f343fb47e0Timo Sirainenstatic void mbox_mail_set_seq(struct mail *_mail, uint32_t seq, bool saving)
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen{
87490012895b4f371635ded00add04c9107dcfefJosef 'Jeff' Sipek struct index_mail *mail = INDEX_MAIL(_mail);
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen
7631f16156aca373004953fe6b01a7f343fb47e0Timo Sirainen index_mail_set_seq(_mail, seq, saving);
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen mail->data.dont_cache_fetch_fields |= MAIL_FETCH_PHYSICAL_SIZE;
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen}
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainenstatic bool mbox_mail_set_uid(struct mail *_mail, uint32_t uid)
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen{
87490012895b4f371635ded00add04c9107dcfefJosef 'Jeff' Sipek struct index_mail *mail = INDEX_MAIL(_mail);
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen bool ret;
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen ret = index_mail_set_uid(_mail, uid);
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen mail->data.dont_cache_fetch_fields |= MAIL_FETCH_PHYSICAL_SIZE;
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen return ret;
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen}
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenstruct mail_vfuncs mbox_mail_vfuncs = {
0d86aa0d47f7393c669c084b34c0537b193688adTimo Sirainen index_mail_close,
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen index_mail_free,
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen mbox_mail_set_seq,
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen mbox_mail_set_uid,
aa247243412a49f9bdebf7255e131dc6ece4ed46Timo Sirainen index_mail_set_uid_cache_updates,
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen index_mail_prefetch,
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen index_mail_precache,
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainen index_mail_add_temp_wanted_fields,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen index_mail_get_flags,
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen index_mail_get_keywords,
a757f31393b9d6fc7760a9dec8363404ab3ae576Timo Sirainen index_mail_get_keyword_indexes,
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen index_mail_get_modseq,
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen index_mail_get_pvt_modseq,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen index_mail_get_parts,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen index_mail_get_date,
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen mbox_mail_get_received_date,
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen mbox_mail_get_save_date,
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen index_mail_get_virtual_size,
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen mbox_mail_get_physical_size,
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen index_mail_get_first_header,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen index_mail_get_headers,
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen index_mail_get_header_stream,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen mbox_mail_get_stream,
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen index_mail_get_binary_stream,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen mbox_mail_get_special,
21aaa6affb9f134112b75b5db737309fc35ef1cfMartti Rannanjärvi index_mail_get_backend_mail,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen index_mail_update_flags,
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen index_mail_update_keywords,
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen index_mail_update_modseq,
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen index_mail_update_pvt_modseq,
225e82df5dd1e765f4e52b80c954558f00e5a7dfTimo Sirainen NULL,
838e367716bbd5e44b4a1691db9cbf72af53e9f0Timo Sirainen index_mail_expunge,
6564208826b0f46a00f010d1b5711d85944c3c88Timo Sirainen index_mail_set_cache_corrupted,
6de6ec228a41275ddda972d4a554699ea75cd06dTimo Sirainen index_mail_opened,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen};