Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/imap/client.c @ 7226:e6693a0ec8e1 HEAD
Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
replaced them with T_BEGIN/END calls. T_FRAME() made it difficult to debug
code with gdb.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 11 Feb 2008 20:17:00 +0200 |
parents | bca55675d77c |
children | 4f63124e756e |
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 |
6428
7cad076906eb
pool_unref() now takes ** pointer.
Timo Sirainen <tss@iki.fi>
parents:
6418
diff
changeset
|
158 pool_unref(&client->command_pool); |
0 | 159 i_free(client); |
160 | |
161 /* quit the program */ | |
162 my_client = NULL; | |
163 io_loop_stop(ioloop); | |
164 } | |
165 | |
4096
904c53275e83
Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents:
4070
diff
changeset
|
166 void client_disconnect(struct client *client, const char *reason) |
0 | 167 { |
4291
c78bd7fb7ce8
Added assert against NULL reason for client_disconnect().
Timo Sirainen <tss@iki.fi>
parents:
4096
diff
changeset
|
168 i_assert(reason != NULL); |
c78bd7fb7ce8
Added assert against NULL reason for client_disconnect().
Timo Sirainen <tss@iki.fi>
parents:
4096
diff
changeset
|
169 |
4096
904c53275e83
Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents:
4070
diff
changeset
|
170 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
|
171 return; |
904c53275e83
Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents:
4070
diff
changeset
|
172 |
5980
57b70f64f997
Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
173 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
|
174 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
|
175 (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
|
176 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
177 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
|
178 o_stream_close(client->output); |
0 | 179 } |
180 | |
1023
dc660f588218
Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents:
1015
diff
changeset
|
181 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
|
182 { |
dc660f588218
Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents:
1015
diff
changeset
|
183 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
|
184 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
|
185 } |
dc660f588218
Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents:
1015
diff
changeset
|
186 |
2425
8267d11cacfb
LIST command interrupts itself when output buffer gets full and continues
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
187 int client_send_line(struct client *client, const char *data) |
0 | 188 { |
2425
8267d11cacfb
LIST command interrupts itself when output buffer gets full and continues
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
189 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
|
190 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
191 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
|
192 return -1; |
0 | 193 |
2425
8267d11cacfb
LIST command interrupts itself when output buffer gets full and continues
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
194 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
|
195 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
|
196 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
|
197 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
|
198 |
8267d11cacfb
LIST command interrupts itself when output buffer gets full and continues
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
199 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
|
200 return -1; |
5367
fab770c51321
Keep better track of client->last_output timestamp.
Timo Sirainen <tss@iki.fi>
parents:
5331
diff
changeset
|
201 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
|
202 |
3601
edc6e213048f
client_send_line(): Try flushing output immediately if buffer gets full.
Timo Sirainen <tss@iki.fi>
parents:
3469
diff
changeset
|
203 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
|
204 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
|
205 /* 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
|
206 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
|
207 } |
edc6e213048f
client_send_line(): Try flushing output immediately if buffer gets full.
Timo Sirainen <tss@iki.fi>
parents:
3469
diff
changeset
|
208 return 1; |
0 | 209 } |
210 | |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
211 void client_send_tagline(struct client_command_context *cmd, const char *data) |
0 | 212 { |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
213 struct client *client = cmd->client; |
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
214 const char *tag = cmd->tag; |
0 | 215 |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
216 if (client->output->closed || cmd->cancel) |
0 | 217 return; |
218 | |
219 if (tag == NULL || *tag == '\0') | |
220 tag = "*"; | |
221 | |
807
35abd7a5d381
Buffer related cleanups. Use PATH_MAX instead of hardcoded 1024 for paths.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
222 (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
|
223 (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
|
224 (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
|
225 (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
|
226 |
fab770c51321
Keep better track of client->last_output timestamp.
Timo Sirainen <tss@iki.fi>
parents:
5331
diff
changeset
|
227 client->last_output = ioloop_time; |
0 | 228 } |
229 | |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
230 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
|
231 const char *msg) |
0 | 232 { |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
233 struct client *client = cmd->client; |
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
234 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
|
235 bool fatal; |
0 | 236 |
1023
dc660f588218
Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents:
1015
diff
changeset
|
237 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
|
238 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
|
239 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
|
240 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
|
241 return; |
dc660f588218
Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents:
1015
diff
changeset
|
242 } |
dc660f588218
Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents:
1015
diff
changeset
|
243 } |
1538
4d1c65eded2c
Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents:
1499
diff
changeset
|
244 |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
245 if (cmd->tag == NULL) |
1538
4d1c65eded2c
Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents:
1499
diff
changeset
|
246 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
|
247 else if (cmd->name == 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 command: ", msg, NULL); |
4d1c65eded2c
Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents:
1499
diff
changeset
|
249 else { |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
250 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
|
251 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
|
252 cmd_name, ": ", msg, NULL); |
1538
4d1c65eded2c
Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents:
1499
diff
changeset
|
253 } |
0 | 254 |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
255 client_send_tagline(cmd, error); |
0 | 256 |
257 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
|
258 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
|
259 "Too many invalid IMAP commands."); |
0 | 260 } |
2508
467af814d5e2
Command parameter errors weren't handled right. This was broken a few
Timo Sirainen <tss@iki.fi>
parents:
2501
diff
changeset
|
261 |
7148
5e3188213724
Added "command state" for running commands. Use it instead of some bitfields
Timo Sirainen <tss@iki.fi>
parents:
7142
diff
changeset
|
262 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
|
263 /* 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
|
264 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
|
265 FALSE. */ |
7148
5e3188213724
Added "command state" for running commands. Use it instead of some bitfields
Timo Sirainen <tss@iki.fi>
parents:
7142
diff
changeset
|
266 cmd->state = CLIENT_COMMAND_STATE_DONE; |
0 | 267 } |
268 | |
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
|
269 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
|
270 unsigned int flags, const struct imap_arg **args_r) |
0 | 271 { |
272 int ret; | |
273 | |
1015
40a327d356de
Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents:
1001
diff
changeset
|
274 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
|
275 |
5835
d59ed6a31b66
Added more consts to imap-parser API
Timo Sirainen <tss@iki.fi>
parents:
5812
diff
changeset
|
276 ret = imap_parser_read_args(cmd->parser, count, flags, args_r); |
720 | 277 if (ret >= (int)count) { |
0 | 278 /* 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
|
279 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
|
280 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
|
281 cmd->client->input_lock = NULL; |
0 | 282 return TRUE; |
283 } else if (ret == -2) { | |
284 /* 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
|
285 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
|
286 /* disconnected */ |
7148
5e3188213724
Added "command state" for running commands. Use it instead of some bitfields
Timo Sirainen <tss@iki.fi>
parents:
7142
diff
changeset
|
287 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
|
288 } |
0 | 289 return FALSE; |
290 } else { | |
291 /* error, or missing arguments */ | |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
292 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
|
293 "Missing arguments"); |
0 | 294 return FALSE; |
295 } | |
296 } | |
297 | |
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
|
298 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
|
299 unsigned int count, ...) |
0 | 300 { |
5835
d59ed6a31b66
Added more consts to imap-parser API
Timo Sirainen <tss@iki.fi>
parents:
5812
diff
changeset
|
301 const struct imap_arg *imap_args; |
0 | 302 va_list va; |
303 const char *str; | |
304 unsigned int i; | |
305 | |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
306 if (!client_read_args(cmd, count, 0, &imap_args)) |
0 | 307 return FALSE; |
308 | |
309 va_start(va, count); | |
310 for (i = 0; i < count; i++) { | |
311 const char **ret = va_arg(va, const char **); | |
312 | |
1015
40a327d356de
Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents:
1001
diff
changeset
|
313 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
|
314 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
|
315 break; |
40a327d356de
Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents:
1001
diff
changeset
|
316 } |
40a327d356de
Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents:
1001
diff
changeset
|
317 |
0 | 318 str = imap_arg_string(&imap_args[i]); |
319 if (str == NULL) { | |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
320 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
|
321 break; |
0 | 322 } |
323 | |
324 if (ret != NULL) | |
325 *ret = str; | |
326 } | |
327 va_end(va); | |
328 | |
1015
40a327d356de
Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents:
1001
diff
changeset
|
329 return i == count; |
0 | 330 } |
331 | |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
332 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
|
333 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
|
334 enum command_flags flags) |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
335 { |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
336 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
|
337 |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
338 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
|
339 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
|
340 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
|
341 return cmd; |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
342 } |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
343 return NULL; |
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 |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
346 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
|
347 { |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
348 enum command_flags flags; |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
349 bool broken_client = FALSE; |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
350 |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
351 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
|
352 /* 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
|
353 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
|
354 broken_client = TRUE; |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
355 } 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
|
356 /* 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
|
357 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
|
358 } else { |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
359 return FALSE; |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
360 } |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
361 |
5812
71176467310e
Fixes to handling command ambiguity. Don't allow any commands that handle
Timo Sirainen <tss@iki.fi>
parents:
5805
diff
changeset
|
362 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
|
363 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
|
364 /* 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
|
365 return TRUE; |
71176467310e
Fixes to handling command ambiguity. Don't allow any commands that handle
Timo Sirainen <tss@iki.fi>
parents:
5805
diff
changeset
|
366 } |
4941
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
367 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
|
368 } |
4941
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
369 |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
370 if (broken_client) { |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
371 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
|
372 "* 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
|
373 } |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
374 |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
375 return TRUE; |
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 |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
378 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
|
379 client_command_new(struct client *client) |
0 | 380 { |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
381 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
|
382 |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
383 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
|
384 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
|
385 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
|
386 |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
387 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
|
388 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
|
389 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
|
390 } else { |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
391 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
|
392 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
|
393 } |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
394 |
7150
8a531386c856
Use linked list macros for command queue.
Timo Sirainen <tss@iki.fi>
parents:
7149
diff
changeset
|
395 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
|
396 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
|
397 |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
398 return cmd; |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
399 } |
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 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
|
402 { |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
403 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
|
404 |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2058
diff
changeset
|
405 /* 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
|
406 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
|
407 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
|
408 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
|
409 |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
410 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
|
411 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
|
412 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
|
413 } |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
414 |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
415 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
|
416 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
|
417 |
5415 | 418 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
|
419 client->input_lock = NULL; |
5415 | 420 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
|
421 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
|
422 |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
423 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
|
424 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
|
425 else { |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
426 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
|
427 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
|
428 } |
0 | 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 client->command_queue_size--; |
7150
8a531386c856
Use linked list macros for command queue.
Timo Sirainen <tss@iki.fi>
parents:
7149
diff
changeset
|
431 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
|
432 cmd = NULL; |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
433 |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
434 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
|
435 /* 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
|
436 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
|
437 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
|
438 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
|
439 } |
5110 | 440 } |
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
|
441 |
5114 | 442 static void client_add_missing_io(struct client *client) |
443 { | |
5196 | 444 if (client->io == NULL && !client->disconnected) { |
445 client->io = io_add(client->fd_in, | |
6418
46d9ee79f292
Removed _ prefix from all public APIs.
Timo Sirainen <tss@iki.fi>
parents:
6411
diff
changeset
|
446 IO_READ, client_input, client); |
5114 | 447 } |
448 } | |
449 | |
6531
d747bfbda43c
Fixed process hanging sometimes when disconnecting.
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
450 void client_continue_pending_input(struct client **_client) |
5110 | 451 { |
6531
d747bfbda43c
Fixed process hanging sometimes when disconnecting.
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
452 struct client *client = *_client; |
5110 | 453 size_t size; |
454 | |
455 i_assert(!client->handling_input); | |
456 | |
6531
d747bfbda43c
Fixed process hanging sometimes when disconnecting.
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
457 if (client->disconnected) { |
6570
86e964111b1f
Don't assert-crash if client disconnects while IDLEing.
Timo Sirainen <tss@iki.fi>
parents:
6531
diff
changeset
|
458 if (!client->destroyed) |
86e964111b1f
Don't assert-crash if client disconnects while IDLEing.
Timo Sirainen <tss@iki.fi>
parents:
6531
diff
changeset
|
459 client_destroy(client, NULL); |
6531
d747bfbda43c
Fixed process hanging sometimes when disconnecting.
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
460 *_client = NULL; |
5110 | 461 return; |
6531
d747bfbda43c
Fixed process hanging sometimes when disconnecting.
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
462 } |
5110 | 463 |
464 if (client->input_lock != NULL) { | |
465 /* 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
|
466 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
|
467 |
323b425a0f46
Replaced waiting_ambiguity bitmask with a command state.
Timo Sirainen <tss@iki.fi>
parents:
7148
diff
changeset
|
468 if (cmd->state != CLIENT_COMMAND_STATE_WAIT_UNAMBIGUITY) |
5110 | 469 return; |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
470 |
5110 | 471 /* the command is waiting for existing ambiguity causing |
472 commands to finish. */ | |
7149
323b425a0f46
Replaced waiting_ambiguity bitmask with a command state.
Timo Sirainen <tss@iki.fi>
parents:
7148
diff
changeset
|
473 if (client_command_check_ambiguity(cmd)) |
5110 | 474 return; |
7149
323b425a0f46
Replaced waiting_ambiguity bitmask with a command state.
Timo Sirainen <tss@iki.fi>
parents:
7148
diff
changeset
|
475 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
|
476 } |
5110 | 477 |
5114 | 478 client_add_missing_io(client); |
5110 | 479 |
480 /* if there's unread data in buffer, handle it. */ | |
481 (void)i_stream_get_data(client->input, &size); | |
482 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
|
483 (void)client_handle_input(client); |
0 | 484 } |
485 | |
486 /* Skip incoming data until newline is found, | |
487 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
|
488 static bool client_skip_line(struct client *client) |
0 | 489 { |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
364
diff
changeset
|
490 const unsigned char *data; |
184 | 491 size_t i, data_size; |
0 | 492 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
493 data = i_stream_get_data(client->input, &data_size); |
0 | 494 |
495 for (i = 0; i < data_size; i++) { | |
496 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
|
497 client->input_skip_line = FALSE; |
1538
4d1c65eded2c
Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents:
1499
diff
changeset
|
498 i++; |
0 | 499 break; |
500 } | |
501 } | |
502 | |
1538
4d1c65eded2c
Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents:
1499
diff
changeset
|
503 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
|
504 return !client->input_skip_line; |
0 | 505 } |
506 | |
7103
284dd5f2777d
Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
507 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
|
508 { |
284dd5f2777d
Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
509 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
|
510 "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
|
511 } |
284dd5f2777d
Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
512 |
284dd5f2777d
Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
513 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
|
514 { |
7195
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
515 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
|
516 /* 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
|
517 return FALSE; |
7195
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
518 } |
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
519 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
|
520 /* waiting for something */ |
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
521 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
|
522 /* 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
|
523 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
|
524 } |
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
525 return TRUE; |
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
526 } |
7103
284dd5f2777d
Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
527 |
284dd5f2777d
Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
528 /* 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
|
529 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
|
530 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
|
531 /* 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
|
532 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
|
533 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
|
534 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
|
535 } |
284dd5f2777d
Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
536 return TRUE; |
284dd5f2777d
Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
537 } |
284dd5f2777d
Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
538 |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
539 static bool client_command_input(struct client_command_context *cmd) |
0 | 540 { |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
541 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
|
542 struct command *command; |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
543 |
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
544 if (cmd->func != NULL) { |
0 | 545 /* 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
|
546 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
|
547 /* 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
|
548 client_command_free(cmd); |
5114 | 549 client_add_missing_io(client); |
0 | 550 return TRUE; |
551 } | |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
552 |
7103
284dd5f2777d
Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
553 return client_handle_unfinished_cmd(cmd); |
0 | 554 } |
555 | |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
556 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
|
557 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
|
558 if (cmd->tag == NULL) |
0 | 559 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
|
560 cmd->tag = p_strdup(cmd->pool, cmd->tag); |
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->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
|
564 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
|
565 if (cmd->name == 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->name = p_strdup(cmd->pool, cmd->name); |
0 | 568 } |
569 | |
4941
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
570 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
|
571 |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
572 if (cmd->name == '\0') { |
0 | 573 /* 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
|
574 } 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
|
575 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
|
576 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
|
577 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
|
578 /* 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
|
579 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
|
580 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
|
581 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
|
582 return FALSE; |
4941
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
583 } |
0 | 584 } |
585 | |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
586 if (cmd->func == NULL) { |
0 | 587 /* unknown command */ |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
588 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
|
589 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
|
590 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
|
591 return TRUE; |
0 | 592 } else { |
4831 | 593 i_assert(!client->disconnected); |
594 | |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
595 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
|
596 } |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
597 } |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
598 |
7195
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
599 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
|
600 { |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
601 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
|
602 |
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
|
603 *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
|
604 |
5812
71176467310e
Fixes to handling command ambiguity. Don't allow any commands that handle
Timo Sirainen <tss@iki.fi>
parents:
5805
diff
changeset
|
605 if (client->input_lock != NULL) { |
7149
323b425a0f46
Replaced waiting_ambiguity bitmask with a command state.
Timo Sirainen <tss@iki.fi>
parents:
7148
diff
changeset
|
606 if (client->input_lock->state == |
323b425a0f46
Replaced waiting_ambiguity bitmask with a command state.
Timo Sirainen <tss@iki.fi>
parents:
7148
diff
changeset
|
607 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
|
608 *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
|
609 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
|
610 } |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
611 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
|
612 } |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
613 |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
614 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
|
615 /* 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
|
616 if (!client_skip_line(client)) |
1172 | 617 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
|
618 client->input_skip_line = FALSE; |
0 | 619 } |
620 | |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
621 /* 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
|
622 some input */ |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
623 (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
|
624 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
|
625 return FALSE; |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
626 |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
627 /* 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
|
628 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
|
629 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
|
630 /* 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
|
631 *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
|
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 |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
635 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
|
636 return client_command_input(client->input_lock); |
0 | 637 } |
638 | |
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
|
639 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
|
640 { |
08a3ba5de497
If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents:
6940
diff
changeset
|
641 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
|
642 |
08a3ba5de497
If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents:
6940
diff
changeset
|
643 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
|
644 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
|
645 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
|
646 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
|
647 } 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
|
648 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
|
649 handled_commands = TRUE; |
7195
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
650 } 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
|
651 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
|
652 |
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 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
|
654 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
|
655 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
|
656 } 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
|
657 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
|
658 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
|
659 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
|
660 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
|
661 if (!handled_commands) |
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
662 return FALSE; |
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
663 |
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
664 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
|
665 if (ret) |
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
666 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
|
667 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
|
668 } |
08a3ba5de497
If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents:
6940
diff
changeset
|
669 } |
08a3ba5de497
If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents:
6940
diff
changeset
|
670 |
6418
46d9ee79f292
Removed _ prefix from all public APIs.
Timo Sirainen <tss@iki.fi>
parents:
6411
diff
changeset
|
671 void client_input(struct client *client) |
0 | 672 { |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
673 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
|
674 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
|
675 ssize_t bytes; |
953
411006be3c66
Naming change for function typedefs.
Timo Sirainen <tss@iki.fi>
parents:
903
diff
changeset
|
676 |
5114 | 677 i_assert(client->io != NULL); |
678 | |
0 | 679 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
|
680 timeout_reset(client->to_idle); |
0 | 681 |
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 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
|
683 if (bytes == -1) { |
0 | 684 /* 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
|
685 client_destroy(client, NULL); |
0 | 686 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
|
687 } |
08a3ba5de497
If client is sending a lot of commands at once, stop reading input instead
Timo Sirainen <tss@iki.fi>
parents:
6940
diff
changeset
|
688 |
7195
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
689 o_stream_ref(output); |
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
690 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
|
691 if (!client_handle_input(client) && bytes == -2) { |
0 | 692 /* parameter word is longer than max. input buffer size. |
693 this is most likely an error, so skip the new data | |
694 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
|
695 client->input_skip_line = TRUE; |
0 | 696 |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
697 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
|
698 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
|
699 cmd->param_error = TRUE; |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
700 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
|
701 client_command_free(cmd); |
0 | 702 } |
7195
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
703 o_stream_uncork(output); |
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
704 o_stream_unref(&output); |
0 | 705 } |
706 | |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
707 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
|
708 { |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
709 bool finished; |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
710 |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
711 /* 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
|
712 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
|
713 |
7103
284dd5f2777d
Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
714 if (!finished) |
284dd5f2777d
Use separate idle timeouts to avoid unneededly checking them every n seconds.
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
715 (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
|
716 else { |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
717 /* 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
|
718 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
|
719 } |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
720 } |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
721 |
6418
46d9ee79f292
Removed _ prefix from all public APIs.
Timo Sirainen <tss@iki.fi>
parents:
6411
diff
changeset
|
722 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
|
723 { |
7151
2ced9dd8b2cc
Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents:
7150
diff
changeset
|
724 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
|
725 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
|
726 |
5110 | 727 i_assert(!client->destroyed); |
728 | |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2058
diff
changeset
|
729 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
|
730 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
|
731 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
|
732 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
|
733 |
2790
02c0b8d532c2
Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents:
2640
diff
changeset
|
734 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
|
735 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
|
736 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
|
737 } |
02c0b8d532c2
Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents:
2640
diff
changeset
|
738 |
7151
2ced9dd8b2cc
Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents:
7150
diff
changeset
|
739 /* mark all commands non-executed */ |
2ced9dd8b2cc
Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents:
7150
diff
changeset
|
740 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
|
741 cmd->temp_executed = FALSE; |
2ced9dd8b2cc
Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents:
7150
diff
changeset
|
742 |
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 o_stream_cork(client->output); |
7151
2ced9dd8b2cc
Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents:
7150
diff
changeset
|
744 if (client->output_lock != NULL) { |
2ced9dd8b2cc
Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents:
7150
diff
changeset
|
745 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
|
746 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
|
747 } |
2ced9dd8b2cc
Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents:
7150
diff
changeset
|
748 while (client->output_lock == NULL) { |
2ced9dd8b2cc
Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents:
7150
diff
changeset
|
749 /* 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
|
750 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
|
751 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
|
752 cmd = client->command_queue; |
7151
2ced9dd8b2cc
Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents:
7150
diff
changeset
|
753 for (; cmd != NULL; cmd = cmd->next) { |
2ced9dd8b2cc
Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents:
7150
diff
changeset
|
754 if (!cmd->temp_executed && |
2ced9dd8b2cc
Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents:
7150
diff
changeset
|
755 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
|
756 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
|
757 client_output_cmd(cmd); |
7151
2ced9dd8b2cc
Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents:
7150
diff
changeset
|
758 break; |
5812
71176467310e
Fixes to handling command ambiguity. Don't allow any commands that handle
Timo Sirainen <tss@iki.fi>
parents:
5805
diff
changeset
|
759 } |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
760 } |
7151
2ced9dd8b2cc
Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents:
7150
diff
changeset
|
761 if (cmd == NULL) { |
2ced9dd8b2cc
Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents:
7150
diff
changeset
|
762 /* all commands executed */ |
2ced9dd8b2cc
Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents:
7150
diff
changeset
|
763 break; |
2ced9dd8b2cc
Use more robust command calling in output handler.
Timo Sirainen <tss@iki.fi>
parents:
7150
diff
changeset
|
764 } |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
765 } |
3402
513abd166949
Changed output handler to work a bit differently to avoid useless
Timo Sirainen <tss@iki.fi>
parents:
3336
diff
changeset
|
766 o_stream_uncork(client->output); |
5110 | 767 |
768 if (client->output->closed) { | |
769 client_destroy(client, NULL); | |
770 return 1; | |
771 } else { | |
7195
bca55675d77c
When pipelining commands, delay synchronizations so that only one combined
Timo Sirainen <tss@iki.fi>
parents:
7151
diff
changeset
|
772 (void)cmd_sync_delayed(client); |
6531
d747bfbda43c
Fixed process hanging sometimes when disconnecting.
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
773 client_continue_pending_input(&client); |
5110 | 774 } |
2800 | 775 return 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
|
776 } |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2058
diff
changeset
|
777 |
0 | 778 void clients_init(void) |
779 { | |
780 my_client = NULL; | |
781 } | |
782 | |
783 void clients_deinit(void) | |
784 { | |
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
|
785 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
|
786 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
|
787 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
|
788 } |
0 | 789 } |