X-Git-Url: https://git.notmuchmail.org/git?p=notmuch;a=blobdiff_plain;f=lib%2Findex.cc;h=f166aefd2fc1f6f6c5ea1e306e4fc033ead09c59;hp=0eb2774a28a5f3f12964c1959e45ba1ab83a6309;hb=506b81679a883d2a96bcd17e7c826a3166bdf82e;hpb=3767c6f9f9c4719f36569daa05cd56470b3fd00f diff --git a/lib/index.cc b/lib/index.cc index 0eb2774a..f166aefd 100644 --- a/lib/index.cc +++ b/lib/index.cc @@ -24,14 +24,8 @@ #include -/* Oh, how I wish that gobject didn't require so much noisy boilerplate! */ -#define NOTMUCH_TYPE_FILTER_DISCARD_UUENCODE (notmuch_filter_discard_uuencode_get_type ()) -#define NOTMUCH_FILTER_DISCARD_UUENCODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NOTMUCH_TYPE_FILTER_DISCARD_UUENCODE, NotmuchFilterDiscardUuencode)) -#define NOTMUCH_FILTER_DISCARD_UUENCODE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NOTMUCH_TYPE_FILTER_DISCARD_UUENCODE, NotmuchFilterDiscardUuencodeClass)) -#define NOTMUCH_IS_FILTER_DISCARD_UUENCODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NOTMUCH_TYPE_FILTER_DISCARD_UUENCODE)) -#define NOTMUCH_IS_FILTER_DISCARD_UUENCODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NOTMUCH_TYPE_FILTER_DISCARD_UUENCODE)) -#define NOTMUCH_FILTER_DISCARD_UUENCODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NOTMUCH_TYPE_FILTER_DISCARD_UUENCODE, NotmuchFilterDiscardUuencodeClass)) - +/* Oh, how I wish that gobject didn't require so much noisy boilerplate! + * (Though I have at least eliminated some of the stock set...) */ typedef struct _NotmuchFilterDiscardUuencode NotmuchFilterDiscardUuencode; typedef struct _NotmuchFilterDiscardUuencodeClass NotmuchFilterDiscardUuencodeClass; @@ -69,12 +63,8 @@ struct _NotmuchFilterDiscardUuencodeClass { GMimeFilterClass parent_class; }; -GType notmuch_filter_discard_uuencode_get_type (void); - -GMimeFilter *notmuch_filter_discard_uuencode_new (void); +static GMimeFilter *notmuch_filter_discard_uuencode_new (void); -static void notmuch_filter_discard_uuencode_class_init (NotmuchFilterDiscardUuencodeClass *klass); -static void notmuch_filter_discard_uuencode_init (NotmuchFilterDiscardUuencode *filter, NotmuchFilterDiscardUuencodeClass *klass); static void notmuch_filter_discard_uuencode_finalize (GObject *object); static GMimeFilter *filter_copy (GMimeFilter *filter); @@ -87,31 +77,6 @@ static void filter_reset (GMimeFilter *filter); static GMimeFilterClass *parent_class = NULL; -GType -notmuch_filter_discard_uuencode_get_type (void) -{ - static GType type = 0; - - if (!type) { - static const GTypeInfo info = { - sizeof (NotmuchFilterDiscardUuencodeClass), - NULL, /* base_class_init */ - NULL, /* base_class_finalize */ - (GClassInitFunc) notmuch_filter_discard_uuencode_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (NotmuchFilterDiscardUuencode), - 0, /* n_preallocs */ - (GInstanceInitFunc) notmuch_filter_discard_uuencode_init, - NULL /* value_table */ - }; - - type = g_type_register_static (GMIME_TYPE_FILTER, "NotmuchFilterDiscardUuencode", &info, (GTypeFlags) 0); - } - - return type; -} - static void notmuch_filter_discard_uuencode_class_init (NotmuchFilterDiscardUuencodeClass *klass) { @@ -128,13 +93,6 @@ notmuch_filter_discard_uuencode_class_init (NotmuchFilterDiscardUuencodeClass *k filter_class->reset = filter_reset; } -static void -notmuch_filter_discard_uuencode_init (NotmuchFilterDiscardUuencode *filter, NotmuchFilterDiscardUuencodeClass *klass) -{ - (void) klass; - filter->state = 0; -} - static void notmuch_filter_discard_uuencode_finalize (GObject *object) { @@ -237,12 +195,30 @@ filter_reset (GMimeFilter *gmime_filter) * * Returns: a new #NotmuchFilterDiscardUuencode filter. **/ -GMimeFilter * +static GMimeFilter * notmuch_filter_discard_uuencode_new (void) { + static GType type = 0; NotmuchFilterDiscardUuencode *filter; - filter = (NotmuchFilterDiscardUuencode *) g_object_newv (NOTMUCH_TYPE_FILTER_DISCARD_UUENCODE, 0, NULL); + if (!type) { + static const GTypeInfo info = { + sizeof (NotmuchFilterDiscardUuencodeClass), + NULL, /* base_class_init */ + NULL, /* base_class_finalize */ + (GClassInitFunc) notmuch_filter_discard_uuencode_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (NotmuchFilterDiscardUuencode), + 0, /* n_preallocs */ + NULL, /* instance_init */ + NULL /* value_table */ + }; + + type = g_type_register_static (GMIME_TYPE_FILTER, "NotmuchFilterDiscardUuencode", &info, (GTypeFlags) 0); + } + + filter = (NotmuchFilterDiscardUuencode *) g_object_newv (type, 0, NULL); filter->state = 0; return (GMimeFilter *) filter; @@ -255,26 +231,22 @@ _index_address_mailbox (notmuch_message_t *message, InternetAddress *address) { InternetAddressMailbox *mailbox = INTERNET_ADDRESS_MAILBOX (address); - const char *name, *addr; + const char *name, *addr, *combined; void *local = talloc_new (message); name = internet_address_get_name (address); addr = internet_address_mailbox_get_addr (mailbox); - /* In the absence of a name, we'll strip the part before the @ - * from the address. */ - if (! name) { - const char *at; - - at = strchr (addr, '@'); - if (at) - name = talloc_strndup (local, addr, at - addr); - } + /* Combine the name and address and index them as a phrase. */ + if (name && addr) + combined = talloc_asprintf (local, "%s %s", name, addr); + else if (name) + combined = name; + else + combined = addr; - if (name) - _notmuch_message_gen_terms (message, prefix_name, name); - if (addr) - _notmuch_message_gen_terms (message, prefix_name, addr); + if (combined) + _notmuch_message_gen_terms (message, prefix_name, combined); talloc_free (local); } @@ -328,26 +300,6 @@ _index_address_list (notmuch_message_t *message, } } -static const char * -skip_re_in_subject (const char *subject) -{ - const char *s = subject; - - if (subject == NULL) - return NULL; - - while (*s) { - while (*s && isspace (*s)) - s++; - if (strncasecmp (s, "re:", 3) == 0) - s += 3; - else - break; - } - - return s; -} - /* Callback to generate terms for each mime part of a message. */ static void _index_mime_part (notmuch_message_t *message, @@ -359,18 +311,46 @@ _index_mime_part (notmuch_message_t *message, GByteArray *byte_array; GMimeContentDisposition *disposition; char *body; + const char *charset; + + if (! part) { + _notmuch_database_log (_notmuch_message_database (message), + "Warning: Not indexing empty mime part.\n"); + return; + } + + GMimeContentType *content_type = g_mime_object_get_content_type(part); + if (content_type) { + char *mime_string = g_mime_content_type_to_string(content_type); + if (mime_string) + { + _notmuch_message_gen_terms (message, "mimetype", mime_string); + g_free(mime_string); + } + } if (GMIME_IS_MULTIPART (part)) { GMimeMultipart *multipart = GMIME_MULTIPART (part); int i; + if (GMIME_IS_MULTIPART_SIGNED (multipart)) + _notmuch_message_add_term (message, "tag", "signed"); + + if (GMIME_IS_MULTIPART_ENCRYPTED (multipart)) + _notmuch_message_add_term (message, "tag", "encrypted"); + for (i = 0; i < g_mime_multipart_get_count (multipart); i++) { if (GMIME_IS_MULTIPART_SIGNED (multipart)) { /* Don't index the signature. */ if (i == 1) continue; if (i > 1) - fprintf (stderr, "Warning: Unexpected extra parts of multipart/signed. Indexing anyway.\n"); + _notmuch_database_log (_notmuch_message_database (message), + "Warning: Unexpected extra parts of multipart/signed. Indexing anyway.\n"); + } + if (GMIME_IS_MULTIPART_ENCRYPTED (multipart)) { + /* Don't index encrypted parts. */ + continue; } _index_mime_part (message, g_mime_multipart_get_part (multipart, i)); @@ -389,14 +369,16 @@ _index_mime_part (notmuch_message_t *message, } if (! (GMIME_IS_PART (part))) { - fprintf (stderr, "Warning: Not indexing unknown mime part: %s.\n", - g_type_name (G_OBJECT_TYPE (part))); + _notmuch_database_log (_notmuch_message_database (message), + "Warning: Not indexing unknown mime part: %s.\n", + g_type_name (G_OBJECT_TYPE (part))); return; } disposition = g_mime_object_get_content_disposition (part); if (disposition && - strcmp (disposition->disposition, GMIME_DISPOSITION_ATTACHMENT) == 0) + strcasecmp (g_mime_content_disposition_get_disposition (disposition), + GMIME_DISPOSITION_ATTACHMENT) == 0) { const char *filename = g_mime_part_get_filename (GMIME_PART (part)); @@ -419,6 +401,20 @@ _index_mime_part (notmuch_message_t *message, g_mime_stream_filter_add (GMIME_STREAM_FILTER (filter), discard_uuencode_filter); + charset = g_mime_object_get_content_type_parameter (part, "charset"); + if (charset) { + GMimeFilter *charset_filter; + charset_filter = g_mime_filter_charset_new (charset, "UTF-8"); + /* This result can be NULL for things like "unknown-8bit". + * Don't set a NULL filter as that makes GMime print + * annoying assertion-failure messages on stderr. */ + if (charset_filter) { + g_mime_stream_filter_add (GMIME_STREAM_FILTER (filter), + charset_filter); + g_object_unref (charset_filter); + } + } + wrapper = g_mime_part_get_content_object (GMIME_PART (part)); if (wrapper) g_mime_data_wrapper_write_to_stream (wrapper, filter); @@ -439,59 +435,36 @@ _index_mime_part (notmuch_message_t *message, notmuch_status_t _notmuch_message_index_file (notmuch_message_t *message, - const char *filename) + notmuch_message_file_t *message_file) { - GMimeStream *stream = NULL; - GMimeParser *parser = NULL; - GMimeMessage *mime_message = NULL; + GMimeMessage *mime_message; InternetAddressList *addresses; - FILE *file = NULL; const char *from, *subject; - notmuch_status_t ret = NOTMUCH_STATUS_SUCCESS; - static int initialized = 0; - - if (! initialized) { - g_mime_init (0); - initialized = 1; - } - - file = fopen (filename, "r"); - if (! file) { - fprintf (stderr, "Error opening %s: %s\n", filename, strerror (errno)); - ret = NOTMUCH_STATUS_FILE_ERROR; - goto DONE; - } - - /* Evil GMime steals my FILE* here so I won't fclose it. */ - stream = g_mime_stream_file_new (file); - - parser = g_mime_parser_new_with_stream (stream); + notmuch_status_t status; - mime_message = g_mime_parser_construct_message (parser); + status = _notmuch_message_file_get_mime_message (message_file, + &mime_message); + if (status) + return status; from = g_mime_message_get_sender (mime_message); - addresses = internet_address_list_parse_string (from); - _index_address_list (message, "from", addresses); + addresses = internet_address_list_parse_string (from); + if (addresses) { + _index_address_list (message, "from", addresses); + g_object_unref (addresses); + } addresses = g_mime_message_get_all_recipients (mime_message); - _index_address_list (message, "to", addresses); + if (addresses) { + _index_address_list (message, "to", addresses); + g_object_unref (addresses); + } subject = g_mime_message_get_subject (mime_message); - subject = skip_re_in_subject (subject); _notmuch_message_gen_terms (message, "subject", subject); _index_mime_part (message, g_mime_message_get_mime_part (mime_message)); - DONE: - if (mime_message) - g_object_unref (mime_message); - - if (parser) - g_object_unref (parser); - - if (stream) - g_object_unref (stream); - - return ret; + return NOTMUCH_STATUS_SUCCESS; }