dovecot-2.0: dovecot.conf: Added support for !include globs.
dovecot at dovecot.org
dovecot at dovecot.org
Mon Jul 27 03:59:48 EEST 2009
details: http://hg.dovecot.org/dovecot-2.0/rev/6cc6913fee1c
changeset: 9669:6cc6913fee1c
user: Timo Sirainen <tss at iki.fi>
date: Sun Jul 26 20:59:40 2009 -0400
description:
dovecot.conf: Added support for !include globs.
Based on patch by Thomas Guthmann.
diffstat:
4 files changed, 170 insertions(+), 52 deletions(-)
configure.in | 4 -
dovecot-example.conf | 5 ++
src/config/config-parser.c | 106 ++++++++++++++++++++++++++++++++----------
src/lib-settings/settings.c | 107 ++++++++++++++++++++++++++++++++-----------
diffs (truncated from 319 to 300 lines):
diff -r 462dcad58a92 -r 6cc6913fee1c configure.in
--- a/configure.in Sun Jul 26 20:13:18 2009 -0400
+++ b/configure.in Sun Jul 26 20:59:40 2009 -0400
@@ -292,7 +292,7 @@ AC_CHECK_HEADERS(strings.h stdint.h unis
sys/quota.h sys/fs/ufs_quota.h ufs/ufs/quota.h jfs/quota.h sys/fs/quota_common.h \
mntent.h sys/mnttab.h sys/event.h sys/time.h sys/mkdev.h linux/dqblk_xfs.h \
xfs/xqm.h execinfo.h ucontext.h malloc_np.h sys/utsname.h sys/vmount.h \
- sys/utsname.h)
+ sys/utsname.h glob.h)
dnl * gcc specific options
if test "x$ac_cv_c_compiler_gnu" = "xyes"; then
@@ -351,7 +351,7 @@ AC_CHECK_FUNCS(fcntl flock lockf inet_at
setrlimit setproctitle seteuid setreuid setegid setresgid \
strtoull strtoll strtouq strtoq \
setpriority quotactl getmntent kqueue kevent backtrace_symbols \
- walkcontext dirfd clearenv malloc_usable_size)
+ walkcontext dirfd clearenv malloc_usable_size glob)
AC_CHECK_LIB(rt, clock_gettime, [
AC_DEFINE(HAVE_CLOCK_GETTIME,, Define if you have the clock_gettime function)
diff -r 462dcad58a92 -r 6cc6913fee1c dovecot-example.conf
--- a/dovecot-example.conf Sun Jul 26 20:13:18 2009 -0400
+++ b/dovecot-example.conf Sun Jul 26 20:59:40 2009 -0400
@@ -1213,3 +1213,8 @@ plugin {
# size and vsize are available only for expunge and copy events.
#mail_log_fields = uid box msgid size
}
+
+# Config files can also be included:
+#!include = /etc/dovecot/conf.d/*.conf
+# Optional configurations, don't give an error if it's not found:
+#!include_try = /etc/dovecot/extra.conf
diff -r 462dcad58a92 -r 6cc6913fee1c src/config/config-parser.c
--- a/src/config/config-parser.c Sun Jul 26 20:13:18 2009 -0400
+++ b/src/config/config-parser.c Sun Jul 26 20:59:40 2009 -0400
@@ -12,6 +12,9 @@
#include <unistd.h>
#include <fcntl.h>
+#ifdef HAVE_GLOB_H
+# include <glob.h>
+#endif
#define IS_WHITE(c) ((c) == ' ' || (c) == '\t')
@@ -265,11 +268,84 @@ str_append_file(string_t *str, const cha
(void)close(fd);
}
+static int settings_add_include(struct parser_context *ctx, const char *path,
+ bool ignore_errors, const char **error_r)
+{
+ struct input_stack *tmp, *new_input;
+ int fd;
+
+ for (tmp = ctx->cur_input; tmp != NULL; tmp = tmp->prev) {
+ if (strcmp(tmp->path, path) == 0)
+ break;
+ }
+ if (tmp != NULL) {
+ *error_r = t_strdup_printf("Recursive include file: %s", path);
+ return -1;
+ }
+
+ if ((fd = open(path, O_RDONLY)) == -1) {
+ if (ignore_errors)
+ return 0;
+
+ *error_r = t_strdup_printf("Couldn't open include file %s: %m",
+ path);
+ return -1;
+ }
+
+ new_input = t_new(struct input_stack, 1);
+ new_input->prev = ctx->cur_input;
+ new_input->path = t_strdup(path);
+ new_input->input = i_stream_create_fd(fd, 2048, TRUE);
+ i_stream_set_return_partial_line(new_input->input, TRUE);
+ ctx->cur_input = new_input;
+ return 0;
+}
+
+static int
+settings_include(struct parser_context *ctx, const char *pattern,
+ bool ignore_errors, const char **error_r)
+{
+#ifdef HAVE_GLOB
+ glob_t globbers;
+ unsigned int i;
+
+ switch (glob(pattern, GLOB_BRACE, NULL, &globbers)) {
+ case 0:
+ break;
+ case GLOB_NOSPACE:
+ *error_r = "glob() failed: Not enough memory";
+ return -1;
+ case GLOB_ABORTED:
+ *error_r = "glob() failed: Read error";
+ return -1;
+ case GLOB_NOMATCH:
+ if (ignore_errors)
+ return 0;
+ *error_r = "No matches";
+ return -1;
+ default:
+ *error_r = "glob() failed: Unknown error";
+ return -1;
+ }
+
+ /* iterate throuth the different files matching the globbing */
+ for (i = 0; i < globbers.gl_pathc; i++) {
+ if (settings_add_include(ctx, globbers.gl_pathv[i],
+ ignore_errors, error_r) < 0)
+ return -1;
+ }
+ globfree(&globbers);
+ return 0;
+#else
+ return settings_add_include(ctx, pattern, ignore_errors, error_r);
+#endif
+}
+
void config_parse_file(const char *path, bool expand_files)
{
enum settings_parser_flags parser_flags =
SETTINGS_PARSER_FLAG_IGNORE_UNKNOWN_KEYS;
- struct input_stack root, *new_input;
+ struct input_stack root;
ARRAY_TYPE(const_string) auth_defaults;
struct config_setting_parser_list *l, *const *parsers;
struct parser_context ctx;
@@ -314,7 +390,6 @@ void config_parse_file(const char *path,
str = t_str_new(256);
full_line = t_str_new(512);
errormsg = NULL;
-newfile:
ctx.cur_input->input = i_stream_create_fd(fd, (size_t)-1, TRUE);
i_stream_set_return_partial_line(ctx.cur_input->input, TRUE);
prevfile:
@@ -378,29 +453,10 @@ prevfile:
ret = 1;
if (strcmp(key, "!include_try") == 0 ||
strcmp(key, "!include") == 0) {
- struct input_stack *tmp;
- const char *path;
-
- path = fix_relative_path(line, ctx.cur_input);
- for (tmp = ctx.cur_input; tmp != NULL; tmp = tmp->prev) {
- if (strcmp(tmp->path, path) == 0)
- break;
- }
- if (tmp != NULL) {
- errormsg = "Recursive include";
- } else if ((fd = open(path, O_RDONLY)) != -1) {
- new_input = t_new(struct input_stack, 1);
- new_input->prev = ctx.cur_input;
- new_input->path = t_strdup(path);
- ctx.cur_input = new_input;
- goto newfile;
- } else {
- /* failed, but ignore failures with include_try. */
- if (strcmp(key, "!include") == 0) {
- errormsg = t_strdup_printf(
- "Couldn't open include file %s: %m", line);
- }
- }
+ if (settings_include(&ctx, fix_relative_path(line, ctx.cur_input),
+ strcmp(key, "!include_try") == 0,
+ &errormsg) == 0)
+ goto prevfile;
} else if (*line == '=') {
/* a) */
*line++ = '\0';
diff -r 462dcad58a92 -r 6cc6913fee1c src/lib-settings/settings.c
--- a/src/lib-settings/settings.c Sun Jul 26 20:13:18 2009 -0400
+++ b/src/lib-settings/settings.c Sun Jul 26 20:59:40 2009 -0400
@@ -8,6 +8,9 @@
#include <stdio.h>
#include <fcntl.h>
+#ifdef HAVE_GLOB_H
+# include <glob.h>
+#endif
#define SECTION_ERRORMSG "%s (section changed in %s at line %d)"
@@ -85,6 +88,79 @@ fix_relative_path(const char *path, stru
return t_strconcat(t_strdup_until(input->path, p+1), path, NULL);
}
+static int settings_add_include(const char *path, struct input_stack **inputp,
+ bool ignore_errors, const char **error_r)
+{
+ struct input_stack *tmp, *new_input;
+ int fd;
+
+ for (tmp = *inputp; tmp != NULL; tmp = tmp->prev) {
+ if (strcmp(tmp->path, path) == 0)
+ break;
+ }
+ if (tmp != NULL) {
+ *error_r = t_strdup_printf("Recursive include file: %s", path);
+ return -1;
+ }
+
+ if ((fd = open(path, O_RDONLY)) == -1) {
+ if (ignore_errors)
+ return 0;
+
+ *error_r = t_strdup_printf("Couldn't open include file %s: %m",
+ path);
+ return -1;
+ }
+
+ new_input = t_new(struct input_stack, 1);
+ new_input->prev = *inputp;
+ new_input->path = t_strdup(path);
+ new_input->input = i_stream_create_fd(fd, 2048, TRUE);
+ i_stream_set_return_partial_line(new_input->input, TRUE);
+ *inputp = new_input;
+ return 0;
+}
+
+static int
+settings_include(const char *pattern, struct input_stack **inputp,
+ bool ignore_errors, const char **error_r)
+{
+#ifdef HAVE_GLOB
+ glob_t globbers;
+ unsigned int i;
+
+ switch (glob(pattern, GLOB_BRACE, NULL, &globbers)) {
+ case 0:
+ break;
+ case GLOB_NOSPACE:
+ *error_r = "glob() failed: Not enough memory";
+ return -1;
+ case GLOB_ABORTED:
+ *error_r = "glob() failed: Read error";
+ return -1;
+ case GLOB_NOMATCH:
+ if (ignore_errors)
+ return 0;
+ *error_r = "No matches";
+ return -1;
+ default:
+ *error_r = "glob() failed: Unknown error";
+ return -1;
+ }
+
+ /* iterate throuth the different files matching the globbing */
+ for (i = 0; i < globbers.gl_pathc; i++) {
+ if (settings_add_include(globbers.gl_pathv[i], inputp,
+ ignore_errors, error_r) < 0)
+ return -1;
+ }
+ globfree(&globbers);
+ return 0;
+#else
+ return settings_add_include(pattern, inputp, ignore_errors, error_r);
+#endif
+}
+
#define IS_WHITE(c) ((c) == ' ' || (c) == '\t')
static bool
@@ -93,7 +169,7 @@ settings_read_real(const char *path, con
settings_section_callback_t *sect_callback, void *context)
{
/* pretty horrible code, but v2.0 will have this rewritten anyway.. */
- struct input_stack root, *input, *new_input;
+ struct input_stack root, *input;
const char *errormsg, *next_section, *name, *last_section_path = NULL;
char *line, *key, *p, quote;
string_t *full_line;
@@ -120,7 +196,6 @@ settings_read_real(const char *path, con
full_line = t_str_new(512);
sections = 0; root_section = 0; errormsg = NULL;
-newfile:
input->input = i_stream_create_fd(fd, 2048, TRUE);
i_stream_set_return_partial_line(input->input, TRUE);
prevfile:
@@ -183,29 +258,11 @@ prevfile:
if (strcmp(key, "!include_try") == 0 ||
strcmp(key, "!include") == 0) {
- struct input_stack *tmp;
- const char *path;
-
- path = fix_relative_path(line, input);
- for (tmp = input; tmp != NULL; tmp = tmp->prev) {
- if (strcmp(tmp->path, path) == 0)
- break;
- }
- if (tmp != NULL) {
- errormsg = "Recursive include";
- } else if ((fd = open(path, O_RDONLY)) != -1) {
- new_input = t_new(struct input_stack, 1);
More information about the dovecot-cvs
mailing list