Try to send tagged replies in the same order as the commands were received HEAD
authorTimo Sirainen <tss@iki.fi>
Thu Mar 20 16:55:44 2008 +0200 (2008-03-20)
branchHEAD
changeset 74344407b7265afd
parent 7433 0ee365c21c16
child 7435 6983dfc231d7
Try to send tagged replies in the same order as the commands were received
(fixes Apple Mail bug).
src/imap/imap-sync.c
     1.1 --- a/src/imap/imap-sync.c	Thu Mar 20 16:54:19 2008 +0200
     1.2 +++ b/src/imap/imap-sync.c	Thu Mar 20 16:55:44 2008 +0200
     1.3 @@ -210,7 +210,7 @@
     1.4  
     1.5  static bool cmd_sync_continue(struct client_command_context *sync_cmd)
     1.6  {
     1.7 -	struct client_command_context *cmd, *next;
     1.8 +	struct client_command_context *cmd, *prev;
     1.9  	struct client *client = sync_cmd->client;
    1.10  	struct imap_sync_context *ctx = sync_cmd->context;
    1.11  	int ret;
    1.12 @@ -229,9 +229,13 @@
    1.13  	}
    1.14  	sync_cmd->context = NULL;
    1.15  
    1.16 -	/* finish all commands that waited for this sync */
    1.17 -	for (cmd = client->command_queue; cmd != NULL; cmd = next) {
    1.18 -		next = cmd->next;
    1.19 +	/* Finish all commands that waited for this sync. Go through the queue
    1.20 +	   backwards, so that tagged replies are sent in the same order as
    1.21 +	   they were received. This fixes problems with clients that rely on
    1.22 +	   this (Apple Mail 3.2) */
    1.23 +	for (cmd = client->command_queue; cmd->next != NULL; cmd = cmd->next) ;
    1.24 +	for (; cmd != NULL; cmd = prev) {
    1.25 +		prev = cmd->prev;
    1.26  
    1.27  		if (cmd->state == CLIENT_COMMAND_STATE_WAIT_SYNC &&
    1.28  		    cmd != sync_cmd &&
    1.29 @@ -365,11 +369,15 @@
    1.30  
    1.31  static bool cmd_sync_drop_fast(struct client *client)
    1.32  {
    1.33 -	struct client_command_context *cmd, *next;
    1.34 +	struct client_command_context *cmd, *prev;
    1.35  	bool ret = FALSE;
    1.36  
    1.37 -	for (cmd = client->command_queue; cmd != NULL; cmd = next) {
    1.38 -		next = cmd->next;
    1.39 +	if (client->command_queue == NULL)
    1.40 +		return FALSE;
    1.41 +
    1.42 +	for (cmd = client->command_queue; cmd->next != NULL; cmd = cmd->next) ;
    1.43 +	for (; cmd != NULL; cmd = prev) {
    1.44 +		prev = cmd->next;
    1.45  
    1.46  		if (cmd->state == CLIENT_COMMAND_STATE_WAIT_SYNC &&
    1.47  		    (cmd->sync->flags & MAILBOX_SYNC_FLAG_FAST) != 0) {