annotate src/imap/client.c @ 8467:03c418eadc8b HEAD

mail_user_*() now handles home directory lookups when necessary. Namespace owner is now a pointer to struct mail_user rather than a string.
author Timo Sirainen <tss@iki.fi>
date Fri, 21 Nov 2008 18:32:02 +0200
parents 6e9100795d89
children 983d38de06c9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
7086
7ed926ed7aa4 Updated copyright notices to include year 2008.
Timo Sirainen <tss@iki.fi>
parents: 7057
diff changeset
1 /* Copyright (c) 2002-2008 Dovecot authors, see the included COPYING file */
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
2
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
3 #include "common.h"
532
3b53dd1280c6 I/O buffers now use real blocking instead of setting up a sub-ioloop to
Timo Sirainen <tss@iki.fi>
parents: 410
diff changeset
4 #include "ioloop.h"
7150
8a531386c856 Use linked list macros for command queue.
Timo Sirainen <tss@iki.fi>
parents: 7149
diff changeset
5 #include "llist.h"
5980
57b70f64f997 Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents: 5835
diff changeset
6 #include "str.h"
164
2660a5684515 Added io_buffer_read_blocking() which can be used to read data blockingly,
Timo Sirainen <tss@iki.fi>
parents: 158
diff changeset
7 #include "network.h"
764
f57c52738f90 Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents: 720
diff changeset
8 #include "istream.h"
f57c52738f90 Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents: 720
diff changeset
9 #include "ostream.h"
5980
57b70f64f997 Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents: 5835
diff changeset
10 #include "var-expand.h"
8412
6e9100795d89 Moved imap-resp-codes to macros.
Timo Sirainen <tss@iki.fi>
parents: 8411
diff changeset
11 #include "imap-resp-code.h"
6e9100795d89 Moved imap-resp-codes to macros.
Timo Sirainen <tss@iki.fi>
parents: 8411
diff changeset
12 #include "mail-namespace.h"
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
13 #include "commands.h"
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
14
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
15 #include <stdlib.h>
3960
aeb424e64f24 Call io_remove() before closing the fd. It's required by kqueue.
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
16 #include <unistd.h>
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
17
903
fd8888f6f037 Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents: 807
diff changeset
18 extern struct mail_storage_callbacks mail_storage_callbacks;
674
b7aefd0d7611 Locking changes triggered a bit larger cleanup :) If we have to wait for a
Timo Sirainen <tss@iki.fi>
parents: 532
diff changeset
19
903
fd8888f6f037 Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents: 807
diff changeset
20 static struct client *my_client; /* we don't need more than one currently */
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
21
7103
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
22 static void client_idle_timeout(struct client *client)
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
23 {
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
24 if (client->output_lock == NULL)
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
25 client_send_line(client, "* BYE Disconnected for inactivity.");
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
26 client_destroy(client, "Disconnected for inactivity");
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
27 }
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
28
8082
db66611fd195 Added struct mail_user and fixed the code to support multiple users per process.
Timo Sirainen <tss@iki.fi>
parents: 7927
diff changeset
29 struct client *client_create(int fd_in, int fd_out, struct mail_user *user)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
30 {
903
fd8888f6f037 Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents: 807
diff changeset
31 struct client *client;
8082
db66611fd195 Added struct mail_user and fixed the code to support multiple users per process.
Timo Sirainen <tss@iki.fi>
parents: 7927
diff changeset
32 struct mail_namespace *ns;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
33
2421
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
34 /* always use nonblocking I/O */
3960
aeb424e64f24 Call io_remove() before closing the fd. It's required by kqueue.
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
35 net_set_nonblock(fd_in, TRUE);
aeb424e64f24 Call io_remove() before closing the fd. It's required by kqueue.
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
36 net_set_nonblock(fd_out, TRUE);
2421
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
37
903
fd8888f6f037 Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents: 807
diff changeset
38 client = i_new(struct client, 1);
3960
aeb424e64f24 Call io_remove() before closing the fd. It's required by kqueue.
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
39 client->fd_in = fd_in;
aeb424e64f24 Call io_remove() before closing the fd. It's required by kqueue.
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
40 client->fd_out = fd_out;
6162
896cc473c1f0 Renamed i_stream_create_file() to i_stream_create_fd().
Timo Sirainen <tss@iki.fi>
parents: 6161
diff changeset
41 client->input = i_stream_create_fd(fd_in, imap_max_line_length, FALSE);
6161
c62f7ee79446 Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents: 6142
diff changeset
42 client->output = o_stream_create_fd(fd_out, (size_t)-1, FALSE);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
43
6418
46d9ee79f292 Removed _ prefix from all public APIs.
Timo Sirainen <tss@iki.fi>
parents: 6411
diff changeset
44 o_stream_set_flush_callback(client->output, client_output, client);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
45
6418
46d9ee79f292 Removed _ prefix from all public APIs.
Timo Sirainen <tss@iki.fi>
parents: 6411
diff changeset
46 client->io = io_add(fd_in, IO_READ, client_input, client);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
47 client->last_input = ioloop_time;
7103
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
48 client->to_idle = timeout_add(CLIENT_IDLE_TIMEOUT_MSECS,
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
49 client_idle_timeout, client);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
50
7195
bca55675d77c When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents: 7151
diff changeset
51 client->command_pool = pool_alloconly_create("client command", 1024*12);
8082
db66611fd195 Added struct mail_user and fixed the code to support multiple users per process.
Timo Sirainen <tss@iki.fi>
parents: 7927
diff changeset
52 client->user = user;
1654
31c4bb26a1e9 Getting ready for namespaces. LIST is still broken with them.
Timo Sirainen <tss@iki.fi>
parents: 1643
diff changeset
53
8082
db66611fd195 Added struct mail_user and fixed the code to support multiple users per process.
Timo Sirainen <tss@iki.fi>
parents: 7927
diff changeset
54 for (ns = user->namespaces; ns != NULL; ns = ns->next) {
db66611fd195 Added struct mail_user and fixed the code to support multiple users per process.
Timo Sirainen <tss@iki.fi>
parents: 7927
diff changeset
55 mail_storage_set_callbacks(ns->storage,
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents: 1654
diff changeset
56 &mail_storage_callbacks, client);
1654
31c4bb26a1e9 Getting ready for namespaces. LIST is still broken with them.
Timo Sirainen <tss@iki.fi>
parents: 1643
diff changeset
57 }
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
58
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
59 i_assert(my_client == NULL);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
60 my_client = client;
1641
6498f3cb9d2c Added hook_client_created and hook_mail_storage_created for modules.
Timo Sirainen <tss@iki.fi>
parents: 1591
diff changeset
61
6498f3cb9d2c Added hook_client_created and hook_mail_storage_created for modules.
Timo Sirainen <tss@iki.fi>
parents: 1591
diff changeset
62 if (hook_client_created != NULL)
1643
ca1c2972b78f hook changes
Timo Sirainen <tss@iki.fi>
parents: 1641
diff changeset
63 hook_client_created(&client);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
64 return client;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
65 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
66
7431
33d8adcc2d44 client_command_free()/cancel(): Take pointer-to-pointer parameter and set it
Timo Sirainen <tss@iki.fi>
parents: 7352
diff changeset
67 void client_command_cancel(struct client_command_context **_cmd)
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
68 {
7431
33d8adcc2d44 client_command_free()/cancel(): Take pointer-to-pointer parameter and set it
Timo Sirainen <tss@iki.fi>
parents: 7352
diff changeset
69 struct client_command_context *cmd = *_cmd;
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
70 bool cmd_ret;
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
71
7583
a99b9735f875 Don't try to call a cancelled command if it hasn't started running. Cancel
Timo Sirainen <tss@iki.fi>
parents: 7524
diff changeset
72 switch (cmd->state) {
a99b9735f875 Don't try to call a cancelled command if it hasn't started running. Cancel
Timo Sirainen <tss@iki.fi>
parents: 7524
diff changeset
73 case CLIENT_COMMAND_STATE_WAIT_INPUT:
a99b9735f875 Don't try to call a cancelled command if it hasn't started running. Cancel
Timo Sirainen <tss@iki.fi>
parents: 7524
diff changeset
74 /* a bit kludgy check: cancel command only if it has context
a99b9735f875 Don't try to call a cancelled command if it hasn't started running. Cancel
Timo Sirainen <tss@iki.fi>
parents: 7524
diff changeset
75 set. currently only append command matches this check. all
a99b9735f875 Don't try to call a cancelled command if it hasn't started running. Cancel
Timo Sirainen <tss@iki.fi>
parents: 7524
diff changeset
76 other commands haven't even started the processing yet. */
a99b9735f875 Don't try to call a cancelled command if it hasn't started running. Cancel
Timo Sirainen <tss@iki.fi>
parents: 7524
diff changeset
77 if (cmd->context == NULL)
a99b9735f875 Don't try to call a cancelled command if it hasn't started running. Cancel
Timo Sirainen <tss@iki.fi>
parents: 7524
diff changeset
78 break;
a99b9735f875 Don't try to call a cancelled command if it hasn't started running. Cancel
Timo Sirainen <tss@iki.fi>
parents: 7524
diff changeset
79 /* fall through */
a99b9735f875 Don't try to call a cancelled command if it hasn't started running. Cancel
Timo Sirainen <tss@iki.fi>
parents: 7524
diff changeset
80 case CLIENT_COMMAND_STATE_WAIT_OUTPUT:
a99b9735f875 Don't try to call a cancelled command if it hasn't started running. Cancel
Timo Sirainen <tss@iki.fi>
parents: 7524
diff changeset
81 cmd->cancel = TRUE;
a99b9735f875 Don't try to call a cancelled command if it hasn't started running. Cancel
Timo Sirainen <tss@iki.fi>
parents: 7524
diff changeset
82 break;
a99b9735f875 Don't try to call a cancelled command if it hasn't started running. Cancel
Timo Sirainen <tss@iki.fi>
parents: 7524
diff changeset
83 case CLIENT_COMMAND_STATE_WAIT_UNAMBIGUITY:
a99b9735f875 Don't try to call a cancelled command if it hasn't started running. Cancel
Timo Sirainen <tss@iki.fi>
parents: 7524
diff changeset
84 case CLIENT_COMMAND_STATE_WAIT_SYNC:
a99b9735f875 Don't try to call a cancelled command if it hasn't started running. Cancel
Timo Sirainen <tss@iki.fi>
parents: 7524
diff changeset
85 /* commands haven't started yet */
a99b9735f875 Don't try to call a cancelled command if it hasn't started running. Cancel
Timo Sirainen <tss@iki.fi>
parents: 7524
diff changeset
86 break;
a99b9735f875 Don't try to call a cancelled command if it hasn't started running. Cancel
Timo Sirainen <tss@iki.fi>
parents: 7524
diff changeset
87 case CLIENT_COMMAND_STATE_DONE:
a99b9735f875 Don't try to call a cancelled command if it hasn't started running. Cancel
Timo Sirainen <tss@iki.fi>
parents: 7524
diff changeset
88 i_unreached();
a99b9735f875 Don't try to call a cancelled command if it hasn't started running. Cancel
Timo Sirainen <tss@iki.fi>
parents: 7524
diff changeset
89 }
a99b9735f875 Don't try to call a cancelled command if it hasn't started running. Cancel
Timo Sirainen <tss@iki.fi>
parents: 7524
diff changeset
90
a99b9735f875 Don't try to call a cancelled command if it hasn't started running. Cancel
Timo Sirainen <tss@iki.fi>
parents: 7524
diff changeset
91 cmd_ret = !cmd->cancel || cmd->func == NULL ? TRUE : cmd->func(cmd);
7148
5e3188213724 Added "command state" for running commands. Use it instead of some bitfields
Timo Sirainen <tss@iki.fi>
parents: 7142
diff changeset
92 if (!cmd_ret && cmd->state != CLIENT_COMMAND_STATE_DONE) {
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
93 if (cmd->client->output->closed)
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
94 i_panic("command didn't cancel itself: %s", cmd->name);
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
95 } else {
7431
33d8adcc2d44 client_command_free()/cancel(): Take pointer-to-pointer parameter and set it
Timo Sirainen <tss@iki.fi>
parents: 7352
diff changeset
96 client_command_free(_cmd);
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
97 }
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
98 }
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
99
5980
57b70f64f997 Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents: 5835
diff changeset
100 static const char *client_stats(struct client *client)
57b70f64f997 Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents: 5835
diff changeset
101 {
57b70f64f997 Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents: 5835
diff changeset
102 static struct var_expand_table static_tab[] = {
57b70f64f997 Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents: 5835
diff changeset
103 { 'i', NULL },
57b70f64f997 Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents: 5835
diff changeset
104 { 'o', NULL },
57b70f64f997 Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents: 5835
diff changeset
105 { '\0', NULL }
57b70f64f997 Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents: 5835
diff changeset
106 };
57b70f64f997 Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents: 5835
diff changeset
107 struct var_expand_table *tab;
57b70f64f997 Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents: 5835
diff changeset
108 string_t *str;
57b70f64f997 Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents: 5835
diff changeset
109
57b70f64f997 Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents: 5835
diff changeset
110 tab = t_malloc(sizeof(static_tab));
57b70f64f997 Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents: 5835
diff changeset
111 memcpy(tab, static_tab, sizeof(static_tab));
57b70f64f997 Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents: 5835
diff changeset
112
57b70f64f997 Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents: 5835
diff changeset
113 tab[0].value = dec2str(client->input->v_offset);
57b70f64f997 Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents: 5835
diff changeset
114 tab[1].value = dec2str(client->output->offset);
57b70f64f997 Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents: 5835
diff changeset
115
57b70f64f997 Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents: 5835
diff changeset
116 str = t_str_new(128);
57b70f64f997 Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents: 5835
diff changeset
117 var_expand(str, logout_format, tab);
57b70f64f997 Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents: 5835
diff changeset
118 return str_c(str);
57b70f64f997 Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents: 5835
diff changeset
119 }
57b70f64f997 Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents: 5835
diff changeset
120
6309
f8c9b1a93521 If read/write to client failed with some error, log it.
Timo Sirainen <tss@iki.fi>
parents: 6210
diff changeset
121 static const char *client_get_disconnect_reason(struct client *client)
f8c9b1a93521 If read/write to client failed with some error, log it.
Timo Sirainen <tss@iki.fi>
parents: 6210
diff changeset
122 {
f8c9b1a93521 If read/write to client failed with some error, log it.
Timo Sirainen <tss@iki.fi>
parents: 6210
diff changeset
123 errno = client->input->stream_errno != 0 ?
f8c9b1a93521 If read/write to client failed with some error, log it.
Timo Sirainen <tss@iki.fi>
parents: 6210
diff changeset
124 client->input->stream_errno :
f8c9b1a93521 If read/write to client failed with some error, log it.
Timo Sirainen <tss@iki.fi>
parents: 6210
diff changeset
125 client->output->stream_errno;
6391
c5cff3c6828a If connection closed because of EPIPE, log it as "Connection closed" instead
Timo Sirainen <tss@iki.fi>
parents: 6310
diff changeset
126 return errno == 0 || errno == EPIPE ? "Connection closed" :
6310
15e10065a472 Changed disconnection reason to "Connection closed"
Timo Sirainen <tss@iki.fi>
parents: 6309
diff changeset
127 t_strdup_printf("Connection closed: %m");
6309
f8c9b1a93521 If read/write to client failed with some error, log it.
Timo Sirainen <tss@iki.fi>
parents: 6210
diff changeset
128 }
f8c9b1a93521 If read/write to client failed with some error, log it.
Timo Sirainen <tss@iki.fi>
parents: 6210
diff changeset
129
4096
904c53275e83 Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents: 4070
diff changeset
130 void client_destroy(struct client *client, const char *reason)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
131 {
7431
33d8adcc2d44 client_command_free()/cancel(): Take pointer-to-pointer parameter and set it
Timo Sirainen <tss@iki.fi>
parents: 7352
diff changeset
132 struct client_command_context *cmd;
8082
db66611fd195 Added struct mail_user and fixed the code to support multiple users per process.
Timo Sirainen <tss@iki.fi>
parents: 7927
diff changeset
133
3871
2506e4077e7a Don't crash if closing with signal while IDLEing.
Timo Sirainen <tss@iki.fi>
parents: 3866
diff changeset
134 i_assert(!client->destroyed);
2506e4077e7a Don't crash if closing with signal while IDLEing.
Timo Sirainen <tss@iki.fi>
parents: 3866
diff changeset
135 client->destroyed = TRUE;
2506e4077e7a Don't crash if closing with signal while IDLEing.
Timo Sirainen <tss@iki.fi>
parents: 3866
diff changeset
136
4096
904c53275e83 Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents: 4070
diff changeset
137 if (!client->disconnected) {
4787
62f534a0fd68 Don't crash if client disconnected while IDLEing.
Timo Sirainen <tss@iki.fi>
parents: 4773
diff changeset
138 client->disconnected = TRUE;
4096
904c53275e83 Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents: 4070
diff changeset
139 if (reason == NULL)
6309
f8c9b1a93521 If read/write to client failed with some error, log it.
Timo Sirainen <tss@iki.fi>
parents: 6210
diff changeset
140 reason = client_get_disconnect_reason(client);
5980
57b70f64f997 Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents: 5835
diff changeset
141 i_info("%s %s", reason, client_stats(client));
4096
904c53275e83 Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents: 4070
diff changeset
142 }
904c53275e83 Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents: 4070
diff changeset
143
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
144 i_stream_close(client->input);
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
145 o_stream_close(client->output);
3871
2506e4077e7a Don't crash if closing with signal while IDLEing.
Timo Sirainen <tss@iki.fi>
parents: 3866
diff changeset
146
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
147 /* finish off all the queued commands. */
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
148 if (client->output_lock != NULL)
7431
33d8adcc2d44 client_command_free()/cancel(): Take pointer-to-pointer parameter and set it
Timo Sirainen <tss@iki.fi>
parents: 7352
diff changeset
149 client_command_cancel(&client->output_lock);
33d8adcc2d44 client_command_free()/cancel(): Take pointer-to-pointer parameter and set it
Timo Sirainen <tss@iki.fi>
parents: 7352
diff changeset
150 while (client->command_queue != NULL) {
33d8adcc2d44 client_command_free()/cancel(): Take pointer-to-pointer parameter and set it
Timo Sirainen <tss@iki.fi>
parents: 7352
diff changeset
151 cmd = client->command_queue;
33d8adcc2d44 client_command_free()/cancel(): Take pointer-to-pointer parameter and set it
Timo Sirainen <tss@iki.fi>
parents: 7352
diff changeset
152 client_command_cancel(&cmd);
33d8adcc2d44 client_command_free()/cancel(): Take pointer-to-pointer parameter and set it
Timo Sirainen <tss@iki.fi>
parents: 7352
diff changeset
153 }
7583
a99b9735f875 Don't try to call a cancelled command if it hasn't started running. Cancel
Timo Sirainen <tss@iki.fi>
parents: 7524
diff changeset
154 /* handle the input_lock command last. it might have been waiting on
a99b9735f875 Don't try to call a cancelled command if it hasn't started running. Cancel
Timo Sirainen <tss@iki.fi>
parents: 7524
diff changeset
155 other queued commands (although we probably should just drop the
a99b9735f875 Don't try to call a cancelled command if it hasn't started running. Cancel
Timo Sirainen <tss@iki.fi>
parents: 7524
diff changeset
156 command at that point since it hasn't started running. but this may
a99b9735f875 Don't try to call a cancelled command if it hasn't started running. Cancel
Timo Sirainen <tss@iki.fi>
parents: 7524
diff changeset
157 change in future). */
a99b9735f875 Don't try to call a cancelled command if it hasn't started running. Cancel
Timo Sirainen <tss@iki.fi>
parents: 7524
diff changeset
158 if (client->input_lock != NULL)
a99b9735f875 Don't try to call a cancelled command if it hasn't started running. Cancel
Timo Sirainen <tss@iki.fi>
parents: 7524
diff changeset
159 client_command_cancel(&client->input_lock);
2501
b7eec64e0735 Deinitialize command handlers always.
Timo Sirainen <tss@iki.fi>
parents: 2462
diff changeset
160
7647
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
161 if (client->mailbox != NULL) {
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
162 client_search_updates_free(client);
3879
928229f8b3e6 deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents: 3871
diff changeset
163 mailbox_close(&client->mailbox);
7647
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
164 }
8467
03c418eadc8b mail_user_*() now handles home directory lookups when necessary.
Timo Sirainen <tss@iki.fi>
parents: 8412
diff changeset
165 mail_user_unref(&client->user);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
166
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
167 if (client->free_parser != NULL)
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
168 imap_parser_destroy(&client->free_parser);
2421
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
169 if (client->io != NULL)
3879
928229f8b3e6 deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents: 3871
diff changeset
170 io_remove(&client->io);
7103
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
171 if (client->to_idle_output != NULL)
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
172 timeout_remove(&client->to_idle_output);
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
173 timeout_remove(&client->to_idle);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
174
4070
71b8faa84ec6 Added i_stream_destroy() and o_stream_destroy() and used them instead of
Timo Sirainen <tss@iki.fi>
parents: 3963
diff changeset
175 i_stream_destroy(&client->input);
71b8faa84ec6 Added i_stream_destroy() and o_stream_destroy() and used them instead of
Timo Sirainen <tss@iki.fi>
parents: 3963
diff changeset
176 o_stream_destroy(&client->output);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
177
3960
aeb424e64f24 Call io_remove() before closing the fd. It's required by kqueue.
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
178 if (close(client->fd_in) < 0)
aeb424e64f24 Call io_remove() before closing the fd. It's required by kqueue.
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
179 i_error("close(client in) failed: %m");
aeb424e64f24 Call io_remove() before closing the fd. It's required by kqueue.
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
180 if (client->fd_in != client->fd_out) {
aeb424e64f24 Call io_remove() before closing the fd. It's required by kqueue.
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
181 if (close(client->fd_out) < 0)
aeb424e64f24 Call io_remove() before closing the fd. It's required by kqueue.
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
182 i_error("close(client out) failed: %m");
aeb424e64f24 Call io_remove() before closing the fd. It's required by kqueue.
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
183 }
aeb424e64f24 Call io_remove() before closing the fd. It's required by kqueue.
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
184
7639
03146f02403f Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents: 7633
diff changeset
185 if (array_is_created(&client->search_saved_uidset))
03146f02403f Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents: 7633
diff changeset
186 array_free(&client->search_saved_uidset);
7647
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
187 if (array_is_created(&client->search_updates))
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
188 array_free(&client->search_updates);
6428
7cad076906eb pool_unref() now takes ** pointer.
Timo Sirainen <tss@iki.fi>
parents: 6418
diff changeset
189 pool_unref(&client->command_pool);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
190 i_free(client);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
191
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
192 /* quit the program */
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
193 my_client = NULL;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
194 io_loop_stop(ioloop);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
195 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
196
4096
904c53275e83 Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents: 4070
diff changeset
197 void client_disconnect(struct client *client, const char *reason)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
198 {
4291
c78bd7fb7ce8 Added assert against NULL reason for client_disconnect().
Timo Sirainen <tss@iki.fi>
parents: 4096
diff changeset
199 i_assert(reason != NULL);
c78bd7fb7ce8 Added assert against NULL reason for client_disconnect().
Timo Sirainen <tss@iki.fi>
parents: 4096
diff changeset
200
4096
904c53275e83 Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents: 4070
diff changeset
201 if (client->disconnected)
904c53275e83 Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents: 4070
diff changeset
202 return;
904c53275e83 Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents: 4070
diff changeset
203
5980
57b70f64f997 Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents: 5835
diff changeset
204 i_info("Disconnected: %s %s", reason, client_stats(client));
4096
904c53275e83 Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents: 4070
diff changeset
205 client->disconnected = TRUE;
2421
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
206 (void)o_stream_flush(client->output);
222
cf4d065f2f85 lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents: 184
diff changeset
207
764
f57c52738f90 Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents: 720
diff changeset
208 i_stream_close(client->input);
f57c52738f90 Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents: 720
diff changeset
209 o_stream_close(client->output);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
210 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
211
1023
dc660f588218 Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
212 void client_disconnect_with_error(struct client *client, const char *msg)
dc660f588218 Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
213 {
dc660f588218 Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
214 client_send_line(client, t_strconcat("* BYE ", msg, NULL));
4096
904c53275e83 Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents: 4070
diff changeset
215 client_disconnect(client, msg);
1023
dc660f588218 Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
216 }
dc660f588218 Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
217
2425
8267d11cacfb LIST command interrupts itself when output buffer gets full and continues
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
218 int client_send_line(struct client *client, const char *data)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
219 {
2425
8267d11cacfb LIST command interrupts itself when output buffer gets full and continues
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
220 struct const_iovec iov[2];
8267d11cacfb LIST command interrupts itself when output buffer gets full and continues
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
221
764
f57c52738f90 Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents: 720
diff changeset
222 if (client->output->closed)
2425
8267d11cacfb LIST command interrupts itself when output buffer gets full and continues
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
223 return -1;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
224
2425
8267d11cacfb LIST command interrupts itself when output buffer gets full and continues
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
225 iov[0].iov_base = data;
8267d11cacfb LIST command interrupts itself when output buffer gets full and continues
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
226 iov[0].iov_len = strlen(data);
8267d11cacfb LIST command interrupts itself when output buffer gets full and continues
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
227 iov[1].iov_base = "\r\n";
8267d11cacfb LIST command interrupts itself when output buffer gets full and continues
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
228 iov[1].iov_len = 2;
8267d11cacfb LIST command interrupts itself when output buffer gets full and continues
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
229
8267d11cacfb LIST command interrupts itself when output buffer gets full and continues
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
230 if (o_stream_sendv(client->output, iov, 2) < 0)
8267d11cacfb LIST command interrupts itself when output buffer gets full and continues
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
231 return -1;
5367
fab770c51321 Keep better track of client->last_output timestamp.
Timo Sirainen <tss@iki.fi>
parents: 5331
diff changeset
232 client->last_output = ioloop_time;
2425
8267d11cacfb LIST command interrupts itself when output buffer gets full and continues
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
233
3601
edc6e213048f client_send_line(): Try flushing output immediately if buffer gets full.
Timo Sirainen <tss@iki.fi>
parents: 3469
diff changeset
234 if (o_stream_get_buffer_used_size(client->output) >=
edc6e213048f client_send_line(): Try flushing output immediately if buffer gets full.
Timo Sirainen <tss@iki.fi>
parents: 3469
diff changeset
235 CLIENT_OUTPUT_OPTIMAL_SIZE) {
edc6e213048f client_send_line(): Try flushing output immediately if buffer gets full.
Timo Sirainen <tss@iki.fi>
parents: 3469
diff changeset
236 /* buffer full, try flushing */
edc6e213048f client_send_line(): Try flushing output immediately if buffer gets full.
Timo Sirainen <tss@iki.fi>
parents: 3469
diff changeset
237 return o_stream_flush(client->output);
edc6e213048f client_send_line(): Try flushing output immediately if buffer gets full.
Timo Sirainen <tss@iki.fi>
parents: 3469
diff changeset
238 }
edc6e213048f client_send_line(): Try flushing output immediately if buffer gets full.
Timo Sirainen <tss@iki.fi>
parents: 3469
diff changeset
239 return 1;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
240 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
241
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
242 void client_send_tagline(struct client_command_context *cmd, const char *data)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
243 {
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
244 struct client *client = cmd->client;
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
245 const char *tag = cmd->tag;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
246
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
247 if (client->output->closed || cmd->cancel)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
248 return;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
249
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
250 if (tag == NULL || *tag == '\0')
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
251 tag = "*";
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
252
807
35abd7a5d381 Buffer related cleanups. Use PATH_MAX instead of hardcoded 1024 for paths.
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
253 (void)o_stream_send_str(client->output, tag);
764
f57c52738f90 Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents: 720
diff changeset
254 (void)o_stream_send(client->output, " ", 1);
807
35abd7a5d381 Buffer related cleanups. Use PATH_MAX instead of hardcoded 1024 for paths.
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
255 (void)o_stream_send_str(client->output, data);
764
f57c52738f90 Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents: 720
diff changeset
256 (void)o_stream_send(client->output, "\r\n", 2);
5367
fab770c51321 Keep better track of client->last_output timestamp.
Timo Sirainen <tss@iki.fi>
parents: 5331
diff changeset
257
fab770c51321 Keep better track of client->last_output timestamp.
Timo Sirainen <tss@iki.fi>
parents: 5331
diff changeset
258 client->last_output = ioloop_time;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
259 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
260
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
261 void client_send_command_error(struct client_command_context *cmd,
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
262 const char *msg)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
263 {
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
264 struct client *client = cmd->client;
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
265 const char *error, *cmd_name;
3863
55df57c028d4 Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents: 3811
diff changeset
266 bool fatal;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
267
1023
dc660f588218 Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
268 if (msg == NULL) {
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
269 msg = imap_parser_get_error(cmd->parser, &fatal);
1023
dc660f588218 Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
270 if (fatal) {
dc660f588218 Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
271 client_disconnect_with_error(client, msg);
dc660f588218 Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
272 return;
dc660f588218 Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
273 }
dc660f588218 Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
274 }
1538
4d1c65eded2c Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents: 1499
diff changeset
275
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
276 if (cmd->tag == NULL)
1538
4d1c65eded2c Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents: 1499
diff changeset
277 error = t_strconcat("BAD Error in IMAP tag: ", msg, NULL);
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
278 else if (cmd->name == NULL)
1538
4d1c65eded2c Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents: 1499
diff changeset
279 error = t_strconcat("BAD Error in IMAP command: ", msg, NULL);
4d1c65eded2c Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents: 1499
diff changeset
280 else {
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
281 cmd_name = t_str_ucase(cmd->name);
1538
4d1c65eded2c Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents: 1499
diff changeset
282 error = t_strconcat("BAD Error in IMAP command ",
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
283 cmd_name, ": ", msg, NULL);
1538
4d1c65eded2c Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents: 1499
diff changeset
284 }
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
285
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
286 client_send_tagline(cmd, error);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
287
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
288 if (++client->bad_counter >= CLIENT_MAX_BAD_COMMANDS) {
1023
dc660f588218 Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
289 client_disconnect_with_error(client,
dc660f588218 Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
290 "Too many invalid IMAP commands.");
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
291 }
2508
467af814d5e2 Command parameter errors weren't handled right. This was broken a few
Timo Sirainen <tss@iki.fi>
parents: 2501
diff changeset
292
7148
5e3188213724 Added "command state" for running commands. Use it instead of some bitfields
Timo Sirainen <tss@iki.fi>
parents: 7142
diff changeset
293 cmd->param_error = TRUE;
2508
467af814d5e2 Command parameter errors weren't handled right. This was broken a few
Timo Sirainen <tss@iki.fi>
parents: 2501
diff changeset
294 /* client_read_args() failures rely on this being set, so that the
467af814d5e2 Command parameter errors weren't handled right. This was broken a few
Timo Sirainen <tss@iki.fi>
parents: 2501
diff changeset
295 command processing is stopped even while command function returns
467af814d5e2 Command parameter errors weren't handled right. This was broken a few
Timo Sirainen <tss@iki.fi>
parents: 2501
diff changeset
296 FALSE. */
7148
5e3188213724 Added "command state" for running commands. Use it instead of some bitfields
Timo Sirainen <tss@iki.fi>
parents: 7142
diff changeset
297 cmd->state = CLIENT_COMMAND_STATE_DONE;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
298 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
299
3863
55df57c028d4 Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents: 3811
diff changeset
300 bool client_read_args(struct client_command_context *cmd, unsigned int count,
5835
d59ed6a31b66 Added more consts to imap-parser API
Timo Sirainen <tss@iki.fi>
parents: 5812
diff changeset
301 unsigned int flags, const struct imap_arg **args_r)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
302 {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
303 int ret;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
304
1015
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 1001
diff changeset
305 i_assert(count <= INT_MAX);
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 1001
diff changeset
306
5835
d59ed6a31b66 Added more consts to imap-parser API
Timo Sirainen <tss@iki.fi>
parents: 5812
diff changeset
307 ret = imap_parser_read_args(cmd->parser, count, flags, args_r);
720
e0825139b0f1 Maybe now?
Timo Sirainen <tss@iki.fi>
parents: 717
diff changeset
308 if (ret >= (int)count) {
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
309 /* all parameters read successfully */
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
310 i_assert(cmd->client->input_lock == NULL ||
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
311 cmd->client->input_lock == cmd);
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
312 cmd->client->input_lock = NULL;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
313 return TRUE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
314 } else if (ret == -2) {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
315 /* need more data */
6179
5c6af3b74d5f If client disconnects in the middle of sending command parameters, don't
Timo Sirainen <tss@iki.fi>
parents: 6162
diff changeset
316 if (cmd->client->input->closed) {
5c6af3b74d5f If client disconnects in the middle of sending command parameters, don't
Timo Sirainen <tss@iki.fi>
parents: 6162
diff changeset
317 /* disconnected */
7148
5e3188213724 Added "command state" for running commands. Use it instead of some bitfields
Timo Sirainen <tss@iki.fi>
parents: 7142
diff changeset
318 cmd->state = CLIENT_COMMAND_STATE_DONE;
6179
5c6af3b74d5f If client disconnects in the middle of sending command parameters, don't
Timo Sirainen <tss@iki.fi>
parents: 6162
diff changeset
319 }
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
320 return FALSE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
321 } else {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
322 /* error, or missing arguments */
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
323 client_send_command_error(cmd, ret < 0 ? NULL :
769
f17a1f59ac3f Fixed "Missing arguments" error msg to work again
Timo Sirainen <tss@iki.fi>
parents: 768
diff changeset
324 "Missing arguments");
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
325 return FALSE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
326 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
327 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
328
3863
55df57c028d4 Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents: 3811
diff changeset
329 bool client_read_string_args(struct client_command_context *cmd,
55df57c028d4 Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents: 3811
diff changeset
330 unsigned int count, ...)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
331 {
5835
d59ed6a31b66 Added more consts to imap-parser API
Timo Sirainen <tss@iki.fi>
parents: 5812
diff changeset
332 const struct imap_arg *imap_args;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
333 va_list va;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
334 const char *str;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
335 unsigned int i;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
336
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
337 if (!client_read_args(cmd, count, 0, &imap_args))
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
338 return FALSE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
339
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
340 va_start(va, count);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
341 for (i = 0; i < count; i++) {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
342 const char **ret = va_arg(va, const char **);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
343
1015
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 1001
diff changeset
344 if (imap_args[i].type == IMAP_ARG_EOL) {
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
345 client_send_command_error(cmd, "Missing arguments.");
1015
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 1001
diff changeset
346 break;
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 1001
diff changeset
347 }
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 1001
diff changeset
348
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
349 str = imap_arg_string(&imap_args[i]);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
350 if (str == NULL) {
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
351 client_send_command_error(cmd, "Invalid arguments.");
1015
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 1001
diff changeset
352 break;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
353 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
354
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
355 if (ret != NULL)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
356 *ret = str;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
357 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
358 va_end(va);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
359
1015
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 1001
diff changeset
360 return i == count;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
361 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
362
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
363 static struct client_command_context *
4941
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
364 client_command_find_with_flags(struct client_command_context *new_cmd,
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
365 enum command_flags flags)
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
366 {
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
367 struct client_command_context *cmd;
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
368
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
369 cmd = new_cmd->client->command_queue;
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
370 for (; cmd != NULL; cmd = cmd->next) {
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
371 if (cmd != new_cmd && (cmd->cmd_flags & flags) != 0)
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
372 return cmd;
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
373 }
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
374 return NULL;
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
375 }
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
376
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
377 static bool client_command_check_ambiguity(struct client_command_context *cmd)
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
378 {
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
379 enum command_flags flags;
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
380 bool broken_client = FALSE;
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
381
7524
c4342385d696 If client tries to change the selected mailbox state while another command
Timo Sirainen <tss@iki.fi>
parents: 7431
diff changeset
382 if ((cmd->cmd_flags & COMMAND_FLAG_BREAKS_MAILBOX) ==
c4342385d696 If client tries to change the selected mailbox state while another command
Timo Sirainen <tss@iki.fi>
parents: 7431
diff changeset
383 COMMAND_FLAG_BREAKS_MAILBOX) {
c4342385d696 If client tries to change the selected mailbox state while another command
Timo Sirainen <tss@iki.fi>
parents: 7431
diff changeset
384 /* there must be no other command running that uses the
c4342385d696 If client tries to change the selected mailbox state while another command
Timo Sirainen <tss@iki.fi>
parents: 7431
diff changeset
385 selected mailbox */
c4342385d696 If client tries to change the selected mailbox state while another command
Timo Sirainen <tss@iki.fi>
parents: 7431
diff changeset
386 flags = COMMAND_FLAG_USES_MAILBOX;
c4342385d696 If client tries to change the selected mailbox state while another command
Timo Sirainen <tss@iki.fi>
parents: 7431
diff changeset
387 } else if ((cmd->cmd_flags & COMMAND_FLAG_USES_SEQS) != 0) {
4941
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
388 /* no existing command must be breaking sequences */
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
389 flags = COMMAND_FLAG_BREAKS_SEQS;
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
390 broken_client = TRUE;
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
391 } else if ((cmd->cmd_flags & COMMAND_FLAG_BREAKS_SEQS) != 0) {
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
392 /* if existing command uses sequences, we'll have to block */
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
393 flags = COMMAND_FLAG_USES_SEQS;
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
394 } else {
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
395 return FALSE;
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
396 }
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
397
5812
71176467310e Fixes to handling command ambiguity. Don't allow any commands that handle
Timo Sirainen <tss@iki.fi>
parents: 5805
diff changeset
398 if (client_command_find_with_flags(cmd, flags) == NULL) {
71176467310e Fixes to handling command ambiguity. Don't allow any commands that handle
Timo Sirainen <tss@iki.fi>
parents: 5805
diff changeset
399 if (cmd->client->syncing) {
71176467310e Fixes to handling command ambiguity. Don't allow any commands that handle
Timo Sirainen <tss@iki.fi>
parents: 5805
diff changeset
400 /* don't do anything until syncing is finished */
71176467310e Fixes to handling command ambiguity. Don't allow any commands that handle
Timo Sirainen <tss@iki.fi>
parents: 5805
diff changeset
401 return TRUE;
71176467310e Fixes to handling command ambiguity. Don't allow any commands that handle
Timo Sirainen <tss@iki.fi>
parents: 5805
diff changeset
402 }
7816
ea6727a1220e Changed the way mailbox changing ambiguity is checked.
Timo Sirainen <tss@iki.fi>
parents: 7798
diff changeset
403 if (cmd->client->mailbox_change_lock != NULL &&
ea6727a1220e Changed the way mailbox changing ambiguity is checked.
Timo Sirainen <tss@iki.fi>
parents: 7798
diff changeset
404 cmd->client->mailbox_change_lock != cmd) {
7632
6e2e4e5c52f3 Fixed CLOSE HIGEHSTMODSEQ race condition. Added some checks to make
Timo Sirainen <tss@iki.fi>
parents: 7620
diff changeset
405 /* don't do anything until mailbox is fully
6e2e4e5c52f3 Fixed CLOSE HIGEHSTMODSEQ race condition. Added some checks to make
Timo Sirainen <tss@iki.fi>
parents: 7620
diff changeset
406 opened/closed */
6e2e4e5c52f3 Fixed CLOSE HIGEHSTMODSEQ race condition. Added some checks to make
Timo Sirainen <tss@iki.fi>
parents: 7620
diff changeset
407 return TRUE;
6e2e4e5c52f3 Fixed CLOSE HIGEHSTMODSEQ race condition. Added some checks to make
Timo Sirainen <tss@iki.fi>
parents: 7620
diff changeset
408 }
4941
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
409 return FALSE;
5812
71176467310e Fixes to handling command ambiguity. Don't allow any commands that handle
Timo Sirainen <tss@iki.fi>
parents: 5805
diff changeset
410 }
4941
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
411
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
412 if (broken_client) {
8412
6e9100795d89 Moved imap-resp-codes to macros.
Timo Sirainen <tss@iki.fi>
parents: 8411
diff changeset
413 client_send_line(cmd->client,
6e9100795d89 Moved imap-resp-codes to macros.
Timo Sirainen <tss@iki.fi>
parents: 8411
diff changeset
414 "* BAD ["IMAP_RESP_CODE_CLIENTBUG"] "
8411
abd0ef855a33 Implemented imap-response-codes draft.
Timo Sirainen <tss@iki.fi>
parents: 8082
diff changeset
415 "Command pipelining results in ambiguity.");
4941
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
416 }
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
417
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
418 return TRUE;
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
419 }
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
420
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
421 static struct client_command_context *
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
422 client_command_new(struct client *client)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
423 {
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
424 struct client_command_context *cmd;
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
425
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
426 cmd = p_new(client->command_pool, struct client_command_context, 1);
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
427 cmd->client = client;
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
428 cmd->pool = client->command_pool;
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
429
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
430 if (client->free_parser != NULL) {
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
431 cmd->parser = client->free_parser;
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
432 client->free_parser = NULL;
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
433 } else {
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
434 cmd->parser = imap_parser_create(client->input, client->output,
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
435 imap_max_line_length);
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
436 }
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
437
7150
8a531386c856 Use linked list macros for command queue.
Timo Sirainen <tss@iki.fi>
parents: 7149
diff changeset
438 DLLIST_PREPEND(&client->command_queue, cmd);
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
439 client->command_queue_size++;
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
440
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
441 return cmd;
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
442 }
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
443
7431
33d8adcc2d44 client_command_free()/cancel(): Take pointer-to-pointer parameter and set it
Timo Sirainen <tss@iki.fi>
parents: 7352
diff changeset
444 void client_command_free(struct client_command_context **_cmd)
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
445 {
7431
33d8adcc2d44 client_command_free()/cancel(): Take pointer-to-pointer parameter and set it
Timo Sirainen <tss@iki.fi>
parents: 7352
diff changeset
446 struct client_command_context *cmd = *_cmd;
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
447 struct client *client = cmd->client;
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
448
7431
33d8adcc2d44 client_command_free()/cancel(): Take pointer-to-pointer parameter and set it
Timo Sirainen <tss@iki.fi>
parents: 7352
diff changeset
449 *_cmd = NULL;
33d8adcc2d44 client_command_free()/cancel(): Take pointer-to-pointer parameter and set it
Timo Sirainen <tss@iki.fi>
parents: 7352
diff changeset
450
2421
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
451 /* reset input idle time because command output might have taken a
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
452 long time and we don't want to disconnect client immediately then */
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
453 client->last_input = ioloop_time;
7103
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
454 timeout_reset(client->to_idle);
2421
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
455
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
456 if (cmd->cancel) {
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
457 cmd->cancel = FALSE;
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
458 client_send_tagline(cmd, "NO Command cancelled.");
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
459 }
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
460
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
461 if (!cmd->param_error)
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
462 client->bad_counter = 0;
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
463
5415
4ba74fec49a4 hang fix after appends
Timo Sirainen <tss@iki.fi>
parents: 5367
diff changeset
464 if (client->input_lock == cmd)
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
465 client->input_lock = NULL;
5415
4ba74fec49a4 hang fix after appends
Timo Sirainen <tss@iki.fi>
parents: 5367
diff changeset
466 if (client->output_lock == cmd)
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
467 client->output_lock = NULL;
7816
ea6727a1220e Changed the way mailbox changing ambiguity is checked.
Timo Sirainen <tss@iki.fi>
parents: 7798
diff changeset
468 if (client->mailbox_change_lock == cmd)
ea6727a1220e Changed the way mailbox changing ambiguity is checked.
Timo Sirainen <tss@iki.fi>
parents: 7798
diff changeset
469 client->mailbox_change_lock = NULL;
2421
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
470
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
471 if (client->free_parser != NULL)
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
472 imap_parser_destroy(&cmd->parser);
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
473 else {
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
474 imap_parser_reset(cmd->parser);
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
475 client->free_parser = cmd->parser;
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
476 }
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
477
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
478 client->command_queue_size--;
7150
8a531386c856 Use linked list macros for command queue.
Timo Sirainen <tss@iki.fi>
parents: 7149
diff changeset
479 DLLIST_REMOVE(&client->command_queue, cmd);
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
480 cmd = NULL;
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
481
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
482 if (client->command_queue == NULL) {
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
483 /* no commands left in the queue, we can clear the pool */
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
484 p_clear(client->command_pool);
7142
58cb2c6f90c7 "Disconnected for inactivity in reading our output" happened after a command
Timo Sirainen <tss@iki.fi>
parents: 7103
diff changeset
485 if (client->to_idle_output != NULL)
58cb2c6f90c7 "Disconnected for inactivity in reading our output" happened after a command
Timo Sirainen <tss@iki.fi>
parents: 7103
diff changeset
486 timeout_remove(&client->to_idle_output);
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
487 }
5110
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
488 }
3763
454863612b5c IDLE: Sending "DONE" + next command in same TCP packet caused the next command not to be executed until yet another command came (which usually didn't happen).
Timo Sirainen <tss@iki.fi>
parents: 3601
diff changeset
489
5114
7413b8e0d765 hangfix
Timo Sirainen <tss@iki.fi>
parents: 5110
diff changeset
490 static void client_add_missing_io(struct client *client)
7413b8e0d765 hangfix
Timo Sirainen <tss@iki.fi>
parents: 5110
diff changeset
491 {
5196
f1b735b905f3 assert-crashfix
Timo Sirainen <tss@iki.fi>
parents: 5115
diff changeset
492 if (client->io == NULL && !client->disconnected) {
f1b735b905f3 assert-crashfix
Timo Sirainen <tss@iki.fi>
parents: 5115
diff changeset
493 client->io = io_add(client->fd_in,
6418
46d9ee79f292 Removed _ prefix from all public APIs.
Timo Sirainen <tss@iki.fi>
parents: 6411
diff changeset
494 IO_READ, client_input, client);
5114
7413b8e0d765 hangfix
Timo Sirainen <tss@iki.fi>
parents: 5110
diff changeset
495 }
7413b8e0d765 hangfix
Timo Sirainen <tss@iki.fi>
parents: 5110
diff changeset
496 }
7413b8e0d765 hangfix
Timo Sirainen <tss@iki.fi>
parents: 5110
diff changeset
497
6531
d747bfbda43c Fixed process hanging sometimes when disconnecting.
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
498 void client_continue_pending_input(struct client **_client)
5110
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
499 {
6531
d747bfbda43c Fixed process hanging sometimes when disconnecting.
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
500 struct client *client = *_client;
5110
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
501 size_t size;
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
502
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
503 i_assert(!client->handling_input);
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
504
6531
d747bfbda43c Fixed process hanging sometimes when disconnecting.
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
505 if (client->disconnected) {
6570
86e964111b1f Don't assert-crash if client disconnects while IDLEing.
Timo Sirainen <tss@iki.fi>
parents: 6531
diff changeset
506 if (!client->destroyed)
86e964111b1f Don't assert-crash if client disconnects while IDLEing.
Timo Sirainen <tss@iki.fi>
parents: 6531
diff changeset
507 client_destroy(client, NULL);
6531
d747bfbda43c Fixed process hanging sometimes when disconnecting.
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
508 *_client = NULL;
5110
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
509 return;
6531
d747bfbda43c Fixed process hanging sometimes when disconnecting.
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
510 }
5110
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
511
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
512 if (client->input_lock != NULL) {
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
513 /* there's a command that has locked the input */
7149
323b425a0f46 Replaced waiting_ambiguity bitmask with a command state.
Timo Sirainen <tss@iki.fi>
parents: 7148
diff changeset
514 struct client_command_context *cmd = client->input_lock;
323b425a0f46 Replaced waiting_ambiguity bitmask with a command state.
Timo Sirainen <tss@iki.fi>
parents: 7148
diff changeset
515
323b425a0f46 Replaced waiting_ambiguity bitmask with a command state.
Timo Sirainen <tss@iki.fi>
parents: 7148
diff changeset
516 if (cmd->state != CLIENT_COMMAND_STATE_WAIT_UNAMBIGUITY)
5110
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
517 return;
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
518
5110
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
519 /* the command is waiting for existing ambiguity causing
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
520 commands to finish. */
7149
323b425a0f46 Replaced waiting_ambiguity bitmask with a command state.
Timo Sirainen <tss@iki.fi>
parents: 7148
diff changeset
521 if (client_command_check_ambiguity(cmd))
5110
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
522 return;
7149
323b425a0f46 Replaced waiting_ambiguity bitmask with a command state.
Timo Sirainen <tss@iki.fi>
parents: 7148
diff changeset
523 cmd->state = CLIENT_COMMAND_STATE_WAIT_INPUT;
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
524 }
5110
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
525
5114
7413b8e0d765 hangfix
Timo Sirainen <tss@iki.fi>
parents: 5110
diff changeset
526 client_add_missing_io(client);
5110
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
527
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
528 /* if there's unread data in buffer, handle it. */
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
529 (void)i_stream_get_data(client->input, &size);
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
530 if (size > 0)
7019
08a3ba5de497 If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
531 (void)client_handle_input(client);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
532 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
533
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
534 /* Skip incoming data until newline is found,
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
535 returns TRUE if newline was found. */
3863
55df57c028d4 Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents: 3811
diff changeset
536 static bool client_skip_line(struct client *client)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
537 {
410
1f0e7229ee58 Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents: 364
diff changeset
538 const unsigned char *data;
184
4223b9ed0c80 move size_t fixes
Timo Sirainen <tss@iki.fi>
parents: 164
diff changeset
539 size_t i, data_size;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
540
764
f57c52738f90 Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents: 720
diff changeset
541 data = i_stream_get_data(client->input, &data_size);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
542
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
543 for (i = 0; i < data_size; i++) {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
544 if (data[i] == '\n') {
764
f57c52738f90 Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents: 720
diff changeset
545 client->input_skip_line = FALSE;
1538
4d1c65eded2c Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents: 1499
diff changeset
546 i++;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
547 break;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
548 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
549 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
550
1538
4d1c65eded2c Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents: 1499
diff changeset
551 i_stream_skip(client->input, i);
764
f57c52738f90 Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents: 720
diff changeset
552 return !client->input_skip_line;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
553 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
554
7103
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
555 static void client_idle_output_timeout(struct client *client)
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
556 {
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
557 client_destroy(client,
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
558 "Disconnected for inactivity in reading our output");
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
559 }
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
560
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
561 bool client_handle_unfinished_cmd(struct client_command_context *cmd)
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
562 {
7195
bca55675d77c When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents: 7151
diff changeset
563 if (cmd->state == CLIENT_COMMAND_STATE_WAIT_INPUT) {
bca55675d77c When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents: 7151
diff changeset
564 /* need more input */
7103
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
565 return FALSE;
7195
bca55675d77c When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents: 7151
diff changeset
566 }
bca55675d77c When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents: 7151
diff changeset
567 if (cmd->state != CLIENT_COMMAND_STATE_WAIT_OUTPUT) {
bca55675d77c When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents: 7151
diff changeset
568 /* waiting for something */
bca55675d77c When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents: 7151
diff changeset
569 if (cmd->state == CLIENT_COMMAND_STATE_WAIT_SYNC) {
bca55675d77c When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents: 7151
diff changeset
570 /* this is mainly for APPEND. */
bca55675d77c When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents: 7151
diff changeset
571 client_add_missing_io(cmd->client);
bca55675d77c When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents: 7151
diff changeset
572 }
bca55675d77c When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents: 7151
diff changeset
573 return TRUE;
bca55675d77c When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents: 7151
diff changeset
574 }
7103
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
575
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
576 /* output is blocking, we can execute more commands */
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
577 o_stream_set_flush_pending(cmd->client->output, TRUE);
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
578 if (cmd->client->to_idle_output == NULL) {
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
579 /* disconnect sooner if client isn't reading our output */
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
580 cmd->client->to_idle_output =
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
581 timeout_add(CLIENT_OUTPUT_TIMEOUT_MSECS,
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
582 client_idle_output_timeout, cmd->client);
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
583 }
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
584 return TRUE;
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
585 }
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
586
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
587 static bool client_command_input(struct client_command_context *cmd)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
588 {
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
589 struct client *client = cmd->client;
7148
5e3188213724 Added "command state" for running commands. Use it instead of some bitfields
Timo Sirainen <tss@iki.fi>
parents: 7142
diff changeset
590 struct command *command;
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
591
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
592 if (cmd->func != NULL) {
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
593 /* command is being executed - continue it */
7148
5e3188213724 Added "command state" for running commands. Use it instead of some bitfields
Timo Sirainen <tss@iki.fi>
parents: 7142
diff changeset
594 if (cmd->func(cmd) || cmd->state == CLIENT_COMMAND_STATE_DONE) {
717
3f817df5eba4 Input parsing was a bit broken in some conditions. Mostly visible with
Timo Sirainen <tss@iki.fi>
parents: 674
diff changeset
595 /* command execution was finished */
7431
33d8adcc2d44 client_command_free()/cancel(): Take pointer-to-pointer parameter and set it
Timo Sirainen <tss@iki.fi>
parents: 7352
diff changeset
596 client_command_free(&cmd);
5114
7413b8e0d765 hangfix
Timo Sirainen <tss@iki.fi>
parents: 5110
diff changeset
597 client_add_missing_io(client);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
598 return TRUE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
599 }
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
600
7103
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
601 return client_handle_unfinished_cmd(cmd);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
602 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
603
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
604 if (cmd->tag == NULL) {
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
605 cmd->tag = imap_parser_read_word(cmd->parser);
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
606 if (cmd->tag == NULL)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
607 return FALSE; /* need more data */
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
608 cmd->tag = p_strdup(cmd->pool, cmd->tag);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
609 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
610
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
611 if (cmd->name == NULL) {
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
612 cmd->name = imap_parser_read_word(cmd->parser);
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
613 if (cmd->name == NULL)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
614 return FALSE; /* need more data */
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
615 cmd->name = p_strdup(cmd->pool, cmd->name);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
616 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
617
4941
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
618 client->input_skip_line = TRUE;
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
619
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
620 if (cmd->name == '\0') {
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
621 /* command not given - cmd_func is already NULL. */
7148
5e3188213724 Added "command state" for running commands. Use it instead of some bitfields
Timo Sirainen <tss@iki.fi>
parents: 7142
diff changeset
622 } else if ((command = command_find(cmd->name)) != NULL) {
5e3188213724 Added "command state" for running commands. Use it instead of some bitfields
Timo Sirainen <tss@iki.fi>
parents: 7142
diff changeset
623 cmd->func = command->func;
5e3188213724 Added "command state" for running commands. Use it instead of some bitfields
Timo Sirainen <tss@iki.fi>
parents: 7142
diff changeset
624 cmd->cmd_flags = command->flags;
5e3188213724 Added "command state" for running commands. Use it instead of some bitfields
Timo Sirainen <tss@iki.fi>
parents: 7142
diff changeset
625 if (client_command_check_ambiguity(cmd)) {
5e3188213724 Added "command state" for running commands. Use it instead of some bitfields
Timo Sirainen <tss@iki.fi>
parents: 7142
diff changeset
626 /* do nothing until existing commands are finished */
5e3188213724 Added "command state" for running commands. Use it instead of some bitfields
Timo Sirainen <tss@iki.fi>
parents: 7142
diff changeset
627 i_assert(cmd->state == CLIENT_COMMAND_STATE_WAIT_INPUT);
7149
323b425a0f46 Replaced waiting_ambiguity bitmask with a command state.
Timo Sirainen <tss@iki.fi>
parents: 7148
diff changeset
628 cmd->state = CLIENT_COMMAND_STATE_WAIT_UNAMBIGUITY;
7148
5e3188213724 Added "command state" for running commands. Use it instead of some bitfields
Timo Sirainen <tss@iki.fi>
parents: 7142
diff changeset
629 io_remove(&client->io);
5e3188213724 Added "command state" for running commands. Use it instead of some bitfields
Timo Sirainen <tss@iki.fi>
parents: 7142
diff changeset
630 return FALSE;
4941
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
631 }
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
632 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
633
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
634 if (cmd->func == NULL) {
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
635 /* unknown command */
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
636 client_send_command_error(cmd, "Unknown command.");
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
637 cmd->param_error = TRUE;
7431
33d8adcc2d44 client_command_free()/cancel(): Take pointer-to-pointer parameter and set it
Timo Sirainen <tss@iki.fi>
parents: 7352
diff changeset
638 client_command_free(&cmd);
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
639 return TRUE;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
640 } else {
4831
7e50162a378c Added asserts
Timo Sirainen <tss@iki.fi>
parents: 4787
diff changeset
641 i_assert(!client->disconnected);
7e50162a378c Added asserts
Timo Sirainen <tss@iki.fi>
parents: 4787
diff changeset
642
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
643 return client_command_input(cmd);
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
644 }
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
645 }
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
646
7195
bca55675d77c When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents: 7151
diff changeset
647 static bool client_handle_next_command(struct client *client, bool *remove_io_r)
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
648 {
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
649 size_t size;
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
650
7019
08a3ba5de497 If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
651 *remove_io_r = FALSE;
08a3ba5de497 If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
652
5812
71176467310e Fixes to handling command ambiguity. Don't allow any commands that handle
Timo Sirainen <tss@iki.fi>
parents: 5805
diff changeset
653 if (client->input_lock != NULL) {
7149
323b425a0f46 Replaced waiting_ambiguity bitmask with a command state.
Timo Sirainen <tss@iki.fi>
parents: 7148
diff changeset
654 if (client->input_lock->state ==
323b425a0f46 Replaced waiting_ambiguity bitmask with a command state.
Timo Sirainen <tss@iki.fi>
parents: 7148
diff changeset
655 CLIENT_COMMAND_STATE_WAIT_UNAMBIGUITY) {
7019
08a3ba5de497 If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
656 *remove_io_r = TRUE;
5812
71176467310e Fixes to handling command ambiguity. Don't allow any commands that handle
Timo Sirainen <tss@iki.fi>
parents: 5805
diff changeset
657 return FALSE;
7019
08a3ba5de497 If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
658 }
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
659 return client_command_input(client->input_lock);
5812
71176467310e Fixes to handling command ambiguity. Don't allow any commands that handle
Timo Sirainen <tss@iki.fi>
parents: 5805
diff changeset
660 }
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
661
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
662 if (client->input_skip_line) {
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
663 /* first eat the previous command line */
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
664 if (!client_skip_line(client))
1172
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents: 1168
diff changeset
665 return FALSE;
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
666 client->input_skip_line = FALSE;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
667 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
668
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
669 /* don't bother creating a new client command before there's at least
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
670 some input */
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
671 (void)i_stream_get_data(client->input, &size);
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
672 if (size == 0)
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
673 return FALSE;
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
674
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
675 /* beginning a new command */
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
676 if (client->command_queue_size >= CLIENT_COMMAND_QUEUE_MAX_SIZE ||
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
677 client->output_lock != NULL) {
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
678 /* wait for some of the commands to finish */
7019
08a3ba5de497 If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
679 *remove_io_r = TRUE;
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
680 return FALSE;
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
681 }
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
682
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
683 client->input_lock = client_command_new(client);
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
684 return client_command_input(client->input_lock);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
685 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
686
7927
2351a81ce699 If commands are pipelined after the login command, pass them to the
Timo Sirainen <tss@iki.fi>
parents: 7816
diff changeset
687 bool client_handle_input(struct client *client)
7019
08a3ba5de497 If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
688 {
08a3ba5de497 If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
689 bool ret, remove_io, handled_commands = FALSE;
08a3ba5de497 If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
690
08a3ba5de497 If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
691 client->handling_input = TRUE;
08a3ba5de497 If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
692 do {
7226
e6693a0ec8e1 Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents: 7195
diff changeset
693 T_BEGIN {
7019
08a3ba5de497 If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
694 ret = client_handle_next_command(client, &remove_io);
7226
e6693a0ec8e1 Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents: 7195
diff changeset
695 } T_END;
7019
08a3ba5de497 If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
696 if (ret)
08a3ba5de497 If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
697 handled_commands = TRUE;
7195
bca55675d77c When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents: 7151
diff changeset
698 } while (ret && !client->disconnected && client->io != NULL);
7019
08a3ba5de497 If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
699 client->handling_input = FALSE;
08a3ba5de497 If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
700
08a3ba5de497 If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
701 if (client->output->closed) {
08a3ba5de497 If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
702 client_destroy(client, NULL);
08a3ba5de497 If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
703 return TRUE;
08a3ba5de497 If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
704 } else {
08a3ba5de497 If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
705 if (remove_io)
08a3ba5de497 If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
706 io_remove(&client->io);
08a3ba5de497 If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
707 else
08a3ba5de497 If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
708 client_add_missing_io(client);
7195
bca55675d77c When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents: 7151
diff changeset
709 if (!handled_commands)
bca55675d77c When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents: 7151
diff changeset
710 return FALSE;
bca55675d77c When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents: 7151
diff changeset
711
bca55675d77c When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents: 7151
diff changeset
712 ret = cmd_sync_delayed(client);
bca55675d77c When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents: 7151
diff changeset
713 if (ret)
bca55675d77c When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents: 7151
diff changeset
714 client_continue_pending_input(&client);
bca55675d77c When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents: 7151
diff changeset
715 return TRUE;
7019
08a3ba5de497 If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
716 }
08a3ba5de497 If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
717 }
08a3ba5de497 If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
718
6418
46d9ee79f292 Removed _ prefix from all public APIs.
Timo Sirainen <tss@iki.fi>
parents: 6411
diff changeset
719 void client_input(struct client *client)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
720 {
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
721 struct client_command_context *cmd;
7195
bca55675d77c When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents: 7151
diff changeset
722 struct ostream *output = client->output;
7019
08a3ba5de497 If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
723 ssize_t bytes;
953
411006be3c66 Naming change for function typedefs.
Timo Sirainen <tss@iki.fi>
parents: 903
diff changeset
724
5114
7413b8e0d765 hangfix
Timo Sirainen <tss@iki.fi>
parents: 5110
diff changeset
725 i_assert(client->io != NULL);
7413b8e0d765 hangfix
Timo Sirainen <tss@iki.fi>
parents: 5110
diff changeset
726
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
727 client->last_input = ioloop_time;
7103
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
728 timeout_reset(client->to_idle);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
729
7019
08a3ba5de497 If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
730 bytes = i_stream_read(client->input);
08a3ba5de497 If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
731 if (bytes == -1) {
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
732 /* disconnected */
4096
904c53275e83 Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents: 4070
diff changeset
733 client_destroy(client, NULL);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
734 return;
7019
08a3ba5de497 If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
735 }
08a3ba5de497 If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
736
7195
bca55675d77c When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents: 7151
diff changeset
737 o_stream_ref(output);
bca55675d77c When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents: 7151
diff changeset
738 o_stream_cork(output);
7019
08a3ba5de497 If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents: 6940
diff changeset
739 if (!client_handle_input(client) && bytes == -2) {
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
740 /* parameter word is longer than max. input buffer size.
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
741 this is most likely an error, so skip the new data
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
742 until newline is found. */
764
f57c52738f90 Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents: 720
diff changeset
743 client->input_skip_line = TRUE;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
744
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
745 cmd = client->input_lock != NULL ? client->input_lock :
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
746 client_command_new(client);
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
747 cmd->param_error = TRUE;
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
748 client_send_command_error(cmd, "Too long argument.");
7431
33d8adcc2d44 client_command_free()/cancel(): Take pointer-to-pointer parameter and set it
Timo Sirainen <tss@iki.fi>
parents: 7352
diff changeset
749 client_command_free(&cmd);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
750 }
7195
bca55675d77c When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents: 7151
diff changeset
751 o_stream_uncork(output);
bca55675d77c When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents: 7151
diff changeset
752 o_stream_unref(&output);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
753 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
754
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
755 static void client_output_cmd(struct client_command_context *cmd)
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
756 {
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
757 bool finished;
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
758
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
759 /* continue processing command */
7148
5e3188213724 Added "command state" for running commands. Use it instead of some bitfields
Timo Sirainen <tss@iki.fi>
parents: 7142
diff changeset
760 finished = cmd->func(cmd) || cmd->state == CLIENT_COMMAND_STATE_DONE;
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
761
7103
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
762 if (!finished)
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
763 (void)client_handle_unfinished_cmd(cmd);
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
764 else {
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
765 /* command execution was finished */
7431
33d8adcc2d44 client_command_free()/cancel(): Take pointer-to-pointer parameter and set it
Timo Sirainen <tss@iki.fi>
parents: 7352
diff changeset
766 client_command_free(&cmd);
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
767 }
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
768 }
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
769
6418
46d9ee79f292 Removed _ prefix from all public APIs.
Timo Sirainen <tss@iki.fi>
parents: 6411
diff changeset
770 int client_output(struct client *client)
2421
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
771 {
7151
2ced9dd8b2cc Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents: 7150
diff changeset
772 struct client_command_context *cmd;
3863
55df57c028d4 Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents: 3811
diff changeset
773 int ret;
2421
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
774
5110
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
775 i_assert(!client->destroyed);
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
776
2421
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
777 client->last_output = ioloop_time;
7103
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
778 timeout_reset(client->to_idle);
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
779 if (client->to_idle_output != NULL)
284dd5f2777d Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
780 timeout_reset(client->to_idle_output);
2421
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
781
2790
02c0b8d532c2 Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents: 2640
diff changeset
782 if ((ret = o_stream_flush(client->output)) < 0) {
4096
904c53275e83 Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents: 4070
diff changeset
783 client_destroy(client, NULL);
2790
02c0b8d532c2 Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents: 2640
diff changeset
784 return 1;
02c0b8d532c2 Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents: 2640
diff changeset
785 }
02c0b8d532c2 Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents: 2640
diff changeset
786
7151
2ced9dd8b2cc Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents: 7150
diff changeset
787 /* mark all commands non-executed */
2ced9dd8b2cc Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents: 7150
diff changeset
788 for (cmd = client->command_queue; cmd != NULL; cmd = cmd->next)
2ced9dd8b2cc Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents: 7150
diff changeset
789 cmd->temp_executed = FALSE;
2ced9dd8b2cc Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents: 7150
diff changeset
790
2790
02c0b8d532c2 Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents: 2640
diff changeset
791 o_stream_cork(client->output);
7151
2ced9dd8b2cc Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents: 7150
diff changeset
792 if (client->output_lock != NULL) {
2ced9dd8b2cc Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents: 7150
diff changeset
793 client->output_lock->temp_executed = TRUE;
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
794 client_output_cmd(client->output_lock);
7151
2ced9dd8b2cc Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents: 7150
diff changeset
795 }
2ced9dd8b2cc Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents: 7150
diff changeset
796 while (client->output_lock == NULL) {
2ced9dd8b2cc Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents: 7150
diff changeset
797 /* go through the entire commands list every time in case
2ced9dd8b2cc Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents: 7150
diff changeset
798 multiple commands were freed. temp_executed keeps track of
2ced9dd8b2cc Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents: 7150
diff changeset
799 which messages we've called so far */
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
800 cmd = client->command_queue;
7151
2ced9dd8b2cc Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents: 7150
diff changeset
801 for (; cmd != NULL; cmd = cmd->next) {
2ced9dd8b2cc Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents: 7150
diff changeset
802 if (!cmd->temp_executed &&
2ced9dd8b2cc Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents: 7150
diff changeset
803 cmd->state == CLIENT_COMMAND_STATE_WAIT_OUTPUT) {
2ced9dd8b2cc Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents: 7150
diff changeset
804 cmd->temp_executed = TRUE;
5812
71176467310e Fixes to handling command ambiguity. Don't allow any commands that handle
Timo Sirainen <tss@iki.fi>
parents: 5805
diff changeset
805 client_output_cmd(cmd);
7151
2ced9dd8b2cc Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents: 7150
diff changeset
806 break;
5812
71176467310e Fixes to handling command ambiguity. Don't allow any commands that handle
Timo Sirainen <tss@iki.fi>
parents: 5805
diff changeset
807 }
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
808 }
7151
2ced9dd8b2cc Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents: 7150
diff changeset
809 if (cmd == NULL) {
2ced9dd8b2cc Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents: 7150
diff changeset
810 /* all commands executed */
2ced9dd8b2cc Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents: 7150
diff changeset
811 break;
2ced9dd8b2cc Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents: 7150
diff changeset
812 }
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
813 }
5110
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
814
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
815 if (client->output->closed) {
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
816 client_destroy(client, NULL);
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
817 return 1;
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
818 } else {
7195
bca55675d77c When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents: 7151
diff changeset
819 (void)cmd_sync_delayed(client);
7352
4f63124e756e uncork stream only after syncing to avoid extra writes.
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
820 o_stream_uncork(client->output);
6531
d747bfbda43c Fixed process hanging sometimes when disconnecting.
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
821 client_continue_pending_input(&client);
7352
4f63124e756e uncork stream only after syncing to avoid extra writes.
Timo Sirainen <tss@iki.fi>
parents: 7226
diff changeset
822 return ret;
5110
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
823 }
2421
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
824 }
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
825
7639
03146f02403f Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents: 7633
diff changeset
826 bool client_handle_search_save_ambiguity(struct client_command_context *cmd)
03146f02403f Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents: 7633
diff changeset
827 {
03146f02403f Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents: 7633
diff changeset
828 struct client_command_context *old_cmd = cmd->next;
03146f02403f Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents: 7633
diff changeset
829
03146f02403f Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents: 7633
diff changeset
830 /* search only commands that were added before this command
03146f02403f Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents: 7633
diff changeset
831 (commands are prepended to the queue, so they're after ourself) */
03146f02403f Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents: 7633
diff changeset
832 for (; old_cmd != NULL; old_cmd = old_cmd->next) {
03146f02403f Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents: 7633
diff changeset
833 if (old_cmd->search_save_result)
03146f02403f Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents: 7633
diff changeset
834 break;
03146f02403f Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents: 7633
diff changeset
835 }
03146f02403f Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents: 7633
diff changeset
836 if (old_cmd == NULL)
03146f02403f Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents: 7633
diff changeset
837 return FALSE;
03146f02403f Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents: 7633
diff changeset
838
03146f02403f Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents: 7633
diff changeset
839 /* ambiguity, wait until it's over */
03146f02403f Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents: 7633
diff changeset
840 i_assert(cmd->state == CLIENT_COMMAND_STATE_WAIT_INPUT);
03146f02403f Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents: 7633
diff changeset
841 cmd->client->input_lock = cmd;
03146f02403f Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents: 7633
diff changeset
842 cmd->state = CLIENT_COMMAND_STATE_WAIT_UNAMBIGUITY;
03146f02403f Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents: 7633
diff changeset
843 io_remove(&cmd->client->io);
03146f02403f Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents: 7633
diff changeset
844 return TRUE;
03146f02403f Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents: 7633
diff changeset
845 }
03146f02403f Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents: 7633
diff changeset
846
7620
4b8c1c164d8f Initial CONDSTORE support.
Timo Sirainen <tss@iki.fi>
parents: 7352
diff changeset
847 void client_enable(struct client *client, enum mailbox_feature features)
4b8c1c164d8f Initial CONDSTORE support.
Timo Sirainen <tss@iki.fi>
parents: 7352
diff changeset
848 {
7633
27a0de620b0c If CONDSTORE is enabled only after mailbox has been selected, send
Timo Sirainen <tss@iki.fi>
parents: 7632
diff changeset
849 struct mailbox_status status;
27a0de620b0c If CONDSTORE is enabled only after mailbox has been selected, send
Timo Sirainen <tss@iki.fi>
parents: 7632
diff changeset
850
27a0de620b0c If CONDSTORE is enabled only after mailbox has been selected, send
Timo Sirainen <tss@iki.fi>
parents: 7632
diff changeset
851 if ((client->enabled_features & features) == features)
27a0de620b0c If CONDSTORE is enabled only after mailbox has been selected, send
Timo Sirainen <tss@iki.fi>
parents: 7632
diff changeset
852 return;
27a0de620b0c If CONDSTORE is enabled only after mailbox has been selected, send
Timo Sirainen <tss@iki.fi>
parents: 7632
diff changeset
853
7620
4b8c1c164d8f Initial CONDSTORE support.
Timo Sirainen <tss@iki.fi>
parents: 7352
diff changeset
854 client->enabled_features |= features;
7633
27a0de620b0c If CONDSTORE is enabled only after mailbox has been selected, send
Timo Sirainen <tss@iki.fi>
parents: 7632
diff changeset
855 if (client->mailbox == NULL)
27a0de620b0c If CONDSTORE is enabled only after mailbox has been selected, send
Timo Sirainen <tss@iki.fi>
parents: 7632
diff changeset
856 return;
27a0de620b0c If CONDSTORE is enabled only after mailbox has been selected, send
Timo Sirainen <tss@iki.fi>
parents: 7632
diff changeset
857
27a0de620b0c If CONDSTORE is enabled only after mailbox has been selected, send
Timo Sirainen <tss@iki.fi>
parents: 7632
diff changeset
858 mailbox_enable(client->mailbox, features);
27a0de620b0c If CONDSTORE is enabled only after mailbox has been selected, send
Timo Sirainen <tss@iki.fi>
parents: 7632
diff changeset
859 if ((features & MAILBOX_FEATURE_CONDSTORE) != 0) {
27a0de620b0c If CONDSTORE is enabled only after mailbox has been selected, send
Timo Sirainen <tss@iki.fi>
parents: 7632
diff changeset
860 /* CONDSTORE being enabled while mailbox is selected.
27a0de620b0c If CONDSTORE is enabled only after mailbox has been selected, send
Timo Sirainen <tss@iki.fi>
parents: 7632
diff changeset
861 Notify client of the latest HIGHESTMODSEQ. */
27a0de620b0c If CONDSTORE is enabled only after mailbox has been selected, send
Timo Sirainen <tss@iki.fi>
parents: 7632
diff changeset
862 mailbox_get_status(client->mailbox,
27a0de620b0c If CONDSTORE is enabled only after mailbox has been selected, send
Timo Sirainen <tss@iki.fi>
parents: 7632
diff changeset
863 STATUS_HIGHESTMODSEQ, &status);
27a0de620b0c If CONDSTORE is enabled only after mailbox has been selected, send
Timo Sirainen <tss@iki.fi>
parents: 7632
diff changeset
864 client_send_line(client, t_strdup_printf(
27a0de620b0c If CONDSTORE is enabled only after mailbox has been selected, send
Timo Sirainen <tss@iki.fi>
parents: 7632
diff changeset
865 "* OK [HIGHESTMODSEQ %llu]",
27a0de620b0c If CONDSTORE is enabled only after mailbox has been selected, send
Timo Sirainen <tss@iki.fi>
parents: 7632
diff changeset
866 (unsigned long long)status.highest_modseq));
27a0de620b0c If CONDSTORE is enabled only after mailbox has been selected, send
Timo Sirainen <tss@iki.fi>
parents: 7632
diff changeset
867 }
7620
4b8c1c164d8f Initial CONDSTORE support.
Timo Sirainen <tss@iki.fi>
parents: 7352
diff changeset
868 }
4b8c1c164d8f Initial CONDSTORE support.
Timo Sirainen <tss@iki.fi>
parents: 7352
diff changeset
869
7647
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
870 struct imap_search_update *
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
871 client_search_update_lookup(struct client *client, const char *tag,
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
872 unsigned int *idx_r)
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
873 {
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
874 struct imap_search_update *updates;
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
875 unsigned int i, count;
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
876
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
877 if (!array_is_created(&client->search_updates))
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
878 return NULL;
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
879
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
880 updates = array_get_modifiable(&client->search_updates, &count);
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
881 for (i = 0; i < count; i++) {
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
882 if (strcmp(updates[i].tag, tag) == 0) {
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
883 *idx_r = i;
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
884 return &updates[i];
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
885 }
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
886 }
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
887 return NULL;
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
888 }
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
889
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
890 void client_search_updates_free(struct client *client)
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
891 {
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
892 struct imap_search_update *updates;
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
893 unsigned int i, count;
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
894
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
895 if (!array_is_created(&client->search_updates))
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
896 return;
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
897
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
898 updates = array_get_modifiable(&client->search_updates, &count);
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
899 for (i = 0; i < count; i++) {
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
900 i_free(updates[i].tag);
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
901 mailbox_search_result_free(&updates[i].result);
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
902 }
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
903 array_clear(&client->search_updates);
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
904 }
879208fdc7e3 Implemented CONTEXT=SEARCH extension.
Timo Sirainen <tss@iki.fi>
parents: 7639
diff changeset
905
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
906 void clients_init(void)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
907 {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
908 my_client = NULL;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
909 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
910
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
911 void clients_deinit(void)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
912 {
158
a1204e882bc7 Flush output buffer to client at exit, and send a nice "BYE Server shutting
Timo Sirainen <tss@iki.fi>
parents: 10
diff changeset
913 if (my_client != NULL) {
a1204e882bc7 Flush output buffer to client at exit, and send a nice "BYE Server shutting
Timo Sirainen <tss@iki.fi>
parents: 10
diff changeset
914 client_send_line(my_client, "* BYE Server shutting down.");
4096
904c53275e83 Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents: 4070
diff changeset
915 client_destroy(my_client, "Server shutting down");
158
a1204e882bc7 Flush output buffer to client at exit, and send a nice "BYE Server shutting
Timo Sirainen <tss@iki.fi>
parents: 10
diff changeset
916 }
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
917 }