changeset 19568:828dd58e03a4

imap-login: Added API for registering/unregistering commands (for plugins).
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Fri, 15 Jan 2016 16:46:34 +0200
parents 11b714c6c31c
children 5bad98da9310
files src/imap-login/Makefile.am src/imap-login/client.c src/imap-login/imap-login-commands.c src/imap-login/imap-login-commands.h
diffstat 4 files changed, 126 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/src/imap-login/Makefile.am	Fri Jan 15 16:07:32 2016 +0200
+++ b/src/imap-login/Makefile.am	Fri Jan 15 16:46:34 2016 +0200
@@ -22,11 +22,13 @@
 imap_login_SOURCES = \
 	client.c \
 	client-authenticate.c \
+	imap-login-commands.c \
 	imap-login-settings.c \
 	imap-proxy.c
 
 noinst_HEADERS = \
 	client.h \
 	client-authenticate.h \
+	imap-login-commands.h \
 	imap-login-settings.h \
 	imap-proxy.h
--- a/src/imap-login/client.c	Fri Jan 15 16:07:32 2016 +0200
+++ b/src/imap-login/client.c	Fri Jan 15 16:46:34 2016 +0200
@@ -19,6 +19,7 @@
 #include "auth-client.h"
 #include "ssl-proxy.h"
 #include "imap-proxy.h"
+#include "imap-login-commands.h"
 #include "imap-login-settings.h"
 
 #if LOGIN_MAX_INBUF_SIZE < 1024+2
@@ -111,7 +112,8 @@
 	return str_c(cap_str);
 }
 
-static int cmd_capability(struct imap_client *imap_client)
+static int cmd_capability(struct imap_client *imap_client,
+			  const struct imap_arg *args ATTR_UNUSED)
 {
 	struct client *client = &imap_client->common;
 
@@ -127,7 +129,8 @@
 	return 1;
 }
 
-static int cmd_starttls(struct imap_client *client)
+static int cmd_starttls(struct imap_client *client,
+			const struct imap_arg *args ATTR_UNUSED)
 {
 	client_cmd_starttls(&client->common);
 	return 1;
@@ -309,14 +312,16 @@
 	}
 }
 
-static int cmd_noop(struct imap_client *client)
+static int cmd_noop(struct imap_client *client,
+		    const struct imap_arg *args ATTR_UNUSED)
 {
 	client_send_reply(&client->common, IMAP_CMD_REPLY_OK,
 			  "NOOP completed.");
 	return 1;
 }
 
-static int cmd_logout(struct imap_client *client)
+static int cmd_logout(struct imap_client *client,
+		      const struct imap_arg *args ATTR_UNUSED)
 {
 	client_send_reply(&client->common, IMAP_CMD_REPLY_BYE, "Logging out");
 	client_send_reply(&client->common, IMAP_CMD_REPLY_OK,
@@ -325,7 +330,8 @@
 	return 1;
 }
 
-static int cmd_enable(struct imap_client *client)
+static int cmd_enable(struct imap_client *client,
+		      const struct imap_arg *args ATTR_UNUSED)
 {
 	client_send_raw(&client->common, "* ENABLED\r\n");
 	client_send_reply(&client->common, IMAP_CMD_REPLY_OK,
@@ -336,21 +342,12 @@
 static int client_command_execute(struct imap_client *client, const char *cmd,
 				  const struct imap_arg *args)
 {
-	cmd = t_str_ucase(cmd);
-	if (strcmp(cmd, "LOGIN") == 0)
-		return cmd_login(client, args);
-	if (strcmp(cmd, "CAPABILITY") == 0)
-		return cmd_capability(client);
-	if (strcmp(cmd, "STARTTLS") == 0)
-		return cmd_starttls(client);
-	if (strcmp(cmd, "NOOP") == 0)
-		return cmd_noop(client);
-	if (strcmp(cmd, "LOGOUT") == 0)
-		return cmd_logout(client);
-	if (strcmp(cmd, "ENABLE") == 0)
-		return cmd_enable(client);
+	struct imap_login_command *login_cmd;
 
-	return -2;
+	login_cmd = imap_login_command_lookup(cmd);
+	if (login_cmd == NULL)
+		return -2;
+	return login_cmd->func(client, args);
 }
 
 static bool imap_is_valid_tag(const char *tag)
@@ -660,13 +657,26 @@
 	login_set_roots = imap_login_setting_roots;
 }
 
+static const struct imap_login_command imap_login_commands[] = {
+	{ "LOGIN", cmd_login },
+	{ "CAPABILITY", cmd_capability },
+	{ "STARTTLS", cmd_starttls },
+	{ "NOOP", cmd_noop },
+	{ "LOGOUT", cmd_logout },
+	{ "ENABLE", cmd_enable }
+};
+
 static void imap_login_init(void)
 {
+	imap_login_commands_init();
+	imap_login_commands_register(imap_login_commands,
+				     N_ELEMENTS(imap_login_commands));
 }
 
 static void imap_login_deinit(void)
 {
 	clients_destroy_all();
+	imap_login_commands_deinit();
 }
 
 static struct client_vfuncs imap_client_vfuncs = {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/imap-login/imap-login-commands.c	Fri Jan 15 16:46:34 2016 +0200
@@ -0,0 +1,70 @@
+/* Copyright (c) 2016 Dovecot authors, see the included COPYING file */
+
+#include "login-common.h"
+#include "array.h"
+#include "imap-login-commands.h"
+
+static ARRAY(struct imap_login_command *) imap_login_commands;
+static pool_t imap_login_commands_pool;
+
+struct imap_login_command *imap_login_command_lookup(const char *name)
+{
+	struct imap_login_command *const *cmdp;
+
+	array_foreach(&imap_login_commands, cmdp) {
+		if (strcasecmp((*cmdp)->name, name) == 0)
+			return *cmdp;
+	}
+	return NULL;
+}
+
+void imap_login_commands_register(const struct imap_login_command *commands,
+				  unsigned int count)
+{
+	struct imap_login_command *cmd;
+	unsigned int i;
+
+	for (i = 0; i < count; i++) {
+		cmd = p_new(imap_login_commands_pool, struct imap_login_command, 1);
+		cmd->name = p_strdup(imap_login_commands_pool, commands[i].name);
+		cmd->func = commands[i].func;
+		array_append(&imap_login_commands, &cmd, 1);
+	}
+}
+
+static void
+imap_login_command_unregister(const struct imap_login_command *unreg_cmd)
+{
+	struct imap_login_command *const *cmdp;
+
+	array_foreach(&imap_login_commands, cmdp) {
+		if ((*cmdp)->func == unreg_cmd->func &&
+		    strcmp((*cmdp)->name, unreg_cmd->name) == 0) {
+			array_delete(&imap_login_commands,
+				array_foreach_idx(&imap_login_commands, cmdp), 1);
+			return;
+		}
+	}
+	i_panic("imap_login_command_unregister: Command '%s' not found", unreg_cmd->name);
+}
+
+void imap_login_commands_unregister(const struct imap_login_command *commands,
+				    unsigned int count)
+{
+	unsigned int i;
+
+	for (i = 0; i < count; i++)
+		imap_login_command_unregister(&commands[i]);
+}
+
+void imap_login_commands_init(void)
+{
+	imap_login_commands_pool =
+		pool_alloconly_create("imap login commands", 128);
+	p_array_init(&imap_login_commands, imap_login_commands_pool, 8);
+}
+
+void imap_login_commands_deinit(void)
+{
+	pool_unref(&imap_login_commands_pool);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/imap-login/imap-login-commands.h	Fri Jan 15 16:46:34 2016 +0200
@@ -0,0 +1,25 @@
+#ifndef IMAP_LOGIN_COMMANDS_H
+#define IMAP_LOGIN_COMMANDS_H
+
+struct imap_arg;
+struct imap_client;
+
+typedef int imap_login_command_t(struct imap_client *client,
+				 const struct imap_arg *args);
+
+struct imap_login_command {
+	const char *name;
+	imap_login_command_t *func;
+};
+
+struct imap_login_command *imap_login_command_lookup(const char *name);
+
+void imap_login_commands_register(const struct imap_login_command *commands,
+				  unsigned int count);
+void imap_login_commands_unregister(const struct imap_login_command *commands,
+				    unsigned int count);
+
+void imap_login_commands_init(void);
+void imap_login_commands_deinit(void);
+
+#endif