bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2007-2018 Dovecot authors, see the included COPYING file */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "lib.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "ioloop.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "istream.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "str.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "index-mail.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "dbox-mail.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "sdbox-storage.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include "sdbox-file.h"
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include <sys/stat.h>
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic void sdbox_mail_set_expunged(struct dbox_mail *mail)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct mail *_mail = &mail->imail.mail.mail;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainen mail_index_refresh(_mail->box->index);
0a7b04ec6441fdcf083392888b2e30844fc3e86dTimo Sirainen if (mail_index_is_expunged(_mail->transaction->view, _mail->seq)) {
0a7b04ec6441fdcf083392888b2e30844fc3e86dTimo Sirainen mail_set_expunged(_mail);
0a7b04ec6441fdcf083392888b2e30844fc3e86dTimo Sirainen return;
0a7b04ec6441fdcf083392888b2e30844fc3e86dTimo Sirainen }
0a7b04ec6441fdcf083392888b2e30844fc3e86dTimo Sirainen
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi mail_set_critical(_mail, "dbox: Unexpectedly lost uid");
0a7b04ec6441fdcf083392888b2e30844fc3e86dTimo Sirainen sdbox_set_mailbox_corrupted(_mail->box);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainenstatic int sdbox_mail_file_set(struct dbox_mail *mail)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct mail *_mail = &mail->imail.mail.mail;
df3963075d67f76ade66b6a74764f4eae31d9c87Josef 'Jeff' Sipek struct sdbox_mailbox *mbox = SDBOX_MAILBOX(_mail->box);
d665e2948cb6fe8016706752a9e4940d64f4a61dTimo Sirainen bool deleted;
d665e2948cb6fe8016706752a9e4940d64f4a61dTimo Sirainen int ret;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (mail->open_file != NULL) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* already set */
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainen return 0;
fc40a9a002458e372ff4b9f6f4e15239520c0bcdTimo Sirainen } else if (!_mail->saving) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mail->open_file = sdbox_file_init(mbox, _mail->uid);
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainen return 0;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen } else {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* mail is being saved in this transaction */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mail->open_file =
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen sdbox_save_file_get_file(_mail->transaction,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen _mail->seq);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mail->open_file->refcount++;
d665e2948cb6fe8016706752a9e4940d64f4a61dTimo Sirainen
d665e2948cb6fe8016706752a9e4940d64f4a61dTimo Sirainen /* it doesn't have input stream yet */
4ca83616715c3bd417e34ced2c1d61852513e427Timo Sirainen ret = dbox_file_open(mail->open_file, &deleted);
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainen if (ret <= 0) {
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi mail_set_critical(_mail,
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi "dbox: Unexpectedly lost mail being saved");
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainen sdbox_set_mailbox_corrupted(_mail->box);
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainen return -1;
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainen }
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainen return 1;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainenstatic int
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainensdbox_mail_get_special(struct mail *_mail, enum mail_fetch_field field,
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen const char **value_r)
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen{
df3963075d67f76ade66b6a74764f4eae31d9c87Josef 'Jeff' Sipek struct sdbox_mailbox *mbox = SDBOX_MAILBOX(_mail->box);
804fa3f03bd9170272168a5ad214053bbe3160c7Josef 'Jeff' Sipek struct dbox_mail *mail = DBOX_MAIL(_mail);
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen struct stat st;
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen switch (field) {
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen case MAIL_FETCH_REFCOUNT:
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen if (sdbox_mail_file_set(mail) < 0)
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen return -1;
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen _mail->transaction->stats.fstat_lookup_count++;
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen if (dbox_file_stat(mail->open_file, &st) < 0) {
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen if (errno == ENOENT)
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen mail_set_expunged(_mail);
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen return -1;
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen }
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen *value_r = p_strdup_printf(mail->imail.mail.data_pool, "%lu",
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen (unsigned long)st.st_nlink);
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen return 0;
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen case MAIL_FETCH_UIDL_BACKEND:
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen if (!dbox_header_have_flag(&mbox->box, mbox->hdr_ext_id,
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen offsetof(struct sdbox_index_header, flags),
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen DBOX_INDEX_HEADER_FLAG_HAVE_POP3_UIDLS)) {
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen *value_r = "";
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen return 0;
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen }
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen break;
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen case MAIL_FETCH_POP3_ORDER:
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen if (!dbox_header_have_flag(&mbox->box, mbox->hdr_ext_id,
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen offsetof(struct sdbox_index_header, flags),
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen DBOX_INDEX_HEADER_FLAG_HAVE_POP3_ORDERS)) {
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen *value_r = "";
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen return 0;
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen }
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen break;
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen default:
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen break;
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen }
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen return dbox_mail_get_special(_mail, field, value_r);
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen}
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenint sdbox_mail_open(struct dbox_mail *mail, uoff_t *offset_r,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct dbox_file **file_r)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct mail *_mail = &mail->imail.mail.mail;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen bool deleted;
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainen int ret;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (_mail->lookup_abort != MAIL_LOOKUP_ABORT_NEVER) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mail_set_aborted(_mail);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return -1;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
7204b8112e005ff81dcf628f7880ef1feed1effeTimo Sirainen _mail->mail_stream_opened = TRUE;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainen ret = sdbox_mail_file_set(mail);
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainen if (ret < 0)
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainen return -1;
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainen if (ret == 0) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (!dbox_file_is_open(mail->open_file))
2d01cc1880cf2afd4fb1c8ad7fa6ce78e562e71eTimo Sirainen _mail->transaction->stats.open_lookup_count++;
4ca83616715c3bd417e34ced2c1d61852513e427Timo Sirainen if (dbox_file_open(mail->open_file, &deleted) <= 0)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return -1;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (deleted) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen sdbox_mail_set_expunged(mail);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return -1;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen *file_r = mail->open_file;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen *offset_r = 0;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return 0;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstruct mail_vfuncs sdbox_mail_vfuncs = {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen dbox_mail_close,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_mail_free,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_mail_set_seq,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_mail_set_uid,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo 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,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_mail_get_flags,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_mail_get_keywords,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_mail_get_keyword_indexes,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_mail_get_modseq,
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen index_mail_get_pvt_modseq,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_mail_get_parts,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_mail_get_date,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen dbox_mail_get_received_date,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen dbox_mail_get_save_date,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen dbox_mail_get_virtual_size,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen dbox_mail_get_physical_size,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_mail_get_first_header,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_mail_get_headers,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_mail_get_header_stream,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen dbox_mail_get_stream,
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen index_mail_get_binary_stream,
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen sdbox_mail_get_special,
21aaa6affb9f134112b75b5db737309fc35ef1cfMartti Rannanjärvi index_mail_get_backend_mail,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_mail_update_flags,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_mail_update_keywords,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_mail_update_modseq,
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen index_mail_update_pvt_modseq,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen NULL,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_mail_expunge,
6564208826b0f46a00f010d1b5711d85944c3c88Timo Sirainen index_mail_set_cache_corrupted,
6de6ec228a41275ddda972d4a554699ea75cd06dTimo Sirainen index_mail_opened,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen};