dovecot-2.0: config: $setting as value returns the setting's cur...

dovecot at dovecot.org dovecot at dovecot.org
Sat Feb 13 08:09:11 EET 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/c26002b81f57
changeset: 10704:c26002b81f57
user:      Timo Sirainen <tss at iki.fi>
date:      Sat Feb 13 08:07:31 2010 +0200
description:
config: $setting as value returns the setting's current value.

diffstat:

 src/config/config-parser.c         |   84 ++++++++++++++++++--
 src/config/config-parser.h         |    2 +-
 src/config/config-request.c        |  166 +++++++++++++++++++++++-----------------
 src/config/config-request.h        |    6 +
 src/lib-settings/settings-parser.c |   16 ++++
 src/lib-settings/settings-parser.h |    4 +
 6 files changed, 197 insertions(+), 81 deletions(-)

diffs (truncated from 402 to 300 lines):

diff -r 951a90e95ebe -r c26002b81f57 src/config/config-parser.c
--- a/src/config/config-parser.c	Sat Feb 13 07:25:56 2010 +0200
+++ b/src/config/config-parser.c	Sat Feb 13 08:07:31 2010 +0200
@@ -11,6 +11,7 @@
 #include "service-settings.h"
 #include "all-settings.h"
 #include "config-filter.h"
+#include "config-request.h"
 #include "config-parser.h"
 
 #include <stdlib.h>
@@ -53,6 +54,7 @@
 	struct input_stack *cur_input;
 
 	struct config_filter_context *filter;
+	unsigned int expand_values:1;
 };
 
 static const enum settings_parser_flags settings_parser_flags =
@@ -445,6 +447,7 @@
 	CONFIG_LINE_TYPE_ERROR,
 	CONFIG_LINE_TYPE_KEYVALUE,
 	CONFIG_LINE_TYPE_KEYFILE,
+	CONFIG_LINE_TYPE_KEYVARIABLE,
 	CONFIG_LINE_TYPE_SECTION_BEGIN,
 	CONFIG_LINE_TYPE_SECTION_END,
 	CONFIG_LINE_TYPE_INCLUDE,
@@ -542,6 +545,10 @@
 			*value_r = line + 1;
 			return CONFIG_LINE_TYPE_KEYFILE;
 		}
+		if (*line == '$') {
+			*value_r = line + 1;
+			return CONFIG_LINE_TYPE_KEYVARIABLE;
+		}
 
 		len = strlen(line);
 		if (len > 0 &&
@@ -607,7 +614,71 @@
 	return ret;
 }
 
-int config_parse_file(const char *path, bool expand_files,
+static const void *
+config_get_value(struct parser_context *ctx, const char *key,
+		 enum setting_type *type_r)
+{
+	struct config_module_parser *l;
+	const void *value;
+
+	for (l = ctx->cur_section->parsers; l->root != NULL; l++) {
+		value = settings_parse_get_value(l->parser, key, type_r);
+		if (value != NULL)
+			return value;
+	}
+	return NULL;
+}
+
+static int config_write_value(struct parser_context *ctx,
+			      string_t *str, enum config_line_type type,
+			      const char *key, const char *value,
+			      const char **errormsg_r)
+{
+	const void *var_value;
+	enum setting_type var_type;
+	bool dump;
+
+	switch (type) {
+	case CONFIG_LINE_TYPE_KEYVALUE:
+		str_append(str, value);
+		break;
+	case CONFIG_LINE_TYPE_KEYFILE:
+		if (!ctx->expand_values) {
+			str_append_c(str, '<');
+			str_append(str, value);
+		} else {
+			if (str_append_file(str, key, value, errormsg_r) < 0) {
+				/* file reading failed */
+				return -1;
+			}
+		}
+		break;
+	case CONFIG_LINE_TYPE_KEYVARIABLE:
+		if (!ctx->expand_values) {
+			str_append_c(str, '$');
+			str_append(str, value);
+		} else {
+			var_value = config_get_value(ctx, value, &var_type);
+			if (var_value == NULL) {
+				*errormsg_r = t_strconcat("Unknown variable: $",
+							  value, NULL);
+				return -1;
+			}
+			if (!config_export_type(str, var_value, NULL,
+						var_type, TRUE, &dump)) {
+				*errormsg_r = t_strconcat("Invalid variable: $",
+							  value, NULL);
+				return -1;
+			}
+		}
+		break;
+	default:
+		i_unreached();
+	}
+	return 0;
+}
+
+int config_parse_file(const char *path, bool expand_values,
 		      const char **error_r)
 {
 	struct input_stack root;
@@ -643,6 +714,7 @@
 	memset(&root, 0, sizeof(root));
 	root.path = path;
 	ctx.cur_input = &root;
+	ctx.expand_values = expand_values;
 
 	p_array_init(&ctx.all_parsers, ctx.pool, 128);
 	ctx.cur_section = p_new(ctx.pool, struct config_section_stack, 1);
@@ -666,19 +738,13 @@
 			break;
 		case CONFIG_LINE_TYPE_KEYVALUE:
 		case CONFIG_LINE_TYPE_KEYFILE:
+		case CONFIG_LINE_TYPE_KEYVARIABLE:
 			str_truncate(str, pathlen);
 			str_append(str, key);
 			str_append_c(str, '=');
 
-			if (type != CONFIG_LINE_TYPE_KEYFILE)
-				str_append(str, value);
-			else if (!expand_files) {
-				str_append_c(str, '<');
-				str_append(str, value);
-			} else if (str_append_file(str, key, value, &errormsg) < 0) {
-				/* file reading failed */
+			if (config_write_value(&ctx, str, type, key, value, &errormsg) < 0)
 				break;
-			}
 			(void)config_apply_line(&ctx, key, str_c(str), NULL, &errormsg);
 			break;
 		case CONFIG_LINE_TYPE_SECTION_BEGIN:
diff -r 951a90e95ebe -r c26002b81f57 src/config/config-parser.h
--- a/src/config/config-parser.h	Sat Feb 13 07:25:56 2010 +0200
+++ b/src/config/config-parser.h	Sat Feb 13 08:07:31 2010 +0200
@@ -13,7 +13,7 @@
 extern struct config_module_parser *config_module_parsers;
 extern struct config_filter_context *config_filter;
 
-int config_parse_file(const char *path, bool expand_files,
+int config_parse_file(const char *path, bool expand_values,
 		      const char **error_r);
 
 void config_parse_load_modules(void);
diff -r 951a90e95ebe -r c26002b81f57 src/config/config-request.c
--- a/src/config/config-request.c	Sat Feb 13 07:25:56 2010 +0200
+++ b/src/config/config-request.c	Sat Feb 13 08:07:31 2010 +0200
@@ -71,6 +71,91 @@
 	return FALSE;
 }
 
+bool config_export_type(string_t *str, const void *value,
+			const void *default_value,
+			enum setting_type type, bool dump_default,
+			bool *dump_r)
+{
+	switch (type) {
+	case SET_BOOL: {
+		const bool *val = value, *dval = default_value;
+
+		if (dump_default || dval == NULL || *val != *dval)
+			str_append(str, *val ? "yes" : "no");
+		break;
+	}
+	case SET_SIZE: {
+		const uoff_t *val = value, *dval = default_value;
+
+		if (dump_default || dval == NULL || *val != *dval)
+			str_printfa(str, "%llu", (unsigned long long)*val);
+		break;
+	}
+	case SET_UINT:
+	case SET_UINT_OCT:
+	case SET_TIME: {
+		const unsigned int *val = value, *dval = default_value;
+
+		if (dump_default || dval == NULL || *val != *dval) {
+			switch (type) {
+			case SET_UINT_OCT:
+				str_printfa(str, "0%o", *val);
+				break;
+			case SET_TIME:
+				str_printfa(str, "%u s", *val);
+				break;
+			default:
+				str_printfa(str, "%u", *val);
+				break;
+			}
+		}
+		break;
+	}
+	case SET_STR_VARS: {
+		const char *const *val = value, *sval;
+		const char *const *_dval = default_value;
+		const char *dval = _dval == NULL ? NULL : *_dval;
+
+		i_assert(*val == NULL ||
+			 **val == SETTING_STRVAR_UNEXPANDED[0]);
+
+		sval = *val == NULL ? NULL : (*val + 1);
+		if ((dump_default || null_strcmp(sval, dval) != 0) &&
+		    sval != NULL) {
+			str_append(str, sval);
+			*dump_r = TRUE;
+		}
+		break;
+	}
+	case SET_STR: {
+		const char *const *val = value;
+		const char *const *_dval = default_value;
+		const char *dval = _dval == NULL ? NULL : *_dval;
+
+		if ((dump_default || null_strcmp(*val, dval) != 0) &&
+		    *val != NULL) {
+			str_append(str, *val);
+			*dump_r = TRUE;
+		}
+		break;
+	}
+	case SET_ENUM: {
+		const char *const *val = value;
+		const char *const *_dval = default_value;
+		const char *dval = _dval == NULL ? NULL : *_dval;
+		unsigned int len = strlen(*val);
+
+		if (dump_default || strncmp(*val, dval, len) != 0 ||
+		    ((*val)[len] != ':' && (*val)[len] != '\0'))
+			str_append(str, *val);
+		break;
+	}
+	default:
+		return FALSE;
+	}
+	return TRUE;
+}
+
 static void
 settings_export(struct settings_export_context *ctx,
 		const struct setting_parser_info *info,
@@ -120,80 +205,19 @@
 		count = 0;
 		str_truncate(ctx->value, 0);
 		switch (def->type) {
-		case SET_BOOL: {
-			const bool *val = value, *dval = default_value;
-			if (dump_default || dval == NULL || *val != *dval) {
-				str_append(ctx->value,
-					   *val ? "yes" : "no");
-			}
-			break;
-		}
-		case SET_SIZE: {
-			const uoff_t *val = value, *dval = default_value;
-			if (dump_default || dval == NULL || *val != *dval) {
-				str_printfa(ctx->value, "%llu",
-					    (unsigned long long)*val);
-			}
-			break;
-		}
+		case SET_BOOL:
+		case SET_SIZE:
 		case SET_UINT:
 		case SET_UINT_OCT:
-		case SET_TIME: {
-			const unsigned int *val = value, *dval = default_value;
-			if (dump_default || dval == NULL || *val != *dval) {
-				switch (def->type) {
-				case SET_UINT_OCT:
-					str_printfa(ctx->value, "0%o", *val);
-					break;
-				case SET_TIME:
-					str_printfa(ctx->value, "%u s", *val);
-					break;
-				default:
-					str_printfa(ctx->value, "%u", *val);
-					break;
-				}
-			}
+		case SET_TIME:
+		case SET_STR_VARS:
+		case SET_STR:
+		case SET_ENUM:
+			if (!config_export_type(ctx->value, value,
+						default_value, def->type,
+						dump_default, &dump))
+				i_unreached();
 			break;
-		}
-		case SET_STR_VARS: {
-			const char *const *val = value, *sval;
-			const char *const *_dval = default_value;


More information about the dovecot-cvs mailing list