/* the only '/' left should be if key is under list/ */
key = key_with_path;
- if (ctx->cur_section->filter_parser->filter.filter_name != NULL) {
+ if (ctx->cur_section->filter_parser->filter.filter_name != NULL &&
+ ctx->cur_section->filter_parser->filter.filter_name_array) {
+ /* For named list filters, try filter name { key } ->
+ filter_name_key first before anything else. */
+ const char *filter_key =
+ t_str_replace(ctx->cur_section->filter_parser->filter.filter_name, '/', '_');
+ const char *key2 = t_strdup_printf("%s_%s", filter_key, key);
+ struct config_filter_parser *last_filter_parser =
+ ctx->cur_section->filter_parser;
+ ret = config_apply_exact_line(ctx, line, key2, value);
+ if (ret > 0 && full_key_r != NULL) {
+ *full_key_r = key2;
+ *root_setting_r = config_filter_is_empty(
+ &ctx->cur_section->filter_parser->filter);
+ }
+ ctx->cur_section->filter_parser = last_filter_parser;
+ }
+ if (ret == 0 &&
+ ctx->cur_section->filter_parser->filter.filter_name != NULL) {
/* first try the filter name-specific prefix, so e.g.
inet_listener { ssl=yes } won't try to change the global
ssl setting. */
return ret;
}
+static void
+try_strip_prefix(const char **key_prefix, const char *strip_prefix,
+ const char *strip_prefix2)
+{
+ if (strip_prefix == NULL)
+ return;
+ if (str_begins(*key_prefix, strip_prefix, key_prefix))
+ return;
+ if (strip_prefix2 == NULL)
+ return;
+ (void)str_begins(*key_prefix, strip_prefix2, key_prefix);
+}
+
static void ATTR_NULL(4)
config_dump_human_output(struct config_dump_human_context *ctx,
struct ostream *output, unsigned int indent,
const char *setting_name_filter,
const char *alt_setting_name_filter,
+ const char *alt_setting_name_filter2,
bool hide_key, bool default_hide_passwords,
- const char *strip_prefix)
+ const char *strip_prefix, const char *strip_prefix2)
{
ARRAY_TYPE(const_string) prefixes_arr;
ARRAY_TYPE(prefix_stack) prefix_stack;
unsigned int i, j, count, prefix_count;
unsigned int prefix_idx = UINT_MAX;
size_t len, skip_len, setting_name_filter_len;
- size_t alt_setting_name_filter_len;
+ size_t alt_setting_name_filter_len, alt_setting_name_filter2_len;
bool bool_list_elem = FALSE;
bool str_list_elem = FALSE;
strlen(setting_name_filter);
alt_setting_name_filter_len = alt_setting_name_filter == NULL ? 0 :
strlen(alt_setting_name_filter);
+ alt_setting_name_filter2_len = alt_setting_name_filter2 == NULL ? 0 :
+ strlen(alt_setting_name_filter2);
if (config_export_all_parsers(&ctx->export_ctx) < 0)
i_unreached(); /* settings aren't checked - this can't happen */
/* alt match */
if (key[alt_setting_name_filter_len] == '\0')
hide_passwords = FALSE;
+ } else if (alt_setting_name_filter2_len > 0 &&
+ (strncmp(alt_setting_name_filter2, key,
+ alt_setting_name_filter2_len) == 0 &&
+ (key[alt_setting_name_filter2_len] == '/' ||
+ key[alt_setting_name_filter2_len] == '\0'))) {
+ /* alt match */
+ if (key[alt_setting_name_filter2_len] == '\0')
+ hide_passwords = FALSE;
} else
goto end;
}
key_prefix = t_strndup(key2, p - key2);
else
key_prefix = key2;
- if (strip_prefix != NULL &&
- str_begins(key_prefix, strip_prefix, &key_prefix))
- key_prefix++;
+ try_strip_prefix(&key_prefix, strip_prefix, strip_prefix2);
str_append(ctx->list_prefix, key_prefix);
str_append(ctx->list_prefix, " {\n");
indent++;
}
const char *full_key = key;
- if (strip_prefix != NULL && str_begins(key, strip_prefix, &key))
- key++;
+ try_strip_prefix(&key, strip_prefix, strip_prefix2);
value = strchr(key, '=');
i_assert(value != NULL);
if (!hide_key || bool_list_elem || str_list_elem) {
config_dump_filter_begin(list_prefix, indent,
&filter_parser->filter);
str_append_str(ctx->list_prefix, list_prefix);
- const char *filter_key =
- filter_parser->filter.filter_name == NULL ? NULL :
- t_strcut(filter_parser->filter.filter_name, '/');
-
+ const char *filter_name = filter_parser->filter.filter_name;
+ const char *strip_prefix, *strip_prefix2 = NULL;
+ strip_prefix = filter_name == NULL ? NULL :
+ t_strconcat(t_strcut(filter_name, '/'), "_", NULL);
const char *alt_set_name_filter =
- set_name_filter != NULL && filter_key != NULL ?
- t_strdup_printf("%s_%s", filter_key, set_name_filter) :
+ set_name_filter != NULL && strip_prefix != NULL ?
+ t_strdup_printf("%s%s", strip_prefix, set_name_filter) :
NULL;
+
+ const char *alt_set_name_filter2 = NULL;
+ if (filter_parser->filter.filter_name_array) {
+ strip_prefix2 = strip_prefix;
+ strip_prefix = t_strconcat(
+ t_str_replace(filter_name, '/', '_'), "_", NULL);
+ alt_set_name_filter2 =
+ set_name_filter == NULL ? NULL :
+ t_strdup_printf("%s%s", strip_prefix, set_name_filter);
+ }
config_dump_human_output(ctx, output, sub_indent,
set_name_filter,
- alt_set_name_filter, hide_key,
- sub_hide_passwords, filter_key);
+ alt_set_name_filter,
+ alt_set_name_filter2,
+ hide_key, sub_hide_passwords,
+ strip_prefix, strip_prefix2);
bool sub_list_prefix_sent = ctx->list_prefix_sent;
if (sub_list_prefix_sent) {
/* Check for the setting always even with a filter - it might be
e.g. plugin/key strlist */
ctx = config_dump_human_init(scope, filter_parser);
- config_dump_human_output(ctx, output, 0, setting_name_filter, NULL,
- hide_key, hide_passwords, NULL);
+ config_dump_human_output(ctx, output, 0, setting_name_filter, NULL, NULL,
+ hide_key, hide_passwords, NULL, NULL);
config_dump_human_deinit(ctx);
string_t *list_prefix = t_str_new(128);
{
if (last_filter_value != NULL) {
i_assert(last_filter_key != NULL);
- /* Try filter/name/key -> filter_key. Do this before the
- non-prefixed check, so e.g. inet_listener/imap/ssl won't
- try to change the global ssl setting. */
+ /* Try filter/name/key -> filter_name_key, and fallback to
+ filter_key. Do this before the non-prefixed check, so e.g.
+ inet_listener/imap/ssl won't try to change the global ssl
+ setting. */
const char *key_prefix = last_filter_key;
if (strcmp(key_prefix, SETTINGS_EVENT_MAILBOX_NAME_WITHOUT_PREFIX) == 0)
key_prefix = SETTINGS_EVENT_MAILBOX_NAME_WITH_PREFIX;
const char *prefixed_key =
- t_strdup_printf("%s_%s", key_prefix, *key);
+ t_strdup_printf("%s_%s_%s", key_prefix,
+ last_filter_value, *key);
+ if (setting_parser_info_find_key(ctx->info, prefixed_key,
+ key_idx_r)) {
+ *key = prefixed_key;
+ return TRUE;
+ }
+
+ prefixed_key = t_strdup_printf("%s_%s", key_prefix, *key);
if (setting_parser_info_find_key(ctx->info, prefixed_key,
key_idx_r)) {
*key = prefixed_key;