doveconf.c revision 6347bb65e93c27f1bf4330786447c9ab0cab4dbf
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng/* Copyright (c) 2005-2016 Dovecot authors, see the included COPYING file */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include "lib.h"
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include "array.h"
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include "abspath.h"
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include "module-dir.h"
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include "env-util.h"
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include "guid.h"
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include "hash.h"
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include "hostpid.h"
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include "ostream.h"
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include "str.h"
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include "strescape.h"
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include "settings-parser.h"
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include "master-service.h"
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include "all-settings.h"
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include "sysinfo-get.h"
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include "config-connection.h"
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include "config-parser.h"
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include "config-request.h"
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include "dovecot-version.h"
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include <stdio.h>
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include <ctype.h>
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include <unistd.h>
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include <sysexits.h>
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstruct prefix_stack {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng unsigned int prefix_idx;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng unsigned int str_pos;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng};
da14cebe459d3275048785f25bd869cb09b5307fEric ChengARRAY_DEFINE_TYPE(prefix_stack, struct prefix_stack);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstruct config_dump_human_context {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng pool_t pool;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng string_t *list_prefix;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ARRAY_TYPE(const_string) strings;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ARRAY_TYPE(const_string) errors;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng struct config_export_context *export_ctx;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng unsigned int list_prefix_sent:1;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng};
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#define LIST_KEY_PREFIX "\001"
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#define UNIQUE_KEY_SUFFIX "\xff"
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic const char *indent_str = " !!!!";
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void
da14cebe459d3275048785f25bd869cb09b5307fEric Chengconfig_request_get_strings(const char *key, const char *value,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng enum config_key_type type, void *context)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng struct config_dump_human_context *ctx = context;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const char *p;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng switch (type) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng case CONFIG_KEY_NORMAL:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng value = p_strdup_printf(ctx->pool, "%s=%s", key, value);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng break;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng case CONFIG_KEY_LIST:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng value = p_strdup_printf(ctx->pool, LIST_KEY_PREFIX"%s=%s",
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng key, value);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng break;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng case CONFIG_KEY_UNIQUE_KEY:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng p = strrchr(key, '/');
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng i_assert(p != NULL);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng value = p_strdup_printf(ctx->pool, "%s/"UNIQUE_KEY_SUFFIX"%s=%s",
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng t_strdup_until(key, p), p + 1, value);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng break;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng case CONFIG_KEY_ERROR:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng value = p_strdup(ctx->pool, value);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng array_append(&ctx->errors, &value, 1);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng array_append(&ctx->strings, &value, 1);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng}
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic int config_string_cmp(const char *const *p1, const char *const *p2)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const char *s1 = *p1, *s2 = *p2;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng unsigned int i = 0;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng while (s1[i] == s2[i]) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (s1[i] == '\0' || s1[i] == '=')
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return 0;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng i++;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (s1[i] == '=')
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return -1;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (s2[i] == '=')
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return 1;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return s1[i] - s2[i];
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng}
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic struct prefix_stack prefix_stack_pop(ARRAY_TYPE(prefix_stack) *stack)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const struct prefix_stack *s;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng struct prefix_stack sc;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng unsigned int count;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng s = array_get(stack, &count);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng i_assert(count > 0);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (count == 1) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng sc.prefix_idx = UINT_MAX;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng } else {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng sc.prefix_idx = s[count-2].prefix_idx;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng sc.str_pos = s[count-1].str_pos;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng array_delete(stack, count-1, 1);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return sc;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng}
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void prefix_stack_reset_str(ARRAY_TYPE(prefix_stack) *stack)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng struct prefix_stack *s;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng array_foreach_modifiable(stack, s)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng s->str_pos = UINT_MAX;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng}
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic struct config_dump_human_context *
da14cebe459d3275048785f25bd869cb09b5307fEric Chengconfig_dump_human_init(const char *const *modules, enum config_dump_scope scope,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng bool check_settings)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng struct config_dump_human_context *ctx;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng enum config_dump_flags flags;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng pool_t pool;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng pool = pool_alloconly_create(MEMPOOL_GROWING"config human strings", 1024*32);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ctx = p_new(pool, struct config_dump_human_context, 1);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ctx->pool = pool;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ctx->list_prefix = str_new(ctx->pool, 128);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng i_array_init(&ctx->strings, 256);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng i_array_init(&ctx->errors, 256);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng flags = CONFIG_DUMP_FLAG_HIDE_LIST_DEFAULTS |
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng CONFIG_DUMP_FLAG_CALLBACK_ERRORS;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (check_settings)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng flags |= CONFIG_DUMP_FLAG_CHECK_SETTINGS;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ctx->export_ctx = config_export_init(modules, scope, flags,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng config_request_get_strings, ctx);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return ctx;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng}
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void config_dump_human_deinit(struct config_dump_human_context *ctx)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng array_free(&ctx->strings);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng array_free(&ctx->errors);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng pool_unref(&ctx->pool);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng}
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic bool value_need_quote(const char *value)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng unsigned int len = strlen(value);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (len == 0)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return FALSE;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (strchr(value, '#') != NULL)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return TRUE;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (IS_WHITE(value[0]) || IS_WHITE(value[len-1]))
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return TRUE;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return FALSE;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng}
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic int ATTR_NULL(4)
da14cebe459d3275048785f25bd869cb09b5307fEric Chengconfig_dump_human_output(struct config_dump_human_context *ctx,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng struct ostream *output, unsigned int indent,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const char *setting_name_filter, bool hide_passwords)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ARRAY_TYPE(const_string) prefixes_arr;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ARRAY_TYPE(prefix_stack) prefix_stack;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng struct prefix_stack prefix;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const char *const *strings, *const *args, *p, *str, *const *prefixes;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const char *key, *key2, *value;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng unsigned int i, j, count, len, prefix_count, skip_len;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng unsigned int setting_name_filter_len, prefix_idx = UINT_MAX;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng bool unique_key;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng int ret = 0;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng setting_name_filter_len = setting_name_filter == NULL ? 0 :
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng strlen(setting_name_filter);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (config_export_finish(&ctx->export_ctx) < 0)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return -1;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng array_sort(&ctx->strings, config_string_cmp);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng strings = array_get(&ctx->strings, &count);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* strings are sorted so that all lists come first */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng p_array_init(&prefixes_arr, ctx->pool, 32);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng for (i = 0; i < count && strings[i][0] == LIST_KEY_PREFIX[0]; i++) T_BEGIN {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng p = strchr(strings[i], '=');
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng i_assert(p != NULL);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (p[1] == '\0') {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* "strlist=" */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng str = p_strdup_printf(ctx->pool, "%s/",
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng t_strcut(strings[i]+1, '='));
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng array_append(&prefixes_arr, &str, 1);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng } else {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* string is in format: "list=0 1 2" */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng for (args = t_strsplit(p + 1, " "); *args != NULL; args++) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng str = p_strdup_printf(ctx->pool, "%s/%s/",
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng t_strcut(strings[i]+1, '='),
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *args);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng array_append(&prefixes_arr, &str, 1);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng } T_END;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng prefixes = array_get(&prefixes_arr, &prefix_count);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng p_array_init(&prefix_stack, ctx->pool, 8);
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer for (; i < count; i++) T_BEGIN {
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer value = strchr(strings[i], '=');
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer i_assert(value != NULL);
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer key = t_strdup_until(strings[i], value++);
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer unique_key = FALSE;
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer p = strrchr(key, '/');
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer if (p != NULL && p[1] == UNIQUE_KEY_SUFFIX[0]) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng key = t_strconcat(t_strdup_until(key, p + 1),
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng p + 2, NULL);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng unique_key = TRUE;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (setting_name_filter_len > 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* see if this setting matches the name filter */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (!(strncmp(setting_name_filter, key,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng setting_name_filter_len) == 0 &&
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng (key[setting_name_filter_len] == '/' ||
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng key[setting_name_filter_len] == '\0')))
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng goto end;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng again:
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng j = 0;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* if there are open sections and this key isn't in it,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng close the sections */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng while (prefix_idx != UINT_MAX) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng len = strlen(prefixes[prefix_idx]);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (strncmp(prefixes[prefix_idx], key, len) != 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng prefix = prefix_stack_pop(&prefix_stack);
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer indent--;
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer if (prefix.str_pos != UINT_MAX)
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer str_truncate(ctx->list_prefix, prefix.str_pos);
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer else {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng o_stream_nsend(output, indent_str, indent*2);
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer o_stream_nsend_str(output, "}\n");
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai }
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai prefix_idx = prefix.prefix_idx;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng } else {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* keep the prefix */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng j = prefix_idx + 1;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng break;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* see if this key is in some section */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng for (; j < prefix_count; j++) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng len = strlen(prefixes[j]);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (strncmp(prefixes[j], key, len) == 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng key2 = key + (prefix_idx == UINT_MAX ? 0 :
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng strlen(prefixes[prefix_idx]));
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng prefix.str_pos = !unique_key ? UINT_MAX :
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng str_len(ctx->list_prefix);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng prefix_idx = j;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng prefix.prefix_idx = prefix_idx;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng array_append(&prefix_stack, &prefix, 1);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng str_append_n(ctx->list_prefix, indent_str, indent*2);
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer p = strchr(key2, '/');
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer if (p != NULL)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng str_append_n(ctx->list_prefix, key2, p - key2);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng else
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng str_append(ctx->list_prefix, key2);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (unique_key && *value != '\0') {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (strchr(value, ' ') == NULL)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng str_printfa(ctx->list_prefix, " %s", value);
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer else
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer str_printfa(ctx->list_prefix, " \"%s\"", str_escape(value));
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer }
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer str_append(ctx->list_prefix, " {\n");
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer indent++;
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer if (unique_key)
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer goto end;
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer else
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer goto again;
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer }
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer }
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer o_stream_nsend(output, str_data(ctx->list_prefix), str_len(ctx->list_prefix));
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer str_truncate(ctx->list_prefix, 0);
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer prefix_stack_reset_str(&prefix_stack);
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer ctx->list_prefix_sent = TRUE;
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer skip_len = prefix_idx == UINT_MAX ? 0 : strlen(prefixes[prefix_idx]);
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer i_assert(skip_len == 0 ||
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer strncmp(prefixes[prefix_idx], strings[i], skip_len) == 0);
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer o_stream_nsend(output, indent_str, indent*2);
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer key = strings[i] + skip_len;
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer if (unique_key) key++;
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer value = strchr(key, '=');
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer i_assert(value != NULL);
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer o_stream_nsend(output, key, value-key);
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer o_stream_nsend_str(output, " = ");
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer if (hide_passwords && value[1] != '\0' &&
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer value-key > 9 && strncmp(value-9, "_password", 9) == 0) {
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer o_stream_nsend_str(output, " # hidden, use -P to show it");
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer } else if (!value_need_quote(value+1))
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer o_stream_nsend_str(output, value+1);
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer else {
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer o_stream_nsend(output, "\"", 1);
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer o_stream_nsend_str(output, str_escape(value+1));
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer o_stream_nsend(output, "\"", 1);
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer }
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer o_stream_nsend(output, "\n", 1);
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer end: ;
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer } T_END;
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer while (prefix_idx != UINT_MAX) {
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer prefix = prefix_stack_pop(&prefix_stack);
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer if (prefix.str_pos != UINT_MAX)
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer break;
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer prefix_idx = prefix.prefix_idx;
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer indent--;
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer o_stream_nsend(output, indent_str, indent*2);
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer o_stream_nsend_str(output, "}\n");
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer }
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer /* flush output before writing errors */
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer o_stream_uncork(output);
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer array_foreach(&ctx->errors, strings) {
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer i_error("%s", *strings);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ret = -1;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return ret;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng}
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic unsigned int
da14cebe459d3275048785f25bd869cb09b5307fEric Chengconfig_dump_filter_begin(string_t *str,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const struct config_filter *filter)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng unsigned int indent = 0;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (filter->local_bits > 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng str_printfa(str, "local %s", net_ip2addr(&filter->local_net));
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da0006029e69465355313f503741ac6ebe0d513bGirish Moodalbail if (IPADDR_IS_V4(&filter->local_net)) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (filter->local_bits != 32)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng str_printfa(str, "/%u", filter->local_bits);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng } else {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (filter->local_bits != 128)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng str_printfa(str, "/%u", filter->local_bits);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng str_append(str, " {\n");
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng indent++;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (filter->local_name != NULL) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng str_append_n(str, indent_str, indent*2);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng str_printfa(str, "local_name %s {\n", filter->local_name);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng indent++;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (filter->remote_bits > 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng str_append_n(str, indent_str, indent*2);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng str_printfa(str, "remote %s", net_ip2addr(&filter->remote_net));
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (IPADDR_IS_V4(&filter->remote_net)) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (filter->remote_bits != 32)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng str_printfa(str, "/%u", filter->remote_bits);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng } else {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (filter->remote_bits != 128)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng str_printfa(str, "/%u", filter->remote_bits);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek str_append(str, " {\n");
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng indent++;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (filter->service != NULL) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng str_append_n(str, indent_str, indent*2);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng str_printfa(str, "protocol %s {\n", filter->service);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng indent++;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return indent;
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer}
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void
da14cebe459d3275048785f25bd869cb09b5307fEric Chengconfig_dump_filter_end(struct ostream *output, unsigned int indent)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng while (indent > 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng indent--;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng o_stream_nsend(output, indent_str, indent*2);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng o_stream_nsend(output, "}\n", 2);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng}
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic int
da14cebe459d3275048785f25bd869cb09b5307fEric Chengconfig_dump_human_sections(struct ostream *output,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const struct config_filter *filter,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const char *const *modules, bool hide_passwords)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng struct config_filter_parser *const *filters;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng static struct config_dump_human_context *ctx;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng unsigned int indent;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng int ret = 0;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng filters = config_filter_find_subset(config_filter, filter);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* first filter should be the global one */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng i_assert(filters[0] != NULL && filters[0]->filter.service == NULL);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng filters++;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng for (; *filters != NULL; filters++) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ctx = config_dump_human_init(modules, CONFIG_DUMP_SCOPE_SET,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng FALSE);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng indent = config_dump_filter_begin(ctx->list_prefix,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng &(*filters)->filter);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng config_export_parsers(ctx->export_ctx, (*filters)->parsers);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (config_dump_human_output(ctx, output, indent, NULL, hide_passwords) < 0)
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer ret = -1;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (ctx->list_prefix_sent)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng config_dump_filter_end(output, indent);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng config_dump_human_deinit(ctx);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return ret;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng}
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic int ATTR_NULL(4)
da14cebe459d3275048785f25bd869cb09b5307fEric Chengconfig_dump_human(const struct config_filter *filter, const char *const *modules,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng enum config_dump_scope scope, const char *setting_name_filter,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng bool hide_passwords)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng static struct config_dump_human_context *ctx;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng struct ostream *output;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng int ret;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng output = o_stream_create_fd(STDOUT_FILENO, 0, FALSE);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng o_stream_set_no_error_handling(output, TRUE);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng o_stream_cork(output);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer ctx = config_dump_human_init(modules, scope, TRUE);
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer config_export_by_filter(ctx->export_ctx, filter);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ret = config_dump_human_output(ctx, output, 0, setting_name_filter, hide_passwords);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng config_dump_human_deinit(ctx);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (setting_name_filter == NULL)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ret = config_dump_human_sections(output, filter, modules, hide_passwords);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng o_stream_uncork(output);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng o_stream_destroy(&output);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return ret;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng}
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic int
da14cebe459d3275048785f25bd869cb09b5307fEric Chengconfig_dump_one(const struct config_filter *filter, bool hide_key,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng enum config_dump_scope scope, const char *setting_name_filter,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng bool hide_passwords)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng static struct config_dump_human_context *ctx;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const char *const *str;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng unsigned int len;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng bool dump_section = FALSE;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ctx = config_dump_human_init(NULL, scope, FALSE);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng config_export_by_filter(ctx->export_ctx, filter);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (config_export_finish(&ctx->export_ctx) < 0)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return -1;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng len = strlen(setting_name_filter);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng array_foreach(&ctx->strings, str) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (strncmp(*str, setting_name_filter, len) != 0)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng continue;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if ((*str)[len] == '=') {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (hide_key)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng printf("%s\n", *str + len+1);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng else {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng printf("%s = %s\n", setting_name_filter,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *str + len+1);
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer }
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer dump_section = FALSE;
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer break;
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer } else if ((*str)[len] == '/') {
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer dump_section = TRUE;
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer }
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer }
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer config_dump_human_deinit(ctx);
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer if (dump_section)
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer (void)config_dump_human(filter, NULL, scope, setting_name_filter, hide_passwords);
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer return 0;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng}
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void config_request_simple_stdout(const char *key, const char *value,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng enum config_key_type type ATTR_UNUSED,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng void *context)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng char **setting_name_filters = context;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng unsigned int i, filter_len;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (setting_name_filters == NULL) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng printf("%s=%s\n", key, value);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng for (i = 0; setting_name_filters[i] != NULL; i++) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng filter_len = strlen(setting_name_filters[i]);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (strncmp(setting_name_filters[i], key, filter_len) == 0 &&
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng (key[filter_len] == '\0' || key[filter_len] == '/'))
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng printf("%s=%s\n", key, value);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng}
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void config_request_putenv(const char *key, const char *value,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng enum config_key_type type ATTR_UNUSED,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng void *context ATTR_UNUSED)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng T_BEGIN {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng env_put(t_strconcat(t_str_ucase(key), "=", value, NULL));
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng } T_END;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng}
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic const char *get_setting(const char *module, const char *name)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng struct config_module_parser *l;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const struct setting_define *def;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const char *const *value;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const void *set;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng for (l = config_module_parsers; l->root != NULL; l++) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (strcmp(l->root->module_name, module) != 0)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng continue;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng set = settings_parser_get(l->parser);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng for (def = l->root->defines; def->key != NULL; def++) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (strcmp(def->key, name) == 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng value = CONST_PTR_OFFSET(set, def->offset);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return *value;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return "";
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng}
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void filter_parse_arg(struct config_filter *filter, const char *arg)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const char *key, *value, *error;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng value = strchr(arg, '=');
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (value != NULL)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng key = t_strdup_until(arg, value++);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng else {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng key = arg;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng value = "";
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (strcmp(key, "service") == 0)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng filter->service = value;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng else if (strcmp(key, "protocol") == 0)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng filter->service = value;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng else if (strcmp(key, "lname") == 0)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng filter->local_name = value;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng else if (strcmp(key, "local") == 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (config_parse_net(value, &filter->local_net,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng &filter->local_bits, &error) < 0)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng i_fatal("local filter: %s", error);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng } else if (strcmp(key, "remote") == 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (config_parse_net(value, &filter->remote_net,
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer &filter->remote_bits, &error) < 0)
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer i_fatal("remote filter: %s", error);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng } else {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng i_fatal("Unknown filter argument: %s", arg);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng}
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstruct hostname_format {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const char *prefix, *suffix;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng unsigned int numcount;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng bool zeropadding;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng};
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void
da14cebe459d3275048785f25bd869cb09b5307fEric Chenghostname_format_write(string_t *str, const struct hostname_format *fmt,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng unsigned int num)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng str_truncate(str, 0);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng str_append(str, fmt->prefix);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (!fmt->zeropadding)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng str_printfa(str, "%d", num);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng else
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng str_printfa(str, "%0*d", fmt->numcount, num);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng str_append(str, fmt->suffix);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng}
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyerstatic void hostname_verify_format(const char *arg)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng struct hostname_format fmt;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const char *p;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng unsigned char hash[GUID_128_HOST_HASH_SIZE];
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng unsigned int len, n, limit;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng HASH_TABLE(void *, void *) hosts;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng void *key, *value;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng string_t *host;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const char *host2;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng bool duplicates = FALSE;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng memset(&fmt, 0, sizeof(fmt));
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (arg != NULL) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* host%d, host%2d, host%02d */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng p = strchr(arg, '%');
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (p == NULL)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng i_fatal("Host parameter missing %%d");
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng fmt.prefix = t_strdup_until(arg, p++);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (*p == '0') {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng fmt.zeropadding = TRUE;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng p++;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (!i_isdigit(*p))
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng fmt.numcount = 1;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng else
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng fmt.numcount = *p++ - '0';
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (*p++ != 'd')
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng i_fatal("Host parameter missing %%d");
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng fmt.suffix = p;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng } else {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* detect host1[suffix] vs host01[suffix] */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng len = strlen(my_hostname);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng while (len > 0 && !i_isdigit(my_hostname[len-1]))
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng len--;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng fmt.suffix = my_hostname + len;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng fmt.numcount = 0;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng while (len > 0 && i_isdigit(my_hostname[len-1])) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng len--;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng fmt.numcount++;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (my_hostname[len] == '0')
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng fmt.zeropadding = TRUE;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng fmt.prefix = t_strndup(my_hostname, len);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (fmt.numcount == 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng i_fatal("Hostname '%s' has no digits, can't verify",
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng my_hostname);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng for (n = 0, limit = 1; n < fmt.numcount; n++)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng limit *= 10;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng host = t_str_new(128);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng hash_table_create_direct(&hosts, default_pool, limit);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng for (n = 0; n < limit; n++) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng hostname_format_write(host, &fmt, n);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng guid_128_host_hash_get(str_c(host), hash);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng i_assert(sizeof(key) >= sizeof(hash));
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng key = NULL; memcpy(&key, hash, sizeof(hash));
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng value = hash_table_lookup(hosts, key);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (value != NULL) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng host2 = t_strdup(str_c(host));
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng hostname_format_write(host, &fmt,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng POINTER_CAST_TO(value, unsigned int)-1);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng i_error("Duplicate host hashes: %s and %s",
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng str_c(host), host2);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng duplicates = TRUE;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng } else {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng hash_table_insert(hosts, key, POINTER_CAST(n+1));
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng hash_table_destroy(&hosts);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (duplicates)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng exit(EX_CONFIG);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng else {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng host2 = t_strdup(str_c(host));
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng hostname_format_write(host, &fmt, 0);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng printf("No duplicate host hashes in %s .. %s\n",
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng str_c(host), host2);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng exit(0);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
}
static void check_wrong_config(const char *config_path)
{
const char *base_dir, *symlink_path, *prev_path;
base_dir = get_setting("master", "base_dir");
symlink_path = t_strconcat(base_dir, "/"PACKAGE".conf", NULL);
if (t_readlink(symlink_path, &prev_path) < 0)
return;
if (strcmp(prev_path, config_path) != 0) {
i_warning("Dovecot was last started using %s, "
"but this config is %s", prev_path, config_path);
}
}
static void failure_exit_callback(int *status)
{
/* don't use EX_CONFIG, because it often causes MTAs to bounce
the mails back. */
*status = EX_TEMPFAIL;
}
int main(int argc, char *argv[])
{
enum config_dump_scope scope = CONFIG_DUMP_SCOPE_ALL;
const char *orig_config_path, *config_path, *module;
ARRAY(const char *) module_names;
struct config_filter filter;
const char *const *wanted_modules, *error;
char **exec_args = NULL, **setting_name_filters = NULL;
unsigned int i;
int c, ret, ret2;
bool config_path_specified, expand_vars = FALSE, hide_key = FALSE;
bool parse_full_config = FALSE, simple_output = FALSE;
bool dump_defaults = FALSE, host_verify = FALSE;
bool print_plugin_banner = FALSE, hide_passwords = TRUE;
if (getenv("USE_SYSEXITS") != NULL) {
/* we're coming from (e.g.) LDA */
i_set_failure_exit_callback(failure_exit_callback);
}
memset(&filter, 0, sizeof(filter));
master_service = master_service_init("config",
MASTER_SERVICE_FLAG_STANDALONE,
&argc, &argv, "adf:hHm:nNpPexS");
orig_config_path = master_service_get_config_path(master_service);
i_set_failure_prefix("doveconf: ");
t_array_init(&module_names, 4);
while ((c = master_getopt(master_service)) > 0) {
if (c == 'e') {
expand_vars = TRUE;
break;
}
switch (c) {
case 'a':
break;
case 'd':
dump_defaults = TRUE;
break;
case 'f':
filter_parse_arg(&filter, optarg);
break;
case 'h':
hide_key = TRUE;
break;
case 'H':
host_verify = TRUE;
break;
case 'm':
module = t_strdup(optarg);
array_append(&module_names, &module, 1);
break;
case 'n':
scope = CONFIG_DUMP_SCOPE_CHANGED;
break;
case 'N':
scope = CONFIG_DUMP_SCOPE_SET;
break;
case 'p':
parse_full_config = TRUE;
break;
case 'P':
hide_passwords = FALSE;
break;
case 'S':
simple_output = TRUE;
break;
case 'x':
expand_vars = TRUE;
break;
default:
return FATAL_DEFAULT;
}
}
array_append_zero(&module_names);
wanted_modules = array_count(&module_names) == 1 ? NULL :
array_idx(&module_names, 0);
config_path = master_service_get_config_path(master_service);
/* use strcmp() instead of !=, because dovecot -n always gives us
-c parameter */
config_path_specified = strcmp(config_path, orig_config_path) != 0;
if (host_verify)
hostname_verify_format(argv[optind]);
if (c == 'e') {
if (argv[optind] == NULL)
i_fatal("Missing command for -e");
exec_args = &argv[optind];
} else if (argv[optind] != NULL) {
/* print only a single config setting */
setting_name_filters = argv+optind;
} else if (!simple_output) {
/* print the config file path before parsing it, so in case
of errors it's still shown */
printf("# "DOVECOT_VERSION_FULL": %s\n", config_path);
print_plugin_banner = TRUE;
fflush(stdout);
}
master_service_init_finish(master_service);
config_parse_load_modules();
if (print_plugin_banner) {
struct module *m;
for (m = modules; m != NULL; m = m->next) {
const char **str = module_get_symbol_quiet(m,
t_strdup_printf("%s_doveconf_banner", m->name));
if (str != NULL)
printf("# %s\n", *str);
}
}
if ((ret = config_parse_file(dump_defaults ? NULL : config_path,
expand_vars,
parse_full_config ? NULL : wanted_modules,
&error)) == 0 &&
access(EXAMPLE_CONFIG_DIR, X_OK) == 0) {
i_fatal("%s (copy example configs from "EXAMPLE_CONFIG_DIR"/)",
error);
}
if ((ret == -1 && exec_args != NULL) || ret == 0 || ret == -2)
i_fatal("%s", error);
if (simple_output) {
struct config_export_context *ctx;
ctx = config_export_init(wanted_modules, scope,
CONFIG_DUMP_FLAG_CHECK_SETTINGS,
config_request_simple_stdout,
setting_name_filters);
config_export_by_filter(ctx, &filter);
ret2 = config_export_finish(&ctx);
} else if (setting_name_filters != NULL) {
ret2 = 0;
/* ignore settings-check failures in configuration. this allows
using doveconf to lookup settings for things like install or
uninstall scripts where the configuration might
(temporarily) not be fully usable */
ret = 0;
for (i = 0; setting_name_filters[i] != NULL; i++) {
if (config_dump_one(&filter, hide_key, scope,
setting_name_filters[i], hide_passwords) < 0)
ret2 = -1;
}
} else if (exec_args == NULL) {
const char *info;
info = sysinfo_get(get_setting("mail", "mail_location"));
if (*info != '\0')
printf("# %s\n", info);
if (!config_path_specified)
check_wrong_config(config_path);
if (scope == CONFIG_DUMP_SCOPE_ALL)
printf("# NOTE: Send doveconf -n output instead when asking for help.\n");
fflush(stdout);
ret2 = config_dump_human(&filter, wanted_modules, scope, NULL, hide_passwords);
} else {
struct config_export_context *ctx;
env_put("DOVECONF_ENV=1");
ctx = config_export_init(wanted_modules, CONFIG_DUMP_SCOPE_SET,
CONFIG_DUMP_FLAG_CHECK_SETTINGS,
config_request_putenv, NULL);
config_export_by_filter(ctx, &filter);
if (config_export_finish(&ctx) < 0)
i_fatal("Invalid configuration");
execvp(exec_args[0], exec_args);
i_fatal("execvp(%s) failed: %m", exec_args[0]);
}
if (ret < 0) {
/* delayed error */
i_fatal("%s", error);
}
if (ret2 < 0)
i_fatal("Errors in configuration");
config_filter_deinit(&config_filter);
module_dir_unload(&modules);
config_parser_deinit();
master_service_deinit(&master_service);
return 0;
}