From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) by finch.gentoo.org (Postfix) with ESMTP id DC54A1384B4 for ; Thu, 5 Nov 2015 18:53:48 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 1D2A7E086A; Thu, 5 Nov 2015 18:53:47 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id 6306CE085A for ; Thu, 5 Nov 2015 18:53:46 +0000 (UTC) Received: from oystercatcher.gentoo.org (oystercatcher.gentoo.org [148.251.78.52]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 0FDCE34078E for ; Thu, 5 Nov 2015 18:53:45 +0000 (UTC) Received: from localhost.localdomain (localhost [127.0.0.1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id 4FEE52034 for ; Thu, 5 Nov 2015 18:53:41 +0000 (UTC) From: "William Hubbs" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "William Hubbs" Message-ID: <1446741624.c09eeca49145b034df6527c500099ba22f28e824.williamh@OpenRC> Subject: [gentoo-commits] proj/openrc:master commit in: sh/, src/librc/ X-VCS-Repository: proj/openrc X-VCS-Files: sh/openrc-run.sh.in src/librc/librc-misc.c src/librc/rc.h.in X-VCS-Directories: sh/ src/librc/ X-VCS-Committer: williamh X-VCS-Committer-Name: William Hubbs X-VCS-Revision: c09eeca49145b034df6527c500099ba22f28e824 X-VCS-Branch: master Date: Thu, 5 Nov 2015 18:53:41 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Archives-Salt: 57584a9a-173a-43ef-ba90-fe208e791d85 X-Archives-Hash: aff9bc8e7c9b224274a93a30b2b09f6f commit: c09eeca49145b034df6527c500099ba22f28e824 Author: William Hubbs gmail com> AuthorDate: Fri Oct 30 17:32:32 2015 +0000 Commit: William Hubbs gentoo 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 /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 + #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"