[PATCH 1/2] Make Received: header special in notmuch_message_file_get_header
authorDirk Hohndel <hohndel@infradead.org>
Mon, 26 Apr 2010 19:58:34 +0000 (12:58 +1700)
committerW. Trevor King <wking@tremily.us>
Fri, 7 Nov 2014 17:36:56 +0000 (09:36 -0800)
a0/d5c7387523b99b089e210f9af70211b49c4fdd [new file with mode: 0644]

diff --git a/a0/d5c7387523b99b089e210f9af70211b49c4fdd b/a0/d5c7387523b99b089e210f9af70211b49c4fdd
new file mode 100644 (file)
index 0000000..615aff1
--- /dev/null
@@ -0,0 +1,178 @@
+Return-Path: <hohndel@gr8dns.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 1A1C2418C34\r
+       for <notmuch@notmuchmail.org>; Mon, 26 Apr 2010 12:58:50 -0700 (PDT)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: -1.9\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=-1.9 tagged_above=-999 required=5\r
+       tests=[BAYES_00=-1.9] autolearn=ham\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 ghW6EbU4IuoM for <notmuch@notmuchmail.org>;\r
+       Mon, 26 Apr 2010 12:58:48 -0700 (PDT)\r
+Received: from mail.hohndel.org (mail.hohndel.org [65.23.157.147])\r
+       by olra.theworths.org (Postfix) with ESMTP id 549DD431FC1\r
+       for <notmuch@notmuchmail.org>; Mon, 26 Apr 2010 12:58:48 -0700 (PDT)\r
+Received: by mail.hohndel.org (Postfix, from userid 112)\r
+       id A5965340FA; Mon, 26 Apr 2010 15:58:47 -0400 (EDT)\r
+Received: from x200.gr8dns.org (unknown [65.23.157.147])\r
+       by mail.hohndel.org (Postfix) with ESMTP id 6BB76340F4;\r
+       Mon, 26 Apr 2010 15:58:42 -0400 (EDT)\r
+Received: by x200.gr8dns.org (Postfix, from userid 500)\r
+       id 5483FCC906; Mon, 26 Apr 2010 12:58:42 -0700 (PDT)\r
+From: Dirk Hohndel <hohndel@infradead.org>\r
+To: <notmuch@notmuchmail.org>\r
+Subject: [PATCH 1/2] Make Received: header special in\r
+       notmuch_message_file_get_header\r
+Date: Mon, 26 Apr 2010 12:58:34 -0700\r
+Message-Id: <1272311915-30575-2-git-send-email-hohndel@infradead.org>\r
+X-Mailer: git-send-email 1.6.6.1\r
+In-Reply-To: <1272311915-30575-1-git-send-email-hohndel@infradead.org>\r
+References: <m3sk6lcu9c.fsf@x200.gr8dns.org>\r
+       <1272311915-30575-1-git-send-email-hohndel@infradead.org>\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, 26 Apr 2010 19:58:50 -0000\r
+\r
+With this patch the Received: header becomes special in the way\r
+we treat headers - this is the only header for which we concatenate\r
+all the instances we find (instead of just returning the first one).\r
+\r
+This will be used in the From guessing code for replies as we need to\r
+be able to walk ALL of the Received: headers in a message to have a\r
+good chance to guess which mailbox this email was delivered to.\r
+\r
+Signed-off-by: Dirk Hohndel <hohndel@infradead.org>\r
+---\r
+ lib/message-file.c    |   58 ++++++++++++++++++++++++++++++++++++++-----------\r
+ lib/notmuch-private.h |    3 ++\r
+ 2 files changed, 48 insertions(+), 13 deletions(-)\r
+\r
+diff --git a/lib/message-file.c b/lib/message-file.c\r
+index 0c152a3..7722832 100644\r
+--- a/lib/message-file.c\r
++++ b/lib/message-file.c\r
+@@ -209,17 +209,24 @@ copy_header_unfolding (header_value_closure_t *value,\r
\r
+ /* As a special-case, a value of NULL for header_desired will force\r
+  * the entire header to be parsed if it is not parsed already. This is\r
+- * used by the _notmuch_message_file_get_headers_end function. */\r
++ * used by the _notmuch_message_file_get_headers_end function.\r
++ * Another special case is the Received: header. For this header we\r
++ * want to concatenate all instances of the header instead of just\r
++ * hashing the first instance as we use this when analyzing the path\r
++ * the mail has taken from sender to recipient.\r
++ */\r
+ const char *\r
+ notmuch_message_file_get_header (notmuch_message_file_t *message,\r
+                                const char *header_desired)\r
+ {\r
+     int contains;\r
+-    char *header, *decoded_value;\r
++    char *header, *decoded_value, *header_sofar, *combined_header;\r
+     const char *s, *colon;\r
+-    int match;\r
++    int match, newhdr, hdrsofar, is_received;\r
+     static int initialized = 0;\r
\r
++    is_received = (strcmp(header_desired,"received") == 0);\r
++\r
+     if (! initialized) {\r
+       g_mime_init (0);\r
+       initialized = 1;\r
+@@ -312,22 +319,39 @@ notmuch_message_file_get_header (notmuch_message_file_t *message,\r
\r
+       NEXT_HEADER_LINE (&message->value);\r
\r
+-      if (header_desired == 0)\r
++      if (header_desired == NULL)\r
+           match = 0;\r
+       else\r
+           match = (strcasecmp (header, header_desired) == 0);\r
\r
+       decoded_value = g_mime_utils_header_decode_text (message->value.str);\r
+-      if (g_hash_table_lookup (message->headers, header) == NULL) {\r
+-          /* Only insert if we don't have a value for this header, yet.\r
+-           * This way we always return the FIRST instance of any header\r
+-           * we search for\r
+-           * FIXME: we should be returning ALL instances of a header\r
+-           *        or at least provide a way to iterate over them\r
+-           */\r
+-          g_hash_table_insert (message->headers, header, decoded_value);\r
++      header_sofar = (char *)g_hash_table_lookup (message->headers, header);\r
++      /* we treat the Received: header special - we want to concat ALL of \r
++       * the Received: headers we encounter.\r
++       * for everything else we return the first instance of a header */\r
++      if (is_received) {\r
++          if (header_sofar == NULL) {\r
++              /* first Received: header we encountered; just add it */\r
++              g_hash_table_insert (message->headers, header, decoded_value);\r
++          } else {\r
++              /* we need to add the header to those we already collected */\r
++              newhdr = strlen(decoded_value);\r
++              hdrsofar = strlen(header_sofar);\r
++              combined_header = xmalloc(hdrsofar + newhdr + 2);\r
++              strncpy(combined_header,header_sofar,hdrsofar);\r
++              *(combined_header+hdrsofar) = ' ';\r
++              strncpy(combined_header+hdrsofar+1,decoded_value,newhdr+1);\r
++              g_hash_table_insert (message->headers, header, combined_header);\r
++          }\r
++      } else {\r
++          if (header_sofar == NULL) {\r
++              /* Only insert if we don't have a value for this header, yet. */\r
++              g_hash_table_insert (message->headers, header, decoded_value);\r
++          }\r
+       }\r
+-      if (match)\r
++      /* if we found a match we can bail - unless of course we are\r
++       * collecting all the Received: headers */\r
++      if (match && !is_received)\r
+           return decoded_value;\r
+     }\r
\r
+@@ -347,6 +371,14 @@ notmuch_message_file_get_header (notmuch_message_file_t *message,\r
+       message->value.len = 0;\r
+     }\r
\r
++    /* For the Received: header we actually might end up here even\r
++     * though we found the header (as we force continued parsing\r
++     * in that case). So let's check if that's the header we were\r
++     * looking for and return the value that we found (if any)\r
++     */\r
++    if (is_received)\r
++      return (char *)g_hash_table_lookup (message->headers, "received");\r
++\r
+     /* We've parsed all headers and never found the one we're looking\r
+      * for. It's probably just not there, but let's check that we\r
+      * didn't make a mistake preventing us from seeing it. */\r
+diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h\r
+index 6e83cc3..3768d6f 100644\r
+--- a/lib/notmuch-private.h\r
++++ b/lib/notmuch-private.h\r
+@@ -344,6 +344,9 @@ notmuch_message_file_restrict_headersv (notmuch_message_file_t *message,\r
+  *\r
+  * The header name is case insensitive.\r
+  *\r
++ * The Received: header is special - for it all Received: headers in\r
++ * the message are concatenated\r
++ *\r
+  * The returned value is owned by the notmuch message and is valid\r
+  * only until the message is closed. The caller should copy it if\r
+  * needing to modify the value or to hold onto it for longer.\r
+-- \r
+1.6.6.1\r
+\r