[PATCH] WIP: support XDG database directory

David Bremner david at tethera.net
Sat Dec 30 12:07:40 PST 2017


---

Just a rebase against current master, based on discussion in IRC
today.  AFAIK, the general approach could be extended to support a
"NOTMUCH_DATABASE_DIRECTORY" environment variable, which if think is
what Tomi was suggesting previously.

 lib/database.cc        | 65 ++++++++++++++++++++++++++++++++++++++++----------
 test/T560-lib-error.sh |  2 +-
 test/T590-libconfig.sh | 35 +++++++++++++++++++++++++++
 3 files changed, 89 insertions(+), 13 deletions(-)

diff --git a/lib/database.cc b/lib/database.cc
index 02444e09..521949cd 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -800,6 +800,23 @@ notmuch_database_open (const char *path,
     return status;
 }
 
+static char *
+_xdg_database_path (void *ctx) {
+
+    const char *data_dir = NULL;
+
+    data_dir = getenv ("XDG_DATA_HOME");
+
+    if (! data_dir) {
+	const char *home = getenv ("HOME");
+	if (! home)
+	    return NULL;
+
+	data_dir = talloc_asprintf (ctx, "%s/.local/share", home);
+    }
+    return talloc_asprintf (ctx, "%s/notmuch", data_dir);
+}
+
 notmuch_status_t
 notmuch_database_open_verbose (const char *path,
 			       notmuch_database_mode_t mode,
@@ -810,6 +827,7 @@ notmuch_database_open_verbose (const char *path,
     void *local = talloc_new (NULL);
     notmuch_database_t *notmuch = NULL;
     char *notmuch_path, *xapian_path, *incompat_features;
+    char *xdg_path = NULL;
     char *message = NULL;
     struct stat st;
     int err;
@@ -817,21 +835,29 @@ notmuch_database_open_verbose (const char *path,
     static int initialized = 0;
 
     if (path == NULL) {
-	message = strdup ("Error: Cannot open a database for a NULL path.\n");
-	status = NOTMUCH_STATUS_NULL_POINTER;
-	goto DONE;
+	xdg_path = _xdg_database_path (local);
+	if (! xdg_path) {
+	    message = strdup ("Error: NULL path, and cannot compute XDG_DATA_HOME.\n");
+	    status = NOTMUCH_STATUS_NULL_POINTER;
+	    goto DONE;
+	}
     }
 
-    if (path[0] != '/') {
+    if (path && path[0] != '/') {
 	message = strdup ("Error: Database path must be absolute.\n");
 	status = NOTMUCH_STATUS_PATH_ERROR;
 	goto DONE;
     }
 
-    if (! (notmuch_path = talloc_asprintf (local, "%s/%s", path, ".notmuch"))) {
-	message = strdup ("Out of memory\n");
-	status = NOTMUCH_STATUS_OUT_OF_MEMORY;
-	goto DONE;
+    if (xdg_path) {
+	notmuch_path = xdg_path;
+    } else {
+	notmuch_path = talloc_asprintf (local, "%s/%s", path, ".notmuch");
+	if (! (notmuch_path)) {
+	    message = strdup ("Out of memory\n");
+	    status = NOTMUCH_STATUS_OUT_OF_MEMORY;
+	    goto DONE;
+	}
     }
 
     err = stat (notmuch_path, &st);
@@ -862,9 +888,12 @@ notmuch_database_open_verbose (const char *path,
     notmuch = talloc_zero (NULL, notmuch_database_t);
     notmuch->exception_reported = false;
     notmuch->status_string = NULL;
-    notmuch->path = talloc_strdup (notmuch, path);
-
-    strip_trailing(notmuch->path, '/');
+    if (path) {
+	notmuch->path = talloc_strdup (notmuch, path);
+        strip_trailing(notmuch->path, '/');
+    } else {
+	notmuch->path = NULL;
+    }
 
     notmuch->mode = mode;
     notmuch->atomic_nesting = 0;
@@ -1254,7 +1283,19 @@ notmuch_database_destroy (notmuch_database_t *notmuch)
 const char *
 notmuch_database_get_path (notmuch_database_t *notmuch)
 {
-    return notmuch->path;
+    char *path = NULL;
+    notmuch_status_t status;
+
+    if (notmuch->path)
+	return notmuch->path;
+
+    status = notmuch_database_get_config (notmuch, "maildir_root", &path);
+    if (status) {
+	_notmuch_database_log (notmuch, "unable to find maildir_root\n");
+	return NULL;
+    }
+
+    return path;
 }
 
 unsigned int
diff --git a/test/T560-lib-error.sh b/test/T560-lib-error.sh
index 06a6b860..115a0a35 100755
--- a/test/T560-lib-error.sh
+++ b/test/T560-lib-error.sh
@@ -22,7 +22,7 @@ EOF
 cat <<'EOF' >EXPECTED
 == stdout ==
 == stderr ==
-Error: Cannot open a database for a NULL path.
+Error opening database at CWD/home/.local/share/notmuch: No such file or directory
 EOF
 test_expect_equal_file EXPECTED OUTPUT
 
diff --git a/test/T590-libconfig.sh b/test/T590-libconfig.sh
index 46f3a76d..eaaec43f 100755
--- a/test/T590-libconfig.sh
+++ b/test/T590-libconfig.sh
@@ -132,4 +132,39 @@ notmuch restore --include=config <EXPECTED
 notmuch dump --include=config >OUTPUT
 test_expect_equal_file EXPECTED OUTPUT
 
+XDG_DIR=$HOME/.local/share/notmuch
+test_begin_subtest "Split database and maildir"
+xapian-metadata set ${MAIL_DIR}/.notmuch/xapian Cmaildir_root ${MAIL_DIR}
+mkdir -p $XDG_DIR
+mv ${MAIL_DIR}/.notmuch/xapian $XDG_DIR
+test_C <<EOF >OUTPUT
+#include <stdio.h>
+#include <notmuch.h>
+
+int main (int argc, char** argv)
+{
+   notmuch_database_t *db;
+   char *val;
+   notmuch_status_t stat;
+   notmuch_message_t *message;
+
+   stat=notmuch_database_open (NULL, NOTMUCH_DATABASE_MODE_READ_WRITE, &db);
+   printf("database_open status = %d\n", stat);
+   stat = notmuch_database_find_message (db, "87ocn0qh6d.fsf at yoom.home.cworth.org", &message);
+   printf("find_message status = %d\n", stat);
+   printf("found message = %d\n", message != NULL);
+   printf("filename = %s\n",notmuch_message_get_filename (message));
+}
+EOF
+
+cat <<EOF >EXPECTED
+== stdout ==
+database_open status = 0
+find_message status = 0
+found message = 1
+filename = MAIL_DIR/cur/41:2,
+== stderr ==
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
 test_done
-- 
2.15.1



More information about the notmuch mailing list