]> git.notmuchmail.org Git - notmuch/blobdiff - lib/index.cc
lib: content disposition values are not case-sensitive
[notmuch] / lib / index.cc
index cf930251c8c7be4c34bb53dab6930cca940d0302..f166aefd2fc1f6f6c5ea1e306e4fc033ead09c59 100644 (file)
@@ -63,7 +63,7 @@ struct _NotmuchFilterDiscardUuencodeClass {
     GMimeFilterClass parent_class;
 };
 
-GMimeFilter *notmuch_filter_discard_uuencode_new (void);
+static GMimeFilter *notmuch_filter_discard_uuencode_new (void);
 
 static void notmuch_filter_discard_uuencode_finalize (GObject *object);
 
@@ -195,7 +195,7 @@ filter_reset (GMimeFilter *gmime_filter)
  *
  * Returns: a new #NotmuchFilterDiscardUuencode filter.
  **/
-GMimeFilter *
+static GMimeFilter *
 notmuch_filter_discard_uuencode_new (void)
 {
     static GType type = 0;
@@ -231,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);
 }
@@ -304,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,
@@ -335,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));
@@ -365,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));
 
@@ -395,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);
@@ -415,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;
-    }
+    notmuch_status_t status;
 
-    /* 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);
-
-    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;
 }