annotate src/imap/client.c @ 3866:c1bf2b79eb7f HEAD

Added assert
author Timo Sirainen <tss@iki.fi>
date Sat, 14 Jan 2006 14:54:32 +0200
parents 55df57c028d4
children 2506e4077e7a
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>
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
12
903
fd8888f6f037 Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents: 807
diff changeset
13 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
14
903
fd8888f6f037 Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents: 807
diff changeset
15 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
16 static struct timeout *to_idle;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
17
3811
03a2ff05bd12 If append command failed because input line was too long (highly unlikely),
Timo Sirainen <tss@iki.fi>
parents: 3763
diff changeset
18 static int _client_output(void *context);
03a2ff05bd12 If append command failed because input line was too long (highly unlikely),
Timo Sirainen <tss@iki.fi>
parents: 3763
diff changeset
19
1654
31c4bb26a1e9 Getting ready for namespaces. LIST is still broken with them.
Timo Sirainen <tss@iki.fi>
parents: 1643
diff changeset
20 struct client *client_create(int hin, int hout, 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 */
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
25 net_set_nonblock(hin, TRUE);
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
26 net_set_nonblock(hout, TRUE);
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);
764
f57c52738f90 Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents: 720
diff changeset
29 client->input = i_stream_create_file(hin, 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
30 imap_max_line_length, 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
31 client->output = o_stream_create_file(hout, default_pool,
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
32 (size_t)-1, FALSE);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
33
2878
904c31d74acc APPEND was using all CPU.
Timo Sirainen <tss@iki.fi>
parents: 2800
diff changeset
34 o_stream_set_flush_callback(client->output, _client_output, client);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
35
2460
3accbeb04383 crashfixes
Timo Sirainen <tss@iki.fi>
parents: 2445
diff changeset
36 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
37 client->parser = imap_parser_create(client->input, client->output,
1591
6eca99b727a0 IMAP parser memory limits are now enforced by bytes per line rather than
Timo Sirainen <tss@iki.fi>
parents: 1538
diff changeset
38 imap_max_line_length);
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
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
41 client->cmd.pool = pool_alloconly_create("command pool", 8192);
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
42 client->cmd.client = client;
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
43
1958
4dec6a3d79fd s/custom flags/keywords/
Timo Sirainen <tss@iki.fi>
parents: 1915
diff changeset
44 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
45 client->namespaces = namespaces;
31c4bb26a1e9 Getting ready for namespaces. LIST is still broken with them.
Timo Sirainen <tss@iki.fi>
parents: 1643
diff changeset
46
31c4bb26a1e9 Getting ready for namespaces. LIST is still broken with them.
Timo Sirainen <tss@iki.fi>
parents: 1643
diff changeset
47 while (namespaces != NULL) {
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents: 1654
diff changeset
48 mail_storage_set_callbacks(namespaces->storage,
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents: 1654
diff changeset
49 &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
50 namespaces = namespaces->next;
31c4bb26a1e9 Getting ready for namespaces. LIST is still broken with them.
Timo Sirainen <tss@iki.fi>
parents: 1643
diff changeset
51 }
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
52
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
53 i_assert(my_client == NULL);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
54 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
55
6498f3cb9d2c Added hook_client_created and hook_mail_storage_created for modules.
Timo Sirainen <tss@iki.fi>
parents: 1591
diff changeset
56 if (hook_client_created != NULL)
1643
ca1c2972b78f hook changes
Timo Sirainen <tss@iki.fi>
parents: 1641
diff changeset
57 hook_client_created(&client);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
58 return client;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
59 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
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 void client_destroy(struct client *client)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
62 {
2947
a519f183bacf Added assert
Timo Sirainen <tss@iki.fi>
parents: 2878
diff changeset
63 int ret;
a519f183bacf Added assert
Timo Sirainen <tss@iki.fi>
parents: 2878
diff changeset
64
2979
10d1fd8d0865 Deinitialize pending command only if it's actually executing. Fixes crash if
Timo Sirainen <tss@iki.fi>
parents: 2947
diff changeset
65 if (client->command_pending) {
2501
b7eec64e0735 Deinitialize command handlers always.
Timo Sirainen <tss@iki.fi>
parents: 2462
diff changeset
66 /* try to deinitialize the command */
3866
c1bf2b79eb7f Added assert
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
67 i_assert(client->cmd.func != NULL);
2501
b7eec64e0735 Deinitialize command handlers always.
Timo Sirainen <tss@iki.fi>
parents: 2462
diff changeset
68 i_stream_close(client->input);
b7eec64e0735 Deinitialize command handlers always.
Timo Sirainen <tss@iki.fi>
parents: 2462
diff changeset
69 o_stream_close(client->output);
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
70 ret = client->cmd.func(&client->cmd);
2947
a519f183bacf Added assert
Timo Sirainen <tss@iki.fi>
parents: 2878
diff changeset
71 i_assert(ret);
2501
b7eec64e0735 Deinitialize command handlers always.
Timo Sirainen <tss@iki.fi>
parents: 2462
diff changeset
72 }
b7eec64e0735 Deinitialize command handlers always.
Timo Sirainen <tss@iki.fi>
parents: 2462
diff changeset
73
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
74 if (client->mailbox != NULL)
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents: 1654
diff changeset
75 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
76 namespace_deinit(client->namespaces);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
77
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
78 imap_parser_destroy(client->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
79 if (client->io != NULL)
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
80 io_remove(client->io);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
81
764
f57c52738f90 Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents: 720
diff changeset
82 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
83 o_stream_unref(client->output);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
84
1958
4dec6a3d79fd s/custom flags/keywords/
Timo Sirainen <tss@iki.fi>
parents: 1915
diff changeset
85 pool_unref(client->keywords.pool);
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
86 pool_unref(client->cmd.pool);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
87 i_free(client);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
88
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
89 /* quit the program */
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
90 my_client = NULL;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
91 io_loop_stop(ioloop);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
92 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
93
903
fd8888f6f037 Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents: 807
diff changeset
94 void client_disconnect(struct client *client)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
95 {
2421
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
96 (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
97
764
f57c52738f90 Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents: 720
diff changeset
98 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
99 o_stream_close(client->output);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
100 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
101
1023
dc660f588218 Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
102 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
103 {
dc660f588218 Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
104 client_send_line(client, t_strconcat("* BYE ", msg, NULL));
dc660f588218 Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
105 client_disconnect(client);
dc660f588218 Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
106 }
dc660f588218 Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
107
2425
8267d11cacfb LIST command interrupts itself when output buffer gets full and continues
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
108 int client_send_line(struct client *client, const char *data)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
109 {
2425
8267d11cacfb LIST command interrupts itself when output buffer gets full and continues
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
110 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
111
764
f57c52738f90 Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents: 720
diff changeset
112 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
113 return -1;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
114
2425
8267d11cacfb LIST command interrupts itself when output buffer gets full and continues
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
115 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
116 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
117 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
118 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
119
8267d11cacfb LIST command interrupts itself when output buffer gets full and continues
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
120 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
121 return -1;
8267d11cacfb LIST command interrupts itself when output buffer gets full and continues
Timo Sirainen <tss@iki.fi>
parents: 2421
diff changeset
122
3601
edc6e213048f client_send_line(): Try flushing output immediately if buffer gets full.
Timo Sirainen <tss@iki.fi>
parents: 3469
diff changeset
123 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
124 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
125 /* 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
126 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
127 }
edc6e213048f client_send_line(): Try flushing output immediately if buffer gets full.
Timo Sirainen <tss@iki.fi>
parents: 3469
diff changeset
128 return 1;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
129 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
130
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
131 void client_send_tagline(struct client_command_context *cmd, const char *data)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
132 {
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
133 struct client *client = cmd->client;
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
134 const char *tag = cmd->tag;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
135
764
f57c52738f90 Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents: 720
diff changeset
136 if (client->output->closed)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
137 return;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
138
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
139 if (tag == NULL || *tag == '\0')
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
140 tag = "*";
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
141
807
35abd7a5d381 Buffer related cleanups. Use PATH_MAX instead of hardcoded 1024 for paths.
Timo Sirainen <tss@iki.fi>
parents: 805
diff changeset
142 (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
143 (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
144 (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
145 (void)o_stream_send(client->output, "\r\n", 2);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
146 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
147
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
148 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
149 const char *msg)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
150 {
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
151 struct client *client = cmd->client;
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
152 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
153 bool fatal;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
154
1023
dc660f588218 Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
155 if (msg == NULL) {
dc660f588218 Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
156 msg = imap_parser_get_error(client->parser, &fatal);
dc660f588218 Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
157 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
158 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
159 return;
dc660f588218 Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
160 }
dc660f588218 Disconnect client if given non-sync literal size is too large. Better than
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
161 }
1538
4d1c65eded2c Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents: 1499
diff changeset
162
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
163 if (cmd->tag == NULL)
1538
4d1c65eded2c Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents: 1499
diff changeset
164 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
165 else if (cmd->name == NULL)
1538
4d1c65eded2c Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents: 1499
diff changeset
166 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
167 else {
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
168 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
169 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
170 cmd_name, ": ", msg, NULL);
1538
4d1c65eded2c Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents: 1499
diff changeset
171 }
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
172
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
173 client_send_tagline(cmd, error);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
174
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
175 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
176 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
177 "Too many invalid IMAP commands.");
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
178 }
2508
467af814d5e2 Command parameter errors weren't handled right. This was broken a few
Timo Sirainen <tss@iki.fi>
parents: 2501
diff changeset
179
467af814d5e2 Command parameter errors weren't handled right. This was broken a few
Timo Sirainen <tss@iki.fi>
parents: 2501
diff changeset
180 /* 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
181 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
182 FALSE. */
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
183 cmd->param_error = TRUE;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
184 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
185
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
186 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
187 unsigned int flags, struct imap_arg **args)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
188 {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
189 int ret;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
190
1015
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 1001
diff changeset
191 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
192
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
193 ret = imap_parser_read_args(cmd->client->parser, count, flags, args);
720
e0825139b0f1 Maybe now?
Timo Sirainen <tss@iki.fi>
parents: 717
diff changeset
194 if (ret >= (int)count) {
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
195 /* all parameters read successfully */
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
196 return TRUE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
197 } else if (ret == -2) {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
198 /* need more data */
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
199 return FALSE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
200 } else {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
201 /* error, or missing arguments */
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
202 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
203 "Missing arguments");
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
204 return FALSE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
205 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
206 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
207
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
208 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
209 unsigned int count, ...)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
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 struct imap_arg *imap_args;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
212 va_list va;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
213 const char *str;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
214 unsigned int i;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
215
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
216 if (!client_read_args(cmd, count, 0, &imap_args))
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
217 return FALSE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
218
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
219 va_start(va, count);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
220 for (i = 0; i < count; i++) {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
221 const char **ret = va_arg(va, const char **);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
222
1015
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 1001
diff changeset
223 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
224 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
225 break;
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 1001
diff changeset
226 }
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 1001
diff changeset
227
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
228 str = imap_arg_string(&imap_args[i]);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
229 if (str == NULL) {
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
230 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
231 break;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
232 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
233
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
234 if (ret != NULL)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
235 *ret = str;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
236 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
237 va_end(va);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
238
1015
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 1001
diff changeset
239 return i == count;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
240 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
241
1172
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents: 1168
diff changeset
242 void _client_reset_command(struct client *client)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
243 {
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
244 pool_t pool;
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
245 size_t size;
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
246
2421
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
247 /* 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
248 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
249 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
250
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
251 client->command_pending = FALSE;
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
252 if (client->io == NULL) {
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
253 client->io = io_add(i_stream_get_fd(client->input),
2460
3accbeb04383 crashfixes
Timo Sirainen <tss@iki.fi>
parents: 2445
diff changeset
254 IO_READ, _client_input, 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
255 }
3811
03a2ff05bd12 If append command failed because input line was too long (highly unlikely),
Timo Sirainen <tss@iki.fi>
parents: 3763
diff changeset
256 o_stream_set_flush_callback(client->output, _client_output, 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
257
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
258 pool = client->cmd.pool;
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
259 memset(&client->cmd, 0, sizeof(client->cmd));
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
260
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
261 p_clear(pool);
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
262 client->cmd.pool = pool;
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
263 client->cmd.client = client;
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
264
2427
e1616067df5c Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents: 2425
diff changeset
265 imap_parser_reset(client->parser);
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
266
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
267 /* if there's unread data in buffer, remember that there's input
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
268 pending and we should get around to calling client_input() soon.
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
269 This is mostly for APPEND/IDLE. */
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
270 (void)i_stream_get_data(client->input, &size);
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
271 if (size > 0)
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
272 client->input_pending = TRUE;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
273 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
274
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
275 /* Skip incoming data until newline is found,
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
276 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
277 static bool client_skip_line(struct client *client)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
278 {
410
1f0e7229ee58 Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents: 364
diff changeset
279 const unsigned char *data;
184
4223b9ed0c80 move size_t fixes
Timo Sirainen <tss@iki.fi>
parents: 164
diff changeset
280 size_t i, data_size;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
281
764
f57c52738f90 Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents: 720
diff changeset
282 data = i_stream_get_data(client->input, &data_size);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
283
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
284 for (i = 0; i < data_size; i++) {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
285 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
286 client->input_skip_line = FALSE;
1538
4d1c65eded2c Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents: 1499
diff changeset
287 i++;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
288 break;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
289 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
290 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
291
1538
4d1c65eded2c Give more verbose protocol level errors + some fixes.
Timo Sirainen <tss@iki.fi>
parents: 1499
diff changeset
292 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
293 return !client->input_skip_line;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
294 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
295
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
296 static bool client_handle_input(struct client_command_context *cmd)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
297 {
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
298 struct client *client = cmd->client;
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
299
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
300 if (cmd->func != NULL) {
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
301 /* 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
302 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
303 /* command execution was finished */
2445
5376a3c388c0 Set bad_counter before calling client_command_reset because it may parse
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
304 client->bad_counter = 0;
1172
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents: 1168
diff changeset
305 _client_reset_command(client);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
306 return TRUE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
307 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
308 return FALSE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
309 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
310
764
f57c52738f90 Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents: 720
diff changeset
311 if (client->input_skip_line) {
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
312 /* we're just waiting for new line.. */
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
313 if (!client_skip_line(client))
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
314 return FALSE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
315
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
316 /* got the newline */
1172
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents: 1168
diff changeset
317 _client_reset_command(client);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
318
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
319 /* pass through to parse next command */
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
320 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
321
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
322 if (cmd->tag == NULL) {
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
323 cmd->tag = imap_parser_read_word(client->parser);
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
324 if (cmd->tag == NULL)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
325 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
326 cmd->tag = p_strdup(cmd->pool, cmd->tag);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
327 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
328
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
329 if (cmd->name == NULL) {
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
330 cmd->name = imap_parser_read_word(client->parser);
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
331 if (cmd->name == NULL)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
332 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
333 cmd->name = p_strdup(cmd->pool, cmd->name);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
334 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
335
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
336 if (cmd->name == '\0') {
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
337 /* command not given - cmd_func is already NULL. */
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
338 } else {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
339 /* find the command function */
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
340 cmd->func = command_find(cmd->name);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
341 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
342
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
343 if (cmd->func == NULL) {
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
344 /* unknown command */
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
345 client_send_command_error(cmd, "Unknown command.");
1015
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 1001
diff changeset
346 client->input_skip_line = TRUE;
1172
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents: 1168
diff changeset
347 _client_reset_command(client);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
348 } else {
1015
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 1001
diff changeset
349 client->input_skip_line = TRUE;
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
350 if (cmd->func(cmd) || cmd->param_error) {
2508
467af814d5e2 Command parameter errors weren't handled right. This was broken a few
Timo Sirainen <tss@iki.fi>
parents: 2501
diff changeset
351 /* command execution was finished. */
2445
5376a3c388c0 Set bad_counter before calling client_command_reset because it may parse
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
352 client->bad_counter = 0;
1172
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents: 1168
diff changeset
353 _client_reset_command(client);
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents: 1168
diff changeset
354 } else {
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents: 1168
diff changeset
355 /* unfinished */
3336
a3a72d5bdfce o_stream_uncork() was previously always setting IO_WRITE handler even if
Timo Sirainen <tss@iki.fi>
parents: 3141
diff changeset
356 if (client->command_pending) {
a3a72d5bdfce o_stream_uncork() was previously always setting IO_WRITE handler even if
Timo Sirainen <tss@iki.fi>
parents: 3141
diff changeset
357 o_stream_set_flush_pending(client->output,
a3a72d5bdfce o_stream_uncork() was previously always setting IO_WRITE handler even if
Timo Sirainen <tss@iki.fi>
parents: 3141
diff changeset
358 TRUE);
a3a72d5bdfce o_stream_uncork() was previously always setting IO_WRITE handler even if
Timo Sirainen <tss@iki.fi>
parents: 3141
diff changeset
359 }
1172
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents: 1168
diff changeset
360 return FALSE;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
361 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
362 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
363
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
364 return TRUE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
365 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
366
2460
3accbeb04383 crashfixes
Timo Sirainen <tss@iki.fi>
parents: 2445
diff changeset
367 void _client_input(void *context)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
368 {
953
411006be3c66 Naming change for function typedefs.
Timo Sirainen <tss@iki.fi>
parents: 903
diff changeset
369 struct client *client = context;
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
370 struct client_command_context *cmd = &client->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
371 int ret;
953
411006be3c66 Naming change for function typedefs.
Timo Sirainen <tss@iki.fi>
parents: 903
diff changeset
372
2421
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
373 if (client->command_pending) {
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
374 /* already processing one command. wait. */
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
375 io_remove(client->io);
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
376 client->io = NULL;
2513
f6fdf9048a01 Input handler tried to process multiple commands at once which broke things.
Timo Sirainen <tss@iki.fi>
parents: 2508
diff changeset
377 return;
2421
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
378 }
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
379
2427
e1616067df5c Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents: 2425
diff changeset
380 client->input_pending = FALSE;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
381 client->last_input = ioloop_time;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
382
764
f57c52738f90 Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents: 720
diff changeset
383 switch (i_stream_read(client->input)) {
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
384 case -1:
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
385 /* disconnected */
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
386 client_destroy(client);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
387 return;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
388 case -2:
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
389 /* parameter word is longer than max. input buffer size.
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
390 this is most likely an error, so skip the new data
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
391 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
392 client->input_skip_line = TRUE;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
393
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
394 client_send_command_error(cmd, "Too long argument.");
1172
f7c273202dc3 Support for IDLE extension.
Timo Sirainen <tss@iki.fi>
parents: 1168
diff changeset
395 _client_reset_command(client);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
396 break;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
397 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
398
764
f57c52738f90 Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents: 720
diff changeset
399 o_stream_cork(client->output);
3469
7e39590da48a Call t_push/t_pop around client command execution function, so if client
Timo Sirainen <tss@iki.fi>
parents: 3402
diff changeset
400 do {
7e39590da48a Call t_push/t_pop around client command execution function, so if client
Timo Sirainen <tss@iki.fi>
parents: 3402
diff changeset
401 t_push();
7e39590da48a Call t_push/t_pop around client command execution function, so if client
Timo Sirainen <tss@iki.fi>
parents: 3402
diff changeset
402 ret = client_handle_input(cmd);
7e39590da48a Call t_push/t_pop around client command execution function, so if client
Timo Sirainen <tss@iki.fi>
parents: 3402
diff changeset
403 t_pop();
7e39590da48a Call t_push/t_pop around client command execution function, so if client
Timo Sirainen <tss@iki.fi>
parents: 3402
diff changeset
404 } while (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
405 o_stream_uncork(client->output);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
406
2427
e1616067df5c Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents: 2425
diff changeset
407 if (client->command_pending)
e1616067df5c Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents: 2425
diff changeset
408 client->input_pending = TRUE;
e1616067df5c Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents: 2425
diff changeset
409
764
f57c52738f90 Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents: 720
diff changeset
410 if (client->output->closed)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
411 client_destroy(client);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
412 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
413
3811
03a2ff05bd12 If append command failed because input line was too long (highly unlikely),
Timo Sirainen <tss@iki.fi>
parents: 3763
diff changeset
414 static int _client_output(void *context)
2421
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
415 {
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
416 struct client *client = context;
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
417 struct client_command_context *cmd = &client->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
418 int ret;
55df57c028d4 Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents: 3811
diff changeset
419 bool finished;
2421
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
420
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
421 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
422
2790
02c0b8d532c2 Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents: 2640
diff changeset
423 if ((ret = o_stream_flush(client->output)) < 0) {
02c0b8d532c2 Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents: 2640
diff changeset
424 client_destroy(client);
02c0b8d532c2 Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents: 2640
diff changeset
425 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
426 }
02c0b8d532c2 Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents: 2640
diff changeset
427
02c0b8d532c2 Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents: 2640
diff changeset
428 if (!client->command_pending)
02c0b8d532c2 Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents: 2640
diff changeset
429 return 1;
2462
Timo Sirainen <tss@iki.fi>
parents: 2460
diff changeset
430
2790
02c0b8d532c2 Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents: 2640
diff changeset
431 /* continue processing command */
02c0b8d532c2 Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents: 2640
diff changeset
432 o_stream_cork(client->output);
2800
3f7d4af90ec1 IDLE used 100% CPU.
Timo Sirainen <tss@iki.fi>
parents: 2790
diff changeset
433 client->output_pending = TRUE;
3141
61abed5f7864 Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents: 2979
diff changeset
434 finished = cmd->func(cmd) || cmd->param_error;
2462
Timo Sirainen <tss@iki.fi>
parents: 2460
diff changeset
435
3402
513abd166949 Changed output handler to work a bit differently to avoid useless
Timo Sirainen <tss@iki.fi>
parents: 3336
diff changeset
436 /* a bit kludgy check. normally we would want to get back to this
513abd166949 Changed output handler to work a bit differently to avoid useless
Timo Sirainen <tss@iki.fi>
parents: 3336
diff changeset
437 output handler, but IDLE is a special case which has command
513abd166949 Changed output handler to work a bit differently to avoid useless
Timo Sirainen <tss@iki.fi>
parents: 3336
diff changeset
438 pending but without necessarily anything to write. */
513abd166949 Changed output handler to work a bit differently to avoid useless
Timo Sirainen <tss@iki.fi>
parents: 3336
diff changeset
439 if (!finished && client->output_pending)
513abd166949 Changed output handler to work a bit differently to avoid useless
Timo Sirainen <tss@iki.fi>
parents: 3336
diff changeset
440 o_stream_set_flush_pending(client->output, TRUE);
513abd166949 Changed output handler to work a bit differently to avoid useless
Timo Sirainen <tss@iki.fi>
parents: 3336
diff changeset
441
513abd166949 Changed output handler to work a bit differently to avoid useless
Timo Sirainen <tss@iki.fi>
parents: 3336
diff changeset
442 o_stream_uncork(client->output);
2800
3f7d4af90ec1 IDLE used 100% CPU.
Timo Sirainen <tss@iki.fi>
parents: 2790
diff changeset
443
2790
02c0b8d532c2 Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents: 2640
diff changeset
444 if (finished) {
02c0b8d532c2 Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents: 2640
diff changeset
445 /* command execution was finished */
02c0b8d532c2 Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents: 2640
diff changeset
446 client->bad_counter = 0;
02c0b8d532c2 Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents: 2640
diff changeset
447 _client_reset_command(client);
02c0b8d532c2 Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents: 2640
diff changeset
448
02c0b8d532c2 Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents: 2640
diff changeset
449 if (client->input_pending)
02c0b8d532c2 Changed ostream's flush callback to have return value which can tell if
Timo Sirainen <tss@iki.fi>
parents: 2640
diff changeset
450 _client_input(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
451 }
2800
3f7d4af90ec1 IDLE used 100% CPU.
Timo Sirainen <tss@iki.fi>
parents: 2790
diff changeset
452 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
453 }
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
454
1036
f782b3319553 Removed useless parameters from io_callback_t and timeout_callback_t.
Timo Sirainen <tss@iki.fi>
parents: 1023
diff changeset
455 static void idle_timeout(void *context __attr_unused__)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
456 {
2421
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
457 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
458
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
459 if (my_client == NULL)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
460 return;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
461
2421
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
462 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
463 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
464
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
465 if (my_client->command_pending &&
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
466 o_stream_get_buffer_used_size(my_client->output) > 0 &&
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
467 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
468 /* client isn't reading our output */
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
469 client_destroy(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
470 } 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
471 /* client isn't sending us anything */
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
472 if (!my_client->command_pending) {
d141e1bfdd63 We never do blocking reads/writes to network anymore. Changed imap and pop3
Timo Sirainen <tss@iki.fi>
parents: 2058
diff changeset
473 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
474 "* 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
475 }
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
476 client_destroy(my_client);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
477 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
478 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
479
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
480 void clients_init(void)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
481 {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
482 my_client = NULL;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
483 to_idle = timeout_add(10000, idle_timeout, NULL);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
484 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
485
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
486 void clients_deinit(void)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
487 {
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
488 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
489 client_send_line(my_client, "* BYE Server shutting down.");
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
490 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
491 }
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
492
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
493 timeout_remove(to_idle);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
494 }