Mercurial > dovecot > core-2.2
changeset 12760:8e222035b6e9
imapc: Fixed crashing in IDLE handling when server got disconnected.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 24 Feb 2011 11:27:42 +0200 |
parents | ea1c0e39f794 |
children | 3e8ee35da672 |
files | src/lib-storage/index/imapc/imapc-connection.c |
diffstat | 1 files changed, 28 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/index/imapc/imapc-connection.c Thu Feb 24 11:26:27 2011 +0200 +++ b/src/lib-storage/index/imapc/imapc-connection.c Thu Feb 24 11:27:42 2011 +0200 @@ -47,6 +47,8 @@ imapc_command_callback_t *callback; void *context; + + unsigned int idle:1; }; struct imapc_connection_literal { @@ -158,6 +160,10 @@ reply.text_without_resp = reply.text_full = "Disconnected from server"; + conn->idling = FALSE; + conn->idle_plus_waiting = FALSE; + conn->idle_stopping = FALSE; + while (array_count(&conn->cmd_wait_list) > 0) { cmdp = array_idx(&conn->cmd_wait_list, 0); cmd = *cmdp; @@ -1179,6 +1185,9 @@ static void imapc_command_send_done(struct imapc_connection *conn, struct imapc_command *cmd) { + if (cmd->idle) + conn->idle_plus_waiting = TRUE; + /* everything sent. move command to wait list. */ i_assert(*array_idx(&conn->cmd_send_queue, 0) == cmd); array_delete(&conn->cmd_send_queue, 0, 1); @@ -1287,15 +1296,25 @@ } } -void imapc_connection_cmd(struct imapc_connection *conn, const char *cmdline, - imapc_command_callback_t *callback, void *context) +static struct imapc_command * +imapc_connection_cmd_build(const char *cmdline, + imapc_command_callback_t *callback, void *context) { struct imapc_command *cmd; unsigned int len = strlen(cmdline); cmd = imapc_command_begin(callback, context); - cmd->data = str_new(cmd->pool, len + 2); + cmd->data = str_new(cmd->pool, 6 + len + 2); str_printfa(cmd->data, "%u %s\r\n", cmd->tag, cmdline); + return cmd; +} + +void imapc_connection_cmd(struct imapc_connection *conn, const char *cmdline, + imapc_command_callback_t *callback, void *context) +{ + struct imapc_command *cmd; + + cmd = imapc_connection_cmd_build(cmdline, callback, context); imapc_command_send(conn, cmd); } @@ -1437,13 +1456,16 @@ void imapc_connection_idle(struct imapc_connection *conn) { + struct imapc_command *cmd; + if (array_count(&conn->cmd_send_queue) != 0 || array_count(&conn->cmd_wait_list) != 0 || conn->idling || conn->idle_plus_waiting || (conn->capabilities & IMAPC_CAPABILITY_IDLE) == 0) return; - imapc_connection_cmd(conn, "IDLE", - imapc_connection_idle_callback, conn); - conn->idle_plus_waiting = TRUE; + cmd = imapc_connection_cmd_build("IDLE", imapc_connection_idle_callback, + conn); + cmd->idle = TRUE; + imapc_command_send(conn, cmd); }