annotate src/lib-storage/index/imapc/imapc-connection.c @ 12624:893e0738733b

imapc: Added support for STARTTLS.
author Timo Sirainen <tss@iki.fi>
date Mon, 31 Jan 2011 19:29:17 +0200
parents 31eb7db0c4b9
children 49f487b435bd
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1 /* Copyright (c) 2011 Dovecot authors, see the included COPYING file */
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
2
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
3 #include "lib.h"
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
4 #include "ioloop.h"
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
5 #include "network.h"
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
6 #include "istream.h"
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
7 #include "ostream.h"
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
8 #include "base64.h"
12615
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
9 #include "write-full.h"
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
10 #include "str.h"
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
11 #include "dns-lookup.h"
12617
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
12 #include "iostream-ssl.h"
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
13 #include "imap-quote.h"
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
14 #include "imap-util.h"
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
15 #include "imap-parser.h"
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
16 #include "imapc-client-private.h"
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
17 #include "imapc-seqmap.h"
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
18 #include "imapc-connection.h"
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
19
12615
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
20 #include <unistd.h>
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
21 #include <ctype.h>
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
22
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
23 #define IMAPC_DNS_LOOKUP_TIMEOUT_MSECS (1000*30)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
24 #define IMAPC_CONNECT_TIMEOUT_MSECS (1000*30)
12615
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
25 #define IMAPC_MAX_INLINE_LITERAL_SIZE (1024*32)
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
26
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
27 enum imapc_input_state {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
28 IMAPC_INPUT_STATE_NONE = 0,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
29 IMAPC_INPUT_STATE_UNTAGGED,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
30 IMAPC_INPUT_STATE_UNTAGGED_NUM,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
31 IMAPC_INPUT_STATE_TAGGED,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
32 IMAPC_INPUT_STATE_SKIPLINE
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
33 };
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
34
12604
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
35 struct imapc_command_stream {
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
36 unsigned int pos;
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
37 struct istream *input;
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
38 };
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
39
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
40 struct imapc_command {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
41 pool_t pool;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
42 buffer_t *data;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
43 unsigned int send_pos;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
44 unsigned int tag;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
45
12604
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
46 ARRAY_DEFINE(streams, struct imapc_command_stream);
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
47
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
48 imapc_command_callback_t *callback;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
49 void *context;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
50 };
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
51
12615
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
52 struct imapc_connection_literal {
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
53 char *temp_path;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
54 int fd;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
55 uoff_t bytes_left;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
56
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
57 const struct imap_arg *parent_arg;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
58 unsigned int list_idx;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
59 };
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
60
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
61 struct imapc_connection {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
62 struct imapc_client *client;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
63 char *name;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
64
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
65 int fd;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
66 struct io *io;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
67 struct istream *input;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
68 struct ostream *output;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
69 struct imap_parser *parser;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
70 struct timeout *to;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
71
12617
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
72 struct ssl_iostream *ssl_iostream;
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
73
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
74 int (*input_callback)(struct imapc_connection *conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
75 enum imapc_input_state input_state;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
76 unsigned int cur_tag;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
77 uint32_t cur_num;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
78
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
79 struct imapc_client_mailbox *selecting_box, *selected_box;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
80 enum imapc_connection_state state;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
81
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
82 enum imapc_capability capabilities;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
83 char **capabilities_list;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
84
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
85 ARRAY_DEFINE(cmd_send_queue, struct imapc_command *);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
86 ARRAY_DEFINE(cmd_wait_list, struct imapc_command *);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
87
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
88 unsigned int ips_count, prev_connect_idx;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
89 struct ip_addr *ips;
12592
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
90
12615
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
91 struct imapc_connection_literal literal;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
92 ARRAY_DEFINE(literal_files, struct imapc_arg_file);
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
93
12592
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
94 unsigned int idling:1;
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
95 unsigned int idle_stopping:1;
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
96 unsigned int idle_plus_waiting:1;
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
97 };
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
98
12624
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
99 static int imapc_connection_ssl_init(struct imapc_connection *conn);
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
100 static void imapc_connection_disconnect(struct imapc_connection *conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
101
12604
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
102 static void imapc_command_free(struct imapc_command *cmd);
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
103 static void imapc_command_send_more(struct imapc_connection *conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
104 struct imapc_command *cmd);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
105
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
106 struct imapc_connection *
12595
5d97dfa9d86c imapc: Fixed mailbox deletion and some error handling. Code cleanups.
Timo Sirainen <tss@iki.fi>
parents: 12592
diff changeset
107 imapc_connection_init(struct imapc_client *client)
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
108 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
109 struct imapc_connection *conn;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
110
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
111 conn = i_new(struct imapc_connection, 1);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
112 conn->client = client;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
113 conn->fd = -1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
114 conn->name = i_strdup_printf("%s:%u", client->set.host,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
115 client->set.port);
12615
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
116 conn->literal.fd = -1;
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
117 i_array_init(&conn->cmd_send_queue, 8);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
118 i_array_init(&conn->cmd_wait_list, 32);
12615
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
119 i_array_init(&conn->literal_files, 4);
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
120 return conn;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
121 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
122
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
123 void imapc_connection_deinit(struct imapc_connection **_conn)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
124 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
125 struct imapc_connection *conn = *_conn;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
126
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
127 *_conn = NULL;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
128
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
129 imapc_connection_disconnect(conn);
12617
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
130 if (conn->capabilities_list != NULL)
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
131 p_strsplit_free(default_pool, conn->capabilities_list);
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
132 array_free(&conn->cmd_send_queue);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
133 array_free(&conn->cmd_wait_list);
12615
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
134 array_free(&conn->literal_files);
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
135 i_free(conn->ips);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
136 i_free(conn->name);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
137 i_free(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
138 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
139
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
140 void imapc_connection_ioloop_changed(struct imapc_connection *conn)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
141 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
142 if (conn->io != NULL)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
143 conn->io = io_loop_move_io(&conn->io);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
144 if (conn->to != NULL)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
145 conn->to = io_loop_move_timeout(&conn->to);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
146 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
147
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
148 static void imapc_connection_set_state(struct imapc_connection *conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
149 enum imapc_connection_state state)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
150 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
151 if (state == IMAPC_CONNECTION_STATE_DISCONNECTED) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
152 /* abort all pending commands */
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
153 struct imapc_command_reply reply;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
154 struct imapc_command *const *cmdp, *cmd;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
155
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
156 memset(&reply, 0, sizeof(reply));
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
157 reply.state = IMAPC_COMMAND_STATE_DISCONNECTED;
12590
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
158 reply.text_without_resp = reply.text_full =
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
159 "Disconnected from server";
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
160
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
161 while (array_count(&conn->cmd_wait_list) > 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
162 cmdp = array_idx(&conn->cmd_wait_list, 0);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
163 cmd = *cmdp;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
164 array_delete(&conn->cmd_wait_list, 0, 1);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
165
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
166 cmd->callback(&reply, cmd->context);
12604
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
167 imapc_command_free(cmd);
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
168 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
169 while (array_count(&conn->cmd_send_queue) > 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
170 cmdp = array_idx(&conn->cmd_send_queue, 0);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
171 cmd = *cmdp;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
172 array_delete(&conn->cmd_send_queue, 0, 1);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
173
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
174 cmd->callback(&reply, cmd->context);
12604
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
175 imapc_command_free(cmd);
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
176 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
177 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
178 if (state == IMAPC_CONNECTION_STATE_DONE) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
179 if (array_count(&conn->cmd_send_queue) > 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
180 struct imapc_command *const *cmd_p =
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
181 array_idx(&conn->cmd_send_queue, 0);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
182 imapc_command_send_more(conn, *cmd_p);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
183 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
184 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
185 conn->state = state;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
186 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
187
12615
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
188 static void imapc_connection_lfiles_free(struct imapc_connection *conn)
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
189 {
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
190 struct imapc_arg_file *lfile;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
191
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
192 array_foreach_modifiable(&conn->literal_files, lfile) {
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
193 if (close(lfile->fd) < 0)
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
194 i_error("imapc: close(literal file) failed: %m");
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
195 }
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
196 array_clear(&conn->literal_files);
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
197 }
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
198
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
199 static void
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
200 imapc_connection_literal_reset(struct imapc_connection_literal *literal)
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
201 {
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
202 if (literal->fd != -1) {
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
203 if (close(literal->fd) < 0)
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
204 i_error("close(%s) failed: %m", literal->temp_path);
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
205 }
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
206 i_free_and_null(literal->temp_path);
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
207
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
208 memset(literal, 0, sizeof(*literal));
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
209 literal->fd = -1;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
210 }
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
211
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
212 static void imapc_connection_disconnect(struct imapc_connection *conn)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
213 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
214 if (conn->fd == -1)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
215 return;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
216
12615
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
217 imapc_connection_lfiles_free(conn);
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
218 imapc_connection_literal_reset(&conn->literal);
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
219 if (conn->to != NULL)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
220 timeout_remove(&conn->to);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
221 imap_parser_destroy(&conn->parser);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
222 io_remove(&conn->io);
12617
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
223 if (conn->ssl_iostream != NULL)
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
224 ssl_iostream_unref(&conn->ssl_iostream);
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
225 i_stream_destroy(&conn->input);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
226 o_stream_destroy(&conn->output);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
227 net_disconnect(conn->fd);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
228 conn->fd = -1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
229
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
230 imapc_connection_set_state(conn, IMAPC_CONNECTION_STATE_DISCONNECTED);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
231 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
232
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
233 static void ATTR_FORMAT(2, 3)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
234 imapc_connection_input_error(struct imapc_connection *conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
235 const char *fmt, ...)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
236 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
237 va_list va;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
238
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
239 va_start(va, fmt);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
240 i_error("imapc(%s): Server sent invalid input: %s",
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
241 conn->name, t_strdup_vprintf(fmt, va));
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
242 imapc_connection_disconnect(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
243 va_end(va);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
244 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
245
12615
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
246 static bool last_arg_is_fetch_body(const struct imap_arg *args,
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
247 const struct imap_arg **parent_arg_r,
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
248 unsigned int *idx_r)
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
249 {
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
250 const struct imap_arg *list;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
251 const char *name;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
252 unsigned int count;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
253
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
254 if (args[0].type == IMAP_ARG_ATOM &&
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
255 imap_arg_atom_equals(&args[1], "FETCH") &&
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
256 imap_arg_get_list_full(&args[2], &list, &count) && count >= 2 &&
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
257 list[count].type == IMAP_ARG_LITERAL_SIZE &&
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
258 imap_arg_get_atom(&list[count-1], &name) &&
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
259 strncasecmp(name, "BODY[", 5) == 0) {
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
260 *parent_arg_r = &args[2];
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
261 *idx_r = count;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
262 return TRUE;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
263 }
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
264 return FALSE;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
265 }
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
266
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
267 static int
12615
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
268 imapc_connection_read_literal_init(struct imapc_connection *conn, uoff_t size,
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
269 const struct imap_arg *args)
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
270 {
12615
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
271 const char *path;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
272 const struct imap_arg *parent_arg;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
273 unsigned int idx;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
274
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
275 i_assert(size > 0);
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
276 i_assert(conn->literal.fd == -1);
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
277
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
278 if (size <= IMAPC_MAX_INLINE_LITERAL_SIZE ||
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
279 !last_arg_is_fetch_body(args, &parent_arg, &idx)) {
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
280 /* read the literal directly into parser */
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
281 return 0;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
282 }
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
283
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
284 conn->literal.fd = imapc_client_create_temp_fd(conn->client, &path);
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
285 if (conn->literal.fd == -1)
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
286 return -1;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
287 conn->literal.temp_path = i_strdup(path);
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
288 conn->literal.bytes_left = size;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
289 conn->literal.parent_arg = parent_arg;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
290 conn->literal.list_idx = idx;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
291 return 1;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
292 }
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
293
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
294 static int imapc_connection_read_literal(struct imapc_connection *conn)
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
295 {
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
296 struct imapc_arg_file *lfile;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
297 const unsigned char *data;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
298 size_t size;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
299
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
300 if (conn->literal.bytes_left == 0)
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
301 return 1;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
302
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
303 data = i_stream_get_data(conn->input, &size);
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
304 if (size > conn->literal.bytes_left)
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
305 size = conn->literal.bytes_left;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
306 if (size > 0) {
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
307 if (write_full(conn->literal.fd, data, size) < 0) {
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
308 i_error("imapc(%s): write(%s) failed: %m",
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
309 conn->name, conn->literal.temp_path);
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
310 imapc_connection_disconnect(conn);
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
311 return -1;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
312 }
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
313 i_stream_skip(conn->input, size);
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
314 conn->literal.bytes_left -= size;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
315 }
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
316 if (conn->literal.bytes_left > 0)
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
317 return 0;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
318
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
319 /* finished */
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
320 lfile = array_append_space(&conn->literal_files);
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
321 lfile->fd = conn->literal.fd;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
322 lfile->parent_arg = conn->literal.parent_arg;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
323 lfile->list_idx = conn->literal.list_idx;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
324
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
325 conn->literal.fd = -1;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
326 imapc_connection_literal_reset(&conn->literal);
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
327 return 1;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
328 }
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
329
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
330 static int
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
331 imapc_connection_read_line_more(struct imapc_connection *conn,
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
332 const struct imap_arg **imap_args_r)
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
333 {
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
334 uoff_t literal_size;
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
335 bool fatal;
12615
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
336 int ret;
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
337
12615
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
338 if ((ret = imapc_connection_read_literal(conn)) <= 0)
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
339 return ret;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
340
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
341 ret = imap_parser_read_args(conn->parser, 0,
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
342 IMAP_PARSE_FLAG_LITERAL_SIZE |
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
343 IMAP_PARSE_FLAG_ATOM_ALLCHARS, imap_args_r);
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
344 if (ret == -2) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
345 /* need more data */
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
346 return 0;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
347 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
348 if (ret < 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
349 imapc_connection_input_error(conn, "Error parsing input: %s",
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
350 imap_parser_get_error(conn->parser, &fatal));
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
351 return -1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
352 }
12615
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
353
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
354 if (imap_parser_get_literal_size(conn->parser, &literal_size)) {
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
355 if (imapc_connection_read_literal_init(conn, literal_size,
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
356 *imap_args_r) <= 0) {
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
357 imap_parser_read_last_literal(conn->parser);
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
358 return 2;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
359 }
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
360 return imapc_connection_read_line_more(conn, imap_args_r);
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
361 }
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
362 return 1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
363 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
364
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
365 static int
12615
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
366 imapc_connection_read_line(struct imapc_connection *conn,
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
367 const struct imap_arg **imap_args_r)
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
368 {
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
369 int ret;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
370
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
371 while ((ret = imapc_connection_read_line_more(conn, imap_args_r)) == 2)
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
372 ;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
373 return ret;
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
374 }
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
375
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
376 static int
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
377 imapc_connection_parse_capability(struct imapc_connection *conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
378 const char *value)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
379 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
380 const char *const *tmp;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
381 unsigned int i;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
382
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
383 conn->capabilities = 0;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
384 if (conn->capabilities_list != NULL)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
385 p_strsplit_free(default_pool, conn->capabilities_list);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
386 conn->capabilities_list = p_strsplit(default_pool, value, " ");
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
387
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
388 for (tmp = t_strsplit(value, " "); *tmp != NULL; tmp++) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
389 for (i = 0; imapc_capability_names[i].name != NULL; i++) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
390 const struct imapc_capability_name *cap =
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
391 &imapc_capability_names[i];
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
392
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
393 if (strcasecmp(*tmp, cap->name) == 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
394 conn->capabilities |= cap->capability;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
395 break;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
396 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
397 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
398 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
399
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
400 if ((conn->capabilities & IMAPC_CAPABILITY_IMAP4REV1) == 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
401 imapc_connection_input_error(conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
402 "CAPABILITY list is missing IMAP4REV1");
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
403 return -1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
404 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
405 return 0;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
406 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
407
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
408 static int
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
409 imapc_connection_handle_resp_text_code(struct imapc_connection *conn,
12590
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
410 const char *key, const char *value)
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
411 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
412 if (strcasecmp(key, "CAPABILITY") == 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
413 if (imapc_connection_parse_capability(conn, value) < 0)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
414 return -1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
415 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
416 if (strcasecmp(key, "CLOSED") == 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
417 /* QRESYNC: SELECTing another mailbox */
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
418 if (conn->selecting_box != NULL) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
419 conn->selected_box = conn->selecting_box;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
420 conn->selecting_box = NULL;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
421 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
422 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
423 return 0;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
424 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
425
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
426 static int
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
427 imapc_connection_handle_resp_text(struct imapc_connection *conn,
12590
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
428 const char *text,
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
429 const char **key_r, const char **value_r)
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
430 {
12590
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
431 const char *p, *value;
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
432
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
433 i_assert(text[0] == '[');
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
434
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
435 p = strchr(text, ']');
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
436 if (p == NULL) {
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
437 imapc_connection_input_error(conn, "Missing ']' in resp-text");
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
438 return -1;
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
439 }
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
440 text = t_strdup_until(text + 1, p);
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
441 value = strchr(text, ' ');
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
442 if (value != NULL) {
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
443 *key_r = t_strdup_until(text, value);
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
444 *value_r = value + 1;
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
445 } else {
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
446 *key_r = text;
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
447 *value_r = NULL;
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
448 }
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
449 return 0;
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
450 }
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
451
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
452 static int
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
453 imapc_connection_handle_imap_resp_text(struct imapc_connection *conn,
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
454 const struct imap_arg *args,
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
455 const char **key_r, const char **value_r)
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
456 {
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
457 const char *text;
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
458
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
459 if (args->type != IMAP_ARG_ATOM)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
460 return 0;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
461
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
462 text = imap_args_to_str(args);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
463 if (*text != '[') {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
464 if (*text == '\0') {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
465 imapc_connection_input_error(conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
466 "Missing text in resp-text");
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
467 return -1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
468 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
469 return 0;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
470 }
12590
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
471 if (imapc_connection_handle_resp_text(conn, text, key_r, value_r) < 0)
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
472 return -1;
12590
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
473
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
474 return imapc_connection_handle_resp_text_code(conn, *key_r, *value_r);
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
475 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
476
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
477 static bool need_literal(const char *str)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
478 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
479 unsigned int i;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
480
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
481 for (i = 0; str[i] != '\0'; i++) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
482 unsigned char c = str[i];
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
483
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
484 if ((c & 0x80) != 0 || c == '\r' || c == '\n')
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
485 return TRUE;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
486 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
487 return FALSE;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
488 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
489
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
490 static void imapc_connection_input_reset(struct imapc_connection *conn)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
491 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
492 conn->input_state = IMAPC_INPUT_STATE_NONE;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
493 conn->cur_tag = 0;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
494 conn->cur_num = 0;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
495 imap_parser_reset(conn->parser);
12615
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
496 imapc_connection_lfiles_free(conn);
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
497 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
498
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
499 static int imapc_connection_skip_line(struct imapc_connection *conn)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
500 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
501 const unsigned char *data;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
502 size_t i, data_size;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
503 int ret = 0;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
504
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
505 data = i_stream_get_data(conn->input, &data_size);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
506 for (i = 0; i < data_size; i++) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
507 if (data[i] == '\n') {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
508 imapc_connection_input_reset(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
509 ret = 1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
510 i++;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
511 break;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
512 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
513 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
514 i_stream_skip(conn->input, i);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
515 return ret;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
516 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
517
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
518 static void imapc_connection_login_cb(const struct imapc_command_reply *reply,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
519 void *context)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
520 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
521 struct imapc_connection *conn = context;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
522
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
523 if (reply->state != IMAPC_COMMAND_STATE_OK) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
524 imapc_connection_input_error(conn, "Authentication failed: %s",
12590
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
525 reply->text_full);
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
526 return;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
527 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
528
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
529 timeout_remove(&conn->to);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
530 imapc_connection_set_state(conn, IMAPC_CONNECTION_STATE_DONE);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
531 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
532
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
533 static const char *
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
534 imapc_connection_get_sasl_plain_request(struct imapc_connection *conn)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
535 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
536 const struct imapc_client_settings *set = &conn->client->set;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
537 string_t *in, *out;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
538
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
539 in = t_str_new(128);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
540 if (set->master_user != NULL) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
541 str_append(in, set->username);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
542 str_append_c(in, '\0');
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
543 str_append(in, set->master_user);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
544 } else {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
545 str_append_c(in, '\0');
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
546 str_append(in, set->username);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
547 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
548 str_append_c(in, '\0');
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
549 str_append(in, set->password);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
550
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
551 out = t_str_new(128);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
552 base64_encode(in->data, in->used, out);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
553 return str_c(out);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
554 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
555
12621
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
556 static void imapc_connection_authenticate(struct imapc_connection *conn)
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
557 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
558 const struct imapc_client_settings *set = &conn->client->set;
12621
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
559 const char *cmd;
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
560
12621
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
561 if ((set->master_user == NULL &&
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
562 need_literal(set->username) && need_literal(set->password)) ||
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
563 (conn->capabilities & IMAPC_CAPABILITY_AUTH_PLAIN) == 0) {
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
564 /* We can use LOGIN command */
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
565 imapc_connection_cmdf(conn, imapc_connection_login_cb, conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
566 "LOGIN %s %s",
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
567 set->username, set->password);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
568 } else if ((conn->capabilities & IMAPC_CAPABILITY_SASL_IR) != 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
569 cmd = t_strdup_printf("AUTHENTICATE PLAIN %s",
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
570 imapc_connection_get_sasl_plain_request(conn));
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
571 imapc_connection_cmd(conn, cmd,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
572 imapc_connection_login_cb, conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
573 } else {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
574 cmd = t_strdup_printf("AUTHENTICATE PLAIN\r\n%s",
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
575 imapc_connection_get_sasl_plain_request(conn));
12582
3949d0091a44 imapc: Fixed authenticating with AUTHENTICATE command without SASL-IR.
Timo Sirainen <tss@iki.fi>
parents: 12581
diff changeset
576 imapc_connection_cmd(conn, cmd,
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
577 imapc_connection_login_cb, conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
578 }
12621
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
579 }
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
580
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
581 static void
12624
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
582 imapc_connection_starttls_cb(const struct imapc_command_reply *reply,
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
583 void *context)
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
584 {
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
585 struct imapc_connection *conn = context;
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
586
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
587 if (reply->state != IMAPC_COMMAND_STATE_OK) {
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
588 imapc_connection_input_error(conn, "STARTTLS failed: %s",
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
589 reply->text_full);
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
590 return;
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
591 }
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
592
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
593 if (imapc_connection_ssl_init(conn) < 0)
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
594 imapc_connection_disconnect(conn);
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
595 else
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
596 imapc_connection_authenticate(conn);
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
597 }
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
598
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
599 static void imapc_connection_starttls(struct imapc_connection *conn)
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
600 {
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
601 if (conn->client->set.ssl_mode == IMAPC_CLIENT_SSL_MODE_STARTTLS &&
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
602 conn->ssl_iostream == NULL) {
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
603 if ((conn->capabilities & IMAPC_CAPABILITY_STARTTLS) == 0) {
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
604 i_error("imapc(%s): Requested STARTTLS, "
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
605 "but server doesn't support it",
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
606 conn->name);
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
607 imapc_connection_disconnect(conn);
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
608 return;
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
609 }
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
610 imapc_connection_cmd(conn, "STARTTLS",
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
611 imapc_connection_starttls_cb, conn);
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
612 return;
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
613 }
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
614 imapc_connection_authenticate(conn);
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
615 }
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
616
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
617 static void
12621
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
618 imapc_connection_capability_cb(const struct imapc_command_reply *reply,
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
619 void *context)
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
620 {
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
621 struct imapc_connection *conn = context;
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
622
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
623 if (reply->state != IMAPC_COMMAND_STATE_OK) {
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
624 imapc_connection_input_error(conn,
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
625 "Failed to get capabilities: %s", reply->text_full);
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
626 } else if (conn->capabilities == 0) {
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
627 imapc_connection_input_error(conn,
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
628 "Capabilities not returned by server");
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
629 } else {
12624
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
630 imapc_connection_starttls(conn);
12621
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
631 }
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
632 }
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
633
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
634 static int imapc_connection_input_banner(struct imapc_connection *conn)
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
635 {
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
636 const struct imap_arg *imap_args;
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
637 const char *key, *value;
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
638 int ret;
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
639
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
640 if ((ret = imapc_connection_read_line(conn, &imap_args)) <= 0)
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
641 return ret;
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
642
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
643 if (imapc_connection_handle_imap_resp_text(conn, imap_args,
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
644 &key, &value) < 0)
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
645 return -1;
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
646 imapc_connection_set_state(conn, IMAPC_CONNECTION_STATE_AUTHENTICATING);
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
647
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
648 if (conn->capabilities == 0) {
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
649 /* capabilities weren't sent in the banner. ask for them. */
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
650 imapc_connection_cmd(conn, "CAPABILITY",
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
651 imapc_connection_capability_cb, conn);
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
652 } else {
12624
893e0738733b imapc: Added support for STARTTLS.
Timo Sirainen <tss@iki.fi>
parents: 12622
diff changeset
653 imapc_connection_starttls(conn);
12621
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
654 }
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
655 conn->input_callback = NULL;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
656 imapc_connection_input_reset(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
657 return 1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
658 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
659
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
660 static int imapc_connection_input_untagged(struct imapc_connection *conn)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
661 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
662 const struct imap_arg *imap_args;
12621
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
663 const char *name, *value;
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
664 struct imapc_untagged_reply reply;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
665 int ret;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
666
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
667 if (conn->state == IMAPC_CONNECTION_STATE_CONNECTING) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
668 /* input banner */
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
669 name = imap_parser_read_word(conn->parser);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
670 if (name == NULL)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
671 return 0;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
672
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
673 if (strcasecmp(name, "OK") != 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
674 imapc_connection_input_error(conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
675 "Banner doesn't begin with OK: %s", name);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
676 return -1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
677 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
678 conn->input_callback = imapc_connection_input_banner;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
679 return 1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
680 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
681
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
682 if ((ret = imapc_connection_read_line(conn, &imap_args)) <= 0)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
683 return ret;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
684 if (!imap_arg_get_atom(&imap_args[0], &name)) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
685 imapc_connection_input_error(conn, "Invalid untagged reply");
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
686 return -1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
687 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
688 imap_args++;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
689
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
690 if (conn->input_state == IMAPC_INPUT_STATE_UNTAGGED &&
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
691 str_to_uint32(name, &conn->cur_num) == 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
692 /* <seq> <event> */
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
693 conn->input_state = IMAPC_INPUT_STATE_UNTAGGED_NUM;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
694 if (!imap_arg_get_atom(&imap_args[0], &name)) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
695 imapc_connection_input_error(conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
696 "Invalid untagged reply");
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
697 return -1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
698 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
699 imap_args++;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
700 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
701 memset(&reply, 0, sizeof(reply));
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
702
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
703 if (strcasecmp(name, "OK") == 0) {
12590
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
704 if (imapc_connection_handle_imap_resp_text(conn, imap_args,
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
705 &reply.resp_text_key,
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
706 &reply.resp_text_value) < 0)
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
707 return -1;
12621
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
708 } else if (strcasecmp(name, "CAPABILITY") == 0) {
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
709 value = imap_args_to_str(imap_args);
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
710 if (imapc_connection_parse_capability(conn, value) < 0)
4244c828b59d imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
Timo Sirainen <tss@iki.fi>
parents: 12617
diff changeset
711 return -1;
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
712 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
713
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
714 reply.name = name;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
715 reply.num = conn->cur_num;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
716 reply.args = imap_args;
12615
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
717 reply.file_args = array_get(&conn->literal_files,
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
718 &reply.file_args_count);
3dde816d945d imapc: Write large message bodies to temp files rather than keeping in memory.
Timo Sirainen <tss@iki.fi>
parents: 12609
diff changeset
719
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
720 if (conn->selected_box != NULL) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
721 reply.untagged_box_context =
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
722 conn->selected_box->untagged_box_context;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
723 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
724 conn->client->untagged_callback(&reply, conn->client->untagged_context);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
725 if (imap_arg_atom_equals(imap_args, "EXPUNGE") &&
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
726 conn->selected_box != NULL) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
727 /* keep track of expunge map internally */
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
728 imapc_seqmap_expunge(conn->selected_box->seqmap, conn->cur_num);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
729 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
730 imapc_connection_input_reset(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
731 return 1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
732 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
733
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
734 static int imapc_connection_input_plus(struct imapc_connection *conn)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
735 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
736 struct imapc_command *const *cmd_p;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
737
12592
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
738 if (conn->idle_plus_waiting) {
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
739 /* "+ idling" reply for IDLE command */
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
740 conn->idle_plus_waiting = FALSE;
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
741 conn->idling = TRUE;
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
742 return imapc_connection_skip_line(conn);
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
743 }
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
744
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
745 if (array_count(&conn->cmd_send_queue) == 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
746 imapc_connection_input_error(conn, "Unexpected '+'");
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
747 return -1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
748 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
749 cmd_p = array_idx(&conn->cmd_send_queue, 0);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
750 imapc_command_send_more(conn, *cmd_p);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
751
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
752 conn->input_state = IMAPC_INPUT_STATE_SKIPLINE;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
753 return imapc_connection_skip_line(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
754 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
755
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
756 static int imapc_connection_input_tagged(struct imapc_connection *conn)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
757 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
758 struct imapc_command *const *cmds, *cmd = NULL;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
759 unsigned int i, count;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
760 char *line, *linep;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
761 const char *p;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
762 struct imapc_command_reply reply;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
763
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
764 line = i_stream_next_line(conn->input);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
765 if (line == NULL)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
766 return 0;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
767
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
768 memset(&reply, 0, sizeof(reply));
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
769
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
770 linep = strchr(line, ' ');
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
771 if (linep == NULL)
12590
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
772 reply.text_full = "";
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
773 else {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
774 *linep = '\0';
12590
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
775 reply.text_full = linep + 1;
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
776 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
777
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
778 if (strcasecmp(line, "ok") == 0)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
779 reply.state = IMAPC_COMMAND_STATE_OK;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
780 else if (strcasecmp(line, "no") == 0)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
781 reply.state = IMAPC_COMMAND_STATE_NO;
12592
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
782 else if (strcasecmp(line, "bad") == 0) {
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
783 i_error("imapc(%s): Command failed with BAD: %u %s",
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
784 conn->name, conn->cur_tag, line);
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
785 reply.state = IMAPC_COMMAND_STATE_BAD;
12592
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
786 } else {
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
787 imapc_connection_input_error(conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
788 "Invalid state in tagged reply: %u %s",
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
789 conn->cur_tag, line);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
790 return -1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
791 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
792
12590
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
793 if (reply.text_full[0] == '[') {
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
794 /* get resp-text */
12590
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
795 if (imapc_connection_handle_resp_text(conn, reply.text_full,
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
796 &reply.resp_text_key,
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
797 &reply.resp_text_value) < 0)
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
798 return -1;
12590
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
799
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
800 p = strchr(reply.text_full, ']');
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
801 i_assert(p != NULL);
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
802 reply.text_without_resp = p + 1;
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
803 if (reply.text_without_resp[0] == ' ')
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
804 reply.text_without_resp++;
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
805 } else {
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
806 reply.text_without_resp = reply.text_full;
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
807 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
808
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
809 /* find the command. it's either the first command in send queue
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
810 (literal failed) or somewhere in wait list. */
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
811 cmds = array_get(&conn->cmd_send_queue, &count);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
812 if (count > 0 && cmds[0]->tag == conn->cur_tag) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
813 cmd = cmds[0];
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
814 array_delete(&conn->cmd_send_queue, 0, 1);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
815 } else {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
816 cmds = array_get(&conn->cmd_wait_list, &count);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
817 for (i = 0; i < count; i++) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
818 if (cmds[i]->tag == conn->cur_tag) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
819 cmd = cmds[i];
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
820 array_delete(&conn->cmd_wait_list, i, 1);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
821 break;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
822 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
823 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
824 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
825
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
826 if (cmd == NULL) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
827 imapc_connection_input_error(conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
828 "Unknown tag in a reply: %u %s", conn->cur_tag, line);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
829 return -1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
830 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
831
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
832 imapc_connection_input_reset(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
833 cmd->callback(&reply, cmd->context);
12604
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
834 imapc_command_free(cmd);
12601
1413a0fa9ae7 imapc: Added support for changing flags and expunging.
Timo Sirainen <tss@iki.fi>
parents: 12596
diff changeset
835 return 1;
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
836 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
837
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
838 static int imapc_connection_input_one(struct imapc_connection *conn)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
839 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
840 const char *tag;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
841 int ret = -1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
842
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
843 if (conn->input_callback != NULL)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
844 return conn->input_callback(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
845
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
846 switch (conn->input_state) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
847 case IMAPC_INPUT_STATE_NONE:
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
848 tag = imap_parser_read_word(conn->parser);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
849 if (tag == NULL)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
850 return 0;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
851
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
852 if (strcmp(tag, "") == 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
853 /* FIXME: why do we get here.. */
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
854 conn->input_state = IMAPC_INPUT_STATE_SKIPLINE;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
855 return imapc_connection_skip_line(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
856 } else if (strcmp(tag, "*") == 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
857 conn->input_state = IMAPC_INPUT_STATE_UNTAGGED;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
858 conn->cur_num = 0;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
859 ret = imapc_connection_input_untagged(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
860 } else if (strcmp(tag, "+") == 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
861 ret = imapc_connection_input_plus(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
862 } else {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
863 conn->input_state = IMAPC_INPUT_STATE_TAGGED;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
864 if (str_to_uint(tag, &conn->cur_tag) < 0 ||
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
865 conn->cur_tag == 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
866 imapc_connection_input_error(conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
867 "Invalid command tag: %s", tag);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
868 ret = -1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
869 } else {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
870 ret = imapc_connection_input_tagged(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
871 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
872 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
873 break;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
874 case IMAPC_INPUT_STATE_UNTAGGED:
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
875 case IMAPC_INPUT_STATE_UNTAGGED_NUM:
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
876 ret = imapc_connection_input_untagged(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
877 break;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
878 case IMAPC_INPUT_STATE_TAGGED:
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
879 ret = imapc_connection_input_tagged(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
880 break;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
881 case IMAPC_INPUT_STATE_SKIPLINE:
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
882 ret = imapc_connection_skip_line(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
883 break;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
884 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
885 return ret;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
886 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
887
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
888 static void imapc_connection_input(struct imapc_connection *conn)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
889 {
12617
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
890 ssize_t ret;
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
891
12622
31eb7db0c4b9 imapc: Avoid hanging with SSL
Timo Sirainen <tss@iki.fi>
parents: 12621
diff changeset
892 /* we need to read as much as we can with SSL streams to avoid
31eb7db0c4b9 imapc: Avoid hanging with SSL
Timo Sirainen <tss@iki.fi>
parents: 12621
diff changeset
893 hanging */
31eb7db0c4b9 imapc: Avoid hanging with SSL
Timo Sirainen <tss@iki.fi>
parents: 12621
diff changeset
894 while (conn->input != NULL && (ret = i_stream_read(conn->input)) > 0)
12617
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
895 imapc_connection_input_pending(conn);
12622
31eb7db0c4b9 imapc: Avoid hanging with SSL
Timo Sirainen <tss@iki.fi>
parents: 12621
diff changeset
896
31eb7db0c4b9 imapc: Avoid hanging with SSL
Timo Sirainen <tss@iki.fi>
parents: 12621
diff changeset
897 if (ret < 0) {
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
898 /* disconnected */
12617
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
899 if (conn->ssl_iostream == NULL) {
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
900 i_error("imapc(%s): Server disconnected unexpectedly",
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
901 conn->name);
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
902 } else {
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
903 i_error("imapc(%s): Server disconnected: %s", conn->name,
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
904 ssl_iostream_get_last_error(conn->ssl_iostream));
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
905 }
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
906 imapc_connection_disconnect(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
907 return;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
908 }
12617
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
909 }
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
910
12617
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
911 static int imapc_connection_ssl_handshaked(void *context)
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
912 {
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
913 struct imapc_connection *conn = context;
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
914
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
915 if (ssl_iostream_has_valid_client_cert(conn->ssl_iostream))
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
916 return 0;
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
917
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
918 if (!ssl_iostream_has_broken_client_cert(conn->ssl_iostream)) {
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
919 i_error("imapc(%s): SSL certificate not received", conn->name);
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
920 } else {
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
921 i_error("imapc(%s): Received invalid SSL certificate",
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
922 conn->name);
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
923 }
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
924 i_stream_close(conn->input);
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
925 return -1;
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
926 }
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
927
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
928 static int imapc_connection_ssl_init(struct imapc_connection *conn)
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
929 {
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
930 struct ssl_iostream_settings ssl_set;
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
931 const char *source;
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
932
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
933 if (conn->client->ssl_ctx == NULL) {
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
934 i_error("imapc(%s): No SSL context", conn->name);
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
935 return -1;
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
936 }
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
937
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
938 memset(&ssl_set, 0, sizeof(ssl_set));
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
939 ssl_set.verbose_invalid_cert = TRUE;
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
940 ssl_set.verify_remote_cert = TRUE;
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
941 ssl_set.require_valid_cert = TRUE;
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
942
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
943 source = t_strdup_printf("imapc(%s): ", conn->name);
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
944 if (io_stream_create_ssl(conn->client->ssl_ctx, source, &ssl_set,
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
945 &conn->input, &conn->output,
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
946 &conn->ssl_iostream) < 0) {
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
947 i_error("imapc(%s): Couldn't initialize SSL client",
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
948 conn->name);
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
949 return -1;
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
950 }
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
951 ssl_iostream_set_handshake_callback(conn->ssl_iostream,
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
952 imapc_connection_ssl_handshaked,
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
953 conn);
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
954 if (ssl_iostream_handshake(conn->ssl_iostream) < 0) {
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
955 i_error("imapc(%s): SSL handshake failed", conn->name);
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
956 return -1;
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
957 }
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
958 imap_parser_set_streams(conn->parser, conn->input, NULL);
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
959 return 0;
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
960 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
961
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
962 static void imapc_connection_connected(struct imapc_connection *conn)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
963 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
964 const struct ip_addr *ip = &conn->ips[conn->prev_connect_idx];
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
965 int err;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
966
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
967 err = net_geterror(conn->fd);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
968 if (err != 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
969 i_error("imapc(%s): connect(%s, %u) failed: %s",
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
970 conn->name, net_ip2addr(ip), conn->client->set.port,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
971 strerror(err));
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
972 imapc_connection_disconnect(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
973 return;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
974 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
975 io_remove(&conn->io);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
976 conn->io = io_add(conn->fd, IO_READ, imapc_connection_input, conn);
12617
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
977
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
978 if (conn->client->set.ssl_mode == IMAPC_CLIENT_SSL_MODE_IMMEDIATE) {
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
979 if (imapc_connection_ssl_init(conn) < 0)
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
980 imapc_connection_disconnect(conn);
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
981 }
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
982 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
983
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
984 static void imapc_connection_timeout(struct imapc_connection *conn)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
985 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
986 const struct ip_addr *ip = &conn->ips[conn->prev_connect_idx];
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
987
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
988 switch (conn->state) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
989 case IMAPC_CONNECTION_STATE_CONNECTING:
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
990 i_error("imapc(%s): connect(%s, %u) timed out after %u seconds",
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
991 conn->name, net_ip2addr(ip), conn->client->set.port,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
992 IMAPC_CONNECT_TIMEOUT_MSECS/1000);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
993 break;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
994 case IMAPC_CONNECTION_STATE_AUTHENTICATING:
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
995 i_error("imapc(%s): Authentication timed out after %u seconds",
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
996 conn->name, IMAPC_CONNECT_TIMEOUT_MSECS/1000);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
997 break;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
998 default:
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
999 i_unreached();
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1000 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1001 imapc_connection_disconnect(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1002 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1003
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1004 static void imapc_connection_connect_next_ip(struct imapc_connection *conn)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1005 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1006 int fd;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1007
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1008 conn->prev_connect_idx = (conn->prev_connect_idx+1) % conn->ips_count;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1009 fd = net_connect_ip(&conn->ips[conn->prev_connect_idx],
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1010 conn->client->set.port, NULL);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1011 if (fd == -1) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1012 imapc_connection_set_state(conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1013 IMAPC_CONNECTION_STATE_DISCONNECTED);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1014 return;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1015 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1016 conn->fd = fd;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1017 conn->input = i_stream_create_fd(fd, (size_t)-1, FALSE);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1018 conn->output = o_stream_create_fd(fd, (size_t)-1, FALSE);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1019 conn->io = io_add(fd, IO_WRITE, imapc_connection_connected, conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1020 conn->parser = imap_parser_create(conn->input, NULL, (size_t)-1);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1021 conn->to = timeout_add(IMAPC_CONNECT_TIMEOUT_MSECS,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1022 imapc_connection_timeout, conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1023 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1024
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1025 static void
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1026 imapc_connection_dns_callback(const struct dns_lookup_result *result,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1027 void *context)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1028 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1029 struct imapc_connection *conn = context;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1030
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1031 if (result->ret != 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1032 i_error("imapc(%s): dns_lookup(%s) failed: %s",
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1033 conn->name, conn->client->set.host, result->error);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1034 imapc_connection_set_state(conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1035 IMAPC_CONNECTION_STATE_DISCONNECTED);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1036 return;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1037 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1038
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1039 i_assert(result->ips_count > 0);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1040 conn->ips_count = result->ips_count;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1041 conn->ips = i_new(struct ip_addr, conn->ips_count);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1042 memcpy(conn->ips, result->ips, sizeof(*conn->ips) * conn->ips_count);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1043 conn->prev_connect_idx = conn->ips_count - 1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1044
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1045 imapc_connection_connect_next_ip(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1046 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1047
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1048 void imapc_connection_connect(struct imapc_connection *conn)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1049 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1050 struct dns_lookup_settings dns_set;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1051
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1052 if (conn->fd != -1)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1053 return;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1054
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1055 memset(&dns_set, 0, sizeof(dns_set));
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1056 dns_set.dns_client_socket_path =
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1057 conn->client->set.dns_client_socket_path;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1058 dns_set.timeout_msecs = IMAPC_DNS_LOOKUP_TIMEOUT_MSECS;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1059
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1060 imapc_connection_set_state(conn, IMAPC_CONNECTION_STATE_CONNECTING);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1061 if (conn->ips_count == 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1062 (void)dns_lookup(conn->client->set.host, &dns_set,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1063 imapc_connection_dns_callback, conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1064 } else {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1065 imapc_connection_connect_next_ip(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1066 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1067 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1068
12609
391ba80cb125 imapc: Send UID FETCH commands with larger uidset parameter if possible.
Timo Sirainen <tss@iki.fi>
parents: 12604
diff changeset
1069 void imapc_connection_input_pending(struct imapc_connection *conn)
391ba80cb125 imapc: Send UID FETCH commands with larger uidset parameter if possible.
Timo Sirainen <tss@iki.fi>
parents: 12604
diff changeset
1070 {
391ba80cb125 imapc: Send UID FETCH commands with larger uidset parameter if possible.
Timo Sirainen <tss@iki.fi>
parents: 12604
diff changeset
1071 int ret = 1;
391ba80cb125 imapc: Send UID FETCH commands with larger uidset parameter if possible.
Timo Sirainen <tss@iki.fi>
parents: 12604
diff changeset
1072
391ba80cb125 imapc: Send UID FETCH commands with larger uidset parameter if possible.
Timo Sirainen <tss@iki.fi>
parents: 12604
diff changeset
1073 if (conn->input == NULL)
391ba80cb125 imapc: Send UID FETCH commands with larger uidset parameter if possible.
Timo Sirainen <tss@iki.fi>
parents: 12604
diff changeset
1074 return;
391ba80cb125 imapc: Send UID FETCH commands with larger uidset parameter if possible.
Timo Sirainen <tss@iki.fi>
parents: 12604
diff changeset
1075
391ba80cb125 imapc: Send UID FETCH commands with larger uidset parameter if possible.
Timo Sirainen <tss@iki.fi>
parents: 12604
diff changeset
1076 o_stream_cork(conn->output);
12617
7b7434fef6ff imapc: Added initial support for SSL.
Timo Sirainen <tss@iki.fi>
parents: 12615
diff changeset
1077 while (ret > 0 && !conn->client->stop_now && conn->input != NULL) {
12609
391ba80cb125 imapc: Send UID FETCH commands with larger uidset parameter if possible.
Timo Sirainen <tss@iki.fi>
parents: 12604
diff changeset
1078 T_BEGIN {
391ba80cb125 imapc: Send UID FETCH commands with larger uidset parameter if possible.
Timo Sirainen <tss@iki.fi>
parents: 12604
diff changeset
1079 ret = imapc_connection_input_one(conn);
391ba80cb125 imapc: Send UID FETCH commands with larger uidset parameter if possible.
Timo Sirainen <tss@iki.fi>
parents: 12604
diff changeset
1080 } T_END;
391ba80cb125 imapc: Send UID FETCH commands with larger uidset parameter if possible.
Timo Sirainen <tss@iki.fi>
parents: 12604
diff changeset
1081 }
391ba80cb125 imapc: Send UID FETCH commands with larger uidset parameter if possible.
Timo Sirainen <tss@iki.fi>
parents: 12604
diff changeset
1082
391ba80cb125 imapc: Send UID FETCH commands with larger uidset parameter if possible.
Timo Sirainen <tss@iki.fi>
parents: 12604
diff changeset
1083 if (conn->output != NULL)
391ba80cb125 imapc: Send UID FETCH commands with larger uidset parameter if possible.
Timo Sirainen <tss@iki.fi>
parents: 12604
diff changeset
1084 o_stream_uncork(conn->output);
391ba80cb125 imapc: Send UID FETCH commands with larger uidset parameter if possible.
Timo Sirainen <tss@iki.fi>
parents: 12604
diff changeset
1085 }
391ba80cb125 imapc: Send UID FETCH commands with larger uidset parameter if possible.
Timo Sirainen <tss@iki.fi>
parents: 12604
diff changeset
1086
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1087 static struct imapc_command *
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1088 imapc_command_begin(imapc_command_callback_t *callback, void *context)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1089 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1090 static unsigned int cmd_tag_counter = 0;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1091 struct imapc_command *cmd;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1092 pool_t pool;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1093
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1094 pool = pool_alloconly_create("imapc command", 1024);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1095 cmd = p_new(pool, struct imapc_command, 1);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1096 cmd->pool = pool;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1097 cmd->callback = callback;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1098 cmd->context = context;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1099
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1100 if (++cmd_tag_counter == 0)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1101 cmd_tag_counter++;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1102 cmd->tag = cmd_tag_counter;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1103 return cmd;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1104 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1105
12604
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1106 static void imapc_command_free(struct imapc_command *cmd)
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1107 {
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1108 struct imapc_command_stream *stream;
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1109
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1110 if (array_is_created(&cmd->streams)) {
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1111 array_foreach_modifiable(&cmd->streams, stream)
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1112 i_stream_unref(&stream->input);
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1113 }
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1114 pool_unref(&cmd->pool);
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1115 }
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1116
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1117 static bool
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1118 parse_sync_literal(const unsigned char *data, unsigned int pos,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1119 unsigned int *value_r)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1120 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1121 unsigned int value = 0, mul = 1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1122
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1123 /* data should contain "{size}\r\n" and pos points after \n */
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1124 if (pos <= 4 || data[pos-1] != '\n' || data[pos-2] != '\r' ||
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1125 data[pos-3] != '}' || !i_isdigit(data[pos-4]))
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1126 return FALSE;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1127 pos -= 4;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1128
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1129 do {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1130 value += (data[pos] - '0') * mul;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1131 mul = mul*10;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1132 pos--;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1133 } while (pos > 0 && i_isdigit(data[pos]));
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1134
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1135 if (pos == 0 || data[pos] != '{')
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1136 return FALSE;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1137
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1138 *value_r = value;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1139 return TRUE;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1140 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1141
12604
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1142 static void imapc_command_send_done(struct imapc_connection *conn,
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1143 struct imapc_command *cmd)
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1144 {
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1145 /* everything sent. move command to wait list. */
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1146 i_assert(*array_idx(&conn->cmd_send_queue, 0) == cmd);
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1147 array_delete(&conn->cmd_send_queue, 0, 1);
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1148 array_append(&conn->cmd_wait_list, &cmd, 1);
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1149
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1150 if (array_count(&conn->cmd_send_queue) > 0 &&
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1151 conn->state == IMAPC_CONNECTION_STATE_DONE) {
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1152 /* send the next command in queue */
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1153 struct imapc_command *const *cmd2_p =
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1154 array_idx(&conn->cmd_send_queue, 0);
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1155 imapc_command_send_more(conn, *cmd2_p);
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1156 }
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1157 }
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1158
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1159 static int imapc_command_try_send_stream(struct imapc_connection *conn,
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1160 struct imapc_command *cmd)
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1161 {
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1162 struct imapc_command_stream *stream;
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1163
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1164 if (!array_is_created(&cmd->streams) || array_count(&cmd->streams) == 0)
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1165 return -1;
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1166
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1167 stream = array_idx_modifiable(&cmd->streams, 0);
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1168 if (stream->pos != cmd->send_pos)
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1169 return -1;
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1170
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1171 /* we're sending the stream now */
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1172 (void)o_stream_send_istream(conn->output, stream->input);
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1173 if (!i_stream_is_eof(stream->input))
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1174 return 0;
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1175
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1176 /* finished with the stream */
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1177 i_stream_unref(&stream->input);
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1178 array_delete(&cmd->streams, 0, 1);
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1179
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1180 i_assert(cmd->send_pos != cmd->data->used);
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1181 return 1;
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1182 }
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1183
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1184 static void imapc_command_send_more(struct imapc_connection *conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1185 struct imapc_command *cmd)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1186 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1187 const unsigned char *p;
12581
9db6762167fb imapc: Fixed sending non-syncing literals.
Timo Sirainen <tss@iki.fi>
parents: 12580
diff changeset
1188 unsigned int seek_pos, start_pos, end_pos, size;
12604
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1189 int ret;
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1190
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1191 i_assert(cmd->send_pos < cmd->data->used);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1192
12604
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1193 if ((ret = imapc_command_try_send_stream(conn, cmd)) == 0)
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1194 return;
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1195
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1196 seek_pos = cmd->send_pos;
12604
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1197 if (seek_pos != 0 && ret < 0) {
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1198 /* skip over the literal. we can also get here from
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1199 AUTHENTICATE command, which doesn't use a literal */
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1200 if (parse_sync_literal(cmd->data->data, seek_pos, &size)) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1201 seek_pos += size;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1202 i_assert(seek_pos <= cmd->data->used);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1203 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1204 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1205
12581
9db6762167fb imapc: Fixed sending non-syncing literals.
Timo Sirainen <tss@iki.fi>
parents: 12580
diff changeset
1206 do {
9db6762167fb imapc: Fixed sending non-syncing literals.
Timo Sirainen <tss@iki.fi>
parents: 12580
diff changeset
1207 start_pos = seek_pos;
9db6762167fb imapc: Fixed sending non-syncing literals.
Timo Sirainen <tss@iki.fi>
parents: 12580
diff changeset
1208 p = memchr(CONST_PTR_OFFSET(cmd->data->data, seek_pos), '\n',
9db6762167fb imapc: Fixed sending non-syncing literals.
Timo Sirainen <tss@iki.fi>
parents: 12580
diff changeset
1209 cmd->data->used - seek_pos);
9db6762167fb imapc: Fixed sending non-syncing literals.
Timo Sirainen <tss@iki.fi>
parents: 12580
diff changeset
1210 i_assert(p != NULL);
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1211
12581
9db6762167fb imapc: Fixed sending non-syncing literals.
Timo Sirainen <tss@iki.fi>
parents: 12580
diff changeset
1212 seek_pos = p - (const unsigned char *)cmd->data->data + 1;
9db6762167fb imapc: Fixed sending non-syncing literals.
Timo Sirainen <tss@iki.fi>
parents: 12580
diff changeset
1213 /* keep going for LITERAL+ command */
9db6762167fb imapc: Fixed sending non-syncing literals.
Timo Sirainen <tss@iki.fi>
parents: 12580
diff changeset
1214 } while (start_pos + 3 < seek_pos &&
9db6762167fb imapc: Fixed sending non-syncing literals.
Timo Sirainen <tss@iki.fi>
parents: 12580
diff changeset
1215 p[-1] == '\r' && p[-2] == '}' && p[-3] == '+');
9db6762167fb imapc: Fixed sending non-syncing literals.
Timo Sirainen <tss@iki.fi>
parents: 12580
diff changeset
1216 end_pos = seek_pos;
9db6762167fb imapc: Fixed sending non-syncing literals.
Timo Sirainen <tss@iki.fi>
parents: 12580
diff changeset
1217
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1218 o_stream_send(conn->output,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1219 CONST_PTR_OFFSET(cmd->data->data, cmd->send_pos),
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1220 end_pos - cmd->send_pos);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1221 cmd->send_pos = end_pos;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1222
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1223 if (cmd->send_pos == cmd->data->used) {
12604
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1224 i_assert(!array_is_created(&cmd->streams) ||
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1225 array_count(&cmd->streams) == 0);
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1226 imapc_command_send_done(conn, cmd);
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1227 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1228 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1229
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1230 static void imapc_command_send(struct imapc_connection *conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1231 struct imapc_command *cmd)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1232 {
12592
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1233 if ((conn->idling || conn->idle_plus_waiting) && !conn->idle_stopping) {
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1234 conn->idle_stopping = TRUE;
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1235 o_stream_send_str(conn->output, "DONE\r\n");
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1236 }
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1237 switch (conn->state) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1238 case IMAPC_CONNECTION_STATE_AUTHENTICATING:
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1239 array_insert(&conn->cmd_send_queue, 0, &cmd, 1);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1240 imapc_command_send_more(conn, cmd);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1241 break;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1242 case IMAPC_CONNECTION_STATE_DONE:
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1243 array_append(&conn->cmd_send_queue, &cmd, 1);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1244 if (array_count(&conn->cmd_send_queue) == 1)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1245 imapc_command_send_more(conn, cmd);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1246 break;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1247 default:
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1248 array_append(&conn->cmd_send_queue, &cmd, 1);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1249 break;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1250 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1251 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1252
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1253 void imapc_connection_cmd(struct imapc_connection *conn, const char *cmdline,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1254 imapc_command_callback_t *callback, void *context)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1255 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1256 struct imapc_command *cmd;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1257 unsigned int len = strlen(cmdline);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1258
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1259 cmd = imapc_command_begin(callback, context);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1260 cmd->data = str_new(cmd->pool, len + 2);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1261 str_printfa(cmd->data, "%u %s\r\n", cmd->tag, cmdline);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1262 imapc_command_send(conn, cmd);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1263 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1264
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1265 void imapc_connection_cmdf(struct imapc_connection *conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1266 imapc_command_callback_t *callback, void *context,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1267 const char *cmd_fmt, ...)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1268 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1269 va_list args;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1270
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1271 va_start(args, cmd_fmt);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1272 imapc_connection_cmdvf(conn, callback, context, cmd_fmt, args);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1273 va_end(args);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1274 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1275
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1276 void imapc_connection_cmdvf(struct imapc_connection *conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1277 imapc_command_callback_t *callback, void *context,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1278 const char *cmd_fmt, va_list args)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1279 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1280 struct imapc_command *cmd;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1281 unsigned int i;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1282
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1283 cmd = imapc_command_begin(callback, context);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1284 cmd->data = str_new(cmd->pool, 128);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1285 str_printfa(cmd->data, "%u ", cmd->tag);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1286
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1287 for (i = 0; cmd_fmt[i] != '\0'; i++) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1288 if (cmd_fmt[i] != '%') {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1289 str_append_c(cmd->data, cmd_fmt[i]);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1290 continue;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1291 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1292
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1293 switch (cmd_fmt[++i]) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1294 case '\0':
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1295 i_unreached();
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1296 case 'u': {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1297 unsigned int arg = va_arg(args, unsigned int);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1298
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1299 str_printfa(cmd->data, "%u", arg);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1300 break;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1301 }
12604
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1302 case 'p': {
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1303 struct istream *input = va_arg(args, struct istream *);
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1304 struct imapc_command_stream *s;
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1305 uoff_t size;
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1306
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1307 if (!array_is_created(&cmd->streams))
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1308 p_array_init(&cmd->streams, cmd->pool, 2);
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1309 if (i_stream_get_size(input, TRUE, &size) < 0)
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1310 size = 0;
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1311 str_printfa(cmd->data, "{%"PRIuSIZE_T"}\r\n", size);
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1312 s = array_append_space(&cmd->streams);
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1313 s->pos = str_len(cmd->data);
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1314 s->input = input;
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1315 i_stream_ref(input);
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1316 break;
0e5c36a54ce8 imapc: Added support for saving and copying messages.
Timo Sirainen <tss@iki.fi>
parents: 12601
diff changeset
1317 }
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1318 case 's': {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1319 const char *arg = va_arg(args, const char *);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1320
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1321 if (!need_literal(arg))
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1322 imap_dquote_append(cmd->data, arg);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1323 else if ((conn->capabilities &
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1324 IMAPC_CAPABILITY_LITERALPLUS) != 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1325 str_printfa(cmd->data, "{%"PRIuSIZE_T"+}\r\n%s",
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1326 strlen(arg), arg);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1327 } else {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1328 str_printfa(cmd->data, "{%"PRIuSIZE_T"}\r\n%s",
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1329 strlen(arg), arg);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1330 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1331 break;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1332 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1333 case '1': {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1334 /* %1s - no quoting */
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1335 const char *arg = va_arg(args, const char *);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1336
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1337 i_assert(cmd_fmt[++i] == 's');
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1338 str_append(cmd->data, arg);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1339 break;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1340 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1341 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1342 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1343 str_append(cmd->data, "\r\n");
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1344
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1345 imapc_command_send(conn, cmd);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1346 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1347
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1348 enum imapc_connection_state
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1349 imapc_connection_get_state(struct imapc_connection *conn)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1350 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1351 return conn->state;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1352 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1353
12592
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1354 enum imapc_capability
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1355 imapc_connection_get_capabilities(struct imapc_connection *conn)
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1356 {
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1357 return conn->capabilities;
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1358 }
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1359
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1360 void imapc_connection_select(struct imapc_client_mailbox *box, const char *name,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1361 imapc_command_callback_t *callback, void *context)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1362 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1363 struct imapc_connection *conn = box->conn;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1364
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1365 i_assert(conn->selecting_box == NULL);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1366
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1367 if (conn->selected_box != NULL &&
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1368 (conn->capabilities & IMAPC_CAPABILITY_QRESYNC) != 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1369 /* server will send a [CLOSED] once selected mailbox is
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1370 closed */
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1371 conn->selecting_box = box;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1372 } else {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1373 /* we'll have to assume that all the future untagged messages
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1374 are for the mailbox we're selecting */
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1375 conn->selected_box = box;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1376 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1377
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1378 imapc_connection_cmdf(conn, callback, context, "SELECT %s", name);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1379 }
12592
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1380
12596
d75d4841c890 imapc: Implemented more methods.
Timo Sirainen <tss@iki.fi>
parents: 12595
diff changeset
1381 void imapc_connection_unselect(struct imapc_client_mailbox *box)
d75d4841c890 imapc: Implemented more methods.
Timo Sirainen <tss@iki.fi>
parents: 12595
diff changeset
1382 {
d75d4841c890 imapc: Implemented more methods.
Timo Sirainen <tss@iki.fi>
parents: 12595
diff changeset
1383 i_assert(box->conn->selected_box == box ||
d75d4841c890 imapc: Implemented more methods.
Timo Sirainen <tss@iki.fi>
parents: 12595
diff changeset
1384 box->conn->selecting_box == box);
d75d4841c890 imapc: Implemented more methods.
Timo Sirainen <tss@iki.fi>
parents: 12595
diff changeset
1385
d75d4841c890 imapc: Implemented more methods.
Timo Sirainen <tss@iki.fi>
parents: 12595
diff changeset
1386 box->conn->selected_box = NULL;
d75d4841c890 imapc: Implemented more methods.
Timo Sirainen <tss@iki.fi>
parents: 12595
diff changeset
1387 box->conn->selecting_box = NULL;
d75d4841c890 imapc: Implemented more methods.
Timo Sirainen <tss@iki.fi>
parents: 12595
diff changeset
1388 }
d75d4841c890 imapc: Implemented more methods.
Timo Sirainen <tss@iki.fi>
parents: 12595
diff changeset
1389
12592
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1390 static void
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1391 imapc_connection_idle_callback(const struct imapc_command_reply *reply ATTR_UNUSED,
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1392 void *context)
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1393 {
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1394 struct imapc_connection *conn = context;
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1395
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1396 conn->idling = FALSE;
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1397 conn->idle_plus_waiting = FALSE;
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1398 conn->idle_stopping = FALSE;
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1399 }
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1400
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1401 void imapc_connection_idle(struct imapc_connection *conn)
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1402 {
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1403 if (array_count(&conn->cmd_send_queue) != 0 ||
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1404 array_count(&conn->cmd_wait_list) != 0 ||
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1405 conn->idling || conn->idle_plus_waiting ||
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1406 (conn->capabilities & IMAPC_CAPABILITY_IDLE) == 0)
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1407 return;
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1408
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1409 imapc_connection_cmd(conn, "IDLE",
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1410 imapc_connection_idle_callback, conn);
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1411 conn->idle_plus_waiting = TRUE;
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1412 }