* [gentoo-commits] proj/openrc:master commit in: sh/, src/librc/
@ 2015-11-05 18:53 William Hubbs
0 siblings, 0 replies; only message in thread
From: William Hubbs @ 2015-11-05 18:53 UTC (permalink / raw
To: gentoo-commits
commit: c09eeca49145b034df6527c500099ba22f28e824
Author: William Hubbs <w.d.hubbs <AT> gmail <DOT> com>
AuthorDate: Fri Oct 30 17:32:32 2015 +0000
Commit: William Hubbs <williamh <AT> gentoo <DOT> org>
CommitDate: Thu Nov 5 16:40:24 2015 +0000
URL: https://gitweb.gentoo.org/proj/openrc.git/commit/?id=c09eeca4
Add rc.conf.d support
This makes it possible to override settings in rc.conf by adding a
directory @SYSCONFDIR <AT> /rc.conf.d and putting files in this directory.
The files will be processed in lexical order, and the last setting in
these files will be used.
sh/openrc-run.sh.in | 6 +++
src/librc/librc-misc.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++
src/librc/rc.h.in | 1 +
3 files changed, 110 insertions(+)
diff --git a/sh/openrc-run.sh.in b/sh/openrc-run.sh.in
index 8aba4e0..749af2c 100644
--- a/sh/openrc-run.sh.in
+++ b/sh/openrc-run.sh.in
@@ -184,6 +184,12 @@ unset _conf_d
# Load any system overrides
sourcex -e "@SYSCONFDIR@/rc.conf"
+if [ -d "@SYSCONFDIR@/rc.conf.d" ]; then
+ for _f in "@SYSCONFDIR@"/rc.conf.d/*.conf; do
+ sourcex -e "$_f"
+ done
+fi
+
# load service supervisor functions
sourcex "@LIBEXECDIR@/sh/s6.sh"
diff --git a/src/librc/librc-misc.c b/src/librc/librc-misc.c
index 2e9de80..1eedc96 100644
--- a/src/librc/librc-misc.c
+++ b/src/librc/librc-misc.c
@@ -28,6 +28,8 @@
* SUCH DAMAGE.
*/
+#include <fnmatch.h>
+
#include "queue.h"
#include "librc.h"
@@ -214,6 +216,69 @@ rc_config_list(const char *file)
}
librc_hidden_def(rc_config_list)
+static void rc_config_set_value(RC_STRINGLIST *config, char *value)
+{
+ RC_STRING *cline;
+ char *entry;
+ size_t i = 0;
+ char *newline;
+ char *p = value;
+ bool replaced;
+ char *token;
+
+ if (! p)
+ return;
+ if (strncmp(p, "export ", 7) == 0)
+ p += 7;
+ if (! (token = strsep(&p, "=")))
+ return;
+
+ entry = xstrdup(token);
+ /* Preserve shell coloring */
+ if (*p == '$')
+ token = value;
+ else
+ do {
+ /* Bash variables are usually quoted */
+ token = strsep(&p, "\"\'");
+ } while (token && *token == '\0');
+
+ /* Drop a newline if that's all we have */
+ if (token) {
+ i = strlen(token) - 1;
+ if (token[i] == '\n')
+ token[i] = 0;
+
+ i = strlen(entry) + strlen(token) + 2;
+ newline = xmalloc(sizeof(char) * i);
+ snprintf(newline, i, "%s=%s", entry, token);
+ } else {
+ i = strlen(entry) + 2;
+ newline = xmalloc(sizeof(char) * i);
+ snprintf(newline, i, "%s=", entry);
+ }
+
+ replaced = false;
+ /* In shells the last item takes precedence, so we need to remove
+ any prior values we may already have */
+ TAILQ_FOREACH(cline, config, entries) {
+ i = strlen(entry);
+ if (strncmp(entry, cline->value, i) == 0 && cline->value[i] == '=') {
+ /* We have a match now - to save time we directly replace it */
+ free(cline->value);
+ cline->value = newline;
+ replaced = true;
+ break;
+ }
+ }
+
+ if (!replaced) {
+ rc_stringlist_add(config, newline);
+ free(newline);
+ }
+ free(entry);
+}
+
/*
* Override some specific rc.conf options on the kernel command line
*/
@@ -272,6 +337,42 @@ static RC_STRINGLIST *rc_config_override(RC_STRINGLIST *config)
}
#endif
+static RC_STRINGLIST * rc_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;
+
+ if ((dp = opendir(RC_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", RC_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);
+ }
+ }
+ return config;
+}
+
RC_STRINGLIST *
rc_config_load(const char *file)
{
@@ -401,6 +502,8 @@ rc_conf_value(const char *setting)
#endif
}
+ rc_conf = rc_config_directory(rc_conf);
+
/* Convert old uppercase to lowercase */
TAILQ_FOREACH(s, rc_conf, entries) {
p = s->value;
diff --git a/src/librc/rc.h.in b/src/librc/rc.h.in
index 13e1b5b..e3a586f 100644
--- a/src/librc/rc.h.in
+++ b/src/librc/rc.h.in
@@ -56,6 +56,7 @@ extern "C" {
#define RC_SYS_WHITELIST RC_LIBEXECDIR "/conf.d/env_whitelist"
#define RC_USR_WHITELIST RC_SYSCONFDIR "/conf.d/env_whitelist"
#define RC_CONF RC_SYSCONFDIR "/rc.conf"
+#define RC_CONF_D RC_SYSCONFDIR "/rc.conf.d"
#define RC_CONF_OLD RC_SYSCONFDIR "/conf.d/rc"
#define RC_PATH_PREFIX RC_LIBEXECDIR "/bin:/bin:/sbin:/usr/bin:/usr/sbin"
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2015-11-05 18:53 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-11-05 18:53 [gentoo-commits] proj/openrc:master commit in: sh/, src/librc/ William Hubbs
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox