dovecot-2.0-sslstream: config: Added SET_DEFLIST_UNIQUE type. Se...

dovecot at dovecot.org dovecot at dovecot.org
Sat Feb 13 02:55:37 EET 2010


details:   http://hg.dovecot.org/dovecot-2.0-sslstream/rev/eaac22ecc168
changeset: 10176:eaac22ecc168
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Oct 23 19:10:42 2009 -0400
description:
config: Added SET_DEFLIST_UNIQUE type. Settings in unique sections can be overridden.

diffstat:

4 files changed, 214 insertions(+), 53 deletions(-)
src/config/config-parser.c         |   50 +++++++-
src/config/config-request.c        |    7 -
src/lib-settings/settings-parser.c |  207 ++++++++++++++++++++++++++++--------
src/lib-settings/settings-parser.h |    3 

diffs (truncated from 466 to 300 lines):

diff -r 429641734346 -r eaac22ecc168 src/config/config-parser.c
--- a/src/config/config-parser.c	Fri Oct 23 19:09:33 2009 -0400
+++ b/src/config/config-parser.c	Fri Oct 23 19:10:42 2009 -0400
@@ -565,14 +565,49 @@ static int config_parse_finish(struct pa
 	return 0;
 }
 
+static const char *section_name_escape(const char *name)
+{
+#define CHAR_NEED_ESCAPE(c) \
+	((c) == '=' || (c) == SETTINGS_SEPARATOR || (c) == '\\')
+	string_t *str;
+	unsigned int i;
+
+	for (i = 0; name[i] != '\0'; i++) {
+		if (CHAR_NEED_ESCAPE(name[i]))
+			break;
+	}
+	if (name[i] == '\0')
+		return name;
+
+	str = t_str_new(i + strlen(name+i) + 8);
+	str_append_n(str, name, i);
+	for (; name[i] != '\0'; i++) {
+		switch (name[i]) {
+		case '=':
+			str_append(str, "\\e");
+			break;
+		case SETTINGS_SEPARATOR:
+			str_append(str, "\\s");
+			break;
+		case '\\':
+			str_append(str, "\\\\");
+			break;
+		default:
+			str_append_c(str, name[i]);
+			break;
+		}
+	}
+	return str_c(str);
+}
+
 int config_parse_file(const char *path, bool expand_files,
 		      const char **error_r)
 {
 	struct input_stack root;
 	struct parser_context ctx;
 	unsigned int pathlen = 0;
-	unsigned int i, count, counter = 0, cur_counter;
-	const char *errormsg, *key, *value;
+	unsigned int i, count, counter = 0;
+	const char *errormsg, *key, *value, *section_name;
 	string_t *str, *full_line;
 	enum config_line_type type;
 	char *line;
@@ -650,20 +685,25 @@ prevfile:
 			}
 
 			/* new config section */
+			if (*value == '\0') {
+				/* no section name, use a counter */
+				section_name = dec2str(counter++);
+			} else {
+				section_name = section_name_escape(value);
+			}
 			str_truncate(str, pathlen);
 			str_append(str, key);
 			pathlen = str_len(str);
-			cur_counter = counter++;
 
 			str_append_c(str, '=');
-			str_printfa(str, "%u", cur_counter);
+			str_append(str, section_name);
 
 			if (config_apply_line(&ctx, key, str_c(str), value, &errormsg) < 0)
 				break;
 
 			str_truncate(str, pathlen);
 			str_append_c(str, SETTINGS_SEPARATOR);
-			str_printfa(str, "%u", cur_counter);
+			str_append(str, section_name);
 			str_append_c(str, SETTINGS_SEPARATOR);
 			pathlen = str_len(str);
 			break;
diff -r 429641734346 -r eaac22ecc168 src/config/config-request.c
--- a/src/config/config-request.c	Fri Oct 23 19:09:33 2009 -0400
+++ b/src/config/config-request.c	Fri Oct 23 19:10:42 2009 -0400
@@ -157,7 +157,8 @@ static void settings_export(struct setti
 				str_append(ctx->value, *val);
 			break;
 		}
-		case SET_DEFLIST: {
+		case SET_DEFLIST:
+		case SET_DEFLIST_UNIQUE: {
 			const ARRAY_TYPE(void_array) *val = value;
 			const ARRAY_TYPE(void_array) *change_val = change_value;
 
@@ -212,8 +213,8 @@ static void settings_export(struct setti
 					  def->key, NULL);
 			if (hash_table_lookup(ctx->keys, key) == NULL) {
 				ctx->callback(key, str_c(ctx->value),
-					      def->type == SET_DEFLIST,
-					      ctx->context);
+					SETTING_TYPE_IS_DEFLIST(def->type),
+					ctx->context);
 				hash_table_insert(ctx->keys, key, key);
 			}
 		}
diff -r 429641734346 -r eaac22ecc168 src/lib-settings/settings-parser.c
--- a/src/lib-settings/settings-parser.c	Fri Oct 23 19:09:33 2009 -0400
+++ b/src/lib-settings/settings-parser.c	Fri Oct 23 19:10:42 2009 -0400
@@ -61,6 +61,11 @@ static const struct setting_parser_info 
 	MEMBER(parent_offset) (size_t)-1
 };
 
+static int
+settings_apply(struct setting_link *dest_link,
+	       const struct setting_link *src_link,
+	       pool_t pool, const char **conflict_key_r);
+
 struct setting_parser_context *
 settings_parser_init(pool_t set_pool, const struct setting_parser_info *root,
 		     enum settings_parser_flags flags)
@@ -262,6 +267,7 @@ static int get_enum(struct setting_parse
 
 static int
 get_deflist(struct setting_parser_context *ctx, struct setting_link *parent,
+	    const struct setting_define *def,
 	    const struct setting_parser_info *info,
 	    const char *key, const char *value, ARRAY_TYPE(void_array) *result,
 	    ARRAY_TYPE(void_array) *change_result)
@@ -284,7 +290,11 @@ get_deflist(struct setting_parser_contex
 
 		full_key = p_strconcat(ctx->parser_pool, key,
 				       SETTINGS_SEPARATOR_S, *list, NULL);
-		if (hash_table_lookup(ctx->links, full_key) != NULL) {
+		link = hash_table_lookup(ctx->links, full_key);
+		if (link != NULL) {
+			if (def != NULL && def->type == SET_DEFLIST_UNIQUE &&
+			    link->parent == parent && link->info == info)
+				return 0;
 			ctx->error = p_strconcat(ctx->parser_pool, full_key,
 						 " already exists", NULL);
 			return -1;
@@ -363,13 +373,14 @@ settings_parse(struct setting_parser_con
 			return -1;
 		break;
 	case SET_DEFLIST:
+	case SET_DEFLIST_UNIQUE:
 		ctx->prev_info = def->list_info;
-		return get_deflist(ctx, link, def->list_info,
+		return get_deflist(ctx, link, def, def->list_info,
 				   key, value, (ARRAY_TYPE(void_array) *)ptr,
 				   (ARRAY_TYPE(void_array) *)change_ptr);
 	case SET_STRLIST: {
 		ctx->prev_info = &strlist_info;
-		if (get_deflist(ctx, link, &strlist_info, key, value,
+		if (get_deflist(ctx, link, NULL, &strlist_info, key, value,
 				(ARRAY_TYPE(void_array) *)ptr, NULL) < 0)
 			return -1;
 		break;
@@ -707,10 +718,10 @@ bool settings_check(const struct setting
 	}
 
 	for (def = info->defines; def->key != NULL; def++) {
-		if (def->type != SET_DEFLIST)
+		if (!SETTING_TYPE_IS_DEFLIST(def->type))
 			continue;
 
-		val = CONST_PTR_OFFSET(set, def->offset);;
+		val = CONST_PTR_OFFSET(set, def->offset);
 		if (!array_is_created(val))
 			continue;
 
@@ -791,6 +802,12 @@ settings_var_expand_info(const struct se
 	for (def = info->defines; def->key != NULL; def++) {
 		value = PTR_OFFSET(set, def->offset);
 		switch (def->type) {
+		case SET_BOOL:
+		case SET_UINT:
+		case SET_STR:
+		case SET_ENUM:
+		case SET_STRLIST:
+			break;
 		case SET_STR_VARS: {
 			const char **val = value;
 
@@ -811,7 +828,8 @@ settings_var_expand_info(const struct se
 			}
 			break;
 		}
-		case SET_DEFLIST: {
+		case SET_DEFLIST:
+		case SET_DEFLIST_UNIQUE: {
 			const ARRAY_TYPE(void_array) *val = value;
 
 			if (!array_is_created(val))
@@ -825,8 +843,6 @@ settings_var_expand_info(const struct se
 			}
 			break;
 		}
-		default:
-			break;
 		}
 	}
 }
@@ -855,6 +871,12 @@ bool settings_vars_have_key(const struct
 	for (def = info->defines; def->key != NULL; def++) {
 		value = CONST_PTR_OFFSET(set, def->offset);
 		switch (def->type) {
+		case SET_BOOL:
+		case SET_UINT:
+		case SET_STR:
+		case SET_ENUM:
+		case SET_STRLIST:
+			break;
 		case SET_STR_VARS: {
 			const char *const *val = value;
 
@@ -873,7 +895,8 @@ bool settings_vars_have_key(const struct
 			}
 			break;
 		}
-		case SET_DEFLIST: {
+		case SET_DEFLIST:
+		case SET_DEFLIST_UNIQUE: {
 			const ARRAY_TYPE(void_array) *val = value;
 
 			if (!array_is_created(val))
@@ -889,8 +912,6 @@ bool settings_vars_have_key(const struct
 			}
 			break;
 		}
-		default:
-			break;
 		}
 	}
 	return FALSE;
@@ -936,6 +957,7 @@ setting_copy(enum setting_type type, con
 		break;
 	}
 	case SET_DEFLIST:
+	case SET_DEFLIST_UNIQUE:
 		return FALSE;
 	case SET_STRLIST: {
 		const ARRAY_TYPE(const_string) *src_arr = src;
@@ -1025,7 +1047,8 @@ settings_changes_dup(const struct settin
 		case SET_STRLIST:
 			*((char *)dest) = *((char *)src);
 			break;
-		case SET_DEFLIST: {
+		case SET_DEFLIST:
+		case SET_DEFLIST_UNIQUE: {
 			const ARRAY_TYPE(void_array) *src_arr = src;
 			ARRAY_TYPE(void_array) *dest_arr = dest;
 			void *child_set;
@@ -1268,7 +1291,7 @@ settings_changes_init(const struct setti
 
 	dest_set = p_malloc(pool, info->struct_size);
 	for (def = info->defines; def->key != NULL; def++) {
-		if (def->type != SET_DEFLIST)
+		if (!SETTING_TYPE_IS_DEFLIST(def->type))
 			continue;
 
 		src_arr = CONST_PTR_OFFSET(change_set, def->offset);
@@ -1288,6 +1311,119 @@ settings_changes_init(const struct setti
 	return dest_set;
 }
 
+static void settings_copy_deflist(const struct setting_define *def,
+				  const struct setting_link *src_link,
+				  struct setting_link *dest_link,
+				  pool_t pool)
+{
+	const ARRAY_TYPE(void_array) *src_arr;
+	ARRAY_TYPE(void_array) *dest_arr;
+	void *const *children, *child_set;
+	unsigned int i, count;
+
+	src_arr = CONST_PTR_OFFSET(src_link->set_struct, def->offset);
+	dest_arr = PTR_OFFSET(dest_link->set_struct, def->offset);
+
+	if (!array_is_created(src_arr))
+		return;
+
+	children = array_get(src_arr, &count);
+	if (!array_is_created(dest_arr))
+		p_array_init(dest_arr, pool, count);
+	for (i = 0; i < count; i++) {
+		child_set = settings_dup(def->list_info, children[i], pool);
+		array_append(dest_arr, &child_set, 1);
+		settings_set_parent(def->list_info, child_set,
+				    dest_link->set_struct);
+	}
+
+	/* copy changes */
+	dest_arr = PTR_OFFSET(dest_link->change_struct, def->offset);
+	if (!array_is_created(dest_arr))
+		p_array_init(dest_arr, pool, count);
+	for (i = 0; i < count; i++) {


More information about the dovecot-cvs mailing list