cydir-mail.c revision aa247243412a49f9bdebf7255e131dc6ece4ed46
45312f52ff3a3d4c137447be4c7556500c2f8bf2Timo Sirainen/* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#include "lib.h"
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#include "istream.h"
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#include "index-mail.h"
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#include "cydir-storage.h"
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#include <fcntl.h>
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#include <unistd.h>
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#include <sys/stat.h>
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainenstatic const char *cydir_mail_get_path(struct mail *mail)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen{
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen const char *dir;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen dir = mailbox_list_get_path(mail->box->storage->list, mail->box->name,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen MAILBOX_LIST_PATH_TYPE_MAILBOX);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen return t_strdup_printf("%s/%u.", dir, mail->uid);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen}
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainenstatic int cydir_mail_stat(struct mail *mail, struct stat *st_r)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen{
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen const char *path;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen path = cydir_mail_get_path(mail);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen if (stat(path, st_r) < 0) {
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen if (errno == ENOENT)
910fa4e4204a73d3d24c03f3059dd24e727ca057Timo Sirainen mail_set_expunged(mail);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen else {
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen mail_storage_set_critical(mail->box->storage,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen "stat(%s) failed: %m", path);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen }
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen return -1;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen }
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen return 0;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen}
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenstatic int cydir_mail_get_received_date(struct mail *_mail, time_t *date_r)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen{
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct index_mail_data *data = &mail->data;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct stat st;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen if (index_mail_get_received_date(_mail, date_r) == 0)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return 0;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen if (cydir_mail_stat(_mail, &st) < 0)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return -1;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen data->received_date = st.st_mtime;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen *date_r = data->received_date;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return 0;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen}
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenstatic int cydir_mail_get_save_date(struct mail *_mail, time_t *date_r)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen{
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct index_mail_data *data = &mail->data;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct stat st;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen if (index_mail_get_save_date(_mail, date_r) == 0)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return 0;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen if (cydir_mail_stat(_mail, &st) < 0)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen return (time_t)-1;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen data->save_date = st.st_ctime;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen *date_r = data->save_date;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return 0;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen}
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenstatic int cydir_mail_get_physical_size(struct mail *_mail, uoff_t *size_r)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen{
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct index_mail_data *data = &mail->data;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct stat st;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen if (index_mail_get_physical_size(_mail, size_r) == 0)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return 0;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen if (cydir_mail_stat(_mail, &st) < 0)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return -1;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
75f3dddc3a5922c92a1bdb921b653ead51227cabTimo Sirainen data->physical_size = data->virtual_size = st.st_size;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen *size_r = data->physical_size;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return 0;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen}
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenstatic int
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainencydir_mail_get_stream(struct mail *_mail, struct message_size *hdr_size,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen struct message_size *body_size, struct istream **stream_r)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen{
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen const char *path;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen int fd;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen if (mail->data.stream == NULL) {
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen path = cydir_mail_get_path(_mail);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen fd = open(path, O_RDONLY);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen if (fd == -1) {
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen if (errno == ENOENT)
910fa4e4204a73d3d24c03f3059dd24e727ca057Timo Sirainen mail_set_expunged(_mail);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen else {
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen mail_storage_set_critical(_mail->box->storage,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen "open(%s) failed: %m", path);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen }
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return -1;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen }
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen mail->data.stream =
2526d52441ef368215ab6bf04fd0356d3b09d235Timo Sirainen i_stream_create_fd(fd, MAIL_READ_BLOCK_SIZE, TRUE);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen }
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return index_mail_init_stream(mail, hdr_size, body_size, stream_r);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen}
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainenstruct mail_vfuncs cydir_mail_vfuncs = {
0d86aa0d47f7393c669c084b34c0537b193688adTimo Sirainen index_mail_close,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_mail_free,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_mail_set_seq,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_mail_set_uid,
aa247243412a49f9bdebf7255e131dc6ece4ed46Timo Sirainen index_mail_set_uid_cache_updates,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_mail_get_flags,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_mail_get_keywords,
a757f31393b9d6fc7760a9dec8363404ab3ae576Timo Sirainen index_mail_get_keyword_indexes,
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen index_mail_get_modseq,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_mail_get_parts,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_mail_get_date,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen cydir_mail_get_received_date,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen cydir_mail_get_save_date,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen cydir_mail_get_physical_size, /* physical = virtual in our case */
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen cydir_mail_get_physical_size,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_mail_get_first_header,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_mail_get_headers,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_mail_get_header_stream,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen cydir_mail_get_stream,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_mail_get_special,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_mail_update_flags,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_mail_update_keywords,
838e367716bbd5e44b4a1691db9cbf72af53e9f0Timo Sirainen index_mail_expunge,
01404d41657a104c5ea1c12bb87f9c321e9c1ac4Timo Sirainen index_mail_set_cache_corrupted,
01404d41657a104c5ea1c12bb87f9c321e9c1ac4Timo Sirainen index_mail_get_index_mail
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen};