Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/imap/client.c @ 7639:03146f02403f HEAD
Implemented SEARCHRES extension.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 16 Mar 2008 11:05:53 +0200 |
parents | 27a0de620b0c |
children | 879208fdc7e3 |
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 | 2 |
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" |
0 | 11 #include "commands.h" |
5500
4862cb37106c
Moved namespace handling to lib-storage. Beginnings of namespace support for
Timo Sirainen <tss@iki.fi>
parents:
5415
diff
changeset
|
12 #include "mail-namespace.h" |
0 | 13 |
14 #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
|
15 #include <unistd.h> |
0 | 16 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
17 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
|
18 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
19 static struct client *my_client; /* we don't need more than one currently */ |
0 | 20 |
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
|
21 static bool client_handle_input(struct client *client); |
08a3ba5de497
If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents:
6940
diff
changeset
|
22 |
7103
284dd5f2777d
Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
23 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
|
24 { |
284dd5f2777d
Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
25 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
|
26 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
|
27 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
|
28 } |
284dd5f2777d
Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
29 |
3960
aeb424e64f24
Call io_remove() before closing the fd. It's required by kqueue.
Timo Sirainen <tss@iki.fi>
parents:
3879
diff
changeset
|
30 struct client *client_create(int fd_in, int fd_out, |
5500
4862cb37106c
Moved namespace handling to lib-storage. Beginnings of namespace support for
Timo Sirainen <tss@iki.fi>
parents:
5415
diff
changeset
|
31 struct mail_namespace *namespaces) |
0 | 32 { |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
33 struct client *client; |
0 | 34 |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2058
diff
changeset
|
35 /* 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
|
36 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
|
37 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
|
38 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
39 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
|
40 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
|
41 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
|
42 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
|
43 client->output = o_stream_create_fd(fd_out, (size_t)-1, FALSE); |
0 | 44 |
6418
46d9ee79f292
Removed _ prefix from all public APIs.
Timo Sirainen <tss@iki.fi>
parents:
6411
diff
changeset
|
45 o_stream_set_flush_callback(client->output, client_output, client); |
0 | 46 |
6418
46d9ee79f292
Removed _ prefix from all public APIs.
Timo Sirainen <tss@iki.fi>
parents:
6411
diff
changeset
|
47 client->io = io_add(fd_in, IO_READ, client_input, client); |
0 | 48 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
|
49 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
|
50 client_idle_timeout, client); |
0 | 51 |
7195
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
52 client->command_pool = pool_alloconly_create("client command", 1024*12); |
1654
31c4bb26a1e9
Getting ready for namespaces. LIST is still broken with them.
Timo Sirainen <tss@iki.fi>
parents:
1643
diff
changeset
|
53 client->namespaces = namespaces; |
31c4bb26a1e9
Getting ready for namespaces. LIST is still broken with them.
Timo Sirainen <tss@iki.fi>
parents:
1643
diff
changeset
|
54 |
31c4bb26a1e9
Getting ready for namespaces. LIST is still broken with them.
Timo Sirainen <tss@iki.fi>
parents:
1643
diff
changeset
|
55 while (namespaces != NULL) { |
1915
79790750c349
importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
1654
diff
changeset
|
56 mail_storage_set_callbacks(namespaces->storage, |
79790750c349
importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
1654
diff
changeset
|
57 &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
|
58 namespaces = namespaces->next; |
31c4bb26a1e9
Getting ready for namespaces. LIST is still broken with them.
Timo Sirainen <tss@iki.fi>
parents:
1643
diff
changeset
|
59 } |
0 | 60 |
61 i_assert(my_client == NULL); | |
62 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
|
63 |
6498f3cb9d2c
Added hook_client_created and hook_mail_storage_created for modules.
Timo Sirainen <tss@iki.fi>
parents:
1591
diff
changeset
|
64 if (hook_client_created != NULL) |
1643 | 65 hook_client_created(&client); |
0 | 66 return client; |
67 } | |
68 | |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
69 void client_command_cancel(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
|
70 { |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
71 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
|
72 |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
73 cmd->cancel = TRUE; |
5115
0c89a2f72f86
Don't crash if client disconnects in the middle of sending a command line.
Timo Sirainen <tss@iki.fi>
parents:
5114
diff
changeset
|
74 cmd_ret = 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
|
75 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
|
76 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
|
77 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
|
78 } else { |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
79 client_command_free(cmd); |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
80 } |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
81 } |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
82 |
5980
57b70f64f997
Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
83 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
|
84 { |
57b70f64f997
Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
85 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
|
86 { 'i', NULL }, |
57b70f64f997
Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
87 { 'o', NULL }, |
57b70f64f997
Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
88 { '\0', NULL } |
57b70f64f997
Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
89 }; |
57b70f64f997
Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
90 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
|
91 string_t *str; |
57b70f64f997
Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
92 |
57b70f64f997
Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
93 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
|
94 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
|
95 |
57b70f64f997
Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
96 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
|
97 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
|
98 |
57b70f64f997
Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
99 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
|
100 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
|
101 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
|
102 } |
57b70f64f997
Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
103 |
6309
f8c9b1a93521
If read/write to client failed with some error, log it.
Timo Sirainen <tss@iki.fi>
parents:
6210
diff
changeset
|
104 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
|
105 { |
f8c9b1a93521
If read/write to client failed with some error, log it.
Timo Sirainen <tss@iki.fi>
parents:
6210
diff
changeset
|
106 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
|
107 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
|
108 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
|
109 return errno == 0 || errno == EPIPE ? "Connection closed" : |
6310
15e10065a472
Changed disconnection reason to "Connection closed"
Timo Sirainen <tss@iki.fi>
parents:
6309
diff
changeset
|
110 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
|
111 } |
f8c9b1a93521
If read/write to client failed with some error, log it.
Timo Sirainen <tss@iki.fi>
parents:
6210
diff
changeset
|
112 |
4096
904c53275e83
Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents:
4070
diff
changeset
|
113 void client_destroy(struct client *client, const char *reason) |
0 | 114 { |
3871
2506e4077e7a
Don't crash if closing with signal while IDLEing.
Timo Sirainen <tss@iki.fi>
parents:
3866
diff
changeset
|
115 i_assert(!client->destroyed); |
2506e4077e7a
Don't crash if closing with signal while IDLEing.
Timo Sirainen <tss@iki.fi>
parents:
3866
diff
changeset
|
116 client->destroyed = TRUE; |
2506e4077e7a
Don't crash if closing with signal while IDLEing.
Timo Sirainen <tss@iki.fi>
parents:
3866
diff
changeset
|
117 |
4096
904c53275e83
Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents:
4070
diff
changeset
|
118 if (!client->disconnected) { |
4787
62f534a0fd68
Don't crash if client disconnected while IDLEing.
Timo Sirainen <tss@iki.fi>
parents:
4773
diff
changeset
|
119 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
|
120 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
|
121 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
|
122 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
|
123 } |
904c53275e83
Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents:
4070
diff
changeset
|
124 |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
125 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
|
126 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
|
127 |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
128 /* 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
|
129 if (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
|
130 client_command_cancel(client->output_lock); |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
131 if (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
|
132 client_command_cancel(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
|
133 while (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
|
134 client_command_cancel(client->command_queue); |
2501
b7eec64e0735
Deinitialize command handlers always.
Timo Sirainen <tss@iki.fi>
parents:
2462
diff
changeset
|
135 |
0 | 136 if (client->mailbox != NULL) |
3879
928229f8b3e6
deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents:
3871
diff
changeset
|
137 mailbox_close(&client->mailbox); |
5500
4862cb37106c
Moved namespace handling to lib-storage. Beginnings of namespace support for
Timo Sirainen <tss@iki.fi>
parents:
5415
diff
changeset
|
138 mail_namespaces_deinit(&client->namespaces); |
0 | 139 |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
140 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
|
141 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
|
142 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
|
143 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
|
144 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
|
145 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
|
146 timeout_remove(&client->to_idle); |
0 | 147 |
4070
71b8faa84ec6
Added i_stream_destroy() and o_stream_destroy() and used them instead of
Timo Sirainen <tss@iki.fi>
parents:
3963
diff
changeset
|
148 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
|
149 o_stream_destroy(&client->output); |
0 | 150 |
3960
aeb424e64f24
Call io_remove() before closing the fd. It's required by kqueue.
Timo Sirainen <tss@iki.fi>
parents:
3879
diff
changeset
|
151 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
|
152 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
|
153 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
|
154 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
|
155 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
|
156 } |
aeb424e64f24
Call io_remove() before closing the fd. It's required by kqueue.
Timo Sirainen <tss@iki.fi>
parents:
3879
diff
changeset
|
157 |
7639
03146f02403f
Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents:
7633
diff
changeset
|
158 if (array_is_created(&client->search_saved_uidset)) |
03146f02403f
Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents:
7633
diff
changeset
|
159 array_free(&client->search_saved_uidset); |
6428
7cad076906eb
pool_unref() now takes ** pointer.
Timo Sirainen <tss@iki.fi>
parents:
6418
diff
changeset
|
160 pool_unref(&client->command_pool); |
0 | 161 i_free(client); |
162 | |
163 /* quit the program */ | |
164 my_client = NULL; | |
165 io_loop_stop(ioloop); | |
166 } | |
167 | |
4096
904c53275e83
Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents:
4070
diff
changeset
|
168 void client_disconnect(struct client *client, const char *reason) |
0 | 169 { |
4291
c78bd7fb7ce8
Added assert against NULL reason for client_disconnect().
Timo Sirainen <tss@iki.fi>
parents:
4096
diff
changeset
|
170 i_assert(reason != NULL); |
c78bd7fb7ce8
Added assert against NULL reason for client_disconnect().
Timo Sirainen <tss@iki.fi>
parents:
4096
diff
changeset
|
171 |
4096
904c53275e83
Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents:
4070
diff
changeset
|
172 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
|
173 return; |
904c53275e83
Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents:
4070
diff
changeset
|
174 |
5980
57b70f64f997
Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
175 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
|
176 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
|
177 (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
|
178 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
179 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
|
180 o_stream_close(client->output); |
0 | 181 } |
182 | |
1023
dc660f588218
Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents:
1015
diff
changeset
|
183 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
|
184 { |
dc660f588218
Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents:
1015
diff
changeset
|
185 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
|
186 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
|
187 } |
dc660f588218
Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents:
1015
diff
changeset
|
188 |
2425
8267d11cacfb
LIST command interrupts itself when output buffer gets full and continues
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
189 int client_send_line(struct client *client, const char *data) |
0 | 190 { |
2425
8267d11cacfb
LIST command interrupts itself when output buffer gets full and continues
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
191 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
|
192 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
193 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
|
194 return -1; |
0 | 195 |
2425
8267d11cacfb
LIST command interrupts itself when output buffer gets full and continues
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
196 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
|
197 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
|
198 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
|
199 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
|
200 |
8267d11cacfb
LIST command interrupts itself when output buffer gets full and continues
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
201 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
|
202 return -1; |
5367
fab770c51321
Keep better track of client->last_output timestamp.
Timo Sirainen <tss@iki.fi>
parents:
5331
diff
changeset
|
203 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
|
204 |
3601
edc6e213048f
client_send_line(): Try flushing output immediately if buffer gets full.
Timo Sirainen <tss@iki.fi>
parents:
3469
diff
changeset
|
205 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
|
206 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
|
207 /* 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
|
208 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
|
209 } |
edc6e213048f
client_send_line(): Try flushing output immediately if buffer gets full.
Timo Sirainen <tss@iki.fi>
parents:
3469
diff
changeset
|
210 return 1; |
0 | 211 } |
212 | |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
213 void client_send_tagline(struct client_command_context *cmd, const char *data) |
0 | 214 { |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
215 struct client *client = cmd->client; |
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
216 const char *tag = cmd->tag; |
0 | 217 |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
218 if (client->output->closed || cmd->cancel) |
0 | 219 return; |
220 | |
221 if (tag == NULL || *tag == '\0') | |
222 tag = "*"; | |
223 | |
807
35abd7a5d381
Buffer related cleanups. Use PATH_MAX instead of hardcoded 1024 for paths.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
224 (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
|
225 (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
|
226 (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
|
227 (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
|
228 |
fab770c51321
Keep better track of client->last_output timestamp.
Timo Sirainen <tss@iki.fi>
parents:
5331
diff
changeset
|
229 client->last_output = ioloop_time; |
0 | 230 } |
231 | |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
232 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
|
233 const char *msg) |
0 | 234 { |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
235 struct client *client = cmd->client; |
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
236 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
|
237 bool fatal; |
0 | 238 |
1023
dc660f588218
Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents:
1015
diff
changeset
|
239 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
|
240 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
|
241 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
|
242 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
|
243 return; |
dc660f588218
Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents:
1015
diff
changeset
|
244 } |
dc660f588218
Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents:
1015
diff
changeset
|
245 } |
1538
4d1c65eded2c
Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents:
1499
diff
changeset
|
246 |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
247 if (cmd->tag == NULL) |
1538
4d1c65eded2c
Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents:
1499
diff
changeset
|
248 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
|
249 else if (cmd->name == NULL) |
1538
4d1c65eded2c
Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents:
1499
diff
changeset
|
250 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
|
251 else { |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
252 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
|
253 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
|
254 cmd_name, ": ", msg, NULL); |
1538
4d1c65eded2c
Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents:
1499
diff
changeset
|
255 } |
0 | 256 |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
257 client_send_tagline(cmd, error); |
0 | 258 |
259 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
|
260 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
|
261 "Too many invalid IMAP commands."); |
0 | 262 } |
2508
467af814d5e2
Command parameter errors weren't handled right. This was broken a few
Timo Sirainen <tss@iki.fi>
parents:
2501
diff
changeset
|
263 |
7148
5e3188213724
Added "command state" for running commands. Use it instead of some bitfields
Timo Sirainen <tss@iki.fi>
parents:
7142
diff
changeset
|
264 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
|
265 /* 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
|
266 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
|
267 FALSE. */ |
7148
5e3188213724
Added "command state" for running commands. Use it instead of some bitfields
Timo Sirainen <tss@iki.fi>
parents:
7142
diff
changeset
|
268 cmd->state = CLIENT_COMMAND_STATE_DONE; |
0 | 269 } |
270 | |
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
|
271 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
|
272 unsigned int flags, const struct imap_arg **args_r) |
0 | 273 { |
274 int ret; | |
275 | |
1015
40a327d356de
Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents:
1001
diff
changeset
|
276 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
|
277 |
5835
d59ed6a31b66
Added more consts to imap-parser API
Timo Sirainen <tss@iki.fi>
parents:
5812
diff
changeset
|
278 ret = imap_parser_read_args(cmd->parser, count, flags, args_r); |
720 | 279 if (ret >= (int)count) { |
0 | 280 /* 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
|
281 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
|
282 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
|
283 cmd->client->input_lock = NULL; |
0 | 284 return TRUE; |
285 } else if (ret == -2) { | |
286 /* 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
|
287 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
|
288 /* disconnected */ |
7148
5e3188213724
Added "command state" for running commands. Use it instead of some bitfields
Timo Sirainen <tss@iki.fi>
parents:
7142
diff
changeset
|
289 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
|
290 } |
0 | 291 return FALSE; |
292 } else { | |
293 /* error, or missing arguments */ | |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
294 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
|
295 "Missing arguments"); |
0 | 296 return FALSE; |
297 } | |
298 } | |
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_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
|
301 unsigned int count, ...) |
0 | 302 { |
5835
d59ed6a31b66
Added more consts to imap-parser API
Timo Sirainen <tss@iki.fi>
parents:
5812
diff
changeset
|
303 const struct imap_arg *imap_args; |
0 | 304 va_list va; |
305 const char *str; | |
306 unsigned int i; | |
307 | |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
308 if (!client_read_args(cmd, count, 0, &imap_args)) |
0 | 309 return FALSE; |
310 | |
311 va_start(va, count); | |
312 for (i = 0; i < count; i++) { | |
313 const char **ret = va_arg(va, const char **); | |
314 | |
1015
40a327d356de
Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents:
1001
diff
changeset
|
315 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
|
316 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
|
317 break; |
40a327d356de
Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents:
1001
diff
changeset
|
318 } |
40a327d356de
Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents:
1001
diff
changeset
|
319 |
0 | 320 str = imap_arg_string(&imap_args[i]); |
321 if (str == NULL) { | |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
322 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
|
323 break; |
0 | 324 } |
325 | |
326 if (ret != NULL) | |
327 *ret = str; | |
328 } | |
329 va_end(va); | |
330 | |
1015
40a327d356de
Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents:
1001
diff
changeset
|
331 return i == count; |
0 | 332 } |
333 | |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
334 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
|
335 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
|
336 enum command_flags flags) |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
337 { |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
338 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
|
339 |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
340 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
|
341 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
|
342 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
|
343 return cmd; |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
344 } |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
345 return NULL; |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
346 } |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
347 |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
348 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
|
349 { |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
350 enum command_flags flags; |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
351 bool broken_client = FALSE; |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
352 |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
353 if ((cmd->cmd_flags & COMMAND_FLAG_USES_SEQS) != 0) { |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
354 /* 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
|
355 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
|
356 broken_client = TRUE; |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
357 } 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
|
358 /* 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
|
359 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
|
360 } else { |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
361 return FALSE; |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
362 } |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
363 |
5812
71176467310e
Fixes to handling command ambiguity. Don't allow any commands that handle
Timo Sirainen <tss@iki.fi>
parents:
5805
diff
changeset
|
364 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
|
365 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
|
366 /* 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
|
367 return TRUE; |
71176467310e
Fixes to handling command ambiguity. Don't allow any commands that handle
Timo Sirainen <tss@iki.fi>
parents:
5805
diff
changeset
|
368 } |
7632
6e2e4e5c52f3
Fixed CLOSE HIGEHSTMODSEQ race condition. Added some checks to make
Timo Sirainen <tss@iki.fi>
parents:
7620
diff
changeset
|
369 if (cmd->client->changing_mailbox) { |
6e2e4e5c52f3
Fixed CLOSE HIGEHSTMODSEQ race condition. Added some checks to make
Timo Sirainen <tss@iki.fi>
parents:
7620
diff
changeset
|
370 /* 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
|
371 opened/closed */ |
6e2e4e5c52f3
Fixed CLOSE HIGEHSTMODSEQ race condition. Added some checks to make
Timo Sirainen <tss@iki.fi>
parents:
7620
diff
changeset
|
372 return TRUE; |
6e2e4e5c52f3
Fixed CLOSE HIGEHSTMODSEQ race condition. Added some checks to make
Timo Sirainen <tss@iki.fi>
parents:
7620
diff
changeset
|
373 } |
4941
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
374 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
|
375 } |
4941
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 if (broken_client) { |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
378 client_send_line(cmd->client, |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
379 "* BAD Command pipelining results in ambiguity."); |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
380 } |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
381 |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
382 return TRUE; |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
383 } |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
384 |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
385 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
|
386 client_command_new(struct client *client) |
0 | 387 { |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
388 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
|
389 |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
390 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
|
391 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
|
392 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
|
393 |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
394 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
|
395 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
|
396 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
|
397 } else { |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
398 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
|
399 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
|
400 } |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
401 |
7150
8a531386c856
Use linked list macros for command queue.
Timo Sirainen <tss@iki.fi>
parents:
7149
diff
changeset
|
402 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
|
403 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
|
404 |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
405 return cmd; |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
406 } |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
407 |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
408 void client_command_free(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
|
409 { |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
410 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
|
411 |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2058
diff
changeset
|
412 /* 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
|
413 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
|
414 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
|
415 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
|
416 |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
417 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
|
418 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
|
419 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
|
420 } |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
421 |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
422 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
|
423 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
|
424 |
5415 | 425 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
|
426 client->input_lock = NULL; |
5415 | 427 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
|
428 client->output_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
|
429 |
4939
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 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
|
432 else { |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
433 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
|
434 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
|
435 } |
0 | 436 |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
437 client->command_queue_size--; |
7150
8a531386c856
Use linked list macros for command queue.
Timo Sirainen <tss@iki.fi>
parents:
7149
diff
changeset
|
438 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
|
439 cmd = NULL; |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
440 |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
441 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
|
442 /* 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
|
443 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
|
444 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
|
445 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
|
446 } |
5110 | 447 } |
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
|
448 |
5114 | 449 static void client_add_missing_io(struct client *client) |
450 { | |
5196 | 451 if (client->io == NULL && !client->disconnected) { |
452 client->io = io_add(client->fd_in, | |
6418
46d9ee79f292
Removed _ prefix from all public APIs.
Timo Sirainen <tss@iki.fi>
parents:
6411
diff
changeset
|
453 IO_READ, client_input, client); |
5114 | 454 } |
455 } | |
456 | |
6531
d747bfbda43c
Fixed process hanging sometimes when disconnecting.
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
457 void client_continue_pending_input(struct client **_client) |
5110 | 458 { |
6531
d747bfbda43c
Fixed process hanging sometimes when disconnecting.
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
459 struct client *client = *_client; |
5110 | 460 size_t size; |
461 | |
462 i_assert(!client->handling_input); | |
463 | |
6531
d747bfbda43c
Fixed process hanging sometimes when disconnecting.
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
464 if (client->disconnected) { |
6570
86e964111b1f
Don't assert-crash if client disconnects while IDLEing.
Timo Sirainen <tss@iki.fi>
parents:
6531
diff
changeset
|
465 if (!client->destroyed) |
86e964111b1f
Don't assert-crash if client disconnects while IDLEing.
Timo Sirainen <tss@iki.fi>
parents:
6531
diff
changeset
|
466 client_destroy(client, NULL); |
6531
d747bfbda43c
Fixed process hanging sometimes when disconnecting.
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
467 *_client = NULL; |
5110 | 468 return; |
6531
d747bfbda43c
Fixed process hanging sometimes when disconnecting.
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
469 } |
5110 | 470 |
471 if (client->input_lock != NULL) { | |
472 /* 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
|
473 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
|
474 |
323b425a0f46
Replaced waiting_ambiguity bitmask with a command state.
Timo Sirainen <tss@iki.fi>
parents:
7148
diff
changeset
|
475 if (cmd->state != CLIENT_COMMAND_STATE_WAIT_UNAMBIGUITY) |
5110 | 476 return; |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
477 |
5110 | 478 /* the command is waiting for existing ambiguity causing |
479 commands to finish. */ | |
7149
323b425a0f46
Replaced waiting_ambiguity bitmask with a command state.
Timo Sirainen <tss@iki.fi>
parents:
7148
diff
changeset
|
480 if (client_command_check_ambiguity(cmd)) |
5110 | 481 return; |
7149
323b425a0f46
Replaced waiting_ambiguity bitmask with a command state.
Timo Sirainen <tss@iki.fi>
parents:
7148
diff
changeset
|
482 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
|
483 } |
5110 | 484 |
5114 | 485 client_add_missing_io(client); |
5110 | 486 |
487 /* if there's unread data in buffer, handle it. */ | |
488 (void)i_stream_get_data(client->input, &size); | |
489 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
|
490 (void)client_handle_input(client); |
0 | 491 } |
492 | |
493 /* Skip incoming data until newline is found, | |
494 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
|
495 static bool client_skip_line(struct client *client) |
0 | 496 { |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
364
diff
changeset
|
497 const unsigned char *data; |
184 | 498 size_t i, data_size; |
0 | 499 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
500 data = i_stream_get_data(client->input, &data_size); |
0 | 501 |
502 for (i = 0; i < data_size; i++) { | |
503 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
|
504 client->input_skip_line = FALSE; |
1538
4d1c65eded2c
Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents:
1499
diff
changeset
|
505 i++; |
0 | 506 break; |
507 } | |
508 } | |
509 | |
1538
4d1c65eded2c
Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents:
1499
diff
changeset
|
510 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
|
511 return !client->input_skip_line; |
0 | 512 } |
513 | |
7103
284dd5f2777d
Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
514 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
|
515 { |
284dd5f2777d
Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
516 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
|
517 "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
|
518 } |
284dd5f2777d
Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
519 |
284dd5f2777d
Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
520 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
|
521 { |
7195
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
522 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
|
523 /* 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
|
524 return FALSE; |
7195
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
525 } |
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
526 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
|
527 /* waiting for something */ |
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
528 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
|
529 /* 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
|
530 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
|
531 } |
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
532 return TRUE; |
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
533 } |
7103
284dd5f2777d
Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
534 |
284dd5f2777d
Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
535 /* 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
|
536 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
|
537 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
|
538 /* 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
|
539 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
|
540 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
|
541 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
|
542 } |
284dd5f2777d
Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
543 return TRUE; |
284dd5f2777d
Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
544 } |
284dd5f2777d
Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
545 |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
546 static bool client_command_input(struct client_command_context *cmd) |
0 | 547 { |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
548 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
|
549 struct command *command; |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
550 |
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
551 if (cmd->func != NULL) { |
0 | 552 /* 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
|
553 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
|
554 /* command execution was finished */ |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
555 client_command_free(cmd); |
5114 | 556 client_add_missing_io(client); |
0 | 557 return TRUE; |
558 } | |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
559 |
7103
284dd5f2777d
Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
560 return client_handle_unfinished_cmd(cmd); |
0 | 561 } |
562 | |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
563 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
|
564 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
|
565 if (cmd->tag == NULL) |
0 | 566 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
|
567 cmd->tag = p_strdup(cmd->pool, cmd->tag); |
0 | 568 } |
569 | |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
570 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
|
571 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
|
572 if (cmd->name == NULL) |
0 | 573 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
|
574 cmd->name = p_strdup(cmd->pool, cmd->name); |
0 | 575 } |
576 | |
4941
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
577 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
|
578 |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
579 if (cmd->name == '\0') { |
0 | 580 /* 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
|
581 } 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
|
582 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
|
583 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
|
584 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
|
585 /* 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
|
586 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
|
587 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
|
588 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
|
589 return FALSE; |
4941
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
590 } |
0 | 591 } |
592 | |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
593 if (cmd->func == NULL) { |
0 | 594 /* unknown command */ |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
595 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
|
596 cmd->param_error = TRUE; |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
597 client_command_free(cmd); |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
598 return TRUE; |
0 | 599 } else { |
4831 | 600 i_assert(!client->disconnected); |
601 | |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
602 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
|
603 } |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
604 } |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
605 |
7195
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
606 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
|
607 { |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
608 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
|
609 |
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
|
610 *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
|
611 |
5812
71176467310e
Fixes to handling command ambiguity. Don't allow any commands that handle
Timo Sirainen <tss@iki.fi>
parents:
5805
diff
changeset
|
612 if (client->input_lock != NULL) { |
7149
323b425a0f46
Replaced waiting_ambiguity bitmask with a command state.
Timo Sirainen <tss@iki.fi>
parents:
7148
diff
changeset
|
613 if (client->input_lock->state == |
323b425a0f46
Replaced waiting_ambiguity bitmask with a command state.
Timo Sirainen <tss@iki.fi>
parents:
7148
diff
changeset
|
614 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
|
615 *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
|
616 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
|
617 } |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
618 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
|
619 } |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
620 |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
621 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
|
622 /* 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
|
623 if (!client_skip_line(client)) |
1172 | 624 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
|
625 client->input_skip_line = FALSE; |
0 | 626 } |
627 | |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
628 /* 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
|
629 some input */ |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
630 (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
|
631 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
|
632 return FALSE; |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
633 |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
634 /* 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
|
635 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
|
636 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
|
637 /* 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
|
638 *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
|
639 return FALSE; |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
640 } |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
641 |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
642 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
|
643 return client_command_input(client->input_lock); |
0 | 644 } |
645 | |
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
|
646 static bool client_handle_input(struct client *client) |
08a3ba5de497
If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents:
6940
diff
changeset
|
647 { |
08a3ba5de497
If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents:
6940
diff
changeset
|
648 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
|
649 |
08a3ba5de497
If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents:
6940
diff
changeset
|
650 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
|
651 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
|
652 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
|
653 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
|
654 } 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
|
655 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
|
656 handled_commands = TRUE; |
7195
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
657 } 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
|
658 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
|
659 |
08a3ba5de497
If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents:
6940
diff
changeset
|
660 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
|
661 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
|
662 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
|
663 } 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
|
664 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
|
665 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
|
666 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
|
667 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
|
668 if (!handled_commands) |
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
669 return FALSE; |
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
670 |
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
671 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
|
672 if (ret) |
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
673 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
|
674 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
|
675 } |
08a3ba5de497
If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents:
6940
diff
changeset
|
676 } |
08a3ba5de497
If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents:
6940
diff
changeset
|
677 |
6418
46d9ee79f292
Removed _ prefix from all public APIs.
Timo Sirainen <tss@iki.fi>
parents:
6411
diff
changeset
|
678 void client_input(struct client *client) |
0 | 679 { |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
680 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
|
681 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
|
682 ssize_t bytes; |
953
411006be3c66
Naming change for function typedefs.
Timo Sirainen <tss@iki.fi>
parents:
903
diff
changeset
|
683 |
5114 | 684 i_assert(client->io != NULL); |
685 | |
0 | 686 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
|
687 timeout_reset(client->to_idle); |
0 | 688 |
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
|
689 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
|
690 if (bytes == -1) { |
0 | 691 /* 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
|
692 client_destroy(client, NULL); |
0 | 693 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
|
694 } |
08a3ba5de497
If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents:
6940
diff
changeset
|
695 |
7195
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
696 o_stream_ref(output); |
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
697 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
|
698 if (!client_handle_input(client) && bytes == -2) { |
0 | 699 /* parameter word is longer than max. input buffer size. |
700 this is most likely an error, so skip the new data | |
701 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
|
702 client->input_skip_line = TRUE; |
0 | 703 |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
704 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
|
705 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
|
706 cmd->param_error = TRUE; |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
707 client_send_command_error(cmd, "Too long argument."); |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
708 client_command_free(cmd); |
0 | 709 } |
7195
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
710 o_stream_uncork(output); |
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
711 o_stream_unref(&output); |
0 | 712 } |
713 | |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
714 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
|
715 { |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
716 bool finished; |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
717 |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
718 /* 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
|
719 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
|
720 |
7103
284dd5f2777d
Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
721 if (!finished) |
284dd5f2777d
Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
722 (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
|
723 else { |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
724 /* command execution was finished */ |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
725 client_command_free(cmd); |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
726 } |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
727 } |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
728 |
6418
46d9ee79f292
Removed _ prefix from all public APIs.
Timo Sirainen <tss@iki.fi>
parents:
6411
diff
changeset
|
729 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
|
730 { |
7151
2ced9dd8b2cc
Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents:
7150
diff
changeset
|
731 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
|
732 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
|
733 |
5110 | 734 i_assert(!client->destroyed); |
735 | |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2058
diff
changeset
|
736 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
|
737 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
|
738 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
|
739 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
|
740 |
2790
02c0b8d532c2
Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents:
2640
diff
changeset
|
741 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
|
742 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
|
743 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
|
744 } |
02c0b8d532c2
Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents:
2640
diff
changeset
|
745 |
7151
2ced9dd8b2cc
Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents:
7150
diff
changeset
|
746 /* mark all commands non-executed */ |
2ced9dd8b2cc
Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents:
7150
diff
changeset
|
747 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
|
748 cmd->temp_executed = FALSE; |
2ced9dd8b2cc
Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents:
7150
diff
changeset
|
749 |
2790
02c0b8d532c2
Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents:
2640
diff
changeset
|
750 o_stream_cork(client->output); |
7151
2ced9dd8b2cc
Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents:
7150
diff
changeset
|
751 if (client->output_lock != NULL) { |
2ced9dd8b2cc
Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents:
7150
diff
changeset
|
752 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
|
753 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
|
754 } |
2ced9dd8b2cc
Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents:
7150
diff
changeset
|
755 while (client->output_lock == NULL) { |
2ced9dd8b2cc
Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents:
7150
diff
changeset
|
756 /* 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
|
757 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
|
758 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
|
759 cmd = client->command_queue; |
7151
2ced9dd8b2cc
Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents:
7150
diff
changeset
|
760 for (; cmd != NULL; cmd = cmd->next) { |
2ced9dd8b2cc
Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents:
7150
diff
changeset
|
761 if (!cmd->temp_executed && |
2ced9dd8b2cc
Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents:
7150
diff
changeset
|
762 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
|
763 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
|
764 client_output_cmd(cmd); |
7151
2ced9dd8b2cc
Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents:
7150
diff
changeset
|
765 break; |
5812
71176467310e
Fixes to handling command ambiguity. Don't allow any commands that handle
Timo Sirainen <tss@iki.fi>
parents:
5805
diff
changeset
|
766 } |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
767 } |
7151
2ced9dd8b2cc
Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents:
7150
diff
changeset
|
768 if (cmd == NULL) { |
2ced9dd8b2cc
Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents:
7150
diff
changeset
|
769 /* all commands executed */ |
2ced9dd8b2cc
Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents:
7150
diff
changeset
|
770 break; |
2ced9dd8b2cc
Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents:
7150
diff
changeset
|
771 } |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
772 } |
5110 | 773 |
774 if (client->output->closed) { | |
775 client_destroy(client, NULL); | |
776 return 1; | |
777 } else { | |
7195
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
778 (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
|
779 o_stream_uncork(client->output); |
6531
d747bfbda43c
Fixed process hanging sometimes when disconnecting.
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
780 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
|
781 return ret; |
5110 | 782 } |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2058
diff
changeset
|
783 } |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2058
diff
changeset
|
784 |
7639
03146f02403f
Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents:
7633
diff
changeset
|
785 bool client_handle_search_save_ambiguity(struct client_command_context *cmd) |
03146f02403f
Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents:
7633
diff
changeset
|
786 { |
03146f02403f
Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents:
7633
diff
changeset
|
787 struct client_command_context *old_cmd = cmd->next; |
03146f02403f
Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents:
7633
diff
changeset
|
788 |
03146f02403f
Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents:
7633
diff
changeset
|
789 /* search only commands that were added before this command |
03146f02403f
Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents:
7633
diff
changeset
|
790 (commands are prepended to the queue, so they're after ourself) */ |
03146f02403f
Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents:
7633
diff
changeset
|
791 for (; old_cmd != NULL; old_cmd = old_cmd->next) { |
03146f02403f
Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents:
7633
diff
changeset
|
792 if (old_cmd->search_save_result) |
03146f02403f
Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents:
7633
diff
changeset
|
793 break; |
03146f02403f
Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents:
7633
diff
changeset
|
794 } |
03146f02403f
Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents:
7633
diff
changeset
|
795 if (old_cmd == NULL) |
03146f02403f
Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents:
7633
diff
changeset
|
796 return FALSE; |
03146f02403f
Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents:
7633
diff
changeset
|
797 |
03146f02403f
Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents:
7633
diff
changeset
|
798 /* ambiguity, wait until it's over */ |
03146f02403f
Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents:
7633
diff
changeset
|
799 i_assert(cmd->state == CLIENT_COMMAND_STATE_WAIT_INPUT); |
03146f02403f
Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents:
7633
diff
changeset
|
800 cmd->client->input_lock = cmd; |
03146f02403f
Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents:
7633
diff
changeset
|
801 cmd->state = CLIENT_COMMAND_STATE_WAIT_UNAMBIGUITY; |
03146f02403f
Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents:
7633
diff
changeset
|
802 io_remove(&cmd->client->io); |
03146f02403f
Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents:
7633
diff
changeset
|
803 return TRUE; |
03146f02403f
Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents:
7633
diff
changeset
|
804 } |
03146f02403f
Implemented SEARCHRES extension.
Timo Sirainen <tss@iki.fi>
parents:
7633
diff
changeset
|
805 |
7620 | 806 void client_enable(struct client *client, enum mailbox_feature features) |
807 { | |
7633
27a0de620b0c
If CONDSTORE is enabled only after mailbox has been selected, send
Timo Sirainen <tss@iki.fi>
parents:
7632
diff
changeset
|
808 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
|
809 |
27a0de620b0c
If CONDSTORE is enabled only after mailbox has been selected, send
Timo Sirainen <tss@iki.fi>
parents:
7632
diff
changeset
|
810 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
|
811 return; |
27a0de620b0c
If CONDSTORE is enabled only after mailbox has been selected, send
Timo Sirainen <tss@iki.fi>
parents:
7632
diff
changeset
|
812 |
7620 | 813 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
|
814 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
|
815 return; |
27a0de620b0c
If CONDSTORE is enabled only after mailbox has been selected, send
Timo Sirainen <tss@iki.fi>
parents:
7632
diff
changeset
|
816 |
27a0de620b0c
If CONDSTORE is enabled only after mailbox has been selected, send
Timo Sirainen <tss@iki.fi>
parents:
7632
diff
changeset
|
817 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
|
818 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
|
819 /* 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
|
820 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
|
821 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
|
822 STATUS_HIGHESTMODSEQ, &status); |
27a0de620b0c
If CONDSTORE is enabled only after mailbox has been selected, send
Timo Sirainen <tss@iki.fi>
parents:
7632
diff
changeset
|
823 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
|
824 "* OK [HIGHESTMODSEQ %llu]", |
27a0de620b0c
If CONDSTORE is enabled only after mailbox has been selected, send
Timo Sirainen <tss@iki.fi>
parents:
7632
diff
changeset
|
825 (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
|
826 } |
7620 | 827 } |
828 | |
0 | 829 void clients_init(void) |
830 { | |
831 my_client = NULL; | |
832 } | |
833 | |
834 void clients_deinit(void) | |
835 { | |
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
|
836 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
|
837 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
|
838 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
|
839 } |
0 | 840 } |