dovecot-2.0: config: If value contains <file, the setting value ...
dovecot at dovecot.org
dovecot at dovecot.org
Thu May 14 02:52:43 EEST 2009
details: http://hg.dovecot.org/dovecot-2.0/rev/39c2db5f1fcc
changeset: 9274:39c2db5f1fcc
user: Timo Sirainen <tss at iki.fi>
date: Wed May 13 19:51:34 2009 -0400
description:
config: If value contains <file, the setting value is read from the given file.
diffstat:
7 files changed, 83 insertions(+), 47 deletions(-)
src/config/config-connection.c | 7 +++
src/config/config-parser.c | 45 ++++++++++++++++++++---
src/config/config-parser.h | 2 -
src/config/doveconf.c | 2 -
src/config/main.c | 2 -
src/lib-settings/settings-parser.c | 69 +++++++++++++++---------------------
src/lib-settings/settings-parser.h | 3 +
diffs (235 lines):
diff -r 1d7965092e0e -r 39c2db5f1fcc src/config/config-connection.c
--- a/src/config/config-connection.c Wed May 13 17:51:16 2009 -0400
+++ b/src/config/config-connection.c Wed May 13 19:51:34 2009 -0400
@@ -4,6 +4,7 @@
#include "llist.h"
#include "istream.h"
#include "ostream.h"
+#include "settings-parser.h"
#include "config-request.h"
#include "config-connection.h"
@@ -46,9 +47,15 @@ config_request_output(const char *key, c
bool list ATTR_UNUSED, void *context)
{
struct ostream *output = context;
+ const char *p;
o_stream_send_str(output, key);
o_stream_send_str(output, "=");
+ while ((p = strchr(value, '\n')) != NULL) {
+ o_stream_send(output, value, p-value);
+ o_stream_send(output, SETTING_STREAM_LF_CHAR, 1);
+ value = p+1;
+ }
o_stream_send_str(output, value);
o_stream_send_str(output, "\n");
}
diff -r 1d7965092e0e -r 39c2db5f1fcc src/config/config-parser.c
--- a/src/config/config-parser.c Wed May 13 17:51:16 2009 -0400
+++ b/src/config/config-parser.c Wed May 13 19:51:34 2009 -0400
@@ -242,7 +242,30 @@ config_all_parsers_check(struct parser_c
config_filter_parser_list_check(ctx, parsers[i]);
}
-void config_parse_file(const char *path)
+static void
+str_append_file(string_t *str, const char *key, const char *path,
+ const char **error_r)
+{
+ unsigned char buf[1024];
+ int fd;
+ ssize_t ret;
+
+ fd = open(path, O_RDONLY);
+ if (fd == -1) {
+ *error_r = t_strdup_printf("%s: Can't open file %s: %m",
+ key, path);
+ return;
+ }
+ while ((ret = read(fd, buf, sizeof(buf))) > 0)
+ str_append_n(str, buf, ret);
+ if (ret < 0) {
+ *error_r = t_strdup_printf("%s: read(%s) failed: %m",
+ key, path);
+ }
+ (void)close(fd);
+}
+
+void config_parse_file(const char *path, bool expand_files)
{
enum settings_parser_flags parser_flags =
SETTINGS_PARSER_FLAG_IGNORE_UNKNOWN_KEYS;
@@ -394,15 +417,27 @@ prevfile:
str_truncate(str, pathlen);
str_append(str, key);
str_append_c(str, '=');
- str_append(str, line);
- if (pathlen == 0 &&
- strncmp(str_c(str), "auth_", 5) == 0) {
+
+ if (*line != '<' || !expand_files)
+ str_append(str, line);
+ else
+ str_append_file(str, key, line+1, &errormsg);
+
+ if (errormsg != NULL) {
+ /* file reading failed */
+ } else if (pathlen == 0 &&
+ strncmp(str_c(str), "auth_", 5) == 0) {
/* verify that the setting is valid,
but delay actually adding it */
const char *s = t_strdup(str_c(str) + 5);
str_truncate(str, 0);
- str_printfa(str, "auth/0/%s=%s", key + 5, line);
+ str_printfa(str, "auth/0/%s=", key + 5);
+ if (*line != '<' || !expand_files)
+ str_append(str, line);
+ else
+ str_append_file(str, key, line+1, &errormsg);
+
errormsg = config_parse_line(parsers, key + 5, str_c(str), NULL);
array_append(&auth_defaults, &s, 1);
} else {
diff -r 1d7965092e0e -r 39c2db5f1fcc src/config/config-parser.h
--- a/src/config/config-parser.h Wed May 13 17:51:16 2009 -0400
+++ b/src/config/config-parser.h Wed May 13 19:51:34 2009 -0400
@@ -3,6 +3,6 @@
extern struct config_filter_context *config_filter;
-void config_parse_file(const char *path);
+void config_parse_file(const char *path, bool expand_files);
#endif
diff -r 1d7965092e0e -r 39c2db5f1fcc src/config/doveconf.c
--- a/src/config/doveconf.c Wed May 13 17:51:16 2009 -0400
+++ b/src/config/doveconf.c Wed May 13 19:51:34 2009 -0400
@@ -248,7 +248,7 @@ int main(int argc, char *argv[])
}
master_service_init_finish(service);
- config_parse_file(config_path);
+ config_parse_file(config_path, FALSE);
if (exec_args == NULL) {
const char *info;
diff -r 1d7965092e0e -r 39c2db5f1fcc src/config/main.c
--- a/src/config/main.c Wed May 13 17:51:16 2009 -0400
+++ b/src/config/main.c Wed May 13 19:51:34 2009 -0400
@@ -30,7 +30,7 @@ int main(int argc, char *argv[])
master_service_init_log(service, "config: ", 0);
master_service_init_finish(service);
- config_parse_file(master_service_get_config_path(service));
+ config_parse_file(master_service_get_config_path(service), TRUE);
master_service_run(service, client_connected);
config_connections_destroy_all();
diff -r 1d7965092e0e -r 39c2db5f1fcc src/lib-settings/settings-parser.c
--- a/src/lib-settings/settings-parser.c Wed May 13 17:51:16 2009 -0400
+++ b/src/lib-settings/settings-parser.c Wed May 13 19:51:34 2009 -0400
@@ -449,59 +449,50 @@ settings_parse_get_prev_info(struct sett
return ctx->prev_info;
}
+static const char *settings_translate_lf(const char *value)
+{
+ char *dest, *p;
+
+ if (strchr(value, SETTING_STREAM_LF_CHAR[0]) == NULL)
+ return value;
+
+ dest = t_strdup_noconst(value);
+ for (p = dest; *p != '\0'; p++) {
+ if (*p == SETTING_STREAM_LF_CHAR[0])
+ *p = '\n';
+ }
+ return dest;
+}
+
int settings_parse_stream(struct setting_parser_context *ctx,
struct istream *input)
{
const char *line;
- string_t *full_line;
- size_t len;
int ret = 1;
- full_line = str_new(default_pool, 512);
while ((line = i_stream_next_line(input)) != NULL) {
if (*line == '\0') {
/* empty line finishes it */
ret = 0;
break;
}
-
ctx->linenum++;
- while (IS_WHITE(*line == ' '))
- line++;
- if (*line == '\0' || *line == '#')
- continue;
-
- len = strlen(line);
- while (len > 0 && IS_WHITE(line[len-1]))
- len--;
- if (line[len] == '\\') {
- /* line continues */
- str_append_n(full_line, line, len - 1);
- } else {
- /* full line */
- if (str_len(full_line) > 0) {
- str_append_n(full_line, line, len);
- line = str_c(full_line);
- }
-
+
+ T_BEGIN {
+ line = settings_translate_lf(line);
ret = settings_parse_line(ctx, line);
- if (ret == 0 &&
- (ctx->flags &
- SETTINGS_PARSER_FLAG_IGNORE_UNKNOWN_KEYS) == 0)
- ret = -1;
-
- if (ret < 0) {
- ctx->error = p_strdup_printf(ctx->parser_pool,
- "Line %u: %s",
- ctx->linenum,
- ctx->error);
- ret = -1;
- break;
- }
- str_truncate(full_line, 0);
- }
- }
- str_free(&full_line);
+ } T_END;
+ if (ret == 0 && (ctx->flags &
+ SETTINGS_PARSER_FLAG_IGNORE_UNKNOWN_KEYS) == 0)
+ ret = -1;
+
+ if (ret < 0) {
+ ctx->error = p_strdup_printf(ctx->parser_pool,
+ "Line %u: %s", ctx->linenum, ctx->error);
+ ret = -1;
+ break;
+ }
+ }
return ret;
}
diff -r 1d7965092e0e -r 39c2db5f1fcc src/lib-settings/settings-parser.h
--- a/src/lib-settings/settings-parser.h Wed May 13 17:51:16 2009 -0400
+++ b/src/lib-settings/settings-parser.h Wed May 13 19:51:34 2009 -0400
@@ -12,6 +12,9 @@ struct var_expand_table;
the initial '1' so it'll be easy to use them. */
#define SETTING_STRVAR_UNEXPANDED "0"
#define SETTING_STRVAR_EXPANDED "1"
+
+/* When parsing streams, this character is translated to LF. */
+#define SETTING_STREAM_LF_CHAR "\003"
enum setting_type {
SET_INTERNAL, /* don't set this variable */
More information about the dovecot-cvs
mailing list