dbox-mail.c revision b8d314c6355009ad0b9e332b6acecdfac5cc8891
5a580c3a38ced62d4bcc95b8ac7c4f2935b5d294Timo Sirainen/* Copyright (c) 2007-2010 Dovecot authors, see the included COPYING file */
08b30498acefc69e223baf7eda6429be98cc3a10Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "lib.h"
16f816d3f3c32ae3351834253f52ddd0212bcbf3Timo Sirainen#include "istream.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "str.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "index-storage.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "index-mail.h"
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen#include "dbox-storage.h"
022412398e56a8f31ef111cfd7271498d64af9a9Timo Sirainen#include "dbox-file.h"
08b30498acefc69e223baf7eda6429be98cc3a10Timo Sirainen#include "dbox-mail.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include <stdlib.h>
5363a534097c170ef9cccbdde5ca802f581f5eb7Timo Sirainen
5363a534097c170ef9cccbdde5ca802f581f5eb7Timo Sirainenstruct mail *
5363a534097c170ef9cccbdde5ca802f581f5eb7Timo Sirainendbox_mail_alloc(struct mailbox_transaction_context *t,
5363a534097c170ef9cccbdde5ca802f581f5eb7Timo Sirainen enum mail_fetch_field wanted_fields,
5363a534097c170ef9cccbdde5ca802f581f5eb7Timo Sirainen struct mailbox_header_lookup_ctx *wanted_headers)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen struct dbox_mail *mail;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen pool_t pool;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen pool = pool_alloconly_create("mail", 2048);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail = p_new(pool, struct dbox_mail, 1);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen mail->imail.mail.pool = pool;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen index_mail_init(&mail->imail, t, wanted_fields, wanted_headers);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return &mail->imail.mail.mail;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen}
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainenvoid dbox_mail_close(struct mail *_mail)
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen{
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen struct dbox_mail *mail = (struct dbox_mail *)_mail;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen if (mail->open_file != NULL)
2d3aac5be07b96f72cf0551fac35ac74a4f07770Timo Sirainen dbox_file_unref(&mail->open_file);
2d3aac5be07b96f72cf0551fac35ac74a4f07770Timo Sirainen index_mail_close(_mail);
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen}
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainenint dbox_mail_metadata_read(struct dbox_mail *mail, struct dbox_file **file_r)
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen{
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen struct dbox_storage *storage =
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen (struct dbox_storage *)mail->imail.mail.mail.box->storage;
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen uoff_t offset;
a205d315b0978985ba77d871f44e4a98273612e6Timo Sirainen
a205d315b0978985ba77d871f44e4a98273612e6Timo Sirainen if (storage->v.mail_open(mail, &offset, file_r) < 0)
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen return -1;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen if (dbox_file_get_mail_stream(*file_r, offset, NULL) <= 0)
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen return -1;
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen if (dbox_file_metadata_read(*file_r) <= 0)
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen return -1;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen
12d34ab79772e0748a1daef30fa749dfe3036608Timo Sirainen if (mail->imail.data.stream != NULL) {
a6a2b38d806f3ab3198160e39240a8200775e525Timo Sirainen /* we just messed up mail's input stream by reading metadata */
a6a2b38d806f3ab3198160e39240a8200775e525Timo Sirainen i_stream_seek((*file_r)->input, offset);
a6a2b38d806f3ab3198160e39240a8200775e525Timo Sirainen i_stream_sync(mail->imail.data.stream);
fb2e0bbb7737f3223b16aa41e4b40fb0cd5f288fTimo Sirainen }
12d34ab79772e0748a1daef30fa749dfe3036608Timo Sirainen return 0;
12d34ab79772e0748a1daef30fa749dfe3036608Timo Sirainen}
12d34ab79772e0748a1daef30fa749dfe3036608Timo Sirainen
12d34ab79772e0748a1daef30fa749dfe3036608Timo Sirainenstatic int
12d34ab79772e0748a1daef30fa749dfe3036608Timo Sirainendbox_mail_metadata_get(struct dbox_mail *mail, enum dbox_metadata_key key,
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen const char **value_r)
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen{
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen struct dbox_file *file;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen if (dbox_mail_metadata_read(mail, &file) < 0)
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen return -1;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen *value_r = dbox_file_metadata_get(file, key);
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen return 0;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen}
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainenint dbox_mail_get_physical_size(struct mail *_mail, uoff_t *size_r)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen{
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen struct dbox_mail *mail = (struct dbox_mail *)_mail;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen struct index_mail_data *data = &mail->imail.data;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen struct dbox_file *file;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen const char *value;
821984ecb6c90696f35c32a8dc4c8a60f9e98f99Timo Sirainen
821984ecb6c90696f35c32a8dc4c8a60f9e98f99Timo Sirainen if (index_mail_get_physical_size(_mail, size_r) == 0)
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen return 0;
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen /* see if we have it in metadata */
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen if (dbox_mail_metadata_read(mail, &file) < 0)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen return -1;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen value = dbox_file_metadata_get(file, DBOX_METADATA_PHYSICAL_SIZE);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen if (value != NULL)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen data->physical_size = strtoul(value, NULL, 16);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen else {
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen /* no. that means we can use the size in the header */
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen data->physical_size = file->cur_physical_size;
e5759add4dc24b96606dccc4a989838e260f2a12Timo Sirainen }
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen *size_r = data->physical_size;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen return 0;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen}
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
4efba37e4f27b93832f6147c3a353d6d22c855c7Timo Sirainenint dbox_mail_get_virtual_size(struct mail *_mail, uoff_t *size_r)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen{
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen struct dbox_mail *mail = (struct dbox_mail *)_mail;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen struct index_mail_data *data = &mail->imail.data;
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen const char *value;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen if (index_mail_get_cached_virtual_size(&mail->imail, size_r))
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen return 0;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen if (dbox_mail_metadata_get(mail, DBOX_METADATA_VIRTUAL_SIZE,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen &value) < 0)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen return -1;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen if (value == NULL)
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen return index_mail_get_virtual_size(_mail, size_r);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen data->virtual_size = strtoul(value, NULL, 16);
8bb360f9e5de1c25e4f875205bb06e8bf15dae14Timo Sirainen *size_r = data->virtual_size;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen return 0;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen}
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
821984ecb6c90696f35c32a8dc4c8a60f9e98f99Timo Sirainenint dbox_mail_get_received_date(struct mail *_mail, time_t *date_r)
821984ecb6c90696f35c32a8dc4c8a60f9e98f99Timo Sirainen{
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen struct dbox_mail *mail = (struct dbox_mail *)_mail;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen struct index_mail_data *data = &mail->imail.data;
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen const char *value;
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen if (index_mail_get_received_date(_mail, date_r) == 0)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen return 0;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen
d22301419109ed4a38351715e6760011421dadecTimo Sirainen if (dbox_mail_metadata_get(mail, DBOX_METADATA_RECEIVED_TIME,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen &value) < 0)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen return -1;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen data->received_date = value == NULL ? 0 : strtoul(value, NULL, 16);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen *date_r = data->received_date;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen return 0;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen}
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainenint dbox_mail_get_save_date(struct mail *_mail, time_t *date_r)
197ad81605dc0f6d2ebc9ad99994db5ca6d76699Timo Sirainen{
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen struct dbox_mail *mail = (struct dbox_mail *)_mail;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen struct index_mail_data *data = &mail->imail.data;
5363a534097c170ef9cccbdde5ca802f581f5eb7Timo Sirainen struct dbox_file *file;
5363a534097c170ef9cccbdde5ca802f581f5eb7Timo Sirainen struct stat st;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen if (index_mail_get_save_date(_mail, date_r) == 0)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen return 0;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen mail->imail.mail.stats_fstat_lookup_count++;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen if (dbox_file_stat(file, &st) < 0) {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen if (errno == ENOENT)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen mail_set_expunged(_mail);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen return -1;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen }
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen *date_r = data->save_date = st.st_ctime;
2054222e84cb972842cc4de88e16516bef41b542Timo Sirainen return 0;
2054222e84cb972842cc4de88e16516bef41b542Timo Sirainen}
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
d22301419109ed4a38351715e6760011421dadecTimo Sirainenstatic int
d22301419109ed4a38351715e6760011421dadecTimo Sirainendbox_get_cached_metadata(struct dbox_mail *mail, enum dbox_metadata_key key,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen enum index_cache_field cache_field,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen const char **value_r)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen{
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen struct index_mail *imail = &mail->imail;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen struct index_mailbox_context *ibox =
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen INDEX_STORAGE_CONTEXT(imail->mail.mail.box);
2054222e84cb972842cc4de88e16516bef41b542Timo Sirainen const char *value;
2054222e84cb972842cc4de88e16516bef41b542Timo Sirainen string_t *str;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen str = str_new(imail->data_pool, 64);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen if (mail_cache_lookup_field(imail->trans->cache_view, str,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen imail->mail.mail.seq,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen ibox->cache_fields[cache_field].idx) > 0) {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen *value_r = str_c(str);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen return 0;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen }
d22301419109ed4a38351715e6760011421dadecTimo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen if (dbox_mail_metadata_get(mail, key, &value) < 0)
5363a534097c170ef9cccbdde5ca802f581f5eb7Timo Sirainen return -1;
5363a534097c170ef9cccbdde5ca802f581f5eb7Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen if (value == NULL)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen value = "";
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen index_mail_cache_add_idx(imail, ibox->cache_fields[cache_field].idx,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen value, strlen(value)+1);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen *value_r = value;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen return 0;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen}
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainenint dbox_mail_get_special(struct mail *_mail, enum mail_fetch_field field,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char **value_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
8bb360f9e5de1c25e4f875205bb06e8bf15dae14Timo Sirainen struct dbox_mail *mail = (struct dbox_mail *)_mail;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen /* keep the UIDL in cache file, otherwise POP3 would open all
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen mail files and read the metadata. same for GUIDs if they're
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen used. */
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen switch (field) {
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen case MAIL_FETCH_UIDL_BACKEND:
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen return dbox_get_cached_metadata(mail, DBOX_METADATA_POP3_UIDL,
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen MAIL_CACHE_POP3_UIDL, value_r);
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen case MAIL_FETCH_GUID:
33ae95df45c9b5ec51332a6b39eb5322038686b9Timo Sirainen return dbox_get_cached_metadata(mail, DBOX_METADATA_GUID,
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen MAIL_CACHE_GUID, value_r);
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen default:
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen break;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
2054222e84cb972842cc4de88e16516bef41b542Timo Sirainen
2054222e84cb972842cc4de88e16516bef41b542Timo Sirainen return index_mail_get_special(_mail, field, value_r);
2054222e84cb972842cc4de88e16516bef41b542Timo Sirainen}
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainenint dbox_mail_get_stream(struct mail *_mail, struct message_size *hdr_size,
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen struct message_size *body_size,
bf301a34ffbfd049be583094019b2644884b6d0bTimo Sirainen struct istream **stream_r)
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen{
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen struct dbox_storage *storage =
58eb2cb24dbeadd94500670acad7ceb1c8b0d9b4Timo Sirainen (struct dbox_storage *)_mail->box->storage;
bf301a34ffbfd049be583094019b2644884b6d0bTimo Sirainen struct dbox_mail *mail = (struct dbox_mail *)_mail;
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen struct index_mail_data *data = &mail->imail.data;
2054222e84cb972842cc4de88e16516bef41b542Timo Sirainen struct istream *input;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uoff_t offset;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
1e76a5b92f9d82d557f81f080f3dfad1c9d8f200Timo Sirainen if (data->stream == NULL) {
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen if (storage->v.mail_open(mail, &offset, &mail->open_file) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret = dbox_file_get_mail_stream(mail->open_file, offset,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen &input);
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen if (ret <= 0) {
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen if (ret < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen dbox_file_set_corrupted(mail->open_file,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "uid=%u points to broken data at offset="
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen "%"PRIuUOFF_T, _mail->uid, offset);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen data->stream = input;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen return index_mail_init_stream(&mail->imail, hdr_size, body_size,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen stream_r);
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen