bool value_quoted;
};
+/* Returns TRUE if section is inside strlist { .. } or boollist { .. } */
+#define config_section_is_in_list(section) \
+ (!(section)->is_filter && (section)->key != NULL)
+
struct config_section_stack {
struct config_section_stack *prev;
const char *key;
struct config_filter_parser *filter_parser;
- size_t pathlen;
const char *open_path;
unsigned int open_linenum;
struct input_stack *cur_input;
uint8_t change_counter;
- string_t *key_path, *value;
+ string_t *value;
const char *error;
const char *dovecot_config_version;
str_append_c(ctx->value, '<');
str_append(ctx->value, line->value);
} else {
- key_with_path = t_strconcat(str_c(ctx->key_path),
- line->key, NULL);
+ key_with_path =
+ config_section_is_in_list(ctx->cur_section) ?
+ t_strdup_printf("%s"SETTINGS_SEPARATOR_S"%s",
+ ctx->cur_section->key,
+ line->key) :
+ line->key;
path = fix_relative_path(line->value, ctx->cur_input);
if (str_append_file(ctx->value, key_with_path, path,
&error) < 0) {
config_apply_error(ctx, line->key) < 0)
break;
} else {
- const char *key_with_path = t_strdup_printf("%s%s",
- str_c(ctx->key_path), line->key);
+ /* Either a global key or list/key */
+ const char *key_with_path =
+ config_section_is_in_list(ctx->cur_section) ?
+ t_strdup_printf("%s"SETTINGS_SEPARATOR_S"%s",
+ ctx->cur_section->key,
+ line->key) :
+ line->key;
if (config_apply_line_full(ctx, line, key_with_path,
str_c(ctx->value),
&full_key) == 0)
break;
case CONFIG_LINE_TYPE_SECTION_BEGIN:
ctx->cur_section = config_add_new_section(ctx);
- ctx->cur_section->pathlen = str_len(ctx->key_path);
ctx->cur_section->key = p_strdup(ctx->pool, line->key);
if (config_filter_add_new_filter(ctx, line)) {
}
/* This is SET_STRLIST or SET_BOOLLIST */
- str_append(ctx->key_path, line->key);
- str_append_c(ctx->key_path, SETTINGS_SEPARATOR);
break;
case CONFIG_LINE_TYPE_SECTION_END:
if (ctx->cur_section->prev == NULL)
ctx->cur_section->filter_def->key,
ctx->cur_section->filter_def->required_setting);
} else {
- str_truncate(ctx->key_path, ctx->cur_section->pathlen);
ctx->cur_section = ctx->cur_section->prev;
}
break;
struct config_filter root_filter = { };
config_add_new_parser(&ctx, &root_filter, ctx.cur_section, TRUE);
- ctx.key_path = str_new(ctx.pool, 256);
ctx.value = str_new(ctx.pool, 256);
full_line = str_new(default_pool, 512);
ctx.cur_input->input = fd != -1 ?
old_settings_handle_path(struct config_parser_context *ctx,
const char *key, const char *value)
{
- if (str_begins_with(str_c(ctx->key_path), "plugin/")) {
+ if (config_section_is_in_list(ctx->cur_section) &&
+ strcmp(ctx->cur_section->key, "plugin") == 0) {
if (strcmp(key, "push_notification_backend") == 0) {
obsolete(ctx, "%s has been replaced by push_notification_driver", key);
config_apply_line(ctx,
break;
case CONFIG_LINE_TYPE_KEYFILE:
case CONFIG_LINE_TYPE_KEYVALUE:
- if (str_len(ctx->key_path) == 0) {
+ if (!config_section_is_in_list(ctx->cur_section)) {
struct config_section_stack *old_section =
ctx->cur_section;
bool ret;
case CONFIG_LINE_TYPE_SECTION_BEGIN:
if (ctx->old->auth_section > 0)
return old_auth_section(ctx, key, value);
- else if (str_len(ctx->key_path) == 0 && strcmp(key, "auth") == 0) {
+ else if (!config_section_is_in_list(ctx->cur_section) &&
+ strcmp(key, "auth") == 0) {
obsolete(ctx, "add auth_ prefix to all settings inside auth {} and remove the auth {} section completely");
ctx->old->auth_section = 1;
return TRUE;
- } else if (str_len(ctx->key_path) == 0 && strcmp(key, "protocol") == 0 &&
+ } else if (!config_section_is_in_list(ctx->cur_section) &&
+ strcmp(key, "protocol") == 0 &&
strcmp(value, "managesieve") == 0) {
obsolete(ctx, "protocol managesieve {} has been replaced by protocol sieve { }");
old_set_parser_apply(ctx, CONFIG_LINE_TYPE_SECTION_BEGIN,
"protocol", "sieve");
return TRUE;
- } else if (str_len(ctx->key_path) == 0 && strcmp(key, "service") == 0 &&
+ } else if (!config_section_is_in_list(ctx->cur_section) &&
+ strcmp(key, "service") == 0 &&
strcmp(value, "dns_client") == 0) {
obsolete(ctx, "service dns_client {} has been replaced by service dns-client { }");
old_set_parser_apply(ctx, CONFIG_LINE_TYPE_SECTION_BEGIN,
"service", "dns-client");
return TRUE;
- } else if (str_len(ctx->key_path) == 0 && strcmp(key, "service") == 0 &&
+ } else if (!config_section_is_in_list(ctx->cur_section) &&
+ strcmp(key, "service") == 0 &&
strcmp(value, "ipc") == 0) {
obsolete(ctx, "service ipc {} no longer exists");
/* continue anyway */