]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
IMAP: Don't crash if IDLE command is pipelined after a long-running UID FETCH or...
authorTimo Sirainen <tss@iki.fi>
Tue, 16 Jun 2009 01:56:22 +0000 (21:56 -0400)
committerTimo Sirainen <tss@iki.fi>
Tue, 16 Jun 2009 01:56:22 +0000 (21:56 -0400)
--HG--
branch : HEAD

src/imap/imap-client.c
src/imap/imap-commands.c
src/imap/imap-commands.h
src/imap/imap-sync.c
src/imap/imap-sync.h

index 73b8c3c22729c6d05c5b866ac0f5e568a8a4eac0..ecd6a932797aa156cdf52672deea167075ad356f 100644 (file)
@@ -412,6 +412,10 @@ static bool client_command_check_ambiguity(struct client_command_context *cmd)
                CLIENT_COMMAND_STATE_WAIT_UNAMBIGUITY;
        bool broken_client = FALSE;
 
+       if ((cmd->cmd_flags & COMMAND_FLAG_REQUIRES_SYNC) != 0 &&
+           !imap_sync_is_allowed(cmd->client))
+               return TRUE;
+
        if ((cmd->cmd_flags & COMMAND_FLAG_BREAKS_MAILBOX) ==
            COMMAND_FLAG_BREAKS_MAILBOX) {
                /* there must be no other command running that uses the
index 70855338b0d860d5a472a05f4740e7bbcf3e2fd5..1fc826d5a3a6f5f651dc27cc2c154a29a3b39980 100644 (file)
@@ -44,7 +44,8 @@ static const struct command imap_ext_commands[] = {
        { "CANCELUPDATE",       cmd_cancelupdate,0 },
        { "ENABLE",             cmd_enable,      0 },
        { "ID",                 cmd_id,          0 },
-       { "IDLE",               cmd_idle,        COMMAND_FLAG_BREAKS_SEQS },
+       { "IDLE",               cmd_idle,        COMMAND_FLAG_BREAKS_SEQS |
+                                                COMMAND_FLAG_REQUIRES_SYNC },
        { "NAMESPACE",          cmd_namespace,   0 },
        { "SORT",               cmd_sort,        COMMAND_FLAG_USES_SEQS },
        { "THREAD",             cmd_thread,      COMMAND_FLAG_USES_SEQS },
index 5b38686d89b4d645fce6f0075f1678cf78d264de..c385f401cf491afbdaa7d292f4bcc718b54a3798 100644 (file)
@@ -21,7 +21,10 @@ enum command_flags {
 
        /* Command uses selected mailbox */
        COMMAND_FLAG_USES_MAILBOX       = COMMAND_FLAG_BREAKS_MAILBOX |
-                                         COMMAND_FLAG_USES_SEQS
+                                         COMMAND_FLAG_USES_SEQS,
+
+       /* Command requires mailbox syncing before it can do its job. */
+       COMMAND_FLAG_REQUIRES_SYNC      = 0x08
 };
 
 struct command {
index c9bc02843ed44da00bc4dcde597a0b28bd434cda..ce02e8a533bd0e82630f6615b8ed201bb548ff14 100644 (file)
@@ -475,6 +475,18 @@ int imap_sync_more(struct imap_sync_context *ctx)
        return ret;
 }
 
+bool imap_sync_is_allowed(struct client *client)
+{
+       if (client->syncing)
+               return FALSE;
+
+       if (client->mailbox != NULL &&
+           mailbox_transaction_get_count(client->mailbox) > 0)
+               return FALSE;
+
+       return TRUE;
+}
+
 static bool cmd_finish_sync(struct client_command_context *cmd)
 {
        if (cmd->sync->callback != NULL)
@@ -676,9 +688,7 @@ bool cmd_sync_delayed(struct client *client)
                return FALSE;
        }
 
-       if (client->syncing ||
-           (client->mailbox != NULL &&
-            mailbox_transaction_get_count(client->mailbox) > 0)) {
+       if (!imap_sync_is_allowed(client)) {
                /* wait until mailbox can be synced */
                return cmd_sync_drop_fast(client);
        }
index 66d3fe1b0bf461bc09415e318b329192ea21cfb2..37d0cc9a008f0898ebe225f7e01ce110ed43df92 100644 (file)
@@ -17,6 +17,9 @@ int imap_sync_deinit(struct imap_sync_context *ctx,
                     struct client_command_context *sync_cmd);
 int imap_sync_more(struct imap_sync_context *ctx);
 
+/* Returns TRUE if syncing would be allowed currently. */
+bool imap_sync_is_allowed(struct client *client);
+
 bool cmd_sync(struct client_command_context *cmd, enum mailbox_sync_flags flags,
              enum imap_sync_flags imap_flags, const char *tagline);
 bool cmd_sync_callback(struct client_command_context *cmd,