[PATCH 6/6] WIP: support XDG database directory

Subject: [PATCH 6/6] WIP: support XDG database directory

Date: Sat, 12 Mar 2016 08:31:30 -0400

To: David Bremner, notmuch@notmuchmail.org

Cc:

From: David Bremner


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

diff --git a/lib/database.cc b/lib/database.cc
index 3b342f1..3d19bec 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -855,6 +855,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,
@@ -865,6 +882,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;
@@ -872,21 +890,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);
@@ -917,10 +943,14 @@ 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);
+    if (path) {
+	notmuch->path = talloc_strdup (notmuch, path);
 
-    if (notmuch->path[strlen (notmuch->path) - 1] == '/')
-	notmuch->path[strlen (notmuch->path) - 1] = '\0';
+	if (notmuch->path[strlen (notmuch->path) - 1] == '/')
+	    notmuch->path[strlen (notmuch->path) - 1] = '\0';
+    } else {
+	notmuch->path = NULL;
+    }
 
     notmuch->mode = mode;
     notmuch->atomic_nesting = 0;
@@ -1303,7 +1333,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 59a479c..8d4eaf5 100755
--- a/test/T560-lib-error.sh
+++ b/test/T560-lib-error.sh
@@ -21,7 +21,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 9c1e566..52b06bb 100755
--- a/test/T590-libconfig.sh
+++ b/test/T590-libconfig.sh
@@ -143,4 +143,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@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.7.0


Thread: