Mercurial > dovecot > core-2.2
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