dovecot-1.2: Added !include and !include_try directives to confi...
dovecot at dovecot.org
dovecot at dovecot.org
Wed Nov 19 19:37:30 EET 2008
details: http://hg.dovecot.org/dovecot-1.2/rev/e14aabe52d8e
changeset: 8451:e14aabe52d8e
user: Timo Sirainen <tss at iki.fi>
date: Wed Nov 19 19:37:26 2008 +0200
description:
Added !include and !include_try directives to config file reader.
diffstat:
1 file changed, 59 insertions(+), 14 deletions(-)
src/lib-settings/settings.c | 73 ++++++++++++++++++++++++++++++++++---------
diffs (136 lines):
diff -r f532e962f05d -r e14aabe52d8e src/lib-settings/settings.c
--- a/src/lib-settings/settings.c Wed Nov 19 19:10:26 2008 +0200
+++ b/src/lib-settings/settings.c Wed Nov 19 19:37:26 2008 +0200
@@ -9,7 +9,15 @@
#include <stdio.h>
#include <fcntl.h>
-#define SECTION_ERRORMSG "%s (section changed at line %d)"
+#define SECTION_ERRORMSG "%s (section changed in %s at line %d)"
+
+struct input_stack {
+ struct input_stack *prev;
+
+ struct istream *input;
+ const char *path;
+ unsigned int linenum;
+};
settings_section_callback_t *null_settings_section_callback = NULL;
@@ -69,12 +77,13 @@ settings_read_real(const char *path, con
settings_callback_t *callback,
settings_section_callback_t *sect_callback, void *context)
{
- struct istream *input;
- const char *errormsg, *next_section, *name;
+ /* pretty horrible code, but v2.0 will have this rewritten anyway.. */
+ struct input_stack root, *input, *new_input;
+ const char *errormsg, *next_section, *name, *last_section_path = NULL;
char *line, *key, *p, quote;
string_t *full_line;
size_t len;
- int fd, linenum, last_section_line = 0, skip, sections, root_section;
+ int fd, last_section_line = 0, skip, sections, root_section;
fd = open(path, O_RDONLY);
if (fd < 0) {
@@ -90,12 +99,18 @@ settings_read_real(const char *path, con
next_section = t_strcut(section, '/');
}
+ memset(&root, 0, sizeof(root));
+ root.path = path;
+ input = &root;
+
full_line = t_str_new(512);
- linenum = 0; sections = 0; root_section = 0; errormsg = NULL;
- input = i_stream_create_fd(fd, 2048, TRUE);
- i_stream_set_return_partial_line(input, TRUE);
- while ((line = i_stream_read_next_line(input)) != NULL) {
- linenum++;
+ 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:
+ while ((line = i_stream_read_next_line(input->input)) != NULL) {
+ input->linenum++;
/* @UNSAFE: line is modified */
@@ -151,7 +166,30 @@ settings_read_real(const char *path, con
while (IS_WHITE(*line)) line++;
}
- if (*line == '=') {
+ if (strcmp(key, "!include_try") == 0 ||
+ strcmp(key, "!include") == 0) {
+ struct input_stack *tmp;
+
+ for (tmp = input; tmp != NULL; tmp = tmp->prev) {
+ if (strcmp(tmp->path, line) == 0)
+ break;
+ }
+ if (tmp != NULL) {
+ errormsg = "Recursive include";
+ } else if ((fd = open(line, O_RDONLY)) != -1) {
+ new_input = t_new(struct input_stack, 1);
+ new_input->prev = input;
+ new_input->path = t_strdup(line);
+ 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);
+ }
+ }
+ } else if (*line == '=') {
/* a) */
*line++ = '\0';
while (IS_WHITE(*line)) line++;
@@ -215,10 +253,12 @@ settings_read_real(const char *path, con
errormsg = t_strdup_printf(
SECTION_ERRORMSG,
errormsg,
+ last_section_path,
last_section_line);
}
}
- last_section_line = linenum;
+ last_section_path = input->path;
+ last_section_line = input->linenum;
}
} else {
/* c) */
@@ -237,20 +277,25 @@ settings_read_real(const char *path, con
break;
}
}
- last_section_line = linenum;
+ last_section_path = input->path;
+ last_section_line = input->linenum;
sections--;
}
}
if (errormsg != NULL) {
i_error("Error in configuration file %s line %d: %s",
- path, linenum, errormsg);
+ input->path, input->linenum, errormsg);
break;
}
str_truncate(full_line, 0);
}
- i_stream_destroy(&input);
+ i_stream_destroy(&input->input);
+ input = input->prev;
+ if (line == NULL && input != NULL)
+ goto prevfile;
+
return errormsg == NULL;
}
More information about the dovecot-cvs
mailing list