dovecot-2.0: doveadm: Added client/server architecture support f...

dovecot at dovecot.org dovecot at dovecot.org
Fri Jul 23 22:37:52 EEST 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/b60e225386bf
changeset: 11897:b60e225386bf
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Jul 23 20:37:35 2010 +0100
description:
doveadm: Added client/server architecture support for running mail commands.
This is done when doveadm_worker_count is non-zero.

diffstat:

 .hgignore                               |    1 +
 doc/example-config/dovecot.conf         |    6 +
 src/doveadm/Makefile.am                 |   52 ++++-
 src/doveadm/client-connection.c         |  239 +++++++++++++++++++++++++++++
 src/doveadm/client-connection.h         |    9 +
 src/doveadm/doveadm-mail-server.c       |  269 +++++++++++++++++++++++++++++++++
 src/doveadm/doveadm-mail.c              |   13 +
 src/doveadm/doveadm-mail.h              |    6 +
 src/doveadm/doveadm-print-server.c      |   82 ++++++++++
 src/doveadm/doveadm-print.c             |    8 +
 src/doveadm/doveadm-print.h             |    1 +
 src/doveadm/doveadm-server.h            |   16 ++
 src/doveadm/doveadm-settings.c          |   69 ++++++++
 src/doveadm/doveadm-settings.h          |    2 +
 src/doveadm/doveadm-util.c              |    2 +-
 src/doveadm/doveadm-util.h              |    2 +-
 src/doveadm/main.c                      |  101 ++++++++++++
 src/doveadm/server-connection.c         |  290 ++++++++++++++++++++++++++++++++++++
 src/doveadm/server-connection.h         |   27 +++
 src/lib-master/master-service-private.h |    1 +
 src/lib-master/master-service.c         |    6 +
 src/lib-master/master-service.h         |    2 +
 src/plugins/expire/doveadm-expire.c     |    1 +
 23 files changed, 1189 insertions(+), 16 deletions(-)

diffs (truncated from 1489 to 300 lines):

diff -r 158be8d93ddc -r b60e225386bf .hgignore
--- a/.hgignore	Fri Jul 23 20:31:21 2010 +0100
+++ b/.hgignore	Fri Jul 23 20:37:35 2010 +0100
@@ -65,6 +65,7 @@
 src/director/director-test
 src/dns/dns-client
 src/doveadm/doveadm
+src/doveadm/doveadm-server
 src/dsync/dsync
 src/imap-login/imap-login
 src/imap/imap
diff -r 158be8d93ddc -r b60e225386bf doc/example-config/dovecot.conf
--- a/doc/example-config/dovecot.conf	Fri Jul 23 20:31:21 2010 +0100
+++ b/doc/example-config/dovecot.conf	Fri Jul 23 20:37:35 2010 +0100
@@ -56,6 +56,12 @@
 # a problem if the upgrade is e.g. because of a security fix).
 #shutdown_clients = yes
 
+# If non-zero, run mail commands via this many connections to doveadm server,
+# instead of running them directly in the same process.
+#doveadm_worker_count = 0
+# UNIX socket or host:port used for connecting to doveadm server
+#doveadm_socket_path = doveadm-server
+
 ##
 ## Dictionary server settings
 ##
diff -r 158be8d93ddc -r b60e225386bf src/doveadm/Makefile.am
--- a/src/doveadm/Makefile.am	Fri Jul 23 20:31:21 2010 +0100
+++ b/src/doveadm/Makefile.am	Fri Jul 23 20:37:35 2010 +0100
@@ -1,6 +1,7 @@
 doveadm_moduledir = $(moduledir)/doveadm
 
 bin_PROGRAMS = doveadm
+pkglibexec_PROGRAMS = doveadm-server
 
 AM_CPPFLAGS = \
 	-I$(top_srcdir)/src/lib \
@@ -33,18 +34,42 @@
 
 libs = \
 	$(LIBDOVECOT_STORAGE) \
-	$(cmd_pw_libs) \
 	$(unused_objects)
 
 doveadm_LDADD = \
 	$(libs) $(AUTH_LIBS) \
+	$(cmd_pw_libs) \
 	$(LIBDOVECOT) \
 	$(MODULE_LIBS)
 doveadm_DEPENDENCIES = \
 	$(libs) \
+	$(cmd_pw_libs) \
 	$(LIBDOVECOT_DEPS)
 
+doveadm_server_LDADD = \
+	$(libs) \
+	$(LIBDOVECOT) \
+	$(MODULE_LIBS)
+doveadm_server_DEPENDENCIES = \
+	$(libs) \
+	$(LIBDOVECOT_DEPS)
+
+common = \
+	doveadm-mail.c \
+	doveadm-mail-altmove.c \
+	doveadm-mail-expunge.c \
+	doveadm-mail-fetch.c \
+	doveadm-mail-iter.c \
+	doveadm-mail-mailbox.c \
+	doveadm-mail-mailbox-status.c \
+	doveadm-mail-list-iter.c \
+	doveadm-mail-search.c \
+	doveadm-print.c \
+	doveadm-settings.c \
+	doveadm-util.c
+
 doveadm_SOURCES = \
+	$(common) \
 	doveadm.c \
 	doveadm-auth.c \
 	doveadm-director.c \
@@ -56,28 +81,26 @@
 	doveadm-kick.c \
 	doveadm-log.c \
 	doveadm-master.c \
-	doveadm-mail.c \
-	doveadm-mail-altmove.c \
-	doveadm-mail-expunge.c \
-	doveadm-mail-fetch.c \
-	doveadm-mail-iter.c \
-	doveadm-mail-mailbox.c \
-	doveadm-mail-mailbox-status.c \
-	doveadm-mail-list-iter.c \
-	doveadm-mail-search.c \
+	doveadm-mail-server.c \
 	doveadm-mutf7.c \
 	doveadm-penalty.c \
-	doveadm-print.c \
 	doveadm-print-flow.c \
 	doveadm-print-pager.c \
 	doveadm-print-tab.c \
 	doveadm-print-table.c \
 	doveadm-pw.c \
-	doveadm-settings.c \
-	doveadm-util.c \
-	doveadm-who.c
+	doveadm-who.c \
+	server-connection.c
+
+doveadm_server_SOURCES = \
+	$(common) \
+	client-connection.c \
+	doveadm-print-server.c \
+	main.c
 
 noinst_HEADERS = \
+	client-connection.h \
+	server-connection.h \
 	doveadm.h \
 	doveadm-dump.h \
 	doveadm-mail.h \
@@ -85,6 +108,7 @@
 	doveadm-mail-list-iter.h \
 	doveadm-print.h \
 	doveadm-print-private.h \
+	doveadm-server.h \
 	doveadm-settings.h \
 	doveadm-util.h \
 	doveadm-who.h
diff -r 158be8d93ddc -r b60e225386bf src/doveadm/client-connection.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/doveadm/client-connection.c	Fri Jul 23 20:37:35 2010 +0100
@@ -0,0 +1,239 @@
+/* Copyright (c) 2010 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "ioloop.h"
+#include "istream.h"
+#include "ostream.h"
+#include "strescape.h"
+#include "master-service.h"
+#include "mail-storage-service.h"
+#include "doveadm-util.h"
+#include "doveadm-server.h"
+#include "doveadm-mail.h"
+#include "doveadm-print.h"
+#include "client-connection.h"
+
+#include <unistd.h>
+
+#define MAX_INBUF_SIZE 1024
+
+struct client_connection {
+	int fd;
+	struct io *io;
+	struct istream *input;
+	struct ostream *output;
+
+	unsigned int handshaked:1;
+	unsigned int authenticated:1;
+};
+
+static bool doveadm_mail_cmd_server(const char *cmd_name, const char *username,
+				    int argc, char *argv[])
+{
+	enum mail_storage_service_flags service_flags =
+		MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT |
+		MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP;
+	struct doveadm_mail_cmd_context *ctx;
+	const struct doveadm_mail_cmd *cmd;
+	const char *getopt_args;
+	bool add_username_header;
+	int c;
+
+	cmd = doveadm_mail_cmd_find(cmd_name);
+	if (cmd == NULL) {
+		i_error("doveadm: Client sent unknown command: %s", cmd_name);
+		return FALSE;
+	}
+
+	if (doveadm_debug)
+		service_flags |= MAIL_STORAGE_SERVICE_FLAG_DEBUG;
+
+	ctx = doveadm_mail_cmd_init(cmd);
+	getopt_args = t_strconcat("Au:", ctx->getopt_args, NULL);
+	while ((c = getopt(argc, argv, getopt_args)) > 0) {
+		switch (c) {
+		case 'A':
+			add_username_header = TRUE;
+			break;
+		case 'u':
+			if (strchr(optarg, '*') != NULL ||
+			    strchr(optarg, '?') != NULL)
+				add_username_header = TRUE;
+			break;
+		default:
+			if ((ctx->v.parse_arg == NULL ||
+			     !ctx->v.parse_arg(ctx, c))) {
+				i_error("doveadm %s: "
+					"Client sent unknown parameter: %c",
+					cmd->name, c);
+				ctx->v.deinit(ctx);
+				return FALSE;
+			}
+		}
+	}
+
+	argv += optind;
+	if (argv[0] != NULL && cmd->usage_args == NULL) {
+		i_error("doveadm %s: Client sent unknown parameter: %s",
+			cmd->name, argv[0]);
+		ctx->v.deinit(ctx);
+		return FALSE;
+	}
+
+	if (doveadm_print_is_initialized() && add_username_header) {
+		doveadm_print_header("username", "Username",
+				     DOVEADM_PRINT_HEADER_FLAG_STICKY |
+				     DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE);
+		doveadm_print_sticky("username", username);
+	}
+
+	ctx->v.init(ctx, (const void *)argv);
+	doveadm_mail_single_user(ctx, username, service_flags);
+	ctx->v.deinit(ctx);
+	doveadm_print_flush();
+	return !ctx->failed;
+}
+
+static bool client_handle_command(struct client_connection *conn, char **args)
+{
+	const char *flags, *username, *cmd_name;
+	unsigned int argc;
+	bool ret;
+
+	for (argc = 0; args[argc] != NULL; argc++)
+		args[argc] = str_tabunescape(args[argc]);
+
+	if (argc < 3) {
+		i_error("doveadm client: No command given");
+		return FALSE;
+	}
+	flags = args[0];
+	username = args[1];
+	cmd_name = args[2];
+	args += 3;
+	argc -= 3;
+
+	doveadm_debug = FALSE;
+	doveadm_verbose = FALSE;
+
+	for (; *flags != '\0'; flags++) {
+		switch (*flags) {
+		case 'D':
+			doveadm_debug = TRUE;
+			doveadm_verbose = TRUE;
+			break;
+		case 'v':
+			doveadm_verbose = TRUE;
+			break;
+		default:
+			i_error("doveadm client: Unknown flag: %c", *flags);
+			return FALSE;
+		}
+	}
+
+	o_stream_cork(conn->output);
+	ret = doveadm_mail_cmd_server(cmd_name, username, argc, args);
+	if (ret)
+		o_stream_send(conn->output, "\n+\n", 3);
+	else
+		o_stream_send(conn->output, "\n-\n", 3);
+	o_stream_uncork(conn->output);
+
+	/* flush the output and disconnect */
+	net_set_nonblock(conn->fd, FALSE);
+	(void)o_stream_flush(conn->output);
+	return FALSE;
+}
+
+static bool
+client_connection_authenticate(struct client_connection *conn ATTR_UNUSED)
+{
+	i_fatal("Authentication not supported yet");
+	return FALSE;
+}
+
+static void client_connection_input(struct client_connection *conn)
+{
+	const char *line;
+	bool ret = TRUE;
+
+	if (!conn->handshaked) {
+		if ((line = i_stream_read_next_line(conn->input)) == NULL) {
+			if (conn->input->eof || conn->input->stream_errno != 0)
+				client_connection_destroy(&conn);
+			return;
+		}
+


More information about the dovecot-cvs mailing list