]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Added istream_opened() method to struct mail.
authorTimo Sirainen <tss@iki.fi>
Wed, 20 Oct 2010 17:55:36 +0000 (18:55 +0100)
committerTimo Sirainen <tss@iki.fi>
Wed, 20 Oct 2010 17:55:36 +0000 (18:55 +0100)
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.

16 files changed:
src/lib-storage/index/cydir/cydir-mail.c
src/lib-storage/index/dbox-common/dbox-attachment.c
src/lib-storage/index/dbox-common/dbox-attachment.h
src/lib-storage/index/dbox-common/dbox-file.c
src/lib-storage/index/dbox-common/dbox-file.h
src/lib-storage/index/dbox-common/dbox-mail.c
src/lib-storage/index/dbox-multi/mdbox-mail.c
src/lib-storage/index/dbox-single/sdbox-mail.c
src/lib-storage/index/index-mail.c
src/lib-storage/index/index-mail.h
src/lib-storage/index/maildir/maildir-mail.c
src/lib-storage/index/mbox/mbox-mail.c
src/lib-storage/index/raw/raw-mail.c
src/lib-storage/mail-storage-private.h
src/lib-storage/test-mail.c
src/plugins/virtual/virtual-mail.c

index 008ddfed17ec7dc18bc6699bce25a0199ed87967..2c5e52283025b99377ee860065225685519e242a 100644 (file)
@@ -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
 };
index c7f6b9364de8c22c851158212ec881460e1c1fee..c99d321977f5d546d65db85ae6799a9825dffd2c 100644 (file)
@@ -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",
index afab07cdff2a325ddf608942f10d59d2400fbbd0..943bdf0ca14393f5b23810cc668d83e8b0102ccd 100644 (file)
@@ -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
index 65060267a587f4bc0d1f67726de1bd9729e3f851..b9d19bd72d35ff66f59e7686055d25f3e9f30da4 100644 (file)
@@ -14,7 +14,6 @@
 #include "eacces-error.h"
 #include "str.h"
 #include "dbox-storage.h"
-#include "dbox-attachment.h"
 #include "dbox-file.h"
 
 #include <stdio.h>
@@ -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)
 {
index 26415b4dee089b3357f3be94defaf1148b31724a..cc9e2ab3699ce5f9d2192eedc6ca555a899bfe37 100644 (file)
@@ -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,
index 23a1d1f23f75e70c2f3165547356ad729a7d17d8..af378982f5388a933b47aed24c32dec9ab6311ef 100644 (file)
@@ -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;
index ddc7e12fd8758b5de932f4ced4f710295c7f1934..da776836c6d27474490dc47d590281f8e31990a0 100644 (file)
@@ -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
 };
index d8a1a8bd1931501d20ba13ddc79026ab6b3c41ab..0b573d910dbb3c02df9af8f9640c752d018d459e 100644 (file)
@@ -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
 };
index 4847688f1b1c6c6dcb775ceb4573de6b962a6efa..89949c044c0873cc8f95cd0ae19d9c798541c87a 100644 (file)
@@ -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;
+}
index 3a7c97c308161799c6296ce0a6d208715d15a342..651d7d438085a97c94ebe860591bfd2fa1b39ec9 100644 (file)
@@ -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,
index 3c17d20aa857eff1f3c67330db598461e0e11c76..e54daa6293f657f8a2ed2feb6e8d089d957ae05c 100644 (file)
@@ -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
 };
index 899a974e6425ffe64f7e3d4660cf56fcc6c01498..28b8afda08393978ba12a1b1c6c7560df387a805 100644 (file)
@@ -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
 };
index e0885cf0665ceb1846d4eb04e8cf60500a46010e..12ad9524f079742781d07a3f4de950d0edaf91d0 100644 (file)
@@ -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
 };
index 433bbf5b45542e8f52bbb6aa47d12b066c281daa..5644c686f35ba0ef4b6762afa9b14198d2177725 100644 (file)
@@ -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 {
index ccf3b3a447d25169eeaa450730e3c7eaf064bf86..d9f5c26b6c291c3fc12d8138bd15f0cef6570c2b 100644 (file)
@@ -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
 };
index 579f1cd82083489d4fb55b295fe0044369de6764..ae7a865174be7d1ee5b222ce25cd2cb05407b641 100644 (file)
@@ -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
 };