[PATCH v5 0/2] lib: drop mbox support, replace header parser with gmime
authorJani Nikula <jani@nikula.org>
Sun, 30 Mar 2014 21:21:47 +0000 (00:21 +0300)
committerW. Trevor King <wking@tremily.us>
Fri, 7 Nov 2014 18:01:06 +0000 (10:01 -0800)
34/d1c9573170f0da095bc2bc89a28a7057d9e755 [new file with mode: 0644]

diff --git a/34/d1c9573170f0da095bc2bc89a28a7057d9e755 b/34/d1c9573170f0da095bc2bc89a28a7057d9e755
new file mode 100644 (file)
index 0000000..b30c779
--- /dev/null
@@ -0,0 +1,368 @@
+Return-Path: <jani@nikula.org>\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 1E975431FBF\r
+       for <notmuch@notmuchmail.org>; Sun, 30 Mar 2014 14:22:04 -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 gDdtV7UPwzA5 for <notmuch@notmuchmail.org>;\r
+       Sun, 30 Mar 2014 14:21:56 -0700 (PDT)\r
+Received: from mail-wg0-f52.google.com (mail-wg0-f52.google.com\r
+ [74.125.82.52])       (using TLSv1 with cipher RC4-SHA (128/128 bits))        (No client\r
+ certificate requested)        by olra.theworths.org (Postfix) with ESMTPS id\r
+ BA5AD431FB6   for <notmuch@notmuchmail.org>; Sun, 30 Mar 2014 14:21:55 -0700\r
+ (PDT)\r
+Received: by mail-wg0-f52.google.com with SMTP id k14so5033638wgh.23\r
+       for <notmuch@notmuchmail.org>; Sun, 30 Mar 2014 14:21:53 -0700 (PDT)\r
+X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;\r
+       d=1e100.net; s=20130820;\r
+       h=x-gm-message-state:from:to:cc:subject:date:message-id;\r
+       bh=pBCeRAcggjGIj292YIYqsT5KoGDdVo79fFjgJbv+mV8=;\r
+       b=aoEkkW2y9oe2lwyyW0BZS8ERg+WKXBde6C6BtL6xeqWBG0gus50e5ggZq9c21iIemx\r
+       aTV4cQqUJiTbgBjW3vDkaovzzTRlWVwmsUoABwFLyZLXP+QlciYS6TqjgpOtaQMBG1i3\r
+       gRx28lTjxWKw/2AlDgxqyvtdAAQD8h/cIK+MU6sm3o5BHIT12R4+oudFzo3b1KaQCcZu\r
+       fQ+DaDQd6ih9uFDsB7zViFiKEmn5RJ1eT/kCntNxKLYw81AXPKRxj7H9l0xuIyMgF4V2\r
+       WrmoWnHiFML2OXxeanJSFSrma+6KPL4x/RGukr6Ec2jGPYBr2TOocpAB9EcUC5ixMzVB\r
+       KITg==\r
+X-Gm-Message-State:\r
+ ALoCoQmQIDhvUlKpB2bHe8/D8sSErpwGy1rL3CVHc0iW42pCjbCN3l7Xy6FOEGOCtJ5chUNe0xEe\r
+X-Received: by 10.194.63.46 with SMTP id d14mr9296656wjs.24.1396214512954;\r
+       Sun, 30 Mar 2014 14:21:52 -0700 (PDT)\r
+Received: from localhost (dsl-hkibrasgw2-58c36f-91.dhcp.inet.fi.\r
+       [88.195.111.91])\r
+       by mx.google.com with ESMTPSA id 48sm28357929eee.2.2014.03.30.14.21.50\r
+       for <multiple recipients>\r
+       (version=TLSv1.2 cipher=RC4-SHA bits=128/128);\r
+       Sun, 30 Mar 2014 14:21:52 -0700 (PDT)\r
+From: Jani Nikula <jani@nikula.org>\r
+To: notmuch@notmuchmail.org\r
+Subject: [PATCH v5 0/2] lib: drop mbox support,\r
+       replace header parser with gmime\r
+Date: Mon, 31 Mar 2014 00:21:47 +0300\r
+Message-Id: <cover.1396214154.git.jani@nikula.org>\r
+X-Mailer: git-send-email 1.9.0\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: Sun, 30 Mar 2014 21:22:04 -0000\r
+\r
+This is v5 of id:1395604866-19188-1-git-send-email-jani@nikula.org\r
+addressing Austin's review. The most significant change is the new patch\r
+dropping support for single-message mbox files. Diff between the\r
+versions is at the end of this cover letter.\r
+\r
+BR,\r
+Jani.\r
+\r
+\r
+Jani Nikula (2):\r
+  lib: drop support for single-message mbox files\r
+  lib: replace the header parser with gmime\r
+\r
+ lib/database.cc       |  15 +-\r
+ lib/index.cc          |  72 +--------\r
+ lib/message-file.c    | 413 ++++++++++++++++++++------------------------------\r
+ lib/notmuch-private.h |  55 +++----\r
+ test/T050-new.sh      |  26 ++--\r
+ 5 files changed, 216 insertions(+), 365 deletions(-)\r
+\r
+-- \r
+1.9.0\r
+\r
+diff --git a/lib/database.cc b/lib/database.cc\r
+index 4750f40cf0fb..1efb14d4a0bd 100644\r
+--- a/lib/database.cc\r
++++ b/lib/database.cc\r
+@@ -1972,7 +1972,7 @@ notmuch_database_add_message (notmuch_database_t *notmuch,\r
+       goto DONE;\r
\r
+     /* Parse message up front to get better error status. */\r
+-    ret = notmuch_message_file_parse (message_file);\r
++    ret = _notmuch_message_file_parse (message_file);\r
+     if (ret)\r
+       goto DONE;\r
\r
+diff --git a/lib/index.cc b/lib/index.cc\r
+index 46a019325454..e1e2a3828f02 100644\r
+--- a/lib/index.cc\r
++++ b/lib/index.cc\r
+@@ -430,10 +430,12 @@ _notmuch_message_index_file (notmuch_message_t *message,\r
+     GMimeMessage *mime_message;\r
+     InternetAddressList *addresses;\r
+     const char *from, *subject;\r
++    notmuch_status_t status;\r
\r
+-    mime_message = notmuch_message_file_get_mime_message (message_file);\r
+-    if (! mime_message)\r
+-      return NOTMUCH_STATUS_FILE_NOT_EMAIL;\r
++    status = _notmuch_message_file_get_mime_message (message_file,\r
++                                                   &mime_message);\r
++    if (status)\r
++      return status;\r
\r
+     from = g_mime_message_get_sender (mime_message);\r
\r
+diff --git a/lib/message-file.c b/lib/message-file.c\r
+index 88662608d319..67828827e61d 100644\r
+--- a/lib/message-file.c\r
++++ b/lib/message-file.c\r
+@@ -116,20 +116,37 @@ notmuch_message_file_close (notmuch_message_file_t *message)\r
+     talloc_free (message);\r
+ }\r
\r
++static notmuch_bool_t\r
++is_mbox (FILE *file)\r
++{\r
++    char from_buf[5];\r
++    notmuch_bool_t ret = FALSE;\r
++\r
++    /* Is this mbox? */\r
++    if (fread (from_buf, sizeof (from_buf), 1, file) == 1 &&\r
++      strncmp (from_buf, "From ", 5) == 0)\r
++      ret = TRUE;\r
++\r
++    rewind (file);\r
++\r
++    return ret;\r
++}\r
++\r
+ notmuch_status_t\r
+-notmuch_message_file_parse (notmuch_message_file_t *message)\r
++_notmuch_message_file_parse (notmuch_message_file_t *message)\r
+ {\r
+     GMimeStream *stream;\r
+     GMimeParser *parser;\r
+     notmuch_status_t status = NOTMUCH_STATUS_SUCCESS;\r
+     static int initialized = 0;\r
+-    char from_buf[5];\r
+-    notmuch_bool_t is_mbox = FALSE;\r
+-    static notmuch_bool_t mbox_warning = FALSE;\r
\r
+     if (message->message)\r
+       return NOTMUCH_STATUS_SUCCESS;\r
\r
++    /* We no longer support mboxes at all. */\r
++    if (is_mbox (message->file))\r
++      return NOTMUCH_STATUS_FILE_NOT_EMAIL;\r
++\r
+     if (! initialized) {\r
+       g_mime_init (GMIME_ENABLE_RFC2047_WORKAROUNDS);\r
+       initialized = 1;\r
+@@ -140,19 +157,13 @@ notmuch_message_file_parse (notmuch_message_file_t *message)\r
+     if (! message->headers)\r
+       return NOTMUCH_STATUS_OUT_OF_MEMORY;\r
\r
+-    /* Is this mbox? */\r
+-    if (fread (from_buf, sizeof (from_buf), 1, message->file) == 1 &&\r
+-      strncmp (from_buf, "From ", 5) == 0)\r
+-      is_mbox = TRUE;\r
+-    rewind (message->file);\r
+-\r
+     stream = g_mime_stream_file_new (message->file);\r
\r
+     /* We'll own and fclose the FILE* ourselves. */\r
+     g_mime_stream_file_set_owner (GMIME_STREAM_FILE (stream), FALSE);\r
\r
+     parser = g_mime_parser_new_with_stream (stream);\r
+-    g_mime_parser_set_scan_from (parser, is_mbox);\r
++    g_mime_parser_set_scan_from (parser, FALSE);\r
\r
+     message->message = g_mime_parser_construct_message (parser);\r
+     if (! message->message) {\r
+@@ -160,26 +171,6 @@ notmuch_message_file_parse (notmuch_message_file_t *message)\r
+       goto DONE;\r
+     }\r
\r
+-    if (is_mbox) {\r
+-      if (! g_mime_parser_eos (parser)) {\r
+-          /* This is a multi-message mbox. */\r
+-          status = NOTMUCH_STATUS_FILE_NOT_EMAIL;\r
+-          goto DONE;\r
+-      }\r
+-      /*\r
+-       * For historical reasons, we support single-message mboxes,\r
+-       * but this behavior is likely to change in the future, so\r
+-       * warn.\r
+-       */\r
+-      if (! mbox_warning) {\r
+-          mbox_warning = TRUE;\r
+-          fprintf (stderr, "\\r
+-Warning: %s is an mbox containing a single message,\n\\r
+-likely caused by misconfigured mail delivery.  Support for single-message\n\\r
+-mboxes is deprecated and may be removed in the future.\n", message->filename);\r
+-      }\r
+-    }\r
+-\r
+   DONE:\r
+     g_object_unref (stream);\r
+     g_object_unref (parser);\r
+@@ -199,13 +190,19 @@ mboxes is deprecated and may be removed in the future.\n", message->filename);\r
+     return status;\r
+ }\r
\r
+-GMimeMessage *\r
+-notmuch_message_file_get_mime_message (notmuch_message_file_t *message)\r
++notmuch_status_t\r
++_notmuch_message_file_get_mime_message (notmuch_message_file_t *message,\r
++                                      GMimeMessage **mime_message)\r
+ {\r
+-    if (notmuch_message_file_parse (message))\r
+-      return NULL;\r
++    notmuch_status_t status;\r
++\r
++    status = _notmuch_message_file_parse (message);\r
++    if (status)\r
++      return status;\r
++\r
++    *mime_message = message->message;\r
\r
+-    return message->message;\r
++    return NOTMUCH_STATUS_SUCCESS;\r
+ }\r
\r
+ /*\r
+@@ -235,13 +232,16 @@ _notmuch_message_file_get_combined_header (notmuch_message_file_t *message,\r
+       goto DONE;\r
\r
+     do {\r
+-    const char *value;\r
++      const char *value;\r
+       char *decoded;\r
\r
+       if (strcasecmp (g_mime_header_iter_get_name (iter), header) != 0)\r
+           continue;\r
\r
++      /* Note that GMime retains ownership of value... */\r
+       value = g_mime_header_iter_get_value (iter);\r
++\r
++      /* ... while decoded needs to be freed with g_free(). */\r
+       decoded = g_mime_utils_header_decode_text (value);\r
+       if (! decoded) {\r
+           if (combined) {\r
+@@ -276,23 +276,20 @@ _notmuch_message_file_get_combined_header (notmuch_message_file_t *message,\r
+     return combined;\r
+ }\r
\r
+-/* Return NULL on errors, empty string for non-existing headers. */\r
+ const char *\r
+ notmuch_message_file_get_header (notmuch_message_file_t *message,\r
+                                const char *header)\r
+ {\r
+-    const char *value = NULL;\r
++    const char *value;\r
+     char *decoded;\r
+-    notmuch_bool_t found;\r
\r
+-    if (notmuch_message_file_parse (message))\r
++    if (_notmuch_message_file_parse (message))\r
+       return NULL;\r
\r
+     /* If we have a cached decoded value, use it. */\r
+-    found = g_hash_table_lookup_extended (message->headers, header,\r
+-                                        NULL, (gpointer *) &value);\r
+-    if (found)\r
+-      return value ? value : "";\r
++    value = g_hash_table_lookup (message->headers, header);\r
++    if (value)\r
++      return value;\r
\r
+     if (strcasecmp (header, "received") == 0) {\r
+       /*\r
+diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h\r
+index 734a4e338554..703ae7bb7a01 100644\r
+--- a/lib/notmuch-private.h\r
++++ b/lib/notmuch-private.h\r
+@@ -354,19 +354,20 @@ notmuch_message_file_close (notmuch_message_file_t *message);\r
+  * status reporting.\r
+  */\r
+ notmuch_status_t\r
+-notmuch_message_file_parse (notmuch_message_file_t *message);\r
++_notmuch_message_file_parse (notmuch_message_file_t *message);\r
\r
+ /* Get the gmime message of a message file.\r
+  *\r
+  * The message file is parsed as necessary.\r
+  *\r
+- * Returns GMimeMessage* on success (which the caller must not unref),\r
+- * NULL if the message file parsing fails.\r
++ * The GMimeMessage* is set to *mime_message on success (which the\r
++ * caller must not unref).\r
+  *\r
+  * XXX: Would be nice to not have to expose GMimeMessage here.\r
+  */\r
+-GMimeMessage *\r
+-notmuch_message_file_get_mime_message (notmuch_message_file_t *message);\r
++notmuch_status_t\r
++_notmuch_message_file_get_mime_message (notmuch_message_file_t *message,\r
++                                      GMimeMessage **mime_message);\r
\r
+ /* Get the value of the specified header from the message as a UTF-8 string.\r
+  *\r
+diff --git a/test/T050-new.sh b/test/T050-new.sh\r
+index ad46ee6d51b6..3c3195428223 100755\r
+--- a/test/T050-new.sh\r
++++ b/test/T050-new.sh\r
+@@ -163,22 +163,6 @@ rm -rf "${MAIL_DIR}"/two\r
+ output=$(NOTMUCH_NEW)\r
+ test_expect_equal "$output" "No new mail. Removed 3 messages."\r
\r
+-test_begin_subtest "Support single-message mbox (deprecated)"\r
+-cat > "${MAIL_DIR}"/mbox_file1 <<EOF\r
+-From test_suite@notmuchmail.org Fri Jan  5 15:43:57 2001\r
+-From: Notmuch Test Suite <test_suite@notmuchmail.org>\r
+-To: Notmuch Test Suite <test_suite@notmuchmail.org>\r
+-Subject: Test mbox message 1\r
+-\r
+-Body.\r
+-EOF\r
+-output=$(NOTMUCH_NEW 2>&1)\r
+-test_expect_equal "$output" \\r
+-"Warning: ${MAIL_DIR}/mbox_file1 is an mbox containing a single message,\r
+-likely caused by misconfigured mail delivery.  Support for single-message\r
+-mboxes is deprecated and may be removed in the future.\r
+-Added 1 new message to the database."\r
+-\r
+ # This test requires that notmuch new has been run at least once.\r
+ test_begin_subtest "Skip and report non-mail files"\r
+ generate_message\r
+@@ -200,14 +184,24 @@ Subject: Test mbox message 2\r
\r
+ Body 2.\r
+ EOF\r
++cat > "${MAIL_DIR}"/mbox_file1 <<EOF\r
++From test_suite@notmuchmail.org Fri Jan  5 15:43:57 2001\r
++From: Notmuch Test Suite <test_suite@notmuchmail.org>\r
++To: Notmuch Test Suite <test_suite@notmuchmail.org>\r
++Subject: Test mbox message 1\r
++\r
++Body.\r
++EOF\r
+ output=$(NOTMUCH_NEW 2>&1)\r
+ test_expect_equal "$output" \\r
+ "Note: Ignoring non-mail file: ${MAIL_DIR}/.git/config\r
+ Note: Ignoring non-mail file: ${MAIL_DIR}/.ignored_hidden_file\r
+ Note: Ignoring non-mail file: ${MAIL_DIR}/ignored_file\r
+ Note: Ignoring non-mail file: ${MAIL_DIR}/mbox_file\r
++Note: Ignoring non-mail file: ${MAIL_DIR}/mbox_file1\r
+ Added 1 new message to the database."\r
+ rm "${MAIL_DIR}"/mbox_file\r
++rm "${MAIL_DIR}"/mbox_file1\r
\r
+ test_begin_subtest "Ignore files and directories specified in new.ignore"\r
+ generate_message\r