PATCH: GMime support for message reading
- From: Magick <magick linux-fan com>
- To: balsa-list gnome org
- Subject: PATCH: GMime support for message reading
- Date: Wed, 17 Oct 2001 00:36:41 +0200
Hi,
Here is a first version of the GMime support. This patch changes the msg
loading/decoding over to GMime. I have done some basic tests on some mbox
mailfolders, other types are not tested. But i think there isn't much
changed there. The sending and printing parts are not yet changed over,
and there is some more cleanup possible.
The patch has some changes in libbalsa/send.c, they are mostly cleanup
except for
- } else {
- /* safe_free bug patch: steal it! */
- msg->content = mutt_copy_body(body->mutt_body, NULL);
which is called on process queue, but it looks like it's not necessary.
I like to hear what you think about this patch.
Bart
BTW This msg is send with this patch applied.
--
GPG key = 1024D/4B086D06 Fingerprint = CD4D 5601 287D F075 6F96 6157 99F9
E56A 4B08 6D06
Index: libbalsa/body.c
===================================================================
RCS file: /cvs/gnome/balsa/libbalsa/body.c,v
retrieving revision 1.14
diff -u -b -B -w -p -r1.14 body.c
--- libbalsa/body.c 2001/09/22 16:44:16 1.14
+++ libbalsa/body.c 2001/10/16 22:54:30
@@ -46,6 +46,8 @@ libbalsa_message_body_new(LibBalsaMessag
body->next = NULL;
body->parts = NULL;
+ body->mime_part = NULL;
+
return body;
}
@@ -75,49 +77,50 @@ libbalsa_message_body_free(LibBalsaMessa
}
void
-libbalsa_message_body_set_mutt_body(LibBalsaMessageBody * body,
- MuttBody * mutt_body)
+libbalsa_message_body_set_mime_body(LibBalsaMessageBody * body,
+ GMimePart * mime_part)
{
- g_return_if_fail(body->mutt_body == NULL);
+ g_return_if_fail(body->mime_part == NULL);
- body->mutt_body = mutt_body;
- body->filename = g_strdup(mutt_body->filename);
- if(body->filename)
- rfc2047_decode(&body->filename);
- if (mutt_body->next) {
- body->next = libbalsa_message_body_new(body->message);
- libbalsa_message_body_set_mutt_body(body->next, mutt_body->next);
- }
-
- if (mutt_body->parts) {
- body->parts = libbalsa_message_body_new(body->message);
- libbalsa_message_body_set_mutt_body(body->parts, mutt_body->parts);
+ body->mime_part = mime_part;
+ if (mime_part->children) {
+ LibBalsaMessageBody *part=NULL;
+ GList *child;
+ for (child=mime_part->children; child; child=g_list_next(child))
+ {
+ if (!part) {
+ part=body->parts = libbalsa_message_body_new(body->message);
+ } else {
+ part->next = libbalsa_message_body_new(body->message);
+ part=part->next;
}
+ libbalsa_message_body_set_mime_body(part, child->data);
}
+ }
+}
LibBalsaMessageBodyType
libbalsa_message_body_type(LibBalsaMessageBody * body)
{
- switch (body->mutt_body->type) {
- case TYPEOTHER:
- return LIBBALSA_MESSAGE_BODY_TYPE_OTHER;
- case TYPEAUDIO:
+ const GMimeContentType *type=g_mime_part_get_content_type(body->mime_part);
+
+ if (g_mime_content_type_is_type(type, "audio", "*"))
return LIBBALSA_MESSAGE_BODY_TYPE_AUDIO;
- case TYPEAPPLICATION:
+ else if (g_mime_content_type_is_type(type, "application", "*"))
return LIBBALSA_MESSAGE_BODY_TYPE_APPLICATION;
- case TYPEIMAGE:
+ else if (g_mime_content_type_is_type(type, "image", "*"))
return LIBBALSA_MESSAGE_BODY_TYPE_IMAGE;
- case TYPEMESSAGE:
+ else if (g_mime_content_type_is_type(type, "message", "*"))
return LIBBALSA_MESSAGE_BODY_TYPE_MESSAGE;
- case TYPEMODEL:
+ else if (g_mime_content_type_is_type(type, "model", "*"))
return LIBBALSA_MESSAGE_BODY_TYPE_MODEL;
- case TYPEMULTIPART:
+ else if (g_mime_content_type_is_type(type, "multipart", "*"))
return LIBBALSA_MESSAGE_BODY_TYPE_MULTIPART;
- case TYPETEXT:
+ else if (g_mime_content_type_is_type(type, "text", "*"))
return LIBBALSA_MESSAGE_BODY_TYPE_TEXT;
- case TYPEVIDEO:
+ else if (g_mime_content_type_is_type(type, "video", "*"))
return LIBBALSA_MESSAGE_BODY_TYPE_VIDEO;
- }
+ else return LIBBALSA_MESSAGE_BODY_TYPE_OTHER;
g_assert_not_reached();
return LIBBALSA_MESSAGE_BODY_TYPE_OTHER;
@@ -127,13 +130,13 @@ gchar *
libbalsa_message_body_get_parameter(LibBalsaMessageBody * body,
const gchar * param)
{
- gchar *res;
+ const gchar *res;
+ const GMimeContentType *type;
g_return_val_if_fail(body != NULL, NULL);
- libbalsa_lock_mutt();
- res = mutt_get_parameter(param, body->mutt_body->parameter);
- libbalsa_unlock_mutt();
+ type=g_mime_part_get_content_type(body->mime_part);
+ res = g_mime_content_type_get_parameter(type, param);
return g_strdup(res);
}
@@ -178,32 +181,17 @@ gboolean
libbalsa_message_body_save(LibBalsaMessageBody * body, gchar * prefix,
gchar * filename)
{
- FILE *stream;
- STATE s;
-
- stream =
- libbalsa_mailbox_get_message_stream(body->message->mailbox,
- body->message);
-
- g_return_val_if_fail(stream != NULL, FALSE);
-
- fseek(stream, body->mutt_body->offset, 0);
-
- s.fpin = stream;
-
- s.prefix = prefix;
- s.fpout = safe_fopen(filename, "w");
- if (!s.fpout)
+ FILE *fpout;
+ const gchar *buf;
+ guint len;
+ fpout=safe_fopen(filename, "w");
+ if (!fpout)
return FALSE;
+ buf=g_mime_part_get_content(body->mime_part, &len);
+ fwrite(buf, len , 1, fpout);
+ fflush(fpout);
+ fclose(fpout);
- libbalsa_lock_mutt();
- mutt_decode_attachment(body->mutt_body, &s);
- libbalsa_unlock_mutt();
-
- fflush(s.fpout);
- fclose(s.fpout);
- fclose(s.fpin);
-
return TRUE;
}
@@ -211,19 +199,15 @@ gchar *
libbalsa_message_body_get_content_type(LibBalsaMessageBody * body)
{
gchar *res;
-
- if (body->mutt_body->subtype)
- res =
- g_strdup_printf("%s/%s", TYPE(body->mutt_body),
- body->mutt_body->subtype);
- else
- res = g_strdup(TYPE(body->mutt_body));
+ const GMimeContentType *type=g_mime_part_get_content_type(body->mime_part);
+ res=g_mime_content_type_to_string(type);
+ g_strdown(res);
return res;
}
gboolean
libbalsa_message_body_is_multipart(LibBalsaMessageBody * body)
{
- return is_multipart(body->mutt_body);
+ return body->mime_part->children;
}
Index: libbalsa/body.h
===================================================================
RCS file: /cvs/gnome/balsa/libbalsa/body.h,v
retrieving revision 1.10
diff -u -b -B -w -p -r1.10 body.h
--- libbalsa/body.h 2001/10/15 07:06:27 1.10
+++ libbalsa/body.h 2001/10/16 22:54:30
@@ -26,6 +26,7 @@
#include <stdio.h>
#include <glib.h>
+#include <gmime/gmime.h>
typedef enum _LibBalsaMessageBodyType LibBalsaMessageBodyType;
@@ -50,6 +51,7 @@ struct _LibBalsaMessageBody {
gboolean attach_as_extbody; /* if an attachment shall be appended as external-body (sending) */
gchar *temp_filename; /* Holds the filename of a the temporary file where this part is saved */
gchar *charset; /* the charset, used for sending, replying. */
+ GMimePart *mime_part; /* mime body */
LibBalsaMessageBody *next; /* Next part in the message */
LibBalsaMessageBody *parts; /* The parts of a multipart or message/rfc822 message */
@@ -61,8 +63,8 @@ void libbalsa_message_body_free(LibBalsa
LibBalsaMessageBodyType libbalsa_message_body_type(LibBalsaMessageBody *
body);
-void libbalsa_message_body_set_mutt_body(LibBalsaMessageBody * body,
- MuttBody * mutt_body);
+void libbalsa_message_body_set_mime_body(LibBalsaMessageBody * body,
+ GMimePart * mime_part);
gboolean libbalsa_message_body_save(LibBalsaMessageBody * body,
gchar * prefixm, gchar * filename);
Index: libbalsa/message.c
===================================================================
RCS file: /cvs/gnome/balsa/libbalsa/message.c,v
retrieving revision 1.65
diff -u -b -B -w -p -r1.65 message.c
--- libbalsa/message.c 2001/10/08 22:16:16 1.65
+++ libbalsa/message.c 2001/10/16 22:54:35
@@ -47,6 +47,8 @@
#include "threads.h"
#endif
+#include <gmime/gmime.h>
+
static void libbalsa_message_class_init(LibBalsaMessageClass * klass);
static void libbalsa_message_init(LibBalsaMessage * message);
@@ -294,27 +296,22 @@ libbalsa_message_pathname(LibBalsaMessag
return message->header->path;
}
+static void libbalsa_message_find_charset(GMimePart *mime_part, gpointer data)
+{
+ const GMimeContentType *type;
+ if (*(gchar **)data)
+ return;
+ type=g_mime_part_get_content_type(mime_part);
+ *(const gchar **)data=g_mime_content_type_get_parameter(type, "charset");
+}
+
static const gchar *
libbalsa_message_body_charset(LibBalsaMessageBody * body)
{
gchar *charset = NULL;
-
- while (body) {
- libbalsa_lock_mutt();
- charset = mutt_get_parameter("charset", body->mutt_body->parameter);
- libbalsa_unlock_mutt();
-
- if (charset)
- break;
-
- if (body->parts)
- charset = (gchar *)libbalsa_message_body_charset(body->parts);
- if (charset)
- break;
-
- body = body->next;
- }
+ g_mime_part_foreach(body->mime_part,
+ libbalsa_message_find_charset, &charset);
return charset;
}
@@ -820,6 +817,9 @@ libbalsa_message_body_ref(LibBalsaMessag
LibBalsaMessageBody *body;
HEADER *cur;
MESSAGE *msg;
+ GMimePart *mime_part;
+ gchar *raw_mime;
+ gint len;
g_return_val_if_fail(message, FALSE);
if (!message->mailbox) return FALSE;
@@ -844,6 +844,13 @@ libbalsa_message_body_ref(LibBalsaMessag
return FALSE;
}
+ fseek(msg->fp, cur->content->hdr_offset, 0);
+ len=cur->content->length+cur->content->offset-cur->content->hdr_offset;
+ raw_mime=g_malloc(len);
+ fread(raw_mime, len, 1, msg->fp);
+ mime_part=g_mime_parser_construct_part(raw_mime, len);
+ g_free(raw_mime);
+
fseek(msg->fp, cur->content->offset, 0);
if (cur->content->type == TYPEMULTIPART) {
@@ -881,7 +888,7 @@ libbalsa_message_body_ref(LibBalsaMessag
cur->content->type);
#endif
body = libbalsa_message_body_new(message);
- libbalsa_message_body_set_mutt_body(body, cur->content);
+ libbalsa_message_body_set_mime_body(body, mime_part);
libbalsa_message_append_part(message, body);
message->body_ref++;
Index: libbalsa/mime.c
===================================================================
RCS file: /cvs/gnome/balsa/libbalsa/mime.c,v
retrieving revision 1.41
diff -u -b -B -w -p -r1.41 mime.c
--- libbalsa/mime.c 2001/09/23 18:04:48 1.41
+++ libbalsa/mime.c 2001/10/16 22:54:36
@@ -48,6 +48,7 @@ process_mime_part(LibBalsaMessage * mess
size_t alloced;
gchar *res = NULL;
GString *reply = NULL;
+ const GMimeContentType *type;
switch (libbalsa_message_body_type(body)) {
case LIBBALSA_MESSAGE_BODY_TYPE_OTHER:
@@ -63,20 +64,11 @@ process_mime_part(LibBalsaMessage * mess
llen, ignore_html, flow);
break;
case LIBBALSA_MESSAGE_BODY_TYPE_TEXT:
+ type=g_mime_part_get_content_type(body->mime_part);
/* don't return text/html stuff... */
- if (ignore_html && body->mutt_body->subtype &&
- !strcmp("html", body->mutt_body->subtype))
+ if (ignore_html && g_mime_content_type_is_type(type, "*", "html"))
break;
-
- libbalsa_message_body_save_temporary(body, NULL);
-
- part = fopen(body->temp_filename, "r");
- if (!part)
- break;
- alloced = libbalsa_readfile(part, &res);
- fclose(part);
- if (!res)
- break;
+ res=(gchar*)g_mime_part_get_content(body->mime_part, &alloced);
if (llen > 0) {
if (flow && libbalsa_flowed_rfc2646(body)) {
Index: src/Makefile.am
===================================================================
RCS file: /cvs/gnome/balsa/src/Makefile.am,v
retrieving revision 1.105
diff -u -b -B -w -p -r1.105 Makefile.am
--- src/Makefile.am 2001/10/07 19:30:05 1.105
+++ src/Makefile.am 2001/10/16 22:54:54
@@ -71,6 +71,7 @@ balsa_LDADD = \
$(top_builddir)/libinit_balsa/libinit_balsa.a \
-lpspell \
-lltdl \
+ -lgmime \
$(INTLLIBS) \
$(PCRE_LIBS) \
$(PTHREAD_LIB)
Index: src/balsa-message.c
===================================================================
RCS file: /cvs/gnome/balsa/src/balsa-message.c,v
retrieving revision 1.188
diff -u -b -B -w -p -r1.188 balsa-message.c
--- src/balsa-message.c 2001/10/15 22:33:24 1.188
+++ src/balsa-message.c 2001/10/16 22:55:18
@@ -992,8 +992,10 @@ part_info_init_message_extbody_mail(Bals
static void
part_info_init_message(BalsaMessage * bm, BalsaPartInfo * info)
{
- if (info->body && info->body->mutt_body && info->body->mutt_body->subtype &&
- !g_strcasecmp("external-body", info->body->mutt_body->subtype)) {
+ const GMimeContentType *type;
+ if (info->body && info->body->mime_part &&
+ (type=g_mime_part_get_content_type(info->body->mime_part)) &&
+ g_mime_content_type_is_type(type, "*", "external-body")) {
gchar *access_type;
rfc_extbody_id *extbody_type = rfc_extbodys;
@@ -2411,18 +2413,19 @@ static void add_body(BalsaMessage *bm,
static void add_multipart(BalsaMessage *bm, LibBalsaMessageBody *parent)
-/* Remarks: *** The tests/assumptions made are NOT verified with the RFCs */
+/* This function handles multiparts as specified by RFC2046 5.1 */
{
- if(parent->parts) {
- gchar *content_type =
- libbalsa_message_body_get_content_type(parent);
- if(g_strcasecmp(content_type, "multipart/related")==0) {
+ const GMimeContentType *type;
+ type=g_mime_part_get_content_type(parent->mime_part);
+ if (g_mime_content_type_is_type(type, "multipart", "*")) {
+ if (g_mime_content_type_is_type(type, "*", "related")) {
+ /* FIXME: more processing required see RFC1872 */
/* Add the first part */
add_body(bm, parent->parts);
- } else if(g_strcasecmp(content_type, "multipart/alternative")==0) {
+ } else if (g_mime_content_type_is_type(type, "*", "alternative")) {
/* Add the most suitable part. */
add_body(bm, preferred_part(parent->parts));
- } else {
+ } else { /* default to multipart/mixed */
/* Add first (main) part + anything else with
Content-Disposition: inline */
LibBalsaMessageBody *body=parent->parts;
@@ -2430,13 +2433,14 @@ static void add_multipart(BalsaMessage *
if(body) {
add_body(bm, body);
for(body=body->next; body; body=body->next) {
- if(body->mutt_body &&
- body->mutt_body->disposition==DISPINLINE)
+ const gchar *disposition;
+ disposition=g_mime_part_get_content_disposition(body->mime_part);
+ if (disposition && g_strcasecmp(disposition, "inline")==0) {
add_body(bm, body);
}
}
}
- g_free(content_type);
+ }
}
}
Index: libbalsa/send.c
===================================================================
RCS file: /cvs/gnome/balsa/libbalsa/send.c,v
retrieving revision 1.137
diff -u -b -B -w -p -r1.137 send.c
--- libbalsa/send.c 2001/10/15 22:33:24 1.137
+++ libbalsa/send.c 2001/10/16 22:29:14
@@ -231,34 +231,57 @@ encode_descriptions (BODY *b)
}
static BODY *
-add_mutt_body_plain(const gchar * charset, gint encoding_style,
+add_mutt_body_plain(LibBalsaMessageBody *body, gint encoding_style,
gboolean flow)
{
- BODY *body;
+ BODY *mutt_body;
gchar buffer[PATH_MAX];
+ const gchar * charset;
+ FILE *tempfp = NULL;
+ g_return_val_if_fail(body, NULL);
+ charset=body->charset;
g_return_val_if_fail(charset, NULL);
libbalsa_lock_mutt();
- body = mutt_new_body();
+ mutt_body = mutt_new_body();
- body->type = TYPETEXT;
- body->subtype = g_strdup("plain");
- body->unlink = 1;
- body->use_disp = 0;
+ mutt_body->type = TYPETEXT;
+ mutt_body->subtype = g_strdup("plain");
+ mutt_body->unlink = 1;
+ mutt_body->use_disp = 0;
- body->encoding = encoding_style;
+ mutt_body->encoding = encoding_style;
- mutt_set_parameter("charset", charset, &body->parameter);
+ mutt_set_parameter("charset", charset, &mutt_body->parameter);
if (flow)
- mutt_set_parameter("format", "flowed", &body->parameter);
+ mutt_set_parameter("format", "flowed", &mutt_body->parameter);
mutt_mktemp(buffer);
- body->filename = g_strdup(buffer);
- mutt_update_encoding(body);
+ mutt_body->filename = g_strdup(buffer);
+ mutt_update_encoding(mutt_body);
libbalsa_unlock_mutt();
- return body;
+ if (body->mime_type) {
+ /* change the type and subtype within the mutt body */
+ gchar *type, *subtype;
+
+ type = g_strdup (body->mime_type);
+ if ((subtype = strchr (type, '/'))) {
+ *subtype++ = 0;
+ libbalsa_lock_mutt();
+ mutt_body->type = mutt_check_mime_type (type);
+ g_free(mutt_body->subtype);
+ mutt_body->subtype = g_strdup(subtype);
+ libbalsa_unlock_mutt();
+ }
+ g_free (type);
+ }
+ tempfp = safe_fopen(mutt_body->filename, "w+");
+ fputs(body->buffer, tempfp);
+ fclose(tempfp);
+ tempfp = NULL;
+ return mutt_body;
}
static BODY *
@@ -1202,7 +1225,6 @@ libbalsa_message_postpone(LibBalsaMessag
last = last->next;
while (body) {
- FILE *tempfp = NULL;
newbdy = NULL;
if (body->filename) {
@@ -1239,25 +1261,7 @@ libbalsa_message_postpone(LibBalsaMessag
g_strfreev(mime_type);
}
} else if (body->buffer) {
- newbdy = add_mutt_body_plain(body->charset, encoding, flow);
- if (body->mime_type) {
- /* change the type and subtype within the mutt body */
- gchar *type, *subtype;
-
- type = g_strdup (body->mime_type);
- if ((subtype = strchr (type, '/'))) {
- *subtype++ = 0;
- libbalsa_lock_mutt();
- newbdy->type = mutt_check_mime_type (type);
- newbdy->subtype = g_strdup(subtype);
- libbalsa_unlock_mutt();
- }
- g_free (type);
- }
- tempfp = safe_fopen(newbdy->filename, "w+");
- fputs(body->buffer, tempfp);
- fclose(tempfp);
- tempfp = NULL;
+ newbdy = add_mutt_body_plain(body, encoding, flow);
}
if (newbdy) {
@@ -1395,7 +1399,6 @@ libbalsa_create_msg(LibBalsaMessage * me
last = last->next;
while (body) {
- FILE *tempfp = NULL;
newbdy = NULL;
if (body->filename) {
@@ -1439,29 +1442,7 @@ libbalsa_create_msg(LibBalsaMessage * me
}
}
} else if (body->buffer) {
- newbdy = add_mutt_body_plain(body->charset, encoding, flow);
- if (body->mime_type) {
- /* change the type and subtype within the mutt body */
- gchar *type, *subtype;
-
- type = g_strdup (body->mime_type);
- if ((subtype = strchr (type, '/'))) {
- *subtype++ = 0;
- libbalsa_lock_mutt();
- newbdy->type = mutt_check_mime_type (type);
- g_free(newbdy->subtype);
- newbdy->subtype = g_strdup(subtype);
- libbalsa_unlock_mutt();
- }
- g_free (type);
- }
- tempfp = safe_fopen(newbdy->filename, "w+");
- fputs(body->buffer, tempfp);
- fclose(tempfp);
- tempfp = NULL;
+ newbdy = add_mutt_body_plain(body, encoding, flow);
- } else {
- /* safe_free bug patch: steal it! */
- msg->content = mutt_copy_body(body->mutt_body, NULL);
}
if (newbdy) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]