Mercurial > dovecot > core-2.2
changeset 9274:39c2db5f1fcc HEAD
config: If value contains <file, the setting value is read from the given file.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 13 May 2009 19:51:34 -0400 |
parents | 1d7965092e0e |
children | c38f3fb4c6b6 |
files | src/config/config-connection.c src/config/config-parser.c src/config/config-parser.h src/config/doveconf.c src/config/main.c src/lib-settings/settings-parser.c src/lib-settings/settings-parser.h |
diffstat | 7 files changed, 79 insertions(+), 43 deletions(-) [+] |
line wrap: on
line diff
--- 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 @@ 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"); }
--- 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_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 @@ 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 {
--- 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
--- 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 @@ } master_service_init_finish(service); - config_parse_file(config_path); + config_parse_file(config_path, FALSE); if (exec_args == NULL) { const char *info;
--- 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 @@ 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();
--- 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 @@ 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; + } 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; - } - str_truncate(full_line, 0); + if (ret < 0) { + ctx->error = p_strdup_printf(ctx->parser_pool, + "Line %u: %s", ctx->linenum, ctx->error); + ret = -1; + break; } } - str_free(&full_line); return ret; }
--- 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 @@ -13,6 +13,9 @@ #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 */ SET_BOOL,