Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/imap/client.c @ 6428:7cad076906eb HEAD
pool_unref() now takes ** pointer.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 16 Sep 2007 14:04:06 +0300 |
parents | 46d9ee79f292 |
children | 65c69a53a7be |
rev | line source |
---|---|
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2058
diff
changeset
|
1 /* Copyright (C) 2002-2004 Timo Sirainen */ |
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" |
5980
57b70f64f997
Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
5 #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
|
6 #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
|
7 #include "istream.h" |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
8 #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
|
9 #include "var-expand.h" |
0 | 10 #include "commands.h" |
5500
4862cb37106c
Moved namespace handling to lib-storage. Beginnings of namespace support for
Timo Sirainen <tss@iki.fi>
parents:
5415
diff
changeset
|
11 #include "mail-namespace.h" |
0 | 12 |
13 #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
|
14 #include <unistd.h> |
0 | 15 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
16 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
|
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 static struct client *my_client; /* we don't need more than one currently */ |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
19 static struct timeout *to_idle; |
0 | 20 |
3960
aeb424e64f24
Call io_remove() before closing the fd. It's required by kqueue.
Timo Sirainen <tss@iki.fi>
parents:
3879
diff
changeset
|
21 struct client *client_create(int fd_in, int fd_out, |
5500
4862cb37106c
Moved namespace handling to lib-storage. Beginnings of namespace support for
Timo Sirainen <tss@iki.fi>
parents:
5415
diff
changeset
|
22 struct mail_namespace *namespaces) |
0 | 23 { |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
24 struct client *client; |
0 | 25 |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2058
diff
changeset
|
26 /* 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
|
27 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
|
28 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
|
29 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
30 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
|
31 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
|
32 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
|
33 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
|
34 client->output = o_stream_create_fd(fd_out, (size_t)-1, FALSE); |
0 | 35 |
6418
46d9ee79f292
Removed _ prefix from all public APIs.
Timo Sirainen <tss@iki.fi>
parents:
6411
diff
changeset
|
36 o_stream_set_flush_callback(client->output, client_output, client); |
0 | 37 |
6418
46d9ee79f292
Removed _ prefix from all public APIs.
Timo Sirainen <tss@iki.fi>
parents:
6411
diff
changeset
|
38 client->io = io_add(fd_in, IO_READ, client_input, client); |
0 | 39 client->last_input = ioloop_time; |
40 | |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
41 client->command_pool = pool_alloconly_create("client command", 8192); |
1958 | 42 client->keywords.pool = pool_alloconly_create("mailbox_keywords", 512); |
1654
31c4bb26a1e9
Getting ready for namespaces. LIST is still broken with them.
Timo Sirainen <tss@iki.fi>
parents:
1643
diff
changeset
|
43 client->namespaces = namespaces; |
31c4bb26a1e9
Getting ready for namespaces. LIST is still broken with them.
Timo Sirainen <tss@iki.fi>
parents:
1643
diff
changeset
|
44 |
31c4bb26a1e9
Getting ready for namespaces. LIST is still broken with them.
Timo Sirainen <tss@iki.fi>
parents:
1643
diff
changeset
|
45 while (namespaces != NULL) { |
1915
79790750c349
importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
1654
diff
changeset
|
46 mail_storage_set_callbacks(namespaces->storage, |
79790750c349
importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
1654
diff
changeset
|
47 &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
|
48 namespaces = namespaces->next; |
31c4bb26a1e9
Getting ready for namespaces. LIST is still broken with them.
Timo Sirainen <tss@iki.fi>
parents:
1643
diff
changeset
|
49 } |
0 | 50 |
51 i_assert(my_client == NULL); | |
52 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
|
53 |
6498f3cb9d2c
Added hook_client_created and hook_mail_storage_created for modules.
Timo Sirainen <tss@iki.fi>
parents:
1591
diff
changeset
|
54 if (hook_client_created != NULL) |
1643 | 55 hook_client_created(&client); |
0 | 56 return client; |
57 } | |
58 | |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
59 void client_command_cancel(struct client_command_context *cmd) |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
60 { |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
61 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
|
62 |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
63 cmd->cancel = TRUE; |
5115
0c89a2f72f86
Don't crash if client disconnects in the middle of sending a command line.
Timo Sirainen <tss@iki.fi>
parents:
5114
diff
changeset
|
64 cmd_ret = cmd->func == NULL ? TRUE : cmd->func(cmd); |
6179
5c6af3b74d5f
If client disconnects in the middle of sending command parameters, don't
Timo Sirainen <tss@iki.fi>
parents:
6162
diff
changeset
|
65 if (!cmd_ret && !cmd->param_error) { |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
66 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
|
67 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
|
68 } else { |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
69 client_command_free(cmd); |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
70 } |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
71 } |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
72 |
5980
57b70f64f997
Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
73 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
|
74 { |
57b70f64f997
Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
75 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
|
76 { 'i', NULL }, |
57b70f64f997
Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
77 { 'o', NULL }, |
57b70f64f997
Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
78 { '\0', NULL } |
57b70f64f997
Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
79 }; |
57b70f64f997
Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
80 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
|
81 string_t *str; |
57b70f64f997
Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
82 |
57b70f64f997
Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
83 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
|
84 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
|
85 |
57b70f64f997
Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
86 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
|
87 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
|
88 |
57b70f64f997
Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
89 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
|
90 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
|
91 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
|
92 } |
57b70f64f997
Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
93 |
6309
f8c9b1a93521
If read/write to client failed with some error, log it.
Timo Sirainen <tss@iki.fi>
parents:
6210
diff
changeset
|
94 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
|
95 { |
f8c9b1a93521
If read/write to client failed with some error, log it.
Timo Sirainen <tss@iki.fi>
parents:
6210
diff
changeset
|
96 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
|
97 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
|
98 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
|
99 return errno == 0 || errno == EPIPE ? "Connection closed" : |
6310
15e10065a472
Changed disconnection reason to "Connection closed"
Timo Sirainen <tss@iki.fi>
parents:
6309
diff
changeset
|
100 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
|
101 } |
f8c9b1a93521
If read/write to client failed with some error, log it.
Timo Sirainen <tss@iki.fi>
parents:
6210
diff
changeset
|
102 |
4096
904c53275e83
Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents:
4070
diff
changeset
|
103 void client_destroy(struct client *client, const char *reason) |
0 | 104 { |
3871
2506e4077e7a
Don't crash if closing with signal while IDLEing.
Timo Sirainen <tss@iki.fi>
parents:
3866
diff
changeset
|
105 i_assert(!client->destroyed); |
2506e4077e7a
Don't crash if closing with signal while IDLEing.
Timo Sirainen <tss@iki.fi>
parents:
3866
diff
changeset
|
106 client->destroyed = TRUE; |
2506e4077e7a
Don't crash if closing with signal while IDLEing.
Timo Sirainen <tss@iki.fi>
parents:
3866
diff
changeset
|
107 |
4096
904c53275e83
Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents:
4070
diff
changeset
|
108 if (!client->disconnected) { |
4787
62f534a0fd68
Don't crash if client disconnected while IDLEing.
Timo Sirainen <tss@iki.fi>
parents:
4773
diff
changeset
|
109 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
|
110 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
|
111 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
|
112 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
|
113 } |
904c53275e83
Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents:
4070
diff
changeset
|
114 |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
115 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
|
116 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
|
117 |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
118 /* 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
|
119 if (client->output_lock != NULL) |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
120 client_command_cancel(client->output_lock); |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
121 if (client->input_lock != NULL) |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
122 client_command_cancel(client->input_lock); |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
123 while (client->command_queue != NULL) |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
124 client_command_cancel(client->command_queue); |
2501
b7eec64e0735
Deinitialize command handlers always.
Timo Sirainen <tss@iki.fi>
parents:
2462
diff
changeset
|
125 |
0 | 126 if (client->mailbox != NULL) |
3879
928229f8b3e6
deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents:
3871
diff
changeset
|
127 mailbox_close(&client->mailbox); |
5500
4862cb37106c
Moved namespace handling to lib-storage. Beginnings of namespace support for
Timo Sirainen <tss@iki.fi>
parents:
5415
diff
changeset
|
128 mail_namespaces_deinit(&client->namespaces); |
0 | 129 |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
130 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
|
131 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
|
132 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
|
133 io_remove(&client->io); |
0 | 134 |
4070
71b8faa84ec6
Added i_stream_destroy() and o_stream_destroy() and used them instead of
Timo Sirainen <tss@iki.fi>
parents:
3963
diff
changeset
|
135 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
|
136 o_stream_destroy(&client->output); |
0 | 137 |
3960
aeb424e64f24
Call io_remove() before closing the fd. It's required by kqueue.
Timo Sirainen <tss@iki.fi>
parents:
3879
diff
changeset
|
138 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
|
139 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
|
140 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
|
141 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
|
142 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
|
143 } |
aeb424e64f24
Call io_remove() before closing the fd. It's required by kqueue.
Timo Sirainen <tss@iki.fi>
parents:
3879
diff
changeset
|
144 |
6428
7cad076906eb
pool_unref() now takes ** pointer.
Timo Sirainen <tss@iki.fi>
parents:
6418
diff
changeset
|
145 pool_unref(&client->keywords.pool); |
7cad076906eb
pool_unref() now takes ** pointer.
Timo Sirainen <tss@iki.fi>
parents:
6418
diff
changeset
|
146 pool_unref(&client->command_pool); |
0 | 147 i_free(client); |
148 | |
149 /* quit the program */ | |
150 my_client = NULL; | |
151 io_loop_stop(ioloop); | |
152 } | |
153 | |
4096
904c53275e83
Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents:
4070
diff
changeset
|
154 void client_disconnect(struct client *client, const char *reason) |
0 | 155 { |
4291
c78bd7fb7ce8
Added assert against NULL reason for client_disconnect().
Timo Sirainen <tss@iki.fi>
parents:
4096
diff
changeset
|
156 i_assert(reason != NULL); |
c78bd7fb7ce8
Added assert against NULL reason for client_disconnect().
Timo Sirainen <tss@iki.fi>
parents:
4096
diff
changeset
|
157 |
4096
904c53275e83
Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents:
4070
diff
changeset
|
158 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
|
159 return; |
904c53275e83
Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents:
4070
diff
changeset
|
160 |
5980
57b70f64f997
Added imap_logout_format setting with default to bytes=%i/%o
Timo Sirainen <tss@iki.fi>
parents:
5835
diff
changeset
|
161 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
|
162 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
|
163 (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
|
164 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
165 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
|
166 o_stream_close(client->output); |
0 | 167 } |
168 | |
1023
dc660f588218
Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents:
1015
diff
changeset
|
169 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
|
170 { |
dc660f588218
Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents:
1015
diff
changeset
|
171 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
|
172 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
|
173 } |
dc660f588218
Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents:
1015
diff
changeset
|
174 |
2425
8267d11cacfb
LIST command interrupts itself when output buffer gets full and continues
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
175 int client_send_line(struct client *client, const char *data) |
0 | 176 { |
2425
8267d11cacfb
LIST command interrupts itself when output buffer gets full and continues
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
177 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
|
178 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
179 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
|
180 return -1; |
0 | 181 |
2425
8267d11cacfb
LIST command interrupts itself when output buffer gets full and continues
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
182 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
|
183 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
|
184 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
|
185 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
|
186 |
8267d11cacfb
LIST command interrupts itself when output buffer gets full and continues
Timo Sirainen <tss@iki.fi>
parents:
2421
diff
changeset
|
187 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
|
188 return -1; |
5367
fab770c51321
Keep better track of client->last_output timestamp.
Timo Sirainen <tss@iki.fi>
parents:
5331
diff
changeset
|
189 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
|
190 |
3601
edc6e213048f
client_send_line(): Try flushing output immediately if buffer gets full.
Timo Sirainen <tss@iki.fi>
parents:
3469
diff
changeset
|
191 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
|
192 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
|
193 /* 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
|
194 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
|
195 } |
edc6e213048f
client_send_line(): Try flushing output immediately if buffer gets full.
Timo Sirainen <tss@iki.fi>
parents:
3469
diff
changeset
|
196 return 1; |
0 | 197 } |
198 | |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
199 void client_send_tagline(struct client_command_context *cmd, const char *data) |
0 | 200 { |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
201 struct client *client = cmd->client; |
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
202 const char *tag = cmd->tag; |
0 | 203 |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
204 if (client->output->closed || cmd->cancel) |
0 | 205 return; |
206 | |
207 if (tag == NULL || *tag == '\0') | |
208 tag = "*"; | |
209 | |
807
35abd7a5d381
Buffer related cleanups. Use PATH_MAX instead of hardcoded 1024 for paths.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
210 (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
|
211 (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
|
212 (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
|
213 (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
|
214 |
fab770c51321
Keep better track of client->last_output timestamp.
Timo Sirainen <tss@iki.fi>
parents:
5331
diff
changeset
|
215 client->last_output = ioloop_time; |
0 | 216 } |
217 | |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
218 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
|
219 const char *msg) |
0 | 220 { |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
221 struct client *client = cmd->client; |
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
222 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
|
223 bool fatal; |
0 | 224 |
1023
dc660f588218
Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents:
1015
diff
changeset
|
225 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
|
226 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
|
227 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
|
228 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
|
229 return; |
dc660f588218
Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents:
1015
diff
changeset
|
230 } |
dc660f588218
Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents:
1015
diff
changeset
|
231 } |
1538
4d1c65eded2c
Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents:
1499
diff
changeset
|
232 |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
233 if (cmd->tag == NULL) |
1538
4d1c65eded2c
Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents:
1499
diff
changeset
|
234 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
|
235 else if (cmd->name == NULL) |
1538
4d1c65eded2c
Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents:
1499
diff
changeset
|
236 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
|
237 else { |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
238 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
|
239 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
|
240 cmd_name, ": ", msg, NULL); |
1538
4d1c65eded2c
Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents:
1499
diff
changeset
|
241 } |
0 | 242 |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
243 client_send_tagline(cmd, error); |
0 | 244 |
245 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
|
246 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
|
247 "Too many invalid IMAP commands."); |
0 | 248 } |
2508
467af814d5e2
Command parameter errors weren't handled right. This was broken a few
Timo Sirainen <tss@iki.fi>
parents:
2501
diff
changeset
|
249 |
467af814d5e2
Command parameter errors weren't handled right. This was broken a few
Timo Sirainen <tss@iki.fi>
parents:
2501
diff
changeset
|
250 /* 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
|
251 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
|
252 FALSE. */ |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
253 cmd->param_error = TRUE; |
0 | 254 } |
255 | |
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
|
256 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
|
257 unsigned int flags, const struct imap_arg **args_r) |
0 | 258 { |
259 int ret; | |
260 | |
1015
40a327d356de
Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents:
1001
diff
changeset
|
261 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
|
262 |
5835
d59ed6a31b66
Added more consts to imap-parser API
Timo Sirainen <tss@iki.fi>
parents:
5812
diff
changeset
|
263 ret = imap_parser_read_args(cmd->parser, count, flags, args_r); |
720 | 264 if (ret >= (int)count) { |
0 | 265 /* 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
|
266 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
|
267 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
|
268 cmd->client->input_lock = NULL; |
0 | 269 return TRUE; |
270 } else if (ret == -2) { | |
271 /* 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
|
272 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
|
273 /* disconnected */ |
5c6af3b74d5f
If client disconnects in the middle of sending command parameters, don't
Timo Sirainen <tss@iki.fi>
parents:
6162
diff
changeset
|
274 cmd->param_error = TRUE; |
5c6af3b74d5f
If client disconnects in the middle of sending command parameters, don't
Timo Sirainen <tss@iki.fi>
parents:
6162
diff
changeset
|
275 } |
0 | 276 return FALSE; |
277 } else { | |
278 /* error, or missing arguments */ | |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
279 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
|
280 "Missing arguments"); |
0 | 281 return FALSE; |
282 } | |
283 } | |
284 | |
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
|
285 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
|
286 unsigned int count, ...) |
0 | 287 { |
5835
d59ed6a31b66
Added more consts to imap-parser API
Timo Sirainen <tss@iki.fi>
parents:
5812
diff
changeset
|
288 const struct imap_arg *imap_args; |
0 | 289 va_list va; |
290 const char *str; | |
291 unsigned int i; | |
292 | |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
293 if (!client_read_args(cmd, count, 0, &imap_args)) |
0 | 294 return FALSE; |
295 | |
296 va_start(va, count); | |
297 for (i = 0; i < count; i++) { | |
298 const char **ret = va_arg(va, const char **); | |
299 | |
1015
40a327d356de
Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents:
1001
diff
changeset
|
300 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
|
301 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
|
302 break; |
40a327d356de
Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents:
1001
diff
changeset
|
303 } |
40a327d356de
Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents:
1001
diff
changeset
|
304 |
0 | 305 str = imap_arg_string(&imap_args[i]); |
306 if (str == NULL) { | |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
307 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
|
308 break; |
0 | 309 } |
310 | |
311 if (ret != NULL) | |
312 *ret = str; | |
313 } | |
314 va_end(va); | |
315 | |
1015
40a327d356de
Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents:
1001
diff
changeset
|
316 return i == count; |
0 | 317 } |
318 | |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
319 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
|
320 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
|
321 enum command_flags flags) |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
322 { |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
323 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
|
324 |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
325 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
|
326 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
|
327 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
|
328 return cmd; |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
329 } |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
330 return NULL; |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
331 } |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
332 |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
333 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
|
334 { |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
335 enum command_flags flags; |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
336 bool broken_client = FALSE; |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
337 |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
338 if ((cmd->cmd_flags & COMMAND_FLAG_USES_SEQS) != 0) { |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
339 /* 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
|
340 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
|
341 broken_client = TRUE; |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
342 } 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
|
343 /* 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
|
344 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
|
345 } else { |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
346 return FALSE; |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
347 } |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
348 |
5812
71176467310e
Fixes to handling command ambiguity. Don't allow any commands that handle
Timo Sirainen <tss@iki.fi>
parents:
5805
diff
changeset
|
349 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
|
350 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
|
351 /* 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
|
352 return TRUE; |
71176467310e
Fixes to handling command ambiguity. Don't allow any commands that handle
Timo Sirainen <tss@iki.fi>
parents:
5805
diff
changeset
|
353 } |
4941
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
354 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
|
355 } |
4941
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
356 |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
357 if (broken_client) { |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
358 client_send_line(cmd->client, |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
359 "* BAD Command pipelining results in ambiguity."); |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
360 } |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
361 |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
362 return TRUE; |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
363 } |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
364 |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
365 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
|
366 client_command_new(struct client *client) |
0 | 367 { |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
368 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
|
369 |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
370 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
|
371 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
|
372 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
|
373 |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
374 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
|
375 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
|
376 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
|
377 } else { |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
378 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
|
379 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
|
380 } |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
381 |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
382 /* add to beginning of the queue */ |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
383 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
|
384 client->command_queue->prev = cmd; |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
385 cmd->next = client->command_queue; |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
386 } |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
387 client->command_queue = cmd; |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
388 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
|
389 |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
390 return cmd; |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
391 } |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
392 |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
393 void client_command_free(struct client_command_context *cmd) |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
394 { |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
395 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
|
396 |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2058
diff
changeset
|
397 /* 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
|
398 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
|
399 client->last_input = ioloop_time; |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2058
diff
changeset
|
400 |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
401 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
|
402 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
|
403 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
|
404 } |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
405 |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
406 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
|
407 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
|
408 |
5415 | 409 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
|
410 client->input_lock = NULL; |
5415 | 411 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
|
412 client->output_lock = NULL; |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2058
diff
changeset
|
413 |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
414 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
|
415 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
|
416 else { |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
417 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
|
418 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
|
419 } |
0 | 420 |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
421 client->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
|
422 if (cmd->prev != NULL) |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
423 cmd->prev->next = cmd->next; |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
424 else |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
425 client->command_queue = cmd->next; |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
426 if (cmd->next != NULL) |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
427 cmd->next->prev = cmd->prev; |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
428 cmd = NULL; |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
429 |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
430 if (client->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
|
431 /* 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
|
432 p_clear(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
|
433 } |
5110 | 434 } |
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
|
435 |
5114 | 436 static void client_add_missing_io(struct client *client) |
437 { | |
5196 | 438 if (client->io == NULL && !client->disconnected) { |
439 client->io = io_add(client->fd_in, | |
6418
46d9ee79f292
Removed _ prefix from all public APIs.
Timo Sirainen <tss@iki.fi>
parents:
6411
diff
changeset
|
440 IO_READ, client_input, client); |
5114 | 441 } |
442 } | |
443 | |
5110 | 444 void client_continue_pending_input(struct client *client) |
445 { | |
446 size_t size; | |
447 | |
448 i_assert(!client->handling_input); | |
449 | |
450 if (client->disconnected) | |
451 return; | |
452 | |
453 if (client->input_lock != NULL) { | |
454 /* there's a command that has locked the input */ | |
455 if (!client->input_lock->waiting_unambiguity) | |
456 return; | |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
457 |
5110 | 458 /* the command is waiting for existing ambiguity causing |
459 commands to finish. */ | |
460 if (client_command_check_ambiguity(client->input_lock)) | |
461 return; | |
5812
71176467310e
Fixes to handling command ambiguity. Don't allow any commands that handle
Timo Sirainen <tss@iki.fi>
parents:
5805
diff
changeset
|
462 client->input_lock->waiting_unambiguity = FALSE; |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
463 } |
5110 | 464 |
5114 | 465 client_add_missing_io(client); |
5110 | 466 |
467 /* if there's unread data in buffer, handle it. */ | |
468 (void)i_stream_get_data(client->input, &size); | |
469 if (size > 0) | |
6418
46d9ee79f292
Removed _ prefix from all public APIs.
Timo Sirainen <tss@iki.fi>
parents:
6411
diff
changeset
|
470 client_input(client); |
0 | 471 } |
472 | |
473 /* Skip incoming data until newline is found, | |
474 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
|
475 static bool client_skip_line(struct client *client) |
0 | 476 { |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
364
diff
changeset
|
477 const unsigned char *data; |
184 | 478 size_t i, data_size; |
0 | 479 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
480 data = i_stream_get_data(client->input, &data_size); |
0 | 481 |
482 for (i = 0; i < data_size; i++) { | |
483 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
|
484 client->input_skip_line = FALSE; |
1538
4d1c65eded2c
Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents:
1499
diff
changeset
|
485 i++; |
0 | 486 break; |
487 } | |
488 } | |
489 | |
1538
4d1c65eded2c
Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents:
1499
diff
changeset
|
490 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
|
491 return !client->input_skip_line; |
0 | 492 } |
493 | |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
494 static bool client_command_input(struct client_command_context *cmd) |
0 | 495 { |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
496 struct client *client = cmd->client; |
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
497 |
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
498 if (cmd->func != NULL) { |
0 | 499 /* command is being executed - continue it */ |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
500 if (cmd->func(cmd) || cmd->param_error) { |
717
3f817df5eba4
Input parsing was a bit broken in some conditions. Mostly visible with
Timo Sirainen <tss@iki.fi>
parents:
674
diff
changeset
|
501 /* command execution was finished */ |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
502 client_command_free(cmd); |
5114 | 503 client_add_missing_io(client); |
0 | 504 return TRUE; |
505 } | |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
506 |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
507 /* unfinished */ |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
508 if (cmd->output_pending) |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
509 o_stream_set_flush_pending(client->output, TRUE); |
0 | 510 return FALSE; |
511 } | |
512 | |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
513 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
|
514 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
|
515 if (cmd->tag == NULL) |
0 | 516 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
|
517 cmd->tag = p_strdup(cmd->pool, cmd->tag); |
0 | 518 } |
519 | |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
520 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
|
521 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
|
522 if (cmd->name == NULL) |
0 | 523 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
|
524 cmd->name = p_strdup(cmd->pool, cmd->name); |
0 | 525 } |
526 | |
4941
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
527 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
|
528 |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
529 if (cmd->name == '\0') { |
0 | 530 /* command not given - cmd_func is already NULL. */ |
531 } else { | |
532 /* find the command function */ | |
4941
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
533 struct command *command = command_find(cmd->name); |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
534 |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
535 if (command != NULL) { |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
536 cmd->func = command->func; |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
537 cmd->cmd_flags = command->flags; |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
538 if (client_command_check_ambiguity(cmd)) { |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
539 /* do nothing until existing commands are |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
540 finished */ |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
541 cmd->waiting_unambiguity = TRUE; |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
542 io_remove(&client->io); |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
543 return FALSE; |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
544 } |
f612d2086448
If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents:
4939
diff
changeset
|
545 } |
0 | 546 } |
547 | |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
548 if (cmd->func == NULL) { |
0 | 549 /* unknown command */ |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
550 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
|
551 cmd->param_error = TRUE; |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
552 client_command_free(cmd); |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
553 return TRUE; |
0 | 554 } else { |
4831 | 555 i_assert(!client->disconnected); |
556 | |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
557 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
|
558 } |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
559 } |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
560 |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
561 static bool client_handle_next_command(struct client *client) |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
562 { |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
563 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
|
564 |
5812
71176467310e
Fixes to handling command ambiguity. Don't allow any commands that handle
Timo Sirainen <tss@iki.fi>
parents:
5805
diff
changeset
|
565 if (client->input_lock != NULL) { |
71176467310e
Fixes to handling command ambiguity. Don't allow any commands that handle
Timo Sirainen <tss@iki.fi>
parents:
5805
diff
changeset
|
566 if (client->input_lock->waiting_unambiguity) |
71176467310e
Fixes to handling command ambiguity. Don't allow any commands that handle
Timo Sirainen <tss@iki.fi>
parents:
5805
diff
changeset
|
567 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
|
568 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
|
569 } |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
570 |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
571 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
|
572 /* 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
|
573 if (!client_skip_line(client)) |
1172 | 574 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
|
575 client->input_skip_line = FALSE; |
0 | 576 } |
577 | |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
578 /* 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
|
579 some input */ |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
580 (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
|
581 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
|
582 return FALSE; |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
583 |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
584 /* 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
|
585 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
|
586 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
|
587 /* wait for some of the commands to finish */ |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
588 io_remove(&client->io); |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
589 return FALSE; |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
590 } |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
591 |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
592 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
|
593 return client_command_input(client->input_lock); |
0 | 594 } |
595 | |
6418
46d9ee79f292
Removed _ prefix from all public APIs.
Timo Sirainen <tss@iki.fi>
parents:
6411
diff
changeset
|
596 void client_input(struct client *client) |
0 | 597 { |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
598 struct client_command_context *cmd; |
3469
7e39590da48a
Call t_push/t_pop around client command execution function, so if client
Timo Sirainen <tss@iki.fi>
parents:
3402
diff
changeset
|
599 int ret; |
953
411006be3c66
Naming change for function typedefs.
Timo Sirainen <tss@iki.fi>
parents:
903
diff
changeset
|
600 |
5114 | 601 i_assert(client->io != NULL); |
602 | |
0 | 603 client->last_input = ioloop_time; |
604 | |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
605 switch (i_stream_read(client->input)) { |
0 | 606 case -1: |
607 /* 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
|
608 client_destroy(client, NULL); |
0 | 609 return; |
610 case -2: | |
611 /* parameter word is longer than max. input buffer size. | |
612 this is most likely an error, so skip the new data | |
613 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
|
614 client->input_skip_line = TRUE; |
0 | 615 |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
616 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
|
617 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
|
618 cmd->param_error = TRUE; |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
2979
diff
changeset
|
619 client_send_command_error(cmd, "Too long argument."); |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
620 client_command_free(cmd); |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
621 return; |
0 | 622 } |
623 | |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
624 o_stream_cork(client->output); |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
625 client->handling_input = TRUE; |
3469
7e39590da48a
Call t_push/t_pop around client command execution function, so if client
Timo Sirainen <tss@iki.fi>
parents:
3402
diff
changeset
|
626 do { |
7e39590da48a
Call t_push/t_pop around client command execution function, so if client
Timo Sirainen <tss@iki.fi>
parents:
3402
diff
changeset
|
627 t_push(); |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
628 ret = client_handle_next_command(client); |
3469
7e39590da48a
Call t_push/t_pop around client command execution function, so if client
Timo Sirainen <tss@iki.fi>
parents:
3402
diff
changeset
|
629 t_pop(); |
4994
b7daf0849f27
Don't assert-crash if a command is waiting in queue after we've disconnected the client for some reason.
Timo Sirainen <tss@iki.fi>
parents:
4941
diff
changeset
|
630 } while (ret && !client->disconnected); |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
631 client->handling_input = FALSE; |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2058
diff
changeset
|
632 o_stream_uncork(client->output); |
0 | 633 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
634 if (client->output->closed) |
4096
904c53275e83
Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents:
4070
diff
changeset
|
635 client_destroy(client, NULL); |
5110 | 636 else |
5331
e505fa0cecdc
Fixed infinite looping in some conditions
Timo Sirainen <tss@iki.fi>
parents:
5196
diff
changeset
|
637 client_add_missing_io(client); |
0 | 638 } |
639 | |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
640 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
|
641 { |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
642 struct client *client = cmd->client; |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
643 bool finished; |
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 /* continue processing command */ |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
646 finished = cmd->func(cmd) || 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
|
647 |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
648 if (!finished) { |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
649 if (cmd->output_pending) |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
650 o_stream_set_flush_pending(client->output, TRUE); |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
651 } else { |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
652 /* command execution was finished */ |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
653 client_command_free(cmd); |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
654 } |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
655 } |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
656 |
6418
46d9ee79f292
Removed _ prefix from all public APIs.
Timo Sirainen <tss@iki.fi>
parents:
6411
diff
changeset
|
657 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
|
658 { |
5415 | 659 struct client_command_context *cmd, *next; |
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
|
660 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
|
661 |
5110 | 662 i_assert(!client->destroyed); |
663 | |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2058
diff
changeset
|
664 client->last_output = ioloop_time; |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2058
diff
changeset
|
665 |
2790
02c0b8d532c2
Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents:
2640
diff
changeset
|
666 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
|
667 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
|
668 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
|
669 } |
02c0b8d532c2
Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents:
2640
diff
changeset
|
670 |
02c0b8d532c2
Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents:
2640
diff
changeset
|
671 o_stream_cork(client->output); |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
672 if (client->output_lock != NULL) |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
673 client_output_cmd(client->output_lock); |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
674 if (client->output_lock == NULL) { |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
675 cmd = client->command_queue; |
5415 | 676 for (; cmd != NULL; cmd = next) { |
677 next = cmd->next; | |
5812
71176467310e
Fixes to handling command ambiguity. Don't allow any commands that handle
Timo Sirainen <tss@iki.fi>
parents:
5805
diff
changeset
|
678 if (!cmd->waiting_unambiguity) { |
71176467310e
Fixes to handling command ambiguity. Don't allow any commands that handle
Timo Sirainen <tss@iki.fi>
parents:
5805
diff
changeset
|
679 client_output_cmd(cmd); |
71176467310e
Fixes to handling command ambiguity. Don't allow any commands that handle
Timo Sirainen <tss@iki.fi>
parents:
5805
diff
changeset
|
680 if (client->output_lock != NULL) |
71176467310e
Fixes to handling command ambiguity. Don't allow any commands that handle
Timo Sirainen <tss@iki.fi>
parents:
5805
diff
changeset
|
681 break; |
71176467310e
Fixes to handling command ambiguity. Don't allow any commands that handle
Timo Sirainen <tss@iki.fi>
parents:
5805
diff
changeset
|
682 } |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
683 } |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
684 } |
3402
513abd166949
Changed output handler to work a bit differently to avoid useless
Timo Sirainen <tss@iki.fi>
parents:
3336
diff
changeset
|
685 o_stream_uncork(client->output); |
5110 | 686 |
687 if (client->output->closed) { | |
688 client_destroy(client, NULL); | |
689 return 1; | |
690 } else { | |
691 client_continue_pending_input(client); | |
692 } | |
2800 | 693 return ret; |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2058
diff
changeset
|
694 } |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2058
diff
changeset
|
695 |
6411
6a64e64fa3a3
Renamed __attr_*__ to ATTR_*. Renamed __attrs_used__ to ATTRS_DEFINED.
Timo Sirainen <tss@iki.fi>
parents:
6391
diff
changeset
|
696 static void idle_timeout(void *context ATTR_UNUSED) |
0 | 697 { |
5805
3fd09104fd77
Changes sent by IDLE shouldn't affect the client's inactivity timeout
Timo Sirainen <tss@iki.fi>
parents:
5500
diff
changeset
|
698 time_t idle_time, last_change; |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2058
diff
changeset
|
699 |
0 | 700 if (my_client == NULL) |
701 return; | |
702 | |
6210
da3c8d825f5c
Client is now never disconnected in IDLE because it hasn't sent anything.
Timo Sirainen <tss@iki.fi>
parents:
6179
diff
changeset
|
703 last_change = I_MAX(my_client->last_input, my_client->last_output); |
5805
3fd09104fd77
Changes sent by IDLE shouldn't affect the client's inactivity timeout
Timo Sirainen <tss@iki.fi>
parents:
5500
diff
changeset
|
704 idle_time = ioloop_time - last_change; |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2058
diff
changeset
|
705 |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
706 if (o_stream_get_buffer_used_size(my_client->output) > 0 && |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2058
diff
changeset
|
707 idle_time >= CLIENT_OUTPUT_TIMEOUT) { |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2058
diff
changeset
|
708 /* client isn't reading our output */ |
4096
904c53275e83
Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents:
4070
diff
changeset
|
709 client_destroy(my_client, "Disconnected for inactivity " |
904c53275e83
Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents:
4070
diff
changeset
|
710 "in reading our 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
|
711 } else if (idle_time >= CLIENT_IDLE_TIMEOUT) { |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2058
diff
changeset
|
712 /* client isn't sending us anything */ |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
713 if (my_client->output_lock == NULL) { |
2421
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2058
diff
changeset
|
714 client_send_line(my_client, |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2058
diff
changeset
|
715 "* BYE Disconnected for inactivity."); |
d141e1bfdd63
We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents:
2058
diff
changeset
|
716 } |
4096
904c53275e83
Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents:
4070
diff
changeset
|
717 client_destroy(my_client, "Disconnected for inactivity"); |
0 | 718 } |
719 } | |
720 | |
721 void clients_init(void) | |
722 { | |
723 my_client = NULL; | |
724 to_idle = timeout_add(10000, idle_timeout, NULL); | |
725 } | |
726 | |
727 void clients_deinit(void) | |
728 { | |
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
|
729 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
|
730 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
|
731 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
|
732 } |
0 | 733 |
3879
928229f8b3e6
deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents:
3871
diff
changeset
|
734 timeout_remove(&to_idle); |
0 | 735 } |