annotate src/imap/cmd-idle.c @ 9095:9a0aa39a3a14 HEAD

imap: Cleaned up "command pending" handling code. Should fix hangs caused by recent changes.
author Timo Sirainen <tss@iki.fi>
date Tue, 26 May 2009 14:21:59 -0400
parents 3a4bed08b59d
children 373b22cbabac
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
8590
b9faf4db2a9f Updated copyright notices to include year 2009.
Timo Sirainen <tss@iki.fi>
parents: 7817
diff changeset
1 /* Copyright (c) 2002-2009 Dovecot authors, see the included COPYING file */
1172
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
2
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
3 #include "common.h"
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
4 #include "ioloop.h"
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
5 #include "istream.h"
1225
8c85c03e0485 cork the output before sending the ending IDLE replies.
Timo Sirainen <tss@iki.fi>
parents: 1221
diff changeset
6 #include "ostream.h"
1172
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
7 #include "commands.h"
2322
aae574ed7f4c Broke mailbox_sync() into iterator.
Timo Sirainen <tss@iki.fi>
parents: 1915
diff changeset
8 #include "imap-sync.h"
1172
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
9
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
10 #include <stdlib.h>
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
11
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
12 #define DEFAULT_IDLE_CHECK_INTERVAL 30
3838
e0881596af32 When idling, send an OK message every two minutes to break NAT/firewall timeouts.
Timo Sirainen <tss@iki.fi>
parents: 3826
diff changeset
13 /* Send some noice to client every few minutes to avoid NATs and stateful
e0881596af32 When idling, send an OK message every two minutes to break NAT/firewall timeouts.
Timo Sirainen <tss@iki.fi>
parents: 3826
diff changeset
14 firewalls from closing the connection */
8955
8de5b2a19a08 Added imap_idle_notify_interval setting.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
15 #define DEFAULT_IMAP_IDLE_NOTIFY_INTERVAL (2*60)
1172
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
16
2427
e1616067df5c Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
17 struct cmd_idle_context {
e1616067df5c Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
18 struct client *client;
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2800
diff changeset
19 struct client_command_context *cmd;
2427
e1616067df5c Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
20
e1616067df5c Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
21 struct imap_sync_context *sync_ctx;
6210
da3c8d825f5c Client is now never disconnected in IDLE because it hasn't sent anything.
Timo Sirainen <tss@iki.fi>
parents: 5805
diff changeset
22 struct timeout *keepalive_to;
2427
e1616067df5c Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
23
4832
9ea62a9720ec When mailbox changes are noticed and they're sent to client, cork before
Timo Sirainen <tss@iki.fi>
parents: 4830
diff changeset
24 unsigned int manual_cork:1;
2427
e1616067df5c Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
25 unsigned int sync_pending:1;
e1616067df5c Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
26 };
e1616067df5c Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
27
3863
55df57c028d4 Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents: 3838
diff changeset
28 static bool cmd_idle_continue(struct client_command_context *cmd);
2427
e1616067df5c Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
29
5431
712409f6d4d3 crashfix
Timo Sirainen <tss@iki.fi>
parents: 5110
diff changeset
30 static void
712409f6d4d3 crashfix
Timo Sirainen <tss@iki.fi>
parents: 5110
diff changeset
31 idle_finish(struct cmd_idle_context *ctx, bool done_ok, bool free_cmd)
1172
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
32 {
2427
e1616067df5c Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
33 struct client *client = ctx->client;
e1616067df5c Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
34
3879
928229f8b3e6 deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
35 if (ctx->keepalive_to != NULL)
928229f8b3e6 deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
36 timeout_remove(&ctx->keepalive_to);
1212
9ced30dda6c3 workaround: outlook-idle
Timo Sirainen <tss@iki.fi>
parents: 1172
diff changeset
37
3727
de92177c8113 If DONE was sent while output was still being sent to clients, we didn't
Timo Sirainen <tss@iki.fi>
parents: 3520
diff changeset
38 if (ctx->sync_ctx != NULL) {
de92177c8113 If DONE was sent while output was still being sent to clients, we didn't
Timo Sirainen <tss@iki.fi>
parents: 3520
diff changeset
39 /* we're here only in connection failure cases */
7817
ffaf1ea49704 QRESYNC: Send HIGHESTMODSEQ automatically in all tagged replies whenever it
Timo Sirainen <tss@iki.fi>
parents: 7437
diff changeset
40 (void)imap_sync_deinit(ctx->sync_ctx, ctx->cmd);
3727
de92177c8113 If DONE was sent while output was still being sent to clients, we didn't
Timo Sirainen <tss@iki.fi>
parents: 3520
diff changeset
41 }
de92177c8113 If DONE was sent while output was still being sent to clients, we didn't
Timo Sirainen <tss@iki.fi>
parents: 3520
diff changeset
42
1225
8c85c03e0485 cork the output before sending the ending IDLE replies.
Timo Sirainen <tss@iki.fi>
parents: 1221
diff changeset
43 o_stream_cork(client->output);
6499
4cb03870a714 Crashfix in some conditions
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
44 if (client->io != NULL)
4cb03870a714 Crashfix in some conditions
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
45 io_remove(&client->io);
1172
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
46
2322
aae574ed7f4c Broke mailbox_sync() into iterator.
Timo Sirainen <tss@iki.fi>
parents: 1915
diff changeset
47 if (client->mailbox != NULL)
4907
5b4c9b20eba0 Replaced void *context from a lot of callbacks with the actual context
Timo Sirainen <tss@iki.fi>
parents: 4832
diff changeset
48 mailbox_notify_changes_stop(client->mailbox);
1172
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
49
1220
Timo Sirainen <tss@iki.fi>
parents: 1213
diff changeset
50 if (done_ok)
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2800
diff changeset
51 client_send_tagline(ctx->cmd, "OK Idle completed.");
1220
Timo Sirainen <tss@iki.fi>
parents: 1213
diff changeset
52 else
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2800
diff changeset
53 client_send_tagline(ctx->cmd, "BAD Expected DONE.");
1220
Timo Sirainen <tss@iki.fi>
parents: 1213
diff changeset
54
2421
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2322
diff changeset
55 o_stream_uncork(client->output);
5431
712409f6d4d3 crashfix
Timo Sirainen <tss@iki.fi>
parents: 5110
diff changeset
56 if (free_cmd)
7431
33d8adcc2d44 client_command_free()/cancel(): Take pointer-to-pointer parameter and set it
Timo Sirainen <tss@iki.fi>
parents: 7266
diff changeset
57 client_command_free(&ctx->cmd);
1172
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
58 }
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
59
4907
5b4c9b20eba0 Replaced void *context from a lot of callbacks with the actual context
Timo Sirainen <tss@iki.fi>
parents: 4832
diff changeset
60 static void idle_client_input(struct cmd_idle_context *ctx)
1172
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
61 {
2427
e1616067df5c Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
62 struct client *client = ctx->client;
1172
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
63 char *line;
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
64
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
65 client->last_input = ioloop_time;
7126
0861436bfe14 Reset idle timeout also in APPEND/IDLE.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
66 timeout_reset(client->to_idle);
1172
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
67
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
68 switch (i_stream_read(client->input)) {
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
69 case -1:
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
70 /* disconnected */
4096
904c53275e83 Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents: 4095
diff changeset
71 client_destroy(client, "Disconnected in IDLE");
1172
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
72 return;
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
73 case -2:
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
74 client->input_skip_line = TRUE;
5431
712409f6d4d3 crashfix
Timo Sirainen <tss@iki.fi>
parents: 5110
diff changeset
75 idle_finish(ctx, FALSE, TRUE);
9095
9a0aa39a3a14 imap: Cleaned up "command pending" handling code. Should fix hangs caused by recent changes.
Timo Sirainen <tss@iki.fi>
parents: 9012
diff changeset
76 client_continue_pending_input(client);
1221
bff971233e5d handle error condition better
Timo Sirainen <tss@iki.fi>
parents: 1220
diff changeset
77 return;
1172
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
78 }
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
79
3727
de92177c8113 If DONE was sent while output was still being sent to clients, we didn't
Timo Sirainen <tss@iki.fi>
parents: 3520
diff changeset
80 if (ctx->sync_ctx != NULL) {
de92177c8113 If DONE was sent while output was still being sent to clients, we didn't
Timo Sirainen <tss@iki.fi>
parents: 3520
diff changeset
81 /* we're still sending output to client. wait until it's all
de92177c8113 If DONE was sent while output was still being sent to clients, we didn't
Timo Sirainen <tss@iki.fi>
parents: 3520
diff changeset
82 sent so we don't lose any changes. */
3879
928229f8b3e6 deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
83 io_remove(&client->io);
3727
de92177c8113 If DONE was sent while output was still being sent to clients, we didn't
Timo Sirainen <tss@iki.fi>
parents: 3520
diff changeset
84 return;
de92177c8113 If DONE was sent while output was still being sent to clients, we didn't
Timo Sirainen <tss@iki.fi>
parents: 3520
diff changeset
85 }
de92177c8113 If DONE was sent while output was still being sent to clients, we didn't
Timo Sirainen <tss@iki.fi>
parents: 3520
diff changeset
86
1172
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
87 while ((line = i_stream_next_line(client->input)) != NULL) {
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
88 if (client->input_skip_line)
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
89 client->input_skip_line = FALSE;
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
90 else {
9012
3a4bed08b59d IDLE: Check DONE case-insensitively.
Timo Sirainen <tss@iki.fi>
parents: 8955
diff changeset
91 idle_finish(ctx, strcasecmp(line, "DONE") == 0, TRUE);
1172
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
92 break;
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
93 }
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
94 }
9095
9a0aa39a3a14 imap: Cleaned up "command pending" handling code. Should fix hangs caused by recent changes.
Timo Sirainen <tss@iki.fi>
parents: 9012
diff changeset
95 if (client->disconnected)
9a0aa39a3a14 imap: Cleaned up "command pending" handling code. Should fix hangs caused by recent changes.
Timo Sirainen <tss@iki.fi>
parents: 9012
diff changeset
96 client_destroy(client, NULL);
9a0aa39a3a14 imap: Cleaned up "command pending" handling code. Should fix hangs caused by recent changes.
Timo Sirainen <tss@iki.fi>
parents: 9012
diff changeset
97 else
9a0aa39a3a14 imap: Cleaned up "command pending" handling code. Should fix hangs caused by recent changes.
Timo Sirainen <tss@iki.fi>
parents: 9012
diff changeset
98 client_continue_pending_input(client);
1172
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
99 }
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
100
4907
5b4c9b20eba0 Replaced void *context from a lot of callbacks with the actual context
Timo Sirainen <tss@iki.fi>
parents: 4832
diff changeset
101 static void keepalive_timeout(struct cmd_idle_context *ctx)
3838
e0881596af32 When idling, send an OK message every two minutes to break NAT/firewall timeouts.
Timo Sirainen <tss@iki.fi>
parents: 3826
diff changeset
102 {
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
103 if (ctx->client->output_lock != NULL) {
3838
e0881596af32 When idling, send an OK message every two minutes to break NAT/firewall timeouts.
Timo Sirainen <tss@iki.fi>
parents: 3826
diff changeset
104 /* it's busy sending output */
e0881596af32 When idling, send an OK message every two minutes to break NAT/firewall timeouts.
Timo Sirainen <tss@iki.fi>
parents: 3826
diff changeset
105 return;
e0881596af32 When idling, send an OK message every two minutes to break NAT/firewall timeouts.
Timo Sirainen <tss@iki.fi>
parents: 3826
diff changeset
106 }
e0881596af32 When idling, send an OK message every two minutes to break NAT/firewall timeouts.
Timo Sirainen <tss@iki.fi>
parents: 3826
diff changeset
107
7437
498975950370 Workaround to never idle-disconnect IDLEing clients got broken by timeout
Timo Sirainen <tss@iki.fi>
parents: 7431
diff changeset
108 /* Sending this keeps NATs/stateful firewalls alive. Sending this
498975950370 Workaround to never idle-disconnect IDLEing clients got broken by timeout
Timo Sirainen <tss@iki.fi>
parents: 7431
diff changeset
109 also catches dead connections. */
3838
e0881596af32 When idling, send an OK message every two minutes to break NAT/firewall timeouts.
Timo Sirainen <tss@iki.fi>
parents: 3826
diff changeset
110 client_send_line(ctx->client, "* OK Still here");
7437
498975950370 Workaround to never idle-disconnect IDLEing clients got broken by timeout
Timo Sirainen <tss@iki.fi>
parents: 7431
diff changeset
111 /* Make sure idling connections don't get disconnected. There are
498975950370 Workaround to never idle-disconnect IDLEing clients got broken by timeout
Timo Sirainen <tss@iki.fi>
parents: 7431
diff changeset
112 several clients that really want to IDLE forever and there's not
498975950370 Workaround to never idle-disconnect IDLEing clients got broken by timeout
Timo Sirainen <tss@iki.fi>
parents: 7431
diff changeset
113 much harm in letting them do so. */
498975950370 Workaround to never idle-disconnect IDLEing clients got broken by timeout
Timo Sirainen <tss@iki.fi>
parents: 7431
diff changeset
114 timeout_reset(ctx->client->to_idle);
3838
e0881596af32 When idling, send an OK message every two minutes to break NAT/firewall timeouts.
Timo Sirainen <tss@iki.fi>
parents: 3826
diff changeset
115 }
e0881596af32 When idling, send an OK message every two minutes to break NAT/firewall timeouts.
Timo Sirainen <tss@iki.fi>
parents: 3826
diff changeset
116
3777
39c293635875 Don't crash if client disconnected in IDLE. If mailbox had been changed before IDLE
Timo Sirainen <tss@iki.fi>
parents: 3765
diff changeset
117 static void idle_sync_now(struct mailbox *box, struct cmd_idle_context *ctx)
39c293635875 Don't crash if client disconnected in IDLE. If mailbox had been changed before IDLE
Timo Sirainen <tss@iki.fi>
parents: 3765
diff changeset
118 {
39c293635875 Don't crash if client disconnected in IDLE. If mailbox had been changed before IDLE
Timo Sirainen <tss@iki.fi>
parents: 3765
diff changeset
119 i_assert(ctx->sync_ctx == NULL);
39c293635875 Don't crash if client disconnected in IDLE. If mailbox had been changed before IDLE
Timo Sirainen <tss@iki.fi>
parents: 3765
diff changeset
120
39c293635875 Don't crash if client disconnected in IDLE. If mailbox had been changed before IDLE
Timo Sirainen <tss@iki.fi>
parents: 3765
diff changeset
121 ctx->sync_pending = FALSE;
39c293635875 Don't crash if client disconnected in IDLE. If mailbox had been changed before IDLE
Timo Sirainen <tss@iki.fi>
parents: 3765
diff changeset
122 ctx->sync_ctx = imap_sync_init(ctx->client, box, 0, 0);
39c293635875 Don't crash if client disconnected in IDLE. If mailbox had been changed before IDLE
Timo Sirainen <tss@iki.fi>
parents: 3765
diff changeset
123 cmd_idle_continue(ctx->cmd);
39c293635875 Don't crash if client disconnected in IDLE. If mailbox had been changed before IDLE
Timo Sirainen <tss@iki.fi>
parents: 3765
diff changeset
124 }
39c293635875 Don't crash if client disconnected in IDLE. If mailbox had been changed before IDLE
Timo Sirainen <tss@iki.fi>
parents: 3765
diff changeset
125
4907
5b4c9b20eba0 Replaced void *context from a lot of callbacks with the actual context
Timo Sirainen <tss@iki.fi>
parents: 4832
diff changeset
126 static void idle_callback(struct mailbox *box, struct cmd_idle_context *ctx)
2322
aae574ed7f4c Broke mailbox_sync() into iterator.
Timo Sirainen <tss@iki.fi>
parents: 1915
diff changeset
127 {
2427
e1616067df5c Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
128 if (ctx->sync_ctx != NULL)
e1616067df5c Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
129 ctx->sync_pending = TRUE;
4832
9ea62a9720ec When mailbox changes are noticed and they're sent to client, cork before
Timo Sirainen <tss@iki.fi>
parents: 4830
diff changeset
130 else {
9ea62a9720ec When mailbox changes are noticed and they're sent to client, cork before
Timo Sirainen <tss@iki.fi>
parents: 4830
diff changeset
131 ctx->manual_cork = TRUE;
9ea62a9720ec When mailbox changes are noticed and they're sent to client, cork before
Timo Sirainen <tss@iki.fi>
parents: 4830
diff changeset
132 idle_sync_now(box, ctx);
9ea62a9720ec When mailbox changes are noticed and they're sent to client, cork before
Timo Sirainen <tss@iki.fi>
parents: 4830
diff changeset
133 }
2427
e1616067df5c Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
134 }
2322
aae574ed7f4c Broke mailbox_sync() into iterator.
Timo Sirainen <tss@iki.fi>
parents: 1915
diff changeset
135
3863
55df57c028d4 Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents: 3838
diff changeset
136 static bool cmd_idle_continue(struct client_command_context *cmd)
2427
e1616067df5c Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
137 {
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2800
diff changeset
138 struct client *client = cmd->client;
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2800
diff changeset
139 struct cmd_idle_context *ctx = cmd->context;
8955
8de5b2a19a08 Added imap_idle_notify_interval setting.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
140 uoff_t orig_offset = client->output->offset;
2427
e1616067df5c Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
141
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
142 if (cmd->cancel) {
5431
712409f6d4d3 crashfix
Timo Sirainen <tss@iki.fi>
parents: 5110
diff changeset
143 idle_finish(ctx, FALSE, FALSE);
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
144 return TRUE;
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
145 }
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
146
4832
9ea62a9720ec When mailbox changes are noticed and they're sent to client, cork before
Timo Sirainen <tss@iki.fi>
parents: 4830
diff changeset
147 if (ctx->manual_cork) {
9ea62a9720ec When mailbox changes are noticed and they're sent to client, cork before
Timo Sirainen <tss@iki.fi>
parents: 4830
diff changeset
148 /* we're coming from idle_callback instead of a normal
9ea62a9720ec When mailbox changes are noticed and they're sent to client, cork before
Timo Sirainen <tss@iki.fi>
parents: 4830
diff changeset
149 I/O handler, so we'll have to do corking manually */
9ea62a9720ec When mailbox changes are noticed and they're sent to client, cork before
Timo Sirainen <tss@iki.fi>
parents: 4830
diff changeset
150 o_stream_cork(client->output);
9ea62a9720ec When mailbox changes are noticed and they're sent to client, cork before
Timo Sirainen <tss@iki.fi>
parents: 4830
diff changeset
151 }
9ea62a9720ec When mailbox changes are noticed and they're sent to client, cork before
Timo Sirainen <tss@iki.fi>
parents: 4830
diff changeset
152
2474
d2a64ae90011 Crashfix
Timo Sirainen <tss@iki.fi>
parents: 2445
diff changeset
153 if (ctx->sync_ctx != NULL) {
d2a64ae90011 Crashfix
Timo Sirainen <tss@iki.fi>
parents: 2445
diff changeset
154 if (imap_sync_more(ctx->sync_ctx) == 0) {
d2a64ae90011 Crashfix
Timo Sirainen <tss@iki.fi>
parents: 2445
diff changeset
155 /* unfinished */
4832
9ea62a9720ec When mailbox changes are noticed and they're sent to client, cork before
Timo Sirainen <tss@iki.fi>
parents: 4830
diff changeset
156 if (ctx->manual_cork) {
9ea62a9720ec When mailbox changes are noticed and they're sent to client, cork before
Timo Sirainen <tss@iki.fi>
parents: 4830
diff changeset
157 ctx->manual_cork = FALSE;
9ea62a9720ec When mailbox changes are noticed and they're sent to client, cork before
Timo Sirainen <tss@iki.fi>
parents: 4830
diff changeset
158 o_stream_uncork(client->output);
9ea62a9720ec When mailbox changes are noticed and they're sent to client, cork before
Timo Sirainen <tss@iki.fi>
parents: 4830
diff changeset
159 }
7148
5e3188213724 Added "command state" for running commands. Use it instead of some bitfields
Timo Sirainen <tss@iki.fi>
parents: 7126
diff changeset
160 cmd->state = CLIENT_COMMAND_STATE_WAIT_OUTPUT;
2474
d2a64ae90011 Crashfix
Timo Sirainen <tss@iki.fi>
parents: 2445
diff changeset
161 return FALSE;
d2a64ae90011 Crashfix
Timo Sirainen <tss@iki.fi>
parents: 2445
diff changeset
162 }
2427
e1616067df5c Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
163
7817
ffaf1ea49704 QRESYNC: Send HIGHESTMODSEQ automatically in all tagged replies whenever it
Timo Sirainen <tss@iki.fi>
parents: 7437
diff changeset
164 if (imap_sync_deinit(ctx->sync_ctx, ctx->cmd) < 0) {
2474
d2a64ae90011 Crashfix
Timo Sirainen <tss@iki.fi>
parents: 2445
diff changeset
165 client_send_untagged_storage_error(client,
d2a64ae90011 Crashfix
Timo Sirainen <tss@iki.fi>
parents: 2445
diff changeset
166 mailbox_get_storage(client->mailbox));
4907
5b4c9b20eba0 Replaced void *context from a lot of callbacks with the actual context
Timo Sirainen <tss@iki.fi>
parents: 4832
diff changeset
167 mailbox_notify_changes_stop(client->mailbox);
2474
d2a64ae90011 Crashfix
Timo Sirainen <tss@iki.fi>
parents: 2445
diff changeset
168 }
d2a64ae90011 Crashfix
Timo Sirainen <tss@iki.fi>
parents: 2445
diff changeset
169 ctx->sync_ctx = NULL;
1212
9ced30dda6c3 workaround: outlook-idle
Timo Sirainen <tss@iki.fi>
parents: 1172
diff changeset
170 }
8955
8de5b2a19a08 Added imap_idle_notify_interval setting.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
171 if (client->output->offset != orig_offset &&
8de5b2a19a08 Added imap_idle_notify_interval setting.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
172 ctx->keepalive_to != NULL)
8de5b2a19a08 Added imap_idle_notify_interval setting.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
173 timeout_reset(ctx->keepalive_to);
2427
e1616067df5c Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
174
6210
da3c8d825f5c Client is now never disconnected in IDLE because it hasn't sent anything.
Timo Sirainen <tss@iki.fi>
parents: 5805
diff changeset
175 if (ctx->sync_pending) {
3520
e2fe8222449d s/occured/occurred/
Timo Sirainen <tss@iki.fi>
parents: 3141
diff changeset
176 /* more changes occurred while we were sending changes to
2427
e1616067df5c Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
177 client */
3826
20430dbf04d4 Recent changes broke IDLE when no mailbox was opened.
Timo Sirainen <tss@iki.fi>
parents: 3777
diff changeset
178 idle_sync_now(client->mailbox, ctx);
4786
65bbeb211a30 If mailbox is changed while syncing is being done, and the second sync's
Timo Sirainen <tss@iki.fi>
parents: 4096
diff changeset
179 /* NOTE: this recurses back to this function,
65bbeb211a30 If mailbox is changed while syncing is being done, and the second sync's
Timo Sirainen <tss@iki.fi>
parents: 4096
diff changeset
180 so we return here instead of doing everything twice. */
65bbeb211a30 If mailbox is changed while syncing is being done, and the second sync's
Timo Sirainen <tss@iki.fi>
parents: 4096
diff changeset
181 return FALSE;
2427
e1616067df5c Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
182 }
7149
323b425a0f46 Replaced waiting_ambiguity bitmask with a command state.
Timo Sirainen <tss@iki.fi>
parents: 7148
diff changeset
183 cmd->state = CLIENT_COMMAND_STATE_WAIT_INPUT;
2501
b7eec64e0735 Deinitialize command handlers always.
Timo Sirainen <tss@iki.fi>
parents: 2474
diff changeset
184
4832
9ea62a9720ec When mailbox changes are noticed and they're sent to client, cork before
Timo Sirainen <tss@iki.fi>
parents: 4830
diff changeset
185 if (ctx->manual_cork) {
9ea62a9720ec When mailbox changes are noticed and they're sent to client, cork before
Timo Sirainen <tss@iki.fi>
parents: 4830
diff changeset
186 ctx->manual_cork = FALSE;
9ea62a9720ec When mailbox changes are noticed and they're sent to client, cork before
Timo Sirainen <tss@iki.fi>
parents: 4830
diff changeset
187 o_stream_uncork(client->output);
9ea62a9720ec When mailbox changes are noticed and they're sent to client, cork before
Timo Sirainen <tss@iki.fi>
parents: 4830
diff changeset
188 }
9ea62a9720ec When mailbox changes are noticed and they're sent to client, cork before
Timo Sirainen <tss@iki.fi>
parents: 4830
diff changeset
189
4830
a642d3df700f If syncing finished with an error and client had disconnected, we
Timo Sirainen <tss@iki.fi>
parents: 4786
diff changeset
190 if (client->output->closed) {
5431
712409f6d4d3 crashfix
Timo Sirainen <tss@iki.fi>
parents: 5110
diff changeset
191 idle_finish(ctx, FALSE, FALSE);
4830
a642d3df700f If syncing finished with an error and client had disconnected, we
Timo Sirainen <tss@iki.fi>
parents: 4786
diff changeset
192 return TRUE;
a642d3df700f If syncing finished with an error and client had disconnected, we
Timo Sirainen <tss@iki.fi>
parents: 4786
diff changeset
193 }
3727
de92177c8113 If DONE was sent while output was still being sent to clients, we didn't
Timo Sirainen <tss@iki.fi>
parents: 3520
diff changeset
194 if (client->io == NULL) {
de92177c8113 If DONE was sent while output was still being sent to clients, we didn't
Timo Sirainen <tss@iki.fi>
parents: 3520
diff changeset
195 /* input is pending */
de92177c8113 If DONE was sent while output was still being sent to clients, we didn't
Timo Sirainen <tss@iki.fi>
parents: 3520
diff changeset
196 client->io = io_add(i_stream_get_fd(client->input),
de92177c8113 If DONE was sent while output was still being sent to clients, we didn't
Timo Sirainen <tss@iki.fi>
parents: 3520
diff changeset
197 IO_READ, idle_client_input, ctx);
de92177c8113 If DONE was sent while output was still being sent to clients, we didn't
Timo Sirainen <tss@iki.fi>
parents: 3520
diff changeset
198 idle_client_input(ctx);
de92177c8113 If DONE was sent while output was still being sent to clients, we didn't
Timo Sirainen <tss@iki.fi>
parents: 3520
diff changeset
199 }
2427
e1616067df5c Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
200 return FALSE;
1212
9ced30dda6c3 workaround: outlook-idle
Timo Sirainen <tss@iki.fi>
parents: 1172
diff changeset
201 }
9ced30dda6c3 workaround: outlook-idle
Timo Sirainen <tss@iki.fi>
parents: 1172
diff changeset
202
3863
55df57c028d4 Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents: 3838
diff changeset
203 bool cmd_idle(struct client_command_context *cmd)
1172
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
204 {
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2800
diff changeset
205 struct client *client = cmd->client;
2427
e1616067df5c Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
206 struct cmd_idle_context *ctx;
1172
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
207 const char *str;
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
208 unsigned int interval;
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
209
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2800
diff changeset
210 ctx = p_new(cmd->pool, struct cmd_idle_context, 1);
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2800
diff changeset
211 ctx->cmd = cmd;
2427
e1616067df5c Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
212 ctx->client = client;
e1616067df5c Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
213
8955
8de5b2a19a08 Added imap_idle_notify_interval setting.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
214 str = getenv("IMAP_IDLE_NOTIFY_INTERVAL");
8de5b2a19a08 Added imap_idle_notify_interval setting.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
215 interval = str != NULL ?
8de5b2a19a08 Added imap_idle_notify_interval setting.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
216 (unsigned int)strtoul(str, NULL, 10) :
8de5b2a19a08 Added imap_idle_notify_interval setting.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
217 DEFAULT_IMAP_IDLE_NOTIFY_INTERVAL;
8de5b2a19a08 Added imap_idle_notify_interval setting.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
218 ctx->keepalive_to = interval == 0 ? NULL :
8de5b2a19a08 Added imap_idle_notify_interval setting.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
219 timeout_add(interval * 1000,
8de5b2a19a08 Added imap_idle_notify_interval setting.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
220 keepalive_timeout, ctx);
1212
9ced30dda6c3 workaround: outlook-idle
Timo Sirainen <tss@iki.fi>
parents: 1172
diff changeset
221
1172
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
222 str = getenv("MAILBOX_IDLE_CHECK_INTERVAL");
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
223 interval = str == NULL ? 0 : (unsigned int)strtoul(str, NULL, 10);
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
224 if (interval == 0)
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
225 interval = DEFAULT_IDLE_CHECK_INTERVAL;
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
226
2322
aae574ed7f4c Broke mailbox_sync() into iterator.
Timo Sirainen <tss@iki.fi>
parents: 1915
diff changeset
227 if (client->mailbox != NULL) {
aae574ed7f4c Broke mailbox_sync() into iterator.
Timo Sirainen <tss@iki.fi>
parents: 1915
diff changeset
228 mailbox_notify_changes(client->mailbox, interval,
2427
e1616067df5c Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
229 idle_callback, ctx);
2322
aae574ed7f4c Broke mailbox_sync() into iterator.
Timo Sirainen <tss@iki.fi>
parents: 1915
diff changeset
230 }
1172
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
231 client_send_line(client, "+ idling");
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
232
3879
928229f8b3e6 deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
233 io_remove(&client->io);
1172
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
234 client->io = io_add(i_stream_get_fd(client->input),
2427
e1616067df5c Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
235 IO_READ, idle_client_input, ctx);
e1616067df5c Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
236
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2800
diff changeset
237 cmd->func = cmd_idle_continue;
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2800
diff changeset
238 cmd->context = ctx;
3777
39c293635875 Don't crash if client disconnected in IDLE. If mailbox had been changed before IDLE
Timo Sirainen <tss@iki.fi>
parents: 3765
diff changeset
239
39c293635875 Don't crash if client disconnected in IDLE. If mailbox had been changed before IDLE
Timo Sirainen <tss@iki.fi>
parents: 3765
diff changeset
240 /* check immediately if there are changes. if they came before we
39c293635875 Don't crash if client disconnected in IDLE. If mailbox had been changed before IDLE
Timo Sirainen <tss@iki.fi>
parents: 3765
diff changeset
241 added mailbox-notifier, we wouldn't see them otherwise. */
3826
20430dbf04d4 Recent changes broke IDLE when no mailbox was opened.
Timo Sirainen <tss@iki.fi>
parents: 3777
diff changeset
242 if (client->mailbox != NULL)
20430dbf04d4 Recent changes broke IDLE when no mailbox was opened.
Timo Sirainen <tss@iki.fi>
parents: 3777
diff changeset
243 idle_sync_now(client->mailbox, ctx);
1172
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
244 return FALSE;
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
245 }