bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2007-2018 Dovecot authors, see the included COPYING file */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainendbox_mail_alloc(struct mailbox_transaction_context *t,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct mailbox_header_lookup_ctx *wanted_headers)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_mail_init(&mail->imail, t, wanted_fields, wanted_headers);
804fa3f03bd9170272168a5ad214053bbe3160c7Josef 'Jeff' Sipek struct dbox_mail *mail = DBOX_MAIL(_mail);
010affb9f4b9cca9b94e1d8d570cf179daff08d7Timo Sirainen /* close the dbox file only after index is closed, since it may still
010affb9f4b9cca9b94e1d8d570cf179daff08d7Timo Sirainen try to read from it. */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenint dbox_mail_metadata_read(struct dbox_mail *mail, struct dbox_file **file_r)
804fa3f03bd9170272168a5ad214053bbe3160c7Josef 'Jeff' Sipek DBOX_STORAGE(mail->imail.mail.mail.box->storage);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (storage->v.mail_open(mail, &offset, file_r) < 0)
b58aafbd21b365117538f73f306d22f75acd91f1Timo Sirainen /* we just messed up mail's input stream by reading metadata */
b58aafbd21b365117538f73f306d22f75acd91f1Timo Sirainendbox_mail_metadata_get(struct dbox_mail *mail, enum dbox_metadata_key key,
b58aafbd21b365117538f73f306d22f75acd91f1Timo Sirainen const char **value_r)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenint dbox_mail_get_physical_size(struct mail *_mail, uoff_t *size_r)
804fa3f03bd9170272168a5ad214053bbe3160c7Josef 'Jeff' Sipek struct dbox_mail *mail = DBOX_MAIL(_mail);
b58aafbd21b365117538f73f306d22f75acd91f1Timo Sirainen struct index_mail_data *data = &mail->imail.data;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (index_mail_get_physical_size(_mail, size_r) == 0)
427ad9fea54628d52f04c8a76269749a8e6fae7aTimo Sirainen data->physical_size = dbox_file_get_plaintext_size(file);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenint dbox_mail_get_virtual_size(struct mail *_mail, uoff_t *size_r)
804fa3f03bd9170272168a5ad214053bbe3160c7Josef 'Jeff' Sipek struct dbox_mail *mail = DBOX_MAIL(_mail);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct index_mail_data *data = &mail->imail.data;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (index_mail_get_cached_virtual_size(&mail->imail, size_r))
b58aafbd21b365117538f73f306d22f75acd91f1Timo Sirainen if (dbox_mail_metadata_get(mail, DBOX_METADATA_VIRTUAL_SIZE,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return index_mail_get_virtual_size(_mail, size_r);
e48f289d2e5b2546a2c5dcc90f7ab624cc58cca2Stephan Bosch if (str_to_uintmax_hex(value, &size) < 0 || size > (uoff_t)-1)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenint dbox_mail_get_received_date(struct mail *_mail, time_t *date_r)
804fa3f03bd9170272168a5ad214053bbe3160c7Josef 'Jeff' Sipek struct dbox_mail *mail = DBOX_MAIL(_mail);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct index_mail_data *data = &mail->imail.data;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (index_mail_get_received_date(_mail, date_r) == 0)
b58aafbd21b365117538f73f306d22f75acd91f1Timo Sirainen if (dbox_mail_metadata_get(mail, DBOX_METADATA_RECEIVED_TIME,
e48f289d2e5b2546a2c5dcc90f7ab624cc58cca2Stephan Bosch if (value != NULL && str_to_uintmax_hex(value, &time) < 0)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenint dbox_mail_get_save_date(struct mail *_mail, time_t *date_r)
804fa3f03bd9170272168a5ad214053bbe3160c7Josef 'Jeff' Sipek struct dbox_storage *storage = DBOX_STORAGE(_mail->box->storage);
804fa3f03bd9170272168a5ad214053bbe3160c7Josef 'Jeff' Sipek struct dbox_mail *mail = DBOX_MAIL(_mail);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct index_mail_data *data = &mail->imail.data;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (index_mail_get_save_date(_mail, date_r) == 0)
ea1f67e14d727496179ee4ff391f592bce8f4f2dTimo Sirainen if (storage->v.mail_open(mail, &offset, &file) < 0)
2d01cc1880cf2afd4fb1c8ad7fa6ce78e562e71eTimo Sirainen _mail->transaction->stats.fstat_lookup_count++;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainendbox_get_cached_metadata(struct dbox_mail *mail, enum dbox_metadata_key key,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen const char **value_r)
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen if (mail_cache_lookup_field(imail->mail.mail.transaction->cache_view,
baa93d5ed7c015309dc51aa238f8d0c79561121fTimo Sirainen /* order=0 means it doesn't exist. we don't
baa93d5ed7c015309dc51aa238f8d0c79561121fTimo Sirainen want to return "0" though, because then the
baa93d5ed7c015309dc51aa238f8d0c79561121fTimo Sirainen mails get ordered to beginning, while
baa93d5ed7c015309dc51aa238f8d0c79561121fTimo Sirainen nonexistent are supposed to be ordered at
b58aafbd21b365117538f73f306d22f75acd91f1Timo Sirainen if (dbox_mail_metadata_get(mail, key, &value) < 0)
147a788fea2a88f7125b27226451271d55cf5b01Timo Sirainen index_mail_cache_add_idx(imail, ibox->cache_fields[cache_field].idx,
147a788fea2a88f7125b27226451271d55cf5b01Timo Sirainen index_mail_cache_add_idx(imail, ibox->cache_fields[cache_field].idx,
0dc7a67fb62b2aac82ff1c03319bd4976c56dbc1Timo Sirainen /* don't return pointer to dbox metadata directly, since it may
0dc7a67fb62b2aac82ff1c03319bd4976c56dbc1Timo Sirainen change unexpectedly */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenint dbox_mail_get_special(struct mail *_mail, enum mail_fetch_field field,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen const char **value_r)
804fa3f03bd9170272168a5ad214053bbe3160c7Josef 'Jeff' Sipek struct dbox_mail *mail = DBOX_MAIL(_mail);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* keep the UIDL in cache file, otherwise POP3 would open all
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mail files and read the metadata. same for GUIDs if they're
2b9dbb270ad82e58d5f3581436e6f143176d5819Timo Sirainen ret = dbox_get_cached_metadata(mail, DBOX_METADATA_POP3_UIDL,
2b9dbb270ad82e58d5f3581436e6f143176d5819Timo Sirainen index_pop3_uidl_update_exists(&mail->imail.mail.mail,
2b9dbb270ad82e58d5f3581436e6f143176d5819Timo Sirainen /* we're assuming that if there's a POP3 order, there's
2b9dbb270ad82e58d5f3581436e6f143176d5819Timo Sirainen also a UIDL */
147a788fea2a88f7125b27226451271d55cf5b01Timo Sirainen return dbox_get_cached_metadata(mail, DBOX_METADATA_POP3_ORDER,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return dbox_get_cached_metadata(mail, DBOX_METADATA_GUID,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return index_mail_get_special(_mail, field, value_r);
6564208826b0f46a00f010d1b5711d85944c3c88Timo Sirainenget_mail_stream(struct dbox_mail *mail, uoff_t offset,
6564208826b0f46a00f010d1b5711d85944c3c88Timo Sirainen struct mail_private *pmail = &mail->imail.mail;
a4d796994ba01c207f1d3e373f58f06c6779af53Timo Sirainen if ((ret = dbox_file_seek(file, offset)) <= 0) {
6564208826b0f46a00f010d1b5711d85944c3c88Timo Sirainen *stream_r = i_stream_create_limit(file->input, file->cur_physical_size);
6564208826b0f46a00f010d1b5711d85944c3c88Timo Sirainen if (pmail->v.istream_opened(&pmail->mail, stream_r) < 0)
6564208826b0f46a00f010d1b5711d85944c3c88Timo Sirainen return dbox_attachment_file_get_stream(file, stream_r);
6df0ab0c1ab91f06b6418cb30eff44405a1b8f02Timo Sirainenint dbox_mail_get_stream(struct mail *_mail, bool get_body ATTR_UNUSED,
804fa3f03bd9170272168a5ad214053bbe3160c7Josef 'Jeff' Sipek struct dbox_storage *storage = DBOX_STORAGE(_mail->box->storage);
804fa3f03bd9170272168a5ad214053bbe3160c7Josef 'Jeff' Sipek struct dbox_mail *mail = DBOX_MAIL(_mail);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct index_mail_data *data = &mail->imail.data;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (storage->v.mail_open(mail, &offset, &mail->open_file) < 0)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen "uid=%u points to broken data at offset="
c853a862402035236200982bab5d6d25fce5162fTimo Sirainen index_mail_set_read_buffer_size(_mail, input);