$OpenBSD: patch-pan_usenet-utils_mime-utils_cc,v 1.1 2010/09/13 16:23:47 ajacoutot Exp $

Fix build with GMime 2.4:
    https://bugzilla.gnome.org/show_bug.cgi?id=541676

--- pan/usenet-utils/mime-utils.cc.orig	Sat Jul  5 08:15:24 2008
+++ pan/usenet-utils/mime-utils.cc	Sat Sep 11 10:42:52 2010
@@ -455,10 +455,10 @@ namespace
       part->stream = g_mime_stream_mem_new ();
       if (part->type != ENC_PLAIN) {
 	part->filter_stream =
-	  g_mime_stream_filter_new_with_stream (part->stream);
+	  g_mime_stream_filter_new (part->stream);
         part->filter = part->type == ENC_UU
-	  ? g_mime_filter_basic_new_type (GMIME_FILTER_BASIC_UU_DEC)
-	  : g_mime_filter_yenc_new (GMIME_FILTER_YENC_DIRECTION_DECODE);
+	  ? g_mime_filter_basic_new (GMIME_CONTENT_ENCODING_UUENCODE, FALSE)
+	  : g_mime_filter_yenc_new (FALSE);
 	g_mime_stream_filter_add (GMIME_STREAM_FILTER(part->filter_stream),
                                   part->filter);
       }
@@ -722,18 +722,21 @@ namespace
   {
     // if the part is a multipart, check its subparts
     if (GMIME_IS_MULTIPART (*part)) {
-      GList * subparts = GMIME_MULTIPART (*part)->subparts;
-      while (subparts) {
-        GMimeObject * subpart = (GMimeObject *) subparts->data;
+      GMimeMultipart *multipart = (GMimeMultipart *) *part;
+      int count = g_mime_multipart_get_count(multipart);
+      int i;
+      
+      for (i = 0; i < count; i++) {
+        GMimeObject * subpart = g_mime_multipart_remove_at (multipart, i);
         handle_uu_and_yenc_in_text_plain (&subpart);
-        subparts->data = subpart;
-        subparts = subparts->next;
+        g_mime_multipart_insert (multipart, i, subpart);
+        g_object_unref (subpart);
       }
       return;
     }
 
     // we assume that inlined yenc and uu are only in text/plain blocks
-    const GMimeContentType * content_type = g_mime_object_get_content_type (*part);
+    GMimeContentType * content_type = g_mime_object_get_content_type (*part);
     if (!g_mime_content_type_is_type (content_type, "text", "plain"))
       return;
 
@@ -746,8 +749,8 @@ namespace
     GMimeStream * stream = g_mime_data_wrapper_get_stream (content);
     g_mime_stream_reset (stream);
     GMimeStream * istream = g_mime_stream_buffer_new (stream, GMIME_STREAM_BUFFER_BLOCK_READ);
-    g_object_unref (stream);
-    g_object_unref (content);
+//    g_object_unref (stream); //SKG if this is unrefed, when istream is unrefed below, content loses its stream
+//    g_object_unref (content); //SKG gmime 2.4 don't unref returned data wrapper
 
     // break it into separate parts for text, uu, and yenc pieces.
     temp_parts_t parts;
@@ -774,22 +777,22 @@ namespace
           g_mime_part_set_filename (subpart, filename);
 
         GMimeStream * subpart_stream = tmp_part->stream;
-        content = g_mime_data_wrapper_new_with_stream (subpart_stream, GMIME_PART_ENCODING_DEFAULT);
+        content = g_mime_data_wrapper_new_with_stream (subpart_stream, GMIME_CONTENT_ENCODING_DEFAULT);
         g_mime_part_set_content_object (subpart, content);
-        g_mime_multipart_add_part (GMIME_MULTIPART (multipart), GMIME_OBJECT (subpart));
+        g_mime_multipart_add (GMIME_MULTIPART (multipart), GMIME_OBJECT (subpart));
 
         g_object_unref (content);
         g_object_unref (subpart);
       }
 		
       // replace the old part with the new multipart
-      g_mime_object_unref (*part);
+      g_object_unref (*part);
       *part = GMIME_OBJECT (multipart);
     }
 
     foreach (temp_parts_t, parts, it)
       delete *it;
-    g_mime_stream_unref (istream);
+    g_object_unref (istream);
   }
 }
 
@@ -831,15 +834,15 @@ mime :: construct_message (GMimeStream  ** istreams,
       GMimeStream * stream = g_mime_data_wrapper_get_stream (wrapper);
       g_mime_stream_reset (stream);
       g_mime_stream_cat_add_source (GMIME_STREAM_CAT (cat), stream);
-      g_object_unref (stream);
-      g_object_unref (wrapper);
+//      g_object_unref (stream); //SKG if this is unrefed cat loses its stream
+//      g_object_unref (wrapper); //SKG gmime 2.4 don't unref returned data wrapper
     }
 
     GMimeMessage * message = messages[0];
     GMimeDataWrapper * wrapper = g_mime_part_get_content_object (GMIME_PART(message->mime_part));
     g_mime_stream_reset (cat);
     g_mime_data_wrapper_set_stream (wrapper, cat);
-    g_object_unref (wrapper);
+//    g_object_unref (wrapper); //SKG gmime 2.4 don't unref returned data wrapper
     g_object_unref (cat);
   }
 
@@ -1006,4 +1009,175 @@ mime :: remove_multipart_part_from_subject (const Stri
                                             std::string         & setme)
 {
   normalize_subject (subject, STRIP_MULTIPART_NUMERATOR, setme);
+}
+
+static GMimeObject *
+handle_multipart_mixed (GMimeMultipart *multipart, gboolean *is_html);
+
+static GMimeObject *
+handle_multipart_alternative (GMimeMultipart *multipart, gboolean *is_html)
+{
+        GMimeObject *mime_part, *text_part = NULL;
+        GMimeContentType *type;
+        int count = g_mime_multipart_get_count (multipart);
+
+        for (int i = 0; i < count; ++i) {
+                mime_part = g_mime_multipart_get_part (multipart, i);
+
+                type = g_mime_object_get_content_type (mime_part);
+                if (g_mime_content_type_is_type (type, "text", "*")) {
+                        if (!text_part || !g_ascii_strcasecmp (type->subtype, "plain")) {
+                                *is_html = !g_ascii_strcasecmp (type->subtype, "html");
+                                text_part = mime_part;
+                        }
+                }
+        }
+
+        return text_part;
+}
+
+static GMimeObject *
+handle_multipart_mixed (GMimeMultipart *multipart, gboolean *is_html)
+{
+        GMimeObject *mime_part, *text_part = NULL;
+        GMimeContentType *type, *first_type = NULL;
+        int count = g_mime_multipart_get_count (multipart);
+
+        for (int i = 0; i < count; ++i) {
+                mime_part = g_mime_multipart_get_part (multipart, i);
+
+                type = g_mime_object_get_content_type (mime_part);
+                if (GMIME_IS_MULTIPART (mime_part)) {
+                        multipart = GMIME_MULTIPART (mime_part);
+                        if (g_mime_content_type_is_type (type, "multipart", "alternative")) {
+                                mime_part = handle_multipart_alternative (multipart, is_html);
+                                if (mime_part)
+                                        return mime_part;
+                        } else {
+                                mime_part = handle_multipart_mixed (multipart, is_html);
+                                if (mime_part && !text_part)
+                                        text_part = mime_part;
+                        }
+                } else if (g_mime_content_type_is_type (type, "text", "*")) {
+                        if (!g_ascii_strcasecmp (type->subtype, "plain")) {
+                                /* we got what we came for */
+                                *is_html = !g_ascii_strcasecmp (type->subtype, "html");
+                                return mime_part;
+                        }
+
+                        /* if we haven't yet found a text part or if it is a type we can
+ *                          * understand and it is the first of that type, save it */
+                        if (!text_part || (!g_ascii_strcasecmp (type->subtype, "plain") && (first_type &&
+                                           g_ascii_strcasecmp (type->subtype, first_type->subtype) != 0))) {
+                                *is_html = !g_ascii_strcasecmp (type->subtype, "html");
+                                text_part = mime_part;
+                                first_type = type;
+                        }
+                }
+        }
+
+        return text_part;
+}
+
+#define NEEDS_DECODING(encoding) ((encoding == GMIME_CONTENT_ENCODING_BASE64) ||   \
+                                  (encoding == GMIME_CONTENT_ENCODING_UUENCODE) || \
+                                  (encoding == GMIME_CONTENT_ENCODING_QUOTEDPRINTABLE))
+
+static const char *
+g_mime_part_get_content (const GMimePart *mime_part, size_t *len)
+{
+        const char *retval = NULL;
+        GMimeStream *stream;
+
+        g_return_val_if_fail (GMIME_IS_PART (mime_part), NULL);
+
+        if (!mime_part->content || !mime_part->content->stream) {
+                g_warning ("no content set on this mime part");
+                return NULL;
+        }
+
+        stream = mime_part->content->stream;
+        if (!GMIME_IS_STREAM_MEM (stream) || NEEDS_DECODING (mime_part->content->encoding)) {
+                /* Decode and cache this mime part's contents... */
+                GMimeStream *cache;
+                GByteArray *buf;
+
+                buf = g_byte_array_new ();
+                cache = g_mime_stream_mem_new_with_byte_array (buf);
+
+                g_mime_data_wrapper_write_to_stream (mime_part->content, cache);
+
+                g_mime_data_wrapper_set_stream (mime_part->content, cache);
+                g_mime_data_wrapper_set_encoding (mime_part->content, GMIME_CONTENT_ENCODING_DEFAULT);
+                g_object_unref (cache);
+
+                *len = buf->len;
+                retval = (char *) buf->data;
+        } else {
+                GByteArray *buf = GMIME_STREAM_MEM (stream)->buffer;
+                off_t end_index = (off_t) buf->len;
+                off_t start_index = 0;
+
+                /* check boundaries */
+                if (stream->bound_start >= 0)
+                        start_index = CLAMP (stream->bound_start, 0, (off_t) buf->len);
+                if (stream->bound_end >= 0)
+                        end_index = CLAMP (stream->bound_end, 0, (off_t) buf->len);
+                if (end_index < start_index)
+                        end_index = start_index;
+
+                *len = end_index - start_index;
+                retval = (char *) buf->data + start_index;
+        }
+
+        return retval;
+}
+
+char *g_mime_message_get_body (GMimeMessage *message, gboolean *is_html)
+{
+        GMimeObject *mime_part = NULL;
+        GMimeContentType *type;
+        GMimeMultipart *multipart;
+        const char *content;
+        char *body = NULL;
+        size_t len = 0;
+
+        g_return_val_if_fail (GMIME_IS_MESSAGE (message), NULL);
+        g_return_val_if_fail (is_html != NULL, NULL);
+
+        type = g_mime_object_get_content_type (message->mime_part);
+        if (GMIME_IS_MULTIPART (message->mime_part)) {
+                /* let's see if we can find a body in the multipart */
+                multipart = GMIME_MULTIPART (message->mime_part);
+                if (g_mime_content_type_is_type (type, "multipart", "alternative"))
+                        mime_part = handle_multipart_alternative (multipart, is_html);
+                else
+                        mime_part = handle_multipart_mixed (multipart, is_html);
+        } else if (g_mime_content_type_is_type (type, "text", "*")) {
+                /* this *has* to be the message body */
+                if (g_mime_content_type_is_type (type, "text", "html"))
+                        *is_html = TRUE;
+                else
+                        *is_html = FALSE;
+                mime_part = message->mime_part;
+        }
+
+        if (mime_part != NULL) {
+                content = g_mime_part_get_content (GMIME_PART (mime_part), &len);
+                body = g_strndup (content, len);
+        }
+
+        return body;
+}
+
+void g_mime_message_add_recipients_from_string (GMimeMessage *message, GMimeRecipientType type, const char *string)
+{
+        InternetAddressList *addrlist;
+        if ((addrlist = internet_address_list_parse_string (string))) {
+        	for (int i = 0; i < internet_address_list_length (addrlist); ++i) {
+                	InternetAddress *ia = internet_address_list_get_address (addrlist, i);
+                	if (INTERNET_ADDRESS_IS_MAILBOX(ia))
+				g_mime_message_add_recipient (message, type, internet_address_get_name(ia), internet_address_mailbox_get_addr(INTERNET_ADDRESS_MAILBOX(ia)));
+		}
+        }
 }
