maildir-mail.c revision 677e22747b82bf15b339e31d1d0106d62bf806da
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Copyright (C) 2003 Timo Sirainen */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "lib.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "istream.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "index-mail.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "maildir-storage.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "maildir-uidlist.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include <fcntl.h>
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include <unistd.h>
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include <sys/stat.h>
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainenstatic int
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainendo_open(struct maildir_mailbox *mbox, const char *path, void *context)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int *fd = context;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *fd = open(path, O_RDONLY);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (*fd != -1)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (errno == ENOENT)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8153fdec343e40e2a78f5c12353e89b994b28f74Timo Sirainen mail_storage_set_critical(STORAGE(mbox->storage),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "open(%s) failed: %m", path);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainenstatic int
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainendo_stat(struct maildir_mailbox *mbox, const char *path, void *context)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct stat *st = context;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (stat(path, st) == 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (errno == ENOENT)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8153fdec343e40e2a78f5c12353e89b994b28f74Timo Sirainen mail_storage_set_critical(STORAGE(mbox->storage),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "stat(%s) failed: %m", path);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic struct istream *
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainenmaildir_open_mail(struct maildir_mailbox *mbox, struct mail *mail,
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen bool *deleted_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen const char *path;
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen int fd = -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen *deleted_r = FALSE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen if (mail->uid != 0) {
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen if (maildir_file_do(mbox, mail->uid, do_open, &fd) < 0)
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen return NULL;
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen } else {
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen path = maildir_save_file_get_path(mail->transaction, mail->seq);
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen if (do_open(mbox, path, &fd) <= 0)
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen return NULL;
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (fd == -1) {
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen *deleted_r = TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return NULL;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen if (mbox->ibox.mail_read_mmaped) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return i_stream_create_mmap(fd, default_pool,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MAIL_MMAP_BLOCK_SIZE, 0, 0, TRUE);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen } else {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return i_stream_create_file(fd, default_pool,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MAIL_READ_BLOCK_SIZE, TRUE);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic time_t maildir_mail_get_received_date(struct mail *_mail)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen struct maildir_mailbox *mbox = (struct maildir_mailbox *)mail->ibox;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct index_mail_data *data = &mail->data;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct stat st;
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen const char *path;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int fd;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen (void)index_mail_get_received_date(_mail);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (data->received_date != (time_t)-1)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return data->received_date;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
55773f17bccf6361d6599ffcbe072d7c9fe205bfTimo Sirainen if (data->access_part != 0 && data->stream == NULL) {
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainen /* we're going to open the mail anyway */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen (void)mail_get_stream(_mail, NULL, NULL);
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainen }
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (data->stream != NULL) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen fd = i_stream_get_fd(data->stream);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(fd != -1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (fstat(fd, &st) < 0) {
8153fdec343e40e2a78f5c12353e89b994b28f74Timo Sirainen mail_storage_set_critical(STORAGE(mbox->storage),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "fstat(maildir) failed: %m");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return (time_t)-1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen } else if (_mail->uid != 0) {
d9e5b8e97506db35c357684eec08306c8464a55aTimo Sirainen if (maildir_file_do(mbox, _mail->uid, do_stat, &st) <= 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return (time_t)-1;
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen } else {
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen path = maildir_save_file_get_path(_mail->transaction,
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen _mail->seq);
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen if (do_stat(mbox, path, &st) <= 0)
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen return (time_t)-1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen data->received_date = st.st_mtime;
97511ac4d7607e1ba64ce151eda3d9b5f9775519Timo Sirainen index_mail_cache_add(mail, MAIL_CACHE_RECEIVED_DATE,
97511ac4d7607e1ba64ce151eda3d9b5f9775519Timo Sirainen &data->received_date, sizeof(data->received_date));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return data->received_date;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainenstatic uoff_t maildir_mail_get_virtual_size(struct mail *_mail)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen struct maildir_mailbox *mbox = (struct maildir_mailbox *)mail->ibox;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct index_mail_data *data = &mail->data;
677e22747b82bf15b339e31d1d0106d62bf806daTimo Sirainen const char *fname;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uoff_t virtual_size;
641f0c0900ee6e7cf9667f4b40ed95cec7d0cdcaTimo Sirainen enum maildir_uidlist_rec_flag flags;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen if (data->virtual_size != (uoff_t)-1)
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen return data->virtual_size;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen if ((mail->wanted_fields & MAIL_FETCH_VIRTUAL_SIZE) == 0) {
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen data->virtual_size = index_mail_get_cached_virtual_size(mail);
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen if (data->virtual_size != (uoff_t)-1)
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen return data->virtual_size;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen if (_mail->uid != 0) {
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen fname = maildir_uidlist_lookup(mbox->uidlist, _mail->uid,
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen &flags);
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen if (fname == NULL)
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen return (uoff_t)-1;
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen } else {
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen fname = maildir_save_file_get_path(_mail->transaction,
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen _mail->seq);
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* size can be included in filename */
677e22747b82bf15b339e31d1d0106d62bf806daTimo Sirainen if (maildir_filename_get_size(fname, MAILDIR_EXTRA_VIRTUAL_SIZE,
677e22747b82bf15b339e31d1d0106d62bf806daTimo Sirainen &virtual_size)) {
677e22747b82bf15b339e31d1d0106d62bf806daTimo Sirainen index_mail_cache_add(mail, MAIL_CACHE_VIRTUAL_FULL_SIZE,
677e22747b82bf15b339e31d1d0106d62bf806daTimo Sirainen &virtual_size, sizeof(virtual_size));
677e22747b82bf15b339e31d1d0106d62bf806daTimo Sirainen return virtual_size;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen return index_mail_get_virtual_size(_mail);
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen}
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen
366d6311c9d5bac6613e3cd64619eb878adce9ecTimo Sirainenstatic const char *
366d6311c9d5bac6613e3cd64619eb878adce9ecTimo Sirainenmaildir_mail_get_special(struct mail *_mail, enum mail_fetch_field field)
366d6311c9d5bac6613e3cd64619eb878adce9ecTimo Sirainen{
366d6311c9d5bac6613e3cd64619eb878adce9ecTimo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen struct maildir_mailbox *mbox = (struct maildir_mailbox *)mail->ibox;
366d6311c9d5bac6613e3cd64619eb878adce9ecTimo Sirainen enum maildir_uidlist_rec_flag flags;
366d6311c9d5bac6613e3cd64619eb878adce9ecTimo Sirainen const char *fname, *end;
366d6311c9d5bac6613e3cd64619eb878adce9ecTimo Sirainen
366d6311c9d5bac6613e3cd64619eb878adce9ecTimo Sirainen if (field == MAIL_FETCH_UIDL_FILE_NAME) {
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen if (_mail->uid != 0) {
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen fname = maildir_uidlist_lookup(mbox->uidlist,
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen _mail->uid, &flags);
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen } else {
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen fname = maildir_save_file_get_path(_mail->transaction,
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen _mail->seq);
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen }
8754bb7a1f24705ffa5434f9e10d57e0b3b88d6eTimo Sirainen end = strchr(fname, MAILDIR_INFO_SEP);
366d6311c9d5bac6613e3cd64619eb878adce9ecTimo Sirainen return end == NULL ? fname : t_strdup_until(fname, end);
366d6311c9d5bac6613e3cd64619eb878adce9ecTimo Sirainen }
366d6311c9d5bac6613e3cd64619eb878adce9ecTimo Sirainen
366d6311c9d5bac6613e3cd64619eb878adce9ecTimo Sirainen return index_mail_get_special(_mail, field);
366d6311c9d5bac6613e3cd64619eb878adce9ecTimo Sirainen}
366d6311c9d5bac6613e3cd64619eb878adce9ecTimo Sirainen
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainenstatic uoff_t maildir_mail_get_physical_size(struct mail *_mail)
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen{
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen struct maildir_mailbox *mbox = (struct maildir_mailbox *)mail->ibox;
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen struct index_mail_data *data = &mail->data;
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen struct stat st;
677e22747b82bf15b339e31d1d0106d62bf806daTimo Sirainen const char *fname;
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen uoff_t size;
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen enum maildir_uidlist_rec_flag flags;
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen size = index_mail_get_physical_size(_mail);
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen if (size != (uoff_t)-1)
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen return size;
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen if (_mail->uid != 0) {
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen fname = maildir_uidlist_lookup(mbox->uidlist, _mail->uid,
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen &flags);
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen if (fname == NULL)
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen return (uoff_t)-1;
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen } else {
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen fname = maildir_save_file_get_path(_mail->transaction,
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen _mail->seq);
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen }
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen /* size can be included in filename */
677e22747b82bf15b339e31d1d0106d62bf806daTimo Sirainen if (!maildir_filename_get_size(fname, MAILDIR_EXTRA_FILE_SIZE, &size)) {
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen if (_mail->uid != 0) {
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen if (maildir_file_do(mbox, _mail->uid,
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen do_stat, &st) <= 0)
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen return (uoff_t)-1;
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen } else {
677e22747b82bf15b339e31d1d0106d62bf806daTimo Sirainen /* saved mail which hasn't been committed yet */
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen if (do_stat(mbox, fname, &st) <= 0)
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen return (uoff_t)-1;
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen }
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen size = st.st_size;
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen }
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen
97511ac4d7607e1ba64ce151eda3d9b5f9775519Timo Sirainen index_mail_cache_add(mail, MAIL_CACHE_PHYSICAL_FULL_SIZE,
97511ac4d7607e1ba64ce151eda3d9b5f9775519Timo Sirainen &size, sizeof(size));
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen data->physical_size = size;
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen return size;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic struct istream *maildir_mail_get_stream(struct mail *_mail,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct message_size *hdr_size,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct message_size *body_size)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen struct maildir_mailbox *mbox = (struct maildir_mailbox *)mail->ibox;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct index_mail_data *data = &mail->data;
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen bool deleted;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (data->stream == NULL) {
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen data->stream = maildir_open_mail(mbox, _mail, &deleted);
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainen if (data->stream == NULL) {
b093b87c303d420bd14aeb53498f881ef2944aa0Timo Sirainen _mail->expunged = deleted;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return NULL;
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return index_mail_init_stream(mail, hdr_size, body_size);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenstruct mail_vfuncs maildir_mail_vfuncs = {
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen index_mail_free,
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen index_mail_set_seq,
a12399903f415a7e14c2816cffa2f7a09dcbb097Timo Sirainen index_mail_set_uid,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
439980f88f421039dea8335e92d3fa82b3f470a1Timo Sirainen index_mail_get_flags,
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen index_mail_get_keywords,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen index_mail_get_parts,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen maildir_mail_get_received_date,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen index_mail_get_date,
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen maildir_mail_get_virtual_size,
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen maildir_mail_get_physical_size,
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen index_mail_get_first_header,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen index_mail_get_headers,
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen index_mail_get_header_stream,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen maildir_mail_get_stream,
366d6311c9d5bac6613e3cd64619eb878adce9ecTimo Sirainen maildir_mail_get_special,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen index_mail_update_flags,
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen index_mail_update_keywords,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen index_mail_expunge
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};