maildir-mail.c revision 6ef7e31619edfaa17ed044b45861d106a86191ef
45312f52ff3a3d4c137447be4c7556500c2f8bf2Timo 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"
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen#include "maildir-uidlist.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen#include <fcntl.h>
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include <unistd.h>
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen#include <sys/stat.h>
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainendo_open(struct maildir_mailbox *mbox, const char *path, void *context)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen int *fd = context;
2cfe9983ce7a6280636ee12beccc2e865111967bTimo 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
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_storage_set_critical(STORAGE(mbox->storage),
ccc895c0358108d2304239063e940b7d75f364abTimo Sirainen "open(%s) failed: %m", path);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainendo_stat(struct maildir_mailbox *mbox, const char *path, void *context)
2cfe9983ce7a6280636ee12beccc2e865111967bTimo 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;
ccc895c0358108d2304239063e940b7d75f364abTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_storage_set_critical(STORAGE(mbox->storage),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "stat(%s) failed: %m", path);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainenstatic struct istream *
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainenmaildir_open_mail(struct maildir_mailbox *mbox, uint32_t uid, bool *deleted)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen int fd;
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *deleted = FALSE;
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen fd = -1;
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen if (maildir_file_do(mbox, uid, do_open, &fd) < 0)
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen return NULL;
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen if (fd == -1) {
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen *deleted = TRUE;
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen return NULL;
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen }
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mbox->ibox.mail_read_mmaped) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return i_stream_create_mmap(fd, default_pool,
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo 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);
2526d52441ef368215ab6bf04fd0356d3b09d235Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainenstatic time_t maildir_mail_get_received_date(struct mail *_mail)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen struct maildir_mailbox *mbox = (struct maildir_mailbox *)mail->ibox;
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen struct index_mail_data *data = &mail->data;
e9d29ae46d435aee85514decfe6ee27399ebf794Timo Sirainen struct stat st;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int fd;
55773f17bccf6361d6599ffcbe072d7c9fe205bfTimo Sirainen
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainen (void)index_mail_get_received_date(_mail);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen if (data->received_date != (time_t)-1)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return data->received_date;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainen if (data->access_part != 0 && data->stream == NULL) {
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainen /* we're going to open the mail anyway */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen (void)mail_get_stream(_mail, NULL, NULL);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (data->stream != NULL) {
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen fd = i_stream_get_fd(data->stream);
ccc895c0358108d2304239063e940b7d75f364abTimo Sirainen i_assert(fd != -1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen if (fstat(fd, &st) < 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_storage_set_critical(STORAGE(mbox->storage),
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen "fstat(maildir) failed: %m");
e9d29ae46d435aee85514decfe6ee27399ebf794Timo Sirainen return (time_t)-1;
e9d29ae46d435aee85514decfe6ee27399ebf794Timo Sirainen }
e9d29ae46d435aee85514decfe6ee27399ebf794Timo Sirainen } else {
e9d29ae46d435aee85514decfe6ee27399ebf794Timo Sirainen if (maildir_file_do(mbox, mail->mail.mail.uid,
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen do_stat, &st) <= 0)
e9d29ae46d435aee85514decfe6ee27399ebf794Timo Sirainen return (time_t)-1;
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen }
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen data->received_date = st.st_mtime;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen mail_cache_add(mail->trans->cache_trans, mail->data.seq,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen MAIL_CACHE_RECEIVED_DATE,
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen &data->received_date, sizeof(data->received_date));
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return data->received_date;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainenstatic uoff_t maildir_mail_get_virtual_size(struct mail *_mail)
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen{
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen struct maildir_mailbox *mbox = (struct maildir_mailbox *)mail->ibox;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen struct index_mail_data *data = &mail->data;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen const char *fname, *p;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen uoff_t virtual_size;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen enum maildir_uidlist_rec_flag flags;
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen if (data->virtual_size != (uoff_t)-1)
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen return data->virtual_size;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen if ((mail->wanted_fields & MAIL_FETCH_VIRTUAL_SIZE) == 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen data->virtual_size = index_mail_get_cached_virtual_size(mail);
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen if (data->virtual_size != (uoff_t)-1)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return data->virtual_size;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen fname = maildir_uidlist_lookup(mbox->uidlist,
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen mail->mail.mail.uid, &flags);
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen if (fname == NULL)
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen return (uoff_t)-1;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen /* size can be included in filename */
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen p = strstr(fname, MAILDIR_EXTRA_SEP_S MAILDIR_EXTRA_VIRTUAL_SIZE "=");
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen if (p != NULL) {
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen p += 3;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen virtual_size = 0;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen while (*p >= '0' && *p <= '9') {
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen virtual_size = virtual_size * 10 + (*p - '0');
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen p++;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen }
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen if (*p == MAILDIR_INFO_SEP || *p == MAILDIR_EXTRA_SEP ||
3ec2c1f31631bb5ff86f5fc93a563c33e5cae90dTimo Sirainen *p == '\0') {
3ec2c1f31631bb5ff86f5fc93a563c33e5cae90dTimo Sirainen mail_cache_add(mail->trans->cache_trans, mail->data.seq,
3ec2c1f31631bb5ff86f5fc93a563c33e5cae90dTimo Sirainen MAIL_CACHE_VIRTUAL_FULL_SIZE,
3ec2c1f31631bb5ff86f5fc93a563c33e5cae90dTimo Sirainen &virtual_size, sizeof(virtual_size));
3ec2c1f31631bb5ff86f5fc93a563c33e5cae90dTimo Sirainen return virtual_size;
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen }
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen }
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen
3ec2c1f31631bb5ff86f5fc93a563c33e5cae90dTimo Sirainen return index_mail_get_virtual_size(_mail);
3ec2c1f31631bb5ff86f5fc93a563c33e5cae90dTimo Sirainen}
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainenstatic const char *
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainenmaildir_mail_get_special(struct mail *_mail, enum mail_fetch_field field)
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen{
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen struct maildir_mailbox *mbox = (struct maildir_mailbox *)mail->ibox;
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen enum maildir_uidlist_rec_flag flags;
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen const char *fname, *end;
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen if (field == MAIL_FETCH_UIDL_FILE_NAME) {
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen fname = maildir_uidlist_lookup(mbox->uidlist,
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen mail->mail.mail.uid, &flags);
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen end = strchr(fname, MAILDIR_INFO_SEP);
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen return end == NULL ? fname : t_strdup_until(fname, end);
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen }
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen return index_mail_get_special(_mail, field);
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen}
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen
3ec2c1f31631bb5ff86f5fc93a563c33e5cae90dTimo Sirainenstatic uoff_t maildir_mail_get_physical_size(struct mail *_mail)
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen{
3ec2c1f31631bb5ff86f5fc93a563c33e5cae90dTimo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
3ec2c1f31631bb5ff86f5fc93a563c33e5cae90dTimo Sirainen struct maildir_mailbox *mbox = (struct maildir_mailbox *)mail->ibox;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen struct index_mail_data *data = &mail->data;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen struct stat st;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen const char *fname, *p;
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen uoff_t size;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen enum maildir_uidlist_rec_flag flags;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen size = index_mail_get_physical_size(_mail);
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen if (size != (uoff_t)-1)
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen return size;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen fname = maildir_uidlist_lookup(mbox->uidlist,
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen mail->mail.mail.uid, &flags);
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen if (fname == NULL)
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen return (uoff_t)-1;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen /* size can be included in filename */
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen p = strstr(fname, MAILDIR_EXTRA_SEP_S MAILDIR_EXTRA_FILE_SIZE "=");
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen if (p != NULL) {
8b58939517a381db55670089c0984da39fc0f099Timo Sirainen p += 3;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen size = 0;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen while (*p >= '0' && *p <= '9') {
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen size = size * 10 + (*p - '0');
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen p++;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen }
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen if (*p != MAILDIR_INFO_SEP &&
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen *p != MAILDIR_EXTRA_SEP && *p != '\0')
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen size = (uoff_t)-1;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen }
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen if (size == (uoff_t)-1) {
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen if (maildir_file_do(mbox, mail->mail.mail.uid,
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen do_stat, &st) <= 0)
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen return (uoff_t)-1;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen size = st.st_size;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen }
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen mail_cache_add(mail->trans->cache_trans, mail->data.seq,
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen MAIL_CACHE_PHYSICAL_FULL_SIZE, &size, sizeof(size));
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen data->physical_size = size;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen return size;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen}
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainenstatic struct istream *maildir_mail_get_stream(struct mail *_mail,
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen struct message_size *hdr_size,
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen struct message_size *body_size)
236bedf76e31651ea9fca63fbdc25be673819526Timo Sirainen{
04870054863757edf048c81dcce3c5e7dec453cdTimo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
04870054863757edf048c81dcce3c5e7dec453cdTimo Sirainen struct maildir_mailbox *mbox = (struct maildir_mailbox *)mail->ibox;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen struct index_mail_data *data = &mail->data;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen bool deleted;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen if (data->stream == NULL) {
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen data->stream = maildir_open_mail(mbox,
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen mail->mail.mail.uid, &deleted);
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen if (data->stream == NULL) {
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen _mail->expunged = deleted;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen return NULL;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen }
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen }
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen return index_mail_init_stream(mail, hdr_size, body_size);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainenstruct mail_vfuncs maildir_mail_vfuncs = {
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen index_mail_free,
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen index_mail_set_seq,
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen index_mail_get_flags,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen index_mail_get_keywords,
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen index_mail_get_parts,
3ec2c1f31631bb5ff86f5fc93a563c33e5cae90dTimo Sirainen maildir_mail_get_received_date,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen index_mail_get_date,
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen maildir_mail_get_virtual_size,
b142deb9a831c89b1bb9129ada655f3e56b9d4ccTimo Sirainen maildir_mail_get_physical_size,
b142deb9a831c89b1bb9129ada655f3e56b9d4ccTimo Sirainen index_mail_get_first_header,
b142deb9a831c89b1bb9129ada655f3e56b9d4ccTimo Sirainen index_mail_get_headers,
b142deb9a831c89b1bb9129ada655f3e56b9d4ccTimo Sirainen index_mail_get_header_stream,
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen maildir_mail_get_stream,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen maildir_mail_get_special,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen index_mail_update_flags,
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen index_mail_update_keywords,
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen index_mail_expunge
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen};
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen