annotate src/imap/client.c @ 5110:ce804b173797 HEAD

Command handling fixes.
author Timo Sirainen <tss@iki.fi>
date Tue, 06 Feb 2007 14:56:12 +0200
parents b7daf0849f27
children 7413b8e0d765
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
2
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
3 #include "common.h"
532
3b53dd1280c6 I/O buffers now use real blocking instead of setting up a sub-ioloop to
Timo Sirainen <tss@iki.fi>
parents: 410
diff changeset
4 #include "ioloop.h"
164
2660a5684515 Added io_buffer_read_blocking() which can be used to read data blockingly,
Timo Sirainen <tss@iki.fi>
parents: 158
diff changeset
5 #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
6 #include "istream.h"
f57c52738f90 Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents: 720
diff changeset
7 #include "ostream.h"
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
8 #include "commands.h"
1654
31c4bb26a1e9 Getting ready for namespaces. LIST is still broken with them.
Timo Sirainen <tss@iki.fi>
parents: 1643
diff changeset
9 #include "namespace.h"
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
10
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
11 #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
12 #include <unistd.h>
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
13
903
fd8888f6f037 Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents: 807
diff changeset
14 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
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 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
17 static struct timeout *to_idle;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
18
3960
aeb424e64f24 Call io_remove() before closing the fd. It's required by kqueue.
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
19 struct client *client_create(int fd_in, int fd_out,
aeb424e64f24 Call io_remove() before closing the fd. It's required by kqueue.
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
20 struct namespace *namespaces)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
21 {
903
fd8888f6f037 Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents: 807
diff changeset
22 struct client *client;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
23
2421
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
24 /* 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
25 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
26 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
27
903
fd8888f6f037 Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents: 807
diff changeset
28 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
29 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
30 client->fd_out = fd_out;
aeb424e64f24 Call io_remove() before closing the fd. It's required by kqueue.
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
31 client->input = i_stream_create_file(fd_in, default_pool,
1591
6eca99b727a0 IMAP parser memory limits are now enforced by bytes per line rather than
Timo Sirainen <tss@iki.fi>
parents: 1538
diff changeset
32 imap_max_line_length, FALSE);
3960
aeb424e64f24 Call io_remove() before closing the fd. It's required by kqueue.
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
33 client->output = o_stream_create_file(fd_out, default_pool,
2421
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
34 (size_t)-1, FALSE);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
35
2878
904c31d74acc APPEND was using all CPU.
Timo Sirainen <tss@iki.fi>
parents: 2800
diff changeset
36 o_stream_set_flush_callback(client->output, _client_output, client);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
37
3960
aeb424e64f24 Call io_remove() before closing the fd. It's required by kqueue.
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
38 client->io = io_add(fd_in, IO_READ, _client_input, client);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
39 client->last_input = ioloop_time;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
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
4dec6a3d79fd s/custom flags/keywords/
Timo Sirainen <tss@iki.fi>
parents: 1915
diff changeset
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
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
50
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
51 i_assert(my_client == NULL);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
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
ca1c2972b78f hook changes
Timo Sirainen <tss@iki.fi>
parents: 1641
diff changeset
55 hook_client_created(&client);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
56 return client;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
57 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
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;
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
64 cmd_ret = cmd->func(cmd);
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
65 if (!cmd_ret) {
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
4096
904c53275e83 Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents: 4070
diff changeset
73 void client_destroy(struct client *client, const char *reason)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
74 {
3871
2506e4077e7a Don't crash if closing with signal while IDLEing.
Timo Sirainen <tss@iki.fi>
parents: 3866
diff changeset
75 i_assert(!client->destroyed);
2506e4077e7a Don't crash if closing with signal while IDLEing.
Timo Sirainen <tss@iki.fi>
parents: 3866
diff changeset
76 client->destroyed = TRUE;
2506e4077e7a Don't crash if closing with signal while IDLEing.
Timo Sirainen <tss@iki.fi>
parents: 3866
diff changeset
77
4096
904c53275e83 Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents: 4070
diff changeset
78 if (!client->disconnected) {
4787
62f534a0fd68 Don't crash if client disconnected while IDLEing.
Timo Sirainen <tss@iki.fi>
parents: 4773
diff changeset
79 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
80 if (reason == NULL)
904c53275e83 Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents: 4070
diff changeset
81 reason = "Disconnected";
904c53275e83 Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents: 4070
diff changeset
82 i_info("%s", reason);
904c53275e83 Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents: 4070
diff changeset
83 }
904c53275e83 Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents: 4070
diff changeset
84
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
85 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
86 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
87
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
88 /* 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
89 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
90 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
91 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
92 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
93 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
94 client_command_cancel(client->command_queue);
2501
b7eec64e0735 Deinitialize command handlers always.
Timo Sirainen <tss@iki.fi>
parents: 2462
diff changeset
95
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
96 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
97 mailbox_close(&client->mailbox);
1654
31c4bb26a1e9 Getting ready for namespaces. LIST is still broken with them.
Timo Sirainen <tss@iki.fi>
parents: 1643
diff changeset
98 namespace_deinit(client->namespaces);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
99
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
100 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
101 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
102 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
103 io_remove(&client->io);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
104
4070
71b8faa84ec6 Added i_stream_destroy() and o_stream_destroy() and used them instead of
Timo Sirainen <tss@iki.fi>
parents: 3963
diff changeset
105 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
106 o_stream_destroy(&client->output);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
107
3960
aeb424e64f24 Call io_remove() before closing the fd. It's required by kqueue.
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
108 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
109 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
110 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
111 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
112 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
113 }
aeb424e64f24 Call io_remove() before closing the fd. It's required by kqueue.
Timo Sirainen <tss@iki.fi>
parents: 3879
diff changeset
114
1958
4dec6a3d79fd s/custom flags/keywords/
Timo Sirainen <tss@iki.fi>
parents: 1915
diff changeset
115 pool_unref(client->keywords.pool);
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
116 pool_unref(client->command_pool);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
117 i_free(client);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
118
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
119 /* quit the program */
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
120 my_client = NULL;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
121 io_loop_stop(ioloop);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
122 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
123
4096
904c53275e83 Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents: 4070
diff changeset
124 void client_disconnect(struct client *client, const char *reason)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
125 {
4291
c78bd7fb7ce8 Added assert against NULL reason for client_disconnect().
Timo Sirainen <tss@iki.fi>
parents: 4096
diff changeset
126 i_assert(reason != NULL);
c78bd7fb7ce8 Added assert against NULL reason for client_disconnect().
Timo Sirainen <tss@iki.fi>
parents: 4096
diff changeset
127
4096
904c53275e83 Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents: 4070
diff changeset
128 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
129 return;
904c53275e83 Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents: 4070
diff changeset
130
904c53275e83 Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents: 4070
diff changeset
131 i_info("Disconnected: %s", reason);
904c53275e83 Log a line when IMAP client disconnects with a reason why it happened.
Timo Sirainen <tss@iki.fi>
parents: 4070
diff changeset
132 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
133 (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
134
764
f57c52738f90 Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents: 720
diff changeset
135 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
136 o_stream_close(client->output);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
137 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
138
1023
dc660f588218 Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
139 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
140 {
dc660f588218 Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
141 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
142 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
143 }
dc660f588218 Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
144
2425
8267d11cacfb LIST command interrupts itself when output buffer gets full and continues
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
145 int client_send_line(struct client *client, const char *data)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
146 {
2425
8267d11cacfb LIST command interrupts itself when output buffer gets full and continues
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
147 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
148
764
f57c52738f90 Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents: 720
diff changeset
149 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
150 return -1;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
151
2425
8267d11cacfb LIST command interrupts itself when output buffer gets full and continues
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
152 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
153 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
154 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
155 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
156
8267d11cacfb LIST command interrupts itself when output buffer gets full and continues
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
157 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
158 return -1;
8267d11cacfb LIST command interrupts itself when output buffer gets full and continues
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
159
3601
edc6e213048f client_send_line(): Try flushing output immediately if buffer gets full.
Timo Sirainen <tss@iki.fi>
parents: 3469
diff changeset
160 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
161 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
162 /* 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
163 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
164 }
edc6e213048f client_send_line(): Try flushing output immediately if buffer gets full.
Timo Sirainen <tss@iki.fi>
parents: 3469
diff changeset
165 return 1;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
166 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
167
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
168 void client_send_tagline(struct client_command_context *cmd, const char *data)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
169 {
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
170 struct client *client = cmd->client;
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
171 const char *tag = cmd->tag;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
172
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
173 if (client->output->closed || cmd->cancel)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
174 return;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
175
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
176 if (tag == NULL || *tag == '\0')
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
177 tag = "*";
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
178
807
35abd7a5d381 Buffer related cleanups. Use PATH_MAX instead of hardcoded 1024 for paths.
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
179 (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
180 (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
181 (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
182 (void)o_stream_send(client->output, "\r\n", 2);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
183 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
184
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
185 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
186 const char *msg)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
187 {
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
188 struct client *client = cmd->client;
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
189 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
190 bool fatal;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
191
1023
dc660f588218 Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
192 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
193 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
194 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
195 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
196 return;
dc660f588218 Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
197 }
dc660f588218 Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
198 }
1538
4d1c65eded2c Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents: 1499
diff changeset
199
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
200 if (cmd->tag == NULL)
1538
4d1c65eded2c Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents: 1499
diff changeset
201 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
202 else if (cmd->name == NULL)
1538
4d1c65eded2c Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents: 1499
diff changeset
203 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
204 else {
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
205 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
206 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
207 cmd_name, ": ", msg, NULL);
1538
4d1c65eded2c Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents: 1499
diff changeset
208 }
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
209
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
210 client_send_tagline(cmd, error);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
211
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
212 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
213 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
214 "Too many invalid IMAP commands.");
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
215 }
2508
467af814d5e2 Command parameter errors weren't handled right. This was broken a few
Timo Sirainen <tss@iki.fi>
parents: 2501
diff changeset
216
467af814d5e2 Command parameter errors weren't handled right. This was broken a few
Timo Sirainen <tss@iki.fi>
parents: 2501
diff changeset
217 /* 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
218 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
219 FALSE. */
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
220 cmd->param_error = TRUE;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
221 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
222
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 client_read_args(struct client_command_context *cmd, unsigned int count,
55df57c028d4 Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents: 3811
diff changeset
224 unsigned int flags, struct imap_arg **args)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
225 {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
226 int ret;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
227
1015
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 1001
diff changeset
228 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
229
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
230 ret = imap_parser_read_args(cmd->parser, count, flags, args);
720
e0825139b0f1 Maybe now?
Timo Sirainen <tss@iki.fi>
parents: 717
diff changeset
231 if (ret >= (int)count) {
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
232 /* 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
233 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
234 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
235 cmd->client->input_lock = NULL;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
236 return TRUE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
237 } else if (ret == -2) {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
238 /* need more data */
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
239 return FALSE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
240 } else {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
241 /* error, or missing arguments */
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
242 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
243 "Missing arguments");
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
244 return FALSE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
245 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
246 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
247
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
248 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
249 unsigned int count, ...)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
250 {
903
fd8888f6f037 Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents: 807
diff changeset
251 struct imap_arg *imap_args;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
252 va_list va;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
253 const char *str;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
254 unsigned int i;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
255
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
256 if (!client_read_args(cmd, count, 0, &imap_args))
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
257 return FALSE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
258
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
259 va_start(va, count);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
260 for (i = 0; i < count; i++) {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
261 const char **ret = va_arg(va, const char **);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
262
1015
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 1001
diff changeset
263 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
264 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
265 break;
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 1001
diff changeset
266 }
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 1001
diff changeset
267
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
268 str = imap_arg_string(&imap_args[i]);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
269 if (str == NULL) {
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
270 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
271 break;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
272 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
273
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
274 if (ret != NULL)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
275 *ret = str;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
276 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
277 va_end(va);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
278
1015
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 1001
diff changeset
279 return i == count;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
280 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
281
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
282 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
283 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
284 enum command_flags flags)
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
285 {
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
286 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
287
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
288 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
289 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
290 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
291 return cmd;
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
292 }
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
293 return NULL;
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
294 }
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
295
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
296 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
297 {
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
298 enum command_flags flags;
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
299 bool broken_client = FALSE;
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
300
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
301 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
302 /* 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
303 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
304 broken_client = TRUE;
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
305 } 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
306 /* 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
307 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
308 } else {
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
309 return FALSE;
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
310 }
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
311
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
312 if (client_command_find_with_flags(cmd, flags) == NULL)
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
313 return FALSE;
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
314
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
315 if (broken_client) {
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
316 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
317 "* 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
318 }
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
319
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
320 return TRUE;
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
321 }
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 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
324 client_command_new(struct client *client)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
325 {
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
326 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
327
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
328 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
329 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
330 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
331
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
332 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
333 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
334 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
335 } else {
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
336 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
337 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
338 }
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
339
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
340 /* 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
341 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
342 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
343 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
344 }
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
345 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
346 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
347
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
348 return cmd;
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
349 }
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
350
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
351 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
352 {
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
353 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
354
2421
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
355 /* 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
356 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
357 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
358
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
359 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
360 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
361 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
362 }
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
363
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
364 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
365 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
366
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
367 if (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
368 /* reset the input handler in case it was changed */
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
369 client->input_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
370 }
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
371 if (client->output_lock == cmd) {
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
372 /* reset the output handler in case it was changed */
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
373 o_stream_set_flush_callback(client->output,
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
374 _client_output, client);
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
375 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
376 }
2421
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
377
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
378 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
379 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
380 else {
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
381 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
382 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
383 }
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
384
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
385 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
386 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
387 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
388 else
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
389 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
390 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
391 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
392 cmd = NULL;
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
393
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
394 if (client->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
395 /* 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
396 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
397 }
5110
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
398 }
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
399
5110
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
400 void client_continue_pending_input(struct client *client)
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
401 {
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
402 size_t size;
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
403
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
404 i_assert(!client->handling_input);
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
405
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
406 if (client->disconnected)
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
407 return;
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
408
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
409 if (client->input_lock != NULL) {
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
410 /* there's a command that has locked the input */
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
411 if (!client->input_lock->waiting_unambiguity)
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
412 return;
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
413
5110
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
414 /* the command is waiting for existing ambiguity causing
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
415 commands to finish. */
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
416 if (client_command_check_ambiguity(client->input_lock))
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
417 return;
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
418 }
5110
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
419
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
420 if (client->io == NULL) {
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
421 i_assert(i_stream_get_fd(client->input) >= 0);
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
422 client->io = io_add(i_stream_get_fd(client->input),
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
423 IO_READ, _client_input, client);
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
424 }
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
425
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
426 /* if there's unread data in buffer, handle it. */
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
427 (void)i_stream_get_data(client->input, &size);
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
428 if (size > 0)
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
429 _client_input(client);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
430 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
431
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
432 /* Skip incoming data until newline is found,
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
433 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
434 static bool client_skip_line(struct client *client)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
435 {
410
1f0e7229ee58 Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents: 364
diff changeset
436 const unsigned char *data;
184
4223b9ed0c80 move size_t fixes
Timo Sirainen <tss@iki.fi>
parents: 164
diff changeset
437 size_t i, data_size;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
438
764
f57c52738f90 Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents: 720
diff changeset
439 data = i_stream_get_data(client->input, &data_size);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
440
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
441 for (i = 0; i < data_size; i++) {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
442 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
443 client->input_skip_line = FALSE;
1538
4d1c65eded2c Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents: 1499
diff changeset
444 i++;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
445 break;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
446 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
447 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
448
1538
4d1c65eded2c Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents: 1499
diff changeset
449 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
450 return !client->input_skip_line;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
451 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
452
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
453 static bool client_command_input(struct client_command_context *cmd)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
454 {
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
455 struct client *client = cmd->client;
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
456
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
457 if (cmd->func != NULL) {
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
458 /* 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
459 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
460 /* 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
461 client_command_free(cmd);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
462 return TRUE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
463 }
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
464
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
465 /* unfinished */
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
466 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
467 o_stream_set_flush_pending(client->output, TRUE);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
468 return FALSE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
469 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
470
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
471 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
472 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
473 if (cmd->tag == NULL)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
474 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
475 cmd->tag = p_strdup(cmd->pool, cmd->tag);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
476 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
477
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
478 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
479 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
480 if (cmd->name == NULL)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
481 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
482 cmd->name = p_strdup(cmd->pool, cmd->name);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
483 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
484
4941
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
485 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
486
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
487 if (cmd->name == '\0') {
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
488 /* command not given - cmd_func is already NULL. */
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
489 } else {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
490 /* 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
491 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
492
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
493 if (command != NULL) {
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
494 cmd->func = command->func;
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
495 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
496 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
497 /* 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
498 finished */
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
499 cmd->waiting_unambiguity = TRUE;
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
500 io_remove(&client->io);
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
501 return FALSE;
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
502 }
f612d2086448 If running commands in parallel would cause ambiguity, run them
Timo Sirainen <tss@iki.fi>
parents: 4939
diff changeset
503 }
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
504 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
505
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
506 if (cmd->func == NULL) {
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
507 /* unknown command */
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
508 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
509 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
510 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
511 return TRUE;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
512 } else {
4831
7e50162a378c Added asserts
Timo Sirainen <tss@iki.fi>
parents: 4787
diff changeset
513 i_assert(!client->disconnected);
7e50162a378c Added asserts
Timo Sirainen <tss@iki.fi>
parents: 4787
diff changeset
514
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
515 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
516 }
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
517 }
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
518
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
519 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
520 {
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
521 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
522
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
523 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
524 return client_command_input(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
525
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
526 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
527 /* 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
528 if (!client_skip_line(client))
1172
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents: 1168
diff changeset
529 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
530 client->input_skip_line = FALSE;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
531 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
532
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
533 /* 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
534 some input */
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
535 (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
536 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
537 return FALSE;
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
538
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
539 /* 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
540 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
541 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
542 /* 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
543 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
544 return FALSE;
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
545 }
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
546
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
547 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
548 return client_command_input(client->input_lock);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
549 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
550
4907
5b4c9b20eba0 Replaced void *context from a lot of callbacks with the actual context
Timo Sirainen <tss@iki.fi>
parents: 4831
diff changeset
551 void _client_input(struct client *client)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
552 {
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
553 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
554 int ret;
953
411006be3c66 Naming change for function typedefs.
Timo Sirainen <tss@iki.fi>
parents: 903
diff changeset
555
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
556 client->last_input = ioloop_time;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
557
764
f57c52738f90 Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents: 720
diff changeset
558 switch (i_stream_read(client->input)) {
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
559 case -1:
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
560 /* 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
561 client_destroy(client, NULL);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
562 return;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
563 case -2:
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
564 /* parameter word is longer than max. input buffer size.
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
565 this is most likely an error, so skip the new data
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
566 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
567 client->input_skip_line = TRUE;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
568
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
569 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
570 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
571 cmd->param_error = TRUE;
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
572 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
573 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
574 return;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
575 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
576
764
f57c52738f90 Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents: 720
diff changeset
577 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
578 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
579 do {
7e39590da48a Call t_push/t_pop around client command execution function, so if client
Timo Sirainen <tss@iki.fi>
parents: 3402
diff changeset
580 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
581 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
582 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
583 } 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
584 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
585 o_stream_uncork(client->output);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
586
764
f57c52738f90 Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents: 720
diff changeset
587 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
588 client_destroy(client, NULL);
5110
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
589 else
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
590 client_continue_pending_input(client);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
591 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
592
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
593 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
594 {
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
595 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
596 bool finished;
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
597
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
598 /* 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
599 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
600
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
601 if (!finished) {
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
602 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
603 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
604 } else {
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
605 /* 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
606 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
607 }
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
608 }
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
609
4907
5b4c9b20eba0 Replaced void *context from a lot of callbacks with the actual context
Timo Sirainen <tss@iki.fi>
parents: 4831
diff changeset
610 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
611 {
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
612 struct client_command_context *cmd;
3863
55df57c028d4 Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents: 3811
diff changeset
613 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
614
5110
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
615 i_assert(!client->destroyed);
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
616
2421
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
617 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
618
2790
02c0b8d532c2 Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents: 2640
diff changeset
619 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
620 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
621 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
622 }
02c0b8d532c2 Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents: 2640
diff changeset
623
02c0b8d532c2 Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents: 2640
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 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
626 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
627 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
628 cmd = 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
629 for (; cmd != NULL; cmd = cmd->next) {
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
630 client_output_cmd(cmd);
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
631 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
632 break;
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
633 }
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
634 }
3402
513abd166949 Changed output handler to work a bit differently to avoid useless
Timo Sirainen <tss@iki.fi>
parents: 3336
diff changeset
635 o_stream_uncork(client->output);
5110
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
636
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
637 if (client->output->closed) {
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
638 client_destroy(client, NULL);
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
639 return 1;
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
640 } else {
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
641 client_continue_pending_input(client);
ce804b173797 Command handling fixes.
Timo Sirainen <tss@iki.fi>
parents: 4994
diff changeset
642 }
2800
3f7d4af90ec1 IDLE used 100% CPU.
Timo Sirainen <tss@iki.fi>
parents: 2790
diff changeset
643 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
644 }
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
645
1036
f782b3319553 Removed useless parameters from io_callback_t and timeout_callback_t.
Timo Sirainen <tss@iki.fi>
parents: 1023
diff changeset
646 static void idle_timeout(void *context __attr_unused__)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
647 {
2421
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
648 time_t idle_time;
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
649
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
650 if (my_client == NULL)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
651 return;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
652
2421
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
653 idle_time = 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
654 I_MAX(my_client->last_input, my_client->last_output);
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
655
4939
ff2272c228cc Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents: 4907
diff changeset
656 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
657 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
658 /* 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
659 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
660 "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
661 } 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
662 /* 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
663 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
664 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
665 "* 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
666 }
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(my_client, "Disconnected for inactivity");
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
668 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
669 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
670
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
671 void clients_init(void)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
672 {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
673 my_client = NULL;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
674 to_idle = timeout_add(10000, idle_timeout, NULL);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
675 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
676
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
677 void clients_deinit(void)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
678 {
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
679 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
680 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
681 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
682 }
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
683
3879
928229f8b3e6 deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents: 3871
diff changeset
684 timeout_remove(&to_idle);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
685 }