From f13c9ae4f96d4d13b3996ec716a959cf3380896c Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Fri, 22 May 2009 19:24:26 -0400 Subject: [PATCH] imap, pop3 no longer assume that there's only a single client in process. --HG-- branch : HEAD --- src/imap/imap-client.c | 23 ++++++++--------------- src/imap/imap-client.h | 7 ++++--- src/imap/main.c | 4 +--- src/pop3/main.c | 4 +--- src/pop3/pop3-client.c | 27 ++++++++++++--------------- src/pop3/pop3-client.h | 5 +++-- 6 files changed, 29 insertions(+), 41 deletions(-) diff --git a/src/imap/imap-client.c b/src/imap/imap-client.c index 30a05ddb11..1b8e9de7c2 100644 --- a/src/imap/imap-client.c +++ b/src/imap/imap-client.c @@ -21,7 +21,7 @@ extern struct mail_storage_callbacks mail_storage_callbacks; struct imap_module_register imap_module_register = { 0 }; -static struct client *my_client; /* we don't need more than one currently */ +static struct client *imap_clients = NULL; static void client_idle_timeout(struct client *client) { @@ -77,9 +77,7 @@ struct client *client_create(int fd_in, int fd_out, struct mail_user *user, client->anvil_sent = TRUE; } - i_assert(my_client == NULL); - my_client = client; - + DLLIST_PREPEND(&imap_clients, client); if (hook_client_created != NULL) hook_client_created(&client); return client; @@ -162,6 +160,8 @@ void client_destroy(struct client *client, const char *reason) i_info("%s %s", reason, client_stats(client)); } + DLLIST_REMOVE(&imap_clients, client); + i_stream_close(client->input); o_stream_close(client->output); @@ -217,8 +217,6 @@ void client_destroy(struct client *client, const char *reason) pool_unref(&client->command_pool); i_free(client); - /* quit the program */ - my_client = NULL; master_service_client_connection_destroyed(master_service); } @@ -941,15 +939,10 @@ void client_search_updates_free(struct client *client) array_clear(&client->search_updates); } -void clients_init(void) -{ - my_client = NULL; -} - -void clients_deinit(void) +void clients_destroy_all(void) { - if (my_client != NULL) { - client_send_line(my_client, "* BYE Server shutting down."); - client_destroy(my_client, "Server shutting down"); + while (imap_clients != NULL) { + client_send_line(imap_clients, "* BYE Server shutting down."); + client_destroy(imap_clients, "Server shutting down."); } } diff --git a/src/imap/imap-client.h b/src/imap/imap-client.h index 4a94b963e6..d86f9e167f 100644 --- a/src/imap/imap-client.h +++ b/src/imap/imap-client.h @@ -86,6 +86,8 @@ struct client_command_context { }; struct client { + struct client *prev, *next; + int fd_in, fd_out; struct io *io; struct istream *input; @@ -185,9 +187,6 @@ client_search_update_lookup(struct client *client, const char *tag, unsigned int *idx_r); void client_search_updates_free(struct client *client); -void clients_init(void); -void clients_deinit(void); - void client_command_cancel(struct client_command_context **cmd); void client_command_free(struct client_command_context **cmd); @@ -198,4 +197,6 @@ void client_input(struct client *client); bool client_handle_input(struct client *client); int client_output(struct client *client); +void clients_destroy_all(void); + #endif diff --git a/src/imap/main.c b/src/imap/main.c index e40c416421..1e7a038739 100644 --- a/src/imap/main.c +++ b/src/imap/main.c @@ -115,8 +115,6 @@ static void main_init(const struct imap_settings *set, struct mail_user *user, log_error_callback, NULL); } - clients_init(); - client = client_create(0, 1, user, set); client->workarounds = parse_workarounds(set); @@ -137,7 +135,7 @@ static void main_deinit(void) { if (log_io != NULL) io_remove(&log_io); - clients_deinit(); + clients_destroy_all(); } static void client_connected(const struct master_service_connection *conn) diff --git a/src/pop3/main.c b/src/pop3/main.c index a2bb49fb96..c9d397dd69 100644 --- a/src/pop3/main.c +++ b/src/pop3/main.c @@ -42,8 +42,6 @@ static bool main_init(const struct pop3_settings *set, struct mail_user *user) log_error_callback, NULL); } - clients_init(); - client = client_create(0, 1, user, set); if (client == NULL) return FALSE; @@ -68,7 +66,7 @@ static void main_deinit(void) { if (log_io != NULL) io_remove(&log_io); - clients_deinit(); + clients_destroy_all(); } static void client_connected(const struct master_service_connection *conn) diff --git a/src/pop3/pop3-client.c b/src/pop3/pop3-client.c index bf23cab205..524d828f41 100644 --- a/src/pop3/pop3-client.c +++ b/src/pop3/pop3-client.c @@ -7,6 +7,7 @@ #include "istream.h" #include "ostream.h" #include "str.h" +#include "llist.h" #include "hostpid.h" #include "var-expand.h" #include "master-service.h" @@ -45,7 +46,7 @@ static struct client_workaround_list client_workaround_list[] = { { NULL, 0 } }; -static struct client *my_client; /* we don't need more than one currently */ +static struct client *pop3_clients; static void client_input(struct client *client); static int client_output(struct client *client); @@ -294,9 +295,7 @@ struct client *client_create(int fd_in, int fd_out, struct mail_user *user, client->anvil_sent = TRUE; } - i_assert(my_client == NULL); - my_client = client; - + DLLIST_PREPEND(&pop3_clients, client); if (hook_client_created != NULL) hook_client_created(&client); return client; @@ -364,6 +363,8 @@ void client_destroy(struct client *client, const char *reason) client->cmd(client); i_assert(client->cmd == NULL); } + DLLIST_REMOVE(&pop3_clients, client); + if (client->trans != NULL) { /* client didn't QUIT, but we still want to save any changes done in this transaction. especially the cached virtual @@ -402,8 +403,6 @@ void client_destroy(struct client *client, const char *reason) i_free(client); - /* quit the program */ - my_client = NULL; master_service_client_connection_destroyed(master_service); } @@ -586,15 +585,13 @@ static int client_output(struct client *client) return client->cmd == NULL; } -void clients_init(void) -{ - my_client = NULL; -} - -void clients_deinit(void) +void clients_destroy_all(void) { - if (my_client != NULL) { - client_send_line(my_client, "-ERR Server shutting down."); - client_destroy(my_client, "Server shutting down"); + while (pop3_clients != NULL) { + if (pop3_clients->cmd == NULL) { + client_send_line(pop3_clients, + "-ERR Server shutting down."); + } + client_destroy(pop3_clients, "Server shutting down."); } } diff --git a/src/pop3/pop3-client.h b/src/pop3/pop3-client.h index 909d4575dc..8bc503d99e 100644 --- a/src/pop3/pop3-client.h +++ b/src/pop3/pop3-client.h @@ -10,6 +10,8 @@ typedef void command_func_t(struct client *client); (((client)->messages_count + (CHAR_BIT-1)) / CHAR_BIT) struct client { + struct client *prev, *next; + int fd_in, fd_out; struct io *io; struct istream *input; @@ -76,7 +78,6 @@ void client_send_storage_error(struct client *client); bool client_handle_input(struct client *client); bool client_update_mails(struct client *client); -void clients_init(void); -void clients_deinit(void); +void clients_destroy_all(void); #endif -- 2.47.3