annotate src/lib-storage/index/imapc/imapc-connection.c @ 12592:475050722f54

imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
author Timo Sirainen <tss@iki.fi>
date Sun, 23 Jan 2011 22:57:01 +0200
parents 9e471f267fb4
children 5d97dfa9d86c
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"
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
9 #include "str.h"
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
10 #include "dns-lookup.h"
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
11 #include "imap-quote.h"
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
12 #include "imap-util.h"
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
13 #include "imap-parser.h"
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
14 #include "imapc-client-private.h"
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
15 #include "imapc-seqmap.h"
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
16 #include "imapc-connection.h"
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
17
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
18 #include <ctype.h>
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
19
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
20 #define IMAPC_DNS_LOOKUP_TIMEOUT_MSECS (1000*30)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
21 #define IMAPC_CONNECT_TIMEOUT_MSECS (1000*30)
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 enum imapc_input_state {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
24 IMAPC_INPUT_STATE_NONE = 0,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
25 IMAPC_INPUT_STATE_UNTAGGED,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
26 IMAPC_INPUT_STATE_UNTAGGED_NUM,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
27 IMAPC_INPUT_STATE_TAGGED,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
28 IMAPC_INPUT_STATE_SKIPLINE
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
29 };
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
30
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
31 struct imapc_command {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
32 pool_t pool;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
33 buffer_t *data;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
34 unsigned int send_pos;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
35 unsigned int tag;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
36
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
37 imapc_command_callback_t *callback;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
38 void *context;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
39 };
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
40
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
41 struct imapc_connection {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
42 struct imapc_client *client;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
43 char *name;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
44
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
45 int fd;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
46 struct io *io;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
47 struct istream *input;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
48 struct ostream *output;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
49 struct imap_parser *parser;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
50 struct timeout *to;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
51
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
52 int (*input_callback)(struct imapc_connection *conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
53 enum imapc_input_state input_state;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
54 unsigned int cur_tag;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
55 uint32_t cur_num;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
56
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
57 struct imapc_client_mailbox *selecting_box, *selected_box;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
58
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
59 imapc_connection_state_change *state_callback;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
60 enum imapc_connection_state state;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
61
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
62 enum imapc_capability capabilities;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
63 char **capabilities_list;
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 ARRAY_DEFINE(cmd_send_queue, struct imapc_command *);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
66 ARRAY_DEFINE(cmd_wait_list, struct imapc_command *);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
67
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
68 unsigned int ips_count, prev_connect_idx;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
69 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
70
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
71 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
72 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
73 unsigned int idle_plus_waiting:1;
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
74 };
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
75
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
76 static void imapc_connection_disconnect(struct imapc_connection *conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
77
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
78 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
79 struct imapc_command *cmd);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
80
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
81 struct imapc_connection *
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
82 imapc_connection_init(struct imapc_client *client,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
83 imapc_connection_state_change *state_callback)
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 struct imapc_connection *conn;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
86
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
87 conn = i_new(struct imapc_connection, 1);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
88 conn->client = client;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
89 conn->state_callback = state_callback;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
90 conn->fd = -1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
91 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
92 client->set.port);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
93 i_array_init(&conn->cmd_send_queue, 8);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
94 i_array_init(&conn->cmd_wait_list, 32);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
95 return conn;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
96 }
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 void imapc_connection_deinit(struct imapc_connection **_conn)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
99 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
100 struct imapc_connection *conn = *_conn;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
101
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
102 *_conn = NULL;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
103
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
104 imapc_connection_disconnect(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
105 p_strsplit_free(default_pool, conn->capabilities_list);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
106 array_free(&conn->cmd_send_queue);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
107 array_free(&conn->cmd_wait_list);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
108 i_free(conn->ips);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
109 i_free(conn->name);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
110 i_free(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
111 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
112
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
113 void imapc_connection_ioloop_changed(struct imapc_connection *conn)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
114 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
115 if (conn->io != NULL)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
116 conn->io = io_loop_move_io(&conn->io);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
117 if (conn->to != NULL)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
118 conn->to = io_loop_move_timeout(&conn->to);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
119 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
120
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
121 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
122 enum imapc_connection_state state)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
123 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
124 enum imapc_connection_state prev_state = conn->state;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
125
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
126 if (state == IMAPC_CONNECTION_STATE_DISCONNECTED) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
127 /* abort all pending commands */
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
128 struct imapc_command_reply reply;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
129 struct imapc_command *const *cmdp, *cmd;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
130
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
131 memset(&reply, 0, sizeof(reply));
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
132 reply.state = IMAPC_COMMAND_STATE_DISCONNECTED;
12590
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
133 reply.text_without_resp = reply.text_full =
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
134 "Disconnected from server";
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
135
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
136 while (array_count(&conn->cmd_wait_list) > 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
137 cmdp = array_idx(&conn->cmd_wait_list, 0);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
138 cmd = *cmdp;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
139 array_delete(&conn->cmd_wait_list, 0, 1);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
140
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
141 cmd->callback(&reply, cmd->context);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
142 pool_unref(&cmd->pool);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
143 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
144 while (array_count(&conn->cmd_send_queue) > 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
145 cmdp = array_idx(&conn->cmd_send_queue, 0);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
146 cmd = *cmdp;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
147 array_delete(&conn->cmd_send_queue, 0, 1);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
148
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
149 cmd->callback(&reply, cmd->context);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
150 pool_unref(&cmd->pool);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
151 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
152 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
153 if (state == IMAPC_CONNECTION_STATE_DONE) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
154 if (array_count(&conn->cmd_send_queue) > 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
155 struct imapc_command *const *cmd_p =
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
156 array_idx(&conn->cmd_send_queue, 0);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
157 imapc_command_send_more(conn, *cmd_p);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
158 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
159 }
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 conn->state = state;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
162 conn->state_callback(conn, conn->client, prev_state);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
163 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
164
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
165 static void imapc_connection_disconnect(struct imapc_connection *conn)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
166 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
167 if (conn->fd == -1)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
168 return;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
169
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
170 if (conn->to != NULL)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
171 timeout_remove(&conn->to);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
172 imap_parser_destroy(&conn->parser);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
173 io_remove(&conn->io);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
174 i_stream_destroy(&conn->input);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
175 o_stream_destroy(&conn->output);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
176 net_disconnect(conn->fd);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
177 conn->fd = -1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
178
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
179 imapc_connection_set_state(conn, IMAPC_CONNECTION_STATE_DISCONNECTED);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
180 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
181
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
182 static void ATTR_FORMAT(2, 3)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
183 imapc_connection_input_error(struct imapc_connection *conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
184 const char *fmt, ...)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
185 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
186 va_list va;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
187
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
188 va_start(va, fmt);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
189 i_error("imapc(%s): Server sent invalid input: %s",
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
190 conn->name, t_strdup_vprintf(fmt, va));
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
191 imapc_connection_disconnect(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
192 va_end(va);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
193 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
194
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
195 static int
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
196 imapc_connection_read_line(struct imapc_connection *conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
197 const struct imap_arg **imap_args_r)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
198 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
199 int ret;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
200 bool fatal;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
201
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
202 ret = imap_parser_read_args(conn->parser, 0, 0, imap_args_r);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
203 if (ret == -2) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
204 /* need more data */
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
205 return 0;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
206 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
207 if (ret < 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
208 imapc_connection_input_error(conn, "Error parsing input: %s",
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
209 imap_parser_get_error(conn->parser, &fatal));
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
210 return -1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
211 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
212 return 1;
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
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
215 static int
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
216 imapc_connection_parse_capability(struct imapc_connection *conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
217 const char *value)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
218 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
219 const char *const *tmp;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
220 unsigned int i;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
221
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
222 conn->capabilities = 0;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
223 if (conn->capabilities_list != NULL)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
224 p_strsplit_free(default_pool, conn->capabilities_list);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
225 conn->capabilities_list = p_strsplit(default_pool, value, " ");
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
226
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
227 for (tmp = t_strsplit(value, " "); *tmp != NULL; tmp++) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
228 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
229 const struct imapc_capability_name *cap =
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
230 &imapc_capability_names[i];
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 if (strcasecmp(*tmp, cap->name) == 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
233 conn->capabilities |= cap->capability;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
234 break;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
235 }
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 }
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 if ((conn->capabilities & IMAPC_CAPABILITY_IMAP4REV1) == 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
240 imapc_connection_input_error(conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
241 "CAPABILITY list is missing IMAP4REV1");
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
242 return -1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
243 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
244 return 0;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
245 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
246
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
247 static int
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
248 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
249 const char *key, const char *value)
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
250 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
251 if (strcasecmp(key, "CAPABILITY") == 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
252 if (imapc_connection_parse_capability(conn, value) < 0)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
253 return -1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
254 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
255 if (strcasecmp(key, "CLOSED") == 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
256 /* QRESYNC: SELECTing another mailbox */
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
257 if (conn->selecting_box != NULL) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
258 conn->selected_box = conn->selecting_box;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
259 conn->selecting_box = NULL;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
260 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
261 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
262 return 0;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
263 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
264
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
265 static int
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
266 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
267 const char *text,
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
268 const char **key_r, const char **value_r)
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
269 {
12590
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
270 const char *p, *value;
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
271
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
272 i_assert(text[0] == '[');
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
273
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
274 p = strchr(text, ']');
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
275 if (p == NULL) {
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
276 imapc_connection_input_error(conn, "Missing ']' in resp-text");
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
277 return -1;
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
278 }
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
279 text = t_strdup_until(text + 1, p);
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
280 value = strchr(text, ' ');
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
281 if (value != NULL) {
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
282 *key_r = t_strdup_until(text, value);
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
283 *value_r = value + 1;
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
284 } else {
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
285 *key_r = text;
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
286 *value_r = NULL;
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
287 }
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
288 return 0;
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
289 }
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
290
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
291 static int
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
292 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
293 const struct imap_arg *args,
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
294 const char **key_r, const char **value_r)
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
295 {
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
296 const char *text;
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
297
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
298 if (args->type != IMAP_ARG_ATOM)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
299 return 0;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
300
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
301 text = imap_args_to_str(args);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
302 if (*text != '[') {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
303 if (*text == '\0') {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
304 imapc_connection_input_error(conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
305 "Missing text in resp-text");
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
306 return -1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
307 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
308 return 0;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
309 }
12590
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
310 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
311 return -1;
12590
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
312
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
313 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
314 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
315
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
316 static bool need_literal(const char *str)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
317 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
318 unsigned int i;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
319
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
320 for (i = 0; str[i] != '\0'; i++) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
321 unsigned char c = str[i];
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
322
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
323 if ((c & 0x80) != 0 || c == '\r' || c == '\n')
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
324 return TRUE;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
325 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
326 return FALSE;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
327 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
328
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
329 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
330 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
331 conn->input_state = IMAPC_INPUT_STATE_NONE;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
332 conn->cur_tag = 0;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
333 conn->cur_num = 0;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
334 imap_parser_reset(conn->parser);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
335 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
336
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
337 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
338 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
339 const unsigned char *data;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
340 size_t i, data_size;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
341 int ret = 0;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
342
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
343 data = i_stream_get_data(conn->input, &data_size);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
344 for (i = 0; i < data_size; i++) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
345 if (data[i] == '\n') {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
346 imapc_connection_input_reset(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
347 ret = 1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
348 i++;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
349 break;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
350 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
351 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
352 i_stream_skip(conn->input, i);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
353 return ret;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
354 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
355
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
356 static void
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
357 imapc_connection_capability_cb(const struct imapc_command_reply *reply,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
358 void *context)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
359 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
360 struct imapc_connection *conn = context;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
361
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
362 if (reply->state != IMAPC_COMMAND_STATE_OK) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
363 imapc_connection_input_error(conn,
12590
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
364 "Failed to get capabilities: %s", reply->text_full);
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
365 } else if (conn->capabilities == 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
366 imapc_connection_input_error(conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
367 "Capabilities not returned by server");
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
368 } else {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
369 timeout_remove(&conn->to);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
370 imapc_connection_set_state(conn, IMAPC_CONNECTION_STATE_DONE);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
371 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
372 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
373
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
374 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
375 void *context)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
376 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
377 struct imapc_connection *conn = context;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
378
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
379 if (reply->state != IMAPC_COMMAND_STATE_OK) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
380 imapc_connection_input_error(conn, "Authentication failed: %s",
12590
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
381 reply->text_full);
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
382 return;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
383 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
384
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
385 if (conn->capabilities == 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
386 /* server didn't send capabilities automatically.
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
387 request them manually before we're done. */
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
388 imapc_connection_cmd(conn, "CAPABILITY",
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
389 imapc_connection_capability_cb, conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
390 return;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
391 }
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 timeout_remove(&conn->to);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
394 imapc_connection_set_state(conn, IMAPC_CONNECTION_STATE_DONE);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
395 }
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 static const char *
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
398 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
399 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
400 const struct imapc_client_settings *set = &conn->client->set;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
401 string_t *in, *out;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
402
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
403 in = t_str_new(128);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
404 if (set->master_user != NULL) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
405 str_append(in, set->username);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
406 str_append_c(in, '\0');
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
407 str_append(in, set->master_user);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
408 } else {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
409 str_append_c(in, '\0');
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
410 str_append(in, set->username);
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 str_append_c(in, '\0');
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
413 str_append(in, set->password);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
414
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
415 out = t_str_new(128);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
416 base64_encode(in->data, in->used, out);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
417 return str_c(out);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
418 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
419
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
420 static int imapc_connection_input_banner(struct imapc_connection *conn)
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 const struct imapc_client_settings *set = &conn->client->set;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
423 const struct imap_arg *imap_args;
12590
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
424 const char *cmd, *key, *value;
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
425 int ret;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
426
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
427 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
428 return ret;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
429
12590
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
430 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
431 &key, &value) < 0)
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
432 return -1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
433 imapc_connection_set_state(conn, IMAPC_CONNECTION_STATE_AUTHENTICATING);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
434
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
435 if (set->master_user == NULL &&
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
436 need_literal(set->username) && need_literal(set->password)) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
437 /* We can use LOGIN command */
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
438 imapc_connection_cmdf(conn, imapc_connection_login_cb, conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
439 "LOGIN %s %s",
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
440 set->username, set->password);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
441 } else if ((conn->capabilities & IMAPC_CAPABILITY_SASL_IR) != 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
442 cmd = t_strdup_printf("AUTHENTICATE PLAIN %s",
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
443 imapc_connection_get_sasl_plain_request(conn));
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
444 imapc_connection_cmd(conn, cmd,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
445 imapc_connection_login_cb, conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
446 } else {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
447 cmd = t_strdup_printf("AUTHENTICATE PLAIN\r\n%s",
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
448 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
449 imapc_connection_cmd(conn, cmd,
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
450 imapc_connection_login_cb, conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
451 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
452 conn->input_callback = NULL;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
453 imapc_connection_input_reset(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
454 return 1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
455 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
456
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
457 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
458 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
459 const struct imap_arg *imap_args;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
460 const char *name;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
461 struct imapc_untagged_reply reply;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
462 int ret;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
463
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
464 if (conn->state == IMAPC_CONNECTION_STATE_CONNECTING) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
465 /* input banner */
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
466 name = imap_parser_read_word(conn->parser);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
467 if (name == NULL)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
468 return 0;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
469
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
470 if (strcasecmp(name, "OK") != 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
471 imapc_connection_input_error(conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
472 "Banner doesn't begin with OK: %s", name);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
473 return -1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
474 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
475 conn->input_callback = imapc_connection_input_banner;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
476 return 1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
477 }
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 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
480 return ret;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
481 if (!imap_arg_get_atom(&imap_args[0], &name)) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
482 imapc_connection_input_error(conn, "Invalid untagged reply");
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
483 return -1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
484 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
485 imap_args++;
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 if (conn->input_state == IMAPC_INPUT_STATE_UNTAGGED &&
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
488 str_to_uint32(name, &conn->cur_num) == 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
489 /* <seq> <event> */
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
490 conn->input_state = IMAPC_INPUT_STATE_UNTAGGED_NUM;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
491 if (!imap_arg_get_atom(&imap_args[0], &name)) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
492 imapc_connection_input_error(conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
493 "Invalid untagged reply");
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
494 return -1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
495 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
496 imap_args++;
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 memset(&reply, 0, sizeof(reply));
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
499
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
500 if (strcasecmp(name, "OK") == 0) {
12590
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
501 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
502 &reply.resp_text_key,
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
503 &reply.resp_text_value) < 0)
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
504 return -1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
505 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
506
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
507 reply.name = name;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
508 reply.num = conn->cur_num;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
509 reply.args = imap_args;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
510 if (conn->selected_box != NULL) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
511 reply.untagged_box_context =
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
512 conn->selected_box->untagged_box_context;
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 conn->client->untagged_callback(&reply, conn->client->untagged_context);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
515 if (imap_arg_atom_equals(imap_args, "EXPUNGE") &&
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
516 conn->selected_box != NULL) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
517 /* keep track of expunge map internally */
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
518 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
519 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
520 imapc_connection_input_reset(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
521 return 1;
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
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
524 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
525 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
526 struct imapc_command *const *cmd_p;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
527
12592
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
528 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
529 /* "+ 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
530 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
531 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
532 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
533 }
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
534
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
535 if (array_count(&conn->cmd_send_queue) == 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
536 imapc_connection_input_error(conn, "Unexpected '+'");
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
537 return -1;
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 cmd_p = array_idx(&conn->cmd_send_queue, 0);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
540 imapc_command_send_more(conn, *cmd_p);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
541
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
542 conn->input_state = IMAPC_INPUT_STATE_SKIPLINE;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
543 return imapc_connection_skip_line(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
544 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
545
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
546 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
547 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
548 struct imapc_command *const *cmds, *cmd = NULL;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
549 unsigned int i, count;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
550 char *line, *linep;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
551 const char *p;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
552 struct imapc_command_reply reply;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
553
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
554 line = i_stream_next_line(conn->input);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
555 if (line == NULL)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
556 return 0;
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 memset(&reply, 0, sizeof(reply));
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
559
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
560 linep = strchr(line, ' ');
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
561 if (linep == NULL)
12590
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
562 reply.text_full = "";
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
563 else {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
564 *linep = '\0';
12590
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
565 reply.text_full = linep + 1;
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
566 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
567
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
568 if (strcasecmp(line, "ok") == 0)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
569 reply.state = IMAPC_COMMAND_STATE_OK;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
570 else if (strcasecmp(line, "no") == 0)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
571 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
572 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
573 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
574 conn->name, conn->cur_tag, line);
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
575 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
576 } else {
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
577 imapc_connection_input_error(conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
578 "Invalid state in tagged reply: %u %s",
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
579 conn->cur_tag, line);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
580 return -1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
581 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
582
12590
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
583 if (reply.text_full[0] == '[') {
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
584 /* get resp-text */
12590
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
585 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
586 &reply.resp_text_key,
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
587 &reply.resp_text_value) < 0)
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
588 return -1;
12590
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
589
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
590 p = strchr(reply.text_full, ']');
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
591 i_assert(p != NULL);
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
592 reply.text_without_resp = p + 1;
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
593 if (reply.text_without_resp[0] == ' ')
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
594 reply.text_without_resp++;
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
595 } else {
9e471f267fb4 imapc: Code cleanups and fixes.
Timo Sirainen <tss@iki.fi>
parents: 12582
diff changeset
596 reply.text_without_resp = reply.text_full;
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
597 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
598
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
599 /* 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
600 (literal failed) or somewhere in wait list. */
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
601 cmds = array_get(&conn->cmd_send_queue, &count);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
602 if (count > 0 && cmds[0]->tag == conn->cur_tag) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
603 cmd = cmds[0];
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
604 array_delete(&conn->cmd_send_queue, 0, 1);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
605 } else {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
606 cmds = array_get(&conn->cmd_wait_list, &count);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
607 for (i = 0; i < count; i++) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
608 if (cmds[i]->tag == conn->cur_tag) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
609 cmd = cmds[i];
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
610 array_delete(&conn->cmd_wait_list, i, 1);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
611 break;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
612 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
613 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
614 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
615
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
616 if (cmd == NULL) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
617 imapc_connection_input_error(conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
618 "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
619 return -1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
620 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
621
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
622 imapc_connection_input_reset(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
623 cmd->callback(&reply, cmd->context);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
624 pool_unref(&cmd->pool);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
625 return 0;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
626 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
627
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
628 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
629 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
630 const char *tag;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
631 int ret = -1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
632
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
633 if (conn->input_callback != NULL)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
634 return conn->input_callback(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
635
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
636 switch (conn->input_state) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
637 case IMAPC_INPUT_STATE_NONE:
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
638 tag = imap_parser_read_word(conn->parser);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
639 if (tag == NULL)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
640 return 0;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
641
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
642 if (strcmp(tag, "") == 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
643 /* FIXME: why do we get here.. */
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
644 conn->input_state = IMAPC_INPUT_STATE_SKIPLINE;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
645 return imapc_connection_skip_line(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
646 } else if (strcmp(tag, "*") == 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
647 conn->input_state = IMAPC_INPUT_STATE_UNTAGGED;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
648 conn->cur_num = 0;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
649 ret = imapc_connection_input_untagged(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
650 } else if (strcmp(tag, "+") == 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
651 ret = imapc_connection_input_plus(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
652 } else {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
653 conn->input_state = IMAPC_INPUT_STATE_TAGGED;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
654 if (str_to_uint(tag, &conn->cur_tag) < 0 ||
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
655 conn->cur_tag == 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
656 imapc_connection_input_error(conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
657 "Invalid command tag: %s", tag);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
658 ret = -1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
659 } else {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
660 ret = imapc_connection_input_tagged(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 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
663 break;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
664 case IMAPC_INPUT_STATE_UNTAGGED:
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
665 case IMAPC_INPUT_STATE_UNTAGGED_NUM:
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
666 ret = imapc_connection_input_untagged(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
667 break;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
668 case IMAPC_INPUT_STATE_TAGGED:
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
669 ret = imapc_connection_input_tagged(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
670 break;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
671 case IMAPC_INPUT_STATE_SKIPLINE:
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
672 ret = imapc_connection_skip_line(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
673 break;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
674 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
675 return ret;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
676 }
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 static void imapc_connection_input(struct imapc_connection *conn)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
679 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
680 int ret;
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 (i_stream_read(conn->input) == -1) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
683 /* disconnected */
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
684 i_error("imapc(%s): Server disconnected unexpectedly",
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
685 conn->name);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
686 imapc_connection_disconnect(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
687 return;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
688 }
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 o_stream_cork(conn->output);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
691 do {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
692 T_BEGIN {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
693 ret = imapc_connection_input_one(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
694 } T_END;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
695 } while (ret > 0);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
696
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
697 if (conn->output != NULL)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
698 o_stream_uncork(conn->output);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
699 }
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 static void imapc_connection_connected(struct imapc_connection *conn)
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 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
704 int err;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
705
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
706 err = net_geterror(conn->fd);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
707 if (err != 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
708 i_error("imapc(%s): connect(%s, %u) failed: %s",
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
709 conn->name, net_ip2addr(ip), conn->client->set.port,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
710 strerror(err));
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
711 imapc_connection_disconnect(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
712 return;
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 io_remove(&conn->io);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
715 conn->io = io_add(conn->fd, IO_READ, imapc_connection_input, conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
716 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
717
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
718 static void imapc_connection_timeout(struct imapc_connection *conn)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
719 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
720 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
721
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
722 switch (conn->state) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
723 case IMAPC_CONNECTION_STATE_CONNECTING:
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
724 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
725 conn->name, net_ip2addr(ip), conn->client->set.port,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
726 IMAPC_CONNECT_TIMEOUT_MSECS/1000);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
727 break;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
728 case IMAPC_CONNECTION_STATE_AUTHENTICATING:
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
729 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
730 conn->name, IMAPC_CONNECT_TIMEOUT_MSECS/1000);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
731 break;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
732 default:
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
733 i_unreached();
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
734 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
735 imapc_connection_disconnect(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
736 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
737
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
738 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
739 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
740 int fd;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
741
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
742 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
743 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
744 conn->client->set.port, NULL);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
745 if (fd == -1) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
746 imapc_connection_set_state(conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
747 IMAPC_CONNECTION_STATE_DISCONNECTED);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
748 return;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
749 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
750 conn->fd = fd;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
751 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
752 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
753 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
754 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
755 conn->to = timeout_add(IMAPC_CONNECT_TIMEOUT_MSECS,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
756 imapc_connection_timeout, 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
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
759 static void
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
760 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
761 void *context)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
762 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
763 struct imapc_connection *conn = context;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
764
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
765 if (result->ret != 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
766 i_error("imapc(%s): dns_lookup(%s) failed: %s",
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
767 conn->name, conn->client->set.host, result->error);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
768 imapc_connection_set_state(conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
769 IMAPC_CONNECTION_STATE_DISCONNECTED);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
770 return;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
771 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
772
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
773 i_assert(result->ips_count > 0);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
774 conn->ips_count = result->ips_count;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
775 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
776 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
777 conn->prev_connect_idx = conn->ips_count - 1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
778
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
779 imapc_connection_connect_next_ip(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
780 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
781
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
782 void imapc_connection_connect(struct imapc_connection *conn)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
783 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
784 struct dns_lookup_settings dns_set;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
785
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
786 if (conn->fd != -1)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
787 return;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
788
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
789 memset(&dns_set, 0, sizeof(dns_set));
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
790 dns_set.dns_client_socket_path =
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
791 conn->client->set.dns_client_socket_path;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
792 dns_set.timeout_msecs = IMAPC_DNS_LOOKUP_TIMEOUT_MSECS;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
793
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
794 imapc_connection_set_state(conn, IMAPC_CONNECTION_STATE_CONNECTING);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
795 if (conn->ips_count == 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
796 (void)dns_lookup(conn->client->set.host, &dns_set,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
797 imapc_connection_dns_callback, conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
798 } else {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
799 imapc_connection_connect_next_ip(conn);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
800 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
801 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
802
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
803 static struct imapc_command *
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
804 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
805 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
806 static unsigned int cmd_tag_counter = 0;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
807 struct imapc_command *cmd;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
808 pool_t pool;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
809
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
810 pool = pool_alloconly_create("imapc command", 1024);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
811 cmd = p_new(pool, struct imapc_command, 1);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
812 cmd->pool = pool;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
813 cmd->callback = callback;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
814 cmd->context = context;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
815
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
816 if (++cmd_tag_counter == 0)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
817 cmd_tag_counter++;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
818 cmd->tag = cmd_tag_counter;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
819 return cmd;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
820 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
821
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
822 static bool
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
823 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
824 unsigned int *value_r)
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 unsigned int value = 0, mul = 1;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
827
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
828 /* 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
829 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
830 data[pos-3] != '}' || !i_isdigit(data[pos-4]))
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
831 return FALSE;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
832 pos -= 4;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
833
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
834 do {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
835 value += (data[pos] - '0') * mul;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
836 mul = mul*10;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
837 pos--;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
838 } while (pos > 0 && i_isdigit(data[pos]));
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 if (pos == 0 || data[pos] != '{')
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
841 return FALSE;
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 *value_r = value;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
844 return TRUE;
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
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
847 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
848 struct imapc_command *cmd)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
849 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
850 const unsigned char *p;
12581
9db6762167fb imapc: Fixed sending non-syncing literals.
Timo Sirainen <tss@iki.fi>
parents: 12580
diff changeset
851 unsigned int seek_pos, start_pos, end_pos, size;
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
852
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
853 i_assert(cmd->send_pos < cmd->data->used);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
854
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
855 seek_pos = cmd->send_pos;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
856 if (seek_pos != 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
857 /* 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
858 AUTHENTICATE command, which doesn't use a literal */
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
859 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
860 seek_pos += size;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
861 i_assert(seek_pos <= cmd->data->used);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
862 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
863 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
864
12581
9db6762167fb imapc: Fixed sending non-syncing literals.
Timo Sirainen <tss@iki.fi>
parents: 12580
diff changeset
865 do {
9db6762167fb imapc: Fixed sending non-syncing literals.
Timo Sirainen <tss@iki.fi>
parents: 12580
diff changeset
866 start_pos = seek_pos;
9db6762167fb imapc: Fixed sending non-syncing literals.
Timo Sirainen <tss@iki.fi>
parents: 12580
diff changeset
867 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
868 cmd->data->used - seek_pos);
9db6762167fb imapc: Fixed sending non-syncing literals.
Timo Sirainen <tss@iki.fi>
parents: 12580
diff changeset
869 i_assert(p != NULL);
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
870
12581
9db6762167fb imapc: Fixed sending non-syncing literals.
Timo Sirainen <tss@iki.fi>
parents: 12580
diff changeset
871 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
872 /* keep going for LITERAL+ command */
9db6762167fb imapc: Fixed sending non-syncing literals.
Timo Sirainen <tss@iki.fi>
parents: 12580
diff changeset
873 } while (start_pos + 3 < seek_pos &&
9db6762167fb imapc: Fixed sending non-syncing literals.
Timo Sirainen <tss@iki.fi>
parents: 12580
diff changeset
874 p[-1] == '\r' && p[-2] == '}' && p[-3] == '+');
9db6762167fb imapc: Fixed sending non-syncing literals.
Timo Sirainen <tss@iki.fi>
parents: 12580
diff changeset
875 end_pos = seek_pos;
9db6762167fb imapc: Fixed sending non-syncing literals.
Timo Sirainen <tss@iki.fi>
parents: 12580
diff changeset
876
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
877 o_stream_send(conn->output,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
878 CONST_PTR_OFFSET(cmd->data->data, cmd->send_pos),
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
879 end_pos - cmd->send_pos);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
880 cmd->send_pos = end_pos;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
881
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
882 if (cmd->send_pos == cmd->data->used) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
883 /* everything sent. move command to wait list. */
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
884 i_assert(*array_idx(&conn->cmd_send_queue, 0) == cmd);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
885 array_delete(&conn->cmd_send_queue, 0, 1);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
886 array_append(&conn->cmd_wait_list, &cmd, 1);
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 if (array_count(&conn->cmd_send_queue) > 0 &&
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
889 conn->state == IMAPC_CONNECTION_STATE_DONE) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
890 /* send the next command in queue */
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
891 struct imapc_command *const *cmd2_p =
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
892 array_idx(&conn->cmd_send_queue, 0);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
893 imapc_command_send_more(conn, *cmd2_p);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
894 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
895 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
896 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
897
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
898 static void imapc_command_send(struct imapc_connection *conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
899 struct imapc_command *cmd)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
900 {
12592
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
901 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
902 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
903 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
904 }
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
905 switch (conn->state) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
906 case IMAPC_CONNECTION_STATE_AUTHENTICATING:
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
907 array_insert(&conn->cmd_send_queue, 0, &cmd, 1);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
908 imapc_command_send_more(conn, cmd);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
909 break;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
910 case IMAPC_CONNECTION_STATE_DONE:
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
911 array_append(&conn->cmd_send_queue, &cmd, 1);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
912 if (array_count(&conn->cmd_send_queue) == 1)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
913 imapc_command_send_more(conn, cmd);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
914 break;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
915 default:
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
916 array_append(&conn->cmd_send_queue, &cmd, 1);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
917 break;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
918 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
919 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
920
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
921 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
922 imapc_command_callback_t *callback, void *context)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
923 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
924 struct imapc_command *cmd;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
925 unsigned int len = strlen(cmdline);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
926
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
927 cmd = imapc_command_begin(callback, context);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
928 cmd->data = str_new(cmd->pool, len + 2);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
929 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
930 imapc_command_send(conn, cmd);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
931 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
932
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
933 void imapc_connection_cmdf(struct imapc_connection *conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
934 imapc_command_callback_t *callback, void *context,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
935 const char *cmd_fmt, ...)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
936 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
937 va_list args;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
938
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
939 va_start(args, cmd_fmt);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
940 imapc_connection_cmdvf(conn, callback, context, cmd_fmt, args);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
941 va_end(args);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
942 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
943
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
944 void imapc_connection_cmdvf(struct imapc_connection *conn,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
945 imapc_command_callback_t *callback, void *context,
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
946 const char *cmd_fmt, va_list args)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
947 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
948 struct imapc_command *cmd;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
949 unsigned int i;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
950
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
951 cmd = imapc_command_begin(callback, context);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
952 cmd->data = str_new(cmd->pool, 128);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
953 str_printfa(cmd->data, "%u ", cmd->tag);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
954
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
955 for (i = 0; cmd_fmt[i] != '\0'; i++) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
956 if (cmd_fmt[i] != '%') {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
957 str_append_c(cmd->data, cmd_fmt[i]);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
958 continue;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
959 }
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 switch (cmd_fmt[++i]) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
962 case '\0':
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
963 i_unreached();
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
964 case 'u': {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
965 unsigned int arg = va_arg(args, unsigned int);
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 str_printfa(cmd->data, "%u", arg);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
968 break;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
969 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
970 case 's': {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
971 const char *arg = va_arg(args, const char *);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
972
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
973 if (!need_literal(arg))
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
974 imap_dquote_append(cmd->data, arg);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
975 else if ((conn->capabilities &
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
976 IMAPC_CAPABILITY_LITERALPLUS) != 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
977 str_printfa(cmd->data, "{%"PRIuSIZE_T"+}\r\n%s",
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
978 strlen(arg), arg);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
979 } else {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
980 str_printfa(cmd->data, "{%"PRIuSIZE_T"}\r\n%s",
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
981 strlen(arg), arg);
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 break;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
984 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
985 case '1': {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
986 /* %1s - no quoting */
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
987 const char *arg = va_arg(args, const char *);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
988
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
989 i_assert(cmd_fmt[++i] == 's');
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
990 str_append(cmd->data, arg);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
991 break;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
992 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
993 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
994 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
995 str_append(cmd->data, "\r\n");
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
996
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
997 imapc_command_send(conn, cmd);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
998 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
999
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1000 enum imapc_connection_state
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1001 imapc_connection_get_state(struct imapc_connection *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 return conn->state;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1004 }
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1005
12592
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1006 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
1007 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
1008 {
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1009 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
1010 }
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1011
12580
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1012 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
1013 imapc_command_callback_t *callback, void *context)
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1014 {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1015 struct imapc_connection *conn = box->conn;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1016
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1017 i_assert(conn->selecting_box == NULL);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1018
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1019 if (conn->selected_box != NULL &&
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1020 (conn->capabilities & IMAPC_CAPABILITY_QRESYNC) != 0) {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1021 /* server will send a [CLOSED] once selected mailbox is
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1022 closed */
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1023 conn->selecting_box = box;
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1024 } else {
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1025 /* 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
1026 are for the mailbox we're selecting */
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1027 conn->selected_box = box;
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
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1030 imapc_connection_cmdf(conn, callback, context, "SELECT %s", name);
7dd1e45721ae Added initial implementation of "imapc" storage.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1031 }
12592
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1032
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1033 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
1034 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
1035 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
1036 {
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1037 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
1038
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1039 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
1040 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
1041 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
1042 }
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1043
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1044 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
1045 {
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1046 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
1047 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
1048 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
1049 (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
1050 return;
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1051
475050722f54 imapc: Handle properly mailbox changes while it's selected. Added support for IDLE.
Timo Sirainen <tss@iki.fi>
parents: 12590
diff changeset
1052 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
1053 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
1054 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
1055 }