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