aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAnna (navi) Figueiredo Gomes <navi@vlhl.dev>2023-03-18 01:03:28 -0300
committerAnna (navi) Figueiredo Gomes <navi@vlhl.dev>2023-10-19 10:56:54 +0200
commitc4b7a25b3781dd6ac645fef5cf8e0262d077da26 (patch)
treecbd7867698d889306414f303f157d8a0387be421 /src
parentb7069282021aec7b486a1123c8521ac4e67250c0 (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.c75
-rw-r--r--src/librc/rc.h.in4
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);