From 39fd2b127d8b64f39d8a61ced43b85de76ac8cf7 Mon Sep 17 00:00:00 2001 From: Olli Helenius Date: Thu, 12 Sep 2024 23:04:05 +0300 Subject: [PATCH 1/2] Add get_user_home Add an utility function for locating the current user's home directory using either $HOME or their passwd entry. --- src/common-utils/common-utils.c | 34 ++++++++++++++++++++++++--------- src/common-utils/common-utils.h | 1 + 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/common-utils/common-utils.c b/src/common-utils/common-utils.c index f24f1bf..c5bb35c 100644 --- a/src/common-utils/common-utils.c +++ b/src/common-utils/common-utils.c @@ -296,6 +296,29 @@ void nvfree(void *s) /* misc */ /****************************************************************************/ +/* + * get_user_home() - locate current user's home directory using either + * the enrivonment variable or their passwd entry. + * + * Returns NULL if the home directory cannot be located, otherwise + * returns a statically allocated string that is either the value + * of the environment variable or the passwd entry. + */ +const char *get_user_home() +{ + char *home = getenv("HOME"); + struct passwd *pw; + + if (home) return home; + + /* $HOME isn't set; get the home directory from /etc/passwd */ + + pw = getpwuid(getuid()); + if (pw) return pw->pw_dir; + + return NULL; +} + /* * tilde_expansion() - do tilde expansion on the given path name; * based loosely on code snippets found in the comp.unix.programmer @@ -310,7 +333,7 @@ void nvfree(void *s) char *tilde_expansion(const char *str) { - char *prefix = NULL; + const char *prefix = NULL; const char *replace; char *user, *ret; struct passwd *pw; @@ -324,14 +347,7 @@ char *tilde_expansion(const char *str) /* expand to the current user's home directory */ - prefix = getenv("HOME"); - if (!prefix) { - - /* $HOME isn't set; get the home directory from /etc/passwd */ - - pw = getpwuid(getuid()); - if (pw) prefix = pw->pw_dir; - } + prefix = get_user_home(); replace = str + 1; diff --git a/src/common-utils/common-utils.h b/src/common-utils/common-utils.h index 1705acf..2a60787 100644 --- a/src/common-utils/common-utils.h +++ b/src/common-utils/common-utils.h @@ -64,6 +64,7 @@ char *nvasprintf(const char *fmt, ...) NV_ATTRIBUTE_PRINTF(1, 2); void nv_append_sprintf(char **buf, const char *fmt, ...) NV_ATTRIBUTE_PRINTF(2, 3); void nvfree(void *s); +const char *get_user_home(); char *tilde_expansion(const char *str); char *nv_prepend_to_string_list(char *list, const char *item, const char *delim); From 92fc719fbc4277472672a3c30c9ca167785e6786 Mon Sep 17 00:00:00 2001 From: Olli Helenius Date: Thu, 12 Sep 2024 23:10:24 +0300 Subject: [PATCH 2/2] Save the settings file under XDG_CONFIG_HOME by default If the settings file does not exist in its legacy location in `~/.nvidia-settings-rc`, store it in `$XDG_CONFIG_HOME/nvidia/settings-rc` instead. Fixes #30. --- src/command-line.c | 69 +++++++++++++++++++++++++++++++++++++++- src/command-line.h | 7 ++-- src/gtk+-2.x/ctkconfig.c | 5 ++- src/option-table.h | 2 +- 4 files changed, 76 insertions(+), 7 deletions(-) diff --git a/src/command-line.c b/src/command-line.c index 863e371..64cdfe4 100644 --- a/src/command-line.c +++ b/src/command-line.c @@ -17,13 +17,16 @@ * along with this program. If not, see . */ +#include #include #include #include #include +#include #include #include #include +#include #include "option-table.h" #include "query-assign.h" @@ -199,6 +202,70 @@ void print_help(void) nvgetopt_print_help(__options, 0, print_help_helper); } +/* + * locate_default_rc_file() - find a suitable location for the default + * configuration file. This will be one of: + * - $XDG_CONFIG_HOME/nvidia/settings-rc, + * - $HOME/.config/nvidia/settings-rc or + * - $HOME/.nvidia-settings-rc + * The last of which is chosen only if the file already exists, for + * backwards compatibility. + * + * The parent directory, `nvidia` for the first two options will be + * created if it doesn't already exist. + * + * The string returned is malloc'ed, but must not be freed as it is + * re-used if this is called multiple times. + */ +const char *locate_default_rc_file(void) +{ + static char *default_rc_file = NULL; + const char *home; + const char *xdg_config_home; + + if (default_rc_file) { + return default_rc_file; + } + + home = get_user_home(); + xdg_config_home = getenv("XDG_CONFIG_HOME"); + + /* Prefer the legacy dot-file in $HOME if it exists. */ + + if (home) { + nv_append_sprintf(&default_rc_file, "%s/.nvidia-settings-rc", home); + + if (access(default_rc_file, F_OK) == 0) { + return default_rc_file; + } + + nvfree(default_rc_file); + default_rc_file = NULL; + } + + if (xdg_config_home) { + nv_append_sprintf(&default_rc_file, "%s/nvidia", xdg_config_home); + } else if (home) { + nv_append_sprintf(&default_rc_file, "%s/.config/nvidia", home); + } else { + /* Store in the current directory as the last resort if we cannot find a home. */ + + default_rc_file = ".nvidia-settings-rc"; + return default_rc_file; + } + + if (access(default_rc_file, F_OK) != 0) { + if (mkdir(default_rc_file, 0755) < 0) { + fprintf(stderr, + "Failed to create the default configuration directory '%s': %s.\n", + default_rc_file, strerror(errno)); + } + } + + nv_append_sprintf(&default_rc_file, "/settings-rc"); + + return default_rc_file; +} /* * parse_command_line() - malloc an Options structure, initialize it @@ -218,7 +285,7 @@ Options *parse_command_line(int argc, char *argv[], int boolval; op = nvalloc(sizeof(Options)); - op->config = DEFAULT_RC_FILE; + op->config = locate_default_rc_file(); op->write_config = NV_TRUE; /* diff --git a/src/command-line.h b/src/command-line.h index aa0298c..4169a14 100644 --- a/src/command-line.h +++ b/src/command-line.h @@ -27,7 +27,6 @@ */ struct _CtrlSystemList; -#define DEFAULT_RC_FILE "~/.nvidia-settings-rc" #define CONFIG_FILE_OPTION 1 #define DISPLAY_OPTION 2 @@ -47,8 +46,8 @@ typedef struct { char *config; /* * The name of the configuration file (to be * read from, and to be written to); defaults - * to the value of the constant - * DEFAULT_RC_FILE. + * to $XDG_CONFIG_HOME/nvidia/settings-rc or + * ~/.nvidia-settings-rc if the latter exists. */ char **assignments; /* @@ -124,7 +123,7 @@ typedef struct { } Options; - +const char *locate_default_rc_file(void); Options *parse_command_line(int argc, char *argv[], struct _CtrlSystemList *systems); diff --git a/src/gtk+-2.x/ctkconfig.c b/src/gtk+-2.x/ctkconfig.c index 56318da..53438c6 100644 --- a/src/gtk+-2.x/ctkconfig.c +++ b/src/gtk+-2.x/ctkconfig.c @@ -24,6 +24,7 @@ */ #include "ctkconfig.h" +#include "command-line.h" #include "ctkhelp.h" #include "ctkwindow.h" #include "ctkutils.h" @@ -305,12 +306,14 @@ static void save_rc_clicked(GtkWidget *widget, gpointer user_data) CtkWindow *ctk_window = CTK_WINDOW(ctk_get_parent_window(GTK_WIDGET(ctk_config))); + char *default_rc_file = locate_default_rc_file(); + filename = ctk_get_filename_from_dialog("Please select a file to save to.", GTK_WINDOW(ctk_window), ctk_config->rc_filename ? ctk_config->rc_filename : - DEFAULT_RC_FILE); + default_rc_file); if (!filename) { return; diff --git a/src/option-table.h b/src/option-table.h index 1b67fc5..a52223d 100644 --- a/src/option-table.h +++ b/src/option-table.h @@ -42,7 +42,7 @@ static const NVGetoptOption __options[] = { { "config", CONFIG_FILE_OPTION, NVGETOPT_STRING_ARGUMENT | NVGETOPT_HELP_ALWAYS, NULL, "Use the configuration file &CONFIG& rather than the " - "default &" DEFAULT_RC_FILE "&" }, + "default &$XDG_CONFIG_HOME/nvidia/settings-rc&" }, { "ctrl-display", 'c', NVGETOPT_STRING_ARGUMENT | NVGETOPT_HELP_ALWAYS, NULL,