dovecot-2.0: doveconf: With -p only protocol-specific settings a...
dovecot at dovecot.org
dovecot at dovecot.org
Thu Apr 30 22:02:53 EEST 2009
details: http://hg.dovecot.org/dovecot-2.0/rev/f8460b27db00
changeset: 9179:f8460b27db00
user: Timo Sirainen <tss at iki.fi>
date: Thu Apr 30 15:02:44 2009 -0400
description:
doveconf: With -p only protocol-specific settings are returned. -n and -a return human-readable output.
diffstat:
14 files changed, 486 insertions(+), 266 deletions(-)
src/config/Makefile.am | 2
src/config/common.h | 8 -
src/config/config-connection.c | 205 +++++++++++++++++++++++++++----
src/config/config-connection.h | 7 -
src/config/config-parser.c | 223 ++--------------------------------
src/config/config-parser.h | 3
src/config/config-request.c | 236 ++++++++++++++++++++++++++++++++++++
src/config/config-request.h | 15 ++
src/config/main.c | 21 +--
src/config/settings-get.pl | 3
src/imap/imap-settings.c | 8 +
src/lib-lda/lda-settings.c | 11 +
src/lib-settings/settings-parser.h | 2
src/pop3/pop3-settings.c | 8 +
diffs (truncated from 1034 to 300 lines):
diff -r 13bbdd7b15b8 -r f8460b27db00 src/config/Makefile.am
--- a/src/config/Makefile.am Thu Apr 30 14:48:54 2009 -0400
+++ b/src/config/Makefile.am Thu Apr 30 15:02:44 2009 -0400
@@ -22,11 +22,11 @@ doveconf_SOURCES = \
all-settings.c \
config-connection.c \
config-parser.c \
+ config-request.c \
main.c
noinst_HEADERS = \
all-settings.h \
- common.h \
config-connection.h \
config-parser.h
diff -r 13bbdd7b15b8 -r f8460b27db00 src/config/common.h
--- a/src/config/common.h Thu Apr 30 14:48:54 2009 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-#ifndef COMMON_H
-#define COMMON_H
-
-#include "lib.h"
-
-extern ARRAY_TYPE(const_string) config_strings;
-
-#endif
diff -r 13bbdd7b15b8 -r f8460b27db00 src/config/config-connection.c
--- a/src/config/config-connection.c Thu Apr 30 14:48:54 2009 -0400
+++ b/src/config/config-connection.c Thu Apr 30 15:02:44 2009 -0400
@@ -1,19 +1,18 @@
/* Copyright (C) 2005-2009 Dovecot authors, see the included COPYING file */
-#include "common.h"
+#include "lib.h"
#include "array.h"
-#include "str.h"
#include "llist.h"
#include "ioloop.h"
#include "network.h"
#include "istream.h"
#include "ostream.h"
#include "env-util.h"
+#include "config-request.h"
#include "config-connection.h"
#include <stdlib.h>
#include <unistd.h>
-#include <fcntl.h>
#define MAX_INBUF_SIZE 1024
@@ -46,24 +45,176 @@ config_connection_next_line(struct confi
return t_strsplit(line, "\t");
}
+static void
+config_request_output(const char *key, const char *value,
+ bool list ATTR_UNUSED, void *context)
+{
+ struct ostream *output = context;
+
+ o_stream_send_str(output, key);
+ o_stream_send_str(output, "=");
+ o_stream_send_str(output, value);
+ o_stream_send_str(output, "\n");
+}
+
+struct config_request_get_string_ctx {
+ pool_t pool;
+ ARRAY_TYPE(const_string) strings;
+};
+
+static void
+config_request_get_strings(const char *key, const char *value,
+ bool list, void *context)
+{
+ struct config_request_get_string_ctx *ctx = context;
+
+ value = p_strdup_printf(ctx->pool, list ? "-%s=%s" : "%s=%s",
+ key, value);
+ array_append(&ctx->strings, &value, 1);
+}
+
+static int config_string_cmp(const void *p1, const void *p2)
+{
+ const char *s1 = *(const char *const *)p1;
+ const char *s2 = *(const char *const *)p2;
+ unsigned int i = 0;
+
+ while (s1[i] == s2[i]) {
+ if (s1[i] == '\0' || s1[i] == '=')
+ return 0;
+ i++;
+ }
+
+ if (s1[i] == '=')
+ return -1;
+ if (s2[i] == '=')
+ return 1;
+ return s1[i] - s2[i];
+}
+
+static unsigned int prefix_stack_pop(ARRAY_TYPE(uint) *stack)
+{
+ const unsigned int *indexes;
+ unsigned int idx, count;
+
+ indexes = array_get(stack, &count);
+ idx = count <= 1 ? -1U : indexes[count-2];
+ array_delete(stack, count-1, 1);
+ return idx;
+}
+
+static void config_connection_request_human(struct ostream *output,
+ const char *service,
+ enum config_dump_flags flags)
+{
+ static const char *ident_str = " ";
+ ARRAY_TYPE(const_string) prefixes_arr;
+ ARRAY_TYPE(uint) prefix_idx_stack;
+ struct config_request_get_string_ctx ctx;
+ const char **strings, *const *args, *p, *str, *const *prefixes;
+ const char *key, *value;
+ unsigned int i, j, count, len, prefix_count, skip_len;
+ unsigned int indent = 0, prefix_idx = -1U;
+
+ ctx.pool = pool_alloconly_create("config human strings", 10240);
+ i_array_init(&ctx.strings, 256);
+ config_request_handle(service, flags, config_request_get_strings, &ctx);
+
+ strings = array_get_modifiable(&ctx.strings, &count);
+ qsort(strings, count, sizeof(*strings), config_string_cmp);
+
+ p_array_init(&prefixes_arr, ctx.pool, 32);
+ for (i = 0; i < count && strings[i][0] == '-'; i++) T_BEGIN {
+ p = strchr(strings[i], '=');
+ i_assert(p != NULL);
+ for (args = t_strsplit(p + 1, " "); *args != NULL; args++) {
+ str = p_strdup_printf(ctx.pool, "%s/%s/",
+ t_strcut(strings[i]+1, '='),
+ *args);
+ array_append(&prefixes_arr, &str, 1);
+ }
+ } T_END;
+ prefixes = array_get(&prefixes_arr, &prefix_count);
+
+ p_array_init(&prefix_idx_stack, ctx.pool, 8);
+ for (; i < count; i++) T_BEGIN {
+ value = strchr(strings[i], '=');
+ i_assert(value != NULL);
+ key = t_strdup_until(strings[i], value);
+ value++;
+
+ j = 0;
+ while (prefix_idx != -1U) {
+ len = strlen(prefixes[prefix_idx]);
+ if (strncmp(prefixes[prefix_idx], key, len) != 0) {
+ prefix_idx = prefix_stack_pop(&prefix_idx_stack);
+ indent--;
+ o_stream_send(output, ident_str, indent*2);
+ o_stream_send_str(output, "}\n");
+ } else if (strchr(key + len, '/') == NULL) {
+ /* keep the prefix */
+ j = prefix_count;
+ break;
+ } else {
+ /* subprefix */
+ break;
+ }
+ }
+ for (; j < prefix_count; j++) {
+ len = strlen(prefixes[j]);
+ if (strncmp(prefixes[j], key, len) == 0 &&
+ strchr(key + len, '/') == NULL) {
+ key += prefix_idx == -1U ? 0 :
+ strlen(prefixes[prefix_idx]);
+ o_stream_send(output, ident_str, indent*2);
+ o_stream_send_str(output, t_strcut(key, '/'));
+ o_stream_send_str(output, " {\n");
+ indent++;
+ prefix_idx = j;
+ array_append(&prefix_idx_stack, &prefix_idx, 1);
+ break;
+ }
+ }
+ skip_len = prefix_idx == -1U ? 0 : strlen(prefixes[prefix_idx]);
+ i_assert(strncmp(prefixes[prefix_idx], strings[i], skip_len) == 0);
+ o_stream_send(output, ident_str, indent*2);
+ key = strings[i] + skip_len;
+ value = strchr(key, '=');
+ o_stream_send(output, key, value-key);
+ o_stream_send_str(output, " = ");
+ o_stream_send_str(output, value+1);
+ o_stream_send(output, "\n", 1);
+ } T_END;
+
+ while (prefix_idx != -1U) {
+ prefix_idx = prefix_stack_pop(&prefix_idx_stack);
+ indent--;
+ o_stream_send(output, ident_str, indent*2);
+ o_stream_send_str(output, "}\n");
+ }
+
+ array_free(&ctx.strings);
+ pool_unref(&ctx.pool);
+}
+
static void config_connection_request(struct config_connection *conn,
const char *const *args,
enum config_dump_flags flags)
{
- const char *const *strings;
- unsigned int i, count;
- string_t *str;
-
- /* <process> [<args>] */
- str = t_str_new(256);
- strings = array_get(&config_strings, &count);
+ const char *service = "";
+
+ /* [<service> [<args>]] */
+ if (args[0] != NULL)
+ service = args[0];
+
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");
+ if ((flags & CONFIG_DUMP_FLAG_HUMAN) == 0) {
+ config_request_handle(service, flags, config_request_output,
+ conn->output);
+ o_stream_send_str(conn->output, "\n");
+ } else {
+ config_connection_request_human(conn->output, service, flags);
+ }
o_stream_uncork(conn->output);
}
@@ -138,20 +289,22 @@ void config_connection_dump_request(int
const char *args[2] = { service, NULL };
conn = config_connection_create(fd);
- config_connection_request(conn, args, flags);
+ config_connection_request(conn, args, flags);
config_connection_destroy(conn);
}
-void config_connection_putenv(void)
-{
- 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));
+static void config_request_putenv(const char *key, const char *value,
+ bool list ATTR_UNUSED,
+ void *context ATTR_UNUSED)
+{
+ T_BEGIN {
+ env_put(t_strconcat(t_str_ucase(key), "=", value, NULL));
} T_END;
+}
+
+void config_connection_putenv(const char *service)
+{
+ config_request_handle(service, 0, config_request_putenv, NULL);
}
void config_connections_destroy_all(void)
diff -r 13bbdd7b15b8 -r f8460b27db00 src/config/config-connection.h
--- a/src/config/config-connection.h Thu Apr 30 14:48:54 2009 -0400
+++ b/src/config/config-connection.h Thu Apr 30 15:02:44 2009 -0400
@@ -1,17 +1,14 @@
#ifndef CONFIG_CONNECTION_H
#define CONFIG_CONNECTION_H
-enum config_dump_flags {
- CONFIG_DUMP_FLAG_HUMAN = 0x01,
- CONFIG_DUMP_FLAG_DEFAULTS = 0x02
-};
+enum config_dump_flags;
struct config_connection *config_connection_create(int fd);
void config_connection_destroy(struct config_connection *conn);
void config_connection_dump_request(int fd, const char *service,
enum config_dump_flags flags);
-void config_connection_putenv(void);
+void config_connection_putenv(const char *service);
void config_connections_destroy_all(void);
diff -r 13bbdd7b15b8 -r f8460b27db00 src/config/config-parser.c
More information about the dovecot-cvs
mailing list