]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
imap: Fixed SELECT QRESYNC not to crash on mailbox close if a lot of changes were...
authorTimo Sirainen <tss@iki.fi>
Tue, 2 Nov 2010 17:14:25 +0000 (17:14 +0000)
committerTimo Sirainen <tss@iki.fi>
Tue, 2 Nov 2010 17:14:25 +0000 (17:14 +0000)
src/imap/cmd-select.c
src/imap/imap-client.c
src/imap/main.c

index 073ce6665aafe2717b5953c75d46de9a39e36091..5951f171d3cf3fecd3ed5154c3e7e2ec8233fa5c 100644 (file)
@@ -263,11 +263,11 @@ static int select_qresync(struct imap_select_context *ctx)
 
                        ctx->cmd->func = cmd_select_continue;
                        ctx->cmd->context = ctx;
-                       return FALSE;
+                       return 0;
                }
        }
 
-       return imap_fetch_deinit(fetch_ctx);
+       return imap_fetch_deinit(fetch_ctx) < 0 ? -1 : 1;
 }
 
 static int
@@ -276,6 +276,7 @@ select_open(struct imap_select_context *ctx, const char *mailbox, bool readonly)
        struct client *client = ctx->cmd->client;
        struct mailbox_status status;
        enum mailbox_flags flags = 0;
+       int ret;
 
        if (readonly)
                flags |= MAILBOX_FLAG_READONLY | MAILBOX_FLAG_KEEP_RECENT;
@@ -339,13 +340,15 @@ select_open(struct imap_select_context *ctx, const char *mailbox, bool readonly)
        }
 
        if (ctx->qresync_uid_validity == status.uidvalidity) {
-               if (select_qresync(ctx) < 0) {
+               if ((ret = select_qresync(ctx)) < 0) {
                        client_send_storage_error(ctx->cmd,
                                mailbox_get_storage(ctx->box));
                        return -1;
                }
+       } else {
+               ret = 1;
        }
-       return 0;
+       return ret;
 }
 
 static void close_selected_mailbox(struct client *client)
@@ -424,6 +427,8 @@ bool cmd_select_full(struct client_command_context *cmd, bool readonly)
        }
 
        ret = select_open(ctx, storage_name, readonly);
+       if (ret == 0)
+               return FALSE;
        cmd_select_finish(ctx, ret);
        return TRUE;
 }
index 95cd8e9cb30276eae330a77cce4a4519504d1fbf..bc8edb8782b3af30797e1827362bb2601006f2bf 100644 (file)
@@ -424,6 +424,8 @@ client_command_find_with_flags(struct client_command_context *new_cmd,
 
        cmd = new_cmd->client->command_queue;
        for (; cmd != NULL; cmd = cmd->next) {
+               i_warning("cmd=%s state=%d<=%d flags=%x & %x",
+                         cmd->name, cmd->state, max_state, cmd->cmd_flags, flags);
                if (cmd->state <= max_state &&
                    cmd != new_cmd && (cmd->cmd_flags & flags) != 0)
                        return cmd;
index 0889fa4559ee767226c99cf77b0bb70899a16475..ad4d3349ec631a02119813191dd17c17404a89b3 100644 (file)
@@ -250,6 +250,7 @@ static void
 login_client_connected(const struct master_login_client *client,
                       const char *username, const char *const *extra_fields)
 {
+#define MSG_BYE_INTERNAL_ERROR "* BYE "MAIL_ERRSTR_CRITICAL_MSG"\r\n"
        struct mail_storage_service_input input;
        const char *error;
        buffer_t input_buf;
@@ -265,6 +266,11 @@ login_client_connected(const struct master_login_client *client,
                                 client->auth_req.data_size);
        if (client_create_from_input(&input, client, client->fd, client->fd,
                                     &input_buf, &error) < 0) {
+               if (write(client->fd, MSG_BYE_INTERNAL_ERROR,
+                         strlen(MSG_BYE_INTERNAL_ERROR)) < 0) {
+                       if (errno != EAGAIN && errno != EPIPE)
+                               i_error("write(client) failed: %m");
+               }
                i_error("%s", error);
                (void)close(client->fd);
                master_service_client_connection_destroyed(master_service);