[pulseaudio-discuss] [PATCH v2 1/2] conf-parser: add support for .d directories
Tanu Kaskinen
tanuk at iki.fi
Thu Dec 3 21:58:24 PST 2015
This allows a configuration scheme where prior to loading
configuration from "somefile", the parser first loads configuration
from files in directory "somefile.d". This feature needs to be enabled
on a per-file basis, though, and this patch doesn't yet enable the
feature for any files.
---
src/daemon/daemon-conf.c | 2 +-
src/modules/alsa/alsa-mixer.c | 4 ++--
src/modules/module-augment-properties.c | 2 +-
src/pulse/client-conf.c | 2 +-
src/pulsecore/conf-parser.c | 42 +++++++++++++++++++++++++++++++--
src/pulsecore/conf-parser.h | 8 ++++++-
6 files changed, 52 insertions(+), 8 deletions(-)
diff --git a/src/daemon/daemon-conf.c b/src/daemon/daemon-conf.c
index f94cdeb..306c8cb 100644
--- a/src/daemon/daemon-conf.c
+++ b/src/daemon/daemon-conf.c
@@ -617,7 +617,7 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
ci.default_channel_map_set = ci.default_sample_spec_set = false;
ci.conf = c;
- r = f ? pa_config_parse(c->config_file, f, table, NULL, NULL) : 0;
+ r = f ? pa_config_parse(c->config_file, f, table, NULL, false, NULL) : 0;
if (r >= 0) {
diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index 3f51717..273b2d6 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -2594,7 +2594,7 @@ pa_alsa_path* pa_alsa_path_new(const char *paths_dir, const char *fname, pa_alsa
fn = pa_maybe_prefix_path(fname, paths_dir);
- r = pa_config_parse(fn, NULL, items, p->proplist, p);
+ r = pa_config_parse(fn, NULL, items, p->proplist, false, p);
pa_xfree(fn);
if (r < 0)
@@ -4410,7 +4410,7 @@ pa_alsa_profile_set* pa_alsa_profile_set_new(const char *fname, const pa_channel
pa_run_from_build_tree() ? PA_SRCDIR "/modules/alsa/mixer/profile-sets/" :
PA_ALSA_PROFILE_SETS_DIR);
- r = pa_config_parse(fn, NULL, items, NULL, ps);
+ r = pa_config_parse(fn, NULL, items, NULL, false, ps);
pa_xfree(fn);
if (r < 0)
diff --git a/src/modules/module-augment-properties.c b/src/modules/module-augment-properties.c
index 42b6fd9..541f0e7 100644
--- a/src/modules/module-augment-properties.c
+++ b/src/modules/module-augment-properties.c
@@ -204,7 +204,7 @@ static void update_rule(struct rule *r) {
table[0].data = &r->application_name;
table[1].data = &r->icon_name;
- if (pa_config_parse(fn, NULL, table, NULL, r) < 0)
+ if (pa_config_parse(fn, NULL, table, NULL, false, r) < 0)
pa_log_warn("Failed to parse .desktop file %s.", fn);
pa_xfree(fn);
diff --git a/src/pulse/client-conf.c b/src/pulse/client-conf.c
index 47fe183..c2ece90 100644
--- a/src/pulse/client-conf.c
+++ b/src/pulse/client-conf.c
@@ -149,7 +149,7 @@ void pa_client_conf_load(pa_client_conf *c, bool load_from_x11, bool load_from_e
f = pa_open_config_file(DEFAULT_CLIENT_CONFIG_FILE, DEFAULT_CLIENT_CONFIG_FILE_USER, ENV_CLIENT_CONFIG_FILE, &fn);
if (f) {
- pa_config_parse(fn, f, table, NULL, NULL);
+ pa_config_parse(fn, f, table, NULL, false, NULL);
pa_xfree(fn);
fclose(f);
}
diff --git a/src/pulsecore/conf-parser.c b/src/pulsecore/conf-parser.c
index 2dcd45a..67f3d41 100644
--- a/src/pulsecore/conf-parser.c
+++ b/src/pulsecore/conf-parser.c
@@ -21,6 +21,7 @@
#include <config.h>
#endif
+#include <dirent.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
@@ -103,7 +104,7 @@ static int parse_line(pa_config_parser_state *state) {
}
}
- r = pa_config_parse(fn, NULL, state->item_table, state->proplist, state->userdata);
+ r = pa_config_parse(fn, NULL, state->item_table, state->proplist, false, state->userdata);
pa_xfree(path);
return r;
}
@@ -152,8 +153,13 @@ static int parse_line(pa_config_parser_state *state) {
return normal_assignment(state);
}
+static int conf_filter(const struct dirent *entry) {
+ return pa_endswith(entry->d_name, ".conf");
+}
+
/* Go through the file and parse each line */
-int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, pa_proplist *proplist, void *userdata) {
+int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, pa_proplist *proplist, bool use_dot_d,
+ void *userdata) {
int r = -1;
bool do_close = !f;
pa_config_parser_state state;
@@ -163,6 +169,38 @@ int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, pa_p
pa_zero(state);
+ if (use_dot_d) {
+ char *dir_name;
+ int n;
+ struct dirent **entries = NULL;
+
+ dir_name = pa_sprintf_malloc("%s.d", filename);
+
+ n = scandir(dir_name, &entries, conf_filter, alphasort);
+ if (n >= 0) {
+ int i;
+
+ for (i = 0; i < n; i++) {
+ char *filename2;
+
+ filename2 = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", dir_name, entries[i]->d_name);
+ pa_config_parse(filename2, NULL, t, proplist, false, userdata);
+ pa_xfree(filename2);
+
+ free(entries[i]);
+ }
+
+ free(entries);
+ } else {
+ if (errno == ENOENT)
+ pa_log_debug("%s does not exist, ignoring.", dir_name);
+ else
+ pa_log_warn("scandir(\"%s\") failed: %s", dir_name, pa_cstrerror(errno));
+ }
+
+ pa_xfree(dir_name);
+ }
+
if (!f && !(f = pa_fopen_cloexec(filename, "r"))) {
if (errno == ENOENT) {
pa_log_debug("Failed to open configuration file '%s': %s", filename, pa_cstrerror(errno));
diff --git a/src/pulsecore/conf-parser.h b/src/pulsecore/conf-parser.h
index dbb6f5c..cc20d7d 100644
--- a/src/pulsecore/conf-parser.h
+++ b/src/pulsecore/conf-parser.h
@@ -59,6 +59,11 @@ struct pa_config_parser_state {
* pa_config_items in *t that is terminated by an item where lvalue is
* NULL.
*
+ * If use_dot_d is true, then before parsing the file named by the filename
+ * argument, the function will parse all files ending with ".conf" in
+ * alphabetical order from a directory whose name is filename + ".d", if such
+ * directory exists.
+ *
* Some configuration files may contain a Properties section, which
* is a bit special. Normally all accepted lvalues must be predefined
* in the pa_config_item table, but in the Properties section the
@@ -68,7 +73,8 @@ struct pa_config_parser_state {
* properties, and those properties will be merged into the given
* proplist. If proplist is NULL, then sections named "Properties"
* are not allowed at all in the configuration file. */
-int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, pa_proplist *proplist, void *userdata);
+int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, pa_proplist *proplist, bool use_dot_d,
+ void *userdata);
/* Generic parsers for integers, size_t, booleans and strings */
int pa_config_parse_int(pa_config_parser_state *state);
--
2.6.2
More information about the pulseaudio-discuss
mailing list