maildir-mail.c revision bc6ef0b01b99c43ee46aa796420516e89a744c30
2e37d45867d081db150ab78dad303b9077aea24fTimo Sirainen/* Copyright (c) 2003-2011 Dovecot authors, see the included COPYING file */
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-filename.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "maildir-uidlist.h"
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen#include "maildir-sync.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen#include <stdlib.h>
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include <fcntl.h>
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include <unistd.h>
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include <sys/stat.h>
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
f0a2d04321ba456e5c5ba821c0d1ed9e8e0e2e08Timo Sirainenstruct maildir_open_context {
f0a2d04321ba456e5c5ba821c0d1ed9e8e0e2e08Timo Sirainen int fd;
f0a2d04321ba456e5c5ba821c0d1ed9e8e0e2e08Timo Sirainen char *path;
f0a2d04321ba456e5c5ba821c0d1ed9e8e0e2e08Timo Sirainen};
f0a2d04321ba456e5c5ba821c0d1ed9e8e0e2e08Timo Sirainen
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainenstatic int
f0a2d04321ba456e5c5ba821c0d1ed9e8e0e2e08Timo Sirainendo_open(struct maildir_mailbox *mbox, const char *path,
f0a2d04321ba456e5c5ba821c0d1ed9e8e0e2e08Timo Sirainen struct maildir_open_context *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
f0a2d04321ba456e5c5ba821c0d1ed9e8e0e2e08Timo Sirainen ctx->fd = open(path, O_RDONLY);
f0a2d04321ba456e5c5ba821c0d1ed9e8e0e2e08Timo Sirainen if (ctx->fd != -1) {
f0a2d04321ba456e5c5ba821c0d1ed9e8e0e2e08Timo Sirainen ctx->path = i_strdup(path);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 1;
f0a2d04321ba456e5c5ba821c0d1ed9e8e0e2e08Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (errno == ENOENT)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
98922c5675bbbfadc84d58768bef867fe82256c2Timo Sirainen if (errno == EACCES) {
98922c5675bbbfadc84d58768bef867fe82256c2Timo Sirainen mail_storage_set_critical(&mbox->storage->storage, "%s",
98922c5675bbbfadc84d58768bef867fe82256c2Timo Sirainen mail_error_eacces_msg("open", path));
98922c5675bbbfadc84d58768bef867fe82256c2Timo Sirainen } else {
98922c5675bbbfadc84d58768bef867fe82256c2Timo Sirainen mail_storage_set_critical(&mbox->storage->storage,
98922c5675bbbfadc84d58768bef867fe82256c2Timo Sirainen "open(%s) failed: %m", path);
98922c5675bbbfadc84d58768bef867fe82256c2Timo Sirainen }
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
98922c5675bbbfadc84d58768bef867fe82256c2Timo Sirainen if (errno == EACCES) {
98922c5675bbbfadc84d58768bef867fe82256c2Timo Sirainen mail_storage_set_critical(&mbox->storage->storage, "%s",
98922c5675bbbfadc84d58768bef867fe82256c2Timo Sirainen mail_error_eacces_msg("stat", path));
98922c5675bbbfadc84d58768bef867fe82256c2Timo Sirainen } else {
98922c5675bbbfadc84d58768bef867fe82256c2Timo Sirainen mail_storage_set_critical(&mbox->storage->storage,
98922c5675bbbfadc84d58768bef867fe82256c2Timo Sirainen "stat(%s) failed: %m", path);
98922c5675bbbfadc84d58768bef867fe82256c2Timo Sirainen }
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{
b0a901f1dbe9e05ac1c92a0974af6bce0274f31aTimo Sirainen struct mail_private *p = (struct mail_private *)mail;
d42eb03b3a4e79a2da22a1be2de59b95660af2beTimo Sirainen struct istream *input;
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen const char *path;
f0a2d04321ba456e5c5ba821c0d1ed9e8e0e2e08Timo Sirainen struct maildir_open_context ctx;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen *deleted_r = FALSE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
f0a2d04321ba456e5c5ba821c0d1ed9e8e0e2e08Timo Sirainen ctx.fd = -1;
f0a2d04321ba456e5c5ba821c0d1ed9e8e0e2e08Timo Sirainen ctx.path = NULL;
f0a2d04321ba456e5c5ba821c0d1ed9e8e0e2e08Timo Sirainen
1eb17e61d3d38372674aa0c55caedb0185a985f5Timo Sirainen p->stats_open_lookup_count++;
fc40a9a002458e372ff4b9f6f4e15239520c0bcdTimo Sirainen if (!mail->saving) {
f0a2d04321ba456e5c5ba821c0d1ed9e8e0e2e08Timo Sirainen if (maildir_file_do(mbox, mail->uid, do_open, &ctx) < 0)
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen return NULL;
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen } else {
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen path = maildir_save_file_get_path(mail->transaction, mail->seq);
f0a2d04321ba456e5c5ba821c0d1ed9e8e0e2e08Timo Sirainen if (do_open(mbox, path, &ctx) <= 0)
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen return NULL;
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
f0a2d04321ba456e5c5ba821c0d1ed9e8e0e2e08Timo Sirainen if (ctx.fd == -1) {
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen *deleted_r = TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return NULL;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
f0a2d04321ba456e5c5ba821c0d1ed9e8e0e2e08Timo Sirainen input = i_stream_create_fd(ctx.fd, 0, TRUE);
c60d1eda4df179d83d531647732d5e3e45064219Timo Sirainen if (input->stream_errno == EISDIR) {
c60d1eda4df179d83d531647732d5e3e45064219Timo Sirainen i_stream_destroy(&input);
f6f021c133f680cf3d559187524fd9abcbaae9b9Timo Sirainen if (maildir_lose_unexpected_dir(&mbox->storage->storage,
f6f021c133f680cf3d559187524fd9abcbaae9b9Timo Sirainen ctx.path) >= 0)
c60d1eda4df179d83d531647732d5e3e45064219Timo Sirainen *deleted_r = TRUE;
c60d1eda4df179d83d531647732d5e3e45064219Timo Sirainen } else {
c60d1eda4df179d83d531647732d5e3e45064219Timo Sirainen i_stream_set_name(input, ctx.path);
c60d1eda4df179d83d531647732d5e3e45064219Timo Sirainen index_mail_set_read_buffer_size(mail, input);
c60d1eda4df179d83d531647732d5e3e45064219Timo Sirainen }
f0a2d04321ba456e5c5ba821c0d1ed9e8e0e2e08Timo Sirainen i_free(ctx.path);
d42eb03b3a4e79a2da22a1be2de59b95660af2beTimo Sirainen return input;
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;
b0a901f1dbe9e05ac1c92a0974af6bce0274f31aTimo Sirainen struct index_mail *imail = (struct index_mail *)mail;
ee1a3e217279dcd0f1cccbd3442e481b7dc90f05Timo Sirainen const struct stat *stp;
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen const char *path;
ee1a3e217279dcd0f1cccbd3442e481b7dc90f05Timo Sirainen int ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
ebe6df72f1309135f02b6a4d2aef1e81a073f91cTimo Sirainen if (mail->lookup_abort == MAIL_LOOKUP_ABORT_NOT_IN_CACHE)
ebe6df72f1309135f02b6a4d2aef1e81a073f91cTimo Sirainen return mail_set_aborted(mail);
ebe6df72f1309135f02b6a4d2aef1e81a073f91cTimo Sirainen
bc6ef0b01b99c43ee46aa796420516e89a744c30Timo Sirainen if (imail->data.access_part != 0 &&
a0aedab7cd06125e4d73638b1bd0c01c7caa2626Timo Sirainen imail->data.stream == NULL) {
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainen /* we're going to open the mail anyway */
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen struct istream *input;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen (void)mail_get_stream(mail, NULL, NULL, &input);
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainen }
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainen
b0a901f1dbe9e05ac1c92a0974af6bce0274f31aTimo Sirainen if (imail->data.stream != NULL) {
1eb17e61d3d38372674aa0c55caedb0185a985f5Timo Sirainen imail->mail.stats_fstat_lookup_count++;
ee1a3e217279dcd0f1cccbd3442e481b7dc90f05Timo Sirainen stp = i_stream_stat(imail->data.stream, FALSE);
ee1a3e217279dcd0f1cccbd3442e481b7dc90f05Timo Sirainen if (stp == NULL)
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen return -1;
ee1a3e217279dcd0f1cccbd3442e481b7dc90f05Timo Sirainen *st = *stp;
3eb63515855f386449c22233d1f1baf1ddfe8a2dTimo Sirainen } else if (!mail->saving) {
1eb17e61d3d38372674aa0c55caedb0185a985f5Timo Sirainen imail->mail.stats_stat_lookup_count++;
e9d29ae46d435aee85514decfe6ee27399ebf794Timo Sirainen ret = maildir_file_do(mbox, mail->uid, do_stat, st);
e9d29ae46d435aee85514decfe6ee27399ebf794Timo Sirainen if (ret <= 0) {
e9d29ae46d435aee85514decfe6ee27399ebf794Timo Sirainen if (ret == 0)
e9d29ae46d435aee85514decfe6ee27399ebf794Timo Sirainen mail_set_expunged(mail);
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen return -1;
e9d29ae46d435aee85514decfe6ee27399ebf794Timo Sirainen }
b6a7e0a7899e7f5d60c23cdaa50e025e4c67d05fTimo Sirainen } else {
1eb17e61d3d38372674aa0c55caedb0185a985f5Timo Sirainen imail->mail.stats_stat_lookup_count++;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen path = maildir_save_file_get_path(mail->transaction, mail->seq);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen if (stat(path, st) < 0) {
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen mail_storage_set_critical(mail->box->storage,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen "stat(%s) failed: %m", path);
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen return -1;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen return 0;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen}
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenstatic int maildir_mail_get_received_date(struct mail *_mail, time_t *date_r)
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;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen if (index_mail_get_received_date(_mail, date_r) == 0)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return 0;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen if (maildir_mail_stat(_mail, &st) < 0)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen *date_r = data->received_date = st.st_mtime;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenstatic int maildir_mail_get_save_date(struct mail *_mail, time_t *date_r)
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;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen if (index_mail_get_save_date(_mail, date_r) == 0)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return 0;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen if (maildir_mail_stat(_mail, &st) < 0)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return -1;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen *date_r = data->save_date = st.st_ctime;
51078c3413b7ed4811bc725acbb1289723361ba9Timo Sirainen return 0;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen}
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen
7ede6554e451ec039a67beec7d6ee4aff61d386eTimo Sirainenstatic int
3ec2c1f31631bb5ff86f5fc93a563c33e5cae90dTimo Sirainenmaildir_mail_get_fname(struct maildir_mailbox *mbox, struct mail *mail,
3ec2c1f31631bb5ff86f5fc93a563c33e5cae90dTimo Sirainen const char **fname_r)
3ec2c1f31631bb5ff86f5fc93a563c33e5cae90dTimo Sirainen{
3ec2c1f31631bb5ff86f5fc93a563c33e5cae90dTimo Sirainen enum maildir_uidlist_rec_flag flags;
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen struct mail_index_view *view;
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen uint32_t seq;
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen bool exists;
7ede6554e451ec039a67beec7d6ee4aff61d386eTimo Sirainen int ret;
3ec2c1f31631bb5ff86f5fc93a563c33e5cae90dTimo Sirainen
6013fbad6638795a00e6c2a2dd2cdbee19612494Timo Sirainen ret = maildir_sync_lookup(mbox, mail->uid, &flags, fname_r);
7ede6554e451ec039a67beec7d6ee4aff61d386eTimo Sirainen if (ret != 0)
7ede6554e451ec039a67beec7d6ee4aff61d386eTimo Sirainen return ret;
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen /* file exists in index file, but not in dovecot-uidlist anymore. */
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen mail_set_expunged(mail);
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen /* one reason this could happen is if we delayed opening
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen dovecot-uidlist and we're trying to open a mail that got recently
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen expunged. Let's test this theory first: */
d22301419109ed4a38351715e6760011421dadecTimo Sirainen (void)mail_index_refresh(mbox->box.index);
d22301419109ed4a38351715e6760011421dadecTimo Sirainen view = mail_index_view_open(mbox->box.index);
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen exists = mail_index_lookup_seq(view, mail->uid, &seq);
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen mail_index_view_close(&view);
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen if (exists) {
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen /* the message still exists in index. this means there's some
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen kind of a desync, which doesn't get fixed if cur/ mtime is
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen the same as in index. fix this by forcing a resync. */
9334fbad0aabb2fed88f40b2205d0d6f80bdffa2Timo Sirainen (void)maildir_storage_sync_force(mbox, mail->uid);
3ec2c1f31631bb5ff86f5fc93a563c33e5cae90dTimo Sirainen }
7ede6554e451ec039a67beec7d6ee4aff61d386eTimo Sirainen return 0;
3ec2c1f31631bb5ff86f5fc93a563c33e5cae90dTimo Sirainen}
3ec2c1f31631bb5ff86f5fc93a563c33e5cae90dTimo Sirainen
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainenstatic int maildir_get_pop3_state(struct index_mail *mail)
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen{
d22301419109ed4a38351715e6760011421dadecTimo Sirainen struct mailbox *box = mail->mail.mail.box;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen struct index_mailbox_context *ibox = INDEX_STORAGE_CONTEXT(box);
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen const struct mail_cache_field *fields;
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen unsigned int i, count, psize_idx, vsize_idx;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen enum mail_cache_decision_type dec, vsize_dec;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen enum mail_fetch_field allowed_pop3_fields;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen bool not_pop3_only = FALSE;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen if (mail->pop3_state_set)
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen return mail->pop3_state;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen /* if this mail itself has non-pop3 fields we know we're not
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen pop3-only */
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen allowed_pop3_fields = MAIL_FETCH_FLAGS | MAIL_FETCH_STREAM_HEADER |
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen MAIL_FETCH_STREAM_BODY | MAIL_FETCH_UIDL_FILE_NAME |
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen MAIL_FETCH_VIRTUAL_SIZE;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen if (mail->wanted_headers != NULL ||
8b58939517a381db55670089c0984da39fc0f099Timo Sirainen (mail->wanted_fields & ~allowed_pop3_fields) != 0)
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen not_pop3_only = TRUE;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen /* get vsize decisions */
d22301419109ed4a38351715e6760011421dadecTimo Sirainen psize_idx = ibox->cache_fields[MAIL_CACHE_PHYSICAL_FULL_SIZE].idx;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen vsize_idx = ibox->cache_fields[MAIL_CACHE_VIRTUAL_FULL_SIZE].idx;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen if (not_pop3_only) {
d22301419109ed4a38351715e6760011421dadecTimo Sirainen vsize_dec = mail_cache_field_get_decision(box->cache,
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen vsize_idx);
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen vsize_dec &= ~MAIL_CACHE_DECISION_FORCED;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen } else {
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen /* also check if there are any non-[pv]size cached fields */
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen vsize_dec = MAIL_CACHE_DECISION_NO;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen fields = mail_cache_register_get_list(box->cache,
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen pool_datastack_create(),
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen &count);
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen for (i = 0; i < count; i++) {
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen dec = fields[i].decision & ~MAIL_CACHE_DECISION_FORCED;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen if (fields[i].idx == vsize_idx)
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen vsize_dec = dec;
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen else if (dec != MAIL_CACHE_DECISION_NO &&
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen fields[i].idx != psize_idx)
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen not_pop3_only = TRUE;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen }
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen }
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen if (!not_pop3_only) {
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen /* either nothing is cached, or only vsize is cached. */
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen mail->pop3_state = 1;
236bedf76e31651ea9fca63fbdc25be673819526Timo Sirainen } else if (vsize_dec != MAIL_CACHE_DECISION_YES &&
d22301419109ed4a38351715e6760011421dadecTimo Sirainen (box->flags & MAILBOX_FLAG_POP3_SESSION) == 0) {
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen /* if virtual size isn't cached permanently,
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen POP3 isn't being used */
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen mail->pop3_state = -1;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen } else {
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen /* possibly a mixed pop3/imap */
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen mail->pop3_state = 0;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen }
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen mail->pop3_state_set = TRUE;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen return mail->pop3_state;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen}
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainenstatic int maildir_quick_size_lookup(struct index_mail *mail, bool vsize,
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen uoff_t *size_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen struct mail *_mail = &mail->mail.mail;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen struct maildir_mailbox *mbox = (struct maildir_mailbox *)_mail->box;
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen enum maildir_uidlist_rec_ext_key key;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen const char *path, *fname, *value;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
3eb63515855f386449c22233d1f1baf1ddfe8a2dTimo Sirainen if (!_mail->saving) {
7ede6554e451ec039a67beec7d6ee4aff61d386eTimo Sirainen if (maildir_mail_get_fname(mbox, _mail, &fname) <= 0)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return -1;
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 */
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen if (maildir_filename_get_size(fname,
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen vsize ? MAILDIR_EXTRA_VIRTUAL_SIZE :
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen MAILDIR_EXTRA_FILE_SIZE,
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen size_r))
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen return 1;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen /* size can be included in uidlist entry */
3eb63515855f386449c22233d1f1baf1ddfe8a2dTimo Sirainen if (!_mail->saving) {
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen key = vsize ? MAILDIR_UIDLIST_REC_EXT_VSIZE :
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen MAILDIR_UIDLIST_REC_EXT_PSIZE;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen value = maildir_uidlist_lookup_ext(mbox->uidlist, _mail->uid,
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen key);
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen if (value != NULL && str_to_uoff(value, size_r) == 0)
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen return 1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen return 0;
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainenstatic void
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainenmaildir_handle_size_caching(struct index_mail *mail, bool quick_check,
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen bool vsize)
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen{
d22301419109ed4a38351715e6760011421dadecTimo Sirainen struct mailbox *box = mail->mail.mail.box;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen struct maildir_mailbox *mbox = (struct maildir_mailbox *)box;
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen enum mail_fetch_field field;
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen uoff_t size;
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen int pop3_state;
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen field = vsize ? MAIL_FETCH_VIRTUAL_SIZE : MAIL_FETCH_PHYSICAL_SIZE;
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen if ((mail->data.dont_cache_fetch_fields & field) != 0)
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen return;
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen
55b6e3105184ad6a2f987346380966f556300055Timo Sirainen if (quick_check && maildir_quick_size_lookup(mail, vsize, &size) > 0) {
7aeaf23f760d86aad525d831efcac9f860a55a39Timo Sirainen /* already in filename / uidlist. don't add it anywhere,
cf49fc07f541c0f74578ac6c3b334ddade143aa1Timo Sirainen including to the uidlist if it's already in filename.
cf49fc07f541c0f74578ac6c3b334ddade143aa1Timo Sirainen do some extra checks here to catch potential cache bugs. */
cf49fc07f541c0f74578ac6c3b334ddade143aa1Timo Sirainen if (vsize && mail->data.virtual_size != size) {
d22301419109ed4a38351715e6760011421dadecTimo Sirainen mail_cache_set_corrupted(box->cache,
63aaafe7e6b201d6633f8c25610ecd30c9cda99cTimo Sirainen "Corrupted virtual size for uid=%u: "
cf49fc07f541c0f74578ac6c3b334ddade143aa1Timo Sirainen "%"PRIuUOFF_T" != %"PRIuUOFF_T,
63aaafe7e6b201d6633f8c25610ecd30c9cda99cTimo Sirainen mail->mail.mail.uid,
cf49fc07f541c0f74578ac6c3b334ddade143aa1Timo Sirainen mail->data.virtual_size, size);
2ff23d6fb7e2ff85aa23b7f4769aeac1d0316a1bTimo Sirainen mail->data.virtual_size = size;
cf49fc07f541c0f74578ac6c3b334ddade143aa1Timo Sirainen } else if (!vsize && mail->data.physical_size != size) {
d22301419109ed4a38351715e6760011421dadecTimo Sirainen mail_cache_set_corrupted(box->cache,
63aaafe7e6b201d6633f8c25610ecd30c9cda99cTimo Sirainen "Corrupted physical size for uid=%u: "
cf49fc07f541c0f74578ac6c3b334ddade143aa1Timo Sirainen "%"PRIuUOFF_T" != %"PRIuUOFF_T,
63aaafe7e6b201d6633f8c25610ecd30c9cda99cTimo Sirainen mail->mail.mail.uid,
cf49fc07f541c0f74578ac6c3b334ddade143aa1Timo Sirainen mail->data.physical_size, size);
2ff23d6fb7e2ff85aa23b7f4769aeac1d0316a1bTimo Sirainen mail->data.physical_size = size;
cf49fc07f541c0f74578ac6c3b334ddade143aa1Timo Sirainen }
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen mail->data.dont_cache_fetch_fields |= field;
7aeaf23f760d86aad525d831efcac9f860a55a39Timo Sirainen return;
7aeaf23f760d86aad525d831efcac9f860a55a39Timo Sirainen }
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen /* 1 = pop3-only, 0 = mixed, -1 = no pop3 */
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen pop3_state = maildir_get_pop3_state(mail);
18065635d4e79dd96eb3b3215718abd12f6a6808Timo Sirainen if (pop3_state >= 0 && mail->mail.mail.uid != 0) {
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen /* if size is wanted permanently, store it to uidlist
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen so that in case cache file gets lost we can get it quickly */
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen mail->data.dont_cache_fetch_fields |= field;
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen size = vsize ? mail->data.virtual_size :
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen mail->data.physical_size;
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen maildir_uidlist_set_ext(mbox->uidlist, mail->mail.mail.uid,
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen vsize ? MAILDIR_UIDLIST_REC_EXT_VSIZE :
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen MAILDIR_UIDLIST_REC_EXT_PSIZE,
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen dec2str(size));
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen }
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen}
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainenstatic int maildir_mail_get_virtual_size(struct mail *_mail, uoff_t *size_r)
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen{
a0aedab7cd06125e4d73638b1bd0c01c7caa2626Timo Sirainen struct maildir_mailbox *mbox = (struct maildir_mailbox *)_mail->box;
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen struct index_mail_data *data = &mail->data;
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen struct message_size hdr_size, body_size;
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen struct istream *input;
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen uoff_t old_offset;
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen
a0aedab7cd06125e4d73638b1bd0c01c7caa2626Timo Sirainen if (maildir_uidlist_is_read(mbox->uidlist) ||
a0aedab7cd06125e4d73638b1bd0c01c7caa2626Timo Sirainen (_mail->box->flags & MAILBOX_FLAG_POP3_SESSION) != 0) {
a0aedab7cd06125e4d73638b1bd0c01c7caa2626Timo Sirainen /* try to get the size from uidlist. this is especially useful
a0aedab7cd06125e4d73638b1bd0c01c7caa2626Timo Sirainen with pop3 to avoid unnecessarily opening the cache file. */
a0aedab7cd06125e4d73638b1bd0c01c7caa2626Timo Sirainen if (maildir_quick_size_lookup(mail, TRUE,
a0aedab7cd06125e4d73638b1bd0c01c7caa2626Timo Sirainen &data->virtual_size) < 0)
a0aedab7cd06125e4d73638b1bd0c01c7caa2626Timo Sirainen return -1;
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen }
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen
a0aedab7cd06125e4d73638b1bd0c01c7caa2626Timo Sirainen if (data->virtual_size == (uoff_t)-1) {
a0aedab7cd06125e4d73638b1bd0c01c7caa2626Timo Sirainen if (index_mail_get_cached_virtual_size(mail, size_r)) {
a0aedab7cd06125e4d73638b1bd0c01c7caa2626Timo Sirainen i_assert(mail->data.virtual_size != (uoff_t)-1);
a0aedab7cd06125e4d73638b1bd0c01c7caa2626Timo Sirainen maildir_handle_size_caching(mail, TRUE, TRUE);
a0aedab7cd06125e4d73638b1bd0c01c7caa2626Timo Sirainen return 0;
a0aedab7cd06125e4d73638b1bd0c01c7caa2626Timo Sirainen }
6d50c4d875bb05f9076e9e0ecbacb8beb2e9ae42Timo Sirainen if (maildir_quick_size_lookup(mail, TRUE,
6d50c4d875bb05f9076e9e0ecbacb8beb2e9ae42Timo Sirainen &data->virtual_size) < 0)
a0aedab7cd06125e4d73638b1bd0c01c7caa2626Timo Sirainen return -1;
a0aedab7cd06125e4d73638b1bd0c01c7caa2626Timo Sirainen }
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen if (data->virtual_size != (uoff_t)-1) {
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen data->dont_cache_fetch_fields |= MAIL_FETCH_VIRTUAL_SIZE;
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen *size_r = data->virtual_size;
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen return 0;
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen }
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen /* fallback to reading the file */
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen old_offset = data->stream == NULL ? 0 : data->stream->v_offset;
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen if (mail_get_stream(_mail, &hdr_size, &body_size, &input) < 0)
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen return -1;
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen i_stream_seek(data->stream, old_offset);
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen maildir_handle_size_caching(mail, FALSE, TRUE);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen *size_r = data->virtual_size;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return 0;
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen}
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainenstatic int maildir_mail_get_physical_size(struct mail *_mail, uoff_t *size_r)
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen{
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen struct maildir_mailbox *mbox = (struct maildir_mailbox *)_mail->box;
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen struct index_mail_data *data = &mail->data;
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen struct stat st;
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen const char *path;
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen int ret;
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen
6d50c4d875bb05f9076e9e0ecbacb8beb2e9ae42Timo Sirainen if (maildir_uidlist_is_read(mbox->uidlist) ||
6d50c4d875bb05f9076e9e0ecbacb8beb2e9ae42Timo Sirainen (_mail->box->flags & MAILBOX_FLAG_POP3_SESSION) != 0) {
6d50c4d875bb05f9076e9e0ecbacb8beb2e9ae42Timo Sirainen /* try to get the size from uidlist (see virtual size above) */
6d50c4d875bb05f9076e9e0ecbacb8beb2e9ae42Timo Sirainen if (maildir_quick_size_lookup(mail, FALSE,
6d50c4d875bb05f9076e9e0ecbacb8beb2e9ae42Timo Sirainen &data->physical_size) < 0)
6d50c4d875bb05f9076e9e0ecbacb8beb2e9ae42Timo Sirainen return -1;
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen }
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen
6d50c4d875bb05f9076e9e0ecbacb8beb2e9ae42Timo Sirainen if (data->physical_size == (uoff_t)-1) {
6d50c4d875bb05f9076e9e0ecbacb8beb2e9ae42Timo Sirainen if (index_mail_get_physical_size(_mail, size_r) == 0) {
6d50c4d875bb05f9076e9e0ecbacb8beb2e9ae42Timo Sirainen i_assert(mail->data.physical_size != (uoff_t)-1);
6d50c4d875bb05f9076e9e0ecbacb8beb2e9ae42Timo Sirainen maildir_handle_size_caching(mail, TRUE, FALSE);
6d50c4d875bb05f9076e9e0ecbacb8beb2e9ae42Timo Sirainen return 0;
6d50c4d875bb05f9076e9e0ecbacb8beb2e9ae42Timo Sirainen }
6d50c4d875bb05f9076e9e0ecbacb8beb2e9ae42Timo Sirainen if (maildir_quick_size_lookup(mail, FALSE,
6d50c4d875bb05f9076e9e0ecbacb8beb2e9ae42Timo Sirainen &data->physical_size) < 0)
6d50c4d875bb05f9076e9e0ecbacb8beb2e9ae42Timo Sirainen return -1;
6d50c4d875bb05f9076e9e0ecbacb8beb2e9ae42Timo Sirainen }
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen if (data->physical_size != (uoff_t)-1) {
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen data->dont_cache_fetch_fields |= MAIL_FETCH_PHYSICAL_SIZE;
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen *size_r = data->physical_size;
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen return 0;
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen }
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen
3eb63515855f386449c22233d1f1baf1ddfe8a2dTimo Sirainen if (!_mail->saving) {
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen ret = maildir_file_do(mbox, _mail->uid, do_stat, &st);
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen if (ret <= 0) {
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen if (ret == 0)
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen mail_set_expunged(_mail);
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen return -1;
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen }
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen } else {
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen /* saved mail which hasn't been committed yet */
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen path = maildir_save_file_get_path(_mail->transaction,
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen _mail->seq);
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen if (stat(path, &st) < 0) {
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen mail_storage_set_critical(_mail->box->storage,
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen "stat(%s) failed: %m", path);
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen return -1;
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen }
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen }
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen data->physical_size = st.st_size;
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen maildir_handle_size_caching(mail, FALSE, FALSE);
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen *size_r = st.st_size;
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen return 0;
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen}
97eb53ade9057e6966dbb77289ad0204c7e1657bTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenstatic int
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenmaildir_mail_get_special(struct mail *_mail, enum mail_fetch_field field,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen const char **value_r)
366d6311c9d5bac6613e3cd64619eb878adce9ecTimo Sirainen{
366d6311c9d5bac6613e3cd64619eb878adce9ecTimo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen struct maildir_mailbox *mbox = (struct maildir_mailbox *)_mail->box;
24cd47a2c8f7507e555459b7e841de771ba3c318Timo Sirainen const char *path, *fname = NULL, *end, *guid, *uidl;
366d6311c9d5bac6613e3cd64619eb878adce9ecTimo Sirainen
b19a1420da0618a10edf67c2cfd13c8c8633057aTimo Sirainen switch (field) {
b19a1420da0618a10edf67c2cfd13c8c8633057aTimo Sirainen case MAIL_FETCH_GUID:
e4e7475f646d66a257d682738fbff1f206ce4924Timo Sirainen /* use GUID from uidlist if it exists */
24cd47a2c8f7507e555459b7e841de771ba3c318Timo Sirainen i_assert(!_mail->saving);
24cd47a2c8f7507e555459b7e841de771ba3c318Timo Sirainen
24cd47a2c8f7507e555459b7e841de771ba3c318Timo Sirainen /* first make sure that we have a refreshed uidlist */
24cd47a2c8f7507e555459b7e841de771ba3c318Timo Sirainen if (maildir_mail_get_fname(mbox, _mail, &fname) <= 0)
24cd47a2c8f7507e555459b7e841de771ba3c318Timo Sirainen return -1;
24cd47a2c8f7507e555459b7e841de771ba3c318Timo Sirainen
e4e7475f646d66a257d682738fbff1f206ce4924Timo Sirainen guid = maildir_uidlist_lookup_ext(mbox->uidlist, _mail->uid,
e4e7475f646d66a257d682738fbff1f206ce4924Timo Sirainen MAILDIR_UIDLIST_REC_EXT_GUID);
e4e7475f646d66a257d682738fbff1f206ce4924Timo Sirainen if (guid != NULL) {
c991c182b019bd85427a4ace2485683b50ea1b83Timo Sirainen *value_r = p_strdup(mail->data_pool, guid);
e4e7475f646d66a257d682738fbff1f206ce4924Timo Sirainen return 0;
e4e7475f646d66a257d682738fbff1f206ce4924Timo Sirainen }
e4e7475f646d66a257d682738fbff1f206ce4924Timo Sirainen
e4e7475f646d66a257d682738fbff1f206ce4924Timo Sirainen /* default to base filename: */
e4e7475f646d66a257d682738fbff1f206ce4924Timo Sirainen case MAIL_FETCH_UIDL_FILE_NAME:
129cc29ae6d8ad64d6d2b72f18da18fa134d0f3eTimo Sirainen if (mail->data.guid != NULL) {
129cc29ae6d8ad64d6d2b72f18da18fa134d0f3eTimo Sirainen *value_r = mail->data.guid;
129cc29ae6d8ad64d6d2b72f18da18fa134d0f3eTimo Sirainen return 0;
129cc29ae6d8ad64d6d2b72f18da18fa134d0f3eTimo Sirainen }
24cd47a2c8f7507e555459b7e841de771ba3c318Timo Sirainen if (fname != NULL) {
24cd47a2c8f7507e555459b7e841de771ba3c318Timo Sirainen /* we came here from MAIL_FETCH_GUID,
24cd47a2c8f7507e555459b7e841de771ba3c318Timo Sirainen avoid a second lookup */
24cd47a2c8f7507e555459b7e841de771ba3c318Timo Sirainen } else if (!_mail->saving) {
7ede6554e451ec039a67beec7d6ee4aff61d386eTimo Sirainen if (maildir_mail_get_fname(mbox, _mail, &fname) <= 0)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return -1;
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);
129cc29ae6d8ad64d6d2b72f18da18fa134d0f3eTimo Sirainen mail->data.guid = end == NULL ?
129cc29ae6d8ad64d6d2b72f18da18fa134d0f3eTimo Sirainen p_strdup(mail->data_pool, fname) :
129cc29ae6d8ad64d6d2b72f18da18fa134d0f3eTimo Sirainen p_strdup_until(mail->data_pool, fname, end);
129cc29ae6d8ad64d6d2b72f18da18fa134d0f3eTimo Sirainen *value_r = mail->data.guid;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return 0;
b19a1420da0618a10edf67c2cfd13c8c8633057aTimo Sirainen case MAIL_FETCH_UIDL_BACKEND:
e76c494ad6535d3de314cc0d3ac7a44b06e53c4bTimo Sirainen uidl = maildir_uidlist_lookup_ext(mbox->uidlist, _mail->uid,
e76c494ad6535d3de314cc0d3ac7a44b06e53c4bTimo Sirainen MAILDIR_UIDLIST_REC_EXT_POP3_UIDL);
89fb98e9eb7e95255a579c8e9d865383c2334a74Timo Sirainen if (uidl == NULL) {
89fb98e9eb7e95255a579c8e9d865383c2334a74Timo Sirainen /* use the default */
89fb98e9eb7e95255a579c8e9d865383c2334a74Timo Sirainen *value_r = "";
89fb98e9eb7e95255a579c8e9d865383c2334a74Timo Sirainen } else if (*uidl == '\0') {
89fb98e9eb7e95255a579c8e9d865383c2334a74Timo Sirainen /* special optimization case: use the base file name */
89fb98e9eb7e95255a579c8e9d865383c2334a74Timo Sirainen return maildir_mail_get_special(_mail,
89fb98e9eb7e95255a579c8e9d865383c2334a74Timo Sirainen MAIL_FETCH_UIDL_FILE_NAME, value_r);
89fb98e9eb7e95255a579c8e9d865383c2334a74Timo Sirainen } else {
c991c182b019bd85427a4ace2485683b50ea1b83Timo Sirainen *value_r = p_strdup(mail->data_pool, uidl);
89fb98e9eb7e95255a579c8e9d865383c2334a74Timo Sirainen }
0d73d91d1a1809f173d433023ccf97e6ec5ba629Timo Sirainen return 0;
b19a1420da0618a10edf67c2cfd13c8c8633057aTimo Sirainen default:
b19a1420da0618a10edf67c2cfd13c8c8633057aTimo Sirainen return index_mail_get_special(_mail, field, value_r);
366d6311c9d5bac6613e3cd64619eb878adce9ecTimo Sirainen }
366d6311c9d5bac6613e3cd64619eb878adce9ecTimo Sirainen}
366d6311c9d5bac6613e3cd64619eb878adce9ecTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenstatic int maildir_mail_get_stream(struct mail *_mail,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen struct message_size *hdr_size,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen struct message_size *body_size,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen struct istream **stream_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen struct maildir_mailbox *mbox = (struct maildir_mailbox *)_mail->box;
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) {
910fa4e4204a73d3d24c03f3059dd24e727ca057Timo Sirainen if (deleted)
910fa4e4204a73d3d24c03f3059dd24e727ca057Timo Sirainen mail_set_expunged(_mail);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return -1;
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainen }
6564208826b0f46a00f010d1b5711d85944c3c88Timo Sirainen if (mail->mail.v.istream_opened != NULL) {
6564208826b0f46a00f010d1b5711d85944c3c88Timo Sirainen if (mail->mail.v.istream_opened(_mail,
6564208826b0f46a00f010d1b5711d85944c3c88Timo Sirainen &data->stream) < 0)
6564208826b0f46a00f010d1b5711d85944c3c88Timo Sirainen return -1;
6564208826b0f46a00f010d1b5711d85944c3c88Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return index_mail_init_stream(mail, hdr_size, body_size, stream_r);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
225e82df5dd1e765f4e52b80c954558f00e5a7dfTimo Sirainenstatic void maildir_update_pop3_uidl(struct mail *_mail, const char *uidl)
225e82df5dd1e765f4e52b80c954558f00e5a7dfTimo Sirainen{
225e82df5dd1e765f4e52b80c954558f00e5a7dfTimo Sirainen struct maildir_mailbox *mbox = (struct maildir_mailbox *)_mail->box;
225e82df5dd1e765f4e52b80c954558f00e5a7dfTimo Sirainen const char *fname;
225e82df5dd1e765f4e52b80c954558f00e5a7dfTimo Sirainen
225e82df5dd1e765f4e52b80c954558f00e5a7dfTimo Sirainen if (maildir_mail_get_special(_mail, MAIL_FETCH_UIDL_FILE_NAME,
225e82df5dd1e765f4e52b80c954558f00e5a7dfTimo Sirainen &fname) == 0 &&
225e82df5dd1e765f4e52b80c954558f00e5a7dfTimo Sirainen strcmp(uidl, fname) == 0) {
225e82df5dd1e765f4e52b80c954558f00e5a7dfTimo Sirainen /* special case optimization: empty UIDL means the same
225e82df5dd1e765f4e52b80c954558f00e5a7dfTimo Sirainen as base filename */
225e82df5dd1e765f4e52b80c954558f00e5a7dfTimo Sirainen uidl = "";
225e82df5dd1e765f4e52b80c954558f00e5a7dfTimo Sirainen }
225e82df5dd1e765f4e52b80c954558f00e5a7dfTimo Sirainen
225e82df5dd1e765f4e52b80c954558f00e5a7dfTimo Sirainen maildir_uidlist_set_ext(mbox->uidlist, _mail->uid,
225e82df5dd1e765f4e52b80c954558f00e5a7dfTimo Sirainen MAILDIR_UIDLIST_REC_EXT_POP3_UIDL, uidl);
225e82df5dd1e765f4e52b80c954558f00e5a7dfTimo Sirainen}
225e82df5dd1e765f4e52b80c954558f00e5a7dfTimo Sirainen
8c9e48cd6de80da0fa32b9c0dee003472c9a7c0dTimo Sirainenstatic void maildir_mail_set_cache_corrupted(struct mail *_mail,
8c9e48cd6de80da0fa32b9c0dee003472c9a7c0dTimo Sirainen enum mail_fetch_field field)
8c9e48cd6de80da0fa32b9c0dee003472c9a7c0dTimo Sirainen{
d22301419109ed4a38351715e6760011421dadecTimo Sirainen struct maildir_mailbox *mbox = (struct maildir_mailbox *)_mail->box;
8c9e48cd6de80da0fa32b9c0dee003472c9a7c0dTimo Sirainen enum maildir_uidlist_rec_flag flags;
8c9e48cd6de80da0fa32b9c0dee003472c9a7c0dTimo Sirainen const char *fname;
8c9e48cd6de80da0fa32b9c0dee003472c9a7c0dTimo Sirainen uoff_t size;
7ede6554e451ec039a67beec7d6ee4aff61d386eTimo Sirainen int ret;
8c9e48cd6de80da0fa32b9c0dee003472c9a7c0dTimo Sirainen
8c9e48cd6de80da0fa32b9c0dee003472c9a7c0dTimo Sirainen if (field == MAIL_FETCH_VIRTUAL_SIZE) {
8c9e48cd6de80da0fa32b9c0dee003472c9a7c0dTimo Sirainen /* make sure it gets removed from uidlist.
8c9e48cd6de80da0fa32b9c0dee003472c9a7c0dTimo Sirainen if it's in file name, we can't really do more than log it. */
6013fbad6638795a00e6c2a2dd2cdbee19612494Timo Sirainen ret = maildir_sync_lookup(mbox, _mail->uid, &flags, &fname);
7ede6554e451ec039a67beec7d6ee4aff61d386eTimo Sirainen if (ret <= 0)
7ede6554e451ec039a67beec7d6ee4aff61d386eTimo Sirainen return;
8c9e48cd6de80da0fa32b9c0dee003472c9a7c0dTimo Sirainen if (maildir_filename_get_size(fname, MAILDIR_EXTRA_VIRTUAL_SIZE,
8c9e48cd6de80da0fa32b9c0dee003472c9a7c0dTimo Sirainen &size)) {
e0645d5232900a5c574780ef0c0362a5b7581abaTimo Sirainen const char *subdir =
e0645d5232900a5c574780ef0c0362a5b7581abaTimo Sirainen (flags & MAILDIR_UIDLIST_REC_FLAG_NEW_DIR) != 0 ?
e0645d5232900a5c574780ef0c0362a5b7581abaTimo Sirainen "new" : "cur";
0d16525a729011f4fced989a3da74d755ea49e6dTimo Sirainen mail_storage_set_critical(_mail->box->storage,
e0645d5232900a5c574780ef0c0362a5b7581abaTimo Sirainen "Maildir filename has wrong W value: %s/%s/%s",
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen mailbox_get_path(&mbox->box), subdir, fname);
8c9e48cd6de80da0fa32b9c0dee003472c9a7c0dTimo Sirainen } else if (maildir_uidlist_lookup_ext(mbox->uidlist, _mail->uid,
8c9e48cd6de80da0fa32b9c0dee003472c9a7c0dTimo Sirainen MAILDIR_UIDLIST_REC_EXT_VSIZE) != NULL) {
8c9e48cd6de80da0fa32b9c0dee003472c9a7c0dTimo Sirainen maildir_uidlist_set_ext(mbox->uidlist, _mail->uid,
8c9e48cd6de80da0fa32b9c0dee003472c9a7c0dTimo Sirainen MAILDIR_UIDLIST_REC_EXT_VSIZE,
8c9e48cd6de80da0fa32b9c0dee003472c9a7c0dTimo Sirainen NULL);
8c9e48cd6de80da0fa32b9c0dee003472c9a7c0dTimo Sirainen }
8c9e48cd6de80da0fa32b9c0dee003472c9a7c0dTimo Sirainen }
8c9e48cd6de80da0fa32b9c0dee003472c9a7c0dTimo Sirainen index_mail_set_cache_corrupted(_mail, field);
8c9e48cd6de80da0fa32b9c0dee003472c9a7c0dTimo Sirainen}
8c9e48cd6de80da0fa32b9c0dee003472c9a7c0dTimo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenstruct mail_vfuncs maildir_mail_vfuncs = {
0d86aa0d47f7393c669c084b34c0537b193688adTimo Sirainen index_mail_close,
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen index_mail_free,
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen index_mail_set_seq,
a12399903f415a7e14c2816cffa2f7a09dcbb097Timo Sirainen index_mail_set_uid,
aa247243412a49f9bdebf7255e131dc6ece4ed46Timo Sirainen index_mail_set_uid_cache_updates,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
439980f88f421039dea8335e92d3fa82b3f470a1Timo Sirainen index_mail_get_flags,
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen index_mail_get_keywords,
a757f31393b9d6fc7760a9dec8363404ab3ae576Timo Sirainen index_mail_get_keyword_indexes,
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen index_mail_get_modseq,
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,
9af6cc9ebc9986c1275ebdfa29c39e152af1557eTimo Sirainen index_mail_get_real_mail,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen index_mail_update_flags,
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen index_mail_update_keywords,
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen index_mail_update_modseq,
225e82df5dd1e765f4e52b80c954558f00e5a7dfTimo Sirainen maildir_update_pop3_uidl,
838e367716bbd5e44b4a1691db9cbf72af53e9f0Timo Sirainen index_mail_expunge,
6564208826b0f46a00f010d1b5711d85944c3c88Timo Sirainen maildir_mail_set_cache_corrupted,
6564208826b0f46a00f010d1b5711d85944c3c88Timo Sirainen index_mail_opened
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};