GPtrArray *parents, *thread_ids;
const char *refs, *in_reply_to, *date, *header;
+ const char *from, *to, *subject;
char *message_id;
time_t time_value;
message = notmuch_message_open (filename);
notmuch_message_restrict_headers (message,
- "references",
+ "date",
+ "from",
"in-reply-to",
"message-id",
- "date",
+ "references",
+ "subject",
(char *) NULL);
try {
doc.add_value (NOTMUCH_VALUE_DATE,
Xapian::sortable_serialise (time_value));
- db->add_document (doc);
+ from = notmuch_message_get_header (message, "from");
+ subject = notmuch_message_get_header (message, "subject");
+ to = notmuch_message_get_header (message, "to");
+
+ if (from == NULL &&
+ subject == NULL &&
+ to == NULL)
+ {
+ notmuch_message_close (message);
+ return NOTMUCH_STATUS_FILE_NOT_EMAIL;
+ } else {
+ db->add_document (doc);
+ }
} catch (const Xapian::Error &error) {
fprintf (stderr, "A Xapian exception occurred: %s.\n",
error.get_msg().c_str());
/* Header storage */
int restrict_headers;
GHashTable *headers;
+ int broken_headers;
+ int good_headers;
/* Parsing state */
char *line;
colon = strchr (message->line, ':');
if (colon == NULL) {
- fprintf (stderr, "Warning: Unexpected non-header line: %s\n",
- message->line);
+ message->broken_headers++;
+ /* A simple heuristic for giving up on things that just
+ * don't look like mail messages. */
+ if (message->broken_headers >= 10 &&
+ message->good_headers < 5)
+ {
+ message->parsing_finished = 1;
+ continue;
+ }
NEXT_HEADER_LINE (NULL);
continue;
}
+ message->good_headers++;
+
header = xstrndup (message->line, colon - message->line);
if (message->restrict_headers &&
int err;
char *next;
struct stat st;
+ notmuch_status_t status;
dir = opendir (path);
stat (next, &st);
if (S_ISREG (st.st_mode)) {
- notmuch_database_add_message (notmuch, next);
- state->count++;
+ status = notmuch_database_add_message (notmuch, next);
+ if (status == NOTMUCH_STATUS_FILE_NOT_EMAIL) {
+ fprintf (stderr, "Note: Ignoring non-mail file: %s\n",
+ next);
+ } else {
+ state->count++;
+ }
if (state->count % 1000 == 0)
add_files_print_progress (state);
} else if (S_ISDIR (st.st_mode)) {
printf ("Notmuch needs to know the top-level directory of your email archive,\n"
"(where you already have mail stored and where messages will be delivered\n"
"in the future). This directory can contain any number of sub-directories\n"
- "but the only files it contains should be individual email messages.\n"
- "Either maildir or mh format directories are fine, but you will want to\n"
- "move away any auxiliary files maintained by other email programs.\n\n");
+ "and primarily just files with indvidual email messages (eg. maildir or mh\n"
+ "archives are perfect). If there are other, non-email files (such as\n"
+ "indexes maintained by other email programs) then notmuch will do its\n"
+ "best to detect those and ignore them.\n\n");
printf ("Mail storage that uses mbox format, (where one mbox file contains many\n"
"messages), will not work with notmuch. If that's how your mail is currently\n"
* NOTMUCH_STATUS_SUCCESS: No error occurred.
*
* NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred
+ *
+ * NOTMUCH_STATUS_FILE_NOT_EMAIL: A file was presented that doesn't
+ * appear to be an email message.
*/
typedef enum _notmuch_status {
NOTMUCH_STATUS_SUCCESS = 0,
- NOTMUCH_STATUS_XAPIAN_EXCEPTION
+ NOTMUCH_STATUS_XAPIAN_EXCEPTION,
+ NOTMUCH_STATUS_FILE_NOT_EMAIL
} notmuch_status_t;
/* An opaque data structure representing a notmuch database. See
* single mail message (not a multi-message mbox) that is expected to
* remain at its current location, (since the notmuch database will
* reference the filename, and will not copy the entire contents of
- * the file. */
+ * the file.
+ *
+ * Return value:
+ *
+ * NOTMUCH_STATUS_SUCCESS: Message successfully added to database.
+ *
+ * NOTMUCH_STATUS_FILE_NOT_EMAIL: the contents of filename don't look
+ * like an email message. Nothing added to the database.
+ */
notmuch_status_t
notmuch_database_add_message (notmuch_database_t *database,
const char *filename);