[dovecot-cvs]
dovecot/src/imap client.c,1.27,1.28 client.h,1.14,1.15
cmd-uid.c,1.4,1.5 commands.c,1.9,1.10 commands.h,1.11,1.12
main.c,1.31,1.32
cras at procontrol.fi
cras at procontrol.fi
Wed May 14 21:23:13 EEST 2003
Update of /home/cvs/dovecot/src/imap
In directory danu:/tmp/cvs-serv17074
Modified Files:
client.c client.h cmd-uid.c commands.c commands.h main.c
Log Message:
Added command_register() and related functions so we can dynamically
register new commands.
Index: client.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/client.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- client.c 20 Feb 2003 00:46:17 -0000 1.27
+++ client.c 14 May 2003 17:23:11 -0000 1.28
@@ -292,7 +292,7 @@
/* command not given - cmd_func is already NULL. */
} else {
/* find the command function */
- client->cmd_func = client_command_find(client->cmd_name);
+ client->cmd_func = command_find(client->cmd_name);
}
if (client->cmd_func == NULL) {
Index: client.h
===================================================================
RCS file: /home/cvs/dovecot/src/imap/client.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- client.h 20 Feb 2003 00:46:17 -0000 1.14
+++ client.h 14 May 2003 17:23:11 -0000 1.15
@@ -6,7 +6,7 @@
struct imap_parser;
struct imap_arg;
-typedef int client_command_func_t(struct client *client);
+typedef int command_func_t(struct client *client);
struct mailbox_custom_flags {
pool_t pool; /* will be p_clear()ed when changed */
@@ -32,7 +32,7 @@
struct imap_parser *parser;
const char *cmd_tag; /* tag of command (allocated from parser pool), */
const char *cmd_name; /* command name (allocated from parser pool) */
- client_command_func_t *cmd_func;
+ command_func_t *cmd_func;
struct timeout *idle_to;
unsigned int idle_expunge;
Index: cmd-uid.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/cmd-uid.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- cmd-uid.c 8 Jan 2003 20:49:52 -0000 1.4
+++ cmd-uid.c 14 May 2003 17:23:11 -0000 1.5
@@ -12,33 +12,7 @@
if (cmd == NULL)
return FALSE;
- client->cmd_func = NULL;
- switch (*cmd) {
- case 'c':
- case 'C':
- if (strcasecmp(cmd, "COPY") == 0)
- client->cmd_func = cmd_copy;
- break;
- case 'f':
- case 'F':
- if (strcasecmp(cmd, "FETCH") == 0)
- client->cmd_func = cmd_fetch;
- break;
- case 's':
- case 'S':
- if (strcasecmp(cmd, "STORE") == 0)
- client->cmd_func = cmd_store;
- else if (strcasecmp(cmd, "SEARCH") == 0)
- client->cmd_func = cmd_search;
- else if (strcasecmp(cmd, "SORT") == 0)
- client->cmd_func = cmd_sort;
- break;
- case 't':
- case 'T':
- if (strcasecmp(cmd, "THREAD") == 0)
- client->cmd_func = cmd_thread;
- break;
- }
+ client->cmd_func = command_find(t_strconcat("UID ", cmd, NULL));
if (client->cmd_func != NULL) {
client->cmd_uid = TRUE;
Index: commands.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/commands.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- commands.c 14 Feb 2003 10:46:44 -0000 1.9
+++ commands.c 14 May 2003 17:23:11 -0000 1.10
@@ -1,96 +1,149 @@
/* Copyright (C) 2002 Timo Sirainen */
#include "common.h"
+#include "buffer.h"
#include "commands.h"
-client_command_func_t *client_command_find(const char *name)
+#include <stdlib.h>
+
+const struct command imap4rev1_commands[] = {
+ { "AUTHENTICATE", cmd_authenticate },
+ { "CAPABILITY", cmd_capability },
+ { "LOGIN", cmd_login },
+ { "LOGOUT", cmd_logout },
+ { "NOOP", cmd_noop },
+
+ { "APPEND", cmd_append },
+ { "EXAMINE", cmd_examine },
+ { "CREATE", cmd_create },
+ { "DELETE", cmd_delete },
+ { "RENAME", cmd_rename },
+ { "LIST", cmd_list },
+ { "LSUB", cmd_lsub },
+ { "SELECT", cmd_select },
+ { "STATUS", cmd_status },
+ { "SUBSCRIBE", cmd_subscribe },
+ { "UNSUBSCRIBE", cmd_unsubscribe },
+
+ { "CHECK", cmd_check },
+ { "CLOSE", cmd_close },
+ { "COPY", cmd_copy },
+ { "EXPUNGE", cmd_expunge },
+ { "FETCH", cmd_fetch },
+ { "SEARCH", cmd_search },
+ { "STORE", cmd_store },
+ { "UID", cmd_uid },
+ { "UID COPY", cmd_copy },
+ { "UID FETCH", cmd_fetch },
+ { "UID SEARCH", cmd_search },
+ { "UID STORE", cmd_store }
+};
+#define IMAP4REV1_COMMANDS_COUNT \
+ (sizeof(imap4rev1_commands) / sizeof(imap4rev1_commands[0]))
+
+const struct command imap_ext_commands[] = {
+ { "IDLE", cmd_idle },
+ { "SORT", cmd_sort },
+ { "THREAD", cmd_thread },
+ { "UID SORT", cmd_sort },
+ { "UID THREAD", cmd_thread },
+ { "UNSELECT", cmd_unselect }
+};
+#define IMAP_EXT_COMMANDS_COUNT \
+ (sizeof(imap_ext_commands) / sizeof(imap_ext_commands[0]))
+
+static buffer_t *cmdbuf;
+static int cmdbuf_unsorted;
+
+void command_register(const char *name, command_func_t *func)
{
- /* keep the command uppercased */
- name = str_ucase(t_strdup_noconst(name));
+ struct command *cmd;
- switch (*name) {
- case 'A':
- if (strcmp(name, "APPEND") == 0)
- return cmd_append;
- if (strcmp(name, "AUTHENTICATE") == 0)
- return cmd_authenticate;
- break;
- case 'C':
- if (strcmp(name, "CREATE") == 0)
- return cmd_create;
- if (strcmp(name, "COPY") == 0)
- return cmd_copy;
- if (strcmp(name, "CLOSE") == 0)
- return cmd_close;
- if (strcmp(name, "CHECK") == 0)
- return cmd_check;
- if (strcmp(name, "CAPABILITY") == 0)
- return cmd_capability;
- break;
- case 'D':
- if (strcmp(name, "DELETE") == 0)
- return cmd_delete;
- break;
- case 'E':
- if (strcmp(name, "EXPUNGE") == 0)
- return cmd_expunge;
- if (strcmp(name, "EXAMINE") == 0)
- return cmd_examine;
- break;
- case 'F':
- if (strcmp(name, "FETCH") == 0)
- return cmd_fetch;
- break;
- case 'I':
- if (strcmp(name, "IDLE") == 0)
- return cmd_idle;
- break;
- case 'L':
- if (strcmp(name, "LIST") == 0)
- return cmd_list;
- if (strcmp(name, "LSUB") == 0)
- return cmd_lsub;
- if (strcmp(name, "LOGOUT") == 0)
- return cmd_logout;
- if (strcmp(name, "LOGIN") == 0)
- return cmd_login;
- break;
- case 'N':
- if (strcmp(name, "NOOP") == 0)
- return cmd_noop;
- break;
- case 'R':
- if (strcmp(name, "RENAME") == 0)
- return cmd_rename;
- break;
- case 'S':
- if (strcmp(name, "STORE") == 0)
- return cmd_store;
- if (strcmp(name, "SEARCH") == 0)
- return cmd_search;
- if (strcmp(name, "SORT") == 0)
- return cmd_sort;
- if (strcmp(name, "SELECT") == 0)
- return cmd_select;
- if (strcmp(name, "STATUS") == 0)
- return cmd_status;
- if (strcmp(name, "SUBSCRIBE") == 0)
- return cmd_subscribe;
- break;
- case 'T':
- if (strcmp(name, "THREAD") == 0)
- return cmd_thread;
- break;
- case 'U':
- if (strcmp(name, "UID") == 0)
- return cmd_uid;
- if (strcmp(name, "UNSUBSCRIBE") == 0)
- return cmd_unsubscribe;
- if (strcmp(name, "UNSELECT") == 0)
- return cmd_unselect;
+ cmd = buffer_append_space(cmdbuf, sizeof(*cmd));
+ cmd->name = name;
+ cmd->func = func;
- break;
+ cmdbuf_unsorted = TRUE;
+}
+
+void command_unregister(const char *name)
+{
+ const struct command *cmd;
+ size_t i, size, count;
+
+ cmd = buffer_get_data(cmdbuf, &size);
+ count = size / sizeof(*cmd);
+
+ for (i = 0; i < count; i++) {
+ if (strcasecmp(cmd[i].name, name) == 0) {
+ buffer_delete(cmdbuf, i * sizeof(*cmd), sizeof(*cmd));
+ return;
+ }
}
- return NULL;
+ i_error("Trying to unregister unknown command '%s'", name);
+}
+
+void command_register_array(const struct command *commands, size_t count)
+{
+ cmdbuf_unsorted = TRUE;
+ buffer_append(cmdbuf, commands, sizeof(*commands) * count);
+}
+
+void command_unregister_array(const struct command *commands, size_t count)
+{
+ while (count > 0) {
+ command_unregister(commands->name);
+ count--; commands++;
+ }
+}
+
+static int command_cmp(const void *p1, const void *p2)
+{
+ const struct command *c1 = p1, *c2 = p2;
+
+ return strcasecmp(c1->name, c2->name);
+}
+
+static int command_bsearch(const void *name, const void *cmd_p)
+{
+ const struct command *cmd = cmd_p;
+
+ return strcasecmp(name, cmd->name);
+}
+
+command_func_t *command_find(const char *name)
+{
+ const struct command *cmd;
+ void *base;
+ size_t size;
+
+ base = buffer_get_modifyable_data(cmdbuf, &size);
+ size /= sizeof(struct command);
+
+ if (cmdbuf_unsorted) {
+ qsort(base, size, sizeof(struct command), command_cmp);
+ cmdbuf_unsorted = FALSE;
+ }
+
+ cmd = bsearch(name, base, size, sizeof(struct command),
+ command_bsearch);
+ return cmd == NULL ? NULL : cmd->func;
+}
+
+void commands_init(void)
+{
+ cmdbuf = buffer_create_dynamic(system_pool,
+ sizeof(struct command) * 64, (size_t)-1);
+ cmdbuf_unsorted = FALSE;
+
+ command_register_array(imap4rev1_commands, IMAP4REV1_COMMANDS_COUNT);
+ command_register_array(imap_ext_commands, IMAP_EXT_COMMANDS_COUNT);
+}
+
+void commands_deinit(void)
+{
+ command_unregister_array(imap4rev1_commands, IMAP4REV1_COMMANDS_COUNT);
+ command_unregister_array(imap_ext_commands, IMAP_EXT_COMMANDS_COUNT);
+ buffer_free(cmdbuf);
}
Index: commands.h
===================================================================
RCS file: /home/cvs/dovecot/src/imap/commands.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- commands.h 24 Feb 2003 17:39:32 -0000 1.11
+++ commands.h 14 May 2003 17:23:11 -0000 1.12
@@ -5,7 +5,26 @@
#include "imap-parser.h"
#include "commands-util.h"
-client_command_func_t *client_command_find(const char *name);
+struct command {
+ const char *name;
+ command_func_t *func;
+};
+
+/* Register command. Given name parameter must be permanently stored until
+ command is unregistered. */
+void command_register(const char *name, command_func_t *func);
+void command_unregister(const char *name);
+
+/* Register array of commands. */
+void command_register_array(const struct command *commands, size_t count);
+void command_unregister_array(const struct command *commands, size_t count);
+
+command_func_t *command_find(const char *name);
+
+void commands_init(void);
+void commands_deinit(void);
+
+/* IMAP4rev1 commands: */
/* Non-Authenticated State */
int cmd_authenticate(struct client *client);
@@ -37,12 +56,14 @@
int cmd_close(struct client *client);
int cmd_expunge(struct client *client);
int cmd_search(struct client *client);
-int cmd_sort(struct client *client);
-int cmd_thread(struct client *client);
int cmd_fetch(struct client *client);
int cmd_store(struct client *client);
int cmd_copy(struct client *client);
int cmd_uid(struct client *client);
+
+/* IMAP extensions: */
+int cmd_sort(struct client *client);
+int cmd_thread(struct client *client);
int cmd_unselect(struct client *client);
int cmd_idle(struct client *client);
Index: main.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/main.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -d -r1.31 -r1.32
--- main.c 10 Apr 2003 22:37:25 -0000 1.31
+++ main.c 14 May 2003 17:23:11 -0000 1.32
@@ -8,6 +8,7 @@
#include "fd-close-on-exec.h"
#include "process-title.h"
#include "mail-storage.h"
+#include "commands.h"
#include <stdlib.h>
#include <unistd.h>
@@ -87,6 +88,7 @@
mail_storage_init();
mail_storage_register_all();
+ commands_init();
clients_init();
mail = getenv("MAIL");
@@ -143,6 +145,7 @@
i_warning("Killed with signal %d", lib_signal_kill);
clients_deinit();
+ commands_deinit();
mail_storage_deinit();
closelog();
More information about the dovecot-cvs
mailing list