]> git.notmuchmail.org Git - notmuch/blobdiff - database.cc
Move thread_id generation code from database.cc to message.cc
[notmuch] / database.cc
index 77b2eff22973073aa511c2d0c0baa31d20190e31..c5d774763307ab8b9c1b862ef7c0b4371d586511 100644 (file)
 
 using namespace std;
 
-/* "128 bits of thread-id ought to be enough for anybody" */
-#define NOTMUCH_THREAD_ID_BITS  128
-#define NOTMUCH_THREAD_ID_DIGITS (NOTMUCH_THREAD_ID_BITS / 4)
-typedef struct _thread_id {
-    char str[NOTMUCH_THREAD_ID_DIGITS + 1];
-} thread_id_t;
-
-static void
-thread_id_generate (thread_id_t *thread_id)
+const char *
+notmuch_status_to_string (notmuch_status_t status)
 {
-    static int seeded = 0;
-    FILE *dev_random;
-    uint32_t value;
-    char *s;
-    int i;
-
-    if (! seeded) {
-       dev_random = fopen ("/dev/random", "r");
-       if (dev_random == NULL) {
-           srand (time (NULL));
-       } else {
-           fread ((void *) &value, sizeof (value), 1, dev_random);
-           srand (value);
-           fclose (dev_random);
-       }
-       seeded = 1;
-    }
-
-    s = thread_id->str;
-    for (i = 0; i < NOTMUCH_THREAD_ID_DIGITS; i += 8) {
-       value = rand ();
-       sprintf (s, "%08x", value);
-       s += 8;
+    switch (status) {
+    case NOTMUCH_STATUS_SUCCESS:
+       return "No error occurred";
+    case NOTMUCH_STATUS_XAPIAN_EXCEPTION:
+       return "A Xapian exception occurred";
+    case NOTMUCH_STATUS_FILE_ERROR:
+       return "Something went wrong trying to read or write a file";
+    case NOTMUCH_STATUS_FILE_NOT_EMAIL:
+       return "File is not an email";
+    case NOTMUCH_STATUS_NULL_POINTER:
+       return "Erroneous NULL pointer";
+    case NOTMUCH_STATUS_TAG_TOO_LONG:
+       return "Tag value is too long";
+    default:
+    case NOTMUCH_STATUS_LAST_STATUS:
+       return "Unknown error status value";
     }
 }
 
+/* XXX: We should drop this function and convert all callers to call
+ * _notmuch_message_add_term instead. */
 static void
 add_term (Xapian::Document doc,
          const char *prefix_name,
@@ -465,7 +453,8 @@ notmuch_database_add_message (notmuch_database_t *notmuch,
 {
     Xapian::WritableDatabase *db = notmuch->xapian_db;
     Xapian::Document doc;
-    notmuch_message_file_t *message;
+    notmuch_message_file_t *message_file;
+    notmuch_status_t ret = NOTMUCH_STATUS_SUCCESS;
 
     GPtrArray *parents, *thread_ids;
 
@@ -476,15 +465,20 @@ notmuch_database_add_message (notmuch_database_t *notmuch,
     time_t time_value;
     unsigned int i;
 
-    message = notmuch_message_file_open (filename);
+    message_file = notmuch_message_file_open (filename);
+    if (message_file == NULL) {
+       ret = NOTMUCH_STATUS_FILE_ERROR;
+       goto DONE;
+    }
 
-    notmuch_message_file_restrict_headers (message,
+    notmuch_message_file_restrict_headers (message_file,
                                           "date",
                                           "from",
                                           "in-reply-to",
                                           "message-id",
                                           "references",
                                           "subject",
+                                          "to",
                                           (char *) NULL);
 
     try {
@@ -494,16 +488,16 @@ notmuch_database_add_message (notmuch_database_t *notmuch,
 
        parents = g_ptr_array_new ();
 
-       refs = notmuch_message_file_get_header (message, "references");
+       refs = notmuch_message_file_get_header (message_file, "references");
        parse_references (parents, refs);
 
-       in_reply_to = notmuch_message_file_get_header (message, "in-reply-to");
+       in_reply_to = notmuch_message_file_get_header (message_file, "in-reply-to");
        parse_references (parents, in_reply_to);
 
        for (i = 0; i < parents->len; i++)
            add_term (doc, "ref", (char *) g_ptr_array_index (parents, i));
 
-       header = notmuch_message_file_get_header (message, "message-id");
+       header = notmuch_message_file_get_header (message_file, "message-id");
        if (header) {
            message_id = parse_message_id (header, NULL);
            /* So the header value isn't RFC-compliant, but it's
@@ -511,9 +505,18 @@ notmuch_database_add_message (notmuch_database_t *notmuch,
            if (message_id == NULL)
                message_id = xstrdup (header);
        } else {
-           /* XXX: Should generate a message_id here, (such as a SHA1
-            * sum of the message itself) */
-           message_id = NULL;
+           /* No message-id at all, let's generate one by taking a
+            * hash over the file's contents. */
+           char *sha1 = notmuch_sha1_of_file (filename);
+
+           /* If that failed too, something is really wrong. Give up. */
+           if (sha1 == NULL) {
+               ret = NOTMUCH_STATUS_FILE_ERROR;
+               goto DONE;
+           }
+
+           message_id = g_strdup_printf ("notmuch-sha1-%s", sha1);
+           free (sha1);
        }
 
        thread_ids = find_thread_ids (notmuch, parents, message_id);
@@ -521,10 +524,11 @@ notmuch_database_add_message (notmuch_database_t *notmuch,
        for (i = 0; i < parents->len; i++)
            g_free (g_ptr_array_index (parents, i));
        g_ptr_array_free (parents, TRUE);
-       if (message_id) {
-           add_term (doc, "msgid", message_id);
-           doc.add_value (NOTMUCH_VALUE_MESSAGE_ID, message_id);
-       }
+
+       add_term (doc, "msgid", message_id);
+       doc.add_value (NOTMUCH_VALUE_MESSAGE_ID, message_id);
+
+       free (message_id);
 
        if (thread_ids->len) {
            unsigned int i;
@@ -543,7 +547,7 @@ notmuch_database_add_message (notmuch_database_t *notmuch,
            }
            doc.add_value (NOTMUCH_VALUE_THREAD, thread_id->str);
            g_string_free (thread_id, TRUE);
-       } else if (message_id) {
+       } else {
            /* If not part of any existing thread, generate a new thread_id. */
            thread_id_t thread_id;
 
@@ -554,34 +558,35 @@ notmuch_database_add_message (notmuch_database_t *notmuch,
 
        g_ptr_array_free (thread_ids, TRUE);
 
-       free (message_id);
-
-       date = notmuch_message_file_get_header (message, "date");
+       date = notmuch_message_file_get_header (message_file, "date");
        time_value = notmuch_parse_date (date, NULL);
 
        doc.add_value (NOTMUCH_VALUE_DATE,
                       Xapian::sortable_serialise (time_value));
 
-       from = notmuch_message_file_get_header (message, "from");
-       subject = notmuch_message_file_get_header (message, "subject");
-       to = notmuch_message_file_get_header (message, "to");
+       from = notmuch_message_file_get_header (message_file, "from");
+       subject = notmuch_message_file_get_header (message_file, "subject");
+       to = notmuch_message_file_get_header (message_file, "to");
 
        if (from == NULL &&
            subject == NULL &&
            to == NULL)
        {
-           notmuch_message_file_close (message);
-           return NOTMUCH_STATUS_FILE_NOT_EMAIL;
+           ret = NOTMUCH_STATUS_FILE_NOT_EMAIL;
+           goto DONE;
        } else {
            db->add_document (doc);
        }
     } catch (const Xapian::Error &error) {
        fprintf (stderr, "A Xapian exception occurred: %s.\n",
                 error.get_msg().c_str());
-       return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
+       ret = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
+       goto DONE;
     }
 
-    notmuch_message_file_close (message);
+  DONE:
+    if (message_file)
+       notmuch_message_file_close (message_file);
 
-    return NOTMUCH_STATUS_SUCCESS;
+    return ret;
 }