bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2005-2018 Dovecot authors, see the included COPYING file */
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen#include "lib.h"
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen#include "array.h"
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen#include "str.h"
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen#include "hash.h"
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen#include "ostream.h"
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen#include "settings-parser.h"
72f67d7d7681934bb3d4baaea1d88f79521dee3dTimo Sirainen#include "master-service-settings.h"
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen#include "all-settings.h"
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen#include "config-parser.h"
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen#include "config-request.h"
42cb779853b1814d7ab052436b0b6d1f507c742bAki Tuomi#include "old-set-parser.h"
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainenstruct config_export_context {
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen pool_t pool;
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen string_t *value;
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen string_t *prefix;
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen HASH_TABLE(char *, char *) keys;
56439f2879ad690d9ac637e2b90b612760d2f219Timo Sirainen enum config_dump_scope scope;
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen config_request_callback_t *callback;
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen void *context;
50fe5e053d565b40b0ed2cc7a64b6b98971c0305Timo Sirainen
633a3da9d3e9a5befd3405f6651043a6bdd327cbTimo Sirainen const char *const *modules;
50fe5e053d565b40b0ed2cc7a64b6b98971c0305Timo Sirainen enum config_dump_flags flags;
c0787d6ab19f4a17ec08699d0bbc77f13a9b02a9Timo Sirainen const struct config_module_parser *parsers;
c0787d6ab19f4a17ec08699d0bbc77f13a9b02a9Timo Sirainen struct config_module_parser *dup_parsers;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen struct master_service_settings_output output;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen bool failed;
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen};
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainenstatic void config_export_size(string_t *str, uoff_t size)
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen{
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen static const char suffixes[] = { 'B', 'k', 'M', 'G', 'T' };
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen char suffix = suffixes[0];
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen unsigned int i;
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen if (size == 0) {
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen str_append_c(str, '0');
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen return;
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen }
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen for (i = 1; i < N_ELEMENTS(suffixes) && (size % 1024) == 0; i++) {
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen suffix = suffixes[i];
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen size /= 1024;
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen }
47a5a7e8296f3b8f2fac9a0659d4de3f2723ba4aMartti Rannanjärvi str_printfa(str, "%"PRIuUOFF_T" %c", size, suffix);
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen}
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainenstatic void config_export_time(string_t *str, unsigned int stamp)
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen{
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen const char *suffix = "secs";
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen if (stamp == 0) {
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen str_append_c(str, '0');
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen return;
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen }
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen if (stamp % 60 == 0) {
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen stamp /= 60;
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen suffix = "mins";
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen if (stamp % 60 == 0) {
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen stamp /= 60;
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen suffix = "hours";
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen if (stamp % 24 == 0) {
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen stamp /= 24;
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen suffix = "days";
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen if (stamp % 7 == 0) {
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen stamp /= 7;
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen suffix = "weeks";
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen }
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen }
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen }
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen }
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen str_printfa(str, "%u %s", stamp, suffix);
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen}
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen
2ed05ea827dc49e715a4859a2ca485dc1934f1a3Timo Sirainenstatic void config_export_time_msecs(string_t *str, unsigned int stamp_msecs)
2ed05ea827dc49e715a4859a2ca485dc1934f1a3Timo Sirainen{
2ed05ea827dc49e715a4859a2ca485dc1934f1a3Timo Sirainen if ((stamp_msecs % 1000) == 0)
2ed05ea827dc49e715a4859a2ca485dc1934f1a3Timo Sirainen config_export_time(str, stamp_msecs/1000);
2ed05ea827dc49e715a4859a2ca485dc1934f1a3Timo Sirainen else
2ed05ea827dc49e715a4859a2ca485dc1934f1a3Timo Sirainen str_printfa(str, "%u ms", stamp_msecs);
2ed05ea827dc49e715a4859a2ca485dc1934f1a3Timo Sirainen}
2ed05ea827dc49e715a4859a2ca485dc1934f1a3Timo Sirainen
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainenbool config_export_type(string_t *str, const void *value,
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen const void *default_value,
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen enum setting_type type, bool dump_default,
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen bool *dump_r)
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen{
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen switch (type) {
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen case SET_BOOL: {
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen const bool *val = value, *dval = default_value;
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen if (dump_default || dval == NULL || *val != *dval)
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen str_append(str, *val ? "yes" : "no");
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen break;
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen }
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen case SET_SIZE: {
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen const uoff_t *val = value, *dval = default_value;
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen if (dump_default || dval == NULL || *val != *dval)
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen config_export_size(str, *val);
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen break;
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen }
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen case SET_UINT:
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen case SET_UINT_OCT:
2ed05ea827dc49e715a4859a2ca485dc1934f1a3Timo Sirainen case SET_TIME:
2ed05ea827dc49e715a4859a2ca485dc1934f1a3Timo Sirainen case SET_TIME_MSECS: {
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen const unsigned int *val = value, *dval = default_value;
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen if (dump_default || dval == NULL || *val != *dval) {
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen switch (type) {
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen case SET_UINT_OCT:
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen str_printfa(str, "0%o", *val);
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen break;
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen case SET_TIME:
ca7e608c21bdfd7b6a2e7fcb2678ade4c1c1972cTimo Sirainen config_export_time(str, *val);
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen break;
2ed05ea827dc49e715a4859a2ca485dc1934f1a3Timo Sirainen case SET_TIME_MSECS:
2ed05ea827dc49e715a4859a2ca485dc1934f1a3Timo Sirainen config_export_time_msecs(str, *val);
2ed05ea827dc49e715a4859a2ca485dc1934f1a3Timo Sirainen break;
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen default:
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen str_printfa(str, "%u", *val);
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen break;
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen }
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen }
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen break;
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen }
3ba70a3fa363850cc513d3cf28d1916e2469b90fTimo Sirainen case SET_IN_PORT: {
009217abb57a24a4076092e8e4e165545747839eStephan Bosch const in_port_t *val = value, *dval = default_value;
009217abb57a24a4076092e8e4e165545747839eStephan Bosch
009217abb57a24a4076092e8e4e165545747839eStephan Bosch if (dump_default || dval == NULL || *val != *dval)
009217abb57a24a4076092e8e4e165545747839eStephan Bosch str_printfa(str, "%u", *val);
009217abb57a24a4076092e8e4e165545747839eStephan Bosch break;
009217abb57a24a4076092e8e4e165545747839eStephan Bosch }
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen case SET_STR_VARS: {
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen const char *const *val = value, *sval;
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen const char *const *_dval = default_value;
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen const char *dval = _dval == NULL ? NULL : *_dval;
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen i_assert(*val == NULL ||
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen **val == SETTING_STRVAR_UNEXPANDED[0]);
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen sval = *val == NULL ? NULL : (*val + 1);
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen if ((dump_default || null_strcmp(sval, dval) != 0) &&
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen sval != NULL) {
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen str_append(str, sval);
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen *dump_r = TRUE;
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen }
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen break;
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen }
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen case SET_STR: {
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen const char *const *val = value;
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen const char *const *_dval = default_value;
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen const char *dval = _dval == NULL ? NULL : *_dval;
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen if ((dump_default || null_strcmp(*val, dval) != 0) &&
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen *val != NULL) {
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen str_append(str, *val);
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen *dump_r = TRUE;
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen }
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen break;
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen }
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen case SET_ENUM: {
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen const char *const *val = value;
2ac5f36aa7c2e7a07ba8815d43a6d7483f62e74cTimo Sirainen size_t len = strlen(*val);
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen
b879ed8dd4b5850987e6b89a92f794d87c6be7d7Timo Sirainen if (dump_default)
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen str_append(str, *val);
b879ed8dd4b5850987e6b89a92f794d87c6be7d7Timo Sirainen else {
b879ed8dd4b5850987e6b89a92f794d87c6be7d7Timo Sirainen const char *const *_dval = default_value;
b879ed8dd4b5850987e6b89a92f794d87c6be7d7Timo Sirainen const char *dval = _dval == NULL ? NULL : *_dval;
b879ed8dd4b5850987e6b89a92f794d87c6be7d7Timo Sirainen
b879ed8dd4b5850987e6b89a92f794d87c6be7d7Timo Sirainen i_assert(dval != NULL);
b879ed8dd4b5850987e6b89a92f794d87c6be7d7Timo Sirainen if (strncmp(*val, dval, len) != 0 ||
b879ed8dd4b5850987e6b89a92f794d87c6be7d7Timo Sirainen ((*val)[len] != ':' && (*val)[len] != '\0'))
b879ed8dd4b5850987e6b89a92f794d87c6be7d7Timo Sirainen str_append(str, *val);
b879ed8dd4b5850987e6b89a92f794d87c6be7d7Timo Sirainen }
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen break;
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen }
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen default:
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen return FALSE;
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen }
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen return TRUE;
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen}
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen
d1d425c3ed541dde4ae11e88291a0044e6c55f88Timo Sirainenstatic void
d1d425c3ed541dde4ae11e88291a0044e6c55f88Timo Sirainensetting_export_section_name(string_t *str, const struct setting_define *def,
d1d425c3ed541dde4ae11e88291a0044e6c55f88Timo Sirainen const void *set, unsigned int idx)
d1d425c3ed541dde4ae11e88291a0044e6c55f88Timo Sirainen{
d1d425c3ed541dde4ae11e88291a0044e6c55f88Timo Sirainen const char *const *name;
d1d425c3ed541dde4ae11e88291a0044e6c55f88Timo Sirainen size_t name_offset;
d1d425c3ed541dde4ae11e88291a0044e6c55f88Timo Sirainen
d1d425c3ed541dde4ae11e88291a0044e6c55f88Timo Sirainen if (def->type != SET_DEFLIST_UNIQUE) {
d1d425c3ed541dde4ae11e88291a0044e6c55f88Timo Sirainen /* not unique, use the index */
d1d425c3ed541dde4ae11e88291a0044e6c55f88Timo Sirainen str_printfa(str, "%u", idx);
d1d425c3ed541dde4ae11e88291a0044e6c55f88Timo Sirainen return;
d1d425c3ed541dde4ae11e88291a0044e6c55f88Timo Sirainen }
d1d425c3ed541dde4ae11e88291a0044e6c55f88Timo Sirainen name_offset = def->list_info->type_offset;
d1d425c3ed541dde4ae11e88291a0044e6c55f88Timo Sirainen i_assert(name_offset != (size_t)-1);
d1d425c3ed541dde4ae11e88291a0044e6c55f88Timo Sirainen
d1d425c3ed541dde4ae11e88291a0044e6c55f88Timo Sirainen name = CONST_PTR_OFFSET(set, name_offset);
d1d425c3ed541dde4ae11e88291a0044e6c55f88Timo Sirainen if (*name == NULL || **name == '\0') {
d1d425c3ed541dde4ae11e88291a0044e6c55f88Timo Sirainen /* no name, this one isn't unique. use the index. */
d1d425c3ed541dde4ae11e88291a0044e6c55f88Timo Sirainen str_printfa(str, "%u", idx);
d1d425c3ed541dde4ae11e88291a0044e6c55f88Timo Sirainen } else {
d1d425c3ed541dde4ae11e88291a0044e6c55f88Timo Sirainen str_append(str, settings_section_escape(*name));
d1d425c3ed541dde4ae11e88291a0044e6c55f88Timo Sirainen }
d1d425c3ed541dde4ae11e88291a0044e6c55f88Timo Sirainen}
d1d425c3ed541dde4ae11e88291a0044e6c55f88Timo Sirainen
d84c270231a617298088f597474a73f4a14921aeTimo Sirainenstatic void
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainensettings_export(struct config_export_context *ctx,
d84c270231a617298088f597474a73f4a14921aeTimo Sirainen const struct setting_parser_info *info,
d84c270231a617298088f597474a73f4a14921aeTimo Sirainen bool parent_unique_deflist,
d84c270231a617298088f597474a73f4a14921aeTimo Sirainen const void *set, const void *change_set)
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen{
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen const struct setting_define *def;
56439f2879ad690d9ac637e2b90b612760d2f219Timo Sirainen const void *value, *default_value, *change_value;
25f959d63f5379702f44f5ae125eb3b70a6a47d7Timo Sirainen void *const *children, *const *change_children = NULL;
2ac5f36aa7c2e7a07ba8815d43a6d7483f62e74cTimo Sirainen unsigned int i, count, count2;
2ac5f36aa7c2e7a07ba8815d43a6d7483f62e74cTimo Sirainen size_t prefix_len;
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen const char *str;
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen char *key;
56439f2879ad690d9ac637e2b90b612760d2f219Timo Sirainen bool dump, dump_default = FALSE;
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen for (def = info->defines; def->key != NULL; def++) {
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen value = CONST_PTR_OFFSET(set, def->offset);
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen default_value = info->defaults == NULL ? NULL :
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen CONST_PTR_OFFSET(info->defaults, def->offset);
56439f2879ad690d9ac637e2b90b612760d2f219Timo Sirainen change_value = CONST_PTR_OFFSET(change_set, def->offset);
56439f2879ad690d9ac637e2b90b612760d2f219Timo Sirainen switch (ctx->scope) {
56439f2879ad690d9ac637e2b90b612760d2f219Timo Sirainen case CONFIG_DUMP_SCOPE_ALL:
56439f2879ad690d9ac637e2b90b612760d2f219Timo Sirainen dump_default = TRUE;
56439f2879ad690d9ac637e2b90b612760d2f219Timo Sirainen break;
56439f2879ad690d9ac637e2b90b612760d2f219Timo Sirainen case CONFIG_DUMP_SCOPE_SET:
56439f2879ad690d9ac637e2b90b612760d2f219Timo Sirainen dump_default = *((const char *)change_value) != 0;
56439f2879ad690d9ac637e2b90b612760d2f219Timo Sirainen break;
56439f2879ad690d9ac637e2b90b612760d2f219Timo Sirainen case CONFIG_DUMP_SCOPE_CHANGED:
56439f2879ad690d9ac637e2b90b612760d2f219Timo Sirainen dump_default = FALSE;
56439f2879ad690d9ac637e2b90b612760d2f219Timo Sirainen break;
56439f2879ad690d9ac637e2b90b612760d2f219Timo Sirainen }
50fe5e053d565b40b0ed2cc7a64b6b98971c0305Timo Sirainen if (!parent_unique_deflist ||
50fe5e053d565b40b0ed2cc7a64b6b98971c0305Timo Sirainen (ctx->flags & CONFIG_DUMP_FLAG_HIDE_LIST_DEFAULTS) == 0) {
50fe5e053d565b40b0ed2cc7a64b6b98971c0305Timo Sirainen /* .. */
50fe5e053d565b40b0ed2cc7a64b6b98971c0305Timo Sirainen } else if (*((const char *)change_value) == 0 &&
50fe5e053d565b40b0ed2cc7a64b6b98971c0305Timo Sirainen def->offset != info->type_offset) {
6899af0c40f5e1ef80bd18961cea3a192134a4a4Timo Sirainen /* this is mainly for service {} blocks. if value
6899af0c40f5e1ef80bd18961cea3a192134a4a4Timo Sirainen hasn't changed, it's the default. even if
6899af0c40f5e1ef80bd18961cea3a192134a4a4Timo Sirainen info->defaults has a different value. */
6899af0c40f5e1ef80bd18961cea3a192134a4a4Timo Sirainen default_value = value;
50fe5e053d565b40b0ed2cc7a64b6b98971c0305Timo Sirainen } else {
d84c270231a617298088f597474a73f4a14921aeTimo Sirainen /* value is set explicitly, but we don't know the
d84c270231a617298088f597474a73f4a14921aeTimo Sirainen default here. assume it's not the default. */
d84c270231a617298088f597474a73f4a14921aeTimo Sirainen dump_default = TRUE;
6899af0c40f5e1ef80bd18961cea3a192134a4a4Timo Sirainen }
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen
396999508030c8498cb538eb8943e6b61394994cTimo Sirainen dump = FALSE;
25f959d63f5379702f44f5ae125eb3b70a6a47d7Timo Sirainen count = 0; children = NULL;
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen str_truncate(ctx->value, 0);
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen switch (def->type) {
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen case SET_BOOL:
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen case SET_SIZE:
50e20db49f29917fe9adcf1b56b11badf28bd0e4Timo Sirainen case SET_UINT:
57fc30eb8669d1a564372a2ca9842da4f118663fTimo Sirainen case SET_UINT_OCT:
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen case SET_TIME:
2ed05ea827dc49e715a4859a2ca485dc1934f1a3Timo Sirainen case SET_TIME_MSECS:
009217abb57a24a4076092e8e4e165545747839eStephan Bosch case SET_IN_PORT:
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen case SET_STR_VARS:
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen case SET_STR:
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen case SET_ENUM:
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen if (!config_export_type(ctx->value, value,
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen default_value, def->type,
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen dump_default, &dump))
7a5e2e937f0f388465c2938645ee971b4fd01bf1Timo Sirainen i_unreached();
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen break;
4b94ae3dcbace4781b64e87aea00ec0bc03a0d8aTimo Sirainen case SET_DEFLIST:
4b94ae3dcbace4781b64e87aea00ec0bc03a0d8aTimo Sirainen case SET_DEFLIST_UNIQUE: {
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen const ARRAY_TYPE(void_array) *val = value;
56439f2879ad690d9ac637e2b90b612760d2f219Timo Sirainen const ARRAY_TYPE(void_array) *change_val = change_value;
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen if (!array_is_created(val))
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen break;
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen children = array_get(val, &count);
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen for (i = 0; i < count; i++) {
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen if (i > 0)
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen str_append_c(ctx->value, ' ');
d1d425c3ed541dde4ae11e88291a0044e6c55f88Timo Sirainen setting_export_section_name(ctx->value, def, children[i], i);
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen }
56439f2879ad690d9ac637e2b90b612760d2f219Timo Sirainen change_children = array_get(change_val, &count2);
56439f2879ad690d9ac637e2b90b612760d2f219Timo Sirainen i_assert(count == count2);
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen break;
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen }
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen case SET_STRLIST: {
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen const ARRAY_TYPE(const_string) *val = value;
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen const char *const *strings;
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen if (!array_is_created(val))
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen break;
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen key = p_strconcat(ctx->pool, str_c(ctx->prefix),
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen def->key, NULL);
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen if (hash_table_lookup(ctx->keys, key) != NULL) {
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen /* already added all of these */
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen break;
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen }
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen hash_table_insert(ctx->keys, key, key);
c84c0d4cb7f16aedbcb3d5db6b2d41851cc572c9Timo Sirainen /* for doveconf -n to see this KEY_LIST */
c84c0d4cb7f16aedbcb3d5db6b2d41851cc572c9Timo Sirainen ctx->callback(key, "", CONFIG_KEY_LIST, ctx->context);
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen strings = array_get(val, &count);
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen i_assert(count % 2 == 0);
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen for (i = 0; i < count; i += 2) {
6851806b0d2e134d52757147e3fc242557ce8b4dTimo Sirainen str = p_strdup_printf(ctx->pool, "%s%s%c%s",
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen str_c(ctx->prefix),
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen def->key,
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen SETTINGS_SEPARATOR,
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen strings[i]);
d84c270231a617298088f597474a73f4a14921aeTimo Sirainen ctx->callback(str, strings[i+1],
d84c270231a617298088f597474a73f4a14921aeTimo Sirainen CONFIG_KEY_NORMAL, ctx->context);
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen }
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen count = 0;
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen break;
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen }
ff561236f26a203378f5bc1682dda406c78822ccTimo Sirainen case SET_ALIAS:
ff561236f26a203378f5bc1682dda406c78822ccTimo Sirainen break;
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen }
396999508030c8498cb538eb8943e6b61394994cTimo Sirainen if (str_len(ctx->value) > 0 || dump) {
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen key = p_strconcat(ctx->pool, str_c(ctx->prefix),
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen def->key, NULL);
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen if (hash_table_lookup(ctx->keys, key) == NULL) {
d84c270231a617298088f597474a73f4a14921aeTimo Sirainen enum config_key_type type;
d84c270231a617298088f597474a73f4a14921aeTimo Sirainen
d84c270231a617298088f597474a73f4a14921aeTimo Sirainen if (def->offset == info->type_offset &&
d84c270231a617298088f597474a73f4a14921aeTimo Sirainen parent_unique_deflist)
d84c270231a617298088f597474a73f4a14921aeTimo Sirainen type = CONFIG_KEY_UNIQUE_KEY;
d84c270231a617298088f597474a73f4a14921aeTimo Sirainen else if (SETTING_TYPE_IS_DEFLIST(def->type))
d84c270231a617298088f597474a73f4a14921aeTimo Sirainen type = CONFIG_KEY_LIST;
d84c270231a617298088f597474a73f4a14921aeTimo Sirainen else
d84c270231a617298088f597474a73f4a14921aeTimo Sirainen type = CONFIG_KEY_NORMAL;
d84c270231a617298088f597474a73f4a14921aeTimo Sirainen ctx->callback(key, str_c(ctx->value), type,
4b94ae3dcbace4781b64e87aea00ec0bc03a0d8aTimo Sirainen ctx->context);
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen hash_table_insert(ctx->keys, key, key);
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen }
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen }
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen
25f959d63f5379702f44f5ae125eb3b70a6a47d7Timo Sirainen i_assert(count == 0 || children != NULL);
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen prefix_len = str_len(ctx->prefix);
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen for (i = 0; i < count; i++) {
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen str_append(ctx->prefix, def->key);
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen str_append_c(ctx->prefix, SETTINGS_SEPARATOR);
d1d425c3ed541dde4ae11e88291a0044e6c55f88Timo Sirainen setting_export_section_name(ctx->prefix, def, children[i], i);
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen str_append_c(ctx->prefix, SETTINGS_SEPARATOR);
d84c270231a617298088f597474a73f4a14921aeTimo Sirainen settings_export(ctx, def->list_info,
d84c270231a617298088f597474a73f4a14921aeTimo Sirainen def->type == SET_DEFLIST_UNIQUE,
d84c270231a617298088f597474a73f4a14921aeTimo Sirainen children[i], change_children[i]);
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen str_truncate(ctx->prefix, prefix_len);
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen }
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen }
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen}
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainenstruct config_export_context *
633a3da9d3e9a5befd3405f6651043a6bdd327cbTimo Sirainenconfig_export_init(const char *const *modules, enum config_dump_scope scope,
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen enum config_dump_flags flags,
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen config_request_callback_t *callback, void *context)
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen{
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen struct config_export_context *ctx;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen pool_t pool;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen
acb0236a7a1242f567cec83480c1efc9fc352f63Timo Sirainen pool = pool_alloconly_create(MEMPOOL_GROWING"config export", 1024*64);
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen ctx = p_new(pool, struct config_export_context, 1);
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen ctx->pool = pool;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen
3b3a70990ab21c97140fcc2d1e3eb84c17d90388Timo Sirainen ctx->modules = modules == NULL ? NULL : p_strarray_dup(pool, modules);
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen ctx->flags = flags;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen ctx->callback = callback;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen ctx->context = context;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen ctx->scope = scope;
33bd898e7756b289e65f43133312d9637afc1371Timo Sirainen ctx->value = str_new(pool, 256);
33bd898e7756b289e65f43133312d9637afc1371Timo Sirainen ctx->prefix = str_new(pool, 64);
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen hash_table_create(&ctx->keys, ctx->pool, 0, str_hash, strcmp);
c0787d6ab19f4a17ec08699d0bbc77f13a9b02a9Timo Sirainen return ctx;
c0787d6ab19f4a17ec08699d0bbc77f13a9b02a9Timo Sirainen}
c0787d6ab19f4a17ec08699d0bbc77f13a9b02a9Timo Sirainen
c0787d6ab19f4a17ec08699d0bbc77f13a9b02a9Timo Sirainenvoid config_export_by_filter(struct config_export_context *ctx,
c0787d6ab19f4a17ec08699d0bbc77f13a9b02a9Timo Sirainen const struct config_filter *filter)
c0787d6ab19f4a17ec08699d0bbc77f13a9b02a9Timo Sirainen{
c0787d6ab19f4a17ec08699d0bbc77f13a9b02a9Timo Sirainen const char *error;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen
194755bdfb97c07ca8b9df071099f68947b971e3Timo Sirainen if (config_filter_parsers_get(config_filter, ctx->pool,
633a3da9d3e9a5befd3405f6651043a6bdd327cbTimo Sirainen ctx->modules, filter,
c0787d6ab19f4a17ec08699d0bbc77f13a9b02a9Timo Sirainen &ctx->dup_parsers, &ctx->output,
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen &error) < 0) {
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen i_error("%s", error);
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen ctx->failed = TRUE;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen }
c0787d6ab19f4a17ec08699d0bbc77f13a9b02a9Timo Sirainen ctx->parsers = ctx->dup_parsers;
c0787d6ab19f4a17ec08699d0bbc77f13a9b02a9Timo Sirainen}
c0787d6ab19f4a17ec08699d0bbc77f13a9b02a9Timo Sirainen
c0787d6ab19f4a17ec08699d0bbc77f13a9b02a9Timo Sirainenvoid config_export_parsers(struct config_export_context *ctx,
c0787d6ab19f4a17ec08699d0bbc77f13a9b02a9Timo Sirainen const struct config_module_parser *parsers)
c0787d6ab19f4a17ec08699d0bbc77f13a9b02a9Timo Sirainen{
c0787d6ab19f4a17ec08699d0bbc77f13a9b02a9Timo Sirainen ctx->parsers = parsers;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen}
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainenvoid config_export_get_output(struct config_export_context *ctx,
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen struct master_service_settings_output *output_r)
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen{
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen *output_r = ctx->output;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen}
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen
4ecee121e141083faf1db165f0ee3bc0cd232d7eTimo Sirainenconst char *
4ecee121e141083faf1db165f0ee3bc0cd232d7eTimo Sirainenconfig_export_get_import_environment(struct config_export_context *ctx)
4ecee121e141083faf1db165f0ee3bc0cd232d7eTimo Sirainen{
4ecee121e141083faf1db165f0ee3bc0cd232d7eTimo Sirainen enum setting_type stype;
4ecee121e141083faf1db165f0ee3bc0cd232d7eTimo Sirainen unsigned int i;
4ecee121e141083faf1db165f0ee3bc0cd232d7eTimo Sirainen
4ecee121e141083faf1db165f0ee3bc0cd232d7eTimo Sirainen for (i = 0; ctx->parsers[i].root != NULL; i++) {
4ecee121e141083faf1db165f0ee3bc0cd232d7eTimo Sirainen if (ctx->parsers[i].root == &master_service_setting_parser_info) {
4ecee121e141083faf1db165f0ee3bc0cd232d7eTimo Sirainen const char *const *value =
4ecee121e141083faf1db165f0ee3bc0cd232d7eTimo Sirainen settings_parse_get_value(ctx->parsers[i].parser,
4ecee121e141083faf1db165f0ee3bc0cd232d7eTimo Sirainen "import_environment", &stype);
4ecee121e141083faf1db165f0ee3bc0cd232d7eTimo Sirainen i_assert(value != NULL);
4ecee121e141083faf1db165f0ee3bc0cd232d7eTimo Sirainen return *value;
4ecee121e141083faf1db165f0ee3bc0cd232d7eTimo Sirainen }
4ecee121e141083faf1db165f0ee3bc0cd232d7eTimo Sirainen }
4ecee121e141083faf1db165f0ee3bc0cd232d7eTimo Sirainen i_unreached();
4ecee121e141083faf1db165f0ee3bc0cd232d7eTimo Sirainen}
4ecee121e141083faf1db165f0ee3bc0cd232d7eTimo Sirainen
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainenstatic void config_export_free(struct config_export_context *ctx)
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen{
c0787d6ab19f4a17ec08699d0bbc77f13a9b02a9Timo Sirainen if (ctx->dup_parsers != NULL)
c0787d6ab19f4a17ec08699d0bbc77f13a9b02a9Timo Sirainen config_filter_parsers_free(ctx->dup_parsers);
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen hash_table_destroy(&ctx->keys);
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen pool_unref(&ctx->pool);
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen}
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainenint config_export_finish(struct config_export_context **_ctx)
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen{
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen struct config_export_context *ctx = *_ctx;
c0787d6ab19f4a17ec08699d0bbc77f13a9b02a9Timo Sirainen const struct config_module_parser *parser;
637ec4c33b4715737a41f7e58c9b6d1f693c27e2Timo Sirainen const char *error;
6ed1e82824590b514201d9db84ba96bdfc832dd5Timo Sirainen unsigned int i;
637ec4c33b4715737a41f7e58c9b6d1f693c27e2Timo Sirainen int ret = 0;
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen *_ctx = NULL;
637ec4c33b4715737a41f7e58c9b6d1f693c27e2Timo Sirainen
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen if (ctx->failed) {
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen config_export_free(ctx);
637ec4c33b4715737a41f7e58c9b6d1f693c27e2Timo Sirainen return -1;
637ec4c33b4715737a41f7e58c9b6d1f693c27e2Timo Sirainen }
637ec4c33b4715737a41f7e58c9b6d1f693c27e2Timo Sirainen
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen for (i = 0; ctx->parsers[i].root != NULL; i++) {
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen parser = &ctx->parsers[i];
633a3da9d3e9a5befd3405f6651043a6bdd327cbTimo Sirainen if (!config_module_want_parser(config_module_parsers,
633a3da9d3e9a5befd3405f6651043a6bdd327cbTimo Sirainen ctx->modules, parser->root))
637ec4c33b4715737a41f7e58c9b6d1f693c27e2Timo Sirainen continue;
637ec4c33b4715737a41f7e58c9b6d1f693c27e2Timo Sirainen
33bd898e7756b289e65f43133312d9637afc1371Timo Sirainen T_BEGIN {
de4869f239d3cae00f4ddab43edb01f8b0223f7dAki Tuomi enum setting_type stype;
de4869f239d3cae00f4ddab43edb01f8b0223f7dAki Tuomi const char *const *value = settings_parse_get_value(parser->parser, "ssl", &stype);
de4869f239d3cae00f4ddab43edb01f8b0223f7dAki Tuomi
63e9db4f938bec812ec1b2b447c7de45183a4f43Aki Tuomi if ((ctx->flags & CONFIG_DUMP_FLAG_IN_SECTION) == 0 &&
a70d867d1fe3584149811c65eb6213deb72be824Aki Tuomi value != NULL && strcmp(*value, "no") != 0 &&
de4869f239d3cae00f4ddab43edb01f8b0223f7dAki Tuomi settings_parse_is_valid_key(parser->parser, "ssl_dh")) {
de4869f239d3cae00f4ddab43edb01f8b0223f7dAki Tuomi value = settings_parse_get_value(parser->parser,
42cb779853b1814d7ab052436b0b6d1f507c742bAki Tuomi "ssl_dh", &stype);
42cb779853b1814d7ab052436b0b6d1f507c742bAki Tuomi
de4869f239d3cae00f4ddab43edb01f8b0223f7dAki Tuomi if (value == NULL || **value == '\0') {
42cb779853b1814d7ab052436b0b6d1f507c742bAki Tuomi const char *newval;
42cb779853b1814d7ab052436b0b6d1f507c742bAki Tuomi if (old_settings_ssl_dh_load(&newval, &error)) {
551f3b2ebd588ca125c01f49b54c4103fbd5b2c5Aki Tuomi if (newval != NULL)
551f3b2ebd588ca125c01f49b54c4103fbd5b2c5Aki Tuomi settings_parse_line(parser->parser, t_strdup_printf("%s=%s", "ssl_dh", newval));
42cb779853b1814d7ab052436b0b6d1f507c742bAki Tuomi } else {
42cb779853b1814d7ab052436b0b6d1f507c742bAki Tuomi i_error("%s", error);
42cb779853b1814d7ab052436b0b6d1f507c742bAki Tuomi ret = -1;
42cb779853b1814d7ab052436b0b6d1f507c742bAki Tuomi }
42cb779853b1814d7ab052436b0b6d1f507c742bAki Tuomi }
42cb779853b1814d7ab052436b0b6d1f507c742bAki Tuomi }
33bd898e7756b289e65f43133312d9637afc1371Timo Sirainen settings_export(ctx, parser->root, FALSE,
33bd898e7756b289e65f43133312d9637afc1371Timo Sirainen settings_parser_get(parser->parser),
33bd898e7756b289e65f43133312d9637afc1371Timo Sirainen settings_parser_get_changes(parser->parser));
33bd898e7756b289e65f43133312d9637afc1371Timo Sirainen } T_END;
637ec4c33b4715737a41f7e58c9b6d1f693c27e2Timo Sirainen
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen if ((ctx->flags & CONFIG_DUMP_FLAG_CHECK_SETTINGS) != 0) {
df6551ce47053de2c366f490bef60803207beaa4Timo Sirainen settings_parse_var_skip(parser->parser);
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen if (!settings_parser_check(parser->parser, ctx->pool,
637ec4c33b4715737a41f7e58c9b6d1f693c27e2Timo Sirainen &error)) {
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen if ((ctx->flags & CONFIG_DUMP_FLAG_CALLBACK_ERRORS) != 0) {
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen ctx->callback(NULL, error, CONFIG_KEY_ERROR,
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen ctx->context);
4383941ed43d004f34f77334a06ad14e6a305607Timo Sirainen } else {
4383941ed43d004f34f77334a06ad14e6a305607Timo Sirainen i_error("%s", error);
4383941ed43d004f34f77334a06ad14e6a305607Timo Sirainen ret = -1;
4383941ed43d004f34f77334a06ad14e6a305607Timo Sirainen break;
4383941ed43d004f34f77334a06ad14e6a305607Timo Sirainen }
637ec4c33b4715737a41f7e58c9b6d1f693c27e2Timo Sirainen }
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen }
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen }
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen config_export_free(ctx);
637ec4c33b4715737a41f7e58c9b6d1f693c27e2Timo Sirainen return ret;
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen}