A small cleanup of the IMAP code.
* mailbox/folder_imap.c (imap_body): Destry the cache header if it was previously set on a SCAN. * mailbox/mbx_imap.c (delete_to_string): New function, to generate a string of IMAP message numbers. (imap_expunge): use delete_to_string; (attribute_string): Removed. (flags_string): Removed. (flags_to_string): Replace attribute_string() and flags_string(). (message_operation): Rename to fetch_operation. * mailbox/include/imap0.h(struct _f_imap): field func and id removed, never used.
Showing
4 changed files
with
424 additions
and
402 deletions
1 | 2001-10-11 Alain Magloire | 1 | 2001-10-11 Alain Magloire |
2 | 2 | ||
3 | A small cleanup of the IMAP code. | ||
4 | |||
5 | * mailbox/folder_imap.c (imap_body): Destry the cache header | ||
6 | if it was previously set on a SCAN. | ||
7 | * mailbox/mbx_imap.c (delete_to_string): New function, to generate | ||
8 | a string of IMAP message numbers. | ||
9 | (imap_expunge): use delete_to_string; | ||
10 | (attribute_string): Removed. | ||
11 | (flags_string): Removed. | ||
12 | (flags_to_string): Replace attribute_string() and flags_string(). | ||
13 | (message_operation): Rename to fetch_operation. | ||
14 | * mailbox/include/imap0.h(struct _f_imap): field func and id | ||
15 | removed, never used. | ||
16 | |||
17 | 2001-10-11 Alain Magloire | ||
18 | |||
3 | * mailbox/folder_imap.c (imap_quoted_string): Free the buffer. | 19 | * mailbox/folder_imap.c (imap_quoted_string): Free the buffer. |
4 | (imap_string): Free the buffer. | 20 | (imap_string): Free the buffer. |
5 | (imap_body): Check if we already have the fheader header. | 21 | (imap_body): Check if we already have the fheader header. |
... | @@ -7,14 +23,15 @@ | ... | @@ -7,14 +23,15 @@ |
7 | 23 | ||
8 | 2001-10-11 Alain Magloire | 24 | 2001-10-11 Alain Magloire |
9 | 25 | ||
10 | In order to boost performance, when doing the scan we use | 26 | In order to boost performance, when doing the scan, we use |
11 | the approach of downloading part of the header of the total | 27 | the approach of downloading a subset of the header from all |
12 | set of messages. The it was done before is that the headers | 28 | of messages. The way it was done before was that the headers |
13 | were ask one by one per message. This was causing performance | 29 | were requested one by one per message. This was causing performance |
14 | delay because we were doing a lot of small transaction on | 30 | issues because we were doing a lot of small transactions on |
15 | the TCP/IP stack. By bundling the entire thing in one request | 31 | the TCP/IP stack. By bundling the entire thing in one request |
16 | there was much less transcation and the speed was increase | 32 | "a0000 FETCH 1:* (FLAGS RFC822.SIZE BODY.PEEK[HEADER.FIELDS(..)])\r\n" |
17 | by a factor of 10++. | 33 | there were less transcations and the speed was increase |
34 | by a factor of 100+. | ||
18 | The Imap code folder_imap.c and mbx_imap.c is now messy. | 35 | The Imap code folder_imap.c and mbx_imap.c is now messy. |
19 | The rewrite in mailbox2 should clean this up though. | 36 | The rewrite in mailbox2 should clean this up though. |
20 | 37 | ... | ... |
... | @@ -61,6 +61,7 @@ record_t imap_record = &_imap_record; | ... | @@ -61,6 +61,7 @@ record_t imap_record = &_imap_record; |
61 | #ifndef HAVE_STRTOK_R | 61 | #ifndef HAVE_STRTOK_R |
62 | char *strtok_r __P ((char *, const char *, char **)); | 62 | char *strtok_r __P ((char *, const char *, char **)); |
63 | #endif | 63 | #endif |
64 | |||
64 | /* Concrete IMAP implementation. */ | 65 | /* Concrete IMAP implementation. */ |
65 | static int folder_imap_open __P ((folder_t, int)); | 66 | static int folder_imap_open __P ((folder_t, int)); |
66 | static int folder_imap_create __P ((folder_t)); | 67 | static int folder_imap_create __P ((folder_t)); |
... | @@ -122,7 +123,7 @@ _folder_imap_init (folder_t folder) | ... | @@ -122,7 +123,7 @@ _folder_imap_init (folder_t folder) |
122 | return 0; | 123 | return 0; |
123 | } | 124 | } |
124 | 125 | ||
125 | /* Destroy the resources. */ | 126 | /* Destroy the folder resources. */ |
126 | static void | 127 | static void |
127 | folder_imap_destroy (folder_t folder) | 128 | folder_imap_destroy (folder_t folder) |
128 | { | 129 | { |
... | @@ -1374,9 +1375,12 @@ imap_body (f_imap_t f_imap, char **ptr) | ... | @@ -1374,9 +1375,12 @@ imap_body (f_imap_t f_imap, char **ptr) |
1374 | } | 1375 | } |
1375 | } | 1376 | } |
1376 | status = imap_string (f_imap, ptr); | 1377 | status = imap_string (f_imap, ptr); |
1377 | if (f_imap->callback.msg_imap->fheader == NULL | 1378 | |
1378 | && f_imap->state == IMAP_SCAN_ACK && f_imap->callback.total) | 1379 | /* If the state scan. Catch it here. */ |
1380 | if (f_imap->state == IMAP_SCAN_ACK) | ||
1379 | { | 1381 | { |
1382 | if (f_imap->callback.msg_imap->fheader) | ||
1383 | header_destroy (&f_imap->callback.msg_imap->fheader, NULL); | ||
1380 | status = header_create (&f_imap->callback.msg_imap->fheader, | 1384 | status = header_create (&f_imap->callback.msg_imap->fheader, |
1381 | f_imap->callback.buffer, f_imap->callback.total, | 1385 | f_imap->callback.buffer, f_imap->callback.total, |
1382 | NULL); | 1386 | NULL); | ... | ... |
... | @@ -39,7 +39,7 @@ extern "C" { | ... | @@ -39,7 +39,7 @@ extern "C" { |
39 | #endif /*__P */ | 39 | #endif /*__P */ |
40 | 40 | ||
41 | #define CLEAR_STATE(f_imap) \ | 41 | #define CLEAR_STATE(f_imap) \ |
42 | f_imap->selected = NULL, f_imap->id = 0, f_imap->func = NULL, f_imap->state = IMAP_NO_STATE | 42 | f_imap->selected = NULL, f_imap->state = IMAP_NO_STATE |
43 | 43 | ||
44 | /* Clear the state and close the stream. */ | 44 | /* Clear the state and close the stream. */ |
45 | #define CHECK_ERROR_CLOSE(folder, f_imap, status) \ | 45 | #define CHECK_ERROR_CLOSE(folder, f_imap, status) \ |
... | @@ -136,8 +136,6 @@ struct _f_imap | ... | @@ -136,8 +136,6 @@ struct _f_imap |
136 | m_imap_t selected; | 136 | m_imap_t selected; |
137 | 137 | ||
138 | enum imap_state state; | 138 | enum imap_state state; |
139 | void *func; | ||
140 | size_t id; | ||
141 | 139 | ||
142 | size_t seq; /* Sequence number to build a tag. */ | 140 | size_t seq; /* Sequence number to build a tag. */ |
143 | char *capa; /* Cabilities of the server. */ | 141 | char *capa; /* Cabilities of the server. */ | ... | ... |
... | @@ -39,61 +39,63 @@ | ... | @@ -39,61 +39,63 @@ |
39 | 39 | ||
40 | #define MU_IMAP_CACHE_HEADERS "Bcc Cc Content-Language Content-Transfer-Encoding Content-Type Date From In-Reply-To Message-ID Reference Reply-To Sender Subject To X-UIDL" | 40 | #define MU_IMAP_CACHE_HEADERS "Bcc Cc Content-Language Content-Transfer-Encoding Content-Type Date From In-Reply-To Message-ID Reference Reply-To Sender Subject To X-UIDL" |
41 | 41 | ||
42 | /* Functions to overload the mailbox_t API. */ | 42 | /* mailbox_t API. */ |
43 | static void mailbox_imap_destroy __P ((mailbox_t)); | 43 | static void mailbox_imap_destroy __P ((mailbox_t)); |
44 | static int mailbox_imap_open __P ((mailbox_t, int)); | 44 | static int mailbox_imap_open __P ((mailbox_t, int)); |
45 | static int mailbox_imap_close __P ((mailbox_t)); | 45 | static int mailbox_imap_close __P ((mailbox_t)); |
46 | static int imap_uidvalidity __P ((mailbox_t, unsigned long *)); | 46 | static int imap_uidvalidity __P ((mailbox_t, unsigned long *)); |
47 | static int imap_uidnext __P ((mailbox_t, size_t *)); | 47 | static int imap_uidnext __P ((mailbox_t, size_t *)); |
48 | static int imap_expunge __P ((mailbox_t)); | 48 | static int imap_expunge __P ((mailbox_t)); |
49 | static int imap_get_message __P ((mailbox_t, size_t, message_t *)); | 49 | static int imap_get_message __P ((mailbox_t, size_t, message_t *)); |
50 | static int imap_messages_count __P ((mailbox_t, size_t *)); | 50 | static int imap_messages_count __P ((mailbox_t, size_t *)); |
51 | static int imap_messages_recent __P ((mailbox_t, size_t *)); | 51 | static int imap_messages_recent __P ((mailbox_t, size_t *)); |
52 | static int imap_message_unseen __P ((mailbox_t, size_t *)); | 52 | static int imap_message_unseen __P ((mailbox_t, size_t *)); |
53 | static int imap_scan __P ((mailbox_t, size_t, size_t *)); | 53 | static int imap_scan __P ((mailbox_t, size_t, size_t *)); |
54 | static int imap_is_updated __P ((mailbox_t)); | 54 | static int imap_is_updated __P ((mailbox_t)); |
55 | static int imap_append_message __P ((mailbox_t, message_t)); | 55 | static int imap_append_message __P ((mailbox_t, message_t)); |
56 | static int imap_copy_message __P ((mailbox_t, message_t)); | 56 | static int imap_copy_message __P ((mailbox_t, message_t)); |
57 | 57 | ||
58 | /* Message API. */ | 58 | /* message_t API. */ |
59 | 59 | static int imap_submessage_size __P ((msg_imap_t, size_t *)); | |
60 | static int imap_submessage_size __P ((msg_imap_t, size_t *)); | 60 | static int imap_message_size __P ((message_t, size_t *)); |
61 | static int imap_message_size __P ((message_t, size_t *)); | 61 | static int imap_message_lines __P ((message_t, size_t *)); |
62 | static int imap_message_lines __P ((message_t, size_t *)); | 62 | static int imap_message_fd __P ((stream_t, int *)); |
63 | static int imap_message_fd __P ((stream_t, int *)); | 63 | static int imap_message_read __P ((stream_t , char *, size_t, off_t, size_t *)); |
64 | static int imap_message_read __P ((stream_t , char *, size_t, off_t, size_t *)); | 64 | static int imap_message_uid __P ((message_t, size_t *)); |
65 | static int imap_message_uid __P ((message_t, size_t *)); | 65 | |
66 | 66 | /* mime_t API. */ | |
67 | /* Mime handling. */ | 67 | static int imap_is_multipart __P ((message_t, int *)); |
68 | static int imap_is_multipart __P ((message_t, int *)); | 68 | static int imap_get_num_parts __P ((message_t, size_t *)); |
69 | static int imap_get_num_parts __P ((message_t, size_t *)); | 69 | static int imap_get_part __P ((message_t, size_t, message_t *)); |
70 | static int imap_get_part __P ((message_t, size_t, message_t *)); | 70 | |
71 | 71 | /* envelope_t API */ | |
72 | /* Envelope. */ | 72 | static int imap_envelope_sender __P ((envelope_t, char *, size_t, size_t *)); |
73 | static int imap_envelope_sender __P ((envelope_t, char *, size_t, size_t *)); | 73 | static int imap_envelope_date __P ((envelope_t, char *, size_t, size_t *)); |
74 | static int imap_envelope_date __P ((envelope_t, char *, size_t, size_t *)); | 74 | |
75 | 75 | /* attribute_t API */ | |
76 | /* Attributes. */ | 76 | static int imap_attr_get_flags __P ((attribute_t, int *)); |
77 | static int imap_attr_get_flags __P ((attribute_t, int *)); | 77 | static int imap_attr_set_flags __P ((attribute_t, int)); |
78 | static int imap_attr_set_flags __P ((attribute_t, int)); | 78 | static int imap_attr_unset_flags __P ((attribute_t, int)); |
79 | static int imap_attr_unset_flags __P ((attribute_t, int)); | 79 | |
80 | 80 | /* header_t API. */ | |
81 | /* Header. */ | 81 | static int imap_header_read __P ((header_t, char*, size_t, off_t, size_t *)); |
82 | static int imap_header_read __P ((header_t, char*, size_t, off_t, size_t *)); | 82 | static int imap_header_get_value __P ((header_t, const char*, char *, size_t, size_t *)); |
83 | static int imap_header_get_value __P ((header_t, const char*, char *, size_t, size_t *)); | 83 | static int imap_header_get_fvalue __P ((header_t, const char*, char *, size_t, size_t *)); |
84 | static int imap_header_get_fvalue __P ((header_t, const char*, char *, size_t, size_t *)); | 84 | |
85 | 85 | /* body_t API. */ | |
86 | /* Body. */ | 86 | static int imap_body_read __P ((stream_t, char *, size_t, off_t, size_t *)); |
87 | static int imap_body_read __P ((stream_t, char *, size_t, off_t, size_t *)); | 87 | static int imap_body_size __P ((body_t, size_t *)); |
88 | static int imap_body_size __P ((body_t, size_t *)); | 88 | static int imap_body_lines __P ((body_t, size_t *)); |
89 | static int imap_body_lines __P ((body_t, size_t *)); | 89 | static int imap_body_fd __P ((stream_t, int *)); |
90 | static int imap_body_fd __P ((stream_t, int *)); | 90 | |
91 | 91 | /* Helpers. */ | |
92 | /* Private. */ | 92 | static int imap_get_fd __P ((msg_imap_t, int *)); |
93 | static int imap_get_fd __P ((msg_imap_t, int *)); | 93 | static int imap_get_message0 __P ((msg_imap_t, message_t *)); |
94 | static int imap_get_message0 __P ((msg_imap_t, message_t *)); | 94 | static int fetch_operation __P ((f_imap_t, msg_imap_t, char *, size_t, size_t *)); |
95 | static int message_operation __P ((f_imap_t, msg_imap_t, char *, size_t, size_t *)); | 95 | static void free_subparts __P ((msg_imap_t)); |
96 | static void free_subparts __P ((msg_imap_t)); | 96 | static int flags_to_string __P ((char **, int)); |
97 | static int delete_to_string __P ((m_imap_t, char **)); | ||
98 | static int is_same_folder __P ((mailbox_t, message_t)); | ||
97 | 99 | ||
98 | /* Initialize the concrete object mailbox_t by overloading the function of the | 100 | /* Initialize the concrete object mailbox_t by overloading the function of the |
99 | structure. */ | 101 | structure. */ |
... | @@ -102,7 +104,7 @@ _mailbox_imap_init (mailbox_t mailbox) | ... | @@ -102,7 +104,7 @@ _mailbox_imap_init (mailbox_t mailbox) |
102 | { | 104 | { |
103 | m_imap_t m_imap; | 105 | m_imap_t m_imap; |
104 | size_t name_len = 0; | 106 | size_t name_len = 0; |
105 | m_imap = mailbox->data = calloc (1, sizeof (*m_imap)); | 107 | m_imap = mailbox->data = calloc (1, sizeof *m_imap); |
106 | if (m_imap == NULL) | 108 | if (m_imap == NULL) |
107 | return ENOMEM; | 109 | return ENOMEM; |
108 | 110 | ||
... | @@ -161,8 +163,10 @@ free_subparts (msg_imap_t msg_imap) | ... | @@ -161,8 +163,10 @@ free_subparts (msg_imap_t msg_imap) |
161 | { | 163 | { |
162 | size_t i; | 164 | size_t i; |
163 | for (i = 0; i < msg_imap->num_parts; i++) | 165 | for (i = 0; i < msg_imap->num_parts; i++) |
164 | if (msg_imap->parts[i]) | 166 | { |
165 | free_subparts (msg_imap->parts[i]); | 167 | if (msg_imap->parts[i]) |
168 | free_subparts (msg_imap->parts[i]); | ||
169 | } | ||
166 | 170 | ||
167 | if (msg_imap->message) | 171 | if (msg_imap->message) |
168 | message_destroy (&(msg_imap->message), msg_imap); | 172 | message_destroy (&(msg_imap->message), msg_imap); |
... | @@ -173,7 +177,7 @@ free_subparts (msg_imap_t msg_imap) | ... | @@ -173,7 +177,7 @@ free_subparts (msg_imap_t msg_imap) |
173 | free(msg_imap); | 177 | free(msg_imap); |
174 | } | 178 | } |
175 | 179 | ||
176 | /* Give back all the resources. But is does not mean to shutdown the channel | 180 | /* Give back all the resources. But it does not mean to shutdown the channel |
177 | this is done on the folder. */ | 181 | this is done on the folder. */ |
178 | static void | 182 | static void |
179 | mailbox_imap_destroy (mailbox_t mailbox) | 183 | mailbox_imap_destroy (mailbox_t mailbox) |
... | @@ -191,8 +195,10 @@ mailbox_imap_destroy (mailbox_t mailbox) | ... | @@ -191,8 +195,10 @@ mailbox_imap_destroy (mailbox_t mailbox) |
191 | monitor_wrlock (mailbox->monitor); | 195 | monitor_wrlock (mailbox->monitor); |
192 | /* Destroy the imap messages and ressources associated to them. */ | 196 | /* Destroy the imap messages and ressources associated to them. */ |
193 | for (i = 0; i < m_imap->imessages_count; i++) | 197 | for (i = 0; i < m_imap->imessages_count; i++) |
194 | if (m_imap->imessages[i]) | 198 | { |
195 | free_subparts (m_imap->imessages[i]); | 199 | if (m_imap->imessages[i]) |
200 | free_subparts (m_imap->imessages[i]); | ||
201 | } | ||
196 | if (m_imap->imessages) | 202 | if (m_imap->imessages) |
197 | free (m_imap->imessages); | 203 | free (m_imap->imessages); |
198 | if (m_imap->name) | 204 | if (m_imap->name) |
... | @@ -203,9 +209,10 @@ mailbox_imap_destroy (mailbox_t mailbox) | ... | @@ -203,9 +209,10 @@ mailbox_imap_destroy (mailbox_t mailbox) |
203 | } | 209 | } |
204 | } | 210 | } |
205 | 211 | ||
206 | /* If the connection was not up it is open by the folder. It is not necessary | 212 | /* If the connection was not up it is open by the folder since the stream |
207 | to set this mailbox selected on the folder, there maybe on going operation. | 213 | socket is actually created by the folder. It is not necessary |
208 | But on any operation, if is not selected will send the SELECT. */ | 214 | to set select the mailbox right away, there are maybe on going operations. |
215 | But on any operation by a particular mailbox, it will be selected first. */ | ||
209 | static int | 216 | static int |
210 | mailbox_imap_open (mailbox_t mailbox, int flags) | 217 | mailbox_imap_open (mailbox_t mailbox, int flags) |
211 | { | 218 | { |
... | @@ -249,8 +256,10 @@ mailbox_imap_close (mailbox_t mailbox) | ... | @@ -249,8 +256,10 @@ mailbox_imap_close (mailbox_t mailbox) |
249 | monitor_wrlock (mailbox->monitor); | 256 | monitor_wrlock (mailbox->monitor); |
250 | /* Destroy the imap messages and ressources associated to them. */ | 257 | /* Destroy the imap messages and ressources associated to them. */ |
251 | for (i = 0; i < m_imap->imessages_count; i++) | 258 | for (i = 0; i < m_imap->imessages_count; i++) |
252 | if (m_imap->imessages[i]) | 259 | { |
253 | free_subparts (m_imap->imessages[i]); | 260 | if (m_imap->imessages[i]) |
261 | free_subparts (m_imap->imessages[i]); | ||
262 | } | ||
254 | if (m_imap->imessages) | 263 | if (m_imap->imessages) |
255 | free (m_imap->imessages); | 264 | free (m_imap->imessages); |
256 | m_imap->imessages = NULL; | 265 | m_imap->imessages = NULL; |
... | @@ -260,8 +269,10 @@ mailbox_imap_close (mailbox_t mailbox) | ... | @@ -260,8 +269,10 @@ mailbox_imap_close (mailbox_t mailbox) |
260 | m_imap->unseen = 0; | 269 | m_imap->unseen = 0; |
261 | monitor_unlock (mailbox->monitor); | 270 | monitor_unlock (mailbox->monitor); |
262 | } | 271 | } |
272 | break; | ||
263 | 273 | ||
264 | default: | 274 | default: |
275 | /* mu_error ("imap_close unknown state: reconnect\n");*/ | ||
265 | break; | 276 | break; |
266 | } | 277 | } |
267 | 278 | ||
... | @@ -281,25 +292,27 @@ imap_get_message (mailbox_t mailbox, size_t msgno, message_t *pmsg) | ... | @@ -281,25 +292,27 @@ imap_get_message (mailbox_t mailbox, size_t msgno, message_t *pmsg) |
281 | m_imap_t m_imap = mailbox->data; | 292 | m_imap_t m_imap = mailbox->data; |
282 | msg_imap_t msg_imap; | 293 | msg_imap_t msg_imap; |
283 | int status = 0; | 294 | int status = 0; |
284 | size_t i; | ||
285 | 295 | ||
286 | if (pmsg == NULL || msgno == 0 || msgno > m_imap->messages_count) | 296 | if (pmsg == NULL || msgno == 0 || msgno > m_imap->messages_count) |
287 | return EINVAL; | 297 | return EINVAL; |
288 | 298 | ||
299 | /* Check to see if we have already this message. */ | ||
289 | monitor_rdlock (mailbox->monitor); | 300 | monitor_rdlock (mailbox->monitor); |
290 | /* See if we have already this message. */ | 301 | { |
291 | for (i = 0; i < m_imap->imessages_count; i++) | 302 | size_t i; |
292 | { | 303 | for (i = 0; i < m_imap->imessages_count; i++) |
293 | if (m_imap->imessages[i]) | 304 | { |
294 | { | 305 | if (m_imap->imessages[i]) |
295 | if (m_imap->imessages[i]->num == msgno) | 306 | { |
296 | { | 307 | if (m_imap->imessages[i]->num == msgno) |
297 | *pmsg = m_imap->imessages[i]->message; | 308 | { |
298 | monitor_unlock (mailbox->monitor); | 309 | *pmsg = m_imap->imessages[i]->message; |
299 | return 0; | 310 | monitor_unlock (mailbox->monitor); |
300 | } | 311 | return 0; |
301 | } | 312 | } |
302 | } | 313 | } |
314 | } | ||
315 | } | ||
303 | monitor_unlock (mailbox->monitor); | 316 | monitor_unlock (mailbox->monitor); |
304 | 317 | ||
305 | /* Allocate a concrete imap message. */ | 318 | /* Allocate a concrete imap message. */ |
... | @@ -317,7 +330,7 @@ imap_get_message (mailbox_t mailbox, size_t msgno, message_t *pmsg) | ... | @@ -317,7 +330,7 @@ imap_get_message (mailbox_t mailbox, size_t msgno, message_t *pmsg) |
317 | { | 330 | { |
318 | msg_imap_t *m ; | 331 | msg_imap_t *m ; |
319 | m = realloc (m_imap->imessages, | 332 | m = realloc (m_imap->imessages, |
320 | (m_imap->imessages_count + 1) * sizeof (*m)); | 333 | (m_imap->imessages_count + 1) * sizeof *m); |
321 | if (m == NULL) | 334 | if (m == NULL) |
322 | { | 335 | { |
323 | message_destroy (pmsg, msg_imap); | 336 | message_destroy (pmsg, msg_imap); |
... | @@ -331,7 +344,6 @@ imap_get_message (mailbox_t mailbox, size_t msgno, message_t *pmsg) | ... | @@ -331,7 +344,6 @@ imap_get_message (mailbox_t mailbox, size_t msgno, message_t *pmsg) |
331 | monitor_unlock (mailbox->monitor); | 344 | monitor_unlock (mailbox->monitor); |
332 | 345 | ||
333 | msg_imap->message = *pmsg; | 346 | msg_imap->message = *pmsg; |
334 | msg_imap->m_imap = m_imap; | ||
335 | } | 347 | } |
336 | else | 348 | else |
337 | free (msg_imap); | 349 | free (msg_imap); |
... | @@ -346,7 +358,7 @@ imap_get_message0 (msg_imap_t msg_imap, message_t *pmsg) | ... | @@ -346,7 +358,7 @@ imap_get_message0 (msg_imap_t msg_imap, message_t *pmsg) |
346 | message_t msg = NULL; | 358 | message_t msg = NULL; |
347 | mailbox_t mailbox = msg_imap->m_imap->mailbox; | 359 | mailbox_t mailbox = msg_imap->m_imap->mailbox; |
348 | 360 | ||
349 | /* Create the message. */ | 361 | /* Create the message and its stream. */ |
350 | { | 362 | { |
351 | stream_t stream = NULL; | 363 | stream_t stream = NULL; |
352 | if ((status = message_create (&msg, msg_imap)) != 0 | 364 | if ((status = message_create (&msg, msg_imap)) != 0 |
... | @@ -379,9 +391,6 @@ imap_get_message0 (msg_imap_t msg_imap, message_t *pmsg) | ... | @@ -379,9 +391,6 @@ imap_get_message0 (msg_imap_t msg_imap, message_t *pmsg) |
379 | message_set_header (msg, header, msg_imap); | 391 | message_set_header (msg, header, msg_imap); |
380 | } | 392 | } |
381 | 393 | ||
382 | /* We do not create any special attribute, since nothing is send to the | ||
383 | server. When the attributes change they are cache, they are only | ||
384 | sent to the server on mailbox_close or mailbox_expunge. */ | ||
385 | /* Create the attribute. */ | 394 | /* Create the attribute. */ |
386 | { | 395 | { |
387 | attribute_t attribute; | 396 | attribute_t attribute; |
... | @@ -442,6 +451,7 @@ imap_get_message0 (msg_imap_t msg_imap, message_t *pmsg) | ... | @@ -442,6 +451,7 @@ imap_get_message0 (msg_imap_t msg_imap, message_t *pmsg) |
442 | message_set_uid (msg, imap_message_uid, msg_imap); | 451 | message_set_uid (msg, imap_message_uid, msg_imap); |
443 | message_set_mailbox (msg, mailbox, msg_imap); | 452 | message_set_mailbox (msg, mailbox, msg_imap); |
444 | 453 | ||
454 | /* We are done here. */ | ||
445 | *pmsg = msg; | 455 | *pmsg = msg; |
446 | return 0; | 456 | return 0; |
447 | } | 457 | } |
... | @@ -480,8 +490,8 @@ imap_uidnext (mailbox_t mailbox, size_t *puidnext) | ... | @@ -480,8 +490,8 @@ imap_uidnext (mailbox_t mailbox, size_t *puidnext) |
480 | 490 | ||
481 | /* There is no explicit call to get the message count. The count is send on | 491 | /* There is no explicit call to get the message count. The count is send on |
482 | a SELECT/EXAMINE command it is also sent async, meaning it will be piggy | 492 | a SELECT/EXAMINE command it is also sent async, meaning it will be piggy |
483 | back on other server response as an untag "EXIST" response. But we still | 493 | back on other server response as an untag "EXIST" response. The |
484 | send a SELECT. */ | 494 | function is also use as a way to select mailbox by other functions. */ |
485 | static int | 495 | static int |
486 | imap_messages_count (mailbox_t mailbox, size_t *pnum) | 496 | imap_messages_count (mailbox_t mailbox, size_t *pnum) |
487 | { | 497 | { |
... | @@ -497,9 +507,6 @@ imap_messages_count (mailbox_t mailbox, size_t *pnum) | ... | @@ -497,9 +507,6 @@ imap_messages_count (mailbox_t mailbox, size_t *pnum) |
497 | return 0; | 507 | return 0; |
498 | } | 508 | } |
499 | 509 | ||
500 | /* Put the mailbox as selected. */ | ||
501 | f_imap->selected = m_imap; | ||
502 | |||
503 | switch (f_imap->state) | 510 | switch (f_imap->state) |
504 | { | 511 | { |
505 | case IMAP_NO_STATE: | 512 | case IMAP_NO_STATE: |
... | @@ -521,10 +528,13 @@ imap_messages_count (mailbox_t mailbox, size_t *pnum) | ... | @@ -521,10 +528,13 @@ imap_messages_count (mailbox_t mailbox, size_t *pnum) |
521 | break; | 528 | break; |
522 | 529 | ||
523 | default: | 530 | default: |
524 | CHECK_EAGAIN (f_imap, status); | 531 | /*mu_error ("imap_message_count unknown state: reconnect\n");*/ |
525 | return status; | 532 | break; |
526 | } | 533 | } |
527 | 534 | ||
535 | /* Put the mailbox as selected. */ | ||
536 | f_imap->selected = m_imap; | ||
537 | |||
528 | if (pnum) | 538 | if (pnum) |
529 | *pnum = m_imap->messages_count; | 539 | *pnum = m_imap->messages_count; |
530 | 540 | ||
... | @@ -532,7 +542,14 @@ imap_messages_count (mailbox_t mailbox, size_t *pnum) | ... | @@ -532,7 +542,14 @@ imap_messages_count (mailbox_t mailbox, size_t *pnum) |
532 | return status; | 542 | return status; |
533 | } | 543 | } |
534 | 544 | ||
535 | /* We simulate by sending a notification for the total of msgno. */ | 545 | /* Usually when this function is call it is because there is an oberver |
546 | attach an the client is try to build some sort of list/tree header | ||
547 | as the scanning progress. But doing this for each message can be | ||
548 | time consuming and inefficient. So we bundle all the request | ||
549 | into one and ask the server for everything "FETCH 1:*". The good | ||
550 | side is that everything will be faster and we do not do lot of small | ||
551 | transcation but rather a big one. The bad thing is that every thing | ||
552 | will be cache in the structure using a lot of memory. */ | ||
536 | static int | 553 | static int |
537 | imap_scan (mailbox_t mailbox, size_t msgno, size_t *pcount) | 554 | imap_scan (mailbox_t mailbox, size_t msgno, size_t *pcount) |
538 | { | 555 | { |
... | @@ -571,8 +588,8 @@ imap_scan (mailbox_t mailbox, size_t msgno, size_t *pcount) | ... | @@ -571,8 +588,8 @@ imap_scan (mailbox_t mailbox, size_t msgno, size_t *pcount) |
571 | break; | 588 | break; |
572 | 589 | ||
573 | default: | 590 | default: |
574 | CHECK_EAGAIN (f_imap, status); | 591 | /*mu_error ("imap_scan unknown state: reconnect\n");*/ |
575 | return status; | 592 | return EINVAL; |
576 | } | 593 | } |
577 | 594 | ||
578 | f_imap->state = IMAP_NO_STATE; | 595 | f_imap->state = IMAP_NO_STATE; |
... | @@ -585,7 +602,7 @@ imap_scan (mailbox_t mailbox, size_t msgno, size_t *pcount) | ... | @@ -585,7 +602,7 @@ imap_scan (mailbox_t mailbox, size_t msgno, size_t *pcount) |
585 | { | 602 | { |
586 | if (observable_notify (mailbox->observable, MU_EVT_MESSAGE_ADD) != 0) | 603 | if (observable_notify (mailbox->observable, MU_EVT_MESSAGE_ADD) != 0) |
587 | break; | 604 | break; |
588 | if (((i + 1) % 10) == 0) | 605 | if (((i + 1) % 100) == 0) |
589 | { | 606 | { |
590 | observable_notify (mailbox->observable, MU_EVT_MAILBOX_PROGRESS); | 607 | observable_notify (mailbox->observable, MU_EVT_MAILBOX_PROGRESS); |
591 | } | 608 | } |
... | @@ -593,7 +610,7 @@ imap_scan (mailbox_t mailbox, size_t msgno, size_t *pcount) | ... | @@ -593,7 +610,7 @@ imap_scan (mailbox_t mailbox, size_t msgno, size_t *pcount) |
593 | return 0; | 610 | return 0; |
594 | } | 611 | } |
595 | 612 | ||
596 | /* Send a NOOP and see if the count has change. */ | 613 | /* Send a NOOP and see if the count has changed. */ |
597 | static int | 614 | static int |
598 | imap_is_updated (mailbox_t mailbox) | 615 | imap_is_updated (mailbox_t mailbox) |
599 | { | 616 | { |
... | @@ -602,14 +619,15 @@ imap_is_updated (mailbox_t mailbox) | ... | @@ -602,14 +619,15 @@ imap_is_updated (mailbox_t mailbox) |
602 | f_imap_t f_imap = m_imap->f_imap; | 619 | f_imap_t f_imap = m_imap->f_imap; |
603 | int status = 0; | 620 | int status = 0; |
604 | 621 | ||
622 | /* Selected. */ | ||
623 | status = imap_messages_count (mailbox, &oldcount); | ||
624 | if (status != 0) | ||
625 | return status; | ||
626 | |||
605 | /* Send a noop, and let imap piggy pack the information. */ | 627 | /* Send a noop, and let imap piggy pack the information. */ |
606 | switch (f_imap->state) | 628 | switch (f_imap->state) |
607 | { | 629 | { |
608 | case IMAP_NO_STATE: | 630 | case IMAP_NO_STATE: |
609 | /* Selected. */ | ||
610 | status = imap_messages_count (mailbox, &oldcount); | ||
611 | if (status != 0) | ||
612 | return status; | ||
613 | status = imap_writeline (f_imap, "g%d NOOP\r\n", f_imap->seq++); | 631 | status = imap_writeline (f_imap, "g%d NOOP\r\n", f_imap->seq++); |
614 | CHECK_ERROR (f_imap, status); | 632 | CHECK_ERROR (f_imap, status); |
615 | MAILBOX_DEBUG0 (mailbox, MU_DEBUG_PROT, f_imap->buffer); | 633 | MAILBOX_DEBUG0 (mailbox, MU_DEBUG_PROT, f_imap->buffer); |
... | @@ -624,8 +642,10 @@ imap_is_updated (mailbox_t mailbox) | ... | @@ -624,8 +642,10 @@ imap_is_updated (mailbox_t mailbox) |
624 | status = imap_parse (f_imap); | 642 | status = imap_parse (f_imap); |
625 | CHECK_EAGAIN (f_imap, status); | 643 | CHECK_EAGAIN (f_imap, status); |
626 | MAILBOX_DEBUG0 (mailbox, MU_DEBUG_PROT, f_imap->buffer); | 644 | MAILBOX_DEBUG0 (mailbox, MU_DEBUG_PROT, f_imap->buffer); |
645 | break; | ||
627 | 646 | ||
628 | default: | 647 | default: |
648 | /*mu_error ("imap_noop unknown state: reconnect\n"); */ | ||
629 | break; | 649 | break; |
630 | } | 650 | } |
631 | f_imap->state = IMAP_NO_STATE; | 651 | f_imap->state = IMAP_NO_STATE; |
... | @@ -633,53 +653,53 @@ imap_is_updated (mailbox_t mailbox) | ... | @@ -633,53 +653,53 @@ imap_is_updated (mailbox_t mailbox) |
633 | } | 653 | } |
634 | 654 | ||
635 | 655 | ||
636 | /* FIXME: Not asyn, please fix to make usable when non blocking. */ | 656 | /* It is only here that the Deleted flags are sent. Expunge is not |
657 | call rather the mailbox is close explicitely, letting the server | ||
658 | do the expunge without sending the notifications. It's faster. */ | ||
637 | static int | 659 | static int |
638 | imap_expunge (mailbox_t mailbox) | 660 | imap_expunge (mailbox_t mailbox) |
639 | { | 661 | { |
640 | size_t i; | ||
641 | int status; | 662 | int status; |
642 | m_imap_t m_imap = mailbox->data; | 663 | m_imap_t m_imap = mailbox->data; |
643 | f_imap_t f_imap = m_imap->f_imap; | 664 | f_imap_t f_imap = m_imap->f_imap; |
644 | 665 | ||
645 | /* Select first. */ | 666 | /* Select first. */ |
646 | status = imap_messages_count (mailbox, &i); | 667 | status = imap_messages_count (mailbox, NULL); |
647 | if (status != 0) | 668 | if (status != 0) |
648 | return status; | 669 | return status; |
649 | 670 | ||
650 | for (i = 0; i < m_imap->imessages_count; ++i) | 671 | switch (f_imap->state) |
651 | { | 672 | { |
652 | if (m_imap->imessages[i]->flags & MU_ATTRIBUTE_DELETED) | 673 | case IMAP_NO_STATE: |
653 | { | 674 | { |
654 | switch (f_imap->state) | 675 | char *set; |
655 | { | 676 | status = delete_to_string (m_imap, &set); |
656 | case IMAP_NO_STATE: | 677 | CHECK_ERROR (f_imap, status); |
657 | status = imap_writeline (f_imap, | 678 | status = imap_writeline (f_imap, |
658 | "g%d STORE %d +FLAGS.SILENT (\\Deleted)\r\n", | 679 | "g%d STORE %s +FLAGS.SILENT (\\Deleted)\r\n", |
659 | f_imap->seq++, | 680 | f_imap->seq++, set); |
660 | m_imap->imessages[i]->num); | 681 | free (set); |
661 | CHECK_ERROR (f_imap, status); | 682 | CHECK_ERROR (f_imap, status); |
662 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); | 683 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); |
663 | f_imap->state = IMAP_STORE; | 684 | f_imap->state = IMAP_STORE; |
664 | 685 | } | |
665 | case IMAP_STORE: | 686 | |
666 | /* Send DELETE. */ | 687 | /* Send DELETE. */ |
667 | status = imap_send (f_imap); | 688 | case IMAP_STORE: |
668 | CHECK_EAGAIN (f_imap, status); | 689 | status = imap_send (f_imap); |
669 | f_imap->state = IMAP_STORE_ACK; | 690 | CHECK_EAGAIN (f_imap, status); |
670 | 691 | f_imap->state = IMAP_STORE_ACK; | |
671 | case IMAP_STORE_ACK: | 692 | |
672 | status = imap_parse (f_imap); | 693 | case IMAP_STORE_ACK: |
673 | CHECK_EAGAIN (f_imap, status); | 694 | status = imap_parse (f_imap); |
674 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); | 695 | CHECK_EAGAIN (f_imap, status); |
675 | f_imap->state = IMAP_NO_STATE; | 696 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); |
676 | 697 | f_imap->state = IMAP_NO_STATE; | |
677 | default: | 698 | |
678 | /* mu_error ("imap_expunge: unknow state\n"); */ | 699 | default: |
679 | break; | 700 | /* mu_error ("imap_expunge: unknow state\n"); */ |
680 | } /* switch (state) */ | 701 | break; |
681 | } /* message_get_attribute() */ | 702 | } |
682 | } /* for */ | ||
683 | 703 | ||
684 | /* Tell the server to delete the messages but without sending the | 704 | /* Tell the server to delete the messages but without sending the |
685 | EXPUNGE response. We can do the calculations. */ | 705 | EXPUNGE response. We can do the calculations. */ |
... | @@ -687,95 +707,11 @@ imap_expunge (mailbox_t mailbox) | ... | @@ -687,95 +707,11 @@ imap_expunge (mailbox_t mailbox) |
687 | return status; | 707 | return status; |
688 | } | 708 | } |
689 | 709 | ||
690 | static int | ||
691 | attribute_string (attribute_t attribute, char **pbuf) | ||
692 | { | ||
693 | char *abuf = *pbuf; | ||
694 | if (attribute_is_deleted (attribute)) | ||
695 | { | ||
696 | char *tmp = realloc (abuf, strlen (abuf) + strlen ("\\Deleted") + 2); | ||
697 | if (tmp == NULL) | ||
698 | { | ||
699 | free (abuf); | ||
700 | return ENOMEM; | ||
701 | } | ||
702 | abuf = tmp; | ||
703 | if (*abuf) | ||
704 | strcat (abuf, " "); | ||
705 | strcat (abuf, "\\Deleted"); | ||
706 | } | ||
707 | if (attribute_is_seen (attribute) || attribute_is_read (attribute)) | ||
708 | { | ||
709 | char *tmp = realloc (abuf, strlen (abuf) + strlen ("\\Seen") + 2); | ||
710 | if (tmp == NULL) | ||
711 | { | ||
712 | free (abuf); | ||
713 | return ENOMEM; | ||
714 | } | ||
715 | abuf = tmp; | ||
716 | if (*abuf) | ||
717 | strcat (abuf, " "); | ||
718 | strcat (abuf, "\\Seen"); | ||
719 | } | ||
720 | if (attribute_is_answered (attribute)) | ||
721 | { | ||
722 | char *tmp = realloc (abuf, strlen (abuf) + strlen ("\\Answered") + 2); | ||
723 | if (tmp == NULL) | ||
724 | { | ||
725 | free (abuf); | ||
726 | return ENOMEM; | ||
727 | } | ||
728 | abuf = tmp; | ||
729 | if (*abuf) | ||
730 | strcat (abuf, " "); | ||
731 | strcat (abuf, "\\Answered"); | ||
732 | } | ||
733 | if (attribute_is_draft (attribute)) | ||
734 | { | ||
735 | char *tmp = realloc (abuf, strlen (abuf) + strlen ("\\Draft") + 2); | ||
736 | if (tmp == NULL) | ||
737 | { | ||
738 | free (abuf); | ||
739 | return ENOMEM; | ||
740 | } | ||
741 | abuf = tmp; | ||
742 | if (*abuf) | ||
743 | strcat (abuf, " "); | ||
744 | strcat (abuf, "\\Draft"); | ||
745 | } | ||
746 | if (attribute_is_flagged (attribute)) | ||
747 | { | ||
748 | char *tmp = realloc (abuf, strlen (abuf) + strlen ("\\Flagged") + 2); | ||
749 | if (tmp == NULL) | ||
750 | { | ||
751 | free (abuf); | ||
752 | return ENOMEM; | ||
753 | } | ||
754 | abuf = tmp; | ||
755 | if (*abuf) | ||
756 | strcat (abuf, " "); | ||
757 | strcat (abuf, "\\Flagged"); | ||
758 | } | ||
759 | *pbuf = abuf; | ||
760 | return 0; | ||
761 | } | ||
762 | |||
763 | static int | ||
764 | is_same_folder (mailbox_t mailbox, message_t msg) | ||
765 | { | ||
766 | mailbox_t mbox = NULL; | ||
767 | message_get_mailbox (msg, &mbox); | ||
768 | return (mbox != NULL && mbox->url != NULL | ||
769 | && url_is_same_scheme (mbox->url, mailbox->url) | ||
770 | && url_is_same_host (mbox->url, mailbox->url) | ||
771 | && url_is_same_port (mbox->url, mailbox->url)); | ||
772 | } | ||
773 | |||
774 | /* Not Nonblocking safe. */ | 710 | /* Not Nonblocking safe. */ |
775 | /* DANGER: The message_t object makes no guarenty the size and the lines | 711 | /* DANGER: The message_t object makes no guaranty about the size and the lines |
776 | that it returns are exact if its pointing to non-local file messages. | 712 | that it returns, if its pointing to non-local file messages. |
777 | FIXME: So we should download the message to a floating message so to | 713 | FIXME: So we should download the message to a floating message so to |
778 | make sure that we know the exacte size then transmit it back the IMAP | 714 | make sure that we know the exact size then transmit it back the IMAP |
779 | server. */ | 715 | server. */ |
780 | static int | 716 | static int |
781 | imap_append_message (mailbox_t mailbox, message_t msg) | 717 | imap_append_message (mailbox_t mailbox, message_t msg) |
... | @@ -788,13 +724,11 @@ imap_append_message (mailbox_t mailbox, message_t msg) | ... | @@ -788,13 +724,11 @@ imap_append_message (mailbox_t mailbox, message_t msg) |
788 | /* FIXME: Can we append to self. */ | 724 | /* FIXME: Can we append to self. */ |
789 | 725 | ||
790 | /* Check to see if we are selected. If the message was not modified | 726 | /* Check to see if we are selected. If the message was not modified |
791 | and came from the imap folder. use COPY.*/ | 727 | and came from the same imap folder. use COPY.*/ |
792 | if (f_imap->selected != m_imap && !message_is_modified (msg) | 728 | if (f_imap->selected != m_imap && !message_is_modified (msg) |
793 | && is_same_folder (mailbox, msg)) | 729 | && is_same_folder (mailbox, msg)) |
794 | return imap_copy_message (mailbox, msg); | 730 | return imap_copy_message (mailbox, msg); |
795 | 731 | ||
796 | /* FIXME: Do we need to get the envelope_date? */ | ||
797 | |||
798 | switch (f_imap->state) | 732 | switch (f_imap->state) |
799 | { | 733 | { |
800 | case IMAP_NO_STATE: | 734 | case IMAP_NO_STATE: |
... | @@ -808,8 +742,10 @@ imap_append_message (mailbox_t mailbox, message_t msg) | ... | @@ -808,8 +742,10 @@ imap_append_message (mailbox_t mailbox, message_t msg) |
808 | *abuf = '\0'; | 742 | *abuf = '\0'; |
809 | { | 743 | { |
810 | attribute_t attribute = NULL; | 744 | attribute_t attribute = NULL; |
745 | int flags = 0; | ||
811 | message_get_attribute (msg, &attribute); | 746 | message_get_attribute (msg, &attribute); |
812 | status = attribute_string (attribute, &abuf); | 747 | attribute_get_flags (attribute, &flags); |
748 | status = flags_to_string (&abuf, flags); | ||
813 | if (status != 0) | 749 | if (status != 0) |
814 | return status; | 750 | return status; |
815 | if (*abuf != '\0') | 751 | if (*abuf != '\0') |
... | @@ -825,16 +761,29 @@ imap_append_message (mailbox_t mailbox, message_t msg) | ... | @@ -825,16 +761,29 @@ imap_append_message (mailbox_t mailbox, message_t msg) |
825 | abuf = tmp; | 761 | abuf = tmp; |
826 | } | 762 | } |
827 | } | 763 | } |
764 | |||
765 | /* Get the mailbox filepath. */ | ||
828 | { | 766 | { |
829 | size_t n = 0; | 767 | size_t n = 0; |
830 | url_get_path (mailbox->url, NULL, 0, &n); | 768 | url_get_path (mailbox->url, NULL, 0, &n); |
831 | if (n == 0) | 769 | if (n == 0) |
832 | return EINVAL; | 770 | { |
771 | free (abuf); | ||
772 | return EINVAL; | ||
773 | } | ||
833 | path = calloc (n + 1, sizeof (*path)); | 774 | path = calloc (n + 1, sizeof (*path)); |
834 | if (path == NULL) | 775 | if (path == NULL) |
835 | return ENOMEM; | 776 | { |
777 | free (abuf); | ||
778 | return ENOMEM; | ||
779 | } | ||
836 | url_get_path (mailbox->url, path, n + 1, NULL); | 780 | url_get_path (mailbox->url, path, n + 1, NULL); |
837 | } | 781 | } |
782 | |||
783 | /* FIXME: we need to get the envelope_date and use it. | ||
784 | currently it is ignored. */ | ||
785 | |||
786 | /* Get the total size, assuming that it is in UNIX format. */ | ||
838 | lines = size = 0; | 787 | lines = size = 0; |
839 | message_size (msg, &size); | 788 | message_size (msg, &size); |
840 | message_lines (msg, &lines); | 789 | message_lines (msg, &lines); |
... | @@ -900,14 +849,15 @@ imap_append_message (mailbox_t mailbox, message_t msg) | ... | @@ -900,14 +849,15 @@ imap_append_message (mailbox_t mailbox, message_t msg) |
900 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); | 849 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); |
901 | 850 | ||
902 | default: | 851 | default: |
903 | /* mu_error ("imap_expunge: unknow state\n"); */ | 852 | /* mu_error ("imap_append: unknow state\n"); */ |
904 | break; | 853 | break; |
905 | } | 854 | } |
906 | f_imap->state = IMAP_NO_STATE; | 855 | f_imap->state = IMAP_NO_STATE; |
907 | return status; | 856 | return status; |
908 | } | 857 | } |
909 | 858 | ||
910 | /* Not Nonblocking safe. */ | 859 | /* If the message is on the same server. Use the COPY command much more |
860 | efficient. */ | ||
911 | static int | 861 | static int |
912 | imap_copy_message (mailbox_t mailbox, message_t msg) | 862 | imap_copy_message (mailbox_t mailbox, message_t msg) |
913 | { | 863 | { |
... | @@ -921,17 +871,15 @@ imap_copy_message (mailbox_t mailbox, message_t msg) | ... | @@ -921,17 +871,15 @@ imap_copy_message (mailbox_t mailbox, message_t msg) |
921 | case IMAP_NO_STATE: | 871 | case IMAP_NO_STATE: |
922 | { | 872 | { |
923 | char *path; | 873 | char *path; |
874 | size_t n = 0; | ||
924 | /* Check for a valid mailbox name. */ | 875 | /* Check for a valid mailbox name. */ |
925 | { | 876 | url_get_path (mailbox->url, NULL, 0, &n); |
926 | size_t n = 0; | 877 | if (n == 0) |
927 | url_get_path (mailbox->url, NULL, 0, &n); | 878 | return EINVAL; |
928 | if (n == 0) | 879 | path = calloc (n + 1, sizeof (*path)); |
929 | return EINVAL; | 880 | if (path == NULL) |
930 | path = calloc (n + 1, sizeof (*path)); | 881 | return ENOMEM; |
931 | if (path == NULL) | 882 | url_get_path (mailbox->url, path, n + 1, NULL); |
932 | return ENOMEM; | ||
933 | url_get_path (mailbox->url, path, n + 1, NULL); | ||
934 | } | ||
935 | status = imap_writeline (f_imap, "g%d COPY %d %s\r\n", f_imap->seq++, | 883 | status = imap_writeline (f_imap, "g%d COPY %d %s\r\n", f_imap->seq++, |
936 | msg_imap->num, path); | 884 | msg_imap->num, path); |
937 | free (path); | 885 | free (path); |
... | @@ -957,7 +905,7 @@ imap_copy_message (mailbox_t mailbox, message_t msg) | ... | @@ -957,7 +905,7 @@ imap_copy_message (mailbox_t mailbox, message_t msg) |
957 | return status; | 905 | return status; |
958 | } | 906 | } |
959 | 907 | ||
960 | /* Message. */ | 908 | /* Message read overload */ |
961 | static int | 909 | static int |
962 | imap_message_read (stream_t stream, char *buffer, size_t buflen, | 910 | imap_message_read (stream_t stream, char *buffer, size_t buflen, |
963 | off_t offset, size_t *plen) | 911 | off_t offset, size_t *plen) |
... | @@ -974,32 +922,28 @@ imap_message_read (stream_t stream, char *buffer, size_t buflen, | ... | @@ -974,32 +922,28 @@ imap_message_read (stream_t stream, char *buffer, size_t buflen, |
974 | /* Select first. */ | 922 | /* Select first. */ |
975 | if (f_imap->state == IMAP_NO_STATE) | 923 | if (f_imap->state == IMAP_NO_STATE) |
976 | { | 924 | { |
925 | char *section = NULL; | ||
977 | int status = imap_messages_count (m_imap->mailbox, NULL); | 926 | int status = imap_messages_count (m_imap->mailbox, NULL); |
978 | if (status != 0) | 927 | if (status != 0) |
979 | return status; | 928 | return status; |
980 | /* We strip the \r, but the offset/size on the imap server is with that | 929 | |
981 | octet so add it in the offset, since it's the number of lines. */ | ||
982 | if (msg_imap->part) | 930 | if (msg_imap->part) |
983 | { | 931 | section = section_name (msg_imap); |
984 | char *section = section_name (msg_imap); | 932 | |
985 | status = imap_writeline (f_imap, | 933 | /* We have strip the \r, but the offset on the imap server is with that |
986 | "g%d FETCH %d BODY.PEEK[%s]<%d.%d>\r\n", | 934 | octet(CFLF) so add it in the offset, it's the number of lines. */ |
987 | f_imap->seq++, msg_imap->num, | 935 | status = imap_writeline (f_imap, |
988 | (section) ? section : "", | 936 | "g%d FETCH %d BODY.PEEK[%s]<%d.%d>\r\n", |
989 | offset + msg_imap->message_lines, buflen); | 937 | f_imap->seq++, msg_imap->num, |
990 | if (section) | 938 | (section) ? section : "", |
991 | free (section); | 939 | offset + msg_imap->message_lines, buflen); |
992 | } | 940 | if (section) |
993 | else | 941 | free (section); |
994 | status = imap_writeline (f_imap, | ||
995 | "g%d FETCH %d BODY.PEEK[]<%d.%d>\r\n", | ||
996 | f_imap->seq++, msg_imap->num, | ||
997 | offset + msg_imap->message_lines, buflen); | ||
998 | CHECK_ERROR (f_imap, status); | 942 | CHECK_ERROR (f_imap, status); |
999 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); | 943 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); |
1000 | f_imap->state = IMAP_FETCH; | 944 | f_imap->state = IMAP_FETCH; |
1001 | } | 945 | } |
1002 | return message_operation (f_imap, msg_imap, buffer, buflen, plen); | 946 | return fetch_operation (f_imap, msg_imap, buffer, buflen, plen); |
1003 | } | 947 | } |
1004 | 948 | ||
1005 | static int | 949 | static int |
... | @@ -1056,9 +1000,7 @@ imap_message_size (message_t msg, size_t *psize) | ... | @@ -1056,9 +1000,7 @@ imap_message_size (message_t msg, size_t *psize) |
1056 | the full size of mime messages, so the message_size retrieved from | 1000 | the full size of mime messages, so the message_size retrieved from |
1057 | doing a bodystructure represents rather the body_size. */ | 1001 | doing a bodystructure represents rather the body_size. */ |
1058 | if (msg_imap->parent) | 1002 | if (msg_imap->parent) |
1059 | { | 1003 | return imap_submessage_size (msg_imap, psize); |
1060 | return imap_submessage_size (msg_imap, psize); | ||
1061 | } | ||
1062 | 1004 | ||
1063 | if (msg_imap->message_size == 0) | 1005 | if (msg_imap->message_size == 0) |
1064 | { | 1006 | { |
... | @@ -1078,7 +1020,7 @@ imap_message_size (message_t msg, size_t *psize) | ... | @@ -1078,7 +1020,7 @@ imap_message_size (message_t msg, size_t *psize) |
1078 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); | 1020 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); |
1079 | f_imap->state = IMAP_FETCH; | 1021 | f_imap->state = IMAP_FETCH; |
1080 | } | 1022 | } |
1081 | status = message_operation (f_imap, msg_imap, 0, 0, 0); | 1023 | status = fetch_operation (f_imap, msg_imap, 0, 0, 0); |
1082 | } | 1024 | } |
1083 | 1025 | ||
1084 | if (status == 0) | 1026 | if (status == 0) |
... | @@ -1116,7 +1058,7 @@ imap_message_uid (message_t msg, size_t *puid) | ... | @@ -1116,7 +1058,7 @@ imap_message_uid (message_t msg, size_t *puid) |
1116 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); | 1058 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); |
1117 | f_imap->state = IMAP_FETCH; | 1059 | f_imap->state = IMAP_FETCH; |
1118 | } | 1060 | } |
1119 | status = message_operation (f_imap, msg_imap, 0, 0, 0); | 1061 | status = fetch_operation (f_imap, msg_imap, 0, 0, 0); |
1120 | if (status != 0) | 1062 | if (status != 0) |
1121 | return status; | 1063 | return status; |
1122 | *puid = msg_imap->uid; | 1064 | *puid = msg_imap->uid; |
... | @@ -1159,7 +1101,7 @@ imap_is_multipart (message_t msg, int *ismulti) | ... | @@ -1159,7 +1101,7 @@ imap_is_multipart (message_t msg, int *ismulti) |
1159 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); | 1101 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); |
1160 | f_imap->state = IMAP_FETCH; | 1102 | f_imap->state = IMAP_FETCH; |
1161 | } | 1103 | } |
1162 | status = message_operation (f_imap, msg_imap, 0, 0, 0); | 1104 | status = fetch_operation (f_imap, msg_imap, 0, 0, 0); |
1163 | if (status != 0) | 1105 | if (status != 0) |
1164 | return status; | 1106 | return status; |
1165 | if (ismulti) | 1107 | if (ismulti) |
... | @@ -1295,7 +1237,7 @@ imap_envelope_date (envelope_t envelope, char *buffer, size_t buflen, | ... | @@ -1295,7 +1237,7 @@ imap_envelope_date (envelope_t envelope, char *buffer, size_t buflen, |
1295 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); | 1237 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); |
1296 | f_imap->state = IMAP_FETCH; | 1238 | f_imap->state = IMAP_FETCH; |
1297 | } | 1239 | } |
1298 | status = message_operation (f_imap, msg_imap, datebuf, sizeof datebuf, NULL); | 1240 | status = fetch_operation (f_imap, msg_imap, datebuf, sizeof datebuf, NULL); |
1299 | if (status != 0) | 1241 | if (status != 0) |
1300 | return status; | 1242 | return status; |
1301 | 1243 | ||
... | @@ -1363,7 +1305,7 @@ imap_attr_get_flags (attribute_t attribute, int *pflags) | ... | @@ -1363,7 +1305,7 @@ imap_attr_get_flags (attribute_t attribute, int *pflags) |
1363 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); | 1305 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); |
1364 | f_imap->state = IMAP_FETCH; | 1306 | f_imap->state = IMAP_FETCH; |
1365 | } | 1307 | } |
1366 | status = message_operation (f_imap, msg_imap, NULL, 0, NULL); | 1308 | status = fetch_operation (f_imap, msg_imap, NULL, 0, NULL); |
1367 | if (status == 0) | 1309 | if (status == 0) |
1368 | { | 1310 | { |
1369 | if (pflags) | 1311 | if (pflags) |
... | @@ -1373,79 +1315,6 @@ imap_attr_get_flags (attribute_t attribute, int *pflags) | ... | @@ -1373,79 +1315,6 @@ imap_attr_get_flags (attribute_t attribute, int *pflags) |
1373 | } | 1315 | } |
1374 | 1316 | ||
1375 | static int | 1317 | static int |
1376 | flags_string (int flag, char **pbuf) | ||
1377 | { | ||
1378 | char *abuf = *pbuf; | ||
1379 | if (flag & MU_ATTRIBUTE_DELETED) | ||
1380 | { | ||
1381 | char *tmp = realloc (abuf, strlen (abuf) + strlen ("\\Deleted") + 2); | ||
1382 | if (tmp == NULL) | ||
1383 | { | ||
1384 | free (abuf); | ||
1385 | return ENOMEM; | ||
1386 | } | ||
1387 | abuf = tmp; | ||
1388 | if (*abuf) | ||
1389 | strcat (abuf, " "); | ||
1390 | strcat (abuf, "\\Deleted"); | ||
1391 | } | ||
1392 | if ((flag & MU_ATTRIBUTE_SEEN) || (flag & MU_ATTRIBUTE_READ)) | ||
1393 | { | ||
1394 | char *tmp = realloc (abuf, strlen (abuf) + strlen ("\\Seen") + 2); | ||
1395 | if (tmp == NULL) | ||
1396 | { | ||
1397 | free (abuf); | ||
1398 | return ENOMEM; | ||
1399 | } | ||
1400 | abuf = tmp; | ||
1401 | if (*abuf) | ||
1402 | strcat (abuf, " "); | ||
1403 | strcat (abuf, "\\Seen"); | ||
1404 | } | ||
1405 | if (flag & MU_ATTRIBUTE_ANSWERED) | ||
1406 | { | ||
1407 | char *tmp = realloc (abuf, strlen (abuf) + strlen ("\\Answered") + 2); | ||
1408 | if (tmp == NULL) | ||
1409 | { | ||
1410 | free (abuf); | ||
1411 | return ENOMEM; | ||
1412 | } | ||
1413 | abuf = tmp; | ||
1414 | if (*abuf) | ||
1415 | strcat (abuf, " "); | ||
1416 | strcat (abuf, "\\Answered"); | ||
1417 | } | ||
1418 | if (flag & MU_ATTRIBUTE_DRAFT) | ||
1419 | { | ||
1420 | char *tmp = realloc (abuf, strlen (abuf) + strlen ("\\Draft") + 2); | ||
1421 | if (tmp == NULL) | ||
1422 | { | ||
1423 | free (abuf); | ||
1424 | return ENOMEM; | ||
1425 | } | ||
1426 | abuf = tmp; | ||
1427 | if (*abuf) | ||
1428 | strcat (abuf, " "); | ||
1429 | strcat (abuf, "\\Draft"); | ||
1430 | } | ||
1431 | if (flag & MU_ATTRIBUTE_FLAGGED) | ||
1432 | { | ||
1433 | char *tmp = realloc (abuf, strlen (abuf) + strlen ("\\Flagged") + 2); | ||
1434 | if (tmp == NULL) | ||
1435 | { | ||
1436 | free (abuf); | ||
1437 | return ENOMEM; | ||
1438 | } | ||
1439 | abuf = tmp; | ||
1440 | if (*abuf) | ||
1441 | strcat (abuf, " "); | ||
1442 | strcat (abuf, "\\Flagged"); | ||
1443 | } | ||
1444 | *pbuf = abuf; | ||
1445 | return 0; | ||
1446 | } | ||
1447 | |||
1448 | static int | ||
1449 | imap_attr_set_flags (attribute_t attribute, int flag) | 1318 | imap_attr_set_flags (attribute_t attribute, int flag) |
1450 | { | 1319 | { |
1451 | message_t msg = attribute_get_owner (attribute); | 1320 | message_t msg = attribute_get_owner (attribute); |
... | @@ -1467,7 +1336,7 @@ imap_attr_set_flags (attribute_t attribute, int flag) | ... | @@ -1467,7 +1336,7 @@ imap_attr_set_flags (attribute_t attribute, int flag) |
1467 | if (abuf == NULL) | 1336 | if (abuf == NULL) |
1468 | return ENOMEM; | 1337 | return ENOMEM; |
1469 | *abuf = '\0'; | 1338 | *abuf = '\0'; |
1470 | status = flags_string (flag, &abuf); | 1339 | status = flags_to_string (&abuf, flag); |
1471 | if (status != 0) | 1340 | if (status != 0) |
1472 | return status; | 1341 | return status; |
1473 | /* No flags to send?? */ | 1342 | /* No flags to send?? */ |
... | @@ -1484,7 +1353,7 @@ imap_attr_set_flags (attribute_t attribute, int flag) | ... | @@ -1484,7 +1353,7 @@ imap_attr_set_flags (attribute_t attribute, int flag) |
1484 | msg_imap->flags |= flag; | 1353 | msg_imap->flags |= flag; |
1485 | f_imap->state = IMAP_FETCH; | 1354 | f_imap->state = IMAP_FETCH; |
1486 | } | 1355 | } |
1487 | return message_operation (f_imap, msg_imap, NULL, 0, NULL); | 1356 | return fetch_operation (f_imap, msg_imap, NULL, 0, NULL); |
1488 | } | 1357 | } |
1489 | 1358 | ||
1490 | static int | 1359 | static int |
... | @@ -1509,7 +1378,7 @@ imap_attr_unset_flags (attribute_t attribute, int flag) | ... | @@ -1509,7 +1378,7 @@ imap_attr_unset_flags (attribute_t attribute, int flag) |
1509 | if (abuf == NULL) | 1378 | if (abuf == NULL) |
1510 | return ENOMEM; | 1379 | return ENOMEM; |
1511 | *abuf = '\0'; | 1380 | *abuf = '\0'; |
1512 | status = flags_string (flag, &abuf); | 1381 | status = flags_to_string (&abuf, flag); |
1513 | if (status != 0) | 1382 | if (status != 0) |
1514 | return status; | 1383 | return status; |
1515 | /* No flags to send?? */ | 1384 | /* No flags to send?? */ |
... | @@ -1526,7 +1395,7 @@ imap_attr_unset_flags (attribute_t attribute, int flag) | ... | @@ -1526,7 +1395,7 @@ imap_attr_unset_flags (attribute_t attribute, int flag) |
1526 | msg_imap->flags &= ~flag; | 1395 | msg_imap->flags &= ~flag; |
1527 | f_imap->state = IMAP_FETCH; | 1396 | f_imap->state = IMAP_FETCH; |
1528 | } | 1397 | } |
1529 | return message_operation (f_imap, msg_imap, NULL, 0, NULL); | 1398 | return fetch_operation (f_imap, msg_imap, NULL, 0, NULL); |
1530 | } | 1399 | } |
1531 | 1400 | ||
1532 | /* Header. */ | 1401 | /* Header. */ |
... | @@ -1566,7 +1435,7 @@ imap_header_get_value (header_t header, const char *field, char * buffer, | ... | @@ -1566,7 +1435,7 @@ imap_header_get_value (header_t header, const char *field, char * buffer, |
1566 | } | 1435 | } |
1567 | 1436 | ||
1568 | value = calloc (len, sizeof (*value)); | 1437 | value = calloc (len, sizeof (*value)); |
1569 | status = message_operation (f_imap, msg_imap, value, len, &len); | 1438 | status = fetch_operation (f_imap, msg_imap, value, len, &len); |
1570 | if (status == 0) | 1439 | if (status == 0) |
1571 | { | 1440 | { |
1572 | char *colon; | 1441 | char *colon; |
... | @@ -1641,7 +1510,7 @@ imap_header_get_fvalue (header_t header, const char *field, char * buffer, | ... | @@ -1641,7 +1510,7 @@ imap_header_get_fvalue (header_t header, const char *field, char * buffer, |
1641 | /* Should be enough for our needs. */ | 1510 | /* Should be enough for our needs. */ |
1642 | len = 2048; | 1511 | len = 2048; |
1643 | value = calloc (len, sizeof *value); | 1512 | value = calloc (len, sizeof *value); |
1644 | status = message_operation (f_imap, msg_imap, value, len, &len); | 1513 | status = fetch_operation (f_imap, msg_imap, value, len, &len); |
1645 | if (status == 0) | 1514 | if (status == 0) |
1646 | { | 1515 | { |
1647 | status = header_create (&msg_imap->fheader, value, len, NULL); | 1516 | status = header_create (&msg_imap->fheader, value, len, NULL); |
... | @@ -1669,33 +1538,29 @@ imap_header_read (header_t header, char *buffer, size_t buflen, off_t offset, | ... | @@ -1669,33 +1538,29 @@ imap_header_read (header_t header, char *buffer, size_t buflen, off_t offset, |
1669 | /* Select first. */ | 1538 | /* Select first. */ |
1670 | if (f_imap->state == IMAP_NO_STATE) | 1539 | if (f_imap->state == IMAP_NO_STATE) |
1671 | { | 1540 | { |
1541 | char *section = NULL; | ||
1672 | int status = imap_messages_count (m_imap->mailbox, NULL); | 1542 | int status = imap_messages_count (m_imap->mailbox, NULL); |
1673 | if (status != 0) | 1543 | if (status != 0) |
1674 | return status; | 1544 | return status; |
1545 | |||
1546 | if (msg_imap->part) | ||
1547 | section = section_name (msg_imap); | ||
1548 | |||
1675 | /* We strip the \r, but the offset/size on the imap server is with that | 1549 | /* We strip the \r, but the offset/size on the imap server is with that |
1676 | octet so add it in the offset, since it's the number of lines. */ | 1550 | octet so add it in the offset, since it's the number of lines. */ |
1677 | if (msg_imap->part) | 1551 | status = imap_writeline (f_imap, |
1678 | { | 1552 | "g%d FETCH %d BODY.PEEK[%s.MIME]<%d.%d>\r\n", |
1679 | char *section = section_name (msg_imap); | 1553 | f_imap->seq++, msg_imap->num, |
1680 | status = imap_writeline (f_imap, | 1554 | (section) ? section : "", |
1681 | "g%d FETCH %d BODY.PEEK[%s.MIME]<%d.%d>\r\n", | 1555 | offset + msg_imap->header_lines, buflen); |
1682 | f_imap->seq++, msg_imap->num, | 1556 | if (section) |
1683 | (section) ? section : "", | 1557 | free (section); |
1684 | offset + msg_imap->header_lines, buflen); | ||
1685 | if (section) | ||
1686 | free (section); | ||
1687 | } | ||
1688 | else | ||
1689 | status = imap_writeline (f_imap, | ||
1690 | "g%d FETCH %d BODY.PEEK[HEADER]<%d.%d>\r\n", | ||
1691 | f_imap->seq++, msg_imap->num, | ||
1692 | offset + msg_imap->header_lines, buflen); | ||
1693 | CHECK_ERROR (f_imap, status); | 1558 | CHECK_ERROR (f_imap, status); |
1694 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); | 1559 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); |
1695 | f_imap->state = IMAP_FETCH; | 1560 | f_imap->state = IMAP_FETCH; |
1696 | 1561 | ||
1697 | } | 1562 | } |
1698 | return message_operation (f_imap, msg_imap, buffer, buflen, plen); | 1563 | return fetch_operation (f_imap, msg_imap, buffer, buflen, plen); |
1699 | } | 1564 | } |
1700 | 1565 | ||
1701 | /* Body. */ | 1566 | /* Body. */ |
... | @@ -1771,33 +1636,29 @@ imap_body_read (stream_t stream, char *buffer, size_t buflen, off_t offset, | ... | @@ -1771,33 +1636,29 @@ imap_body_read (stream_t stream, char *buffer, size_t buflen, off_t offset, |
1771 | /* Select first. */ | 1636 | /* Select first. */ |
1772 | if (f_imap->state == IMAP_NO_STATE) | 1637 | if (f_imap->state == IMAP_NO_STATE) |
1773 | { | 1638 | { |
1639 | char *section = NULL; | ||
1774 | status = imap_messages_count (m_imap->mailbox, NULL); | 1640 | status = imap_messages_count (m_imap->mailbox, NULL); |
1775 | if (status != 0) | 1641 | if (status != 0) |
1776 | return status; | 1642 | return status; |
1643 | |||
1644 | if (msg_imap->part) | ||
1645 | section = section_name (msg_imap); | ||
1646 | |||
1777 | /* We strip the \r, but the offset/size on the imap server is with the | 1647 | /* We strip the \r, but the offset/size on the imap server is with the |
1778 | octet, so add it since it's the number of lines. */ | 1648 | octet, so add it since it's the number of lines. */ |
1779 | if (msg_imap->part) | 1649 | status = imap_writeline (f_imap, |
1780 | { | 1650 | "g%d FETCH %d BODY.PEEK[%s]<%d.%d>\r\n", |
1781 | char *section = section_name (msg_imap); | 1651 | f_imap->seq++, msg_imap->num, |
1782 | status = imap_writeline (f_imap, | 1652 | (section) ? section: "", |
1783 | "g%d FETCH %d BODY.PEEK[%s]<%d.%d>\r\n", | 1653 | offset + msg_imap->body_lines, buflen); |
1784 | f_imap->seq++, msg_imap->num, | 1654 | if (section) |
1785 | (section) ? section: "", | 1655 | free (section); |
1786 | offset + msg_imap->body_lines, buflen); | ||
1787 | if (section) | ||
1788 | free (section); | ||
1789 | } | ||
1790 | else | ||
1791 | status = imap_writeline (f_imap, | ||
1792 | "g%d FETCH %d BODY.PEEK[TEXT]<%d.%d>\r\n", | ||
1793 | f_imap->seq++, msg_imap->num, | ||
1794 | offset + msg_imap->body_lines, buflen); | ||
1795 | CHECK_ERROR (f_imap, status); | 1656 | CHECK_ERROR (f_imap, status); |
1796 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); | 1657 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); |
1797 | f_imap->state = IMAP_FETCH; | 1658 | f_imap->state = IMAP_FETCH; |
1798 | 1659 | ||
1799 | } | 1660 | } |
1800 | status = message_operation (f_imap, msg_imap, buffer, buflen, plen); | 1661 | status = fetch_operation (f_imap, msg_imap, buffer, buflen, plen); |
1801 | if (oldbuf) | 1662 | if (oldbuf) |
1802 | oldbuf[0] = buffer[0]; | 1663 | oldbuf[0] = buffer[0]; |
1803 | return status; | 1664 | return status; |
... | @@ -1824,8 +1685,9 @@ imap_get_fd (msg_imap_t msg_imap, int *pfd) | ... | @@ -1824,8 +1685,9 @@ imap_get_fd (msg_imap_t msg_imap, int *pfd) |
1824 | return EINVAL; | 1685 | return EINVAL; |
1825 | } | 1686 | } |
1826 | 1687 | ||
1688 | /* Since so many operations are fetch, we regoup this into one function. */ | ||
1827 | static int | 1689 | static int |
1828 | message_operation (f_imap_t f_imap, msg_imap_t msg_imap, char *buffer, | 1690 | fetch_operation (f_imap_t f_imap, msg_imap_t msg_imap, char *buffer, |
1829 | size_t buflen, size_t *plen) | 1691 | size_t buflen, size_t *plen) |
1830 | { | 1692 | { |
1831 | int status = 0; | 1693 | int status = 0; |
... | @@ -1835,7 +1697,6 @@ message_operation (f_imap_t f_imap, msg_imap_t msg_imap, char *buffer, | ... | @@ -1835,7 +1697,6 @@ message_operation (f_imap_t f_imap, msg_imap_t msg_imap, char *buffer, |
1835 | case IMAP_FETCH: | 1697 | case IMAP_FETCH: |
1836 | status = imap_send (f_imap); | 1698 | status = imap_send (f_imap); |
1837 | CHECK_EAGAIN (f_imap, status); | 1699 | CHECK_EAGAIN (f_imap, status); |
1838 | /* Set the callback, we want the results. */ | ||
1839 | if (f_imap->callback.buffer) | 1700 | if (f_imap->callback.buffer) |
1840 | free (f_imap->callback.buffer); | 1701 | free (f_imap->callback.buffer); |
1841 | f_imap->callback.buffer = NULL; | 1702 | f_imap->callback.buffer = NULL; |
... | @@ -1859,14 +1720,15 @@ message_operation (f_imap_t f_imap, msg_imap_t msg_imap, char *buffer, | ... | @@ -1859,14 +1720,15 @@ message_operation (f_imap_t f_imap, msg_imap_t msg_imap, char *buffer, |
1859 | if (status == 0 && f_imap->isopen == 0 && f_imap->callback.total == 0) | 1720 | if (status == 0 && f_imap->isopen == 0 && f_imap->callback.total == 0) |
1860 | status = EBADF; | 1721 | status = EBADF; |
1861 | 1722 | ||
1862 | /* Clear the callback. */ | ||
1863 | buflen = min (buflen, f_imap->callback.total); | 1723 | buflen = min (buflen, f_imap->callback.total); |
1864 | if (buffer && f_imap->callback.buffer) | 1724 | if (f_imap->callback.buffer) |
1865 | memcpy (buffer, f_imap->callback.buffer, buflen); | 1725 | { |
1726 | if (buffer) | ||
1727 | memcpy (buffer, f_imap->callback.buffer, buflen); | ||
1728 | free (f_imap->callback.buffer); | ||
1729 | } | ||
1866 | if (plen) | 1730 | if (plen) |
1867 | *plen = buflen; | 1731 | *plen = buflen; |
1868 | if (f_imap->callback.buffer) | ||
1869 | free (f_imap->callback.buffer); | ||
1870 | f_imap->callback.buffer = NULL; | 1732 | f_imap->callback.buffer = NULL; |
1871 | f_imap->callback.buflen = 0; | 1733 | f_imap->callback.buflen = 0; |
1872 | f_imap->callback.total = 0; | 1734 | f_imap->callback.total = 0; |
... | @@ -1876,3 +1738,144 @@ message_operation (f_imap_t f_imap, msg_imap_t msg_imap, char *buffer, | ... | @@ -1876,3 +1738,144 @@ message_operation (f_imap_t f_imap, msg_imap_t msg_imap, char *buffer, |
1876 | f_imap->state = IMAP_NO_STATE; | 1738 | f_imap->state = IMAP_NO_STATE; |
1877 | return status; | 1739 | return status; |
1878 | } | 1740 | } |
1741 | |||
1742 | /* Decide whether the message came from the same folder as the mailbox. */ | ||
1743 | static int | ||
1744 | is_same_folder (mailbox_t mailbox, message_t msg) | ||
1745 | { | ||
1746 | mailbox_t mbox = NULL; | ||
1747 | message_get_mailbox (msg, &mbox); | ||
1748 | return (mbox != NULL && mbox->url != NULL | ||
1749 | && url_is_same_scheme (mbox->url, mailbox->url) | ||
1750 | && url_is_same_host (mbox->url, mailbox->url) | ||
1751 | && url_is_same_port (mbox->url, mailbox->url)); | ||
1752 | } | ||
1753 | |||
1754 | /* Convert flag attribute to IMAP String attributes. */ | ||
1755 | static int | ||
1756 | flags_to_string (char **pbuf, int flag) | ||
1757 | { | ||
1758 | char *abuf = *pbuf; | ||
1759 | if (flag & MU_ATTRIBUTE_DELETED) | ||
1760 | { | ||
1761 | char *tmp = realloc (abuf, strlen (abuf) + strlen ("\\Deleted") + 2); | ||
1762 | if (tmp == NULL) | ||
1763 | { | ||
1764 | free (abuf); | ||
1765 | return ENOMEM; | ||
1766 | } | ||
1767 | abuf = tmp; | ||
1768 | if (*abuf) | ||
1769 | strcat (abuf, " "); | ||
1770 | strcat (abuf, "\\Deleted"); | ||
1771 | } | ||
1772 | if ((flag & MU_ATTRIBUTE_SEEN) || (flag & MU_ATTRIBUTE_READ)) | ||
1773 | { | ||
1774 | char *tmp = realloc (abuf, strlen (abuf) + strlen ("\\Seen") + 2); | ||
1775 | if (tmp == NULL) | ||
1776 | { | ||
1777 | free (abuf); | ||
1778 | return ENOMEM; | ||
1779 | } | ||
1780 | abuf = tmp; | ||
1781 | if (*abuf) | ||
1782 | strcat (abuf, " "); | ||
1783 | strcat (abuf, "\\Seen"); | ||
1784 | } | ||
1785 | if (flag & MU_ATTRIBUTE_ANSWERED) | ||
1786 | { | ||
1787 | char *tmp = realloc (abuf, strlen (abuf) + strlen ("\\Answered") + 2); | ||
1788 | if (tmp == NULL) | ||
1789 | { | ||
1790 | free (abuf); | ||
1791 | return ENOMEM; | ||
1792 | } | ||
1793 | abuf = tmp; | ||
1794 | if (*abuf) | ||
1795 | strcat (abuf, " "); | ||
1796 | strcat (abuf, "\\Answered"); | ||
1797 | } | ||
1798 | if (flag & MU_ATTRIBUTE_DRAFT) | ||
1799 | { | ||
1800 | char *tmp = realloc (abuf, strlen (abuf) + strlen ("\\Draft") + 2); | ||
1801 | if (tmp == NULL) | ||
1802 | { | ||
1803 | free (abuf); | ||
1804 | return ENOMEM; | ||
1805 | } | ||
1806 | abuf = tmp; | ||
1807 | if (*abuf) | ||
1808 | strcat (abuf, " "); | ||
1809 | strcat (abuf, "\\Draft"); | ||
1810 | } | ||
1811 | if (flag & MU_ATTRIBUTE_FLAGGED) | ||
1812 | { | ||
1813 | char *tmp = realloc (abuf, strlen (abuf) + strlen ("\\Flagged") + 2); | ||
1814 | if (tmp == NULL) | ||
1815 | { | ||
1816 | free (abuf); | ||
1817 | return ENOMEM; | ||
1818 | } | ||
1819 | abuf = tmp; | ||
1820 | if (*abuf) | ||
1821 | strcat (abuf, " "); | ||
1822 | strcat (abuf, "\\Flagged"); | ||
1823 | } | ||
1824 | *pbuf = abuf; | ||
1825 | return 0; | ||
1826 | } | ||
1827 | |||
1828 | /* Convert a suite of number to IMAP message number. */ | ||
1829 | static int | ||
1830 | delete_to_string (m_imap_t m_imap, char **pset) | ||
1831 | { | ||
1832 | size_t i, prev = 0, is_range = 0; | ||
1833 | char *set = calloc (1, 1); | ||
1834 | |||
1835 | if (set == NULL) | ||
1836 | return ENOMEM; | ||
1837 | |||
1838 | /* Reformat the number for IMAP. */ | ||
1839 | for (i = 0; i < m_imap->imessages_count; ++i) | ||
1840 | { | ||
1841 | if (m_imap->imessages[i]->flags & MU_ATTRIBUTE_DELETED) | ||
1842 | { | ||
1843 | char *tmp; | ||
1844 | char buf[128]; | ||
1845 | size_t cur = m_imap->imessages[i]->num; | ||
1846 | *buf = '\0'; | ||
1847 | /* The first number. */ | ||
1848 | if (prev == 0) | ||
1849 | { | ||
1850 | snprintf (buf, sizeof buf, "%d", cur); | ||
1851 | } | ||
1852 | /* Is it still a sequence? */ | ||
1853 | else if ((prev + 1) == cur) | ||
1854 | { | ||
1855 | is_range = 1; | ||
1856 | continue; | ||
1857 | } | ||
1858 | /* We had a previous seqence. */ | ||
1859 | else if (is_range) | ||
1860 | { | ||
1861 | snprintf (buf, sizeof buf, ":%d,%d", prev, cur); | ||
1862 | is_range = 0; | ||
1863 | } | ||
1864 | else | ||
1865 | { | ||
1866 | snprintf (buf, sizeof buf, ",%d", cur); | ||
1867 | } | ||
1868 | prev = cur; | ||
1869 | tmp = realloc (set, strlen (set) + strlen (buf) + 1); | ||
1870 | if (tmp == NULL) | ||
1871 | { | ||
1872 | free (set); | ||
1873 | return ENOMEM; | ||
1874 | } | ||
1875 | set = tmp; | ||
1876 | strcat (set, buf); | ||
1877 | } | ||
1878 | } /* for () */ | ||
1879 | *pset = set; | ||
1880 | return 0; | ||
1881 | } | ... | ... |
-
Please register or sign in to post a comment