diff options
author | Anna (navi) Figueiredo Gomes <navi@vlhl.dev> | 2023-03-18 01:03:28 -0300 |
---|---|---|
committer | Anna (navi) Figueiredo Gomes <navi@vlhl.dev> | 2023-10-19 10:56:54 +0200 |
commit | c4b7a25b3781dd6ac645fef5cf8e0262d077da26 (patch) | |
tree | cbd7867698d889306414f303f157d8a0387be421 /src | |
parent | b7069282021aec7b486a1123c8521ac4e67250c0 (diff) |
librc: Allow user to override system-wide rc.conf
This change read a user version of rc.conf, to be located in
`~/.config/rc.conf`. The user version is loaded first, so it has
priority, thus overriding the system settings.
Signed-off-by: Anna (navi) Figueiredo Gomes <navi@vlhl.dev>
Diffstat (limited to 'src')
-rw-r--r-- | src/librc/librc-misc.c | 75 | ||||
-rw-r--r-- | src/librc/rc.h.in | 4 |
2 files changed, 77 insertions, 2 deletions
diff --git a/src/librc/librc-misc.c b/src/librc/librc-misc.c index ce658f5c..2dab1249 100644 --- a/src/librc/librc-misc.c +++ b/src/librc/librc-misc.c @@ -364,6 +364,52 @@ static RC_STRINGLIST * rc_config_directory(RC_STRINGLIST *config) return config; } +#ifdef RC_USER_SERVICES +static RC_STRINGLIST * rc_user_config_directory(RC_STRINGLIST *config) +{ + DIR *dp; + struct dirent *d; + RC_STRINGLIST *rc_conf_d_files = rc_stringlist_new(); + RC_STRING *fname; + RC_STRINGLIST *rc_conf_d_list; + char path[PATH_MAX]; + RC_STRING *line; + char *sysconf = rc_user_sysconfdir(); + char *user_conf_d; + + xasprintf(&user_conf_d, "%s/%s", sysconf, RC_USER_CONF_D); + + if ((dp = opendir(user_conf_d)) != NULL) { + while ((d = readdir(dp)) != NULL) { + if (fnmatch("*.conf", d->d_name, FNM_PATHNAME) == 0) { + rc_stringlist_addu(rc_conf_d_files, d->d_name); + } + } + closedir(dp); + + if (rc_conf_d_files) { + rc_stringlist_sort(&rc_conf_d_files); + TAILQ_FOREACH(fname, rc_conf_d_files, entries) { + if (!fname->value) + continue; + sprintf(path, "%s/%s", user_conf_d, fname->value); + rc_conf_d_list = rc_config_list(path); + TAILQ_FOREACH(line, rc_conf_d_list, entries) + if (line->value) + rc_config_set_value(config, line->value); + rc_stringlist_free(rc_conf_d_list); + } + rc_stringlist_free(rc_conf_d_files); + } + } + + free(sysconf); + free(user_conf_d); + return config; +} + +#endif + RC_STRINGLIST * rc_config_load(const char *file) { @@ -412,12 +458,37 @@ _free_rc_conf(void) char * rc_conf_value(const char *setting) { - RC_STRINGLIST *old; + RC_STRINGLIST *system, *old; RC_STRING *s; char *p; +#ifdef RC_USER_SERVICES + RC_STRINGLIST *user; + char *userconf, *user_sysconf; +#endif if (!rc_conf) { - rc_conf = rc_config_load(RC_CONF); + rc_conf = rc_stringlist_new(); + +#ifdef RC_USER_SERVICES + if (rc_is_user()) { + user_sysconf = rc_user_sysconfdir(); + xasprintf(&userconf, "%s/%s", user_sysconf, RC_USER_CONF); + + user = rc_config_load(userconf); + TAILQ_CONCAT(rc_conf, user, entries); + rc_stringlist_free(user); + + free(userconf); + free(user_sysconf); + + rc_user_config_directory(rc_conf); + } +#endif + + system = rc_config_load(RC_CONF); + TAILQ_CONCAT(rc_conf, system, entries); + rc_stringlist_free(system); + atexit(_free_rc_conf); /* Support old configs. */ diff --git a/src/librc/rc.h.in b/src/librc/rc.h.in index 02e7d53f..1ffeba5a 100644 --- a/src/librc/rc.h.in +++ b/src/librc/rc.h.in @@ -56,6 +56,10 @@ extern "C" { #define RC_USER_RUNLEVELS_FOLDER "/runlevels" #define RC_USER_RUNTIME_FOLDER "/openrc" + +#define RC_USER_CONF "/rc.conf" +#define RC_USER_CONF_D "/rc.conf.d" + /*! Is openrc being ran in usermode? * @return true if yes, otherwise false */ bool rc_is_user(void); |