doveconf.c revision 6347bb65e93c27f1bf4330786447c9ab0cab4dbf
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng/* Copyright (c) 2005-2016 Dovecot authors, see the included COPYING file */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng unsigned int prefix_idx;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng unsigned int str_pos;
da14cebe459d3275048785f25bd869cb09b5307fEric ChengARRAY_DEFINE_TYPE(prefix_stack, struct prefix_stack);
da14cebe459d3275048785f25bd869cb09b5307fEric Chengconfig_request_get_strings(const char *key, const char *value,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const char *p;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng value = p_strdup_printf(ctx->pool, "%s=%s", key, value);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng value = p_strdup_printf(ctx->pool, LIST_KEY_PREFIX"%s=%s",
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng value = p_strdup_printf(ctx->pool, "%s/"UNIQUE_KEY_SUFFIX"%s=%s",
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic int config_string_cmp(const char *const *p1, const char *const *p2)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng unsigned int i = 0;
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic struct prefix_stack prefix_stack_pop(ARRAY_TYPE(prefix_stack) *stack)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const struct prefix_stack *s;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng unsigned int count;
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void prefix_stack_reset_str(ARRAY_TYPE(prefix_stack) *stack)
da14cebe459d3275048785f25bd869cb09b5307fEric Chengconfig_dump_human_init(const char *const *modules, enum config_dump_scope scope,
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->export_ctx = config_export_init(modules, scope, flags,
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void config_dump_human_deinit(struct config_dump_human_context *ctx)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (IS_WHITE(value[0]) || IS_WHITE(value[len-1]))
da14cebe459d3275048785f25bd869cb09b5307fEric Chengconfig_dump_human_output(struct config_dump_human_context *ctx,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const char *setting_name_filter, bool hide_passwords)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const char *const *strings, *const *args, *p, *str, *const *prefixes;
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 setting_name_filter_len = setting_name_filter == NULL ? 0 :
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* strings are sorted so that all lists come first */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng for (i = 0; i < count && strings[i][0] == LIST_KEY_PREFIX[0]; i++) T_BEGIN {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* "strlist=" */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* string is in format: "list=0 1 2" */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng for (args = t_strsplit(p + 1, " "); *args != NULL; args++) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng prefixes = array_get(&prefixes_arr, &prefix_count);
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer if (p != NULL && p[1] == UNIQUE_KEY_SUFFIX[0]) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* see if this setting matches the name filter */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* if there are open sections and this key isn't in it,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng close the sections */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (strncmp(prefixes[prefix_idx], key, len) != 0) {
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer str_truncate(ctx->list_prefix, prefix.str_pos);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* keep the prefix */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* see if this key is in some section */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng for (; j < prefix_count; j++) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng str_append_n(ctx->list_prefix, indent_str, indent*2);
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer str_printfa(ctx->list_prefix, " \"%s\"", str_escape(value));
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer o_stream_nsend(output, str_data(ctx->list_prefix), str_len(ctx->list_prefix));
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer skip_len = prefix_idx == UINT_MAX ? 0 : strlen(prefixes[prefix_idx]);
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer strncmp(prefixes[prefix_idx], strings[i], skip_len) == 0);
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer o_stream_nsend(output, indent_str, indent*2);
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 o_stream_nsend_str(output, str_escape(value+1));
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer o_stream_nsend(output, indent_str, indent*2);
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer /* flush output before writing errors */
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic unsigned int
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng unsigned int indent = 0;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng str_printfa(str, "local %s", net_ip2addr(&filter->local_net));
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng str_printfa(str, "local_name %s {\n", filter->local_name);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng str_printfa(str, "remote %s", net_ip2addr(&filter->remote_net));
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng str_printfa(str, "protocol %s {\n", filter->service);
da14cebe459d3275048785f25bd869cb09b5307fEric Chengconfig_dump_filter_end(struct ostream *output, unsigned int indent)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng while (indent > 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Chengconfig_dump_human_sections(struct ostream *output,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng unsigned int indent;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng filters = config_filter_find_subset(config_filter, filter);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* first filter should be the global one */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng i_assert(filters[0] != NULL && filters[0]->filter.service == NULL);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ctx = config_dump_human_init(modules, CONFIG_DUMP_SCOPE_SET,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng indent = config_dump_filter_begin(ctx->list_prefix,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng config_export_parsers(ctx->export_ctx, (*filters)->parsers);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (config_dump_human_output(ctx, output, indent, NULL, hide_passwords) < 0)
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 output = o_stream_create_fd(STDOUT_FILENO, 0, FALSE);
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 ret = config_dump_human_sections(output, filter, modules, hide_passwords);
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 const char *const *str;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng unsigned int len;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ctx = config_dump_human_init(NULL, scope, FALSE);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng config_export_by_filter(ctx->export_ctx, filter);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (strncmp(*str, setting_name_filter, len) != 0)
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer (void)config_dump_human(filter, NULL, scope, setting_name_filter, hide_passwords);
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void config_request_simple_stdout(const char *key, const char *value,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng unsigned int i, filter_len;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng for (i = 0; setting_name_filters[i] != NULL; i++) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (strncmp(setting_name_filters[i], key, filter_len) == 0 &&
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng (key[filter_len] == '\0' || key[filter_len] == '/'))
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void config_request_putenv(const char *key, const char *value,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng env_put(t_strconcat(t_str_ucase(key), "=", value, NULL));
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic const char *get_setting(const char *module, const char *name)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const char *const *value;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const void *set;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng for (l = config_module_parsers; l->root != NULL; l++) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng for (def = l->root->defines; def->key != NULL; def++) {
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void filter_parse_arg(struct config_filter *filter, const char *arg)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng unsigned int numcount;
da14cebe459d3275048785f25bd869cb09b5307fEric Chenghostname_format_write(string_t *str, const struct hostname_format *fmt,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng unsigned int num)
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyerstatic void hostname_verify_format(const char *arg)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const char *p;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const char *host2;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* host%d, host%2d, host%02d */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (*p == '0') {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (*p++ != 'd')
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* detect host1[suffix] vs host01[suffix] */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng while (len > 0 && !i_isdigit(my_hostname[len-1]))
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng while (len > 0 && i_isdigit(my_hostname[len-1])) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng i_fatal("Hostname '%s' has no digits, can't verify",
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng hash_table_create_direct(&hosts, default_pool, limit);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng for (n = 0; n < limit; n++) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng hash_table_insert(hosts, key, POINTER_CAST(n+1));
return FATAL_DEFAULT;
if (host_verify)
} else if (!simple_output) {
if (print_plugin_banner) {
struct module *m;
&error)) == 0 &&
error);
if (simple_output) {
ret2 = 0;
ret = 0;
const char *info;
if (!config_path_specified)
if (ret < 0) {
if (ret2 < 0)