X-Git-Url: https://git.notmuchmail.org/git?a=blobdiff_plain;f=lib%2Fmessage-file.c;h=d7acf0d5b4e2739eac56756c1ca35f30eeacf424;hb=4ce7591610444a1c5ef6f56b57af8e180437fa62;hp=67828827e61d5a065b16e527013024c41b2abea4;hpb=473930bb6fb167078a9428ad85f53accf7d4559f;p=notmuch diff --git a/lib/message-file.c b/lib/message-file.c index 67828827..d7acf0d5 100644 --- a/lib/message-file.c +++ b/lib/message-file.c @@ -13,7 +13,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program. If not, see http://www.gnu.org/licenses/ . + * along with this program. If not, see https://www.gnu.org/licenses/ . * * Author: Carl Worth */ @@ -37,27 +37,6 @@ struct _notmuch_message_file { GMimeMessage *message; }; -static int -strcase_equal (const void *a, const void *b) -{ - return strcasecmp (a, b) == 0; -} - -static unsigned int -strcase_hash (const void *ptr) -{ - const char *s = ptr; - - /* This is the djb2 hash. */ - unsigned int hash = 5381; - while (s && *s) { - hash = ((hash << 5) + hash) + tolower (*s); - s++; - } - - return hash; -} - static int _notmuch_message_file_destructor (notmuch_message_file_t *message) { @@ -76,7 +55,8 @@ _notmuch_message_file_destructor (notmuch_message_file_t *message) /* Create a new notmuch_message_file_t for 'filename' with 'ctx' as * the talloc owner. */ notmuch_message_file_t * -_notmuch_message_file_open_ctx (void *ctx, const char *filename) +_notmuch_message_file_open_ctx (notmuch_database_t *notmuch, + void *ctx, const char *filename) { notmuch_message_file_t *message; @@ -98,26 +78,28 @@ _notmuch_message_file_open_ctx (void *ctx, const char *filename) return message; FAIL: - fprintf (stderr, "Error opening %s: %s\n", filename, strerror (errno)); - notmuch_message_file_close (message); + _notmuch_database_log (notmuch, "Error opening %s: %s\n", + filename, strerror (errno)); + _notmuch_message_file_close (message); return NULL; } notmuch_message_file_t * -notmuch_message_file_open (const char *filename) +_notmuch_message_file_open (notmuch_database_t *notmuch, + const char *filename) { - return _notmuch_message_file_open_ctx (NULL, filename); + return _notmuch_message_file_open_ctx (notmuch, NULL, filename); } void -notmuch_message_file_close (notmuch_message_file_t *message) +_notmuch_message_file_close (notmuch_message_file_t *message) { talloc_free (message); } static notmuch_bool_t -is_mbox (FILE *file) +_is_mbox (FILE *file) { char from_buf[5]; notmuch_bool_t ret = FALSE; @@ -139,13 +121,12 @@ _notmuch_message_file_parse (notmuch_message_file_t *message) GMimeParser *parser; notmuch_status_t status = NOTMUCH_STATUS_SUCCESS; static int initialized = 0; + notmuch_bool_t is_mbox; if (message->message) return NOTMUCH_STATUS_SUCCESS; - /* We no longer support mboxes at all. */ - if (is_mbox (message->file)) - return NOTMUCH_STATUS_FILE_NOT_EMAIL; + is_mbox = _is_mbox (message->file); if (! initialized) { g_mime_init (GMIME_ENABLE_RFC2047_WORKAROUNDS); @@ -163,7 +144,7 @@ _notmuch_message_file_parse (notmuch_message_file_t *message) g_mime_stream_file_set_owner (GMIME_STREAM_FILE (stream), FALSE); parser = g_mime_parser_new_with_stream (stream); - g_mime_parser_set_scan_from (parser, FALSE); + g_mime_parser_set_scan_from (parser, is_mbox); message->message = g_mime_parser_construct_message (parser); if (! message->message) { @@ -171,6 +152,14 @@ _notmuch_message_file_parse (notmuch_message_file_t *message) goto DONE; } + if (is_mbox && ! g_mime_parser_eos (parser)) { + /* + * This is a multi-message mbox. (For historical reasons, we + * do support single-message mboxes.) + */ + status = NOTMUCH_STATUS_FILE_NOT_EMAIL; + } + DONE: g_object_unref (stream); g_object_unref (parser); @@ -212,6 +201,38 @@ _notmuch_message_file_get_mime_message (notmuch_message_file_t *message, * * Return NULL on errors, empty string for non-existing headers. */ + +static char * +_extend_header (char *combined, const char *value) { + char *decoded; + + decoded = g_mime_utils_header_decode_text (value); + if (! decoded) { + if (combined) { + g_free (combined); + combined = NULL; + } + goto DONE; + } + + if (combined) { + char *tmp = g_strdup_printf ("%s %s", combined, decoded); + g_free (decoded); + g_free (combined); + if (! tmp) { + combined = NULL; + goto DONE; + } + + combined = tmp; + } else { + combined = decoded; + } + DONE: + return combined; +} + +#if (GMIME_MAJOR_VERSION < 3) static char * _notmuch_message_file_get_combined_header (notmuch_message_file_t *message, const char *header) @@ -233,37 +254,13 @@ _notmuch_message_file_get_combined_header (notmuch_message_file_t *message, do { const char *value; - char *decoded; - if (strcasecmp (g_mime_header_iter_get_name (iter), header) != 0) continue; /* Note that GMime retains ownership of value... */ value = g_mime_header_iter_get_value (iter); - /* ... while decoded needs to be freed with g_free(). */ - decoded = g_mime_utils_header_decode_text (value); - if (! decoded) { - if (combined) { - g_free (combined); - combined = NULL; - } - goto DONE; - } - - if (combined) { - char *tmp = g_strdup_printf ("%s %s", combined, decoded); - g_free (decoded); - g_free (combined); - if (! tmp) { - combined = NULL; - goto DONE; - } - - combined = tmp; - } else { - combined = decoded; - } + combined = _extend_header (combined, value); } while (g_mime_header_iter_next (iter)); /* Return empty string for non-existing headers. */ @@ -275,9 +272,42 @@ _notmuch_message_file_get_combined_header (notmuch_message_file_t *message, return combined; } +#else +static char * +_notmuch_message_file_get_combined_header (notmuch_message_file_t *message, + const char *header) +{ + char *combined = NULL; + GMimeHeaderList *headers; + + headers = g_mime_object_get_header_list (GMIME_OBJECT (message->message)); + if (! headers) + return NULL; + + + for (int i=0; i < g_mime_header_list_get_count (headers); i++) { + const char *value; + GMimeHeader *g_header = g_mime_header_list_get_header_at (headers, i); + + if (strcasecmp (g_mime_header_get_name (g_header), header) != 0) + continue; + + /* GMime retains ownership of value, we hope */ + value = g_mime_header_get_value (g_header); + + combined = _extend_header (combined, value); + } + + /* Return empty string for non-existing headers. */ + if (! combined) + combined = g_strdup (""); + + return combined; +} +#endif const char * -notmuch_message_file_get_header (notmuch_message_file_t *message, +_notmuch_message_file_get_header (notmuch_message_file_t *message, const char *header) { const char *value;