From 735dd1d0545d8769ac018ff3714c01d39057d7ce Mon Sep 17 00:00:00 2001
From: Milan Crha <mcrha@redhat.com>
Date: Mon, 13 Dec 2010 16:30:21 +0100
Subject: Bug #436914 - Reply to inline GPG quotes raw GPG message

---
 em-format/Makefile.am        |   2 +
 em-format/em-format-quote.c  |  60 ++++++
 em-format/em-inline-filter.c | 444 +++++++++++++++++++++++++++++++++++++++++++
 em-format/em-inline-filter.h |  80 ++++++++
 mail/Makefile.am             |   2 -
 mail/em-format-html.c        |   2 +-
 mail/em-inline-filter.c      | 388 -------------------------------------
 mail/em-inline-filter.h      |  77 --------
 8 files changed, 587 insertions(+), 468 deletions(-)
 create mode 100644 em-format/em-inline-filter.c
 create mode 100644 em-format/em-inline-filter.h
 delete mode 100644 mail/em-inline-filter.c
 delete mode 100644 mail/em-inline-filter.h

diff --git a/em-format/Makefile.am b/em-format/Makefile.am
index 212b45f074..df052fe915 100644
--- a/em-format/Makefile.am
+++ b/em-format/Makefile.am
@@ -5,6 +5,7 @@ privsolib_LTLIBRARIES = libemformat.la
 emformatinclude_HEADERS =				\
 	em-format.h					\
 	em-format-quote.h				\
+	em-inline-filter.h				\
 	em-stripsig-filter.h
 
 libemformat_la_CPPFLAGS =				\
@@ -18,6 +19,7 @@ libemformat_la_SOURCES =				\
 	$(emformatinclude_HEADERS)			\
 	em-format.c					\
 	em-format-quote.c				\
+	em-inline-filter.c				\
 	em-stripsig-filter.c
 
 libemformat_la_LDFLAGS = $(NO_UNDEFINED)
diff --git a/em-format/em-format-quote.c b/em-format/em-format-quote.c
index 6d6ed6a4ab..bdb632b252 100644
--- a/em-format/em-format-quote.c
+++ b/em-format/em-format-quote.c
@@ -30,6 +30,7 @@
 #include <glib/gi18n.h>
 #include <gconf/gconf-client.h>
 
+#include "em-inline-filter.h"
 #include "em-stripsig-filter.h"
 #include "em-format-quote.h"
 
@@ -529,6 +530,52 @@ emfq_format_message (EMFormat *emf,
 			cancellable, NULL);
 }
 
+/* Decodes inline encoded parts of 'part'. The returned pointer, if not NULL, should
+   be unreffed with g_object_unref().
+*/
+static CamelMimePart *
+decode_inline_parts (CamelMimePart *part, GCancellable *cancellable)
+{
+	CamelMultipart *mp;
+	CamelStream *null;
+	CamelStream *filtered_stream;
+	EMInlineFilter *inline_filter;
+
+	g_return_val_if_fail (part != NULL, NULL);
+
+	null = camel_stream_null_new ();
+	filtered_stream = camel_stream_filter_new (null);
+	g_object_unref (null);
+
+	inline_filter = em_inline_filter_new (camel_mime_part_get_encoding (part), camel_mime_part_get_content_type (part));
+	camel_stream_filter_add (
+		CAMEL_STREAM_FILTER (filtered_stream),
+		CAMEL_MIME_FILTER (inline_filter));
+	camel_data_wrapper_decode_to_stream_sync (
+		camel_medium_get_content (CAMEL_MEDIUM (part)), (CamelStream *)filtered_stream, cancellable, NULL);
+	camel_stream_close ((CamelStream *)filtered_stream, cancellable, NULL);
+	g_object_unref (filtered_stream);
+
+	if (!em_inline_filter_found_any (inline_filter)) {
+		g_object_unref (inline_filter);
+		return NULL;
+	}
+
+	mp = em_inline_filter_get_multipart (inline_filter);
+
+	g_object_unref (inline_filter);
+
+	if (mp) {
+		part = camel_mime_part_new ();
+		camel_medium_set_content (CAMEL_MEDIUM (part), CAMEL_DATA_WRAPPER (mp));
+		g_object_unref (mp);
+	} else {
+		g_object_ref (part);
+	}
+
+	return part;
+}
+
 static void
 emfq_text_plain (EMFormat *emf,
                  CamelStream *stream,
@@ -541,6 +588,7 @@ emfq_text_plain (EMFormat *emf,
 	CamelStream *filtered_stream;
 	CamelMimeFilter *html_filter;
 	CamelMimeFilter *sig_strip;
+	CamelMimePart *mp;
 	CamelContentType *type;
 	const gchar *format;
 	guint32 rgb = 0x737373, flags;
@@ -548,6 +596,18 @@ emfq_text_plain (EMFormat *emf,
 	if (!part)
 		return;
 
+	mp = decode_inline_parts (part, cancellable);
+	if (mp) {
+		if (CAMEL_IS_MULTIPART (camel_medium_get_content (CAMEL_MEDIUM (mp)))) {
+			em_format_part (emf, stream, mp, cancellable);
+			g_object_unref (mp);
+
+			return;
+		}
+
+		g_object_unref (mp);
+	}
+
 	flags = emfq->text_html_flags;
 
 	/* Check for RFC 2646 flowed text. */
diff --git a/em-format/em-inline-filter.c b/em-format/em-inline-filter.c
new file mode 100644
index 0000000000..23e5a6f6ed
--- /dev/null
+++ b/em-format/em-inline-filter.c
@@ -0,0 +1,444 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ *		Michael Zucchi <notzed@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include "em-inline-filter.h"
+
+#include "em-format/em-format.h"
+
+#define d(x)
+
+G_DEFINE_TYPE (EMInlineFilter, em_inline_filter, CAMEL_TYPE_MIME_FILTER)
+
+enum {
+	EMIF_PLAIN,
+	EMIF_BINHEX,
+	EMIF_POSTSCRIPT,
+	EMIF_PGPSIGNED,
+	EMIF_PGPENCRYPTED
+};
+
+static const struct {
+	const gchar *type;
+	const gchar *subtype;
+	CamelTransferEncoding encoding;
+	guint plain:1;
+} emif_types[] = {
+	{ "text",        "plain",                 CAMEL_TRANSFER_ENCODING_DEFAULT,  1, },
+	{ "application", "mac-binhex40",          CAMEL_TRANSFER_ENCODING_7BIT,     0, },
+	{ "application", "postscript",            CAMEL_TRANSFER_ENCODING_7BIT,     0, },
+	{ "application", "x-inlinepgp-signed",    CAMEL_TRANSFER_ENCODING_DEFAULT,  0, },
+	{ "application", "x-inlinepgp-encrypted", CAMEL_TRANSFER_ENCODING_DEFAULT,  0, },
+};
+
+static CamelMimePart *
+construct_part_from_stream (CamelStream *mem, const GByteArray *data)
+{
+	CamelMimePart *part = NULL;
+	CamelMimeParser *parser;
+
+	g_return_val_if_fail (mem != NULL, NULL);
+	g_return_val_if_fail (data != NULL, NULL);
+
+	if (data->len <= 13 || g_ascii_strncasecmp ((const gchar *) data->data, "Content-Type:", 13) != 0)
+		return NULL;
+
+	parser = camel_mime_parser_new ();
+	camel_mime_parser_scan_from (parser, FALSE);
+	camel_mime_parser_scan_pre_from (parser, FALSE);
+
+	if (camel_mime_parser_init_with_stream (parser, mem, NULL) != -1) {
+		part = camel_mime_part_new ();
+		if (!camel_mime_part_construct_from_parser_sync (part, parser, NULL, NULL)) {
+			g_object_unref (part);
+			part = NULL;
+		}
+	}
+
+	g_object_unref (parser);
+
+	return part;
+}
+
+static void
+inline_filter_add_part (EMInlineFilter *emif, const gchar *data, gint len)
+{
+	CamelTransferEncoding encoding;
+	CamelContentType *content_type;
+	CamelDataWrapper *dw;
+	const gchar *mimetype;
+	CamelMimePart *part;
+	CamelStream *mem;
+	gchar *type;
+
+	if (emif->state == EMIF_PLAIN || emif->state == EMIF_PGPSIGNED || emif->state == EMIF_PGPENCRYPTED)
+		encoding = emif->base_encoding;
+	else
+		encoding = emif_types[emif->state].encoding;
+
+	g_byte_array_append (emif->data, (guchar *)data, len);
+	/* check the part will actually have content */
+	if (emif->data->len <= 0) {
+		return;
+	}
+
+	mem = camel_stream_mem_new_with_byte_array (emif->data);
+	part = construct_part_from_stream (mem, emif->data);
+	if (part) {
+		g_object_unref (mem);
+		emif->data = g_byte_array_new ();
+		g_free (emif->filename);
+		emif->filename = NULL;
+
+		emif->parts = g_slist_append (emif->parts, part);
+		emif->found_any = TRUE;
+
+		return;
+	}
+
+	emif->data = g_byte_array_new ();
+	camel_stream_reset (mem, NULL);
+
+	dw = camel_data_wrapper_new ();
+	if (encoding == emif->base_encoding && (encoding == CAMEL_TRANSFER_ENCODING_BASE64 || encoding == CAMEL_TRANSFER_ENCODING_QUOTEDPRINTABLE)) {
+		CamelMimeFilter *enc_filter = camel_mime_filter_basic_new (encoding == CAMEL_TRANSFER_ENCODING_BASE64 ? CAMEL_MIME_FILTER_BASIC_BASE64_ENC : CAMEL_MIME_FILTER_BASIC_QP_ENC);
+		CamelStream *filter_stream;
+
+		filter_stream = camel_stream_filter_new (mem);
+		camel_stream_filter_add (CAMEL_STREAM_FILTER (filter_stream), enc_filter);
+
+		/* properly encode content */
+		camel_data_wrapper_construct_from_stream_sync (
+			dw, filter_stream, NULL, NULL);
+
+		g_object_unref (enc_filter);
+		g_object_unref (filter_stream);
+	} else {
+		camel_data_wrapper_construct_from_stream_sync (
+			dw, mem, NULL, NULL);
+	}
+	g_object_unref (mem);
+
+	if (emif_types[emif->state].plain && emif->base_type) {
+		/* create a copy */
+		type = camel_content_type_format (emif->base_type);
+		content_type = camel_content_type_decode (type);
+		g_free (type);
+	} else {
+		/* we want to preserve all params */
+		type = camel_content_type_format (emif->base_type);
+		content_type = camel_content_type_decode (type);
+		g_free (type);
+
+		g_free (content_type->type);
+		g_free (content_type->subtype);
+		content_type->type = g_strdup (emif_types[emif->state].type);
+		content_type->subtype = g_strdup (emif_types[emif->state].subtype);
+	}
+
+	camel_data_wrapper_set_mime_type_field (dw, content_type);
+	camel_content_type_unref (content_type);
+	dw->encoding = encoding;
+
+	part = camel_mime_part_new ();
+	camel_medium_set_content ((CamelMedium *)part, dw);
+	camel_mime_part_set_encoding (part, encoding);
+	g_object_unref (dw);
+
+	if (emif->filename)
+		camel_mime_part_set_filename (part, emif->filename);
+
+	/* pre-snoop the mime type of unknown objects, and poke and hack it into place */
+	if (camel_content_type_is(dw->mime_type, "application", "octet-stream")
+	    && (mimetype = em_format_snoop_type (part))
+	    && strcmp(mimetype, "application/octet-stream") != 0) {
+		camel_data_wrapper_set_mime_type (dw, mimetype);
+		camel_mime_part_set_content_type (part, mimetype);
+		if (emif->filename)
+			camel_mime_part_set_filename (part, emif->filename);
+	}
+
+	g_free (emif->filename);
+	emif->filename = NULL;
+
+	emif->parts = g_slist_append (emif->parts, part);
+}
+
+static gint
+inline_filter_scan (CamelMimeFilter *f, gchar *in, gsize len, gint final)
+{
+	EMInlineFilter *emif = (EMInlineFilter *)f;
+	gchar *inptr = in, *inend = in+len;
+	gchar *data_start = in;
+	gchar *start = in;
+
+	while (inptr < inend) {
+		gint rest_len;
+
+		start = inptr;
+
+		while (inptr < inend && *inptr != '\n')
+			inptr++;
+
+		if (inptr == inend && start == inptr) {
+			if (!final) {
+				camel_mime_filter_backup (f, start, inend-start);
+				inend = start;
+			}
+			break;
+		}
+
+		rest_len = inend - start;
+		if (inptr < inend)
+			*inptr++ = 0;
+
+		#define restore_inptr() G_STMT_START { if (inptr < inend) inptr[-1] = '\n'; } G_STMT_END
+
+		switch (emif->state) {
+		case EMIF_PLAIN:
+			if (rest_len >= 45 && strncmp (start, "(This file must be converted with BinHex 4.0)", 45) == 0) {
+				restore_inptr ();
+				inline_filter_add_part (emif, data_start, start-data_start);
+				data_start = start;
+				emif->state = EMIF_BINHEX;
+			} else if (rest_len >= 11 && strncmp (start, "%!PS-Adobe-", 11) == 0) {
+				restore_inptr ();
+				inline_filter_add_part (emif, data_start, start-data_start);
+				data_start = start;
+				emif->state = EMIF_POSTSCRIPT;
+			} else if (rest_len >= 34 && strncmp (start, "-----BEGIN PGP SIGNED MESSAGE-----", 34) == 0) {
+				restore_inptr ();
+				inline_filter_add_part (emif, data_start, start-data_start);
+				data_start = start;
+				emif->state = EMIF_PGPSIGNED;
+			} else if (rest_len >= 27 && strncmp (start, "-----BEGIN PGP MESSAGE-----", 27) == 0) {
+				restore_inptr ();
+				inline_filter_add_part (emif, data_start, start-data_start);
+				data_start = start;
+				emif->state = EMIF_PGPENCRYPTED;
+			}
+
+			break;
+		case EMIF_BINHEX:
+			if (inptr > (start+1) && inptr[-2] == ':') {
+				restore_inptr ();
+				inline_filter_add_part (emif, data_start, inptr-data_start);
+				data_start = inptr;
+				emif->state = EMIF_PLAIN;
+				emif->found_any = TRUE;
+			}
+			break;
+		case EMIF_POSTSCRIPT:
+			if (rest_len >= 5 && strncmp (start, "%%EOF", 5) == 0) {
+				restore_inptr ();
+				inline_filter_add_part (emif, data_start, inptr-data_start);
+				data_start = inptr;
+				emif->state = EMIF_PLAIN;
+				emif->found_any = TRUE;
+			}
+			break;
+		case EMIF_PGPSIGNED:
+			if (rest_len >= 27 && strncmp (start, "-----END PGP SIGNATURE-----", 27) == 0) {
+				restore_inptr ();
+				inline_filter_add_part (emif, data_start, inptr-data_start);
+				data_start = inptr;
+				emif->state = EMIF_PLAIN;
+				emif->found_any = TRUE;
+			}
+			break;
+		case EMIF_PGPENCRYPTED:
+			if (rest_len >= 25 && strncmp (start, "-----END PGP MESSAGE-----", 25) == 0) {
+				restore_inptr ();
+				inline_filter_add_part (emif, data_start, inptr-data_start);
+				data_start = inptr;
+				emif->state = EMIF_PLAIN;
+				emif->found_any = TRUE;
+			}
+			break;
+		}
+
+		restore_inptr ();
+
+		#undef restore_inptr
+	}
+
+	if (final) {
+		/* always stop as plain, especially when not read those tags fully */
+		emif->state = EMIF_PLAIN;
+
+		inline_filter_add_part (emif, data_start, inend - data_start);
+	} else if (start > data_start) {
+		/* backup the last line, in case the tag is divided within buffers */
+		camel_mime_filter_backup (f, start, inend - start);
+		g_byte_array_append (emif->data, (guchar *)data_start, start - data_start);
+	} else {
+		g_byte_array_append (emif->data, (guchar *)data_start, inend - data_start);
+	}
+
+	return 0;
+}
+
+static void
+inline_filter_finalize (GObject *object)
+{
+	EMInlineFilter *emif = EM_INLINE_FILTER (object);
+
+	if (emif->base_type)
+		camel_content_type_unref (emif->base_type);
+
+	camel_mime_filter_reset (CAMEL_MIME_FILTER (object));
+	g_byte_array_free (emif->data, TRUE);
+	g_free (emif->filename);
+
+	/* Chain up to parent's finalize() method. */
+	G_OBJECT_CLASS (em_inline_filter_parent_class)->finalize (object);
+}
+
+static void
+inline_filter_filter (CamelMimeFilter *filter,
+                      const gchar *in,
+                      gsize len,
+                      gsize prespace,
+                      gchar **out,
+                      gsize *outlen,
+                      gsize *outprespace)
+{
+	inline_filter_scan (filter, (gchar *)in, len, FALSE);
+
+	*out = (gchar *)in;
+	*outlen = len;
+	*outprespace = prespace;
+}
+
+static void
+inline_filter_complete (CamelMimeFilter *filter,
+                        const gchar *in,
+                        gsize len,
+                        gsize prespace,
+                        gchar **out,
+                        gsize *outlen,
+                        gsize *outprespace)
+{
+	inline_filter_scan (filter, (gchar *)in, len, TRUE);
+
+	*out = (gchar *)in;
+	*outlen = len;
+	*outprespace = prespace;
+}
+
+static void
+inline_filter_reset (CamelMimeFilter *filter)
+{
+	EMInlineFilter *emif = EM_INLINE_FILTER (filter);
+	GSList *l;
+
+	l = emif->parts;
+	while (l) {
+		GSList *n = l->next;
+
+		g_object_unref (l->data);
+		g_slist_free_1 (l);
+
+		l = n;
+	}
+	emif->parts = NULL;
+	g_byte_array_set_size (emif->data, 0);
+	emif->found_any = FALSE;
+}
+
+static void
+em_inline_filter_class_init (EMInlineFilterClass *class)
+{
+	GObjectClass *object_class;
+	CamelMimeFilterClass *mime_filter_class;
+
+	object_class = G_OBJECT_CLASS (class);
+	object_class->finalize = inline_filter_finalize;
+
+	mime_filter_class = CAMEL_MIME_FILTER_CLASS (class);
+	mime_filter_class->filter = inline_filter_filter;
+	mime_filter_class->complete = inline_filter_complete;
+	mime_filter_class->reset = inline_filter_reset;
+}
+
+static void
+em_inline_filter_init (EMInlineFilter *emif)
+{
+	emif->data = g_byte_array_new ();
+	emif->found_any = FALSE;
+}
+
+/**
+ * em_inline_filter_new:
+ * @base_encoding: The base transfer-encoding of the
+ * raw data being processed.
+ * @base_type: The base content-type of the raw data, should always be
+ * text/plain.
+ *
+ * Create a filter which will scan a (text) stream for
+ * embedded parts.  You can then retrieve the contents
+ * as a CamelMultipart object.
+ *
+ * Return value:
+ **/
+EMInlineFilter *
+em_inline_filter_new (CamelTransferEncoding base_encoding, CamelContentType *base_type)
+{
+	EMInlineFilter *emif;
+
+	emif = g_object_new (EM_TYPE_INLINE_FILTER, NULL);
+	emif->base_encoding = base_encoding;
+	if (base_type) {
+		emif->base_type = base_type;
+		camel_content_type_ref (emif->base_type);
+	}
+
+	return emif;
+}
+
+CamelMultipart *
+em_inline_filter_get_multipart (EMInlineFilter *emif)
+{
+	GSList *l = emif->parts;
+	CamelMultipart *mp;
+
+	mp = camel_multipart_new ();
+	while (l) {
+		camel_multipart_add_part (mp, l->data);
+		l = l->next;
+	}
+
+	return mp;
+}
+
+gboolean
+em_inline_filter_found_any (EMInlineFilter *emif)
+{
+	g_return_val_if_fail (emif != NULL, FALSE);
+
+	return emif->found_any;
+}
diff --git a/em-format/em-inline-filter.h b/em-format/em-inline-filter.h
new file mode 100644
index 0000000000..503ec7c66c
--- /dev/null
+++ b/em-format/em-inline-filter.h
@@ -0,0 +1,80 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ *		Michael Zucchi <notzed@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef EM_INLINE_FILTER_H
+#define EM_INLINE_FILTER_H
+
+#include <camel/camel.h>
+
+/* Standard GObject macros */
+#define EM_TYPE_INLINE_FILTER \
+	(em_inline_filter_get_type ())
+#define EM_INLINE_FILTER(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), EM_TYPE_INLINE_FILTER, EMInlineFilter))
+#define EM_INLINE_FILTER_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), EM_TYPE_INLINE_FILTER, EMInlineFilterClass))
+#define EM_IS_INLINE_FILTER(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), EM_TYPE_INLINE_FILTER))
+#define EM_IS_INLINE_FILTER_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), EM_TYPE_INLINE_FILTER))
+#define EM_INLINE_FILTER_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), EM_TYPE_INLINE_FILTER, EMInlineFilterClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMInlineFilter EMInlineFilter;
+typedef struct _EMInlineFilterClass EMInlineFilterClass;
+
+struct _EMInlineFilter {
+	CamelMimeFilter filter;
+
+	gint state;
+
+	CamelTransferEncoding base_encoding;
+	CamelContentType *base_type;
+
+	GByteArray *data;
+	gchar *filename;
+	GSList *parts;
+
+	gboolean found_any;
+};
+
+struct _EMInlineFilterClass {
+	CamelMimeFilterClass filter_class;
+};
+
+GType		em_inline_filter_get_type	(void);
+EMInlineFilter *em_inline_filter_new		(CamelTransferEncoding base_encoding,
+						 CamelContentType *type);
+CamelMultipart *em_inline_filter_get_multipart	(EMInlineFilter *emif);
+gboolean	em_inline_filter_found_any	(EMInlineFilter *emif);
+
+G_END_DECLS
+
+#endif /* EM_INLINE_FILTER_H */
diff --git a/mail/Makefile.am b/mail/Makefile.am
index a88a7c889a..520e6876cd 100644
--- a/mail/Makefile.am
+++ b/mail/Makefile.am
@@ -91,7 +91,6 @@ mailinclude_HEADERS =					\
 	em-format-html-display.h			\
 	em-format-html-print.h				\
 	em-html-stream.h				\
-	em-inline-filter.h				\
 	em-junk.h					\
 	em-search-context.h				\
 	em-subscription-editor.h			\
@@ -164,7 +163,6 @@ libevolution_mail_la_SOURCES =				\
 	em-format-html-display.c			\
 	em-format-html-print.c				\
 	em-html-stream.c				\
-	em-inline-filter.c				\
 	em-junk.c					\
 	em-search-context.c				\
 	em-subscription-editor.c			\
diff --git a/mail/em-format-html.c b/mail/em-format-html.c
index de8c0b5961..6b74da70b5 100644
--- a/mail/em-format-html.c
+++ b/mail/em-format-html.c
@@ -1595,7 +1595,7 @@ efh_object_requested (GtkHTML *html, GtkHTMLEmbedded *eb, EMFormatHTML *efh)
 }
 
 /* ********************************************************************** */
-#include "em-inline-filter.h"
+#include "em-format/em-inline-filter.h"
 
 /* FIXME: This is duplicated in em-format-html-display, should be exported or in security module */
 static const struct {
diff --git a/mail/em-inline-filter.c b/mail/em-inline-filter.c
deleted file mode 100644
index 7222c03489..0000000000
--- a/mail/em-inline-filter.c
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- *		Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-
-#include "em-inline-filter.h"
-
-#include "em-utils.h"
-#include "em-format/em-format.h"
-
-#define d(x)
-
-G_DEFINE_TYPE (EMInlineFilter, em_inline_filter, CAMEL_TYPE_MIME_FILTER)
-
-enum {
-	EMIF_PLAIN,
-	EMIF_BINHEX,
-	EMIF_POSTSCRIPT,
-	EMIF_PGPSIGNED,
-	EMIF_PGPENCRYPTED
-};
-
-static const struct {
-	const gchar *type;
-	const gchar *subtype;
-	CamelTransferEncoding encoding;
-	guint plain:1;
-} emif_types[] = {
-	{ "text",        "plain",                 CAMEL_TRANSFER_ENCODING_DEFAULT,  1, },
-	{ "application", "mac-binhex40",          CAMEL_TRANSFER_ENCODING_7BIT,     0, },
-	{ "application", "postscript",            CAMEL_TRANSFER_ENCODING_7BIT,     0, },
-	{ "application", "x-inlinepgp-signed",    CAMEL_TRANSFER_ENCODING_DEFAULT,  0, },
-	{ "application", "x-inlinepgp-encrypted", CAMEL_TRANSFER_ENCODING_DEFAULT,  0, },
-};
-
-static void
-inline_filter_add_part (EMInlineFilter *emif, const gchar *data, gint len)
-{
-	CamelTransferEncoding encoding;
-	CamelContentType *content_type;
-	CamelDataWrapper *dw;
-	const gchar *mimetype;
-	CamelMimePart *part;
-	CamelStream *mem;
-	gchar *type;
-
-	if (emif->state == EMIF_PLAIN || emif->state == EMIF_PGPSIGNED || emif->state == EMIF_PGPENCRYPTED)
-		encoding = emif->base_encoding;
-	else
-		encoding = emif_types[emif->state].encoding;
-
-	g_byte_array_append (emif->data, (guchar *)data, len);
-	/* check the part will actually have content */
-	if (emif->data->len <= 0) {
-		return;
-	}
-
-	mem = camel_stream_mem_new_with_byte_array (emif->data);
-	emif->data = g_byte_array_new ();
-
-	dw = camel_data_wrapper_new ();
-	if (encoding == emif->base_encoding && (encoding == CAMEL_TRANSFER_ENCODING_BASE64 || encoding == CAMEL_TRANSFER_ENCODING_QUOTEDPRINTABLE)) {
-		CamelMimeFilter *enc_filter = camel_mime_filter_basic_new (encoding == CAMEL_TRANSFER_ENCODING_BASE64 ? CAMEL_MIME_FILTER_BASIC_BASE64_ENC : CAMEL_MIME_FILTER_BASIC_QP_ENC);
-		CamelStream *filter_stream;
-
-		filter_stream = camel_stream_filter_new (mem);
-		camel_stream_filter_add (CAMEL_STREAM_FILTER (filter_stream), enc_filter);
-
-		/* properly encode content */
-		camel_data_wrapper_construct_from_stream_sync (
-			dw, filter_stream, NULL, NULL);
-
-		g_object_unref (enc_filter);
-		g_object_unref (filter_stream);
-	} else {
-		camel_data_wrapper_construct_from_stream_sync (
-			dw, mem, NULL, NULL);
-	}
-	g_object_unref (mem);
-
-	if (emif_types[emif->state].plain && emif->base_type) {
-		/* create a copy */
-		type = camel_content_type_format (emif->base_type);
-		content_type = camel_content_type_decode (type);
-		g_free (type);
-	} else {
-		/* we want to preserve all params */
-		type = camel_content_type_format (emif->base_type);
-		content_type = camel_content_type_decode (type);
-		g_free (type);
-
-		g_free (content_type->type);
-		g_free (content_type->subtype);
-		content_type->type = g_strdup (emif_types[emif->state].type);
-		content_type->subtype = g_strdup (emif_types[emif->state].subtype);
-	}
-
-	camel_data_wrapper_set_mime_type_field (dw, content_type);
-	camel_content_type_unref (content_type);
-	dw->encoding = encoding;
-
-	part = camel_mime_part_new ();
-	camel_medium_set_content ((CamelMedium *)part, dw);
-	camel_mime_part_set_encoding (part, encoding);
-	g_object_unref (dw);
-
-	if (emif->filename)
-		camel_mime_part_set_filename (part, emif->filename);
-
-	/* pre-snoop the mime type of unknown objects, and poke and hack it into place */
-	if (camel_content_type_is(dw->mime_type, "application", "octet-stream")
-	    && (mimetype = em_format_snoop_type (part))
-	    && strcmp(mimetype, "application/octet-stream") != 0) {
-		camel_data_wrapper_set_mime_type (dw, mimetype);
-		camel_mime_part_set_content_type (part, mimetype);
-		if (emif->filename)
-			camel_mime_part_set_filename (part, emif->filename);
-	}
-
-	g_free (emif->filename);
-	emif->filename = NULL;
-
-	emif->parts = g_slist_append (emif->parts, part);
-}
-
-static gint
-inline_filter_scan (CamelMimeFilter *f, gchar *in, gsize len, gint final)
-{
-	EMInlineFilter *emif = (EMInlineFilter *)f;
-	gchar *inptr = in, *inend = in+len;
-	gchar *data_start = in;
-	gchar *start = in;
-
-	while (inptr < inend) {
-		gint rest_len;
-
-		start = inptr;
-
-		while (inptr < inend && *inptr != '\n')
-			inptr++;
-
-		if (inptr == inend && start == inptr) {
-			if (!final) {
-				camel_mime_filter_backup (f, start, inend-start);
-				inend = start;
-			}
-			break;
-		}
-
-		rest_len = inend - start;
-		if (inptr < inend)
-			*inptr++ = 0;
-
-		#define restore_inptr() G_STMT_START { if (inptr < inend) inptr[-1] = '\n'; } G_STMT_END
-
-		switch (emif->state) {
-		case EMIF_PLAIN:
-			if (rest_len >= 45 && strncmp (start, "(This file must be converted with BinHex 4.0)", 45) == 0) {
-				restore_inptr ();
-				inline_filter_add_part (emif, data_start, start-data_start);
-				data_start = start;
-				emif->state = EMIF_BINHEX;
-			} else if (rest_len >= 11 && strncmp (start, "%!PS-Adobe-", 11) == 0) {
-				restore_inptr ();
-				inline_filter_add_part (emif, data_start, start-data_start);
-				data_start = start;
-				emif->state = EMIF_POSTSCRIPT;
-			} else if (rest_len >= 34 && strncmp (start, "-----BEGIN PGP SIGNED MESSAGE-----", 34) == 0) {
-				restore_inptr ();
-				inline_filter_add_part (emif, data_start, start-data_start);
-				data_start = start;
-				emif->state = EMIF_PGPSIGNED;
-			} else if (rest_len >= 27 && strncmp (start, "-----BEGIN PGP MESSAGE-----", 27) == 0) {
-				restore_inptr ();
-				inline_filter_add_part (emif, data_start, start-data_start);
-				data_start = start;
-				emif->state = EMIF_PGPENCRYPTED;
-			}
-
-			break;
-		case EMIF_BINHEX:
-			if (inptr > (start+1) && inptr[-2] == ':') {
-				restore_inptr ();
-				inline_filter_add_part (emif, data_start, inptr-data_start);
-				data_start = inptr;
-				emif->state = EMIF_PLAIN;
-			}
-			break;
-		case EMIF_POSTSCRIPT:
-			if (rest_len >= 5 && strncmp (start, "%%EOF", 5) == 0) {
-				restore_inptr ();
-				inline_filter_add_part (emif, data_start, inptr-data_start);
-				data_start = inptr;
-				emif->state = EMIF_PLAIN;
-			}
-			break;
-		case EMIF_PGPSIGNED:
-			if (rest_len >= 27 && strncmp (start, "-----END PGP SIGNATURE-----", 27) == 0) {
-				restore_inptr ();
-				inline_filter_add_part (emif, data_start, inptr-data_start);
-				data_start = inptr;
-				emif->state = EMIF_PLAIN;
-			}
-			break;
-		case EMIF_PGPENCRYPTED:
-			if (rest_len >= 25 && strncmp (start, "-----END PGP MESSAGE-----", 25) == 0) {
-				restore_inptr ();
-				inline_filter_add_part (emif, data_start, inptr-data_start);
-				data_start = inptr;
-				emif->state = EMIF_PLAIN;
-			}
-			break;
-		}
-
-		restore_inptr ();
-
-		#undef restore_inptr
-	}
-
-	if (final) {
-		/* always stop as plain, especially when not read those tags fully */
-		emif->state = EMIF_PLAIN;
-
-		inline_filter_add_part (emif, data_start, inend - data_start);
-	} else if (start > data_start) {
-		/* backup the last line, in case the tag is divided within buffers */
-		camel_mime_filter_backup (f, start, inend - start);
-		g_byte_array_append (emif->data, (guchar *)data_start, start - data_start);
-	} else {
-		g_byte_array_append (emif->data, (guchar *)data_start, inend - data_start);
-	}
-
-	return 0;
-}
-
-static void
-inline_filter_finalize (GObject *object)
-{
-	EMInlineFilter *emif = EM_INLINE_FILTER (object);
-
-	if (emif->base_type)
-		camel_content_type_unref (emif->base_type);
-
-	camel_mime_filter_reset (CAMEL_MIME_FILTER (object));
-	g_byte_array_free (emif->data, TRUE);
-	g_free (emif->filename);
-
-	/* Chain up to parent's finalize() method. */
-	G_OBJECT_CLASS (em_inline_filter_parent_class)->finalize (object);
-}
-
-static void
-inline_filter_filter (CamelMimeFilter *filter,
-                      const gchar *in,
-                      gsize len,
-                      gsize prespace,
-                      gchar **out,
-                      gsize *outlen,
-                      gsize *outprespace)
-{
-	inline_filter_scan (filter, (gchar *)in, len, FALSE);
-
-	*out = (gchar *)in;
-	*outlen = len;
-	*outprespace = prespace;
-}
-
-static void
-inline_filter_complete (CamelMimeFilter *filter,
-                        const gchar *in,
-                        gsize len,
-                        gsize prespace,
-                        gchar **out,
-                        gsize *outlen,
-                        gsize *outprespace)
-{
-	inline_filter_scan (filter, (gchar *)in, len, TRUE);
-
-	*out = (gchar *)in;
-	*outlen = len;
-	*outprespace = prespace;
-}
-
-static void
-inline_filter_reset (CamelMimeFilter *filter)
-{
-	EMInlineFilter *emif = EM_INLINE_FILTER (filter);
-	GSList *l;
-
-	l = emif->parts;
-	while (l) {
-		GSList *n = l->next;
-
-		g_object_unref (l->data);
-		g_slist_free_1 (l);
-
-		l = n;
-	}
-	emif->parts = NULL;
-	g_byte_array_set_size (emif->data, 0);
-}
-
-static void
-em_inline_filter_class_init (EMInlineFilterClass *class)
-{
-	GObjectClass *object_class;
-	CamelMimeFilterClass *mime_filter_class;
-
-	object_class = G_OBJECT_CLASS (class);
-	object_class->finalize = inline_filter_finalize;
-
-	mime_filter_class = CAMEL_MIME_FILTER_CLASS (class);
-	mime_filter_class->filter = inline_filter_filter;
-	mime_filter_class->complete = inline_filter_complete;
-	mime_filter_class->reset = inline_filter_reset;
-}
-
-static void
-em_inline_filter_init (EMInlineFilter *emif)
-{
-	emif->data = g_byte_array_new ();
-}
-
-/**
- * em_inline_filter_new:
- * @base_encoding: The base transfer-encoding of the
- * raw data being processed.
- * @base_type: The base content-type of the raw data, should always be
- * text/plain.
- *
- * Create a filter which will scan a (text) stream for
- * embedded parts.  You can then retrieve the contents
- * as a CamelMultipart object.
- *
- * Return value:
- **/
-EMInlineFilter *
-em_inline_filter_new (CamelTransferEncoding base_encoding, CamelContentType *base_type)
-{
-	EMInlineFilter *emif;
-
-	emif = g_object_new (EM_TYPE_INLINE_FILTER, NULL);
-	emif->base_encoding = base_encoding;
-	if (base_type) {
-		emif->base_type = base_type;
-		camel_content_type_ref (emif->base_type);
-	}
-
-	return emif;
-}
-
-CamelMultipart *
-em_inline_filter_get_multipart (EMInlineFilter *emif)
-{
-	GSList *l = emif->parts;
-	CamelMultipart *mp;
-
-	mp = camel_multipart_new ();
-	while (l) {
-		camel_multipart_add_part (mp, l->data);
-		l = l->next;
-	}
-
-	return mp;
-}
diff --git a/mail/em-inline-filter.h b/mail/em-inline-filter.h
deleted file mode 100644
index 8ee90a6640..0000000000
--- a/mail/em-inline-filter.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- *		Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef EM_INLINE_FILTER_H
-#define EM_INLINE_FILTER_H
-
-#include <camel/camel.h>
-
-/* Standard GObject macros */
-#define EM_TYPE_INLINE_FILTER \
-	(em_inline_filter_get_type ())
-#define EM_INLINE_FILTER(obj) \
-	(G_TYPE_CHECK_INSTANCE_CAST \
-	((obj), EM_TYPE_INLINE_FILTER, EMInlineFilter))
-#define EM_INLINE_FILTER_CLASS(cls) \
-	(G_TYPE_CHECK_CLASS_CAST \
-	((cls), EM_TYPE_INLINE_FILTER, EMInlineFilterClass))
-#define EM_IS_INLINE_FILTER(obj) \
-	(G_TYPE_CHECK_INSTANCE_TYPE \
-	((obj), EM_TYPE_INLINE_FILTER))
-#define EM_IS_INLINE_FILTER_CLASS(cls) \
-	(G_TYPE_CHECK_CLASS_TYPE \
-	((cls), EM_TYPE_INLINE_FILTER))
-#define EM_INLINE_FILTER_GET_CLASS(obj) \
-	(G_TYPE_INSTANCE_GET_CLASS \
-	((obj), EM_TYPE_INLINE_FILTER, EMInlineFilterClass))
-
-G_BEGIN_DECLS
-
-typedef struct _EMInlineFilter EMInlineFilter;
-typedef struct _EMInlineFilterClass EMInlineFilterClass;
-
-struct _EMInlineFilter {
-	CamelMimeFilter filter;
-
-	gint state;
-
-	CamelTransferEncoding base_encoding;
-	CamelContentType *base_type;
-
-	GByteArray *data;
-	gchar *filename;
-	GSList *parts;
-};
-
-struct _EMInlineFilterClass {
-	CamelMimeFilterClass filter_class;
-};
-
-GType		em_inline_filter_get_type	(void);
-EMInlineFilter *em_inline_filter_new		(CamelTransferEncoding base_encoding,
-						 CamelContentType *type);
-CamelMultipart *em_inline_filter_get_multipart	(EMInlineFilter *emif);
-
-G_END_DECLS
-
-#endif /* EM_INLINE_FILTER_H */
-- 
cgit v1.2.3