bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2007-2018 Dovecot authors, see the included COPYING file */
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#include "lib.h"
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#include "istream.h"
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#include "index-mail.h"
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#include "cydir-storage.h"
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#include <fcntl.h>
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#include <unistd.h>
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#include <sys/stat.h>
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainenstatic const char *cydir_mail_get_path(struct mail *mail)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen{
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen const char *dir;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
feaa6a3d82ea61496ced1f83a726ff33047c7da2Timo Sirainen dir = mailbox_get_path(mail->box);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen return t_strdup_printf("%s/%u.", dir, mail->uid);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen}
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainenstatic int cydir_mail_stat(struct mail *mail, struct stat *st_r)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen{
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen const char *path;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
35283613d4c04ce18836e9fc431582c87b3710a0Timo Sirainen if (mail->lookup_abort == MAIL_LOOKUP_ABORT_NOT_IN_CACHE) {
35283613d4c04ce18836e9fc431582c87b3710a0Timo Sirainen mail_set_aborted(mail);
35283613d4c04ce18836e9fc431582c87b3710a0Timo Sirainen return -1;
35283613d4c04ce18836e9fc431582c87b3710a0Timo Sirainen }
7204b8112e005ff81dcf628f7880ef1feed1effeTimo Sirainen mail->mail_metadata_accessed = TRUE;
ebe6df72f1309135f02b6a4d2aef1e81a073f91cTimo Sirainen
2d01cc1880cf2afd4fb1c8ad7fa6ce78e562e71eTimo Sirainen mail->transaction->stats.stat_lookup_count++;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen path = cydir_mail_get_path(mail);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen if (stat(path, st_r) < 0) {
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen if (errno == ENOENT)
910fa4e4204a73d3d24c03f3059dd24e727ca057Timo Sirainen mail_set_expunged(mail);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen else {
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi mail_set_critical(mail, "stat(%s) failed: %m", path);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen }
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen return -1;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen }
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen return 0;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen}
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenstatic int cydir_mail_get_received_date(struct mail *_mail, time_t *date_r)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen{
87490012895b4f371635ded00add04c9107dcfefJosef 'Jeff' Sipek struct index_mail *mail = INDEX_MAIL(_mail);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct index_mail_data *data = &mail->data;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct stat st;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen if (index_mail_get_received_date(_mail, date_r) == 0)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return 0;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen if (cydir_mail_stat(_mail, &st) < 0)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return -1;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen data->received_date = st.st_mtime;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen *date_r = data->received_date;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return 0;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen}
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenstatic int cydir_mail_get_save_date(struct mail *_mail, time_t *date_r)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen{
87490012895b4f371635ded00add04c9107dcfefJosef 'Jeff' Sipek struct index_mail *mail = INDEX_MAIL(_mail);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct index_mail_data *data = &mail->data;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct stat st;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen if (index_mail_get_save_date(_mail, date_r) == 0)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return 0;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen if (cydir_mail_stat(_mail, &st) < 0)
97ee61d723f99fa20fc9c95cfe17b3816c613ff5Timo Sirainen return -1;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen data->save_date = st.st_ctime;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen *date_r = data->save_date;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return 0;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen}
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenstatic int cydir_mail_get_physical_size(struct mail *_mail, uoff_t *size_r)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen{
87490012895b4f371635ded00add04c9107dcfefJosef 'Jeff' Sipek struct index_mail *mail = INDEX_MAIL(_mail);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct index_mail_data *data = &mail->data;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct stat st;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen if (index_mail_get_physical_size(_mail, size_r) == 0)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return 0;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen if (cydir_mail_stat(_mail, &st) < 0)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return -1;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
75f3dddc3a5922c92a1bdb921b653ead51227cabTimo Sirainen data->physical_size = data->virtual_size = st.st_size;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen *size_r = data->physical_size;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return 0;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen}
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenstatic int
6df0ab0c1ab91f06b6418cb30eff44405a1b8f02Timo Sirainencydir_mail_get_stream(struct mail *_mail, bool get_body ATTR_UNUSED,
6df0ab0c1ab91f06b6418cb30eff44405a1b8f02Timo Sirainen struct message_size *hdr_size,
6df0ab0c1ab91f06b6418cb30eff44405a1b8f02Timo Sirainen struct message_size *body_size,
6df0ab0c1ab91f06b6418cb30eff44405a1b8f02Timo Sirainen struct istream **stream_r)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen{
87490012895b4f371635ded00add04c9107dcfefJosef 'Jeff' Sipek struct index_mail *mail = INDEX_MAIL(_mail);
a4d796994ba01c207f1d3e373f58f06c6779af53Timo Sirainen struct istream *input;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen const char *path;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen int fd;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen if (mail->data.stream == NULL) {
2d01cc1880cf2afd4fb1c8ad7fa6ce78e562e71eTimo Sirainen _mail->transaction->stats.open_lookup_count++;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen path = cydir_mail_get_path(_mail);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen fd = open(path, O_RDONLY);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen if (fd == -1) {
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen if (errno == ENOENT)
910fa4e4204a73d3d24c03f3059dd24e727ca057Timo Sirainen mail_set_expunged(_mail);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen else {
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi mail_set_critical(_mail, "open(%s) failed: %m",
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi path);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen }
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return -1;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen }
bace943c67e6cd14ce6c994f533d82a3caad5bf1Timo Sirainen input = i_stream_create_fd_autoclose(&fd, 0);
a4d796994ba01c207f1d3e373f58f06c6779af53Timo Sirainen i_stream_set_name(input, path);
a4d796994ba01c207f1d3e373f58f06c6779af53Timo Sirainen index_mail_set_read_buffer_size(_mail, input);
6564208826b0f46a00f010d1b5711d85944c3c88Timo Sirainen if (mail->mail.v.istream_opened != NULL) {
a4d796994ba01c207f1d3e373f58f06c6779af53Timo Sirainen if (mail->mail.v.istream_opened(_mail, &input) < 0) {
a4d796994ba01c207f1d3e373f58f06c6779af53Timo Sirainen i_stream_unref(&input);
6564208826b0f46a00f010d1b5711d85944c3c88Timo Sirainen return -1;
a4d796994ba01c207f1d3e373f58f06c6779af53Timo Sirainen }
6564208826b0f46a00f010d1b5711d85944c3c88Timo Sirainen }
a4d796994ba01c207f1d3e373f58f06c6779af53Timo Sirainen mail->data.stream = input;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen }
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return index_mail_init_stream(mail, hdr_size, body_size, stream_r);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen}
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainenstruct mail_vfuncs cydir_mail_vfuncs = {
0d86aa0d47f7393c669c084b34c0537b193688adTimo Sirainen index_mail_close,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_mail_free,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_mail_set_seq,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo 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,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_mail_get_flags,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo 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,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_mail_get_parts,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_mail_get_date,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen cydir_mail_get_received_date,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen cydir_mail_get_save_date,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen cydir_mail_get_physical_size, /* physical = virtual in our case */
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen cydir_mail_get_physical_size,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_mail_get_first_header,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_mail_get_headers,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_mail_get_header_stream,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen cydir_mail_get_stream,
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen index_mail_get_binary_stream,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_mail_get_special,
21aaa6affb9f134112b75b5db737309fc35ef1cfMartti Rannanjärvi index_mail_get_backend_mail,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_mail_update_flags,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo 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,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen};