Skip to content

Commit

Permalink
librc: Allow user to override system-wide rc.conf
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
navi-desu committed Apr 19, 2023
1 parent 60bfe7f commit 6f37372
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 2 deletions.
75 changes: 73 additions & 2 deletions src/librc/librc-misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,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)
{
Expand Down Expand Up @@ -411,12 +457,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. */
Expand Down
4 changes: 4 additions & 0 deletions src/librc/rc.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 6f37372

Please sign in to comment.