Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/imap/client.c @ 953:411006be3c66 HEAD
Naming change for function typedefs.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 11 Jan 2003 21:55:56 +0200 |
parents | fd8888f6f037 |
children | fb9c95a8847f |
rev | line source |
---|---|
0 | 1 /* Copyright (C) 2002 Timo Sirainen */ |
2 | |
3 #include "common.h" | |
532
3b53dd1280c6
I/O buffers now use real blocking instead of setting up a sub-ioloop to
Timo Sirainen <tss@iki.fi>
parents:
410
diff
changeset
|
4 #include "ioloop.h" |
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 | 8 #include "commands.h" |
9 | |
10 #include <stdlib.h> | |
11 | |
12 /* max. size of one parameter in line */ | |
13 #define MAX_INBUF_SIZE 8192 | |
14 | |
768
8b3518bb327e
Limited max. command argument elements to 128. Added more verbose error
Timo Sirainen <tss@iki.fi>
parents:
764
diff
changeset
|
15 /* max. number of IMAP argument elements to accept. The maximum memory usage |
8b3518bb327e
Limited max. command argument elements to 128. Added more verbose error
Timo Sirainen <tss@iki.fi>
parents:
764
diff
changeset
|
16 for command from user is around MAX_INBUF_SIZE * MAX_IMAP_ARG_ELEMENTS */ |
8b3518bb327e
Limited max. command argument elements to 128. Added more verbose error
Timo Sirainen <tss@iki.fi>
parents:
764
diff
changeset
|
17 #define MAX_IMAP_ARG_ELEMENTS 128 |
8b3518bb327e
Limited max. command argument elements to 128. Added more verbose error
Timo Sirainen <tss@iki.fi>
parents:
764
diff
changeset
|
18 |
0 | 19 /* If we can't send a buffer in a minute, disconnect the client */ |
20 #define CLIENT_OUTPUT_TIMEOUT (60*1000) | |
21 | |
164
2660a5684515
Added io_buffer_read_blocking() which can be used to read data blockingly,
Timo Sirainen <tss@iki.fi>
parents:
158
diff
changeset
|
22 /* If we don't soon receive expected data from client while processing |
2660a5684515
Added io_buffer_read_blocking() which can be used to read data blockingly,
Timo Sirainen <tss@iki.fi>
parents:
158
diff
changeset
|
23 a command, disconnect the client */ |
2660a5684515
Added io_buffer_read_blocking() which can be used to read data blockingly,
Timo Sirainen <tss@iki.fi>
parents:
158
diff
changeset
|
24 #define CLIENT_CMDINPUT_TIMEOUT CLIENT_OUTPUT_TIMEOUT |
2660a5684515
Added io_buffer_read_blocking() which can be used to read data blockingly,
Timo Sirainen <tss@iki.fi>
parents:
158
diff
changeset
|
25 |
0 | 26 /* Disconnect client when it sends too many bad commands */ |
27 #define CLIENT_MAX_BAD_COMMANDS 20 | |
28 | |
29 /* Disconnect client after idling this many seconds */ | |
30 #define CLIENT_IDLE_TIMEOUT (60*30) | |
31 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
32 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
|
33 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
34 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
|
35 static struct timeout *to_idle; |
0 | 36 |
953
411006be3c66
Naming change for function typedefs.
Timo Sirainen <tss@iki.fi>
parents:
903
diff
changeset
|
37 static void client_input(void *context, int fd __attr_unused__, |
411006be3c66
Naming change for function typedefs.
Timo Sirainen <tss@iki.fi>
parents:
903
diff
changeset
|
38 struct io *io __attr_unused__); |
0 | 39 |
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
|
40 static void client_output_timeout(void *context) |
0 | 41 { |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
42 struct client *client = context; |
164
2660a5684515
Added io_buffer_read_blocking() which can be used to read data blockingly,
Timo Sirainen <tss@iki.fi>
parents:
158
diff
changeset
|
43 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
44 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
|
45 o_stream_close(client->output); |
0 | 46 } |
47 | |
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
|
48 static void client_input_timeout(void *context) |
164
2660a5684515
Added io_buffer_read_blocking() which can be used to read data blockingly,
Timo Sirainen <tss@iki.fi>
parents:
158
diff
changeset
|
49 { |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
50 struct client *client = context; |
164
2660a5684515
Added io_buffer_read_blocking() which can be used to read data blockingly,
Timo Sirainen <tss@iki.fi>
parents:
158
diff
changeset
|
51 |
2660a5684515
Added io_buffer_read_blocking() which can be used to read data blockingly,
Timo Sirainen <tss@iki.fi>
parents:
158
diff
changeset
|
52 client_send_line(my_client, "* BYE Disconnected for inactivity " |
2660a5684515
Added io_buffer_read_blocking() which can be used to read data blockingly,
Timo Sirainen <tss@iki.fi>
parents:
158
diff
changeset
|
53 "while waiting for command data."); |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
54 o_stream_close(client->output); |
164
2660a5684515
Added io_buffer_read_blocking() which can be used to read data blockingly,
Timo Sirainen <tss@iki.fi>
parents:
158
diff
changeset
|
55 } |
2660a5684515
Added io_buffer_read_blocking() which can be used to read data blockingly,
Timo Sirainen <tss@iki.fi>
parents:
158
diff
changeset
|
56 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
57 struct client *client_create(int hin, int hout, struct mail_storage *storage) |
0 | 58 { |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
59 struct client *client; |
0 | 60 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
61 client = i_new(struct client, 1); |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
62 client->input = i_stream_create_file(hin, default_pool, |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
364
diff
changeset
|
63 MAX_INBUF_SIZE, FALSE); |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
64 client->output = o_stream_create_file(hout, default_pool, 4096, |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
364
diff
changeset
|
65 IO_PRIORITY_DEFAULT, FALSE); |
0 | 66 |
164
2660a5684515
Added io_buffer_read_blocking() which can be used to read data blockingly,
Timo Sirainen <tss@iki.fi>
parents:
158
diff
changeset
|
67 /* set timeout for reading expected data (eg. APPEND). This is |
2660a5684515
Added io_buffer_read_blocking() which can be used to read data blockingly,
Timo Sirainen <tss@iki.fi>
parents:
158
diff
changeset
|
68 different from the actual idle time. */ |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
69 i_stream_set_blocking(client->input, CLIENT_CMDINPUT_TIMEOUT, |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
364
diff
changeset
|
70 client_input_timeout, client); |
0 | 71 |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
364
diff
changeset
|
72 /* set timeout for sending data */ |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
73 o_stream_set_blocking(client->output, CLIENT_OUTPUT_TIMEOUT, |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
364
diff
changeset
|
74 client_output_timeout, client); |
0 | 75 |
953
411006be3c66
Naming change for function typedefs.
Timo Sirainen <tss@iki.fi>
parents:
903
diff
changeset
|
76 client->io = io_add(hin, IO_READ, client_input, client); |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
77 client->parser = imap_parser_create(client->input, client->output, |
768
8b3518bb327e
Limited max. command argument elements to 128. Added more verbose error
Timo Sirainen <tss@iki.fi>
parents:
764
diff
changeset
|
78 MAX_INBUF_SIZE, |
8b3518bb327e
Limited max. command argument elements to 128. Added more verbose error
Timo Sirainen <tss@iki.fi>
parents:
764
diff
changeset
|
79 MAX_IMAP_ARG_ELEMENTS); |
0 | 80 client->last_input = ioloop_time; |
81 | |
82 client->storage = storage; | |
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
|
83 storage->set_callbacks(storage, &mail_storage_callbacks, client); |
0 | 84 |
85 i_assert(my_client == NULL); | |
86 my_client = client; | |
87 return client; | |
88 } | |
89 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
90 void client_destroy(struct client *client) |
0 | 91 { |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
92 o_stream_flush(client->output); |
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
|
93 |
0 | 94 if (client->mailbox != NULL) |
95 client->mailbox->close(client->mailbox); | |
96 mail_storage_destroy(client->storage); | |
97 | |
98 imap_parser_destroy(client->parser); | |
99 io_remove(client->io); | |
100 | |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
101 i_stream_unref(client->input); |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
102 o_stream_unref(client->output); |
0 | 103 |
104 i_free(client); | |
105 | |
106 /* quit the program */ | |
107 my_client = NULL; | |
108 io_loop_stop(ioloop); | |
109 } | |
110 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
111 void client_disconnect(struct client *client) |
0 | 112 { |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
113 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
|
114 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
115 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
|
116 o_stream_close(client->output); |
0 | 117 } |
118 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
119 void client_send_line(struct client *client, const char *data) |
0 | 120 { |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
121 if (client->output->closed) |
0 | 122 return; |
123 | |
807
35abd7a5d381
Buffer related cleanups. Use PATH_MAX instead of hardcoded 1024 for paths.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
124 (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
|
125 (void)o_stream_send(client->output, "\r\n", 2); |
0 | 126 } |
127 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
128 void client_send_tagline(struct client *client, const char *data) |
0 | 129 { |
130 const char *tag = client->cmd_tag; | |
131 | |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
132 if (client->output->closed) |
0 | 133 return; |
134 | |
135 if (tag == NULL || *tag == '\0') | |
136 tag = "*"; | |
137 | |
807
35abd7a5d381
Buffer related cleanups. Use PATH_MAX instead of hardcoded 1024 for paths.
Timo Sirainen <tss@iki.fi>
parents:
805
diff
changeset
|
138 (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
|
139 (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
|
140 (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
|
141 (void)o_stream_send(client->output, "\r\n", 2); |
0 | 142 } |
143 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
144 void client_send_command_error(struct client *client, const char *msg) |
0 | 145 { |
146 const char *error; | |
147 | |
148 if (msg == NULL) | |
768
8b3518bb327e
Limited max. command argument elements to 128. Added more verbose error
Timo Sirainen <tss@iki.fi>
parents:
764
diff
changeset
|
149 msg = imap_parser_get_error(client->parser); |
8b3518bb327e
Limited max. command argument elements to 128. Added more verbose error
Timo Sirainen <tss@iki.fi>
parents:
764
diff
changeset
|
150 error = t_strconcat("BAD Error in IMAP command: ", msg, NULL); |
0 | 151 |
152 client->cmd_error = TRUE; | |
153 client_send_tagline(client, error); | |
154 | |
155 if (++client->bad_counter >= CLIENT_MAX_BAD_COMMANDS) { | |
156 client_send_line(client, | |
157 "* BYE Too many invalid IMAP commands."); | |
158 client_disconnect(client); | |
159 } | |
160 } | |
161 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
162 int client_read_args(struct client *client, unsigned int count, |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
163 unsigned int flags, struct imap_arg **args) |
0 | 164 { |
165 int ret; | |
166 | |
167 ret = imap_parser_read_args(client->parser, count, flags, args); | |
720 | 168 if (ret >= (int)count) { |
0 | 169 /* all parameters read successfully */ |
170 return TRUE; | |
171 } else if (ret == -2) { | |
172 /* need more data */ | |
173 return FALSE; | |
174 } else { | |
175 /* error, or missing arguments */ | |
769
f17a1f59ac3f
Fixed "Missing arguments" error msg to work again
Timo Sirainen <tss@iki.fi>
parents:
768
diff
changeset
|
176 client_send_command_error(client, ret < 0 ? NULL : |
f17a1f59ac3f
Fixed "Missing arguments" error msg to work again
Timo Sirainen <tss@iki.fi>
parents:
768
diff
changeset
|
177 "Missing arguments"); |
0 | 178 return FALSE; |
179 } | |
180 } | |
181 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
182 int client_read_string_args(struct client *client, unsigned int count, ...) |
0 | 183 { |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
184 struct imap_arg *imap_args; |
0 | 185 va_list va; |
186 const char *str; | |
187 unsigned int i; | |
188 | |
189 if (!client_read_args(client, count, 0, &imap_args)) | |
190 return FALSE; | |
191 | |
192 va_start(va, count); | |
193 for (i = 0; i < count; i++) { | |
194 const char **ret = va_arg(va, const char **); | |
195 | |
196 str = imap_arg_string(&imap_args[i]); | |
197 if (str == NULL) { | |
198 client_send_command_error(client, "Missing arguments."); | |
199 va_end(va); | |
200 return FALSE; | |
201 } | |
202 | |
203 if (ret != NULL) | |
204 *ret = str; | |
205 } | |
206 va_end(va); | |
207 | |
208 return TRUE; | |
209 } | |
210 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
211 static void client_reset_command(struct client *client) |
0 | 212 { |
213 client->cmd_tag = NULL; | |
214 client->cmd_name = NULL; | |
215 client->cmd_func = NULL; | |
216 client->cmd_error = FALSE; | |
217 client->cmd_uid = FALSE; | |
218 | |
219 imap_parser_reset(client->parser); | |
220 } | |
221 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
222 static void client_command_finished(struct client *client) |
0 | 223 { |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
224 client->input_skip_line = TRUE; |
0 | 225 client_reset_command(client); |
226 } | |
227 | |
228 /* Skip incoming data until newline is found, | |
229 returns TRUE if newline was found. */ | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
230 static int client_skip_line(struct client *client) |
0 | 231 { |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
364
diff
changeset
|
232 const unsigned char *data; |
184 | 233 size_t i, data_size; |
0 | 234 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
235 data = i_stream_get_data(client->input, &data_size); |
0 | 236 |
237 for (i = 0; i < data_size; i++) { | |
238 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
|
239 client->input_skip_line = FALSE; |
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
240 i_stream_skip(client->input, i+1); |
0 | 241 break; |
242 } | |
243 } | |
244 | |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
245 return !client->input_skip_line; |
0 | 246 } |
247 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
248 static int client_handle_input(struct client *client) |
0 | 249 { |
250 if (client->cmd_func != NULL) { | |
251 /* command is being executed - continue it */ | |
717
3f817df5eba4
Input parsing was a bit broken in some conditions. Mostly visible with
Timo Sirainen <tss@iki.fi>
parents:
674
diff
changeset
|
252 if (client->cmd_func(client) || client->cmd_error) { |
3f817df5eba4
Input parsing was a bit broken in some conditions. Mostly visible with
Timo Sirainen <tss@iki.fi>
parents:
674
diff
changeset
|
253 /* command execution was finished */ |
0 | 254 client_command_finished(client); |
255 return TRUE; | |
256 } | |
257 return FALSE; | |
258 } | |
259 | |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
260 if (client->input_skip_line) { |
0 | 261 /* we're just waiting for new line.. */ |
262 if (!client_skip_line(client)) | |
263 return FALSE; | |
264 | |
265 /* got the newline */ | |
266 client_reset_command(client); | |
267 | |
268 /* pass through to parse next command */ | |
269 } | |
270 | |
271 if (client->cmd_tag == NULL) { | |
272 client->cmd_tag = imap_parser_read_word(client->parser); | |
273 if (client->cmd_tag == NULL) | |
274 return FALSE; /* need more data */ | |
275 } | |
276 | |
277 if (client->cmd_name == NULL) { | |
278 client->cmd_name = imap_parser_read_word(client->parser); | |
279 if (client->cmd_name == NULL) | |
280 return FALSE; /* need more data */ | |
281 } | |
282 | |
283 if (client->cmd_name == '\0') { | |
284 /* command not given - cmd_func is already NULL. */ | |
285 } else { | |
286 /* find the command function */ | |
287 client->cmd_func = client_command_find(client->cmd_name); | |
288 } | |
289 | |
290 if (client->cmd_func == NULL) { | |
291 /* unknown command */ | |
292 client_send_command_error(client, t_strconcat( | |
293 "Unknown command '", client->cmd_name, "'", NULL)); | |
294 client_command_finished(client); | |
295 } else { | |
296 if (client->cmd_func(client) || client->cmd_error) { | |
297 /* command execution was finished */ | |
298 client_command_finished(client); | |
299 } | |
300 } | |
301 | |
302 return TRUE; | |
303 } | |
304 | |
953
411006be3c66
Naming change for function typedefs.
Timo Sirainen <tss@iki.fi>
parents:
903
diff
changeset
|
305 static void client_input(void *context, int fd __attr_unused__, |
411006be3c66
Naming change for function typedefs.
Timo Sirainen <tss@iki.fi>
parents:
903
diff
changeset
|
306 struct io *io __attr_unused__) |
0 | 307 { |
953
411006be3c66
Naming change for function typedefs.
Timo Sirainen <tss@iki.fi>
parents:
903
diff
changeset
|
308 struct client *client = context; |
411006be3c66
Naming change for function typedefs.
Timo Sirainen <tss@iki.fi>
parents:
903
diff
changeset
|
309 |
0 | 310 client->last_input = ioloop_time; |
311 | |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
312 switch (i_stream_read(client->input)) { |
0 | 313 case -1: |
314 /* disconnected */ | |
315 client_destroy(client); | |
316 return; | |
317 case -2: | |
318 /* parameter word is longer than max. input buffer size. | |
319 this is most likely an error, so skip the new data | |
320 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
|
321 client->input_skip_line = TRUE; |
0 | 322 |
323 client_send_command_error(client, "Too long argument."); | |
324 client_command_finished(client); | |
325 break; | |
326 } | |
327 | |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
328 o_stream_cork(client->output); |
0 | 329 while (client_handle_input(client)) |
330 ; | |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
331 o_stream_flush(client->output); |
0 | 332 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
720
diff
changeset
|
333 if (client->output->closed) |
0 | 334 client_destroy(client); |
335 } | |
336 | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
337 static void idle_timeout(void *context __attr_unused__, |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
338 struct timeout *timeout __attr_unused__) |
0 | 339 { |
340 if (my_client == NULL) | |
341 return; | |
342 | |
343 if (ioloop_time - my_client->last_input >= CLIENT_IDLE_TIMEOUT) { | |
344 client_send_line(my_client, | |
345 "* BYE Disconnected for inactivity."); | |
346 client_destroy(my_client); | |
347 } | |
348 } | |
349 | |
350 void clients_init(void) | |
351 { | |
352 my_client = NULL; | |
353 to_idle = timeout_add(10000, idle_timeout, NULL); | |
354 } | |
355 | |
356 void clients_deinit(void) | |
357 { | |
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
|
358 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
|
359 client_send_line(my_client, "* BYE Server shutting down."); |
0 | 360 client_destroy(my_client); |
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
|
361 } |
0 | 362 |
363 timeout_remove(to_idle); | |
364 } |