/* Copyright (C) 2005-2009 Dovecot authors, see the included COPYING file */
#include "common.h"
+#include "array.h"
#include "str.h"
#include "ioloop.h"
#include "network.h"
}
static void config_connection_request(struct config_connection *conn,
- const char *const *args)
+ const char *const *args,
+ enum config_dump_flags flags)
{
+ const char *const *strings;
+ unsigned int i, count;
+ string_t *str;
+
/* <process> [<args>] */
- // FIXME
- o_stream_send(conn->output, str_data(config_string),
- str_len(config_string));
- o_stream_flush(conn->output);
+ str = t_str_new(256);
+ strings = array_get(&config_strings, &count);
+ o_stream_cork(conn->output);
+ for (i = 0; i < count; i += 2) {
+ str_truncate(str, 0);
+ str_printfa(str, "%s=%s\n", strings[i], strings[i+1]);
+ o_stream_send(conn->output, str_data(str), str_len(str));
+ }
+ o_stream_send_str(conn->output, "\n");
+ o_stream_uncork(conn->output);
}
static void config_connection_input(void *context)
if (args[0] == NULL)
continue;
if (strcmp(args[0], "REQ") == 0)
- config_connection_request(conn, args + 1);
+ config_connection_request(conn, args + 1, 0);
}
t_pop();
}
i_free(conn);
}
-void config_connection_dump_request(int fd, const char *service)
+void config_connection_dump_request(int fd, const char *service,
+ enum config_dump_flags flags)
{
struct config_connection *conn;
const char *args[2] = { service, NULL };
conn = config_connection_create(fd);
- config_connection_request(conn, args);
+ config_connection_request(conn, args, flags);
config_connection_destroy(conn);
}
void config_connection_putenv(void)
{
- const char *env, *p, *key, *value;
-
- env = str_c(config_string);
- for (; *env != '\0'; env = p + 1) {
- p = strchr(env, '\n');
- if (env == p || p == NULL)
- break;
-
- T_BEGIN {
- value = strchr(env, '=');
- i_assert(value != NULL && value < p);
- key = t_str_ucase(t_strdup_until(env, value));
- value = t_strdup_until(value, p);
- env_put(t_strconcat(key, value, NULL));
- } T_END;
- }
+ const char *const *strings;
+ unsigned int i, count;
+
+ strings = array_get(&config_strings, &count);
+ for (i = 0; i < count; i += 2) T_BEGIN {
+ env_put(t_strconcat(t_str_ucase(strings[i]), "=",
+ strings[i+1], NULL));
+ } T_END;
}
}
struct settings_export_context {
- string_t *dest;
+ pool_t pool;
+ ARRAY_TYPE(const_string) *dest;
string_t *value;
string_t *prefix;
struct hash_table *keys;
- pool_t pool;
bool export_defaults;
};
const void *value, *default_value;
void *const *children = NULL;
unsigned int i, count, prefix_len;
+ const char *str;
char *key;
for (def = info->defines; def->key != NULL; def++) {
}
case SET_STRLIST: {
const ARRAY_TYPE(const_string) *val = value;
- unsigned int pos = str_len(ctx->dest);
const char *const *strings;
if (!array_is_created(val))
break;
- str_append_str(ctx->dest, ctx->prefix);
- str_append(ctx->dest, def->key);
- str_append(ctx->dest, "=0\n");
+ key = p_strconcat(ctx->pool, str_c(ctx->prefix),
+ def->key, NULL);
- if (hash_table_lookup(ctx->keys,
- str_c(ctx->dest) + pos) != NULL) {
+ if (hash_table_lookup(ctx->keys, key) != NULL) {
/* already added all of these */
- str_truncate(ctx->dest, pos);
break;
}
- key = p_strdup(ctx->pool, str_c(ctx->dest) + pos);
hash_table_insert(ctx->keys, key, key);
+ str = key;
+ array_append(ctx->dest, &str, 1);
+ str = "0";
+ array_append(ctx->dest, &str, 1);
+
strings = array_get(val, &count);
i_assert(count % 2 == 0);
for (i = 0; i < count; i += 2) {
- str_append_str(ctx->dest, ctx->prefix);
- str_append(ctx->dest, def->key);
- str_append_c(ctx->dest, SETTINGS_SEPARATOR);
- str_append_c(ctx->dest, '0');
- str_append_c(ctx->dest, SETTINGS_SEPARATOR);
- str_append(ctx->dest, strings[i+0]);
- str_append_c(ctx->dest, '=');
- str_append(ctx->dest, strings[i+1]);
- str_append_c(ctx->dest, '\n');
+ str = p_strdup_printf(ctx->pool, "%s%s%c0%c%s",
+ str_c(ctx->prefix),
+ def->key,
+ SETTINGS_SEPARATOR,
+ SETTINGS_SEPARATOR,
+ strings[i]);
+ array_append(ctx->dest, &str, 1);
+ str = p_strdup(ctx->pool, strings[i+1]);
+ array_append(ctx->dest, &str, 1);
}
count = 0;
break;
}
}
if (str_len(ctx->value) > 0) {
- unsigned int pos = str_len(ctx->dest);
- str_append_str(ctx->dest, ctx->prefix);
- str_append(ctx->dest, def->key);
-
- if (hash_table_lookup(ctx->keys,
- str_c(ctx->dest) + pos) != NULL) {
- /* already exists */
- str_truncate(ctx->dest, pos);
- } else {
- str_append_c(ctx->dest, '=');
- str_append_str(ctx->dest, ctx->value);
- str_append_c(ctx->dest, '\n');
- key = p_strconcat(ctx->pool, str_c(ctx->prefix),
- def->key, NULL);
+ key = p_strconcat(ctx->pool, str_c(ctx->prefix),
+ def->key, NULL);
+ if (hash_table_lookup(ctx->keys, key) == NULL) {
+ str = key;
+ array_append(ctx->dest, &str, 1);
+ str = p_strdup(ctx->pool, str_c(ctx->value));
+ array_append(ctx->dest, &str, 1);
hash_table_insert(ctx->keys, key, key);
}
}
}
}
-static void config_export(string_t *dest)
+static void config_export(pool_t pool, ARRAY_TYPE(const_string) *dest)
{
struct config_setting_parser_list *l;
struct settings_export_context ctx;
const void *set;
memset(&ctx, 0, sizeof(ctx));
+ ctx.pool = pool;
ctx.dest = dest;
ctx.export_defaults = FALSE;
ctx.value = t_str_new(256);
ctx.prefix = t_str_new(64);
- ctx.pool = pool_alloconly_create("config keys", 10240);
ctx.keys = hash_table_create(default_pool, ctx.pool, 0,
str_hash, (hash_cmp_callback_t *)strcmp);
}
}
hash_table_destroy(&ctx.keys);
- pool_unref(&ctx.pool);
}
static const char *info_type_name_find(const struct setting_parser_info *info)
return NULL;
}
-void config_parse_file(string_t *dest, const char *path, const char *service)
+void config_parse_file(pool_t dest_pool, ARRAY_TYPE(const_string) *dest,
+ const char *path, const char *service)
{
struct input_stack root, *input, *new_input;
ARRAY_DEFINE(pathlen_stack, unsigned int);
string_t *str, *full_line;
size_t len;
pool_t pool;
- bool asis;
pool = pool_alloconly_create("config file parser", 10240);
str = t_str_new(256);
full_line = t_str_new(512);
- errormsg = NULL; ignore = 0; asis = FALSE;
+ errormsg = NULL; ignore = 0;
newfile:
input->input = i_stream_create_fd(fd, (size_t)-1, TRUE);
i_stream_set_return_partial_line(input->input, TRUE);
str_printfa(str, "auth/0/%s=%s", key + 5, line);
errormsg = config_parse_line(pool, key + 5, str_c(str), &info);
array_append(&auth_defaults, &s, 1);
- } else if (asis) {
- /* don't do any parsing, just add it */
- str_append(dest, str_c(str));
- str_append_c(dest, '\n');
} else {
errormsg = config_parse_line(pool, key, str_c(str), &info);
}
if (ignore > 0)
ignore--;
- asis = FALSE;
arr = array_get(&pathlen_stack, &pathlen_count);
if (pathlen_count == 0)
}
}
- config_export(dest);
+ config_export(dest_pool, dest);
}
#include "common.h"
#include "lib-signals.h"
#include "ioloop.h"
+#include "array.h"
#include "env-util.h"
#include "str.h"
#include "config-connection.h"
#include <stdlib.h>
#include <unistd.h>
-string_t *config_string;
-pool_t parsers_pool;
+ARRAY_TYPE(const_string) config_strings;
static const char *config_path = SYSCONFDIR "/" PACKAGE ".conf";
+static pool_t config_pool;
static void main_init(const char *service)
{
if (getenv("LOG_TO_MASTER") != NULL)
i_set_failure_internal();
- config_string = str_new(default_pool, 10240);
- config_parse_file(config_string, config_path, service);
- str_append_c(config_string, '\n');
+ config_pool = pool_alloconly_create("config parser", 10240);
+ p_array_init(&config_strings, config_pool, 256);
+ config_parse_file(config_pool, &config_strings, config_path, service);
}
int main(int argc, char *argv[])
{
+ enum config_dump_flags flags = 0;
struct ioloop *ioloop;
const char *service = "";
char **exec_args = NULL;
- bool dump_nondefaults = FALSE, human_readable = FALSE;
int i;
lib_init();
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-a") == 0) {
- /* FIXME: make it work */
- human_readable = TRUE;
+ flags |= CONFIG_DUMP_FLAG_HUMAN |
+ CONFIG_DUMP_FLAG_DEFAULTS;
} else if (strcmp(argv[i], "-c") == 0) {
/* config file */
i++;
if (i == argc) i_fatal("Missing config file argument");
config_path = argv[i];
} else if (strcmp(argv[i], "-n") == 0) {
- dump_nondefaults = TRUE;
- human_readable = TRUE;
+ flags |= CONFIG_DUMP_FLAG_HUMAN;
} else if (strcmp(argv[i], "-s") == 0) {
/* service */
i++;
main_init(service);
ioloop = io_loop_create();
if (exec_args == NULL)
- config_connection_dump_request(STDOUT_FILENO, "master");
+ config_connection_dump_request(STDOUT_FILENO, "master", flags);
else {
config_connection_putenv();
env_put("DOVECONF_ENV=1");
execvp(exec_args[0], exec_args);
i_fatal("execvp(%s) failed: %m", exec_args[0]);
}
+ pool_unref(&config_pool);
io_loop_destroy(&ioloop);
lib_deinit();
return 0;