]> git.notmuchmail.org Git - notmuch/blobdiff - lib/message.cc
lib: fix error handling
[notmuch] / lib / message.cc
index ed96477f98b7773d6905dd5325fe3d38ec28de3d..c91f3a59836f65ceb9b92a8e337603ea2d2a69ea 100644 (file)
@@ -266,18 +266,18 @@ _notmuch_message_get_term (notmuch_message_t *message,
                           const char *prefix)
 {
     int prefix_len = strlen (prefix);
-    const char *term = NULL;
     char *value;
 
     i.skip_to (prefix);
 
-    if (i != end)
-       term = (*i).c_str ();
+    if (i == end)
+       return NULL;
 
-    if (!term || strncmp (term, prefix, prefix_len))
+    std::string term = *i;
+    if (strncmp (term.c_str(), prefix, prefix_len))
        return NULL;
 
-    value = talloc_strdup (message, term + prefix_len);
+    value = talloc_strdup (message, term.c_str() + prefix_len);
 
 #if DEBUG_DATABASE_SANITY
     i++;
@@ -412,19 +412,27 @@ _notmuch_message_ensure_message_file (notmuch_message_t *message)
 const char *
 notmuch_message_get_header (notmuch_message_t *message, const char *header)
 {
-    std::string value;
+    try {
+           std::string value;
 
-    /* Fetch header from the appropriate xapian value field if
-     * available */
-    if (strcasecmp (header, "from") == 0)
-       value = message->doc.get_value (NOTMUCH_VALUE_FROM);
-    else if (strcasecmp (header, "subject") == 0)
-       value = message->doc.get_value (NOTMUCH_VALUE_SUBJECT);
-    else if (strcasecmp (header, "message-id") == 0)
-       value = message->doc.get_value (NOTMUCH_VALUE_MESSAGE_ID);
+           /* Fetch header from the appropriate xapian value field if
+            * available */
+           if (strcasecmp (header, "from") == 0)
+               value = message->doc.get_value (NOTMUCH_VALUE_FROM);
+           else if (strcasecmp (header, "subject") == 0)
+               value = message->doc.get_value (NOTMUCH_VALUE_SUBJECT);
+           else if (strcasecmp (header, "message-id") == 0)
+               value = message->doc.get_value (NOTMUCH_VALUE_MESSAGE_ID);
 
-    if (!value.empty())
-       return talloc_strdup (message, value.c_str ());
+           if (!value.empty())
+               return talloc_strdup (message, value.c_str ());
+
+    } catch (Xapian::Error &error) {
+       fprintf (stderr, "A Xapian exception occurred when reading header: %s\n",
+                error.get_msg().c_str());
+       message->notmuch->exception_reported = TRUE;
+       return NULL;
+    }
 
     /* Otherwise fall back to parsing the file */
     _notmuch_message_ensure_message_file (message);
@@ -462,9 +470,9 @@ notmuch_message_get_thread_id (notmuch_message_t *message)
 
 void
 _notmuch_message_add_reply (notmuch_message_t *message,
-                           notmuch_message_node_t *reply)
+                           notmuch_message_t *reply)
 {
-    _notmuch_message_list_append (message->replies, reply);
+    _notmuch_message_list_add_message (message->replies, reply);
 }
 
 notmuch_messages_t *
@@ -766,7 +774,9 @@ notmuch_message_get_date (notmuch_message_t *message)
     try {
        value = message->doc.get_value (NOTMUCH_VALUE_TIMESTAMP);
     } catch (Xapian::Error &error) {
-       INTERNAL_ERROR ("Failed to read timestamp value from document.");
+       fprintf (stderr, "A Xapian exception occurred when reading date: %s\n",
+                error.get_msg().c_str());
+       message->notmuch->exception_reported = TRUE;
        return 0;
     }
 
@@ -788,7 +798,9 @@ notmuch_message_get_tags (notmuch_message_t *message)
      * possible to modify the message tags (which talloc_unlink's the
      * current list from the message) while still iterating because
      * the iterator will keep the current list alive. */
-    talloc_reference (message, message->tag_list);
+    if (!talloc_reference (message, message->tag_list))
+       return NULL;
+
     return tags;
 }
 
@@ -1074,7 +1086,7 @@ notmuch_message_maildir_flags_to_tags (notmuch_message_t *message)
     const char *flags;
     notmuch_status_t status;
     notmuch_filenames_t *filenames;
-    const char *filename;
+    const char *filename, *dir;
     char *combined_flags = talloc_strdup (message, "");
     unsigned i;
     int seen_maildir_info = 0;
@@ -1084,15 +1096,25 @@ notmuch_message_maildir_flags_to_tags (notmuch_message_t *message)
         notmuch_filenames_move_to_next (filenames))
     {
        filename = notmuch_filenames_get (filenames);
+       dir = _filename_is_in_maildir (filename);
 
-       flags = strstr (filename, ":2,");
-       if (! flags)
+       if (! dir)
            continue;
 
-       seen_maildir_info = 1;
-       flags += 3;
-
-       combined_flags = talloc_strdup_append (combined_flags, flags);
+       flags = strstr (filename, ":2,");
+       if (flags) {
+           seen_maildir_info = 1;
+           flags += 3;
+           combined_flags = talloc_strdup_append (combined_flags, flags);
+       } else if (STRNCMP_LITERAL (dir, "new/") == 0) {
+           /* Messages are delivered to new/ with no "info" part, but
+            * they effectively have default maildir flags.  According
+            * to the spec, we should ignore the info part for
+            * messages in new/, but some MUAs (mutt) can set maildir
+            * flags on messages in new/, so we're liberal in what we
+            * accept. */
+           seen_maildir_info = 1;
+       }
     }
 
     /* If none of the filenames have any maildir info field (not even
@@ -1183,7 +1205,9 @@ _get_maildir_flag_actions (notmuch_message_t *message,
  * compute the new maildir filename.
  *
  * If the existing filename is in the directory "new", the new
- * filename will be in the directory "cur".
+ * filename will be in the directory "cur", except for the case when
+ * no flags are changed and the existing filename does not contain
+ * maildir info (starting with ",2:").
  *
  * After a sequence of ":2," in the filename, any subsequent
  * single-character flags will be added or removed according to the
@@ -1206,6 +1230,7 @@ _new_maildir_filename (void *ctx,
     char *filename_new, *dir;
     char flag_map[128];
     int flags_in_map = 0;
+    notmuch_bool_t flags_changed = FALSE;
     unsigned int i;
     char *s;
 
@@ -1246,6 +1271,7 @@ _new_maildir_filename (void *ctx,
        if (flag_map[flag] == 0) {
            flag_map[flag] = 1;
            flags_in_map++;
+           flags_changed = TRUE;
        }
     }
 
@@ -1254,9 +1280,16 @@ _new_maildir_filename (void *ctx,
        if (flag_map[flag]) {
            flag_map[flag] = 0;
            flags_in_map--;
+           flags_changed = TRUE;
        }
     }
 
+    /* Messages in new/ without maildir info can be kept in new/ if no
+     * flags have changed. */
+    dir = (char *) _filename_is_in_maildir (filename);
+    if (dir && STRNCMP_LITERAL (dir, "new/") == 0 && !*info && !flags_changed)
+       return talloc_strdup (ctx, filename);
+
     filename_new = (char *) talloc_size (ctx,
                                         info - filename +
                                         strlen (":2,") + flags_in_map + 1);