]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
imap-login: Added API for registering/unregistering commands (for plugins).
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Fri, 15 Jan 2016 14:46:34 +0000 (16:46 +0200)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Fri, 15 Jan 2016 16:31:52 +0000 (18:31 +0200)
src/imap-login/Makefile.am
src/imap-login/client.c
src/imap-login/imap-login-commands.c [new file with mode: 0644]
src/imap-login/imap-login-commands.h [new file with mode: 0644]

index 5cc5e8c8896457b77c44d4cdc1867290d50bd3a5..0f5d3116efd3a38fd10a22eeae5cd508640a15dc 100644 (file)
@@ -22,11 +22,13 @@ imap_login_DEPENDENCIES = \
 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
index 5326d6a6260f1d7040c6fdca9625da9acc739692..7b833e1f75f5768ddffbe1dffcf335c15434115b 100644 (file)
@@ -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 @@ static const char *get_capability(struct client *client)
        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 @@ static int cmd_capability(struct imap_client *imap_client)
        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_id(struct imap_client *client)
        }
 }
 
-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 @@ static int cmd_logout(struct imap_client *client)
        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 cmd_enable(struct imap_client *client)
 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 @@ static void imap_login_preinit(void)
        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 = {
diff --git a/src/imap-login/imap-login-commands.c b/src/imap-login/imap-login-commands.c
new file mode 100644 (file)
index 0000000..cdb4d4a
--- /dev/null
@@ -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);
+}
diff --git a/src/imap-login/imap-login-commands.h b/src/imap-login/imap-login-commands.h
new file mode 100644 (file)
index 0000000..d9ecd1c
--- /dev/null
@@ -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