diff options
Diffstat (limited to 'src/sdtui.c')
-rw-r--r-- | src/sdtui.c | 122 |
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 |