bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2007-2018 Dovecot authors, see the included COPYING file */
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen#include "lib.h"
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen#include "istream.h"
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen#include "index-mail.h"
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen#include "raw-storage.h"
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen#include <fcntl.h>
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen#include <unistd.h>
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen#include <sys/stat.h>
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainenstatic int raw_mail_stat(struct mail *mail)
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen{
8af1a286fb27446eeb0e7a8764cd3ed8d35ff2acJosef 'Jeff' Sipek struct raw_mailbox *mbox = RAW_MAILBOX(mail->box);
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen const struct stat *st;
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen if (mail->lookup_abort == MAIL_LOOKUP_ABORT_NOT_IN_CACHE) {
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen mail_set_aborted(mail);
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen return -1;
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen }
7204b8112e005ff81dcf628f7880ef1feed1effeTimo Sirainen mail->mail_metadata_accessed = TRUE;
ebe6df72f1309135f02b6a4d2aef1e81a073f91cTimo Sirainen
2d01cc1880cf2afd4fb1c8ad7fa6ce78e562e71eTimo Sirainen mail->transaction->stats.fstat_lookup_count++;
01f4ee4a0243f3fe9af763e1a540cd5cff0d63f5Timo Sirainen if (i_stream_stat(mail->box->input, TRUE, &st) < 0) {
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi mail_set_critical(mail, "stat(%s) failed: %m",
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi i_stream_get_name(mail->box->input));
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen return -1;
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen }
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen
8ff3b9b8e5d9263bbaeb7bd4b7df9c54c6dd35a2Timo Sirainen if (mbox->mtime != (time_t)-1)
8ff3b9b8e5d9263bbaeb7bd4b7df9c54c6dd35a2Timo Sirainen mbox->mtime = st->st_mtime;
8ff3b9b8e5d9263bbaeb7bd4b7df9c54c6dd35a2Timo Sirainen if (mbox->ctime != (time_t)-1)
8ff3b9b8e5d9263bbaeb7bd4b7df9c54c6dd35a2Timo Sirainen mbox->ctime = st->st_ctime;
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen mbox->size = st->st_size;
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen return 0;
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen}
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainenstatic int raw_mail_get_received_date(struct mail *_mail, time_t *date_r)
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen{
87490012895b4f371635ded00add04c9107dcfefJosef 'Jeff' Sipek struct index_mail *mail = INDEX_MAIL(_mail);
8af1a286fb27446eeb0e7a8764cd3ed8d35ff2acJosef 'Jeff' Sipek struct raw_mailbox *mbox = RAW_MAILBOX(_mail->box);
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen if (mbox->mtime == (time_t)-1) {
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen if (raw_mail_stat(_mail) < 0)
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen return -1;
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen }
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen *date_r = mail->data.received_date = mbox->mtime;
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen return 0;
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen}
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainenstatic int raw_mail_get_save_date(struct mail *_mail, time_t *date_r)
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen{
87490012895b4f371635ded00add04c9107dcfefJosef 'Jeff' Sipek struct index_mail *mail = INDEX_MAIL(_mail);
8af1a286fb27446eeb0e7a8764cd3ed8d35ff2acJosef 'Jeff' Sipek struct raw_mailbox *mbox = RAW_MAILBOX(_mail->box);
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen if (mbox->ctime == (time_t)-1) {
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen if (raw_mail_stat(_mail) < 0)
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen return -1;
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen }
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen *date_r = mail->data.save_date = mbox->ctime;
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen return 0;
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen}
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainenstatic int raw_mail_get_physical_size(struct mail *_mail, uoff_t *size_r)
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen{
87490012895b4f371635ded00add04c9107dcfefJosef 'Jeff' Sipek struct index_mail *mail = INDEX_MAIL(_mail);
8af1a286fb27446eeb0e7a8764cd3ed8d35ff2acJosef 'Jeff' Sipek struct raw_mailbox *mbox = RAW_MAILBOX(_mail->box);
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen if (mbox->size == (uoff_t)-1) {
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen if (raw_mail_stat(_mail) < 0)
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen return -1;
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen }
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen *size_r = mail->data.physical_size = mbox->size;
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen return 0;
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen}
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainenstatic int
6df0ab0c1ab91f06b6418cb30eff44405a1b8f02Timo Sirainenraw_mail_get_stream(struct mail *_mail, bool get_body ATTR_UNUSED,
6df0ab0c1ab91f06b6418cb30eff44405a1b8f02Timo Sirainen struct message_size *hdr_size,
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen struct message_size *body_size, struct istream **stream_r)
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen{
87490012895b4f371635ded00add04c9107dcfefJosef 'Jeff' Sipek struct index_mail *mail = INDEX_MAIL(_mail);
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen if (mail->data.stream == NULL) {
ba7feb1cccc99ce1e8a03d35ca024192ea9233b1Timo Sirainen /* we can't just reference mbox->input, because
ba7feb1cccc99ce1e8a03d35ca024192ea9233b1Timo Sirainen index_mail_close() expects to be able to free the stream */
ba7feb1cccc99ce1e8a03d35ca024192ea9233b1Timo Sirainen mail->data.stream =
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen i_stream_create_limit(_mail->box->input, (uoff_t)-1);
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen }
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen return index_mail_init_stream(mail, hdr_size, body_size, stream_r);
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen}
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen
8fa302c0c0f110aecf266d20673aae567bd77f3bTimo Sirainenstatic int
8fa302c0c0f110aecf266d20673aae567bd77f3bTimo Sirainenraw_mail_get_special(struct mail *_mail, enum mail_fetch_field field,
8fa302c0c0f110aecf266d20673aae567bd77f3bTimo Sirainen const char **value_r)
8fa302c0c0f110aecf266d20673aae567bd77f3bTimo Sirainen{
8af1a286fb27446eeb0e7a8764cd3ed8d35ff2acJosef 'Jeff' Sipek struct raw_mailbox *mbox = RAW_MAILBOX(_mail->box);
8fa302c0c0f110aecf266d20673aae567bd77f3bTimo Sirainen
8fa302c0c0f110aecf266d20673aae567bd77f3bTimo Sirainen switch (field) {
8fa302c0c0f110aecf266d20673aae567bd77f3bTimo Sirainen case MAIL_FETCH_FROM_ENVELOPE:
b512e566e8c899484bf42419b6153a66815ad146Timo Sirainen *value_r = mbox->envelope_sender != NULL ?
b512e566e8c899484bf42419b6153a66815ad146Timo Sirainen mbox->envelope_sender : "";
8fa302c0c0f110aecf266d20673aae567bd77f3bTimo Sirainen return 0;
5eb85ec9546bac4eea7d78de8997920ba3debd30Timo Sirainen case MAIL_FETCH_STORAGE_ID:
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen *value_r = mbox->have_filename ?
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen mailbox_get_path(_mail->box) : "";
80cc932b7d4fd914ed6ccb68e988e9002118d5deTimo Sirainen return 0;
8fa302c0c0f110aecf266d20673aae567bd77f3bTimo Sirainen default:
8fa302c0c0f110aecf266d20673aae567bd77f3bTimo Sirainen return index_mail_get_special(_mail, field, value_r);
8fa302c0c0f110aecf266d20673aae567bd77f3bTimo Sirainen }
8fa302c0c0f110aecf266d20673aae567bd77f3bTimo Sirainen}
8fa302c0c0f110aecf266d20673aae567bd77f3bTimo Sirainen
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainenstruct mail_vfuncs raw_mail_vfuncs = {
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen index_mail_close,
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen index_mail_free,
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen index_mail_set_seq,
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen index_mail_set_uid,
aa247243412a49f9bdebf7255e131dc6ece4ed46Timo Sirainen index_mail_set_uid_cache_updates,
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen index_mail_prefetch,
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen index_mail_precache,
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainen index_mail_add_temp_wanted_fields,
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen index_mail_get_flags,
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen index_mail_get_keywords,
a757f31393b9d6fc7760a9dec8363404ab3ae576Timo Sirainen index_mail_get_keyword_indexes,
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen index_mail_get_modseq,
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen index_mail_get_pvt_modseq,
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen index_mail_get_parts,
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen index_mail_get_date,
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen raw_mail_get_received_date,
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen raw_mail_get_save_date,
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen index_mail_get_virtual_size,
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen raw_mail_get_physical_size,
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen index_mail_get_first_header,
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen index_mail_get_headers,
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen index_mail_get_header_stream,
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen raw_mail_get_stream,
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen index_mail_get_binary_stream,
8fa302c0c0f110aecf266d20673aae567bd77f3bTimo Sirainen raw_mail_get_special,
21aaa6affb9f134112b75b5db737309fc35ef1cfMartti Rannanjärvi index_mail_get_backend_mail,
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen index_mail_update_flags,
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen index_mail_update_keywords,
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen index_mail_update_modseq,
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen index_mail_update_pvt_modseq,
225e82df5dd1e765f4e52b80c954558f00e5a7dfTimo Sirainen NULL,
838e367716bbd5e44b4a1691db9cbf72af53e9f0Timo Sirainen index_mail_expunge,
6564208826b0f46a00f010d1b5711d85944c3c88Timo Sirainen index_mail_set_cache_corrupted,
6de6ec228a41275ddda972d4a554699ea75cd06dTimo Sirainen index_mail_opened,
4146f38412c650f4d0e100cf22d7b32e7d24b2b6Timo Sirainen};