summaryrefslogtreecommitdiff
path: root/config.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2013-09-03 09:03:56 +1000
committerNeilBrown <neilb@suse.de>2013-09-03 09:16:33 +1000
commit343b7e75e886c3b1d38fdedf1ecc2e9cd7ec96ad (patch)
treec97a68608fcf328e88325b2f47679bc44e1ac7ca /config.c
parent15af96928334a5a050bd12b3b3479f1b3afee140 (diff)
Conf: allow conf file to be a directory.
If config file is a directory, process each file within with a name ending in ".conf" that doesn't start with ".". Files are processed in lexical order. Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'config.c')
-rw-r--r--config.c63
1 files changed, 62 insertions, 1 deletions
diff --git a/config.c b/config.c
index 3b6f29b2..c15102c7 100644
--- a/config.c
+++ b/config.c
@@ -728,6 +728,67 @@ void conf_file(FILE *f)
}
}
+struct fname {
+ struct fname *next;
+ char name[];
+};
+
+void conf_file_or_dir(FILE *f)
+{
+ struct stat st;
+ DIR *dir;
+ struct dirent *dp;
+ struct fname *list = NULL;
+
+ fstat(fileno(f), &st);
+ if (S_ISREG(st.st_mode))
+ conf_file(f);
+ else if (!S_ISDIR(st.st_mode))
+ return;
+#if _XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L
+ dir = fdopendir(fileno(f));
+ if (!dir)
+ return;
+ while ((dp = readdir(dir)) != NULL) {
+ int l;
+ struct fname *fn, **p;
+ if (dp->d_ino == 0)
+ continue;
+ if (dp->d_name[0] == '.')
+ continue;
+ l = strlen(dp->d_name);
+ if (l < 6 || strcmp(dp->d_name+l-5, ".conf") != 0)
+ continue;
+ fn = xmalloc(sizeof(*fn)+l+1);
+ strcpy(fn->name, dp->d_name);
+ for (p = &list;
+ *p && strcmp((*p)->name, fn->name) < 0;
+ p = & (*p)->next)
+ ;
+ fn->next = *p;
+ *p = fn;
+ }
+ while (list) {
+ int fd;
+ FILE *f2;
+ struct fname *fn = list;
+ list = list->next;
+ fd = openat(fileno(f), fn->name, O_RDONLY);
+ free(fn);
+ if (fd < 0)
+ continue;
+ f2 = fdopen(fd, "r");
+ if (!f2) {
+ close(fd);
+ continue;
+ }
+ conf_file(f2);
+ fclose(f2);
+ }
+ closedir(dir);
+#endif
+}
+
void load_conffile(void)
{
FILE *f;
@@ -765,7 +826,7 @@ void load_conffile(void)
return;
loaded = 1;
- conf_file(f);
+ conf_file_or_dir(f);
fclose(f);