Esempio n. 1
0
bool message_search_more_get_decoded(struct message_search_context *ctx,
				     struct message_block *raw_block,
				     struct message_block *decoded_block_r)
{
	struct message_header_line *hdr = raw_block->hdr;
	struct message_block decoded_block;

	memset(decoded_block_r, 0, sizeof(*decoded_block_r));
	decoded_block_r->part = raw_block->part;

	if (raw_block->part != ctx->prev_part) {
		/* part changes. we must change this before looking at
		   content type */
		message_search_reset(ctx);
		ctx->prev_part = raw_block->part;

		if (hdr == NULL) {
			/* we're returning to a multipart message. */
			ctx->content_type_text = FALSE;
		}
	}

	if (hdr != NULL) {
		handle_header(ctx, hdr);
		if ((ctx->flags & MESSAGE_SEARCH_FLAG_SKIP_HEADERS) != 0) {
			/* we want to search only message bodies, but
			   but decoder needs some headers so that it can
			   decode the body properly. */
			if (hdr->name_len != 12 && hdr->name_len != 25)
				return FALSE;
			if (strcasecmp(hdr->name, "Content-Type") != 0 &&
			    strcasecmp(hdr->name,
				       "Content-Transfer-Encoding") != 0)
				return FALSE;
		}
	} else {
		/* body */
		if (!ctx->content_type_text)
			return FALSE;
	}
	if (!message_decoder_decode_next_block(ctx->decoder, raw_block,
					       &decoded_block))
		return FALSE;

	if (decoded_block.hdr != NULL &&
	    (ctx->flags & MESSAGE_SEARCH_FLAG_SKIP_HEADERS) != 0) {
		/* Content-* header */
		return FALSE;
	}

	*decoded_block_r = decoded_block;
	return message_search_more_decoded2(ctx, &decoded_block);
}
Esempio n. 2
0
int message_snippet_generate(struct istream *input,
			     unsigned int max_snippet_chars,
			     string_t *snippet)
{
	struct message_parser_ctx *parser;
	struct message_part *parts;
	struct message_decoder_context *decoder;
	struct message_block raw_block, block;
	struct snippet_context ctx;
	pool_t pool;
	int ret;

	memset(&ctx, 0, sizeof(ctx));
	pool = pool_alloconly_create("message snippet", 1024);
	ctx.snippet = snippet;
	ctx.chars_left = max_snippet_chars;

	parser = message_parser_init(pool_datastack_create(), input, 0, 0);
	decoder = message_decoder_init(NULL, 0);
	while ((ret = message_parser_parse_next_block(parser, &raw_block)) > 0) {
		if (!message_decoder_decode_next_block(decoder, &raw_block, &block))
			continue;
		if (block.size == 0) {
			const char *ct;

			if (block.hdr != NULL)
				continue;

			/* end of headers - verify that we can use this
			   Content-Type. we get here only once, because we
			   always handle only one non-multipart MIME part. */
			ct = message_decoder_current_content_type(decoder);
			if (ct == NULL)
				/* text/plain */ ;
			else if (mail_html2text_content_type_match(ct)) {
				ctx.html2text = mail_html2text_init(MAIL_HTML2TEXT_FLAG_SKIP_QUOTED);
				ctx.plain_output = buffer_create_dynamic(pool, 1024);
			} else if (strncasecmp(ct, "text/", 5) != 0)
				break;
			continue;
		}
		if (!snippet_generate(&ctx, block.data, block.size))
			break;
	}
	i_assert(ret != 0);
	message_decoder_deinit(&decoder);
	message_parser_deinit(&parser, &parts);
	if (ctx.html2text != NULL)
		mail_html2text_deinit(&ctx.html2text);
	pool_unref(&pool);
	return input->stream_errno == 0 ? 0 : -1;
}