diff options
author | Milan Crha <mcrha@redhat.com> | 2009-05-20 22:50:00 +0800 |
---|---|---|
committer | Milan Crha <mcrha@redhat.com> | 2009-05-20 22:50:00 +0800 |
commit | f4cf9af33ccde3142a3011e8b2dbcfb4cbc9ae81 (patch) | |
tree | 1c0228db536f5fa0efc6e0f779bb86df610989d0 /mail | |
parent | 3acc45b10c9849aa5385a762b4d139472916dca1 (diff) | |
download | gsoc2013-evolution-f4cf9af33ccde3142a3011e8b2dbcfb4cbc9ae81.tar gsoc2013-evolution-f4cf9af33ccde3142a3011e8b2dbcfb4cbc9ae81.tar.gz gsoc2013-evolution-f4cf9af33ccde3142a3011e8b2dbcfb4cbc9ae81.tar.bz2 gsoc2013-evolution-f4cf9af33ccde3142a3011e8b2dbcfb4cbc9ae81.tar.lz gsoc2013-evolution-f4cf9af33ccde3142a3011e8b2dbcfb4cbc9ae81.tar.xz gsoc2013-evolution-f4cf9af33ccde3142a3011e8b2dbcfb4cbc9ae81.tar.zst gsoc2013-evolution-f4cf9af33ccde3142a3011e8b2dbcfb4cbc9ae81.zip |
Use -no-undefined on Linux too
There still left two things opened, search for KILL-BONOBO to find them.
One is in calendar's Makefile.am, one in composer.
Diffstat (limited to 'mail')
-rw-r--r-- | mail/Makefile.am | 17 | ||||
-rw-r--r-- | mail/em-format-hook.h | 2 | ||||
-rw-r--r-- | mail/em-format-html.h | 2 | ||||
-rw-r--r-- | mail/em-format-quote.c | 584 | ||||
-rw-r--r-- | mail/em-format-quote.h | 81 | ||||
-rw-r--r-- | mail/em-format.c | 1846 | ||||
-rw-r--r-- | mail/em-format.h | 403 | ||||
-rw-r--r-- | mail/em-inline-filter.c | 3 | ||||
-rw-r--r-- | mail/em-mailer-prefs.c | 2 | ||||
-rw-r--r-- | mail/em-stripsig-filter.c | 169 | ||||
-rw-r--r-- | mail/em-stripsig-filter.h | 63 | ||||
-rw-r--r-- | mail/em-utils.c | 128 | ||||
-rw-r--r-- | mail/em-utils.h | 3 | ||||
-rw-r--r-- | mail/importers/Makefile.am | 31 | ||||
-rw-r--r-- | mail/mail-component.c | 2 |
15 files changed, 14 insertions, 3322 deletions
diff --git a/mail/Makefile.am b/mail/Makefile.am index 11ee7f5edc..56a946480b 100644 --- a/mail/Makefile.am +++ b/mail/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = default importers +SUBDIRS = default mailincludedir = $(privincludedir)/mail @@ -7,6 +7,7 @@ INCLUDES = \ -I$(top_srcdir)/widgets/e-text \ -I$(top_srcdir)/widgets/misc \ -I$(top_srcdir) \ + -I$(top_srcdir)/em-format \ -I$(top_srcdir)/mail \ -I$(top_srcdir)/composer \ -I$(top_builddir)/composer \ @@ -112,8 +113,6 @@ libevolution_module_mail_la_SOURCES = \ em-folder-tree-model.h \ em-folder-utils.c \ em-folder-utils.h \ - em-format.c \ - em-format.h \ em-format-hook.c \ em-format-hook.h \ em-format-html.c \ @@ -122,8 +121,6 @@ libevolution_module_mail_la_SOURCES = \ em-format-html-display.h \ em-format-html-print.c \ em-format-html-print.h \ - em-format-quote.c \ - em-format-quote.h \ em-html-stream.c \ em-html-stream.h \ em-icon-stream.c \ @@ -142,8 +139,6 @@ libevolution_module_mail_la_SOURCES = \ em-popup.h \ em-search-context.c \ em-search-context.h \ - em-stripsig-filter.c \ - em-stripsig-filter.h \ em-subscribe-editor.c \ em-subscribe-editor.h \ em-sync-stream.c \ @@ -179,7 +174,12 @@ libevolution_module_mail_la_SOURCES = \ message-tag-editor.c \ message-tag-editor.h \ message-tag-followup.c \ - message-tag-followup,h + message-tag-followup.h \ + importers/mail-importer.c \ + importers/mail-importer.h \ + importers/elm-importer.c \ + importers/pine-importer.c \ + importers/evolution-mbox-importer.c libevolution_module_mail_la_LIBADD = \ $(top_builddir)/e-util/libeutil.la \ @@ -188,7 +188,6 @@ libevolution_module_mail_la_LIBADD = \ $(top_builddir)/widgets/table/libetable.la \ $(top_builddir)/widgets/text/libetext.la \ $(top_builddir)/widgets/misc/libemiscwidgets.la \ - $(top_builddir)/mail/importers/libevolution-mail-importers.la \ $(top_builddir)/addressbook/gui/contact-editor/libecontacteditor.la \ $(top_builddir)/addressbook/gui/contact-list-editor/libecontactlisteditor.la \ $(SMIME_LIBS) diff --git a/mail/em-format-hook.h b/mail/em-format-hook.h index 3665bbf0db..4c7dc16517 100644 --- a/mail/em-format-hook.h +++ b/mail/em-format-hook.h @@ -28,7 +28,7 @@ #include "libedataserver/e-msgport.h" #include "e-util/e-plugin.h" -#include "mail/em-format.h" +#include "em-format/em-format.h" #ifdef __cplusplus extern "C" { diff --git a/mail/em-format-html.h b/mail/em-format-html.h index d35556316a..758307e0f8 100644 --- a/mail/em-format-html.h +++ b/mail/em-format-html.h @@ -28,7 +28,7 @@ #ifndef EM_FORMAT_HTML_H #define EM_FORMAT_HTML_H -#include <mail/em-format.h> +#include <em-format/em-format.h> #include <mail/mail-config.h> #include <camel/camel-medium.h> #include <camel/camel-mime-part.h> diff --git a/mail/em-format-quote.c b/mail/em-format-quote.c deleted file mode 100644 index 43c7e2e55c..0000000000 --- a/mail/em-format-quote.c +++ /dev/null @@ -1,584 +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: - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> - -#include <camel/camel-iconv.h> -#include <camel/camel-stream-filter.h> -#include <camel/camel-mime-filter-tohtml.h> -#include <camel/camel-mime-filter-enriched.h> -#include <camel/camel-string-utils.h> -#include <camel/camel-mime-message.h> -#include <camel/camel-url.h> - -#include <glib/gi18n.h> -#include <gconf/gconf-client.h> - -#include "em-stripsig-filter.h" -#include "em-format-quote.h" -#include "mail-config.h" - -struct _EMFormatQuotePrivate { - int dummy; -}; - -static void emfq_format_clone(EMFormat *, CamelFolder *, const char *, CamelMimeMessage *, EMFormat *); -static void emfq_format_error(EMFormat *emf, CamelStream *stream, const char *txt); -static void emfq_format_message(EMFormat *, CamelStream *, CamelMimePart *, const EMFormatHandler *); -static void emfq_format_source(EMFormat *, CamelStream *, CamelMimePart *); -static void emfq_format_attachment(EMFormat *, CamelStream *, CamelMimePart *, const char *, const EMFormatHandler *); - -static void emfq_builtin_init(EMFormatQuoteClass *efhc); - -static gpointer parent_class; - -static void -emfq_init(GObject *o) -{ - EMFormatQuote *emfq =(EMFormatQuote *) o; - - /* we want to convert url's etc */ - emfq->text_html_flags = CAMEL_MIME_FILTER_TOHTML_PRE | CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS - | CAMEL_MIME_FILTER_TOHTML_CONVERT_ADDRESSES; -} - -static void -emfq_finalize (GObject *object) -{ - EMFormatQuote *emfq =(EMFormatQuote *) object; - - if (emfq->stream) - camel_object_unref(emfq->stream); - g_free(emfq->credits); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -emfq_base_init(EMFormatQuoteClass *emfqclass) -{ - emfq_builtin_init(emfqclass); -} - -static void -emfq_class_init (EMFormatQuoteClass *class) -{ - GObjectClass *object_class; - EMFormatClass *format_class; - - parent_class = g_type_class_peek_parent (class); - g_type_class_add_private (class, sizeof (EMFormatQuotePrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->finalize = emfq_finalize; - - format_class = EM_FORMAT_CLASS (class); - format_class->format_clone = emfq_format_clone; - format_class->format_error = emfq_format_error; - format_class->format_source = emfq_format_source; - format_class->format_attachment = emfq_format_attachment; -} - -GType -em_format_quote_get_type (void) -{ - static GType type = 0; - - if (G_UNLIKELY (type == 0)) { - static const GTypeInfo type_info = { - sizeof (EMFormatQuoteClass), - (GBaseInitFunc) emfq_base_init, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) emfq_class_init, - (GClassFinalizeFunc) NULL, - NULL, /* class_data */ - sizeof (EMFormatQuote), - 0, /* n_preallocs */ - (GInstanceInitFunc) emfq_init, - NULL /* value_table */ - }; - - type = g_type_register_static ( - EM_TYPE_FORMAT, "EMFormatQuote", &type_info, 0); - } - - return type; -} - -EMFormatQuote * -em_format_quote_new (const gchar *credits, - CamelStream *stream, - guint32 flags) -{ - EMFormatQuote *emfq; - - emfq = g_object_new (EM_TYPE_FORMAT_QUOTE, NULL); - - emfq->credits = g_strdup (credits); - emfq->stream = stream; - camel_object_ref (stream); - emfq->flags = flags; - - return emfq; -} - -static void -emfq_format_empty_line(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info) -{ - camel_stream_printf(stream, "<br>\n"); -} - -static void -emfq_format_clone(EMFormat *emf, CamelFolder *folder, const char *uid, CamelMimeMessage *msg, EMFormat *src) -{ - EMFormatQuote *emfq = (EMFormatQuote *) emf; - const EMFormatHandler *handle; - - /* Chain up to parent's format_clone() method. */ - EM_FORMAT_CLASS (parent_class)->format_clone (emf, folder, uid, msg, src); - - camel_stream_reset(emfq->stream); - if (gconf_client_get_bool(mail_config_get_gconf_client(), "/apps/evolution/mail/composer/top_signature", NULL)) - emfq_format_empty_line(emf, emfq->stream, (CamelMimePart *)msg, NULL); - handle = em_format_find_handler(emf, "x-evolution/message/prefix"); - if (handle) - handle->handler(emf, emfq->stream, (CamelMimePart *)msg, handle); - handle = em_format_find_handler(emf, "x-evolution/message/rfc822"); - if (handle) - handle->handler(emf, emfq->stream, (CamelMimePart *)msg, handle); - - camel_stream_flush(emfq->stream); - - g_signal_emit_by_name(emf, "complete"); -} - -static void -emfq_format_error(EMFormat *emf, CamelStream *stream, const char *txt) -{ - /* FIXME: should we even bother writing error text for quoting? probably not... */ -} - -static void -emfq_format_text_header (EMFormatQuote *emfq, CamelStream *stream, const char *label, const char *value, guint32 flags, int is_html) -{ - const char *fmt, *html; - char *mhtml = NULL; - - if (value == NULL) - return; - - while (*value == ' ') - value++; - - if (!is_html) - html = mhtml = camel_text_to_html (value, 0, 0); - else - html = value; - - if (flags & EM_FORMAT_HEADER_BOLD) - fmt = "<b>%s</b>: %s<br>"; - else - fmt = "%s: %s<br>"; - - camel_stream_printf (stream, fmt, label, html); - g_free (mhtml); -} - -static char *addrspec_hdrs[] = { - "Sender", "From", "Reply-To", "To", "Cc", "Bcc", - "Resent-Sender", "Resent-from", "Resent-Reply-To", - "Resent-To", "Resent-cc", "Resent-Bcc", NULL -}; - -#if 0 -/* FIXME: include Sender and Resent-* headers too? */ -/* For Translators only: The following strings are used in the header table in the preview pane */ -static char *i18n_hdrs[] = { - N_("From"), N_("Reply-To"), N_("To"), N_("Cc"), N_("Bcc") -}; -#endif - -static void -emfq_format_address (GString *out, struct _camel_header_address *a) -{ - guint32 flags = CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES; - char *name, *mailto, *addr; - - while (a) { - if (a->name) - name = camel_text_to_html (a->name, flags, 0); - else - name = NULL; - - switch (a->type) { - case CAMEL_HEADER_ADDRESS_NAME: - if (name && *name) { - char *real, *mailaddr; - - g_string_append_printf (out, "%s <", name); - /* rfc2368 for mailto syntax and url encoding extras */ - if ((real = camel_header_encode_phrase ((unsigned char *)a->name))) { - mailaddr = g_strdup_printf ("%s <%s>", real, a->v.addr); - g_free (real); - mailto = camel_url_encode (mailaddr, "?=&()"); - g_free (mailaddr); - } else { - mailto = camel_url_encode (a->v.addr, "?=&()"); - } - } else { - mailto = camel_url_encode (a->v.addr, "?=&()"); - } - addr = camel_text_to_html (a->v.addr, flags, 0); - g_string_append_printf (out, "<a href=\"mailto:%s\">%s</a>", mailto, addr); - g_free (mailto); - g_free (addr); - - if (name && *name) - g_string_append (out, ">"); - break; - case CAMEL_HEADER_ADDRESS_GROUP: - g_string_append_printf (out, "%s: ", name); - emfq_format_address (out, a->v.members); - g_string_append_printf (out, ";"); - break; - default: - g_warning ("Invalid address type"); - break; - } - - g_free (name); - - a = a->next; - if (a) - g_string_append (out, ", "); - } -} - -static void -canon_header_name (char *name) -{ - char *inptr = name; - - /* canonicalise the header name... first letter is - * capitalised and any letter following a '-' also gets - * capitalised */ - - if (*inptr >= 'a' && *inptr <= 'z') - *inptr -= 0x20; - - inptr++; - - while (*inptr) { - if (inptr[-1] == '-' && *inptr >= 'a' && *inptr <= 'z') - *inptr -= 0x20; - else if (*inptr >= 'A' && *inptr <= 'Z') - *inptr += 0x20; - - inptr++; - } -} - -static void -emfq_format_header (EMFormat *emf, CamelStream *stream, CamelMedium *part, const char *namein, guint32 flags, const char *charset) -{ - CamelMimeMessage *msg = (CamelMimeMessage *) part; - EMFormatQuote *emfq = (EMFormatQuote *) emf; - char *name, *buf, *value = NULL; - const char *txt, *label; - gboolean addrspec = FALSE; - int is_html = FALSE; - int i; - - name = g_alloca (strlen (namein) + 1); - strcpy (name, namein); - canon_header_name (name); - - for (i = 0; addrspec_hdrs[i]; i++) { - if (!strcmp (name, addrspec_hdrs[i])) { - addrspec = TRUE; - break; - } - } - - label = _(name); - - if (addrspec) { - struct _camel_header_address *addrs; - GString *html; - - if (!(txt = camel_medium_get_header (part, name))) - return; - - buf = camel_header_unfold (txt); - if (!(addrs = camel_header_address_decode (txt, emf->charset ? emf->charset : emf->default_charset))) { - g_free (buf); - return; - } - - g_free (buf); - - html = g_string_new (""); - emfq_format_address (html, addrs); - camel_header_address_unref (addrs); - txt = value = html->str; - g_string_free (html, FALSE); - flags |= EM_FORMAT_HEADER_BOLD; - is_html = TRUE; - } else if (!strcmp (name, "Subject")) { - txt = camel_mime_message_get_subject (msg); - label = _("Subject"); - flags |= EM_FORMAT_HEADER_BOLD; - } else if (!strcmp (name, "X-Evolution-Mailer")) { /* pseudo-header */ - if (!(txt = camel_medium_get_header (part, "x-mailer"))) - if (!(txt = camel_medium_get_header (part, "user-agent"))) - if (!(txt = camel_medium_get_header (part, "x-newsreader"))) - if (!(txt = camel_medium_get_header (part, "x-mimeole"))) - return; - - txt = value = camel_header_format_ctext (txt, charset); - - label = _("Mailer"); - flags |= EM_FORMAT_HEADER_BOLD; - } else if (!strcmp (name, "Date") || !strcmp (name, "Resent-Date")) { - if (!(txt = camel_medium_get_header (part, name))) - return; - - flags |= EM_FORMAT_HEADER_BOLD; - } else { - txt = camel_medium_get_header (part, name); - buf = camel_header_unfold (txt); - txt = value = camel_header_decode_string (txt, charset); - g_free (buf); - } - - emfq_format_text_header (emfq, stream, label, txt, flags, is_html); - - g_free (value); -} - -static void -emfq_format_headers (EMFormatQuote *emfq, CamelStream *stream, CamelMedium *part) -{ - EMFormat *emf = (EMFormat *) emfq; - CamelContentType *ct; - const char *charset; - EMFormatHeader *h; - - if (!part) - return; - - ct = camel_mime_part_get_content_type ((CamelMimePart *) part); - charset = camel_content_type_param (ct, "charset"); - charset = camel_iconv_charset_name (charset); - - /* dump selected headers */ - h = (EMFormatHeader *) emf->header_list.head; - while (h->next) { - emfq_format_header (emf, stream, part, h->name, h->flags, charset); - h = h->next; - } - - camel_stream_printf(stream, "<br>\n"); -} - -static void -emfq_format_message_prefix(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info) -{ - EMFormatQuote *emfq = (EMFormatQuote *) emf; - - if (emfq->credits) - camel_stream_printf(stream, "%s<br>\n", emfq->credits); -} - -static void -emfq_format_message(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info) -{ - EMFormatQuote *emfq = (EMFormatQuote *) emf; - - if (emfq->flags & EM_FORMAT_QUOTE_CITE) - camel_stream_printf(stream, "<!--+GtkHTML:<DATA class=\"ClueFlow\" key=\"orig\" value=\"1\">-->\n" - "<blockquote type=cite>\n"); - - if (((CamelMimePart *)emf->message) != part) { - camel_stream_printf(stream, "%s</br>\n", _("-------- Forwarded Message --------")); - emfq_format_headers (emfq, stream, (CamelMedium *)part); - } else if (emfq->flags & EM_FORMAT_QUOTE_HEADERS) - emfq_format_headers (emfq, stream, (CamelMedium *)part); - - em_format_part (emf, stream, part); - - if (emfq->flags & EM_FORMAT_QUOTE_CITE) - camel_stream_write_string(stream, "</blockquote><!--+GtkHTML:<DATA class=\"ClueFlow\" clear=\"orig\">-->"); -} - -static void -emfq_format_source(EMFormat *emf, CamelStream *stream, CamelMimePart *part) -{ - CamelStreamFilter *filtered_stream; - CamelMimeFilter *html_filter; - - filtered_stream = camel_stream_filter_new_with_stream ((CamelStream *) stream); - html_filter = camel_mime_filter_tohtml_new (CAMEL_MIME_FILTER_TOHTML_CONVERT_NL - | CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES - | CAMEL_MIME_FILTER_TOHTML_ESCAPE_8BIT, 0); - camel_stream_filter_add(filtered_stream, html_filter); - camel_object_unref(html_filter); - - em_format_format_text(emf, (CamelStream *)filtered_stream, (CamelDataWrapper *)part); - camel_object_unref(filtered_stream); -} - -static void -emfq_format_attachment(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const char *mime_type, const EMFormatHandler *handle) -{ - if (handle && em_format_is_inline(emf, emf->part_id->str, part, handle)) { - char *text, *html; - - camel_stream_write_string(stream, - "<table border=1 cellspacing=0 cellpadding=0><tr><td><font size=-1>\n"); - - /* output some info about it */ - text = em_format_describe_part(part, mime_type); - html = camel_text_to_html(text, ((EMFormatQuote *)emf)->text_html_flags & CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS, 0); - camel_stream_write_string(stream, html); - g_free(html); - g_free(text); - - camel_stream_write_string(stream, "</font></td></tr></table>"); - - handle->handler(emf, stream, part, handle); - } -} - -#include <camel/camel-medium.h> -#include <camel/camel-mime-part.h> -#include <camel/camel-multipart.h> -#include <camel/camel-url.h> - -static void -emfq_text_plain(EMFormatQuote *emfq, CamelStream *stream, CamelMimePart *part, EMFormatHandler *info) -{ - CamelStreamFilter *filtered_stream; - CamelMimeFilter *html_filter; - CamelMimeFilter *sig_strip; - CamelContentType *type; - const char *format; - guint32 rgb = 0x737373, flags; - - if (!part) - return; - - flags = emfq->text_html_flags; - - /* Check for RFC 2646 flowed text. */ - type = camel_mime_part_get_content_type(part); - if (camel_content_type_is(type, "text", "plain") - && (format = camel_content_type_param(type, "format")) - && !g_ascii_strcasecmp(format, "flowed")) - flags |= CAMEL_MIME_FILTER_TOHTML_FORMAT_FLOWED; - - filtered_stream = camel_stream_filter_new_with_stream(stream); - - if (emfq->flags != 0) { - sig_strip = em_stripsig_filter_new (); - camel_stream_filter_add (filtered_stream, sig_strip); - camel_object_unref (sig_strip); - } - - html_filter = camel_mime_filter_tohtml_new(flags, rgb); - camel_stream_filter_add(filtered_stream, html_filter); - camel_object_unref(html_filter); - - em_format_format_text((EMFormat *)emfq, (CamelStream *)filtered_stream, (CamelDataWrapper *)part); - camel_stream_flush((CamelStream *)filtered_stream); - camel_object_unref(filtered_stream); -} - -static void -emfq_text_enriched(EMFormatQuote *emfq, CamelStream *stream, CamelMimePart *part, EMFormatHandler *info) -{ - CamelStreamFilter *filtered_stream; - CamelMimeFilter *enriched; - CamelDataWrapper *dw; - guint32 flags = 0; - - dw = camel_medium_get_content_object((CamelMedium *)part); - - if (!strcmp(info->mime_type, "text/richtext")) { - flags = CAMEL_MIME_FILTER_ENRICHED_IS_RICHTEXT; - camel_stream_write_string(stream, "\n<!-- text/richtext -->\n"); - } else { - camel_stream_write_string(stream, "\n<!-- text/enriched -->\n"); - } - - enriched = camel_mime_filter_enriched_new(flags); - filtered_stream = camel_stream_filter_new_with_stream (stream); - camel_stream_filter_add(filtered_stream, enriched); - camel_object_unref(enriched); - - camel_stream_write_string(stream, "<br><hr><br>"); - em_format_format_text((EMFormat *)emfq, (CamelStream *)filtered_stream, (CamelDataWrapper *)part); - camel_object_unref(filtered_stream); -} - -static void -emfq_text_html(EMFormat *emf, CamelStream *stream, CamelMimePart *part, EMFormatHandler *info) -{ - camel_stream_write_string(stream, "\n<!-- text/html -->\n"); - em_format_format_text(emf, stream, (CamelDataWrapper *)part); -} - -static void -emfq_ignore(EMFormat *emf, CamelStream *stream, CamelMimePart *part, EMFormatHandler *info) -{ - /* NOOP */ -} - -static EMFormatHandler type_builtin_table[] = { - { "text/plain",(EMFormatFunc)emfq_text_plain }, - { "text/enriched",(EMFormatFunc)emfq_text_enriched }, - { "text/richtext",(EMFormatFunc)emfq_text_enriched }, - { "text/html",(EMFormatFunc)emfq_text_html }, -/* { "multipart/related",(EMFormatFunc)emfq_multipart_related },*/ - { "message/external-body", (EMFormatFunc)emfq_ignore }, - { "multipart/appledouble", (EMFormatFunc)emfq_ignore }, - - /* internal evolution types */ - { "x-evolution/evolution-rss-feed", (EMFormatFunc)emfq_text_html }, - { "x-evolution/message/rfc822", (EMFormatFunc)emfq_format_message }, - { "x-evolution/message/prefix", (EMFormatFunc)emfq_format_message_prefix }, -}; - -static void -emfq_builtin_init(EMFormatQuoteClass *efhc) -{ - int i; - - for (i=0;i<sizeof(type_builtin_table)/sizeof(type_builtin_table[0]);i++) - em_format_class_add_handler((EMFormatClass *)efhc, &type_builtin_table[i]); -} diff --git a/mail/em-format-quote.h b/mail/em-format-quote.h deleted file mode 100644 index 87f0151a50..0000000000 --- a/mail/em-format-quote.h +++ /dev/null @@ -1,81 +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: - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef EM_FORMAT_QUOTE_H -#define EM_FORMAT_QUOTE_H - -#include <camel/camel-stream.h> -#include "mail/em-format.h" - -/* Standard GObject macros */ -#define EM_TYPE_FORMAT_QUOTE \ - (em_format_quote_get_type ()) -#define EM_FORMAT_QUOTE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), EM_TYPE_FORMAT_QUOTE, EMFormatQuote)) -#define EM_FORMAT_QUOTE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), EM_TYPE_FORMAT_QUOTE, EMFormatQuoteClass)) -#define EM_IS_FORMAT_QUOTE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), EM_TYPE_FORMAT_QUOTE)) -#define EM_IS_FORMAT_QUOTE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), EM_TYPE_FORMAT_QUOTE)) -#define EM_FORMAT_QUOTE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), EM_TYPE_FORMAT_QUOTE, EMFormatQuoteClass)) - -#define EM_FORMAT_QUOTE_CITE (1<<0) -#define EM_FORMAT_QUOTE_HEADERS (1<<1) - -G_BEGIN_DECLS - -typedef struct _EMFormatQuote EMFormatQuote; -typedef struct _EMFormatQuoteClass EMFormatQuoteClass; -typedef struct _EMFormatQuotePrivate EMFormatQuotePrivate; - -struct _EMFormatQuote { - EMFormat format; - - EMFormatQuotePrivate *priv; - - char *credits; - CamelStream *stream; - guint32 flags; - - guint32 text_html_flags; - guint32 citation_colour; -}; - -struct _EMFormatQuoteClass { - EMFormatClass format_class; -}; - -GType em_format_quote_get_type (void); -EMFormatQuote * em_format_quote_new (const gchar *credits, - CamelStream *stream, - guint32 flags); - -G_END_DECLS - -#endif /* EM_FORMAT_QUOTE_H */ diff --git a/mail/em-format.c b/mail/em-format.c deleted file mode 100644 index 27c627a185..0000000000 --- a/mail/em-format.c +++ /dev/null @@ -1,1846 +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> - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <string.h> - -#include <glib/gi18n.h> -#include <gio/gio.h> - -#include <libedataserver/e-msgport.h> -#include <camel/camel-stream.h> -#include <camel/camel-stream-mem.h> -#include <camel/camel-multipart.h> -#include <camel/camel-multipart-encrypted.h> -#include <camel/camel-multipart-signed.h> -#include <camel/camel-medium.h> -#include <camel/camel-mime-message.h> -#include <camel/camel-gpg-context.h> -#include <camel/camel-smime-context.h> -#include <camel/camel-string-utils.h> -#include <camel/camel-stream-filter.h> -#include <camel/camel-stream-null.h> -#include <camel/camel-stream-mem.h> -#include <camel/camel-mime-filter-charset.h> -#include <camel/camel-mime-filter-windows.h> -#include <camel/camel-mime-filter-pgp.h> - -#include "em-format.h" -#include "em-utils.h" -#include "mail-config.h" -#include "mail-session.h" - -#define d(x) - -/* Used to cache various data/info for redraws - The validity stuff could be cached at a higher level but this is easier - This absolutely relies on the partid being _globally unique_ - This is still kind of yucky, we should maintian a full tree of all this data, - along with/as part of the puri tree */ -struct _EMFormatCache { - CamelCipherValidity *valid; /* validity copy */ - CamelMimePart *secured; /* encrypted subpart */ - - unsigned int state:2; /* inline state */ - - char partid[1]; -}; - -#define INLINE_UNSET (0) -#define INLINE_ON (1) -#define INLINE_OFF (2) - -static void emf_builtin_init(EMFormatClass *); - -static const EMFormatHandler *emf_find_handler(EMFormat *emf, const char *mime_type); -static void emf_format_clone(EMFormat *emf, CamelFolder *folder, const char *uid, CamelMimeMessage *msg, EMFormat *emfsource); -static void emf_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, CamelCipherValidity *valid); -static gboolean emf_busy(EMFormat *emf); -enum { - EMF_COMPLETE, - EMF_LAST_SIGNAL, -}; - -static gpointer parent_class; -static guint signals[EMF_LAST_SIGNAL]; - -static void -emf_free_cache(struct _EMFormatCache *efc) -{ - if (efc->valid) - camel_cipher_validity_free(efc->valid); - if (efc->secured) - camel_object_unref(efc->secured); - g_free(efc); -} - -static struct _EMFormatCache * -emf_insert_cache(EMFormat *emf, const char *partid) -{ - struct _EMFormatCache *new; - - new = g_malloc0(sizeof(*new)+strlen(partid)); - strcpy(new->partid, partid); - g_hash_table_insert(emf->inline_table, new->partid, new); - - return new; -} - -static void -emf_finalize (GObject *object) -{ - EMFormat *emf = EM_FORMAT (object); - - if (emf->session) - camel_object_unref (emf->session); - - g_hash_table_destroy (emf->inline_table); - - em_format_clear_headers(emf); - camel_cipher_validity_free(emf->valid); - g_free(emf->charset); - g_free (emf->default_charset); - g_string_free(emf->part_id, TRUE); - - /* FIXME: check pending jobs */ - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -emf_base_init (EMFormatClass *class) -{ - class->type_handlers = g_hash_table_new (g_str_hash, g_str_equal); - emf_builtin_init (class); -} - -static void -emf_class_init (EMFormatClass *class) -{ - GObjectClass *object_class; - - parent_class = g_type_class_peek_parent (class); - - object_class = G_OBJECT_CLASS (class); - object_class->finalize = emf_finalize; - - class->find_handler = emf_find_handler; - class->format_clone = emf_format_clone; - class->format_secure = emf_format_secure; - class->busy = emf_busy; - - signals[EMF_COMPLETE] = g_signal_new ( - "complete", - G_OBJECT_CLASS_TYPE (class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EMFormatClass, complete), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - class->type_handlers = g_hash_table_new (g_str_hash, g_str_equal); - emf_builtin_init (class); -} - -static void -emf_init (EMFormat *emf) -{ - emf->inline_table = g_hash_table_new_full ( - g_str_hash, g_str_equal, - (GDestroyNotify) NULL, - (GDestroyNotify) emf_free_cache); - emf->composer = FALSE; - emf->print = FALSE; - e_dlist_init(&emf->header_list); - em_format_default_headers(emf); - emf->part_id = g_string_new(""); - - emf->session = session; - camel_object_ref (emf->session); -} - -GType -em_format_get_type (void) -{ - static GType type = 0; - - if (G_UNLIKELY (type == 0)) { - static const GTypeInfo type_info = { - sizeof (EMFormatClass), - (GBaseInitFunc) emf_base_init, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) emf_class_init, - (GClassFinalizeFunc) NULL, - NULL, /* class_data */ - sizeof (EMFormat), - 0, /* n_preallocs */ - (GInstanceInitFunc) emf_init, - NULL /* value_table */ - }; - - type = g_type_register_static ( - G_TYPE_OBJECT, "EMFormat", &type_info, 0); - } - - return type; -} - -/** - * em_format_class_add_handler: - * @emfc: EMFormatClass - * @info: Callback information. - * - * Add a mime type handler to this class. This is only used by - * implementing classes. The @info.old pointer will automatically be - * setup to point to the old hanlder if one was already set. This can - * be used for overrides a fallback. - * - * When a mime type described by @info is encountered, the callback will - * be invoked. Note that @info may be extended by sub-classes if - * they require additional context information. - * - * Use a mime type of "foo/ *" to insert a fallback handler for type "foo". - **/ -void -em_format_class_add_handler(EMFormatClass *emfc, EMFormatHandler *info) -{ - d(printf("adding format handler to '%s' '%s'\n", g_type_name_from_class((GTypeClass *)emfc), info->mime_type)); - info->old = g_hash_table_lookup(emfc->type_handlers, info->mime_type); - g_hash_table_insert(emfc->type_handlers, info->mime_type, info); -} - -struct _class_handlers { - EMFormatClass *old; - EMFormatClass *new; -}; -static void -merge_missing (gpointer key, gpointer value, gpointer userdata) -{ - struct _class_handlers *classes = (struct _class_handlers *) userdata; - EMFormatHandler *info, *oldinfo; - - oldinfo = (EMFormatHandler *) value; - info = g_hash_table_lookup (classes->new->type_handlers, key); - if (!info) { - /* Might be from a plugin */ - g_hash_table_insert (classes->new->type_handlers, key, value); - } - -} - -void -em_format_merge_handler(EMFormat *new, EMFormat *old) -{ - EMFormatClass *oldc = (EMFormatClass *)G_OBJECT_GET_CLASS(old); - EMFormatClass *newc = (EMFormatClass *)G_OBJECT_GET_CLASS(new); - struct _class_handlers fclasses; - - fclasses.old = oldc; - fclasses.new = newc; - - g_hash_table_foreach (oldc->type_handlers, merge_missing, &fclasses); - -} - -/** - * em_format_class_remove_handler: - * @emfc: - * @info: - * - * Remove a handler. @info must be a value which was previously - * added. - **/ -void -em_format_class_remove_handler(EMFormatClass *emfc, EMFormatHandler *info) -{ - EMFormatHandler *current; - - /* TODO: thread issues? */ - - current = g_hash_table_lookup(emfc->type_handlers, info->mime_type); - if (current == info) { - current = info->old; - if (current) - g_hash_table_insert(emfc->type_handlers, current->mime_type, current); - else - g_hash_table_remove(emfc->type_handlers, info->mime_type); - } else { - while (current && current->old != info) - current = current->old; - g_return_if_fail(current != NULL); - current->old = info->old; - } -} - -const EMFormatHandler * -em_format_find_handler (EMFormat *emf, - const gchar *mime_type) -{ - EMFormatClass *class; - - g_return_val_if_fail (EM_IS_FORMAT (emf), NULL); - g_return_val_if_fail (mime_type != NULL, NULL); - - class = EM_FORMAT_GET_CLASS (emf); - g_return_val_if_fail (class->find_handler != NULL, NULL); - return class->find_handler (emf, mime_type); -} - -/** - * em_format_find_handler: - * @emf: - * @mime_type: - * - * Find a format handler by @mime_type. - * - * Return value: NULL if no handler is available. - **/ -static const EMFormatHandler * -emf_find_handler(EMFormat *emf, const char *mime_type) -{ - EMFormatClass *emfc = (EMFormatClass *)G_OBJECT_GET_CLASS(emf); - - return g_hash_table_lookup(emfc->type_handlers, mime_type); -} - -/** - * em_format_fallback_handler: - * @emf: - * @mime_type: - * - * Try to find a format handler based on the major type of the @mime_type. - * - * The subtype is replaced with "*" and a lookup performed. - * - * Return value: - **/ -const EMFormatHandler * -em_format_fallback_handler(EMFormat *emf, const char *mime_type) -{ - char *mime, *s; - - s = strchr(mime_type, '/'); - if (s == NULL) - mime = (char *)mime_type; - else { - size_t len = (s-mime_type)+1; - - mime = alloca(len+2); - strncpy(mime, mime_type, len); - strcpy(mime+len, "*"); - } - - return em_format_find_handler(emf, mime); -} - -/** - * em_format_add_puri: - * @emf: - * @size: - * @cid: Override the autogenerated content id. - * @part: - * @func: - * - * Add a pending-uri handler. When formatting parts that reference - * other parts, a pending-uri (PURI) can be used to track the reference. - * - * @size is used to allocate the structure, so that it can be directly - * subclassed by implementors. - * - * @cid can be used to override the key used to retreive the PURI, if NULL, - * then the content-location and the content-id of the @part are stored - * as lookup keys for the part. - * - * FIXME: This may need a free callback. - * - * Return value: A new PURI, with a referenced copy of @part, and the cid - * always set. The uri will be set if one is available. Clashes - * are resolved by forgetting the old PURI in the global index. - **/ -EMFormatPURI * -em_format_add_puri(EMFormat *emf, size_t size, const char *cid, CamelMimePart *part, EMFormatPURIFunc func) -{ - EMFormatPURI *puri; - const char *tmp; - - d(printf("adding puri for part: %s\n", emf->part_id->str)); - - if (size < sizeof(*puri)) { - g_warning ( - "size (%" G_GSIZE_FORMAT - ") less than size of puri\n", size); - size = sizeof (*puri); - } - - puri = g_malloc0(size); - - puri->format = emf; - puri->func = func; - puri->use_count = 0; - puri->cid = g_strdup(cid); - puri->part_id = g_strdup(emf->part_id->str); - - if (part) { - camel_object_ref(part); - puri->part = part; - } - - if (part != NULL && cid == NULL) { - tmp = camel_mime_part_get_content_id(part); - if (tmp) - puri->cid = g_strdup_printf("cid:%s", tmp); - else - puri->cid = g_strdup_printf("em-no-cid:%s", emf->part_id->str); - - d(printf("built cid '%s'\n", puri->cid)); - - /* not quite same as old behaviour, it also put in the relative uri and a fallback for no parent uri */ - tmp = camel_mime_part_get_content_location(part); - puri->uri = NULL; - if (tmp == NULL) { - /* no location, don't set a uri at all, html parts do this themselves */ - } else { - if (strchr(tmp, ':') == NULL && emf->base != NULL) { - CamelURL *uri; - - uri = camel_url_new_with_base(emf->base, tmp); - puri->uri = camel_url_to_string(uri, 0); - camel_url_free(uri); - } else { - puri->uri = g_strdup(tmp); - } - } - } - - g_return_val_if_fail (puri->cid != NULL, NULL); - g_return_val_if_fail (emf->pending_uri_level != NULL, NULL); - g_return_val_if_fail (emf->pending_uri_table != NULL, NULL); - - e_dlist_addtail(&emf->pending_uri_level->uri_list, (EDListNode *)puri); - - if (puri->uri) - g_hash_table_insert(emf->pending_uri_table, puri->uri, puri); - g_hash_table_insert(emf->pending_uri_table, puri->cid, puri); - - return puri; -} - -/** - * em_format_push_level: - * @emf: - * - * This is used to build a heirarchy of visible PURI objects based on - * the structure of the message. Used by multipart/alternative formatter. - * - * FIXME: This could probably also take a uri so it can automaticall update - * the base location. - **/ -void -em_format_push_level(EMFormat *emf) -{ - struct _EMFormatPURITree *purilist; - - d(printf("em_format_push_level\n")); - purilist = g_malloc0(sizeof(*purilist)); - e_dlist_init(&purilist->children); - e_dlist_init(&purilist->uri_list); - purilist->parent = emf->pending_uri_level; - if (emf->pending_uri_tree == NULL) { - emf->pending_uri_tree = purilist; - } else { - e_dlist_addtail(&emf->pending_uri_level->children, (EDListNode *)purilist); - } - emf->pending_uri_level = purilist; -} - -/** - * em_format_pull_level: - * @emf: - * - * Drop a level of visibility back to the parent. Note that - * no PURI values are actually freed. - **/ -void -em_format_pull_level(EMFormat *emf) -{ - d(printf("em_format_pull_level\n")); - emf->pending_uri_level = emf->pending_uri_level->parent; -} - -/** - * em_format_find_visible_puri: - * @emf: - * @uri: - * - * Search for a PURI based on the visibility defined by :push_level() - * and :pull_level(). - * - * Return value: - **/ -EMFormatPURI * -em_format_find_visible_puri(EMFormat *emf, const char *uri) -{ - EMFormatPURI *pw; - struct _EMFormatPURITree *ptree; - - d(printf("checking for visible uri '%s'\n", uri)); - - ptree = emf->pending_uri_level; - while (ptree) { - pw = (EMFormatPURI *)ptree->uri_list.head; - while (pw->next) { - d(printf(" pw->uri = '%s' pw->cid = '%s\n", pw->uri?pw->uri:"", pw->cid)); - if ((pw->uri && !strcmp(pw->uri, uri)) || !strcmp(pw->cid, uri)) - return pw; - pw = pw->next; - } - ptree = ptree->parent; - } - - return NULL; -} - -/** - * em_format_find_puri: - * @emf: - * @uri: - * - * Search for a PURI based on a uri. Both the content-id - * and content-location are checked. - * - * Return value: - **/ -EMFormatPURI * - -em_format_find_puri(EMFormat *emf, const char *uri) -{ - return g_hash_table_lookup(emf->pending_uri_table, uri); -} - -static void -emf_clear_puri_node(struct _EMFormatPURITree *node) -{ - { - EMFormatPURI *pw, *pn; - - /* clear puri's at this level */ - pw = (EMFormatPURI *)node->uri_list.head; - pn = pw->next; - while (pn) { - d(printf ("freeing pw %p format:%p\n", pw, pw->format)); - if (pw->free) - pw->free(pw); - g_free(pw->uri); - g_free(pw->cid); - g_free(pw->part_id); - if (pw->part) - camel_object_unref(pw->part); - g_free(pw); - pw = pn; - pn = pn->next; - } - } - - { - struct _EMFormatPURITree *cw, *cn; - - /* clear child nodes */ - cw = (struct _EMFormatPURITree *)node->children.head; - cn = cw->next; - while (cn) { - emf_clear_puri_node(cw); - cw = cn; - cn = cn->next; - } - } - - g_free(node); -} - -/** - * em_format_clear_puri_tree: - * @emf: - * - * For use by implementors to clear out the message structure - * data. - **/ -void -em_format_clear_puri_tree(EMFormat *emf) -{ - d(printf("clearing pending uri's\n")); - - if (emf->pending_uri_table) { - g_hash_table_destroy(emf->pending_uri_table); - emf_clear_puri_node(emf->pending_uri_tree); - emf->pending_uri_level = NULL; - emf->pending_uri_tree = NULL; - } - emf->pending_uri_table = g_hash_table_new(g_str_hash, g_str_equal); - em_format_push_level(emf); -} - -/* use mime_type == NULL to force showing as application/octet-stream */ -void -em_format_part_as(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const char *mime_type) -{ - const EMFormatHandler *handle = NULL; - const char *snoop_save = emf->snoop_mime_type, *tmp; - CamelURL *base_save = emf->base, *base = NULL; - char *basestr = NULL; - - d(printf("format_part_as()\n")); - - emf->snoop_mime_type = NULL; - - /* RFC 2110, we keep track of content-base, and absolute content-location headers - This is actually only required for html, but, *shrug* */ - tmp = camel_medium_get_header((CamelMedium *)part, "Content-Base"); - if (tmp == NULL) { - tmp = camel_mime_part_get_content_location(part); - if (tmp && strchr(tmp, ':') == NULL) - tmp = NULL; - } else { - tmp = basestr = camel_header_location_decode(tmp); - } - d(printf("content-base is '%s'\n", tmp?tmp:"<unset>")); - if (tmp - && (base = camel_url_new(tmp, NULL))) { - emf->base = base; - d(printf("Setting content base '%s'\n", tmp)); - } - g_free(basestr); - - if (mime_type != NULL) { - if (g_ascii_strcasecmp(mime_type, "application/octet-stream") == 0) { - emf->snoop_mime_type = mime_type = em_utils_snoop_type(part); - if (mime_type == NULL) - mime_type = "application/octet-stream"; - } - - handle = em_format_find_handler(emf, mime_type); - if (handle == NULL) - handle = em_format_fallback_handler(emf, mime_type); - - if (handle != NULL - && !em_format_is_attachment(emf, part)) { - d(printf("running handler for type '%s'\n", mime_type)); - handle->handler(emf, stream, part, handle); - goto finish; - } - d(printf("this type is an attachment? '%s'\n", mime_type)); - } else { - mime_type = "application/octet-stream"; - } - - ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->format_attachment(emf, stream, part, mime_type, handle); -finish: - emf->base = base_save; - emf->snoop_mime_type = snoop_save; - - if (base) - camel_url_free(base); -} - -void -em_format_part(EMFormat *emf, CamelStream *stream, CamelMimePart *part) -{ - char *mime_type; - CamelDataWrapper *dw; - - dw = camel_medium_get_content_object((CamelMedium *)part); - mime_type = camel_data_wrapper_get_mime_type(dw); - if (mime_type) { - camel_strdown(mime_type); - em_format_part_as(emf, stream, part, mime_type); - g_free(mime_type); - } else - em_format_part_as(emf, stream, part, "text/plain"); -} - -static void -emf_clone_inlines(void *key, void *val, void *data) -{ - struct _EMFormatCache *emfc = val, *new; - - new = emf_insert_cache((EMFormat *)data, emfc->partid); - new->state = emfc->state; - if (emfc->valid) - new->valid = camel_cipher_validity_clone(emfc->valid); - if (emfc->secured) - camel_object_ref((new->secured = emfc->secured)); -} - -static void -emf_format_clone(EMFormat *emf, CamelFolder *folder, const char *uid, CamelMimeMessage *msg, EMFormat *emfsource) -{ - em_format_clear_puri_tree(emf); - - if (emf != emfsource) { - g_hash_table_remove_all(emf->inline_table); - if (emfsource) { - struct _EMFormatHeader *h; - - /* We clone the current state here */ - g_hash_table_foreach(emfsource->inline_table, emf_clone_inlines, emf); - emf->mode = emfsource->mode; - g_free(emf->charset); - emf->charset = g_strdup(emfsource->charset); - g_free (emf->default_charset); - emf->default_charset = g_strdup (emfsource->default_charset); - - em_format_clear_headers(emf); - for (h = (struct _EMFormatHeader *)emfsource->header_list.head; h->next; h = h->next) - em_format_add_header(emf, h->name, h->flags); - } - } - - /* what a mess */ - if (folder != emf->folder) { - if (emf->folder) - camel_object_unref(emf->folder); - if (folder) - camel_object_ref(folder); - emf->folder = folder; - } - - if (uid != emf->uid) { - g_free(emf->uid); - emf->uid = g_strdup(uid); - } - - if (msg != emf->message) { - if (emf->message) - camel_object_unref(emf->message); - if (msg) - camel_object_ref(msg); - emf->message = msg; - } - - g_string_truncate(emf->part_id, 0); - if (folder != NULL) - /* TODO build some string based on the folder name/location? */ - g_string_append_printf(emf->part_id, ".%p", folder); - if (uid != NULL) - g_string_append_printf(emf->part_id, ".%s", uid); -} - -static void -emf_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, CamelCipherValidity *valid) -{ - CamelCipherValidity *save = emf->valid_parent; - int len; - - /* Note that this also requires support from higher up in the class chain - - validity needs to be cleared when you start output - - also needs to be cleared (but saved) whenever you start a new message. */ - - if (emf->valid == NULL) { - emf->valid = valid; - } else { - camel_dlist_addtail(&emf->valid_parent->children, (CamelDListNode *)valid); - camel_cipher_validity_envelope(emf->valid_parent, valid); - } - - emf->valid_parent = valid; - - len = emf->part_id->len; - g_string_append_printf(emf->part_id, ".secured"); - em_format_part(emf, stream, part); - g_string_truncate(emf->part_id, len); - - emf->valid_parent = save; -} - -static gboolean -emf_busy(EMFormat *emf) -{ - return FALSE; -} - -/** - * em_format_format_clone: - * @emf: an #EMFormat - * @folder: a #CamelFolder or %NULL - * @uid: Message UID or %NULL - * @msg: a #CamelMimeMessage or %NULL - * @emfsource: Used as a basis for user-altered layout, e.g. inline viewed - * attachments. - * - * Format a message @msg. If @emfsource is non NULL, then the status of - * inlined expansion and so forth is copied direction from @emfsource. - * - * By passing the same value for @emf and @emfsource, you can perform - * a display refresh, or it can be used to generate an identical layout, - * e.g. to print what the user has shown inline. - **/ -void -em_format_format_clone (EMFormat *emf, - CamelFolder *folder, - const gchar *uid, - CamelMimeMessage *message, - EMFormat *source) -{ - EMFormatClass *class; - - g_return_if_fail (EM_IS_FORMAT (emf)); - g_return_if_fail (folder == NULL || CAMEL_IS_FOLDER (folder)); - g_return_if_fail (message == NULL || CAMEL_IS_MIME_MESSAGE (message)); - g_return_if_fail (source == NULL || EM_IS_FORMAT (source)); - - class = EM_FORMAT_GET_CLASS (emf); - g_return_if_fail (class->format_clone != NULL); - class->format_clone (emf, folder, uid, message, source); -} - -void -em_format_format (EMFormat *emf, - CamelFolder *folder, - const gchar *uid, - CamelMimeMessage *message) -{ - /* em_format_format_clone() will check the arguments. */ - em_format_format_clone (emf, folder, uid, message, NULL); -} - -void -em_format_redraw (EMFormat *emf) -{ - g_return_if_fail (EM_IS_FORMAT (emf)); - - em_format_format_clone ( - emf, emf->folder, emf->uid, emf->message, emf); -} - -/** - * em_format_set_mode: - * @emf: - * @type: - * - * Set display mode, EM_FORMAT_SOURCE, EM_FORMAT_ALLHEADERS, or - * EM_FORMAT_NORMAL. - **/ -void -em_format_set_mode(EMFormat *emf, em_format_mode_t type) -{ - if (emf->mode == type) - return; - - emf->mode = type; - - /* force redraw if type changed afterwards */ - if (emf->message) - em_format_redraw(emf); -} - -/** - * em_format_set_charset: - * @emf: - * @charset: - * - * set override charset on formatter. message will be redisplayed if - * required. - **/ -void -em_format_set_charset(EMFormat *emf, const char *charset) -{ - if ((emf->charset && charset && g_ascii_strcasecmp(emf->charset, charset) == 0) - || (emf->charset == NULL && charset == NULL) - || (emf->charset == charset)) - return; - - g_free(emf->charset); - emf->charset = g_strdup(charset); - - if (emf->message) - em_format_redraw(emf); -} - -/** - * em_format_set_default_charset: - * @emf: - * @charset: - * - * Set the fallback, default system charset to use when no other charsets - * are present. Message will be redisplayed if required (and sometimes redisplayed - * when it isn't). - **/ -void -em_format_set_default_charset(EMFormat *emf, const char *charset) -{ - if ((emf->default_charset && charset && g_ascii_strcasecmp(emf->default_charset, charset) == 0) - || (emf->default_charset == NULL && charset == NULL) - || (emf->default_charset == charset)) - return; - - g_free(emf->default_charset); - emf->default_charset = g_strdup(charset); - - if (emf->message && emf->charset == NULL) - em_format_redraw(emf); -} - -/** - * em_format_clear_headers: - * @emf: - * - * Clear the list of headers to be displayed. This will force all headers to - * be shown. - **/ -void -em_format_clear_headers(EMFormat *emf) -{ - EMFormatHeader *eh; - - while ((eh = (EMFormatHeader *)e_dlist_remhead(&emf->header_list))) - g_free(eh); -} - -/* note: also copied in em-mailer-prefs.c */ -static const struct { - const char *name; - guint32 flags; -} default_headers[] = { - { N_("From"), EM_FORMAT_HEADER_BOLD }, - { N_("Reply-To"), EM_FORMAT_HEADER_BOLD }, - { N_("To"), EM_FORMAT_HEADER_BOLD }, - { N_("Cc"), EM_FORMAT_HEADER_BOLD }, - { N_("Bcc"), EM_FORMAT_HEADER_BOLD }, - { N_("Subject"), EM_FORMAT_HEADER_BOLD }, - { N_("Date"), EM_FORMAT_HEADER_BOLD }, - { N_("Newsgroups"), EM_FORMAT_HEADER_BOLD }, - { N_("Face"), 0 }, -}; - -/** - * em_format_default_headers: - * @emf: - * - * Set the headers to show to the default list. - * - * From, Reply-To, To, Cc, Bcc, Subject and Date. - **/ -void -em_format_default_headers(EMFormat *emf) -{ - int i; - - em_format_clear_headers(emf); - for (i=0; i<sizeof(default_headers)/sizeof(default_headers[0]); i++) - em_format_add_header(emf, default_headers[i].name, default_headers[i].flags); -} - -/** - * em_format_add_header: - * @emf: - * @name: The name of the header, as it will appear during output. - * @flags: EM_FORMAT_HEAD_* defines to control display attributes. - * - * Add a specific header to show. If any headers are set, they will - * be displayed in the order set by this function. Certain known - * headers included in this list will be shown using special - * formatting routines. - **/ -void em_format_add_header(EMFormat *emf, const char *name, guint32 flags) -{ - EMFormatHeader *h; - - h = g_malloc(sizeof(*h) + strlen(name)); - h->flags = flags; - strcpy(h->name, name); - e_dlist_addtail(&emf->header_list, (EDListNode *)h); -} - -/** - * em_format_is_attachment: - * @emf: - * @part: Part to check. - * - * Returns true if the part is an attachment. - * - * A part is not considered an attachment if it is a - * multipart, or a text part with no filename. It is used - * to determine if an attachment header should be displayed for - * the part. - * - * Content-Disposition is not checked. - * - * Return value: TRUE/FALSE - **/ -int em_format_is_attachment(EMFormat *emf, CamelMimePart *part) -{ - /*CamelContentType *ct = camel_mime_part_get_content_type(part);*/ - CamelDataWrapper *dw = camel_medium_get_content_object((CamelMedium *)part); - - /*printf("checking is attachment %s/%s\n", ct->type, ct->subtype);*/ - return !(camel_content_type_is (dw->mime_type, "multipart", "*") - || camel_content_type_is(dw->mime_type, "application", "x-pkcs7-mime") - || camel_content_type_is(dw->mime_type, "application", "pkcs7-mime") - || camel_content_type_is(dw->mime_type, "application", "x-inlinepgp-signed") - || camel_content_type_is(dw->mime_type, "application", "x-inlinepgp-encrypted") - || camel_content_type_is(dw->mime_type, "x-evolution", "evolution-rss-feed") - || (camel_content_type_is (dw->mime_type, "text", "*") - && camel_mime_part_get_filename(part) == NULL)); -} - -/** - * em_format_is_inline: - * @emf: - * @part: - * @partid: format->part_id part id of this part. - * @handle: handler for this part - * - * Returns true if the part should be displayed inline. Any part with - * a Content-Disposition of inline, or if the @handle has a default - * inline set, will be shown inline. - * - * :set_inline() called on the same part will override any calculated - * value. - * - * Return value: - **/ -int em_format_is_inline(EMFormat *emf, const char *partid, CamelMimePart *part, const EMFormatHandler *handle) -{ - struct _EMFormatCache *emfc; - const char *tmp; - - if (handle == NULL) - return FALSE; - - emfc = g_hash_table_lookup(emf->inline_table, partid); - if (emfc && emfc->state != INLINE_UNSET) - return emfc->state & 1; - - /* some types need to override the disposition, e.g. application/x-pkcs7-mime */ - if (handle->flags & EM_FORMAT_HANDLER_INLINE_DISPOSITION) - return TRUE; - - tmp = camel_mime_part_get_disposition(part); - if (tmp) - return g_ascii_strcasecmp(tmp, "inline") == 0; - - /* otherwise, use the default for this handler type */ - return (handle->flags & EM_FORMAT_HANDLER_INLINE) != 0; -} - -/** - * em_format_set_inline: - * @emf: - * @partid: id of part - * @state: - * - * Force the attachment @part to be expanded or hidden explictly to match - * @state. This is used only to record the change for a redraw or - * cloned layout render and does not force a redraw. - **/ -void em_format_set_inline(EMFormat *emf, const char *partid, int state) -{ - struct _EMFormatCache *emfc; - - emfc = g_hash_table_lookup(emf->inline_table, partid); - if (emfc == NULL) { - emfc = emf_insert_cache(emf, partid); - } else if (emfc->state != INLINE_UNSET && (emfc->state & 1) == state) - return; - - emfc->state = state?INLINE_ON:INLINE_OFF; - - if (emf->message) - em_format_redraw(emf); -} - -void -em_format_format_attachment (EMFormat *emf, - CamelStream *stream, - CamelMimePart *mime_part, - const gchar *mime_type, - const struct _EMFormatHandler *info) -{ - EMFormatClass *class; - - g_return_if_fail (EM_IS_FORMAT (emf)); - g_return_if_fail (CAMEL_IS_STREAM (stream)); - g_return_if_fail (CAMEL_IS_MIME_PART (mime_part)); - g_return_if_fail (mime_type != NULL); - g_return_if_fail (info != NULL); - - class = EM_FORMAT_GET_CLASS (emf); - g_return_if_fail (class->format_attachment != NULL); - class->format_attachment (emf, stream, mime_part, mime_type, info); -} - -void -em_format_format_error (EMFormat *emf, - CamelStream *stream, - const gchar *format, - ...) -{ - EMFormatClass *class; - gchar *errmsg; - va_list ap; - - g_return_if_fail (EM_IS_FORMAT (emf)); - g_return_if_fail (CAMEL_IS_STREAM (stream)); - g_return_if_fail (format != NULL); - - class = EM_FORMAT_GET_CLASS (emf); - g_return_if_fail (class->format_error != NULL); - - va_start (ap, format); - errmsg = g_strdup_vprintf (format, ap); - class->format_error (emf, stream, errmsg); - g_free (errmsg); - va_end (ap); -} - -void -em_format_format_secure (EMFormat *emf, - CamelStream *stream, - CamelMimePart *mime_part, - CamelCipherValidity *valid) -{ - EMFormatClass *class; - - g_return_if_fail (EM_IS_FORMAT (emf)); - g_return_if_fail (CAMEL_IS_STREAM (stream)); - g_return_if_fail (CAMEL_IS_MIME_PART (mime_part)); - g_return_if_fail (valid != NULL); - - class = EM_FORMAT_GET_CLASS (emf); - g_return_if_fail (class->format_secure != NULL); - class->format_secure (emf, stream, mime_part, valid); - - if (emf->valid_parent == NULL && emf->valid != NULL) { - camel_cipher_validity_free (emf->valid); - emf->valid = NULL; - } -} - -void -em_format_format_source (EMFormat *emf, - CamelStream *stream, - CamelMimePart *mime_part) -{ - EMFormatClass *class; - - g_return_if_fail (EM_IS_FORMAT (emf)); - g_return_if_fail (CAMEL_IS_STREAM (stream)); - g_return_if_fail (CAMEL_IS_MIME_PART (mime_part)); - - class = EM_FORMAT_GET_CLASS (emf); - g_return_if_fail (class->format_source != NULL); - class->format_source (emf, stream, mime_part); -} - -gboolean -em_format_busy (EMFormat *emf) -{ - EMFormatClass *class; - - g_return_val_if_fail (EM_IS_FORMAT (emf), FALSE); - - class = EM_FORMAT_GET_CLASS (emf); - g_return_val_if_fail (class->busy != NULL, FALSE); - return class->busy (emf); -} - -/* should this be virtual? */ -void -em_format_format_content(EMFormat *emf, CamelStream *stream, CamelMimePart *part) -{ - CamelDataWrapper *dw = camel_medium_get_content_object((CamelMedium *)part); - - if (camel_content_type_is (dw->mime_type, "text", "*")) - em_format_format_text(emf, stream, (CamelDataWrapper *)part); - else - camel_data_wrapper_decode_to_stream(dw, stream); -} - -/** - * em_format_format_content: - * @emf: - * @stream: Where to write the converted text - * @part: Part whose container is to be formatted - * - * Decode/output a part's content to @stream. - **/ -void -em_format_format_text(EMFormat *emf, CamelStream *stream, CamelDataWrapper *dw) -{ - CamelStreamFilter *filter_stream; - CamelMimeFilterCharset *filter; - const char *charset = NULL; - CamelMimeFilterWindows *windows = NULL; - CamelStream *mem_stream = NULL; - size_t size; - size_t max; - - if (emf->charset) { - charset = emf->charset; - } else if (dw->mime_type - && (charset = camel_content_type_param (dw->mime_type, "charset")) - && g_ascii_strncasecmp(charset, "iso-8859-", 9) == 0) { - CamelStream *null; - - /* Since a few Windows mailers like to claim they sent - * out iso-8859-# encoded text when they really sent - * out windows-cp125#, do some simple sanity checking - * before we move on... */ - - null = camel_stream_null_new(); - filter_stream = camel_stream_filter_new_with_stream(null); - camel_object_unref(null); - - windows = (CamelMimeFilterWindows *)camel_mime_filter_windows_new(charset); - camel_stream_filter_add(filter_stream, (CamelMimeFilter *)windows); - - camel_data_wrapper_decode_to_stream(dw, (CamelStream *)filter_stream); - camel_stream_flush((CamelStream *)filter_stream); - camel_object_unref(filter_stream); - - charset = camel_mime_filter_windows_real_charset (windows); - } else if (charset == NULL) { - charset = emf->default_charset; - } - - mem_stream = (CamelStream *)camel_stream_mem_new (); - filter_stream = camel_stream_filter_new_with_stream(mem_stream); - - if ((filter = camel_mime_filter_charset_new_convert(charset, "UTF-8"))) { - camel_stream_filter_add(filter_stream, (CamelMimeFilter *) filter); - camel_object_unref(filter); - } - - max = mail_config_get_message_limit(); - size = camel_data_wrapper_decode_to_stream(emf->mode == EM_FORMAT_SOURCE ? (CamelDataWrapper *)dw: camel_medium_get_content_object((CamelMedium *)dw), (CamelStream *)filter_stream); - camel_stream_flush((CamelStream *)filter_stream); - camel_object_unref(filter_stream); - camel_stream_reset (mem_stream); - - if (max == -1 || size == -1 || size < (max * 1024) || emf->composer) { - camel_stream_write_to_stream(mem_stream, (CamelStream *)stream); - camel_stream_flush((CamelStream *)stream); - } else { - ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->format_optional(emf, stream, (CamelMimePart *)dw, mem_stream); - } - - if (windows) - camel_object_unref(windows); -} - -/** - * em_format_describe_part: - * @part: - * @mimetype: - * - * Generate a simple textual description of a part, @mime_type represents the - * the content. - * - * Return value: - **/ -char * -em_format_describe_part(CamelMimePart *part, const char *mime_type) -{ - GString *stext; - const char *filename, *description; - char *content_type, *desc; - - stext = g_string_new(""); - content_type = g_content_type_from_mime_type (mime_type); - desc = g_content_type_get_description (content_type ? content_type : mime_type); - g_free (content_type); - g_string_append_printf (stext, _("%s attachment"), desc ? desc : mime_type); - g_free (desc); - if ((filename = camel_mime_part_get_filename (part))) - g_string_append_printf(stext, " (%s)", filename); - if ((description = camel_mime_part_get_description(part)) && - (*description != 0) && - !(filename && (strcmp(filename, description) == 0))) - g_string_append_printf(stext, ", \"%s\"", description); - - return g_string_free (stext, FALSE); -} - -/* ********************************************************************** */ - -#ifdef ENABLE_SMIME -static void -emf_application_xpkcs7mime(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info) -{ - CamelCipherContext *context; - CamelException *ex; - extern CamelSession *session; - CamelMimePart *opart; - CamelCipherValidity *valid; - struct _EMFormatCache *emfc; - - /* should this perhaps run off a key of ".secured" ? */ - emfc = g_hash_table_lookup(emf->inline_table, emf->part_id->str); - if (emfc && emfc->valid) { - em_format_format_secure(emf, stream, emfc->secured, camel_cipher_validity_clone(emfc->valid)); - return; - } - - ex = camel_exception_new(); - - context = camel_smime_context_new(session); - - opart = camel_mime_part_new(); - valid = camel_cipher_decrypt(context, part, opart, ex); - if (valid == NULL) { - em_format_format_error(emf, stream, "%s", ex->desc?ex->desc:_("Could not parse S/MIME message: Unknown error")); - em_format_part_as(emf, stream, part, NULL); - } else { - if (emfc == NULL) - emfc = emf_insert_cache(emf, emf->part_id->str); - - emfc->valid = camel_cipher_validity_clone(valid); - camel_object_ref((emfc->secured = opart)); - - em_format_format_secure(emf, stream, opart, valid); - } - - camel_object_unref(opart); - camel_object_unref(context); - camel_exception_free(ex); -} -#endif - -/* RFC 1740 */ -static void -emf_multipart_appledouble(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info) -{ - CamelMultipart *mp = (CamelMultipart *)camel_medium_get_content_object((CamelMedium *)part); - CamelMimePart *mime_part; - int len; - - if (!CAMEL_IS_MULTIPART(mp)) { - em_format_format_source(emf, stream, part); - return; - } - - mime_part = camel_multipart_get_part(mp, 1); - if (mime_part) { - /* try the data fork for something useful, doubtful but who knows */ - len = emf->part_id->len; - g_string_append_printf(emf->part_id, ".appledouble.1"); - em_format_part(emf, stream, mime_part); - g_string_truncate(emf->part_id, len); - } else - em_format_format_source(emf, stream, part); - -} - -/* RFC ??? */ -static void -emf_multipart_mixed(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info) -{ - CamelMultipart *mp = (CamelMultipart *)camel_medium_get_content_object((CamelMedium *)part); - int i, nparts, len; - - if (!CAMEL_IS_MULTIPART(mp)) { - em_format_format_source(emf, stream, part); - return; - } - - len = emf->part_id->len; - nparts = camel_multipart_get_number(mp); - for (i = 0; i < nparts; i++) { - part = camel_multipart_get_part(mp, i); - g_string_append_printf(emf->part_id, ".mixed.%d", i); - em_format_part(emf, stream, part); - g_string_truncate(emf->part_id, len); - } -} - -/* RFC 1740 */ -static void -emf_multipart_alternative(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info) -{ - CamelMultipart *mp = (CamelMultipart *)camel_medium_get_content_object((CamelMedium *)part); - int i, nparts, bestid = 0; - CamelMimePart *best = NULL; - - if (!CAMEL_IS_MULTIPART(mp)) { - em_format_format_source(emf, stream, part); - return; - } - - /* as per rfc, find the last part we know how to display */ - nparts = camel_multipart_get_number(mp); - for (i = 0; i < nparts; i++) { - CamelContentType *type; - char *mime_type; - - /* is it correct to use the passed in *part here? */ - part = camel_multipart_get_part(mp, i); - - if (!part) - continue; - - type = camel_mime_part_get_content_type (part); - mime_type = camel_content_type_simple (type); - - camel_strdown (mime_type); - - /*if (want_plain && !strcmp (mime_type, "text/plain")) - return part;*/ - - if (em_format_find_handler(emf, mime_type) - || (best == NULL && em_format_fallback_handler(emf, mime_type))) { - best = part; - bestid = i; - } - - g_free(mime_type); - } - - if (best) { - int len = emf->part_id->len; - - g_string_append_printf(emf->part_id, ".alternative.%d", bestid); - em_format_part(emf, stream, best); - g_string_truncate(emf->part_id, len); - } else - emf_multipart_mixed(emf, stream, part, info); -} - -static void -emf_multipart_encrypted(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info) -{ - CamelCipherContext *context; - CamelException *ex; - const char *protocol; - CamelMimePart *opart; - CamelCipherValidity *valid; - CamelMultipartEncrypted *mpe; - struct _EMFormatCache *emfc; - - /* should this perhaps run off a key of ".secured" ? */ - emfc = g_hash_table_lookup(emf->inline_table, emf->part_id->str); - if (emfc && emfc->valid) { - em_format_format_secure(emf, stream, emfc->secured, camel_cipher_validity_clone(emfc->valid)); - return; - } - - mpe = (CamelMultipartEncrypted*)camel_medium_get_content_object((CamelMedium *)part); - if (!CAMEL_IS_MULTIPART_ENCRYPTED(mpe)) { - em_format_format_error(emf, stream, _("Could not parse MIME message. Displaying as source.")); - em_format_format_source(emf, stream, part); - return; - } - - /* Currently we only handle RFC2015-style PGP encryption. */ - protocol = camel_content_type_param(((CamelDataWrapper *)mpe)->mime_type, "protocol"); - if (!protocol || g_ascii_strcasecmp (protocol, "application/pgp-encrypted") != 0) { - em_format_format_error(emf, stream, _("Unsupported encryption type for multipart/encrypted")); - em_format_part_as(emf, stream, part, "multipart/mixed"); - return; - } - - ex = camel_exception_new(); - context = camel_gpg_context_new(emf->session); - opart = camel_mime_part_new(); - valid = camel_cipher_decrypt(context, part, opart, ex); - if (valid == NULL) { - em_format_format_error(emf, stream, ex->desc?_("Could not parse PGP/MIME message"):_("Could not parse PGP/MIME message: Unknown error")); - if (ex->desc) - em_format_format_error(emf, stream, "%s", ex->desc); - em_format_part_as(emf, stream, part, "multipart/mixed"); - } else { - if (emfc == NULL) - emfc = emf_insert_cache(emf, emf->part_id->str); - - emfc->valid = camel_cipher_validity_clone(valid); - camel_object_ref((emfc->secured = opart)); - - em_format_format_secure(emf, stream, opart, valid); - } - - /* TODO: Make sure when we finalize this part, it is zero'd out */ - camel_object_unref(opart); - camel_object_unref(context); - camel_exception_free(ex); -} - -static void -emf_write_related(EMFormat *emf, CamelStream *stream, EMFormatPURI *puri) -{ - em_format_format_content(emf, stream, puri->part); - camel_stream_close(stream); -} - -/* RFC 2387 */ -static void -emf_multipart_related(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info) -{ - CamelMultipart *mp = (CamelMultipart *)camel_medium_get_content_object((CamelMedium *)part); - CamelMimePart *body_part, *display_part = NULL; - CamelContentType *content_type; - const char *start; - int i, nparts, partidlen, displayid = 0; - char *oldpartid; - struct _EMFormatPURITree *ptree; - EMFormatPURI *puri, *purin; - - if (!CAMEL_IS_MULTIPART(mp)) { - em_format_format_source(emf, stream, part); - return; - } - - /* FIXME: put this stuff in a shared function */ - nparts = camel_multipart_get_number(mp); - content_type = camel_mime_part_get_content_type(part); - start = camel_content_type_param (content_type, "start"); - if (start && strlen(start)>2) { - int len; - const char *cid; - - /* strip <>'s */ - len = strlen (start) - 2; - start++; - - for (i=0; i<nparts; i++) { - body_part = camel_multipart_get_part(mp, i); - cid = camel_mime_part_get_content_id(body_part); - - if (cid && !strncmp(cid, start, len) && strlen(cid) == len) { - display_part = body_part; - displayid = i; - break; - } - } - } else { - display_part = camel_multipart_get_part(mp, 0); - } - - if (display_part == NULL) { - emf_multipart_mixed(emf, stream, part, info); - return; - } - - em_format_push_level(emf); - - oldpartid = g_strdup(emf->part_id->str); - partidlen = emf->part_id->len; - - /* queue up the parts for possible inclusion */ - for (i = 0; i < nparts; i++) { - body_part = camel_multipart_get_part(mp, i); - if (body_part != display_part) { - /* set the partid since add_puri uses it */ - g_string_append_printf(emf->part_id, ".related.%d", i); - puri = em_format_add_puri(emf, sizeof(EMFormatPURI), NULL, body_part, emf_write_related); - g_string_truncate(emf->part_id, partidlen); - d(printf(" part '%s' '%s' added\n", puri->uri?puri->uri:"", puri->cid)); - } - } - - g_string_append_printf(emf->part_id, ".related.%d", displayid); - em_format_part(emf, stream, display_part); - g_string_truncate(emf->part_id, partidlen); - camel_stream_flush(stream); - - ptree = emf->pending_uri_level; - puri = (EMFormatPURI *)ptree->uri_list.head; - purin = puri->next; - while (purin) { - if (puri->use_count == 0) { - d(printf("part '%s' '%s' used '%d'\n", puri->uri?puri->uri:"", puri->cid, puri->use_count)); - if (puri->func == emf_write_related) { - g_string_printf(emf->part_id, "%s", puri->part_id); - em_format_part(emf, stream, puri->part); - } else - d(printf("unreferenced uri generated by format code: %s\n", puri->uri?puri->uri:puri->cid)); - } - puri = purin; - purin = purin->next; - } - - g_string_printf(emf->part_id, "%s", oldpartid); - g_free(oldpartid); - - em_format_pull_level(emf); -} - -static void -emf_multipart_signed(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info) -{ - CamelMimePart *cpart; - CamelMultipartSigned *mps; - CamelCipherContext *cipher = NULL; - struct _EMFormatCache *emfc; - - /* should this perhaps run off a key of ".secured" ? */ - emfc = g_hash_table_lookup(emf->inline_table, emf->part_id->str); - if (emfc && emfc->valid) { - em_format_format_secure(emf, stream, emfc->secured, camel_cipher_validity_clone(emfc->valid)); - return; - } - - mps = (CamelMultipartSigned *)camel_medium_get_content_object((CamelMedium *)part); - if (!CAMEL_IS_MULTIPART_SIGNED(mps) - || (cpart = camel_multipart_get_part((CamelMultipart *)mps, CAMEL_MULTIPART_SIGNED_CONTENT)) == NULL) { - em_format_format_error(emf, stream, _("Could not parse MIME message. Displaying as source.")); - em_format_format_source(emf, stream, part); - return; - } - - /* FIXME: Should be done via a plugin interface */ - /* FIXME: duplicated in em-format-html-display.c */ - if (mps->protocol) { -#ifdef ENABLE_SMIME - if (g_ascii_strcasecmp("application/x-pkcs7-signature", mps->protocol) == 0 - || g_ascii_strcasecmp("application/pkcs7-signature", mps->protocol) == 0) - cipher = camel_smime_context_new(emf->session); - else -#endif - if (g_ascii_strcasecmp("application/pgp-signature", mps->protocol) == 0) - cipher = camel_gpg_context_new(emf->session); - } - - if (cipher == NULL) { - em_format_format_error(emf, stream, _("Unsupported signature format")); - em_format_part_as(emf, stream, part, "multipart/mixed"); - } else { - CamelException *ex = camel_exception_new(); - CamelCipherValidity *valid; - - valid = camel_cipher_verify(cipher, part, ex); - if (valid == NULL) { - em_format_format_error(emf, stream, ex->desc?_("Error verifying signature"):_("Unknown error verifying signature")); - if (ex->desc) - em_format_format_error(emf, stream, "%s", ex->desc); - em_format_part_as(emf, stream, part, "multipart/mixed"); - } else { - if (emfc == NULL) - emfc = emf_insert_cache(emf, emf->part_id->str); - - emfc->valid = camel_cipher_validity_clone(valid); - camel_object_ref((emfc->secured = cpart)); - - em_format_format_secure(emf, stream, cpart, valid); - } - - camel_exception_free(ex); - camel_object_unref(cipher); - } -} - -static void -emf_message_rfc822(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info) -{ - CamelDataWrapper *dw = camel_medium_get_content_object((CamelMedium *)part); - const EMFormatHandler *handle; - int len; - - if (!CAMEL_IS_MIME_MESSAGE(dw)) { - em_format_format_source(emf, stream, part); - return; - } - - len = emf->part_id->len; - g_string_append_printf(emf->part_id, ".rfc822"); - - handle = em_format_find_handler(emf, "x-evolution/message/rfc822"); - if (handle) - handle->handler(emf, stream, (CamelMimePart *)dw, handle); - - g_string_truncate(emf->part_id, len); -} - -static void -emf_message_deliverystatus(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info) -{ - em_format_format_text(emf, stream, (CamelDataWrapper *)part); -} - -static void -emf_inlinepgp_signed(EMFormat *emf, CamelStream *stream, CamelMimePart *ipart, EMFormatHandler *info) -{ - CamelStreamFilter *filtered_stream; - CamelMimeFilterPgp *pgp_filter; - CamelContentType *content_type; - CamelCipherContext *cipher; - CamelCipherValidity *valid; - CamelDataWrapper *dw; - CamelMimePart *opart; - CamelStream *ostream; - CamelException *ex; - char *type; - - if (!ipart) { - em_format_format_error(emf, stream, _("Unknown error verifying signature")); - return; - } - - ex = camel_exception_new(); - cipher = camel_gpg_context_new(emf->session); - /* Verify the signature of the message */ - valid = camel_cipher_verify(cipher, ipart, ex); - if (!valid) { - em_format_format_error(emf, stream, ex->desc?_("Error verifying signature"):_("Unknown error verifying signature")); - if (ex->desc) - em_format_format_error(emf, stream, "%s", ex->desc); - em_format_format_source(emf, stream, ipart); - /* I think this will loop: em_format_part_as(emf, stream, part, "text/plain"); */ - camel_exception_free(ex); - camel_object_unref(cipher); - return; - } - - /* Setup output stream */ - ostream = camel_stream_mem_new(); - filtered_stream = camel_stream_filter_new_with_stream(ostream); - - /* Add PGP header / footer filter */ - pgp_filter = (CamelMimeFilterPgp *)camel_mime_filter_pgp_new(); - camel_stream_filter_add(filtered_stream, (CamelMimeFilter *)pgp_filter); - camel_object_unref(pgp_filter); - - /* Pass through the filters that have been setup */ - dw = camel_medium_get_content_object((CamelMedium *)ipart); - camel_data_wrapper_decode_to_stream(dw, (CamelStream *)filtered_stream); - camel_stream_flush((CamelStream *)filtered_stream); - camel_object_unref(filtered_stream); - - /* Create a new text/plain MIME part containing the signed content preserving the original part's Content-Type params */ - content_type = camel_mime_part_get_content_type (ipart); - type = camel_content_type_format (content_type); - content_type = camel_content_type_decode (type); - g_free (type); - - g_free (content_type->type); - content_type->type = g_strdup ("text"); - g_free (content_type->subtype); - content_type->subtype = g_strdup ("plain"); - type = camel_content_type_format (content_type); - camel_content_type_unref (content_type); - - dw = camel_data_wrapper_new (); - camel_data_wrapper_construct_from_stream (dw, ostream); - camel_data_wrapper_set_mime_type (dw, type); - g_free (type); - - opart = camel_mime_part_new (); - camel_medium_set_content_object ((CamelMedium *) opart, dw); - camel_data_wrapper_set_mime_type_field ((CamelDataWrapper *) opart, dw->mime_type); - - /* Pass it off to the real formatter */ - em_format_format_secure(emf, stream, opart, valid); - - /* Clean Up */ - camel_object_unref(dw); - camel_object_unref(opart); - camel_object_unref(ostream); - camel_object_unref(cipher); - camel_exception_free(ex); -} - -static void -emf_inlinepgp_encrypted(EMFormat *emf, CamelStream *stream, CamelMimePart *ipart, EMFormatHandler *info) -{ - CamelCipherContext *cipher; - CamelCipherValidity *valid; - CamelException *ex; - CamelMimePart *opart; - CamelDataWrapper *dw; - char *mime_type; - - cipher = camel_gpg_context_new(emf->session); - ex = camel_exception_new(); - opart = camel_mime_part_new(); - /* Decrypt the message */ - valid = camel_cipher_decrypt (cipher, ipart, opart, ex); - if (!valid) { - em_format_format_error(emf, stream, ex->desc?_("Could not parse PGP message"):_("Could not parse PGP message: Unknown error")); - if (ex->desc) - em_format_format_error(emf, stream, "%s", ex->desc); - em_format_format_source(emf, stream, ipart); - /* I think this will loop: em_format_part_as(emf, stream, part, "text/plain"); */ - camel_exception_free(ex); - camel_object_unref(cipher); - camel_object_unref(opart); - return; - } - - dw = camel_medium_get_content_object ((CamelMedium *)opart); - mime_type = camel_data_wrapper_get_mime_type (dw); - - /* this ensures to show the 'opart' as inlined, if possible */ - if (mime_type && g_ascii_strcasecmp (mime_type, "application/octet-stream") == 0) { - const char *snoop = em_utils_snoop_type (opart); - - if (snoop) - camel_data_wrapper_set_mime_type (dw, snoop); - } - - g_free (mime_type); - - /* Pass it off to the real formatter */ - em_format_format_secure(emf, stream, opart, valid); - - /* Clean Up */ - camel_object_unref(opart); - camel_object_unref (cipher); - camel_exception_free (ex); -} - -static EMFormatHandler type_builtin_table[] = { -#ifdef ENABLE_SMIME - { "application/x-pkcs7-mime", (EMFormatFunc)emf_application_xpkcs7mime, EM_FORMAT_HANDLER_INLINE_DISPOSITION }, -#endif - { "multipart/alternative", emf_multipart_alternative }, - { "multipart/appledouble", emf_multipart_appledouble }, - { "multipart/encrypted", emf_multipart_encrypted }, - { "multipart/mixed", emf_multipart_mixed }, - { "multipart/signed", emf_multipart_signed }, - { "multipart/related", emf_multipart_related }, - { "multipart/*", emf_multipart_mixed }, - { "message/rfc822", emf_message_rfc822, EM_FORMAT_HANDLER_INLINE }, - { "message/news", emf_message_rfc822, EM_FORMAT_HANDLER_INLINE }, - { "message/delivery-status", emf_message_deliverystatus }, - { "message/*", emf_message_rfc822, EM_FORMAT_HANDLER_INLINE }, - - /* Insert brokenly-named parts here */ -#ifdef ENABLE_SMIME - { "application/pkcs7-mime", (EMFormatFunc)emf_application_xpkcs7mime, EM_FORMAT_HANDLER_INLINE_DISPOSITION }, -#endif - - /* internal types */ - { "application/x-inlinepgp-signed", (EMFormatFunc)emf_inlinepgp_signed }, - { "application/x-inlinepgp-encrypted", (EMFormatFunc)emf_inlinepgp_encrypted }, -}; - -static void -emf_builtin_init(EMFormatClass *class) -{ - int i; - - for (i=0;i<sizeof(type_builtin_table)/sizeof(type_builtin_table[0]);i++) - g_hash_table_insert(class->type_handlers, type_builtin_table[i].mime_type, &type_builtin_table[i]); -} diff --git a/mail/em-format.h b/mail/em-format.h deleted file mode 100644 index f262d49be1..0000000000 --- a/mail/em-format.h +++ /dev/null @@ -1,403 +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) - * - */ - -/* - Abstract class for formatting mime messages -*/ - -#ifndef EM_FORMAT_H -#define EM_FORMAT_H - -#include <glib-object.h> -#include <camel/camel-url.h> -#include <camel/camel-folder.h> -#include <camel/camel-stream.h> -#include <camel/camel-session.h> -#include <camel/camel-mime-part.h> -#include <camel/camel-mime-message.h> -#include <camel/camel-cipher-context.h> -#include <libedataserver/e-msgport.h> - -/* Standard GObject macros */ -#define EM_TYPE_FORMAT \ - (em_format_get_type ()) -#define EM_FORMAT(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), EM_TYPE_FORMAT, EMFormat)) -#define EM_FORMAT_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), EM_TYPE_FORMAT, EMFormatClass)) -#define EM_IS_FORMAT(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), EM_TYPE_FORMAT)) -#define EM_IS_FORMAT_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), EM_TYPE_FORMAT)) -#define EM_FORMAT_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), EM_TYPE_FORMAT, EMFormatClass)) - -G_BEGIN_DECLS - -typedef struct _EMFormat EMFormat; -typedef struct _EMFormatClass EMFormatClass; -typedef struct _EMFormatPrivate EMFormatPrivate; - -typedef struct _EMFormatHandler EMFormatHandler; -typedef struct _EMFormatHeader EMFormatHeader; - -typedef void (*EMFormatFunc) (EMFormat *md, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info); - -typedef enum _em_format_mode_t { - EM_FORMAT_NORMAL, - EM_FORMAT_ALLHEADERS, - EM_FORMAT_SOURCE, -} em_format_mode_t; - -/** - * struct _EMFormatHandler - MIME type handler. - * - * @mime_type: Type this handler handles. - * @handler: The handler callback. - * @flags: Handling flags, see enum _em_format_handler_t. - * @old: The last handler set on this type. Allows overrides to - * fallback to previous implementation. - * - **/ -struct _EMFormatHandler { - char *mime_type; - EMFormatFunc handler; - guint32 flags; - - struct _EMFormatHandler *old; -}; - -/** - * enum _em_format_handler_t - Format handler flags. - * - * @EM_FORMAT_HANDLER_INLINE: This type should be shown expanded - * inline by default. - * @EM_FORMAT_HANDLER_INLINE_DISPOSITION: This type should always be - * shown inline, despite what the Content-Disposition suggests. - * - **/ -enum _em_format_handler_t { - EM_FORMAT_HANDLER_INLINE = 1<<0, - EM_FORMAT_HANDLER_INLINE_DISPOSITION = 1<<1, -}; - - -typedef struct _EMFormatPURI EMFormatPURI; -typedef void (*EMFormatPURIFunc)(EMFormat *md, CamelStream *stream, EMFormatPURI *puri); - -/** - * struct _EMFormatPURI - Pending URI object. - * - * @next: Double-linked list header. - * @prev: Double-linked list header. - * @free: May be set by allocator and will be called when no longer needed. - * @format: - * @uri: Calculated URI of the part, if the part has one in its - * Content-Location field. - * @cid: The RFC2046 Content-Id of the part. If none is present, a unique value - * is calculated from @part_id. - * @part_id: A unique identifier for each part. - * @func: Callback for when the URI is requested. The callback writes - * its data to the supplied stream. - * @part: - * @use_count: - * - * This is used for multipart/related, and other formatters which may - * need to include a reference to out-of-band data in the content - * stream. - * - * This object may be subclassed as a struct. - **/ -struct _EMFormatPURI { - struct _EMFormatPURI *next; - struct _EMFormatPURI *prev; - - void (*free)(struct _EMFormatPURI *p); /* optional callback for freeing user-fields */ - struct _EMFormat *format; - - char *uri; /* will be the location of the part, may be empty */ - char *cid; /* will always be set, a fake one created if needed */ - char *part_id; /* will always be set, emf->part_id->str for this part */ - - EMFormatPURIFunc func; - CamelMimePart *part; - - unsigned int use_count; /* used by multipart/related to see if it was accessed */ -}; - -/** - * struct _EMFormatPURITree - Pending URI visibility tree. - * - * @next: Double-linked list header. - * @prev: Double-linked list header. - * @parent: Parent in tree. - * @uri_list: List of EMFormatPURI objects at this level. - * @children: Child nodes of EMFormatPURITree. - * - * This structure is used internally to form a visibility tree of - * parts in the current formatting stream. This is to implement the - * part resolution rules for RFC2387 to implement multipart/related. - **/ -struct _EMFormatPURITree { - struct _EMFormatPURITree *next; - struct _EMFormatPURITree *prev; - struct _EMFormatPURITree *parent; - - EDList uri_list; - EDList children; -}; - -struct _EMFormatHeader { - struct _EMFormatHeader *next, *prev; - - guint32 flags; /* E_FORMAT_HEADER_* */ - char name[1]; -}; - -#define EM_FORMAT_HEADER_BOLD (1<<0) -#define EM_FORMAT_HEADER_LAST (1<<4) /* reserve 4 slots */ - -/** - * struct _EMFormat - Mail formatter object. - * - * @parent: - * @priv: - * @message: - * @folder: - * @uid: - * @part_id: - * @header_list: - * @session: - * @base url: - * @snoop_mime_type: - * @valid: - * @valid_parent: - * @inline_table: - * @pending_uri_table: - * @pending_uri_tree: - * @pending_uri_level: - * @mode: - * @charset: - * @default_charset: - * - * Most fields are private or read-only. - * - * This is the base MIME formatter class. It provides no formatting - * itself, but drives most of the basic types, including multipart / * types. - **/ -struct _EMFormat { - GObject parent; - - EMFormatPrivate *priv; - - CamelMimeMessage *message; /* the current message */ - - CamelFolder *folder; - char *uid; - - GString *part_id; /* current part id prefix, for identifying parts directly */ - - EDList header_list; /* if empty, then all */ - - CamelSession *session; /* session, used for authentication when required */ - CamelURL *base; /* content-base header or absolute content-location, for any part */ - - const char *snoop_mime_type; /* if we snooped an application/octet-stream type, what we snooped */ - - /* for validity enveloping */ - CamelCipherValidity *valid; - CamelCipherValidity *valid_parent; - - /* for forcing inlining */ - GHashTable *inline_table; - - /* global lookup table for message */ - GHashTable *pending_uri_table; - - /* visibility tree, also stores every puri permanently */ - struct _EMFormatPURITree *pending_uri_tree; - /* current level to search from */ - struct _EMFormatPURITree *pending_uri_level; - - em_format_mode_t mode; /* source/headers/etc */ - char *charset; /* charset override */ - char *default_charset; /* charset fallback */ - gboolean composer; /* Formatting from composer ?*/ - gboolean print; -}; - -struct _EMFormatClass { - GObjectClass parent_class; - - GHashTable *type_handlers; - - /* lookup handler, default falls back to hashtable above */ - const EMFormatHandler *(*find_handler)(EMFormat *, const char *mime_type); - - /* start formatting a message */ - void (*format_clone)(EMFormat *, CamelFolder *, const char *uid, CamelMimeMessage *, EMFormat *); - - /* some internel error/inconsistency */ - void (*format_error)(EMFormat *, CamelStream *, const char *msg); - - /* use for external structured parts */ - void (*format_attachment)(EMFormat *, CamelStream *, CamelMimePart *, const char *mime_type, const struct _EMFormatHandler *info); - - /* use for unparsable content */ - void (*format_source)(EMFormat *, CamelStream *, CamelMimePart *); - /* for outputing secure(d) content */ - void (*format_secure)(EMFormat *, CamelStream *, CamelMimePart *, CamelCipherValidity *); - - /* returns true if the formatter is still busy with pending stuff */ - gboolean (*busy)(EMFormat *); - - /* Shows optional way to open messages */ - void (*format_optional)(EMFormat *, CamelStream *, CamelMimePart *, CamelStream* ); - - /* signals */ - /* complete, alternative to polling busy, for asynchronous work */ - void (*complete)(EMFormat *); -}; - -void em_format_set_mode (EMFormat *emf, - em_format_mode_t type); -void em_format_set_charset (EMFormat *emf, - const char *charset); -void em_format_set_default_charset (EMFormat *emf, - const char *charset); - -/* also indicates to show all headers */ -void em_format_clear_headers (EMFormat *emf); - -void em_format_default_headers (EMFormat *emf); -void em_format_add_header (EMFormat *emf, - const gchar *name, - guint32 flags); - -/* FIXME: Need a 'clone' api to copy details about the current view (inlines etc) - Or maybe it should live with sub-classes? */ - -int em_format_is_attachment (EMFormat *emf, - CamelMimePart *part); - -int em_format_is_inline (EMFormat *emf, - const char *partid, - CamelMimePart *part, - const EMFormatHandler *handle); -void em_format_set_inline (EMFormat *emf, - const char *partid, - int state); - -char * em_format_describe_part (CamelMimePart *part, - const char *mime_type); - -/* for implementers */ -GType em_format_get_type (void); - -void em_format_class_add_handler (EMFormatClass *emfc, - EMFormatHandler *info); -void em_format_class_remove_handler (EMFormatClass *emfc, - EMFormatHandler *info); -const EMFormatHandler * - em_format_find_handler (EMFormat *emf, - const gchar *mime_type); -const EMFormatHandler * - em_format_fallback_handler (EMFormat *emf, - const gchar *mime_type); - -/* puri is short for pending uri ... really */ -EMFormatPURI * em_format_add_puri (EMFormat *emf, - size_t size, - const char *uri, - CamelMimePart *part, - EMFormatPURIFunc func); -EMFormatPURI * em_format_find_visible_puri (EMFormat *emf, - const char *uri); -EMFormatPURI * em_format_find_puri (EMFormat *emf, - const char *uri); -void em_format_clear_puri_tree (EMFormat *emf); -void em_format_push_level (EMFormat *emf); -void em_format_pull_level (EMFormat *emf); - -/* clones inline state/view and format, or use to redraw */ -void em_format_format_clone (EMFormat *emf, - CamelFolder *folder, - const gchar *uid, - CamelMimeMessage *message, - EMFormat *source); - -/* formats a new message */ -void em_format_format (EMFormat *emf, - CamelFolder *folder, - const gchar *uid, - CamelMimeMessage *message); -void em_format_redraw (EMFormat *emf); -void em_format_format_attachment (EMFormat *emf, - CamelStream *stream, - CamelMimePart *mime_part, - const gchar *mime_type, - const struct _EMFormatHandler *info); -void em_format_format_error (EMFormat *emf, - CamelStream *stream, - const gchar *format, - ...) G_GNUC_PRINTF (3, 4); -void em_format_format_secure (EMFormat *emf, - CamelStream *stream, - CamelMimePart *mime_part, - CamelCipherValidity *valid); -void em_format_format_source (EMFormat *emf, - CamelStream *stream, - CamelMimePart *mime_part); - -gboolean em_format_busy (EMFormat *emf); - -/* raw content only */ -void em_format_format_content (EMFormat *emf, - CamelStream *stream, - CamelMimePart *part); - -/* raw content text parts - should this just be checked/done by above? */ -void em_format_format_text (EMFormat *emf, - CamelStream *stream, - CamelDataWrapper *part); - -void em_format_part_as (EMFormat *emf, - CamelStream *stream, - CamelMimePart *part, - const gchar *mime_type); -void em_format_part (EMFormat *emf, - CamelStream *stream, - CamelMimePart *part); -void em_format_merge_handler (EMFormat *new, - EMFormat *old); - -G_END_DECLS - -G_END_DECLS - -#endif /* EM_FORMAT_H */ diff --git a/mail/em-inline-filter.c b/mail/em-inline-filter.c index 07c7afa192..99d64112d2 100644 --- a/mail/em-inline-filter.c +++ b/mail/em-inline-filter.c @@ -32,6 +32,7 @@ #include <camel/camel-stream-mem.h> #include "em-utils.h" +#include "em-format/em-format.h" #define d(x) @@ -176,7 +177,7 @@ emif_add_part(EMInlineFilter *emif, const char *data, int len) /* 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_utils_snoop_type(part)) + && (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); diff --git a/mail/em-mailer-prefs.c b/mail/em-mailer-prefs.c index 379d126c0b..6c4fff4138 100644 --- a/mail/em-mailer-prefs.c +++ b/mail/em-mailer-prefs.c @@ -28,7 +28,7 @@ #include <glib/gi18n-lib.h> #include "em-mailer-prefs.h" -#include "em-format.h" +#include "em-format/em-format.h" #include <camel/camel-iconv.h> #include <gtkhtml/gtkhtml-properties.h> diff --git a/mail/em-stripsig-filter.c b/mail/em-stripsig-filter.c deleted file mode 100644 index 7dd8a87416..0000000000 --- a/mail/em-stripsig-filter.c +++ /dev/null @@ -1,169 +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: - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <string.h> - -#include "em-stripsig-filter.h" - - -static void em_stripsig_filter_class_init (EMStripSigFilterClass *klass); -static void em_stripsig_filter_init (EMStripSigFilter *filter, EMStripSigFilterClass *klass); - -static void filter_filter (CamelMimeFilter *filter, char *in, size_t len, size_t prespace, - char **out, size_t *outlen, size_t *outprespace); -static void filter_complete (CamelMimeFilter *filter, char *in, size_t len, size_t prespace, - char **out, size_t *outlen, size_t *outprespace); -static void filter_reset (CamelMimeFilter *filter); - - -static CamelMimeFilterClass *parent_class = NULL; - - -CamelType -em_stripsig_filter_get_type (void) -{ - static CamelType type = CAMEL_INVALID_TYPE; - - if (type == CAMEL_INVALID_TYPE) { - type = camel_type_register (camel_mime_filter_get_type (), - "EMStripSigFilter", - sizeof (EMStripSigFilter), - sizeof (EMStripSigFilterClass), - (CamelObjectClassInitFunc) em_stripsig_filter_class_init, - NULL, - (CamelObjectInitFunc) em_stripsig_filter_init, - NULL); - } - - return type; -} - - -static void -em_stripsig_filter_class_init (EMStripSigFilterClass *klass) -{ - CamelMimeFilterClass *filter_class = (CamelMimeFilterClass *) klass; - - parent_class = CAMEL_MIME_FILTER_CLASS (camel_type_get_global_classfuncs (camel_mime_filter_get_type ())); - - filter_class->reset = filter_reset; - filter_class->filter = filter_filter; - filter_class->complete = filter_complete; -} - -static void -em_stripsig_filter_init (EMStripSigFilter *filter, EMStripSigFilterClass *klass) -{ - filter->midline = FALSE; -} - -static void -strip_signature (CamelMimeFilter *filter, char *in, size_t len, size_t prespace, - char **out, size_t *outlen, size_t *outprespace, int flush) -{ - EMStripSigFilter *stripsig = (EMStripSigFilter *) filter; - register const char *inptr = in; - const char *inend = in + len; - const char *start = NULL; - - if (stripsig->midline) { - while (inptr < inend && *inptr != '\n') - inptr++; - - if (inptr < inend) { - stripsig->midline = FALSE; - inptr++; - } - } - - while (inptr < inend) { - if ((inend - inptr) >= 4 && !strncmp (inptr, "-- \n", 4)) { - start = inptr; - inptr += 4; - } else { - while (inptr < inend && *inptr != '\n') - inptr++; - - if (inptr == inend) { - stripsig->midline = TRUE; - break; - } - - inptr++; - } - } - - if (start != NULL) - inptr = start; - - if (!flush && inend > inptr) - camel_mime_filter_backup (filter, inptr, inend - inptr); - else if (!start) - inptr = inend; - - *out = in; - *outlen = inptr - in; - *outprespace = prespace; -} - -static void -filter_filter (CamelMimeFilter *filter, char *in, size_t len, size_t prespace, - char **out, size_t *outlen, size_t *outprespace) -{ - strip_signature (filter, in, len, prespace, out, outlen, outprespace, FALSE); -} - -static void -filter_complete (CamelMimeFilter *filter, char *in, size_t len, size_t prespace, - char **out, size_t *outlen, size_t *outprespace) -{ - strip_signature (filter, in, len, prespace, out, outlen, outprespace, TRUE); -} - -/* should this 'flush' outstanding state/data bytes? */ -static void -filter_reset (CamelMimeFilter *filter) -{ - EMStripSigFilter *stripsig = (EMStripSigFilter *) filter; - - stripsig->midline = FALSE; -} - - -/** - * em_stripsig_filter_new: - * - * Creates a new stripsig filter. - * - * Returns a new stripsig filter. - **/ -CamelMimeFilter * -em_stripsig_filter_new (void) -{ - return (CamelMimeFilter *) camel_object_new (EM_TYPE_STRIPSIG_FILTER); -} diff --git a/mail/em-stripsig-filter.h b/mail/em-stripsig-filter.h deleted file mode 100644 index be72cef3df..0000000000 --- a/mail/em-stripsig-filter.h +++ /dev/null @@ -1,63 +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: - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef __EM_STRIPSIG_FILTER_H__ -#define __EM_STRIPSIG_FILTER_H__ - -#include <camel/camel-mime-filter.h> - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - -#define EM_TYPE_STRIPSIG_FILTER (em_stripsig_filter_get_type ()) -#define EM_STRIPSIG_FILTER(obj) (CAMEL_CHECK_CAST ((obj), EM_TYPE_STRIPSIG_FILTER, EMStripSigFilter)) -#define EM_STRIPSIG_FILTER_CLASS(klass) (CAMEL_CHECK_CLASS_CAST ((klass), EM_TYPE_STRIPSIG_FILTER, EMStripSigFilterClass)) -#define EM_IS_STRIPSIG_FILTER(obj) (CAMEL_CHECK_TYPE ((obj), EM_TYPE_STRIPSIG_FILTER)) -#define EM_IS_STRIPSIG_FILTER_CLASS(klass) (CAMEL_CHECK_CLASS_TYPE ((klass), EM_TYPE_STRIPSIG_FILTER)) -#define EM_STRIPSIG_FILTER_GET_CLASS(obj) (CAMEL_CHECK_GET_CLASS ((obj), EM_TYPE_STRIPSIG_FILTER, EMStripSigFilterClass)) - -typedef struct _EMStripSigFilter EMStripSigFilter; -typedef struct _EMStripSigFilterClass EMStripSigFilterClass; - -struct _EMStripSigFilter { - CamelMimeFilter parent_object; - - guint32 midline:1; -}; - -struct _EMStripSigFilterClass { - CamelMimeFilterClass parent_class; - -}; - - -CamelType em_stripsig_filter_get_type (void); - -CamelMimeFilter *em_stripsig_filter_new (void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __EM_STRIPSIG_FILTER_H__ */ diff --git a/mail/em-utils.c b/mail/em-utils.c index 45f54abbcf..2a7ce74c70 100644 --- a/mail/em-utils.c +++ b/mail/em-utils.c @@ -1628,52 +1628,6 @@ em_utils_get_proxy_uri (const char *pUri) } /** - * em_utils_part_to_html: - * @part: - * - * Converts a mime part's contents into html text. If @credits is given, - * then it will be used as an attribution string, and the - * content will be cited. Otherwise no citation or attribution - * will be performed. - * - * Return Value: The part in displayable html format. - **/ -char * -em_utils_part_to_html(CamelMimePart *part, ssize_t *len, EMFormat *source) -{ - EMFormatQuote *emfq; - CamelStreamMem *mem; - GByteArray *buf; - char *text; - - buf = g_byte_array_new (); - mem = (CamelStreamMem *) camel_stream_mem_new (); - camel_stream_mem_set_byte_array (mem, buf); - - emfq = em_format_quote_new(NULL, (CamelStream *)mem, 0); - ((EMFormat *) emfq)->composer = TRUE; - if (source) { - /* copy over things we can, other things are internal, perhaps need different api than 'clone' */ - if (source->default_charset) - em_format_set_default_charset((EMFormat *)emfq, source->default_charset); - if (source->charset) - em_format_set_default_charset((EMFormat *)emfq, source->charset); - } - em_format_part((EMFormat *) emfq, (CamelStream *)mem, part); - g_object_unref(emfq); - - camel_stream_write((CamelStream *) mem, "", 1); - camel_object_unref(mem); - - text = (char *)buf->data; - if (len) - *len = buf->len-1; - g_byte_array_free (buf, FALSE); - - return text; -} - -/** * em_utils_message_to_html: * @message: * @credits: @@ -2328,88 +2282,6 @@ em_utils_contact_photo (struct _CamelInternetAddress *cia, gboolean local) return part; } -/** - * em_utils_snoop_type: - * @part: - * - * Tries to snoop the mime type of a part. - * - * Return value: NULL if unknown (more likely application/octet-stream). - **/ -const char * -em_utils_snoop_type(CamelMimePart *part) -{ - /* cache is here only to be able still return const char * */ - static GHashTable *types_cache = NULL; - - const char *filename; - char *name_type = NULL, *magic_type = NULL, *res, *tmp; - CamelDataWrapper *dw; - - filename = camel_mime_part_get_filename (part); - if (filename != NULL) - name_type = e_util_guess_mime_type (filename, FALSE); - - dw = camel_medium_get_content_object((CamelMedium *)part); - if (!camel_data_wrapper_is_offline(dw)) { - CamelStreamMem *mem = (CamelStreamMem *)camel_stream_mem_new(); - - if (camel_data_wrapper_decode_to_stream(dw, (CamelStream *)mem) > 0) { - char *ct = g_content_type_guess (filename, mem->buffer->data, mem->buffer->len, NULL); - - if (ct) - magic_type = g_content_type_get_mime_type (ct); - - g_free (ct); - } - camel_object_unref(mem); - } - - d(printf("snooped part, magic_type '%s' name_type '%s'\n", magic_type, name_type)); - - /* If gvfs doesn't recognize the data by magic, but it - * contains English words, it will call it text/plain. If the - * filename-based check came up with something different, use - * that instead and if it returns "application/octet-stream" - * try to do better with the filename check. - */ - - if (magic_type) { - if (name_type - && (!strcmp(magic_type, "text/plain") - || !strcmp(magic_type, "application/octet-stream"))) - res = name_type; - else - res = magic_type; - } else - res = name_type; - - - if (res != name_type) - g_free (name_type); - - if (res != magic_type) - g_free (magic_type); - - if (!types_cache) - types_cache = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) NULL); - - if (res) { - tmp = g_hash_table_lookup (types_cache, res); - if (tmp) { - g_free (res); - res = tmp; - } else { - g_hash_table_insert (types_cache, res, res); - } - } - - return res; - - /* We used to load parts to check their type, we dont anymore, - see bug #11778 for some discussion */ -} - void em_utils_clear_get_password_canceled_accounts_flag (void) { diff --git a/mail/em-utils.h b/mail/em-utils.h index 60c6e22c47..3167dba8fb 100644 --- a/mail/em-utils.h +++ b/mail/em-utils.h @@ -83,7 +83,6 @@ void em_utils_adjustment_page(GtkAdjustment *adj, gboolean down); char *em_utils_get_proxy_uri (const char *uri); /* FIXME: should this have an override charset? */ -char *em_utils_part_to_html(CamelMimePart *part, ssize_t *len, struct _EMFormat *source); char *em_utils_message_to_html(CamelMimeMessage *msg, const char *credits, guint32 flags, ssize_t *len, struct _EMFormat *source, const char *append); void em_utils_expunge_folder (GtkWidget *parent, CamelFolder *folder); @@ -104,8 +103,6 @@ void em_utils_show_info_silent (GtkWidget *widget); gboolean em_utils_in_addressbook (CamelInternetAddress *addr, gboolean local_only); CamelMimePart *em_utils_contact_photo (CamelInternetAddress *addr, gboolean local); -const char *em_utils_snoop_type(CamelMimePart *part); - /* clears flag 'get_password_canceled' at every known accounts, so if needed, get_password will show dialog */ void em_utils_clear_get_password_canceled_accounts_flag (void); diff --git a/mail/importers/Makefile.am b/mail/importers/Makefile.am deleted file mode 100644 index 25b5648949..0000000000 --- a/mail/importers/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -if OS_WIN32 -WIN32_BOOTSTRAP_LIBS = $(top_builddir)/win32/libevolution-mail.la -endif - -privsolib_LTLIBRARIES = libevolution-mail-importers.la - -INCLUDES = -I.. \ - -I$(srcdir)/.. \ - -I$(top_srcdir) \ - -DG_LOG_DOMAIN=\"evolution-mail-importer\" \ - -I$(top_srcdir)/addressbook/backend \ - -I$(top_builddir)/addressbook/backend \ - -DEVOLUTION_PRIVDATADIR=\""$(privdatadir)"\" \ - $(IMPORTERS_CFLAGS) - -libevolution_mail_importers_la_SOURCES = \ - mail-importer.c \ - mail-importer.h \ - elm-importer.c \ - pine-importer.c \ - evolution-mbox-importer.c - -libevolution_mail_importers_la_LDFLAGS = $(NO_UNDEFINED) - -libevolution_mail_importers_la_LIBADD = \ - $(WIN32_BOOTSTRAP_LIBS) \ - $(top_builddir)/e-util/libeutil.la \ - $(top_builddir)/filter/libfilter.la \ - $(IMPORTERS_LIBS) - --include $(top_srcdir)/git.mk diff --git a/mail/mail-component.c b/mail/mail-component.c index 926f5716c9..6167cc58f6 100644 --- a/mail/mail-component.c +++ b/mail/mail-component.c @@ -37,7 +37,7 @@ #include <libedataserver/e-data-server-util.h> #include "em-utils.h" #include "em-composer-utils.h" -#include "em-format.h" +#include "em-format/em-format.h" #include "em-folder-tree.h" #include "em-folder-browser.h" #include "em-message-browser.h" |