void config_filter_deinit(struct config_filter_context **_ctx)
{
struct config_filter_context *ctx = *_ctx;
+ unsigned int i;
*_ctx = NULL;
+ for (i = 0; ctx->parsers[i] != NULL; i++)
+ config_filter_parsers_free(ctx->parsers[i]->parsers);
pool_unref(&ctx->pool);
}
return 0;
}
-int config_filter_get_parsers(struct config_filter_context *ctx, pool_t pool,
+int config_filter_parsers_get(struct config_filter_context *ctx, pool_t pool,
const struct config_filter *filter,
- const struct config_module_parser **parsers_r,
+ struct config_module_parser **parsers_r,
const char **error_r)
{
struct config_filter_parser *const *src;
if (config_module_parser_apply_changes(dest, src[i], pool,
error_p) < 0) {
+ config_filter_parsers_free(dest);
*error_r = error;
return -1;
}
*parsers_r = dest;
return 0;
}
+
+void config_filter_parsers_free(struct config_module_parser *parsers)
+{
+ unsigned int i;
+
+ for (i = 0; parsers[i].module_name != NULL; i++)
+ settings_parser_deinit(&parsers[i].parser);
+}
struct config_filter_parser *const *parsers);
/* Build new parsers from all existing ones matching the given filter. */
-int config_filter_get_parsers(struct config_filter_context *ctx, pool_t pool,
+int config_filter_parsers_get(struct config_filter_context *ctx, pool_t pool,
const struct config_filter *filter,
- const struct config_module_parser **parsers_r,
+ struct config_module_parser **parsers_r,
const char **error_r);
+void config_filter_parsers_free(struct config_module_parser *parsers);
/* Returns TRUE if filter matches mask. */
bool config_filter_match(const struct config_filter *mask,
const char **error_r)
{
struct config_filter_parser *const *parsers;
- const struct config_module_parser *tmp_parsers;
+ struct config_module_parser *tmp_parsers;
unsigned int i, count;
pool_t tmp_pool;
+ int ret = 0;
tmp_pool = pool_alloconly_create("config parsers check", 1024*32);
parsers = array_get(&ctx->all_parsers, &count);
i_assert(count > 0 && parsers[count-1] == NULL);
count--;
- for (i = 0; i < count; i++) {
- p_clear(tmp_pool);
- if (config_filter_get_parsers(new_filter, tmp_pool,
+ for (i = 0; i < count && ret == 0; i++) {
+ if (config_filter_parsers_get(new_filter, tmp_pool,
&parsers[i]->filter,
- &tmp_parsers, error_r) < 0)
+ &tmp_parsers, error_r) < 0) {
+ ret = -1;
break;
+ }
- if (config_filter_parser_check(ctx, tmp_parsers, error_r) < 0)
- break;
+ ret = config_filter_parser_check(ctx, tmp_parsers, error_r);
+ config_filter_parsers_free(tmp_parsers);
+ p_clear(tmp_pool);
}
- return i == count ? 0 : -1;
+ pool_unref(&tmp_pool);
+ return ret;
}
static int
bool check_settings,
config_request_callback_t *callback, void *context)
{
- const struct config_module_parser *l;
+ struct config_module_parser *parsers, *parser;
struct settings_export_context ctx;
const char *error;
+ unsigned int i;
int ret = 0;
memset(&ctx, 0, sizeof(ctx));
ctx.pool = pool_alloconly_create("config request", 1024*16);
- if (config_filter_get_parsers(config_filter, ctx.pool, filter,
- &l, &error) < 0) {
+ if (config_filter_parsers_get(config_filter, ctx.pool, filter,
+ &parsers, &error) < 0) {
i_error("%s", error);
pool_unref(&ctx.pool);
return -1;
ctx.keys = hash_table_create(default_pool, ctx.pool, 0,
str_hash, (hash_cmp_callback_t *)strcmp);
- for (; l->module_name != NULL; l++) {
+ for (i = 0; parsers[i].module_name != NULL; i++) {
+ parser = &parsers[i];
if (*module != '\0' &&
- !config_module_parser_is_in_service(l, module))
+ !config_module_parser_is_in_service(parser, module))
continue;
- settings_export(&ctx, l->root, settings_parser_get(l->parser),
- settings_parser_get_changes(l->parser));
+ settings_export(&ctx, parser->root,
+ settings_parser_get(parser->parser),
+ settings_parser_get_changes(parser->parser));
if (check_settings) {
- if (!settings_parser_check(l->parser, ctx.pool,
+ if (!settings_parser_check(parser->parser, ctx.pool,
&error)) {
i_error("%s", error);
ret = -1;
}
}
}
+ config_filter_parsers_free(parsers);
hash_table_destroy(&ctx.keys);
pool_unref(&ctx.pool);
return ret;
o_stream_cork(output);
config_connection_request_human(output, filter, module, scope);
o_stream_uncork(output);
+ o_stream_unref(&output);
}
static void config_request_putenv(const char *key, const char *value,
execvp(exec_args[0], exec_args);
i_fatal("execvp(%s) failed: %m", exec_args[0]);
}
+ config_filter_deinit(&config_filter);
master_service_deinit(&master_service);
return 0;
}
master_service_run(master_service, client_connected);
config_connections_destroy_all();
+
+ config_filter_deinit(&config_filter);
master_service_deinit(&master_service);
return 0;
}
lib_signals_deinit();
io_loop_destroy(&service->ioloop);
+ i_free(service->listeners);
i_free(service->name);
i_free(service);
i_assert(count > 0);
- pool_ref(set_pool);
parser_pool = pool_alloconly_create("settings parser", 16384);
ctx = p_new(parser_pool, struct setting_parser_context, 1);
ctx->set_pool = set_pool;
struct hash_table *links;
void *key, *value;
unsigned int i;
+ pool_t parser_pool;
pool_ref(new_pool);
- new_ctx = p_new(new_pool, struct setting_parser_context, 1);
+ parser_pool = pool_alloconly_create("dup settings parser", 8192);
+ new_ctx = p_new(parser_pool, struct setting_parser_context, 1);
new_ctx->set_pool = new_pool;
- new_ctx->parser_pool =
- pool_alloconly_create("dup settings parser", 8192);
+ new_ctx->parser_pool = parser_pool;
new_ctx->flags = old_ctx->flags;
new_ctx->str_vars_are_expanded = old_ctx->str_vars_are_expanded;
new_ctx->linenum = old_ctx->linenum;
new_ctx->error = p_strdup(new_ctx->parser_pool, old_ctx->error);
new_ctx->prev_info = old_ctx->prev_info;
- links = hash_table_create(default_pool, default_pool, 0, NULL, NULL);
+ links = hash_table_create(default_pool, new_ctx->parser_pool,
+ 0, NULL, NULL);
new_ctx->root_count = old_ctx->root_count;
new_ctx->roots = p_new(new_ctx->parser_pool, struct setting_link,