From 6e8b7d1fa8ae22cd803f1886ea562049ef68cb1e Mon Sep 17 00:00:00 2001 From: Stefan Becker Date: Sat, 27 Mar 2010 02:03:27 +0200 Subject: [PATCH] core cleanup: implement GMime-based sipe_mime module If GMime 2.4 or 2.6 headers are available then the Purple MIME implementation is disabled and replaced with the one based on GMime. If another backend than purple is enabled then GMime is a mandatory build requirement. The minimum versions are 2.4.16 or 2.5.2 in order to get this bug fix: It also available in version 2.2.26 but GMime upstream maintainers request that we shouldn't use this old obsolete API. That means that on platforms that only offer the GMime 2.0 API you'll only be able to compile the purple plugin. It is doubtful if such outdated platforms would have version 2.2.26 available or would support other frameworks, like telepathy, so this is no real limitation. --- configure.ac | 20 ++++++++-- src/core/Makefile.am | 5 +++ src/core/sipe-mime.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++ src/core/sipe.c | 9 +++++ src/purple/Makefile.am | 11 +++++- 5 files changed, 144 insertions(+), 5 deletions(-) create mode 100644 src/core/sipe-mime.c diff --git a/configure.ac b/configure.ac index 773a99fc..94c3c194 100644 --- a/configure.ac +++ b/configure.ac @@ -155,6 +155,18 @@ fi dnl check for glib PKG_CHECK_MODULES(GLIB, [glib-2.0 >= 2.12.0]) +dnl check for gmime +dnl See also: https://bugzilla.gnome.org/show_bug.cgi?id=613653#c8 +PKG_CHECK_MODULES(GMIME, [gmime-2.6 >= 2.5.2], + [ac_have_gmime=yes], + [PKG_CHECK_MODULES(GMIME, [gmime-2.4 >= 2.4.16], + [ac_have_gmime=yes], + [ac_have_gmime=no]) +]) +AM_CONDITIONAL(SIPE_MIME_GMIME, [test x$ac_have_gmime = xyes]) +AM_COND_IF(SIPE_MIME_GMIME, + [AC_DEFINE(HAVE_GMIME, 1, [Define if gmime should be used in sipe.])]) + dnl check for libxml2 PKG_CHECK_MODULES(LIBXML2, [libxml-2.0]) @@ -256,9 +268,11 @@ fi dnl support for telepathy plugin AM_CONDITIONAL(SIPE_INCLUDE_TELEPATHY, test "$telepathy" != "no") -dnl NOTHING IMPLEMENTED YET!!! -dnl if test "$telepathy" != "no"; then -dnl fi +if test "$telepathy" != "no"; then + AM_COND_IF(SIPE_MIME_GMIME, [], + [AC_ERROR(GMIME package is required for telepathy plugin)]) + dnl NOTHING IMPLEMENTED YET!!! +fi dnl sanity check AS_IF([test "$purple" = "no" -a "$telepathy" = "no"], diff --git a/src/core/Makefile.am b/src/core/Makefile.am index 6397532c..1ff4c81f 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -57,6 +57,11 @@ libsipe_core_la_SOURCES += sip-sec-krb5.h sip-sec-krb5.c libsipe_core_la_CFLAGS += $(KRB5_CFLAGS) endif +if SIPE_MIME_GMIME +libsipe_core_la_SOURCES += sipe-mime.c +libsipe_core_la_CFLAGS += $(GMIME_CFLAGS) +endif + if SIPE_INCLUDE_PURPLE libsipe_core_purple_la_CFLAGS = \ $(libsipe_core_la_CFLAGS) \ diff --git a/src/core/sipe-mime.c b/src/core/sipe-mime.c new file mode 100644 index 00000000..ba4e7f84 --- /dev/null +++ b/src/core/sipe-mime.c @@ -0,0 +1,104 @@ +/** + * @file sipe-mime.c + * + * pidgin-sipe + * + * Copyright (C) 2010 SIPE Project + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#include +#include + +#include "sipe-common.h" +#include "sipe-mime.h" + +#include "sipe-backend.h" + +struct gmime_callback_data { + sipe_mime_parts_cb callback; + gpointer user_data; +}; + +static void gmime_callback(SIPE_UNUSED_PARAMETER GMimeObject *parent, + GMimeObject *part, + gpointer user_data) +{ + GMimeDataWrapper *data = g_mime_part_get_content_object((GMimePart *)part); + + if (data) { + GMimeStream *stream = g_mime_data_wrapper_get_stream(data); + + if (stream) { + ssize_t length = g_mime_stream_length(stream); + + if (length != -1) { + gchar *content = g_malloc(length + 1); + + if (g_mime_stream_read(stream, content, length) == length) { + struct gmime_callback_data *cd = user_data; + gchar *type_name = g_mime_content_type_to_string( + g_mime_object_get_content_type(part)); + + SIPE_DEBUG_INFO("sipe_mime_parts_foreach: type '%s' length %d", type_name, length); + + (*(cd->callback))(cd->user_data, type_name, content, length); + + g_free(type_name); + } + g_free(content); + } + g_object_unref(stream); + } + } +} + +void sipe_mime_parts_foreach(const gchar *type, + const gchar *body, + sipe_mime_parts_cb callback, + gpointer user_data) +{ + gchar *doc = g_strdup_printf("Content-Type: %s\r\n\r\n%s", type, body); + GMimeStream *stream = g_mime_stream_mem_new_with_buffer(doc, strlen(doc)); + + if (stream) { + GMimeParser *parser = g_mime_parser_new_with_stream(stream); + GMimeMultipart *multipart = (GMimeMultipart *)g_mime_parser_construct_part(parser); + + if (multipart) { + struct gmime_callback_data cd = {callback, user_data}; + + SIPE_DEBUG_INFO("sipe_mime_parts_foreach: %d parts", g_mime_multipart_get_count(multipart)); + + g_mime_multipart_foreach(multipart, gmime_callback, &cd); + } + + g_object_unref(parser); + g_object_unref(stream); + } + g_free(doc); +} + +/* + Local Variables: + mode: c + c-file-style: "bsd" + indent-tabs-mode: t + tab-width: 8 + End: +*/ diff --git a/src/core/sipe.c b/src/core/sipe.c index 3413ff13..6499426e 100644 --- a/src/core/sipe.c +++ b/src/core/sipe.c @@ -60,6 +60,9 @@ #include #include +#ifdef HAVE_GMIME +#include +#endif #include "sipe-common.h" @@ -10164,10 +10167,16 @@ void sipe_core_init(void) bind_textdomain_codeset(PACKAGE_NAME, "UTF-8")); textdomain(PACKAGE_NAME); #endif +#ifdef HAVE_GMIME + g_mime_init(0); +#endif } void sipe_core_destroy(void) { +#ifdef HAVE_GMIME + g_mime_shutdown(); +#endif sip_sec_destroy(); } diff --git a/src/purple/Makefile.am b/src/purple/Makefile.am index f85e5c1a..03132b7e 100644 --- a/src/purple/Makefile.am +++ b/src/purple/Makefile.am @@ -11,7 +11,6 @@ EXTRA_DIST = \ libsipe_la_SOURCES = \ purple-debug.c \ purple-markup.c \ - purple-mime.c \ purple-plugin.c AM_CFLAGS = $(st) @@ -40,11 +39,19 @@ libsipe_la_LIBADD += $(KRB5_LIBS) endif check_PROGRAMS = tests -tests_SOURCES = tests.c purple-debug.c purple-markup.c purple-mime.c +tests_SOURCES = tests.c purple-debug.c purple-markup.c tests_CFLAGS = $(libsipe_la_CFLAGS) -I$(srcdir)/../core tests_LDADD = ../core/libsipe_core.la ../core/libsipe_core_purple.la tests_LDFLAGS = $(PURPLE_LIBS) +if SIPE_MIME_GMIME +libsipe_la_LIBADD += $(GMIME_LIBS) +tests_LDFLAGS += $(GMIME_LIBS) +else +libsipe_la_SOURCES += purple-mime.c +tests_SOURCES += purple-mime.c +endif + TESTS = $(check_PROGRAMS) # Remove any libsipe.so from the old incorrect installation location -- 2.11.4.GIT