aboutsummaryrefslogtreecommitdiff
path: root/src/sdtui.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sdtui.c')
-rw-r--r--src/sdtui.c122
1 files changed, 9 insertions, 113 deletions
diff --git a/src/sdtui.c b/src/sdtui.c
index 1158d05..caf08e6 100644
--- a/src/sdtui.c
+++ b/src/sdtui.c
@@ -28,13 +28,11 @@
#include <gio/gio.h>
#include <pango/pango.h>
#include <glib/gi18n.h>
-#include <glib/gstdio.h>
#include <unistd.h>
#include <poll.h>
#include <errno.h>
#include <signal.h>
-#include <pwd.h>
#include <termo.h> // input
#include <ncurses.h> // output
@@ -96,94 +94,6 @@ add_read_watch (int fd, GIOFunc func, gpointer user_data)
return res;
}
-// At times, GLib even with its sheer size is surprisingly useless,
-// and I need to port some code over from "liberty".
-
-static gchar **
-get_xdg_config_dirs (void)
-{
- GPtrArray *paths = g_ptr_array_new ();
- g_ptr_array_add (paths, (gpointer) g_get_user_config_dir ());
- for (const gchar *const *system = g_get_system_config_dirs ();
- *system; system++)
- g_ptr_array_add (paths, (gpointer) *system);
- g_ptr_array_add (paths, NULL);
- return (gchar **) g_ptr_array_free (paths, FALSE);
-}
-
-static gchar *
-resolve_relative_filename_generic
- (gchar **paths, const gchar *tail, const gchar *filename)
-{
- for (; *paths; paths++)
- {
- // As per XDG spec, relative paths are ignored
- if (**paths != '/')
- continue;
-
- gchar *file = g_build_filename (*paths, tail, filename, NULL);
- GStatBuf st;
- if (!g_stat (file, &st))
- return file;
- g_free (file);
- }
- return NULL;
-}
-
-static gchar *
-resolve_relative_config_filename (const gchar *filename)
-{
- gchar **paths = get_xdg_config_dirs ();
- gchar *result = resolve_relative_filename_generic
- (paths, PROJECT_NAME, filename);
- g_strfreev (paths);
- return result;
-}
-
-static gchar *
-try_expand_tilde (const gchar *filename)
-{
- size_t until_slash = strcspn (filename, "/");
- if (!until_slash)
- return g_build_filename (g_get_home_dir () ?: "", filename, NULL);
-
- long buf_len = sysconf (_SC_GETPW_R_SIZE_MAX);
- if (buf_len < 0)
- buf_len = 1024;
- struct passwd pwd, *success = NULL;
-
- gchar *user = g_strndup (filename, until_slash);
- gchar *buf = g_malloc (buf_len);
- while (getpwnam_r (user, &pwd, buf, buf_len, &success) == ERANGE)
- buf = g_realloc (buf, buf_len <<= 1);
- g_free (user);
-
- gchar *result = NULL;
- if (success)
- result = g_strdup_printf ("%s%s", pwd.pw_dir, filename + until_slash);
- g_free (buf);
- return result;
-}
-
-static gchar *
-resolve_filename (const gchar *filename, gchar *(*relative_cb) (const char *))
-{
- // Absolute path is absolute
- if (*filename == '/')
- return g_strdup (filename);
-
- // We don't want to use wordexp() for this as it may execute /bin/sh
- if (*filename == '~')
- {
- // Paths to home directories ought to be absolute
- char *expanded = try_expand_tilde (filename + 1);
- if (expanded)
- return expanded;
- g_debug ("failed to expand the home directory in `%s'", filename);
- }
- return relative_cb (filename);
-}
-
// --- Application -------------------------------------------------------------
#define ATTRIBUTE_TABLE(XX) \
@@ -574,8 +484,8 @@ app_load_config_values (Application *self, GKeyFile *kf)
continue;
// Try to resolve relative paths and expand tildes
- gchar *resolved = resolve_filename
- (path, resolve_relative_config_filename);
+ gchar *resolved =
+ resolve_filename (path, resolve_relative_config_filename);
if (resolved)
g_free (path);
else
@@ -588,30 +498,16 @@ app_load_config_values (Application *self, GKeyFile *kf)
}
static void
-app_load_config (Application *self, GError **e)
+app_load_config (Application *self, GError **error)
{
- GKeyFile *kf = g_key_file_new ();
- gchar **paths = get_xdg_config_dirs ();
-
- // XXX: if there are dashes in the final path component,
- // the function tries to replace them with directory separators,
- // which is completely undocumented
- GError *error = NULL;
- g_key_file_load_from_dirs (kf,
- PROJECT_NAME G_DIR_SEPARATOR_S PROJECT_NAME ".conf",
- (const gchar **) paths, NULL, 0, &error);
- g_strfreev (paths);
-
// TODO: proper error handling showing all relevant information;
// we can afford that here since the terminal hasn't been initialized yet
- if (!error)
- app_load_config_values (self, kf);
- else if (error->code == G_KEY_FILE_ERROR_NOT_FOUND)
- g_error_free (error);
- else
- g_propagate_error (e, error);
-
- g_key_file_free (kf);
+ GKeyFile *key_file = load_project_config_file (error);
+ if (key_file)
+ {
+ app_load_config_values (self, key_file);
+ g_key_file_free (key_file);
+ }
}
static void