Mercurial > dovecot > core-2.2
view src/lib-storage/index/imapc/imapc-mail.c @ 12615:3dde816d945d
imapc: Write large message bodies to temp files rather than keeping in memory.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 31 Jan 2011 04:02:04 +0200 |
parents | 391ba80cb125 |
children | 0c1e221fc140 |
line wrap: on
line source
/* Copyright (c) 2011 Dovecot authors, see the included COPYING file */ #include "lib.h" #include "str.h" #include "istream.h" #include "imapc-mail.h" #include "imapc-client.h" #include "imapc-storage.h" struct mail * imapc_mail_alloc(struct mailbox_transaction_context *t, enum mail_fetch_field wanted_fields, struct mailbox_header_lookup_ctx *wanted_headers) { struct imapc_mail *mail; pool_t pool; pool = pool_alloconly_create("mail", 2048); mail = p_new(pool, struct imapc_mail, 1); mail->imail.mail.pool = pool; index_mail_init(&mail->imail, t, wanted_fields, wanted_headers); return &mail->imail.mail.mail; } static void imapc_mail_free(struct mail *_mail) { struct imapc_mail *mail = (struct imapc_mail *)_mail; if (mail->body != NULL) buffer_free(&mail->body); index_mail_free(_mail); } static int imapc_mail_get_received_date(struct mail *_mail, time_t *date_r) { struct index_mail *mail = (struct index_mail *)_mail; struct index_mail_data *data = &mail->data; if (data->received_date == (time_t)-1) { if (imapc_mail_fetch(_mail, MAIL_FETCH_RECEIVED_DATE) < 0) return -1; if (data->received_date == (time_t)-1) { mail_storage_set_critical(_mail->box->storage, "imapc: Remote server didn't send INTERNALDATE"); return -1; } } *date_r = data->received_date; return 0; } static int imapc_mail_get_save_date(struct mail *_mail, time_t *date_r) { struct index_mail *mail = (struct index_mail *)_mail; struct index_mail_data *data = &mail->data; if (data->save_date == (time_t)-1) { /* FIXME */ return -1; } *date_r = data->save_date; return 0; } static int imapc_mail_get_sizes(struct index_mail *mail) { struct message_size hdr_size, body_size; struct istream *input; uoff_t old_offset; /* fallback to reading the file */ old_offset = mail->data.stream->v_offset; if (mail_get_stream(&mail->mail.mail, &hdr_size, &body_size, &input) < 0) return -1; i_stream_seek(mail->data.stream, old_offset); return 0; } static int imapc_mail_get_virtual_size(struct mail *_mail, uoff_t *size_r) { struct index_mail *mail = (struct index_mail *)_mail; struct index_mail_data *data = &mail->data; if (data->virtual_size == (uoff_t)-1) { if (imapc_mail_get_sizes(mail) < 0) return -1; } *size_r = data->virtual_size; return 0; } static int imapc_mail_get_physical_size(struct mail *_mail, uoff_t *size_r) { struct index_mail *mail = (struct index_mail *)_mail; struct index_mail_data *data = &mail->data; if (data->physical_size == (uoff_t)-1) { if (imapc_mail_get_sizes(mail) < 0) return -1; } *size_r = data->physical_size; return 0; } static int imapc_mail_get_stream(struct mail *_mail, struct message_size *hdr_size, struct message_size *body_size, struct istream **stream_r) { struct index_mail *mail = (struct index_mail *)_mail; struct index_mail_data *data = &mail->data; enum mail_fetch_field fetch_field; if (data->stream == NULL) { if (!mail->data.initialized) { /* coming here from mail_set_seq() */ return -1; } fetch_field = body_size != NULL || (mail->wanted_fields & MAIL_FETCH_STREAM_BODY) != 0 ? MAIL_FETCH_STREAM_BODY : MAIL_FETCH_STREAM_HEADER; if (imapc_mail_fetch(_mail, fetch_field) < 0) return -1; if (data->stream == NULL) { mail_storage_set_critical(_mail->box->storage, "imapc: Remote server didn't send BODY[]"); return -1; } } return index_mail_init_stream(mail, hdr_size, body_size, stream_r); } struct mail_vfuncs imapc_mail_vfuncs = { index_mail_close, imapc_mail_free, index_mail_set_seq, index_mail_set_uid, index_mail_set_uid_cache_updates, index_mail_get_flags, index_mail_get_keywords, index_mail_get_keyword_indexes, index_mail_get_modseq, index_mail_get_parts, index_mail_get_date, imapc_mail_get_received_date, imapc_mail_get_save_date, imapc_mail_get_virtual_size, imapc_mail_get_physical_size, index_mail_get_first_header, index_mail_get_headers, index_mail_get_header_stream, imapc_mail_get_stream, index_mail_get_special, index_mail_get_real_mail, index_mail_update_flags, index_mail_update_keywords, index_mail_update_modseq, NULL, index_mail_expunge, index_mail_set_cache_corrupted, index_mail_opened };