--- /dev/null
+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