[RFC PATCH 02/13] Add the concept of a mailstore in its absolute minimal sense

Ethan Glasser-Camp glasse at cs.rpi.edu
Wed Feb 15 14:01:55 PST 2012


From: Ethan Glasser-Camp <ethan at betacantrips.com>

This introduces (and uses) the mailstore parameter to the
notmuch_message_file_open API, and passes this through wherever it
will be needed. This requires touching a lot of places just to change
one API. We end up adding it to the notmuch_database_t struct because
it is needed for notmuch_database_upgrade.

This doesn't touch the Python bindings, which require a certain amount
of effort. (Therefore, the Python tests will be broken until the next commit.)

Signed-off-by: Ethan Glasser-Camp <ethan at betacantrips.com>
---
 lib/Makefile.local     |    1 +
 lib/database-private.h |    1 +
 lib/database.cc        |   10 +++++---
 lib/mailstore.c        |   59 ++++++++++++++++++++++++++++++++++++++++++++++++
 lib/message-file.c     |   10 +++++---
 lib/message.cc         |   11 +++++---
 lib/notmuch-private.h  |    7 ++++-
 lib/notmuch.h          |   21 ++++++++++++++--
 lib/thread.cc          |   24 +++++++++++--------
 notmuch-client.h       |    6 +++++
 notmuch-config.c       |   12 +++++++++
 notmuch-count.c        |    3 +-
 notmuch-dump.c         |    3 +-
 notmuch-new.c          |    8 +++++-
 notmuch-reply.c        |   45 ++++++++++++++++++++++++------------
 notmuch-restore.c      |    3 +-
 notmuch-search.c       |    3 +-
 notmuch-show.c         |   56 ++++++++++++++++++++++++++++++---------------
 notmuch-tag.c          |    3 +-
 test/symbol-test.cc    |    3 +-
 20 files changed, 220 insertions(+), 69 deletions(-)
 create mode 100644 lib/mailstore.c

diff --git a/lib/Makefile.local b/lib/Makefile.local
index 54c4dea..461e5cd 100644
--- a/lib/Makefile.local
+++ b/lib/Makefile.local
@@ -51,6 +51,7 @@ libnotmuch_c_srcs =		\
 	$(dir)/filenames.c	\
 	$(dir)/string-list.c	\
 	$(dir)/libsha1.c	\
+	$(dir)/mailstore.c	\
 	$(dir)/message-file.c	\
 	$(dir)/messages.c	\
 	$(dir)/sha1.c		\
diff --git a/lib/database-private.h b/lib/database-private.h
index 88532d5..1cb8c43 100644
--- a/lib/database-private.h
+++ b/lib/database-private.h
@@ -39,6 +39,7 @@
 struct _notmuch_database {
     notmuch_bool_t exception_reported;
 
+    notmuch_mailstore_t *mailstore;
     char *path;
 
     notmuch_bool_t needs_upgrade;
diff --git a/lib/database.cc b/lib/database.cc
index c928d02..e3c8095 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -521,7 +521,7 @@ parse_references (void *ctx,
 }
 
 notmuch_database_t *
-notmuch_database_create (const char *path)
+notmuch_database_create (notmuch_mailstore_t *mailstore, const char *path)
 {
     notmuch_database_t *notmuch = NULL;
     char *notmuch_path = NULL;
@@ -556,7 +556,7 @@ notmuch_database_create (const char *path)
 	goto DONE;
     }
 
-    notmuch = notmuch_database_open (path,
+    notmuch = notmuch_database_open (mailstore, path,
 				     NOTMUCH_DATABASE_MODE_READ_WRITE);
     notmuch_database_upgrade (notmuch, NULL, NULL);
 
@@ -579,7 +579,8 @@ _notmuch_database_ensure_writable (notmuch_database_t *notmuch)
 }
 
 notmuch_database_t *
-notmuch_database_open (const char *path,
+notmuch_database_open (notmuch_mailstore_t *mailstore,
+		       const char *path,
 		       notmuch_database_mode_t mode)
 {
     void *local = talloc_new (NULL);
@@ -619,6 +620,7 @@ notmuch_database_open (const char *path,
     notmuch = talloc_zero (NULL, notmuch_database_t);
     notmuch->exception_reported = FALSE;
     notmuch->path = talloc_strdup (notmuch, path);
+    notmuch->mailstore = mailstore;
 
     if (notmuch->path[strlen (notmuch->path) - 1] == '/')
 	notmuch->path[strlen (notmuch->path) - 1] = '\0';
@@ -1636,7 +1638,7 @@ notmuch_database_add_message (notmuch_database_t *notmuch,
     if (ret)
 	return ret;
 
-    message_file = notmuch_message_file_open (filename);
+    message_file = notmuch_message_file_open (notmuch->mailstore, filename);
     if (message_file == NULL)
 	return NOTMUCH_STATUS_FILE_ERROR;
 
diff --git a/lib/mailstore.c b/lib/mailstore.c
new file mode 100644
index 0000000..290da70
--- /dev/null
+++ b/lib/mailstore.c
@@ -0,0 +1,59 @@
+/* mailstore.c - mail storage backends
+ *
+ * Copyright © 2009 Carl Worth
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see http://www.gnu.org/licenses/ .
+ */
+
+#include <stdio.h>
+
+#include "notmuch-private.h"
+
+typedef struct _notmuch_mailstore {
+    FILE *(*open) (struct _notmuch_mailstore *mailstore, const char *filename);
+} _notmuch_mailstore;
+
+static FILE *
+_maildir_open_function (unused (notmuch_mailstore_t *mailstore),
+			const char *filename)
+{
+    return fopen (filename, "r");
+}
+
+/* A mailstore is defined as:
+ *
+ * - A function used to "open" a mail message. This takes the
+ *   "filename" for the file and should return a FILE *.
+ *
+ * - TODO: A way to scan for new messages?
+ *
+ * - TODO: A "constructor"?
+ */
+_notmuch_mailstore
+notmuch_mailstore_maildir = { _maildir_open_function };
+
+_notmuch_mailstore *
+notmuch_mailstore_get_by_name (const char *name)
+{
+    if (strcmp (name, "maildir") == 0)
+	return &notmuch_mailstore_maildir;
+
+    return NULL;
+}
+
+FILE *
+notmuch_mailstore_open (notmuch_mailstore_t *mailstore, const char *filename)
+{
+    return mailstore->open (mailstore, filename);
+}
diff --git a/lib/message-file.c b/lib/message-file.c
index 915aba8..61f4d04 100644
--- a/lib/message-file.c
+++ b/lib/message-file.c
@@ -94,7 +94,8 @@ _notmuch_message_file_destructor (notmuch_message_file_t *message)
 /* Create a new notmuch_message_file_t for 'filename' with 'ctx' as
  * the talloc owner. */
 notmuch_message_file_t *
-_notmuch_message_file_open_ctx (void *ctx, const char *filename)
+_notmuch_message_file_open_ctx (void *ctx, notmuch_mailstore_t *mailstore,
+				const char *filename)
 {
     notmuch_message_file_t *message;
 
@@ -104,7 +105,7 @@ _notmuch_message_file_open_ctx (void *ctx, const char *filename)
 
     talloc_set_destructor (message, _notmuch_message_file_destructor);
 
-    message->file = fopen (filename, "r");
+    message->file = notmuch_mailstore_open (mailstore, filename);
     if (message->file == NULL)
 	goto FAIL;
 
@@ -126,9 +127,10 @@ _notmuch_message_file_open_ctx (void *ctx, const char *filename)
 }
 
 notmuch_message_file_t *
-notmuch_message_file_open (const char *filename)
+notmuch_message_file_open (notmuch_mailstore_t *mailstore,
+			   const char *filename)
 {
-    return _notmuch_message_file_open_ctx (NULL, filename);
+    return _notmuch_message_file_open_ctx (NULL, mailstore, filename);
 }
 
 void
diff --git a/lib/message.cc b/lib/message.cc
index 0075425..762a18f 100644
--- a/lib/message.cc
+++ b/lib/message.cc
@@ -395,7 +395,8 @@ notmuch_message_get_message_id (notmuch_message_t *message)
 }
 
 static void
-_notmuch_message_ensure_message_file (notmuch_message_t *message)
+_notmuch_message_ensure_message_file (notmuch_mailstore_t *mailstore,
+				      notmuch_message_t *message)
 {
     const char *filename;
 
@@ -406,11 +407,13 @@ _notmuch_message_ensure_message_file (notmuch_message_t *message)
     if (unlikely (filename == NULL))
 	return;
 
-    message->message_file = _notmuch_message_file_open_ctx (message, filename);
+    message->message_file = _notmuch_message_file_open_ctx (message, mailstore,
+							    filename);
 }
 
 const char *
-notmuch_message_get_header (notmuch_message_t *message, const char *header)
+notmuch_message_get_header (notmuch_mailstore_t *mailstore,
+			    notmuch_message_t *message, const char *header)
 {
     std::string value;
 
@@ -427,7 +430,7 @@ notmuch_message_get_header (notmuch_message_t *message, const char *header)
 	return talloc_strdup (message, value.c_str ());
 
     /* Otherwise fall back to parsing the file */
-    _notmuch_message_ensure_message_file (message);
+    _notmuch_message_ensure_message_file (mailstore, message);
     if (message->message_file == NULL)
 	return NULL;
 
diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
index 7bf153e..0f01437 100644
--- a/lib/notmuch-private.h
+++ b/lib/notmuch-private.h
@@ -331,11 +331,14 @@ typedef struct _notmuch_message_file notmuch_message_file_t;
  * Returns NULL if any error occurs.
  */
 notmuch_message_file_t *
-notmuch_message_file_open (const char *filename);
+notmuch_message_file_open (notmuch_mailstore_t *mailstore,
+			   const char *filename);
 
 /* Like notmuch_message_file_open but with 'ctx' as the talloc owner. */
 notmuch_message_file_t *
-_notmuch_message_file_open_ctx (void *ctx, const char *filename);
+_notmuch_message_file_open_ctx (void *ctx,
+				notmuch_mailstore_t *mailstore,
+				const char *filename);
 
 /* Close a notmuch message previously opened with notmuch_message_open. */
 void
diff --git a/lib/notmuch.h b/lib/notmuch.h
index 7929fe7..7ebe034 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -123,6 +123,7 @@ typedef struct _notmuch_message notmuch_message_t;
 typedef struct _notmuch_tags notmuch_tags_t;
 typedef struct _notmuch_directory notmuch_directory_t;
 typedef struct _notmuch_filenames notmuch_filenames_t;
+typedef struct _notmuch_mailstore notmuch_mailstore_t;
 
 /* Create a new, empty notmuch database located at 'path'.
  *
@@ -144,7 +145,7 @@ typedef struct _notmuch_filenames notmuch_filenames_t;
  * an error message on stderr).
  */
 notmuch_database_t *
-notmuch_database_create (const char *path);
+notmuch_database_create (notmuch_mailstore_t *mailstore, const char *path);
 
 typedef enum {
     NOTMUCH_DATABASE_MODE_READ_ONLY = 0,
@@ -172,7 +173,8 @@ typedef enum {
  * an error message on stderr).
  */
 notmuch_database_t *
-notmuch_database_open (const char *path,
+notmuch_database_open (notmuch_mailstore_t *mailstore,
+		       const char *path,
 		       notmuch_database_mode_t mode);
 
 /* Close the given notmuch database, freeing all associated
@@ -409,6 +411,18 @@ notmuch_database_find_message_by_filename (notmuch_database_t *notmuch,
 notmuch_tags_t *
 notmuch_database_get_all_tags (notmuch_database_t *db);
 
+/* Return a mail storage backend based on the given name.
+ *
+ * Storage backends are required in order to manipulate message files.
+ */
+notmuch_mailstore_t *
+notmuch_mailstore_get_by_name (const char *name);
+
+/* Get an input stream for a filename.
+ */
+FILE *
+notmuch_mailstore_open (notmuch_mailstore_t *mailstore, const char *filename);
+
 /* Create a new query for 'database'.
  *
  * Here, 'database' should be an open database, (see
@@ -929,7 +943,8 @@ notmuch_message_get_date  (notmuch_message_t *message);
  * header line matching 'header'. Returns NULL if any error occurs.
  */
 const char *
-notmuch_message_get_header (notmuch_message_t *message, const char *header);
+notmuch_message_get_header (notmuch_mailstore_t *mailstore,
+			    notmuch_message_t *message, const char *header);
 
 /* Get the tags for 'message', returning a notmuch_tags_t object which
  * can be used to iterate over all tags.
diff --git a/lib/thread.cc b/lib/thread.cc
index 0435ee6..73edf83 100644
--- a/lib/thread.cc
+++ b/lib/thread.cc
@@ -213,7 +213,8 @@ _thread_cleanup_author (notmuch_thread_t *thread,
  * reference to it.
  */
 static void
-_thread_add_message (notmuch_thread_t *thread,
+_thread_add_message (notmuch_mailstore_t *mailstore,
+		     notmuch_thread_t *thread,
 		     notmuch_message_t *message)
 {
     notmuch_tags_t *tags;
@@ -231,7 +232,7 @@ _thread_add_message (notmuch_thread_t *thread,
 			 xstrdup (notmuch_message_get_message_id (message)),
 			 message);
 
-    from = notmuch_message_get_header (message, "from");
+    from = notmuch_message_get_header (mailstore, message, "from");
     if (from)
 	list = internet_address_list_parse_string (from);
 
@@ -253,7 +254,7 @@ _thread_add_message (notmuch_thread_t *thread,
 
     if (! thread->subject) {
 	const char *subject;
-	subject = notmuch_message_get_header (message, "subject");
+	subject = notmuch_message_get_header (mailstore, message, "subject");
 	thread->subject = talloc_strdup (thread, subject ? subject : "");
     }
 
@@ -267,13 +268,14 @@ _thread_add_message (notmuch_thread_t *thread,
 }
 
 static void
-_thread_set_subject_from_message (notmuch_thread_t *thread,
+_thread_set_subject_from_message (notmuch_mailstore_t *mailstore,
+				  notmuch_thread_t *thread,
 				  notmuch_message_t *message)
 {
     const char *subject;
     const char *cleaned_subject;
 
-    subject = notmuch_message_get_header (message, "subject");
+    subject = notmuch_message_get_header (mailstore, message, "subject");
     if (! subject)
 	return;
 
@@ -300,7 +302,8 @@ _thread_set_subject_from_message (notmuch_thread_t *thread,
  * oldest or newest matching subject is applied to the thread as a
  * whole. */
 static void
-_thread_add_matched_message (notmuch_thread_t *thread,
+_thread_add_matched_message (notmuch_mailstore_t *mailstore,
+			     notmuch_thread_t *thread,
 			     notmuch_message_t *message,
 			     notmuch_sort_t sort)
 {
@@ -312,13 +315,13 @@ _thread_add_matched_message (notmuch_thread_t *thread,
     if (date < thread->oldest || ! thread->matched_messages) {
 	thread->oldest = date;
 	if (sort == NOTMUCH_SORT_OLDEST_FIRST)
-	    _thread_set_subject_from_message (thread, message);
+	    _thread_set_subject_from_message (mailstore, thread, message);
     }
 
     if (date > thread->newest || ! thread->matched_messages) {
 	thread->newest = date;
 	if (sort != NOTMUCH_SORT_OLDEST_FIRST)
-	    _thread_set_subject_from_message (thread, message);
+	    _thread_set_subject_from_message (mailstore, thread, message);
     }
 
     thread->matched_messages++;
@@ -467,11 +470,12 @@ _notmuch_thread_create (void *ctx,
 	if (doc_id == seed_doc_id)
 	    message = seed_message;
 
-	_thread_add_message (thread, message);
+	_thread_add_message (notmuch->mailstore, thread, message);
 
 	if ( _notmuch_doc_id_set_contains (match_set, doc_id)) {
 	    _notmuch_doc_id_set_remove (match_set, doc_id);
-	    _thread_add_matched_message (thread, message, sort);
+	    _thread_add_matched_message (notmuch->mailstore, thread,
+					 message, sort);
 	}
 
 	_notmuch_message_close (message);
diff --git a/notmuch-client.h b/notmuch-client.h
index 4518cb0..c1c30a2 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -68,14 +68,17 @@ struct notmuch_show_params;
 typedef struct notmuch_show_format {
     const char *message_set_start;
     void (*part) (const void *ctx,
+		  notmuch_mailstore_t *mailstore,
 		  struct mime_node *node, int indent,
 		  const struct notmuch_show_params *params);
     const char *message_start;
     void (*message) (const void *ctx,
+		     notmuch_mailstore_t *mailstore,
 		     notmuch_message_t *message,
 		     int indent);
     const char *header_start;
     void (*header) (const void *ctx,
+		    notmuch_mailstore_t *mailstore,
 		    notmuch_message_t *message);
     void (*header_message_part) (GMimeMessage *message);
     const char *header_end;
@@ -226,6 +229,9 @@ void
 notmuch_config_set_database_type (notmuch_config_t *config,
 				  const char *database_type);
 
+notmuch_mailstore_t *
+notmuch_config_get_mailstore (notmuch_config_t *config);
+
 const char *
 notmuch_config_get_user_name (notmuch_config_t *config);
 
diff --git a/notmuch-config.c b/notmuch-config.c
index b8bee69..f611b26 100644
--- a/notmuch-config.c
+++ b/notmuch-config.c
@@ -584,6 +584,18 @@ notmuch_config_set_database_type (notmuch_config_t *config,
     config->database_type = NULL;
 }
 
+notmuch_mailstore_t *
+notmuch_config_get_mailstore (notmuch_config_t *config)
+{
+    /* This is just a stub since there's only one mailstore.
+     *
+     * When there are multiple mailstore types and "constructors" for
+     * them, this may have to be much more complicated.
+     */
+    const char *type = notmuch_config_get_database_type (config);
+    return notmuch_mailstore_get_by_name (type);
+}
+
 const char *
 notmuch_config_get_user_name (notmuch_config_t *config)
 {
diff --git a/notmuch-count.c b/notmuch-count.c
index 63459fb..0c7beef 100644
--- a/notmuch-count.c
+++ b/notmuch-count.c
@@ -57,7 +57,8 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
     if (config == NULL)
 	return 1;
 
-    notmuch = notmuch_database_open (notmuch_config_get_database_path (config),
+    notmuch = notmuch_database_open (notmuch_config_get_mailstore (config),
+				     notmuch_config_get_database_path (config),
 				     NOTMUCH_DATABASE_MODE_READ_ONLY);
     if (notmuch == NULL)
 	return 1;
diff --git a/notmuch-dump.c b/notmuch-dump.c
index a735875..f7729dd 100644
--- a/notmuch-dump.c
+++ b/notmuch-dump.c
@@ -36,7 +36,8 @@ notmuch_dump_command (unused (void *ctx), int argc, char *argv[])
     if (config == NULL)
 	return 1;
 
-    notmuch = notmuch_database_open (notmuch_config_get_database_path (config),
+    notmuch = notmuch_database_open (notmuch_config_get_mailstore (config),
+				     notmuch_config_get_database_path (config),
 				     NOTMUCH_DATABASE_MODE_READ_ONLY);
     if (notmuch == NULL)
 	return 1;
diff --git a/notmuch-new.c b/notmuch-new.c
index 8dbebb3..355dde4 100644
--- a/notmuch-new.c
+++ b/notmuch-new.c
@@ -808,6 +808,7 @@ notmuch_new_command (void *ctx, int argc, char *argv[])
 {
     notmuch_config_t *config;
     notmuch_database_t *notmuch;
+    notmuch_mailstore_t *mailstore;
     add_files_state_t add_files_state;
     double elapsed;
     struct timeval tv_now, tv_start;
@@ -843,6 +844,7 @@ notmuch_new_command (void *ctx, int argc, char *argv[])
     add_files_state.new_tags = notmuch_config_get_new_tags (config, &add_files_state.new_tags_length);
     add_files_state.synchronize_flags = notmuch_config_get_maildir_synchronize_flags (config);
     db_path = notmuch_config_get_database_path (config);
+    mailstore = notmuch_config_get_mailstore (config);
 
     if (run_hooks) {
 	ret = notmuch_run_hook (db_path, "pre-new");
@@ -861,10 +863,12 @@ notmuch_new_command (void *ctx, int argc, char *argv[])
 	    return 1;
 
 	printf ("Found %d total files (that's not much mail).\n", count);
-	notmuch = notmuch_database_create (db_path);
+	notmuch = notmuch_database_create (mailstore,
+					   db_path);
 	add_files_state.total_files = count;
     } else {
-	notmuch = notmuch_database_open (db_path,
+	notmuch = notmuch_database_open (mailstore,
+					 db_path,
 					 NOTMUCH_DATABASE_MODE_READ_WRITE);
 	if (notmuch == NULL)
 	    return 1;
diff --git a/notmuch-reply.c b/notmuch-reply.c
index 6b244e6..cb1dd6e 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -256,14 +256,15 @@ scan_address_string (const char *recipients,
  * in either the 'To' or 'Cc' header of the message?
  */
 static int
-reply_to_header_is_redundant (notmuch_message_t *message)
+reply_to_header_is_redundant (notmuch_mailstore_t *mailstore,
+			      notmuch_message_t *message)
 {
     const char *reply_to, *to, *cc, *addr;
     InternetAddressList *list;
     InternetAddress *address;
     InternetAddressMailbox *mailbox;
 
-    reply_to = notmuch_message_get_header (message, "reply-to");
+    reply_to = notmuch_message_get_header (mailstore, message, "reply-to");
     if (reply_to == NULL || *reply_to == '\0')
 	return 0;
 
@@ -279,8 +280,8 @@ reply_to_header_is_redundant (notmuch_message_t *message)
     mailbox = INTERNET_ADDRESS_MAILBOX (address);
     addr = internet_address_mailbox_get_addr (mailbox);
 
-    to = notmuch_message_get_header (message, "to");
-    cc = notmuch_message_get_header (message, "cc");
+    to = notmuch_message_get_header (mailstore, message, "to");
+    cc = notmuch_message_get_header (mailstore, message, "cc");
 
     if ((to && strstr (to, addr) != 0) ||
 	(cc && strstr (cc, addr) != 0))
@@ -319,10 +320,13 @@ add_recipients_from_message (GMimeMessage *reply,
 	{ "cc",         NULL, GMIME_RECIPIENT_TYPE_CC  },
 	{ "bcc",        NULL, GMIME_RECIPIENT_TYPE_BCC }
     };
+    notmuch_mailstore_t *mailstore;
     const char *from_addr = NULL;
     unsigned int i;
     unsigned int n = 0;
 
+    mailstore = notmuch_config_get_mailstore (config);
+
     /* Some mailing lists munge the Reply-To header despite it being A Bad
      * Thing, see http://www.unicom.com/pw/reply-to-harmful.html
      *
@@ -334,7 +338,7 @@ add_recipients_from_message (GMimeMessage *reply,
      * that the address in the Reply-To header will always appear in
      * the reply.
      */
-    if (reply_to_header_is_redundant (message)) {
+    if (reply_to_header_is_redundant (mailstore, message)) {
 	reply_to_map[0].header = "from";
 	reply_to_map[0].fallback = NULL;
     }
@@ -342,10 +346,10 @@ add_recipients_from_message (GMimeMessage *reply,
     for (i = 0; i < ARRAY_SIZE (reply_to_map); i++) {
 	const char *recipients;
 
-	recipients = notmuch_message_get_header (message,
+	recipients = notmuch_message_get_header (mailstore, message,
 						 reply_to_map[i].header);
 	if ((recipients == NULL || recipients[0] == '\0') && reply_to_map[i].fallback)
-	    recipients = notmuch_message_get_header (message,
+	    recipients = notmuch_message_get_header (mailstore, message,
 						     reply_to_map[i].fallback);
 
 	n += scan_address_string (recipients, config, reply,
@@ -374,6 +378,7 @@ add_recipients_from_message (GMimeMessage *reply,
 static const char *
 guess_from_received_header (notmuch_config_t *config, notmuch_message_t *message)
 {
+    notmuch_mailstore_t *mailstore;
     const char *received,*primary,*by;
     const char **other;
     char *tohdr;
@@ -387,6 +392,7 @@ guess_from_received_header (notmuch_config_t *config, notmuch_message_t *message
 
     primary = notmuch_config_get_user_primary_email (config);
     other = notmuch_config_get_user_other_email (config, &other_len);
+    mailstore = notmuch_config_get_mailstore (config);
 
     /* sadly, there is no standard way to find out to which email
      * address a mail was delivered - what is in the headers depends
@@ -403,7 +409,8 @@ guess_from_received_header (notmuch_config_t *config, notmuch_message_t *message
      * If none of these work, we give up and return NULL
      */
     for (i = 0; i < sizeof(to_headers)/sizeof(*to_headers); i++) {
-	tohdr = xstrdup(notmuch_message_get_header (message, to_headers[i]));
+	tohdr = xstrdup(notmuch_message_get_header (mailstore,
+						    message, to_headers[i]));
 	if (tohdr && *tohdr) {
 	    /* tohdr is potentialy a list of email addresses, so here we
 	     * check if one of the email addresses is a substring of tohdr
@@ -428,7 +435,7 @@ guess_from_received_header (notmuch_config_t *config, notmuch_message_t *message
      * The Received: header is special in our get_header function
      * and is always concatenated.
      */
-    received = notmuch_message_get_header (message, "received");
+    received = notmuch_message_get_header (mailstore, message, "received");
     if (received == NULL)
 	return NULL;
 
@@ -515,10 +522,12 @@ notmuch_reply_format_default(void *ctx,
     GMimeMessage *reply;
     notmuch_messages_t *messages;
     notmuch_message_t *message;
+    notmuch_mailstore_t *mailstore;
     const char *subject, *from_addr = NULL;
     const char *in_reply_to, *orig_references, *references;
     const notmuch_show_format_t *format = &format_reply;
 
+    mailstore = notmuch_config_get_mailstore (config);
     for (messages = notmuch_query_search_messages (query);
 	 notmuch_messages_valid (messages);
 	 notmuch_messages_move_to_next (messages))
@@ -532,7 +541,7 @@ notmuch_reply_format_default(void *ctx,
 	    return 1;
 	}
 
-	subject = notmuch_message_get_header (message, "subject");
+	subject = notmuch_message_get_header (mailstore, message, "subject");
 	if (subject) {
 	    if (strncasecmp (subject, "Re:", 3))
 		subject = talloc_asprintf (ctx, "Re: %s", subject);
@@ -560,7 +569,8 @@ notmuch_reply_format_default(void *ctx,
 	g_mime_object_set_header (GMIME_OBJECT (reply),
 				  "In-Reply-To", in_reply_to);
 
-	orig_references = notmuch_message_get_header (message, "references");
+	orig_references = notmuch_message_get_header (mailstore,
+						      message, "references");
 	references = talloc_asprintf (ctx, "%s%s%s",
 				      orig_references ? orig_references : "",
 				      orig_references ? " " : "",
@@ -574,8 +584,8 @@ notmuch_reply_format_default(void *ctx,
 	reply = NULL;
 
 	printf ("On %s, %s wrote:\n",
-		notmuch_message_get_header (message, "date"),
-		notmuch_message_get_header (message, "from"));
+		notmuch_message_get_header (mailstore, message, "date"),
+		notmuch_message_get_header (mailstore, message, "from"));
 
 	show_message_body (message, format, params);
 
@@ -595,9 +605,12 @@ notmuch_reply_format_headers_only(void *ctx,
     GMimeMessage *reply;
     notmuch_messages_t *messages;
     notmuch_message_t *message;
+    notmuch_mailstore_t *mailstore;
     const char *in_reply_to, *orig_references, *references;
     char *reply_headers;
 
+    mailstore = notmuch_config_get_mailstore (config);
+
     for (messages = notmuch_query_search_messages (query);
 	 notmuch_messages_valid (messages);
 	 notmuch_messages_move_to_next (messages))
@@ -618,7 +631,8 @@ notmuch_reply_format_headers_only(void *ctx,
 				  "In-Reply-To", in_reply_to);
 
 
-	orig_references = notmuch_message_get_header (message, "references");
+	orig_references = notmuch_message_get_header (mailstore, message,
+						      "references");
 
 	/* We print In-Reply-To followed by References because git format-patch treats them
          * specially.  Git does not interpret the other headers specially
@@ -720,7 +734,8 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
 	return 1;
     }
 
-    notmuch = notmuch_database_open (notmuch_config_get_database_path (config),
+    notmuch = notmuch_database_open (notmuch_config_get_mailstore (config),
+				     notmuch_config_get_database_path (config),
 				     NOTMUCH_DATABASE_MODE_READ_ONLY);
     if (notmuch == NULL)
 	return 1;
diff --git a/notmuch-restore.c b/notmuch-restore.c
index 87d9772..b382b7b 100644
--- a/notmuch-restore.c
+++ b/notmuch-restore.c
@@ -40,7 +40,8 @@ notmuch_restore_command (unused (void *ctx), int argc, char *argv[])
     if (config == NULL)
 	return 1;
 
-    notmuch = notmuch_database_open (notmuch_config_get_database_path (config),
+    notmuch = notmuch_database_open (notmuch_config_get_mailstore (config),
+				     notmuch_config_get_database_path (config),
 				     NOTMUCH_DATABASE_MODE_READ_WRITE);
     if (notmuch == NULL)
 	return 1;
diff --git a/notmuch-search.c b/notmuch-search.c
index d504051..8ba3c48 100644
--- a/notmuch-search.c
+++ b/notmuch-search.c
@@ -470,7 +470,8 @@ notmuch_search_command (void *ctx, int argc, char *argv[])
     if (config == NULL)
 	return 1;
 
-    notmuch = notmuch_database_open (notmuch_config_get_database_path (config),
+    notmuch = notmuch_database_open (notmuch_config_get_mailstore (config),
+				     notmuch_config_get_database_path (config),
 				     NOTMUCH_DATABASE_MODE_READ_ONLY);
     if (notmuch == NULL)
 	return 1;
diff --git a/notmuch-show.c b/notmuch-show.c
index d930f94..81d4cf0 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -24,7 +24,8 @@ static void
 format_headers_message_part_text (GMimeMessage *message);
 
 static void
-format_part_text (const void *ctx, mime_node_t *node,
+format_part_text (const void *ctx, notmuch_mailstore_t *mailstore,
+		  mime_node_t *node,
 		  int indent, const notmuch_show_params_t *params);
 
 static const notmuch_show_format_t format_text = {
@@ -36,10 +37,12 @@ static const notmuch_show_format_t format_text = {
 
 static void
 format_message_json (const void *ctx,
+		     notmuch_mailstore_t *mailstore,
 		     notmuch_message_t *message,
 		     unused (int indent));
 static void
 format_headers_json (const void *ctx,
+		     notmuch_mailstore_t *mailstore,
 		     notmuch_message_t *message);
 
 static void
@@ -83,6 +86,7 @@ static const notmuch_show_format_t format_json = {
 
 static void
 format_message_mbox (const void *ctx,
+		     notmuch_mailstore_t *mailstore,
 		     notmuch_message_t *message,
 		     unused (int indent));
 
@@ -149,14 +153,15 @@ _get_tags_as_string (const void *ctx, notmuch_message_t *message)
 
 /* Get a nice, single-line summary of message. */
 static const char *
-_get_one_line_summary (const void *ctx, notmuch_message_t *message)
+_get_one_line_summary (const void *ctx, notmuch_mailstore_t *mailstore,
+		       notmuch_message_t *message)
 {
     const char *from;
     time_t date;
     const char *relative_date;
     const char *tags;
 
-    from = notmuch_message_get_header (message, "from");
+    from = notmuch_message_get_header (mailstore, message, "from");
 
     date = notmuch_message_get_date (message);
     relative_date = notmuch_time_relative_date (ctx, date);
@@ -168,7 +173,8 @@ _get_one_line_summary (const void *ctx, notmuch_message_t *message)
 }
 
 static void
-format_message_json (const void *ctx, notmuch_message_t *message, unused (int indent))
+format_message_json (const void *ctx, unused (notmuch_mailstore_t *mailstore),
+		     notmuch_message_t *message, unused (int indent))
 {
     notmuch_tags_t *tags;
     int first = 1;
@@ -262,6 +268,7 @@ _is_from_line (const char *line)
  */
 static void
 format_message_mbox (const void *ctx,
+		     notmuch_mailstore_t *mailstore,
 		     notmuch_message_t *message,
 		     unused (int indent))
 {
@@ -285,7 +292,7 @@ format_message_mbox (const void *ctx,
 	return;
     }
 
-    from = notmuch_message_get_header (message, "from");
+    from = notmuch_message_get_header (mailstore, message, "from");
     from = _extract_email_address (ctx, from);
 
     date = notmuch_message_get_date (message);
@@ -327,7 +334,7 @@ format_headers_message_part_text (GMimeMessage *message)
 }
 
 static void
-format_headers_json (const void *ctx, notmuch_message_t *message)
+format_headers_json (const void *ctx, notmuch_mailstore_t *mailstore, notmuch_message_t *message)
 {
     const char *headers[] = {
 	"Subject", "From", "To", "Cc", "Bcc", "Date"
@@ -339,7 +346,7 @@ format_headers_json (const void *ctx, notmuch_message_t *message)
 
     for (i = 0; i < ARRAY_SIZE (headers); i++) {
 	name = headers[i];
-	value = notmuch_message_get_header (message, name);
+	value = notmuch_message_get_header (mailstore, message, name);
 	if (value)
 	{
 	    if (!first_header)
@@ -719,7 +726,8 @@ format_part_content_raw (GMimeObject *part)
 }
 
 static void
-format_part_text (const void *ctx, mime_node_t *node,
+format_part_text (const void *ctx, notmuch_mailstore_t *mailstore,
+		  mime_node_t *node,
 		  int indent, const notmuch_show_params_t *params)
 {
     /* The disposition and content-type metadata are associated with
@@ -768,7 +776,8 @@ format_part_text (const void *ctx, mime_node_t *node,
 
 	printf ("\fheader{\n");
 	if (node->envelope_file)
-	    printf ("%s\n", _get_one_line_summary (ctx, node->envelope_file));
+	    printf ("%s\n", _get_one_line_summary (ctx, mailstore,
+						   node->envelope_file));
 	printf ("Subject: %s\n", g_mime_message_get_subject (message));
 	printf ("From: %s\n", g_mime_message_get_sender (message));
 	recipients = g_mime_message_get_recipients (message, GMIME_RECIPIENT_TYPE_TO);
@@ -800,7 +809,8 @@ format_part_text (const void *ctx, mime_node_t *node,
     }
 
     for (i = 0; i < node->nchildren; i++)
-	format_part_text (ctx, mime_node_child (node, i), indent, params);
+	format_part_text (ctx, mailstore, mime_node_child (node, i),
+			  indent, params);
 
     if (GMIME_IS_MESSAGE (node->part))
 	printf ("\fbody}\n");
@@ -811,6 +821,7 @@ format_part_text (const void *ctx, mime_node_t *node,
 static void
 show_message (void *ctx,
 	      const notmuch_show_format_t *format,
+	      notmuch_mailstore_t *mailstore,
 	      notmuch_message_t *message,
 	      int indent,
 	      notmuch_show_params_t *params)
@@ -823,7 +834,7 @@ show_message (void *ctx,
 			    &root) == NOTMUCH_STATUS_SUCCESS &&
 	    (part = mime_node_seek_dfs (root, (params->part < 0 ?
 					       0 : params->part))))
-	    format->part (local, part, indent, params);
+	    format->part (local, mailstore, part, indent, params);
 	talloc_free (local);
 	return;
     }
@@ -831,11 +842,11 @@ show_message (void *ctx,
     if (params->part <= 0) {
 	fputs (format->message_start, stdout);
 	if (format->message)
-	    format->message(ctx, message, indent);
+	    format->message(ctx, mailstore, message, indent);
 
 	fputs (format->header_start, stdout);
 	if (format->header)
-	    format->header(ctx, message);
+	    format->header(ctx, mailstore, message);
 	fputs (format->header_end, stdout);
 
 	fputs (format->body_start, stdout);
@@ -854,6 +865,7 @@ show_message (void *ctx,
 static void
 show_messages (void *ctx,
 	       const notmuch_show_format_t *format,
+	       notmuch_mailstore_t *mailstore,
 	       notmuch_messages_t *messages,
 	       int indent,
 	       notmuch_show_params_t *params)
@@ -882,7 +894,7 @@ show_messages (void *ctx,
 	next_indent = indent;
 
 	if (match || params->entire_thread) {
-	    show_message (ctx, format, message, indent, params);
+	    show_message (ctx, format, mailstore, message, indent, params);
 	    next_indent = indent + 1;
 
 	    fputs (format->message_set_sep, stdout);
@@ -890,6 +902,7 @@ show_messages (void *ctx,
 
 	show_messages (ctx,
 		       format,
+		       mailstore,
 		       notmuch_message_get_replies (message),
 		       next_indent,
 		       params);
@@ -905,6 +918,7 @@ show_messages (void *ctx,
 /* Formatted output of single message */
 static int
 do_show_single (void *ctx,
+		notmuch_mailstore_t *mailstore,
 		notmuch_query_t *query,
 		const notmuch_show_format_t *format,
 		notmuch_show_params_t *params)
@@ -966,7 +980,7 @@ do_show_single (void *ctx,
 
     } else {
 
-	show_message (ctx, format, message, 0, params);
+	show_message (ctx, format, mailstore, message, 0, params);
 
     }
 
@@ -976,6 +990,7 @@ do_show_single (void *ctx,
 /* Formatted output of threads */
 static int
 do_show (void *ctx,
+	 notmuch_mailstore_t *mailstore,
 	 notmuch_query_t *query,
 	 const notmuch_show_format_t *format,
 	 notmuch_show_params_t *params)
@@ -1003,7 +1018,7 @@ do_show (void *ctx,
 	    fputs (format->message_set_sep, stdout);
 	first_toplevel = 0;
 
-	show_messages (ctx, format, messages, 0, params);
+	show_messages (ctx, format, mailstore, messages, 0, params);
 
 	notmuch_thread_destroy (thread);
 
@@ -1027,6 +1042,7 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[]))
 {
     notmuch_config_t *config;
     notmuch_database_t *notmuch;
+    notmuch_mailstore_t *mailstore;
     notmuch_query_t *query;
     char *query_string;
     int opt_index, ret;
@@ -1122,7 +1138,9 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[]))
 	return 1;
     }
 
-    notmuch = notmuch_database_open (notmuch_config_get_database_path (config),
+    mailstore = notmuch_config_get_mailstore (config);
+    notmuch = notmuch_database_open (mailstore,
+				     notmuch_config_get_database_path (config),
 				     NOTMUCH_DATABASE_MODE_READ_ONLY);
     if (notmuch == NULL)
 	return 1;
@@ -1134,9 +1152,9 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[]))
     }
 
     if (params.part >= 0)
-	ret = do_show_single (ctx, query, format, &params);
+	ret = do_show_single (ctx, mailstore, query, format, &params);
     else
-	ret = do_show (ctx, query, format, &params);
+	ret = do_show (ctx, mailstore, query, format, &params);
 
     notmuch_query_destroy (query);
     notmuch_database_close (notmuch);
diff --git a/notmuch-tag.c b/notmuch-tag.c
index 36b9b09..5e8d74a 100644
--- a/notmuch-tag.c
+++ b/notmuch-tag.c
@@ -187,7 +187,8 @@ notmuch_tag_command (void *ctx, int argc, char *argv[])
     if (config == NULL)
 	return 1;
 
-    notmuch = notmuch_database_open (notmuch_config_get_database_path (config),
+    notmuch = notmuch_database_open (notmuch_config_get_mailstore (config),
+				     notmuch_config_get_database_path (config),
 				     NOTMUCH_DATABASE_MODE_READ_WRITE);
     if (notmuch == NULL)
 	return 1;
diff --git a/test/symbol-test.cc b/test/symbol-test.cc
index 1548ca4..36c6ddb 100644
--- a/test/symbol-test.cc
+++ b/test/symbol-test.cc
@@ -4,7 +4,8 @@
 
 
 int main() {
-  (void) notmuch_database_open("fakedb", NOTMUCH_DATABASE_MODE_READ_ONLY);
+  (void) notmuch_database_open (notmuch_mailstore_get_by_name ("maildir"),
+                                "fakedb", NOTMUCH_DATABASE_MODE_READ_ONLY);
 
   try {
     (void) new Xapian::WritableDatabase("./nonexistant", Xapian::DB_OPEN);
-- 
1.7.5.4



More information about the notmuch mailing list