From: Timo Sirainen Date: Wed, 20 Oct 2010 17:55:36 +0000 (+0100) Subject: lib-storage: Added istream_opened() method to struct mail. X-Git-Tag: 2.0.6~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6564208826b0f46a00f010d1b5711d85944c3c88;p=thirdparty%2Fdovecot%2Fcore.git lib-storage: Added istream_opened() method to struct mail. This can be hooked into by plugins that want to do something with the message's stream in the message file, rather than the virtual resulting stream visible to client. For example when using dbox attachments, this stream contains only the data in the dbox files without any external attachments. --- diff --git a/src/lib-storage/index/cydir/cydir-mail.c b/src/lib-storage/index/cydir/cydir-mail.c index 008ddfed17..2c5e522830 100644 --- a/src/lib-storage/index/cydir/cydir-mail.c +++ b/src/lib-storage/index/cydir/cydir-mail.c @@ -115,6 +115,10 @@ cydir_mail_get_stream(struct mail *_mail, struct message_size *hdr_size, mail->data.stream = i_stream_create_fd(fd, 0, TRUE); i_stream_set_name(mail->data.stream, path); index_mail_set_read_buffer_size(_mail, mail->data.stream); + if (mail->mail.v.istream_opened != NULL) { + if (mail->mail.v.istream_opened(_mail, stream_r) < 0) + return -1; + } } return index_mail_init_stream(mail, hdr_size, body_size, stream_r); @@ -148,5 +152,6 @@ struct mail_vfuncs cydir_mail_vfuncs = { index_mail_update_modseq, NULL, index_mail_expunge, - index_mail_set_cache_corrupted + index_mail_set_cache_corrupted, + index_mail_opened }; diff --git a/src/lib-storage/index/dbox-common/dbox-attachment.c b/src/lib-storage/index/dbox-common/dbox-attachment.c index c7f6b9364d..c99d321977 100644 --- a/src/lib-storage/index/dbox-common/dbox-attachment.c +++ b/src/lib-storage/index/dbox-common/dbox-attachment.c @@ -139,14 +139,14 @@ bool dbox_attachment_parse_extref(const char *line, pool_t pool, static int dbox_attachment_file_get_stream_from(struct dbox_file *file, const char *ext_refs, - struct istream **stream_r) + struct istream **stream) { ARRAY_TYPE(mail_attachment_extref) extrefs_arr; ARRAY_DEFINE(streams, struct istream *); const struct mail_attachment_extref *extref; struct istream **inputs, *input, *input2; const char *path, *path_suffix; - uoff_t root_offset, last_voffset = 0; + uoff_t last_voffset = 0; unsigned int i; t_array_init(&extrefs_arr, 16); @@ -154,7 +154,6 @@ dbox_attachment_file_get_stream_from(struct dbox_file *file, &extrefs_arr)) return 0; - root_offset = file->input->v_offset; t_array_init(&streams, 8); array_foreach(&extrefs_arr, extref) { path_suffix = file->storage->v.get_attachment_path_suffix(file); @@ -164,10 +163,9 @@ dbox_attachment_file_get_stream_from(struct dbox_file *file, if (extref->start_offset != last_voffset) { uoff_t part_size = extref->start_offset - last_voffset; - input = i_stream_create_limit(file->input, part_size); + input = i_stream_create_limit(*stream, part_size); array_append(&streams, &input, 1); - i_stream_seek(file->input, - file->input->v_offset + part_size); + i_stream_seek(*stream, (*stream)->v_offset + part_size); last_voffset += part_size; } @@ -187,24 +185,25 @@ dbox_attachment_file_get_stream_from(struct dbox_file *file, array_append(&streams, &input, 1); } - if (file->cur_physical_size != file->input->v_offset-root_offset) { + if (file->cur_physical_size != (*stream)->v_offset) { uoff_t trailer_size = file->cur_physical_size - - (file->input->v_offset - root_offset); + (*stream)->v_offset; - input = i_stream_create_limit(file->input, trailer_size); + input = i_stream_create_limit(*stream, trailer_size); array_append(&streams, &input, 1); (void)array_append_space(&streams); } inputs = array_idx_modifiable(&streams, 0); - *stream_r = i_stream_create_concat(inputs); + i_stream_unref(stream); + *stream = i_stream_create_concat(inputs); for (i = 0; inputs[i] != NULL; i++) i_stream_unref(&inputs[i]); return 1; } int dbox_attachment_file_get_stream(struct dbox_file *file, - struct istream **stream_r) + struct istream **stream) { const char *ext_refs; int ret; @@ -216,16 +215,13 @@ int dbox_attachment_file_get_stream(struct dbox_file *file, i_stream_seek(file->input, file->cur_offset + file->msg_header_size); ext_refs = dbox_file_metadata_get(file, DBOX_METADATA_EXT_REF); - if (ext_refs == NULL) { - *stream_r = i_stream_create_limit(file->input, - file->cur_physical_size); + if (ext_refs == NULL) return 1; - } /* we have external references. */ T_BEGIN { ret = dbox_attachment_file_get_stream_from(file, ext_refs, - stream_r); + stream); } T_END; if (ret == 0) { dbox_file_set_corrupted(file, "Ext refs metadata corrupted: %s", diff --git a/src/lib-storage/index/dbox-common/dbox-attachment.h b/src/lib-storage/index/dbox-common/dbox-attachment.h index afab07cdff..943bdf0ca1 100644 --- a/src/lib-storage/index/dbox-common/dbox-attachment.h +++ b/src/lib-storage/index/dbox-common/dbox-attachment.h @@ -15,6 +15,6 @@ bool dbox_attachment_parse_extref(const char *line, pool_t pool, /* Build a single message body stream out of the current message and all of its attachments. */ int dbox_attachment_file_get_stream(struct dbox_file *file, - struct istream **stream_r); + struct istream **stream); #endif diff --git a/src/lib-storage/index/dbox-common/dbox-file.c b/src/lib-storage/index/dbox-common/dbox-file.c index 65060267a5..b9d19bd72d 100644 --- a/src/lib-storage/index/dbox-common/dbox-file.c +++ b/src/lib-storage/index/dbox-common/dbox-file.c @@ -14,7 +14,6 @@ #include "eacces-error.h" #include "str.h" #include "dbox-storage.h" -#include "dbox-attachment.h" #include "dbox-file.h" #include @@ -390,21 +389,6 @@ int dbox_file_seek(struct dbox_file *file, uoff_t offset) return 1; } -int dbox_file_get_mail_stream(struct dbox_file *file, uoff_t offset, - struct istream **stream_r) -{ - int ret; - - if ((ret = dbox_file_seek(file, offset)) <= 0) - return ret; - - if (file->storage->attachment_dir != NULL) - return dbox_attachment_file_get_stream(file, stream_r); - - *stream_r = i_stream_create_limit(file->input, file->cur_physical_size); - return 1; -} - static int dbox_file_seek_next_at_metadata(struct dbox_file *file, uoff_t *offset) { diff --git a/src/lib-storage/index/dbox-common/dbox-file.h b/src/lib-storage/index/dbox-common/dbox-file.h index 26415b4dee..cc9e2ab369 100644 --- a/src/lib-storage/index/dbox-common/dbox-file.h +++ b/src/lib-storage/index/dbox-common/dbox-file.h @@ -156,9 +156,6 @@ void dbox_file_unlock(struct dbox_file *file); /* Seek to given offset in file. Returns 1 if ok/expunged, 0 if file/offset is corrupted, -1 if I/O error. */ int dbox_file_seek(struct dbox_file *file, uoff_t offset); -/* Same as dbox_file_seek(), but return also input stream for message. */ -int dbox_file_get_mail_stream(struct dbox_file *file, uoff_t offset, - struct istream **input_r); /* Start seeking at the beginning of the file. */ void dbox_file_seek_rewind(struct dbox_file *file); /* Seek to next message after current one. If there are no more messages, diff --git a/src/lib-storage/index/dbox-common/dbox-mail.c b/src/lib-storage/index/dbox-common/dbox-mail.c index 23a1d1f23f..af378982f5 100644 --- a/src/lib-storage/index/dbox-common/dbox-mail.c +++ b/src/lib-storage/index/dbox-common/dbox-mail.c @@ -5,6 +5,7 @@ #include "str.h" #include "index-storage.h" #include "index-mail.h" +#include "dbox-attachment.h" #include "dbox-storage.h" #include "dbox-file.h" #include "dbox-mail.h" @@ -211,7 +212,29 @@ int dbox_mail_get_special(struct mail *_mail, enum mail_fetch_field field, return index_mail_get_special(_mail, field, value_r); } - + +static int +get_mail_stream(struct dbox_mail *mail, uoff_t offset, + struct istream **stream_r) +{ + struct mail_private *pmail = &mail->imail.mail; + struct dbox_file *file = mail->open_file; + int ret; + + if ((ret = dbox_file_seek(file, offset)) <= 0) + return ret; + + *stream_r = i_stream_create_limit(file->input, file->cur_physical_size); + if (pmail->v.istream_opened != NULL) { + if (pmail->v.istream_opened(&pmail->mail, stream_r) < 0) + return -1; + } + if (file->storage->attachment_dir == NULL) + return 1; + else + return dbox_attachment_file_get_stream(file, stream_r); +} + int dbox_mail_get_stream(struct mail *_mail, struct message_size *hdr_size, struct message_size *body_size, struct istream **stream_r) @@ -228,8 +251,7 @@ int dbox_mail_get_stream(struct mail *_mail, struct message_size *hdr_size, if (storage->v.mail_open(mail, &offset, &mail->open_file) < 0) return -1; - ret = dbox_file_get_mail_stream(mail->open_file, offset, - &input); + ret = get_mail_stream(mail, offset, &input); if (ret <= 0) { if (ret < 0) return -1; diff --git a/src/lib-storage/index/dbox-multi/mdbox-mail.c b/src/lib-storage/index/dbox-multi/mdbox-mail.c index ddc7e12fd8..da776836c6 100644 --- a/src/lib-storage/index/dbox-multi/mdbox-mail.c +++ b/src/lib-storage/index/dbox-multi/mdbox-mail.c @@ -214,5 +214,6 @@ struct mail_vfuncs mdbox_mail_vfuncs = { index_mail_update_modseq, NULL, index_mail_expunge, - index_mail_set_cache_corrupted + index_mail_set_cache_corrupted, + index_mail_opened }; diff --git a/src/lib-storage/index/dbox-single/sdbox-mail.c b/src/lib-storage/index/dbox-single/sdbox-mail.c index d8a1a8bd19..0b573d910d 100644 --- a/src/lib-storage/index/dbox-single/sdbox-mail.c +++ b/src/lib-storage/index/dbox-single/sdbox-mail.c @@ -104,5 +104,6 @@ struct mail_vfuncs sdbox_mail_vfuncs = { index_mail_update_modseq, NULL, index_mail_expunge, - index_mail_set_cache_corrupted + index_mail_set_cache_corrupted, + index_mail_opened }; diff --git a/src/lib-storage/index/index-mail.c b/src/lib-storage/index/index-mail.c index 4847688f1b..89949c044c 100644 --- a/src/lib-storage/index/index-mail.c +++ b/src/lib-storage/index/index-mail.c @@ -1550,3 +1550,9 @@ void index_mail_set_cache_corrupted(struct mail *mail, "Broken %s for mail UID %u", field_name, mail->uid); } + +int index_mail_opened(struct mail *mail ATTR_UNUSED, + struct istream **stream ATTR_UNUSED) +{ + return 0; +} diff --git a/src/lib-storage/index/index-mail.h b/src/lib-storage/index/index-mail.h index 3a7c97c308..651d7d4380 100644 --- a/src/lib-storage/index/index-mail.h +++ b/src/lib-storage/index/index-mail.h @@ -204,6 +204,7 @@ void index_mail_update_modseq(struct mail *mail, uint64_t min_modseq); void index_mail_expunge(struct mail *mail); void index_mail_set_cache_corrupted(struct mail *mail, enum mail_fetch_field field); +int index_mail_opened(struct mail *mail, struct istream **stream); struct index_mail *index_mail_get_index_mail(struct mail *mail); bool index_mail_get_cached_uoff_t(struct index_mail *mail, diff --git a/src/lib-storage/index/maildir/maildir-mail.c b/src/lib-storage/index/maildir/maildir-mail.c index 3c17d20aa8..e54daa6293 100644 --- a/src/lib-storage/index/maildir/maildir-mail.c +++ b/src/lib-storage/index/maildir/maildir-mail.c @@ -549,6 +549,11 @@ static int maildir_mail_get_stream(struct mail *_mail, mail_set_expunged(_mail); return -1; } + if (mail->mail.v.istream_opened != NULL) { + if (mail->mail.v.istream_opened(_mail, + &data->stream) < 0) + return -1; + } } return index_mail_init_stream(mail, hdr_size, body_size, stream_r); @@ -633,5 +638,6 @@ struct mail_vfuncs maildir_mail_vfuncs = { index_mail_update_modseq, maildir_update_pop3_uidl, index_mail_expunge, - maildir_mail_set_cache_corrupted + maildir_mail_set_cache_corrupted, + index_mail_opened }; diff --git a/src/lib-storage/index/mbox/mbox-mail.c b/src/lib-storage/index/mbox/mbox-mail.c index 899a974e64..28b8afda08 100644 --- a/src/lib-storage/index/mbox/mbox-mail.c +++ b/src/lib-storage/index/mbox/mbox-mail.c @@ -409,5 +409,6 @@ struct mail_vfuncs mbox_mail_vfuncs = { index_mail_update_modseq, NULL, index_mail_expunge, - index_mail_set_cache_corrupted + index_mail_set_cache_corrupted, + index_mail_opened }; diff --git a/src/lib-storage/index/raw/raw-mail.c b/src/lib-storage/index/raw/raw-mail.c index e0885cf066..12ad9524f0 100644 --- a/src/lib-storage/index/raw/raw-mail.c +++ b/src/lib-storage/index/raw/raw-mail.c @@ -138,5 +138,6 @@ struct mail_vfuncs raw_mail_vfuncs = { index_mail_update_modseq, NULL, index_mail_expunge, - index_mail_set_cache_corrupted + index_mail_set_cache_corrupted, + index_mail_opened }; diff --git a/src/lib-storage/mail-storage-private.h b/src/lib-storage/mail-storage-private.h index 433bbf5b45..5644c686f3 100644 --- a/src/lib-storage/mail-storage-private.h +++ b/src/lib-storage/mail-storage-private.h @@ -329,6 +329,7 @@ struct mail_vfuncs { void (*expunge)(struct mail *mail); void (*set_cache_corrupted)(struct mail *mail, enum mail_fetch_field field); + int (*istream_opened)(struct mail *mail, struct istream **input); }; union mail_module_context { diff --git a/src/lib-storage/test-mail.c b/src/lib-storage/test-mail.c index ccf3b3a447..d9f5c26b6c 100644 --- a/src/lib-storage/test-mail.c +++ b/src/lib-storage/test-mail.c @@ -229,5 +229,6 @@ struct mail_vfuncs test_mail_vfuncs = { test_mail_update_modseq, NULL, test_mail_expunge, - test_mail_set_cache_corrupted + test_mail_set_cache_corrupted, + NULL }; diff --git a/src/plugins/virtual/virtual-mail.c b/src/plugins/virtual/virtual-mail.c index 579f1cd820..ae7a865174 100644 --- a/src/plugins/virtual/virtual-mail.c +++ b/src/plugins/virtual/virtual-mail.c @@ -407,5 +407,6 @@ struct mail_vfuncs virtual_mail_vfuncs = { index_mail_update_modseq, virtual_mail_update_pop3_uidl, virtual_mail_expunge, - virtual_mail_set_cache_corrupted + virtual_mail_set_cache_corrupted, + NULL };