Re: [PATCH 6/6] reply: Use RFC 2822/MIME wholly for text format template
authorAustin Clements <amdragon@MIT.EDU>
Mon, 12 Aug 2013 20:01:26 +0000 (16:01 +2000)
committerW. Trevor King <wking@tremily.us>
Fri, 7 Nov 2014 17:56:17 +0000 (09:56 -0800)
4e/82e05f27c085d6dbc4c824abf9f9c43e69ec43 [new file with mode: 0644]

diff --git a/4e/82e05f27c085d6dbc4c824abf9f9c43e69ec43 b/4e/82e05f27c085d6dbc4c824abf9f9c43e69ec43
new file mode 100644 (file)
index 0000000..c317c79
--- /dev/null
@@ -0,0 +1,578 @@
+Return-Path: <amdragon@mit.edu>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+       by olra.theworths.org (Postfix) with ESMTP id E1058431FAF\r
+       for <notmuch@notmuchmail.org>; Mon, 12 Aug 2013 13:01:38 -0700 (PDT)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: -0.7\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=-0.7 tagged_above=-999 required=5\r
+       tests=[RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+       by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+       with ESMTP id 3nQtVavw5v5M for <notmuch@notmuchmail.org>;\r
+       Mon, 12 Aug 2013 13:01:34 -0700 (PDT)\r
+Received: from dmz-mailsec-scanner-1.mit.edu (dmz-mailsec-scanner-1.mit.edu\r
+       [18.9.25.12])\r
+       by olra.theworths.org (Postfix) with ESMTP id BE5A6431FAE\r
+       for <notmuch@notmuchmail.org>; Mon, 12 Aug 2013 13:01:33 -0700 (PDT)\r
+X-AuditID: 1209190c-b7fac8e000006335-67-52093f1b1d5e\r
+Received: from mailhub-auth-3.mit.edu ( [18.9.21.43])\r
+       by dmz-mailsec-scanner-1.mit.edu (Symantec Messaging Gateway) with SMTP\r
+       id 83.F6.25397.B1F39025; Mon, 12 Aug 2013 16:01:32 -0400 (EDT)\r
+Received: from outgoing.mit.edu (outgoing-auth-1.mit.edu [18.9.28.11])\r
+       by mailhub-auth-3.mit.edu (8.13.8/8.9.2) with ESMTP id r7CK1UVW006906\r
+       for <notmuch@notmuchmail.org>; Mon, 12 Aug 2013 16:01:31 -0400\r
+Received: from awakening.csail.mit.edu (awakening.csail.mit.edu [18.26.4.91])\r
+       (authenticated bits=0)\r
+       (User authenticated as amdragon@ATHENA.MIT.EDU)\r
+       by outgoing.mit.edu (8.13.8/8.12.4) with ESMTP id r7CK1SmX004563\r
+       (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NOT)\r
+       for <notmuch@notmuchmail.org>; Mon, 12 Aug 2013 16:01:30 -0400\r
+Received: from amthrax by awakening.csail.mit.edu with local (Exim 4.80)\r
+       (envelope-from <amdragon@mit.edu>) id 1V8yIy-00006h-0d\r
+       for notmuch@notmuchmail.org; Mon, 12 Aug 2013 16:01:28 -0400\r
+Date: Mon, 12 Aug 2013 16:01:26 -0400\r
+From: Austin Clements <amdragon@MIT.EDU>\r
+To: notmuch@notmuchmail.org\r
+Subject: Re: [PATCH 6/6] reply: Use RFC 2822/MIME wholly for text format\r
+       template\r
+Message-ID: <20130812200126.GC13257@mit.edu>\r
+References: <1376332839-22825-1-git-send-email-amdragon@mit.edu>\r
+       <1376332839-22825-7-git-send-email-amdragon@mit.edu>\r
+MIME-Version: 1.0\r
+Content-Type: text/plain; charset=utf-8\r
+Content-Disposition: inline\r
+Content-Transfer-Encoding: 8bit\r
+In-Reply-To: <1376332839-22825-7-git-send-email-amdragon@mit.edu>\r
+User-Agent: Mutt/1.5.21 (2010-09-15)\r
+X-Brightmail-Tracker:\r
+ H4sIAAAAAAAAA+NgFprIKsWRmVeSWpSXmKPExsUixCmqrStjzxlksCDG4vrNmcwOjB7PVt1i\r
+       DmCM4rJJSc3JLEst0rdL4Mr49u4Ue8HbXsaKh/PKGhh/FXQxcnJICJhI3Jh0ggXCFpO4cG89\r
+       WxcjF4eQwD5GiUPPvkA55xklvsx8wAzhvGSS+HyziRHCOcQocentHjaQfhYBVYmdl7ezg9hs\r
+       AhoS2/YvZwSxRQSkJXbenc0KYgsLBEvc+HWFCcTmFdCRuDV7HlhcSKBcYvuGE8wQcUGJkzOf\r
+       gN3ELKAu8WfeJaA4B5AtLbH8HwdEWF6ieetssHJOAUeJOwdPgtmiAioSU05uY5vAKDQLyaRZ\r
+       SCbNQpg0C8mkBYwsqxhlU3KrdHMTM3OKU5N1i5MT8/JSi3QN9XIzS/RSU0o3MYJDW5JnB+Ob\r
+       g0qHGAU4GJV4eDM+cgQJsSaWFVfmHmKU5GBSEuXNseEMEuJLyk+pzEgszogvKs1JLQaGEwez\r
+       kgjvSR2gHG9KYmVValE+TEqag0VJnPfp07OBQgLpiSWp2ampBalFMFkZDg4lCV49O6BGwaLU\r
+       9NSKtMycEoQ0EwcnyHAeoOGdIDW8xQWJucWZ6RD5U4y6HBd6F3xiFGLJy89LlRLn5QQpEgAp\r
+       yijNg5sDS0mvGMWB3hLmlQOp4gGmM7hJr4CWMAEtMWrmAFlSkoiQkmpgLPWXvbPlHEvYpez3\r
+       sYolfRvvGoRF5Bnu09ThY3+oflE9YcVFv+Oy/T7SHw3F5q3aY8U50VdsXdymM31vEkRnqKQu\r
+       ONfUk8CRZnnhrJdE1fKQzGUBbMVLv97aU6GX7fTysjaz5vYfC5MONzxU+5TcXWqr1hq6Umr+\r
+       0ePTTM80LnbJvcXxjl9CiaU4I9FQi7moOBEA3FqKlSQDAAA=\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+       <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Mon, 12 Aug 2013 20:01:39 -0000\r
+\r
+Quoth myself on Aug 12 at  2:40 pm:\r
+> Previously, reply's default text format used an odd mix of RFC 2045\r
+> MIME encoding for the reply template's body and some made-up RFC\r
+> 2822-like UTF-8 format for the headers.  The intent was to present the\r
+> headers to the user in a nice, un-encoded format, but this assumed\r
+> that whatever ultimately sent the email would RFC 2047-encode the\r
+> headers, while at the same time the body was already RFC 2045 encoded,\r
+> so it assumed that whatever sent the email would *not* re-encode the\r
+> body.\r
+> \r
+> This can be fixed by either producing a fully decoded UTF-8 reply\r
+> template, or a fully encoded MIME-compliant RFC 2822 message.  This\r
+> patch does the latter because it is\r
+> \r
+> a) Well-defined by RFC 2822 and MIME (while any UTF-8 format would be\r
+>    ad hoc).\r
+> \r
+> b) Ready to be piped to sendmail.  The point of the text format is to\r
+>    be minimal, so a user should be able to pop up the tmeplate in\r
+>    whatever editor they want, edit it, and push it to sendmail.\r
+> \r
+> c) Consistent with how frontend capabilities.  If a frontend has the\r
+\r
+This was supposed to be "Consistent with frontend capabilities." of\r
+course.\r
+\r
+>    smarts to RFC 2047 encode the headers before sending the mail, it\r
+>    probably has the smarts to RFC 2047 decode them before presenting\r
+>    the template to a user for editing.\r
+> \r
+> Also, as far as I know, nothing automated consumes the reply text\r
+> format, so changing this should not cause serious problems.  (And if\r
+> anything does still consume this format, it probably gets these\r
+> encoding issues wrong anyway.)\r
+> ---\r
+>  Makefile.local           |    1 -\r
+>  gmime-filter-headers.c   |  263 ----------------------------------------------\r
+>  gmime-filter-headers.h   |   69 ------------\r
+>  man/man1/notmuch-reply.1 |    2 +-\r
+>  notmuch-reply.c          |   15 +--\r
+>  test/reply               |    9 +-\r
+>  test/reply-to-sender     |    4 +-\r
+>  7 files changed, 12 insertions(+), 351 deletions(-)\r
+>  delete mode 100644 gmime-filter-headers.c\r
+>  delete mode 100644 gmime-filter-headers.h\r
+> \r
+> diff --git a/Makefile.local b/Makefile.local\r
+> index 84043fe..b7cd266 100644\r
+> --- a/Makefile.local\r
+> +++ b/Makefile.local\r
+> @@ -255,7 +255,6 @@ notmuch_client_srcs =            \\r
+>      command-line-arguments.c\\r
+>      debugger.c              \\r
+>      gmime-filter-reply.c    \\r
+> -    gmime-filter-headers.c  \\r
+>      hooks.c                 \\r
+>      notmuch.c               \\r
+>      notmuch-config.c        \\r
+> diff --git a/gmime-filter-headers.c b/gmime-filter-headers.c\r
+> deleted file mode 100644\r
+> index 7db3779..0000000\r
+> --- a/gmime-filter-headers.c\r
+> +++ /dev/null\r
+> @@ -1,263 +0,0 @@\r
+> -/*\r
+> - * Copyright © 2009 Keith Packard <keithp@keithp.com>\r
+> - * Copyright © 2010 Michal Sojka <sojkam1@fel.cvut.cz>\r
+> - *\r
+> - * This program is free software; you can redistribute it and/or modify\r
+> - * it under the terms of the GNU General Public License as published by\r
+> - * the Free Software Foundation, either version 3 of the License, or\r
+> - * (at your option) any later version.\r
+> - *\r
+> - * This program is distributed in the hope that it will be useful, but\r
+> - * WITHOUT ANY WARRANTY; without even the implied warranty of\r
+> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+> - * General Public License for more details.\r
+> - *\r
+> - * You should have received a copy of the GNU General Public License along\r
+> - * with this program; if not, write to the Free Software Foundation, Inc.,\r
+> - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.\r
+> - */\r
+> -\r
+> -#include "gmime-filter-headers.h"\r
+> -#include <string.h>\r
+> -#include <gmime/gmime-utils.h>\r
+> -#include <glib/gprintf.h>\r
+> -#include <stdlib.h>\r
+> -#include <xutil.h>\r
+> -\r
+> -/**\r
+> - * SECTION: gmime-filter-headers\r
+> - * @title: GMimeFilterHeaders\r
+> - * @short_description: Add/remove headers markers\r
+> - *\r
+> - * A #GMimeFilter for decoding rfc2047 encoded headers to UTF-8\r
+> - **/\r
+> -\r
+> -\r
+> -static void g_mime_filter_headers_class_init (GMimeFilterHeadersClass *klass);\r
+> -static void g_mime_filter_headers_init (GMimeFilterHeaders *filter, GMimeFilterHeadersClass *klass);\r
+> -static void g_mime_filter_headers_finalize (GObject *object);\r
+> -\r
+> -static GMimeFilter *filter_copy (GMimeFilter *filter);\r
+> -static void filter_filter (GMimeFilter *filter, char *in, size_t len, size_t prespace,\r
+> -                       char **out, size_t *outlen, size_t *outprespace);\r
+> -static void filter_complete (GMimeFilter *filter, char *in, size_t len, size_t prespace,\r
+> -                         char **out, size_t *outlen, size_t *outprespace);\r
+> -static void filter_reset (GMimeFilter *filter);\r
+> -\r
+> -\r
+> -static GMimeFilterClass *parent_class = NULL;\r
+> -\r
+> -GType\r
+> -g_mime_filter_headers_get_type (void)\r
+> -{\r
+> -    static GType type = 0;\r
+> -\r
+> -    if (!type) {\r
+> -            static const GTypeInfo info = {\r
+> -                    sizeof (GMimeFilterHeadersClass),\r
+> -                    NULL, /* base_class_init */\r
+> -                    NULL, /* base_class_finalize */\r
+> -                    (GClassInitFunc) g_mime_filter_headers_class_init,\r
+> -                    NULL, /* class_finalize */\r
+> -                    NULL, /* class_data */\r
+> -                    sizeof (GMimeFilterHeaders),\r
+> -                    0,    /* n_preallocs */\r
+> -                    (GInstanceInitFunc) g_mime_filter_headers_init,\r
+> -                    NULL    /* value_table */\r
+> -            };\r
+> -\r
+> -            type = g_type_register_static (GMIME_TYPE_FILTER, "GMimeFilterHeaders", &info, (GTypeFlags) 0);\r
+> -    }\r
+> -\r
+> -    return type;\r
+> -}\r
+> -\r
+> -\r
+> -static void\r
+> -g_mime_filter_headers_class_init (GMimeFilterHeadersClass *klass)\r
+> -{\r
+> -    GObjectClass *object_class = G_OBJECT_CLASS (klass);\r
+> -    GMimeFilterClass *filter_class = GMIME_FILTER_CLASS (klass);\r
+> -\r
+> -    parent_class = (GMimeFilterClass *) g_type_class_ref (GMIME_TYPE_FILTER);\r
+> -\r
+> -    object_class->finalize = g_mime_filter_headers_finalize;\r
+> -\r
+> -    filter_class->copy = filter_copy;\r
+> -    filter_class->filter = filter_filter;\r
+> -    filter_class->complete = filter_complete;\r
+> -    filter_class->reset = filter_reset;\r
+> -}\r
+> -\r
+> -static void\r
+> -g_mime_filter_headers_init (GMimeFilterHeaders *filter, GMimeFilterHeadersClass *klass)\r
+> -{\r
+> -    (void) klass;\r
+> -    filter->saw_nl = TRUE;\r
+> -    filter->line = NULL;\r
+> -    filter->line_size = 0;\r
+> -    filter->lineptr = NULL;\r
+> -}\r
+> -\r
+> -static void\r
+> -g_mime_filter_headers_finalize (GObject *object)\r
+> -{\r
+> -    free (GMIME_FILTER_HEADERS (object)->line);\r
+> -    G_OBJECT_CLASS (parent_class)->finalize (object);\r
+> -}\r
+> -\r
+> -\r
+> -static GMimeFilter *\r
+> -filter_copy (GMimeFilter *filter)\r
+> -{\r
+> -    (void) filter;\r
+> -    return g_mime_filter_headers_new ();\r
+> -}\r
+> -\r
+> -static void\r
+> -output_decoded_header (GMimeFilterHeaders *headers, char **outptr)\r
+> -{\r
+> -    char *colon, *name, *s, *decoded_value;\r
+> -    size_t offset;\r
+> -    gint ret;\r
+> -\r
+> -    colon = strchr (headers->line, ':');\r
+> -    if (colon == NULL)\r
+> -            return;\r
+> -\r
+> -    name = headers->line;\r
+> -    *colon = '\0';\r
+> -    s = colon + 1;\r
+> -    while (*s == ' ' || *s == '\t')\r
+> -            s++;\r
+> -    decoded_value = g_mime_utils_header_decode_text(s);\r
+> -    if (decoded_value == NULL)\r
+> -            return;\r
+> -    offset = *outptr - GMIME_FILTER (headers)->outbuf;\r
+> -    g_mime_filter_set_size (GMIME_FILTER (headers), strlen(name) + 2 +\r
+> -                           strlen(decoded_value) + 2, TRUE);\r
+> -    *outptr = GMIME_FILTER (headers)->outbuf + offset;\r
+> -    ret = g_sprintf (*outptr, "%s: %s\n", name, decoded_value);\r
+> -    if (ret > 0)\r
+> -            *outptr += ret;\r
+> -    free (decoded_value);\r
+> -}\r
+> -\r
+> -static void\r
+> -output_final_newline (GMimeFilterHeaders *headers, char **outptr)\r
+> -{\r
+> -    size_t offset;\r
+> -\r
+> -    offset = *outptr - GMIME_FILTER (headers)->outbuf;\r
+> -    g_mime_filter_set_size (GMIME_FILTER (headers), 1, TRUE);\r
+> -    *outptr = GMIME_FILTER (headers)->outbuf + offset;\r
+> -    *(*outptr)++ = '\n';\r
+> -}\r
+> -\r
+> -static void\r
+> -filter_filter (GMimeFilter *filter, char *inbuf, size_t inlen, size_t prespace,\r
+> -           char **outbuf, size_t *outlen, size_t *outprespace)\r
+> -{\r
+> -    GMimeFilterHeaders *headers = (GMimeFilterHeaders *) filter;\r
+> -    register const char *inptr = inbuf;\r
+> -    const char *inend = inbuf + inlen;\r
+> -    char *lineptr, *lineend, *outptr;\r
+> -\r
+> -    (void) prespace;\r
+> -    if (headers->line == NULL) {\r
+> -            headers->line_size = 200;\r
+> -            headers->lineptr = headers->line = malloc (headers->line_size);\r
+> -    }\r
+> -    lineptr = headers->lineptr;\r
+> -    lineend = headers->line + headers->line_size - 1;\r
+> -    if (lineptr == NULL)\r
+> -            return;\r
+> -    outptr = filter->outbuf;\r
+> -    while (inptr < inend) {\r
+> -            if (*inptr == '\n') {\r
+> -                    if (headers->saw_nl)\r
+> -                            output_final_newline(headers, &outptr);\r
+> -                    headers->saw_nl = TRUE;\r
+> -                    inptr++;\r
+> -                    continue;\r
+> -            }\r
+> -\r
+> -            if (lineptr == lineend) {\r
+> -                    headers->line_size *= 2;\r
+> -                    headers->line = xrealloc (headers->line, headers->line_size);\r
+> -                    lineptr = headers->line + (headers->line_size / 2) - 1;\r
+> -                    lineend = headers->line + headers->line_size - 1;\r
+> -            }\r
+> -\r
+> -            if (headers->saw_nl && *inptr != ' ' && *inptr != '\t') {\r
+> -                    *lineptr = '\0';\r
+> -                    output_decoded_header (headers, &outptr);\r
+> -                    lineptr = headers->line;\r
+> -            }\r
+> -            if (headers->saw_nl && (*inptr == ' ' || *inptr == '\t')) {\r
+> -                    *lineptr = ' ';\r
+> -                    lineptr++;\r
+> -                    while (inptr < inend && (*inptr == ' ' || *inptr == '\t'))\r
+> -                            inptr++;\r
+> -                    headers->saw_nl = FALSE;\r
+> -                    continue;\r
+> -            }\r
+> -            headers->saw_nl = FALSE;\r
+> -\r
+> -            if (*inptr != '\r')\r
+> -                    *lineptr++ = *inptr;\r
+> -            inptr++;\r
+> -    }\r
+> -    if (headers->saw_nl) {\r
+> -            *lineptr = '\0';\r
+> -            output_decoded_header (headers, &outptr);\r
+> -            lineptr = headers->line;\r
+> -    }\r
+> -    headers->lineptr = lineptr;\r
+> -    *outlen = outptr - filter->outbuf;\r
+> -    *outprespace = filter->outpre;\r
+> -    *outbuf = filter->outbuf;\r
+> -}\r
+> -\r
+> -static void\r
+> -filter_complete (GMimeFilter *filter, char *inbuf, size_t inlen, size_t prespace,\r
+> -             char **outbuf, size_t *outlen, size_t *outprespace)\r
+> -{\r
+> -    if (inbuf && inlen)\r
+> -            filter_filter (filter, inbuf, inlen, prespace, outbuf, outlen, outprespace);\r
+> -}\r
+> -\r
+> -static void\r
+> -filter_reset (GMimeFilter *filter)\r
+> -{\r
+> -    GMimeFilterHeaders *headers = (GMimeFilterHeaders *) filter;\r
+> -\r
+> -    headers->saw_nl = TRUE;\r
+> -    free(headers->line);\r
+> -    headers->line = NULL;\r
+> -    headers->line_size = 0;\r
+> -}\r
+> -\r
+> -\r
+> -/**\r
+> - * g_mime_filter_headers_new:\r
+> - * @encode: %TRUE if the filter should encode or %FALSE otherwise\r
+> - * @dots: encode/decode dots (as for SMTP)\r
+> - *\r
+> - * Creates a new #GMimeFilterHeaders filter.\r
+> - *\r
+> - * If @encode is %TRUE, then all lines will be prefixed by "> ",\r
+> - * otherwise any lines starting with "> " will have that removed\r
+> - *\r
+> - * Returns: a new #GMimeFilterHeaders filter.\r
+> - **/\r
+> -GMimeFilter *\r
+> -g_mime_filter_headers_new (void)\r
+> -{\r
+> -    GMimeFilterHeaders *new_headers;\r
+> -\r
+> -    new_headers = (GMimeFilterHeaders *) g_object_newv (GMIME_TYPE_FILTER_HEADERS, 0, NULL);\r
+> -\r
+> -    return (GMimeFilter *) new_headers;\r
+> -}\r
+> -\r
+> diff --git a/gmime-filter-headers.h b/gmime-filter-headers.h\r
+> deleted file mode 100644\r
+> index 1d1a3eb..0000000\r
+> --- a/gmime-filter-headers.h\r
+> +++ /dev/null\r
+> @@ -1,69 +0,0 @@\r
+> -/*\r
+> - * Copyright © 2009 Keith Packard <keithp@keithp.com>\r
+> - * Copyright © 2010 Michal Sojka <sojkam1@fel.cvut.cz>\r
+> - *\r
+> - * This program is free software; you can redistribute it and/or modify\r
+> - * it under the terms of the GNU General Public License as published by\r
+> - * the Free Software Foundation, either version 3 of the License, or\r
+> - * (at your option) any later version.\r
+> - *\r
+> - * This program is distributed in the hope that it will be useful, but\r
+> - * WITHOUT ANY WARRANTY; without even the implied warranty of\r
+> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+> - * General Public License for more details.\r
+> - *\r
+> - * You should have received a copy of the GNU General Public License along\r
+> - * with this program; if not, write to the Free Software Foundation, Inc.,\r
+> - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.\r
+> - */\r
+> -\r
+> -#ifndef _GMIME_FILTER_HEADERS_H_\r
+> -#define _GMIME_FILTER_HEADERS_H_\r
+> -\r
+> -#include <gmime/gmime-filter.h>\r
+> -\r
+> -G_BEGIN_DECLS\r
+> -\r
+> -#define GMIME_TYPE_FILTER_HEADERS            (g_mime_filter_headers_get_type ())\r
+> -#define GMIME_FILTER_HEADERS(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMIME_TYPE_FILTER_HEADERS, GMimeFilterHeaders))\r
+> -#define GMIME_FILTER_HEADERS_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMIME_TYPE_FILTER_HEADERS, GMimeFilterHeadersClass))\r
+> -#define GMIME_IS_FILTER_HEADERS(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMIME_TYPE_FILTER_HEADERS))\r
+> -#define GMIME_IS_FILTER_HEADERS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GMIME_TYPE_FILTER_HEADERS))\r
+> -#define GMIME_FILTER_HEADERS_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GMIME_TYPE_FILTER_HEADERS, GMimeFilterHeadersClass))\r
+> -\r
+> -typedef struct _GMimeFilterHeaders GMimeFilterHeaders;\r
+> -typedef struct _GMimeFilterHeadersClass GMimeFilterHeadersClass;\r
+> -\r
+> -/**\r
+> - * GMimeFilterHeaders:\r
+> - * @parent_object: parent #GMimeFilter\r
+> - * @saw_nl: previous char was a \n\r
+> - * @line: temporary buffer for line unfolding\r
+> - * @line_size: size of currently allocated memory for @line\r
+> - * @lineptr: pointer to the first unused character in @line\r
+> - *\r
+> - * A filter to decode rfc2047 encoded headers\r
+> - **/\r
+> -struct _GMimeFilterHeaders {\r
+> -    GMimeFilter parent_object;\r
+> -\r
+> -    gboolean saw_nl;\r
+> -    char *line;\r
+> -    size_t line_size;\r
+> -    char *lineptr;\r
+> -};\r
+> -\r
+> -struct _GMimeFilterHeadersClass {\r
+> -    GMimeFilterClass parent_class;\r
+> -\r
+> -};\r
+> -\r
+> -\r
+> -GType g_mime_filter_headers_get_type (void);\r
+> -\r
+> -GMimeFilter *g_mime_filter_headers_new (void);\r
+> -\r
+> -G_END_DECLS\r
+> -\r
+> -\r
+> -#endif /* _GMIME_FILTER_HEADERS_H_ */\r
+> diff --git a/man/man1/notmuch-reply.1 b/man/man1/notmuch-reply.1\r
+> index ac76b07..e553145 100644\r
+> --- a/man/man1/notmuch-reply.1\r
+> +++ b/man/man1/notmuch-reply.1\r
+> @@ -41,7 +41,7 @@ include\r
+>  .RS\r
+>  .TP 4\r
+>  .BR default\r
+> -Includes subject and quoted message body.\r
+> +Includes subject and quoted message body as an RFC 2822 message.\r
+>  .TP\r
+>  .BR json\r
+>  Produces JSON output containing headers for a reply message and the\r
+> diff --git a/notmuch-reply.c b/notmuch-reply.c\r
+> index 0f3b9cd..bfd0f51 100644\r
+> --- a/notmuch-reply.c\r
+> +++ b/notmuch-reply.c\r
+> @@ -21,28 +21,17 @@\r
+>   */\r
+>  \r
+>  #include "notmuch-client.h"\r
+> -#include "gmime-filter-headers.h"\r
+>  #include "sprinter.h"\r
+>  \r
+>  static void\r
+>  show_reply_headers (GMimeMessage *message)\r
+>  {\r
+> -    GMimeStream *stream_stdout = NULL, *stream_filter = NULL;\r
+> +    GMimeStream *stream_stdout = NULL;\r
+>  \r
+>      stream_stdout = g_mime_stream_file_new (stdout);\r
+>      if (stream_stdout) {\r
+>      g_mime_stream_file_set_owner (GMIME_STREAM_FILE (stream_stdout), FALSE);\r
+> -    stream_filter = g_mime_stream_filter_new(stream_stdout);\r
+> -    if (stream_filter) {\r
+> -            // g_mime_object_write_to_stream will produce\r
+> -            // RFC2047-encoded headers, but we want to present the\r
+> -            // user with decoded headers and let whatever\r
+> -            // ultimately sends the mail do the RFC2047 encoding.\r
+> -            g_mime_stream_filter_add(GMIME_STREAM_FILTER(stream_filter),\r
+> -                                     g_mime_filter_headers_new());\r
+> -            g_mime_object_write_to_stream(GMIME_OBJECT(message), stream_filter);\r
+> -            g_object_unref(stream_filter);\r
+> -    }\r
+> +    g_mime_object_write_to_stream (GMIME_OBJECT(message), stream_stdout);\r
+>      g_object_unref(stream_stdout);\r
+>      }\r
+>  }\r
+> diff --git a/test/reply b/test/reply\r
+> index a85ebe5..d4389cf 100755\r
+> --- a/test/reply\r
+> +++ b/test/reply\r
+> @@ -132,7 +132,9 @@ add_message '[subject]="This subject is exactly 200 bytes in length. Other than\r
+>          '[body]="200-byte header"'\r
+>  output=$(notmuch reply id:${gen_msg_id})\r
+>  test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>\r
+> -Subject: Re: This subject is exactly 200 bytes in length. Other than its length there is not much of note here. Note that the length of 200 bytes includes the Subject: and Re: prefixes with two spaces\r
+> +Subject: Re: This subject is exactly 200 bytes in length. Other than its\r
+> + length there is not much of note here. Note that the length of 200 bytes\r
+> + includes the Subject: and Re: prefixes with two spaces\r
+>  In-Reply-To: <${gen_msg_id}>\r
+>  References: <${gen_msg_id}>\r
+>  \r
+> @@ -200,10 +202,11 @@ add_message '[subject]="=?iso-8859-1?q?=e0=df=e7?="' \\r
+>          '[body]="Encoding"'\r
+>  \r
+>  output=$(notmuch reply id:${gen_msg_id})\r
+> +# Note that GMime changes from Q- to B-encoding\r
+>  test_expect_equal "$output" "\\r
+>  From: Notmuch Test Suite <test_suite@notmuchmail.org>\r
+> -Subject: Re: àßç\r
+> -To: ☃ <snowman@example.com>\r
+> +Subject: Re: =?iso-8859-1?b?4N/n?=\r
+> +To: =?UTF-8?b?4piD?= <snowman@example.com>\r
+>  In-Reply-To: <${gen_msg_id}>\r
+>  References: <${gen_msg_id}>\r
+>  \r
+> diff --git a/test/reply-to-sender b/test/reply-to-sender\r
+> index c7d15bb..30e5e38 100755\r
+> --- a/test/reply-to-sender\r
+> +++ b/test/reply-to-sender\r
+> @@ -200,7 +200,9 @@ add_message '[subject]="This subject is exactly 200 bytes in length. Other than\r
+>              '[body]="200-byte header"'\r
+>  output=$(notmuch reply  --reply-to=sender id:${gen_msg_id})\r
+>  test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>\r
+> -Subject: Re: This subject is exactly 200 bytes in length. Other than its length there is not much of note here. Note that the length of 200 bytes includes the Subject: and Re: prefixes with two spaces\r
+> +Subject: Re: This subject is exactly 200 bytes in length. Other than its\r
+> + length there is not much of note here. Note that the length of 200 bytes\r
+> + includes the Subject: and Re: prefixes with two spaces\r
+>  In-Reply-To: <${gen_msg_id}>\r
+>  References: <${gen_msg_id}>\r
+>  \r
+\r
+-- \r
+Austin Clements                                      MIT/'06/PhD/CSAIL\r
+amdragon@mit.edu                           http://web.mit.edu/amdragon\r
+       Somewhere in the dream we call reality you will find me,\r
+              searching for the reality we call dreams.\r