# HG changeset patch # User Timo Sirainen # Date 1242666565 14400 # Node ID 44548a7fb10d6ad4475d5d6c81aa901a6dd21854 # Parent d99c62c8ddd215a45ffff49c602d9564cdcb3df3 message-decoder now supports optionally returning non-text bodyparts as-is. diff -r d99c62c8ddd2 -r 44548a7fb10d src/lib-mail/message-decoder.c --- a/src/lib-mail/message-decoder.c Mon May 18 02:41:22 2009 -0400 +++ b/src/lib-mail/message-decoder.c Mon May 18 13:09:25 2009 -0400 @@ -28,6 +28,7 @@ #define MAX_TRANSLATION_BUF_SIZE 10 struct message_decoder_context { + enum message_decoder_flags flags; struct message_part *prev_part; struct message_header_line hdr; @@ -44,16 +45,17 @@ char *content_charset; enum content_type content_type; - unsigned int dtcase:1; unsigned int charset_utf8:1; + unsigned int binary_input:1; }; -struct message_decoder_context *message_decoder_init(bool dtcase) +struct message_decoder_context * +message_decoder_init(enum message_decoder_flags flags) { struct message_decoder_context *ctx; ctx = i_new(struct message_decoder_context, 1); - ctx->dtcase = dtcase; + ctx->flags = flags; ctx->buf = buffer_create_dynamic(default_pool, 8192); ctx->buf2 = buffer_create_dynamic(default_pool, 8192); return ctx; @@ -139,6 +141,7 @@ struct message_header_line *hdr, struct message_block *output) { + bool dtcase = (ctx->flags & MESSAGE_DECODER_FLAG_DTCASE) != 0; size_t value_len; if (hdr->continues) { @@ -157,10 +160,10 @@ buffer_set_used_size(ctx->buf, 0); message_header_decode_utf8(hdr->full_value, hdr->full_value_len, - ctx->buf, ctx->dtcase); + ctx->buf, dtcase); value_len = ctx->buf->used; - if (ctx->dtcase) { + if (dtcase) { (void)uni_utf8_to_decomposed_titlecase(hdr->name, hdr->name_len, ctx->buf); buffer_append_c(ctx->buf, '\0'); @@ -170,7 +173,7 @@ ctx->hdr.full_value = ctx->buf->data; ctx->hdr.full_value_len = value_len; ctx->hdr.value_len = 0; - if (ctx->dtcase) { + if (dtcase) { ctx->hdr.name = CONST_PTR_OFFSET(ctx->buf->data, ctx->hdr.full_value_len); ctx->hdr.name_len = ctx->buf->used - 1 - value_len; @@ -210,7 +213,9 @@ ctx->translation_size = 0; } -static void message_decode_body_init_charset(struct message_decoder_context *ctx) +static void +message_decode_body_init_charset(struct message_decoder_context *ctx, + struct message_part *part) { enum charset_flags flags; @@ -225,9 +230,17 @@ if (ctx->charset_trans != NULL) charset_to_utf8_end(&ctx->charset_trans); - i_free(ctx->charset_trans_charset); + i_free_and_null(ctx->charset_trans_charset); - flags = ctx->dtcase ? CHARSET_FLAG_DECOMP_TITLECASE : 0; + ctx->binary_input = ctx->content_charset == NULL && + (ctx->flags & MESSAGE_DECODER_FLAG_RETURN_BINARY) != 0 && + (part->flags & (MESSAGE_PART_FLAG_TEXT | + MESSAGE_PART_FLAG_MESSAGE_RFC822)) == 0; + if (ctx->binary_input) + return; + + flags = (ctx->flags & MESSAGE_DECODER_FLAG_DTCASE) != 0 ? + CHARSET_FLAG_DECOMP_TITLECASE : 0; ctx->charset_trans_charset = i_strdup(ctx->content_charset != NULL ? ctx->content_charset : "UTF-8"); if (charset_to_utf8_begin(ctx->charset_trans_charset, @@ -318,9 +331,12 @@ ctx->encoding_size = 0; } - if (ctx->charset_utf8) { + if (ctx->binary_input) { + output->data = data; + output->size = size; + } else if (ctx->charset_utf8) { buffer_set_used_size(ctx->buf2, 0); - if (ctx->dtcase) { + if ((ctx->flags & MESSAGE_DECODER_FLAG_DTCASE) != 0) { (void)uni_utf8_to_decomposed_titlecase(data, size, ctx->buf2); output->data = ctx->buf2->data; @@ -384,7 +400,7 @@ else { output->hdr = NULL; output->size = 0; - message_decode_body_init_charset(ctx); + message_decode_body_init_charset(ctx, input->part); return TRUE; } } diff -r d99c62c8ddd2 -r 44548a7fb10d src/lib-mail/message-decoder.h --- a/src/lib-mail/message-decoder.h Mon May 18 02:41:22 2009 -0400 +++ b/src/lib-mail/message-decoder.h Mon May 18 13:09:25 2009 -0400 @@ -1,13 +1,20 @@ #ifndef MESSAGE_DECODER_H #define MESSAGE_DECODER_H +enum message_decoder_flags { + /* Return all headers and parts through + uni_utf8_to_decomposed_titlecase() */ + MESSAGE_DECODER_FLAG_DTCASE = 0x01, + /* Return binary MIME parts as-is without any conversion. */ + MESSAGE_DECODER_FLAG_RETURN_BINARY = 0x02 +}; + struct message_block; /* Decode message's contents as UTF-8, both the headers and the MIME bodies. - The bodies are decoded from quoted-printable and base64 formats if needed. - If dtcase=TRUE, the data is returned through - uni_utf8_to_decomposed_titlecase(). */ -struct message_decoder_context *message_decoder_init(bool dtcase); + The bodies are decoded from quoted-printable and base64 formats if needed. */ +struct message_decoder_context * +message_decoder_init(enum message_decoder_flags flags); void message_decoder_deinit(struct message_decoder_context **ctx); /* Decode input and return decoded output. Headers are returned only in their diff -r d99c62c8ddd2 -r 44548a7fb10d src/lib-mail/message-search.c --- a/src/lib-mail/message-search.c Mon May 18 02:41:22 2009 -0400 +++ b/src/lib-mail/message-search.c Mon May 18 13:09:25 2009 -0400 @@ -46,7 +46,7 @@ ctx->key_len = str_len(key_utf8); ctx->key_charset = i_strdup(charset); ctx->flags = flags; - ctx->decoder = message_decoder_init(TRUE); + ctx->decoder = message_decoder_init(MESSAGE_DECODER_FLAG_DTCASE); ctx->str_find_ctx = str_find_init(default_pool, ctx->key); ret = 1; } diff -r d99c62c8ddd2 -r 44548a7fb10d src/plugins/fts/fts-storage.c --- a/src/plugins/fts/fts-storage.c Mon May 18 02:41:22 2009 -0400 +++ b/src/plugins/fts/fts-storage.c Mon May 18 13:09:25 2009 -0400 @@ -126,7 +126,7 @@ parser = message_parser_init(pool_datastack_create(), input, MESSAGE_HEADER_PARSER_FLAG_CLEAN_ONELINE, 0); - decoder = message_decoder_init(TRUE); + decoder = message_decoder_init(MESSAGE_DECODER_FLAG_DTCASE); for (;;) { ret = message_parser_parse_next_block(parser, &raw_block); i_assert(ret != 0);