]> git.notmuchmail.org Git - notmuch/blobdiff - lib/config.cc
lib: provide notmuch_config_path
[notmuch] / lib / config.cc
index 483a02efac8c3287df6fae66f83211e92da7bb9a..7a0da9716bf9a36ef4b1b5abad7cc5aabdee3049 100644 (file)
@@ -22,6 +22,9 @@
 #include "notmuch-private.h"
 #include "database-private.h"
 
+#include <pwd.h>
+#include <netdb.h>
+
 static const std::string CONFIG_PREFIX = "C";
 
 struct _notmuch_config_list {
@@ -38,6 +41,10 @@ struct _notmuch_config_values {
     void *children; /* talloc_context */
 };
 
+struct _notmuch_config_pairs {
+    notmuch_string_map_iterator_t *iter;
+};
+
 static const char *_notmuch_config_key_to_string (notmuch_config_key_t key);
 
 static int
@@ -261,13 +268,19 @@ _notmuch_config_load_from_database (notmuch_database_t *notmuch)
 notmuch_config_values_t *
 notmuch_config_get_values (notmuch_database_t *notmuch, notmuch_config_key_t key)
 {
-    notmuch_config_values_t *values = NULL;
-    bool ok = false;
-
     const char *key_str = _notmuch_config_key_to_string (key);
 
     if (! key_str)
-       goto DONE;
+       return NULL;
+
+    return notmuch_config_get_values_string (notmuch, key_str);
+}
+
+notmuch_config_values_t *
+notmuch_config_get_values_string (notmuch_database_t *notmuch, const char *key_str)
+{
+    notmuch_config_values_t *values = NULL;
+    bool ok = false;
 
     values = talloc (notmuch, notmuch_config_values_t);
     if (unlikely (! values))
@@ -333,6 +346,47 @@ notmuch_config_values_destroy (notmuch_config_values_t *values)
     talloc_free (values);
 }
 
+notmuch_config_pairs_t *
+notmuch_config_get_pairs (notmuch_database_t *notmuch,
+                         const char *prefix)
+{
+    notmuch_config_pairs_t *pairs = talloc (notmuch, notmuch_config_pairs_t);
+
+    pairs->iter = _notmuch_string_map_iterator_create (notmuch->config, prefix, false);
+    return pairs;
+}
+
+notmuch_bool_t
+notmuch_config_pairs_valid (notmuch_config_pairs_t *pairs)
+{
+    return _notmuch_string_map_iterator_valid (pairs->iter);
+}
+
+void
+notmuch_config_pairs_move_to_next (notmuch_config_pairs_t *pairs)
+{
+    _notmuch_string_map_iterator_move_to_next (pairs->iter);
+}
+
+const char *
+notmuch_config_pairs_key (notmuch_config_pairs_t *pairs)
+{
+    return _notmuch_string_map_iterator_key (pairs->iter);
+}
+
+const char *
+notmuch_config_pairs_value (notmuch_config_pairs_t *pairs)
+{
+    return _notmuch_string_map_iterator_value (pairs->iter);
+}
+
+void
+notmuch_config_pairs_destroy (notmuch_config_pairs_t *pairs)
+{
+    _notmuch_string_map_iterator_destroy (pairs->iter);
+    talloc_free (pairs);
+}
+
 notmuch_status_t
 _notmuch_config_load_from_file (notmuch_database_t *notmuch,
                                GKeyFile *file)
@@ -400,14 +454,110 @@ notmuch_config_get_bool (notmuch_database_t *notmuch, notmuch_config_key_t key,
     return NOTMUCH_STATUS_SUCCESS;
 }
 
+static const char *
+_get_name_from_passwd_file (void *ctx)
+{
+    long pw_buf_size;
+    char *pw_buf;
+    struct passwd passwd, *ignored;
+    const char *name;
+    int e;
+
+    pw_buf_size = sysconf (_SC_GETPW_R_SIZE_MAX);
+    if (pw_buf_size == -1) pw_buf_size = 64;
+    pw_buf = (char *) talloc_size (ctx, pw_buf_size);
+
+    while ((e = getpwuid_r (getuid (), &passwd, pw_buf,
+                           pw_buf_size, &ignored)) == ERANGE) {
+       pw_buf_size = pw_buf_size * 2;
+       pw_buf = (char *) talloc_zero_size (ctx, pw_buf_size);
+    }
+
+    if (e == 0) {
+       char *comma = strchr (passwd.pw_gecos, ',');
+       if (comma)
+           name = talloc_strndup (ctx, passwd.pw_gecos,
+                                  comma - passwd.pw_gecos);
+       else
+           name = talloc_strdup (ctx, passwd.pw_gecos);
+    } else {
+       name = talloc_strdup (ctx, "");
+    }
+
+    talloc_free (pw_buf);
+
+    return name;
+}
+
+static char *
+_get_username_from_passwd_file (void *ctx)
+{
+    long pw_buf_size;
+    char *pw_buf;
+    struct passwd passwd, *ignored;
+    char *name;
+    int e;
+
+    pw_buf_size = sysconf (_SC_GETPW_R_SIZE_MAX);
+    if (pw_buf_size == -1) pw_buf_size = 64;
+    pw_buf = (char *) talloc_zero_size (ctx, pw_buf_size);
+
+    while ((e = getpwuid_r (getuid (), &passwd, pw_buf,
+                           pw_buf_size, &ignored)) == ERANGE) {
+       pw_buf_size = pw_buf_size * 2;
+       pw_buf = (char *) talloc_zero_size (ctx, pw_buf_size);
+    }
+
+    if (e == 0)
+       name = talloc_strdup (ctx, passwd.pw_name);
+    else
+       name = talloc_strdup (ctx, "");
+
+    talloc_free (pw_buf);
+
+    return name;
+}
+
+static const char *
+_get_email_from_passwd_file (void *ctx)
+{
+
+    char hostname[256];
+    struct hostent *hostent;
+    const char *domainname;
+    char *email;
+
+    char *username = _get_username_from_passwd_file (ctx);
+
+    gethostname (hostname, 256);
+    hostname[255] = '\0';
+
+    hostent = gethostbyname (hostname);
+    if (hostent && (domainname = strchr (hostent->h_name, '.')))
+       domainname += 1;
+    else
+       domainname = "(none)";
+
+    email = talloc_asprintf (ctx, "%s@%s.%s",
+                            username, hostname, domainname);
+
+    talloc_free (username);
+    talloc_free (email);
+    return email;
+}
+
 static const char *
 _notmuch_config_key_to_string (notmuch_config_key_t key)
 {
     switch (key) {
     case NOTMUCH_CONFIG_DATABASE_PATH:
        return "database.path";
+    case NOTMUCH_CONFIG_MAIL_ROOT:
+       return "database.mail_root";
     case NOTMUCH_CONFIG_HOOK_DIR:
        return "database.hook_dir";
+    case NOTMUCH_CONFIG_BACKUP_DIR:
+       return "database.backup_dir";
     case NOTMUCH_CONFIG_EXCLUDE_TAGS:
        return "search.exclude_tags";
     case NOTMUCH_CONFIG_NEW_TAGS:
@@ -428,29 +578,47 @@ _notmuch_config_key_to_string (notmuch_config_key_t key)
 }
 
 static const char *
-_notmuch_config_default (void *ctx, notmuch_config_key_t key)
+_notmuch_config_default (notmuch_database_t *notmuch, notmuch_config_key_t key)
 {
     char *path;
+    const char *name, *email;
 
     switch (key) {
     case NOTMUCH_CONFIG_DATABASE_PATH:
        path = getenv ("MAILDIR");
        if (path)
-           path = talloc_strdup (ctx, path);
+           path = talloc_strdup (notmuch, path);
        else
-           path = talloc_asprintf (ctx, "%s/mail",
+           path = talloc_asprintf (notmuch, "%s/mail",
                                    getenv ("HOME"));
        return path;
+    case NOTMUCH_CONFIG_MAIL_ROOT:
+       /* by default, mail root is the same as database path */
+       return notmuch_database_get_path (notmuch);
     case NOTMUCH_CONFIG_EXCLUDE_TAGS:
        return "";
     case NOTMUCH_CONFIG_NEW_TAGS:
-       return "inbox;unread";
+       return "unread;inbox";
     case NOTMUCH_CONFIG_SYNC_MAILDIR_FLAGS:
        return "true";
-    case NOTMUCH_CONFIG_HOOK_DIR:
-    case NOTMUCH_CONFIG_NEW_IGNORE:
     case NOTMUCH_CONFIG_USER_NAME:
+       name = getenv ("NAME");
+       if (name)
+           name = talloc_strdup (notmuch, name);
+       else
+           name = _get_name_from_passwd_file (notmuch);
+       return name;
     case NOTMUCH_CONFIG_PRIMARY_EMAIL:
+       email = getenv ("EMAIL");
+       if (email)
+           email = talloc_strdup (notmuch, email);
+       else
+           email = _get_email_from_passwd_file (notmuch);
+       return email;
+    case NOTMUCH_CONFIG_NEW_IGNORE:
+       return "";
+    case NOTMUCH_CONFIG_HOOK_DIR:
+    case NOTMUCH_CONFIG_BACKUP_DIR:
     case NOTMUCH_CONFIG_OTHER_EMAIL:
        return NULL;
     default:
@@ -486,6 +654,12 @@ notmuch_config_get (notmuch_database_t *notmuch, notmuch_config_key_t key)
     return _notmuch_string_map_get (notmuch->config, _notmuch_config_key_to_string (key));
 }
 
+const char *
+notmuch_config_path (notmuch_database_t *notmuch)
+{
+    return notmuch->config_path;
+}
+
 notmuch_status_t
 notmuch_config_set (notmuch_database_t *notmuch, notmuch_config_key_t key, const char *val)
 {