aboutsummaryrefslogtreecommitdiffstats
path: root/testing/mu/0001-Support-gmime-3.0.patch
diff options
context:
space:
mode:
Diffstat (limited to 'testing/mu/0001-Support-gmime-3.0.patch')
-rw-r--r--testing/mu/0001-Support-gmime-3.0.patch702
1 files changed, 702 insertions, 0 deletions
diff --git a/testing/mu/0001-Support-gmime-3.0.patch b/testing/mu/0001-Support-gmime-3.0.patch
new file mode 100644
index 0000000000..25a59c39ab
--- /dev/null
+++ b/testing/mu/0001-Support-gmime-3.0.patch
@@ -0,0 +1,702 @@
+From b110a5990eb9f02b0118401d8960dc1e00a49253 Mon Sep 17 00:00:00 2001
+From: Yuri D'Elia <wavexx@thregr.org>
+Date: Sun, 30 Jul 2017 16:47:38 +0200
+Subject: [PATCH] Support gmime 3.0
+
+---
+ configure.ac | 6 +-
+ contrib/gmime-test.c | 63 +++++++++--------
+ lib/mu-msg-crypto.c | 163 +++++++------------------------------------
+ lib/mu-msg-file.c | 46 ++++++------
+ lib/mu-msg-part.c | 26 ++++---
+ lib/mu-msg.c | 61 +++++++---------
+ 6 files changed, 126 insertions(+), 239 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index 55c0718b..58531ae4 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -139,11 +139,11 @@ AC_SUBST(GLIB_CFLAGS)
+ AC_SUBST(GLIB_LIBS)
+ glib_version="`$PKG_CONFIG --modversion glib-2.0`"
+
+-# gmime, some late-2012 version
+-PKG_CHECK_MODULES(GMIME,gmime-2.6 >= 2.6.7)
++# gmime, version 3.0 or higher
++PKG_CHECK_MODULES(GMIME,gmime-3.0)
+ AC_SUBST(GMIME_CFLAGS)
+ AC_SUBST(GMIME_LIBS)
+-gmime_version="`$PKG_CONFIG --modversion gmime-2.6`"
++gmime_version="`$PKG_CONFIG --modversion gmime-3.0`"
+
+
+ # xapian checking - we need 1.2.x at least
+diff --git a/contrib/gmime-test.c b/contrib/gmime-test.c
+index ce8c6d06..5c59ed2b 100644
+--- a/contrib/gmime-test.c
++++ b/contrib/gmime-test.c
+@@ -31,13 +31,13 @@
+ #include <locale.h>
+
+ static gchar*
+-get_recip (GMimeMessage *msg, GMimeRecipientType rtype)
++get_recip (GMimeMessage *msg, GMimeAddressType atype)
+ {
+ char *recep;
+ InternetAddressList *receps;
+
+- receps = g_mime_message_get_recipients (msg, rtype);
+- recep = (char*)internet_address_list_to_string (receps, FALSE);
++ receps = g_mime_message_get_addresses (msg, atype);
++ recep = (char*)internet_address_list_to_string (receps, NULL, FALSE);
+
+ if (!recep || !*recep) {
+ g_free (recep);
+@@ -51,20 +51,19 @@ static gchar*
+ get_refs_str (GMimeMessage *msg)
+ {
+ const gchar *str;
+- const GMimeReferences *cur;
+ GMimeReferences *mime_refs;
++ int i, refs_len;
+ gchar *rv;
+
+ str = g_mime_object_get_header (GMIME_OBJECT(msg), "References");
+ if (!str)
+ return NULL;
+
+- mime_refs = g_mime_references_decode (str);
+- for (rv = NULL, cur = mime_refs; cur;
+- cur = g_mime_references_get_next(cur)) {
+-
++ mime_refs = g_mime_references_parse (NULL, str);
++ refs_len = g_mime_references_length (mime_refs);
++ for (rv = NULL, i = 0; i < refs_len; ++i) {
+ const char* msgid;
+- msgid = g_mime_references_get_message_id (cur);
++ msgid = g_mime_references_get_message_id (mime_refs, i);
+ rv = g_strdup_printf ("%s%s%s",
+ rv ? rv : "",
+ rv ? "," : "",
+@@ -78,21 +77,21 @@ get_refs_str (GMimeMessage *msg)
+ static void
+ print_date (GMimeMessage *msg)
+ {
+- time_t t;
+- int tz;
+- char buf[64];
+- size_t len;
+- struct tm *t_m;
+-
++ GDateTime *dt;
++ gchar *buf;
+
+- g_mime_message_get_date (msg, &t, &tz);
+- t_m = localtime (&t);
++ dt = g_mime_message_get_date (msg);
++ if (!dt)
++ return;
+
+- len = strftime (buf, sizeof(buf) - 1, "%c", t_m);
++ dt = g_date_time_to_local (dt);
++ buf = g_date_time_format (dt, "%c");
++ g_date_time_unref (dt);
+
+- if (len > 0)
+- g_print ("Date : %s (%s%04d)\n",
+- buf,tz < 0 ? "-" : "+", tz);
++ if (buf) {
++ g_print ("Date : %s\n", buf);
++ g_free (buf);
++ }
+ }
+
+
+@@ -111,7 +110,7 @@ print_body (GMimeMessage *msg)
+ if (!GMIME_IS_PART(body))
+ return;
+
+- wrapper = g_mime_part_get_content_object (GMIME_PART(body));
++ wrapper = g_mime_part_get_content (GMIME_PART(body));
+ if (!GMIME_IS_DATA_WRAPPER(wrapper))
+ return;
+
+@@ -142,17 +141,19 @@ test_message (GMimeMessage *msg)
+ gchar *val;
+ const gchar *str;
+
+- g_print ("From : %s\n", g_mime_message_get_sender (msg));
++ val = get_recip (msg, GMIME_ADDRESS_TYPE_FROM);
++ g_print ("From : %s\n", val ? val : "<none>" );
++ g_free (val);
+
+- val = get_recip (msg, GMIME_RECIPIENT_TYPE_TO);
++ val = get_recip (msg, GMIME_ADDRESS_TYPE_TO);
+ g_print ("To : %s\n", val ? val : "<none>" );
+ g_free (val);
+
+- val = get_recip (msg, GMIME_RECIPIENT_TYPE_CC);
++ val = get_recip (msg, GMIME_ADDRESS_TYPE_CC);
+ g_print ("Cc : %s\n", val ? val : "<none>" );
+ g_free (val);
+
+- val = get_recip (msg, GMIME_RECIPIENT_TYPE_BCC);
++ val = get_recip (msg, GMIME_ADDRESS_TYPE_BCC);
+ g_print ("Bcc : %s\n", val ? val : "<none>" );
+ g_free (val);
+
+@@ -195,7 +196,7 @@ test_stream (GMimeStream *stream)
+ goto leave;
+ }
+
+- msg = g_mime_parser_construct_message (parser);
++ msg = g_mime_parser_construct_message (parser, NULL);
+ if (!msg) {
+ g_warning ("failed to construct message");
+ rv = FALSE;
+@@ -207,8 +208,6 @@ test_stream (GMimeStream *stream)
+ leave:
+ if (parser)
+ g_object_unref (parser);
+- else
+- g_object_unref (stream);
+
+ if (msg)
+ g_object_unref (msg);
+@@ -242,7 +241,9 @@ test_file (const char *path)
+ goto leave;
+ }
+
+- rv = test_stream (stream); /* test-stream will unref it */
++ rv = test_stream (stream);
++ g_object_unref (stream);
++ return rv;
+
+ leave:
+ if (file)
+@@ -264,7 +265,7 @@ main (int argc, char *argv[])
+
+ setlocale (LC_ALL, "");
+
+- g_mime_init(GMIME_ENABLE_RFC2047_WORKAROUNDS);
++ g_mime_init();
+
+ rv = test_file (argv[1]);
+
+diff --git a/lib/mu-msg-crypto.c b/lib/mu-msg-crypto.c
+index 4c9b132c..ba0d5e7c 100644
+--- a/lib/mu-msg-crypto.c
++++ b/lib/mu-msg-crypto.c
+@@ -99,83 +99,6 @@ dummy_password_func (const char *user_id, const char *prompt_ctx,
+ }
+
+
+-static char*
+-get_gpg (GError **err)
+-{
+- char *path;
+- const char *envpath;
+-
+- if ((envpath = g_getenv ("MU_GPG_PATH"))) {
+- if (access (envpath, X_OK) != 0) {
+- mu_util_g_set_error (
+- err, MU_ERROR,
+- "'%s': not a valid gpg path: %s",
+- envpath, strerror (errno));
+- return NULL;
+- }
+- return g_strdup (envpath);
+- }
+-
+- if (!(path = g_find_program_in_path ("gpg2")) &&
+- !(path = g_find_program_in_path ("gpg"))) {
+- mu_util_g_set_error (err, MU_ERROR, "gpg/gpg2 not found");
+- return NULL;
+- } else
+- return path;
+-}
+-
+-
+-static GMimeCryptoContext*
+-get_gpg_crypto_context (MuMsgOptions opts, GError **err)
+-{
+- GMimeCryptoContext *cctx;
+- char *gpg;
+-
+- cctx = NULL;
+- if (!(gpg = get_gpg (err)))
+- return NULL;
+-
+- cctx = g_mime_gpg_context_new (
+- (GMimePasswordRequestFunc)password_requester, gpg);
+- g_free (gpg);
+-
+- if (!cctx) {
+- mu_util_g_set_error (err, MU_ERROR,
+- "failed to get GPG crypto context");
+- return NULL;
+- }
+-
+- /* always try to use the agent */
+- g_mime_gpg_context_set_use_agent (GMIME_GPG_CONTEXT(cctx), TRUE);
+- g_mime_gpg_context_set_auto_key_retrieve
+- (GMIME_GPG_CONTEXT(cctx),
+- opts & MU_MSG_OPTION_AUTO_RETRIEVE ? TRUE:FALSE);
+-
+- return cctx;
+-}
+-
+-
+-static GMimeCryptoContext*
+-get_crypto_context (MuMsgOptions opts, MuMsgPartPasswordFunc password_func,
+- gpointer user_data, GError **err)
+-{
+- CallbackData *cbdata;
+- GMimeCryptoContext *cctx;
+-
+- cctx = get_gpg_crypto_context (opts, err);
+- if (!cctx)
+- return NULL;
+-
+- /* use gobject to pass data to the callback func */
+- cbdata = g_new0 (CallbackData, 1);
+- cbdata->pw_func = password_func ? password_func : dummy_password_func;
+- cbdata->user_data = user_data;
+-
+- g_object_set_data_full (G_OBJECT(cctx), CALLBACK_DATA,
+- cbdata, (GDestroyNotify)g_free);
+- return cctx;
+-}
+-
+ static const char*
+ get_pubkey_algo_name (GMimePubKeyAlgo algo)
+ {
+@@ -250,12 +173,12 @@ get_cert_details (GMimeCertificate *cert)
+ (g_mime_certificate_get_pubkey_algo (cert));
+
+ switch (g_mime_certificate_get_trust (cert)) {
+- case GMIME_CERTIFICATE_TRUST_NONE: trust = "none"; break;
+- case GMIME_CERTIFICATE_TRUST_NEVER: trust = "never"; break;
+- case GMIME_CERTIFICATE_TRUST_UNDEFINED: trust = "undefined"; break;
+- case GMIME_CERTIFICATE_TRUST_MARGINAL: trust = "marginal"; break;
+- case GMIME_CERTIFICATE_TRUST_FULLY: trust = "full"; break;
+- case GMIME_CERTIFICATE_TRUST_ULTIMATE: trust = "ultimate"; break;
++ case GMIME_TRUST_UNKNOWN: trust = "unknown"; break;
++ case GMIME_TRUST_UNDEFINED: trust = "undefined"; break;
++ case GMIME_TRUST_NEVER: trust = "never"; break;
++ case GMIME_TRUST_MARGINAL: trust = "marginal"; break;
++ case GMIME_TRUST_FULL: trust = "full"; break;
++ case GMIME_TRUST_ULTIMATE: trust = "ultimate"; break;
+ default:
+ g_return_val_if_reached (NULL);
+ }
+@@ -277,21 +200,17 @@ get_verdict_report (GMimeSignature *msig)
+ time_t t;
+ const char *created, *expires, *verdict;
+ char *certdata, *report;
+-
+- switch (g_mime_signature_get_status (msig)) {
+- case GMIME_SIGNATURE_STATUS_GOOD:
+- verdict = "good";
+- break;
+- case GMIME_SIGNATURE_STATUS_ERROR:
+- verdict = "error";
+- break;
+- case GMIME_SIGNATURE_STATUS_BAD:
+- verdict = "bad";
+- break;
+- default:
+- g_return_val_if_reached (NULL);
+- return NULL;
+- }
++ GMimeSignatureStatus sigstat;
++
++ sigstat = g_mime_signature_get_status (msig);
++ if (sigstat & GMIME_SIGNATURE_STATUS_ERROR_MASK)
++ verdict = "error";
++ else if (sigstat & GMIME_SIGNATURE_STATUS_RED)
++ verdict = "bad";
++ else if (sigstat & GMIME_SIGNATURE_STATUS_GREEN)
++ verdict = "good";
++ else
++ g_return_val_if_reached (NULL);
+
+ t = g_mime_signature_get_created (msig);
+ created = (t == 0 || t == (time_t)-1) ? "?" : mu_date_str_s ("%x", t);
+@@ -353,17 +272,13 @@ get_status_report (GMimeSignatureList *sigs)
+ msig = g_mime_signature_list_get_signature (sigs, i);
+ sigstat = g_mime_signature_get_status (msig);
+
+- switch (sigstat) {
+- case GMIME_SIGNATURE_STATUS_GOOD:
+- break;
+- case GMIME_SIGNATURE_STATUS_ERROR:
+- status = MU_MSG_PART_SIG_STATUS_ERROR;
+- break;
+- case GMIME_SIGNATURE_STATUS_BAD:
+- status = MU_MSG_PART_SIG_STATUS_BAD;
+- break;
+- default: g_return_val_if_reached (NULL);
+- }
++ /* downgrade our expectations */
++ if ((sigstat & GMIME_SIGNATURE_STATUS_ERROR_MASK) &&
++ status != MU_MSG_PART_SIG_STATUS_ERROR)
++ status = MU_MSG_PART_SIG_STATUS_ERROR;
++ else if ((sigstat & GMIME_SIGNATURE_STATUS_RED) &&
++ status == MU_MSG_PART_SIG_STATUS_GOOD)
++ status = MU_MSG_PART_SIG_STATUS_BAD;
+
+ rep = get_verdict_report (msig);
+ report = g_strdup_printf ("%s%s%d: %s",
+@@ -419,20 +334,11 @@ mu_msg_crypto_verify_part (GMimeMultipartSigned *sig, MuMsgOptions opts,
+ {
+ /* the signature status */
+ MuMsgPartSigStatusReport *report;
+- GMimeCryptoContext *ctx;
+ GMimeSignatureList *sigs;
+
+ g_return_if_fail (GMIME_IS_MULTIPART_SIGNED(sig));
+
+- ctx = get_crypto_context (opts, NULL, NULL, err);
+- if (!ctx) {
+- mu_util_g_set_error (err, MU_ERROR_CRYPTO,
+- "failed to get crypto context");
+- return;
+- }
+-
+- sigs = g_mime_multipart_signed_verify (sig, ctx, err);
+- g_object_unref (ctx);
++ sigs = g_mime_multipart_signed_verify (sig, GMIME_VERIFY_NONE, err);
+ if (!sigs) {
+ if (err && !*err)
+ mu_util_g_set_error (err, MU_ERROR_CRYPTO,
+@@ -482,29 +388,12 @@ mu_msg_crypto_decrypt_part (GMimeMultipartEncrypted *enc, MuMsgOptions opts,
+ GError **err)
+ {
+ GMimeObject *dec;
+- GMimeCryptoContext *ctx;
+ GMimeDecryptResult *res;
+
+ g_return_val_if_fail (GMIME_IS_MULTIPART_ENCRYPTED(enc), NULL);
+
+- ctx = get_crypto_context (opts, func, user_data, err);
+- if (!ctx) {
+- mu_util_g_set_error (err, MU_ERROR_CRYPTO,
+- "failed to get crypto context");
+- return NULL;
+- }
+-
+- /* at the time of writing, there is a small leak in
+- * g_mime_multipart_encrypted_decrypt; I've notified its
+- * author and it has been fixed 2012-09-12:
+- * http://git.gnome.org/browse/gmime/commit/
+- * ?id=1bacd43b50d91bd03a4ae1dc9f46f5783dee61b1
+- * (or GMime > 2.6.10)
+- * */
+ res = NULL;
+- dec = g_mime_multipart_encrypted_decrypt (enc, ctx, &res, err);
+- g_object_unref (ctx);
+-
++ dec = g_mime_multipart_encrypted_decrypt (enc, GMIME_DECRYPT_NONE, NULL, &res, err);
+ check_decrypt_result(enc, res, err);
+
+ if (!dec) {
+diff --git a/lib/mu-msg-file.c b/lib/mu-msg-file.c
+index e727ab12..b143b8e7 100644
+--- a/lib/mu-msg-file.c
++++ b/lib/mu-msg-file.c
+@@ -159,7 +159,7 @@ init_mime_msg (MuMsgFile *self, const char* path, GError **err)
+ return FALSE;
+ }
+
+- self->_mime_msg = g_mime_parser_construct_message (parser);
++ self->_mime_msg = g_mime_parser_construct_message (parser, NULL);
+ g_object_unref (parser);
+ if (!self->_mime_msg) {
+ g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_GMIME,
+@@ -171,15 +171,15 @@ init_mime_msg (MuMsgFile *self, const char* path, GError **err)
+ }
+
+ static char*
+-get_recipient (MuMsgFile *self, GMimeRecipientType rtype)
++get_recipient (MuMsgFile *self, GMimeAddressType atype)
+ {
+ char *recip;
+ InternetAddressList *recips;
+
+- recips = g_mime_message_get_recipients (self->_mime_msg, rtype);
++ recips = g_mime_message_get_addresses (self->_mime_msg, atype);
+
+ /* FALSE --> don't encode */
+- recip = (char*)internet_address_list_to_string (recips, FALSE);
++ recip = (char*)internet_address_list_to_string (recips, NULL, FALSE);
+
+ if (recip && !g_utf8_validate (recip, -1, NULL)) {
+ g_debug ("invalid recipient in %s\n", self->_path);
+@@ -488,7 +488,7 @@ mu_msg_mime_part_to_string (GMimePart *part, gboolean *err)
+ *err = TRUE; /* guilty until proven innocent */
+ g_return_val_if_fail (GMIME_IS_PART(part), NULL);
+
+- wrapper = g_mime_part_get_content_object (part);
++ wrapper = g_mime_part_get_content (part);
+ if (!wrapper) {
+ /* this happens with invalid mails */
+ g_debug ("failed to create data wrapper");
+@@ -545,20 +545,21 @@ get_references (MuMsgFile *self)
+ for (msgids = NULL, u = 0; headers[u]; ++u) {
+
+ char *str;
+- const GMimeReferences *cur;
+ GMimeReferences *mime_refs;
++ int i, refs_len;
+
+ str = mu_msg_file_get_header (self, headers[u]);
+ if (!str)
+ continue;
+
+- mime_refs = g_mime_references_decode (str);
++ mime_refs = g_mime_references_parse (NULL, str);
+ g_free (str);
+
+- for (cur = mime_refs; cur;
+- cur = g_mime_references_get_next(cur)) {
++ refs_len = g_mime_references_length (mime_refs);
++ for (i = 0; i < refs_len; ++i) {
+ const char* msgid;
+- msgid = g_mime_references_get_message_id (cur);
++ msgid = g_mime_references_get_message_id (mime_refs, i);
++
+ /* don't include duplicates */
+ if (msgid && !contains (msgids, msgid))
+ /* explicitly ensure it's utf8-safe,
+@@ -638,13 +639,14 @@ cleanup_maybe (const char *str, gboolean *do_free)
+
+
+
+-G_GNUC_CONST static GMimeRecipientType
+-recipient_type (MuMsgFieldId mfid)
++G_GNUC_CONST static GMimeAddressType
++address_type (MuMsgFieldId mfid)
+ {
+ switch (mfid) {
+- case MU_MSG_FIELD_ID_BCC: return GMIME_RECIPIENT_TYPE_BCC;
+- case MU_MSG_FIELD_ID_CC : return GMIME_RECIPIENT_TYPE_CC;
+- case MU_MSG_FIELD_ID_TO : return GMIME_RECIPIENT_TYPE_TO;
++ case MU_MSG_FIELD_ID_BCC : return GMIME_ADDRESS_TYPE_BCC;
++ case MU_MSG_FIELD_ID_CC : return GMIME_ADDRESS_TYPE_CC;
++ case MU_MSG_FIELD_ID_TO : return GMIME_ADDRESS_TYPE_TO;
++ case MU_MSG_FIELD_ID_FROM: return GMIME_ADDRESS_TYPE_FROM;
+ default: g_return_val_if_reached (-1);
+ }
+ }
+@@ -679,12 +681,10 @@ mu_msg_file_get_str_field (MuMsgFile *self, MuMsgFieldId mfid,
+
+ case MU_MSG_FIELD_ID_BCC:
+ case MU_MSG_FIELD_ID_CC:
+- case MU_MSG_FIELD_ID_TO: *do_free = TRUE;
+- return get_recipient (self, recipient_type(mfid));
+-
+ case MU_MSG_FIELD_ID_FROM:
+- return (char*)cleanup_maybe
+- (g_mime_message_get_sender (self->_mime_msg), do_free);
++ case MU_MSG_FIELD_ID_TO:
++ *do_free = TRUE;
++ return get_recipient (self, address_type(mfid));
+
+ case MU_MSG_FIELD_ID_PATH: return self->_path;
+
+@@ -736,9 +736,9 @@ mu_msg_file_get_num_field (MuMsgFile *self, const MuMsgFieldId mfid)
+ switch (mfid) {
+
+ case MU_MSG_FIELD_ID_DATE: {
+- time_t t;
+- g_mime_message_get_date (self->_mime_msg, &t, NULL);
+- return (time_t)t;
++ GDateTime *dt;
++ dt = g_mime_message_get_date (self->_mime_msg);
++ return dt ? g_date_time_to_unix (dt) : 0;
+ }
+
+ case MU_MSG_FIELD_ID_FLAGS:
+diff --git a/lib/mu-msg-part.c b/lib/mu-msg-part.c
+index a1037fe7..67045016 100644
+--- a/lib/mu-msg-part.c
++++ b/lib/mu-msg-part.c
+@@ -113,18 +113,22 @@ accumulate_text_message (MuMsg *msg, MuMsgPart *part, GString **gstrp)
+ /* put sender, recipients and subject in the string, so they
+ * can be indexed as well */
+ mimemsg = GMIME_MESSAGE (part->data);
+- str = g_mime_message_get_sender (mimemsg);
++ addresses = g_mime_message_get_addresses (mimemsg, GMIME_ADDRESS_TYPE_FROM);
++ adrs = internet_address_list_to_string (addresses, NULL, FALSE);
+ g_string_append_printf
+- (*gstrp, "%s%s", str ? str : "", str ? "\n" : "");
++ (*gstrp, "%s%s", adrs ? adrs : "", adrs ? "\n" : "");
++ g_free (adrs);
++
+ str = g_mime_message_get_subject (mimemsg);
+ g_string_append_printf
+ (*gstrp, "%s%s", str ? str : "", str ? "\n" : "");
+- addresses = g_mime_message_get_all_recipients (mimemsg);
+- adrs = internet_address_list_to_string (addresses, FALSE);
+- g_object_unref (addresses);
+- g_string_append_printf
+- (*gstrp, "%s%s", adrs ? adrs : "", adrs ? "\n" : "");
+- g_free (adrs);
++
++ addresses = g_mime_message_get_all_recipients (mimemsg);
++ adrs = internet_address_list_to_string (addresses, NULL, FALSE);
++ g_object_unref (addresses);
++ g_string_append_printf
++ (*gstrp, "%s%s", adrs ? adrs : "", adrs ? "\n" : "");
++ g_free (adrs);
+ }
+
+ static void
+@@ -225,7 +229,7 @@ get_part_size (GMimePart *part)
+ GMimeDataWrapper *wrapper;
+ GMimeStream *stream;
+
+- wrapper = g_mime_part_get_content_object (part);
++ wrapper = g_mime_part_get_content (part);
+ if (!GMIME_IS_DATA_WRAPPER(wrapper))
+ return -1;
+
+@@ -665,7 +669,7 @@ write_part_to_fd (GMimePart *part, int fd, GError **err)
+ }
+ g_mime_stream_fs_set_owner (GMIME_STREAM_FS(stream), FALSE);
+
+- wrapper = g_mime_part_get_content_object (part);
++ wrapper = g_mime_part_get_content (part);
+ if (!GMIME_IS_DATA_WRAPPER(wrapper)) {
+ g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_GMIME,
+ "failed to create wrapper");
+@@ -694,7 +698,7 @@ static gboolean
+ write_object_to_fd (GMimeObject *obj, int fd, GError **err)
+ {
+ gchar *str;
+- str = g_mime_object_to_string (obj);
++ str = g_mime_object_to_string (obj, NULL);
+
+ if (!str) {
+ g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_GMIME,
+diff --git a/lib/mu-msg.c b/lib/mu-msg.c
+index 8a9d03f3..93d4d241 100644
+--- a/lib/mu-msg.c
++++ b/lib/mu-msg.c
+@@ -48,12 +48,7 @@ gmime_init (void)
+ {
+ g_return_if_fail (!_gmime_initialized);
+
+-#ifdef GMIME_ENABLE_RFC2047_WORKAROUNDS
+- g_mime_init(GMIME_ENABLE_RFC2047_WORKAROUNDS);
+-#else
+- g_mime_init(0);
+-#endif /* GMIME_ENABLE_RFC2047_WORKAROUNDS */
+-
++ g_mime_init();
+ _gmime_initialized = TRUE;
+ }
+
+@@ -385,7 +380,7 @@ mu_msg_get_mailing_list (MuMsg *self)
+ if (!ml)
+ return NULL;
+
+- decml = g_mime_utils_header_decode_text (ml);
++ decml = g_mime_utils_header_decode_text (NULL, ml);
+ if (!decml)
+ return NULL;
+
+@@ -566,21 +561,22 @@ get_content_type_parameters (MuMsg *self, MuMsgOptions opts, gboolean want_html)
+
+ if (cdata.ctype) {
+
+- GSList *paramlist;
++ GSList *gslist;
++ GMimeParamList *paramlist;
+ const GMimeParam *param;
++ int i, len;
+
+- paramlist = NULL;
+- param = g_mime_content_type_get_params (cdata.ctype);
+-
+- for (; param; param = param->next) {
+- paramlist = g_slist_prepend (paramlist,
+- g_strdup (param->name));
++ gslist = NULL;
++ paramlist = g_mime_content_type_get_parameters (cdata.ctype);
++ len = g_mime_param_list_length (paramlist);
+
+- paramlist = g_slist_prepend (paramlist,
+- g_strdup (param->value));
++ for (i = 0; i < len; ++i) {
++ param = g_mime_param_list_get_parameter_at (paramlist, i);
++ gslist = g_slist_prepend (gslist, g_strdup (param->name));
++ gslist = g_slist_prepend (gslist, g_strdup (param->value));
+ }
+
+- return free_later_lst(self, g_slist_reverse (paramlist));
++ return free_later_lst (self, g_slist_reverse (gslist));
+ }
+ return NULL;
+ }
+@@ -660,6 +656,10 @@ fill_contact (MuMsgContact *self, InternetAddress *addr,
+ return FALSE;
+
+ self->name = internet_address_get_name (addr);
++ if (mu_str_is_empty (self->name)) {
++ self->name = NULL;
++ }
++
+ self->type = ctype;
+
+ /* we only support internet mailbox addresses; if we don't
+@@ -716,7 +716,7 @@ addresses_foreach (const char* addrs, MuMsgContactType ctype,
+ if (!addrs)
+ return;
+
+- addrlist = internet_address_list_parse_string (addrs);
++ addrlist = internet_address_list_parse (NULL, addrs);
+ if (addrlist) {
+ address_list_foreach (addrlist, ctype, func, user_data);
+ g_object_unref (addrlist);
+@@ -730,27 +730,20 @@ msg_contact_foreach_file (MuMsg *msg, MuMsgContactForeachFunc func,
+ {
+ int i;
+ struct {
+- GMimeRecipientType _gmime_type;
+- MuMsgContactType _type;
++ GMimeAddressType _gmime_type;
++ MuMsgContactType _type;
+ } ctypes[] = {
+- {GMIME_RECIPIENT_TYPE_TO, MU_MSG_CONTACT_TYPE_TO},
+- {GMIME_RECIPIENT_TYPE_CC, MU_MSG_CONTACT_TYPE_CC},
+- {GMIME_RECIPIENT_TYPE_BCC, MU_MSG_CONTACT_TYPE_BCC},
++ {GMIME_ADDRESS_TYPE_FROM, MU_MSG_CONTACT_TYPE_FROM},
++ {GMIME_ADDRESS_TYPE_REPLY_TO, MU_MSG_CONTACT_TYPE_REPLY_TO},
++ {GMIME_ADDRESS_TYPE_TO, MU_MSG_CONTACT_TYPE_TO},
++ {GMIME_ADDRESS_TYPE_CC, MU_MSG_CONTACT_TYPE_CC},
++ {GMIME_ADDRESS_TYPE_BCC, MU_MSG_CONTACT_TYPE_BCC},
+ };
+
+- /* sender */
+- addresses_foreach (g_mime_message_get_sender (msg->_file->_mime_msg),
+- MU_MSG_CONTACT_TYPE_FROM, func, user_data);
+-
+- /* reply_to */
+- addresses_foreach (g_mime_message_get_reply_to (msg->_file->_mime_msg),
+- MU_MSG_CONTACT_TYPE_REPLY_TO, func, user_data);
+-
+- /* get to, cc, bcc */
+ for (i = 0; i != G_N_ELEMENTS(ctypes); ++i) {
+ InternetAddressList *addrlist;
+- addrlist = g_mime_message_get_recipients (msg->_file->_mime_msg,
+- ctypes[i]._gmime_type);
++ addrlist = g_mime_message_get_addresses (msg->_file->_mime_msg,
++ ctypes[i]._gmime_type);
+ address_list_foreach (addrlist, ctypes[i]._type, func, user_data);
+ }
+ }
+--
+2.17.0
+