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);
index_mail_update_modseq,
NULL,
index_mail_expunge,
- index_mail_set_cache_corrupted
+ index_mail_set_cache_corrupted,
+ index_mail_opened
};
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);
&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);
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;
}
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;
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",
/* 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
#include "eacces-error.h"
#include "str.h"
#include "dbox-storage.h"
-#include "dbox-attachment.h"
#include "dbox-file.h"
#include <stdio.h>
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)
{
/* 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,
#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"
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)
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_mail_update_modseq,
NULL,
index_mail_expunge,
- index_mail_set_cache_corrupted
+ index_mail_set_cache_corrupted,
+ index_mail_opened
};
index_mail_update_modseq,
NULL,
index_mail_expunge,
- index_mail_set_cache_corrupted
+ index_mail_set_cache_corrupted,
+ index_mail_opened
};
"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;
+}
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,
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);
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_mail_update_modseq,
NULL,
index_mail_expunge,
- index_mail_set_cache_corrupted
+ index_mail_set_cache_corrupted,
+ index_mail_opened
};
index_mail_update_modseq,
NULL,
index_mail_expunge,
- index_mail_set_cache_corrupted
+ index_mail_set_cache_corrupted,
+ index_mail_opened
};
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 {
test_mail_update_modseq,
NULL,
test_mail_expunge,
- test_mail_set_cache_corrupted
+ test_mail_set_cache_corrupted,
+ NULL
};
index_mail_update_modseq,
virtual_mail_update_pop3_uidl,
virtual_mail_expunge,
- virtual_mail_set_cache_corrupted
+ virtual_mail_set_cache_corrupted,
+ NULL
};