sdbox-mail.c revision 804fa3f03bd9170272168a5ad214053bbe3160c7
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen/* Copyright (c) 2007-2017 Dovecot authors, see the included COPYING file */
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen#include "lib.h"
767431e5084a037c4dbefdf30ebfa03c84b1f449Timo Sirainen#include "ioloop.h"
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen#include "istream.h"
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainen#include "str.h"
5fb3f13537dffd15a31e997da133a721c0728af8Timo Sirainen#include "index-mail.h"
0779e926687b319fe1bcc0f1010ba7f88023e789Timo Sirainen#include "dbox-mail.h"
97437f768d1a3e6134fed1971202803fd250eef2Timo Sirainen#include "sdbox-storage.h"
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen#include "sdbox-file.h"
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainen
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainen#include <sys/stat.h>
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainen
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainenstatic void sdbox_mail_set_expunged(struct dbox_mail *mail)
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen{
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainen struct mail *_mail = &mail->imail.mail.mail;
e09c7dc961cb9cab04ec7cc79215c2f6318fbde0Timo Sirainen
23878bd03d1de531e3261a25598beec621351910Timo Sirainen mail_index_refresh(_mail->box->index);
23878bd03d1de531e3261a25598beec621351910Timo Sirainen if (mail_index_is_expunged(_mail->transaction->view, _mail->seq)) {
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainen mail_set_expunged(_mail);
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainen return;
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainen }
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainen
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainen mail_storage_set_critical(_mail->box->storage,
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainen "dbox %s: Unexpectedly lost uid=%u",
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen mailbox_get_path(_mail->box), _mail->uid);
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainen sdbox_set_mailbox_corrupted(_mail->box);
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainen}
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainen
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainenstatic int sdbox_mail_file_set(struct dbox_mail *mail)
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainen{
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainen struct mail *_mail = &mail->imail.mail.mail;
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainen struct sdbox_mailbox *mbox = (struct sdbox_mailbox *)_mail->box;
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainen bool deleted;
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainen int ret;
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainen
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainen if (mail->open_file != NULL) {
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainen /* already set */
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainen return 0;
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainen } else if (!_mail->saving) {
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainen mail->open_file = sdbox_file_init(mbox, _mail->uid);
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainen return 0;
7358272563d8ef77366447708ab0e58c0cff4151Timo Sirainen } else {
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainen /* mail is being saved in this transaction */
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainen mail->open_file =
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainen sdbox_save_file_get_file(_mail->transaction,
7358272563d8ef77366447708ab0e58c0cff4151Timo Sirainen _mail->seq);
7358272563d8ef77366447708ab0e58c0cff4151Timo Sirainen mail->open_file->refcount++;
97437f768d1a3e6134fed1971202803fd250eef2Timo Sirainen
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainen /* it doesn't have input stream yet */
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainen ret = dbox_file_open(mail->open_file, &deleted);
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen if (ret <= 0) {
23878bd03d1de531e3261a25598beec621351910Timo Sirainen mail_storage_set_critical(_mail->box->storage,
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen "dbox %s: Unexpectedly lost mail being saved",
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen mailbox_get_path(_mail->box));
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen sdbox_set_mailbox_corrupted(_mail->box);
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen return -1;
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen }
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen return 1;
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainen }
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainen}
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainenstatic int
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainensdbox_mail_get_special(struct mail *_mail, enum mail_fetch_field field,
0779e926687b319fe1bcc0f1010ba7f88023e789Timo Sirainen const char **value_r)
0f9a8663b0ff6fe30389d02284a2b002c40914ebTimo Sirainen{
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen struct sdbox_mailbox *mbox = (struct sdbox_mailbox *)_mail->box;
a9efdb661eb7a8a33aacfdcc3486dcc675a21543Timo Sirainen struct dbox_mail *mail = DBOX_MAIL(_mail);
a9efdb661eb7a8a33aacfdcc3486dcc675a21543Timo Sirainen struct stat st;
fab850a6aee4aaef4f4795bd7946807a3ba45041Timo Sirainen
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen switch (field) {
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen case MAIL_FETCH_REFCOUNT:
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen if (sdbox_mail_file_set(mail) < 0)
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen return -1;
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen
0779e926687b319fe1bcc0f1010ba7f88023e789Timo Sirainen _mail->transaction->stats.fstat_lookup_count++;
0779e926687b319fe1bcc0f1010ba7f88023e789Timo Sirainen if (dbox_file_stat(mail->open_file, &st) < 0) {
0779e926687b319fe1bcc0f1010ba7f88023e789Timo Sirainen if (errno == ENOENT)
0779e926687b319fe1bcc0f1010ba7f88023e789Timo Sirainen mail_set_expunged(_mail);
0779e926687b319fe1bcc0f1010ba7f88023e789Timo Sirainen return -1;
0779e926687b319fe1bcc0f1010ba7f88023e789Timo Sirainen }
97437f768d1a3e6134fed1971202803fd250eef2Timo Sirainen *value_r = p_strdup_printf(mail->imail.mail.data_pool, "%lu",
97437f768d1a3e6134fed1971202803fd250eef2Timo Sirainen (unsigned long)st.st_nlink);
97afa073e3e1e0301dc41173ec34beb08edcce50Timo Sirainen return 0;
97afa073e3e1e0301dc41173ec34beb08edcce50Timo Sirainen case MAIL_FETCH_UIDL_BACKEND:
b8b085f7bc6f1c0367802a9f00062bbbd981690dTimo Sirainen if (!dbox_header_have_flag(&mbox->box, mbox->hdr_ext_id,
b8b085f7bc6f1c0367802a9f00062bbbd981690dTimo Sirainen offsetof(struct sdbox_index_header, flags),
b8b085f7bc6f1c0367802a9f00062bbbd981690dTimo Sirainen DBOX_INDEX_HEADER_FLAG_HAVE_POP3_UIDLS)) {
94ba4820927b906b333e39445c1508a29387c3aaTimo Sirainen *value_r = "";
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainen return 0;
23878bd03d1de531e3261a25598beec621351910Timo Sirainen }
23878bd03d1de531e3261a25598beec621351910Timo Sirainen break;
23878bd03d1de531e3261a25598beec621351910Timo Sirainen case MAIL_FETCH_POP3_ORDER:
23878bd03d1de531e3261a25598beec621351910Timo Sirainen if (!dbox_header_have_flag(&mbox->box, mbox->hdr_ext_id,
23878bd03d1de531e3261a25598beec621351910Timo Sirainen offsetof(struct sdbox_index_header, flags),
23878bd03d1de531e3261a25598beec621351910Timo Sirainen DBOX_INDEX_HEADER_FLAG_HAVE_POP3_ORDERS)) {
23878bd03d1de531e3261a25598beec621351910Timo Sirainen *value_r = "";
23878bd03d1de531e3261a25598beec621351910Timo Sirainen return 0;
23878bd03d1de531e3261a25598beec621351910Timo Sirainen }
23878bd03d1de531e3261a25598beec621351910Timo Sirainen break;
23878bd03d1de531e3261a25598beec621351910Timo Sirainen default:
23878bd03d1de531e3261a25598beec621351910Timo Sirainen break;
ecbbdf594f9329fc15a182bd6c7c4a7fb144ed74Timo Sirainen }
ecbbdf594f9329fc15a182bd6c7c4a7fb144ed74Timo Sirainen return dbox_mail_get_special(_mail, field, value_r);
b8b085f7bc6f1c0367802a9f00062bbbd981690dTimo Sirainen}
94ba4820927b906b333e39445c1508a29387c3aaTimo Sirainen
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainenint sdbox_mail_open(struct dbox_mail *mail, uoff_t *offset_r,
struct dbox_file **file_r)
{
struct mail *_mail = &mail->imail.mail.mail;
bool deleted;
int ret;
if (_mail->lookup_abort != MAIL_LOOKUP_ABORT_NEVER) {
mail_set_aborted(_mail);
return -1;
}
_mail->mail_stream_opened = TRUE;
ret = sdbox_mail_file_set(mail);
if (ret < 0)
return -1;
if (ret == 0) {
if (!dbox_file_is_open(mail->open_file))
_mail->transaction->stats.open_lookup_count++;
if (dbox_file_open(mail->open_file, &deleted) <= 0)
return -1;
if (deleted) {
sdbox_mail_set_expunged(mail);
return -1;
}
}
*file_r = mail->open_file;
*offset_r = 0;
return 0;
}
struct mail_vfuncs sdbox_mail_vfuncs = {
dbox_mail_close,
index_mail_free,
index_mail_set_seq,
index_mail_set_uid,
index_mail_set_uid_cache_updates,
index_mail_prefetch,
index_mail_precache,
index_mail_add_temp_wanted_fields,
index_mail_get_flags,
index_mail_get_keywords,
index_mail_get_keyword_indexes,
index_mail_get_modseq,
index_mail_get_pvt_modseq,
index_mail_get_parts,
index_mail_get_date,
dbox_mail_get_received_date,
dbox_mail_get_save_date,
dbox_mail_get_virtual_size,
dbox_mail_get_physical_size,
index_mail_get_first_header,
index_mail_get_headers,
index_mail_get_header_stream,
dbox_mail_get_stream,
index_mail_get_binary_stream,
sdbox_mail_get_special,
index_mail_get_backend_mail,
index_mail_update_flags,
index_mail_update_keywords,
index_mail_update_modseq,
index_mail_update_pvt_modseq,
NULL,
index_mail_expunge,
index_mail_set_cache_corrupted,
index_mail_opened,
};