X-Git-Url: https://git.notmuchmail.org/git?p=notmuch;a=blobdiff_plain;f=message-file.c;h=75caba6d8b055e5c3b57b2d72d1926381ff11fc8;hp=18275fbf853fc89ecb4c5b703c34a5a9b084e995;hb=aa34eb2a3761c770b485486d0f94564f5e925128;hpb=c12823648ee84b4748e0e9f0cd97f7264911b589 diff --git a/message-file.c b/message-file.c index 18275fbf..75caba6d 100644 --- a/message-file.c +++ b/message-file.c @@ -22,6 +22,8 @@ #include "notmuch-private.h" +#include + #include /* GHashTable */ typedef struct { @@ -39,6 +41,7 @@ struct _notmuch_message_file { GHashTable *headers; int broken_headers; int good_headers; + size_t header_size; /* Length of full message header in bytes. */ /* Parsing state */ char *line; @@ -204,28 +207,41 @@ 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. */ const char * notmuch_message_file_get_header (notmuch_message_file_t *message, const char *header_desired) { int contains; - char *header, *value; + char *header, *decoded_value; const char *s, *colon; int match; + static int initialized = 0; + + if (! initialized) { + g_mime_init (0); + initialized = 1; + } message->parsing_started = 1; - contains = g_hash_table_lookup_extended (message->headers, - header_desired, NULL, - (gpointer *) &value); - if (contains && value) - return value; + if (header_desired == NULL) + contains = 0; + else + contains = g_hash_table_lookup_extended (message->headers, + header_desired, NULL, + (gpointer *) &decoded_value); + + if (contains && decoded_value) + return decoded_value; if (message->parsing_finished) return NULL; #define NEXT_HEADER_LINE(closure) \ - do { \ + while (1) { \ ssize_t bytes_read = getline (&message->line, \ &message->line_size, \ message->file); \ @@ -242,7 +258,11 @@ notmuch_message_file_get_header (notmuch_message_file_t *message, { \ copy_header_unfolding ((closure), message->line); \ } \ - } while (*message->line == ' ' || *message->line == '\t'); + if (*message->line == ' ' || *message->line == '\t') \ + message->header_size += strlen (message->line); \ + else \ + break; \ + } if (message->line == NULL) NEXT_HEADER_LINE (NULL); @@ -268,6 +288,8 @@ notmuch_message_file_get_header (notmuch_message_file_t *message, continue; } + message->header_size += strlen (message->line); + message->good_headers++; header = xstrndup (message->line, colon - message->line); @@ -290,14 +312,17 @@ notmuch_message_file_get_header (notmuch_message_file_t *message, NEXT_HEADER_LINE (&message->value); - match = (strcasecmp (header, header_desired) == 0); + if (header_desired == 0) + match = 0; + else + match = (strcasecmp (header, header_desired) == 0); - value = xstrdup (message->value.str); + decoded_value = g_mime_utils_header_decode_text (message->value.str); - g_hash_table_insert (message->headers, header, value); + g_hash_table_insert (message->headers, header, decoded_value); if (match) - return value; + return decoded_value; } if (message->line) @@ -314,7 +339,7 @@ notmuch_message_file_get_header (notmuch_message_file_t *message, /* 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. */ - if (message->restrict_headers && + if (message->restrict_headers && header_desired && ! g_hash_table_lookup_extended (message->headers, header_desired, NULL, NULL)) {