mbox-mail.c revision 18565c69efcd7db003dbf27cf625ed822e889fb1
7cb128dc4cae2a03a742f63ba7afee23c78e3af0Phil Carmody/* Copyright (C) 2003 Timo Sirainen */
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen#include "lib.h"
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen#include "istream.h"
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen#include "index-mail.h"
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainen#include "mbox-storage.h"
65988f5a8abed57e9894fec77105941e046d3490Timo Sirainen#include "mbox-file.h"
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen#include "mbox-sync-private.h"
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen#include "istream-raw-mbox.h"
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainen#include "istream-header-filter.h"
dabb4cec4cf9bdb34013de682b08f1284cfb670fTimo Sirainen
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen#include <fcntl.h>
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen#include <unistd.h>
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen#include <sys/stat.h>
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen
64510d2cc23a79d2142030bf5bade44baa490db3Timo Sirainenstatic int mbox_mail_seek(struct index_mail *mail)
64510d2cc23a79d2142030bf5bade44baa490db3Timo Sirainen{
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen struct index_mailbox *ibox = mail->ibox;
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen const void *data;
5cbefc6537aefbf1491416c433de00fc3e649a13Timo Sirainen uint64_t offset;
d9076f5939edf5d20a261494b1a861dcbb0d32e2Timo Sirainen int ret;
f335accff54f408a8bbb328f8098ad458f2ff58eTimo Sirainen
f335accff54f408a8bbb328f8098ad458f2ff58eTimo Sirainen if (ibox->mbox_lock_type == F_UNLCK) {
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen if (mbox_sync(ibox, FALSE, FALSE, TRUE) < 0)
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen return -1;
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen
2e03303e721a293d796c0287829396f5caea76eaTimo Sirainen i_assert(ibox->mbox_lock_type != F_UNLCK);
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen mail->ibox->mbox_mail_lock_id = ibox->mbox_lock_id;
2c70dc3ca3f0e9e67b76065c4824aba6b2e4251cTimo Sirainen }
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen if (mbox_file_open_stream(ibox) < 0)
db24d60c306c9d477392ff5b61cb3fc95fef3bb7Timo Sirainen return -1;
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen ret = mail_index_lookup_extra(ibox->view, mail->mail.seq,
4e2d7dd2b201ae2083b6637d7ec0d37f49faca45Timo Sirainen ibox->mbox_extra_idx, &data);
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen if (ret <= 0) {
5cbefc6537aefbf1491416c433de00fc3e649a13Timo Sirainen if (ret < 0)
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen mail_storage_set_index_error(ibox);
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen return -1;
7e50cca6b1dab5a7e2a90a8949678c62f4a0958aTimo Sirainen }
7e50cca6b1dab5a7e2a90a8949678c62f4a0958aTimo Sirainen
7e50cca6b1dab5a7e2a90a8949678c62f4a0958aTimo Sirainen offset = *((const uint64_t *)data);
7e50cca6b1dab5a7e2a90a8949678c62f4a0958aTimo Sirainen if (istream_raw_mbox_seek(ibox->mbox_stream, offset) < 0) {
5cbefc6537aefbf1491416c433de00fc3e649a13Timo Sirainen mail_storage_set_critical(ibox->box.storage,
d9076f5939edf5d20a261494b1a861dcbb0d32e2Timo Sirainen "Cached message offset %s is invalid for mbox file %s",
d9076f5939edf5d20a261494b1a861dcbb0d32e2Timo Sirainen dec2str(offset), ibox->path);
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen mail_index_mark_corrupted(ibox->index);
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen return -1;
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen }
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen return 0;
5cbefc6537aefbf1491416c433de00fc3e649a13Timo Sirainen}
d9076f5939edf5d20a261494b1a861dcbb0d32e2Timo Sirainen
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainenstatic const struct mail_full_flags *mbox_mail_get_flags(struct mail *_mail)
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen{
db24d60c306c9d477392ff5b61cb3fc95fef3bb7Timo Sirainen return index_mail_get_flags(_mail);
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen /*FIXME:struct index_mail *mail = (struct index_mail *)_mail;
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen struct index_mail_data *data = &mail->data;
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen i_assert(_mail->seq <= mail->ibox->mbox_data_count);
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen (void)index_mail_get_flags(_mail);
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen if ((mail->ibox->mbox_data[_mail->seq-1] & 1) != 0)
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen data->flags.flags |= MAIL_RECENT;
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen
c69a255a68103a50fa3f04a527281a169075403fTimo Sirainen return &data->flags;*/
c69a255a68103a50fa3f04a527281a169075403fTimo Sirainen}
c69a255a68103a50fa3f04a527281a169075403fTimo Sirainen
db24d60c306c9d477392ff5b61cb3fc95fef3bb7Timo Sirainenstatic time_t mbox_mail_get_received_date(struct mail *_mail)
0f66f12eb4cdbf47670975044c88d8f388bf92dfTimo Sirainen{
0f66f12eb4cdbf47670975044c88d8f388bf92dfTimo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
2e03303e721a293d796c0287829396f5caea76eaTimo Sirainen struct index_mail_data *data = &mail->data;
c69a255a68103a50fa3f04a527281a169075403fTimo Sirainen
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen (void)index_mail_get_received_date(_mail);
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen if (data->received_date != (time_t)-1)
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen return data->received_date;
7e50cca6b1dab5a7e2a90a8949678c62f4a0958aTimo Sirainen
7e50cca6b1dab5a7e2a90a8949678c62f4a0958aTimo Sirainen if (mbox_mail_seek(mail) < 0)
7e50cca6b1dab5a7e2a90a8949678c62f4a0958aTimo Sirainen return (time_t)-1;
7e50cca6b1dab5a7e2a90a8949678c62f4a0958aTimo Sirainen data->received_date =
7e50cca6b1dab5a7e2a90a8949678c62f4a0958aTimo Sirainen istream_raw_mbox_get_received_time(mail->ibox->mbox_stream);
7e50cca6b1dab5a7e2a90a8949678c62f4a0958aTimo Sirainen if (data->received_date == (time_t)-1) {
7e50cca6b1dab5a7e2a90a8949678c62f4a0958aTimo Sirainen /* it's broken and conflicts with our "not found"
7e50cca6b1dab5a7e2a90a8949678c62f4a0958aTimo Sirainen return value. change it. */
7e50cca6b1dab5a7e2a90a8949678c62f4a0958aTimo Sirainen data->received_date = 0;
7e50cca6b1dab5a7e2a90a8949678c62f4a0958aTimo Sirainen }
4e2d7dd2b201ae2083b6637d7ec0d37f49faca45Timo Sirainen
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen index_mail_cache_add(mail, MAIL_CACHE_RECEIVED_DATE,
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainen &data->received_date,
4e2d7dd2b201ae2083b6637d7ec0d37f49faca45Timo Sirainen sizeof(data->received_date));
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainen return data->received_date;
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainen}
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainen
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainenstatic const char *
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainenmbox_mail_get_special(struct mail *_mail, enum mail_fetch_field field)
4e8d6d03c2ff85448df79b181a2ea850fb5d4199Timo Sirainen{
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen
4e2d7dd2b201ae2083b6637d7ec0d37f49faca45Timo Sirainen if (field == MAIL_FETCH_FROM_ENVELOPE) {
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainen if (mbox_mail_seek(mail) < 0)
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen return NULL;
87b426af6a2365c6840b14281a98c23e903bf28eTimo Sirainen
87b426af6a2365c6840b14281a98c23e903bf28eTimo Sirainen return istream_raw_mbox_get_sender(mail->ibox->mbox_stream);
4e2d7dd2b201ae2083b6637d7ec0d37f49faca45Timo Sirainen
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen }
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen
87b426af6a2365c6840b14281a98c23e903bf28eTimo Sirainen return index_mail_get_special(_mail, field);
4e2d7dd2b201ae2083b6637d7ec0d37f49faca45Timo Sirainen}
87b426af6a2365c6840b14281a98c23e903bf28eTimo Sirainen
4e2d7dd2b201ae2083b6637d7ec0d37f49faca45Timo Sirainenstatic struct istream *mbox_mail_get_stream(struct mail *_mail,
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen struct message_size *hdr_size,
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen struct message_size *body_size)
87b426af6a2365c6840b14281a98c23e903bf28eTimo Sirainen{
4e2d7dd2b201ae2083b6637d7ec0d37f49faca45Timo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen struct index_mail_data *data = &mail->data;
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen struct istream *raw_stream;
4e2d7dd2b201ae2083b6637d7ec0d37f49faca45Timo Sirainen uoff_t offset;
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen if (data->stream == NULL) {
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen if (mbox_mail_seek(mail) < 0)
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainen return NULL;
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainen
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen // FIXME: need to hide the headers
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainen raw_stream = mail->ibox->mbox_stream;
dabb4cec4cf9bdb34013de682b08f1284cfb670fTimo Sirainen offset = istream_raw_mbox_get_header_offset(raw_stream);
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainen raw_stream = i_stream_create_limit(default_pool, raw_stream,
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainen offset, (uoff_t)-1);
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainen data->stream =
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainen i_stream_create_header_filter(default_pool,
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainen raw_stream,
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainen mbox_hide_headers,
4e8d6d03c2ff85448df79b181a2ea850fb5d4199Timo Sirainen mbox_hide_headers_count);
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainen i_stream_unref(raw_stream);
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen }
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainen
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen return index_mail_init_stream(mail, hdr_size, body_size);
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainen}
dabb4cec4cf9bdb34013de682b08f1284cfb670fTimo Sirainen
dabb4cec4cf9bdb34013de682b08f1284cfb670fTimo Sirainenstruct mail mbox_mail = {
dabb4cec4cf9bdb34013de682b08f1284cfb670fTimo Sirainen 0, 0, 0, 0, 0, 0,
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainen
687d1dee0e92229232aa8be416897b640df67d07Timo Sirainen mbox_mail_get_flags,
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen index_mail_get_parts,
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen mbox_mail_get_received_date,
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen index_mail_get_date,
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen index_mail_get_size,
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen index_mail_get_header,
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen index_mail_get_headers,
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen mbox_mail_get_stream,
0ce8f754204c7eeb33805993807393f74faf2cd3Timo Sirainen mbox_mail_get_special,
0ce8f754204c7eeb33805993807393f74faf2cd3Timo Sirainen index_mail_update_flags,
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen index_mail_expunge
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen};
050975ee630c761ab237fce7b8f84fe189bb02d2Timo Sirainen