maildir-mail.c revision 3ec2c1f31631bb5ff86f5fc93a563c33e5cae90d
76b43e4417bab52e913da39b5f5bc2a130d3f149Timo Sirainen/* Copyright (C) 2003 Timo Sirainen */
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "lib.h"
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen#include "istream.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "index-mail.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "maildir-storage.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "maildir-filename.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "maildir-uidlist.h"
f1901fd21906911f7be075c965ac882f6a87b4c3Timo Sirainen
63a61b7a739ae0f3f520215137d9c50f94d0f34fTimo Sirainen#include <fcntl.h>
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include <unistd.h>
18565c69efcd7db003dbf27cf625ed822e889fb1Timo Sirainen#include <sys/stat.h>
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenstatic int
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainendo_open(struct maildir_mailbox *mbox, const char *path, int *fd)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen{
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen *fd = open(path, O_RDONLY);
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen if (*fd != -1)
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen return 1;
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen if (errno == ENOENT)
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen return 0;
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen mail_storage_set_critical(&mbox->storage->storage,
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen "open(%s) failed: %m", path);
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen return -1;
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen}
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainenstatic int
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainendo_stat(struct maildir_mailbox *mbox, const char *path, struct stat *st)
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen{
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen if (stat(path, st) == 0)
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen return 1;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen if (errno == ENOENT)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen return 0;
af1f4b17a92ca7b2661737e65c7849df289d3070Timo Sirainen
af1f4b17a92ca7b2661737e65c7849df289d3070Timo Sirainen mail_storage_set_critical(&mbox->storage->storage,
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen "stat(%s) failed: %m", path);
f1901fd21906911f7be075c965ac882f6a87b4c3Timo Sirainen return -1;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen}
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen
01cbf4ac5d44137ab434791be7f838d98d0fcf3bTimo Sirainenstatic struct istream *
4b41116563110d00330896a568eff1078c382827Timo Sirainenmaildir_open_mail(struct maildir_mailbox *mbox, struct mail *mail,
4b41116563110d00330896a568eff1078c382827Timo Sirainen bool *deleted_r)
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainen{
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen const char *path;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen int fd = -1;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen *deleted_r = FALSE;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen if (mail->uid != 0) {
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen if (maildir_file_do(mbox, mail->uid, do_open, &fd) < 0)
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen return NULL;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen } else {
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen path = maildir_save_file_get_path(mail->transaction, mail->seq);
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen if (do_open(mbox, path, &fd) <= 0)
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen return NULL;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen }
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen if (fd == -1) {
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen *deleted_r = TRUE;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen return NULL;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen }
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen return i_stream_create_file(fd, default_pool,
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen MAIL_READ_BLOCK_SIZE, TRUE);
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen}
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen
597dce34068d603fb759b4dff404b34049213e51Timo Sirainenstatic int maildir_mail_stat(struct mail *mail, struct stat *st)
63a61b7a739ae0f3f520215137d9c50f94d0f34fTimo Sirainen{
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen struct maildir_mailbox *mbox = (struct maildir_mailbox *)mail->box;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen struct index_mail_data *data = &((struct index_mail *)mail)->data;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen const char *path;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen int fd;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen if (data->access_part != 0 && data->stream == NULL) {
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen /* we're going to open the mail anyway */
4b41116563110d00330896a568eff1078c382827Timo Sirainen (void)mail_get_stream(mail, NULL, NULL);
910fa4e4204a73d3d24c03f3059dd24e727ca057Timo Sirainen }
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen
f1901fd21906911f7be075c965ac882f6a87b4c3Timo Sirainen if (data->stream != NULL) {
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen fd = i_stream_get_fd(data->stream);
f1901fd21906911f7be075c965ac882f6a87b4c3Timo Sirainen i_assert(fd != -1);
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen
6060b7c8edf8fce73470d0df6a2479b69b01c537Timo Sirainen if (fstat(fd, st) < 0) {
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen mail_storage_set_critical(&mbox->storage->storage,
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen "fstat(maildir) failed: %m");
ccc895c0358108d2304239063e940b7d75f364abTimo Sirainen return -1;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen }
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen } else if (mail->uid != 0) {
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen if (maildir_file_do(mbox, mail->uid, do_stat, st) <= 0)
4b41116563110d00330896a568eff1078c382827Timo Sirainen return -1;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen } else {
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen path = maildir_save_file_get_path(mail->transaction, mail->seq);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen if (do_stat(mbox, path, st) <= 0)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen return -1;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen }
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen return 0;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen}
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainenstatic time_t maildir_mail_get_received_date(struct mail *_mail)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen{
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
4b41116563110d00330896a568eff1078c382827Timo Sirainen struct index_mail_data *data = &mail->data;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen struct stat st;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen uint32_t t;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen (void)index_mail_get_received_date(_mail);
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen if (data->received_date != (time_t)-1)
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen return data->received_date;
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen if (maildir_mail_stat(_mail, &st) < 0)
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen return (time_t)-1;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen data->received_date = t = st.st_mtime;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen index_mail_cache_add(mail, MAIL_CACHE_RECEIVED_DATE, &t, sizeof(t));
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen return data->received_date;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen}
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo 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;
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen struct index_mail_data *data = &mail->data;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen struct stat st;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo 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;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen if (maildir_mail_stat(_mail, &st) < 0)
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen return (time_t)-1;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen data->save_date = t = st.st_ctime;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen index_mail_cache_add(mail, MAIL_CACHE_SAVE_DATE, &t, sizeof(t));
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return data->save_date;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen}
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenstatic bool
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainenmaildir_mail_get_fname(struct maildir_mailbox *mbox, struct mail *mail,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen const char **fname_r)
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen{
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen enum maildir_uidlist_rec_flag flags;
4b41116563110d00330896a568eff1078c382827Timo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen *fname_r = maildir_uidlist_lookup(mbox->uidlist, mail->uid, &flags);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen if (*fname_r == NULL) {
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen mail_set_expunged(mail);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return FALSE;
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen }
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return TRUE;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen}
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenstatic uoff_t maildir_mail_get_virtual_size(struct mail *_mail)
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen{
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen struct maildir_mailbox *mbox = (struct maildir_mailbox *)mail->ibox;
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen struct index_mail_data *data = &mail->data;
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen const char *path, *fname;
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen uoff_t virtual_size;
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen if (data->virtual_size != (uoff_t)-1)
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen return data->virtual_size;
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen if ((mail->wanted_fields & MAIL_FETCH_VIRTUAL_SIZE) == 0) {
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen data->virtual_size = index_mail_get_cached_virtual_size(mail);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen if (data->virtual_size != (uoff_t)-1)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return data->virtual_size;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen }
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen if (_mail->uid != 0) {
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen if (!maildir_mail_get_fname(mbox, _mail, &fname))
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen return (uoff_t)-1;
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen } else {
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen path = maildir_save_file_get_path(_mail->transaction,
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen _mail->seq);
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen fname = strrchr(path, '/');
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen fname = fname != NULL ? fname + 1 : path;
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen }
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen /* size can be included in filename */
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen if (maildir_filename_get_size(fname, MAILDIR_EXTRA_VIRTUAL_SIZE,
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen &virtual_size)) {
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen index_mail_cache_add(mail, MAIL_CACHE_VIRTUAL_FULL_SIZE,
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen &virtual_size, sizeof(virtual_size));
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen return virtual_size;
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen }
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen return index_mail_get_virtual_size(_mail);
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen}
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainenstatic const char *
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainenmaildir_mail_get_special(struct mail *_mail, enum mail_fetch_field field)
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen{
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen struct maildir_mailbox *mbox = (struct maildir_mailbox *)mail->ibox;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen const char *path, *fname, *end;
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen if (field == MAIL_FETCH_UIDL_FILE_NAME) {
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen if (_mail->uid != 0) {
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen if (!maildir_mail_get_fname(mbox, _mail, &fname))
aa215ab623706463cea1d047f975ffe51d3f0c05Timo Sirainen return NULL;
aa215ab623706463cea1d047f975ffe51d3f0c05Timo Sirainen } else {
a5c8dc283ef673fcdae158513b8032e74b45f59aTimo Sirainen path = maildir_save_file_get_path(_mail->transaction,
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen _mail->seq);
aa215ab623706463cea1d047f975ffe51d3f0c05Timo Sirainen fname = strrchr(path, '/');
aa215ab623706463cea1d047f975ffe51d3f0c05Timo Sirainen fname = fname != NULL ? fname + 1 : path;
aa215ab623706463cea1d047f975ffe51d3f0c05Timo Sirainen }
aa215ab623706463cea1d047f975ffe51d3f0c05Timo Sirainen end = strchr(fname, MAILDIR_INFO_SEP);
a5c8dc283ef673fcdae158513b8032e74b45f59aTimo Sirainen return end == NULL ? fname : t_strdup_until(fname, end);
aa215ab623706463cea1d047f975ffe51d3f0c05Timo Sirainen }
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen
a1808be0774cbcb28fec45341aabf803ec44bae5Timo Sirainen return index_mail_get_special(_mail, field);
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen}
aa215ab623706463cea1d047f975ffe51d3f0c05Timo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenstatic uoff_t maildir_mail_get_physical_size(struct mail *_mail)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen{
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen struct maildir_mailbox *mbox = (struct maildir_mailbox *)mail->ibox;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen struct index_mail_data *data = &mail->data;
1b5366b2234892f8930a29351da06b193e385150Timo Sirainen struct stat st;
1b5366b2234892f8930a29351da06b193e385150Timo Sirainen const char *path, *fname;
1b5366b2234892f8930a29351da06b193e385150Timo Sirainen uoff_t size;
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen
1b5366b2234892f8930a29351da06b193e385150Timo Sirainen size = index_mail_get_physical_size(_mail);
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen if (size != (uoff_t)-1)
1b5366b2234892f8930a29351da06b193e385150Timo Sirainen return size;
1b5366b2234892f8930a29351da06b193e385150Timo Sirainen
1b5366b2234892f8930a29351da06b193e385150Timo Sirainen if (_mail->uid != 0) {
aa215ab623706463cea1d047f975ffe51d3f0c05Timo Sirainen if (!maildir_mail_get_fname(mbox, _mail, &fname))
aa215ab623706463cea1d047f975ffe51d3f0c05Timo Sirainen return (uoff_t)-1;
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen path = NULL;
aa215ab623706463cea1d047f975ffe51d3f0c05Timo Sirainen } else {
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen path = maildir_save_file_get_path(_mail->transaction,
a5c8dc283ef673fcdae158513b8032e74b45f59aTimo Sirainen _mail->seq);
a5c8dc283ef673fcdae158513b8032e74b45f59aTimo Sirainen fname = strrchr(path, '/');
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen fname = fname != NULL ? fname + 1 : path;
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen }
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen /* size can be included in filename */
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen if (!maildir_filename_get_size(fname, MAILDIR_EXTRA_FILE_SIZE, &size)) {
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen if (_mail->uid != 0) {
b2ecd50bb98c44816cb07c17aa17fae2b425f941Timo Sirainen if (maildir_file_do(mbox, _mail->uid,
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen do_stat, &st) <= 0)
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen return (uoff_t)-1;
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen } else {
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen /* saved mail which hasn't been committed yet */
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen if (do_stat(mbox, path, &st) <= 0)
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen return (uoff_t)-1;
4b41116563110d00330896a568eff1078c382827Timo Sirainen }
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen size = st.st_size;
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen }
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen index_mail_cache_add(mail, MAIL_CACHE_PHYSICAL_FULL_SIZE,
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen &size, sizeof(size));
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen data->physical_size = size;
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen return size;
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen}
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainenstatic struct istream *maildir_mail_get_stream(struct mail *_mail,
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen struct message_size *hdr_size,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen struct message_size *body_size)
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen{
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen struct maildir_mailbox *mbox = (struct maildir_mailbox *)mail->ibox;
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen struct index_mail_data *data = &mail->data;
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen bool deleted;
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen
8f017a40470ef2f4b530000d947a8bce44350a5eTimo Sirainen if (data->stream == NULL) {
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen data->stream = maildir_open_mail(mbox, _mail, &deleted);
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen if (data->stream == NULL) {
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen if (deleted)
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen mail_set_expunged(_mail);
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen return NULL;
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen }
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen }
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen return index_mail_init_stream(mail, hdr_size, body_size);
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen}
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainenstruct mail_vfuncs maildir_mail_vfuncs = {
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen index_mail_free,
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen index_mail_set_seq,
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen index_mail_set_uid,
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen index_mail_get_flags,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen index_mail_get_keywords,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen index_mail_get_parts,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen index_mail_get_date,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen maildir_mail_get_received_date,
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen maildir_mail_get_save_date,
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen maildir_mail_get_virtual_size,
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen maildir_mail_get_physical_size,
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen index_mail_get_first_header,
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen index_mail_get_headers,
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen index_mail_get_header_stream,
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen maildir_mail_get_stream,
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen maildir_mail_get_special,
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen index_mail_update_flags,
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen index_mail_update_keywords,
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen index_mail_expunge
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen};
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen