config-request.c revision 50fe5e053d565b40b0ed2cc7a64b6b98971c0305
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch/* Copyright (C) 2005-2009 Dovecot authors, see the included COPYING file */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "lib.h"
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch#include "array.h"
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch#include "str.h"
1920ef85b63738a06914e56508049dd0afe38732Timo Sirainen#include "hash.h"
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch#include "ostream.h"
74c09aceb0118b564f8443e1276c465738d19c17Timo Sirainen#include "settings-parser.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "master-service-settings.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "all-settings.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "config-parser.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "config-request.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Boschstruct settings_export_context {
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch pool_t pool;
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch string_t *value;
1d048c5050f03c24251e5af8087e640de21b2d62Timo Sirainen string_t *prefix;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct hash_table *keys;
7944646fad6aa1e7c649c3d33e454c516b0220b6Timo Sirainen enum config_dump_scope scope;
7944646fad6aa1e7c649c3d33e454c516b0220b6Timo Sirainen
7944646fad6aa1e7c649c3d33e454c516b0220b6Timo Sirainen config_request_callback_t *callback;
7944646fad6aa1e7c649c3d33e454c516b0220b6Timo Sirainen void *context;
7944646fad6aa1e7c649c3d33e454c516b0220b6Timo Sirainen
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch enum config_dump_flags flags;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch};
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch
56d1345c43bbd28c36b7faa85e4163bd9e874290Timo Sirainenstatic bool parsers_are_connected(const struct setting_parser_info *root,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch const struct setting_parser_info *info)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
35e962a9186b4e9b2001628c1d7b55c24b33ce84Timo Sirainen const struct setting_parser_info *p;
35e962a9186b4e9b2001628c1d7b55c24b33ce84Timo Sirainen const struct setting_parser_info *const *dep;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
b99130e4cf4af4e6b103b949456222f3a2dff424Timo Sirainen /* we're trying to find info or its parents from root's dependencies. */
b99130e4cf4af4e6b103b949456222f3a2dff424Timo Sirainen
b99130e4cf4af4e6b103b949456222f3a2dff424Timo Sirainen for (p = info; p != NULL; p = p->parent) {
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch if (p == root)
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch return TRUE;
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch }
4219de12b28f1936219e27501b9c4b27a4f8d53cStephan Bosch
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch if (root->dependencies != NULL) {
4c4c4a740bbb1b674d4b0dae009d1919f8ad96b7Stephan Bosch for (dep = root->dependencies; *dep != NULL; dep++) {
4219de12b28f1936219e27501b9c4b27a4f8d53cStephan Bosch for (p = info; p != NULL; p = p->parent) {
4219de12b28f1936219e27501b9c4b27a4f8d53cStephan Bosch if (p == *dep)
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch return TRUE;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch }
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch }
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch }
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch return FALSE;
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch}
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic bool
7384b4e78eaab44693c985192276e31322155e32Stephan Boschconfig_module_parser_is_in_service(const struct config_module_parser *list,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch const char *module)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct config_module_parser *l;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (strcmp(list->root->module_name, module) == 0)
ad03049781fc14807248007d524be4daf06c3ee2Stephan Bosch return TRUE;
ad03049781fc14807248007d524be4daf06c3ee2Stephan Bosch if (list->root == &master_service_setting_parser_info) {
ad03049781fc14807248007d524be4daf06c3ee2Stephan Bosch /* everyone wants master service settings */
e47c2f17d8136c4d972d1074a3f84ba2ecef4fdcStephan Bosch return TRUE;
e47c2f17d8136c4d972d1074a3f84ba2ecef4fdcStephan Bosch }
e47c2f17d8136c4d972d1074a3f84ba2ecef4fdcStephan Bosch
e47c2f17d8136c4d972d1074a3f84ba2ecef4fdcStephan Bosch for (l = config_module_parsers; l->root != NULL; l++) {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (strcmp(l->root->module_name, module) != 0)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch continue;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* see if we can find a way to get from the original parser
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch to this parser */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (parsers_are_connected(l->root, list->root))
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return TRUE;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch }
9d746c6785d17e421c3f3c74cf29d059ae2ab233Stephan Bosch return FALSE;
9d746c6785d17e421c3f3c74cf29d059ae2ab233Stephan Bosch}
9d746c6785d17e421c3f3c74cf29d059ae2ab233Stephan Bosch
9d746c6785d17e421c3f3c74cf29d059ae2ab233Stephan Boschstatic void
9d746c6785d17e421c3f3c74cf29d059ae2ab233Stephan Boschsettings_export(struct settings_export_context *ctx,
9d746c6785d17e421c3f3c74cf29d059ae2ab233Stephan Bosch const struct setting_parser_info *info,
9d746c6785d17e421c3f3c74cf29d059ae2ab233Stephan Bosch bool parent_unique_deflist,
9d746c6785d17e421c3f3c74cf29d059ae2ab233Stephan Bosch const void *set, const void *change_set)
9d746c6785d17e421c3f3c74cf29d059ae2ab233Stephan Bosch{
9d746c6785d17e421c3f3c74cf29d059ae2ab233Stephan Bosch const struct setting_define *def;
9d746c6785d17e421c3f3c74cf29d059ae2ab233Stephan Bosch const void *value, *default_value, *change_value;
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch void *const *children = NULL, *const *change_children = NULL;
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch unsigned int i, count, count2, prefix_len;
94d1b08c9e20d637db568a3eab3dfc2b9e96e62aStephan Bosch const char *str;
94d1b08c9e20d637db568a3eab3dfc2b9e96e62aStephan Bosch char *key;
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch bool dump, dump_default = FALSE;
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch for (def = info->defines; def->key != NULL; def++) {
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch value = CONST_PTR_OFFSET(set, def->offset);
b66def5dadd3e7c250313a938d26ad113663f86bStephan Bosch default_value = info->defaults == NULL ? NULL :
b66def5dadd3e7c250313a938d26ad113663f86bStephan Bosch CONST_PTR_OFFSET(info->defaults, def->offset);
b66def5dadd3e7c250313a938d26ad113663f86bStephan Bosch change_value = CONST_PTR_OFFSET(change_set, def->offset);
b66def5dadd3e7c250313a938d26ad113663f86bStephan Bosch switch (ctx->scope) {
b66def5dadd3e7c250313a938d26ad113663f86bStephan Bosch case CONFIG_DUMP_SCOPE_ALL:
b66def5dadd3e7c250313a938d26ad113663f86bStephan Bosch dump_default = TRUE;
a8c4e79ff50fac21b05a7368b052583d410ca15cTimo Sirainen break;
a8c4e79ff50fac21b05a7368b052583d410ca15cTimo Sirainen case CONFIG_DUMP_SCOPE_SET:
a8c4e79ff50fac21b05a7368b052583d410ca15cTimo Sirainen dump_default = *((const char *)change_value) != 0;
a8c4e79ff50fac21b05a7368b052583d410ca15cTimo Sirainen break;
a8c4e79ff50fac21b05a7368b052583d410ca15cTimo Sirainen case CONFIG_DUMP_SCOPE_CHANGED:
a8c4e79ff50fac21b05a7368b052583d410ca15cTimo Sirainen dump_default = FALSE;
70505f4839520ac67895992621c97d2480c22e7fTimo Sirainen break;
70505f4839520ac67895992621c97d2480c22e7fTimo Sirainen }
70505f4839520ac67895992621c97d2480c22e7fTimo Sirainen if (!parent_unique_deflist ||
70505f4839520ac67895992621c97d2480c22e7fTimo Sirainen (ctx->flags & CONFIG_DUMP_FLAG_HIDE_LIST_DEFAULTS) == 0) {
a8c4e79ff50fac21b05a7368b052583d410ca15cTimo Sirainen /* .. */
93cc87bb22386e020cee1093b6bd59295e0b33f0Stephan Bosch } else if (*((const char *)change_value) == 0 &&
93cc87bb22386e020cee1093b6bd59295e0b33f0Stephan Bosch def->offset != info->type_offset) {
93cc87bb22386e020cee1093b6bd59295e0b33f0Stephan Bosch /* this is mainly for service {} blocks. if value
93cc87bb22386e020cee1093b6bd59295e0b33f0Stephan Bosch hasn't changed, it's the default. even if
93cc87bb22386e020cee1093b6bd59295e0b33f0Stephan Bosch info->defaults has a different value. */
93cc87bb22386e020cee1093b6bd59295e0b33f0Stephan Bosch default_value = value;
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch } else {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* value is set explicitly, but we don't know the
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch default here. assume it's not the default. */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch dump_default = TRUE;
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch }
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch dump = FALSE;
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch count = 0;
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch str_truncate(ctx->value, 0);
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch switch (def->type) {
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch case SET_BOOL: {
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch const bool *val = value, *dval = default_value;
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch if (dump_default || dval == NULL || *val != *dval) {
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch str_append(ctx->value,
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch *val ? "yes" : "no");
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch }
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch break;
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch }
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch case SET_UINT: {
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch const unsigned int *val = value, *dval = default_value;
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch if (dump_default || dval == NULL || *val != *dval)
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch str_printfa(ctx->value, "%u", *val);
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch break;
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch }
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch case SET_STR_VARS: {
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch const char *const *val = value, *sval;
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch const char *const *_dval = default_value;
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch const char *dval = _dval == NULL ? NULL : *_dval;
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch i_assert(*val == NULL ||
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch **val == SETTING_STRVAR_UNEXPANDED[0]);
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch sval = *val == NULL ? NULL : (*val + 1);
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch if ((dump_default || null_strcmp(sval, dval) != 0) &&
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch sval != NULL) {
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch str_append(ctx->value, sval);
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch dump = TRUE;
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch }
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch break;
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch }
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch case SET_STR: {
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch const char *const *val = value;
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch const char *const *_dval = default_value;
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch const char *dval = _dval == NULL ? NULL : *_dval;
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch if ((dump_default || null_strcmp(*val, dval) != 0) &&
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch *val != NULL) {
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch str_append(ctx->value, *val);
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch dump = TRUE;
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch }
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch break;
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch }
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch case SET_ENUM: {
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch const char *const *val = value;
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch const char *const *_dval = default_value;
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch const char *dval = _dval == NULL ? NULL : *_dval;
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch unsigned int len = strlen(*val);
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch if (dump_default || strncmp(*val, dval, len) != 0 ||
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch ((*val)[len] != ':' && (*val)[len] != '\0'))
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch str_append(ctx->value, *val);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch break;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch }
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch case SET_DEFLIST:
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch case SET_DEFLIST_UNIQUE: {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch const ARRAY_TYPE(void_array) *val = value;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch const ARRAY_TYPE(void_array) *change_val = change_value;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (!array_is_created(val))
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch break;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch children = array_get(val, &count);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch for (i = 0; i < count; i++) {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (i > 0)
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch str_append_c(ctx->value, ' ');
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch str_printfa(ctx->value, "%u", i);
4219de12b28f1936219e27501b9c4b27a4f8d53cStephan Bosch }
4219de12b28f1936219e27501b9c4b27a4f8d53cStephan Bosch change_children = array_get(change_val, &count2);
4219de12b28f1936219e27501b9c4b27a4f8d53cStephan Bosch i_assert(count == count2);
4219de12b28f1936219e27501b9c4b27a4f8d53cStephan Bosch break;
4219de12b28f1936219e27501b9c4b27a4f8d53cStephan Bosch }
4219de12b28f1936219e27501b9c4b27a4f8d53cStephan Bosch case SET_STRLIST: {
4219de12b28f1936219e27501b9c4b27a4f8d53cStephan Bosch const ARRAY_TYPE(const_string) *val = value;
4219de12b28f1936219e27501b9c4b27a4f8d53cStephan Bosch const char *const *strings;
4219de12b28f1936219e27501b9c4b27a4f8d53cStephan Bosch
4219de12b28f1936219e27501b9c4b27a4f8d53cStephan Bosch if (!array_is_created(val))
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch break;
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch key = p_strconcat(ctx->pool, str_c(ctx->prefix),
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch def->key, NULL);
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch if (hash_table_lookup(ctx->keys, key) != NULL) {
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch /* already added all of these */
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch break;
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch }
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch hash_table_insert(ctx->keys, key, key);
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch ctx->callback(key, "0", CONFIG_KEY_LIST, ctx->context);
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch strings = array_get(val, &count);
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch i_assert(count % 2 == 0);
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch for (i = 0; i < count; i += 2) {
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch str = p_strdup_printf(ctx->pool, "%s%s%c0%c%s",
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch str_c(ctx->prefix),
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch def->key,
e47c2f17d8136c4d972d1074a3f84ba2ecef4fdcStephan Bosch SETTINGS_SEPARATOR,
e47c2f17d8136c4d972d1074a3f84ba2ecef4fdcStephan Bosch SETTINGS_SEPARATOR,
e47c2f17d8136c4d972d1074a3f84ba2ecef4fdcStephan Bosch strings[i]);
e47c2f17d8136c4d972d1074a3f84ba2ecef4fdcStephan Bosch ctx->callback(str, strings[i+1],
e47c2f17d8136c4d972d1074a3f84ba2ecef4fdcStephan Bosch CONFIG_KEY_NORMAL, ctx->context);
e47c2f17d8136c4d972d1074a3f84ba2ecef4fdcStephan Bosch }
e47c2f17d8136c4d972d1074a3f84ba2ecef4fdcStephan Bosch count = 0;
e47c2f17d8136c4d972d1074a3f84ba2ecef4fdcStephan Bosch break;
e47c2f17d8136c4d972d1074a3f84ba2ecef4fdcStephan Bosch }
e47c2f17d8136c4d972d1074a3f84ba2ecef4fdcStephan Bosch }
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch if (str_len(ctx->value) > 0 || dump) {
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch key = p_strconcat(ctx->pool, str_c(ctx->prefix),
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch def->key, NULL);
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch if (hash_table_lookup(ctx->keys, key) == NULL) {
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch enum config_key_type type;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (def->offset == info->type_offset &&
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch parent_unique_deflist)
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch type = CONFIG_KEY_UNIQUE_KEY;
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch else if (SETTING_TYPE_IS_DEFLIST(def->type))
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch type = CONFIG_KEY_LIST;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch else
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch type = CONFIG_KEY_NORMAL;
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch ctx->callback(key, str_c(ctx->value), type,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch ctx->context);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch hash_table_insert(ctx->keys, key, key);
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch }
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch }
84740b03d3ee9e96a2e446a54729188764c99292Timo Sirainen
84740b03d3ee9e96a2e446a54729188764c99292Timo Sirainen prefix_len = str_len(ctx->prefix);
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch for (i = 0; i < count; i++) {
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch str_append(ctx->prefix, def->key);
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch str_append_c(ctx->prefix, SETTINGS_SEPARATOR);
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch str_printfa(ctx->prefix, "%u", i);
6d573191bea1a64d6046be070487a5705a2d0204Stephan Bosch str_append_c(ctx->prefix, SETTINGS_SEPARATOR);
6d573191bea1a64d6046be070487a5705a2d0204Stephan Bosch settings_export(ctx, def->list_info,
6d573191bea1a64d6046be070487a5705a2d0204Stephan Bosch def->type == SET_DEFLIST_UNIQUE,
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch children[i], change_children[i]);
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch str_truncate(ctx->prefix, prefix_len);
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch }
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch }
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch}
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Boschint config_request_handle(const struct config_filter *filter,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch const char *module, enum config_dump_scope scope,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch enum config_dump_flags flags,
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch config_request_callback_t *callback, void *context)
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch{
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch struct config_module_parser *parsers, *parser;
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch struct settings_export_context ctx;
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch const char *error;
7a13cd2268a5a99d2975a1648d6d14ffe1b6ccb0Stephan Bosch unsigned int i;
7a13cd2268a5a99d2975a1648d6d14ffe1b6ccb0Stephan Bosch int ret = 0;
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Bosch
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch memset(&ctx, 0, sizeof(ctx));
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch ctx.pool = pool_alloconly_create("config request", 1024*32);
b66def5dadd3e7c250313a938d26ad113663f86bStephan Bosch
b66def5dadd3e7c250313a938d26ad113663f86bStephan Bosch if (config_filter_parsers_get(config_filter, ctx.pool, filter,
b66def5dadd3e7c250313a938d26ad113663f86bStephan Bosch &parsers, &error) < 0) {
b66def5dadd3e7c250313a938d26ad113663f86bStephan Bosch i_error("%s", error);
b66def5dadd3e7c250313a938d26ad113663f86bStephan Bosch pool_unref(&ctx.pool);
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch return -1;
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch }
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch ctx.flags = flags;
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch ctx.callback = callback;
30f35cf5d1e1374d7fab4231e86144fc106a8e79Stephan Bosch ctx.context = context;
30f35cf5d1e1374d7fab4231e86144fc106a8e79Stephan Bosch ctx.scope = scope;
30f35cf5d1e1374d7fab4231e86144fc106a8e79Stephan Bosch ctx.value = t_str_new(256);
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch ctx.prefix = t_str_new(64);
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch ctx.keys = hash_table_create(default_pool, ctx.pool, 0,
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch str_hash, (hash_cmp_callback_t *)strcmp);
93cc87bb22386e020cee1093b6bd59295e0b33f0Stephan Bosch
93cc87bb22386e020cee1093b6bd59295e0b33f0Stephan Bosch for (i = 0; parsers[i].root != NULL; i++) {
93cc87bb22386e020cee1093b6bd59295e0b33f0Stephan Bosch parser = &parsers[i];
93cc87bb22386e020cee1093b6bd59295e0b33f0Stephan Bosch if (*module != '\0' &&
de0181258ab66b527ad8dc7e51a8efa76b4658d0Stephan Bosch !config_module_parser_is_in_service(parser, module))
de0181258ab66b527ad8dc7e51a8efa76b4658d0Stephan Bosch continue;
93cc87bb22386e020cee1093b6bd59295e0b33f0Stephan Bosch
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch settings_export(&ctx, parser->root, FALSE,
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch settings_parser_get(parser->parser),
2a9cadfccc8fb2c609eedbb929952b49181b6d25Stephan Bosch settings_parser_get_changes(parser->parser));
2a9cadfccc8fb2c609eedbb929952b49181b6d25Stephan Bosch
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch if ((flags & CONFIG_DUMP_FLAG_CHECK_SETTINGS) != 0) {
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch settings_parse_var_skip(parser->parser);
2a9cadfccc8fb2c609eedbb929952b49181b6d25Stephan Bosch if (!settings_parser_check(parser->parser, ctx.pool,
2a9cadfccc8fb2c609eedbb929952b49181b6d25Stephan Bosch &error)) {
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch i_error("%s", error);
1d048c5050f03c24251e5af8087e640de21b2d62Timo Sirainen ret = -1;
2a9cadfccc8fb2c609eedbb929952b49181b6d25Stephan Bosch break;
2a9cadfccc8fb2c609eedbb929952b49181b6d25Stephan Bosch }
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch }
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch }
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch config_filter_parsers_free(parsers);
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch hash_table_destroy(&ctx.keys);
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch pool_unref(&ctx.pool);
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch return ret;
6c768e0e1ca2da178e79f7435c32ced01f6bcb24Timo Sirainen}
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch