X-Git-Url: https://git.notmuchmail.org/git?p=notmuch;a=blobdiff_plain;f=lib%2Fmessage-file.c;h=a2850c278b5a10ba9a5041a6662aab4ed09e3861;hp=75caba6d8b055e5c3b57b2d72d1926381ff11fc8;hb=8fb16e277e4d6c32bafa79ae7967e1e6ba9258e0;hpb=146549321044615d9aef2b30cedccda9c49f3f38 diff --git a/lib/message-file.c b/lib/message-file.c index 75caba6d..a2850c27 100644 --- a/lib/message-file.c +++ b/lib/message-file.c @@ -111,7 +111,7 @@ _notmuch_message_file_open_ctx (void *ctx, const char *filename) message->headers = g_hash_table_new_full (strcase_hash, strcase_equal, free, - free); + g_free); message->parsing_started = 0; message->parsing_finished = 0; @@ -209,19 +209,26 @@ copy_header_unfolding (header_value_closure_t *value, /* As a special-case, a value of NULL for header_desired will force * the entire header to be parsed if it is not parsed already. This is - * used by the _notmuch_message_file_get_headers_end function. */ + * used by the _notmuch_message_file_get_headers_end function. + * Another special case is the Received: header. For this header we + * want to concatenate all instances of the header instead of just + * hashing the first instance as we use this when analyzing the path + * the mail has taken from sender to recipient. + */ const char * notmuch_message_file_get_header (notmuch_message_file_t *message, const char *header_desired) { int contains; - char *header, *decoded_value; + char *header, *decoded_value, *header_sofar, *combined_header; const char *s, *colon; - int match; + int match, newhdr, hdrsofar, is_received; static int initialized = 0; + is_received = (strcmp(header_desired,"received") == 0); + if (! initialized) { - g_mime_init (0); + g_mime_init (GMIME_ENABLE_RFC2047_WORKAROUNDS); initialized = 1; } @@ -238,7 +245,7 @@ notmuch_message_file_get_header (notmuch_message_file_t *message, return decoded_value; if (message->parsing_finished) - return NULL; + return ""; #define NEXT_HEADER_LINE(closure) \ while (1) { \ @@ -282,7 +289,7 @@ notmuch_message_file_get_header (notmuch_message_file_t *message, message->good_headers < 5) { message->parsing_finished = 1; - continue; + break; } NEXT_HEADER_LINE (NULL); continue; @@ -312,19 +319,52 @@ notmuch_message_file_get_header (notmuch_message_file_t *message, NEXT_HEADER_LINE (&message->value); - if (header_desired == 0) + if (header_desired == NULL) match = 0; else match = (strcasecmp (header, header_desired) == 0); decoded_value = g_mime_utils_header_decode_text (message->value.str); - - g_hash_table_insert (message->headers, header, decoded_value); - - if (match) + header_sofar = (char *)g_hash_table_lookup (message->headers, header); + /* we treat the Received: header special - we want to concat ALL of + * the Received: headers we encounter. + * for everything else we return the first instance of a header */ + if (strcasecmp(header, "received") == 0) { + if (header_sofar == NULL) { + /* first Received: header we encountered; just add it */ + g_hash_table_insert (message->headers, header, decoded_value); + } else { + /* we need to add the header to those we already collected */ + newhdr = strlen(decoded_value); + hdrsofar = strlen(header_sofar); + combined_header = g_malloc(hdrsofar + newhdr + 2); + strncpy(combined_header,header_sofar,hdrsofar); + *(combined_header+hdrsofar) = ' '; + strncpy(combined_header+hdrsofar+1,decoded_value,newhdr+1); + g_free (decoded_value); + g_hash_table_insert (message->headers, header, combined_header); + } + } else { + if (header_sofar == NULL) { + /* Only insert if we don't have a value for this header, yet. */ + g_hash_table_insert (message->headers, header, decoded_value); + } else { + free (header); + g_free (decoded_value); + decoded_value = header_sofar; + } + } + /* if we found a match we can bail - unless of course we are + * collecting all the Received: headers */ + if (match && !is_received) return decoded_value; } + if (message->parsing_finished) { + fclose (message->file); + message->file = NULL; + } + if (message->line) free (message->line); message->line = NULL; @@ -336,6 +376,14 @@ notmuch_message_file_get_header (notmuch_message_file_t *message, message->value.len = 0; } + /* For the Received: header we actually might end up here even + * though we found the header (as we force continued parsing + * in that case). So let's check if that's the header we were + * looking for and return the value that we found (if any) + */ + if (is_received) + return (char *)g_hash_table_lookup (message->headers, "received"); + /* We've parsed all headers and never found the one we're looking * for. It's probably just not there, but let's check that we * didn't make a mistake preventing us from seeing it. */ @@ -348,5 +396,5 @@ notmuch_message_file_get_header (notmuch_message_file_t *message, header_desired); } - return NULL; + return ""; }