index-mail.c revision 61e27995aadbc2f97927d3635f98d1d4ac4751e0
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina/* Copyright (c) 2002-2010 Dovecot authors, see the included COPYING file */
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina#include "lib.h"
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina#include "array.h"
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina#include "buffer.h"
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina#include "ioloop.h"
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina#include "istream.h"
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina#include "str.h"
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina#include "message-date.h"
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina#include "message-part-serialize.h"
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina#include "message-parser.h"
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina#include "imap-bodystructure.h"
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina#include "imap-envelope.h"
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina#include "mail-cache.h"
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina#include "mail-index-modseq.h"
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina#include "index-storage.h"
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina#include "istream-mail-stats.h"
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina#include "index-mail.h"
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březinastruct mail_cache_field global_cache_fields[MAIL_INDEX_CACHE_FIELD_COUNT] = {
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina { "flags", 0, MAIL_CACHE_FIELD_BITMASK, sizeof(uint32_t), 0 },
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina { "date.sent", 0, MAIL_CACHE_FIELD_FIXED_SIZE,
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina sizeof(struct mail_sent_date), 0 },
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina { "date.received", 0, MAIL_CACHE_FIELD_FIXED_SIZE,
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina sizeof(uint32_t), 0 },
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina { "date.save", 0, MAIL_CACHE_FIELD_FIXED_SIZE,
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina sizeof(uint32_t), 0 },
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose { "size.virtual", 0, MAIL_CACHE_FIELD_FIXED_SIZE,
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina sizeof(uoff_t), 0 },
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina { "size.physical", 0, MAIL_CACHE_FIELD_FIXED_SIZE,
4169fb26ea2ff93c19ecdad6e09382732ea5deebPavel Březina sizeof(uoff_t), 0 },
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina { "imap.body", 0, MAIL_CACHE_FIELD_STRING, 0, 0 },
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina { "imap.bodystructure", 0, MAIL_CACHE_FIELD_STRING, 0, 0 },
d3c82d0170d6d7407549afdadd08aa7e11aeb9a2Pavel Březina { "imap.envelope", 0, MAIL_CACHE_FIELD_STRING, 0, 0 },
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina { "pop3.uidl", 0, MAIL_CACHE_FIELD_STRING, 0, 0 },
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina { "guid", 0, MAIL_CACHE_FIELD_STRING, 0, 0 },
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina { "mime.parts", 0, MAIL_CACHE_FIELD_VARIABLE_SIZE, 0, 0 }
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina};
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozekstatic int index_mail_parse_body(struct index_mail *mail,
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek enum index_cache_field field);
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozekint index_mail_cache_lookup_field(struct index_mail *mail, buffer_t *buf,
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek unsigned int field_idx)
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek{
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek int ret;
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek ret = mail_cache_lookup_field(mail->trans->cache_view, buf,
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek mail->data.seq, field_idx);
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina if (ret > 0)
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina mail->mail.stats_cache_hit_count++;
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek return ret;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina}
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březinastatic struct message_part *get_unserialized_parts(struct index_mail *mail)
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek{
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina unsigned int field_idx =
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina mail->ibox->cache_fields[MAIL_CACHE_MESSAGE_PARTS].idx;
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek struct message_part *parts;
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek buffer_t *part_buf;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina const char *error;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina int ret;
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina part_buf = buffer_create_dynamic(pool_datastack_create(), 128);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina ret = index_mail_cache_lookup_field(mail, part_buf, field_idx);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if (ret <= 0)
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina return NULL;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina parts = message_part_deserialize(mail->data_pool, part_buf->data,
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina part_buf->used, &error);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if (parts == NULL) {
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail_cache_set_corrupted(mail->mail.mail.box->cache,
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina "Corrupted cached message_part data (%s)", error);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina return parts;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina}
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březinastatic bool get_cached_parts(struct index_mail *mail)
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina{
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina struct message_part *part;
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina T_BEGIN {
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina part = get_unserialized_parts(mail);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina } T_END;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if (part == NULL)
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina return FALSE;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina /* we know the NULs now, update them */
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina if ((part->flags & MESSAGE_PART_FLAG_HAS_NULS) != 0) {
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina mail->mail.mail.has_nuls = TRUE;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina mail->mail.mail.has_no_nuls = FALSE;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina } else {
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina mail->mail.mail.has_nuls = FALSE;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina mail->mail.mail.has_no_nuls = TRUE;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina }
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina mail->data.parts = part;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina return TRUE;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina}
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březinastatic bool index_mail_get_fixed_field(struct index_mail *mail,
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina enum index_cache_field field,
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina void *data, size_t data_size)
cee85e8fb9534ec997e5388fce59f392cf029573Jakub Hrozek{
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek unsigned int field_idx = mail->ibox->cache_fields[field].idx;
cee85e8fb9534ec997e5388fce59f392cf029573Jakub Hrozek buffer_t buf;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina int ret;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina buffer_create_data(&buf, data, data_size);
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina if (index_mail_cache_lookup_field(mail, &buf, field_idx) <= 0)
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina ret = FALSE;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina else {
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina i_assert(buf.used == data_size);
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina ret = TRUE;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina }
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina return ret;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina}
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březinabool index_mail_get_cached_uoff_t(struct index_mail *mail,
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina enum index_cache_field field, uoff_t *size_r)
b206e1abb7f6ea373d12537b3338552aed6b656dPavel Březina{
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina return index_mail_get_fixed_field(mail,
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina mail->ibox->cache_fields[field].idx,
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina size_r, sizeof(*size_r));
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina}
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina
b206e1abb7f6ea373d12537b3338552aed6b656dPavel Březinaenum mail_flags index_mail_get_flags(struct mail *mail)
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina{
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina const struct mail_index_record *rec;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina enum mail_flags flags;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina rec = mail_index_lookup(mail->transaction->view, mail->seq);
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina flags = rec->flags & (MAIL_FLAGS_NONRECENT |
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina MAIL_INDEX_MAIL_FLAG_BACKEND);
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina if (index_mailbox_is_recent(mail->box, mail->uid))
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina flags |= MAIL_RECENT;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina
b206e1abb7f6ea373d12537b3338552aed6b656dPavel Březina return flags;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina}
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březinauint64_t index_mail_get_modseq(struct mail *_mail)
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina{
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina struct index_mail *mail = (struct index_mail *)_mail;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina if (mail->data.modseq != 0)
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina return mail->data.modseq;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina mail_index_modseq_enable(_mail->box->index);
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina mail->data.modseq =
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina mail_index_modseq_lookup(_mail->transaction->view, _mail->seq);
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina return mail->data.modseq;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina}
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březinaconst char *const *index_mail_get_keywords(struct mail *_mail)
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina{
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina struct index_mail *mail = (struct index_mail *)_mail;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina struct index_mail_data *data = &mail->data;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina const char *const *names;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina const unsigned int *keyword_indexes;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina unsigned int i, count, names_count;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina if (array_is_created(&data->keywords))
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina return array_idx(&data->keywords, 0);
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina (void)index_mail_get_keyword_indexes(_mail);
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina keyword_indexes = array_get(&data->keyword_indexes, &count);
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina names = array_get(mail->ibox->keyword_names, &names_count);
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina p_array_init(&data->keywords, mail->data_pool, count + 1);
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina for (i = 0; i < count; i++) {
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina const char *name;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina i_assert(keyword_indexes[i] < names_count);
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina
11a87c5f091d6c092b5dadd3d67f900213e280daPetr Cech name = names[keyword_indexes[i]];
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina array_append(&data->keywords, &name, 1);
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina }
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina /* end with NULL */
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina (void)array_append_space(&data->keywords);
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina return array_idx(&data->keywords, 0);
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina}
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březinaconst ARRAY_TYPE(keyword_indexes) *
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březinaindex_mail_get_keyword_indexes(struct mail *_mail)
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina{
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina struct index_mail *mail = (struct index_mail *)_mail;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina struct index_mail_data *data = &mail->data;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina
b206e1abb7f6ea373d12537b3338552aed6b656dPavel Březina if (!array_is_created(&data->keyword_indexes)) {
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina p_array_init(&data->keyword_indexes, mail->data_pool, 32);
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina mail_index_lookup_keywords(_mail->transaction->view,
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina mail->data.seq,
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina &data->keyword_indexes);
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina }
b206e1abb7f6ea373d12537b3338552aed6b656dPavel Březina return &data->keyword_indexes;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina}
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březinaint index_mail_get_parts(struct mail *_mail, struct message_part **parts_r)
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina{
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina struct index_mail *mail = (struct index_mail *)_mail;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina struct index_mail_data *data = &mail->data;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina data->cache_fetch_fields |= MAIL_FETCH_MESSAGE_PARTS;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina if (data->parts != NULL || get_cached_parts(mail)) {
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina *parts_r = data->parts;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina return 0;
b206e1abb7f6ea373d12537b3338552aed6b656dPavel Březina }
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina if (data->parser_ctx == NULL) {
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina if (index_mail_parse_headers(mail, NULL) < 0)
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina return -1;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina }
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina data->save_message_parts = TRUE;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina if (index_mail_parse_body(mail, 0) < 0)
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina return -1;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina *parts_r = data->parts;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina return 0;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina}
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březinaint index_mail_get_received_date(struct mail *_mail, time_t *date_r)
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina{
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina struct index_mail *mail = (struct index_mail *)_mail;
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose struct index_mail_data *data = &mail->data;
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose data->cache_fetch_fields |= MAIL_FETCH_RECEIVED_DATE;
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose if (data->received_date == (time_t)-1) {
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose uint32_t t;
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose if (index_mail_get_fixed_field(mail, MAIL_CACHE_RECEIVED_DATE,
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose &t, sizeof(t)))
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose data->received_date = t;
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose }
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose *date_r = data->received_date;
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose return *date_r == (time_t)-1 ? -1 : 0;
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose}
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose
827a016a07d5f911cc4195be89896a376fd71f59Sumit Boseint index_mail_get_save_date(struct mail *_mail, time_t *date_r)
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose{
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose struct index_mail *mail = (struct index_mail *)_mail;
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose struct index_mail_data *data = &mail->data;
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose data->cache_fetch_fields |= MAIL_FETCH_SAVE_DATE;
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose if (data->save_date == (time_t)-1) {
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose uint32_t t;
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose if (index_mail_get_fixed_field(mail, MAIL_CACHE_SAVE_DATE,
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose &t, sizeof(t)))
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose data->save_date = t;
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose }
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose *date_r = data->save_date;
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose return *date_r == (time_t)-1 ? -1 : 0;
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose}
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bosestatic int index_mail_cache_sent_date(struct index_mail *mail)
cee85e8fb9534ec997e5388fce59f392cf029573Jakub Hrozek{
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek struct index_mail_data *data = &mail->data;
cee85e8fb9534ec997e5388fce59f392cf029573Jakub Hrozek const char *str;
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose time_t t;
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose int ret, tz;
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose if (data->sent_date.time != (uint32_t)-1)
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose return 0;
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose if ((ret = mail_get_first_header(&mail->mail.mail, "Date", &str)) < 0)
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose return ret;
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose if (ret == 0 ||
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose !message_date_parse((const unsigned char *)str,
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose strlen(str), &t, &tz)) {
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose /* 0 = not found / invalid */
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose t = 0;
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose tz = 0;
b206e1abb7f6ea373d12537b3338552aed6b656dPavel Březina }
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose data->sent_date.time = t;
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose data->sent_date.timezone = tz;
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose index_mail_cache_add(mail, MAIL_CACHE_SENT_DATE,
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose &data->sent_date, sizeof(data->sent_date));
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose return 0;
b206e1abb7f6ea373d12537b3338552aed6b656dPavel Březina}
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose
827a016a07d5f911cc4195be89896a376fd71f59Sumit Boseint index_mail_get_date(struct mail *_mail, time_t *date_r, int *timezone_r)
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose{
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose struct index_mail *mail = (struct index_mail *)_mail;
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose struct index_mail_data *data = &mail->data;
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose data->cache_fetch_fields |= MAIL_FETCH_DATE;
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose if (data->sent_date.time != (uint32_t)-1) {
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose *timezone_r = data->sent_date.timezone;
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose *date_r = data->sent_date.time;
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose return 0;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose }
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose (void)index_mail_get_fixed_field(mail, MAIL_CACHE_SENT_DATE,
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose &data->sent_date,
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose sizeof(data->sent_date));
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose if (index_mail_cache_sent_date(mail) < 0)
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose return -1;
b206e1abb7f6ea373d12537b3338552aed6b656dPavel Březina
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose *timezone_r = data->sent_date.timezone;
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose *date_r = data->sent_date.time;
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose return 0;
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose}
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bosestatic bool get_cached_msgpart_sizes(struct index_mail *mail)
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose{
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose struct index_mail_data *data = &mail->data;
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose if (data->parts == NULL)
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose get_cached_parts(mail);
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose if (data->parts != NULL) {
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose data->hdr_size_set = TRUE;
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose data->hdr_size = data->parts->header_size;
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose data->body_size = data->parts->body_size;
827a016a07d5f911cc4195be89896a376fd71f59Sumit Bose data->body_size_set = TRUE;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose data->virtual_size = data->parts->header_size.virtual_size +
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose data->body_size.virtual_size;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose data->physical_size = data->parts->header_size.physical_size +
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose data->body_size.physical_size;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose }
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose return data->parts != NULL;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose}
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bosebool index_mail_get_cached_virtual_size(struct index_mail *mail, uoff_t *size_r)
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose{
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose struct index_mail_data *data = &mail->data;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose data->cache_fetch_fields |= MAIL_FETCH_VIRTUAL_SIZE;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose if (data->virtual_size == (uoff_t)-1) {
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose if (!index_mail_get_cached_uoff_t(mail,
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose MAIL_CACHE_VIRTUAL_FULL_SIZE,
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose &data->virtual_size)) {
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose if (!get_cached_msgpart_sizes(mail))
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose return FALSE;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose }
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose }
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose if (data->hdr_size_set && data->physical_size != (uoff_t)-1) {
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose data->body_size.physical_size = data->physical_size -
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose data->hdr_size.physical_size;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose data->body_size.virtual_size = data->virtual_size -
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose data->hdr_size.virtual_size;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose data->body_size_set = TRUE;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose }
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose *size_r = data->virtual_size;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose return TRUE;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose}
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bosestatic void index_mail_get_cached_body_size(struct index_mail *mail)
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose{
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose struct index_mail_data *data = &mail->data;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose uoff_t tmp;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose if (!data->hdr_size_set)
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose return;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose /* we've already called get_cached_msgpart_sizes() and it didn't work.
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose try to do this by using cached virtual size and a quick physical
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose size lookup. */
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose if (!index_mail_get_cached_virtual_size(mail, &tmp))
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose return;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose if (!data->body_size_set) {
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose if (mail_get_physical_size(&mail->mail.mail, &tmp) < 0)
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose return;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose /* we should have everything now. try again. */
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose (void)index_mail_get_cached_virtual_size(mail, &tmp);
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose }
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose}
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Boseint index_mail_get_virtual_size(struct mail *_mail, uoff_t *size_r)
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose{
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose struct index_mail *mail = (struct index_mail *)_mail;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose struct index_mail_data *data = &mail->data;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose struct message_size hdr_size, body_size;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose struct istream *input;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose uoff_t old_offset;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose if (index_mail_get_cached_virtual_size(mail, size_r))
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose return 0;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose old_offset = data->stream == NULL ? 0 : data->stream->v_offset;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose if (mail_get_stream(_mail, &hdr_size, &body_size, &input) < 0)
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose return -1;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose i_stream_seek(data->stream, old_offset);
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose i_assert(data->virtual_size != (uoff_t)-1);
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose *size_r = data->virtual_size;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose return 0;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose}
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Boseint index_mail_get_physical_size(struct mail *_mail, uoff_t *size_r)
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose{
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose struct index_mail *mail = (struct index_mail *)_mail;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose struct index_mail_data *data = &mail->data;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose data->cache_fetch_fields |= MAIL_FETCH_PHYSICAL_SIZE;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose if (data->physical_size == (uoff_t)-1) {
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose if (!index_mail_get_cached_uoff_t(mail,
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose MAIL_CACHE_PHYSICAL_FULL_SIZE,
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose &data->physical_size))
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose (void)get_cached_msgpart_sizes(mail);
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose }
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose *size_r = data->physical_size;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose return *size_r == (uoff_t)-1 ? -1 : 0;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose}
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bosevoid index_mail_cache_add(struct index_mail *mail, enum index_cache_field field,
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose const void *data, size_t data_size)
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose{
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose index_mail_cache_add_idx(mail, mail->ibox->cache_fields[field].idx,
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose data, data_size);
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose}
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bosevoid index_mail_cache_add_idx(struct index_mail *mail, unsigned int field_idx,
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose const void *data, size_t data_size)
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose{
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose const struct mail_storage_settings *set =
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose mail->mail.mail.box->storage->set;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose const struct mail_index_header *hdr;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose if (set->mail_cache_min_mail_count > 0) {
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose /* First check if we've configured caching not to be used with
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose low enough message count. */
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose hdr = mail_index_get_header(mail->mail.mail.box->view);
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose if (hdr->messages_count < set->mail_cache_min_mail_count)
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose return;
861dbe0794739a1c93a5bed00913c7442a2bdac9Sumit Bose }
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek if (!mail->data.no_caching &&
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek mail->data.dont_cache_field_idx != field_idx) {
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek mail_cache_add(mail->trans->cache_trans, mail->data.seq,
5d855b5d546eb995023d80d61433bbe91888dbdfFabiano Fidêncio field_idx, data, data_size);
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek }
5d855b5d546eb995023d80d61433bbe91888dbdfFabiano Fidêncio}
5d855b5d546eb995023d80d61433bbe91888dbdfFabiano Fidêncio
5d855b5d546eb995023d80d61433bbe91888dbdfFabiano Fidênciostatic void parse_bodystructure_part_header(struct message_part *part,
5d855b5d546eb995023d80d61433bbe91888dbdfFabiano Fidêncio struct message_header_line *hdr,
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek pool_t pool)
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek{
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek imap_bodystructure_parse_header(pool, part, hdr);
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek}
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozekstatic bool want_plain_bodystructure_cached(struct index_mail *mail)
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek{
5d855b5d546eb995023d80d61433bbe91888dbdfFabiano Fidêncio if ((mail->wanted_fields & (MAIL_FETCH_IMAP_BODY |
5d855b5d546eb995023d80d61433bbe91888dbdfFabiano Fidêncio MAIL_FETCH_IMAP_BODYSTRUCTURE)) != 0)
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek return TRUE;
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek if (mail_cache_field_want_add(mail->trans->cache_trans, mail->data.seq,
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek mail->ibox->cache_fields[MAIL_CACHE_IMAP_BODY].idx))
5d855b5d546eb995023d80d61433bbe91888dbdfFabiano Fidêncio return TRUE;
5d855b5d546eb995023d80d61433bbe91888dbdfFabiano Fidêncio if (mail_cache_field_want_add(mail->trans->cache_trans, mail->data.seq,
5d855b5d546eb995023d80d61433bbe91888dbdfFabiano Fidêncio mail->ibox->cache_fields[MAIL_CACHE_IMAP_BODYSTRUCTURE].idx))
5d855b5d546eb995023d80d61433bbe91888dbdfFabiano Fidêncio return TRUE;
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek return FALSE;
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek}
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bosestatic void index_mail_body_parsed_cache_flags(struct index_mail *mail)
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose{
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose struct index_mail_data *data = &mail->data;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose unsigned int cache_flags_idx;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose uint32_t cache_flags = data->cache_flags;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose bool want_cached;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose cache_flags_idx = mail->ibox->cache_fields[MAIL_CACHE_FLAGS].idx;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose want_cached = mail_cache_field_want_add(mail->trans->cache_trans,
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose data->seq, cache_flags_idx);
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose if (data->parsed_bodystructure &&
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose imap_bodystructure_is_plain_7bit(data->parts) &&
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose (want_cached || want_plain_bodystructure_cached(mail))) {
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose cache_flags |= MAIL_CACHE_FLAG_TEXT_PLAIN_7BIT_ASCII;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose /* we need message_parts cached to be able to
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose actually use it in BODY/BODYSTRUCTURE reply */
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose want_cached = TRUE;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose data->save_message_parts = TRUE;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose }
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose /* cache flags should never get unset as long as the message doesn't
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose change, but try to handle it anyway */
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose cache_flags &= ~(MAIL_CACHE_FLAG_BINARY_HEADER |
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose MAIL_CACHE_FLAG_BINARY_BODY |
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose MAIL_CACHE_FLAG_HAS_NULS |
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose MAIL_CACHE_FLAG_HAS_NO_NULS);
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose if ((data->parts->flags & MESSAGE_PART_FLAG_HAS_NULS) != 0) {
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose mail->mail.mail.has_nuls = TRUE;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose mail->mail.mail.has_no_nuls = FALSE;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose cache_flags |= MAIL_CACHE_FLAG_HAS_NULS;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose } else {
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose mail->mail.mail.has_nuls = FALSE;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose mail->mail.mail.has_no_nuls = TRUE;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose cache_flags |= MAIL_CACHE_FLAG_HAS_NO_NULS;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose }
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose if (data->hdr_size.virtual_size == data->hdr_size.physical_size)
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose cache_flags |= MAIL_CACHE_FLAG_BINARY_HEADER;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose if (data->body_size.virtual_size == data->body_size.physical_size)
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose cache_flags |= MAIL_CACHE_FLAG_BINARY_BODY;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose if (cache_flags != data->cache_flags && want_cached) {
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose index_mail_cache_add_idx(mail, cache_flags_idx,
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose &cache_flags, sizeof(cache_flags));
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose }
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose data->cache_flags = cache_flags;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose}
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bosestatic void index_mail_body_parsed_cache_message_parts(struct index_mail *mail)
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose{
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose struct index_mail_data *data = &mail->data;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose unsigned int cache_field =
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose mail->ibox->cache_fields[MAIL_CACHE_MESSAGE_PARTS].idx;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose enum mail_cache_decision_type decision;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose buffer_t *buffer;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose if (data->messageparts_saved_to_cache ||
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose mail_cache_field_exists(mail->trans->cache_view, mail->data.seq,
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose cache_field) != 0) {
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose /* already cached */
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose return;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose }
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose decision = mail_cache_field_get_decision(mail->mail.mail.box->cache,
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose cache_field);
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose if (decision == (MAIL_CACHE_DECISION_NO | MAIL_CACHE_DECISION_FORCED)) {
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose /* we never want it cached */
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose return;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose }
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose if (decision == MAIL_CACHE_DECISION_NO &&
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose !data->save_message_parts &&
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose (mail->wanted_fields & MAIL_FETCH_MESSAGE_PARTS) == 0) {
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose /* we didn't really care about the message parts themselves,
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose just wanted to use something that depended on it */
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose return;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose }
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose T_BEGIN {
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose buffer = buffer_create_dynamic(pool_datastack_create(), 1024);
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose message_part_serialize(mail->data.parts, buffer);
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose index_mail_cache_add_idx(mail, cache_field,
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose buffer->data, buffer->used);
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose } T_END;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose
cee85e8fb9534ec997e5388fce59f392cf029573Jakub Hrozek data->messageparts_saved_to_cache = TRUE;
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek}
cee85e8fb9534ec997e5388fce59f392cf029573Jakub Hrozek
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bosestatic void
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Boseindex_mail_body_parsed_cache_bodystructure(struct index_mail *mail,
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose enum index_cache_field field)
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose{
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose struct index_mail_data *data = &mail->data;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose unsigned int cache_field_parts =
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose mail->ibox->cache_fields[MAIL_CACHE_MESSAGE_PARTS].idx;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose unsigned int cache_field_body =
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose mail->ibox->cache_fields[MAIL_CACHE_IMAP_BODY].idx;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose unsigned int cache_field_bodystructure =
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose mail->ibox->cache_fields[MAIL_CACHE_IMAP_BODYSTRUCTURE].idx;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose enum mail_cache_decision_type dec;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose string_t *str;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose bool bodystructure_cached = FALSE;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose bool plain_bodystructure = FALSE;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose bool cache_bodystructure, cache_body;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose if ((data->cache_flags & MAIL_CACHE_FLAG_TEXT_PLAIN_7BIT_ASCII) != 0) {
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose if (data->messageparts_saved_to_cache ||
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose mail_cache_field_exists(mail->trans->cache_view, data->seq,
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose cache_field_parts) > 0) {
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose /* cached it as flag + message_parts */
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose plain_bodystructure = TRUE;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose }
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose }
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose if (!data->parsed_bodystructure)
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose return;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose /* If BODY is fetched first but BODYSTRUCTURE is also wanted, we don't
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose normally want to first cache BODY and then BODYSTRUCTURE. So check
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose the wanted_fields also in here. */
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose if (plain_bodystructure)
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose cache_bodystructure = FALSE;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose else if (field == MAIL_CACHE_IMAP_BODYSTRUCTURE ||
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose (mail->wanted_fields & MAIL_FETCH_IMAP_BODYSTRUCTURE) != 0) {
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose cache_bodystructure =
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose mail_cache_field_can_add(mail->trans->cache_trans,
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose data->seq, cache_field_bodystructure);
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose } else {
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose cache_bodystructure =
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose mail_cache_field_want_add(mail->trans->cache_trans,
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose data->seq, cache_field_bodystructure);
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose }
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose if (cache_bodystructure) {
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose str = str_new(mail->data_pool, 128);
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose imap_bodystructure_write(data->parts, str, TRUE);
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose data->bodystructure = str_c(str);
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose index_mail_cache_add(mail, MAIL_CACHE_IMAP_BODYSTRUCTURE,
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose str_c(str), str_len(str)+1);
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose bodystructure_cached = TRUE;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose } else {
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose bodystructure_cached =
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose mail_cache_field_exists(mail->trans->cache_view,
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose data->seq, cache_field_bodystructure) > 0;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose }
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose /* normally don't cache both BODY and BODYSTRUCTURE, but do it
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose if BODY is forced to be cached */
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose dec = mail_cache_field_get_decision(mail->mail.mail.box->cache,
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose cache_field_body);
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose if (plain_bodystructure ||
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose (bodystructure_cached &&
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose (dec != (MAIL_CACHE_DECISION_FORCED | MAIL_CACHE_DECISION_YES))))
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose cache_body = FALSE;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose else if (field == MAIL_CACHE_IMAP_BODY) {
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose cache_body =
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose mail_cache_field_can_add(mail->trans->cache_trans,
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose data->seq, cache_field_body);
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose } else {
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose cache_body =
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose mail_cache_field_want_add(mail->trans->cache_trans,
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose data->seq, cache_field_body);
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose }
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose if (cache_body) {
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose str = str_new(mail->data_pool, 128);
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose imap_bodystructure_write(data->parts, str, FALSE);
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose data->body = str_c(str);
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek index_mail_cache_add(mail, MAIL_CACHE_IMAP_BODY,
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose str_c(str), str_len(str)+1);
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose }
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose}
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bosestatic bool
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Boseindex_mail_want_cache(struct index_mail *mail, enum index_cache_field field)
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose{
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose enum mail_fetch_field fetch_field;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose unsigned int cache_field;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose switch (field) {
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose case MAIL_CACHE_SENT_DATE:
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose fetch_field = MAIL_FETCH_DATE;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose break;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose case MAIL_CACHE_RECEIVED_DATE:
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose fetch_field = MAIL_FETCH_RECEIVED_DATE;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose break;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose case MAIL_CACHE_SAVE_DATE:
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose fetch_field = MAIL_FETCH_SAVE_DATE;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose break;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose case MAIL_CACHE_VIRTUAL_FULL_SIZE:
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose fetch_field = MAIL_FETCH_VIRTUAL_SIZE;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose break;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose case MAIL_CACHE_PHYSICAL_FULL_SIZE:
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose fetch_field = MAIL_FETCH_PHYSICAL_SIZE;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose break;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose default:
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose i_unreached();
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose }
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose if ((mail->data.dont_cache_fetch_fields & fetch_field) != 0)
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose return FALSE;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose cache_field = mail->ibox->cache_fields[field].idx;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose if ((mail->data.cache_fetch_fields & fetch_field) != 0) {
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose return mail_cache_field_can_add(mail->trans->cache_trans,
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose mail->data.seq, cache_field);
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose } else {
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose return mail_cache_field_want_add(mail->trans->cache_trans,
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose mail->data.seq, cache_field);
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose }
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose}
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bosestatic void index_mail_cache_sizes(struct index_mail *mail)
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose{
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose static enum index_cache_field size_fields[] = {
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose MAIL_CACHE_VIRTUAL_FULL_SIZE,
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose MAIL_CACHE_PHYSICAL_FULL_SIZE
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose };
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose uoff_t sizes[N_ELEMENTS(size_fields)];
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose unsigned int i;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose sizes[0] = mail->data.virtual_size;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose sizes[1] = mail->data.physical_size;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose for (i = 0; i < N_ELEMENTS(size_fields); i++) {
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose if (sizes[i] != (uoff_t)-1 &&
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose index_mail_want_cache(mail, size_fields[i])) {
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose index_mail_cache_add(mail, size_fields[i],
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose &sizes[i], sizeof(sizes[i]));
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose }
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose }
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose}
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bosestatic void index_mail_cache_dates(struct index_mail *mail)
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose{
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose static enum index_cache_field date_fields[] = {
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose MAIL_CACHE_RECEIVED_DATE,
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose MAIL_CACHE_SAVE_DATE
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose };
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose time_t dates[N_ELEMENTS(date_fields)];
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose unsigned int i;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose uint32_t t;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose dates[0] = mail->data.received_date;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose dates[1] = mail->data.save_date;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose for (i = 0; i < N_ELEMENTS(date_fields); i++) {
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose if (dates[i] != (time_t)-1 &&
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose index_mail_want_cache(mail, date_fields[i])) {
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose t = dates[i];
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose index_mail_cache_add(mail, date_fields[i],
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose &t, sizeof(t));
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose }
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose }
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose if (mail->data.sent_date_parsed &&
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose index_mail_want_cache(mail, MAIL_CACHE_SENT_DATE))
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose (void)index_mail_cache_sent_date(mail);
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose}
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bosestatic int index_mail_parse_body_finish(struct index_mail *mail,
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose enum index_cache_field field)
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose{
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose if (message_parser_deinit(&mail->data.parser_ctx,
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose &mail->data.parts) < 0) {
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose mail_set_cache_corrupted(&mail->mail.mail,
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose MAIL_FETCH_MESSAGE_PARTS);
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose mail->data.parsed_bodystructure = FALSE;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose return -1;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose }
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose if (mail->data.no_caching) {
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose /* if we're here because we aborted parsing, don't get any
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose further or we may crash while generating output from
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose incomplete data */
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose return 0;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose }
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose (void)get_cached_msgpart_sizes(mail);
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose index_mail_body_parsed_cache_flags(mail);
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose index_mail_body_parsed_cache_message_parts(mail);
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose index_mail_body_parsed_cache_bodystructure(mail, field);
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose index_mail_cache_sizes(mail);
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose index_mail_cache_dates(mail);
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose return 0;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose}
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bosestatic int index_mail_stream_check_failure(struct index_mail *mail)
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose{
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose if (mail->data.stream->stream_errno == 0)
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose return 0;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose errno = mail->data.stream->stream_errno;
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose mail_storage_set_critical(mail->mail.mail.box->storage,
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose "read(mail, uid=%u) failed: %m", mail->mail.mail.uid);
ef55b0e470a8fbcf6e6d0a55883145e02a907842Sumit Bose return -1;
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek}
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozekstatic int index_mail_parse_body(struct index_mail *mail,
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek enum index_cache_field field)
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina{
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina struct index_mail_data *data = &mail->data;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina uoff_t old_offset;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina int ret;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek i_assert(data->parser_ctx != NULL);
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek old_offset = data->stream->v_offset;
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek i_stream_seek(data->stream, data->hdr_size.physical_size);
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek if (data->save_bodystructure_body) {
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek /* bodystructure header is parsed, we want the body's mime
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek headers too */
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek i_assert(!data->save_bodystructure_header);
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek message_parser_parse_body(data->parser_ctx,
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek parse_bodystructure_part_header,
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek mail->data_pool);
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek data->save_bodystructure_body = FALSE;
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek data->parsed_bodystructure = TRUE;
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek } else {
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek message_parser_parse_body(data->parser_ctx,
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek null_message_part_header_callback, NULL);
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek }
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek ret = index_mail_stream_check_failure(mail);
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek if (index_mail_parse_body_finish(mail, field) < 0)
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek ret = -1;
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek i_stream_seek(data->stream, old_offset);
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek return ret;
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek}
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozekstatic void index_mail_stream_destroy_callback(struct index_mail *mail)
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek{
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek i_assert(mail->data.destroying_stream);
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek mail->data.destroying_stream = FALSE;
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek}
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březinavoid index_mail_set_read_buffer_size(struct mail *_mail, struct istream *input)
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina{
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina struct index_mail *mail = (struct index_mail *)_mail;
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek unsigned int block_size;
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek i_stream_set_max_buffer_size(input, MAIL_READ_FULL_BLOCK_SIZE);
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek block_size = (mail->data.access_part & READ_BODY) != 0 ?
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek MAIL_READ_FULL_BLOCK_SIZE : MAIL_READ_HDR_BLOCK_SIZE;
b010f24f4d96d15c5c85021bb4aa83db25cd3df5Jakub Hrozek i_stream_set_init_buffer_size(input, block_size);
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek}
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozekint index_mail_init_stream(struct index_mail *mail,
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek struct message_size *hdr_size,
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek struct message_size *body_size,
b206e1abb7f6ea373d12537b3338552aed6b656dPavel Březina struct istream **stream_r)
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek{
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek struct index_mail_data *data = &mail->data;
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek struct istream *input;
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek int ret;
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek if (!data->initialized_wrapper_stream && mail->mail.stats_track) {
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek input = i_stream_create_mail_stats_counter(&mail->mail,
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek data->stream);
b010f24f4d96d15c5c85021bb4aa83db25cd3df5Jakub Hrozek i_stream_unref(&data->stream);
b010f24f4d96d15c5c85021bb4aa83db25cd3df5Jakub Hrozek data->stream = input;
b010f24f4d96d15c5c85021bb4aa83db25cd3df5Jakub Hrozek data->initialized_wrapper_stream = TRUE;
b010f24f4d96d15c5c85021bb4aa83db25cd3df5Jakub Hrozek }
b010f24f4d96d15c5c85021bb4aa83db25cd3df5Jakub Hrozek
b010f24f4d96d15c5c85021bb4aa83db25cd3df5Jakub Hrozek if (!data->destroy_callback_set) {
b010f24f4d96d15c5c85021bb4aa83db25cd3df5Jakub Hrozek /* do this only once in case a plugin changes the stream.
b010f24f4d96d15c5c85021bb4aa83db25cd3df5Jakub Hrozek otherwise the check would break. */
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek data->destroy_callback_set = TRUE;
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek i_stream_set_destroy_callback(data->stream,
877b92e80bde510d5cd9f03dbf01e2bcf73ab072Michal Židek index_mail_stream_destroy_callback, mail);
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek }
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek if (hdr_size != NULL || body_size != NULL)
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek (void)get_cached_msgpart_sizes(mail);
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek if (hdr_size != NULL || body_size != NULL) {
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek i_stream_seek(data->stream, 0);
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek if (!data->hdr_size_set) {
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek if ((data->access_part & PARSE_HDR) != 0) {
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek (void)get_cached_parts(mail);
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek if (index_mail_parse_headers(mail, NULL) < 0)
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek return -1;
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek } else {
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek message_get_header_size(data->stream,
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek &data->hdr_size, NULL);
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek data->hdr_size_set = TRUE;
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek }
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek }
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek if (hdr_size != NULL)
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek *hdr_size = data->hdr_size;
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek }
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina if (body_size != NULL) {
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina if (!data->body_size_set)
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina index_mail_get_cached_body_size(mail);
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina if (!data->body_size_set) {
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina i_stream_seek(data->stream,
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek data->hdr_size.physical_size);
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek if ((data->access_part & PARSE_BODY) != 0) {
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek if (index_mail_parse_body(mail, 0) < 0)
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek return -1;
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek } else {
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek message_get_body_size(data->stream,
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek &data->body_size, NULL);
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek data->body_size_set = TRUE;
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek }
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek }
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek *body_size = data->body_size;
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek }
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek if (data->hdr_size_set && data->body_size_set) {
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek data->virtual_size = data->hdr_size.virtual_size +
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek data->body_size.virtual_size;
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek data->physical_size = data->hdr_size.physical_size +
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek data->body_size.physical_size;
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek }
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek ret = index_mail_stream_check_failure(mail);
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek i_stream_seek(data->stream, 0);
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek *stream_r = data->stream;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina return ret;
c747b0c875785ce693f70b50bdda0237c4b04e35Pavel Březina}
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozekstatic int index_mail_parse_bodystructure(struct index_mail *mail,
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek enum index_cache_field field)
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek{
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek struct index_mail_data *data = &mail->data;
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek string_t *str;
b206e1abb7f6ea373d12537b3338552aed6b656dPavel Březina
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek if (data->parsed_bodystructure) {
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek /* we have everything parsed already, but just not written to
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek a string */
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek index_mail_body_parsed_cache_bodystructure(mail, field);
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek } else {
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek if (data->save_bodystructure_header ||
b206e1abb7f6ea373d12537b3338552aed6b656dPavel Březina !data->save_bodystructure_body) {
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek /* we haven't parsed the header yet */
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek data->save_bodystructure_header = TRUE;
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek data->save_bodystructure_body = TRUE;
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek (void)get_cached_parts(mail);
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek if (index_mail_parse_headers(mail, NULL) < 0)
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek return -1;
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek }
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek if (index_mail_parse_body(mail, field) < 0)
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek return -1;
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek }
5d855b5d546eb995023d80d61433bbe91888dbdfFabiano Fidêncio i_assert(data->parts != NULL);
5d855b5d546eb995023d80d61433bbe91888dbdfFabiano Fidêncio
5d855b5d546eb995023d80d61433bbe91888dbdfFabiano Fidêncio /* if we didn't want to have the body(structure) cached,
5d855b5d546eb995023d80d61433bbe91888dbdfFabiano Fidêncio it's still not written. */
5d855b5d546eb995023d80d61433bbe91888dbdfFabiano Fidêncio switch (field) {
5d855b5d546eb995023d80d61433bbe91888dbdfFabiano Fidêncio case MAIL_CACHE_IMAP_BODY:
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek if (data->body == NULL) {
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek str = str_new(mail->data_pool, 128);
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek imap_bodystructure_write(data->parts, str, FALSE);
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek data->body = str_c(str);
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek }
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek break;
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek case MAIL_CACHE_IMAP_BODYSTRUCTURE:
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek if (data->bodystructure == NULL) {
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek str = str_new(mail->data_pool, 128);
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek imap_bodystructure_write(data->parts, str, TRUE);
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek data->bodystructure = str_c(str);
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek }
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek break;
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek default:
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek i_unreached();
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek }
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek return 0;
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek}
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozekstatic void
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozekindex_mail_get_plain_bodystructure(struct index_mail *mail, string_t *str,
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek bool extended)
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek{
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek str_printfa(str, IMAP_BODY_PLAIN_7BIT_ASCII" %"PRIuUOFF_T" %u",
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek mail->data.parts->body_size.virtual_size,
bdf32fbb3c947dd1b2c54d1c21d8028a1ddc80e6Jakub Hrozek mail->data.parts->body_size.lines);
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek if (extended)
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek str_append(str, " NIL NIL NIL NIL");
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek}
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozekint index_mail_get_special(struct mail *_mail,
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek enum mail_fetch_field field, const char **value_r)
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek{
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek struct index_mail *mail = (struct index_mail *)_mail;
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek struct index_mail_data *data = &mail->data;
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek struct mail_cache_field *cache_fields = mail->ibox->cache_fields;
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek string_t *str;
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek switch (field) {
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek case MAIL_FETCH_IMAP_BODY: {
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek unsigned int body_cache_field =
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek cache_fields[MAIL_CACHE_IMAP_BODY].idx;
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek unsigned int bodystructure_cache_field =
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek cache_fields[MAIL_CACHE_IMAP_BODYSTRUCTURE].idx;
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek if (data->body != NULL) {
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek *value_r = data->body;
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek return 0;
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek }
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek /* 1) use plain-7bit-ascii flag if it exists
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek 2) get BODY if it exists
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek 3) get it using BODYSTRUCTURE if it exists
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek 4) parse body structure, and save BODY/BODYSTRUCTURE
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek depending on what we want cached */
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek str = str_new(mail->data_pool, 128);
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek if ((mail->data.cache_flags &
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek MAIL_CACHE_FLAG_TEXT_PLAIN_7BIT_ASCII) != 0 &&
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek get_cached_parts(mail)) {
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek index_mail_get_plain_bodystructure(mail, str, FALSE);
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek data->body = str_c(str);
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek } else if (index_mail_cache_lookup_field(mail, str,
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek body_cache_field) > 0)
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek data->body = str_c(str);
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek else if (index_mail_cache_lookup_field(mail, str,
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek bodystructure_cache_field) > 0) {
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek data->bodystructure =
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek p_strdup(mail->data_pool, str_c(str));
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek str_truncate(str, 0);
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek if (imap_body_parse_from_bodystructure(
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek data->bodystructure, str))
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek data->body = str_c(str);
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek else {
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek /* broken, continue.. */
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek mail_set_cache_corrupted(_mail,
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina MAIL_FETCH_IMAP_BODYSTRUCTURE);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if (data->body == NULL) {
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina str_free(&str);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if (index_mail_parse_bodystructure(mail,
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek MAIL_CACHE_IMAP_BODY) < 0)
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina return -1;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek i_assert(data->body != NULL);
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek *value_r = data->body;
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek return 0;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina case MAIL_FETCH_IMAP_BODYSTRUCTURE: {
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina unsigned int bodystructure_cache_field =
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina cache_fields[MAIL_CACHE_IMAP_BODYSTRUCTURE].idx;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if (data->bodystructure != NULL) {
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina *value_r = data->bodystructure;
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek return 0;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina str = str_new(mail->data_pool, 128);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if ((mail->data.cache_flags &
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina MAIL_CACHE_FLAG_TEXT_PLAIN_7BIT_ASCII) != 0 &&
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina get_cached_parts(mail)) {
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek index_mail_get_plain_bodystructure(mail, str, TRUE);
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek data->bodystructure = str_c(str);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina } else if (index_mail_cache_lookup_field(mail, str,
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina bodystructure_cache_field) > 0) {
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina data->bodystructure = str_c(str);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina } else {
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina str_free(&str);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if (index_mail_parse_bodystructure(mail,
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina MAIL_CACHE_IMAP_BODYSTRUCTURE) < 0)
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina return -1;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina i_assert(data->bodystructure != NULL);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina *value_r = data->bodystructure;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina return 0;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina case MAIL_FETCH_IMAP_ENVELOPE:
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if (data->envelope == NULL) {
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if (index_mail_headers_get_envelope(mail) < 0)
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina return -1;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina *value_r = data->envelope;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina return 0;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina case MAIL_FETCH_FROM_ENVELOPE:
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina case MAIL_FETCH_UIDL_FILE_NAME:
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina case MAIL_FETCH_UIDL_BACKEND:
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina case MAIL_FETCH_SEARCH_SCORE:
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina case MAIL_FETCH_GUID:
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina case MAIL_FETCH_HEADER_MD5:
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina *value_r = "";
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina return 0;
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek case MAIL_FETCH_MAILBOX_NAME:
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina *value_r = _mail->box->vname;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina return 0;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina default:
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina i_unreached();
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina return -1;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina}
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březinastruct mail *index_mail_get_real_mail(struct mail *mail)
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek{
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek return mail;
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek}
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozekstruct mail *
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozekindex_mail_alloc(struct mailbox_transaction_context *t,
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek enum mail_fetch_field wanted_fields,
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek struct mailbox_header_lookup_ctx *wanted_headers)
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek{
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek struct index_mail *mail;
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek pool_t pool;
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek pool = pool_alloconly_create("mail", 2048);
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek mail = p_new(pool, struct index_mail, 1);
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek mail->mail.pool = pool;
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek index_mail_init(mail, t, wanted_fields, wanted_headers);
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek return &mail->mail.mail;
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek}
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozekvoid index_mail_init(struct index_mail *mail,
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek struct mailbox_transaction_context *_t,
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek enum mail_fetch_field wanted_fields,
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek struct mailbox_header_lookup_ctx *_wanted_headers)
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek{
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek struct index_transaction_context *t =
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek (struct index_transaction_context *)_t;
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek struct index_header_lookup_ctx *wanted_headers =
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek (struct index_header_lookup_ctx *)_wanted_headers;
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek const struct mail_index_header *hdr;
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek array_create(&mail->mail.module_contexts, mail->mail.pool,
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek sizeof(void *), 5);
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek mail->mail.v = *_t->box->mail_vfuncs;
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek mail->mail.mail.box = _t->box;
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek mail->mail.mail.transaction = &t->mailbox_ctx;
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek mail->mail.wanted_fields = wanted_fields;
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek mail->mail.wanted_headers = _wanted_headers;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina hdr = mail_index_get_header(_t->box->view);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail->uid_validity = hdr->uid_validity;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina t->mail_ref_count++;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail->data_pool = pool_alloconly_create("index_mail", 16384);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail->ibox = INDEX_STORAGE_CONTEXT(_t->box);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail->trans = t;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail->wanted_fields = wanted_fields;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if (wanted_headers != NULL) {
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail->wanted_headers = wanted_headers;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mailbox_header_lookup_ref(_wanted_headers);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina}
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březinavoid index_mail_close(struct mail *_mail)
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina{
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina struct index_mail *mail = (struct index_mail *)_mail;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina struct message_part *parts;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina /* If uid == 0 but seq != 0, we came here from saving a (non-mbox)
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina message. If that happens, don't bother checking if anything should
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina be cached since it was already checked. Also by now the transaction
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek may have already been rollbacked and seq point to a non-existing
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina message. */
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if (mail->mail.mail.uid != 0) {
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina index_mail_cache_sizes(mail);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina index_mail_cache_dates(mail);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if (mail->data.parser_ctx != NULL) {
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if (message_parser_deinit(&mail->data.parser_ctx, &parts) < 0) {
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail_set_cache_corrupted(_mail,
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina MAIL_FETCH_MESSAGE_PARTS);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if (mail->data.filter_stream != NULL)
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina i_stream_unref(&mail->data.filter_stream);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if (mail->data.stream != NULL) {
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail->data.destroying_stream = TRUE;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina i_stream_unref(&mail->data.stream);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina i_assert(!mail->data.destroying_stream);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina}
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březinastatic void index_mail_reset(struct index_mail *mail)
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina{
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina struct index_mail_data *data = &mail->data;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail->mail.v.close(&mail->mail.mail);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek memset(data, 0, sizeof(*data));
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina p_clear(mail->data_pool);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina data->virtual_size = (uoff_t)-1;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina data->physical_size = (uoff_t)-1;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina data->save_date = (time_t)-1;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina data->received_date = (time_t)-1;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina data->sent_date.time = (uint32_t)-1;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina data->dont_cache_field_idx = -1U;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail->mail.mail.seq = 0;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail->mail.mail.uid = 0;
cee85e8fb9534ec997e5388fce59f392cf029573Jakub Hrozek mail->mail.mail.expunged = FALSE;
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek mail->mail.mail.has_nuls = FALSE;
11a87c5f091d6c092b5dadd3d67f900213e280daPetr Cech mail->mail.mail.has_no_nuls = FALSE;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina}
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březinastatic void check_envelope(struct index_mail *mail)
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina{
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina unsigned int cache_field_envelope =
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail->ibox->cache_fields[MAIL_CACHE_IMAP_ENVELOPE].idx;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina unsigned int cache_field_hdr;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if ((mail->data.access_part & PARSE_HDR) != 0) {
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail->data.save_envelope = TRUE;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina return;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina /* if "imap.envelope" is cached, that's all we need */
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if (mail_cache_field_exists(mail->trans->cache_view,
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail->mail.mail.seq,
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina cache_field_envelope) > 0)
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina return;
b206e1abb7f6ea373d12537b3338552aed6b656dPavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina /* don't waste time doing full checks for all required
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina headers. assume that if we have "hdr.message-id" cached,
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina we don't need to parse the header. */
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina cache_field_hdr = mail_cache_register_lookup(mail->mail.mail.box->cache,
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina "hdr.message-id");
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if (cache_field_hdr == (unsigned int)-1 ||
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail_cache_field_exists(mail->trans->cache_view,
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail->mail.mail.seq,
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina cache_field_hdr) <= 0)
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail->data.access_part |= PARSE_HDR;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail->data.save_envelope = TRUE;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina}
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březinavoid index_mail_set_seq(struct mail *_mail, uint32_t seq)
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina{
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina struct index_mail *mail = (struct index_mail *)_mail;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina struct index_mail_data *data = &mail->data;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina struct mail_cache_field *cache_fields = mail->ibox->cache_fields;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina struct mail_cache_view *cache_view = mail->trans->cache_view;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina const struct mail_index_header *hdr;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina struct istream *input;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if (data->seq == seq)
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina return;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
d0faaf01fd24a935d9779032886d228b3861fa48Jakub Hrozek index_mail_reset(mail);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina data->seq = seq;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail->mail.mail.seq = seq;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail_index_lookup_uid(_mail->transaction->view, seq,
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina &mail->mail.mail.uid);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if (mail_index_view_is_inconsistent(_mail->transaction->view)) {
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail_set_expunged(&mail->mail.mail);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina return;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if ((mail->wanted_fields & (MAIL_FETCH_NUL_STATE |
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina MAIL_FETCH_IMAP_BODY |
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina MAIL_FETCH_IMAP_BODYSTRUCTURE)) != 0) {
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina (void)index_mail_get_fixed_field(mail, MAIL_CACHE_FLAGS,
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina &data->cache_flags,
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina sizeof(data->cache_flags));
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail->mail.mail.has_nuls =
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina (data->cache_flags & MAIL_CACHE_FLAG_HAS_NULS) != 0;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail->mail.mail.has_no_nuls =
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina (data->cache_flags & MAIL_CACHE_FLAG_HAS_NO_NULS) != 0;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina /* see if wanted_fields can tell us if we need to read/parse
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina header/body */
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if ((mail->wanted_fields & MAIL_FETCH_MESSAGE_PARTS) != 0) {
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina unsigned int cache_field =
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina cache_fields[MAIL_CACHE_MESSAGE_PARTS].idx;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if (mail_cache_field_exists(cache_view, seq,
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina cache_field) <= 0) {
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina data->access_part |= PARSE_HDR | PARSE_BODY;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina data->save_message_parts = TRUE;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
e9a2e7afbd09c23dd8748246e09831ed7b17d7c5Thomas Equeter if ((mail->wanted_fields & MAIL_FETCH_VIRTUAL_SIZE) != 0) {
e9a2e7afbd09c23dd8748246e09831ed7b17d7c5Thomas Equeter unsigned int cache_field =
e9a2e7afbd09c23dd8748246e09831ed7b17d7c5Thomas Equeter cache_fields[MAIL_CACHE_VIRTUAL_FULL_SIZE].idx;
e9a2e7afbd09c23dd8748246e09831ed7b17d7c5Thomas Equeter
e9a2e7afbd09c23dd8748246e09831ed7b17d7c5Thomas Equeter if (mail_cache_field_exists(cache_view, seq, cache_field) <= 0)
e9a2e7afbd09c23dd8748246e09831ed7b17d7c5Thomas Equeter data->access_part |= READ_HDR | READ_BODY;
e9a2e7afbd09c23dd8748246e09831ed7b17d7c5Thomas Equeter }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if ((mail->wanted_fields & MAIL_FETCH_IMAP_ENVELOPE) != 0)
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina check_envelope(mail);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if ((mail->wanted_fields & MAIL_FETCH_IMAP_BODY) != 0 &&
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina (data->cache_flags & MAIL_CACHE_FLAG_TEXT_PLAIN_7BIT_ASCII) == 0) {
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina /* we need either imap.body or imap.bodystructure */
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina unsigned int cache_field1 =
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina cache_fields[MAIL_CACHE_IMAP_BODY].idx;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina unsigned int cache_field2 =
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina cache_fields[MAIL_CACHE_IMAP_BODYSTRUCTURE].idx;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if (mail_cache_field_exists(cache_view,
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina seq, cache_field1) <= 0 &&
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail_cache_field_exists(cache_view,
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina seq, cache_field2) <= 0) {
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina data->access_part |= PARSE_HDR | PARSE_BODY;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina data->save_bodystructure_header = TRUE;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina data->save_bodystructure_body = TRUE;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if ((mail->wanted_fields & MAIL_FETCH_IMAP_BODYSTRUCTURE) != 0 &&
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina (data->cache_flags & MAIL_CACHE_FLAG_TEXT_PLAIN_7BIT_ASCII) == 0) {
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina unsigned int cache_field =
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina cache_fields[MAIL_CACHE_IMAP_BODYSTRUCTURE].idx;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if (mail_cache_field_exists(cache_view, seq,
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina cache_field) <= 0) {
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina data->access_part |= PARSE_HDR | PARSE_BODY;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina data->save_bodystructure_header = TRUE;
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek data->save_bodystructure_body = TRUE;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if ((mail->wanted_fields & MAIL_FETCH_DATE) != 0) {
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina unsigned int cache_field =
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina cache_fields[MAIL_CACHE_SENT_DATE].idx;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if (mail_cache_field_exists(cache_view, seq,
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina cache_field) <= 0) {
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina data->access_part |= PARSE_HDR;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina data->save_sent_date = TRUE;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if ((mail->wanted_fields & (MAIL_FETCH_STREAM_HEADER |
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina MAIL_FETCH_STREAM_BODY)) != 0) {
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina /* open stream immediately to set expunged flag if
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina it's already lost */
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if ((mail->wanted_fields & MAIL_FETCH_STREAM_HEADER) != 0)
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina data->access_part |= READ_HDR;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if ((mail->wanted_fields & MAIL_FETCH_STREAM_BODY) != 0)
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina data->access_part |= READ_BODY;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina /* open the stream only if we didn't get here from
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mailbox_save_init() */
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina hdr = mail_index_get_header(_mail->box->view);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if (_mail->uid != 0 && _mail->uid < hdr->next_uid)
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina (void)mail_get_stream(_mail, NULL, NULL, &input);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina}
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březinabool index_mail_set_uid(struct mail *_mail, uint32_t uid)
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek{
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina struct index_mail *mail = (struct index_mail *)_mail;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina uint32_t seq;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
788146c3e3a564f333f39a2fcffccf3012cc2679Jakub Hrozek if (mail_index_lookup_seq(_mail->box->view, uid, &seq)) {
788146c3e3a564f333f39a2fcffccf3012cc2679Jakub Hrozek index_mail_set_seq(_mail, seq);
788146c3e3a564f333f39a2fcffccf3012cc2679Jakub Hrozek return TRUE;
788146c3e3a564f333f39a2fcffccf3012cc2679Jakub Hrozek } else {
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina index_mail_reset(mail);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail->mail.mail.uid = uid;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail_set_expunged(&mail->mail.mail);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina return FALSE;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina}
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březinavoid index_mail_set_uid_cache_updates(struct mail *_mail, bool set)
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina{
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina struct index_mail *mail = (struct index_mail *)_mail;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina mail->data.no_caching = set || mail->data.forced_no_caching;
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina}
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březinavoid index_mail_free(struct mail *_mail)
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina{
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina struct index_mail *mail = (struct index_mail *)_mail;
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina struct mailbox_header_lookup_ctx *headers_ctx =
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina (struct mailbox_header_lookup_ctx *)mail->wanted_headers;
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina mail->mail.v.close(_mail);
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina i_assert(mail->trans->mail_ref_count > 0);
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina mail->trans->mail_ref_count--;
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina if (mail->header_data != NULL)
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina buffer_free(&mail->header_data);
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina if (array_is_created(&mail->header_lines))
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina array_free(&mail->header_lines);
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina if (array_is_created(&mail->header_match))
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina array_free(&mail->header_match);
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina if (array_is_created(&mail->header_match_lines))
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina array_free(&mail->header_match_lines);
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina if (headers_ctx != NULL)
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina mailbox_header_lookup_unref(&headers_ctx);
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina pool_unref(&mail->data_pool);
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina pool_unref(&mail->mail.pool);
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina}
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březinavoid index_mail_cache_parse_continue(struct mail *_mail)
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina{
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina struct index_mail *mail = (struct index_mail *)_mail;
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina struct message_block block;
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina while (message_parser_parse_next_block(mail->data.parser_ctx,
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina &block) > 0) {
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina if (block.size != 0)
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina continue;
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina if (!mail->data.header_parsed) {
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina index_mail_parse_header(block.part, block.hdr, mail);
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina if (block.hdr == NULL)
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina mail->data.header_parsed = TRUE;
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina } else {
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina imap_bodystructure_parse_header(mail->data_pool,
37d2194cc9ea4d0254c88a3419e2376572562babPavel Březina block.part, block.hdr);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina}
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březinavoid index_mail_cache_parse_deinit(struct mail *_mail, time_t received_date,
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina bool success)
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek{
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek struct index_mail *mail = (struct index_mail *)_mail;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if (!success) {
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina /* we're going to delete this mail anyway,
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina don't bother trying to update cache file */
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail->data.no_caching = TRUE;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail->data.forced_no_caching = TRUE;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina /* This is needed with 0 byte mails to get hdr=NULL call done. */
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina index_mail_cache_parse_continue(_mail);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if (mail->data.received_date == (time_t)-1)
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail->data.received_date = received_date;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if (mail->data.save_date == (time_t)-1) {
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina /* this save_date may not be exactly the same as what we get
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina in future, but then again neither mbox nor maildir
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina guarantees it anyway. */
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail->data.save_date = ioloop_time;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail->data.save_bodystructure_body = FALSE;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail->data.parsed_bodystructure = TRUE;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina (void)index_mail_parse_body_finish(mail, 0);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina}
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březinastatic void index_mail_drop_recent_flag(struct mail *mail)
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina{
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina const struct mail_index_header *hdr;
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek uint32_t first_recent_uid = mail->uid + 1;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina hdr = mail_index_get_header(mail->transaction->view);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if (hdr->first_recent_uid < first_recent_uid) {
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail_index_update_header(mail->transaction->itrans,
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina offsetof(struct mail_index_header, first_recent_uid),
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina &first_recent_uid, sizeof(first_recent_uid), FALSE);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina}
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březinavoid index_mail_update_flags(struct mail *mail, enum modify_type modify_type,
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek enum mail_flags flags)
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek{
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek if ((flags & MAIL_RECENT) == 0 &&
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek index_mailbox_is_recent(mail->box, mail->uid))
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek index_mail_drop_recent_flag(mail);
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek flags &= MAIL_FLAGS_NONRECENT | MAIL_INDEX_MAIL_FLAG_BACKEND;
0e238c259c066cf997aaa940d33d6bda96c15925Sumit Bose mail_index_update_flags(mail->transaction->itrans, mail->seq,
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek modify_type, flags);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina}
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březinavoid index_mail_update_keywords(struct mail *mail, enum modify_type modify_type,
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina struct mail_keywords *keywords)
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina{
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina struct index_mail *imail = (struct index_mail *)mail;
98195e591c4d97caa6125e8214879660b740973fSumit Bose
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if (array_is_created(&imail->data.keyword_indexes))
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina array_free(&imail->data.keyword_indexes);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if (array_is_created(&imail->data.keywords)) {
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina /* clear the keywords array so the next mail_get_keywords()
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina returns the updated keywords. don't free the array, because
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina then any existing mail_get_keywords() return values would
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina point to broken data. this won't leak memory because the
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina array is allocated from mail's memory pool. */
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek memset(&imail->data.keywords, 0,
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina sizeof(imail->data.keywords));
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail_index_update_keywords(mail->transaction->itrans, mail->seq,
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina modify_type, keywords);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina}
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březinavoid index_mail_update_modseq(struct mail *mail, uint64_t min_modseq)
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina{
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail_index_update_modseq(mail->transaction->itrans, mail->seq,
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina min_modseq);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina}
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březinavoid index_mail_update_uid(struct mail *mail, uint32_t new_uid)
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina{
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail_index_update_uid(mail->transaction->itrans, mail->seq, new_uid);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina}
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březinavoid index_mail_expunge(struct mail *mail)
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina{
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina const char *value;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina uint8_t guid_128[MAIL_GUID_128_SIZE];
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina if (mail_get_special(mail, MAIL_FETCH_GUID, &value) < 0)
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail_index_expunge(mail->transaction->itrans, mail->seq);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina else {
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail_generate_guid_128_hash(value, guid_128);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail_index_expunge_guid(mail->transaction->itrans,
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina mail->seq, guid_128);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina }
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina}
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březinavoid index_mail_set_cache_corrupted(struct mail *mail,
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina enum mail_fetch_field field)
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina{
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina struct index_mail *imail = (struct index_mail *)mail;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina const char *field_name;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina switch (field) {
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina case 0:
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina field_name = "fields";
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina break;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina case MAIL_FETCH_VIRTUAL_SIZE:
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina field_name = "virtual size";
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina imail->data.physical_size = (uoff_t)-1;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina imail->data.virtual_size = (uoff_t)-1;
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina imail->data.parts = NULL;
d3c82d0170d6d7407549afdadd08aa7e11aeb9a2Pavel Březina break;
d3c82d0170d6d7407549afdadd08aa7e11aeb9a2Pavel Březina case MAIL_FETCH_MESSAGE_PARTS:
d3c82d0170d6d7407549afdadd08aa7e11aeb9a2Pavel Březina field_name = "MIME parts";
d3c82d0170d6d7407549afdadd08aa7e11aeb9a2Pavel Březina imail->data.parts = NULL;
d3c82d0170d6d7407549afdadd08aa7e11aeb9a2Pavel Březina break;
d3c82d0170d6d7407549afdadd08aa7e11aeb9a2Pavel Březina case MAIL_FETCH_IMAP_BODY:
d3c82d0170d6d7407549afdadd08aa7e11aeb9a2Pavel Březina field_name = "IMAP BODY";
d3c82d0170d6d7407549afdadd08aa7e11aeb9a2Pavel Březina imail->data.body = NULL;
d3c82d0170d6d7407549afdadd08aa7e11aeb9a2Pavel Březina imail->data.bodystructure = NULL;
d3c82d0170d6d7407549afdadd08aa7e11aeb9a2Pavel Březina break;
d3c82d0170d6d7407549afdadd08aa7e11aeb9a2Pavel Březina case MAIL_FETCH_IMAP_BODYSTRUCTURE:
d3c82d0170d6d7407549afdadd08aa7e11aeb9a2Pavel Březina field_name = "IMAP BODYSTRUCTURE";
d3c82d0170d6d7407549afdadd08aa7e11aeb9a2Pavel Březina imail->data.body = NULL;
d3c82d0170d6d7407549afdadd08aa7e11aeb9a2Pavel Březina imail->data.bodystructure = NULL;
d3c82d0170d6d7407549afdadd08aa7e11aeb9a2Pavel Březina break;
d3c82d0170d6d7407549afdadd08aa7e11aeb9a2Pavel Březina default:
d3c82d0170d6d7407549afdadd08aa7e11aeb9a2Pavel Březina field_name = t_strdup_printf("#%x", field);
d3c82d0170d6d7407549afdadd08aa7e11aeb9a2Pavel Březina }
d3c82d0170d6d7407549afdadd08aa7e11aeb9a2Pavel Březina
d3c82d0170d6d7407549afdadd08aa7e11aeb9a2Pavel Březina /* make sure we don't cache invalid values */
d3c82d0170d6d7407549afdadd08aa7e11aeb9a2Pavel Březina mail_cache_transaction_reset(imail->trans->cache_trans);
d3c82d0170d6d7407549afdadd08aa7e11aeb9a2Pavel Březina imail->data.no_caching = TRUE;
35f0f5ff9dac790f6c947190fcdc00d01ae9077cJakub Hrozek imail->data.forced_no_caching = TRUE;
d3c82d0170d6d7407549afdadd08aa7e11aeb9a2Pavel Březina mail_cache_set_corrupted(mail->box->cache,
d3c82d0170d6d7407549afdadd08aa7e11aeb9a2Pavel Březina "Broken %s for mail UID %u",
d3c82d0170d6d7407549afdadd08aa7e11aeb9a2Pavel Březina field_name, mail->uid);
d3c82d0170d6d7407549afdadd08aa7e11aeb9a2Pavel Březina}
d3c82d0170d6d7407549afdadd08aa7e11aeb9a2Pavel Březina