dbox-mail.c revision baa93d5ed7c015309dc51aa238f8d0c79561121f
b9f30617c2c96d54acbc4f85ed17b939c4f28916Timo Sirainen/* Copyright (c) 2007-2016 Dovecot authors, see the included COPYING file */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "lib.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "istream.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "str.h"
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include "index-storage.h"
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen#include "index-mail.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "dbox-attachment.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "dbox-storage.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "dbox-file.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "dbox-mail.h"
7744586e3e0fd60158abfbb03a233d3bd8d6c48bTimo Sirainen
7744586e3e0fd60158abfbb03a233d3bd8d6c48bTimo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenstruct mail *
d477acb83e14a776ece4ca94dcd1869e75d0c6eeTimo Sirainendbox_mail_alloc(struct mailbox_transaction_context *t,
d477acb83e14a776ece4ca94dcd1869e75d0c6eeTimo Sirainen enum mail_fetch_field wanted_fields,
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen struct mailbox_header_lookup_ctx *wanted_headers)
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen{
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen struct dbox_mail *mail;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen pool_t pool;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen pool = pool_alloconly_create("mail", 2048);
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen mail = p_new(pool, struct dbox_mail, 1);
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen mail->imail.mail.pool = pool;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen index_mail_init(&mail->imail, t, wanted_fields, wanted_headers);
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen return &mail->imail.mail.mail;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen}
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainenvoid dbox_mail_close(struct mail *_mail)
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen{
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen struct dbox_mail *mail = (struct dbox_mail *)_mail;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen index_mail_close(_mail);
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen /* close the dbox file only after index is closed, since it may still
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen try to read from it. */
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen if (mail->open_file != NULL)
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen dbox_file_unref(&mail->open_file);
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen}
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainenint dbox_mail_metadata_read(struct dbox_mail *mail, struct dbox_file **file_r)
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen{
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen struct dbox_storage *storage =
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen (struct dbox_storage *)mail->imail.mail.mail.box->storage;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen uoff_t offset;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen if (storage->v.mail_open(mail, &offset, file_r) < 0)
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen return -1;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen if (dbox_file_seek(*file_r, offset) <= 0)
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen return -1;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen if (dbox_file_metadata_read(*file_r) <= 0)
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen return -1;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen if (mail->imail.data.stream != NULL) {
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen /* we just messed up mail's input stream by reading metadata */
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen i_stream_seek((*file_r)->input, offset);
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen i_stream_sync(mail->imail.data.stream);
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen }
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen return 0;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen}
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainenstatic int
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainendbox_mail_metadata_get(struct dbox_mail *mail, enum dbox_metadata_key key,
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen const char **value_r)
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen{
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen struct dbox_file *file;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen if (dbox_mail_metadata_read(mail, &file) < 0)
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen return -1;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen *value_r = dbox_file_metadata_get(file, key);
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen return 0;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen}
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainenint dbox_mail_get_physical_size(struct mail *_mail, uoff_t *size_r)
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen{
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen struct dbox_mail *mail = (struct dbox_mail *)_mail;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen struct index_mail_data *data = &mail->imail.data;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen struct dbox_file *file;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen if (index_mail_get_physical_size(_mail, size_r) == 0)
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen return 0;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen if (dbox_mail_metadata_read(mail, &file) < 0)
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen return -1;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen data->physical_size = dbox_file_get_plaintext_size(file);
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen *size_r = data->physical_size;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen return 0;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen}
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainenint dbox_mail_get_virtual_size(struct mail *_mail, uoff_t *size_r)
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen{
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen struct dbox_mail *mail = (struct dbox_mail *)_mail;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen struct index_mail_data *data = &mail->imail.data;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen const char *value;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen uintmax_t size;
7744586e3e0fd60158abfbb03a233d3bd8d6c48bTimo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (index_mail_get_cached_virtual_size(&mail->imail, size_r))
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return 0;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (dbox_mail_metadata_get(mail, DBOX_METADATA_VIRTUAL_SIZE,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen &value) < 0)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return -1;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (value == NULL)
7744586e3e0fd60158abfbb03a233d3bd8d6c48bTimo Sirainen return index_mail_get_virtual_size(_mail, size_r);
1cfdcb36985904eff281fc6d7ea2d13b3c375980Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (str_to_uintmax_hex(value, &size) < 0 || size > (uoff_t)-1)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return -1;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen data->virtual_size = (uoff_t)size;
383d0e8c24451468d6bea17e4b55d74de744abe6Timo Sirainen *size_r = data->virtual_size;
383d0e8c24451468d6bea17e4b55d74de744abe6Timo Sirainen return 0;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen}
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
383d0e8c24451468d6bea17e4b55d74de744abe6Timo Sirainenint dbox_mail_get_received_date(struct mail *_mail, time_t *date_r)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen{
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen struct dbox_mail *mail = (struct dbox_mail *)_mail;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen struct index_mail_data *data = &mail->imail.data;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen const char *value;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen uintmax_t time;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
7744586e3e0fd60158abfbb03a233d3bd8d6c48bTimo Sirainen if (index_mail_get_received_date(_mail, date_r) == 0)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return 0;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (dbox_mail_metadata_get(mail, DBOX_METADATA_RECEIVED_TIME,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen &value) < 0)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return -1;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
7744586e3e0fd60158abfbb03a233d3bd8d6c48bTimo Sirainen time = 0;
1cfdcb36985904eff281fc6d7ea2d13b3c375980Timo Sirainen if (value != NULL && str_to_uintmax_hex(value, &time) < 0)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return -1;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen data->received_date = (time_t)time;
383d0e8c24451468d6bea17e4b55d74de744abe6Timo Sirainen *date_r = data->received_date;
383d0e8c24451468d6bea17e4b55d74de744abe6Timo Sirainen return 0;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen}
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
383d0e8c24451468d6bea17e4b55d74de744abe6Timo Sirainenint dbox_mail_get_save_date(struct mail *_mail, time_t *date_r)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen{
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen struct dbox_storage *storage =
57d2429fae575e96ca276355af675deb66b76d00Timo Sirainen (struct dbox_storage *)_mail->box->storage;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen struct dbox_mail *mail = (struct dbox_mail *)_mail;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen struct index_mail_data *data = &mail->imail.data;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen struct dbox_file *file;
57d2429fae575e96ca276355af675deb66b76d00Timo Sirainen struct stat st;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen uoff_t offset;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (index_mail_get_save_date(_mail, date_r) == 0)
7744586e3e0fd60158abfbb03a233d3bd8d6c48bTimo Sirainen return 0;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (storage->v.mail_open(mail, &offset, &file) < 0)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return -1;
61618d4c58080570f689614fec204ae14e90cef2Timo Sirainen
50e20db49f29917fe9adcf1b56b11badf28bd0e4Timo Sirainen _mail->transaction->stats.fstat_lookup_count++;
50e20db49f29917fe9adcf1b56b11badf28bd0e4Timo Sirainen if (dbox_file_stat(file, &st) < 0) {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (errno == ENOENT)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen mail_set_expunged(_mail);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return -1;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen *date_r = data->save_date = st.st_ctime;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return 0;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen}
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
50e20db49f29917fe9adcf1b56b11badf28bd0e4Timo Sirainenstatic int
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainendbox_get_cached_metadata(struct dbox_mail *mail, enum dbox_metadata_key key,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen enum index_cache_field cache_field,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen const char **value_r)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen{
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen struct index_mail *imail = &mail->imail;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen struct index_mailbox_context *ibox =
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen INDEX_STORAGE_CONTEXT(imail->mail.mail.box);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen const char *value;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen string_t *str;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen uint32_t order;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen str = str_new(imail->mail.data_pool, 64);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (mail_cache_lookup_field(imail->mail.mail.transaction->cache_view,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen str, imail->mail.mail.seq,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen ibox->cache_fields[cache_field].idx) > 0) {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (cache_field == MAIL_CACHE_POP3_ORDER) {
7744586e3e0fd60158abfbb03a233d3bd8d6c48bTimo Sirainen i_assert(str_len(str) == sizeof(order));
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen memcpy(&order, str_data(str), sizeof(order));
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen str_truncate(str, 0);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (order != 0)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen str_printfa(str, "%u", order);
50e20db49f29917fe9adcf1b56b11badf28bd0e4Timo Sirainen else {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen /* order=0 means it doesn't exist. we don't
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen want to return "0" though, because then the
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen mails get ordered to beginning, while
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen nonexistent are supposed to be ordered at
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen the end. */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen *value_r = str_c(str);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return 0;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (dbox_mail_metadata_get(mail, key, &value) < 0)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return -1;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (value == NULL)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen value = "";
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (cache_field != MAIL_CACHE_POP3_ORDER) {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen index_mail_cache_add_idx(imail, ibox->cache_fields[cache_field].idx,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen value, strlen(value)+1);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen } else {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (str_to_uint(value, &order) < 0)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen order = 0;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen index_mail_cache_add_idx(imail, ibox->cache_fields[cache_field].idx,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen &order, sizeof(order));
7744586e3e0fd60158abfbb03a233d3bd8d6c48bTimo Sirainen }
1cfdcb36985904eff281fc6d7ea2d13b3c375980Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen /* don't return pointer to dbox metadata directly, since it may
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen change unexpectedly */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen str_truncate(str, 0);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen str_append(str, value);
2024157e8de36edd31f5fd72f5ea7364a0955fa7Timo Sirainen *value_r = str_c(str);
383d0e8c24451468d6bea17e4b55d74de744abe6Timo Sirainen return 0;
383d0e8c24451468d6bea17e4b55d74de744abe6Timo Sirainen}
383d0e8c24451468d6bea17e4b55d74de744abe6Timo Sirainen
383d0e8c24451468d6bea17e4b55d74de744abe6Timo Sirainenint dbox_mail_get_special(struct mail *_mail, enum mail_fetch_field field,
2024157e8de36edd31f5fd72f5ea7364a0955fa7Timo Sirainen const char **value_r)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen{
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen struct dbox_mail *mail = (struct dbox_mail *)_mail;
d477acb83e14a776ece4ca94dcd1869e75d0c6eeTimo Sirainen
9575316ab47b32f14c5f8527bbb9673b2827dee0Timo Sirainen /* keep the UIDL in cache file, otherwise POP3 would open all
2024157e8de36edd31f5fd72f5ea7364a0955fa7Timo Sirainen mail files and read the metadata. same for GUIDs if they're
d477acb83e14a776ece4ca94dcd1869e75d0c6eeTimo Sirainen used. */
d477acb83e14a776ece4ca94dcd1869e75d0c6eeTimo Sirainen switch (field) {
d477acb83e14a776ece4ca94dcd1869e75d0c6eeTimo Sirainen case MAIL_FETCH_UIDL_BACKEND:
15f526e5ac611b4532568d131fcd0abf664abe41Timo Sirainen return dbox_get_cached_metadata(mail, DBOX_METADATA_POP3_UIDL,
15f526e5ac611b4532568d131fcd0abf664abe41Timo Sirainen MAIL_CACHE_POP3_UIDL, value_r);
15f526e5ac611b4532568d131fcd0abf664abe41Timo Sirainen case MAIL_FETCH_POP3_ORDER:
15f526e5ac611b4532568d131fcd0abf664abe41Timo Sirainen return dbox_get_cached_metadata(mail, DBOX_METADATA_POP3_ORDER,
d477acb83e14a776ece4ca94dcd1869e75d0c6eeTimo Sirainen MAIL_CACHE_POP3_ORDER, value_r);
d477acb83e14a776ece4ca94dcd1869e75d0c6eeTimo Sirainen case MAIL_FETCH_GUID:
d477acb83e14a776ece4ca94dcd1869e75d0c6eeTimo Sirainen return dbox_get_cached_metadata(mail, DBOX_METADATA_GUID,
d477acb83e14a776ece4ca94dcd1869e75d0c6eeTimo Sirainen MAIL_CACHE_GUID, value_r);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen default:
2024157e8de36edd31f5fd72f5ea7364a0955fa7Timo Sirainen break;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
2024157e8de36edd31f5fd72f5ea7364a0955fa7Timo Sirainen return index_mail_get_special(_mail, field, value_r);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainenstatic int
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenget_mail_stream(struct dbox_mail *mail, uoff_t offset,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen struct istream **stream_r)
44aac2d461b4cb8e05e8c07f2f209372997a8719Timo Sirainen{
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen struct mail_private *pmail = &mail->imail.mail;
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen struct dbox_file *file = mail->open_file;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen int ret;
2024157e8de36edd31f5fd72f5ea7364a0955fa7Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if ((ret = dbox_file_seek(file, offset)) <= 0) {
*stream_r = NULL;
return ret;
}
*stream_r = i_stream_create_limit(file->input, file->cur_physical_size);
if (pmail->v.istream_opened != NULL) {
if (pmail->v.istream_opened(&pmail->mail, stream_r) < 0)
return -1;
}
if (file->storage->attachment_dir == NULL)
return 1;
else
return dbox_attachment_file_get_stream(file, stream_r);
}
int dbox_mail_get_stream(struct mail *_mail, bool get_body ATTR_UNUSED,
struct message_size *hdr_size,
struct message_size *body_size,
struct istream **stream_r)
{
struct dbox_storage *storage =
(struct dbox_storage *)_mail->box->storage;
struct dbox_mail *mail = (struct dbox_mail *)_mail;
struct index_mail_data *data = &mail->imail.data;
struct istream *input;
uoff_t offset;
int ret;
if (data->stream == NULL) {
if (storage->v.mail_open(mail, &offset, &mail->open_file) < 0)
return -1;
ret = get_mail_stream(mail, offset, &input);
if (ret <= 0) {
if (ret < 0)
return -1;
dbox_file_set_corrupted(mail->open_file,
"uid=%u points to broken data at offset="
"%"PRIuUOFF_T, _mail->uid, offset);
if (input != NULL)
i_stream_unref(&input);
return -1;
}
data->stream = input;
index_mail_set_read_buffer_size(_mail, input);
}
return index_mail_init_stream(&mail->imail, hdr_size, body_size,
stream_r);
}