dovecot-2.2: lib-storage: Use the new istream-attachment-* APIs ...
dovecot at dovecot.org
dovecot at dovecot.org
Fri Jun 29 08:01:25 EEST 2012
details: http://hg.dovecot.org/dovecot-2.2/rev/38b0986605a6
changeset: 14699:38b0986605a6
user: Timo Sirainen <tss at iki.fi>
date: Fri Jun 29 08:01:08 2012 +0300
description:
lib-storage: Use the new istream-attachment-* APIs to handle external mail attachments.
diffstat:
src/lib-storage/index/dbox-common/dbox-attachment.c | 82 +-
src/lib-storage/index/index-attachment.c | 713 +++----------------
2 files changed, 133 insertions(+), 662 deletions(-)
diffs (truncated from 925 to 300 lines):
diff -r ffab35ef2e5b -r 38b0986605a6 src/lib-storage/index/dbox-common/dbox-attachment.c
--- a/src/lib-storage/index/dbox-common/dbox-attachment.c Fri Jun 29 08:00:19 2012 +0300
+++ b/src/lib-storage/index/dbox-common/dbox-attachment.c Fri Jun 29 08:01:08 2012 +0300
@@ -2,10 +2,8 @@
#include "lib.h"
#include "istream.h"
-#include "istream-concat.h"
#include "str.h"
-#include "istream-sized.h"
-#include "istream-base64-encoder.h"
+#include "istream-attachment-connector.h"
#include "dbox-file.h"
#include "dbox-save.h"
#include "dbox-attachment.h"
@@ -143,13 +141,12 @@
const char **error_r)
{
ARRAY_TYPE(mail_attachment_extref) extrefs_arr;
- ARRAY_DEFINE(streams, struct istream *);
const struct mail_attachment_extref *extref;
- struct istream **inputs, *input, *input2;
+ struct istream_attachment_connector *conn;
+ struct istream *input;
const char *path, *path_suffix;
- uoff_t psize, last_voffset = 0;
- unsigned int i;
- int ret = 1;
+ uoff_t msg_size;
+ int ret;
*error_r = NULL;
@@ -159,69 +156,30 @@
*error_r = "Broken ext-refs string";
return 0;
}
- psize = dbox_file_get_plaintext_size(file);
+ msg_size = dbox_file_get_plaintext_size(file);
+ conn = istream_attachment_connector_begin(*stream, msg_size);
- t_array_init(&streams, 8);
+ path_suffix = file->storage->v.get_attachment_path_suffix(file);
array_foreach(&extrefs_arr, extref) {
- path_suffix = file->storage->v.get_attachment_path_suffix(file);
path = t_strdup_printf("%s/%s%s", file->storage->attachment_dir,
extref->path, path_suffix);
+ input = i_stream_create_file(path, IO_BLOCK_SIZE);
- if (extref->start_offset != last_voffset) {
- uoff_t part_size = extref->start_offset - last_voffset;
-
- if ((*stream)->v_offset + part_size > psize) {
- *error_r = t_strdup_printf(
- "ext-refs point outside message "
- "(%"PRIuUOFF_T" + %"PRIuUOFF_T" > %"PRIuUOFF_T")",
- (*stream)->v_offset, part_size, psize);
- ret = 0;
- }
-
- input = i_stream_create_limit(*stream, part_size);
- array_append(&streams, &input, 1);
- i_stream_seek(*stream, (*stream)->v_offset + part_size);
- last_voffset += part_size;
- }
-
- last_voffset += extref->size;
- input2 = i_stream_create_file(path, IO_BLOCK_SIZE);
-
- if (extref->base64_blocks_per_line > 0) {
- input = i_stream_create_base64_encoder(input2,
- extref->base64_blocks_per_line*4,
- extref->base64_have_crlf);
- i_stream_unref(&input2);
- input2 = input;
- }
-
- input = i_stream_create_sized(input2, extref->size);
- i_stream_unref(&input2);
- array_append(&streams, &input, 1);
- }
-
- if (psize != (*stream)->v_offset) {
- if ((*stream)->v_offset > psize) {
- *error_r = t_strdup_printf(
- "ext-refs point outside message "
- "(%"PRIuUOFF_T" > %"PRIuUOFF_T")",
- (*stream)->v_offset, psize);
- ret = 0;
- } else {
- uoff_t trailer_size = psize - last_voffset;
-
- input = i_stream_create_limit(*stream, trailer_size);
- array_append(&streams, &input, 1);
- array_append_zero(&streams);
+ ret = istream_attachment_connector_add(conn, input,
+ extref->start_offset, extref->size,
+ extref->base64_blocks_per_line,
+ extref->base64_have_crlf, error_r);
+ i_stream_unref(&input);
+ if (ret < 0) {
+ istream_attachment_connector_abort(&conn);
+ return 0;
}
}
- inputs = array_idx_modifiable(&streams, 0);
+ input = istream_attachment_connector_finish(&conn);
i_stream_unref(stream);
- *stream = i_stream_create_concat(inputs);
- for (i = 0; inputs[i] != NULL; i++)
- i_stream_unref(&inputs[i]);
- return ret;
+ *stream = input;
+ return 1;
}
int dbox_attachment_file_get_stream(struct dbox_file *file,
diff -r ffab35ef2e5b -r 38b0986605a6 src/lib-storage/index/index-attachment.c
--- a/src/lib-storage/index/index-attachment.c Fri Jun 29 08:00:19 2012 +0300
+++ b/src/lib-storage/index/index-attachment.c Fri Jun 29 08:01:08 2012 +0300
@@ -10,57 +10,17 @@
#include "str.h"
#include "message-parser.h"
#include "rfc822-parser.h"
+#include "istream-attachment-extractor.h"
#include "mail-user.h"
#include "index-mail.h"
#include "index-attachment.h"
-#define BASE64_ATTACHMENT_MAX_EXTRA_BYTES 1024
-
-enum mail_attachment_state {
- MAIL_ATTACHMENT_STATE_NO,
- MAIL_ATTACHMENT_STATE_MAYBE,
- MAIL_ATTACHMENT_STATE_YES
-};
-
-enum base64_state {
- BASE64_STATE_0 = 0,
- BASE64_STATE_1,
- BASE64_STATE_2,
- BASE64_STATE_3,
- BASE64_STATE_CR,
- BASE64_STATE_EOB,
- BASE64_STATE_EOM
-};
-
-struct mail_save_attachment_part {
- char *content_type, *content_disposition;
- enum mail_attachment_state state;
- /* start offset of the message part in the original input stream */
- uoff_t start_offset;
-
- /* for saving attachments base64-decoded: */
- enum base64_state base64_state;
- unsigned int base64_line_blocks, cur_base64_blocks;
- uoff_t base64_bytes;
- bool base64_have_crlf; /* CRLF linefeeds */
- bool base64_failed;
-
- int temp_fd;
- struct ostream *output;
- struct hash_format *part_hash;
- buffer_t *part_buf;
-};
-
struct mail_save_attachment {
pool_t pool;
- struct message_parser_ctx *parser;
struct fs *fs;
struct istream *input;
- /* per-MIME part data */
- struct mail_save_attachment_part part;
- struct message_part *prev_part;
-
+ struct fs_file *cur_file;
ARRAY_TYPE(mail_attachment_extref) extrefs;
};
@@ -70,102 +30,25 @@
storage->set->mail_attachment_dir);
}
-void index_attachment_save_begin(struct mail_save_context *ctx,
- struct fs *fs, struct istream *input)
+static bool index_attachment_want(const struct istream_attachment_header *hdr,
+ void *context)
{
- struct mail_storage *storage = ctx->transaction->box->storage;
- pool_t pool;
+ struct mail_save_context *ctx = context;
+ struct mail_attachment_part apart;
- i_assert(ctx->attach == NULL);
+ memset(&apart, 0, sizeof(apart));
+ apart.part = hdr->part;
+ apart.content_type = hdr->content_type;
+ apart.content_disposition = hdr->content_disposition;
- if (*storage->set->mail_attachment_dir == '\0')
- return;
-
- pool = pool_alloconly_create("save attachment", 1024*4);
- ctx->attach = p_new(pool, struct mail_save_attachment, 1);
- ctx->attach->pool = pool;
- ctx->attach->fs = fs;
- ctx->attach->input = input;
- ctx->attach->parser =
- message_parser_init(ctx->attach->pool, input, 0, 0);
- p_array_init(&ctx->attach->extrefs, ctx->attach->pool, 8);
+ return ctx->part_is_attachment == NULL ? TRUE :
+ ctx->part_is_attachment(ctx, &apart);
}
-static void parse_content_type(struct mail_save_context *ctx,
- const struct message_header_line *hdr)
+static int index_attachment_open_temp_fd(void *context)
{
- struct rfc822_parser_context parser;
- string_t *content_type;
-
- rfc822_parser_init(&parser, hdr->full_value, hdr->full_value_len, NULL);
- rfc822_skip_lwsp(&parser);
-
- T_BEGIN {
- content_type = t_str_new(64);
- if (rfc822_parse_content_type(&parser, content_type) >= 0) {
- i_free(ctx->attach->part.content_type);
- ctx->attach->part.content_type =
- i_strdup(str_c(content_type));
- }
- } T_END;
-}
-
-static void
-parse_content_disposition(struct mail_save_context *ctx,
- const struct message_header_line *hdr)
-{
- /* just pass it as-is to backend. */
- i_free(ctx->attach->part.content_disposition);
- ctx->attach->part.content_disposition =
- i_strndup(hdr->full_value, hdr->full_value_len);
-}
-
-static void index_attachment_save_mail_header(struct mail_save_context *ctx,
- struct message_header_line *hdr)
-{
- if (hdr->continues) {
- hdr->use_full_value = TRUE;
- return;
- }
-
- if (strcasecmp(hdr->name, "Content-Type") == 0)
- parse_content_type(ctx, hdr);
- else if (strcasecmp(hdr->name, "Content-Disposition") == 0)
- parse_content_disposition(ctx, hdr);
-
- o_stream_nsend(ctx->output, hdr->name, hdr->name_len);
- o_stream_nsend(ctx->output, hdr->middle, hdr->middle_len);
- o_stream_nsend(ctx->output, hdr->full_value, hdr->full_value_len);
- if (!hdr->no_newline) {
- if (hdr->crlf_newline)
- o_stream_nsend(ctx->output, "\r\n", 2);
- else
- o_stream_nsend(ctx->output, "\n", 1);
- }
-}
-
-static bool save_is_attachment(struct mail_save_context *ctx,
- struct message_part *part)
-{
- struct mail_attachment_part apart;
-
- if ((part->flags & MESSAGE_PART_FLAG_MULTIPART) != 0) {
- /* multiparts may contain attachments as children,
- but they're never themselves */
- return FALSE;
- }
- if (ctx->part_is_attachment == NULL)
- return TRUE;
-
- memset(&apart, 0, sizeof(apart));
- apart.part = part;
- apart.content_type = ctx->attach->part.content_type;
- apart.content_disposition = ctx->attach->part.content_disposition;
- return ctx->part_is_attachment(ctx, &apart);
-}
-
-static int index_attachment_save_temp_open_fd(struct mail_storage *storage)
-{
+ struct mail_save_context *ctx = context;
+ struct mail_storage *storage = ctx->transaction->box->storage;
string_t *temp_path;
int fd;
@@ -186,203 +69,22 @@
return fd;
}
More information about the dovecot-cvs
mailing list