dbox-mail.c revision 010affb9f4b9cca9b94e1d8d570cf179daff08d7
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (c) 2007-2010 Dovecot authors, see the included COPYING file */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen#include "lib.h"
47e0598840ecffa364ebed523e06939e22738f06Timo Sirainen#include "istream.h"
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen#include "str.h"
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen#include "index-storage.h"
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen#include "index-mail.h"
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen#include "dbox-attachment.h"
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen#include "dbox-storage.h"
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen#include "dbox-file.h"
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen#include "dbox-mail.h"
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen#include <stdlib.h>
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
1d738cce754bc64bbc66d3355ebdaf3f6eac55f1Timo Sirainenstruct mail *
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainendbox_mail_alloc(struct mailbox_transaction_context *t,
bdd7a96c363346f7c38f389791be1487ca08775bTimo Sirainen enum mail_fetch_field wanted_fields,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen struct mailbox_header_lookup_ctx *wanted_headers)
63e2edd14ae7b1dc4a08e2e659501dbf519462f9Timo Sirainen{
f9f30736bc6e4cf535085824e7e124506fe2dbbbTimo Sirainen struct dbox_mail *mail;
f9f30736bc6e4cf535085824e7e124506fe2dbbbTimo Sirainen pool_t pool;
63e2edd14ae7b1dc4a08e2e659501dbf519462f9Timo Sirainen
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen pool = pool_alloconly_create("mail", 2048);
029cfcdce65b284d5230adf1c920a5f526b03b5cTimo Sirainen mail = p_new(pool, struct dbox_mail, 1);
029cfcdce65b284d5230adf1c920a5f526b03b5cTimo Sirainen mail->imail.mail.pool = pool;
029cfcdce65b284d5230adf1c920a5f526b03b5cTimo Sirainen
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen index_mail_init(&mail->imail, t, wanted_fields, wanted_headers);
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen return &mail->imail.mail.mail;
029cfcdce65b284d5230adf1c920a5f526b03b5cTimo Sirainen}
029cfcdce65b284d5230adf1c920a5f526b03b5cTimo Sirainen
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainenvoid dbox_mail_close(struct mail *_mail)
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainen{
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainen struct dbox_mail *mail = (struct dbox_mail *)_mail;
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainen
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainen index_mail_close(_mail);
e925f007930955f10fa8728509a44f7a53d2b13eTimo Sirainen /* close the dbox file only after index is closed, since it may still
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainen try to read from it. */
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainen if (mail->open_file != NULL)
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainen dbox_file_unref(&mail->open_file);
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainen}
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainen
e925f007930955f10fa8728509a44f7a53d2b13eTimo Sirainenint dbox_mail_metadata_read(struct dbox_mail *mail, struct dbox_file **file_r)
e925f007930955f10fa8728509a44f7a53d2b13eTimo Sirainen{
e925f007930955f10fa8728509a44f7a53d2b13eTimo Sirainen struct dbox_storage *storage =
e925f007930955f10fa8728509a44f7a53d2b13eTimo Sirainen (struct dbox_storage *)mail->imail.mail.mail.box->storage;
e925f007930955f10fa8728509a44f7a53d2b13eTimo Sirainen uoff_t offset;
e925f007930955f10fa8728509a44f7a53d2b13eTimo Sirainen
e925f007930955f10fa8728509a44f7a53d2b13eTimo Sirainen if (storage->v.mail_open(mail, &offset, file_r) < 0)
e925f007930955f10fa8728509a44f7a53d2b13eTimo Sirainen return -1;
e925f007930955f10fa8728509a44f7a53d2b13eTimo Sirainen
e925f007930955f10fa8728509a44f7a53d2b13eTimo Sirainen if (dbox_file_seek(*file_r, offset) <= 0)
e925f007930955f10fa8728509a44f7a53d2b13eTimo Sirainen return -1;
e925f007930955f10fa8728509a44f7a53d2b13eTimo Sirainen if (dbox_file_metadata_read(*file_r) <= 0)
e925f007930955f10fa8728509a44f7a53d2b13eTimo Sirainen return -1;
e925f007930955f10fa8728509a44f7a53d2b13eTimo Sirainen
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainen if (mail->imail.data.stream != NULL) {
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainen /* we just messed up mail's input stream by reading metadata */
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainen i_stream_seek((*file_r)->input, offset);
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainen i_stream_sync(mail->imail.data.stream);
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainen }
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainen return 0;
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenstatic int
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainendbox_mail_metadata_get(struct dbox_mail *mail, enum dbox_metadata_key key,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen const char **value_r)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen struct dbox_file *file;
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (dbox_mail_metadata_read(mail, &file) < 0)
90c23747727c85f80e4e8eed7968f0edbeac7ac5Timo Sirainen return -1;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen *value_r = dbox_file_metadata_get(file, key);
19e8adccba16ff419f5675b1575358c2956dce83Timo Sirainen return 0;
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen}
b397665e90fa0fc7c6a9156fdd6cf28b571e8e39Timo Sirainen
b397665e90fa0fc7c6a9156fdd6cf28b571e8e39Timo Sirainenint dbox_mail_get_physical_size(struct mail *_mail, uoff_t *size_r)
b397665e90fa0fc7c6a9156fdd6cf28b571e8e39Timo Sirainen{
b397665e90fa0fc7c6a9156fdd6cf28b571e8e39Timo Sirainen struct dbox_mail *mail = (struct dbox_mail *)_mail;
19e8adccba16ff419f5675b1575358c2956dce83Timo Sirainen struct index_mail_data *data = &mail->imail.data;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen struct dbox_file *file;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen const char *value;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (index_mail_get_physical_size(_mail, size_r) == 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return 0;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* see if we have it in metadata */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (dbox_mail_metadata_read(mail, &file) < 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return -1;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen value = dbox_file_metadata_get(file, DBOX_METADATA_PHYSICAL_SIZE);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (value != NULL)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen data->physical_size = strtoul(value, NULL, 16);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen else {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* no. that means we can use the size in the header */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen data->physical_size = file->cur_physical_size;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen *size_r = data->physical_size;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return 0;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenint dbox_mail_get_virtual_size(struct mail *_mail, uoff_t *size_r)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen{
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen struct dbox_mail *mail = (struct dbox_mail *)_mail;
da4376093d4e1b26b14ea1e945689fb7056fe0a0Timo Sirainen struct index_mail_data *data = &mail->imail.data;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen const char *value;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (index_mail_get_cached_virtual_size(&mail->imail, size_r))
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return 0;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (dbox_mail_metadata_get(mail, DBOX_METADATA_VIRTUAL_SIZE,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen &value) < 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return -1;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (value == NULL)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return index_mail_get_virtual_size(_mail, size_r);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen data->virtual_size = strtoul(value, NULL, 16);
0f66f12eb4cdbf47670975044c88d8f388bf92dfTimo Sirainen *size_r = data->virtual_size;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return 0;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
029cfcdce65b284d5230adf1c920a5f526b03b5cTimo Sirainen
029cfcdce65b284d5230adf1c920a5f526b03b5cTimo Sirainenint dbox_mail_get_received_date(struct mail *_mail, time_t *date_r)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen struct dbox_mail *mail = (struct dbox_mail *)_mail;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen struct index_mail_data *data = &mail->imail.data;
029cfcdce65b284d5230adf1c920a5f526b03b5cTimo Sirainen const char *value;
029cfcdce65b284d5230adf1c920a5f526b03b5cTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (index_mail_get_received_date(_mail, date_r) == 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return 0;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (dbox_mail_metadata_get(mail, DBOX_METADATA_RECEIVED_TIME,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen &value) < 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return -1;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen data->received_date = value == NULL ? 0 : strtoul(value, NULL, 16);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen *date_r = data->received_date;
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen return 0;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenint dbox_mail_get_save_date(struct mail *_mail, time_t *date_r)
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen{
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen struct dbox_storage *storage =
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen (struct dbox_storage *)_mail->box->storage;
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen struct dbox_mail *mail = (struct dbox_mail *)_mail;
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen struct index_mail_data *data = &mail->imail.data;
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen struct dbox_file *file;
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen struct stat st;
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen uoff_t offset;
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen if (index_mail_get_save_date(_mail, date_r) == 0)
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen return 0;
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen if (storage->v.mail_open(mail, &offset, &file) < 0)
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen return -1;
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen mail->imail.mail.stats_fstat_lookup_count++;
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen if (dbox_file_stat(file, &st) < 0) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (errno == ENOENT)
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen mail_set_expunged(_mail);
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen return -1;
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen }
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen *date_r = data->save_date = st.st_ctime;
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen return 0;
0bf3eac1110a902e7ec7e695c64e8e46c114e623Timo Sirainen}
0bf3eac1110a902e7ec7e695c64e8e46c114e623Timo Sirainen
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainenstatic int
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainendbox_get_cached_metadata(struct dbox_mail *mail, enum dbox_metadata_key key,
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen enum index_cache_field cache_field,
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen const char **value_r)
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen{
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen struct index_mail *imail = &mail->imail;
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen struct index_mailbox_context *ibox =
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen INDEX_STORAGE_CONTEXT(imail->mail.mail.box);
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen const char *value;
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen string_t *str;
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen str = str_new(imail->data_pool, 64);
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen if (mail_cache_lookup_field(imail->trans->cache_view, str,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen imail->mail.mail.seq,
f153a2cec0319f549388d28f8cfd4d50229d1132Timo Sirainen ibox->cache_fields[cache_field].idx) > 0) {
f153a2cec0319f549388d28f8cfd4d50229d1132Timo Sirainen *value_r = str_c(str);
f153a2cec0319f549388d28f8cfd4d50229d1132Timo Sirainen return 0;
f153a2cec0319f549388d28f8cfd4d50229d1132Timo Sirainen }
f153a2cec0319f549388d28f8cfd4d50229d1132Timo Sirainen
dffa503fd4ce31334346e539496084c80a2d8d37Timo Sirainen if (dbox_mail_metadata_get(mail, key, &value) < 0)
dffa503fd4ce31334346e539496084c80a2d8d37Timo Sirainen return -1;
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen if (value == NULL)
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen value = "";
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen index_mail_cache_add_idx(imail, ibox->cache_fields[cache_field].idx,
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen value, strlen(value)+1);
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen
f9f30736bc6e4cf535085824e7e124506fe2dbbbTimo Sirainen /* don't return pointer to dbox metadata directly, since it may
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen change unexpectedly */
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen str_truncate(str, 0);
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen str_append(str, value);
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen *value_r = str_c(str);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return 0;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenint dbox_mail_get_special(struct mail *_mail, enum mail_fetch_field field,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen const char **value_r)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen struct dbox_mail *mail = (struct dbox_mail *)_mail;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* keep the UIDL in cache file, otherwise POP3 would open all
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen mail files and read the metadata. same for GUIDs if they're
63e2edd14ae7b1dc4a08e2e659501dbf519462f9Timo Sirainen used. */
63e2edd14ae7b1dc4a08e2e659501dbf519462f9Timo Sirainen switch (field) {
63e2edd14ae7b1dc4a08e2e659501dbf519462f9Timo Sirainen case MAIL_FETCH_UIDL_BACKEND:
63e2edd14ae7b1dc4a08e2e659501dbf519462f9Timo Sirainen return dbox_get_cached_metadata(mail, DBOX_METADATA_POP3_UIDL,
f9f30736bc6e4cf535085824e7e124506fe2dbbbTimo Sirainen MAIL_CACHE_POP3_UIDL, value_r);
63e2edd14ae7b1dc4a08e2e659501dbf519462f9Timo Sirainen case MAIL_FETCH_GUID:
63e2edd14ae7b1dc4a08e2e659501dbf519462f9Timo Sirainen return dbox_get_cached_metadata(mail, DBOX_METADATA_GUID,
63e2edd14ae7b1dc4a08e2e659501dbf519462f9Timo Sirainen MAIL_CACHE_GUID, value_r);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen default:
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen break;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return index_mail_get_special(_mail, field, value_r);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
b5b3b4c9159f506cdfdce7399faaeeffdf73faf7Timo Sirainenstatic int
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenget_mail_stream(struct dbox_mail *mail, uoff_t offset,
57dd2621d4230bc2e06c69a4b9f8cf8f0ff2bc93Timo Sirainen struct istream **stream_r)
57dd2621d4230bc2e06c69a4b9f8cf8f0ff2bc93Timo Sirainen{
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch struct mail_private *pmail = &mail->imail.mail;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen struct dbox_file *file = mail->open_file;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen int ret;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if ((ret = dbox_file_seek(file, offset)) <= 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return ret;
40ad2c4902e9d83557f2e8a4bff3d98fea2c8aa1Timo Sirainen
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen *stream_r = i_stream_create_limit(file->input, file->cur_physical_size);
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen if (pmail->v.istream_opened != NULL) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (pmail->v.istream_opened(&pmail->mail, stream_r) < 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return -1;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen if (file->storage->attachment_dir == NULL)
14c474d9f4591c397ed0b5206af6537c7b52c924Timo Sirainen return 1;
14c474d9f4591c397ed0b5206af6537c7b52c924Timo Sirainen else
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen return dbox_attachment_file_get_stream(file, stream_r);
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen}
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainenint dbox_mail_get_stream(struct mail *_mail, struct message_size *hdr_size,
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen struct message_size *body_size,
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen struct istream **stream_r)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
8d131435ba4648c8821160ec38d508c97177c715Timo Sirainen struct dbox_storage *storage =
8d131435ba4648c8821160ec38d508c97177c715Timo Sirainen (struct dbox_storage *)_mail->box->storage;
8d131435ba4648c8821160ec38d508c97177c715Timo Sirainen struct dbox_mail *mail = (struct dbox_mail *)_mail;
8d131435ba4648c8821160ec38d508c97177c715Timo Sirainen struct index_mail_data *data = &mail->imail.data;
b6612c334604eeb27e1ca2bd804ac66dcbc2eaadTimo Sirainen struct istream *input;
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen uoff_t offset;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen int ret;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (data->stream == NULL) {
1ff03d2244dd08effadfecec365bec28793a1aa0Timo Sirainen if (storage->v.mail_open(mail, &offset, &mail->open_file) < 0)
1ff03d2244dd08effadfecec365bec28793a1aa0Timo Sirainen return -1;
1ff03d2244dd08effadfecec365bec28793a1aa0Timo Sirainen
1ff03d2244dd08effadfecec365bec28793a1aa0Timo Sirainen ret = get_mail_stream(mail, offset, &input);
1ff03d2244dd08effadfecec365bec28793a1aa0Timo Sirainen if (ret <= 0) {
1ff03d2244dd08effadfecec365bec28793a1aa0Timo Sirainen if (ret < 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return -1;
e64d7b6f388fecd0c83a4f2acb54e30d5ac98c6cTimo Sirainen dbox_file_set_corrupted(mail->open_file,
b5b3b4c9159f506cdfdce7399faaeeffdf73faf7Timo Sirainen "uid=%u points to broken data at offset="
b5b3b4c9159f506cdfdce7399faaeeffdf73faf7Timo Sirainen "%"PRIuUOFF_T, _mail->uid, offset);
b5b3b4c9159f506cdfdce7399faaeeffdf73faf7Timo Sirainen return -1;
b5b3b4c9159f506cdfdce7399faaeeffdf73faf7Timo Sirainen }
b5b3b4c9159f506cdfdce7399faaeeffdf73faf7Timo Sirainen data->stream = input;
b5b3b4c9159f506cdfdce7399faaeeffdf73faf7Timo Sirainen index_mail_set_read_buffer_size(_mail, input);
b5b3b4c9159f506cdfdce7399faaeeffdf73faf7Timo Sirainen }
b5b3b4c9159f506cdfdce7399faaeeffdf73faf7Timo Sirainen
e64d7b6f388fecd0c83a4f2acb54e30d5ac98c6cTimo Sirainen return index_mail_init_stream(&mail->imail, hdr_size, body_size,
e64d7b6f388fecd0c83a4f2acb54e30d5ac98c6cTimo Sirainen stream_r);
e64d7b6f388fecd0c83a4f2acb54e30d5ac98c6cTimo Sirainen}
e64d7b6f388fecd0c83a4f2acb54e30d5ac98c6cTimo Sirainen