Gentoo Archives: gentoo-commits

From: William Hubbs <williamh@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/openrc:master commit in: sh/, src/librc/
Date: Thu, 05 Nov 2015 18:53:48
Message-Id: 1446741624.c09eeca49145b034df6527c500099ba22f28e824.williamh@OpenRC
1 commit: c09eeca49145b034df6527c500099ba22f28e824
2 Author: William Hubbs <w.d.hubbs <AT> gmail <DOT> com>
3 AuthorDate: Fri Oct 30 17:32:32 2015 +0000
4 Commit: William Hubbs <williamh <AT> gentoo <DOT> org>
5 CommitDate: Thu Nov 5 16:40:24 2015 +0000
6 URL: https://gitweb.gentoo.org/proj/openrc.git/commit/?id=c09eeca4
7
8 Add rc.conf.d support
9
10 This makes it possible to override settings in rc.conf by adding a
11 directory @SYSCONFDIR <AT> /rc.conf.d and putting files in this directory.
12 The files will be processed in lexical order, and the last setting in
13 these files will be used.
14
15 sh/openrc-run.sh.in | 6 +++
16 src/librc/librc-misc.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++
17 src/librc/rc.h.in | 1 +
18 3 files changed, 110 insertions(+)
19
20 diff --git a/sh/openrc-run.sh.in b/sh/openrc-run.sh.in
21 index 8aba4e0..749af2c 100644
22 --- a/sh/openrc-run.sh.in
23 +++ b/sh/openrc-run.sh.in
24 @@ -184,6 +184,12 @@ unset _conf_d
25
26 # Load any system overrides
27 sourcex -e "@SYSCONFDIR@/rc.conf"
28 +if [ -d "@SYSCONFDIR@/rc.conf.d" ]; then
29 + for _f in "@SYSCONFDIR@"/rc.conf.d/*.conf; do
30 + sourcex -e "$_f"
31 + done
32 +fi
33 +
34
35 # load service supervisor functions
36 sourcex "@LIBEXECDIR@/sh/s6.sh"
37
38 diff --git a/src/librc/librc-misc.c b/src/librc/librc-misc.c
39 index 2e9de80..1eedc96 100644
40 --- a/src/librc/librc-misc.c
41 +++ b/src/librc/librc-misc.c
42 @@ -28,6 +28,8 @@
43 * SUCH DAMAGE.
44 */
45
46 +#include <fnmatch.h>
47 +
48 #include "queue.h"
49 #include "librc.h"
50
51 @@ -214,6 +216,69 @@ rc_config_list(const char *file)
52 }
53 librc_hidden_def(rc_config_list)
54
55 +static void rc_config_set_value(RC_STRINGLIST *config, char *value)
56 +{
57 + RC_STRING *cline;
58 + char *entry;
59 + size_t i = 0;
60 + char *newline;
61 + char *p = value;
62 + bool replaced;
63 + char *token;
64 +
65 + if (! p)
66 + return;
67 + if (strncmp(p, "export ", 7) == 0)
68 + p += 7;
69 + if (! (token = strsep(&p, "=")))
70 + return;
71 +
72 + entry = xstrdup(token);
73 + /* Preserve shell coloring */
74 + if (*p == '$')
75 + token = value;
76 + else
77 + do {
78 + /* Bash variables are usually quoted */
79 + token = strsep(&p, "\"\'");
80 + } while (token && *token == '\0');
81 +
82 + /* Drop a newline if that's all we have */
83 + if (token) {
84 + i = strlen(token) - 1;
85 + if (token[i] == '\n')
86 + token[i] = 0;
87 +
88 + i = strlen(entry) + strlen(token) + 2;
89 + newline = xmalloc(sizeof(char) * i);
90 + snprintf(newline, i, "%s=%s", entry, token);
91 + } else {
92 + i = strlen(entry) + 2;
93 + newline = xmalloc(sizeof(char) * i);
94 + snprintf(newline, i, "%s=", entry);
95 + }
96 +
97 + replaced = false;
98 + /* In shells the last item takes precedence, so we need to remove
99 + any prior values we may already have */
100 + TAILQ_FOREACH(cline, config, entries) {
101 + i = strlen(entry);
102 + if (strncmp(entry, cline->value, i) == 0 && cline->value[i] == '=') {
103 + /* We have a match now - to save time we directly replace it */
104 + free(cline->value);
105 + cline->value = newline;
106 + replaced = true;
107 + break;
108 + }
109 + }
110 +
111 + if (!replaced) {
112 + rc_stringlist_add(config, newline);
113 + free(newline);
114 + }
115 + free(entry);
116 +}
117 +
118 /*
119 * Override some specific rc.conf options on the kernel command line
120 */
121 @@ -272,6 +337,42 @@ static RC_STRINGLIST *rc_config_override(RC_STRINGLIST *config)
122 }
123 #endif
124
125 +static RC_STRINGLIST * rc_config_directory(RC_STRINGLIST *config)
126 +{
127 + DIR *dp;
128 + struct dirent *d;
129 + RC_STRINGLIST *rc_conf_d_files = rc_stringlist_new();
130 + RC_STRING *fname;
131 + RC_STRINGLIST *rc_conf_d_list;
132 + char path[PATH_MAX];
133 + RC_STRING *line;
134 +
135 + if ((dp = opendir(RC_CONF_D)) != NULL) {
136 + while ((d = readdir(dp)) != NULL) {
137 + if (fnmatch("*.conf", d->d_name, FNM_PATHNAME) == 0) {
138 + rc_stringlist_addu(rc_conf_d_files, d->d_name);
139 + }
140 + }
141 + closedir(dp);
142 +
143 + if (rc_conf_d_files) {
144 + rc_stringlist_sort(&rc_conf_d_files);
145 + TAILQ_FOREACH(fname, rc_conf_d_files, entries) {
146 + if (! fname->value)
147 + continue;
148 + sprintf(path, "%s/%s", RC_CONF_D, fname->value);
149 + rc_conf_d_list = rc_config_list(path);
150 + TAILQ_FOREACH(line, rc_conf_d_list, entries)
151 + if (line->value)
152 + rc_config_set_value(config, line->value);
153 + rc_stringlist_free(rc_conf_d_list);
154 + }
155 + rc_stringlist_free(rc_conf_d_files);
156 + }
157 + }
158 + return config;
159 +}
160 +
161 RC_STRINGLIST *
162 rc_config_load(const char *file)
163 {
164 @@ -401,6 +502,8 @@ rc_conf_value(const char *setting)
165 #endif
166 }
167
168 + rc_conf = rc_config_directory(rc_conf);
169 +
170 /* Convert old uppercase to lowercase */
171 TAILQ_FOREACH(s, rc_conf, entries) {
172 p = s->value;
173
174 diff --git a/src/librc/rc.h.in b/src/librc/rc.h.in
175 index 13e1b5b..e3a586f 100644
176 --- a/src/librc/rc.h.in
177 +++ b/src/librc/rc.h.in
178 @@ -56,6 +56,7 @@ extern "C" {
179 #define RC_SYS_WHITELIST RC_LIBEXECDIR "/conf.d/env_whitelist"
180 #define RC_USR_WHITELIST RC_SYSCONFDIR "/conf.d/env_whitelist"
181 #define RC_CONF RC_SYSCONFDIR "/rc.conf"
182 +#define RC_CONF_D RC_SYSCONFDIR "/rc.conf.d"
183 #define RC_CONF_OLD RC_SYSCONFDIR "/conf.d/rc"
184
185 #define RC_PATH_PREFIX RC_LIBEXECDIR "/bin:/bin:/sbin:/usr/bin:/usr/sbin"