openbsd-ports/news/pan/patches/patch-pan_usenet-utils_mime-utils_cc
ajacoutot 800c37c2c6 Update to pan-0.133.
Change maintainer email while here.
Patch to make it build and work with gmime24 (from BZ).

tested by pea@ on amd64 and macppc and myself on i386.
ok pea@ (maintainer)
2010-09-13 16:23:47 +00:00

283 lines
12 KiB
Plaintext

$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)));
+ }
+ }
}