[PATCH v3] config: Expand ~ to $HOME

Subject: [PATCH v3] config: Expand ~ to $HOME

Date: Sat, 14 May 2016 17:15:49 +0200

To: notmuch@notmuchmail.org

Cc:

From: Bijan Chokoufe Nejad


Very useful in case you want to keep your .notmuch-config synchronized across
machines where you have different user names.

---
v2: Check for '~/' instead of checking for '~' and fix memory issue.
    Unit test is still pending
v3: Extended implementation handling also '~foo/' and '~foo'
---
 notmuch-config.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/notmuch-config.c b/notmuch-config.c
index 01bb185..25668a6 100644
--- a/notmuch-config.c
+++ b/notmuch-config.c
@@ -602,9 +602,55 @@ _config_set_list (notmuch_config_t *config,
     *config_var = NULL;
 }
 
+static char *
+_config_get_user_folder (notmuch_config_t *config, const char *path) {
+    char* tmp = talloc_strdup (config, path + 1);
+    const char* user;
+    if (strpbrk(tmp, "/") != NULL) {
+      user = strtok (tmp, "/");
+    }
+    else {
+      user = tmp;
+    }
+    struct passwd * pwd = getpwnam (user);
+
+    if (pwd == NULL) {
+      printf("Config: could not expand %s.\n", path);
+      printf("'%s' doesn't seem to be a valid user on this system.\n", user);
+      exit(EXIT_FAILURE);
+    }
+
+    tmp = talloc_asprintf (config, "%s/%s", pwd->pw_dir, path + strlen (user) + 2);
+    return tmp;
+}
+
+static void
+_config_expand_path (notmuch_config_t *config) {
+    char* path = (char*) _config_get (config, &config->database_path,
+        "database", "path");
+    if (path != NULL && path[0] == '~') {
+      char *new_path;
+      if (strlen (path) == 1 || path[1] == '/') {
+        const char *home_path = getenv("HOME");
+        if (strlen (path) == 1)
+          new_path = talloc_asprintf (config, "%s%s", home_path, path + 1);
+        else if (path[1] == '/')
+          new_path = talloc_asprintf (config, "%s/%s", home_path, path + 2);
+      }
+      else {
+        new_path = _config_get_user_folder (config, path);
+      }
+      notmuch_config_set_database_path (config, new_path);
+      talloc_free (new_path);
+    }
+}
+
 const char *
 notmuch_config_get_database_path (notmuch_config_t *config)
 {
+    // ideally a get_database_path should only get the database path and this
+    // call to _config_expand_path would be done in a setup phase
+    _config_expand_path (config);
     return _config_get (config, &config->database_path, "database", "path");
 }
 
-- 
2.7.4


Thread: