maildir-mail.c revision ccc895c0358108d2304239063e940b7d75f364ab
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
2cfe9983ce7a6280636ee12beccc2e865111967bTimo Sirainendo_open(struct maildir_mailbox *mbox, const char *path, int *fd)
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
ccc895c0358108d2304239063e940b7d75f364abTimo Sirainen mail_storage_set_critical(&mbox->storage->storage,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "open(%s) failed: %m", path);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainenstatic int
2cfe9983ce7a6280636ee12beccc2e865111967bTimo Sirainendo_stat(struct maildir_mailbox *mbox, const char *path, struct stat *st)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (stat(path, st) == 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (errno == ENOENT)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
ccc895c0358108d2304239063e940b7d75f364abTimo Sirainen mail_storage_set_critical(&mbox->storage->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
8cab30d26412f21e814dba57814fa4b57b1d36e7Timo Sirainen return i_stream_create_file(fd, default_pool,
8cab30d26412f21e814dba57814fa4b57b1d36e7Timo Sirainen MAIL_READ_BLOCK_SIZE, TRUE);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainenstatic int maildir_mail_stat(struct mail *mail, struct stat *st)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen struct maildir_mailbox *mbox = (struct maildir_mailbox *)mail->box;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen struct index_mail_data *data = &((struct index_mail *)mail)->data;
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen const char *path;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int fd;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
55773f17bccf6361d6599ffcbe072d7c9fe205bfTimo Sirainen if (data->access_part != 0 && data->stream == NULL) {
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainen /* we're going to open the mail anyway */
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo 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
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen if (fstat(fd, st) < 0) {
ccc895c0358108d2304239063e940b7d75f364abTimo Sirainen mail_storage_set_critical(&mbox->storage->storage,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "fstat(maildir) failed: %m");
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen } else if (mail->uid != 0) {
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen if (maildir_file_do(mbox, mail->uid, do_stat, st) <= 0)
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen return -1;
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen } else {
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen path = maildir_save_file_get_path(mail->transaction, mail->seq);
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen if (do_stat(mbox, path, st) <= 0)
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen return 0;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen}
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainenstatic time_t maildir_mail_get_received_date(struct mail *_mail)
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen{
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen struct index_mail_data *data = &mail->data;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen struct stat st;
c11155a446dbdc9f6cd5b954f09073a9019e27b2Timo Sirainen uint32_t t;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen (void)index_mail_get_received_date(_mail);
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen if (data->received_date != (time_t)-1)
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen return data->received_date;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen if (maildir_mail_stat(_mail, &st) < 0)
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen return (time_t)-1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8000c86be02008b74acc71fa422444dc432e2c01Timo Sirainen data->received_date = t = st.st_mtime;
8000c86be02008b74acc71fa422444dc432e2c01Timo Sirainen index_mail_cache_add(mail, MAIL_CACHE_RECEIVED_DATE, &t, sizeof(t));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return data->received_date;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainenstatic time_t maildir_mail_get_save_date(struct mail *_mail)
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen{
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen struct index_mail_data *data = &mail->data;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen struct stat st;
a63bc30f167a221691ad0a3fe5cd45c57444411eTimo Sirainen uint32_t t;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen (void)index_mail_get_save_date(_mail);
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen if (data->save_date != (time_t)-1)
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen return data->save_date;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen if (maildir_mail_stat(_mail, &st) < 0)
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen return (time_t)-1;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen
a63bc30f167a221691ad0a3fe5cd45c57444411eTimo Sirainen data->save_date = t = st.st_ctime;
a63bc30f167a221691ad0a3fe5cd45c57444411eTimo Sirainen index_mail_cache_add(mail, MAIL_CACHE_SAVE_DATE, &t, sizeof(t));
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen return data->save_date;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen}
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo 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;
b142deb9a831c89b1bb9129ada655f3e56b9d4ccTimo Sirainen const char *path, *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);
683253c6f556b71d7946452644fc3d633f47153cTimo Sirainen if (fname == NULL) {
683253c6f556b71d7946452644fc3d633f47153cTimo Sirainen _mail->expunged = TRUE;
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen return (uoff_t)-1;
683253c6f556b71d7946452644fc3d633f47153cTimo Sirainen }
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen } else {
b142deb9a831c89b1bb9129ada655f3e56b9d4ccTimo Sirainen path = maildir_save_file_get_path(_mail->transaction,
b142deb9a831c89b1bb9129ada655f3e56b9d4ccTimo Sirainen _mail->seq);
b142deb9a831c89b1bb9129ada655f3e56b9d4ccTimo Sirainen fname = strrchr(path, '/');
b142deb9a831c89b1bb9129ada655f3e56b9d4ccTimo Sirainen fname = fname != NULL ? fname + 1 : path;
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;
b142deb9a831c89b1bb9129ada655f3e56b9d4ccTimo Sirainen const char *path, *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);
683253c6f556b71d7946452644fc3d633f47153cTimo Sirainen if (fname == NULL) {
683253c6f556b71d7946452644fc3d633f47153cTimo Sirainen _mail->expunged = TRUE;
683253c6f556b71d7946452644fc3d633f47153cTimo Sirainen return NULL;
683253c6f556b71d7946452644fc3d633f47153cTimo Sirainen }
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen } else {
b142deb9a831c89b1bb9129ada655f3e56b9d4ccTimo Sirainen path = maildir_save_file_get_path(_mail->transaction,
b142deb9a831c89b1bb9129ada655f3e56b9d4ccTimo Sirainen _mail->seq);
b142deb9a831c89b1bb9129ada655f3e56b9d4ccTimo Sirainen fname = strrchr(path, '/');
b142deb9a831c89b1bb9129ada655f3e56b9d4ccTimo Sirainen fname = fname != NULL ? fname + 1 : path;
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;
b142deb9a831c89b1bb9129ada655f3e56b9d4ccTimo Sirainen const char *path, *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);
683253c6f556b71d7946452644fc3d633f47153cTimo Sirainen if (fname == NULL) {
683253c6f556b71d7946452644fc3d633f47153cTimo Sirainen _mail->expunged = TRUE;
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen return (uoff_t)-1;
683253c6f556b71d7946452644fc3d633f47153cTimo Sirainen }
944d096df698dd2b476e376277e9afd634b53270Timo Sirainen path = NULL;
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen } else {
b142deb9a831c89b1bb9129ada655f3e56b9d4ccTimo Sirainen path = maildir_save_file_get_path(_mail->transaction,
b142deb9a831c89b1bb9129ada655f3e56b9d4ccTimo Sirainen _mail->seq);
b142deb9a831c89b1bb9129ada655f3e56b9d4ccTimo Sirainen fname = strrchr(path, '/');
b142deb9a831c89b1bb9129ada655f3e56b9d4ccTimo Sirainen fname = fname != NULL ? fname + 1 : path;
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 */
944d096df698dd2b476e376277e9afd634b53270Timo Sirainen if (do_stat(mbox, path, &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 index_mail_get_date,
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen maildir_mail_get_received_date,
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen maildir_mail_get_save_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};