summaryrefslogtreecommitdiffabout
path: root/libetpan/src/low-level/imap
Unidiff
Diffstat (limited to 'libetpan/src/low-level/imap') (more/less context) (ignore whitespace changes)
-rw-r--r--libetpan/src/low-level/imap/TODO4
-rw-r--r--libetpan/src/low-level/imap/mailimap.c2164
-rw-r--r--libetpan/src/low-level/imap/mailimap.h598
-rw-r--r--libetpan/src/low-level/imap/mailimap_helper.c205
-rw-r--r--libetpan/src/low-level/imap/mailimap_helper.h66
-rw-r--r--libetpan/src/low-level/imap/mailimap_keywords.c353
-rw-r--r--libetpan/src/low-level/imap/mailimap_keywords.h107
-rw-r--r--libetpan/src/low-level/imap/mailimap_parser.c9506
-rw-r--r--libetpan/src/low-level/imap/mailimap_parser.h69
-rw-r--r--libetpan/src/low-level/imap/mailimap_print.c1615
-rw-r--r--libetpan/src/low-level/imap/mailimap_print.h54
-rw-r--r--libetpan/src/low-level/imap/mailimap_sender.c2742
-rw-r--r--libetpan/src/low-level/imap/mailimap_sender.h164
-rw-r--r--libetpan/src/low-level/imap/mailimap_socket.c73
-rw-r--r--libetpan/src/low-level/imap/mailimap_socket.h54
-rw-r--r--libetpan/src/low-level/imap/mailimap_ssl.c73
-rw-r--r--libetpan/src/low-level/imap/mailimap_ssl.h54
-rw-r--r--libetpan/src/low-level/imap/mailimap_types.c2961
-rw-r--r--libetpan/src/low-level/imap/mailimap_types.h3274
-rw-r--r--libetpan/src/low-level/imap/mailimap_types_helper.c1269
-rw-r--r--libetpan/src/low-level/imap/mailimap_types_helper.h758
21 files changed, 26163 insertions, 0 deletions
diff --git a/libetpan/src/low-level/imap/TODO b/libetpan/src/low-level/imap/TODO
new file mode 100644
index 0000000..a787a3b
--- a/dev/null
+++ b/libetpan/src/low-level/imap/TODO
@@ -0,0 +1,4 @@
1- literal data send progress
2- implement draft-16 (rfc 2822 things)
3- more efficient parser
4
diff --git a/libetpan/src/low-level/imap/mailimap.c b/libetpan/src/low-level/imap/mailimap.c
new file mode 100644
index 0000000..ef38413
--- a/dev/null
+++ b/libetpan/src/low-level/imap/mailimap.c
@@ -0,0 +1,2164 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailimap.h"
37#include "mailimap_parser.h"
38#include "mailimap_sender.h"
39#include "mail.h"
40
41#include <stdio.h>
42#include <stdlib.h>
43#include <string.h>
44
45#ifdef DEBUG
46#include "mailimap_print.h"
47#endif
48
49/*
50 RFC 2060 : IMAP4rev1
51 draft-crispin-imapv-15
52 RFC 2222 : Simple Authentication and Security Layer
53
542061 IMAP4 Compatibility with IMAP2bis. M. Crispin. December 1996.
55 (Format: TXT=5867 bytes) (Obsoletes RFC1730) (Status: INFORMATIONAL)
56
572062 Internet Message Access Protocol - Obsolete Syntax. M. Crispin.
58 December 1996. (Format: TXT=14222 bytes) (Status: INFORMATIONAL)
59
602086 IMAP4 ACL extension. J. Myers. January 1997. (Format: TXT=13925
61 bytes) (Status: PROPOSED STANDARD)
62
632087 IMAP4 QUOTA extension. J. Myers. January 1997. (Format: TXT=8542
64 bytes) (Status: PROPOSED STANDARD)
65
662088 IMAP4 non-synchronizing literals. J. Myers. January 1997.
67 (Format: TXT=4052 bytes) (Status: PROPOSED STANDARD)
68
692177 IMAP4 IDLE command. B. Leiba. June 1997. (Format: TXT=6770 bytes)
70 (Status: PROPOSED STANDARD)
71
722180 IMAP4 Multi-Accessed Mailbox Practice. M. Gahrns. July 1997.
73 (Format: TXT=24750 bytes) (Status: INFORMATIONAL)
74
752192 IMAP URL Scheme. C. Newman. September 1997. (Format: TXT=31426
76 bytes) (Status: PROPOSED STANDARD)
77
782193 IMAP4 Mailbox Referrals. M. Gahrns. September 1997. (Format:
79 TXT=16248 bytes) (Status: PROPOSED STANDARD)
80
812195 IMAP/POP AUTHorize Extension for Simple Challenge/Response. J.
82 Klensin, R. Catoe, P. Krumviede. September 1997. (Format: TXT=10468
83 bytes) (Obsoletes RFC2095) (Status: PROPOSED STANDARD)
84
852221 IMAP4 Login Referrals. M. Gahrns. October 1997. (Format: TXT=9251
86 bytes) (Status: PROPOSED STANDARD)
87
882342 IMAP4 Namespace. M. Gahrns, C. Newman. May 1998. (Format:
89 TXT=19489 bytes) (Status: PROPOSED STANDARD)
90
912359 IMAP4 UIDPLUS extension. J. Myers. June 1998. (Format: TXT=10862
92 bytes) (Status: PROPOSED STANDARD)
93
942595 Using TLS with IMAP, POP3 and ACAP. C. Newman. June 1999.
95 (Format: TXT=32440 bytes) (Status: PROPOSED STANDARD)
96
972683 IMAP4 Implementation Recommendations. B. Leiba. September 1999.
98 (Format: TXT=56300 bytes) (Status: INFORMATIONAL)
99
1002971 IMAP4 ID extension. T. Showalter. October 2000. (Format:
101 TXT=14670 bytes) (Status: PROPOSED STANDARD)
102
103http://www.ietf.org/ids.by.wg/imapext.html
104*/
105
106static char * read_line(mailimap * session);
107
108static int send_current_tag(mailimap * session);
109
110static int parse_response(mailimap * session,
111 struct mailimap_response ** result);
112
113static int parse_greeting(mailimap * session,
114 struct mailimap_greeting ** result);
115
116
117/* struct mailimap_response_info * */
118
119static void resp_text_store(mailimap * session,
120 struct mailimap_resp_text *
121 resp_text)
122{
123 struct mailimap_resp_text_code * resp_text_code;
124
125 resp_text_code = resp_text->rsp_code;
126
127 if (resp_text_code != NULL) {
128 switch (resp_text_code->rc_type) {
129 case MAILIMAP_RESP_TEXT_CODE_ALERT:
130 if (session->imap_response_info)
131 if (session->imap_response_info->rsp_alert != NULL)
132 free(session->imap_response_info->rsp_alert);
133 session->imap_response_info->rsp_alert = strdup(resp_text->rsp_text);
134 break;
135
136 case MAILIMAP_RESP_TEXT_CODE_BADCHARSET:
137 if (session->imap_response_info) {
138 if (session->imap_response_info->rsp_badcharset != NULL) {
139 clist_foreach(resp_text_code->rc_data.rc_badcharset,
140 (clist_func) mailimap_astring_free, NULL);
141 clist_free(resp_text_code->rc_data.rc_badcharset);
142 }
143 session->imap_response_info->rsp_badcharset =
144 resp_text_code->rc_data.rc_badcharset;
145 resp_text_code->rc_data.rc_badcharset = NULL;
146 }
147 break;
148
149 case MAILIMAP_RESP_TEXT_CODE_CAPABILITY_DATA:
150 if (session->imap_connection_info) {
151 if (session->imap_connection_info->imap_capability != NULL)
152 mailimap_capability_data_free(session->imap_connection_info->imap_capability);
153 session->imap_connection_info->imap_capability =
154 resp_text_code->rc_data.rc_cap_data;
155 /* detach before free */
156 resp_text_code->rc_data.rc_cap_data = NULL;
157 }
158 break;
159
160 case MAILIMAP_RESP_TEXT_CODE_PARSE:
161 if (session->imap_response_info) {
162 if (session->imap_response_info->rsp_parse != NULL)
163 free(session->imap_response_info->rsp_parse);
164 session->imap_response_info->rsp_parse = strdup(resp_text->rsp_text);
165 }
166 break;
167
168 case MAILIMAP_RESP_TEXT_CODE_PERMANENTFLAGS:
169 if (session->imap_selection_info) {
170 if (session->imap_selection_info->sel_perm_flags != NULL) {
171 clist_foreach(session->imap_selection_info->sel_perm_flags,
172 (clist_func) mailimap_flag_perm_free, NULL);
173 clist_free(session->imap_selection_info->sel_perm_flags);
174 }
175 session->imap_selection_info->sel_perm_flags =
176 resp_text_code->rc_data.rc_perm_flags;
177 /* detach before free */
178 resp_text_code->rc_data.rc_perm_flags = NULL;
179 }
180 break;
181
182 case MAILIMAP_RESP_TEXT_CODE_READ_ONLY:
183 if (session->imap_selection_info)
184 session->imap_selection_info->sel_perm = MAILIMAP_MAILBOX_READONLY;
185 break;
186
187 case MAILIMAP_RESP_TEXT_CODE_READ_WRITE:
188 if (session->imap_selection_info)
189 session->imap_selection_info->sel_perm = MAILIMAP_MAILBOX_READWRITE;
190 break;
191
192 case MAILIMAP_RESP_TEXT_CODE_TRY_CREATE:
193 if (session->imap_response_info)
194 session->imap_response_info->rsp_trycreate = TRUE;
195 break;
196
197 case MAILIMAP_RESP_TEXT_CODE_UIDNEXT:
198 if (session->imap_selection_info)
199 session->imap_selection_info->sel_uidnext =
200 resp_text_code->rc_data.rc_uidnext;
201 break;
202
203 case MAILIMAP_RESP_TEXT_CODE_UIDVALIDITY:
204 if (session->imap_selection_info)
205 session->imap_selection_info->sel_uidvalidity =
206 resp_text_code->rc_data.rc_uidvalidity;
207 break;
208
209 case MAILIMAP_RESP_TEXT_CODE_UNSEEN:
210 if (session->imap_selection_info)
211 session->imap_selection_info->sel_first_unseen =
212 resp_text_code->rc_data.rc_first_unseen;
213 break;
214 }
215 }
216}
217
218static void resp_cond_state_store(mailimap * session,
219 struct mailimap_resp_cond_state * resp_cond_state)
220{
221 resp_text_store(session, resp_cond_state->rsp_text);
222}
223
224static void mailbox_data_store(mailimap * session,
225 struct mailimap_mailbox_data * mb_data)
226{
227 int r;
228
229 switch (mb_data->mbd_type) {
230 case MAILIMAP_MAILBOX_DATA_FLAGS:
231 if (session->imap_selection_info) {
232 if (session->imap_selection_info->sel_flags != NULL)
233 mailimap_flag_list_free(session->imap_selection_info->sel_flags);
234 session->imap_selection_info->sel_flags = mb_data->mbd_data.mbd_flags;
235 mb_data->mbd_data.mbd_flags = NULL;
236 }
237 break;
238
239 case MAILIMAP_MAILBOX_DATA_LIST:
240 if (session->imap_response_info) {
241 r = clist_append(session->imap_response_info->rsp_mailbox_list,
242 mb_data->mbd_data.mbd_list);
243 if (r == 0)
244 mb_data->mbd_data.mbd_list = NULL;
245 else {
246 /* TODO must handle error case */
247 }
248 }
249 break;
250
251 case MAILIMAP_MAILBOX_DATA_LSUB:
252 if (session->imap_response_info) {
253 r = clist_append(session->imap_response_info->rsp_mailbox_lsub,
254 mb_data->mbd_data.mbd_lsub);
255 if (r == 0)
256 mb_data->mbd_data.mbd_lsub = NULL;
257 else {
258 /* TODO must handle error case */
259 }
260 }
261 break;
262
263 case MAILIMAP_MAILBOX_DATA_SEARCH:
264 if (session->imap_response_info) {
265 if (session->imap_response_info->rsp_search_result != NULL) {
266 if (mb_data->mbd_data.mbd_search != NULL) {
267 clist_concat(session->imap_response_info->rsp_search_result,
268 mb_data->mbd_data.mbd_search);
269 clist_free(mb_data->mbd_data.mbd_search);
270 mb_data->mbd_data.mbd_search = NULL;
271 }
272 }
273 else {
274 if (mb_data->mbd_data.mbd_search != NULL) {
275 session->imap_response_info->rsp_search_result =
276 mb_data->mbd_data.mbd_search;
277 mb_data->mbd_data.mbd_search = NULL;
278 }
279 }
280 }
281 break;
282
283 case MAILIMAP_MAILBOX_DATA_STATUS:
284 if (session->imap_response_info) {
285 if (session->imap_response_info->rsp_status != NULL)
286 mailimap_mailbox_data_status_free(session->imap_response_info->rsp_status);
287 session->imap_response_info->rsp_status = mb_data->mbd_data.mbd_status;
288#if 0
289 if (session->imap_selection_info != NULL) {
290 clistiter * cur;
291
292 for(cur = clist_begin(mb_data->status->status_info_list)
293 ; cur != NULL ; cur = clist_next(cur)) {
294 struct mailimap_status_info * info;
295
296 info = clist_content(cur);
297 switch (info->att) {
298 case MAILIMAP_STATUS_ATT_MESSAGES:
299 session->imap_selection_info->exists = info->value;
300 break;
301 case MAILIMAP_STATUS_ATT_RECENT:
302 session->imap_selection_info->recent = info->value;
303 break;
304 case MAILIMAP_STATUS_ATT_UIDNEXT:
305 session->imap_selection_info->uidnext = info->value;
306 break;
307 case MAILIMAP_STATUS_ATT_UIDVALIDITY:
308 session->imap_selection_info->uidvalidity = info->value;
309 break;
310 case MAILIMAP_STATUS_ATT_UNSEEN:
311 session->imap_selection_info->unseen = info->value;
312 break;
313 }
314 }
315 }
316#endif
317#if 0
318 mailimap_mailbox_data_status_free(mb_data->status);
319#endif
320 mb_data->mbd_data.mbd_status = NULL;
321 }
322 break;
323
324 case MAILIMAP_MAILBOX_DATA_EXISTS:
325 if (session->imap_selection_info)
326 session->imap_selection_info->sel_exists = mb_data->mbd_data.mbd_exists;
327 break;
328
329 case MAILIMAP_MAILBOX_DATA_RECENT:
330 if (session->imap_selection_info)
331 session->imap_selection_info->sel_recent =
332 mb_data->mbd_data.mbd_recent;
333 break;
334 }
335}
336
337static void
338message_data_store(mailimap * session,
339 struct mailimap_message_data * msg_data)
340{
341 uint32_t * expunged;
342 int r;
343
344 switch (msg_data->mdt_type) {
345 case MAILIMAP_MESSAGE_DATA_EXPUNGE:
346 if (session->imap_response_info) {
347 expunged = mailimap_number_alloc_new(msg_data->mdt_number);
348 if (expunged != NULL) {
349 r = clist_append(session->imap_response_info->rsp_expunged, expunged);
350 if (r == 0) {
351 /* do nothing */
352 }
353 else {
354 /* TODO : must handle error case */
355 mailimap_number_alloc_free(expunged);
356 }
357 if (session->imap_selection_info != NULL)
358 session->imap_selection_info->sel_exists --;
359 }
360 }
361 break;
362
363 case MAILIMAP_MESSAGE_DATA_FETCH:
364 r = clist_append(session->imap_response_info->rsp_fetch_list,
365 msg_data->mdt_msg_att);
366 if (r == 0) {
367 msg_data->mdt_msg_att->att_number = msg_data->mdt_number;
368 msg_data->mdt_msg_att = NULL;
369 }
370 else {
371 /* TODO : must handle error case */
372 }
373 break;
374 }
375}
376
377static void
378cont_req_or_resp_data_store(mailimap * session,
379 struct mailimap_cont_req_or_resp_data * cont_req_or_resp_data)
380{
381 if (cont_req_or_resp_data->rsp_type == MAILIMAP_RESP_RESP_DATA) {
382 struct mailimap_response_data * resp_data;
383
384 resp_data = cont_req_or_resp_data->rsp_data.rsp_resp_data;
385
386 switch (resp_data->rsp_type) {
387 case MAILIMAP_RESP_DATA_TYPE_COND_STATE:
388 resp_cond_state_store(session, resp_data->rsp_data.rsp_cond_state);
389 break;
390 case MAILIMAP_RESP_DATA_TYPE_MAILBOX_DATA:
391 mailbox_data_store(session, resp_data->rsp_data.rsp_mailbox_data);
392 break;
393 case MAILIMAP_RESP_DATA_TYPE_MESSAGE_DATA:
394 message_data_store(session, resp_data->rsp_data.rsp_message_data);
395 break;
396 case MAILIMAP_RESP_DATA_TYPE_CAPABILITY_DATA:
397 if (session->imap_connection_info) {
398 if (session->imap_connection_info->imap_capability != NULL)
399 mailimap_capability_data_free(session->imap_connection_info->imap_capability);
400 session->imap_connection_info->imap_capability = resp_data->rsp_data.rsp_capability_data;
401 resp_data->rsp_data.rsp_capability_data = NULL;
402 }
403 break;
404 }
405 }
406}
407
408static void response_tagged_store(mailimap * session,
409 struct mailimap_response_tagged * tagged)
410{
411 resp_cond_state_store(session, tagged->rsp_cond_state);
412}
413
414static void resp_cond_bye_store(mailimap * session,
415 struct mailimap_resp_cond_bye * resp_cond_bye)
416{
417 resp_text_store(session, resp_cond_bye->rsp_text);
418}
419
420static void response_fatal_store(mailimap * session,
421 struct mailimap_response_fatal * fatal)
422{
423 resp_cond_bye_store(session, fatal->rsp_bye);
424}
425
426static void response_done_store(mailimap * session,
427 struct mailimap_response_done * resp_done)
428{
429 switch(resp_done->rsp_type) {
430 case MAILIMAP_RESP_DONE_TYPE_TAGGED:
431 response_tagged_store(session, resp_done->rsp_data.rsp_tagged);
432 break;
433 case MAILIMAP_RESP_DONE_TYPE_FATAL:
434 response_fatal_store(session, resp_done->rsp_data.rsp_fatal);
435 break;
436 }
437}
438
439static void
440response_store(mailimap * session,
441 struct mailimap_response * response)
442{
443 clistiter * cur;
444
445 if (session->imap_response_info) {
446 mailimap_response_info_free(session->imap_response_info);
447 session->imap_response_info = NULL;
448 }
449
450 session->imap_response_info = mailimap_response_info_new();
451 if (session->imap_response_info == NULL) {
452 /* ignored error */
453 return;
454 }
455
456 if (response->rsp_cont_req_or_resp_data_list != NULL) {
457 for(cur = clist_begin(response->rsp_cont_req_or_resp_data_list) ;
458 cur != NULL ; cur = clist_next(cur)) {
459 struct mailimap_cont_req_or_resp_data * cont_req_or_resp_data;
460
461 cont_req_or_resp_data = clist_content(cur);
462
463 cont_req_or_resp_data_store(session, cont_req_or_resp_data);
464 }
465 }
466
467 response_done_store(session, response->rsp_resp_done);
468}
469
470static void resp_cond_auth_store(mailimap * session,
471 struct mailimap_resp_cond_auth * cond_auth)
472{
473 resp_text_store(session, cond_auth->rsp_text);
474}
475
476static void greeting_store(mailimap * session,
477 struct mailimap_greeting * greeting)
478{
479 switch (greeting->gr_type) {
480 case MAILIMAP_GREETING_RESP_COND_AUTH:
481 resp_cond_auth_store(session, greeting->gr_data.gr_auth);
482 break;
483
484 case MAILIMAP_GREETING_RESP_COND_BYE:
485 resp_cond_bye_store(session, greeting->gr_data.gr_bye);
486 break;
487 }
488}
489
490int mailimap_connect(mailimap * session, mailstream * s)
491{
492 struct mailimap_greeting * greeting;
493 int r;
494 int auth_type;
495 struct mailimap_connection_info * connection_info;
496
497 if (session->imap_state != MAILIMAP_STATE_DISCONNECTED)
498 return MAILIMAP_ERROR_BAD_STATE;
499
500 session->imap_stream = s;
501
502 if (session->imap_connection_info)
503 mailimap_connection_info_free(session->imap_connection_info);
504 connection_info = mailimap_connection_info_new();
505 if (connection_info != NULL)
506 session->imap_connection_info = connection_info;
507
508 if (read_line(session) == NULL) {
509 return MAILIMAP_ERROR_STREAM;
510 }
511
512 r = parse_greeting(session, &greeting);
513 if (r != MAILIMAP_NO_ERROR) {
514 return r;
515 }
516
517 auth_type = greeting->gr_data.gr_auth->rsp_type;
518
519 mailimap_greeting_free(greeting);
520
521 switch (auth_type) {
522 case MAILIMAP_RESP_COND_AUTH_PREAUTH:
523 session->imap_state = MAILIMAP_STATE_AUTHENTICATED;
524 return MAILIMAP_NO_ERROR_AUTHENTICATED;
525 default:
526 session->imap_state = MAILIMAP_STATE_NON_AUTHENTICATED;
527 return MAILIMAP_NO_ERROR_NON_AUTHENTICATED;
528 }
529}
530
531
532
533
534
535
536
537
538/* ********************************************************************** */
539
540
541
542int mailimap_append(mailimap * session, const char * mailbox,
543 struct mailimap_flag_list * flag_list,
544 struct mailimap_date_time * date_time,
545 const char * literal, size_t literal_size)
546{
547 struct mailimap_response * response;
548 int r;
549 int error_code;
550 struct mailimap_continue_req * cont_req;
551 size_t index;
552 size_t fixed_literal_size;
553
554 if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) &&
555 (session->imap_state != MAILIMAP_STATE_SELECTED))
556 return MAILIMAP_ERROR_BAD_STATE;
557
558 r = send_current_tag(session);
559 if (r != MAILIMAP_NO_ERROR)
560 return r;
561
562 fixed_literal_size = mailstream_get_data_crlf_size(literal, literal_size);
563
564 r = mailimap_append_send(session->imap_stream, mailbox, flag_list, date_time,
565 fixed_literal_size);
566 if (r != MAILIMAP_NO_ERROR)
567 return r;
568
569 if (mailstream_flush(session->imap_stream) == -1)
570 return MAILIMAP_ERROR_STREAM;
571
572 if (read_line(session) == NULL)
573 return MAILIMAP_ERROR_STREAM;
574
575 index = 0;
576
577 r = mailimap_continue_req_parse(session->imap_stream,
578 session->imap_stream_buffer,
579 &index, &cont_req,
580 session->imap_progr_rate, session->imap_progr_fun);
581 if (r == MAILIMAP_NO_ERROR)
582 mailimap_continue_req_free(cont_req);
583
584 if (r == MAILIMAP_ERROR_PARSE) {
585 r = parse_response(session, &response);
586 if (r != MAILIMAP_NO_ERROR)
587 return r;
588 mailimap_response_free(response);
589
590 return MAILIMAP_ERROR_APPEND;
591 }
592
593 r = mailimap_literal_data_send(session->imap_stream, literal, literal_size,
594 session->imap_progr_rate, session->imap_progr_fun);
595 if (r != MAILIMAP_NO_ERROR)
596 return r;
597
598 r = mailimap_crlf_send(session->imap_stream);
599 if (r != MAILIMAP_NO_ERROR)
600 return r;
601
602 if (mailstream_flush(session->imap_stream) == -1)
603 return MAILIMAP_ERROR_STREAM;
604
605 if (read_line(session) == NULL)
606 return MAILIMAP_ERROR_STREAM;
607
608 r = parse_response(session, &response);
609 if (r != MAILIMAP_NO_ERROR)
610 return r;
611
612 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
613
614 mailimap_response_free(response);
615
616 switch (error_code) {
617 case MAILIMAP_RESP_COND_STATE_OK:
618 return MAILIMAP_NO_ERROR;
619
620 default:
621 return MAILIMAP_ERROR_APPEND;
622 }
623}
624
625/*
626gboolean mailimap_authenticate(mailimap * session,
627 gchar * auth_type)
628{
629}
630
631gboolean mailimap_authenticate_resp_send(mailimap * session,
632 gchar * base64)
633{
634}
635*/
636
637int mailimap_noop(mailimap * session)
638{
639 struct mailimap_response * response;
640 int r;
641 int error_code;
642
643 r = send_current_tag(session);
644 if (r != MAILIMAP_NO_ERROR)
645 return r;
646
647 r = mailimap_noop_send(session->imap_stream);
648 if (r != MAILIMAP_NO_ERROR)
649 return r;
650
651 r = mailimap_crlf_send(session->imap_stream);
652 if (r != MAILIMAP_NO_ERROR)
653 return r;
654
655 if (mailstream_flush(session->imap_stream) == -1)
656 return MAILIMAP_ERROR_STREAM;
657
658 if (read_line(session) == NULL)
659 return MAILIMAP_ERROR_STREAM;
660
661 r = parse_response(session, &response);
662 if (r != MAILIMAP_NO_ERROR)
663 return r;
664
665 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
666
667 mailimap_response_free(response);
668
669 switch (error_code) {
670 case MAILIMAP_RESP_COND_STATE_OK:
671 return MAILIMAP_NO_ERROR;
672
673 default:
674 return MAILIMAP_ERROR_NOOP;
675 }
676}
677
678int mailimap_logout(mailimap * session)
679{
680 struct mailimap_response * response;
681 int r;
682 int error_code;
683 int res;
684
685 r = send_current_tag(session);
686 if (r != MAILIMAP_NO_ERROR) {
687 res = r;
688 goto close;
689 }
690
691 r = mailimap_logout_send(session->imap_stream);
692 if (r != MAILIMAP_NO_ERROR) {
693 res = r;
694 goto close;
695 }
696
697 r = mailimap_crlf_send(session->imap_stream);
698 if (r != MAILIMAP_NO_ERROR) {
699 res = r;
700 goto close;
701 }
702
703 if (mailstream_flush(session->imap_stream) == -1) {
704 res = MAILIMAP_ERROR_STREAM;
705 goto close;
706 }
707
708 if (read_line(session) == NULL) {
709 res = MAILIMAP_ERROR_STREAM;
710 goto close;
711 }
712
713 r = parse_response(session, &response);
714 if (r != MAILIMAP_NO_ERROR) {
715 res = r;
716 goto close;
717 }
718
719 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
720
721 mailimap_response_free(response);
722
723 switch (error_code) {
724 case MAILIMAP_RESP_COND_STATE_OK:
725 if (session->imap_connection_info) {
726 mailimap_connection_info_free(session->imap_connection_info);
727 session->imap_connection_info = NULL;
728 }
729 res = MAILIMAP_NO_ERROR;
730 goto close;
731
732 default:
733 res = MAILIMAP_ERROR_LOGOUT;
734 goto close;
735 }
736
737 close:
738 mailstream_close(session->imap_stream);
739 session->imap_stream = NULL;
740 session->imap_state = MAILIMAP_STATE_DISCONNECTED;
741 return res;
742}
743
744/* send the results back to the caller */
745/* duplicate the result */
746
747static struct mailimap_capability *
748mailimap_capability_dup(struct mailimap_capability * orig_cap)
749{
750 struct mailimap_capability * cap;
751 char * auth_type;
752 char * name;
753
754 name = NULL;
755 auth_type = NULL;
756 switch (orig_cap->cap_type) {
757 case MAILIMAP_CAPABILITY_NAME:
758 name = strdup(orig_cap->cap_data.cap_name);
759 if (name == NULL)
760 goto err;
761 break;
762 case MAILIMAP_CAPABILITY_AUTH_TYPE:
763 auth_type = strdup(orig_cap->cap_data.cap_auth_type);
764 if (auth_type == NULL)
765 goto err;
766 break;
767 }
768
769 cap = mailimap_capability_new(orig_cap->cap_type, auth_type, name);
770 if (cap == NULL)
771 goto free;
772
773 return cap;
774
775 free:
776 if (name != NULL)
777 free(name);
778 if (auth_type != NULL)
779 free(auth_type);
780 err:
781 return NULL;
782}
783
784static struct mailimap_capability_data *
785mailimap_capability_data_dup(struct mailimap_capability_data * orig_cap_data)
786{
787 struct mailimap_capability_data * cap_data;
788 struct mailimap_capability * cap_dup;
789 clist * list;
790 clistiter * cur;
791 int r;
792
793 list = clist_new();
794 if (list == NULL)
795 goto err;
796
797 for(cur = clist_begin(orig_cap_data->cap_list) ;
798 cur != NULL ; cur = clist_next(cur)) {
799 struct mailimap_capability * cap;
800
801 cap = clist_content(cur);
802
803 cap_dup = mailimap_capability_dup(cap);
804 if (cap_dup == NULL)
805 goto list;
806
807 r = clist_append(list, cap_dup);
808 if (r < 0) {
809 mailimap_capability_free(cap_dup);
810 goto list;
811 }
812 }
813
814 cap_data = mailimap_capability_data_new(list);
815 if (cap_data == NULL)
816 goto list;
817
818 return cap_data;
819
820list:
821 clist_foreach(list, (clist_func) mailimap_capability_free, NULL);
822 clist_free(list);
823err:
824 return NULL;
825}
826
827int mailimap_capability(mailimap * session,
828 struct mailimap_capability_data ** result)
829{
830 struct mailimap_response * response;
831 int r;
832 int error_code;
833 struct mailimap_capability_data * cap_data;
834
835 r = send_current_tag(session);
836 if (r != MAILIMAP_NO_ERROR)
837 return r;
838
839 r = mailimap_capability_send(session->imap_stream);
840 if (r != MAILIMAP_NO_ERROR)
841 return r;
842
843 r = mailimap_crlf_send(session->imap_stream);
844 if (r != MAILIMAP_NO_ERROR)
845 return r;
846
847 if (mailstream_flush(session->imap_stream) == -1)
848 return MAILIMAP_ERROR_STREAM;
849
850 if (read_line(session) == NULL)
851 return MAILIMAP_ERROR_STREAM;
852
853 r = parse_response(session, &response);
854 if (r != MAILIMAP_NO_ERROR)
855 return r;
856
857 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
858
859 mailimap_response_free(response);
860
861 switch (error_code) {
862 case MAILIMAP_RESP_COND_STATE_OK:
863 cap_data =
864 mailimap_capability_data_dup(session->imap_connection_info->imap_capability);
865 if (cap_data == NULL)
866 return MAILIMAP_ERROR_MEMORY;
867
868 * result = cap_data;
869
870 return MAILIMAP_NO_ERROR;
871
872 default:
873 return MAILIMAP_ERROR_CAPABILITY;
874 }
875}
876
877int mailimap_check(mailimap * session)
878{
879 struct mailimap_response * response;
880 int r;
881 int error_code;
882
883 if (session->imap_state != MAILIMAP_STATE_SELECTED)
884 return MAILIMAP_ERROR_BAD_STATE;
885
886 r = send_current_tag(session);
887 if (r != MAILIMAP_NO_ERROR)
888 return r;
889
890 r = mailimap_check_send(session->imap_stream);
891 if (r != MAILIMAP_NO_ERROR)
892 return r;
893
894 r = mailimap_crlf_send(session->imap_stream);
895 if (r != MAILIMAP_NO_ERROR)
896 return r;
897
898 if (mailstream_flush(session->imap_stream) == -1)
899 return MAILIMAP_ERROR_STREAM;
900
901 if (read_line(session) == NULL)
902 return MAILIMAP_ERROR_STREAM;
903
904 r = parse_response(session, &response);
905 if (r != MAILIMAP_NO_ERROR)
906 return r;
907
908 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
909
910 mailimap_response_free(response);
911
912 switch (error_code) {
913 case MAILIMAP_RESP_COND_STATE_OK:
914 return MAILIMAP_NO_ERROR;
915
916 default:
917 return MAILIMAP_ERROR_CHECK;
918 }
919}
920
921int mailimap_close(mailimap * session)
922{
923 struct mailimap_response * response;
924 int r;
925 int error_code;
926
927 if (session->imap_state != MAILIMAP_STATE_SELECTED)
928 return MAILIMAP_ERROR_BAD_STATE;
929
930 r = send_current_tag(session);
931 if (r != MAILIMAP_NO_ERROR)
932 return r;
933
934 r = mailimap_close_send(session->imap_stream);
935 if (r != MAILIMAP_NO_ERROR)
936 return r;
937
938 r = mailimap_crlf_send(session->imap_stream);
939 if (r != MAILIMAP_NO_ERROR)
940 return r;
941
942 if (mailstream_flush(session->imap_stream) == -1)
943 return MAILIMAP_ERROR_STREAM;
944
945 if (read_line(session) == NULL)
946 return MAILIMAP_ERROR_STREAM;
947
948 r = parse_response(session, &response);
949 if (r != MAILIMAP_NO_ERROR)
950 return r;
951
952 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
953
954 mailimap_response_free(response);
955
956 switch (error_code) {
957 case MAILIMAP_RESP_COND_STATE_OK:
958 /* leave selected state */
959 mailimap_selection_info_free(session->imap_selection_info);
960 session->imap_selection_info = NULL;
961
962 session->imap_state = MAILIMAP_STATE_AUTHENTICATED;
963 return MAILIMAP_NO_ERROR;
964
965 default:
966 return MAILIMAP_ERROR_CLOSE;
967 }
968}
969
970int mailimap_expunge(mailimap * session)
971{
972 struct mailimap_response * response;
973 int r;
974 int error_code;
975
976 if (session->imap_state != MAILIMAP_STATE_SELECTED)
977 return MAILIMAP_ERROR_BAD_STATE;
978
979 r = send_current_tag(session);
980 if (r != MAILIMAP_NO_ERROR)
981 return r;
982
983 r = mailimap_expunge_send(session->imap_stream);
984 if (r != MAILIMAP_NO_ERROR)
985 return r;
986
987 r = mailimap_crlf_send(session->imap_stream);
988 if (r != MAILIMAP_NO_ERROR)
989 return r;
990
991 if (mailstream_flush(session->imap_stream) == -1)
992 return MAILIMAP_ERROR_STREAM;
993
994 if (read_line(session) == NULL)
995 return MAILIMAP_ERROR_STREAM;
996
997 r = parse_response(session, &response);
998 if (r != MAILIMAP_NO_ERROR)
999 return r;
1000
1001 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1002
1003 mailimap_response_free(response);
1004
1005 switch (error_code) {
1006 case MAILIMAP_RESP_COND_STATE_OK:
1007 return MAILIMAP_NO_ERROR;
1008
1009 default:
1010 return MAILIMAP_ERROR_EXPUNGE;
1011 }
1012}
1013
1014int mailimap_copy(mailimap * session, struct mailimap_set * set,
1015 const char * mb)
1016{
1017 struct mailimap_response * response;
1018 int r;
1019 int error_code;
1020
1021 if (session->imap_state != MAILIMAP_STATE_SELECTED)
1022 return MAILIMAP_ERROR_BAD_STATE;
1023
1024 r = send_current_tag(session);
1025 if (r != MAILIMAP_NO_ERROR)
1026 return r;
1027
1028 r = mailimap_copy_send(session->imap_stream, set, mb);
1029 if (r != MAILIMAP_NO_ERROR)
1030 return r;
1031
1032 r = mailimap_crlf_send(session->imap_stream);
1033 if (r != MAILIMAP_NO_ERROR)
1034 return r;
1035
1036 if (mailstream_flush(session->imap_stream) == -1)
1037 return MAILIMAP_ERROR_STREAM;
1038
1039 if (read_line(session) == NULL)
1040 return MAILIMAP_ERROR_STREAM;
1041
1042 r = parse_response(session, &response);
1043 if (r != MAILIMAP_NO_ERROR)
1044 return r;
1045
1046 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1047
1048 mailimap_response_free(response);
1049
1050 switch (error_code) {
1051 case MAILIMAP_RESP_COND_STATE_OK:
1052 return MAILIMAP_NO_ERROR;
1053
1054 default:
1055 return MAILIMAP_ERROR_COPY;
1056 }
1057}
1058
1059int mailimap_uid_copy(mailimap * session, struct mailimap_set * set,
1060 const char * mb)
1061{
1062 struct mailimap_response * response;
1063 int r;
1064 int error_code;
1065
1066 if (session->imap_state != MAILIMAP_STATE_SELECTED)
1067 return MAILIMAP_ERROR_BAD_STATE;
1068
1069 r = send_current_tag(session);
1070 if (r != MAILIMAP_NO_ERROR)
1071 return r;
1072
1073 r = mailimap_uid_copy_send(session->imap_stream, set, mb);
1074 if (r != MAILIMAP_NO_ERROR)
1075 return r;
1076
1077 r = mailimap_crlf_send(session->imap_stream);
1078 if (r != MAILIMAP_NO_ERROR)
1079 return r;
1080
1081 if (mailstream_flush(session->imap_stream) == -1)
1082 return MAILIMAP_ERROR_STREAM;
1083
1084 if (read_line(session) == NULL)
1085 return MAILIMAP_ERROR_STREAM;
1086
1087 r = parse_response(session, &response);
1088 if (r != MAILIMAP_NO_ERROR)
1089 return r;
1090
1091 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1092
1093 mailimap_response_free(response);
1094
1095 switch (error_code) {
1096 case MAILIMAP_RESP_COND_STATE_OK:
1097 return MAILIMAP_NO_ERROR;
1098
1099 default:
1100 return MAILIMAP_ERROR_UID_COPY;
1101 }
1102}
1103
1104int mailimap_create(mailimap * session, const char * mb)
1105{
1106 struct mailimap_response * response;
1107 int r;
1108 int error_code;
1109
1110 if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) &&
1111 (session->imap_state != MAILIMAP_STATE_SELECTED))
1112 return MAILIMAP_ERROR_BAD_STATE;
1113
1114 r = send_current_tag(session);
1115 if (r != MAILIMAP_NO_ERROR)
1116 return r;
1117
1118 r = mailimap_create_send(session->imap_stream, mb);
1119 if (r != MAILIMAP_NO_ERROR)
1120 return r;
1121
1122 r = mailimap_crlf_send(session->imap_stream);
1123 if (r != MAILIMAP_NO_ERROR)
1124 return r;
1125
1126 if (mailstream_flush(session->imap_stream) == -1)
1127 return MAILIMAP_ERROR_STREAM;
1128
1129 if (read_line(session) == NULL)
1130 return MAILIMAP_ERROR_STREAM;
1131
1132 r = parse_response(session, &response);
1133 if (r != MAILIMAP_NO_ERROR)
1134 return r;
1135
1136 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1137
1138 mailimap_response_free(response);
1139
1140 switch (error_code) {
1141 case MAILIMAP_RESP_COND_STATE_OK:
1142 return MAILIMAP_NO_ERROR;
1143
1144 default:
1145 return MAILIMAP_ERROR_CREATE;
1146 }
1147}
1148
1149
1150int mailimap_delete(mailimap * session, const char * mb)
1151{
1152 struct mailimap_response * response;
1153 int r;
1154 int error_code;
1155
1156 if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) &&
1157 (session->imap_state != MAILIMAP_STATE_SELECTED))
1158 return MAILIMAP_ERROR_BAD_STATE;
1159
1160 r = send_current_tag(session);
1161 if (r != MAILIMAP_NO_ERROR)
1162 return r;
1163
1164 r = mailimap_delete_send(session->imap_stream, mb);
1165 if (r != MAILIMAP_NO_ERROR)
1166 return r;
1167
1168 r = mailimap_crlf_send(session->imap_stream);
1169 if (r != MAILIMAP_NO_ERROR)
1170 return r;
1171
1172 if (mailstream_flush(session->imap_stream) == -1)
1173 return MAILIMAP_ERROR_STREAM;
1174
1175 if (read_line(session) == NULL)
1176 return MAILIMAP_ERROR_STREAM;
1177
1178 r = parse_response(session, &response);
1179 if (r != MAILIMAP_NO_ERROR)
1180 return r;
1181
1182 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1183
1184 mailimap_response_free(response);
1185
1186 switch (error_code) {
1187 case MAILIMAP_RESP_COND_STATE_OK:
1188 return MAILIMAP_NO_ERROR;
1189
1190 default:
1191 return MAILIMAP_ERROR_DELETE;
1192 }
1193}
1194
1195int mailimap_examine(mailimap * session, const char * mb)
1196{
1197 struct mailimap_response * response;
1198 int r;
1199 int error_code;
1200
1201 if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) &&
1202 (session->imap_state != MAILIMAP_STATE_SELECTED))
1203 return MAILIMAP_ERROR_BAD_STATE;
1204
1205 r = send_current_tag(session);
1206 if (r != MAILIMAP_NO_ERROR)
1207 return r;
1208
1209 r = mailimap_examine_send(session->imap_stream, mb);
1210 if (r != MAILIMAP_NO_ERROR)
1211 return r;
1212
1213 r = mailimap_crlf_send(session->imap_stream);
1214 if (r != MAILIMAP_NO_ERROR)
1215 return r;
1216
1217 if (mailstream_flush(session->imap_stream) == -1)
1218 return MAILIMAP_ERROR_STREAM;
1219
1220 if (read_line(session) == NULL)
1221 return MAILIMAP_ERROR_STREAM;
1222
1223 if (session->imap_selection_info != NULL)
1224 mailimap_selection_info_free(session->imap_selection_info);
1225 session->imap_selection_info = mailimap_selection_info_new();
1226
1227 r = parse_response(session, &response);
1228 if (r != MAILIMAP_NO_ERROR)
1229 return r;
1230
1231 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1232
1233 mailimap_response_free(response);
1234
1235 switch (error_code) {
1236 case MAILIMAP_RESP_COND_STATE_OK:
1237 session->imap_state = MAILIMAP_STATE_SELECTED;
1238 return MAILIMAP_NO_ERROR;
1239
1240 default:
1241 mailimap_selection_info_free(session->imap_selection_info);
1242 session->imap_selection_info = NULL;
1243 session->imap_state = MAILIMAP_STATE_AUTHENTICATED;
1244 return MAILIMAP_ERROR_EXAMINE;
1245 }
1246}
1247
1248int
1249mailimap_fetch(mailimap * session, struct mailimap_set * set,
1250 struct mailimap_fetch_type * fetch_type, clist ** result)
1251{
1252 struct mailimap_response * response;
1253 int r;
1254 int error_code;
1255
1256 if (session->imap_state != MAILIMAP_STATE_SELECTED)
1257 return MAILIMAP_ERROR_BAD_STATE;
1258
1259 r = send_current_tag(session);
1260 if (r != MAILIMAP_NO_ERROR)
1261 return r;
1262
1263 r = mailimap_fetch_send(session->imap_stream, set, fetch_type);
1264 if (r != MAILIMAP_NO_ERROR)
1265 return r;
1266
1267 r = mailimap_crlf_send(session->imap_stream);
1268 if (r != MAILIMAP_NO_ERROR)
1269 return r;
1270
1271 if (mailstream_flush(session->imap_stream) == -1)
1272 return MAILIMAP_ERROR_STREAM;
1273
1274 if (read_line(session) == NULL)
1275 return MAILIMAP_ERROR_STREAM;
1276
1277 r = parse_response(session, &response);
1278 if (r != MAILIMAP_NO_ERROR)
1279 return r;
1280
1281 * result = session->imap_response_info->rsp_fetch_list;
1282 session->imap_response_info->rsp_fetch_list = NULL;
1283
1284 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1285
1286 mailimap_response_free(response);
1287
1288 switch (error_code) {
1289 case MAILIMAP_RESP_COND_STATE_OK:
1290 return MAILIMAP_NO_ERROR;
1291
1292 default:
1293 return MAILIMAP_ERROR_FETCH;
1294 }
1295}
1296
1297void mailimap_fetch_list_free(clist * fetch_list)
1298{
1299 clist_foreach(fetch_list, (clist_func) mailimap_msg_att_free, NULL);
1300 clist_free(fetch_list);
1301}
1302
1303int
1304mailimap_uid_fetch(mailimap * session,
1305 struct mailimap_set * set,
1306 struct mailimap_fetch_type * fetch_type, clist ** result)
1307{
1308 struct mailimap_response * response;
1309 int r;
1310 int error_code;
1311
1312 if (session->imap_state != MAILIMAP_STATE_SELECTED)
1313 return MAILIMAP_ERROR_BAD_STATE;
1314
1315 r = send_current_tag(session);
1316 if (r != MAILIMAP_NO_ERROR)
1317 return r;
1318
1319 r = mailimap_uid_fetch_send(session->imap_stream, set, fetch_type);
1320 if (r != MAILIMAP_NO_ERROR)
1321 return r;
1322
1323 r = mailimap_crlf_send(session->imap_stream);
1324 if (r != MAILIMAP_NO_ERROR)
1325 return r;
1326
1327 if (mailstream_flush(session->imap_stream) == -1)
1328 return MAILIMAP_ERROR_STREAM;
1329
1330 if (read_line(session) == NULL)
1331 return MAILIMAP_ERROR_STREAM;
1332
1333 r = parse_response(session, &response);
1334
1335 if (r != MAILIMAP_NO_ERROR)
1336 return r;
1337
1338 * result = session->imap_response_info->rsp_fetch_list;
1339 session->imap_response_info->rsp_fetch_list = NULL;
1340
1341 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1342
1343 mailimap_response_free(response);
1344
1345 switch (error_code) {
1346 case MAILIMAP_RESP_COND_STATE_OK:
1347 return MAILIMAP_NO_ERROR;
1348
1349 default:
1350 return MAILIMAP_ERROR_UID_FETCH;
1351 }
1352}
1353
1354int mailimap_list(mailimap * session, const char * mb,
1355 const char * list_mb, clist ** result)
1356{
1357 struct mailimap_response * response;
1358 int r;
1359 int error_code;
1360
1361 if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) &&
1362 (session->imap_state != MAILIMAP_STATE_SELECTED))
1363 return MAILIMAP_ERROR_BAD_STATE;
1364
1365 r = send_current_tag(session);
1366 if (r != MAILIMAP_NO_ERROR)
1367 return r;
1368
1369 r = mailimap_list_send(session->imap_stream, mb, list_mb);
1370 if (r != MAILIMAP_NO_ERROR)
1371 return r;
1372
1373 r = mailimap_crlf_send(session->imap_stream);
1374 if (r != MAILIMAP_NO_ERROR)
1375 return r;
1376
1377 if (mailstream_flush(session->imap_stream) == -1)
1378 return MAILIMAP_ERROR_STREAM;
1379
1380 if (read_line(session) == NULL)
1381 return MAILIMAP_ERROR_STREAM;
1382
1383 r = parse_response(session, &response);
1384 if (r != MAILIMAP_NO_ERROR)
1385 return r;
1386
1387 * result = session->imap_response_info->rsp_mailbox_list;
1388 session->imap_response_info->rsp_mailbox_list = NULL;
1389
1390 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1391
1392 mailimap_response_free(response);
1393
1394 switch (error_code) {
1395 case MAILIMAP_RESP_COND_STATE_OK:
1396 return MAILIMAP_NO_ERROR;
1397
1398 default:
1399 return MAILIMAP_ERROR_LIST;
1400 }
1401}
1402
1403int mailimap_login(mailimap * session,
1404 const char * userid, const char * password)
1405{
1406 struct mailimap_response * response;
1407 int r;
1408 int error_code;
1409
1410 if (session->imap_state != MAILIMAP_STATE_NON_AUTHENTICATED)
1411 return MAILIMAP_ERROR_BAD_STATE;
1412
1413 r = send_current_tag(session);
1414 if (r != MAILIMAP_NO_ERROR)
1415 return r;
1416
1417 r = mailimap_login_send(session->imap_stream, userid, password);
1418 if (r != MAILIMAP_NO_ERROR)
1419 return r;
1420
1421 r = mailimap_crlf_send(session->imap_stream);
1422 if (r != MAILIMAP_NO_ERROR)
1423 return r;
1424
1425 if (mailstream_flush(session->imap_stream) == -1)
1426 return MAILIMAP_ERROR_STREAM;
1427
1428 if (read_line(session) == NULL)
1429 return MAILIMAP_ERROR_STREAM;
1430
1431 r = parse_response(session, &response);
1432 if (r != MAILIMAP_NO_ERROR)
1433 return r;
1434
1435 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1436
1437 mailimap_response_free(response);
1438
1439 switch (error_code) {
1440 case MAILIMAP_RESP_COND_STATE_OK:
1441 session->imap_state = MAILIMAP_STATE_AUTHENTICATED;
1442 return MAILIMAP_NO_ERROR;
1443
1444 default:
1445 return MAILIMAP_ERROR_LOGIN;
1446 }
1447}
1448
1449int mailimap_lsub(mailimap * session, const char * mb,
1450 const char * list_mb, clist ** result)
1451{
1452 struct mailimap_response * response;
1453 int r;
1454 int error_code;
1455
1456 if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) &&
1457 (session->imap_state != MAILIMAP_STATE_SELECTED))
1458 return MAILIMAP_ERROR_BAD_STATE;
1459
1460 r = send_current_tag(session);
1461 if (r != MAILIMAP_NO_ERROR)
1462 return r;
1463
1464 r = mailimap_lsub_send(session->imap_stream, mb, list_mb);
1465 if (r != MAILIMAP_NO_ERROR)
1466 return r;
1467
1468 r = mailimap_crlf_send(session->imap_stream);
1469 if (r != MAILIMAP_NO_ERROR)
1470 return r;
1471
1472 if (mailstream_flush(session->imap_stream) == -1)
1473 return MAILIMAP_ERROR_STREAM;
1474
1475 if (read_line(session) == NULL)
1476 return MAILIMAP_ERROR_STREAM;
1477
1478 r = parse_response(session, &response);
1479 if (r != MAILIMAP_NO_ERROR)
1480 return r;
1481
1482 * result = session->imap_response_info->rsp_mailbox_lsub;
1483 session->imap_response_info->rsp_mailbox_lsub = NULL;
1484
1485 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1486
1487 mailimap_response_free(response);
1488
1489 switch (error_code) {
1490 case MAILIMAP_RESP_COND_STATE_OK:
1491 return MAILIMAP_NO_ERROR;
1492
1493 default:
1494 return MAILIMAP_ERROR_LSUB;
1495 }
1496}
1497
1498void mailimap_list_result_free(clist * list)
1499{
1500 clist_foreach(list, (clist_func) mailimap_mailbox_list_free, NULL);
1501 clist_free(list);
1502}
1503
1504int mailimap_rename(mailimap * session,
1505 const char * mb, const char * new_name)
1506{
1507 struct mailimap_response * response;
1508 int r;
1509 int error_code;
1510
1511 if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) &&
1512 (session->imap_state != MAILIMAP_STATE_SELECTED))
1513 return MAILIMAP_ERROR_BAD_STATE;
1514
1515 r = send_current_tag(session);
1516 if (r != MAILIMAP_NO_ERROR)
1517 return r;
1518
1519 r = mailimap_rename_send(session->imap_stream, mb, new_name);
1520 if (r != MAILIMAP_NO_ERROR)
1521 return r;
1522
1523 if (!mailimap_crlf_send(session->imap_stream))
1524 if (r != MAILIMAP_NO_ERROR)
1525 return r;
1526
1527 if (mailstream_flush(session->imap_stream) == -1)
1528 return MAILIMAP_ERROR_STREAM;
1529
1530 if (read_line(session) == NULL)
1531 return MAILIMAP_ERROR_STREAM;
1532
1533 r = parse_response(session, &response);
1534 if (r != MAILIMAP_NO_ERROR)
1535 return r;
1536
1537 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1538
1539 mailimap_response_free(response);
1540
1541 switch (error_code) {
1542 case MAILIMAP_RESP_COND_STATE_OK:
1543 return MAILIMAP_NO_ERROR;
1544
1545 default:
1546 return MAILIMAP_ERROR_RENAME;
1547 }
1548}
1549
1550int
1551mailimap_search(mailimap * session, const char * charset,
1552 struct mailimap_search_key * key, clist ** result)
1553{
1554 struct mailimap_response * response;
1555 int r;
1556 int error_code;
1557
1558 if (session->imap_state != MAILIMAP_STATE_SELECTED)
1559 return MAILIMAP_ERROR_BAD_STATE;
1560
1561 r = send_current_tag(session);
1562 if (r != MAILIMAP_NO_ERROR)
1563 return r;
1564
1565 r = mailimap_search_send(session->imap_stream, charset, key);
1566 if (r != MAILIMAP_NO_ERROR)
1567 return r;
1568
1569 r = mailimap_crlf_send(session->imap_stream);
1570 if (r != MAILIMAP_NO_ERROR)
1571 return r;
1572
1573 if (mailstream_flush(session->imap_stream) == -1)
1574 return MAILIMAP_ERROR_STREAM;
1575
1576 if (read_line(session) == NULL)
1577 return MAILIMAP_ERROR_STREAM;
1578
1579 r = parse_response(session, &response);
1580 if (r != MAILIMAP_NO_ERROR)
1581 return r;
1582
1583 * result = session->imap_response_info->rsp_search_result;
1584 session->imap_response_info->rsp_search_result = NULL;
1585
1586 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1587
1588 mailimap_response_free(response);
1589
1590 switch (error_code) {
1591 case MAILIMAP_RESP_COND_STATE_OK:
1592 return MAILIMAP_NO_ERROR;
1593
1594 default:
1595 return MAILIMAP_ERROR_SEARCH;
1596 }
1597}
1598
1599int
1600mailimap_uid_search(mailimap * session, const char * charset,
1601 struct mailimap_search_key * key, clist ** result)
1602{
1603 struct mailimap_response * response;
1604 int r;
1605 int error_code;
1606
1607 if (session->imap_state != MAILIMAP_STATE_SELECTED)
1608 return MAILIMAP_ERROR_BAD_STATE;
1609
1610 r = send_current_tag(session);
1611 if (r != MAILIMAP_NO_ERROR)
1612 return r;
1613
1614 r = mailimap_uid_search_send(session->imap_stream, charset, key);
1615 if (r != MAILIMAP_NO_ERROR)
1616 return r;
1617
1618 r = mailimap_crlf_send(session->imap_stream);
1619 if (r != MAILIMAP_NO_ERROR)
1620 return r;
1621
1622 if (mailstream_flush(session->imap_stream) == -1)
1623 return MAILIMAP_ERROR_STREAM;
1624
1625 if (read_line(session) == NULL)
1626 return MAILIMAP_ERROR_STREAM;
1627
1628 r = parse_response(session, &response);
1629 if (r != MAILIMAP_NO_ERROR)
1630 return r;
1631
1632 * result = session->imap_response_info->rsp_search_result;
1633 session->imap_response_info->rsp_search_result = NULL;
1634
1635 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1636
1637 mailimap_response_free(response);
1638
1639 switch (error_code) {
1640 case MAILIMAP_RESP_COND_STATE_OK:
1641 return MAILIMAP_NO_ERROR;
1642
1643 default:
1644 return MAILIMAP_ERROR_UID_SEARCH;
1645 }
1646}
1647
1648void mailimap_search_result_free(clist * search_result)
1649{
1650 clist_foreach(search_result, (clist_func) free, NULL);
1651 clist_free(search_result);
1652}
1653
1654int
1655mailimap_select(mailimap * session, const char * mb)
1656{
1657 struct mailimap_response * response;
1658 int r;
1659 int error_code;
1660
1661 if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) &&
1662 (session->imap_state != MAILIMAP_STATE_SELECTED))
1663 return MAILIMAP_ERROR_BAD_STATE;
1664
1665 r = send_current_tag(session);
1666 if (r != MAILIMAP_NO_ERROR)
1667 return r;
1668
1669 r = mailimap_select_send(session->imap_stream, mb);
1670 if (r != MAILIMAP_NO_ERROR)
1671 return r;
1672
1673 r = mailimap_crlf_send(session->imap_stream);
1674 if (r != MAILIMAP_NO_ERROR)
1675 return r;
1676
1677 if (mailstream_flush(session->imap_stream) == -1)
1678 return MAILIMAP_ERROR_STREAM;
1679
1680 if (read_line(session) == NULL)
1681 return MAILIMAP_ERROR_STREAM;
1682
1683 if (session->imap_selection_info != NULL)
1684 mailimap_selection_info_free(session->imap_selection_info);
1685 session->imap_selection_info = mailimap_selection_info_new();
1686
1687 r = parse_response(session, &response);
1688 if (r != MAILIMAP_NO_ERROR)
1689 return r;
1690
1691 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1692
1693 mailimap_response_free(response);
1694
1695 switch (error_code) {
1696 case MAILIMAP_RESP_COND_STATE_OK:
1697 session->imap_state = MAILIMAP_STATE_SELECTED;
1698 return MAILIMAP_NO_ERROR;
1699
1700 default:
1701 mailimap_selection_info_free(session->imap_selection_info);
1702 session->imap_selection_info = NULL;
1703 session->imap_state = MAILIMAP_STATE_AUTHENTICATED;
1704 return MAILIMAP_ERROR_SELECT;
1705 }
1706}
1707
1708int
1709mailimap_status(mailimap * session, const char * mb,
1710 struct mailimap_status_att_list * status_att_list,
1711 struct mailimap_mailbox_data_status ** result)
1712{
1713 struct mailimap_response * response;
1714 int r;
1715 int error_code;
1716
1717 if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) &&
1718 (session->imap_state != MAILIMAP_STATE_SELECTED))
1719 return MAILIMAP_ERROR_BAD_STATE;
1720
1721 r = send_current_tag(session);
1722 if (r != MAILIMAP_NO_ERROR)
1723 return r;
1724
1725 r = mailimap_status_send(session->imap_stream, mb, status_att_list);
1726 if (r != MAILIMAP_NO_ERROR)
1727 return r;
1728
1729 r = mailimap_crlf_send(session->imap_stream);
1730 if (r != MAILIMAP_NO_ERROR)
1731 return r;
1732
1733 if (mailstream_flush(session->imap_stream) == -1)
1734 return MAILIMAP_ERROR_STREAM;
1735
1736 if (read_line(session) == NULL)
1737 return MAILIMAP_ERROR_STREAM;
1738
1739 r = parse_response(session, &response);
1740 if (r != MAILIMAP_NO_ERROR)
1741 return r;
1742
1743 * result = session->imap_response_info->rsp_status;
1744 session->imap_response_info->rsp_status = NULL;
1745
1746 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1747
1748 mailimap_response_free(response);
1749
1750 switch (error_code) {
1751 case MAILIMAP_RESP_COND_STATE_OK:
1752 return MAILIMAP_NO_ERROR;
1753
1754 default:
1755 return MAILIMAP_ERROR_STATUS;
1756 }
1757}
1758
1759
1760int
1761mailimap_store(mailimap * session,
1762 struct mailimap_set * set,
1763 struct mailimap_store_att_flags * store_att_flags)
1764{
1765 struct mailimap_response * response;
1766 int r;
1767 int error_code;
1768
1769 if (session->imap_state != MAILIMAP_STATE_SELECTED)
1770 return MAILIMAP_ERROR_BAD_STATE;
1771
1772 r = send_current_tag(session);
1773 if (r != MAILIMAP_NO_ERROR)
1774 return r;
1775
1776 r = mailimap_store_send(session->imap_stream, set, store_att_flags);
1777 if (r != MAILIMAP_NO_ERROR)
1778 return r;
1779
1780 r = mailimap_crlf_send(session->imap_stream);
1781 if (r != MAILIMAP_NO_ERROR)
1782 return r;
1783
1784 if (mailstream_flush(session->imap_stream) == -1)
1785 return MAILIMAP_ERROR_STREAM;
1786
1787 if (read_line(session) == NULL)
1788 return MAILIMAP_ERROR_STREAM;
1789
1790 r = parse_response(session, &response);
1791 if (r != MAILIMAP_NO_ERROR)
1792 return r;
1793
1794 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1795
1796 mailimap_response_free(response);
1797
1798 switch (error_code) {
1799 case MAILIMAP_RESP_COND_STATE_OK:
1800 return MAILIMAP_NO_ERROR;
1801
1802 default:
1803 return MAILIMAP_ERROR_STORE;
1804 }
1805}
1806
1807int
1808mailimap_uid_store(mailimap * session,
1809 struct mailimap_set * set,
1810 struct mailimap_store_att_flags * store_att_flags)
1811{
1812 struct mailimap_response * response;
1813 int r;
1814 int error_code;
1815
1816 if (session->imap_state != MAILIMAP_STATE_SELECTED)
1817 return MAILIMAP_ERROR_BAD_STATE;
1818
1819 r = send_current_tag(session);
1820 if (r != MAILIMAP_NO_ERROR)
1821 return r;
1822
1823 r = mailimap_uid_store_send(session->imap_stream, set, store_att_flags);
1824 if (r != MAILIMAP_NO_ERROR)
1825 return r;
1826
1827 r = mailimap_crlf_send(session->imap_stream);
1828 if (r != MAILIMAP_NO_ERROR)
1829 return r;
1830
1831 if (mailstream_flush(session->imap_stream) == -1)
1832 return MAILIMAP_ERROR_STREAM;
1833
1834 if (read_line(session) == NULL)
1835 return MAILIMAP_ERROR_STREAM;
1836
1837 r = parse_response(session, &response);
1838 if (r != MAILIMAP_NO_ERROR)
1839 return r;
1840
1841 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1842
1843 mailimap_response_free(response);
1844
1845 switch (error_code) {
1846 case MAILIMAP_RESP_COND_STATE_OK:
1847 return MAILIMAP_NO_ERROR;
1848
1849 default:
1850 return MAILIMAP_ERROR_UID_STORE;
1851 }
1852}
1853
1854int mailimap_subscribe(mailimap * session, const char * mb)
1855{
1856 struct mailimap_response * response;
1857 int r;
1858 int error_code;
1859
1860 if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) &&
1861 (session->imap_state != MAILIMAP_STATE_SELECTED))
1862 return MAILIMAP_ERROR_BAD_STATE;
1863
1864 r = send_current_tag(session);
1865 if (r != MAILIMAP_NO_ERROR)
1866 return r;
1867
1868 r = mailimap_subscribe_send(session->imap_stream, mb);
1869 if (r != MAILIMAP_NO_ERROR)
1870 return r;
1871
1872 r = mailimap_crlf_send(session->imap_stream);
1873 if (r != MAILIMAP_NO_ERROR)
1874 return r;
1875
1876 if (mailstream_flush(session->imap_stream) == -1)
1877 return MAILIMAP_ERROR_STREAM;
1878
1879 if (read_line(session) == NULL)
1880 return MAILIMAP_ERROR_STREAM;
1881
1882 r = parse_response(session, &response);
1883 if (r != MAILIMAP_NO_ERROR)
1884 return r;
1885
1886 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1887
1888 mailimap_response_free(response);
1889
1890 switch (error_code) {
1891 case MAILIMAP_RESP_COND_STATE_OK:
1892 return MAILIMAP_NO_ERROR;
1893
1894 default:
1895 return MAILIMAP_ERROR_SUBSCRIBE;
1896 }
1897}
1898
1899int mailimap_unsubscribe(mailimap * session, const char * mb)
1900{
1901 struct mailimap_response * response;
1902 int r;
1903 int error_code;
1904
1905 if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) &&
1906 (session->imap_state != MAILIMAP_STATE_SELECTED))
1907 return MAILIMAP_ERROR_BAD_STATE;
1908
1909 r = send_current_tag(session);
1910 if (r != MAILIMAP_NO_ERROR)
1911 return r;
1912
1913 r = mailimap_unsubscribe_send(session->imap_stream, mb);
1914 if (r != MAILIMAP_NO_ERROR)
1915 return r;
1916
1917 r = mailimap_crlf_send(session->imap_stream);
1918 if (r != MAILIMAP_NO_ERROR)
1919 return r;
1920
1921 if (mailstream_flush(session->imap_stream) == -1)
1922 return MAILIMAP_ERROR_STREAM;
1923
1924 if (read_line(session) == NULL)
1925 return MAILIMAP_ERROR_STREAM;
1926
1927 r = parse_response(session, &response);
1928 if (r != MAILIMAP_NO_ERROR)
1929 return r;
1930
1931 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1932
1933 mailimap_response_free(response);
1934
1935 switch (error_code) {
1936 case MAILIMAP_RESP_COND_STATE_OK:
1937 return MAILIMAP_NO_ERROR;
1938
1939 default:
1940 return MAILIMAP_ERROR_UNSUBSCRIBE;
1941 }
1942}
1943
1944
1945int mailimap_starttls(mailimap * session)
1946{
1947 struct mailimap_response * response;
1948 int r;
1949 int error_code;
1950
1951 r = send_current_tag(session);
1952 if (r != MAILIMAP_NO_ERROR)
1953 return r;
1954
1955 r = mailimap_starttls_send(session->imap_stream);
1956 if (r != MAILIMAP_NO_ERROR)
1957 return r;
1958
1959 r = mailimap_crlf_send(session->imap_stream);
1960 if (r != MAILIMAP_NO_ERROR)
1961 return r;
1962
1963 if (mailstream_flush(session->imap_stream) == -1)
1964 return MAILIMAP_ERROR_STREAM;
1965
1966 if (read_line(session) == NULL)
1967 return MAILIMAP_ERROR_STREAM;
1968
1969 r = parse_response(session, &response);
1970 if (r != MAILIMAP_NO_ERROR)
1971 return r;
1972
1973 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1974
1975 mailimap_response_free(response);
1976
1977 switch (error_code) {
1978 case MAILIMAP_RESP_COND_STATE_OK:
1979 return MAILIMAP_NO_ERROR;
1980
1981 default:
1982 return MAILIMAP_ERROR_STARTTLS;
1983 }
1984}
1985
1986
1987
1988static char * read_line(mailimap * session)
1989{
1990 return mailstream_read_line(session->imap_stream, session->imap_stream_buffer);
1991}
1992
1993static int send_current_tag(mailimap * session)
1994{
1995 char tag_str[15];
1996 int r;
1997
1998 session->imap_tag ++;
1999 snprintf(tag_str, 15, "%i", session->imap_tag);
2000
2001 r = mailimap_tag_send(session->imap_stream, tag_str);
2002 if (r != MAILIMAP_NO_ERROR)
2003 return r;
2004
2005 r = mailimap_space_send(session->imap_stream);
2006 if (r != MAILIMAP_NO_ERROR)
2007 return r;
2008
2009 return MAILIMAP_NO_ERROR;
2010}
2011
2012static int parse_response(mailimap * session,
2013 struct mailimap_response ** result)
2014{
2015 size_t index;
2016 struct mailimap_response * response;
2017 char tag_str[15];
2018 int r;
2019
2020 index = 0;
2021
2022 session->imap_response = NULL;
2023
2024 r = mailimap_response_parse(session->imap_stream,
2025 session->imap_stream_buffer,
2026 &index, &response,
2027 session->imap_progr_rate, session->imap_progr_fun);
2028 if (r != MAILIMAP_NO_ERROR)
2029 return r;
2030
2031#if 0
2032 mailimap_response_print(response);
2033#endif
2034
2035 response_store(session, response);
2036
2037 if (mmap_string_assign(session->imap_response_buffer,
2038 response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_text->rsp_text)
2039 == NULL)
2040 return MAILIMAP_ERROR_MEMORY;
2041
2042 session->imap_response = session->imap_response_buffer->str;
2043
2044 if (response->rsp_resp_done->rsp_type == MAILIMAP_RESP_DONE_TYPE_FATAL)
2045 return MAILIMAP_ERROR_FATAL;
2046
2047 snprintf(tag_str, 15, "%i", session->imap_tag);
2048 if (strcmp(response->rsp_resp_done->rsp_data.rsp_tagged->rsp_tag, tag_str) != 0)
2049 return MAILIMAP_ERROR_PROTOCOL;
2050
2051 if (response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type ==
2052 MAILIMAP_RESP_COND_STATE_BAD)
2053 return MAILIMAP_ERROR_PROTOCOL;
2054
2055 * result = response;
2056
2057 return MAILIMAP_NO_ERROR;
2058}
2059
2060
2061static int parse_greeting(mailimap * session,
2062 struct mailimap_greeting ** result)
2063{
2064 size_t index;
2065 struct mailimap_greeting * greeting;
2066 int r;
2067
2068 index = 0;
2069
2070 session->imap_response = NULL;
2071
2072 r = mailimap_greeting_parse(session->imap_stream,
2073 session->imap_stream_buffer,
2074 &index, &greeting, session->imap_progr_rate,
2075 session->imap_progr_fun);
2076 if (r != MAILIMAP_NO_ERROR)
2077 return r;
2078
2079#if 0
2080 mailimap_greeting_print(greeting);
2081#endif
2082
2083 greeting_store(session, greeting);
2084
2085 if (greeting->gr_type == MAILIMAP_GREETING_RESP_COND_BYE) {
2086 if (mmap_string_assign(session->imap_response_buffer,
2087 greeting->gr_data.gr_bye->rsp_text->rsp_text) == NULL)
2088 return MAILIMAP_ERROR_MEMORY;
2089
2090 session->imap_response = session->imap_response_buffer->str;
2091
2092 return MAILIMAP_ERROR_DONT_ACCEPT_CONNECTION;
2093 }
2094
2095 if (mmap_string_assign(session->imap_response_buffer,
2096 greeting->gr_data.gr_auth->rsp_text->rsp_text) == NULL)
2097 return MAILIMAP_ERROR_MEMORY;
2098
2099 session->imap_response = session->imap_response_buffer->str;
2100
2101 * result = greeting;
2102
2103 return MAILIMAP_NO_ERROR;
2104}
2105
2106
2107mailimap * mailimap_new(size_t imap_progr_rate,
2108 progress_function * imap_progr_fun)
2109{
2110 mailimap * f;
2111
2112 f = malloc(sizeof(* f));
2113 if (f == NULL)
2114 goto err;
2115
2116 f->imap_response = NULL;
2117
2118 f->imap_stream = NULL;
2119
2120 f->imap_progr_rate = imap_progr_rate;
2121 f->imap_progr_fun = imap_progr_fun;
2122
2123 f->imap_stream_buffer = mmap_string_new("");
2124 if (f->imap_stream_buffer == NULL)
2125 goto free_f;
2126
2127 f->imap_response_buffer = mmap_string_new("");
2128 if (f->imap_response_buffer == NULL)
2129 goto free_stream_buffer;
2130
2131 f->imap_state = MAILIMAP_STATE_DISCONNECTED;
2132 f->imap_tag = 0;
2133
2134 f->imap_selection_info = NULL;
2135 f->imap_response_info = NULL;
2136 f->imap_connection_info = NULL;
2137
2138 return f;
2139
2140 free_stream_buffer:
2141 mmap_string_free(f->imap_stream_buffer);
2142 free_f:
2143 free(f);
2144 err:
2145 return NULL;
2146}
2147
2148void mailimap_free(mailimap * session)
2149{
2150 if (session->imap_stream)
2151 mailimap_logout(session);
2152
2153 mmap_string_free(session->imap_response_buffer);
2154 mmap_string_free(session->imap_stream_buffer);
2155
2156 if (session->imap_response_info)
2157 mailimap_response_info_free(session->imap_response_info);
2158 if (session->imap_selection_info)
2159 mailimap_selection_info_free(session->imap_selection_info);
2160 if (session->imap_connection_info)
2161 mailimap_connection_info_free(session->imap_connection_info);
2162
2163 free(session);
2164}
diff --git a/libetpan/src/low-level/imap/mailimap.h b/libetpan/src/low-level/imap/mailimap.h
new file mode 100644
index 0000000..e31e2d2
--- a/dev/null
+++ b/libetpan/src/low-level/imap/mailimap.h
@@ -0,0 +1,598 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILIMAP_H
37
38#define MAILIMAP_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mailimap_types.h>
45#include <libetpan/mailimap_types_helper.h>
46#include <libetpan/mailimap_helper.h>
47
48#include <libetpan/mailimap_socket.h>
49#include <libetpan/mailimap_ssl.h>
50
51/*
52 mailimap_connect()
53
54 This function will connect the IMAP session with the given stream.
55
56 @param session the IMAP session
57 @param s stream to use
58
59 @return the return code is one of MAILIMAP_ERROR_XXX or
60 MAILIMAP_NO_ERROR codes
61
62 note that on success, MAILIMAP_NO_ERROR_AUTHENTICATED or
63 MAILIMAP_NO_ERROR_NON_AUTHENTICATED is returned
64
65 MAILIMAP_NO_ERROR_NON_AUTHENTICATED is returned when you need to
66 use mailimap_login() to authenticate, else
67 MAILIMAP_NO_ERROR_AUTHENTICATED is returned.
68*/
69
70int mailimap_connect(mailimap * session, mailstream * s);
71
72/*
73 mailimap_append()
74
75 This function will append a given message to the given mailbox
76 by sending an APPEND command.
77
78 @param session the IMAP session
79 @param mailbox name of the mailbox
80 @param flag_list flags of the message
81 @param date_time timestamp of the message
82 @param literal content of the message
83 @param literal_size size of the message
84
85 @return the return code is one of MAILIMAP_ERROR_XXX or
86 MAILIMAP_NO_ERROR codes
87*/
88
89int mailimap_append(mailimap * session, const char * mailbox,
90 struct mailimap_flag_list * flag_list,
91 struct mailimap_date_time * date_time,
92 const char * literal, size_t literal_size);
93
94/*
95 mailimap_noop()
96
97 This function will poll for an event on the server by
98 sending a NOOP command to the IMAP server
99
100 @param session IMAP session
101
102 @return the return code is one of MAILIMAP_ERROR_XXX or
103 MAILIMAP_NO_ERROR_XXX codes
104*/
105
106int mailimap_noop(mailimap * session);
107
108/*
109 mailimap_logout()
110
111 This function will logout from an IMAP server by sending
112 a LOGOUT command.
113
114 @param session IMAP session
115
116 @return the return code is one of MAILIMAP_ERROR_XXX or
117 MAILIMAP_NO_ERROR codes
118*/
119
120int mailimap_logout(mailimap * session);
121
122/*
123 mailimap_capability()
124
125 This function will query an IMAP server for his capabilities
126 by sending a CAPABILITY command.
127
128 @param session IMAP session
129 @param result The result of this command is a list of
130 capabilities and it is stored into (* result).
131
132 @return the return code is one of MAILIMAP_ERROR_XXX or
133 MAILIMAP_NO_ERROR codes
134 */
135
136int mailimap_capability(mailimap * session,
137 struct mailimap_capability_data ** result);
138
139/*
140 mailimap_check()
141
142 This function will request for a checkpoint of the mailbox by
143 sending a CHECK command.
144
145 @param session IMAP session
146
147 @return the return code is one of MAILIMAP_ERROR_XXX or
148 MAILIMAP_NO_ERROR codes
149 */
150
151int mailimap_check(mailimap * session);
152
153/*
154 mailimap_close()
155
156 This function will close the selected mailbox by sending
157 a CLOSE command.
158
159 @param session IMAP session
160
161 @return the return code is one of MAILIMAP_ERROR_XXX or
162 MAILIMAP_NO_ERROR codes
163 */
164
165int mailimap_close(mailimap * session);
166
167/*
168 mailimap_expunge()
169
170 This function will permanently remove from the selected mailbox
171 message that have the \Deleted flag set.
172
173 @param session IMAP session
174
175 @return the return code is one of MAILIMAP_ERROR_XXX or
176 MAILIMAP_NO_ERROR codes
177*/
178
179int mailimap_expunge(mailimap * session);
180
181/*
182 mailimap_copy()
183
184 This function will copy the given messages from the selected mailbox
185 to the given mailbox.
186
187 @param session IMAP session
188 @param set This is a set of message numbers.
189 @param mb This is the destination mailbox.
190
191 @return the return code is one of MAILIMAP_ERROR_XXX or
192 MAILIMAP_NO_ERROR codes
193 */
194
195int mailimap_copy(mailimap * session, struct mailimap_set * set,
196 const char * mb);
197
198/*
199 mailimap_uid_copy()
200
201 This function will copy the given messages from the selected mailbox
202 to the given mailbox.
203
204 @param session IMAP session
205 @param set This is a set of message unique identifiers.
206 @param mb This is the destination mailbox.
207
208 @return the return code is one of MAILIMAP_ERROR_XXX or
209 MAILIMAP_NO_ERROR codes
210 */
211
212int mailimap_uid_copy(mailimap * session,
213 struct mailimap_set * set, const char * mb);
214
215/*
216 mailimap_create()
217
218 This function will create a mailbox.
219
220 @param session IMAP session
221 @param mb This is the name of the mailbox to create.
222
223 @return the return code is one of MAILIMAP_ERROR_XXX or
224 MAILIMAP_NO_ERROR codes
225*/
226
227int mailimap_create(mailimap * session, const char * mb);
228
229/*
230 mailimap_delete()
231
232 This function will delete a mailox.
233
234 @param session IMAP session
235 @param mb This is the name of the mailbox to delete.
236
237 @return the return code is one of MAILIMAP_ERROR_XXX or
238 MAILIMAP_NO_ERROR codes
239*/
240
241int mailimap_delete(mailimap * session, const char * mb);
242
243/*
244 mailimap_examine()
245
246 This function will select the mailbox for read-only operations.
247
248 @param session IMAP session
249 @param mb This is the name of the mailbox to select.
250
251 @return the return code is one of MAILIMAP_ERROR_XXX or
252 MAILIMAP_NO_ERROR codes
253*/
254
255int mailimap_examine(mailimap * session, const char * mb);
256
257/*
258 mailimap_fetch()
259
260 This function will retrieve data associated with the given message
261 numbers.
262
263 @param session IMAP session
264 @param set set of message numbers
265 @param fetch_type type of information to be retrieved
266 @param result The result of this command is a clist
267 and it is stored into (* result). Each element of the clist is a
268 (struct mailimap_msg_att *).
269
270 @return the return code is one of MAILIMAP_ERROR_XXX or
271 MAILIMAP_NO_ERROR codes
272*/
273
274int
275mailimap_fetch(mailimap * session, struct mailimap_set * set,
276 struct mailimap_fetch_type * fetch_type, clist ** result);
277
278/*
279 mailimap_fetch()
280
281 This function will retrieve data associated with the given message
282 numbers.
283
284 @param session IMAP session
285 @param set set of message unique identifiers
286 @param fetch_type type of information to be retrieved
287 @param result The result of this command is a clist
288 and it is stored into (* result). Each element of the clist is a
289 (struct mailimap_msg_att *).
290
291 @return the return code is one of MAILIMAP_ERROR_XXX or
292 MAILIMAP_NO_ERROR codes
293*/
294
295int
296mailimap_uid_fetch(mailimap * session,
297 struct mailimap_set * set,
298 struct mailimap_fetch_type * fetch_type, clist ** result);
299
300/*
301 mailimap_fetch_list_free()
302
303 This function will free the result of a fetch command.
304
305 @param fetch_list This is the clist containing
306 (struct mailimap_msg_att *) elements to free.
307*/
308
309void mailimap_fetch_list_free(clist * fetch_list);
310
311/*
312 mailimap_list()
313
314 This function will return the list of the mailbox
315 available on the server.
316
317 @param session IMAP session
318 @param mb This is the reference name that informs
319 of the level of hierarchy
320 @param list_mb mailbox name with possible wildcard
321 @param result This will store a clist of (struct mailimap_mailbox_list *)
322 in (* result)
323
324 @return the return code is one of MAILIMAP_ERROR_XXX or
325 MAILIMAP_NO_ERROR codes
326*/
327
328int mailimap_list(mailimap * session, const char * mb,
329 const char * list_mb, clist ** result);
330
331/*
332 mailimap_login()
333
334 This function will authenticate the client.
335
336 @param session IMAP session
337 @param userid login of the user
338 @param password password of the user
339
340 @return the return code is one of MAILIMAP_ERROR_XXX or
341 MAILIMAP_NO_ERROR codes
342*/
343
344int mailimap_login(mailimap * session,
345 const char * userid, const char * password);
346
347/*
348 mailimap_lsub()
349
350 This function will return the list of the mailbox
351 that the client has subscribed to.
352
353 @param session IMAP session
354 @param mb This is the reference name that informs
355 of the level of hierarchy
356 @param list_mb mailbox name with possible wildcard
357 @param result This will store a list of (struct mailimap_mailbox_list *)
358 in (* result)
359
360 @return the return code is one of MAILIMAP_ERROR_XXX or
361 MAILIMAP_NO_ERROR codes
362*/
363
364int mailimap_lsub(mailimap * session, const char * mb,
365 const char * list_mb, clist ** result);
366
367/*
368 mailimap_list_result_free()
369
370 This function will free the clist of (struct mailimap_mailbox_list *)
371
372 @param list This is the clist to free.
373*/
374
375void mailimap_list_result_free(clist * list);
376
377/*
378 mailimap_rename()
379
380 This function will change the name of a mailbox.
381
382 @param session IMAP session
383 @param mb current name
384 @param new_name new name
385
386 @return the return code is one of MAILIMAP_ERROR_XXX or
387 MAILIMAP_NO_ERROR codes
388*/
389
390int mailimap_rename(mailimap * session,
391 const char * mb, const char * new_name);
392
393/*
394 mailimap_search()
395
396 All mails that match the given criteria will be returned
397 their numbers in the result list.
398
399 @param session IMAP session
400 @param charset This indicates the charset of the strings that appears
401 in the searching criteria
402 @param key This is the searching criteria
403 @param result The result is a clist of (uint32_t *) and will be
404 stored in (* result).
405
406 @return the return code is one of MAILIMAP_ERROR_XXX or
407 MAILIMAP_NO_ERROR codes
408*/
409
410int
411mailimap_search(mailimap * session, const char * charset,
412 struct mailimap_search_key * key, clist ** result);
413
414/*
415 mailimap_uid_search()
416
417
418 All mails that match the given criteria will be returned
419 their unique identifiers in the result list.
420
421 @param session IMAP session
422 @param charset This indicates the charset of the strings that appears
423 in the searching criteria
424 @param key This is the searching criteria
425 @param result The result is a clist of (uint32_t *) and will be
426 stored in (* result).
427
428 @return the return code is one of MAILIMAP_ERROR_XXX or
429 MAILIMAP_NO_ERROR codes
430*/
431
432int
433mailimap_uid_search(mailimap * session, const char * charset,
434 struct mailimap_search_key * key, clist ** result);
435
436/*
437 mailimap_search_result_free()
438
439 This function will free the result of the a search.
440
441 @param search_result This is a clist of (uint32_t *) returned
442 by mailimap_uid_search() or mailimap_search()
443*/
444
445void mailimap_search_result_free(clist * search_result);
446
447/*
448 mailimap_select()
449
450 This function will select a given mailbox so that messages in the
451 mailbox can be accessed.
452
453 @param session IMAP session
454 @param mb This is the name of the mailbox to select.
455
456 @return the return code is one of MAILIMAP_ERROR_XXX or
457 MAILIMAP_NO_ERROR codes
458*/
459
460int
461mailimap_select(mailimap * session, const char * mb);
462
463/*
464 mailimap_status()
465
466 This function will return informations about a given mailbox.
467
468 @param session IMAP session
469 @param mb This is the name of the mailbox
470 @param status_att_list This is the list of mailbox information to return
471 @param result List of returned values
472
473 @return the return code is one of MAILIMAP_ERROR_XXX or
474 MAILIMAP_NO_ERROR codes
475*/
476
477int
478mailimap_status(mailimap * session, const char * mb,
479 struct mailimap_status_att_list * status_att_list,
480 struct mailimap_mailbox_data_status ** result);
481
482/*
483 mailimap_uid_store()
484
485 This function will alter the data associated with some messages
486 (flags of the messages).
487
488 @param session IMAP session
489 @param set This is a list of message numbers.
490 @param store_att_flags This is the data to associate with the
491 given messages
492
493 @return the return code is one of MAILIMAP_ERROR_XXX or
494 MAILIMAP_NO_ERROR codes
495*/
496
497int
498mailimap_store(mailimap * session,
499 struct mailimap_set * set,
500 struct mailimap_store_att_flags * store_att_flags);
501
502/*
503 mailimap_uid_store()
504
505 This function will alter the data associated with some messages
506 (flags of the messages).
507
508 @param session IMAP session
509 @param set This is a list of message unique identifiers.
510 @param store_att_flags This is the data to associate with the
511 given messages
512
513 @return the return code is one of MAILIMAP_ERROR_XXX or
514 MAILIMAP_NO_ERROR codes
515*/
516
517int
518mailimap_uid_store(mailimap * session,
519 struct mailimap_set * set,
520 struct mailimap_store_att_flags * store_att_flags);
521
522/*
523 mailimap_subscribe()
524
525 This function adds the specified mailbox name to the
526 server's set of "active" or "subscribed" mailboxes.
527
528 @param session IMAP session
529 @param mb This is the name of the mailbox
530
531 @return the return code is one of MAILIMAP_ERROR_XXX or
532 MAILIMAP_NO_ERROR codes
533*/
534
535int mailimap_subscribe(mailimap * session, const char * mb);
536
537/*
538 mailimap_unsubscribe()
539
540 This function removes the specified mailbox name to the
541 server's set of "active" or "subscribed" mailboxes.
542
543 @param session IMAP session
544 @param mb This is the name of the mailbox
545
546 @return the return code is one of MAILIMAP_ERROR_XXX or
547 MAILIMAP_NO_ERROR codes
548*/
549
550int mailimap_unsubscribe(mailimap * session, const char * mb);
551
552/*
553 mailimap_starttls()
554
555 This function starts change the mode of the connection to
556 switch to SSL connection.
557
558 @param session IMAP session
559
560 @return the return code is one of MAILIMAP_ERROR_XXX or
561 MAILIMAP_NO_ERROR_XXX codes
562 */
563
564int mailimap_starttls(mailimap * session);
565
566/*
567 mailimap_new()
568
569 This function returns a new IMAP session.
570
571 @param progr_rate When downloading messages, a function will be called
572 each time the amount of bytes downloaded reaches a multiple of this
573 value, this can be 0.
574 @param progr_fun This is the function to call to notify the progress,
575 this can be NULL.
576
577 @return an IMAP session is returned.
578 */
579
580mailimap * mailimap_new(size_t imap_progr_rate,
581 progress_function * imap_progr_fun);
582
583/*
584 mailimap_free()
585
586 This function will free the data structures associated with
587 the IMAP session.
588
589 @param session IMAP session
590 */
591
592void mailimap_free(mailimap * session);
593
594#ifdef __cplusplus
595}
596#endif
597
598#endif
diff --git a/libetpan/src/low-level/imap/mailimap_helper.c b/libetpan/src/low-level/imap/mailimap_helper.c
new file mode 100644
index 0000000..cc2a8e6
--- a/dev/null
+++ b/libetpan/src/low-level/imap/mailimap_helper.c
@@ -0,0 +1,205 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailimap_helper.h"
37
38#include <stdlib.h>
39#include "mailimap.h"
40
41int mailimap_fetch_rfc822(mailimap * session,
42 uint32_t msgid, char ** result)
43{
44 int r;
45 clist * fetch_list;
46 struct mailimap_fetch_att * fetch_att;
47 struct mailimap_fetch_type * fetch_type;
48 struct mailimap_set * set;
49 struct mailimap_msg_att * msg_att;
50 struct mailimap_msg_att_item * item;
51 int res;
52
53 fetch_att = mailimap_fetch_att_new_rfc822();
54 fetch_type = mailimap_fetch_type_new_fetch_att(fetch_att);
55 set = mailimap_set_new_single(msgid);
56
57 r = mailimap_fetch(session, set, fetch_type, &fetch_list);
58
59 mailimap_set_free(set);
60 mailimap_fetch_type_free(fetch_type);
61
62 if (r != MAILIMAP_NO_ERROR) {
63 res = r;
64 goto err;
65 }
66
67 if (clist_isempty(fetch_list)) {
68 res = MAILIMAP_ERROR_FETCH;
69 goto free;
70 }
71
72 msg_att = (struct mailimap_msg_att *) clist_begin(fetch_list)->data;
73
74 if (clist_isempty(msg_att->att_list)) {
75 res = MAILIMAP_ERROR_FETCH;
76 goto free;
77 }
78
79 item = (struct mailimap_msg_att_item *) clist_begin(msg_att->att_list)->data;
80
81 if (item->att_type != MAILIMAP_MSG_ATT_ITEM_STATIC) {
82 res = MAILIMAP_ERROR_FETCH;
83 goto free;
84 }
85 if (item->att_data.att_static->att_type != MAILIMAP_MSG_ATT_RFC822) {
86 res = MAILIMAP_ERROR_FETCH;
87 goto free;
88 }
89
90 * result = item->att_data.att_static->att_data.att_rfc822.att_content;
91 item->att_data.att_static->att_data.att_rfc822.att_content = NULL;
92 mailimap_fetch_list_free(fetch_list);
93
94 return MAILIMAP_NO_ERROR;
95
96free:
97 mailimap_fetch_list_free(fetch_list);
98err:
99 return res;
100}
101
102int mailimap_fetch_rfc822_header(mailimap * session,
103 uint32_t msgid, char ** result)
104{
105 int r;
106 int res;
107 clist * fetch_list;
108 struct mailimap_fetch_att * fetch_att;
109 struct mailimap_fetch_type * fetch_type;
110 struct mailimap_set * set;
111 struct mailimap_msg_att * msg_att;
112 struct mailimap_msg_att_item * item;
113
114 fetch_att = mailimap_fetch_att_new_rfc822_header();
115 fetch_type = mailimap_fetch_type_new_fetch_att(fetch_att);
116 set = mailimap_set_new_single(msgid);
117
118 r = mailimap_fetch(session, set, fetch_type, &fetch_list);
119
120 mailimap_set_free(set);
121 mailimap_fetch_type_free(fetch_type);
122
123 if (r != MAILIMAP_NO_ERROR) {
124 res = r;
125 goto err;
126 }
127
128 if (clist_isempty(fetch_list)) {
129 res = MAILIMAP_ERROR_FETCH;
130 goto free;
131 }
132
133 msg_att = (struct mailimap_msg_att *) clist_begin(fetch_list)->data;
134
135 if (clist_isempty(msg_att->att_list)) {
136 res = MAILIMAP_ERROR_FETCH;
137 goto free;
138 }
139
140 item = (struct mailimap_msg_att_item *) clist_begin(msg_att->att_list)->data;
141
142 if (item->att_type != MAILIMAP_MSG_ATT_ITEM_STATIC) {
143 res = MAILIMAP_ERROR_FETCH;
144 goto err;
145 }
146
147 if (item->att_data.att_static->att_type != MAILIMAP_MSG_ATT_RFC822_HEADER) {
148 res = MAILIMAP_ERROR_FETCH;
149 goto err;
150 }
151
152 * result = item->att_data.att_static->att_data.att_rfc822_header.att_content;
153 item->att_data.att_static->att_data.att_rfc822_header.att_content = NULL;
154 mailimap_fetch_list_free(fetch_list);
155
156 return MAILIMAP_NO_ERROR;
157
158free:
159 mailimap_fetch_list_free(fetch_list);
160err:
161 return res;
162}
163
164int mailimap_fetch_envelope(mailimap * session,
165 uint32_t first, uint32_t last,
166 clist ** result)
167{
168 int r;
169 clist * fetch_list;
170 struct mailimap_fetch_att * fetch_att;
171 struct mailimap_fetch_type * fetch_type;
172 struct mailimap_set * set;
173
174 fetch_att = mailimap_fetch_att_new_envelope();
175 fetch_type = mailimap_fetch_type_new_fetch_att(fetch_att);
176 set = mailimap_set_new_interval(first, last);
177
178 r = mailimap_fetch(session, set, fetch_type, &fetch_list);
179
180 mailimap_set_free(set);
181 mailimap_fetch_type_free(fetch_type);
182
183 if (r != MAILIMAP_NO_ERROR)
184 return r;
185
186 * result = fetch_list;
187
188 return MAILIMAP_NO_ERROR;
189}
190
191int mailimap_append_simple(mailimap * session, char * mailbox,
192 char * content, uint32_t size)
193{
194 return mailimap_append(session, mailbox, NULL, NULL, content, size);
195}
196
197int mailimap_login_simple(mailimap * session,
198 char * userid, char * password)
199{
200 if (session->imap_state == MAILIMAP_STATE_NON_AUTHENTICATED)
201 return mailimap_login(session, userid, password);
202 else
203 return MAILIMAP_NO_ERROR;
204}
205
diff --git a/libetpan/src/low-level/imap/mailimap_helper.h b/libetpan/src/low-level/imap/mailimap_helper.h
new file mode 100644
index 0000000..b548271
--- a/dev/null
+++ b/libetpan/src/low-level/imap/mailimap_helper.h
@@ -0,0 +1,66 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILIMAP_HELPER_H
37
38#define MAILIMAP_HELPER_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mailimap_types.h>
45
46int mailimap_fetch_rfc822(mailimap * session,
47 uint32_t msgid, char ** result);
48
49int mailimap_fetch_rfc822_header(mailimap * session,
50 uint32_t msgid, char ** result);
51
52int mailimap_fetch_envelope(mailimap * session,
53 uint32_t first, uint32_t last,
54 clist ** result);
55
56int mailimap_append_simple(mailimap * session, char * mailbox,
57 char * content, uint32_t size);
58
59int mailimap_login_simple(mailimap * session,
60 char * userid, char * password);
61
62#ifdef __cplusplus
63}
64#endif
65
66#endif
diff --git a/libetpan/src/low-level/imap/mailimap_keywords.c b/libetpan/src/low-level/imap/mailimap_keywords.c
new file mode 100644
index 0000000..7e832a3
--- a/dev/null
+++ b/libetpan/src/low-level/imap/mailimap_keywords.c
@@ -0,0 +1,353 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailimap_keywords.h"
37#include "mailimap_types.h"
38#include <string.h>
39#include <stdio.h>
40
41#ifndef UNSTRICT_SYNTAX
42#define UNSTRICT_SYNTAX
43#endif
44
45struct mailimap_token_value {
46 int value;
47 const char * str;
48};
49
50int mailimap_token_case_insensitive_parse(mailstream * fd,
51 MMAPString * buffer,
52 size_t * index,
53 const char * token)
54{
55 int len;
56 size_t cur_token;
57 int r;
58
59 cur_token = * index;
60 len = strlen(token);
61
62#ifdef UNSTRICT_SYNTAX
63 r = mailimap_space_parse(fd, buffer, &cur_token);
64 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE))
65 return r;
66#endif
67
68 if (strncasecmp(buffer->str + cur_token, token, len) == 0) {
69 cur_token += len;
70 * index = cur_token;
71 return MAILIMAP_NO_ERROR;
72 }
73 else
74 return MAILIMAP_ERROR_PARSE;
75}
76
77
78static int is_space_or_tab(char ch)
79{
80 return (ch == ' ') || (ch == '\t');
81}
82
83int mailimap_char_parse(mailstream * fd, MMAPString * buffer,
84 size_t * index, char token)
85{
86 int cur_token;
87
88 cur_token = * index;
89
90 if (buffer->str[cur_token] == token) {
91 cur_token ++;
92 * index = cur_token;
93 return MAILIMAP_NO_ERROR;
94 }
95 else
96 return MAILIMAP_ERROR_PARSE;
97}
98
99int mailimap_space_parse(mailstream * fd, MMAPString * buffer,
100 size_t * index)
101{
102#ifdef UNSTRICT_SYNTAX
103
104 /* can accept unstrict syntax */
105 size_t cur_token;
106
107 cur_token = * index;
108
109 while (is_space_or_tab(* (buffer->str + cur_token)))
110 cur_token ++;
111
112 if (cur_token == * index)
113 return MAILIMAP_ERROR_PARSE;
114
115 * index = cur_token;
116
117 return MAILIMAP_NO_ERROR;
118
119#else
120 return mailimap_char_parse(fd, buffer, index, ' ');
121#endif
122}
123
124
125
126#define mailimap_get_token_str(index, tab) \
127 mailimap_get_token_str_size(index, tab, \
128 sizeof(tab) / sizeof(struct mailimap_token_value))
129
130#define mailimap_get_token_value(fd, buffer, index, tab) \
131 mailimap_get_token_value_size(fd, buffer, index, tab, \
132 sizeof(tab) / sizeof(struct mailimap_token_value))
133
134
135static const char * mailimap_get_token_str_size(int index,
136 struct mailimap_token_value * tab,
137 size_t size)
138{
139 size_t i;
140
141 for(i = 0 ; i < size ; i++)
142 if (index == tab[i].value)
143 return tab[i].str;
144
145 return NULL;
146}
147
148
149
150static int mailimap_get_token_value_size(mailstream * fd, MMAPString * buffer,
151 size_t * index,
152 struct mailimap_token_value * tab,
153 size_t size)
154{
155 size_t i;
156 int r;
157
158#ifdef UNSTRICT_SYNTAX
159 /* can accept unstrict syntax */
160 r = mailimap_space_parse(fd, buffer, index);
161 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE))
162 return r;
163#endif
164
165 for(i = 0 ; i < size ; i++) {
166 r = mailimap_token_case_insensitive_parse(fd, buffer, index, tab[i].str);
167 if (r == MAILIMAP_NO_ERROR)
168 return tab[i].value;
169 }
170
171 return -1;
172}
173
174
175static struct mailimap_token_value status_att_tab[] = {
176 {MAILIMAP_STATUS_ATT_MESSAGES, "MESSAGES"},
177 {MAILIMAP_STATUS_ATT_RECENT, "RECENT"},
178 {MAILIMAP_STATUS_ATT_UIDNEXT, "UIDNEXT"},
179 {MAILIMAP_STATUS_ATT_UIDVALIDITY, "UIDVALIDITY"},
180 {MAILIMAP_STATUS_ATT_UNSEEN, "UNSEEN"}
181};
182
183int mailimap_status_att_get_token_value(mailstream * fd, MMAPString * buffer,
184 size_t * index)
185{
186 int r;
187
188#ifdef UNSTRICT_SYNTAX
189 /* can accept unstrict syntax */
190 r = mailimap_space_parse(fd, buffer, index);
191 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE))
192 return r;
193#endif
194 return mailimap_get_token_value(fd, buffer, index,
195 status_att_tab);
196}
197
198
199const char * mailimap_status_att_get_token_str(size_t index)
200{
201 return mailimap_get_token_str(index, status_att_tab);
202}
203
204static struct mailimap_token_value month_tab[] = {
205 {1, "Jan"},
206 {2, "Feb"},
207 {3, "Mar"},
208 {4, "Apr"},
209 {5, "May"},
210 {6, "Jun"},
211 {7, "Jul"},
212 {8, "Aug"},
213 {9, "Sep"},
214 {10, "Oct"},
215 {11, "Nov"},
216 {12, "Dec"}
217};
218
219int mailimap_month_get_token_value(mailstream * fd, MMAPString * buffer,
220 size_t * index)
221{
222 return mailimap_get_token_value(fd, buffer, index, month_tab);
223}
224
225
226const char * mailimap_month_get_token_str(size_t index)
227{
228 return mailimap_get_token_str(index, month_tab);
229}
230
231
232
233
234
235static struct mailimap_token_value mailimap_flag_tab[] = {
236 {MAILIMAP_FLAG_ANSWERED, "\\Answered"},
237 {MAILIMAP_FLAG_FLAGGED, "\\Flagged"},
238 {MAILIMAP_FLAG_DELETED, "\\Deleted"},
239 {MAILIMAP_FLAG_SEEN, "\\Seen"},
240 {MAILIMAP_FLAG_DRAFT, "\\Draft"}
241};
242
243int mailimap_flag_get_token_value(mailstream * fd, MMAPString * buffer,
244 size_t * index)
245{
246 return mailimap_get_token_value(fd, buffer, index,
247 mailimap_flag_tab);
248}
249
250
251const char * mailimap_flag_get_token_str(size_t index)
252{
253 return mailimap_get_token_str(index, mailimap_flag_tab);
254}
255
256
257
258
259static struct mailimap_token_value encoding_tab[] = {
260 {MAILIMAP_BODY_FLD_ENC_7BIT, "7BIT"},
261 {MAILIMAP_BODY_FLD_ENC_8BIT, "8BIT"},
262 {MAILIMAP_BODY_FLD_ENC_BINARY, "BINARY"},
263 {MAILIMAP_BODY_FLD_ENC_BASE64, "BASE64"},
264 {MAILIMAP_BODY_FLD_ENC_QUOTED_PRINTABLE, "QUOTED-PRINTABLE"}
265};
266
267int mailimap_encoding_get_token_value(mailstream * fd, MMAPString * buffer,
268 size_t * index)
269{
270 return mailimap_get_token_value(fd, buffer, index, encoding_tab);
271}
272
273static struct mailimap_token_value mbx_list_sflag_tab[] = {
274 {MAILIMAP_MBX_LIST_SFLAG_MARKED, "\\Marked"},
275 {MAILIMAP_MBX_LIST_SFLAG_NOSELECT, "\\Noselect"},
276 {MAILIMAP_MBX_LIST_SFLAG_UNMARKED, "\\Unmarked"}
277};
278
279int mailimap_mbx_list_sflag_get_token_value(mailstream * fd,
280 MMAPString * buffer,
281 size_t * index)
282{
283 return mailimap_get_token_value(fd, buffer, index, mbx_list_sflag_tab);
284}
285
286static struct mailimap_token_value media_basic_tab[] = {
287 {MAILIMAP_MEDIA_BASIC_APPLICATION, "APPLICATION"},
288 {MAILIMAP_MEDIA_BASIC_AUDIO, "AUDIO"},
289 {MAILIMAP_MEDIA_BASIC_IMAGE, "IMAGE"},
290 {MAILIMAP_MEDIA_BASIC_MESSAGE, "MESSAGE"},
291 {MAILIMAP_MEDIA_BASIC_VIDEO, "VIDEO"}
292};
293
294int mailimap_media_basic_get_token_value(mailstream * fd, MMAPString * buffer,
295 size_t * index)
296{
297 return mailimap_get_token_value(fd, buffer, index, media_basic_tab);
298}
299
300static struct mailimap_token_value resp_cond_state_tab[] = {
301 {MAILIMAP_RESP_COND_STATE_OK, "OK"},
302 {MAILIMAP_RESP_COND_STATE_NO, "NO"},
303 {MAILIMAP_RESP_COND_STATE_BAD, "BAD"}
304};
305
306int mailimap_resp_cond_state_get_token_value(mailstream * fd,
307 MMAPString * buffer,
308 size_t * index)
309{
310 return mailimap_get_token_value(fd, buffer, index, resp_cond_state_tab);
311}
312
313static struct mailimap_token_value resp_text_code_1_tab[] = {
314 {MAILIMAP_RESP_TEXT_CODE_ALERT, "ALERT"},
315 {MAILIMAP_RESP_TEXT_CODE_PARSE, "PARSE"},
316 {MAILIMAP_RESP_TEXT_CODE_READ_ONLY, "READ-ONLY"},
317 {MAILIMAP_RESP_TEXT_CODE_READ_WRITE, "READ-WRITE"},
318 {MAILIMAP_RESP_TEXT_CODE_TRY_CREATE, "TRYCREATE"}
319};
320
321int mailimap_resp_text_code_1_get_token_value(mailstream * fd,
322 MMAPString * buffer,
323 size_t * index)
324{
325 return mailimap_get_token_value(fd, buffer, index, resp_text_code_1_tab);
326}
327
328static struct mailimap_token_value resp_text_code_2_tab[] = {
329 {MAILIMAP_RESP_TEXT_CODE_UIDNEXT, "UIDNEXT"},
330 {MAILIMAP_RESP_TEXT_CODE_UIDVALIDITY, "UIDVALIDITY"},
331 {MAILIMAP_RESP_TEXT_CODE_UNSEEN, "UNSEEN"},
332};
333
334int mailimap_resp_text_code_2_get_token_value(mailstream * fd,
335 MMAPString * buffer,
336 size_t * index)
337{
338 return mailimap_get_token_value(fd, buffer, index, resp_text_code_2_tab);
339}
340
341static struct mailimap_token_value section_msgtext_tab[] = {
342 {MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS_NOT, "HEADER.FIELDS.NOT"},
343 {MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS, "HEADER.FIELDS"},
344 {MAILIMAP_SECTION_MSGTEXT_HEADER, "HEADER"},
345 {MAILIMAP_SECTION_MSGTEXT_TEXT, "TEXT"}
346};
347
348int mailimap_section_msgtext_get_token_value(mailstream * fd,
349 MMAPString * buffer,
350 size_t * index)
351{
352 return mailimap_get_token_value(fd, buffer, index, section_msgtext_tab);
353}
diff --git a/libetpan/src/low-level/imap/mailimap_keywords.h b/libetpan/src/low-level/imap/mailimap_keywords.h
new file mode 100644
index 0000000..e00f687
--- a/dev/null
+++ b/libetpan/src/low-level/imap/mailimap_keywords.h
@@ -0,0 +1,107 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILIMAP_COMMON_H
37
38#define MAILIMAP_COMMON_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include "mailstream.h"
45
46
47/* tools */
48
49int mailimap_char_parse(mailstream * fd, MMAPString * buffer,
50 size_t * index, char token);
51
52int mailimap_space_parse(mailstream * fd, MMAPString * buffer,
53 size_t * index);
54
55/* tokens */
56
57int mailimap_token_case_insensitive_parse(mailstream * fd,
58 MMAPString * buffer,
59 size_t * index,
60 const char * token);
61
62int mailimap_status_att_get_token_value(mailstream * fd, MMAPString * buffer,
63 size_t * index);
64const char * mailimap_status_att_get_token_str(size_t index);
65
66
67int mailimap_month_get_token_value(mailstream * fd, MMAPString * buffer,
68 size_t * index);
69const char * mailimap_month_get_token_str(size_t index);
70
71
72int mailimap_flag_get_token_value(mailstream * fd, MMAPString * buffer,
73 size_t * index);
74
75const char * mailimap_flag_get_token_str(size_t index);
76
77int mailimap_encoding_get_token_value(mailstream * fd, MMAPString * buffer,
78 size_t * index);
79
80int mailimap_mbx_list_sflag_get_token_value(mailstream * fd,
81 MMAPString * buffer,
82 size_t * index);
83
84int mailimap_media_basic_get_token_value(mailstream * fd, MMAPString * buffer,
85 size_t * index);
86
87int mailimap_resp_cond_state_get_token_value(mailstream * fd,
88 MMAPString * buffer,
89 size_t * index);
90
91int mailimap_resp_text_code_1_get_token_value(mailstream * fd,
92 MMAPString * buffer,
93 size_t * index);
94
95int mailimap_resp_text_code_2_get_token_value(mailstream * fd,
96 MMAPString * buffer,
97 size_t * index);
98
99int mailimap_section_msgtext_get_token_value(mailstream * fd,
100 MMAPString * buffer,
101 size_t * index);
102
103#ifdef __cplusplus
104}
105#endif
106
107#endif
diff --git a/libetpan/src/low-level/imap/mailimap_parser.c b/libetpan/src/low-level/imap/mailimap_parser.c
new file mode 100644
index 0000000..ab4db67
--- a/dev/null
+++ b/libetpan/src/low-level/imap/mailimap_parser.c
@@ -0,0 +1,9506 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include <string.h>
37#include <stdlib.h>
38#include <stdio.h>
39
40#include "mailstream.h"
41#include "mailimap_keywords.h"
42#include "mailimap_parser.h"
43#include "mmapstring.h"
44#include "mail.h"
45
46#ifndef UNSTRICT_SYNTAX
47#define UNSTRICT_SYNTAX
48#endif
49
50/*
51 Document: internet-drafts/draft-crispin-imapv-15.txt
52 RFC 2060 (IMAP but rather used draft)
53 RFC 2234 for all token that are not defined such as ALPHA
54*/
55
56
57
58/* ************************************************************************* */
59/* ************************************************************************* */
60/* ************************************************************************* */
61/* ************************************************************************* */
62/* ************************************************************************* */
63/* ************************************************************************* */
64
65
66
67
68static int mailimap_address_parse(mailstream * fd, MMAPString * buffer,
69 size_t * index,
70 struct mailimap_address ** result,
71 size_t progr_rate,
72 progress_function * progr_fun);
73
74static int mailimap_addr_adl_parse(mailstream * fd, MMAPString * buffer,
75 size_t * index, char ** result,
76 size_t progr_rate,
77 progress_function * progr_fun);
78
79static int mailimap_addr_host_parse(mailstream * fd, MMAPString * buffer,
80 size_t * index, char ** result,
81 size_t progr_rate,
82 progress_function * progr_fun);
83
84static int mailimap_addr_mailbox_parse(mailstream * fd, MMAPString * buffer,
85 size_t * index, char ** result,
86 size_t progr_rate,
87 progress_function * progr_fun);
88
89static int mailimap_addr_name_parse(mailstream * fd, MMAPString * buffer,
90 size_t * index, char ** result,
91 size_t progr_rate,
92 progress_function * progr_fun);
93
94
95static int
96mailimap_astring_parse(mailstream * fd, MMAPString * buffer,
97 size_t * index,
98 char ** result,
99 size_t progr_rate,
100 progress_function * progr_fun);
101
102static int mailimap_atom_parse(mailstream * fd, MMAPString * buffer,
103 size_t * index, char ** result,
104 size_t progr_rate,
105 progress_function * progr_fun);
106
107static int mailimap_auth_type_parse(mailstream * fd, MMAPString * buffer,
108 size_t * index, char ** result,
109 size_t progr_rate,
110 progress_function * progr_fun);
111
112static int mailimap_base64_parse(mailstream * fd, MMAPString * buffer,
113 size_t * index, char ** result,
114 size_t progr_rate,
115 progress_function * progr_fun);
116
117static int mailimap_body_parse(mailstream * fd, MMAPString * buffer,
118 size_t * index,
119 struct mailimap_body ** result,
120 size_t progr_rate,
121 progress_function * progr_fun);
122
123
124static int
125mailimap_body_extension_parse(mailstream * fd, MMAPString * buffer,
126 size_t * index,
127 struct mailimap_body_extension ** result,
128 size_t progr_rate,
129 progress_function * progr_fun);
130
131
132static int
133mailimap_body_ext_1part_parse(mailstream * fd, MMAPString * buffer,
134 size_t * index,
135 struct mailimap_body_ext_1part ** result,
136 size_t progr_rate,
137 progress_function * progr_fun);
138
139
140
141static int
142mailimap_body_ext_mpart_parse(mailstream * fd, MMAPString * buffer,
143 size_t * index,
144 struct mailimap_body_ext_mpart ** result,
145 size_t progr_rate,
146 progress_function * progr_fun);
147
148
149static int
150mailimap_body_fields_parse(mailstream * fd, MMAPString * buffer,
151 size_t * index,
152 struct mailimap_body_fields ** result,
153 size_t progr_rate,
154 progress_function * progr_fun);
155
156static int mailimap_body_fld_desc_parse(mailstream * fd, MMAPString * buffer,
157 size_t * index, char ** result,
158 size_t progr_rate,
159 progress_function * progr_fun);
160
161
162static int
163mailimap_body_fld_dsp_parse(mailstream * fd, MMAPString * buffer,
164 size_t * index,
165 struct mailimap_body_fld_dsp ** result,
166 size_t progr_rate,
167 progress_function * progr_fun);
168
169
170
171static int
172mailimap_body_fld_enc_parse(mailstream * fd, MMAPString * buffer,
173 size_t * index,
174 struct mailimap_body_fld_enc ** result,
175 size_t progr_rate,
176 progress_function * progr_fun);
177
178
179
180static int mailimap_body_fld_id_parse(mailstream * fd, MMAPString * buffer,
181 size_t * index, char ** result,
182 size_t progr_rate,
183 progress_function * progr_fun);
184
185
186static int
187mailimap_body_fld_lang_parse(mailstream * fd, MMAPString * buffer,
188 size_t * index,
189 struct mailimap_body_fld_lang ** result,
190 size_t progr_rate,
191 progress_function * progr_fun);
192
193static int mailimap_body_fld_lines_parse(mailstream * fd,
194 MMAPString * buffer, size_t * index,
195 uint32_t * result);
196
197static int mailimap_body_fld_md5_parse(mailstream * fd, MMAPString * buffer,
198 size_t * index, char ** result,
199 size_t progr_rate,
200 progress_function * progr_fun);
201
202static int mailimap_body_fld_octets_parse(mailstream * fd,
203 MMAPString * buffer, size_t * index,
204 uint32_t * result);
205
206static int
207mailimap_body_fld_param_parse(mailstream * fd,
208 MMAPString * buffer, size_t * index,
209 struct mailimap_body_fld_param ** result,
210 size_t progr_rate,
211 progress_function * progr_fun);
212
213
214
215static int
216mailimap_body_type_1part_parse(mailstream * fd, MMAPString * buffer,
217 size_t * index,
218 struct mailimap_body_type_1part ** result,
219 size_t progr_rate,
220 progress_function * progr_fun);
221
222
223
224static int
225mailimap_body_type_basic_parse(mailstream * fd, MMAPString * buffer,
226 size_t * index,
227 struct mailimap_body_type_basic ** result,
228 size_t progr_rate,
229 progress_function * progr_fun);
230
231
232
233static int
234mailimap_body_type_mpart_parse(mailstream * fd,
235 MMAPString * buffer,
236 size_t * index,
237 struct mailimap_body_type_mpart ** result,
238 size_t progr_rate,
239 progress_function * progr_fun);
240
241
242
243static int
244mailimap_body_type_msg_parse(mailstream * fd, MMAPString * buffer,
245 size_t * index,
246 struct mailimap_body_type_msg ** result,
247 size_t progr_rate,
248 progress_function * progr_fun);
249
250
251
252static int
253mailimap_body_type_text_parse(mailstream * fd, MMAPString * buffer,
254 size_t * index,
255 struct mailimap_body_type_text **
256 result,
257 size_t progr_rate,
258 progress_function * progr_fun);
259
260
261
262static int
263mailimap_capability_parse(mailstream * fd, MMAPString * buffer,
264 size_t * index,
265 struct mailimap_capability ** result,
266 size_t progr_rate,
267 progress_function * progr_fun);
268
269
270
271static int
272mailimap_capability_data_parse(mailstream * fd, MMAPString * buffer,
273 size_t * index,
274 struct mailimap_capability_data ** result,
275 size_t progr_rate,
276 progress_function * progr_fun);
277
278
279/*
280static gboolean mailimap_date_day_parse(mailstream * fd,
281 MMAPString * buffer,
282 guint32 * index,
283 gint * result);
284*/
285static int mailimap_date_day_fixed_parse(mailstream * fd,
286 MMAPString * buffer,
287 size_t * index,
288 int * result);
289
290static int mailimap_date_month_parse(mailstream * fd, MMAPString * buffer,
291 size_t * index, int * result);
292
293/*
294struct mailimap_date_text {
295 gint day;
296 gint month;
297 gint year;
298};
299
300static gboolean
301mailimap_date_text_parse(mailstream * fd, MMAPString * buffer,
302 guint32 * index, struct mailimap_date_text ** result);
303static void mailimap_date_text_free(struct mailimap_date_text * date_text);
304*/
305
306static int mailimap_date_year_parse(mailstream * fd, MMAPString * buffer,
307 size_t * index, int * result);
308
309static int mailimap_date_time_parse(mailstream * fd, MMAPString * buffer,
310 size_t * index,
311 struct mailimap_date_time ** t,
312 size_t progr_rate,
313 progress_function * progr_fun);
314
315#ifndef UNSTRICT_SYNTAX
316static int mailimap_digit_nz_parse(mailstream * fd, MMAPString * buffer,
317 size_t * index, int * result);
318#endif
319
320
321static int mailimap_envelope_parse(mailstream * fd, MMAPString * buffer,
322 size_t * index,
323 struct mailimap_envelope ** result,
324 size_t progr_rate,
325 progress_function * progr_fun);
326
327
328static int
329mailimap_env_bcc_parse(mailstream * fd, MMAPString * buffer,
330 size_t * index, struct mailimap_env_bcc ** result,
331 size_t progr_rate,
332 progress_function * progr_fun);
333
334
335static int
336mailimap_env_cc_parse(mailstream * fd, MMAPString * buffer,
337 size_t * index, struct mailimap_env_cc ** result,
338 size_t progr_rate,
339 progress_function * progr_fun);
340
341static int mailimap_env_date_parse(mailstream * fd, MMAPString * buffer,
342 size_t * index, char ** result,
343 size_t progr_rate,
344 progress_function * progr_fun);
345
346
347static int
348mailimap_env_from_parse(mailstream * fd, MMAPString * buffer,
349 size_t * index, struct mailimap_env_from ** result,
350 size_t progr_rate,
351 progress_function * progr_fun);
352
353
354static int mailimap_env_in_reply_to_parse(mailstream * fd,
355 MMAPString * buffer,
356 size_t * index, char ** result,
357 size_t progr_rate,
358 progress_function * progr_fun);
359
360static int mailimap_env_message_id_parse(mailstream * fd,
361 MMAPString * buffer,
362 size_t * index, char ** result,
363 size_t progr_rate,
364 progress_function * progr_fun);
365
366static int
367mailimap_env_reply_to_parse(mailstream * fd, MMAPString * buffer,
368 size_t * index,
369 struct mailimap_env_reply_to ** result,
370 size_t progr_rate,
371 progress_function * progr_fun);
372
373
374
375static int
376mailimap_env_sender_parse(mailstream * fd, MMAPString * buffer,
377 size_t * index, struct mailimap_env_sender ** result,
378 size_t progr_rate,
379 progress_function * progr_fun);
380
381static int mailimap_env_subject_parse(mailstream * fd, MMAPString * buffer,
382 size_t * index, char ** result,
383 size_t progr_rate,
384 progress_function * progr_fun);
385
386
387static int
388mailimap_env_to_parse(mailstream * fd, MMAPString * buffer,
389 size_t * index,
390 struct mailimap_env_to ** result,
391 size_t progr_rate,
392 progress_function * progr_fun);
393
394
395static int mailimap_flag_parse(mailstream * fd, MMAPString * buffer,
396 size_t * index,
397 struct mailimap_flag ** result,
398 size_t progr_rate,
399 progress_function * progr_fun);
400
401static int mailimap_flag_extension_parse(mailstream * fd,
402 MMAPString * buffer,
403 size_t * index,
404 char ** result,
405 size_t progr_rate,
406 progress_function * progr_fun);
407
408
409
410
411static int
412mailimap_flag_fetch_parse(mailstream * fd, MMAPString * buffer,
413 size_t * index,
414 struct mailimap_flag_fetch ** result,
415 size_t progr_rate,
416 progress_function * progr_fun);
417
418
419
420static int
421mailimap_flag_perm_parse(mailstream * fd, MMAPString * buffer,
422 size_t * index,
423 struct mailimap_flag_perm ** result,
424 size_t progr_rate,
425 progress_function * progr_fun);
426
427
428static int mailimap_flag_keyword_parse(mailstream * fd, MMAPString * buffer,
429 size_t * index,
430 char ** result,
431 size_t progr_rate,
432 progress_function * progr_fun);
433
434
435static int mailimap_flag_list_parse(mailstream * fd, MMAPString * buffer,
436 size_t * index,
437 struct mailimap_flag_list ** result,
438 size_t progr_rate,
439 progress_function * progr_fun);
440
441
442static int
443mailimap_header_fld_name_parse(mailstream * fd,
444 MMAPString * buffer,
445 size_t * index,
446 char ** result,
447 size_t progr_rate,
448 progress_function * progr_fun);
449
450
451
452
453static int
454mailimap_header_list_parse(mailstream * fd, MMAPString * buffer,
455 size_t * index,
456 struct mailimap_header_list ** result,
457 size_t progr_rate,
458 progress_function * progr_fun);
459
460static int mailimap_literal_parse(mailstream * fd, MMAPString * buffer,
461 size_t * index, char ** result,
462 size_t * result_len,
463 size_t progr_rate,
464 progress_function * progr_fun);
465
466
467static int
468mailimap_mailbox_parse(mailstream * fd, MMAPString * buffer,
469 size_t * index, char ** result,
470 size_t progr_rate,
471 progress_function * progr_fun);
472
473
474
475
476static int
477mailimap_mailbox_data_parse(mailstream * fd, MMAPString * buffer,
478 size_t * index,
479 struct mailimap_mailbox_data ** result,
480 size_t progr_rate,
481 progress_function * progr_fun);
482
483
484static int
485mailimap_mbx_list_flags_parse(mailstream * fd, MMAPString * buffer,
486 size_t * index,
487 struct mailimap_mbx_list_flags ** result,
488 size_t progr_rate,
489 progress_function * progr_fun);
490
491
492static int
493mailimap_mbx_list_oflag_parse(mailstream * fd, MMAPString * buffer,
494 size_t * index,
495 struct mailimap_mbx_list_oflag ** result,
496 size_t progr_rate,
497 progress_function * progr_fun);
498
499static int
500mailimap_mbx_list_oflag_no_sflag_parse(mailstream * fd, MMAPString * buffer,
501 size_t * index,
502 struct mailimap_mbx_list_oflag ** result,
503 size_t progr_rate,
504 progress_function * progr_fun);
505
506static int
507mailimap_mbx_list_sflag_parse(mailstream * fd, MMAPString * buffer,
508 size_t * index,
509 int * result);
510
511
512static int
513mailimap_mailbox_list_parse(mailstream * fd, MMAPString * buffer,
514 size_t * index,
515 struct mailimap_mailbox_list ** result,
516 size_t progr_rate,
517 progress_function * progr_fun);
518
519
520
521static int
522mailimap_media_basic_parse(mailstream * fd, MMAPString * buffer,
523 size_t * index,
524 struct mailimap_media_basic ** result,
525 size_t progr_rate,
526 progress_function * progr_fun);
527
528static int
529mailimap_media_message_parse(mailstream * fd, MMAPString * buffer,
530 size_t * index);
531
532static int
533mailimap_media_subtype_parse(mailstream * fd, MMAPString * buffer,
534 size_t * index,
535 char ** result,
536 size_t progr_rate,
537 progress_function * progr_fun);
538
539static int mailimap_media_text_parse(mailstream * fd, MMAPString * buffer,
540 size_t * index,
541 char ** result,
542 size_t progr_rate,
543 progress_function * progr_fun);
544
545
546
547static int
548mailimap_message_data_parse(mailstream * fd, MMAPString * buffer,
549 size_t * index,
550 struct mailimap_message_data ** result,
551 size_t progr_rate,
552 progress_function * progr_fun);
553
554
555
556
557
558static int
559mailimap_msg_att_parse(mailstream * fd, MMAPString * buffer,
560 size_t * index, struct mailimap_msg_att ** result,
561 size_t progr_rate,
562 progress_function * progr_fun);
563
564
565
566static int
567mailimap_msg_att_dynamic_parse(mailstream * fd, MMAPString * buffer,
568 size_t * index,
569 struct mailimap_msg_att_dynamic ** result,
570 size_t progr_rate,
571 progress_function * progr_fun);
572
573
574static int
575mailimap_msg_att_static_parse(mailstream * fd, MMAPString * buffer,
576 size_t * index,
577 struct mailimap_msg_att_static ** result,
578 size_t progr_rate,
579 progress_function * progr_fun);
580
581static int mailimap_nil_parse(mailstream * fd, MMAPString * buffer,
582 size_t * index);
583
584static int mailimap_nstring_parse(mailstream * fd, MMAPString * buffer,
585 size_t * index, char ** result,
586 size_t * result_len,
587 size_t progr_rate,
588 progress_function * progr_fun);
589
590static int
591mailimap_number_parse(mailstream * fd, MMAPString * buffer,
592 size_t * index, uint32_t * result);
593
594static int
595mailimap_nz_number_parse(mailstream * fd, MMAPString * buffer,
596 size_t * index, uint32_t * result);
597
598
599static int
600mailimap_quoted_parse(mailstream * fd, MMAPString * buffer,
601 size_t * index, char ** result,
602 size_t progr_rate,
603 progress_function * progr_fun);
604
605static int
606mailimap_quoted_char_parse(mailstream * fd, MMAPString * buffer,
607 size_t * index, char * result);
608
609
610static int
611mailimap_quoted_specials_parse(mailstream * fd, MMAPString * buffer,
612 size_t * index, char * result);
613
614
615
616
617
618static int
619mailimap_response_data_parse(mailstream * fd, MMAPString * buffer,
620 size_t * index,
621 struct mailimap_response_data ** result,
622 size_t progr_rate,
623 progress_function * progr_fun);
624
625
626
627
628static int
629mailimap_response_done_parse(mailstream * fd, MMAPString * buffer,
630 size_t * index,
631 struct mailimap_response_done ** result,
632 size_t progr_rate,
633 progress_function * progr_fun);
634
635static int
636mailimap_response_fatal_parse(mailstream * fd, MMAPString * buffer,
637 size_t * index,
638 struct mailimap_response_fatal ** result,
639 size_t progr_rate,
640 progress_function * progr_fun);
641
642
643static int
644mailimap_response_tagged_parse(mailstream * fd, MMAPString * buffer,
645 size_t * index,
646 struct mailimap_response_tagged ** result,
647 size_t progr_rate,
648 progress_function * progr_fun);
649
650
651static int
652mailimap_resp_cond_auth_parse(mailstream * fd, MMAPString * buffer,
653 size_t * index,
654 struct mailimap_resp_cond_auth ** result,
655 size_t progr_rate,
656 progress_function * progr_fun);
657
658static int
659mailimap_resp_cond_bye_parse(mailstream * fd, MMAPString * buffer,
660 size_t * index,
661 struct mailimap_resp_cond_bye ** result,
662 size_t progr_rate,
663 progress_function * progr_fun);
664
665
666static int
667mailimap_resp_cond_state_parse(mailstream * fd, MMAPString * buffer,
668 size_t * index,
669 struct mailimap_resp_cond_state ** result,
670 size_t progr_rate,
671 progress_function * progr_fun);
672
673
674static int
675mailimap_resp_text_parse(mailstream * fd, MMAPString * buffer,
676 size_t * index,
677 struct mailimap_resp_text ** result,
678 size_t progr_rate,
679 progress_function * progr_fun);
680
681
682static int
683mailimap_resp_text_code_parse(mailstream * fd, MMAPString * buffer,
684 size_t * index,
685 struct mailimap_resp_text_code ** result,
686 size_t progr_rate,
687 progress_function * progr_fun);
688
689
690static int
691mailimap_section_parse(mailstream * fd, MMAPString * buffer,
692 size_t * index,
693 struct mailimap_section ** result,
694 size_t progr_rate,
695 progress_function * progr_fun);
696
697
698static int
699mailimap_section_msgtext_parse(mailstream * fd, MMAPString * buffer,
700 size_t * index,
701 struct mailimap_section_msgtext ** result,
702 size_t progr_rate,
703 progress_function * progr_fun);
704
705
706static int
707mailimap_section_part_parse(mailstream * fd, MMAPString * buffer,
708 size_t * index,
709 struct mailimap_section_part ** result,
710 size_t progr_rate,
711 progress_function * progr_fun);
712
713
714
715
716static int
717mailimap_section_spec_parse(mailstream * fd, MMAPString * buffer,
718 size_t * index,
719 struct mailimap_section_spec ** result,
720 size_t progr_rate,
721 progress_function * progr_fun);
722
723
724static int
725mailimap_section_text_parse(mailstream * fd, MMAPString * buffer,
726 size_t * index,
727 struct mailimap_section_text ** result,
728 size_t progr_rate,
729 progress_function * progr_fun);
730
731
732static int mailimap_status_att_parse(mailstream * fd, MMAPString * buffer,
733 size_t * index, int * result);
734
735static int
736mailimap_string_parse(mailstream * fd, MMAPString * buffer,
737 size_t * index, char ** result,
738 size_t * result_len,
739 size_t progr_rate,
740 progress_function * progr_fun);
741
742static int mailimap_tag_parse(mailstream * fd, MMAPString * buffer,
743 size_t * index, char ** result,
744 size_t progr_rate,
745 progress_function * progr_fun);
746
747static int mailimap_text_parse(mailstream * fd, MMAPString * buffer,
748 size_t * index, char ** result,
749 size_t progr_rate,
750 progress_function * progr_fun);
751
752static int mailimap_time_parse(mailstream * fd, MMAPString * buffer,
753 size_t * index,
754 int * phour, int * pmin, int * psec);
755
756static int mailimap_uniqueid_parse(mailstream * fd, MMAPString * buffer,
757 size_t * index, uint32_t * result);
758
759static int mailimap_zone_parse(mailstream * fd, MMAPString * buffer,
760 size_t * index, int * result);
761
762
763
764/* ************************************************************************* */
765/* ************************************************************************* */
766/* ************************************************************************* */
767/* ************************************************************************* */
768/* ************************************************************************* */
769/* ************************************************************************* */
770
771
772
773
774
775/* ******************** TOOLS **************************** */
776
777
778static int mailimap_unstrict_char_parse(mailstream * fd, MMAPString * buffer,
779 size_t * index, char token)
780{
781 size_t cur_token;
782 int r;
783
784 cur_token = * index;
785
786#ifdef UNSTRICT_SYNTAX
787 /* can accept unstrict syntax */
788
789 mailimap_space_parse(fd, buffer, &cur_token);
790 if (token == ' ') {
791 * index = cur_token;
792 return MAILIMAP_NO_ERROR;
793 }
794#endif
795
796 r = mailimap_char_parse(fd, buffer, &cur_token, token);
797 if (r != MAILIMAP_NO_ERROR)
798 return r;
799
800 * index = cur_token;
801
802 return MAILIMAP_NO_ERROR;
803}
804
805static int mailimap_oparenth_parse(mailstream * fd, MMAPString * buffer,
806 size_t * index)
807{
808 return mailimap_unstrict_char_parse(fd, buffer, index, '(');
809}
810
811static int mailimap_cparenth_parse(mailstream * fd, MMAPString * buffer,
812 size_t * index)
813{
814 return mailimap_unstrict_char_parse(fd, buffer, index, ')');
815}
816
817static int mailimap_oaccolade_parse(mailstream * fd, MMAPString * buffer,
818 size_t * index)
819{
820 return mailimap_unstrict_char_parse(fd, buffer, index, '{');
821}
822
823static int mailimap_caccolade_parse(mailstream * fd, MMAPString * buffer,
824 size_t * index)
825{
826 return mailimap_unstrict_char_parse(fd, buffer, index, '}');
827}
828
829static int mailimap_plus_parse(mailstream * fd, MMAPString * buffer,
830 size_t * index)
831{
832 return mailimap_unstrict_char_parse(fd, buffer, index, '+');
833}
834
835static int mailimap_minus_parse(mailstream * fd, MMAPString * buffer,
836 size_t * index)
837{
838 return mailimap_unstrict_char_parse(fd, buffer, index, '-');
839}
840
841static int mailimap_star_parse(mailstream * fd, MMAPString * buffer,
842 size_t * index)
843{
844 return mailimap_unstrict_char_parse(fd, buffer, index, '*');
845}
846
847static int mailimap_dot_parse(mailstream * fd, MMAPString * buffer,
848 size_t * index)
849{
850 return mailimap_unstrict_char_parse(fd, buffer, index, '.');
851}
852
853static int mailimap_colon_parse(mailstream * fd, MMAPString * buffer,
854 size_t * index)
855{
856 return mailimap_unstrict_char_parse(fd, buffer, index, ':');
857}
858
859static int mailimap_lower_parse(mailstream * fd, MMAPString * buffer,
860 size_t * index)
861{
862 return mailimap_unstrict_char_parse(fd, buffer, index, '<');
863}
864
865static int mailimap_greater_parse(mailstream * fd, MMAPString * buffer,
866 size_t * index)
867{
868 return mailimap_unstrict_char_parse(fd, buffer, index, '>');
869}
870
871static int mailimap_obracket_parse(mailstream * fd, MMAPString * buffer,
872 size_t * index)
873{
874 return mailimap_unstrict_char_parse(fd, buffer, index, '[');
875}
876
877static int mailimap_cbracket_parse(mailstream * fd, MMAPString * buffer,
878 size_t * index)
879{
880 return mailimap_unstrict_char_parse(fd, buffer, index, ']');
881}
882
883static int mailimap_dquote_parse(mailstream * fd, MMAPString * buffer,
884 size_t * index)
885{
886 return mailimap_char_parse(fd, buffer, index, '\"');
887}
888
889static int mailimap_crlf_parse(mailstream * fd, MMAPString * buffer,
890 size_t * index)
891{
892 size_t cur_token = * index;
893
894#ifdef UNSTRICT_SYNTAX
895 mailimap_space_parse(fd, buffer, &cur_token);
896#endif
897
898 if (mailimap_token_case_insensitive_parse(fd, buffer, &cur_token, "\r\n")) {
899 * index = cur_token;
900 return MAILIMAP_NO_ERROR;
901 }
902
903#ifdef UNSTRICT_SYNTAX
904 else if (mailimap_unstrict_char_parse(fd, buffer, &cur_token, '\n')) {
905 * index = cur_token;
906 return MAILIMAP_NO_ERROR;
907 }
908#endif
909
910 else
911 return MAILIMAP_ERROR_PARSE;
912}
913
914typedef int mailimap_struct_parser(mailstream * fd, MMAPString * buffer,
915 size_t * index, void * result,
916 size_t progr_rate,
917 progress_function * progr_fun);
918typedef int mailimap_struct_destructor(void * result);
919
920
921static int
922mailimap_struct_multiple_parse(mailstream * fd, MMAPString * buffer,
923 size_t * index, clist ** result,
924 mailimap_struct_parser * parser,
925 mailimap_struct_destructor * destructor,
926 size_t progr_rate,
927 progress_function * progr_fun)
928{
929 clist * struct_list;
930 size_t cur_token;
931 void * value;
932 int r;
933 int res;
934
935 cur_token = * index;
936
937 r = parser(fd, buffer, &cur_token, &value, progr_rate, progr_fun);
938 if (r != MAILIMAP_NO_ERROR) {
939 res = r;
940 goto err;
941 }
942
943 struct_list = clist_new();
944 if (struct_list == NULL) {
945 destructor(value);
946 res = MAILIMAP_ERROR_MEMORY;
947 goto err;
948 }
949
950 r = clist_append(struct_list, value);
951 if (r < 0) {
952 destructor(value);
953 res = MAILIMAP_ERROR_MEMORY;
954 goto free_list;
955 }
956
957 while (1) {
958 r = parser(fd, buffer, &cur_token, &value, progr_rate, progr_fun);
959 if (r == MAILIMAP_ERROR_PARSE)
960 break;
961 if (r != MAILIMAP_NO_ERROR) {
962 res = r;
963 goto free_list;
964 }
965
966 r = clist_append(struct_list, value);
967 if (r < 0) {
968 destructor(value);
969 res = MAILIMAP_ERROR_MEMORY;
970 goto free_list;
971 }
972 }
973
974 * result = struct_list;
975 * index = cur_token;
976
977 return MAILIMAP_NO_ERROR;
978
979 free_list:
980 clist_foreach(struct_list, (clist_func) destructor, NULL);
981 clist_free(struct_list);
982 err:
983 return res;
984}
985
986static int
987mailimap_struct_list_parse(mailstream * fd, MMAPString * buffer,
988 size_t * index, clist ** result,
989 char symbol,
990 mailimap_struct_parser * parser,
991 mailimap_struct_destructor * destructor,
992 size_t progr_rate,
993 progress_function * progr_fun)
994{
995 clist * struct_list;
996 size_t cur_token;
997 void * value;
998 size_t final_token;
999 int r;
1000 int res;
1001
1002 cur_token = * index;
1003 struct_list = NULL;
1004
1005 r = parser(fd, buffer, &cur_token, &value, progr_rate, progr_fun);
1006 if (r != MAILIMAP_NO_ERROR) {
1007 res = r;
1008 goto err;
1009 }
1010
1011 struct_list = clist_new();
1012 if (struct_list == NULL) {
1013 destructor(value);
1014 res = MAILIMAP_ERROR_MEMORY;
1015 goto err;
1016 }
1017
1018 r = clist_append(struct_list, value);
1019 if (r < 0) {
1020 destructor(value);
1021 res = MAILIMAP_ERROR_MEMORY;
1022 goto free_list;
1023 }
1024
1025 final_token = cur_token;
1026
1027 while (1) {
1028 r = mailimap_unstrict_char_parse(fd, buffer, &cur_token, symbol);
1029 if (r == MAILIMAP_ERROR_PARSE)
1030 break;
1031 if (r != MAILIMAP_NO_ERROR) {
1032 res = r;
1033 goto free_list;
1034 }
1035
1036 r = parser(fd, buffer, &cur_token, &value, progr_rate, progr_fun);
1037 if (r == MAILIMAP_ERROR_PARSE)
1038 break;
1039
1040 if (r != MAILIMAP_NO_ERROR) {
1041 res = r;
1042 goto free_list;
1043 }
1044
1045 r = clist_append(struct_list, value);
1046 if (r < 0) {
1047 destructor(value);
1048 res = MAILIMAP_ERROR_MEMORY;
1049 goto free_list;
1050 }
1051
1052 final_token = cur_token;
1053 }
1054
1055 * result = struct_list;
1056 * index = final_token;
1057
1058 return MAILIMAP_NO_ERROR;
1059
1060 free_list:
1061 clist_foreach(struct_list, (clist_func) destructor, NULL);
1062 clist_free(struct_list);
1063 err:
1064 return res;
1065}
1066
1067static int
1068mailimap_struct_spaced_list_parse(mailstream * fd, MMAPString * buffer,
1069 size_t * index, clist ** result,
1070 mailimap_struct_parser * parser,
1071 mailimap_struct_destructor * destructor,
1072 size_t progr_rate,
1073 progress_function * progr_fun)
1074{
1075 return mailimap_struct_list_parse(fd, buffer, index, result,
1076 ' ', parser, destructor,
1077 progr_rate, progr_fun);
1078}
1079
1080
1081
1082static int
1083mailimap_custom_string_parse(mailstream * fd, MMAPString * buffer,
1084 size_t * index, char ** result,
1085 int (* is_custom_char)(char))
1086{
1087 size_t begin;
1088 size_t end;
1089 char * gstr;
1090
1091 begin = * index;
1092
1093#ifdef UNSTRICT_SYNTAX
1094 mailimap_space_parse(fd, buffer, &begin);
1095#endif
1096
1097 end = begin;
1098
1099 while (is_custom_char(buffer->str[end]))
1100 end ++;
1101
1102 if (end != begin) {
1103 gstr = malloc(end - begin + 1);
1104 if (gstr == NULL)
1105 return MAILIMAP_ERROR_MEMORY;
1106
1107 strncpy(gstr, buffer->str + begin, end - begin);
1108 gstr[end - begin] = '\0';
1109
1110 * index = end;
1111 * result = gstr;
1112 return MAILIMAP_NO_ERROR;
1113 }
1114 else
1115 return MAILIMAP_ERROR_PARSE;
1116}
1117
1118
1119
1120static int
1121mailimap_nz_number_alloc_parse(mailstream * fd, MMAPString * buffer,
1122 size_t * index,
1123 uint32_t ** result,
1124 size_t progr_rate,
1125 progress_function * progr_fun)
1126{
1127 uint32_t number;
1128 uint32_t * number_alloc;
1129 size_t cur_token;
1130 int r;
1131
1132 cur_token = * index;
1133
1134 r = mailimap_nz_number_parse(fd, buffer, &cur_token, &number);
1135 if (r != MAILIMAP_NO_ERROR)
1136 return r;
1137
1138 number_alloc = mailimap_number_alloc_new(number);
1139 if (number_alloc == NULL)
1140 return MAILIMAP_ERROR_MEMORY;
1141
1142 * index = cur_token;
1143 * result = number_alloc;
1144
1145 return MAILIMAP_NO_ERROR;
1146}
1147
1148
1149static int is_ctl(char ch)
1150{
1151 unsigned char uch = (unsigned char) ch;
1152
1153 return (uch <= 0x1F);
1154}
1155
1156static int is_char(char ch)
1157{
1158#ifdef UNSTRICT_SYNTAX
1159 return (ch != 0);
1160#else
1161 unsigned char uch = ch;
1162
1163 return (uch >= 0x01) && (uch <= 0x7f);
1164#endif
1165}
1166
1167static int is_alpha(char ch)
1168{
1169 return ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && (ch <= 'z')));
1170}
1171
1172static int is_digit(char ch)
1173{
1174 return (ch >= '0') && (ch <= '9');
1175}
1176
1177static int mailimap_digit_parse(mailstream * fd, MMAPString * buffer,
1178 size_t * index, int * result)
1179{
1180 size_t cur_token;
1181
1182 cur_token = * index;
1183
1184 if (is_digit(buffer->str[cur_token])) {
1185 * result = buffer->str[cur_token] - '0';
1186 cur_token ++;
1187 * index = cur_token;
1188 return MAILIMAP_NO_ERROR;
1189 }
1190 else
1191 return MAILIMAP_ERROR_PARSE;
1192}
1193
1194
1195/* ******************** parser **************************** */
1196
1197/*
1198 address = "(" addr-name SP addr-adl SP addr-mailbox SP
1199 addr-host ")"
1200*/
1201
1202static int mailimap_address_parse(mailstream * fd, MMAPString * buffer,
1203 size_t * index,
1204 struct mailimap_address ** result,
1205 size_t progr_rate,
1206 progress_function * progr_fun)
1207{
1208 size_t cur_token;
1209 char * addr_name;
1210 char * addr_adl;
1211 char * addr_mailbox;
1212 char * addr_host;
1213 struct mailimap_address * addr;
1214 int r;
1215 int res;
1216
1217 cur_token = * index;
1218
1219 addr_name = NULL;
1220 addr_adl = NULL;
1221 addr_mailbox = NULL;
1222 addr_host = NULL;
1223
1224 r = mailimap_oparenth_parse(fd, buffer, &cur_token);
1225 if (r != MAILIMAP_NO_ERROR) {
1226 res = r;
1227 goto err;
1228 }
1229
1230 r = mailimap_addr_name_parse(fd, buffer, &cur_token, &addr_name,
1231 progr_rate, progr_fun);
1232 if (r != MAILIMAP_NO_ERROR) {
1233 res = r;
1234 goto err;
1235 }
1236
1237 r = mailimap_space_parse(fd, buffer, &cur_token);
1238 if (r != MAILIMAP_NO_ERROR) {
1239 res = r;
1240 goto addr_name_free;
1241 }
1242
1243 r = mailimap_addr_adl_parse(fd, buffer, &cur_token, &addr_adl,
1244 progr_rate, progr_fun);
1245 if (r != MAILIMAP_NO_ERROR) {
1246 res = r;
1247 goto addr_name_free;
1248 }
1249
1250 r = mailimap_space_parse(fd, buffer, &cur_token);
1251 if (r != MAILIMAP_NO_ERROR) {
1252 res = r;
1253 goto addr_adl_free;
1254 }
1255
1256 r = mailimap_addr_mailbox_parse(fd, buffer, &cur_token, &addr_mailbox,
1257 progr_rate, progr_fun);
1258 if (r != MAILIMAP_NO_ERROR) {
1259 res = r;
1260 goto addr_adl_free;
1261 }
1262
1263 r = mailimap_space_parse(fd, buffer, &cur_token);
1264 if (r != MAILIMAP_NO_ERROR) {
1265 res = r;
1266 goto addr_mailbox_free;
1267 }
1268
1269 r = mailimap_addr_host_parse(fd, buffer, &cur_token, &addr_host,
1270 progr_rate, progr_fun);
1271 if (r != MAILIMAP_NO_ERROR) {
1272 res = r;
1273 goto addr_mailbox_free;
1274 }
1275
1276 r = mailimap_cparenth_parse(fd, buffer, &cur_token);
1277 if (r != MAILIMAP_NO_ERROR) {
1278 res = r;
1279 goto addr_host_free;
1280 }
1281
1282 addr = mailimap_address_new(addr_name, addr_adl, addr_mailbox, addr_host);
1283
1284 if (addr == NULL) {
1285 res = MAILIMAP_ERROR_MEMORY;
1286 goto addr_host_free;
1287 }
1288
1289 * result = addr;
1290 * index = cur_token;
1291
1292 return MAILIMAP_NO_ERROR;
1293
1294 addr_host_free:
1295 mailimap_addr_host_free(addr_host);
1296 addr_mailbox_free:
1297 mailimap_addr_mailbox_free(addr_mailbox);
1298 addr_adl_free:
1299 mailimap_addr_adl_free(addr_adl);
1300 addr_name_free:
1301 mailimap_addr_name_free(addr_name);
1302 err:
1303 return res;
1304}
1305
1306/*
1307 addr-adl = nstring
1308 ; Holds route from [RFC-822] route-addr if
1309 ; non-NIL
1310*/
1311
1312static int mailimap_addr_adl_parse(mailstream * fd, MMAPString * buffer,
1313 size_t * index, char ** result,
1314 size_t progr_rate,
1315 progress_function * progr_fun)
1316{
1317 return mailimap_nstring_parse(fd, buffer, index, result, NULL,
1318 progr_rate, progr_fun);
1319}
1320
1321/*
1322 addr-host = nstring
1323 ; NIL indicates [RFC-822] group syntax.
1324 ; Otherwise, holds [RFC-822] domain name
1325*/
1326
1327static int mailimap_addr_host_parse(mailstream * fd, MMAPString * buffer,
1328 size_t * index, char ** result,
1329 size_t progr_rate,
1330 progress_function * progr_fun)
1331{
1332 return mailimap_nstring_parse(fd, buffer, index, result, NULL,
1333 progr_rate, progr_fun);
1334}
1335
1336/*
1337 addr-mailbox = nstring
1338 ; NIL indicates end of [RFC-822] group; if
1339 ; non-NIL and addr-host is NIL, holds
1340 ; [RFC-822] group name.
1341 ; Otherwise, holds [RFC-822] local-part
1342 ; after removing [RFC-822] quoting
1343 */
1344
1345static int mailimap_addr_mailbox_parse(mailstream * fd, MMAPString * buffer,
1346 size_t * index, char ** result,
1347 size_t progr_rate,
1348 progress_function * progr_fun)
1349{
1350 return mailimap_nstring_parse(fd, buffer, index, result, NULL,
1351 progr_rate, progr_fun);
1352}
1353
1354
1355/*
1356 addr-name = nstring
1357 ; If non-NIL, holds phrase from [RFC-822]
1358 ; mailbox after removing [RFC-822] quoting
1359*/
1360
1361static int mailimap_addr_name_parse(mailstream * fd, MMAPString * buffer,
1362 size_t * index, char ** result,
1363 size_t progr_rate,
1364 progress_function * progr_fun)
1365{
1366 return mailimap_nstring_parse(fd, buffer, index, result, NULL,
1367 progr_rate, progr_fun);
1368}
1369
1370
1371/*
1372 NOT IMPLEMENTED
1373 append = "APPEND" SP mailbox [SP flag-list] [SP date-time] SP
1374 literal
1375*/
1376
1377/*
1378 astring = 1*ASTRING-CHAR / string
1379*/
1380
1381static int is_astring_char(char ch);
1382
1383static int
1384mailimap_atom_astring_parse(mailstream * fd, MMAPString * buffer,
1385 size_t * index, char ** result,
1386 size_t progr_rate,
1387 progress_function * progr_fun)
1388{
1389 return mailimap_custom_string_parse(fd, buffer, index, result,
1390 is_astring_char);
1391}
1392
1393static int
1394mailimap_astring_parse(mailstream * fd, MMAPString * buffer,
1395 size_t * index,
1396 char ** result,
1397 size_t progr_rate,
1398 progress_function * progr_fun)
1399{
1400 size_t cur_token;
1401 char * astring;
1402 int r;
1403
1404 cur_token = * index;
1405
1406 r = mailimap_atom_astring_parse(fd, buffer, &cur_token, &astring,
1407 progr_rate, progr_fun);
1408 switch (r) {
1409 case MAILIMAP_NO_ERROR:
1410 break;
1411
1412 case MAILIMAP_ERROR_PARSE:
1413 r = mailimap_string_parse(fd, buffer, &cur_token, &astring, NULL,
1414 progr_rate, progr_fun);
1415 if (r != MAILIMAP_NO_ERROR)
1416 return r;
1417 break;
1418
1419 default:
1420 return r;
1421 }
1422
1423 * result = astring;
1424 * index = cur_token;
1425
1426 return MAILIMAP_NO_ERROR;
1427}
1428
1429/*
1430 ASTRING-CHAR = ATOM-CHAR / resp-specials
1431*/
1432
1433static int is_atom_char(char ch);
1434static int is_resp_specials(char ch);
1435
1436static int is_astring_char(char ch)
1437{
1438 if (is_atom_char(ch))
1439 return TRUE;
1440 if (is_resp_specials(ch))
1441 return TRUE;
1442 return FALSE;
1443}
1444
1445/*
1446 atom = 1*ATOM-CHAR
1447*/
1448
1449static int mailimap_atom_parse(mailstream * fd, MMAPString * buffer,
1450 size_t * index, char ** result,
1451 size_t progr_rate,
1452 progress_function * progr_fun)
1453{
1454 return mailimap_custom_string_parse(fd, buffer, index, result,
1455 is_atom_char);
1456}
1457
1458/*
1459 ATOM-CHAR = <any CHAR except atom-specials>
1460*/
1461
1462static int is_atom_specials(char ch);
1463
1464static int is_atom_char(char ch)
1465{
1466 if (is_atom_specials(ch))
1467 return FALSE;
1468
1469 return is_char(ch);
1470}
1471
1472/*
1473 atom-specials = "(" / ")" / "{" / SP / CTL / list-wildcards /
1474 quoted-specials / resp-specials
1475
1476no "}" because there is no need (Mark Crispin)
1477*/
1478
1479static int is_quoted_specials(char ch);
1480static int is_list_wildcards(char ch);
1481
1482static int is_atom_specials(char ch)
1483{
1484 switch (ch) {
1485 case '(':
1486 case ')':
1487 case '{':
1488 case ' ':
1489 return TRUE;
1490 };
1491 if (is_ctl(ch))
1492 return TRUE;
1493 if (is_list_wildcards(ch))
1494 return TRUE;
1495 if (is_resp_specials(ch))
1496 return TRUE;
1497
1498 return is_quoted_specials(ch);
1499}
1500
1501/*
1502 NOT IMPLEMENTED
1503 authenticate = "AUTHENTICATE" SP auth-type *(CRLF base64)
1504*/
1505
1506/*
1507 auth-type = atom
1508 ; Defined by [SASL]
1509*/
1510
1511static int mailimap_auth_type_parse(mailstream * fd, MMAPString * buffer,
1512 size_t * index, char ** result,
1513 size_t progr_rate,
1514 progress_function * progr_fun)
1515{
1516 return mailimap_atom_parse(fd, buffer, index, result,
1517 progr_rate, progr_fun);
1518}
1519
1520/*
1521 base64 = *(4base64-char) [base64-terminal]
1522*/
1523
1524static int is_base64_4char(char * str);
1525static int is_base64_terminal(char * str);
1526
1527static int mailimap_base64_parse(mailstream * fd, MMAPString * buffer,
1528 size_t * index, char ** result,
1529 size_t progr_rate,
1530 progress_function * progr_fun)
1531{
1532 size_t begin;
1533 size_t end;
1534 char * gstr;
1535
1536 begin = * index;
1537 end = begin;
1538
1539 while (is_base64_4char(buffer->str + end))
1540 end += 4;
1541 if (is_base64_terminal(buffer->str + end))
1542 end += 4;
1543 else
1544 return MAILIMAP_ERROR_PARSE;
1545
1546 gstr = malloc(end - begin + 1);
1547 if (gstr == NULL)
1548 return MAILIMAP_ERROR_MEMORY;
1549 strncpy(gstr, buffer->str + begin, end - begin);
1550 gstr[end - begin] = '\0';
1551
1552 * result = gstr;
1553 * index = end;
1554
1555 return MAILIMAP_NO_ERROR;
1556}
1557
1558/*
1559 base64-char = ALPHA / DIGIT / "+" / "/"
1560 ; Case-sensitive
1561*/
1562
1563static int is_base64_char(char ch)
1564{
1565 return (is_alpha(ch) || is_digit(ch) || ch == '+' || ch == '/');
1566}
1567
1568static int is_base64_4char(char * str)
1569{
1570 size_t i;
1571
1572 for (i = 0 ; i < 4 ; i++)
1573 if (!is_base64_char(str[i]))
1574 return FALSE;
1575 return TRUE;
1576}
1577
1578/*
1579 base64-terminal = (2base64-char "==") / (3base64-char "=")
1580*/
1581
1582static int is_base64_terminal(char * str)
1583{
1584 if (str[0] == 0)
1585 return FALSE;
1586 if (str[1] == 0)
1587 return FALSE;
1588 if (str[2] == 0)
1589 return FALSE;
1590 if (str[3] == 0)
1591 return FALSE;
1592
1593 if (is_base64_char(str[0]) || is_base64_char(str[1])
1594 || str[2] == '=' || str[3] == '=')
1595 return TRUE;
1596 if (is_base64_char(str[0]) || is_base64_char(str[1])
1597 || is_base64_char(str[2]) || str[3] == '=')
1598 return TRUE;
1599 return FALSE;
1600}
1601
1602
1603/*
1604 body = "(" (body-type-1part / body-type-mpart) ")"
1605*/
1606
1607static int mailimap_body_parse(mailstream * fd, MMAPString * buffer,
1608 size_t * index,
1609 struct mailimap_body ** result,
1610 size_t progr_rate,
1611 progress_function * progr_fun)
1612{
1613 struct mailimap_body_type_1part * body_type_1part;
1614 struct mailimap_body_type_mpart * body_type_mpart;
1615 struct mailimap_body * body;
1616 size_t cur_token;
1617 int type;
1618 int r;
1619 int res;
1620
1621 cur_token = * index;
1622
1623 body_type_1part = NULL;
1624 body_type_mpart = NULL;
1625
1626 r = mailimap_oparenth_parse(fd, buffer, &cur_token);
1627 if (r != MAILIMAP_NO_ERROR) {
1628 res = r;
1629 goto err;
1630 }
1631
1632 type = MAILIMAP_BODY_ERROR; /* XXX - removes a gcc warning */
1633
1634 r = mailimap_body_type_1part_parse(fd, buffer, &cur_token, &body_type_1part,
1635 progr_rate, progr_fun);
1636 if (r == MAILIMAP_NO_ERROR)
1637 type = MAILIMAP_BODY_1PART;
1638
1639 if (r == MAILIMAP_ERROR_PARSE) {
1640 r = mailimap_body_type_mpart_parse(fd, buffer, &cur_token,
1641 &body_type_mpart,
1642 progr_rate, progr_fun);
1643
1644 if (r == MAILIMAP_NO_ERROR)
1645 type = MAILIMAP_BODY_MPART;
1646 }
1647
1648 if (r != MAILIMAP_NO_ERROR) {
1649 res = r;
1650 goto err;
1651 }
1652
1653 r = mailimap_cparenth_parse(fd, buffer, &cur_token);
1654 if (r != MAILIMAP_NO_ERROR) {
1655 res = r;
1656 goto free;
1657 }
1658
1659 body = mailimap_body_new(type, body_type_1part, body_type_mpart);
1660 if (body == NULL) {
1661 res = MAILIMAP_ERROR_MEMORY;
1662 goto free;
1663 }
1664
1665 * result = body;
1666 * index = cur_token;
1667
1668 return MAILIMAP_NO_ERROR;
1669
1670 free:
1671 if (body_type_1part)
1672 mailimap_body_type_1part_free(body_type_1part);
1673 if (body_type_mpart)
1674 mailimap_body_type_mpart_free(body_type_mpart);
1675 err:
1676 return res;
1677}
1678
1679/*
1680 body-extension = nstring / number /
1681 "(" body-extension *(SP body-extension) ")"
1682 ; Future expansion. Client implementations
1683 ; MUST accept body-extension fields. Server
1684 ; implementations MUST NOT generate
1685 ; body-extension fields except as defined by
1686 ; future standard or standards-track
1687 ; revisions of this specification.
1688*/
1689
1690/*
1691 "(" body-extension *(SP body-extension) ")"
1692*/
1693
1694static int
1695mailimap_body_ext_list_parse(mailstream * fd, MMAPString * buffer,
1696 size_t * index,
1697 clist ** result,
1698 size_t progr_rate,
1699 progress_function * progr_fun)
1700{
1701 size_t cur_token;
1702 clist * list;
1703 int r;
1704 int res;
1705
1706 cur_token = * index;
1707
1708 r = mailimap_oparenth_parse(fd, buffer, &cur_token);
1709 if (r != MAILIMAP_NO_ERROR) {
1710 res = r;
1711 goto err;
1712 }
1713
1714 r = mailimap_struct_spaced_list_parse(fd, buffer,
1715 &cur_token, &list,
1716 (mailimap_struct_parser * )
1717 mailimap_body_extension_parse,
1718 (mailimap_struct_destructor * )
1719 mailimap_body_extension_free,
1720 progr_rate, progr_fun);
1721 if (r != MAILIMAP_NO_ERROR) {
1722 res = r;
1723 goto err;
1724 }
1725
1726 r = mailimap_cparenth_parse(fd, buffer, &cur_token);
1727 if (r != MAILIMAP_NO_ERROR) {
1728 res = r;
1729 goto free_list;
1730 }
1731
1732 * index = cur_token;
1733 * result = list;
1734
1735 return MAILIMAP_NO_ERROR;
1736
1737 free_list:
1738 clist_foreach(list, (clist_func) mailimap_body_extension_free, NULL);
1739 clist_free(list);
1740 err:
1741 return res;
1742}
1743
1744/*
1745 body-extension = nstring / number /
1746 "(" body-extension *(SP body-extension) ")"
1747 ; Future expansion. Client implementations
1748 ; MUST accept body-extension fields. Server
1749 ; implementations MUST NOT generate
1750 ; body-extension fields except as defined by
1751 ; future standard or standards-track
1752 ; revisions of this specification.
1753*/
1754
1755static int
1756mailimap_body_extension_parse(mailstream * fd, MMAPString * buffer,
1757 size_t * index,
1758 struct mailimap_body_extension ** result,
1759 size_t progr_rate,
1760 progress_function * progr_fun)
1761{
1762 size_t cur_token;
1763 uint32_t number;
1764 char * nstring;
1765 clist * body_extension_list;
1766 struct mailimap_body_extension * body_extension;
1767 int type;
1768 int r;
1769 int res;
1770
1771 cur_token = * index;
1772
1773 nstring = NULL;
1774 number = 0;
1775 body_extension_list = NULL;
1776 type = MAILIMAP_BODY_EXTENSION_ERROR; /* XXX - removes a gcc warning */
1777
1778 r = mailimap_nstring_parse(fd, buffer, &cur_token, &nstring, NULL,
1779 progr_rate, progr_fun);
1780 if (r == MAILIMAP_NO_ERROR)
1781 type = MAILIMAP_BODY_EXTENSION_NSTRING;
1782
1783 if (r == MAILIMAP_ERROR_PARSE) {
1784 r = mailimap_number_parse(fd, buffer, &cur_token, &number);
1785
1786 if (r == MAILIMAP_NO_ERROR)
1787 type = MAILIMAP_BODY_EXTENSION_NUMBER;
1788 }
1789
1790 if (r == MAILIMAP_ERROR_PARSE) {
1791 r = mailimap_body_ext_list_parse(fd, buffer, &cur_token,
1792 &body_extension_list,
1793 progr_rate, progr_fun);
1794
1795 if (r == MAILIMAP_NO_ERROR)
1796 type = MAILIMAP_BODY_EXTENSION_LIST;
1797 }
1798
1799 if (r != MAILIMAP_NO_ERROR) {
1800 res = r;
1801 goto err;
1802 }
1803
1804 body_extension = mailimap_body_extension_new(type, nstring, number,
1805 body_extension_list);
1806
1807 if (body_extension == NULL) {
1808 res = MAILIMAP_ERROR_MEMORY;
1809 goto free;
1810 }
1811
1812 * result = body_extension;
1813 * index = cur_token;
1814
1815 return MAILIMAP_NO_ERROR;
1816
1817 free:
1818 if (nstring != NULL)
1819 mailimap_nstring_free(nstring);
1820 if (body_extension_list) {
1821 clist_foreach(body_extension_list,
1822 (clist_func) mailimap_body_extension_free,
1823 NULL);
1824 clist_free(body_extension_list);
1825 }
1826 err:
1827 return res;
1828}
1829
1830/*
1831 body-ext-1part = body-fld-md5 [SP body-fld-dsp [SP body-fld-lang
1832 *(SP body-extension)]]
1833 ; MUST NOT be returned on non-extensible
1834 ; "BODY" fetch
1835*/
1836
1837/*
1838 *(SP body-extension)
1839*/
1840
1841static int
1842mailimap_body_ext_1part_3_parse(mailstream * fd, MMAPString * buffer,
1843 size_t * index,
1844 clist ** body_ext_list,
1845 size_t progr_rate,
1846 progress_function * progr_fun)
1847{
1848 size_t cur_token;
1849 int r;
1850
1851 cur_token = * index;
1852 * body_ext_list = NULL;
1853
1854 r = mailimap_space_parse(fd, buffer, &cur_token);
1855 if (r != MAILIMAP_NO_ERROR)
1856 return r;
1857
1858 r = mailimap_struct_spaced_list_parse(fd, buffer, &cur_token,
1859 body_ext_list,
1860 (mailimap_struct_parser *)
1861 mailimap_body_extension_parse,
1862 (mailimap_struct_destructor *)
1863 mailimap_body_extension_free,
1864 progr_rate, progr_fun);
1865 if (r != MAILIMAP_NO_ERROR)
1866 return r;
1867
1868 * index = cur_token;
1869
1870 return MAILIMAP_NO_ERROR;
1871}
1872
1873
1874/*
1875 [SP body-fld-lang
1876 *(SP body-extension)]]
1877*/
1878
1879static int
1880mailimap_body_ext_1part_2_parse(mailstream * fd, MMAPString * buffer,
1881 size_t * index,
1882 struct mailimap_body_fld_lang ** fld_lang,
1883 clist ** body_ext_list,
1884 size_t progr_rate,
1885 progress_function * progr_fun)
1886{
1887 size_t cur_token;
1888 int r;
1889
1890 cur_token = * index;
1891 * fld_lang = NULL;
1892 * body_ext_list = NULL;
1893
1894 r = mailimap_space_parse(fd, buffer, &cur_token);
1895 if (r != MAILIMAP_NO_ERROR)
1896 return r;
1897
1898 r = mailimap_body_fld_lang_parse(fd, buffer, &cur_token, fld_lang,
1899 progr_rate, progr_fun);
1900 if (r != MAILIMAP_NO_ERROR)
1901 return r;
1902
1903 r = mailimap_body_ext_1part_3_parse(fd, buffer, &cur_token,
1904 body_ext_list, progr_rate, progr_fun);
1905 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE))
1906 return r;
1907
1908 * index = cur_token;
1909
1910 return MAILIMAP_NO_ERROR;
1911}
1912
1913
1914/*
1915 SP body-fld-dsp [SP body-fld-lang
1916 *(SP body-extension)]]
1917*/
1918
1919static int
1920mailimap_body_ext_1part_1_parse(mailstream * fd, MMAPString * buffer,
1921 size_t * index,
1922 struct mailimap_body_fld_dsp ** fld_dsp,
1923 struct mailimap_body_fld_lang ** fld_lang,
1924 clist ** body_ext_list,
1925 size_t progr_rate,
1926 progress_function * progr_fun)
1927{
1928 size_t cur_token;
1929 int r;
1930
1931 cur_token = * index;
1932 * fld_dsp = NULL;
1933 * fld_lang = NULL;
1934 * body_ext_list = NULL;
1935
1936 r = mailimap_space_parse(fd, buffer, &cur_token);
1937 if (r != MAILIMAP_NO_ERROR)
1938 return r;
1939
1940 r = mailimap_body_fld_dsp_parse(fd, buffer, &cur_token, fld_dsp,
1941 progr_rate, progr_fun);
1942 if (r != MAILIMAP_NO_ERROR)
1943 return r;
1944
1945 r = mailimap_body_ext_1part_2_parse(fd, buffer, &cur_token,
1946 fld_lang, body_ext_list,
1947 progr_rate, progr_fun);
1948 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE))
1949 return r;
1950
1951 * index = cur_token;
1952
1953 return MAILIMAP_NO_ERROR;
1954}
1955
1956/*
1957 body-ext-1part = body-fld-md5 [SP body-fld-dsp [SP body-fld-lang
1958 *(SP body-extension)]]
1959 ; MUST NOT be returned on non-extensible
1960 ; "BODY" fetch
1961*/
1962
1963static int
1964mailimap_body_ext_1part_parse(mailstream * fd, MMAPString * buffer,
1965 size_t * index,
1966 struct mailimap_body_ext_1part ** result,
1967 size_t progr_rate,
1968 progress_function * progr_fun)
1969{
1970 size_t cur_token;
1971
1972 char * fld_md5;
1973 struct mailimap_body_fld_dsp * fld_dsp;
1974 struct mailimap_body_fld_lang * fld_lang;
1975 clist * body_ext_list;
1976 int r;
1977 int res;
1978
1979 struct mailimap_body_ext_1part * ext_1part;
1980
1981 cur_token = * index;
1982
1983 fld_md5 = NULL;
1984 fld_dsp = NULL;
1985 fld_lang = NULL;
1986 body_ext_list = NULL;
1987
1988 r = mailimap_body_fld_md5_parse(fd, buffer, &cur_token, &fld_md5,
1989 progr_rate, progr_fun);
1990 if (r != MAILIMAP_NO_ERROR) {
1991 res = r;
1992 goto err;
1993 }
1994
1995 r = mailimap_body_ext_1part_1_parse(fd, buffer, &cur_token,
1996 &fld_dsp,
1997 &fld_lang,
1998 &body_ext_list,
1999 progr_rate, progr_fun);
2000 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) {
2001 res = r;
2002 goto free;
2003 }
2004
2005 ext_1part = mailimap_body_ext_1part_new(fld_md5, fld_dsp, fld_lang,
2006 body_ext_list);
2007
2008 if (ext_1part == NULL) {
2009 res = MAILIMAP_ERROR_MEMORY;
2010 goto free;
2011 }
2012
2013 * result = ext_1part;
2014 * index = cur_token;
2015
2016 return MAILIMAP_NO_ERROR;
2017
2018 free:
2019 if (body_ext_list) {
2020 clist_foreach(body_ext_list, (clist_func) mailimap_body_extension_free,
2021 NULL);
2022 clist_free(body_ext_list);
2023 }
2024 if (fld_lang)
2025 mailimap_body_fld_lang_free(fld_lang);
2026 if (fld_dsp)
2027 mailimap_body_fld_dsp_free(fld_dsp);
2028 mailimap_body_fld_md5_free(fld_md5);
2029 err:
2030 return res;
2031}
2032
2033
2034/*
2035 body-ext-mpart = body-fld-param [SP body-fld-dsp [SP body-fld-lang
2036 *(SP body-extension)]]
2037 ; MUST NOT be returned on non-extensible
2038 ; "BODY" fetch
2039*/
2040
2041static int
2042mailimap_body_ext_mpart_parse(mailstream * fd, MMAPString * buffer,
2043 size_t * index,
2044 struct mailimap_body_ext_mpart ** result,
2045 size_t progr_rate,
2046 progress_function * progr_fun)
2047{
2048 size_t cur_token;
2049
2050 struct mailimap_body_fld_dsp * fld_dsp;
2051 struct mailimap_body_fld_lang * fld_lang;
2052 struct mailimap_body_fld_param * fld_param;
2053 clist * body_ext_list;
2054
2055 struct mailimap_body_ext_mpart * ext_mpart;
2056 int r;
2057 int res;
2058
2059 cur_token = * index;
2060
2061 fld_param = NULL;
2062 fld_dsp = NULL;
2063 fld_lang = NULL;
2064 body_ext_list = NULL;
2065
2066 r = mailimap_body_fld_param_parse(fd, buffer, &cur_token, &fld_param,
2067 progr_rate, progr_fun);
2068 if (r != MAILIMAP_NO_ERROR) {
2069 res = r;
2070 goto err;
2071 }
2072
2073 r = mailimap_body_ext_1part_1_parse(fd, buffer, &cur_token,
2074 &fld_dsp,
2075 &fld_lang,
2076 &body_ext_list,
2077 progr_rate, progr_fun);
2078 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) {
2079 res = r;
2080 goto free;
2081 }
2082
2083 ext_mpart = mailimap_body_ext_mpart_new(fld_param, fld_dsp, fld_lang,
2084 body_ext_list);
2085 if (ext_mpart == NULL) {
2086 res = MAILIMAP_ERROR_MEMORY;
2087 goto free;
2088 }
2089
2090 * result = ext_mpart;
2091 * index = cur_token;
2092
2093 return MAILIMAP_NO_ERROR;
2094
2095 free:
2096 if (body_ext_list) {
2097 clist_foreach(body_ext_list, (clist_func) mailimap_body_extension_free,
2098 NULL);
2099 clist_free(body_ext_list);
2100 }
2101 if (fld_lang)
2102 mailimap_body_fld_lang_free(fld_lang);
2103 if (fld_dsp)
2104 mailimap_body_fld_dsp_free(fld_dsp);
2105 if (fld_param != NULL)
2106 mailimap_body_fld_param_free(fld_param);
2107 err:
2108 return res;
2109}
2110
2111/*
2112 body-fields = body-fld-param SP body-fld-id SP body-fld-desc SP
2113 body-fld-enc SP body-fld-octets
2114*/
2115
2116static int
2117mailimap_body_fields_parse(mailstream * fd, MMAPString * buffer,
2118 size_t * index,
2119 struct mailimap_body_fields ** result,
2120 size_t progr_rate,
2121 progress_function * progr_fun)
2122{
2123 struct mailimap_body_fields * body_fields;
2124 size_t cur_token;
2125 struct mailimap_body_fld_param * body_fld_param;
2126 char * body_fld_id;
2127 char * body_fld_desc;
2128 struct mailimap_body_fld_enc * body_fld_enc;
2129 uint32_t body_fld_octets;
2130 int r;
2131 int res;
2132
2133 body_fld_param = NULL;
2134 body_fld_id = NULL;
2135 body_fld_desc = NULL;
2136 body_fld_enc = NULL;
2137 body_fld_octets = 0;
2138
2139 cur_token = * index;
2140
2141 r = mailimap_body_fld_param_parse(fd, buffer, &cur_token, &body_fld_param,
2142 progr_rate, progr_fun);
2143 if (r != MAILIMAP_NO_ERROR) {
2144 res = r;
2145 goto err;
2146 }
2147
2148 r = mailimap_space_parse(fd, buffer, &cur_token);
2149 if (r != MAILIMAP_NO_ERROR) {
2150 res = r;
2151 goto fld_param_free;
2152 }
2153
2154 r = mailimap_body_fld_id_parse(fd, buffer, &cur_token, &body_fld_id,
2155 progr_rate, progr_fun);
2156 if (r != MAILIMAP_NO_ERROR) {
2157 res = r;
2158 goto fld_param_free;
2159 }
2160
2161 r = mailimap_space_parse(fd, buffer, &cur_token);
2162 if (r != MAILIMAP_NO_ERROR) {
2163 res = r;
2164 goto fld_id_free;
2165 }
2166
2167 r = mailimap_body_fld_desc_parse(fd, buffer, &cur_token, &body_fld_desc,
2168 progr_rate, progr_fun);
2169 if (r != MAILIMAP_NO_ERROR) {
2170 res = r;
2171 goto fld_id_free;
2172 }
2173
2174 r = mailimap_space_parse(fd, buffer, &cur_token);
2175 if (r != MAILIMAP_NO_ERROR) {
2176 res = r;
2177 goto fld_desc_free;
2178 }
2179
2180 r = mailimap_body_fld_enc_parse(fd, buffer, &cur_token, &body_fld_enc,
2181 progr_rate, progr_fun);
2182 if (r != MAILIMAP_NO_ERROR) {
2183 res = r;
2184 goto fld_desc_free;
2185 }
2186
2187 r = mailimap_space_parse(fd, buffer, &cur_token);
2188 if (r != MAILIMAP_NO_ERROR) {
2189 res = r;
2190 goto fld_enc_free;
2191 }
2192
2193 r = mailimap_body_fld_octets_parse(fd, buffer, &cur_token,
2194 &body_fld_octets);
2195 if (r != MAILIMAP_NO_ERROR) {
2196 res = r;
2197 goto fld_enc_free;
2198 }
2199
2200 body_fields = mailimap_body_fields_new(body_fld_param,
2201 body_fld_id,
2202 body_fld_desc,
2203 body_fld_enc,
2204 body_fld_octets);
2205 if (body_fields == NULL) {
2206 res = MAILIMAP_ERROR_MEMORY;
2207 goto fld_enc_free;
2208 }
2209
2210 * result = body_fields;
2211 * index = cur_token;
2212
2213 return MAILIMAP_NO_ERROR;
2214
2215 fld_enc_free:
2216 mailimap_body_fld_enc_free(body_fld_enc);
2217 fld_desc_free:
2218 mailimap_body_fld_desc_free(body_fld_desc);
2219 fld_id_free:
2220 mailimap_body_fld_id_free(body_fld_id);
2221 fld_param_free:
2222 if (body_fld_param != NULL)
2223 mailimap_body_fld_param_free(body_fld_param);
2224 err:
2225 return res;
2226}
2227
2228/*
2229 body-fld-desc = nstring
2230*/
2231
2232static int mailimap_body_fld_desc_parse(mailstream * fd, MMAPString * buffer,
2233 size_t * index, char ** result,
2234 size_t progr_rate,
2235 progress_function * progr_fun)
2236{
2237 return mailimap_nstring_parse(fd, buffer, index, result, NULL,
2238 progr_rate, progr_fun);
2239}
2240
2241/*
2242 body-fld-dsp = "(" string SP body-fld-param ")" / nil
2243*/
2244
2245static int
2246mailimap_body_fld_dsp_parse(mailstream * fd, MMAPString * buffer,
2247 size_t * index,
2248 struct mailimap_body_fld_dsp ** result,
2249 size_t progr_rate,
2250 progress_function * progr_fun)
2251{
2252 size_t cur_token;
2253 char * name;
2254 struct mailimap_body_fld_param * body_fld_param;
2255 struct mailimap_body_fld_dsp * body_fld_dsp;
2256 int res;
2257 int r;
2258
2259 cur_token = * index;
2260 name = NULL;
2261 body_fld_param = NULL;
2262
2263 r = mailimap_nil_parse(fd, buffer, &cur_token);
2264 if (r == MAILIMAP_NO_ERROR) {
2265 * result = NULL;
2266 * index = cur_token;
2267 return MAILIMAP_NO_ERROR;
2268 }
2269
2270 if (r != MAILIMAP_ERROR_PARSE) {
2271 res = r;
2272 goto err;
2273 }
2274
2275 r = mailimap_oparenth_parse(fd, buffer, &cur_token);
2276 if (r != MAILIMAP_NO_ERROR) {
2277 res = r;
2278 goto err;
2279 }
2280
2281 r = mailimap_string_parse(fd, buffer, &cur_token, &name, NULL,
2282 progr_rate, progr_fun);
2283 if (r != MAILIMAP_NO_ERROR) {
2284 res = r;
2285 goto err;
2286 }
2287
2288 r = mailimap_space_parse(fd, buffer, &cur_token);
2289 if (r != MAILIMAP_NO_ERROR) {
2290 res = r;
2291 goto string_free;
2292 }
2293
2294 r = mailimap_body_fld_param_parse(fd, buffer, &cur_token,
2295 &body_fld_param,
2296 progr_rate, progr_fun);
2297 if (r != MAILIMAP_NO_ERROR) {
2298 res = r;
2299 goto string_free;
2300 }
2301
2302 r = mailimap_cparenth_parse(fd, buffer, &cur_token);
2303 if (r != MAILIMAP_NO_ERROR) {
2304 res = r;
2305 goto string_free;
2306 }
2307
2308 body_fld_dsp = mailimap_body_fld_dsp_new(name, body_fld_param);
2309 if (body_fld_dsp == NULL) {
2310 res = MAILIMAP_ERROR_MEMORY;
2311 goto fld_param_free;
2312 }
2313
2314 * index = cur_token;
2315 * result = body_fld_dsp;
2316
2317 return MAILIMAP_NO_ERROR;
2318
2319 fld_param_free:
2320 if (body_fld_param != NULL)
2321 mailimap_body_fld_param_free(body_fld_param);
2322 string_free:
2323 mailimap_string_free(name);
2324 err:
2325 return res;
2326}
2327
2328/*
2329 body-fld-enc = (DQUOTE ("7BIT" / "8BIT" / "BINARY" / "BASE64"/
2330 "QUOTED-PRINTABLE") DQUOTE) / string
2331*/
2332
2333static inline int
2334mailimap_body_fld_known_enc_parse(mailstream * fd, MMAPString * buffer,
2335 size_t * index,
2336 int * result,
2337 size_t progr_rate,
2338 progress_function * progr_fun)
2339{
2340 size_t cur_token;
2341 int type;
2342 int r;
2343 int res;
2344
2345 cur_token = * index;
2346
2347 r = mailimap_dquote_parse(fd, buffer, &cur_token);
2348 if (r != MAILIMAP_NO_ERROR) {
2349 res = r;
2350 goto err;
2351 }
2352
2353 type = mailimap_encoding_get_token_value(fd, buffer, &cur_token);
2354
2355 if (type == -1) {
2356 res = MAILIMAP_ERROR_PARSE;
2357 goto err;
2358 }
2359
2360 r = mailimap_dquote_parse(fd, buffer, &cur_token);
2361 if (r != MAILIMAP_NO_ERROR) {
2362 res = r;
2363 goto err;
2364 }
2365
2366 * result = type;
2367 * index = cur_token;
2368
2369 return MAILIMAP_NO_ERROR;
2370
2371 err:
2372 return res;
2373}
2374
2375static int
2376mailimap_body_fld_enc_parse(mailstream * fd, MMAPString * buffer,
2377 size_t * index,
2378 struct mailimap_body_fld_enc ** result,
2379 size_t progr_rate,
2380 progress_function * progr_fun)
2381{
2382 size_t cur_token;
2383 int type;
2384 char * value;
2385 struct mailimap_body_fld_enc * body_fld_enc;
2386 int r;
2387 int res;
2388
2389 cur_token = * index;
2390
2391 r = mailimap_body_fld_known_enc_parse(fd, buffer, &cur_token,
2392 &type, progr_rate, progr_fun);
2393 if (r == MAILIMAP_NO_ERROR) {
2394 value = NULL;
2395 }
2396 else if (r == MAILIMAP_ERROR_PARSE) {
2397 type = MAILIMAP_BODY_FLD_ENC_OTHER;
2398
2399 r = mailimap_string_parse(fd, buffer, &cur_token, &value, NULL,
2400 progr_rate, progr_fun);
2401 if (r != MAILIMAP_NO_ERROR) {
2402 res = r;
2403 goto err;
2404 }
2405 }
2406 else {
2407 res = r;
2408 goto err;
2409 }
2410
2411 body_fld_enc = mailimap_body_fld_enc_new(type, value);
2412 if (body_fld_enc == NULL) {
2413 res = MAILIMAP_ERROR_MEMORY;
2414 goto value_free;
2415 }
2416
2417 * result = body_fld_enc;
2418 * index = cur_token;
2419
2420 return MAILIMAP_NO_ERROR;
2421
2422 value_free:
2423 if (value)
2424 mailimap_string_free(value);
2425 err:
2426 return res;
2427}
2428
2429/*
2430 body-fld-id = nstring
2431*/
2432
2433static int mailimap_body_fld_id_parse(mailstream * fd, MMAPString * buffer,
2434 size_t * index, char ** result,
2435 size_t progr_rate,
2436 progress_function * progr_fun)
2437{
2438 return mailimap_nstring_parse(fd, buffer, index, result, NULL,
2439 progr_rate, progr_fun);
2440}
2441
2442
2443/*
2444 body-fld-lang = nstring / "(" string *(SP string) ")"
2445*/
2446
2447/*
2448"(" string *(SP string) ")"
2449*/
2450
2451static int
2452mailimap_body_fld_lang_list_parse(mailstream * fd, MMAPString * buffer,
2453 size_t * index, clist ** result,
2454 size_t progr_rate,
2455 progress_function * progr_fun)
2456{
2457 size_t cur_token;
2458 clist * list;
2459 int r;
2460 int res;
2461
2462 cur_token = * index;
2463
2464 r = mailimap_oparenth_parse(fd, buffer, &cur_token);
2465 if (r != MAILIMAP_NO_ERROR) {
2466 res = r;
2467 goto err;
2468 }
2469
2470 list = clist_new();
2471 if (list == NULL) {
2472 res = MAILIMAP_ERROR_MEMORY;
2473 goto err;
2474 }
2475
2476 while (1) {
2477 char * elt;
2478
2479 r = mailimap_string_parse(fd, buffer, &cur_token, &elt, NULL,
2480 progr_rate, progr_fun);
2481 if (r != MAILIMAP_ERROR_PARSE)
2482 break;
2483 else if (r == MAILIMAP_NO_ERROR) {
2484 r = clist_append(list, elt);
2485 if (r < 0) {
2486 mailimap_string_free(elt);
2487 res = r;
2488 goto list_free;
2489 }
2490 }
2491 else {
2492 res = r;
2493 goto list_free;
2494 }
2495 }
2496
2497 r = mailimap_cparenth_parse(fd, buffer, &cur_token);
2498 if (r != MAILIMAP_NO_ERROR) {
2499 res = r;
2500 goto list_free;
2501 }
2502
2503 * index = cur_token;
2504 * result = list;
2505
2506 return MAILIMAP_NO_ERROR;
2507
2508 list_free:
2509 clist_foreach(list, (clist_func) mailimap_string_free, NULL);
2510 clist_free(list);
2511 err:
2512 return res;
2513}
2514
2515/*
2516 body-fld-lang = nstring / "(" string *(SP string) ")"
2517*/
2518
2519static int
2520mailimap_body_fld_lang_parse(mailstream * fd, MMAPString * buffer,
2521 size_t * index,
2522 struct mailimap_body_fld_lang ** result,
2523 size_t progr_rate,
2524 progress_function * progr_fun)
2525{
2526 char * value;
2527 clist * list;
2528 struct mailimap_body_fld_lang * fld_lang;
2529 int type;
2530 int r;
2531 int res;
2532
2533 size_t cur_token;
2534
2535 cur_token = * index;
2536
2537 value = NULL;
2538 list = NULL;
2539 type = MAILIMAP_BODY_FLD_LANG_ERROR; /* XXX - removes a gcc warning */
2540
2541 r = mailimap_nstring_parse(fd, buffer, &cur_token, &value, NULL,
2542 progr_rate, progr_fun);
2543 if (r == MAILIMAP_NO_ERROR)
2544 type = MAILIMAP_BODY_FLD_LANG_SINGLE;
2545
2546 if (r == MAILIMAP_ERROR_PARSE) {
2547 r = mailimap_body_fld_lang_list_parse(fd, buffer, &cur_token, &list,
2548 progr_rate, progr_fun);
2549 if (r == MAILIMAP_NO_ERROR)
2550 type = MAILIMAP_BODY_FLD_LANG_LIST;
2551 }
2552
2553 if (r != MAILIMAP_NO_ERROR) {
2554 res = r;
2555 goto err;
2556 }
2557
2558 fld_lang = mailimap_body_fld_lang_new(type, value, list);
2559 if (fld_lang == NULL) {
2560 res = MAILIMAP_ERROR_MEMORY;
2561 goto free;
2562 }
2563
2564 * index = cur_token;
2565 * result = fld_lang;
2566
2567 return MAILIMAP_NO_ERROR;
2568
2569 free:
2570 if (value)
2571 mailimap_nstring_free(value);
2572 if (list) {
2573 clist_foreach(list, (clist_func) mailimap_string_free, NULL);
2574 clist_free(list);
2575 }
2576 err:
2577 return res;
2578}
2579
2580/*
2581 body-fld-lines = number
2582*/
2583
2584static int mailimap_body_fld_lines_parse(mailstream * fd,
2585 MMAPString * buffer, size_t * index,
2586 uint32_t * result)
2587{
2588 return mailimap_number_parse(fd, buffer, index, result);
2589}
2590
2591/*
2592 body-fld-md5 = nstring
2593*/
2594
2595static int mailimap_body_fld_md5_parse(mailstream * fd, MMAPString * buffer,
2596 size_t * index, char ** result,
2597 size_t progr_rate,
2598 progress_function * progr_fun)
2599{
2600 return mailimap_nstring_parse(fd, buffer, index, result, NULL,
2601 progr_rate, progr_fun);
2602}
2603
2604/*
2605 body-fld-octets = number
2606*/
2607
2608static int mailimap_body_fld_octets_parse(mailstream * fd,
2609 MMAPString * buffer, size_t * index,
2610 uint32_t * result)
2611{
2612 return mailimap_number_parse(fd, buffer, index, result);
2613}
2614
2615/*
2616 body-fld-param = "(" string SP string *(SP string SP string) ")" / nil
2617*/
2618
2619/*
2620 string SP string
2621*/
2622
2623static int
2624mailimap_single_body_fld_param_parse(mailstream * fd, MMAPString * buffer,
2625 size_t * index,
2626 struct mailimap_single_body_fld_param **
2627 result,
2628 size_t progr_rate,
2629 progress_function * progr_fun)
2630{
2631 struct mailimap_single_body_fld_param * param;
2632 char * name;
2633 char * value;
2634 size_t cur_token;
2635 int r;
2636 int res;
2637
2638 cur_token = * index;
2639
2640 name = NULL;
2641 value = NULL;
2642
2643 r = mailimap_string_parse(fd, buffer, &cur_token, &name, NULL,
2644 progr_rate, progr_fun);
2645 if (r != MAILIMAP_NO_ERROR) {
2646 res = r;
2647 goto err;
2648 }
2649
2650 r = mailimap_space_parse(fd, buffer, &cur_token);
2651 if (r != MAILIMAP_NO_ERROR) {
2652 res = r;
2653 goto free_name;
2654 }
2655
2656 r = mailimap_string_parse(fd, buffer, &cur_token, &value, NULL,
2657 progr_rate, progr_fun);
2658 if (r != MAILIMAP_NO_ERROR) {
2659 res = r;
2660 goto free_name;
2661 }
2662
2663 param = mailimap_single_body_fld_param_new(name, value);
2664 if (param == NULL) {
2665 res = MAILIMAP_ERROR_MEMORY;
2666 goto free_value;
2667 }
2668
2669 * result = param;
2670 * index = cur_token;
2671
2672 return MAILIMAP_NO_ERROR;
2673
2674 free_value:
2675 mailimap_string_free(name);
2676 free_name:
2677 mailimap_string_free(value);
2678 err:
2679 return res;
2680}
2681
2682/*
2683 body-fld-param = "(" string SP string *(SP string SP string) ")" / nil
2684*/
2685
2686static int
2687mailimap_body_fld_param_parse(mailstream * fd,
2688 MMAPString * buffer, size_t * index,
2689 struct mailimap_body_fld_param ** result,
2690 size_t progr_rate,
2691 progress_function * progr_fun)
2692{
2693 size_t cur_token;
2694 clist * param_list;
2695 struct mailimap_body_fld_param * fld_param;
2696 int r;
2697 int res;
2698
2699 param_list = NULL;
2700 cur_token = * index;
2701
2702 r = mailimap_nil_parse(fd, buffer, &cur_token);
2703 if (r == MAILIMAP_NO_ERROR) {
2704 * result = NULL;
2705 * index = cur_token;
2706 return MAILIMAP_NO_ERROR;
2707 }
2708
2709 if (r != MAILIMAP_ERROR_PARSE) {
2710 res = r;
2711 goto err;
2712 }
2713
2714 r = mailimap_oparenth_parse(fd, buffer, &cur_token);
2715 if (r != MAILIMAP_NO_ERROR) {
2716 res = r;
2717 goto err;
2718 }
2719
2720 r = mailimap_struct_spaced_list_parse(fd, buffer, &cur_token, &param_list,
2721 (mailimap_struct_parser *)
2722 mailimap_single_body_fld_param_parse,
2723 (mailimap_struct_destructor *)
2724 mailimap_single_body_fld_param_free,
2725 progr_rate, progr_fun);
2726 if (r != MAILIMAP_NO_ERROR) {
2727 res = r;
2728 goto err;
2729 }
2730
2731 r = mailimap_cparenth_parse(fd, buffer, &cur_token);
2732 if (r != MAILIMAP_NO_ERROR) {
2733 res = r;
2734 goto free;
2735 }
2736
2737 fld_param = mailimap_body_fld_param_new(param_list);
2738 if (fld_param == NULL) {
2739 res = MAILIMAP_ERROR_MEMORY;
2740 goto free;
2741 }
2742
2743 * index = cur_token;
2744 * result = fld_param;
2745
2746 return MAILIMAP_NO_ERROR;
2747
2748 free:
2749 clist_foreach(param_list,
2750 (clist_func) mailimap_single_body_fld_param_free,
2751 NULL);
2752 clist_free(param_list);
2753 err:
2754 return res;
2755}
2756
2757/*
2758 body-type-1part = (body-type-basic / body-type-msg / body-type-text)
2759 [SP body-ext-1part]
2760*/
2761
2762static int
2763mailimap_body_type_1part_parse(mailstream * fd, MMAPString * buffer,
2764 size_t * index,
2765 struct mailimap_body_type_1part ** result,
2766 size_t progr_rate,
2767 progress_function * progr_fun)
2768{
2769 size_t cur_token;
2770 struct mailimap_body_type_1part * body_type_1part;
2771 struct mailimap_body_type_basic * body_type_basic;
2772 struct mailimap_body_type_msg * body_type_msg;
2773 struct mailimap_body_type_text * body_type_text;
2774 struct mailimap_body_ext_1part * body_ext_1part;
2775 int type;
2776 size_t final_token;
2777 int r;
2778 int res;
2779
2780 cur_token = * index;
2781
2782 body_type_basic = NULL;
2783 body_type_msg = NULL;
2784 body_type_text = NULL;
2785 body_ext_1part = NULL;
2786
2787 type = MAILIMAP_BODY_TYPE_1PART_ERROR; /* XXX - removes a gcc warning */
2788
2789 r = mailimap_body_type_msg_parse(fd, buffer, &cur_token,
2790 &body_type_msg,
2791 progr_rate, progr_fun);
2792 if (r == MAILIMAP_NO_ERROR)
2793 type = MAILIMAP_BODY_TYPE_1PART_MSG;
2794
2795 if (r == MAILIMAP_ERROR_PARSE) {
2796 r = mailimap_body_type_text_parse(fd, buffer, &cur_token,
2797 &body_type_text,
2798 progr_rate, progr_fun);
2799 if (r == MAILIMAP_NO_ERROR)
2800 type = MAILIMAP_BODY_TYPE_1PART_TEXT;
2801 }
2802
2803 if (r == MAILIMAP_ERROR_PARSE) {
2804 r = mailimap_body_type_basic_parse(fd, buffer, &cur_token,
2805 &body_type_basic,
2806 progr_rate, progr_fun);
2807 if (r == MAILIMAP_NO_ERROR)
2808 type = MAILIMAP_BODY_TYPE_1PART_BASIC;
2809 }
2810
2811 if (r != MAILIMAP_NO_ERROR) {
2812 res = r;
2813 goto err;
2814 }
2815
2816 final_token = cur_token;
2817 body_ext_1part = NULL;
2818
2819 r = mailimap_space_parse(fd, buffer, &cur_token);
2820
2821 if (r == MAILIMAP_NO_ERROR) {
2822 r = mailimap_body_ext_1part_parse(fd, buffer, &cur_token, &body_ext_1part,
2823 progr_rate, progr_fun);
2824 if (r == MAILIMAP_NO_ERROR)
2825 final_token = cur_token;
2826 else if (r == MAILIMAP_ERROR_PARSE) {
2827 /* do nothing */
2828 }
2829 else {
2830 res = r;
2831 goto free;
2832 }
2833 }
2834 else if (r == MAILIMAP_ERROR_PARSE) {
2835 /* do nothing */
2836 }
2837 else {
2838 res = r;
2839 goto free;
2840 }
2841
2842 body_type_1part = mailimap_body_type_1part_new(type, body_type_basic,
2843 body_type_msg, body_type_text,
2844 body_ext_1part);
2845 if (body_type_1part == NULL) {
2846 res = MAILIMAP_ERROR_MEMORY;
2847 goto free;
2848 }
2849
2850 * index = final_token;
2851 * result = body_type_1part;
2852
2853 return MAILIMAP_NO_ERROR;
2854
2855 free:
2856 if (body_type_basic)
2857 mailimap_body_type_basic_free(body_type_basic);
2858 if (body_type_msg)
2859 mailimap_body_type_msg_free(body_type_msg);
2860 if (body_type_text)
2861 mailimap_body_type_text_free(body_type_text);
2862 if (body_ext_1part)
2863 mailimap_body_ext_1part_free(body_ext_1part);
2864 err:
2865 return res;
2866}
2867
2868/*
2869 body-type-basic = media-basic SP body-fields
2870 ; MESSAGE subtype MUST NOT be "RFC822"
2871*/
2872
2873static int
2874mailimap_body_type_basic_parse(mailstream * fd, MMAPString * buffer,
2875 size_t * index,
2876 struct mailimap_body_type_basic ** result,
2877 size_t progr_rate,
2878 progress_function * progr_fun)
2879{
2880 size_t cur_token;
2881 struct mailimap_body_type_basic * body_type_basic;
2882 struct mailimap_media_basic * media_basic;
2883 struct mailimap_body_fields * body_fields;
2884 int r;
2885 int res;
2886
2887 cur_token = * index;
2888
2889 media_basic = NULL;
2890 body_fields = NULL;
2891
2892 r = mailimap_media_basic_parse(fd, buffer, &cur_token, &media_basic,
2893 progr_rate, progr_fun);
2894 if (r != MAILIMAP_NO_ERROR) {
2895 res = r;
2896 goto err;
2897 }
2898
2899 r = mailimap_space_parse(fd, buffer, &cur_token);
2900 if (r != MAILIMAP_NO_ERROR) {
2901 res = r;
2902 goto free_media_basic;
2903 }
2904
2905 r = mailimap_body_fields_parse(fd, buffer, &cur_token, &body_fields,
2906 progr_rate, progr_fun);
2907 if (r != MAILIMAP_NO_ERROR) {
2908 res = r;
2909 goto free_media_basic;
2910 }
2911
2912 body_type_basic = mailimap_body_type_basic_new(media_basic, body_fields);
2913 if (body_type_basic == NULL) {
2914 res = MAILIMAP_ERROR_MEMORY;
2915 goto free_body_fields;
2916 }
2917
2918 * index = cur_token;
2919 * result = body_type_basic;
2920
2921 return MAILIMAP_NO_ERROR;
2922
2923 free_body_fields:
2924 mailimap_body_fields_free(body_fields);
2925 free_media_basic:
2926 mailimap_media_basic_free(media_basic);
2927 err:
2928 return res;
2929}
2930
2931/*
2932 body-type-mpart = 1*body SP media-subtype
2933 [SP body-ext-mpart]
2934*/
2935
2936static int
2937mailimap_body_type_mpart_parse(mailstream * fd,
2938 MMAPString * buffer,
2939 size_t * index,
2940 struct mailimap_body_type_mpart ** result,
2941 size_t progr_rate,
2942 progress_function * progr_fun)
2943{
2944 struct mailimap_body_type_mpart * body_type_mpart;
2945 clist * body_list;
2946 size_t cur_token;
2947 size_t final_token;
2948 char * media_subtype;
2949 struct mailimap_body_ext_mpart * body_ext_mpart;
2950 int r;
2951 int res;
2952
2953 cur_token = * index;
2954
2955 body_list = NULL;
2956 media_subtype = NULL;
2957 body_ext_mpart = NULL;
2958
2959 r = mailimap_struct_multiple_parse(fd, buffer, &cur_token,
2960 &body_list,
2961 (mailimap_struct_parser *)
2962 mailimap_body_parse,
2963 (mailimap_struct_destructor *)
2964 mailimap_body_free,
2965 progr_rate, progr_fun);
2966 if (r != MAILIMAP_NO_ERROR) {
2967 res = r;
2968 goto err;
2969 }
2970
2971 r = mailimap_space_parse(fd, buffer, &cur_token);
2972 if (r != MAILIMAP_NO_ERROR) {
2973 res = r;
2974 goto free_body_list;
2975 }
2976
2977 r = mailimap_media_subtype_parse(fd, buffer, &cur_token, &media_subtype,
2978 progr_rate, progr_fun);
2979 if (r != MAILIMAP_NO_ERROR) {
2980 res = r;
2981 goto free_body_list;
2982 }
2983
2984 final_token = cur_token;
2985
2986 body_ext_mpart = NULL;
2987
2988 r = mailimap_space_parse(fd, buffer, &cur_token);
2989 if (r == MAILIMAP_NO_ERROR) {
2990 r = mailimap_body_ext_mpart_parse(fd, buffer, &cur_token, &body_ext_mpart,
2991 progr_rate, progr_fun);
2992 if (r == MAILIMAP_NO_ERROR)
2993 final_token = cur_token;
2994 else if (r == MAILIMAP_ERROR_PARSE) {
2995 /* do nothing */
2996 }
2997 else {
2998 res = r;
2999 goto free_body_list;
3000 }
3001 }
3002 else if (r == MAILIMAP_ERROR_PARSE) {
3003 /* do nothing */
3004 }
3005 else {
3006 res = r;
3007 goto free_body_list;
3008 }
3009
3010 body_type_mpart = mailimap_body_type_mpart_new(body_list, media_subtype,
3011 body_ext_mpart);
3012 if (body_type_mpart == NULL) {
3013 res = MAILIMAP_ERROR_MEMORY;
3014 goto free_body_ext_mpart;
3015 }
3016
3017 * result = body_type_mpart;
3018 * index = final_token;
3019
3020 return MAILIMAP_NO_ERROR;
3021
3022 free_body_ext_mpart:
3023 if (body_ext_mpart)
3024 mailimap_body_ext_mpart_free(body_ext_mpart);
3025 mailimap_media_subtype_free(media_subtype);
3026 free_body_list:
3027 clist_foreach(body_list, (clist_func) mailimap_body_free, NULL);
3028 clist_free(body_list);
3029 err:
3030 return res;
3031}
3032
3033/*
3034 body-type-msg = media-message SP body-fields SP envelope
3035 SP body SP body-fld-lines
3036*/
3037
3038static int
3039mailimap_body_type_msg_parse(mailstream * fd, MMAPString * buffer,
3040 size_t * index,
3041 struct mailimap_body_type_msg ** result,
3042 size_t progr_rate,
3043 progress_function * progr_fun)
3044{
3045 struct mailimap_body_fields * body_fields;
3046 struct mailimap_envelope * envelope;
3047 struct mailimap_body * body;
3048 uint32_t body_fld_lines;
3049 struct mailimap_body_type_msg * body_type_msg;
3050 size_t cur_token;
3051 int r;
3052 int res;
3053
3054 cur_token = * index;
3055
3056 body_fields = NULL;
3057 envelope = NULL;
3058 body = NULL;
3059 body_fld_lines = 0;
3060
3061 r = mailimap_media_message_parse(fd, buffer, &cur_token);
3062 if (r != MAILIMAP_NO_ERROR) {
3063 res = r;
3064 goto err;
3065 }
3066
3067 r = mailimap_space_parse(fd, buffer, &cur_token);
3068 if (r != MAILIMAP_NO_ERROR) {
3069 res = r;
3070 goto err;
3071 }
3072
3073 r = mailimap_body_fields_parse(fd, buffer, &cur_token, &body_fields,
3074 progr_rate, progr_fun);
3075 if (r != MAILIMAP_NO_ERROR) {
3076 res = r;
3077 goto err;
3078 }
3079
3080 r = mailimap_space_parse(fd, buffer, &cur_token);
3081 if (r != MAILIMAP_NO_ERROR) {
3082 res = r;
3083 goto body_fields;
3084 }
3085
3086 r = mailimap_envelope_parse(fd, buffer, &cur_token, &envelope,
3087 progr_rate, progr_fun);
3088 if (r != MAILIMAP_NO_ERROR) {
3089 res = r;
3090 goto body_fields;
3091 }
3092
3093 r = mailimap_space_parse(fd, buffer, &cur_token);
3094 if (r != MAILIMAP_NO_ERROR) {
3095 res = r;
3096 goto envelope;
3097 }
3098
3099 r = mailimap_body_parse(fd, buffer, &cur_token, &body,
3100 progr_rate, progr_fun);
3101 if (r != MAILIMAP_NO_ERROR) {
3102 res = r;
3103 goto envelope;
3104 }
3105
3106 r = mailimap_space_parse(fd, buffer, &cur_token);
3107 if (r != MAILIMAP_NO_ERROR) {
3108 res = r;
3109 goto body;
3110 }
3111
3112 r = mailimap_body_fld_lines_parse(fd, buffer, &cur_token,
3113 &body_fld_lines);
3114 if (r != MAILIMAP_NO_ERROR) {
3115 res = r;
3116 goto body;
3117 }
3118
3119 body_type_msg = mailimap_body_type_msg_new(body_fields, envelope,
3120 body, body_fld_lines);
3121 if (body_type_msg == NULL) {
3122 res = MAILIMAP_ERROR_MEMORY;
3123 goto body;
3124 }
3125
3126 * result = body_type_msg;
3127 * index = cur_token;
3128
3129 return MAILIMAP_NO_ERROR;
3130
3131 body:
3132 mailimap_body_free(body);
3133 envelope:
3134 mailimap_envelope_free(envelope);
3135 body_fields:
3136 mailimap_body_fields_free(body_fields);
3137 err:
3138 return res;
3139}
3140
3141/*
3142 body-type-text = media-text SP body-fields SP body-fld-lines
3143*/
3144
3145static int
3146mailimap_body_type_text_parse(mailstream * fd, MMAPString * buffer,
3147 size_t * index,
3148 struct mailimap_body_type_text **
3149 result,
3150 size_t progr_rate,
3151 progress_function * progr_fun)
3152{
3153 char * media_text;
3154 struct mailimap_body_fields * body_fields;
3155 uint32_t body_fld_lines;
3156 struct mailimap_body_type_text * body_type_text;
3157 size_t cur_token;
3158 int r;
3159 int res;
3160
3161 media_text = NULL;
3162 body_fields = NULL;
3163 body_fld_lines = 0;
3164
3165 cur_token = * index;
3166
3167 r = mailimap_media_text_parse(fd, buffer, &cur_token, &media_text,
3168 progr_rate, progr_fun);
3169 if (r != MAILIMAP_NO_ERROR) {
3170 res = r;
3171 goto err;
3172 }
3173
3174 r = mailimap_space_parse(fd, buffer, &cur_token);
3175 if (r != MAILIMAP_NO_ERROR) {
3176 res = r;
3177 goto free_media_text;
3178 }
3179
3180 r = mailimap_body_fields_parse(fd, buffer, &cur_token, &body_fields,
3181 progr_rate, progr_fun);
3182 if (r != MAILIMAP_NO_ERROR) {
3183 res = r;
3184 goto free_media_text;
3185 }
3186
3187 r = mailimap_space_parse(fd, buffer, &cur_token);
3188 if (r != MAILIMAP_NO_ERROR) {
3189 res = r;
3190 goto free_body_fields;
3191 }
3192
3193 r = mailimap_body_fld_lines_parse(fd, buffer, &cur_token, &body_fld_lines);
3194 if (r != MAILIMAP_NO_ERROR) {
3195 res = r;
3196 goto free_body_fields;
3197 }
3198
3199 body_type_text = mailimap_body_type_text_new(media_text, body_fields,
3200 body_fld_lines);
3201 if (body_type_text == NULL) {
3202 res = MAILIMAP_ERROR_MEMORY;
3203 goto free_body_fields;
3204 }
3205
3206 * result = body_type_text;
3207 * index = cur_token;
3208
3209 return MAILIMAP_NO_ERROR;
3210
3211 free_body_fields:
3212 mailimap_body_fields_free(body_fields);
3213 free_media_text:
3214 mailimap_media_text_free(media_text);
3215 err:
3216 return res;
3217}
3218
3219
3220/*
3221 capability = ("AUTH=" auth-type) / atom
3222 ; New capabilities MUST begin with "X" or be
3223 ; registered with IANA as standard or
3224 ; standards-track
3225*/
3226
3227static int
3228mailimap_capability_parse(mailstream * fd, MMAPString * buffer,
3229 size_t * index,
3230 struct mailimap_capability ** result,
3231 size_t progr_rate,
3232 progress_function * progr_fun)
3233{
3234 size_t cur_token;
3235 int type;
3236 char * auth_type;
3237 char * atom;
3238 struct mailimap_capability * cap;
3239 int r;
3240 int res;
3241
3242 cur_token = * index;
3243
3244 auth_type = NULL;
3245 atom = NULL;
3246
3247 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token, "AUTH=");
3248 switch (r) {
3249 case MAILIMAP_NO_ERROR:
3250 type = MAILIMAP_CAPABILITY_AUTH_TYPE;
3251
3252 r = mailimap_auth_type_parse(fd, buffer, &cur_token, &auth_type,
3253 progr_rate, progr_fun);
3254 if (r != MAILIMAP_NO_ERROR) {
3255 res = r;
3256 goto err;
3257 }
3258 break;
3259
3260 case MAILIMAP_ERROR_PARSE:
3261 r = mailimap_atom_parse(fd, buffer, &cur_token, &atom,
3262 progr_rate, progr_fun);
3263 if (r != MAILIMAP_NO_ERROR) {
3264 res = r;
3265 goto err;
3266 }
3267
3268 type = MAILIMAP_CAPABILITY_NAME;
3269 break;
3270
3271 default:
3272 res = r;
3273 goto err;
3274 }
3275
3276 cap = mailimap_capability_new(type, auth_type, atom);
3277 if (cap == NULL) {
3278 res = MAILIMAP_ERROR_MEMORY;
3279 goto free;
3280 }
3281
3282 * result = cap;
3283 * index = cur_token;
3284
3285 return MAILIMAP_NO_ERROR;
3286
3287 free:
3288 if (auth_type)
3289 mailimap_auth_type_free(auth_type);
3290 if (atom)
3291 mailimap_atom_free(atom);
3292 err:
3293 return res;
3294}
3295
3296/*
3297 capability-data = "CAPABILITY" *(SP capability) SP "IMAP4rev1"
3298 *(SP capability)
3299 ; IMAP4rev1 servers which offer RFC 1730
3300 ; compatibility MUST list "IMAP4" as the first
3301 ; capability.
3302*/
3303
3304/*
3305 SP capability *(SP capability)
3306*/
3307
3308static int mailimap_capability_list_parse(mailstream * fd,
3309 MMAPString * buffer,
3310 size_t * index,
3311 clist ** result,
3312 size_t progr_rate,
3313 progress_function * progr_fun)
3314{
3315 size_t cur_token;
3316 clist * list;
3317 int r;
3318
3319 cur_token = * index;
3320
3321 r = mailimap_space_parse(fd, buffer, &cur_token);
3322 if (r != MAILIMAP_NO_ERROR)
3323 return r;
3324
3325 r = mailimap_struct_spaced_list_parse(fd, buffer, &cur_token, &list,
3326 (mailimap_struct_parser *)
3327 mailimap_capability_parse,
3328 (mailimap_struct_destructor *)
3329 mailimap_capability_free,
3330 progr_rate, progr_fun);
3331 if (r != MAILIMAP_NO_ERROR)
3332 return r;
3333
3334 * index = cur_token;
3335 * result = list;
3336
3337 return MAILIMAP_NO_ERROR;
3338}
3339
3340static int
3341mailimap_capability_data_parse(mailstream * fd, MMAPString * buffer,
3342 size_t * index,
3343 struct mailimap_capability_data ** result,
3344 size_t progr_rate,
3345 progress_function * progr_fun)
3346{
3347 size_t cur_token;
3348 clist * cap_list;
3349#if 0
3350 clist * cap_list_2;
3351#endif
3352 struct mailimap_capability_data * cap_data;
3353 int r;
3354 int res;
3355
3356 cur_token = * index;
3357
3358 cap_list = NULL;
3359#if 0
3360 cap_list_2 = NULL;
3361#endif
3362
3363 r = mailimap_token_case_insensitive_parse(fd, buffer,
3364 &cur_token, "CAPABILITY");
3365 if (r != MAILIMAP_NO_ERROR) {
3366 res = r;
3367 goto err;
3368 }
3369
3370 r = mailimap_capability_list_parse(fd, buffer, &cur_token,
3371 &cap_list,
3372 progr_rate, progr_fun);
3373
3374 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) {
3375 res = r;
3376 goto err;
3377 }
3378
3379#if 0
3380 if (!mailimap_space_parse(fd, buffer, &cur_token)) {
3381 res = r;
3382 goto free_list;
3383 }
3384
3385 if (!mailimap_token_case_insensitive_parse(fd, buffer,
3386 &cur_token, "IMAP4rev1"))
3387 goto free_list;
3388
3389 r = mailimap_capability_list_parse(fd, buffer, &cur_token,
3390 &cap_list_2,
3391 progr_rate, progr_fun);
3392
3393 cap_list = g_list_concat(cap_list, cap_list_2);
3394#endif
3395
3396 cap_data = mailimap_capability_data_new(cap_list);
3397 if (cap_data == NULL) {
3398 res = MAILIMAP_ERROR_MEMORY;
3399 goto free_list;
3400 }
3401
3402 * result = cap_data;
3403 * index = cur_token;
3404
3405 return MAILIMAP_NO_ERROR;
3406
3407 free_list:
3408 if (cap_list) {
3409 clist_foreach(cap_list, (clist_func) mailimap_capability_free, NULL);
3410 clist_free(cap_list);
3411 }
3412 err:
3413 return res;
3414}
3415
3416/*
3417 UNIMPLEMENTED BECAUSE UNUSED (only in literal)
3418 CHAR8 = %x01-ff
3419 ; any OCTET except NUL, %x00
3420*/
3421
3422/*
3423static gboolean is_char8(gchar ch)
3424{
3425 return (ch != 0x00);
3426}
3427*/
3428
3429
3430/*
3431UNIMPLEMENTED
3432 command = tag SP (command-any / command-auth / command-nonauth /
3433 command-select) CRLF
3434 ; Modal based on state
3435*/
3436
3437/*
3438UNIMPLEMENTED
3439 command-any = "CAPABILITY" / "LOGOUT" / "NOOP" / x-command
3440 ; Valid in all states
3441*/
3442
3443/*
3444UNIMPLEMENTED
3445 command-auth = append / create / delete / examine / list / lsub /
3446 rename / select / status / subscribe / unsubscribe
3447 ; Valid only in Authenticated or Selected state
3448*/
3449
3450/*
3451UNIMPLEMENTED
3452 command-nonauth = login / authenticate
3453 ; Valid only when in Not Authenticated state
3454*/
3455
3456/*
3457UNIMPLEMENTED
3458 command-select = "CHECK" / "CLOSE" / "EXPUNGE" / copy / fetch / store /
3459 uid / search
3460 ; Valid only when in Selected state
3461*/
3462
3463/*
3464 continue-req = "+" SP (resp-text / base64) CRLF
3465*/
3466
3467int
3468mailimap_continue_req_parse(mailstream * fd, MMAPString * buffer,
3469 size_t * index,
3470 struct mailimap_continue_req ** result,
3471 size_t progr_rate,
3472 progress_function * progr_fun)
3473{
3474 struct mailimap_resp_text * resp_text;
3475 size_t cur_token;
3476 struct mailimap_continue_req * cont_req;
3477 char * base64;
3478 int type;
3479 int r;
3480 int res;
3481
3482 cur_token = * index;
3483
3484 r = mailimap_plus_parse(fd, buffer, &cur_token);
3485 if (r != MAILIMAP_NO_ERROR)
3486 return r;
3487
3488 r = mailimap_space_parse(fd, buffer, &cur_token);
3489 if (r != MAILIMAP_NO_ERROR)
3490 return r;
3491
3492 resp_text = NULL;
3493 base64 = NULL;
3494
3495 type = MAILIMAP_CONTINUE_REQ_ERROR; /* XXX - removes a gcc warning */
3496
3497 r = mailimap_base64_parse(fd, buffer, &cur_token, &base64,
3498 progr_rate, progr_fun);
3499
3500 if (r == MAILIMAP_NO_ERROR)
3501 type = MAILIMAP_CONTINUE_REQ_BASE64;
3502
3503 if (r == MAILIMAP_ERROR_PARSE) {
3504 r = mailimap_resp_text_parse(fd, buffer, &cur_token, &resp_text,
3505 progr_rate, progr_fun);
3506
3507 if (r == MAILIMAP_NO_ERROR)
3508 type = MAILIMAP_CONTINUE_REQ_TEXT;
3509 }
3510
3511 if (r != MAILIMAP_NO_ERROR) {
3512 res = r;
3513 goto err;
3514 }
3515
3516 r = mailimap_crlf_parse(fd, buffer, &cur_token);
3517 if (r != MAILIMAP_NO_ERROR) {
3518 res = r;
3519 goto free;
3520 }
3521
3522 cont_req = mailimap_continue_req_new(type, resp_text, base64);
3523 if (cont_req == NULL) {
3524 res = MAILIMAP_ERROR_MEMORY;
3525 goto free;
3526 }
3527
3528 * result = cont_req;
3529 * index = cur_token;
3530
3531 return MAILIMAP_NO_ERROR;
3532
3533 free:
3534 if (base64 != NULL)
3535 mailimap_base64_free(base64);
3536 if (resp_text != NULL)
3537 mailimap_resp_text_free(resp_text);
3538 err:
3539 return res;
3540}
3541
3542/*
3543 UNIMPLEMENTED
3544 copy = "COPY" SP set SP mailbox
3545*/
3546
3547/*
3548 UNIMPLEMENTED
3549 create = "CREATE" SP mailbox
3550 ; Use of INBOX gives a NO error
3551*/
3552
3553/*
3554 UNIMPLEMENTED
3555 date = date-text / DQUOTE date-text DQUOTE
3556*/
3557
3558/*
3559 UNIMPLEMENTED
3560 date-day = 1*2DIGIT
3561 ; Day of month
3562*/
3563
3564/*
3565static gboolean mailimap_date_day_parse(mailstream * fd,
3566 MMAPString * buffer,
3567 guint32 * index,
3568 gint * result)
3569{
3570 guint32 cur_token;
3571 gint digit;
3572 gint number;
3573
3574 cur_token = * index;
3575
3576 if (!mailimap_digit_parse(fd, buffer, &cur_token, &digit))
3577 return FALSE;
3578
3579 number = digit;
3580
3581 if (mailimap_digit_parse(fd, buffer, &cur_token, &digit))
3582 number = number * 10 + digit;
3583
3584 * result = number;
3585 * index = cur_token;
3586
3587 return TRUE;
3588}
3589*/
3590
3591/*
3592 date-day-fixed = (SP DIGIT) / 2DIGIT
3593 ; Fixed-format version of date-day
3594*/
3595
3596static int mailimap_date_day_fixed_parse(mailstream * fd,
3597 MMAPString * buffer,
3598 size_t * index,
3599 int * result)
3600{
3601#ifdef UNSTRICT_SYNTAX
3602 size_t cur_token;
3603 uint32_t day;
3604 int r;
3605
3606 cur_token = * index;
3607
3608 r = mailimap_number_parse(fd, buffer, &cur_token, &day);
3609 if (r != MAILIMAP_NO_ERROR)
3610 return r;
3611
3612 * index = cur_token;
3613 * result = day;
3614
3615 return MAILIMAP_NO_ERROR;
3616
3617#else
3618 size_t cur_token;
3619 int r;
3620
3621 cur_token = * index;
3622
3623 if (mailimap_space_parse(fd, buffer, &cur_token)) {
3624 int digit;
3625
3626 r = mailimap_digit_parse(fd, buffer, &cur_token, &digit);
3627 if (r != MAILIMAP_NO_ERROR)
3628 return r;
3629
3630 * result = digit;
3631 * index = cur_token;
3632
3633 return MAILIMAP_NO_ERROR;
3634 }
3635 else {
3636 int digit1;
3637 int digit2;
3638
3639 r = mailimap_digit_parse(fd, buffer, &cur_token, &digit1);
3640 if (r != MAILIMAP_NO_ERROR)
3641 return r;
3642 r = mailimap_digit_parse(fd, buffer, &cur_token, &digit2);
3643 if (r != MAILIMAP_NO_ERROR)
3644 return r;
3645
3646 * result = digit1 * 10 + digit2;
3647 * index = cur_token;
3648
3649 return MAILIMAP_NO_ERROR;
3650 }
3651#endif
3652}
3653
3654
3655/*
3656 date-month = "Jan" / "Feb" / "Mar" / "Apr" / "May" / "Jun" /
3657 "Jul" / "Aug" / "Sep" / "Oct" / "Nov" / "Dec"
3658*/
3659
3660static int mailimap_date_month_parse(mailstream * fd, MMAPString * buffer,
3661 size_t * index, int * result)
3662{
3663 size_t cur_token;
3664 int month;
3665
3666 cur_token = * index;
3667
3668 month = mailimap_month_get_token_value(fd, buffer, &cur_token);
3669 if (month == -1)
3670 return MAILIMAP_ERROR_PARSE;
3671
3672 * result = month;
3673 * index = cur_token;
3674
3675 return MAILIMAP_NO_ERROR;
3676}
3677
3678/*
3679 UNIMPLEMENTED
3680 date-text = date-day "-" date-month "-" date-year
3681*/
3682
3683/*
3684static struct mailimap_date_text *
3685mailimap_date_text_new(gint day, gint month, gint year)
3686{
3687 struct mailimap_date_text * date_text;
3688
3689 date_text = g_new(struct mailimap_date_text, 1);
3690 if (date_text == NULL)
3691 return NULL;
3692
3693 date_text->day = day;
3694 date_text->month = month;
3695 date_text->year = year;
3696
3697 return date_text;
3698}
3699
3700static void mailimap_date_text_free(struct mailimap_date_text * date_text)
3701{
3702 g_free(date_text);
3703}
3704
3705static gboolean
3706mailimap_date_text_parse(mailstream * fd, MMAPString * buffer,
3707 guint32 * index, struct mailimap_date_text ** result)
3708{
3709 struct mailimap_date_text * date_text;
3710 gint day;
3711 gint month;
3712 gint year;
3713 guint32 cur_token;
3714
3715 cur_token = * index;
3716
3717 if (!mailimap_date_day_parse(fd, buffer, &cur_token, &day))
3718 return FALSE;
3719
3720 if (!mailimap_minus_parse(fd, buffer, &cur_token))
3721 return FALSE;
3722
3723 if (!mailimap_date_month_parse(fd, buffer, &cur_token, &month))
3724 return FALSE;
3725
3726 if (!mailimap_minus_parse(fd, buffer, &cur_token))
3727 return FALSE;
3728
3729 if (!mailimap_date_year_parse(fd, buffer, &cur_token, &year))
3730 return FALSE;
3731
3732 date_text = mailimap_date_text_new(day, month, year);
3733 if (date_text == NULL)
3734 return FALSE;
3735
3736 * result = date_text;
3737 * index = cur_token;
3738
3739 return TRUE;
3740}
3741*/
3742
3743/*
3744 date-year = 4DIGIT
3745*/
3746
3747static int mailimap_date_year_parse(mailstream * fd, MMAPString * buffer,
3748 size_t * index, int * result)
3749{
3750#ifdef UNSTRICT_SYNTAX
3751 uint32_t year;
3752 int r;
3753 size_t cur_token;
3754
3755 cur_token = * index;
3756
3757 r = mailimap_number_parse(fd, buffer, &cur_token, &year);
3758 if (r != MAILIMAP_NO_ERROR)
3759 return r;
3760
3761 * result = year;
3762 * index = cur_token;
3763
3764 return MAILIMAP_NO_ERROR;
3765#else
3766 int i;
3767 size_t cur_token;
3768 int year;
3769 int digit;
3770 int r;
3771
3772 cur_token = * index;
3773 year = 0;
3774
3775 for(i = 0 ; i < 4 ; i ++) {
3776 r = mailimap_digit_parse(fd, buffer, &cur_token, &digit);
3777 if (r != MAILIMAP_NO_ERROR)
3778 return r;
3779 year = year * 10 + digit;
3780 }
3781
3782 * result = year;
3783 * index = cur_token;
3784
3785 return MAILIMAP_NO_ERROR;
3786#endif
3787}
3788
3789/*
3790 date-time = DQUOTE date-day-fixed "-" date-month "-" date-year
3791 SP time SP zone DQUOTE
3792*/
3793
3794static int mailimap_date_time_parse(mailstream * fd, MMAPString * buffer,
3795 size_t * index,
3796 struct mailimap_date_time ** result,
3797 size_t progr_rate,
3798 progress_function * progr_fun)
3799{
3800 int day;
3801 int month;
3802 int year;
3803 int hour;
3804 int min;
3805 int sec;
3806 struct mailimap_date_time * date_time;
3807 size_t cur_token;
3808 int zone;
3809 int r;
3810
3811 cur_token = * index;
3812
3813 r = mailimap_dquote_parse(fd, buffer, &cur_token);
3814 if (r != MAILIMAP_NO_ERROR)
3815 return r;
3816
3817 r = mailimap_date_day_fixed_parse(fd, buffer, &cur_token, &day);
3818 if (r != MAILIMAP_NO_ERROR)
3819 return r;
3820
3821 r = mailimap_minus_parse(fd, buffer, &cur_token);
3822 if (r != MAILIMAP_NO_ERROR)
3823 return r;
3824
3825 r = mailimap_date_month_parse(fd, buffer, &cur_token, &month);
3826 if (r != MAILIMAP_NO_ERROR)
3827 return r;
3828
3829 r = mailimap_minus_parse(fd, buffer, &cur_token);
3830 if (r != MAILIMAP_NO_ERROR)
3831 return r;
3832
3833 r = mailimap_date_year_parse(fd, buffer, &cur_token, &year);
3834 if (r != MAILIMAP_NO_ERROR)
3835 return r;
3836
3837 r = mailimap_space_parse(fd, buffer, &cur_token);
3838 if (r != MAILIMAP_NO_ERROR)
3839 return r;
3840
3841 r = mailimap_time_parse(fd, buffer, &cur_token, &hour, &min, &sec);
3842 if (r != MAILIMAP_NO_ERROR)
3843 return r;
3844
3845 r = mailimap_space_parse(fd, buffer, &cur_token);
3846 if (r != MAILIMAP_NO_ERROR)
3847 return r;
3848
3849 r = mailimap_zone_parse(fd, buffer, &cur_token, &zone);
3850 if (r != MAILIMAP_NO_ERROR)
3851 return r;
3852
3853 r = mailimap_dquote_parse(fd, buffer, &cur_token);
3854 if (r != MAILIMAP_NO_ERROR)
3855 return r;
3856
3857 date_time = mailimap_date_time_new(day, month, year, hour, min, sec, zone);
3858 if (date_time == NULL)
3859 return MAILIMAP_ERROR_MEMORY;
3860
3861 * result = date_time;
3862 * index = cur_token;
3863
3864 return MAILIMAP_NO_ERROR;
3865}
3866
3867
3868/*
3869 UNIMPLEMENTED
3870 delete = "DELETE" SP mailbox
3871 ; Use of INBOX gives a NO error
3872*/
3873
3874/*
3875 digit-nz = %x31-39
3876 ; 1-9
3877*/
3878
3879#ifndef UNSTRICT_SYNTAX
3880static int is_digit_nz(char ch)
3881{
3882 return (ch >= '1') && (ch <= '9');
3883}
3884
3885static int mailimap_digit_nz_parse(mailstream * fd, MMAPString * buffer,
3886 size_t * index, int * result)
3887{
3888 size_t cur_token;
3889
3890 cur_token = * index;
3891
3892 if (is_digit_nz(buffer->str[cur_token])) {
3893 * result = buffer->str[cur_token] - '0';
3894 cur_token ++;
3895 * index = cur_token;
3896 return MAILIMAP_NO_ERROR;
3897 }
3898 else
3899 return MAILIMAP_ERROR_PARSE;
3900}
3901#endif
3902
3903/*
3904 envelope = "(" env-date SP env-subject SP env-from SP env-sender SP
3905 env-reply-to SP env-to SP env-cc SP env-bcc SP
3906 env-in-reply-to SP env-message-id ")"
3907*/
3908
3909static int mailimap_envelope_parse(mailstream * fd, MMAPString * buffer,
3910 size_t * index,
3911 struct mailimap_envelope ** result,
3912 size_t progr_rate,
3913 progress_function * progr_fun)
3914{
3915 size_t cur_token;
3916 char * date;
3917 char * subject;
3918 struct mailimap_env_from * from;
3919 struct mailimap_env_sender * sender;
3920 struct mailimap_env_reply_to * reply_to;
3921 struct mailimap_env_to * to;
3922 struct mailimap_env_cc * cc;
3923 struct mailimap_env_bcc * bcc;
3924 char * in_reply_to;
3925 char * message_id;
3926 struct mailimap_envelope * envelope;
3927 int r;
3928 int res;
3929
3930 date = NULL;
3931 subject = NULL;
3932 from = NULL;
3933 sender = NULL;
3934 reply_to = NULL;
3935 to = NULL;
3936 cc = NULL;
3937 bcc = NULL;
3938 in_reply_to = NULL;
3939 message_id = NULL;
3940
3941 cur_token = * index;
3942
3943 r = mailimap_oparenth_parse(fd, buffer, &cur_token);
3944 if (r != MAILIMAP_NO_ERROR) {
3945 res = r;
3946 goto err;
3947 }
3948
3949 r = mailimap_env_date_parse(fd, buffer, &cur_token, &date,
3950 progr_rate, progr_fun);
3951 if (r != MAILIMAP_NO_ERROR) {
3952 res = r;
3953 goto err;
3954 }
3955
3956 r = mailimap_space_parse(fd, buffer, &cur_token);
3957 if (r != MAILIMAP_NO_ERROR) {
3958 res = r;
3959 goto date;
3960 }
3961
3962 r = mailimap_env_subject_parse(fd, buffer, &cur_token, &subject,
3963 progr_rate, progr_fun);
3964 if (r != MAILIMAP_NO_ERROR) {
3965 res = r;
3966 goto date;
3967 }
3968
3969 r = mailimap_space_parse(fd, buffer, &cur_token);
3970 if (r != MAILIMAP_NO_ERROR) {
3971 res = r;
3972 goto subject;
3973 }
3974
3975 r = mailimap_env_from_parse(fd, buffer, &cur_token, &from,
3976 progr_rate, progr_fun);
3977 if (r != MAILIMAP_NO_ERROR) {
3978 res = r;
3979 goto subject;
3980 }
3981
3982 r = mailimap_space_parse(fd, buffer, &cur_token);
3983 if (r != MAILIMAP_NO_ERROR) {
3984 res = r;
3985 goto from;
3986 }
3987
3988 r = mailimap_env_sender_parse(fd, buffer, &cur_token, &sender,
3989 progr_rate, progr_fun);
3990 if (r != MAILIMAP_NO_ERROR) {
3991 res = r;
3992 goto from;
3993 }
3994
3995 r = mailimap_space_parse(fd, buffer, &cur_token);
3996 if (r != MAILIMAP_NO_ERROR) {
3997 res = r;
3998 goto sender;
3999 }
4000
4001 r = mailimap_env_reply_to_parse(fd, buffer, &cur_token, &reply_to,
4002 progr_rate, progr_fun);
4003 if (r != MAILIMAP_NO_ERROR) {
4004 res = r;
4005 goto sender;
4006 }
4007
4008 r = mailimap_space_parse(fd, buffer, &cur_token);
4009 if (r != MAILIMAP_NO_ERROR) {
4010 res = r;
4011 goto reply_to;
4012 }
4013
4014 r = mailimap_env_to_parse(fd, buffer, &cur_token, &to,
4015 progr_rate, progr_fun);
4016 if (r != MAILIMAP_NO_ERROR) {
4017 res = r;
4018 goto reply_to;
4019 }
4020
4021 r = mailimap_space_parse(fd, buffer, &cur_token);
4022 if (r != MAILIMAP_NO_ERROR) {
4023 res = r;
4024 goto to;
4025 }
4026
4027 r = mailimap_env_cc_parse(fd, buffer, &cur_token, &cc,
4028 progr_rate, progr_fun);
4029 if (r != MAILIMAP_NO_ERROR) {
4030 res = r;
4031 goto to;
4032 }
4033
4034 r = mailimap_space_parse(fd, buffer, &cur_token);
4035 if (r != MAILIMAP_NO_ERROR) {
4036 res = r;
4037 goto cc;
4038 }
4039
4040 r = mailimap_env_bcc_parse(fd, buffer, &cur_token, &bcc,
4041 progr_rate, progr_fun);
4042 if (r != MAILIMAP_NO_ERROR) {
4043 res = r;
4044 goto cc;
4045 }
4046
4047 r = mailimap_space_parse(fd, buffer, &cur_token);
4048 if (r != MAILIMAP_NO_ERROR) {
4049 res = r;
4050 goto bcc;
4051 }
4052
4053 r = mailimap_env_in_reply_to_parse(fd, buffer, &cur_token, &in_reply_to,
4054 progr_rate, progr_fun);
4055 if (r != MAILIMAP_NO_ERROR) {
4056 res = r;
4057 goto bcc;
4058 }
4059
4060 r = mailimap_space_parse(fd, buffer, &cur_token);
4061 if (r != MAILIMAP_NO_ERROR) {
4062 res = r;
4063 goto in_reply_to;
4064 }
4065
4066 r = mailimap_env_message_id_parse(fd, buffer, &cur_token, &message_id,
4067 progr_rate, progr_fun);
4068 if (r != MAILIMAP_NO_ERROR) {
4069 res = r;
4070 goto in_reply_to;
4071 }
4072
4073 r = mailimap_cparenth_parse(fd, buffer, &cur_token);
4074 if (r != MAILIMAP_NO_ERROR) {
4075 res = r;
4076 goto message_id;
4077 }
4078
4079 envelope = mailimap_envelope_new(date, subject, from, sender, reply_to, to,
4080 cc, bcc, in_reply_to, message_id);
4081 if (envelope == NULL) {
4082 res = MAILIMAP_ERROR_MEMORY;
4083 goto message_id;
4084 }
4085
4086 * result = envelope;
4087 * index = cur_token;
4088
4089 return MAILIMAP_NO_ERROR;
4090
4091 message_id:
4092 mailimap_env_message_id_free(message_id);
4093 in_reply_to:
4094 mailimap_env_in_reply_to_free(in_reply_to);
4095 bcc:
4096 mailimap_env_bcc_free(bcc);
4097 cc:
4098 mailimap_env_cc_free(cc);
4099 to:
4100 mailimap_env_to_free(to);
4101 reply_to:
4102 mailimap_env_reply_to_free(reply_to);
4103 sender:
4104 mailimap_env_sender_free(sender);
4105 from:
4106 mailimap_env_from_free(from);
4107 subject:
4108 mailimap_env_subject_free(date);
4109 date:
4110 mailimap_env_date_free(date);
4111 err:
4112 return res;
4113}
4114
4115/*
4116 "(" 1*address ")"
4117*/
4118
4119static int mailimap_address_list_parse(mailstream * fd, MMAPString * buffer,
4120 size_t * index,
4121 clist ** result,
4122 size_t progr_rate,
4123 progress_function * progr_fun)
4124{
4125 size_t cur_token;
4126 clist * address_list;
4127 int r;
4128 int res;
4129
4130 cur_token = * index;
4131
4132 address_list = NULL;
4133
4134 r = mailimap_nil_parse(fd, buffer, &cur_token);
4135 switch (r) {
4136 case MAILIMAP_NO_ERROR:
4137 address_list = NULL;
4138 break;
4139
4140 case MAILIMAP_ERROR_PARSE:
4141 r = mailimap_oparenth_parse(fd, buffer, &cur_token);
4142 if (r != MAILIMAP_NO_ERROR) {
4143 res = r;
4144 goto err;
4145 }
4146
4147 r = mailimap_struct_multiple_parse(fd, buffer, &cur_token, &address_list,
4148 (mailimap_struct_parser *)
4149 mailimap_address_parse,
4150 (mailimap_struct_destructor *)
4151 mailimap_address_free,
4152 progr_rate, progr_fun);
4153 if (r != MAILIMAP_NO_ERROR) {
4154 res = r;
4155 goto err;
4156 }
4157
4158 r = mailimap_cparenth_parse(fd, buffer, &cur_token);
4159 if (r != MAILIMAP_NO_ERROR) {
4160 res = r;
4161 goto address_list;
4162 }
4163
4164 break;
4165
4166 default:
4167 res = r;
4168 goto err;
4169 }
4170
4171 * result = address_list;
4172 * index = cur_token;
4173
4174 return MAILIMAP_NO_ERROR;
4175
4176 address_list:
4177 if (address_list) {
4178 clist_foreach(address_list, (clist_func) mailimap_address_free, NULL);
4179 clist_free(address_list);
4180 }
4181 err:
4182 return res;
4183}
4184
4185/*
4186 env-bcc = "(" 1*address ")" / nil
4187*/
4188
4189static int
4190mailimap_env_bcc_parse(mailstream * fd, MMAPString * buffer,
4191 size_t * index, struct mailimap_env_bcc ** result,
4192 size_t progr_rate,
4193 progress_function * progr_fun)
4194{
4195 clist * list;
4196 size_t cur_token;
4197 struct mailimap_env_bcc * env_bcc;
4198 int r;
4199 int res;
4200
4201 cur_token = * index;
4202 list = NULL;
4203
4204 r = mailimap_address_list_parse(fd, buffer, &cur_token, &list,
4205 progr_rate, progr_fun);
4206 if (r != MAILIMAP_NO_ERROR) {
4207 res = r;
4208 goto err;
4209 }
4210
4211 env_bcc = mailimap_env_bcc_new(list);
4212 if (env_bcc == NULL) {
4213 res = MAILIMAP_ERROR_MEMORY;
4214 goto free;
4215 }
4216
4217 * index = cur_token;
4218 * result = env_bcc;
4219
4220 return MAILIMAP_NO_ERROR;
4221
4222 free:
4223 clist_foreach(list, (clist_func) mailimap_address_free, NULL);
4224 clist_free(list);
4225 err:
4226 return res;
4227}
4228
4229/*
4230 env-cc = "(" 1*address ")" / nil
4231*/
4232
4233static int
4234mailimap_env_cc_parse(mailstream * fd, MMAPString * buffer,
4235 size_t * index, struct mailimap_env_cc ** result,
4236 size_t progr_rate,
4237 progress_function * progr_fun)
4238{
4239 clist * list;
4240 size_t cur_token;
4241 struct mailimap_env_cc * env_cc;
4242 int r;
4243 int res;
4244
4245 cur_token = * index;
4246 list = NULL;
4247
4248 r = mailimap_address_list_parse(fd, buffer, &cur_token, &list,
4249 progr_rate, progr_fun);
4250 if (r != MAILIMAP_NO_ERROR) {
4251 res = r;
4252 goto err;
4253 }
4254
4255 env_cc = mailimap_env_cc_new(list);
4256 if (env_cc == NULL) {
4257 res = MAILIMAP_ERROR_MEMORY;
4258 goto free;
4259 }
4260
4261 * index = cur_token;
4262 * result = env_cc;
4263
4264 return MAILIMAP_NO_ERROR;
4265
4266 free:
4267 clist_foreach(list, (clist_func) mailimap_address_free, NULL);
4268 clist_free(list);
4269 err:
4270 return res;
4271}
4272
4273/*
4274 env-date = nstring
4275*/
4276
4277static int mailimap_env_date_parse(mailstream * fd, MMAPString * buffer,
4278 size_t * index, char ** result,
4279 size_t progr_rate,
4280 progress_function * progr_fun)
4281{
4282 return mailimap_nstring_parse(fd, buffer, index, result, NULL,
4283 progr_rate, progr_fun);
4284}
4285
4286/*
4287 env-from = "(" 1*address ")" / nil
4288*/
4289
4290static int
4291mailimap_env_from_parse(mailstream * fd, MMAPString * buffer,
4292 size_t * index, struct mailimap_env_from ** result,
4293 size_t progr_rate,
4294 progress_function * progr_fun)
4295{
4296 clist * list;
4297 size_t cur_token;
4298 struct mailimap_env_from * env_from;
4299 int r;
4300 int res;
4301
4302 cur_token = * index;
4303 list = NULL;
4304
4305 r = mailimap_address_list_parse(fd, buffer, &cur_token, &list,
4306 progr_rate, progr_fun);
4307 if (r != MAILIMAP_NO_ERROR) {
4308 res = r;
4309 goto err;
4310 }
4311
4312 env_from = mailimap_env_from_new(list);
4313 if (env_from == NULL) {
4314 res = MAILIMAP_ERROR_MEMORY;
4315 goto free;
4316 }
4317
4318 * index = cur_token;
4319 * result = env_from;
4320
4321 return MAILIMAP_NO_ERROR;
4322
4323 free:
4324 clist_foreach(list, (clist_func) mailimap_address_free, NULL);
4325 clist_free(list);
4326 err:
4327 return res;
4328}
4329
4330/*
4331 env-in-reply-to = nstring
4332*/
4333
4334static int mailimap_env_in_reply_to_parse(mailstream * fd,
4335 MMAPString * buffer,
4336 size_t * index, char ** result,
4337 size_t progr_rate,
4338 progress_function * progr_fun)
4339{
4340 return mailimap_nstring_parse(fd, buffer, index, result, NULL,
4341 progr_rate, progr_fun);
4342}
4343
4344/*
4345 env-message-id = nstring
4346*/
4347
4348static int mailimap_env_message_id_parse(mailstream * fd,
4349 MMAPString * buffer,
4350 size_t * index, char ** result,
4351 size_t progr_rate,
4352 progress_function * progr_fun)
4353{
4354 return mailimap_nstring_parse(fd, buffer, index, result, NULL,
4355 progr_rate, progr_fun);
4356}
4357
4358/*
4359 env-reply-to = "(" 1*address ")" / nil
4360*/
4361
4362static int
4363mailimap_env_reply_to_parse(mailstream * fd, MMAPString * buffer,
4364 size_t * index,
4365 struct mailimap_env_reply_to ** result,
4366 size_t progr_rate,
4367 progress_function * progr_fun)
4368{
4369 clist * list;
4370 size_t cur_token;
4371 struct mailimap_env_reply_to * env_reply_to;
4372 int r;
4373 int res;
4374
4375 cur_token = * index;
4376 list = NULL;
4377
4378 r = mailimap_address_list_parse(fd, buffer, &cur_token, &list,
4379 progr_rate, progr_fun);
4380 if (r != MAILIMAP_NO_ERROR) {
4381 res = r;
4382 goto err;
4383 }
4384
4385 env_reply_to = mailimap_env_reply_to_new(list);
4386 if (env_reply_to == NULL) {
4387 res = MAILIMAP_ERROR_MEMORY;
4388 goto free;
4389 }
4390
4391 * index = cur_token;
4392 * result = env_reply_to;
4393
4394 return MAILIMAP_NO_ERROR;
4395
4396 free:
4397 clist_foreach(list, (clist_func) mailimap_address_free, NULL);
4398 clist_free(list);
4399 err:
4400 return res;
4401}
4402
4403/*
4404 env-sender = "(" 1*address ")" / nil
4405*/
4406
4407
4408static int
4409mailimap_env_sender_parse(mailstream * fd, MMAPString * buffer,
4410 size_t * index, struct mailimap_env_sender ** result,
4411 size_t progr_rate,
4412 progress_function * progr_fun)
4413{
4414 clist * list;
4415 size_t cur_token;
4416 struct mailimap_env_sender * env_sender;
4417 int r;
4418 int res;
4419
4420 cur_token = * index;
4421 list = NULL;
4422
4423 r = mailimap_address_list_parse(fd, buffer, &cur_token, &list,
4424 progr_rate, progr_fun);
4425 if (r != MAILIMAP_NO_ERROR) {
4426 res = r;
4427 goto err;
4428 }
4429
4430 env_sender = mailimap_env_sender_new(list);
4431 if (env_sender == NULL) {
4432 res = MAILIMAP_ERROR_MEMORY;
4433 goto free;
4434 }
4435
4436 * index = cur_token;
4437 * result = env_sender;
4438
4439 return MAILIMAP_NO_ERROR;
4440
4441 free:
4442 clist_foreach(list, (clist_func) mailimap_address_free, NULL);
4443 clist_free(list);
4444 err:
4445 return res;
4446}
4447
4448
4449/*
4450 env-subject = nstring
4451*/
4452
4453static int mailimap_env_subject_parse(mailstream * fd, MMAPString * buffer,
4454 size_t * index, char ** result,
4455 size_t progr_rate,
4456 progress_function * progr_fun)
4457{
4458 return mailimap_nstring_parse(fd, buffer, index, result, NULL,
4459 progr_rate, progr_fun);
4460}
4461
4462
4463/*
4464 env-to = "(" 1*address ")" / nil
4465*/
4466
4467static int mailimap_env_to_parse(mailstream * fd, MMAPString * buffer,
4468 size_t * index,
4469 struct mailimap_env_to ** result,
4470 size_t progr_rate,
4471 progress_function * progr_fun)
4472{
4473 clist * list;
4474 size_t cur_token;
4475 struct mailimap_env_to * env_to;
4476 int r;
4477 int res;
4478
4479 cur_token = * index;
4480 list = NULL;
4481
4482 r = mailimap_address_list_parse(fd, buffer, &cur_token, &list,
4483 progr_rate, progr_fun);
4484 if (r != MAILIMAP_NO_ERROR) {
4485 res = r;
4486 goto err;
4487 }
4488
4489 env_to = mailimap_env_to_new(list);
4490 if (env_to == NULL) {
4491 res = MAILIMAP_ERROR_MEMORY;
4492 goto free;
4493 }
4494
4495 * index = cur_token;
4496 * result = env_to;
4497
4498 return MAILIMAP_NO_ERROR;
4499
4500 free:
4501 clist_foreach(list, (clist_func) mailimap_address_free, NULL);
4502 clist_free(list);
4503 err:
4504 return res;
4505}
4506
4507
4508/*
4509 UNIMPLEMENTED
4510 examine = "EXAMINE" SP mailbox
4511*/
4512
4513/*
4514 UNIMPLEMENTED
4515 fetch = "FETCH" SP set SP ("ALL" / "FULL" / "FAST" / fetch-att /
4516 "(" fetch-att *(SP fetch-att) ")")
4517*/
4518
4519/*
4520 UNIMPLEMENTED
4521 fetch-att = "ENVELOPE" / "FLAGS" / "INTERNALDATE" /
4522 "RFC822" [".HEADER" / ".SIZE" / ".TEXT"] /
4523 "BODY" ["STRUCTURE"] / "UID" /
4524 "BODY" [".PEEK"] section ["<" number "." nz-number ">"]
4525*/
4526
4527/*
4528 flag = "\Answered" / "\Flagged" / "\Deleted" /
4529 "\Seen" / "\Draft" / flag-keyword / flag-extension
4530 ; Does not include "\Recent"
4531*/
4532
4533static int mailimap_flag_parse(mailstream * fd, MMAPString * buffer,
4534 size_t * index,
4535 struct mailimap_flag ** result,
4536 size_t progr_rate,
4537 progress_function * progr_fun)
4538{
4539 struct mailimap_flag * flag;
4540 size_t cur_token;
4541 char * flag_keyword;
4542 char * flag_extension;
4543 int type;
4544 int r;
4545 int res;
4546
4547 cur_token = * index;
4548
4549 flag_keyword = NULL;
4550 flag_extension = NULL;
4551
4552 type = mailimap_flag_get_token_value(fd, buffer, &cur_token);
4553 if (type == -1) {
4554 r = mailimap_flag_keyword_parse(fd, buffer, &cur_token, &flag_keyword,
4555 progr_rate, progr_fun);
4556 if (r == MAILIMAP_NO_ERROR)
4557 type = MAILIMAP_FLAG_KEYWORD;
4558
4559 if (r == MAILIMAP_ERROR_PARSE) {
4560 r = mailimap_flag_extension_parse(fd, buffer, &cur_token,
4561 &flag_extension,
4562 progr_rate, progr_fun);
4563 type = MAILIMAP_FLAG_EXTENSION;
4564 }
4565
4566 if (r != MAILIMAP_NO_ERROR) {
4567 res = r;
4568 goto err;
4569 }
4570 }
4571
4572 flag = mailimap_flag_new(type, flag_keyword, flag_extension);
4573 if (flag == NULL) {
4574 res = MAILIMAP_ERROR_MEMORY;
4575 goto free;
4576 }
4577
4578 * result = flag;
4579 * index = cur_token;
4580
4581 return MAILIMAP_NO_ERROR;
4582
4583 free:
4584 if (flag_keyword != NULL)
4585 mailimap_flag_keyword_free(flag_keyword);
4586 if (flag_extension != NULL)
4587 mailimap_flag_extension_free(flag_extension);
4588 err:
4589 return res;
4590}
4591
4592/*
4593 flag-extension = "\" atom
4594 ; Future expansion. Client implementations
4595 ; MUST accept flag-extension flags. Server
4596 ; implementations MUST NOT generate
4597 ; flag-extension flags except as defined by
4598 ; future standard or standards-track
4599 ; revisions of this specification.
4600*/
4601
4602static int mailimap_flag_extension_parse(mailstream * fd,
4603 MMAPString * buffer,
4604 size_t * index,
4605 char ** result,
4606 size_t progr_rate,
4607 progress_function * progr_fun)
4608{
4609 size_t cur_token;
4610 char * atom;
4611 int r;
4612
4613 cur_token = * index;
4614
4615 r = mailimap_char_parse(fd, buffer, &cur_token, '\\');
4616 if (r != MAILIMAP_NO_ERROR)
4617 return r;
4618
4619 r = mailimap_atom_parse(fd, buffer, &cur_token, &atom,
4620 progr_rate, progr_fun);
4621 if (r != MAILIMAP_NO_ERROR)
4622 return r;
4623
4624 * result = atom;
4625 * index = cur_token;
4626
4627 return MAILIMAP_NO_ERROR;
4628}
4629
4630/*
4631 flag-fetch = flag / "\Recent"
4632*/
4633
4634static int
4635mailimap_flag_fetch_parse(mailstream * fd, MMAPString * buffer,
4636 size_t * index,
4637 struct mailimap_flag_fetch ** result,
4638 size_t progr_rate,
4639 progress_function * progr_fun)
4640{
4641 size_t cur_token;
4642 struct mailimap_flag * flag;
4643 struct mailimap_flag_fetch * flag_fetch;
4644 int type;
4645 int r;
4646 int res;
4647
4648 cur_token = * index;
4649
4650 flag = NULL;
4651
4652 type = MAILIMAP_FLAG_FETCH_ERROR; /* XXX - removes a gcc warning */
4653
4654 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
4655 "\\Recent");
4656 if (r == MAILIMAP_NO_ERROR)
4657 type = MAILIMAP_FLAG_FETCH_RECENT;
4658
4659 if (r == MAILIMAP_ERROR_PARSE) {
4660 r = mailimap_flag_parse(fd, buffer, &cur_token, &flag,
4661 progr_rate, progr_fun);
4662 if (r == MAILIMAP_NO_ERROR)
4663 type = MAILIMAP_FLAG_FETCH_OTHER;
4664 }
4665
4666 if (r != MAILIMAP_NO_ERROR) {
4667 res = r;
4668 goto err;
4669 }
4670
4671 flag_fetch = mailimap_flag_fetch_new(type, flag);
4672 if (flag_fetch == NULL) {
4673 res = MAILIMAP_ERROR_MEMORY;
4674 goto free;
4675 }
4676
4677 * index = cur_token;
4678 * result = flag_fetch;
4679
4680 return MAILIMAP_NO_ERROR;
4681
4682 free:
4683 if (flag != NULL)
4684 mailimap_flag_free(flag);
4685 err:
4686 return res;
4687}
4688
4689/*
4690 flag-keyword = atom
4691*/
4692
4693static int mailimap_flag_keyword_parse(mailstream * fd, MMAPString * buffer,
4694 size_t * index,
4695 char ** result,
4696 size_t progr_rate,
4697 progress_function * progr_fun)
4698{
4699 return mailimap_atom_parse(fd, buffer, index, result,
4700 progr_rate, progr_fun);
4701}
4702
4703/*
4704 flag-list = "(" [flag *(SP flag)] ")"
4705*/
4706
4707static int mailimap_flag_list_parse(mailstream * fd, MMAPString * buffer,
4708 size_t * index,
4709 struct mailimap_flag_list ** result,
4710 size_t progr_rate,
4711 progress_function * progr_fun)
4712{
4713 size_t cur_token;
4714 clist * list;
4715 struct mailimap_flag_list * flag_list;
4716 int r;
4717 int res;
4718
4719 list = NULL;
4720 cur_token = * index;
4721
4722 r = mailimap_oparenth_parse(fd, buffer, &cur_token);
4723 if (r != MAILIMAP_NO_ERROR) {
4724 res = r;
4725 goto err;
4726 }
4727
4728 r = mailimap_struct_spaced_list_parse(fd, buffer, &cur_token, &list,
4729 (mailimap_struct_parser *)
4730 mailimap_flag_parse,
4731 (mailimap_struct_destructor *)
4732 mailimap_flag_free,
4733 progr_rate, progr_fun);
4734
4735 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) {
4736 res = r;
4737 goto err;
4738 }
4739
4740 r = mailimap_cparenth_parse(fd, buffer, &cur_token);
4741 if (r != MAILIMAP_NO_ERROR) {
4742 res = r;
4743 goto free;
4744 }
4745
4746 flag_list = mailimap_flag_list_new(list);
4747 if (flag_list == NULL) {
4748 res = MAILIMAP_ERROR_MEMORY;
4749 goto free;
4750 }
4751
4752 * result = flag_list;
4753 * index = cur_token;
4754
4755 return MAILIMAP_NO_ERROR;
4756
4757 free:
4758 if (list != NULL) {
4759 clist_foreach(list, (clist_func) mailimap_flag_free, NULL);
4760 clist_free(list);
4761 }
4762 err:
4763 return res;
4764}
4765
4766/*
4767 flag-perm = flag / "\*"
4768*/
4769
4770static int
4771mailimap_flag_perm_parse(mailstream * fd, MMAPString * buffer,
4772 size_t * index,
4773 struct mailimap_flag_perm ** result,
4774 size_t progr_rate,
4775 progress_function * progr_fun)
4776{
4777 size_t cur_token;
4778 struct mailimap_flag_perm * flag_perm;
4779 struct mailimap_flag * flag;
4780 int type;
4781 int r;
4782 int res;
4783
4784 flag = NULL;
4785 cur_token = * index;
4786 type = MAILIMAP_FLAG_PERM_ERROR; /* XXX - removes a gcc warning */
4787
4788 r = mailimap_flag_parse(fd, buffer, &cur_token, &flag,
4789 progr_rate, progr_fun);
4790 if (r == MAILIMAP_NO_ERROR)
4791 type = MAILIMAP_FLAG_PERM_FLAG;
4792
4793 if (r == MAILIMAP_ERROR_PARSE) {
4794 r = mailimap_token_case_insensitive_parse(fd, buffer,
4795 &cur_token, "\\*");
4796 if (r == MAILIMAP_NO_ERROR)
4797 type = MAILIMAP_FLAG_PERM_ALL;
4798 }
4799
4800 if (r != MAILIMAP_NO_ERROR) {
4801 res = r;
4802 goto err;
4803 }
4804
4805 flag_perm = mailimap_flag_perm_new(type, flag);
4806 if (flag_perm == NULL) {
4807 res = MAILIMAP_ERROR_MEMORY;
4808 goto free;
4809 }
4810
4811 * result = flag_perm;
4812 * index = cur_token;
4813
4814 return MAILIMAP_NO_ERROR;
4815
4816 free:
4817 if (flag != NULL)
4818 mailimap_flag_free(flag);
4819 err:
4820 return res;
4821}
4822
4823/*
4824 greeting = "*" SP (resp-cond-auth / resp-cond-bye) CRLF
4825*/
4826
4827int mailimap_greeting_parse(mailstream * fd, MMAPString * buffer,
4828 size_t * index,
4829 struct mailimap_greeting ** result,
4830 size_t progr_rate,
4831 progress_function * progr_fun)
4832{
4833 size_t cur_token;
4834 struct mailimap_resp_cond_auth * resp_cond_auth;
4835 struct mailimap_resp_cond_bye * resp_cond_bye;
4836 struct mailimap_greeting * greeting;
4837 int type;
4838 int r;
4839 int res;
4840
4841 cur_token = * index;
4842 resp_cond_bye = NULL;
4843 resp_cond_auth = NULL;
4844
4845 r = mailimap_star_parse(fd, buffer, &cur_token);
4846 if (r != MAILIMAP_NO_ERROR) {
4847 res = r;
4848 goto err;
4849 }
4850
4851 r = mailimap_space_parse(fd, buffer, &cur_token);
4852 if (r != MAILIMAP_NO_ERROR) {
4853 res = r;
4854 goto err;
4855 }
4856
4857 type = MAILIMAP_GREETING_RESP_COND_ERROR; /* XXX - removes a gcc warning */
4858
4859 r = mailimap_resp_cond_auth_parse(fd, buffer, &cur_token, &resp_cond_auth,
4860 progr_rate, progr_fun);
4861 if (r == MAILIMAP_NO_ERROR)
4862 type = MAILIMAP_GREETING_RESP_COND_AUTH;
4863
4864 if (r == MAILIMAP_ERROR_PARSE) {
4865 r = mailimap_resp_cond_bye_parse(fd, buffer, &cur_token,
4866 &resp_cond_bye,
4867 progr_rate, progr_fun);
4868 if (r == MAILIMAP_NO_ERROR)
4869 type = MAILIMAP_GREETING_RESP_COND_BYE;
4870 }
4871
4872 if (r != MAILIMAP_NO_ERROR) {
4873 res = r;
4874 goto err;
4875 }
4876
4877 r = mailimap_crlf_parse(fd, buffer, &cur_token);
4878 if (r != MAILIMAP_NO_ERROR) {
4879 res = r;
4880 goto free;
4881 }
4882
4883 greeting = mailimap_greeting_new(type, resp_cond_auth, resp_cond_bye);
4884 if (greeting == NULL) {
4885 res = MAILIMAP_ERROR_MEMORY;
4886 goto free;
4887 }
4888
4889 * result = greeting;
4890 * index = cur_token;
4891
4892 return MAILIMAP_NO_ERROR;
4893
4894 free:
4895 if (resp_cond_auth)
4896 mailimap_resp_cond_auth_free(resp_cond_auth);
4897 if (resp_cond_bye)
4898 mailimap_resp_cond_bye_free(resp_cond_bye);
4899 err:
4900 return res;
4901}
4902
4903/*
4904 header-fld-name = astring
4905*/
4906
4907static int
4908mailimap_header_fld_name_parse(mailstream * fd,
4909 MMAPString * buffer,
4910 size_t * index,
4911 char ** result,
4912 size_t progr_rate,
4913 progress_function * progr_fun)
4914{
4915 return mailimap_astring_parse(fd, buffer, index, result,
4916 progr_rate, progr_fun);
4917}
4918
4919/*
4920 header-list = "(" header-fld-name *(SP header-fld-name) ")"
4921*/
4922
4923static int
4924mailimap_header_list_parse(mailstream * fd, MMAPString * buffer,
4925 size_t * index,
4926 struct mailimap_header_list ** result,
4927 size_t progr_rate,
4928 progress_function * progr_fun)
4929{
4930 size_t cur_token;
4931 struct mailimap_header_list * header_list;
4932 clist * list;
4933 int r;
4934 int res;
4935
4936 cur_token = * index;
4937
4938 list = NULL;
4939
4940 r = mailimap_oparenth_parse(fd, buffer, &cur_token);
4941 if (r != MAILIMAP_NO_ERROR) {
4942 res = r;
4943 goto err;
4944 }
4945
4946 r = mailimap_struct_spaced_list_parse(fd, buffer, &cur_token, &list,
4947 (mailimap_struct_parser *)
4948 mailimap_header_fld_name_parse,
4949 (mailimap_struct_destructor *)
4950 mailimap_header_fld_name_free,
4951 progr_rate, progr_fun);
4952 if (r != MAILIMAP_NO_ERROR) {
4953 res = r;
4954 goto err;
4955 }
4956
4957 r = mailimap_cparenth_parse(fd, buffer, &cur_token);
4958 if (r != MAILIMAP_NO_ERROR) {
4959 res = r;
4960 goto free;
4961 }
4962
4963 header_list = mailimap_header_list_new(list);
4964 if (header_list == NULL) {
4965 res = MAILIMAP_ERROR_MEMORY;
4966 goto free;
4967 }
4968
4969 * result = header_list;
4970 * index = cur_token;
4971
4972 return MAILIMAP_NO_ERROR;
4973
4974 free:
4975 clist_foreach(list, (clist_func) mailimap_header_fld_name_free, NULL);
4976 clist_free(list);
4977 err:
4978 return res;
4979}
4980
4981/*
4982UNIMPLEMENTED
4983 list = "LIST" SP mailbox SP list-mailbox
4984
4985UNIMPLEMENTED
4986 list-mailbox = 1*list-char / string
4987
4988UNIMPLEMENTED
4989 list-char = ATOM-CHAR / list-wildcards / resp-specials
4990*/
4991
4992/*
4993 list-wildcards = "%" / "*"
4994*/
4995
4996static int is_list_wildcards(char ch)
4997{
4998 switch (ch) {
4999 case '%':
5000 case '*':
5001 return TRUE;
5002 }
5003 return FALSE;
5004}
5005
5006
5007/*
5008 literal = "{" number "}" CRLF *CHAR8
5009 ; Number represents the number of CHAR8s
5010*/
5011
5012static int mailimap_literal_parse(mailstream * fd, MMAPString * buffer,
5013 size_t * index, char ** result,
5014 size_t * result_len,
5015 size_t progr_rate,
5016 progress_function * progr_fun)
5017{
5018 size_t cur_token;
5019 uint32_t number;
5020 MMAPString * literal;
5021 char * literal_p;
5022 uint32_t left;
5023 int r;
5024 int res;
5025 size_t number_token;
5026
5027 cur_token = * index;
5028
5029 r = mailimap_oaccolade_parse(fd, buffer, &cur_token);
5030 if (r != MAILIMAP_NO_ERROR) {
5031 res = r;
5032 goto err;
5033 }
5034
5035 number_token = cur_token;
5036
5037 r = mailimap_number_parse(fd, buffer, &cur_token, &number);
5038 if (r != MAILIMAP_NO_ERROR) {
5039 res = r;
5040 goto err;
5041 }
5042
5043 r = mailimap_caccolade_parse(fd, buffer, &cur_token);
5044 if (r != MAILIMAP_NO_ERROR) {
5045 res = r;
5046 goto err;
5047 }
5048
5049 r = mailimap_crlf_parse(fd, buffer, &cur_token);
5050 if (r != MAILIMAP_NO_ERROR) {
5051 res = r;
5052 goto err;
5053 }
5054
5055 literal = mmap_string_sized_new(number);
5056 /*
5057 literal = g_new(char, number + 1);
5058 */
5059 if (literal == NULL) {
5060 res = MAILIMAP_ERROR_MEMORY;
5061 goto err;
5062 }
5063
5064 left = buffer->len - cur_token;
5065
5066 if (left >= number) {
5067 /*
5068 if (number > 0)
5069 strncpy(literal, buffer->str + cur_token, number);
5070 literal[number] = 0;
5071 */
5072 if (number > 0)
5073 if (mmap_string_append_len(literal, buffer->str + cur_token,
5074 number) == NULL) {
5075 res = MAILIMAP_ERROR_MEMORY;
5076 goto free_literal;
5077 }
5078 if ((progr_fun != NULL) && (progr_rate != 0))
5079 progr_fun(number, number);
5080
5081 cur_token = cur_token + number;
5082 }
5083 else {
5084 uint32_t needed;
5085 uint32_t current_prog = 0;
5086 uint32_t last_prog = 0;
5087
5088 needed = number - left;
5089 memcpy(literal->str, buffer->str + cur_token, left);
5090 literal->len += left;
5091 literal_p = literal->str + left;
5092 current_prog = left;
5093
5094 while (needed > 0) {
5095 ssize_t read_bytes;
5096
5097 read_bytes = mailstream_read(fd, literal_p, needed);
5098 if (read_bytes == -1) {
5099 res = MAILIMAP_ERROR_STREAM;
5100 goto free_literal;
5101 }
5102 literal->len += read_bytes;
5103 needed -= read_bytes;
5104 literal_p += read_bytes;
5105
5106 current_prog += read_bytes;
5107 if ((progr_fun != NULL) && (progr_rate != 0))
5108 if (current_prog - last_prog > progr_rate) {
5109 progr_fun(current_prog, number);
5110 last_prog = current_prog;
5111 }
5112 }
5113
5114 literal->str[number] = 0;
5115
5116#if 0
5117 literal->str[number] = 0;
5118 if (mmap_string_append_len(buffer, literal->str + left,
5119 literal->len - left) == NULL) {
5120 res = MAILIMAP_ERROR_STREAM;
5121 goto free_literal;
5122 }
5123#endif
5124
5125 if (mmap_string_truncate(buffer, number_token) == NULL) {
5126 res = MAILIMAP_ERROR_MEMORY;
5127 goto free_literal;
5128 }
5129
5130 if (mmap_string_append(buffer, "0}\r\n") == NULL) {
5131 res = MAILIMAP_ERROR_MEMORY;
5132 goto free_literal;
5133 }
5134
5135 cur_token = number_token + 4;
5136 }
5137 if ((progr_fun != NULL) && (progr_rate != 0))
5138 progr_fun(number, number);
5139
5140 if (mailstream_read_line_append(fd, buffer) == NULL) {
5141 res = MAILIMAP_ERROR_STREAM;
5142 goto free_literal;
5143 }
5144
5145 if (mmap_string_ref(literal) < 0) {
5146 res = MAILIMAP_ERROR_MEMORY;
5147 goto free_literal;
5148 }
5149
5150 * result = literal->str;
5151 if (result_len != NULL)
5152 * result_len = literal->len;
5153 * index = cur_token;
5154
5155 return MAILIMAP_NO_ERROR;
5156
5157 free_literal:
5158 mmap_string_free(literal);
5159 err:
5160 return res;
5161}
5162
5163/*
5164 UNIMPLEMENTED
5165 login = "LOGIN" SP userid SP password
5166
5167 UNIMPLEMENTED
5168 lsub = "LSUB" SP mailbox SP list-mailbox
5169*/
5170
5171/*
5172 mailbox = "INBOX" / astring
5173 ; INBOX is case-insensitive. All case variants of
5174 ; INBOX (e.g. "iNbOx") MUST be interpreted as INBOX
5175 ; not as an astring. An astring which consists of
5176 ; the case-insensitive sequence "I" "N" "B" "O" "X"
5177 ; is considered to be INBOX and not an astring.
5178 ; Refer to section 5.1 for further
5179 ; semantic details of mailbox names.
5180*/
5181
5182static int
5183mailimap_mailbox_parse(mailstream * fd, MMAPString * buffer,
5184 size_t * index, char ** result,
5185 size_t progr_rate,
5186 progress_function * progr_fun)
5187{
5188 size_t cur_token;
5189 char * name;
5190 int r;
5191
5192 cur_token = * index;
5193
5194 r = mailimap_astring_parse(fd, buffer, &cur_token, &name,
5195 progr_rate, progr_fun);
5196 if (r != MAILIMAP_NO_ERROR)
5197 return r;
5198
5199 * result = name;
5200 * index = cur_token;
5201
5202 return MAILIMAP_NO_ERROR;
5203}
5204
5205
5206/*
5207 mailbox-data = "FLAGS" SP flag-list / "LIST" SP mailbox-list /
5208 "LSUB" SP mailbox-list / "SEARCH" *(SP nz-number) /
5209 "STATUS" SP mailbox SP "("
5210 [status-att SP number *(SP status-att SP number)] ")" /
5211 number SP "EXISTS" / number SP "RECENT"
5212*/
5213
5214/*
5215 "FLAGS" SP flag-list
5216*/
5217
5218static int
5219mailimap_mailbox_data_flags_parse(mailstream * fd, MMAPString * buffer,
5220 size_t * index,
5221 struct mailimap_flag_list ** result,
5222 size_t progr_rate,
5223 progress_function * progr_fun)
5224{
5225 size_t cur_token;
5226 struct mailimap_flag_list * flag_list;
5227 int r;
5228
5229 cur_token = * index;
5230
5231 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token, "FLAGS");
5232 if (r != MAILIMAP_NO_ERROR)
5233 return r;
5234
5235 r = mailimap_space_parse(fd, buffer, &cur_token);
5236 if (r != MAILIMAP_NO_ERROR)
5237 return r;
5238
5239 r = mailimap_flag_list_parse(fd, buffer, &cur_token, &flag_list,
5240 progr_rate, progr_fun);
5241 if (r != MAILIMAP_NO_ERROR)
5242 return r;
5243
5244 * result = flag_list;
5245 * index = cur_token;
5246
5247 return MAILIMAP_NO_ERROR;
5248}
5249
5250
5251/*
5252 "LIST" SP mailbox-list
5253*/
5254
5255static int
5256mailimap_mailbox_data_list_parse(mailstream * fd, MMAPString * buffer,
5257 size_t * index,
5258 struct mailimap_mailbox_list ** result,
5259 size_t progr_rate,
5260 progress_function * progr_fun)
5261{
5262 size_t cur_token;
5263 struct mailimap_mailbox_list * mb_list;
5264 int r;
5265 int res;
5266
5267 cur_token = * index;
5268
5269 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token, "LIST");
5270 if (r != MAILIMAP_NO_ERROR) {
5271 res = r;
5272 return r;
5273 }
5274
5275 r = mailimap_space_parse(fd, buffer, &cur_token);
5276 if (r != MAILIMAP_NO_ERROR) {
5277 res = r;
5278 return r;
5279 }
5280
5281 r = mailimap_mailbox_list_parse(fd, buffer, &cur_token, &mb_list,
5282 progr_rate, progr_fun);
5283 if (r != MAILIMAP_NO_ERROR) {
5284 res = r;
5285 return r;
5286 }
5287
5288 * result = mb_list;
5289 * index = cur_token;
5290
5291 return MAILIMAP_NO_ERROR;
5292}
5293
5294/*
5295 "LSUB" SP mailbox-list
5296*/
5297
5298static int
5299mailimap_mailbox_data_lsub_parse(mailstream * fd, MMAPString * buffer,
5300 size_t * index,
5301 struct mailimap_mailbox_list ** result,
5302 size_t progr_rate,
5303 progress_function * progr_fun)
5304{
5305 size_t cur_token;
5306 struct mailimap_mailbox_list * mb_list;
5307 int r;
5308
5309 cur_token = * index;
5310
5311 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token, "LSUB");
5312 if (r != MAILIMAP_NO_ERROR)
5313 return r;
5314
5315 r = mailimap_space_parse(fd, buffer, &cur_token);
5316 if (r != MAILIMAP_NO_ERROR)
5317 return r;
5318
5319 r = mailimap_mailbox_list_parse(fd, buffer, &cur_token, &mb_list,
5320 progr_rate, progr_fun);
5321 if (r != MAILIMAP_NO_ERROR)
5322 return r;
5323
5324 * result = mb_list;
5325 * index = cur_token;
5326
5327 return MAILIMAP_NO_ERROR;
5328}
5329
5330/*
5331 "SEARCH" *(SP nz-number)
5332*/
5333
5334
5335static int
5336mailimap_mailbox_data_search_parse(mailstream * fd, MMAPString * buffer,
5337 size_t * index,
5338 clist ** result,
5339 size_t progr_rate,
5340 progress_function * progr_fun)
5341{
5342 size_t cur_token;
5343 size_t final_token;
5344 clist * number_list;
5345 int r;
5346
5347 cur_token = * index;
5348
5349 r = mailimap_token_case_insensitive_parse(fd, buffer,
5350 &cur_token, "SEARCH");
5351 if (r != MAILIMAP_NO_ERROR)
5352 return r;
5353
5354 final_token = cur_token;
5355 number_list = NULL;
5356
5357 r = mailimap_space_parse(fd, buffer, &cur_token);
5358 if (r == MAILIMAP_NO_ERROR) {
5359 r = mailimap_struct_spaced_list_parse(fd, buffer, &cur_token, &number_list,
5360 (mailimap_struct_parser *)
5361 mailimap_nz_number_alloc_parse,
5362 (mailimap_struct_destructor *)
5363 mailimap_number_alloc_free,
5364 progr_rate, progr_fun);
5365 if (r == MAILIMAP_NO_ERROR)
5366 final_token = cur_token;
5367 }
5368
5369 * result = number_list;
5370 * index = final_token;
5371
5372 return MAILIMAP_NO_ERROR;
5373}
5374
5375/*
5376 "STATUS" SP mailbox SP "("
5377 [status-att SP number *(SP status-att SP number)] ")"
5378*/
5379
5380/*
5381 status-att SP number
5382*/
5383
5384static int
5385mailimap_status_info_parse(mailstream * fd, MMAPString * buffer,
5386 size_t * index,
5387 struct mailimap_status_info **
5388 result,
5389 size_t progr_rate,
5390 progress_function * progr_fun)
5391{
5392 size_t cur_token;
5393 int status_att;
5394 uint32_t value;
5395 struct mailimap_status_info * info;
5396 int r;
5397
5398 cur_token = * index;
5399 value = 0;
5400
5401 r = mailimap_status_att_parse(fd, buffer, &cur_token, &status_att);
5402 if (r != MAILIMAP_NO_ERROR)
5403 return r;
5404
5405 r = mailimap_space_parse(fd, buffer, &cur_token);
5406 if (r != MAILIMAP_NO_ERROR)
5407 return r;
5408
5409 r = mailimap_number_parse(fd, buffer, &cur_token, &value);
5410 if (r != MAILIMAP_NO_ERROR)
5411 return r;
5412
5413 info = mailimap_status_info_new(status_att, value);
5414 if (info == NULL)
5415 return MAILIMAP_ERROR_MEMORY;
5416
5417 * result = info;
5418 * index = cur_token;
5419
5420 return MAILIMAP_NO_ERROR;
5421}
5422
5423/*
5424 "STATUS" SP mailbox SP "("
5425 [status-att SP number *(SP status-att SP number)] ")"
5426*/
5427
5428static int
5429mailimap_mailbox_data_status_parse(mailstream * fd, MMAPString * buffer,
5430 size_t * index, struct
5431 mailimap_mailbox_data_status ** result,
5432 size_t progr_rate,
5433 progress_function * progr_fun)
5434{
5435 size_t cur_token;
5436 char * mb;
5437 clist * status_info_list;
5438 struct mailimap_mailbox_data_status * data_status;
5439 int r;
5440 int res;
5441
5442 cur_token = * index;
5443 mb = NULL;
5444 status_info_list = NULL;
5445
5446 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token, "STATUS");
5447 if (r != MAILIMAP_NO_ERROR) {
5448 res = r;
5449 goto err;
5450 }
5451
5452 r = mailimap_space_parse(fd, buffer, &cur_token);
5453 if (r != MAILIMAP_NO_ERROR) {
5454 res = r;
5455 goto err;
5456 }
5457
5458 r = mailimap_mailbox_parse(fd, buffer, &cur_token, &mb,
5459 progr_rate, progr_fun);
5460 if (r != MAILIMAP_NO_ERROR) {
5461 res = r;
5462 goto err;
5463 }
5464
5465 r = mailimap_space_parse(fd, buffer, &cur_token);
5466 if (r != MAILIMAP_NO_ERROR) {
5467 res = r;
5468 goto mailbox;
5469 }
5470
5471 r = mailimap_oparenth_parse(fd, buffer, &cur_token);
5472 if (r != MAILIMAP_NO_ERROR) {
5473 res = r;
5474 goto mailbox;
5475 }
5476
5477 r = mailimap_struct_spaced_list_parse(fd, buffer, &cur_token,
5478 &status_info_list,
5479 (mailimap_struct_parser *)
5480 mailimap_status_info_parse,
5481 (mailimap_struct_destructor *)
5482 mailimap_status_info_free,
5483 progr_rate, progr_fun);
5484 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) {
5485 res = r;
5486 goto mailbox;
5487 }
5488
5489 r = mailimap_cparenth_parse(fd, buffer, &cur_token);
5490 if (r != MAILIMAP_NO_ERROR) {
5491 res = r;
5492 goto status_info_list;
5493 }
5494
5495 data_status = mailimap_mailbox_data_status_new(mb, status_info_list);
5496 if (data_status == NULL) {
5497 res = MAILIMAP_ERROR_MEMORY;
5498 goto status_info_list;
5499 }
5500
5501 * result = data_status;
5502 * index = cur_token;
5503
5504 return MAILIMAP_NO_ERROR;
5505
5506 status_info_list:
5507 if (status_info_list != NULL) {
5508 clist_foreach(status_info_list, (clist_func) mailimap_status_info_free,
5509 NULL);
5510 clist_free(status_info_list);
5511 }
5512 mailbox:
5513 mailimap_mailbox_free(mb);
5514 err:
5515 return res;
5516}
5517
5518/*
5519 number SP "EXISTS"
5520*/
5521
5522static int
5523mailimap_mailbox_data_exists_parse(mailstream * fd, MMAPString * buffer,
5524 size_t * index,
5525 uint32_t * result)
5526{
5527 size_t cur_token;
5528 uint32_t number;
5529 int r;
5530
5531 cur_token = * index;
5532
5533 r = mailimap_number_parse(fd, buffer, &cur_token, &number);
5534 if (r != MAILIMAP_NO_ERROR)
5535 return r;
5536
5537 r = mailimap_space_parse(fd, buffer, &cur_token);
5538 if (r != MAILIMAP_NO_ERROR)
5539 return r;
5540
5541 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token, "EXISTS");
5542 if (r != MAILIMAP_NO_ERROR)
5543 return r;
5544
5545 * result = number;
5546 * index = cur_token;
5547
5548 return MAILIMAP_NO_ERROR;
5549}
5550
5551/*
5552 number SP "RECENT"
5553*/
5554
5555static int
5556mailimap_mailbox_data_recent_parse(mailstream * fd, MMAPString * buffer,
5557 size_t * index,
5558 uint32_t * result)
5559{
5560 size_t cur_token;
5561 uint32_t number;
5562 int r;
5563
5564 cur_token = * index;
5565
5566 r = mailimap_number_parse(fd, buffer, &cur_token, &number);
5567 if (r != MAILIMAP_NO_ERROR)
5568 return r;
5569
5570 r = mailimap_space_parse(fd, buffer, &cur_token);
5571 if (r != MAILIMAP_NO_ERROR)
5572 return r;
5573
5574 r = mailimap_token_case_insensitive_parse(fd, buffer,
5575 &cur_token, "RECENT");
5576 if (r != MAILIMAP_NO_ERROR)
5577 return r;
5578
5579 * result = number;
5580 * index = cur_token;
5581
5582 return MAILIMAP_NO_ERROR;
5583}
5584
5585/*
5586 mailbox-data = "FLAGS" SP flag-list / "LIST" SP mailbox-list /
5587 "LSUB" SP mailbox-list / "SEARCH" *(SP nz-number) /
5588 "STATUS" SP mailbox SP "("
5589 [status-att SP number *(SP status-att SP number)] ")" /
5590 number SP "EXISTS" / number SP "RECENT"
5591*/
5592
5593static int
5594mailimap_mailbox_data_parse(mailstream * fd, MMAPString * buffer,
5595 size_t * index,
5596 struct mailimap_mailbox_data ** result,
5597 size_t progr_rate,
5598 progress_function * progr_fun)
5599{
5600 int type;
5601 struct mailimap_flag_list * data_flags;
5602 struct mailimap_mailbox_list * data_list;
5603 struct mailimap_mailbox_list * data_lsub;
5604 clist * data_search;
5605 struct mailimap_mailbox_data_status * data_status;
5606 uint32_t data_exists;
5607 uint32_t data_recent;
5608
5609 struct mailimap_mailbox_data * mailbox_data;
5610 size_t cur_token;
5611 int r;
5612 int res;
5613
5614 cur_token = * index;
5615
5616 data_flags = NULL;
5617 data_list = NULL;
5618 data_lsub = NULL;
5619 data_search = NULL;
5620 data_status = NULL;
5621 data_exists = 0;
5622 data_recent = 0;
5623
5624 type = MAILIMAP_MAILBOX_DATA_ERROR; /* XXX - removes a gcc warning */
5625
5626 r = mailimap_mailbox_data_flags_parse(fd, buffer, &cur_token,
5627 &data_flags,
5628 progr_rate, progr_fun);
5629 if (r == MAILIMAP_NO_ERROR)
5630 type = MAILIMAP_MAILBOX_DATA_FLAGS;
5631
5632 if (r == MAILIMAP_ERROR_PARSE) {
5633 r = mailimap_mailbox_data_list_parse(fd, buffer, &cur_token,
5634 &data_list,
5635 progr_rate, progr_fun);
5636 if (r == MAILIMAP_NO_ERROR)
5637 type = MAILIMAP_MAILBOX_DATA_LIST;
5638 }
5639
5640 if (r == MAILIMAP_ERROR_PARSE) {
5641 r = mailimap_mailbox_data_lsub_parse(fd, buffer, &cur_token,
5642 &data_lsub,
5643 progr_rate, progr_fun);
5644 if (r == MAILIMAP_NO_ERROR)
5645 type = MAILIMAP_MAILBOX_DATA_LSUB;
5646 }
5647
5648 if (r == MAILIMAP_ERROR_PARSE) {
5649 r = mailimap_mailbox_data_search_parse(fd, buffer, &cur_token,
5650 &data_search,
5651 progr_rate, progr_fun);
5652 if (r == MAILIMAP_NO_ERROR)
5653 type = MAILIMAP_MAILBOX_DATA_SEARCH;
5654 }
5655
5656 if (r == MAILIMAP_ERROR_PARSE) {
5657 r = mailimap_mailbox_data_status_parse(fd, buffer, &cur_token,
5658 &data_status,
5659 progr_rate, progr_fun);
5660 if (r == MAILIMAP_NO_ERROR)
5661 type = MAILIMAP_MAILBOX_DATA_STATUS;
5662 }
5663
5664 if (r == MAILIMAP_ERROR_PARSE) {
5665 r = mailimap_mailbox_data_exists_parse(fd, buffer, &cur_token,
5666 &data_exists);
5667 if (r == MAILIMAP_NO_ERROR)
5668 type = MAILIMAP_MAILBOX_DATA_EXISTS;
5669 }
5670
5671 if (r == MAILIMAP_ERROR_PARSE) {
5672 r = mailimap_mailbox_data_recent_parse(fd, buffer, &cur_token,
5673 &data_recent);
5674 if (r == MAILIMAP_NO_ERROR)
5675 type = MAILIMAP_MAILBOX_DATA_RECENT;
5676 }
5677
5678 if (r != MAILIMAP_NO_ERROR) {
5679 res = r;
5680 goto err;
5681 }
5682
5683 mailbox_data = mailimap_mailbox_data_new(type, data_flags, data_list,
5684 data_lsub, data_search,
5685 data_status,
5686 data_exists, data_recent);
5687
5688 if (mailbox_data == NULL) {
5689 res = MAILIMAP_ERROR_MEMORY;
5690 goto free;
5691 }
5692
5693 * result = mailbox_data;
5694 * index = cur_token;
5695
5696 return MAILIMAP_NO_ERROR;
5697
5698 free:
5699 if (data_flags != NULL)
5700 mailimap_flag_list_free(data_flags);
5701 if (data_list != NULL)
5702 mailimap_mailbox_list_free(data_list);
5703 if (data_lsub != NULL)
5704 mailimap_mailbox_list_free(data_lsub);
5705 if (data_search != NULL)
5706 mailimap_mailbox_data_search_free(data_search);
5707 if (data_status != NULL)
5708 mailimap_mailbox_data_status_free(data_status);
5709 err:
5710 return res;
5711}
5712
5713/*
5714 mailbox-list = "(" [mbx-list-flags] ")" SP
5715 (DQUOTE QUOTED-CHAR DQUOTE / nil) SP mailbox
5716*/
5717
5718/*
5719 DQUOTE QUOTED-CHAR DQUOTE
5720*/
5721
5722static int
5723mailimap_mailbox_list_quoted_char_parse(mailstream * fd, MMAPString * buffer,
5724 size_t * index,
5725 char * result)
5726{
5727 size_t cur_token;
5728 char ch;
5729 int r;
5730
5731 cur_token = * index;
5732
5733 r = mailimap_dquote_parse(fd, buffer, &cur_token);
5734 if (r != MAILIMAP_NO_ERROR)
5735 return r;
5736
5737 r = mailimap_quoted_char_parse(fd, buffer, &cur_token, &ch);
5738 if (r != MAILIMAP_NO_ERROR)
5739 return r;
5740
5741 r = mailimap_dquote_parse(fd, buffer, &cur_token);
5742 if (r != MAILIMAP_NO_ERROR)
5743 return r;
5744
5745 * index = cur_token;
5746 * result = ch;
5747
5748 return MAILIMAP_NO_ERROR;
5749}
5750
5751static int
5752mailimap_mailbox_list_parse(mailstream * fd, MMAPString * buffer,
5753 size_t * index,
5754 struct mailimap_mailbox_list ** result,
5755 size_t progr_rate,
5756 progress_function * progr_fun)
5757{
5758 struct mailimap_mailbox_list * mb_list;
5759 struct mailimap_mbx_list_flags * mb_flag_list;
5760 char ch;
5761 char * mb;
5762 size_t cur_token;
5763 int r;
5764 int res;
5765
5766 cur_token = * index;
5767
5768 r = mailimap_oparenth_parse(fd, buffer, &cur_token);
5769 if (r != MAILIMAP_NO_ERROR) {
5770 res = r;
5771 goto err;
5772 }
5773
5774 mb_flag_list = NULL;
5775 ch = 0;
5776 mb = NULL;
5777
5778 r = mailimap_mbx_list_flags_parse(fd, buffer, &cur_token,
5779 &mb_flag_list, progr_rate, progr_fun);
5780 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) {
5781 res = r;
5782 goto err;
5783 }
5784
5785 r = mailimap_cparenth_parse(fd, buffer, &cur_token);
5786 if (r != MAILIMAP_NO_ERROR) {
5787 res = r;
5788 goto free_list_flags;
5789 }
5790
5791 r = mailimap_space_parse(fd, buffer, &cur_token);
5792 if (r != MAILIMAP_NO_ERROR) {
5793 res = r;
5794 goto free_list_flags;
5795 }
5796
5797 r = mailimap_mailbox_list_quoted_char_parse(fd, buffer, &cur_token, &ch);
5798 if (r == MAILIMAP_ERROR_PARSE)
5799 r = mailimap_nil_parse(fd, buffer, &cur_token);
5800
5801 if (r != MAILIMAP_NO_ERROR) {
5802 res = r;
5803 goto free_list_flags;
5804 }
5805
5806 r = mailimap_space_parse(fd, buffer, &cur_token);
5807 if (r != MAILIMAP_NO_ERROR) {
5808 res = r;
5809 goto free_list_flags;
5810 }
5811
5812 r = mailimap_mailbox_parse(fd, buffer, &cur_token, &mb,
5813 progr_rate, progr_fun);
5814 if (r != MAILIMAP_NO_ERROR) {
5815 res = r;
5816 goto free_list_flags;
5817 }
5818
5819 mb_list = mailimap_mailbox_list_new(mb_flag_list, ch, mb);
5820 if (mb_list == NULL) {
5821 res = MAILIMAP_ERROR_MEMORY;
5822 goto free_mailbox;
5823 }
5824
5825 * result = mb_list;
5826 * index = cur_token;
5827
5828 return MAILIMAP_NO_ERROR;
5829
5830 free_mailbox:
5831 mailimap_mailbox_free(mb);
5832 free_list_flags:
5833 if (mb_flag_list != NULL)
5834 mailimap_mbx_list_flags_free(mb_flag_list);
5835 err:
5836 return res;
5837}
5838
5839/*
5840 mbx-list-flags = *(mbx-list-oflag SP) mbx-list-sflag
5841 *(SP mbx-list-oflag) /
5842 mbx-list-oflag *(SP mbx-list-oflag)
5843*/
5844
5845static int
5846mailimap_mbx_list_flags_parse(mailstream * fd, MMAPString * buffer,
5847 size_t * index,
5848 struct mailimap_mbx_list_flags ** result,
5849 size_t progr_rate,
5850 progress_function * progr_fun)
5851{
5852 struct mailimap_mbx_list_flags * mbx_list_flag;
5853 size_t cur_token;
5854 clist * oflags;
5855 clist * oflags_2;
5856 int sflag;
5857 int type;
5858 int r;
5859 int res;
5860 size_t final_token;
5861 int try_sflag;
5862
5863 cur_token = * index;
5864 final_token = cur_token;
5865
5866 oflags = clist_new();
5867 if (oflags == NULL) {
5868 res = MAILIMAP_ERROR_MEMORY;
5869 goto err;
5870 }
5871
5872 sflag = MAILIMAP_MBX_LIST_SFLAG_ERROR;
5873 oflags_2 = NULL;
5874
5875 r = mailimap_struct_spaced_list_parse(fd, buffer, &cur_token,
5876 &oflags_2,
5877 (mailimap_struct_parser *)
5878 mailimap_mbx_list_oflag_no_sflag_parse,
5879 (mailimap_struct_destructor *)
5880 mailimap_mbx_list_oflag_free,
5881 progr_rate, progr_fun);
5882 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) {
5883 res = r;
5884 goto free;
5885 }
5886
5887 try_sflag = 1;
5888 if (r == MAILIMAP_NO_ERROR) {
5889 clist_concat(oflags, oflags_2);
5890 clist_free(oflags_2);
5891
5892 final_token = cur_token;
5893 try_sflag = 0;
5894 r = mailimap_space_parse(fd, buffer, &cur_token);
5895 if (r == MAILIMAP_NO_ERROR)
5896 try_sflag = 1;
5897 }
5898
5899 type = MAILIMAP_MBX_LIST_FLAGS_NO_SFLAG;
5900 if (try_sflag) {
5901 r = mailimap_mbx_list_sflag_parse(fd, buffer, &cur_token, &sflag);
5902 switch (r) {
5903 case MAILIMAP_ERROR_PARSE:
5904 type = MAILIMAP_MBX_LIST_FLAGS_NO_SFLAG;
5905 break;
5906
5907 case MAILIMAP_NO_ERROR:
5908 type = MAILIMAP_MBX_LIST_FLAGS_SFLAG;
5909
5910 final_token = cur_token;
5911 r = mailimap_space_parse(fd, buffer, &cur_token);
5912 if (r == MAILIMAP_NO_ERROR) {
5913 r = mailimap_struct_spaced_list_parse(fd, buffer, &cur_token,
5914 &oflags_2,
5915 (mailimap_struct_parser *) mailimap_mbx_list_oflag_parse,
5916 (mailimap_struct_destructor *) mailimap_mbx_list_oflag_free,
5917 progr_rate, progr_fun);
5918 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) {
5919 res = r;
5920 goto err;
5921 }
5922
5923 if (r == MAILIMAP_NO_ERROR) {
5924 clist_concat(oflags, oflags_2);
5925 clist_free(oflags_2);
5926
5927 final_token = cur_token;
5928 }
5929 }
5930
5931 break;
5932
5933 default:
5934 res = r;
5935 goto free;
5936 }
5937 }
5938
5939 if ((clist_count(oflags) == 0) && (type == MAILIMAP_MBX_LIST_FLAGS_NO_SFLAG)) {
5940 res = MAILIMAP_ERROR_PARSE;
5941 goto free;
5942 }
5943
5944 cur_token = final_token;
5945 mbx_list_flag = mailimap_mbx_list_flags_new(type, oflags, sflag);
5946 if (mbx_list_flag == NULL) {
5947 res = MAILIMAP_ERROR_MEMORY;
5948 goto free;
5949 }
5950
5951 * result = mbx_list_flag;
5952 * index = cur_token;
5953
5954 return MAILIMAP_NO_ERROR;
5955
5956free:
5957 clist_foreach(oflags, (clist_func) mailimap_mbx_list_oflag_free, NULL);
5958 clist_free(oflags);
5959err:
5960 return res;
5961}
5962
5963/*
5964 mbx-list-oflag = "\Noinferiors" / flag-extension
5965 ; Other flags; multiple possible per LIST response
5966*/
5967
5968static int
5969mailimap_mbx_list_oflag_parse(mailstream * fd, MMAPString * buffer,
5970 size_t * index,
5971 struct mailimap_mbx_list_oflag ** result,
5972 size_t progr_rate,
5973 progress_function * progr_fun)
5974{
5975 int type;
5976 size_t cur_token;
5977 struct mailimap_mbx_list_oflag * oflag;
5978 char * flag_ext;
5979 int r;
5980 int res;
5981 int sflag_type;
5982
5983 cur_token = * index;
5984 flag_ext = NULL;
5985 type = MAILIMAP_MBX_LIST_OFLAG_ERROR; /* XXX - removes a gcc warning */
5986
5987 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
5988 "\\Noinferiors");
5989 if (r == MAILIMAP_NO_ERROR)
5990 type = MAILIMAP_MBX_LIST_OFLAG_NOINFERIORS;
5991
5992 if (r == MAILIMAP_ERROR_PARSE) {
5993 r = mailimap_flag_extension_parse(fd, buffer, &cur_token,
5994 &flag_ext, progr_rate, progr_fun);
5995 if (r == MAILIMAP_NO_ERROR)
5996 type = MAILIMAP_MBX_LIST_OFLAG_FLAG_EXT;
5997 }
5998
5999 if (r != MAILIMAP_NO_ERROR) {
6000 res = r;
6001 goto err;
6002 }
6003
6004 oflag = mailimap_mbx_list_oflag_new(type, flag_ext);
6005 if (oflag == NULL) {
6006 res = MAILIMAP_ERROR_MEMORY;
6007 goto free;
6008 }
6009
6010 * result = oflag;
6011 * index = cur_token;
6012
6013 return MAILIMAP_NO_ERROR;
6014
6015 free:
6016 if (flag_ext != NULL)
6017 mailimap_flag_extension_free(flag_ext);
6018 err:
6019 return res;
6020}
6021
6022static int
6023mailimap_mbx_list_oflag_no_sflag_parse(mailstream * fd, MMAPString * buffer,
6024 size_t * index,
6025 struct mailimap_mbx_list_oflag ** result,
6026 size_t progr_rate,
6027 progress_function * progr_fun)
6028{
6029 size_t cur_token;
6030 int sflag_type;
6031 int r;
6032
6033 cur_token = * index;
6034
6035 r = mailimap_mbx_list_sflag_parse(fd, buffer, &cur_token, &sflag_type);
6036 if (r == MAILIMAP_NO_ERROR)
6037 return MAILIMAP_ERROR_PARSE;
6038
6039 return mailimap_mbx_list_oflag_parse(fd, buffer, index, result,
6040 progr_rate, progr_fun);
6041}
6042
6043
6044/*
6045 mbx-list-sflag = "\Noselect" / "\Marked" / "\Unmarked"
6046 ; Selectability flags; only one per LIST response
6047*/
6048
6049static int
6050mailimap_mbx_list_sflag_parse(mailstream * fd, MMAPString * buffer,
6051 size_t * index,
6052 int * result)
6053{
6054 int type;
6055 size_t cur_token;
6056
6057 cur_token = * index;
6058
6059 type = mailimap_mbx_list_sflag_get_token_value(fd, buffer, &cur_token);
6060 if (type == -1)
6061 return MAILIMAP_ERROR_PARSE;
6062
6063 * result = type;
6064 * index = cur_token;
6065
6066 return MAILIMAP_NO_ERROR;
6067}
6068
6069
6070/*
6071 media-basic = ((DQUOTE ("APPLICATION" / "AUDIO" / "IMAGE" / "MESSAGE" /
6072 "VIDEO") DQUOTE) / string) SP media-subtype
6073 ; Defined in [MIME-IMT]
6074*/
6075
6076/*
6077 DQUOTE ("APPLICATION" / "AUDIO" / "IMAGE" / "MESSAGE" /
6078 "VIDEO") DQUOTE
6079*/
6080
6081static int
6082mailimap_media_basic_standard_parse(mailstream * fd, MMAPString * buffer,
6083 size_t * index,
6084 int * result)
6085{
6086 size_t cur_token;
6087 int type;
6088 int r;
6089
6090 cur_token = * index;
6091
6092 r = mailimap_dquote_parse(fd, buffer, &cur_token);
6093 if (r != MAILIMAP_NO_ERROR)
6094 return r;
6095
6096 type = mailimap_media_basic_get_token_value(fd, buffer, &cur_token);
6097 if (type == -1)
6098 return MAILIMAP_ERROR_PARSE;
6099
6100 r = mailimap_dquote_parse(fd, buffer, &cur_token);
6101 if (r != MAILIMAP_NO_ERROR)
6102 return FALSE;
6103
6104 * index = cur_token;
6105 * result = type;
6106
6107 return MAILIMAP_NO_ERROR;
6108}
6109
6110/*
6111 media-basic = ((DQUOTE ("APPLICATION" / "AUDIO" / "IMAGE" / "MESSAGE" /
6112 "VIDEO") DQUOTE) / string) SP media-subtype
6113 ; Defined in [MIME-IMT]
6114*/
6115
6116static int
6117mailimap_media_basic_parse(mailstream * fd, MMAPString * buffer,
6118 size_t * index,
6119 struct mailimap_media_basic ** result,
6120 size_t progr_rate,
6121 progress_function * progr_fun)
6122{
6123 size_t cur_token;
6124 int type;
6125 char * basic_type;
6126 char * subtype;
6127 struct mailimap_media_basic * media_basic;
6128 int r;
6129 int res;
6130
6131 cur_token = * index;
6132
6133 basic_type = NULL;
6134 subtype = NULL;
6135
6136 r = mailimap_media_basic_standard_parse(fd, buffer, &cur_token,
6137 &type);
6138
6139 if (r == MAILIMAP_ERROR_PARSE) {
6140 r = mailimap_string_parse(fd, buffer, &cur_token, &basic_type, NULL,
6141 progr_rate, progr_fun);
6142 if (r == MAILIMAP_NO_ERROR)
6143 type = MAILIMAP_MEDIA_BASIC_OTHER;
6144 }
6145
6146 if (r != MAILIMAP_NO_ERROR) {
6147 res = r;
6148 goto err;
6149 }
6150
6151 r = mailimap_space_parse(fd, buffer, &cur_token);
6152 if (r != MAILIMAP_NO_ERROR) {
6153 res = r;
6154 goto free_basic_type;
6155 }
6156
6157 r = mailimap_media_subtype_parse(fd, buffer, &cur_token, &subtype,
6158 progr_rate, progr_fun);
6159 if (r != MAILIMAP_NO_ERROR) {
6160 res = r;
6161 goto free_basic_type;
6162 }
6163
6164 media_basic = mailimap_media_basic_new(type, basic_type, subtype);
6165 if (media_basic == NULL) {
6166 res = MAILIMAP_ERROR_MEMORY;
6167 goto free_subtype;
6168 }
6169
6170 * result = media_basic;
6171 * index = cur_token;
6172
6173 return MAILIMAP_NO_ERROR;
6174
6175 free_subtype:
6176 mailimap_media_subtype_free(subtype);
6177 free_basic_type:
6178 if (basic_type != NULL)
6179 mailimap_string_free(basic_type);
6180 err:
6181 return res;
6182}
6183
6184
6185/*
6186 media-message = DQUOTE "MESSAGE" DQUOTE SP DQUOTE "RFC822" DQUOTE
6187 ; Defined in [MIME-IMT]
6188*/
6189
6190static int
6191mailimap_media_message_parse(mailstream * fd, MMAPString * buffer,
6192 size_t * index)
6193{
6194 size_t cur_token;
6195 int r;
6196
6197 cur_token = * index;
6198
6199 r = mailimap_dquote_parse(fd, buffer, &cur_token);
6200 if (r != MAILIMAP_NO_ERROR)
6201 return r;
6202
6203 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
6204 "MESSAGE");
6205 if (r != MAILIMAP_NO_ERROR)
6206 return r;
6207
6208 r = mailimap_dquote_parse(fd, buffer, &cur_token);
6209 if (r != MAILIMAP_NO_ERROR)
6210 return r;
6211
6212 r = mailimap_space_parse(fd, buffer, &cur_token);
6213 if (r != MAILIMAP_NO_ERROR)
6214 return r;
6215
6216 r = mailimap_dquote_parse(fd, buffer, &cur_token);
6217 if (r != MAILIMAP_NO_ERROR)
6218 return r;
6219
6220 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
6221 "RFC822");
6222 if (r != MAILIMAP_NO_ERROR)
6223 return r;
6224
6225 r = mailimap_dquote_parse(fd, buffer, &cur_token);
6226 if (r != MAILIMAP_NO_ERROR)
6227 return r;
6228
6229 * index = cur_token;
6230
6231 return MAILIMAP_NO_ERROR;
6232}
6233
6234/*
6235 media-subtype = string
6236 ; Defined in [MIME-IMT]
6237*/
6238
6239static int
6240mailimap_media_subtype_parse(mailstream * fd, MMAPString * buffer,
6241 size_t * index,
6242 char ** result,
6243 size_t progr_rate,
6244 progress_function * progr_fun)
6245{
6246 return mailimap_string_parse(fd, buffer, index, result, NULL,
6247 progr_rate, progr_fun);
6248}
6249
6250/*
6251 media-text = DQUOTE "TEXT" DQUOTE SP media-subtype
6252 ; Defined in [MIME-IMT]
6253*/
6254
6255static int mailimap_media_text_parse(mailstream * fd, MMAPString * buffer,
6256 size_t * index,
6257 char ** result,
6258 size_t progr_rate,
6259 progress_function * progr_fun)
6260{
6261 size_t cur_token;
6262 char * media_subtype;
6263 int r;
6264
6265 cur_token = * index;
6266
6267 r = mailimap_dquote_parse(fd, buffer, &cur_token);
6268 if (r != MAILIMAP_NO_ERROR)
6269 return r;
6270
6271 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
6272 "TEXT");
6273 if (r != MAILIMAP_NO_ERROR)
6274 return r;
6275
6276 r = mailimap_dquote_parse(fd, buffer, &cur_token);
6277 if (r != MAILIMAP_NO_ERROR)
6278 return r;
6279
6280 r = mailimap_space_parse(fd, buffer, &cur_token);
6281 if (r != MAILIMAP_NO_ERROR)
6282 return r;
6283
6284 r = mailimap_media_subtype_parse(fd, buffer, &cur_token, &media_subtype,
6285 progr_rate, progr_fun);
6286 if (r != MAILIMAP_NO_ERROR)
6287 return r;
6288
6289 * result = media_subtype;
6290 * index = cur_token;
6291
6292 return MAILIMAP_NO_ERROR;
6293}
6294
6295
6296/*
6297 message-data = nz-number SP ("EXPUNGE" / ("FETCH" SP msg-att))
6298*/
6299
6300
6301static int
6302mailimap_message_data_parse(mailstream * fd, MMAPString * buffer,
6303 size_t * index,
6304 struct mailimap_message_data ** result,
6305 size_t progr_rate,
6306 progress_function * progr_fun)
6307{
6308 size_t cur_token;
6309 uint32_t number;
6310 int type;
6311 struct mailimap_msg_att * msg_att;
6312 struct mailimap_message_data * msg_data;
6313 int r;
6314 int res;
6315
6316 cur_token = * index;
6317 msg_att = NULL;
6318
6319 r = mailimap_nz_number_parse(fd, buffer, &cur_token, &number);
6320 if (r != MAILIMAP_NO_ERROR) {
6321 res = r;
6322 goto err;
6323 }
6324
6325 r = mailimap_space_parse(fd, buffer, &cur_token);
6326 if (r != MAILIMAP_NO_ERROR) {
6327 res = r;
6328 goto err;
6329 }
6330
6331 type = MAILIMAP_MESSAGE_DATA_ERROR; /* XXX - removes a gcc warning */
6332
6333 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
6334 "EXPUNGE");
6335 if (r == MAILIMAP_NO_ERROR)
6336 type = MAILIMAP_MESSAGE_DATA_EXPUNGE;
6337
6338 if (r == MAILIMAP_ERROR_PARSE) {
6339 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
6340 "FETCH");
6341 if (r != MAILIMAP_NO_ERROR) {
6342 res = r;
6343 goto err;
6344 }
6345
6346 r = mailimap_space_parse(fd, buffer, &cur_token);
6347 if (r != MAILIMAP_NO_ERROR) {
6348 res = r;
6349 goto err;
6350 }
6351
6352 r = mailimap_msg_att_parse(fd, buffer, &cur_token, &msg_att,
6353 progr_rate, progr_fun);
6354 if (r != MAILIMAP_NO_ERROR) {
6355 res = r;
6356 goto err;
6357 }
6358
6359 type = MAILIMAP_MESSAGE_DATA_FETCH;
6360 }
6361
6362 if (r != MAILIMAP_NO_ERROR) {
6363 res = r;
6364 goto err;
6365 }
6366
6367 msg_data = mailimap_message_data_new(number, type, msg_att);
6368 if (msg_data == NULL) {
6369 res = MAILIMAP_ERROR_MEMORY;
6370 goto free_msg_att;
6371 }
6372
6373 * result = msg_data;
6374 * index = cur_token;
6375
6376 return MAILIMAP_NO_ERROR;
6377
6378 free_msg_att:
6379 if (msg_att != NULL)
6380 mailimap_msg_att_free(msg_att);
6381 err:
6382 return res;
6383}
6384
6385/*
6386 msg-att = "(" (msg-att-dynamic / msg-att-static)
6387 *(SP (msg-att-dynamic / msg-att-static)) ")"
6388*/
6389
6390/*
6391 msg-att-dynamic / msg-att-static
6392*/
6393
6394static int
6395mailimap_msg_att_item_parse(mailstream * fd, MMAPString * buffer,
6396 size_t * index,
6397 struct mailimap_msg_att_item ** result,
6398 size_t progr_rate,
6399 progress_function * progr_fun)
6400{
6401 int type;
6402 struct mailimap_msg_att_dynamic * msg_att_dynamic;
6403 struct mailimap_msg_att_static * msg_att_static;
6404 size_t cur_token;
6405 struct mailimap_msg_att_item * item;
6406 int r;
6407 int res;
6408
6409 cur_token = * index;
6410
6411 msg_att_dynamic = NULL;
6412 msg_att_static = NULL;
6413
6414 type = MAILIMAP_MSG_ATT_ITEM_ERROR; /* XXX - removes a gcc warning */
6415
6416 r = mailimap_msg_att_dynamic_parse(fd, buffer, &cur_token,
6417 &msg_att_dynamic,
6418 progr_rate, progr_fun);
6419 if (r == MAILIMAP_NO_ERROR)
6420 type = MAILIMAP_MSG_ATT_ITEM_DYNAMIC;
6421
6422 if (r == MAILIMAP_ERROR_PARSE) {
6423 r = mailimap_msg_att_static_parse(fd, buffer, &cur_token,
6424 &msg_att_static,
6425 progr_rate, progr_fun);
6426 if (r == MAILIMAP_NO_ERROR)
6427 type = MAILIMAP_MSG_ATT_ITEM_STATIC;
6428 }
6429
6430 if (r != MAILIMAP_NO_ERROR) {
6431 res = r;
6432 goto err;
6433 }
6434
6435 item = mailimap_msg_att_item_new(type, msg_att_dynamic, msg_att_static);
6436 if (item == NULL) {
6437 res = MAILIMAP_ERROR_MEMORY;
6438 goto free;
6439 }
6440
6441 * result = item;
6442 * index = cur_token;
6443
6444 return MAILIMAP_NO_ERROR;
6445
6446 free:
6447 if (msg_att_dynamic != NULL)
6448 mailimap_msg_att_dynamic_free(msg_att_dynamic);
6449 if (msg_att_static != NULL)
6450 mailimap_msg_att_static_free(msg_att_static);
6451 err:
6452 return res;
6453}
6454
6455/*
6456 msg-att = "(" (msg-att-dynamic / msg-att-static)
6457 *(SP (msg-att-dynamic / msg-att-static)) ")"
6458*/
6459
6460static int
6461mailimap_msg_att_parse(mailstream * fd, MMAPString * buffer,
6462 size_t * index, struct mailimap_msg_att ** result,
6463 size_t progr_rate,
6464 progress_function * progr_fun)
6465{
6466 size_t cur_token;
6467 clist * list;
6468 struct mailimap_msg_att * msg_att;
6469 int r;
6470 int res;
6471
6472 cur_token = * index;
6473 list = NULL;
6474
6475 r = mailimap_oparenth_parse(fd, buffer, &cur_token);
6476 if (r != MAILIMAP_NO_ERROR) {
6477 res = r;
6478 goto err;
6479 }
6480
6481 r = mailimap_struct_spaced_list_parse(fd, buffer, &cur_token, &list,
6482 (mailimap_struct_parser *)
6483 mailimap_msg_att_item_parse,
6484 (mailimap_struct_destructor *)
6485 mailimap_msg_att_item_free,
6486 progr_rate, progr_fun);
6487 if (r != MAILIMAP_NO_ERROR) {
6488 res = r;
6489 goto err;
6490 }
6491
6492 r = mailimap_cparenth_parse(fd, buffer, &cur_token);
6493 if (r != MAILIMAP_NO_ERROR) {
6494 res = r;
6495 goto free;
6496 }
6497
6498 msg_att = mailimap_msg_att_new(list);
6499 if (msg_att == NULL) {
6500 res = MAILIMAP_ERROR_MEMORY;
6501 goto free;
6502 }
6503
6504 * index = cur_token;
6505 * result = msg_att;
6506
6507 return MAILIMAP_NO_ERROR;
6508
6509 free:
6510 clist_foreach(list, (clist_func) mailimap_msg_att_item_free, NULL);
6511 clist_free(list);
6512 err:
6513 return res;
6514}
6515
6516/*
6517 msg-att-dynamic = "FLAGS" SP "(" [flag-fetch *(SP flag-fetch)] ")"
6518 ; MAY change for a message
6519*/
6520
6521
6522static int
6523mailimap_msg_att_dynamic_parse(mailstream * fd, MMAPString * buffer,
6524 size_t * index,
6525 struct mailimap_msg_att_dynamic ** result,
6526 size_t progr_rate,
6527 progress_function * progr_fun)
6528{
6529 clist * list;
6530 struct mailimap_msg_att_dynamic * msg_att_dyn;
6531 size_t cur_token;
6532 int r;
6533 int res;
6534
6535 cur_token = * index;
6536
6537 list = NULL;
6538
6539 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token, "FLAGS");
6540 if (r != MAILIMAP_NO_ERROR) {
6541 res = r;
6542 goto err;
6543 }
6544
6545 r = mailimap_space_parse(fd, buffer, &cur_token);
6546 if (r != MAILIMAP_NO_ERROR) {
6547 res = r;
6548 goto err;
6549 }
6550
6551 r = mailimap_oparenth_parse(fd, buffer, &cur_token);
6552 if (r != MAILIMAP_NO_ERROR) {
6553 res = r;
6554 goto err;
6555 }
6556
6557 r = mailimap_struct_spaced_list_parse(fd, buffer, &cur_token,
6558 &list,
6559 (mailimap_struct_parser *)
6560 mailimap_flag_fetch_parse,
6561 (mailimap_struct_destructor *)
6562 mailimap_flag_fetch_free,
6563 progr_rate, progr_fun);
6564 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) {
6565 res = r;
6566 goto err;
6567 }
6568
6569 r = mailimap_cparenth_parse(fd, buffer, &cur_token);
6570 if (r != MAILIMAP_NO_ERROR) {
6571 res = r;
6572 goto free;
6573 }
6574
6575 msg_att_dyn = mailimap_msg_att_dynamic_new(list);
6576 if (msg_att_dyn == NULL) {
6577 res = MAILIMAP_ERROR_MEMORY;
6578 goto free;
6579 }
6580
6581 * result = msg_att_dyn;
6582 * index = cur_token;
6583
6584 return MAILIMAP_NO_ERROR;
6585
6586 free:
6587 if (list != NULL) {
6588 clist_foreach(list, (clist_func) mailimap_flag_fetch_free, NULL);
6589 clist_free(list);
6590 }
6591 err:
6592 return res;
6593}
6594
6595/*
6596 msg-att-static = "ENVELOPE" SP envelope / "INTERNALDATE" SP date-time /
6597 "RFC822" [".HEADER" / ".TEXT"] SP nstring /
6598 "RFC822.SIZE" SP number / "BODY" ["STRUCTURE"] SP body /
6599 "BODY" section ["<" number ">"] SP nstring /
6600 "UID" SP uniqueid
6601 ; MUST NOT change for a message
6602*/
6603
6604/*
6605 "ENVELOPE" SP envelope
6606*/
6607
6608
6609static int
6610mailimap_msg_att_envelope_parse(mailstream * fd,
6611 MMAPString * buffer,
6612 size_t * index,
6613 struct mailimap_envelope ** result,
6614 size_t progr_rate,
6615 progress_function * progr_fun)
6616{
6617 size_t cur_token;
6618 struct mailimap_envelope * env;
6619 int r;
6620
6621 cur_token = * index;
6622
6623 r = mailimap_token_case_insensitive_parse(fd, buffer,
6624 &cur_token, "ENVELOPE");
6625 if (r != MAILIMAP_NO_ERROR)
6626 return r;
6627
6628 r = mailimap_space_parse(fd, buffer, &cur_token);
6629 if (r != MAILIMAP_NO_ERROR)
6630 return r;
6631
6632 r = mailimap_envelope_parse(fd, buffer, &cur_token, &env,
6633 progr_rate, progr_fun);
6634 if (r != MAILIMAP_NO_ERROR)
6635 return r;
6636
6637 * index = cur_token;
6638 * result = env;
6639
6640 return MAILIMAP_NO_ERROR;
6641}
6642
6643
6644/*
6645 "INTERNALDATE" SP date-time
6646*/
6647
6648
6649static int
6650mailimap_msg_att_internaldate_parse(mailstream * fd, MMAPString * buffer,
6651 size_t * index,
6652 struct mailimap_date_time ** result,
6653 size_t progr_rate,
6654 progress_function * progr_fun)
6655{
6656 size_t cur_token;
6657 struct mailimap_date_time * date_time;
6658 int r;
6659
6660 cur_token = * index;
6661
6662 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
6663 "INTERNALDATE");
6664 if (r != MAILIMAP_NO_ERROR)
6665 return r;
6666
6667 r = mailimap_space_parse(fd, buffer, &cur_token);
6668 if (r != MAILIMAP_NO_ERROR)
6669 return FALSE;
6670
6671 r = mailimap_date_time_parse(fd, buffer, &cur_token, &date_time,
6672 progr_rate, progr_fun);
6673 if (r != MAILIMAP_NO_ERROR)
6674 return r;
6675
6676 * result = date_time;
6677 * index = cur_token;
6678
6679 return MAILIMAP_NO_ERROR;
6680}
6681
6682/*
6683 "RFC822" SP nstring
6684*/
6685
6686static int
6687mailimap_msg_att_rfc822_parse(mailstream * fd, MMAPString * buffer,
6688 size_t * index, char ** result,
6689 size_t * result_len,
6690 size_t progr_rate,
6691 progress_function * progr_fun)
6692{
6693 size_t cur_token;
6694 char * rfc822_message;
6695 int r;
6696 size_t length;
6697
6698 cur_token = * index;
6699
6700 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
6701 "RFC822");
6702 if (r != MAILIMAP_NO_ERROR)
6703 return r;
6704
6705 r = mailimap_space_parse(fd, buffer, &cur_token);
6706 if (r != MAILIMAP_NO_ERROR)
6707 return r;
6708
6709 r = mailimap_nstring_parse(fd, buffer, &cur_token, &rfc822_message, &length,
6710 progr_rate, progr_fun);
6711 if (r != MAILIMAP_NO_ERROR)
6712 return r;
6713
6714 * result = rfc822_message;
6715 if (result_len != NULL)
6716 * result_len = length;
6717 * index = cur_token;
6718
6719 return MAILIMAP_NO_ERROR;
6720}
6721
6722/*
6723 "RFC822" ".HEADER" SP nstring
6724*/
6725
6726static int
6727mailimap_msg_att_rfc822_header_parse(mailstream * fd, MMAPString * buffer,
6728 size_t * index, char ** result,
6729 size_t * result_len,
6730 size_t progr_rate,
6731 progress_function * progr_fun)
6732{
6733 size_t cur_token;
6734 char * rfc822_header;
6735 int r;
6736 size_t length;
6737
6738 cur_token = * index;
6739
6740 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
6741 "RFC822");
6742 if (r != MAILIMAP_NO_ERROR)
6743 return r;
6744
6745 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
6746 ".HEADER");
6747 if (r != MAILIMAP_NO_ERROR)
6748 return r;
6749
6750 r = mailimap_space_parse(fd, buffer, &cur_token);
6751 if (r != MAILIMAP_NO_ERROR)
6752 return r;
6753
6754 r = mailimap_nstring_parse(fd, buffer, &cur_token, &rfc822_header, &length,
6755 progr_rate, progr_fun);
6756 if (r != MAILIMAP_NO_ERROR)
6757 return r;
6758
6759 * result = rfc822_header;
6760 if (result_len != NULL)
6761 * result_len = length;
6762 * index = cur_token;
6763
6764 return MAILIMAP_NO_ERROR;
6765}
6766
6767/*
6768 "RFC822" ".TEXT" SP nstring
6769*/
6770
6771static int
6772mailimap_msg_att_rfc822_text_parse(mailstream * fd, MMAPString * buffer,
6773 size_t * index, char ** result,
6774 size_t * result_len,
6775 size_t progr_rate,
6776 progress_function * progr_fun)
6777{
6778 size_t cur_token;
6779 char * rfc822_text;
6780 int r;
6781 size_t length;
6782
6783 cur_token = * index;
6784
6785 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
6786 "RFC822");
6787 if (r != MAILIMAP_NO_ERROR)
6788 return r;
6789
6790 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
6791 ".TEXT");
6792 if (r != MAILIMAP_NO_ERROR)
6793 return r;
6794
6795 r = mailimap_space_parse(fd, buffer, &cur_token);
6796 if (r != MAILIMAP_NO_ERROR)
6797 return r;
6798
6799 r = mailimap_nstring_parse(fd, buffer, &cur_token, &rfc822_text, &length,
6800 progr_rate, progr_fun);
6801 if (r != MAILIMAP_NO_ERROR)
6802 return r;
6803
6804 * result = rfc822_text;
6805 if (result_len != NULL)
6806 * result_len = length;
6807 * index = cur_token;
6808
6809 return MAILIMAP_NO_ERROR;
6810}
6811
6812/*
6813 "RFC822.SIZE" SP number
6814*/
6815
6816static int
6817mailimap_msg_att_rfc822_size_parse(mailstream * fd, MMAPString * buffer,
6818 size_t * index, uint32_t * result)
6819{
6820 size_t cur_token;
6821 uint32_t number;
6822 int r;
6823
6824 cur_token = * index;
6825
6826 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
6827 "RFC822.SIZE");
6828 if (r != MAILIMAP_NO_ERROR)
6829 return r;
6830
6831 r = mailimap_space_parse(fd, buffer, &cur_token);
6832 if (r != MAILIMAP_NO_ERROR)
6833 return r;
6834
6835 r = mailimap_number_parse(fd, buffer, &cur_token, &number);
6836 if (r != MAILIMAP_NO_ERROR)
6837 return r;
6838
6839 * result = number;
6840 * index = cur_token;
6841
6842 return MAILIMAP_NO_ERROR;
6843}
6844
6845/*
6846 "BODY" SP body
6847*/
6848
6849
6850static int
6851mailimap_msg_att_body_parse(mailstream * fd, MMAPString * buffer,
6852 size_t * index, struct mailimap_body ** result,
6853 size_t progr_rate,
6854 progress_function * progr_fun)
6855{
6856 struct mailimap_body * body;
6857 size_t cur_token;
6858 int r;
6859
6860 cur_token = * index;
6861
6862 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
6863 "BODY");
6864 if (r != MAILIMAP_NO_ERROR)
6865 return r;
6866
6867 r = mailimap_space_parse(fd, buffer, &cur_token);
6868 if (r != MAILIMAP_NO_ERROR)
6869 return r;
6870
6871 r = mailimap_body_parse(fd, buffer, &cur_token, &body,
6872 progr_rate, progr_fun);
6873 if (r != MAILIMAP_NO_ERROR)
6874 return r;
6875
6876 * result = body;
6877 * index = cur_token;
6878
6879 return MAILIMAP_NO_ERROR;
6880}
6881
6882/*
6883 "BODY" "STRUCTURE" SP body
6884*/
6885
6886
6887static int
6888mailimap_msg_att_bodystructure_parse(mailstream * fd, MMAPString * buffer,
6889 size_t * index,
6890 struct mailimap_body ** result,
6891 size_t progr_rate,
6892 progress_function * progr_fun)
6893{
6894 struct mailimap_body * body;
6895 size_t cur_token;
6896 int r;
6897
6898 cur_token = * index;
6899
6900 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
6901 "BODY");
6902 if (r != MAILIMAP_NO_ERROR)
6903 return r;
6904
6905 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
6906 "STRUCTURE");
6907 if (r != MAILIMAP_NO_ERROR)
6908 return r;
6909
6910 r = mailimap_space_parse(fd, buffer, &cur_token);
6911 if (r != MAILIMAP_NO_ERROR)
6912 return r;
6913
6914 r = mailimap_body_parse(fd, buffer, &cur_token, &body,
6915 progr_rate, progr_fun);
6916 if (r != MAILIMAP_NO_ERROR)
6917 return r;
6918
6919 * result = body;
6920 * index = cur_token;
6921
6922 return MAILIMAP_NO_ERROR;
6923}
6924
6925/*
6926 "BODY" section ["<" number ">"] SP nstring
6927*/
6928
6929static int
6930mailimap_msg_att_body_section_parse(mailstream * fd, MMAPString * buffer,
6931 size_t * index,
6932 struct mailimap_msg_att_body_section **
6933 result,
6934 size_t progr_rate,
6935 progress_function * progr_fun)
6936{
6937 size_t cur_token;
6938 uint32_t number;
6939 struct mailimap_section * section;
6940 char * body_part;
6941 struct mailimap_msg_att_body_section * msg_att_body_section;
6942 int r;
6943 int res;
6944 size_t length;
6945
6946 cur_token = * index;
6947
6948 section = NULL;
6949 number = 0;
6950 body_part = NULL;
6951
6952 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
6953 "BODY");
6954 if (r != MAILIMAP_NO_ERROR) {
6955 res = r;
6956 goto err;
6957 }
6958
6959 r = mailimap_section_parse(fd, buffer, &cur_token, &section,
6960 progr_rate, progr_fun);
6961 if (r != MAILIMAP_NO_ERROR) {
6962 res = r;
6963 goto err;
6964 }
6965
6966 r = mailimap_lower_parse(fd, buffer, &cur_token);
6967 switch (r) {
6968 case MAILIMAP_NO_ERROR:
6969 r = mailimap_number_parse(fd, buffer, &cur_token, &number);
6970 if (r != MAILIMAP_NO_ERROR) {
6971 res = r;
6972 goto free_section;
6973 }
6974
6975 r = mailimap_greater_parse(fd, buffer, &cur_token);
6976 if (r != MAILIMAP_NO_ERROR) {
6977 res = r;
6978 goto free_section;
6979 }
6980 break;
6981
6982 case MAILIMAP_ERROR_PARSE:
6983 break;
6984
6985 default:
6986 return r;
6987 }
6988
6989 r = mailimap_space_parse(fd, buffer, &cur_token);
6990 if (r != MAILIMAP_NO_ERROR) {
6991 res = r;
6992 goto free_section;
6993 }
6994
6995 r = mailimap_nstring_parse(fd, buffer, &cur_token, &body_part, &length,
6996 progr_rate, progr_fun);
6997 if (r != MAILIMAP_NO_ERROR) {
6998 res = r;
6999 goto free_section;
7000 }
7001
7002 msg_att_body_section =
7003 mailimap_msg_att_body_section_new(section, number, body_part, length);
7004 if (msg_att_body_section == NULL) {
7005 res = MAILIMAP_ERROR_MEMORY;
7006 goto free_string;
7007 }
7008
7009 * result = msg_att_body_section;
7010 * index = cur_token;
7011
7012 return MAILIMAP_NO_ERROR;
7013
7014 free_string:
7015 mailimap_nstring_free(body_part);
7016 free_section:
7017 if (section != NULL)
7018 mailimap_section_free(section);
7019 err:
7020 return res;
7021}
7022
7023/*
7024 "UID" SP uniqueid
7025*/
7026
7027static int
7028mailimap_msg_att_uid_parse(mailstream * fd, MMAPString * buffer,
7029 size_t * index,
7030 uint32_t * result)
7031{
7032 size_t cur_token;
7033 uint32_t uid;
7034 int r;
7035
7036 cur_token = * index;
7037
7038 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token, "UID");
7039 if (r != MAILIMAP_NO_ERROR)
7040 return r;
7041
7042 r = mailimap_space_parse(fd, buffer, &cur_token);
7043 if (r != MAILIMAP_NO_ERROR)
7044 return r;
7045
7046 r = mailimap_uniqueid_parse(fd, buffer, &cur_token, &uid);
7047 if (r != MAILIMAP_NO_ERROR)
7048 return r;
7049
7050 * index = cur_token;
7051 * result = uid;
7052
7053 return MAILIMAP_NO_ERROR;
7054}
7055
7056/*
7057 msg-att-static = "ENVELOPE" SP envelope / "INTERNALDATE" SP date-time /
7058 "RFC822" [".HEADER" / ".TEXT"] SP nstring /
7059 "RFC822.SIZE" SP number / "BODY" ["STRUCTURE"] SP body /
7060 "BODY" section ["<" number ">"] SP nstring /
7061 "UID" SP uniqueid
7062 ; MUST NOT change for a message
7063*/
7064
7065static int
7066mailimap_msg_att_static_parse(mailstream * fd, MMAPString * buffer,
7067 size_t * index,
7068 struct mailimap_msg_att_static ** result,
7069 size_t progr_rate,
7070 progress_function * progr_fun)
7071{
7072 size_t cur_token;
7073 struct mailimap_envelope * env;
7074 struct mailimap_date_time * internal_date;
7075 char * rfc822;
7076 char * rfc822_header;
7077 char * rfc822_text;
7078 uint32_t rfc822_size;
7079 struct mailimap_body * bodystructure;
7080 struct mailimap_body * body;
7081 struct mailimap_msg_att_body_section * body_section;
7082 uint32_t uid;
7083 struct mailimap_msg_att_static * msg_att_static;
7084 int type;
7085 int r;
7086 int res;
7087 size_t length;
7088
7089 cur_token = * index;
7090
7091 env = NULL;
7092 internal_date = NULL;
7093 rfc822 = NULL;
7094 rfc822_header = NULL;
7095 rfc822_text = NULL;
7096 rfc822_size = 0;
7097 length = 0;
7098 bodystructure = NULL;
7099 body = NULL;
7100 body_section = NULL;
7101 uid = 0;
7102
7103 type = MAILIMAP_MSG_ATT_ERROR; /* XXX - removes a gcc warning */
7104
7105 r = mailimap_msg_att_envelope_parse(fd, buffer, &cur_token, &env,
7106 progr_rate, progr_fun);
7107 if (r == MAILIMAP_NO_ERROR)
7108 type = MAILIMAP_MSG_ATT_ENVELOPE;
7109
7110 if (r == MAILIMAP_ERROR_PARSE) {
7111 r = mailimap_msg_att_internaldate_parse(fd, buffer, &cur_token,
7112 &internal_date,
7113 progr_rate, progr_fun);
7114 if (r == MAILIMAP_NO_ERROR)
7115 type = MAILIMAP_MSG_ATT_INTERNALDATE;
7116 }
7117
7118 if (r == MAILIMAP_ERROR_PARSE) {
7119 r = mailimap_msg_att_rfc822_parse(fd, buffer, &cur_token,
7120 &rfc822, &length,
7121 progr_rate, progr_fun);
7122 if (r == MAILIMAP_NO_ERROR)
7123 type = MAILIMAP_MSG_ATT_RFC822;
7124 }
7125
7126 if (r == MAILIMAP_ERROR_PARSE) {
7127 r = mailimap_msg_att_rfc822_header_parse(fd, buffer, &cur_token,
7128 &rfc822_header, &length,
7129 progr_rate, progr_fun);
7130 type = MAILIMAP_MSG_ATT_RFC822_HEADER;
7131 }
7132
7133 if (r == MAILIMAP_ERROR_PARSE) {
7134 r = mailimap_msg_att_rfc822_text_parse(fd, buffer, &cur_token,
7135 &rfc822_text, &length,
7136 progr_rate, progr_fun);
7137 if (r == MAILIMAP_NO_ERROR)
7138 type = MAILIMAP_MSG_ATT_RFC822_TEXT;
7139 }
7140
7141 if (r == MAILIMAP_ERROR_PARSE) {
7142 r = mailimap_msg_att_rfc822_size_parse(fd, buffer, &cur_token,
7143 &rfc822_size);
7144 if (r == MAILIMAP_NO_ERROR)
7145 type = MAILIMAP_MSG_ATT_RFC822_SIZE;
7146 }
7147
7148 if (r == MAILIMAP_ERROR_PARSE) {
7149 r = mailimap_msg_att_body_parse(fd, buffer, &cur_token,
7150 &body, progr_rate, progr_fun);
7151 if (r == MAILIMAP_NO_ERROR)
7152 type = MAILIMAP_MSG_ATT_BODY;
7153 }
7154
7155 if (r == MAILIMAP_ERROR_PARSE) {
7156 r = mailimap_msg_att_bodystructure_parse(fd, buffer, &cur_token,
7157 &bodystructure,
7158 progr_rate, progr_fun);
7159 if (r == MAILIMAP_NO_ERROR)
7160 type = MAILIMAP_MSG_ATT_BODYSTRUCTURE;
7161 }
7162
7163 if (r == MAILIMAP_ERROR_PARSE) {
7164 r = mailimap_msg_att_body_section_parse(fd, buffer, &cur_token,
7165 &body_section,
7166 progr_rate, progr_fun);
7167 if (r == MAILIMAP_NO_ERROR)
7168 type = MAILIMAP_MSG_ATT_BODY_SECTION;
7169 }
7170
7171 if (r == MAILIMAP_ERROR_PARSE) {
7172 r = mailimap_msg_att_uid_parse(fd, buffer, &cur_token,
7173 &uid);
7174 if (r == MAILIMAP_NO_ERROR)
7175 type = MAILIMAP_MSG_ATT_UID;
7176 }
7177
7178 if (r != MAILIMAP_NO_ERROR) {
7179 res = r;
7180 goto err;
7181 }
7182
7183 msg_att_static = mailimap_msg_att_static_new(type, env, internal_date,
7184 rfc822, rfc822_header,
7185 rfc822_text, length,
7186 rfc822_size, bodystructure,
7187 body, body_section, uid);
7188 if (msg_att_static == NULL) {
7189 res = MAILIMAP_ERROR_MEMORY;
7190 goto free;
7191 }
7192
7193 * result = msg_att_static;
7194 * index = cur_token;
7195
7196 return MAILIMAP_NO_ERROR;
7197
7198 free:
7199 if (env)
7200 mailimap_msg_att_envelope_free(env);
7201 if (internal_date)
7202 mailimap_msg_att_internaldate_free(internal_date);
7203 if (rfc822)
7204 mailimap_msg_att_rfc822_free(rfc822);
7205 if (rfc822_header)
7206 mailimap_msg_att_rfc822_header_free(rfc822_header);
7207 if (rfc822_text)
7208 mailimap_msg_att_rfc822_text_free(rfc822_text);
7209 if (bodystructure)
7210 mailimap_msg_att_bodystructure_free(bodystructure);
7211 if (body)
7212 mailimap_msg_att_body_free(body);
7213 if (body_section)
7214 mailimap_msg_att_body_section_free(body_section);
7215 err:
7216 return res;
7217}
7218
7219
7220/*
7221 nil = "NIL"
7222*/
7223
7224static int mailimap_nil_parse(mailstream * fd, MMAPString * buffer,
7225 size_t * index)
7226{
7227 return mailimap_token_case_insensitive_parse(fd, buffer, index, "NIL");
7228}
7229
7230/*
7231 nstring = string / nil
7232*/
7233
7234
7235static int mailimap_nstring_parse(mailstream * fd, MMAPString * buffer,
7236 size_t * index, char ** result,
7237 size_t * result_len,
7238 size_t progr_rate,
7239 progress_function * progr_fun)
7240{
7241 int r;
7242
7243 r = mailimap_string_parse(fd, buffer, index, result, result_len,
7244 progr_rate, progr_fun);
7245 switch (r) {
7246 case MAILIMAP_NO_ERROR:
7247 return MAILIMAP_NO_ERROR;
7248
7249 case MAILIMAP_ERROR_PARSE:
7250 r = mailimap_nil_parse(fd, buffer, index);
7251 if (r != MAILIMAP_NO_ERROR) {
7252 return r;
7253 }
7254
7255 * result = NULL;
7256 if (result_len != NULL)
7257 * result_len = 0;
7258 return MAILIMAP_NO_ERROR;
7259
7260 default:
7261 return r;
7262 }
7263}
7264
7265/*
7266 number = 1*DIGIT
7267 ; Unsigned 32-bit integer
7268 ; (0 <= n < 4,294,967,296)
7269*/
7270
7271static int
7272mailimap_number_parse(mailstream * fd, MMAPString * buffer,
7273 size_t * index, uint32_t * result)
7274{
7275 size_t cur_token;
7276 int digit;
7277 uint32_t number;
7278 int parsed;
7279 int r;
7280
7281 cur_token = * index;
7282 parsed = FALSE;
7283
7284#ifdef UNSTRICT_SYNTAX
7285 mailimap_space_parse(fd, buffer, &cur_token);
7286#endif
7287
7288 number = 0;
7289 while (1) {
7290 r = mailimap_digit_parse(fd, buffer, &cur_token, &digit);
7291 if (r == MAILIMAP_ERROR_PARSE)
7292 break;
7293 else if (r == MAILIMAP_NO_ERROR) {
7294 number *= 10;
7295 number += digit;
7296 parsed = TRUE;
7297 }
7298 else
7299 return r;
7300 }
7301
7302 if (!parsed)
7303 return MAILIMAP_ERROR_PARSE;
7304
7305 * result = number;
7306 * index = cur_token;
7307
7308 return MAILIMAP_NO_ERROR;
7309}
7310
7311/*
7312 nz-number = digit-nz *DIGIT
7313 ; Non-zero unsigned 32-bit integer
7314 ; (0 < n < 4,294,967,296)
7315*/
7316
7317static int
7318mailimap_nz_number_parse(mailstream * fd, MMAPString * buffer,
7319 size_t * index, uint32_t * result)
7320{
7321#ifdef UNSTRICT_SYNTAX
7322 size_t cur_token;
7323 uint32_t number;
7324 int r;
7325
7326 cur_token = * index;
7327
7328 r = mailimap_number_parse(fd, buffer, &cur_token, &number);
7329 if (r != MAILIMAP_NO_ERROR)
7330 return r;
7331
7332 if (number == 0)
7333 return MAILIMAP_ERROR_PARSE;
7334
7335#else
7336 size_t cur_token;
7337 int digit;
7338 uint32_t number;
7339 int r;
7340
7341 cur_token = * index;
7342
7343 r = mailimap_digit_nz_parse(fd, buffer, &cur_token, &digit);
7344 if (r != MAILIMAP_NO_ERROR)
7345 return r;
7346
7347 number = digit;
7348
7349 while (1) {
7350 r = mailimap_digit_parse(fd, buffer, &cur_token, &digit);
7351 if (r == MAILIMAP_ERROR_PARSE)
7352 break;
7353 else if (r == MAILIMAP_NO_ERROR) {
7354 number *= 10;
7355 number += (guint32) digit;
7356 }
7357 else
7358 return r;
7359 }
7360#endif
7361
7362 * result = number;
7363 * index = cur_token;
7364
7365 return MAILIMAP_NO_ERROR;
7366}
7367
7368/*
7369 password = astring
7370*/
7371
7372/*
7373 quoted = DQUOTE *QUOTED-CHAR DQUOTE
7374*/
7375
7376static int
7377mailimap_quoted_parse(mailstream * fd, MMAPString * buffer,
7378 size_t * index, char ** result,
7379 size_t progr_rate,
7380 progress_function * progr_fun)
7381{
7382 char ch;
7383 size_t cur_token;
7384 MMAPString * gstr_quoted;
7385 int r;
7386 int res;
7387
7388 cur_token = * index;
7389
7390#ifdef UNSTRICT_SYNTAX
7391 r = mailimap_space_parse(fd, buffer, &cur_token);
7392 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE))
7393 return r;
7394#endif
7395
7396 r = mailimap_dquote_parse(fd, buffer, &cur_token);
7397 if (r != MAILIMAP_NO_ERROR) {
7398 res = r;
7399 goto err;
7400 }
7401
7402 gstr_quoted = mmap_string_new("");
7403 if (gstr_quoted == NULL) {
7404 res = MAILIMAP_ERROR_MEMORY;
7405 goto err;
7406 }
7407
7408 while (1) {
7409 r = mailimap_quoted_char_parse(fd, buffer, &cur_token, &ch);
7410 if (r == MAILIMAP_ERROR_PARSE)
7411 break;
7412 else if (r == MAILIMAP_NO_ERROR) {
7413 if (mmap_string_append_c(gstr_quoted, ch) == NULL) {
7414 res = MAILIMAP_ERROR_MEMORY;
7415 goto free;
7416 }
7417 }
7418 else {
7419 res = r;
7420 goto free;
7421 }
7422 }
7423
7424 r = mailimap_dquote_parse(fd, buffer, &cur_token);
7425 if (r != MAILIMAP_NO_ERROR) {
7426 res = r;
7427 goto free;
7428 }
7429
7430 if (mmap_string_ref(gstr_quoted) < 0) {
7431 res = MAILIMAP_ERROR_MEMORY;
7432 goto free;
7433 }
7434
7435 * index = cur_token;
7436 * result = gstr_quoted->str;
7437
7438 return MAILIMAP_NO_ERROR;
7439
7440 free:
7441 mmap_string_free(gstr_quoted);
7442 err:
7443 return res;
7444}
7445
7446/*
7447 QUOTED-CHAR = <any TEXT-CHAR except quoted-specials> /
7448 "\" quoted-specials
7449*/
7450
7451static int is_quoted_specials(char ch);
7452
7453static int
7454mailimap_quoted_char_parse(mailstream * fd, MMAPString * buffer,
7455 size_t * index, char * result)
7456{
7457 size_t cur_token;
7458 int r;
7459
7460 cur_token = * index;
7461
7462 if (!is_quoted_specials(buffer->str[cur_token])) {
7463 * result = buffer->str[cur_token];
7464 cur_token ++;
7465 * index = cur_token;
7466 return MAILIMAP_NO_ERROR;
7467 }
7468 else {
7469 char quoted_special;
7470
7471 r = mailimap_char_parse(fd, buffer, &cur_token, '\\');
7472 if (r != MAILIMAP_NO_ERROR)
7473 return r;
7474
7475 r = mailimap_quoted_specials_parse(fd, buffer, &cur_token,
7476 &quoted_special);
7477 if (r != MAILIMAP_NO_ERROR)
7478 return r;
7479
7480 * result = quoted_special;
7481 * index = cur_token;
7482
7483 return MAILIMAP_NO_ERROR;
7484 }
7485}
7486
7487/*
7488 quoted-specials = DQUOTE / "\"
7489*/
7490
7491static int is_quoted_specials(char ch)
7492{
7493 return (ch == '\"') || (ch == '\\');
7494}
7495
7496static int
7497mailimap_quoted_specials_parse(mailstream * fd, MMAPString * buffer,
7498 size_t * index, char * result)
7499{
7500 size_t cur_token;
7501
7502 cur_token = * index;
7503
7504 if (is_quoted_specials(buffer->str[cur_token])) {
7505 * result = buffer->str[cur_token];
7506 cur_token ++;
7507 * index = cur_token;
7508 return MAILIMAP_NO_ERROR;
7509 }
7510 else
7511 return MAILIMAP_ERROR_PARSE;
7512}
7513
7514/*
7515 UNIMPLEMENTED
7516 rename = "RENAME" SP mailbox SP mailbox
7517 ; Use of INBOX as a destination gives a NO error
7518*/
7519
7520/*
7521 response = *(continue-req / response-data) response-done
7522*/
7523
7524/*
7525 continue-req / response-data
7526*/
7527
7528/* static */ int
7529mailimap_cont_req_or_resp_data_parse(mailstream * fd, MMAPString * buffer,
7530 size_t * index,
7531 struct mailimap_cont_req_or_resp_data **
7532 result,
7533 size_t progr_rate,
7534 progress_function * progr_fun)
7535{
7536 size_t cur_token;
7537 struct mailimap_cont_req_or_resp_data * cont_req_or_resp_data;
7538 struct mailimap_continue_req * cont_req;
7539 struct mailimap_response_data * resp_data;
7540 int type;
7541 int r;
7542 int res;
7543
7544 cur_token = * index;
7545
7546 cont_req = NULL;
7547 resp_data = NULL;
7548 type = MAILIMAP_RESP_ERROR; /* XXX - removes a gcc warning */
7549
7550 r = mailimap_continue_req_parse(fd, buffer, &cur_token, &cont_req,
7551 progr_rate, progr_fun);
7552 if (r == MAILIMAP_NO_ERROR)
7553 type = MAILIMAP_RESP_CONT_REQ;
7554
7555 if (r == MAILIMAP_ERROR_PARSE) {
7556 r = mailimap_response_data_parse(fd, buffer, &cur_token, &resp_data,
7557 progr_rate, progr_fun);
7558 if (r == MAILIMAP_NO_ERROR)
7559 type = MAILIMAP_RESP_RESP_DATA;
7560 }
7561
7562 if (r != MAILIMAP_NO_ERROR) {
7563 res = r;
7564 goto err;
7565 }
7566
7567 /*
7568 multi-lines response
7569 read another response line because after that token,
7570 there must have something (continue-req, response-data or response-done)
7571 */
7572
7573 if (!mailstream_read_line_append(fd, buffer)) {
7574 res = MAILIMAP_ERROR_STREAM;
7575 goto free;
7576 }
7577
7578 cont_req_or_resp_data =
7579 mailimap_cont_req_or_resp_data_new(type, cont_req, resp_data);
7580 if (cont_req_or_resp_data == NULL) {
7581 res = MAILIMAP_ERROR_MEMORY;
7582 goto free;
7583 }
7584
7585 * result = cont_req_or_resp_data;
7586 * index = cur_token;
7587
7588 return MAILIMAP_NO_ERROR;
7589
7590 free:
7591 if (cont_req != NULL)
7592 mailimap_continue_req_free(cont_req);
7593 if (resp_data != NULL)
7594 mailimap_response_data_free(resp_data);
7595 err:
7596 return res;
7597}
7598
7599/*
7600 response = *(continue-req / response-data) response-done
7601*/
7602
7603int
7604mailimap_response_parse(mailstream * fd, MMAPString * buffer,
7605 size_t * index, struct mailimap_response ** result,
7606 size_t progr_rate,
7607 progress_function * progr_fun)
7608{
7609 size_t cur_token;
7610 clist * cont_req_or_resp_data_list;
7611 struct mailimap_response * resp;
7612 struct mailimap_response_done * resp_done;
7613 int r;
7614 int res;
7615
7616 cur_token = * index;
7617 cont_req_or_resp_data_list = NULL;
7618 resp_done = NULL;
7619
7620 r = mailimap_struct_multiple_parse(fd, buffer,
7621 &cur_token, &cont_req_or_resp_data_list,
7622 (mailimap_struct_parser *)
7623 mailimap_cont_req_or_resp_data_parse,
7624 (mailimap_struct_destructor *)
7625 mailimap_cont_req_or_resp_data_free,
7626 progr_rate, progr_fun);
7627
7628 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE))
7629 return r;
7630
7631 r = mailimap_response_done_parse(fd, buffer, &cur_token, &resp_done,
7632 progr_rate, progr_fun);
7633 if (r != MAILIMAP_NO_ERROR) {
7634 res = r;
7635 goto free_list;
7636 }
7637
7638 resp = mailimap_response_new(cont_req_or_resp_data_list, resp_done);
7639 if (resp == NULL) {
7640 res = MAILIMAP_ERROR_MEMORY;
7641 goto free_resp_done;
7642 }
7643
7644 * result = resp;
7645 * index = cur_token;
7646
7647 return MAILIMAP_NO_ERROR;
7648
7649 free_resp_done:
7650 mailimap_response_done_free(resp_done);
7651 free_list:
7652 if (cont_req_or_resp_data_list != NULL) {
7653 clist_foreach(cont_req_or_resp_data_list,
7654 (clist_func) mailimap_cont_req_or_resp_data_free, NULL);
7655 clist_free(cont_req_or_resp_data_list);
7656 }
7657 return res;
7658}
7659
7660/*
7661 response-data = "*" SP (resp-cond-state / resp-cond-bye /
7662 mailbox-data / message-data / capability-data) CRLF
7663*/
7664
7665static int
7666mailimap_response_data_parse(mailstream * fd, MMAPString * buffer,
7667 size_t * index,
7668 struct mailimap_response_data ** result,
7669 size_t progr_rate,
7670 progress_function * progr_fun)
7671{
7672 struct mailimap_response_data * resp_data;
7673 size_t cur_token;
7674 int type;
7675 struct mailimap_resp_cond_state * cond_state;
7676 struct mailimap_resp_cond_bye * cond_bye;
7677 struct mailimap_mailbox_data * mb_data;
7678 struct mailimap_message_data * msg_data;
7679 struct mailimap_capability_data * cap_data;
7680 int r;
7681 int res;
7682
7683 cond_state = NULL;
7684 cond_bye = NULL;
7685 mb_data = NULL;
7686 msg_data = NULL;
7687 cap_data = NULL;
7688
7689 cur_token = * index;
7690
7691 r = mailimap_star_parse(fd, buffer, &cur_token);
7692 if (r != MAILIMAP_NO_ERROR) {
7693 res = r;
7694 goto err;
7695 }
7696
7697 r = mailimap_space_parse(fd, buffer, &cur_token);
7698 if (r != MAILIMAP_NO_ERROR) {
7699 res = r;
7700 goto err;
7701 }
7702
7703 type = MAILIMAP_RESP_DATA_TYPE_ERROR; /* XXX - removes a gcc warning */
7704
7705 r = mailimap_resp_cond_state_parse(fd, buffer, &cur_token, &cond_state,
7706 progr_rate, progr_fun);
7707 if (r == MAILIMAP_NO_ERROR)
7708 type = MAILIMAP_RESP_DATA_TYPE_COND_STATE;
7709
7710 if (r == MAILIMAP_ERROR_PARSE) {
7711 r = mailimap_resp_cond_bye_parse(fd, buffer, &cur_token, &cond_bye,
7712 progr_rate, progr_fun);
7713 if (r == MAILIMAP_NO_ERROR)
7714 type = MAILIMAP_RESP_DATA_TYPE_COND_BYE;
7715 }
7716
7717 if (r == MAILIMAP_ERROR_PARSE) {
7718 r = mailimap_mailbox_data_parse(fd, buffer, &cur_token, &mb_data,
7719 progr_rate, progr_fun);
7720 if (r == MAILIMAP_NO_ERROR)
7721 type = MAILIMAP_RESP_DATA_TYPE_MAILBOX_DATA;
7722 }
7723
7724 if (r == MAILIMAP_ERROR_PARSE) {
7725 r = mailimap_message_data_parse(fd, buffer, &cur_token, &msg_data,
7726 progr_rate, progr_fun);
7727 if (r == MAILIMAP_NO_ERROR)
7728 type = MAILIMAP_RESP_DATA_TYPE_MESSAGE_DATA;
7729 }
7730
7731 if (r == MAILIMAP_ERROR_PARSE) {
7732 r = mailimap_capability_data_parse(fd, buffer, &cur_token, &cap_data,
7733 progr_rate, progr_fun);
7734 if (r == MAILIMAP_NO_ERROR)
7735 type = MAILIMAP_RESP_DATA_TYPE_CAPABILITY_DATA;
7736 }
7737
7738 if (r != MAILIMAP_NO_ERROR) {
7739 res = r;
7740 goto err;
7741 }
7742
7743 r = mailimap_crlf_parse(fd, buffer, &cur_token);
7744 if (r != MAILIMAP_NO_ERROR) {
7745 res = r;
7746 goto free;
7747 }
7748
7749 resp_data = mailimap_response_data_new(type, cond_state,
7750 cond_bye, mb_data,
7751 msg_data, cap_data);
7752 if (resp_data == NULL) {
7753 res = MAILIMAP_ERROR_MEMORY;
7754 goto free;
7755 }
7756
7757 * result = resp_data;
7758 * index = cur_token;
7759
7760 return MAILIMAP_NO_ERROR;
7761
7762 free:
7763 if (cond_state)
7764 mailimap_resp_cond_state_free(cond_state);
7765 if (cond_bye)
7766 mailimap_resp_cond_bye_free(cond_bye);
7767 if (mb_data)
7768 mailimap_mailbox_data_free(mb_data);
7769 if (msg_data)
7770 mailimap_message_data_free(msg_data);
7771 if (cap_data)
7772 mailimap_capability_data_free(cap_data);
7773 err:
7774 return res;
7775}
7776
7777/*
7778 response-done = response-tagged / response-fatal
7779*/
7780
7781static int
7782mailimap_response_done_parse(mailstream * fd, MMAPString * buffer,
7783 size_t * index,
7784 struct mailimap_response_done ** result,
7785 size_t progr_rate,
7786 progress_function * progr_fun)
7787{
7788 int type;
7789 struct mailimap_response_done * resp_done;
7790 size_t cur_token;
7791 struct mailimap_response_tagged * tagged;
7792 struct mailimap_response_fatal * fatal;
7793 int r;
7794 int res;
7795
7796 cur_token = * index;
7797
7798 tagged = NULL;
7799 fatal = NULL;
7800
7801 type = MAILIMAP_RESP_DONE_TYPE_ERROR; /* removes a gcc warning */
7802
7803 r = mailimap_response_tagged_parse(fd, buffer, &cur_token, &tagged,
7804 progr_rate, progr_fun);
7805 if (r == MAILIMAP_NO_ERROR)
7806 type = MAILIMAP_RESP_DONE_TYPE_TAGGED;
7807
7808 if (r == MAILIMAP_ERROR_PARSE) {
7809 r = mailimap_response_fatal_parse(fd, buffer, &cur_token, &fatal,
7810 progr_rate, progr_fun);
7811 if (r == MAILIMAP_NO_ERROR)
7812 type = MAILIMAP_RESP_DONE_TYPE_FATAL;
7813 }
7814
7815 if (r != MAILIMAP_NO_ERROR) {
7816 res = r;
7817 goto err;
7818 }
7819
7820 resp_done = mailimap_response_done_new(type, tagged, fatal);
7821 if (resp_done == NULL) {
7822 res = MAILIMAP_ERROR_MEMORY;
7823 goto free;
7824 }
7825
7826 * result = resp_done;
7827 * index = cur_token;
7828
7829 return MAILIMAP_NO_ERROR;
7830
7831 free:
7832 if (tagged == NULL)
7833 mailimap_response_tagged_free(tagged);
7834 if (fatal == NULL)
7835 mailimap_response_fatal_free(fatal);
7836 err:
7837 return res;
7838}
7839
7840/*
7841 response-fatal = "*" SP resp-cond-bye CRLF
7842 ; Server closes connection immediately
7843*/
7844
7845static int
7846mailimap_response_fatal_parse(mailstream * fd, MMAPString * buffer,
7847 size_t * index,
7848 struct mailimap_response_fatal ** result,
7849 size_t progr_rate,
7850 progress_function * progr_fun)
7851{
7852 struct mailimap_resp_cond_bye * cond_bye;
7853 struct mailimap_response_fatal * fatal;
7854 size_t cur_token;
7855 int res;
7856 int r;
7857
7858 cur_token = * index;
7859
7860 r = mailimap_star_parse(fd, buffer, &cur_token);
7861 if (r != MAILIMAP_NO_ERROR) {
7862 res = r;
7863 goto err;
7864 }
7865
7866 r = mailimap_space_parse(fd, buffer, &cur_token);
7867 if (r != MAILIMAP_NO_ERROR) {
7868 res = r;
7869 goto err;
7870 }
7871
7872 r = mailimap_resp_cond_bye_parse(fd, buffer, &cur_token, &cond_bye,
7873 progr_rate, progr_fun);
7874 if (r != MAILIMAP_NO_ERROR) {
7875 res = r;
7876 goto err;
7877 }
7878
7879 r = mailimap_crlf_parse(fd, buffer, &cur_token);
7880 if (r != MAILIMAP_NO_ERROR) {
7881 res = r;
7882 goto free;
7883 }
7884
7885 fatal = mailimap_response_fatal_new(cond_bye);
7886 if (fatal == NULL) {
7887 res = MAILIMAP_ERROR_MEMORY;
7888 goto free;
7889 }
7890
7891 * result = fatal;
7892 * index = cur_token;
7893
7894 return MAILIMAP_NO_ERROR;
7895
7896 free:
7897 mailimap_resp_cond_bye_free(cond_bye);
7898 err:
7899 return res;
7900}
7901
7902/*
7903 response-tagged = tag SP resp-cond-state CRLF
7904*/
7905
7906static int
7907mailimap_response_tagged_parse(mailstream * fd, MMAPString * buffer,
7908 size_t * index,
7909 struct mailimap_response_tagged ** result,
7910 size_t progr_rate,
7911 progress_function * progr_fun)
7912{
7913 size_t cur_token;
7914 char * tag;
7915 struct mailimap_resp_cond_state * cond_state;
7916 struct mailimap_response_tagged * resp_tagged;
7917 int r;
7918 int res;
7919
7920 cur_token = * index;
7921 cond_state = NULL;
7922
7923 r = mailimap_tag_parse(fd, buffer, &cur_token, &tag,
7924 progr_rate, progr_fun);
7925 if (r != MAILIMAP_NO_ERROR) {
7926 res = r;
7927 goto err;
7928 }
7929
7930 r = mailimap_space_parse(fd, buffer, &cur_token);
7931 if (r != MAILIMAP_NO_ERROR) {
7932 res = r;
7933 goto free_tag;
7934 }
7935
7936 r = mailimap_resp_cond_state_parse(fd, buffer, &cur_token, &cond_state,
7937 progr_rate, progr_fun);
7938 if (r != MAILIMAP_NO_ERROR) {
7939 res = r;
7940 goto free_tag;
7941 }
7942
7943 resp_tagged = mailimap_response_tagged_new(tag, cond_state);
7944 if (resp_tagged == NULL) {
7945 res = MAILIMAP_ERROR_MEMORY;
7946 goto free_cond_state;
7947 }
7948
7949 * result = resp_tagged;
7950 * index = cur_token;
7951
7952 return MAILIMAP_NO_ERROR;
7953
7954 free_cond_state:
7955 mailimap_resp_cond_state_free(cond_state);
7956 free_tag:
7957 mailimap_tag_free(tag);
7958 err:
7959 return res;
7960}
7961
7962/*
7963 resp-cond-auth = ("OK" / "PREAUTH") SP resp-text
7964 ; Authentication condition
7965*/
7966
7967static int
7968mailimap_resp_cond_auth_parse(mailstream * fd, MMAPString * buffer,
7969 size_t * index,
7970 struct mailimap_resp_cond_auth ** result,
7971 size_t progr_rate,
7972 progress_function * progr_fun)
7973{
7974 struct mailimap_resp_cond_auth * cond_auth;
7975 size_t cur_token;
7976 struct mailimap_resp_text * text;
7977 int type;
7978 int r;
7979 int res;
7980
7981 cur_token = * index;
7982 text = NULL;
7983
7984 type = MAILIMAP_RESP_COND_AUTH_ERROR; /* XXX - removes a gcc warning */
7985
7986 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token, "OK");
7987 if (r == MAILIMAP_NO_ERROR)
7988 type = MAILIMAP_RESP_COND_AUTH_OK;
7989
7990 if (r == MAILIMAP_ERROR_PARSE) {
7991 r = mailimap_token_case_insensitive_parse(fd, buffer,
7992 &cur_token, "PREAUTH");
7993 if (r == MAILIMAP_NO_ERROR)
7994 type = MAILIMAP_RESP_COND_AUTH_PREAUTH;
7995 }
7996
7997 if (r != MAILIMAP_NO_ERROR) {
7998 res = r;
7999 goto err;
8000 }
8001
8002 r = mailimap_space_parse(fd, buffer, &cur_token);
8003 if (r != MAILIMAP_NO_ERROR) {
8004 res = r;
8005 goto err;
8006 }
8007
8008 r = mailimap_resp_text_parse(fd, buffer, &cur_token, &text,
8009 progr_rate, progr_fun);
8010 if (r != MAILIMAP_NO_ERROR) {
8011 res = r;
8012 goto err;
8013 }
8014
8015 cond_auth = mailimap_resp_cond_auth_new(type, text);
8016 if (cond_auth == NULL) {
8017 res = MAILIMAP_ERROR_MEMORY;
8018 goto free;
8019 }
8020
8021 * result = cond_auth;
8022 * index = cur_token;
8023
8024 return MAILIMAP_NO_ERROR;
8025
8026 free:
8027 mailimap_resp_text_free(text);
8028 err:
8029 return res;
8030}
8031
8032/*
8033 resp-cond-bye = "BYE" SP resp-text
8034*/
8035
8036static int
8037mailimap_resp_cond_bye_parse(mailstream * fd, MMAPString * buffer,
8038 size_t * index,
8039 struct mailimap_resp_cond_bye ** result,
8040 size_t progr_rate,
8041 progress_function * progr_fun)
8042{
8043 size_t cur_token;
8044 struct mailimap_resp_cond_bye * cond_bye;
8045 struct mailimap_resp_text * text;
8046 int r;
8047 int res;
8048
8049 cur_token = * index;
8050
8051 r = mailimap_token_case_insensitive_parse(fd, buffer,
8052 &cur_token, "BYE");
8053 if (r != MAILIMAP_NO_ERROR) {
8054 res = r;
8055 goto err;
8056 }
8057
8058 r = mailimap_space_parse(fd, buffer, &cur_token);
8059 if (r != MAILIMAP_NO_ERROR) {
8060 res = r;
8061 goto err;
8062 }
8063
8064 r = mailimap_resp_text_parse(fd, buffer, &cur_token, &text,
8065 progr_rate, progr_fun);
8066 if (r != MAILIMAP_NO_ERROR) {
8067 res = r;
8068 goto err;
8069 }
8070
8071 cond_bye = mailimap_resp_cond_bye_new(text);
8072 if (cond_bye == NULL) {
8073 res = MAILIMAP_ERROR_MEMORY;
8074 goto free;
8075 }
8076
8077 * index = cur_token;
8078 * result = cond_bye;
8079
8080 return MAILIMAP_NO_ERROR;
8081
8082 free:
8083 mailimap_resp_text_free(text);
8084 err:
8085 return res;
8086}
8087
8088/*
8089 resp-cond-state = ("OK" / "NO" / "BAD") SP resp-text
8090 ; Status condition
8091*/
8092
8093static int
8094mailimap_resp_cond_state_parse(mailstream * fd, MMAPString * buffer,
8095 size_t * index,
8096 struct mailimap_resp_cond_state ** result,
8097 size_t progr_rate,
8098 progress_function * progr_fun)
8099{
8100 struct mailimap_resp_cond_state * cond_state;
8101 size_t cur_token;
8102 struct mailimap_resp_text * text;
8103 int type;
8104 int r;
8105 int res;
8106
8107 cur_token = * index;
8108 text = NULL;
8109
8110 type = mailimap_resp_cond_state_get_token_value(fd, buffer, &cur_token);
8111 if (type == -1) {
8112 res = MAILIMAP_ERROR_PARSE;
8113 goto err;
8114 }
8115
8116 r = mailimap_space_parse(fd, buffer, &cur_token);
8117 if (r != MAILIMAP_NO_ERROR) {
8118 res = r;
8119 goto err;
8120 }
8121
8122 r = mailimap_resp_text_parse(fd, buffer, &cur_token, &text,
8123 progr_rate, progr_fun);
8124 if (r != MAILIMAP_NO_ERROR) {
8125 res = r;
8126 goto err;
8127 }
8128
8129 cond_state = mailimap_resp_cond_state_new(type, text);
8130 if (cond_state == NULL) {
8131 res = MAILIMAP_ERROR_MEMORY;
8132 goto free;
8133 }
8134
8135 * result = cond_state;
8136 * index = cur_token;
8137
8138 return MAILIMAP_NO_ERROR;
8139
8140 free:
8141 mailimap_resp_text_free(text);
8142 err:
8143 return res;
8144}
8145
8146
8147/*
8148 resp-specials = "]"
8149*/
8150
8151static int is_resp_specials(char ch)
8152{
8153 switch (ch) {
8154 case ']':
8155 return TRUE;
8156 };
8157 return FALSE;
8158}
8159
8160/*
8161 resp-text = ["[" resp-text-code "]" SP] text
8162*/
8163
8164/* "[" resp-text-code "]" */
8165
8166static int
8167mailimap_resp_text_resp_text_code_parse(mailstream * fd, MMAPString * buffer,
8168 size_t * index,
8169 struct mailimap_resp_text_code **
8170 result,
8171 size_t progr_rate,
8172 progress_function * progr_fun)
8173{
8174 struct mailimap_resp_text_code * text_code;
8175 size_t cur_token;
8176 int r;
8177 int res;
8178
8179 cur_token = * index;
8180
8181 r = mailimap_obracket_parse(fd, buffer, &cur_token);
8182 if (r != MAILIMAP_NO_ERROR) {
8183 res = r;
8184 goto err;
8185 }
8186
8187 r = mailimap_resp_text_code_parse(fd, buffer, &cur_token, &text_code,
8188 progr_rate, progr_fun);
8189 if (r != MAILIMAP_NO_ERROR) {
8190 res = r;
8191 goto err;
8192 }
8193
8194 r = mailimap_cbracket_parse(fd, buffer, &cur_token);
8195 if (r != MAILIMAP_NO_ERROR) {
8196 res = r;
8197 goto free;
8198 }
8199
8200 r = mailimap_space_parse(fd, buffer, &cur_token);
8201 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) {
8202 res = r;
8203 goto free;
8204 }
8205
8206 * result = text_code;
8207 * index = cur_token;
8208
8209 return MAILIMAP_NO_ERROR;
8210
8211 free:
8212 mailimap_resp_text_code_free(text_code);
8213 err:
8214 return res;
8215}
8216
8217/*
8218 resp-text = ["[" resp-text-code "]" SP] text
8219*/
8220
8221static int
8222mailimap_resp_text_parse(mailstream * fd, MMAPString * buffer,
8223 size_t * index,
8224 struct mailimap_resp_text ** result,
8225 size_t progr_rate,
8226 progress_function * progr_fun)
8227{
8228 size_t cur_token;
8229 struct mailimap_resp_text_code * text_code;
8230 struct mailimap_resp_text * resp_text;
8231 char * text;
8232 int r;
8233 int res;
8234
8235 cur_token = * index;
8236 text = NULL;
8237 text_code = NULL;
8238
8239 r = mailimap_resp_text_resp_text_code_parse(fd, buffer, &cur_token,
8240 &text_code,
8241 progr_rate, progr_fun);
8242 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE))
8243 return r;
8244
8245 r = mailimap_text_parse(fd, buffer, &cur_token, &text,
8246 progr_rate, progr_fun);
8247 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) {
8248 res = r;
8249 goto free_resp_text_code;
8250 }
8251
8252 resp_text = mailimap_resp_text_new(text_code, text);
8253 if (resp_text == NULL) {
8254 res = MAILIMAP_ERROR_MEMORY;
8255 goto free_text;
8256 }
8257
8258 * result = resp_text;
8259 * index = cur_token;
8260
8261 return MAILIMAP_NO_ERROR;
8262
8263 free_resp_text_code:
8264 if (text_code != NULL)
8265 mailimap_resp_text_code_free(text_code);
8266 free_text:
8267 mailimap_text_free(text);
8268 return res;
8269}
8270
8271/*
8272 resp-text-code = "ALERT" /
8273 "BADCHARSET" [SP "(" astring *(SP astring) ")" ] /
8274 capability-data / "PARSE" /
8275 "PERMANENTFLAGS" SP "(" [flag-perm *(SP flag-perm)] ")" /
8276 "READ-ONLY" / "READ-WRITE" / "TRYCREATE" /
8277 "UIDNEXT" SP nz-number / "UIDVALIDITY" SP nz-number /
8278 "UNSEEN" SP nz-number /
8279 atom [SP 1*<any TEXT-CHAR except "]">]
8280*/
8281
8282/*
8283 ALERT / PARSE / READ-ONLY / READ-WRITE / TRYCREATE
8284*/
8285
8286static int
8287mailimap_resp_text_code_1_parse(mailstream * fd, MMAPString * buffer,
8288 size_t * index,
8289 int * result)
8290{
8291 int id;
8292 size_t cur_token;
8293
8294 cur_token = * index;
8295
8296 id = mailimap_resp_text_code_1_get_token_value(fd, buffer, &cur_token);
8297
8298 if (id == -1)
8299 return MAILIMAP_ERROR_PARSE;
8300
8301 * result = id;
8302 * index = cur_token;
8303
8304 return MAILIMAP_NO_ERROR;
8305}
8306
8307
8308/*
8309 "BADCHARSET" [SP "(" astring *(SP astring) ")" ]
8310*/
8311
8312/*
8313 SP "(" astring *(SP astring) ")"
8314*/
8315
8316static int
8317mailimap_resp_text_code_badcharset_1_parse(mailstream * fd,
8318 MMAPString * buffer,
8319 size_t * index,
8320 clist ** result,
8321 size_t progr_rate,
8322 progress_function * progr_fun)
8323{
8324 size_t cur_token;
8325 clist * charset;
8326 int r;
8327 int res;
8328
8329 cur_token = * index;
8330
8331 r = mailimap_space_parse(fd, buffer, &cur_token);
8332 if (r != MAILIMAP_NO_ERROR) {
8333 res = r;
8334 goto err;
8335 }
8336
8337 r = mailimap_oparenth_parse(fd, buffer, &cur_token);
8338 if (r != MAILIMAP_NO_ERROR) {
8339 res = r;
8340 goto err;
8341 }
8342
8343 r = mailimap_struct_spaced_list_parse(fd, buffer, &cur_token, &charset,
8344 (mailimap_struct_parser *)
8345 mailimap_astring_parse,
8346 (mailimap_struct_destructor *)
8347 mailimap_astring_free,
8348 progr_rate, progr_fun);
8349 if (r != MAILIMAP_NO_ERROR) {
8350 res = r;
8351 goto err;
8352 }
8353
8354 r = mailimap_cparenth_parse(fd, buffer, &cur_token);
8355 if (r != MAILIMAP_NO_ERROR) {
8356 res = r;
8357 goto charset;
8358 }
8359
8360 * index = cur_token;
8361 * result = charset;
8362
8363 return MAILIMAP_NO_ERROR;
8364
8365 charset:
8366 clist_foreach(charset, (clist_func) mailimap_string_free, NULL);
8367 clist_free(charset);
8368 err:
8369 return res;
8370}
8371
8372/*
8373 "BADCHARSET" [SP "(" astring *(SP astring) ")" ]
8374*/
8375
8376static int
8377mailimap_resp_text_code_badcharset_parse(mailstream * fd, MMAPString * buffer,
8378 size_t * index,
8379 clist ** result,
8380 size_t progr_rate,
8381 progress_function * progr_fun)
8382{
8383 size_t cur_token;
8384 clist * charset;
8385 int r;
8386
8387 cur_token = * index;
8388
8389 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
8390 "BADCHARSET");
8391 if (r != MAILIMAP_NO_ERROR)
8392 return r;
8393
8394 charset = NULL;
8395
8396 r = mailimap_resp_text_code_badcharset_1_parse(fd, buffer, &cur_token,
8397 &charset,
8398 progr_rate, progr_fun);
8399 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE))
8400 return r;
8401
8402 * result = charset;
8403 * index = cur_token;
8404
8405 return MAILIMAP_NO_ERROR;
8406}
8407
8408/*
8409 "PERMANENTFLAGS" SP "(" [flag-perm *(SP flag-perm)] ")"
8410*/
8411
8412static int
8413mailimap_resp_text_code_permanentflags_parse(mailstream * fd,
8414 MMAPString * buffer,
8415 size_t * index,
8416 clist ** result,
8417 size_t progr_rate,
8418 progress_function * progr_fun)
8419{
8420 size_t cur_token;
8421 clist * flaglist;
8422 int r;
8423 int res;
8424
8425 cur_token = * index;
8426
8427 flaglist = NULL;
8428
8429 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
8430 "PERMANENTFLAGS");
8431 if (r != MAILIMAP_NO_ERROR) {
8432 res = r;
8433 goto err;
8434 }
8435
8436 r = mailimap_space_parse(fd, buffer, &cur_token);
8437 if (r != MAILIMAP_NO_ERROR) {
8438 res = r;
8439 goto err;
8440 }
8441
8442 r = mailimap_oparenth_parse(fd, buffer, &cur_token);
8443 if (r != MAILIMAP_NO_ERROR) {
8444 res = r;
8445 goto err;
8446 }
8447
8448 r = mailimap_struct_spaced_list_parse(fd, buffer, &cur_token, &flaglist,
8449 (mailimap_struct_parser *)
8450 mailimap_flag_perm_parse,
8451 (mailimap_struct_destructor *)
8452 mailimap_flag_perm_free,
8453 progr_rate, progr_fun);
8454 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) {
8455 res = r;
8456 goto err;
8457 }
8458
8459 r = mailimap_cparenth_parse(fd, buffer, &cur_token);
8460 if (r != MAILIMAP_NO_ERROR) {
8461 res = r;
8462 goto free;
8463 }
8464
8465 * index = cur_token;
8466 * result = flaglist;
8467
8468 return MAILIMAP_NO_ERROR;
8469
8470 free:
8471 clist_foreach(flaglist, (clist_func) mailimap_flag_perm_free, NULL);
8472 clist_free(flaglist);
8473 err:
8474 return res;
8475}
8476
8477
8478/*
8479 "UIDNEXT" SP nz-number /
8480 "UIDVALIDITY" SP nz-number /
8481 "UNSEEN" SP nz-number
8482*/
8483
8484static int
8485mailimap_resp_text_code_number_parse(mailstream * fd, MMAPString * buffer,
8486 size_t * index,
8487 struct mailimap_resp_text_code ** result,
8488 size_t progr_rate,
8489 progress_function * progr_fun)
8490{
8491 size_t cur_token;
8492 int type;
8493 uint32_t number;
8494 struct mailimap_resp_text_code * resp_text_code;
8495 int r;
8496
8497 cur_token = * index;
8498
8499 resp_text_code = NULL;
8500
8501 type = mailimap_resp_text_code_2_get_token_value(fd, buffer, &cur_token);
8502 if (type == -1)
8503 return MAILIMAP_ERROR_PARSE;
8504
8505 r = mailimap_space_parse(fd, buffer, &cur_token);
8506 if (r != MAILIMAP_NO_ERROR)
8507 return r;
8508
8509 r = mailimap_nz_number_parse(fd, buffer, &cur_token, &number);
8510 if (r != MAILIMAP_NO_ERROR)
8511 return r;
8512
8513 switch (type) {
8514 case MAILIMAP_RESP_TEXT_CODE_UIDNEXT:
8515 resp_text_code = mailimap_resp_text_code_new(type, NULL, NULL, NULL,
8516 number, 0, 0, NULL , NULL);
8517 break;
8518 case MAILIMAP_RESP_TEXT_CODE_UIDVALIDITY:
8519 resp_text_code = mailimap_resp_text_code_new(type, NULL, NULL, NULL,
8520 0, number, 0, NULL , NULL);
8521 break;
8522 case MAILIMAP_RESP_TEXT_CODE_UNSEEN:
8523 resp_text_code = mailimap_resp_text_code_new(type, NULL, NULL, NULL,
8524 0, 0, number, NULL , NULL);
8525 break;
8526 }
8527
8528 if (resp_text_code == NULL)
8529 return MAILIMAP_ERROR_MEMORY;
8530
8531 * result = resp_text_code;
8532 * index = cur_token;
8533
8534 return MAILIMAP_NO_ERROR;
8535}
8536
8537/*
8538 atom [SP 1*<any TEXT-CHAR except "]">]
8539*/
8540
8541static int is_text_char(char ch);
8542
8543/*
8544 any TEXT-CHAR except "]"
8545*/
8546
8547static int is_text_char_1(char ch)
8548{
8549 if (ch == ']')
8550 return FALSE;
8551 return is_text_char(ch);
8552}
8553
8554/*
8555 1*<any TEXT-CHAR except "]"
8556*/
8557
8558static int
8559mailimap_resp_text_code_other_2_parse(mailstream * fd, MMAPString * buffer,
8560 size_t * index, char ** result,
8561 size_t progr_rate,
8562 progress_function * progr_fun)
8563{
8564 return mailimap_custom_string_parse(fd, buffer, index, result,
8565 is_text_char_1);
8566}
8567
8568/*
8569 SP 1*<any TEXT-CHAR except "]">
8570*/
8571
8572static int
8573mailimap_resp_text_code_other_1_parse(mailstream * fd, MMAPString * buffer,
8574 size_t * index,
8575 char ** result,
8576 size_t progr_rate,
8577 progress_function * progr_fun)
8578{
8579 size_t cur_token;
8580 char * value;
8581 int r;
8582
8583 cur_token = * index;
8584
8585 r = mailimap_space_parse(fd, buffer, &cur_token);
8586 if (r != MAILIMAP_NO_ERROR)
8587 return r;
8588
8589 r = mailimap_resp_text_code_other_2_parse(fd, buffer, &cur_token,
8590 &value,
8591 progr_rate, progr_fun);
8592 if (r != MAILIMAP_NO_ERROR)
8593 return r;
8594
8595 * result = value;
8596 * index = cur_token;
8597
8598 return MAILIMAP_NO_ERROR;
8599}
8600
8601/*
8602 atom [SP 1*<any TEXT-CHAR except "]">]
8603*/
8604
8605static int
8606mailimap_resp_text_code_other_parse(mailstream * fd, MMAPString * buffer,
8607 size_t * index,
8608 struct mailimap_resp_text_code ** result,
8609 size_t progr_rate,
8610 progress_function * progr_fun)
8611{
8612 size_t cur_token;
8613 char * atom;
8614 char * value;
8615 struct mailimap_resp_text_code * resp_text_code;
8616 int r;
8617 int res;
8618
8619 cur_token = * index;
8620 atom = NULL;
8621 value = NULL;
8622
8623 r = mailimap_atom_parse(fd, buffer, &cur_token, &atom,
8624 progr_rate, progr_fun);
8625 if (r != MAILIMAP_NO_ERROR) {
8626 res = r;
8627 goto err;
8628 }
8629
8630 r = mailimap_resp_text_code_other_1_parse(fd, buffer, &cur_token,
8631 &value, progr_rate, progr_fun);
8632 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) {
8633 res = r;
8634 goto err;
8635 }
8636
8637 resp_text_code = mailimap_resp_text_code_new(MAILIMAP_RESP_TEXT_CODE_OTHER,
8638 NULL, NULL, NULL,
8639 0, 0, 0, atom, value);
8640 if (resp_text_code == NULL) {
8641 res = MAILIMAP_ERROR_MEMORY;
8642 goto free_value;
8643 }
8644
8645 * result = resp_text_code;
8646 * index = cur_token;
8647
8648 return MAILIMAP_NO_ERROR;
8649
8650 free_value:
8651 if (value != NULL)
8652 free(value);
8653 mailimap_atom_free(atom);
8654 err:
8655 return res;
8656}
8657
8658
8659
8660/*
8661 resp-text-code = "ALERT" /
8662 "BADCHARSET" [SP "(" astring *(SP astring) ")" ] /
8663 capability-data / "PARSE" /
8664 "PERMANENTFLAGS" SP "(" [flag-perm *(SP flag-perm)] ")" /
8665 "READ-ONLY" / "READ-WRITE" / "TRYCREATE" /
8666 "UIDNEXT" SP nz-number / "UIDVALIDITY" SP nz-number /
8667 "UNSEEN" SP nz-number /
8668 atom [SP 1*<any TEXT-CHAR except "]">]
8669*/
8670
8671static int
8672mailimap_resp_text_code_parse(mailstream * fd, MMAPString * buffer,
8673 size_t * index,
8674 struct mailimap_resp_text_code ** result,
8675 size_t progr_rate,
8676 progress_function * progr_fun)
8677{
8678 size_t cur_token;
8679 struct mailimap_resp_text_code * resp_text_code;
8680 clist * badcharset;
8681 clist * permanentflags;
8682 struct mailimap_capability_data * cap_data;
8683 int type;
8684 int r;
8685 int res;
8686
8687 cur_token = * index;
8688
8689 resp_text_code = NULL;
8690 badcharset = NULL;
8691 cap_data = NULL;
8692 permanentflags = NULL;
8693
8694 r = mailimap_resp_text_code_1_parse(fd, buffer, &cur_token, &type);
8695 if (r == MAILIMAP_NO_ERROR) {
8696 /* do nothing */
8697 }
8698
8699 if (r == MAILIMAP_ERROR_PARSE) {
8700
8701 r = mailimap_resp_text_code_badcharset_parse(fd, buffer, &cur_token,
8702 &badcharset,
8703 progr_rate, progr_fun);
8704 if (r == MAILIMAP_NO_ERROR)
8705 type = MAILIMAP_RESP_TEXT_CODE_BADCHARSET;
8706 }
8707
8708 if (r == MAILIMAP_ERROR_PARSE) {
8709
8710 r = mailimap_capability_data_parse(fd, buffer, &cur_token,
8711 &cap_data,
8712 progr_rate, progr_fun);
8713 if (r == MAILIMAP_NO_ERROR)
8714 type = MAILIMAP_RESP_TEXT_CODE_CAPABILITY_DATA;
8715 }
8716
8717 if (r == MAILIMAP_ERROR_PARSE) {
8718 r = mailimap_resp_text_code_permanentflags_parse(fd, buffer, &cur_token,
8719 &permanentflags,
8720 progr_rate,
8721 progr_fun);
8722 if (r == MAILIMAP_NO_ERROR)
8723 type = MAILIMAP_RESP_TEXT_CODE_PERMANENTFLAGS;
8724 }
8725
8726 if (r == MAILIMAP_ERROR_PARSE) {
8727 r = mailimap_resp_text_code_number_parse(fd, buffer, &cur_token,
8728 &resp_text_code,
8729 progr_rate, progr_fun);
8730 }
8731
8732 if (r == MAILIMAP_ERROR_PARSE) {
8733 r = mailimap_resp_text_code_other_parse(fd, buffer, &cur_token,
8734 &resp_text_code,
8735 progr_rate, progr_fun);
8736 }
8737
8738 if (r != MAILIMAP_NO_ERROR) {
8739 res = r;
8740 goto err;
8741 }
8742
8743 if (resp_text_code == NULL) {
8744 resp_text_code = mailimap_resp_text_code_new(type,
8745 badcharset, cap_data,
8746 permanentflags,
8747 0, 0, 0, NULL, NULL);
8748 if (resp_text_code == NULL) {
8749 res = MAILIMAP_ERROR_MEMORY;
8750 goto free;
8751 }
8752 }
8753
8754 * result = resp_text_code;
8755 * index = cur_token;
8756
8757 return MAILIMAP_NO_ERROR;
8758
8759free:
8760 if (permanentflags) {
8761 clist_foreach(permanentflags,
8762 (clist_func) mailimap_flag_perm_free, NULL);
8763 clist_free(permanentflags);
8764 }
8765 if (cap_data)
8766 mailimap_capability_data_free(cap_data);
8767 if (badcharset) {
8768 clist_foreach(badcharset, (clist_func) mailimap_astring_free, NULL);
8769 clist_free(badcharset);
8770 }
8771err:
8772 return res;
8773}
8774
8775/*
8776 UNIMPLEMENTED
8777 search = "SEARCH" [SP "CHARSET" SP astring] 1*(SP search-key)
8778 ; CHARSET argument to MUST be registered with IANA
8779*/
8780
8781/*
8782 UNIMPLEMENTED
8783 search-key = "ALL" / "ANSWERED" / "BCC" SP astring /
8784 "BEFORE" SP date / "BODY" SP astring /
8785 "CC" SP astring / "DELETED" / "FLAGGED" /
8786 "FROM" SP astring / "KEYWORD" SP flag-keyword / "NEW" /
8787 "OLD" / "ON" SP date / "RECENT" / "SEEN" /
8788 "SINCE" SP date / "SUBJECT" SP astring /
8789 "TEXT" SP astring / "TO" SP astring /
8790 "UNANSWERED" / "UNDELETED" / "UNFLAGGED" /
8791 "UNKEYWORD" SP flag-keyword / "UNSEEN" /
8792 ; Above this line were in [IMAP2]
8793 "DRAFT" / "HEADER" SP header-fld-name SP astring /
8794 "LARGER" SP number / "NOT" SP search-key /
8795 "OR" SP search-key SP search-key /
8796 "SENTBEFORE" SP date / "SENTON" SP date /
8797 "SENTSINCE" SP date / "SMALLER" SP number /
8798 "UID" SP set / "UNDRAFT" / set /
8799 "(" search-key *(SP search-key) ")"
8800*/
8801
8802/*
8803 section = "[" [section-spec] "]"
8804*/
8805
8806static int
8807mailimap_section_parse(mailstream * fd, MMAPString * buffer,
8808 size_t * index,
8809 struct mailimap_section ** result,
8810 size_t progr_rate,
8811 progress_function * progr_fun)
8812{
8813 struct mailimap_section_spec * section_spec;
8814 size_t cur_token;
8815 struct mailimap_section * section;
8816 int r;
8817 int res;
8818
8819 cur_token = * index;
8820
8821 section_spec = NULL;
8822
8823 r = mailimap_obracket_parse(fd, buffer, &cur_token);
8824 if (r != MAILIMAP_NO_ERROR) {
8825 res = r;
8826 goto err;
8827 }
8828
8829 r = mailimap_section_spec_parse(fd, buffer, &cur_token, &section_spec,
8830 progr_rate, progr_fun);
8831 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) {
8832 res = r;
8833 goto err;
8834 }
8835
8836 r = mailimap_cbracket_parse(fd, buffer, &cur_token);
8837 if (r != MAILIMAP_NO_ERROR) {
8838 res = r;
8839 goto err;
8840 }
8841
8842 if (section_spec == NULL)
8843 section = NULL;
8844 else {
8845 section = mailimap_section_new(section_spec);
8846 if (section == NULL) {
8847 res = MAILIMAP_ERROR_MEMORY;
8848 goto free;
8849 }
8850 }
8851
8852 * result = section;
8853 * index = cur_token;
8854
8855 return MAILIMAP_NO_ERROR;
8856
8857 free:
8858 mailimap_section_spec_free(section_spec);
8859 err:
8860 return res;
8861}
8862
8863/*
8864 section-msgtext = "HEADER" / "HEADER.FIELDS" [".NOT"] SP header-list /
8865 "TEXT"
8866 ; top-level or MESSAGE/RFC822 part
8867*/
8868
8869static int
8870mailimap_section_msgtext_parse(mailstream * fd, MMAPString * buffer,
8871 size_t * index,
8872 struct mailimap_section_msgtext ** result,
8873 size_t progr_rate,
8874 progress_function * progr_fun)
8875{
8876 size_t cur_token;
8877 int type;
8878 struct mailimap_header_list * header_list;
8879 struct mailimap_section_msgtext * msgtext;
8880 int r;
8881 int res;
8882
8883 cur_token = * index;
8884
8885 header_list = NULL;
8886
8887 type = mailimap_section_msgtext_get_token_value(fd, buffer, &cur_token);
8888 if (type == -1) {
8889 res = MAILIMAP_ERROR_PARSE;
8890 goto err;
8891 }
8892
8893 if (type == MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS) {
8894 r = mailimap_header_list_parse(fd, buffer, &cur_token, &header_list,
8895 progr_rate, progr_fun);
8896 if (r != MAILIMAP_NO_ERROR) {
8897 res = r;
8898 goto err;
8899 }
8900 }
8901 else if (type == MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS_NOT) {
8902 r = mailimap_header_list_parse(fd, buffer, &cur_token, &header_list,
8903 progr_rate, progr_fun);
8904 if (r != MAILIMAP_NO_ERROR) {
8905 res = r;
8906 goto err;
8907 }
8908 }
8909
8910 msgtext = mailimap_section_msgtext_new(type, header_list);
8911 if (msgtext == NULL) {
8912 res = MAILIMAP_ERROR_MEMORY;
8913 goto free_header_list;
8914 }
8915
8916 * result = msgtext;
8917 * index = cur_token;
8918
8919 return MAILIMAP_NO_ERROR;
8920
8921 free_header_list:
8922 if (header_list)
8923 mailimap_header_list_free(header_list);
8924 err:
8925 return res;
8926}
8927
8928/*
8929 section-part = nz-number *("." nz-number)
8930 ; body part nesting
8931*/
8932
8933static int
8934mailimap_section_part_parse(mailstream * fd, MMAPString * buffer,
8935 size_t * index,
8936 struct mailimap_section_part ** result,
8937 size_t progr_rate,
8938 progress_function * progr_fun)
8939{
8940 struct mailimap_section_part * section_part;
8941 size_t cur_token;
8942 clist * section_id;
8943 int r;
8944 int res;
8945
8946 cur_token = * index;
8947 section_id = NULL;
8948
8949 r = mailimap_struct_list_parse(fd, buffer, &cur_token, &section_id, '.',
8950 (mailimap_struct_parser *)
8951 mailimap_nz_number_alloc_parse,
8952 (mailimap_struct_destructor *)
8953 mailimap_number_alloc_free,
8954 progr_rate, progr_fun);
8955 if (r != MAILIMAP_NO_ERROR) {
8956 res = r;
8957 goto err;
8958 }
8959
8960 section_part = mailimap_section_part_new(section_id);
8961 if (section_part == NULL) {
8962 res = MAILIMAP_ERROR_MEMORY;
8963 goto free_section_id;
8964 }
8965
8966 * result = section_part;
8967 * index = cur_token;
8968
8969 return MAILIMAP_NO_ERROR;
8970
8971 free_section_id:
8972 clist_foreach(section_id, (clist_func) mailimap_number_alloc_free, NULL);
8973 clist_free(section_id);
8974 err:
8975 return res;
8976}
8977
8978/*
8979 section-spec = section-msgtext / (section-part ["." section-text])
8980*/
8981
8982static int
8983mailimap_section_spec_parse(mailstream * fd, MMAPString * buffer,
8984 size_t * index,
8985 struct mailimap_section_spec ** result,
8986 size_t progr_rate,
8987 progress_function * progr_fun)
8988{
8989 int type;
8990 struct mailimap_section_msgtext * section_msgtext;
8991 struct mailimap_section_part * section_part;
8992 struct mailimap_section_text * section_text;
8993 struct mailimap_section_spec * section_spec;
8994 size_t cur_token;
8995 int r;
8996 int res;
8997 size_t final_token;
8998
8999 cur_token = * index;
9000
9001 section_msgtext = NULL;
9002 section_part = NULL;
9003 section_text = NULL;
9004
9005 r = mailimap_section_msgtext_parse(fd, buffer, &cur_token,
9006 &section_msgtext,
9007 progr_rate, progr_fun);
9008 switch (r) {
9009 case MAILIMAP_NO_ERROR:
9010 type = MAILIMAP_SECTION_SPEC_SECTION_MSGTEXT;
9011 break;
9012
9013 case MAILIMAP_ERROR_PARSE:
9014
9015 r = mailimap_section_part_parse(fd, buffer, &cur_token,
9016 &section_part,
9017 progr_rate, progr_fun);
9018 if (r != MAILIMAP_NO_ERROR) {
9019 res = r;
9020 goto err;
9021 }
9022
9023 final_token = cur_token;
9024
9025 type = MAILIMAP_SECTION_SPEC_SECTION_PART;
9026
9027 r = mailimap_dot_parse(fd, buffer, &cur_token);
9028 if (r == MAILIMAP_NO_ERROR) {
9029 r = mailimap_section_text_parse(fd, buffer, &cur_token, &section_text,
9030 progr_rate, progr_fun);
9031 if (r == MAILIMAP_NO_ERROR) {
9032 final_token = cur_token;
9033 }
9034 else if (r != MAILIMAP_ERROR_PARSE) {
9035 res = r;
9036 goto err;
9037 }
9038 }
9039 else if (r != MAILIMAP_ERROR_PARSE) {
9040 res = r;
9041 goto err;
9042 }
9043
9044 cur_token = final_token;
9045 break;
9046
9047 default:
9048 res = r;
9049 goto err;
9050 }
9051
9052 section_spec = mailimap_section_spec_new(type, section_msgtext,
9053 section_part, section_text);
9054 if (section_spec == NULL) {
9055 res = MAILIMAP_ERROR_MEMORY;
9056 goto free;
9057 }
9058
9059 * result = section_spec;
9060 * index = cur_token;
9061
9062 return MAILIMAP_NO_ERROR;
9063
9064 free:
9065 if (section_msgtext)
9066 mailimap_section_msgtext_free(section_msgtext);
9067 if (section_part)
9068 mailimap_section_part_free(section_part);
9069 if (section_text)
9070 mailimap_section_text_free(section_text);
9071 err:
9072 return res;
9073}
9074
9075/*
9076 section-text = section-msgtext / "MIME"
9077 ; text other than actual body part (headers, etc.)
9078*/
9079
9080static int
9081mailimap_section_text_parse(mailstream * fd, MMAPString * buffer,
9082 size_t * index,
9083 struct mailimap_section_text ** result,
9084 size_t progr_rate,
9085 progress_function * progr_fun)
9086{
9087 struct mailimap_section_msgtext * section_msgtext;
9088 size_t cur_token;
9089 struct mailimap_section_text * section_text;
9090 int type;
9091 int r;
9092 int res;
9093
9094 cur_token = * index;
9095
9096 section_msgtext = NULL;
9097
9098 type = MAILIMAP_SECTION_TEXT_ERROR; /* XXX - removes a gcc warning */
9099
9100 r = mailimap_section_msgtext_parse(fd, buffer, &cur_token, &section_msgtext,
9101 progr_rate, progr_fun);
9102 if (r == MAILIMAP_NO_ERROR)
9103 type = MAILIMAP_SECTION_TEXT_SECTION_MSGTEXT;
9104
9105 if (r == MAILIMAP_ERROR_PARSE) {
9106 r= mailimap_token_case_insensitive_parse(fd, buffer, &cur_token, "MIME");
9107
9108 if (r == MAILIMAP_NO_ERROR)
9109 type = MAILIMAP_SECTION_TEXT_MIME;
9110 }
9111
9112 if (r != MAILIMAP_NO_ERROR) {
9113 res = r;
9114 goto err;
9115 }
9116
9117 section_text = mailimap_section_text_new(type, section_msgtext);
9118 if (section_text == NULL) {
9119 res = MAILIMAP_ERROR_MEMORY;
9120 goto free;
9121 }
9122
9123 * result = section_text;
9124 * index = cur_token;
9125
9126 return MAILIMAP_NO_ERROR;
9127
9128 free:
9129 if (section_msgtext)
9130 mailimap_section_msgtext_free(section_msgtext);
9131 err:
9132 return res;
9133}
9134
9135/*
9136 UNIMPLEMENTED
9137 select = "SELECT" SP mailbox
9138*/
9139
9140/*
9141 UNIMPLEMENTED
9142 sequence-num = nz-number / "*"
9143 ; * is the largest number in use. For message
9144 ; sequence numbers, it is the number of messages
9145 ; in the mailbox. For unique identifiers, it is
9146 ; the unique identifier of the last message in
9147 ; the mailbox.
9148*/
9149
9150/*
9151 UNIMPLEMENTED
9152 set = sequence-num / (sequence-num ":" sequence-num) /
9153 (set "," set)
9154 ; Identifies a set of messages. For message
9155 ; sequence numbers, these are consecutive
9156 ; numbers from 1 to the number of messages in
9157 ; the mailbox
9158 ; Comma delimits individual numbers, colon
9159 ; delimits between two numbers inclusive.
9160 ; Example: 2,4:7,9,12:* is 2,4,5,6,7,9,12,13,
9161 ; 14,15 for a mailbox with 15 messages.
9162*/
9163
9164/*
9165 UNIMPLEMENTED
9166 status = "STATUS" SP mailbox SP "(" status-att *(SP status-att) ")"
9167*/
9168
9169/*
9170 status-att = "MESSAGES" / "RECENT" / "UIDNEXT" / "UIDVALIDITY" /
9171 "UNSEEN"
9172*/
9173
9174static int mailimap_status_att_parse(mailstream * fd, MMAPString * buffer,
9175 size_t * index, int * result)
9176{
9177 int type;
9178 size_t cur_token;
9179
9180 cur_token = * index;
9181
9182 type = mailimap_status_att_get_token_value(fd, buffer, &cur_token);
9183
9184 if (type == -1)
9185 return MAILIMAP_ERROR_PARSE;
9186
9187 * result = type;
9188 * index = cur_token;
9189
9190 return MAILIMAP_NO_ERROR;
9191}
9192
9193
9194/*
9195 UNIMPLEMENTED
9196 store = "STORE" SP set SP store-att-flags
9197*/
9198
9199/*
9200 UNIMPLEMENTED
9201 store-att-flags = (["+" / "-"] "FLAGS" [".SILENT"]) SP
9202 (flag-list / (flag *(SP flag)))
9203*/
9204
9205/*
9206 string = quoted / literal
9207*/
9208
9209static int
9210mailimap_string_parse(mailstream * fd, MMAPString * buffer,
9211 size_t * index, char ** result,
9212 size_t * result_len,
9213 size_t progr_rate,
9214 progress_function * progr_fun)
9215{
9216 size_t cur_token;
9217 char * string;
9218 int r;
9219 size_t len;
9220
9221 cur_token = * index;
9222
9223 r = mailimap_quoted_parse(fd, buffer, &cur_token, &string,
9224 progr_rate, progr_fun);
9225 if (r == MAILIMAP_NO_ERROR)
9226 len = strlen(string);
9227 else if (r == MAILIMAP_ERROR_PARSE) {
9228 r = mailimap_literal_parse(fd, buffer, &cur_token, &string, &len,
9229 progr_rate, progr_fun);
9230 }
9231
9232 if (r != MAILIMAP_NO_ERROR)
9233 return r;
9234
9235 * result = string;
9236 if (result_len != NULL)
9237 * result_len = len;
9238 * index = cur_token;
9239
9240 return MAILIMAP_NO_ERROR;
9241}
9242
9243
9244/*
9245 UNIMPLEMENTED
9246 subscribe = "SUBSCRIBE" SP mailbox
9247*/
9248
9249/*
9250 tag = 1*<any ASTRING-CHAR except "+">
9251*/
9252
9253/*
9254 any ASTRING-CHAR except "+"
9255*/
9256
9257static int is_tag_char(char ch)
9258{
9259 if (ch == '+')
9260 return FALSE;
9261 return is_astring_char(ch);
9262}
9263
9264/*
9265 tag = 1*<any ASTRING-CHAR except "+">
9266*/
9267
9268static int mailimap_tag_parse(mailstream * fd, MMAPString * buffer,
9269 size_t * index, char ** result,
9270 size_t progr_rate,
9271 progress_function * progr_fun)
9272{
9273 size_t cur_token;
9274 char * tag;
9275 int r;
9276
9277 cur_token = * index;
9278
9279 r = mailimap_custom_string_parse(fd, buffer, &cur_token, &tag,
9280 is_tag_char);
9281 if (r != MAILIMAP_NO_ERROR)
9282 return r;
9283
9284 * index = cur_token;
9285 * result = tag;
9286
9287 return MAILIMAP_NO_ERROR;
9288}
9289
9290/*
9291 text = 1*TEXT-CHAR
9292*/
9293
9294static int mailimap_text_parse(mailstream * fd, MMAPString * buffer,
9295 size_t * index, char ** result,
9296 size_t progr_rate,
9297 progress_function * progr_fun)
9298{
9299 return mailimap_custom_string_parse(fd, buffer, index, result,
9300 is_text_char);
9301}
9302
9303
9304/*
9305 TEXT-CHAR = <any CHAR except CR and LF>
9306*/
9307
9308static int is_text_char(char ch)
9309{
9310 if ((ch == '\r') || (ch == '\n'))
9311 return FALSE;
9312
9313 return is_char(ch);
9314}
9315
9316/*
9317 time = 2DIGIT ":" 2DIGIT ":" 2DIGIT
9318 ; Hours minutes seconds
9319*/
9320
9321/*
9322 2DIGIT
9323*/
9324
9325static int mailimap_2digit_parse(mailstream * fd, MMAPString * buffer,
9326 size_t * index, int * result)
9327{
9328#ifndef UNSTRICT_SYNTAX
9329 int digit;
9330 int two_digit;
9331 size_t cur_token;
9332 int r;
9333
9334 cur_token = * index;
9335
9336 r = mailimap_digit_parse(fd, buffer, &cur_token, &digit);
9337 if (r != MAILIMAP_NO_ERROR)
9338 return r;
9339
9340 two_digit = digit;
9341
9342 r = mailimap_digit_parse(fd, buffer, &cur_token, &digit);
9343 if (r != MAILIMAP_NO_ERROR)
9344 return r;
9345
9346 two_digit = two_digit * 10 + digit;
9347
9348 * result = two_digit;
9349 * index = cur_token;
9350
9351 return MAILIMAP_NO_ERROR;
9352#else
9353 uint32_t number;
9354 size_t cur_token;
9355 int r;
9356
9357 cur_token = * index;
9358
9359 r = mailimap_number_parse(fd, buffer, &cur_token, &number);
9360 if (r != MAILIMAP_NO_ERROR)
9361 return r;
9362
9363 * index = cur_token;
9364 * result = number;
9365
9366 return MAILIMAP_NO_ERROR;
9367#endif
9368}
9369
9370/*
9371 time = 2DIGIT ":" 2DIGIT ":" 2DIGIT
9372 ; Hours minutes seconds
9373*/
9374
9375static int mailimap_time_parse(mailstream * fd, MMAPString * buffer,
9376 size_t * index,
9377 int * phour, int * pmin, int * psec)
9378{
9379 size_t cur_token;
9380 int hour;
9381 int min;
9382 int sec;
9383 int r;
9384
9385 cur_token = * index;
9386
9387 r = mailimap_2digit_parse(fd, buffer, &cur_token, &hour);
9388 if (r != MAILIMAP_NO_ERROR)
9389 return r;
9390
9391 r = mailimap_colon_parse(fd, buffer, &cur_token);
9392 if (r != MAILIMAP_NO_ERROR)
9393 return r;
9394
9395 r = mailimap_2digit_parse(fd, buffer, &cur_token, &min);
9396 if (r != MAILIMAP_NO_ERROR)
9397 return r;
9398
9399 r = mailimap_colon_parse(fd, buffer, &cur_token);
9400 if (r != MAILIMAP_NO_ERROR)
9401 return r;
9402
9403 r = mailimap_2digit_parse(fd, buffer, &cur_token, &sec);
9404 if (r != MAILIMAP_NO_ERROR)
9405 return r;
9406
9407 * phour = hour;
9408 * pmin = min;
9409 * psec = sec;
9410 * index = cur_token;
9411
9412 return MAILIMAP_NO_ERROR;
9413}
9414
9415/*
9416 UNIMPLEMENTED
9417 uid = "UID" SP (copy / fetch / search / store)
9418 ; Unique identifiers used instead of message
9419 ; sequence numbers
9420*/
9421
9422/*
9423 uniqueid = nz-number
9424 ; Strictly ascending
9425*/
9426
9427static int mailimap_uniqueid_parse(mailstream * fd, MMAPString * buffer,
9428 size_t * index, uint32_t * result)
9429{
9430 return mailimap_nz_number_parse(fd, buffer, index, result);
9431}
9432
9433/*
9434 UNIMPLEMENTED
9435 unsubscribe = "UNSUBSCRIBE" SP mailbox
9436*/
9437
9438/*
9439 UNIMPLEMENTED
9440 userid = astring
9441*/
9442
9443/*
9444 UNIMPLEMENTED
9445 x-command = "X" atom <experimental command arguments>
9446*/
9447
9448/*
9449 zone = ("+" / "-") 4DIGIT
9450 ; Signed four-digit value of hhmm representing
9451 ; hours and minutes east of Greenwich (that is,
9452 ; the amount that the given time differs from
9453 ; Universal Time). Subtracting the timezone
9454 ; from the given time will give the UT form.
9455 ; The Universal Time zone is "+0000".
9456*/
9457
9458static int mailimap_zone_parse(mailstream * fd, MMAPString * buffer,
9459 size_t * index, int * result)
9460{
9461 size_t cur_token;
9462 uint32_t zone;
9463#ifndef UNSTRICT_SYNTAX
9464 int i;
9465 int digit;
9466#endif
9467 int sign;
9468 int r;
9469
9470 cur_token = * index;
9471
9472 sign = 1;
9473 r = mailimap_plus_parse(fd, buffer, &cur_token);
9474 if (r == MAILIMAP_NO_ERROR)
9475 sign = 1;
9476
9477 if (r == MAILIMAP_ERROR_PARSE) {
9478 r = mailimap_minus_parse(fd, buffer, &cur_token);
9479 if (r == MAILIMAP_NO_ERROR)
9480 sign = -1;
9481 }
9482
9483 if (r != MAILIMAP_NO_ERROR)
9484 return r;
9485
9486#ifdef UNSTRICT_SYNTAX
9487 r = mailimap_number_parse(fd, buffer, &cur_token, &zone);
9488 if (r != MAILIMAP_NO_ERROR)
9489 return r;
9490#else
9491 zone = 0;
9492 for(i = 0 ; i < 4 ; i ++) {
9493 r = mailimap_digit_parse(fd, buffer, &cur_token, &digit);
9494 if (r != MAILIMAP_NO_ERROR)
9495 return r;
9496 zone = zone * 10 + digit;
9497 }
9498#endif
9499
9500 zone *= sign;
9501
9502 * result = zone;
9503 * index = cur_token;
9504
9505 return MAILIMAP_NO_ERROR;
9506}
diff --git a/libetpan/src/low-level/imap/mailimap_parser.h b/libetpan/src/low-level/imap/mailimap_parser.h
new file mode 100644
index 0000000..e20a310
--- a/dev/null
+++ b/libetpan/src/low-level/imap/mailimap_parser.h
@@ -0,0 +1,69 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILIMAP_PARSER_H
37
38#define MAILIMAP_PARSER_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include "mailimap_types.h"
45
46int mailimap_greeting_parse(mailstream * fd, MMAPString * buffer,
47 size_t * index,
48 struct mailimap_greeting ** result,
49 size_t progr_rate,
50 progress_function * progr_fun);
51
52int
53mailimap_response_parse(mailstream * fd, MMAPString * buffer,
54 size_t * index, struct mailimap_response ** result,
55 size_t progr_rate,
56 progress_function * progr_fun);
57
58int
59mailimap_continue_req_parse(mailstream * fd, MMAPString * buffer,
60 size_t * index,
61 struct mailimap_continue_req ** result,
62 size_t progr_rate,
63 progress_function * progr_fun);
64
65#ifdef __cplusplus
66}
67#endif
68
69#endif
diff --git a/libetpan/src/low-level/imap/mailimap_print.c b/libetpan/src/low-level/imap/mailimap_print.c
new file mode 100644
index 0000000..005cf09
--- a/dev/null
+++ b/libetpan/src/low-level/imap/mailimap_print.c
@@ -0,0 +1,1615 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35#ifdef DEBUG
36#include "mailimap_print.h"
37
38#include <stdio.h>
39
40static void mailimap_body_fields_print(struct mailimap_body_fields *
41 body_fields);
42static void mailimap_envelope_print(struct mailimap_envelope * env);
43static void mailimap_body_print(struct mailimap_body * body);
44static void mailimap_body_fld_enc_print(struct mailimap_body_fld_enc *
45 fld_enc);
46
47static int indent_size = 0;
48
49static void indent()
50{
51 indent_size ++;
52}
53
54static void unindent()
55{
56 indent_size --;
57}
58
59static void print_indent()
60{
61 int i;
62
63 for (i = 0 ; i < indent_size ; i++)
64 printf(" ");
65}
66
67
68static void mailimap_body_fld_lang_print(struct mailimap_body_fld_lang *
69 fld_lang)
70{
71 clistiter * cur;
72
73 print_indent();
74 printf("body-fld-lang { ");
75
76 switch (fld_lang->lg_type) {
77 case MAILIMAP_BODY_FLD_LANG_SINGLE:
78 printf("%s ", fld_lang->lg_data.lg_single);
79 break;
80
81 case MAILIMAP_BODY_FLD_LANG_LIST:
82 for(cur = clist_begin(fld_lang->lg_data.lg_list) ;
83 cur != NULL ; cur = clist_next(cur)) {
84 char * lang;
85
86 lang = clist_content(cur);
87
88 printf("%s ", lang);
89 }
90 break;
91 }
92
93 print_indent();
94 printf("}\n");
95}
96
97static void
98mailimap_single_body_fld_param_print(struct mailimap_single_body_fld_param *
99 single)
100{
101 printf("(%s = %s)", single->pa_name, single->pa_value);
102}
103
104static void mailimap_body_fld_param_print(struct mailimap_body_fld_param *
105 fld_param)
106{
107 clistiter * cur;
108
109 print_indent();
110 printf("body-fld-param { ");
111
112 for(cur = clist_begin(fld_param->pa_list) ; cur != NULL ;
113 cur = clist_next(cur)) {
114 struct mailimap_single_body_fld_param * single;
115
116 single = clist_content(cur);
117
118 mailimap_single_body_fld_param_print(single);
119 printf(" ");
120 }
121 printf("\n");
122}
123
124static void mailimap_body_fld_dsp_print(struct mailimap_body_fld_dsp * fld_dsp)
125{
126 print_indent();
127 printf("body-fld-dsp {\n");
128 indent();
129
130 print_indent();
131 printf("name { %s }\n", fld_dsp->dsp_type);
132
133 mailimap_body_fld_param_print(fld_dsp->dsp_attributes);
134
135 unindent();
136 print_indent();
137 printf("}\n");
138}
139
140static void mailimap_body_extension_list_print(clist * ext_list);
141
142static void mailimap_body_extension_print(struct mailimap_body_extension * ext)
143{
144 print_indent();
145 printf("body-extention {\n");
146 indent();
147
148 switch (ext->ext_type) {
149 case MAILIMAP_BODY_EXTENSION_NSTRING:
150 print_indent();
151 printf("%s\n", ext->ext_data.ext_nstring);
152 break;
153 case MAILIMAP_BODY_EXTENSION_NUMBER:
154 print_indent();
155 printf("%i\n", ext->ext_data.ext_number);
156 break;
157 case MAILIMAP_BODY_EXTENSION_LIST:
158 mailimap_body_extension_list_print(ext->ext_data.ext_body_extension_list);
159 break;
160 }
161
162 unindent();
163 print_indent();
164 printf("}\n");
165
166}
167
168static void mailimap_body_extension_list_print(clist * ext_list)
169{
170 clistiter * cur;
171
172 print_indent();
173 printf("body-extention-list {\n");
174 indent();
175
176 for (cur = clist_begin(ext_list) ; cur != NULL ;
177 cur = clist_next(cur)) {
178 struct mailimap_body_extension * ext;
179
180 ext = clist_content(cur);
181
182 mailimap_body_extension_print(ext);
183 }
184
185 unindent();
186 print_indent();
187 printf("}");
188}
189
190static void mailimap_body_ext_1part_print(struct mailimap_body_ext_1part *
191 body_ext_1part)
192{
193 print_indent();
194 printf("body-type-1part {\n");
195 indent();
196
197 print_indent();
198 printf("md5 { %s }\n", body_ext_1part->bd_md5);
199 if (body_ext_1part->bd_disposition) {
200 mailimap_body_fld_dsp_print(body_ext_1part->bd_disposition);
201 if (body_ext_1part->bd_language) {
202 mailimap_body_fld_lang_print(body_ext_1part->bd_language);
203
204 if (body_ext_1part->bd_extension_list)
205 mailimap_body_extension_list_print(body_ext_1part->bd_extension_list);
206 }
207 }
208
209 unindent();
210 print_indent();
211 printf("}\n");
212}
213
214static void mailimap_body_type_text_print(struct mailimap_body_type_text *
215 body_type_text)
216{
217 print_indent();
218 printf("body-type-text {\n");
219 indent();
220
221 print_indent();
222 printf("media-text { %s }\n", body_type_text->bd_media_text);
223 mailimap_body_fields_print(body_type_text->bd_fields);
224 print_indent();
225 printf("lines { %i }\n", body_type_text->bd_lines);
226
227 unindent();
228 print_indent();
229 printf("}\n");
230}
231
232static void mailimap_body_type_msg_print(struct mailimap_body_type_msg *
233 body_type_msg)
234{
235 print_indent();
236 printf("body-type-msg {\n");
237 indent();
238
239 mailimap_body_fields_print(body_type_msg->bd_fields);
240 mailimap_envelope_print(body_type_msg->bd_envelope);
241 mailimap_body_print(body_type_msg->bd_body);
242
243 print_indent();
244 printf("lines { %i }\n", body_type_msg->bd_lines);
245
246 unindent();
247 print_indent();
248 printf("}\n");
249}
250
251
252static void mailimap_body_fld_enc_print(struct mailimap_body_fld_enc * fld_enc)
253{
254 print_indent();
255 printf("body-fld-enc { ");
256
257 switch (fld_enc->enc_type) {
258 case MAILIMAP_BODY_FLD_ENC_7BIT:
259 print_indent();
260 printf("7bit");
261 break;
262 case MAILIMAP_BODY_FLD_ENC_8BIT:
263 printf("8bit");
264 break;
265 case MAILIMAP_BODY_FLD_ENC_BINARY:
266 printf("binary");
267 break;
268 case MAILIMAP_BODY_FLD_ENC_BASE64:
269 printf("base64");
270 break;
271 case MAILIMAP_BODY_FLD_ENC_QUOTED_PRINTABLE:
272 printf("quoted-printable");
273 break;
274 case MAILIMAP_BODY_FLD_ENC_OTHER:
275 printf("%s", fld_enc->enc_value);
276 break;
277 }
278
279 printf("}\n");
280}
281
282static void mailimap_body_fields_print(struct mailimap_body_fields *
283 body_fields)
284{
285 print_indent();
286 printf("body-fields {\n");
287 indent();
288
289 mailimap_body_fld_param_print(body_fields->bd_parameter);
290
291 print_indent();
292 printf("body-fld-id { %s }\n", body_fields->bd_id);
293 printf("body-fld-desc { %s }\n", body_fields->bd_description);
294 mailimap_body_fld_enc_print(body_fields->bd_encoding);
295 printf("body-fld-octets { %i }\n", body_fields->bd_size);
296
297 unindent();
298 print_indent();
299 printf("}\n");
300}
301
302static void mailimap_media_basic_print(struct mailimap_media_basic *
303 media_basic)
304{
305 print_indent();
306 printf("media-basic {");
307
308 switch (media_basic->med_type) {
309 case MAILIMAP_MEDIA_BASIC_APPLICATION:
310 printf("application");
311 break;
312 case MAILIMAP_MEDIA_BASIC_AUDIO:
313 printf("audio");
314 break;
315 case MAILIMAP_MEDIA_BASIC_IMAGE:
316 printf("image");
317 break;
318 case MAILIMAP_MEDIA_BASIC_MESSAGE:
319 printf("message");
320 break;
321 case MAILIMAP_MEDIA_BASIC_VIDEO:
322 printf("video");
323 break;
324 case MAILIMAP_MEDIA_BASIC_OTHER:
325 printf("%s", media_basic->med_basic_type);
326 break;
327 }
328 printf(" / %s }\n", media_basic->med_subtype);
329}
330
331static void mailimap_body_type_basic_print(struct mailimap_body_type_basic *
332 body_type_basic)
333{
334 print_indent();
335 printf("body-type-basic {\n");
336 indent();
337
338 mailimap_media_basic_print(body_type_basic->bd_media_basic);
339 mailimap_body_fields_print(body_type_basic->bd_fields);
340
341 unindent();
342 print_indent();
343 printf("}\n");
344}
345
346static void mailimap_body_type_1part_print(struct mailimap_body_type_1part *
347 body_type_1part)
348{
349 print_indent();
350 printf("body-type-1part {\n");
351 indent();
352
353 switch (body_type_1part->bd_type) {
354 case MAILIMAP_BODY_TYPE_1PART_BASIC:
355 mailimap_body_type_basic_print(body_type_1part->bd_data.bd_type_basic);
356 break;
357
358 case MAILIMAP_BODY_TYPE_1PART_MSG:
359 mailimap_body_type_msg_print(body_type_1part->bd_data.bd_type_msg);
360 break;
361
362 case MAILIMAP_BODY_TYPE_1PART_TEXT:
363 mailimap_body_type_text_print(body_type_1part->bd_data.bd_type_text);
364 break;
365 }
366
367 if (body_type_1part->bd_ext_1part != NULL)
368 mailimap_body_ext_1part_print(body_type_1part->bd_ext_1part);
369
370 unindent();
371 print_indent();
372 printf("\n");
373}
374
375static void mailimap_body_ext_mpart(struct mailimap_body_ext_mpart * ext_mpart)
376{
377 print_indent();
378 printf("body-ext-mpart {\n");
379 indent();
380
381 mailimap_body_fld_param_print(ext_mpart->bd_parameter);
382 if (ext_mpart->bd_disposition) {
383 mailimap_body_fld_dsp_print(ext_mpart->bd_disposition);
384 if (ext_mpart->bd_language) {
385 mailimap_body_fld_lang_print(ext_mpart->bd_language);
386
387 if (ext_mpart->bd_extension_list)
388 mailimap_body_extension_list_print(ext_mpart->bd_extension_list);
389 }
390 }
391
392 unindent();
393 print_indent();
394 printf("\n");
395}
396
397static void mailimap_body_type_mpart_print(struct mailimap_body_type_mpart *
398 mpart)
399{
400 clistiter * cur;
401
402 print_indent();
403 printf("body-type-mpart {\n");
404 indent();
405
406 for(cur = clist_begin(mpart->bd_list) ; cur != NULL ;
407 cur = clist_next(cur)) {
408 struct mailimap_body * body;
409
410 body = clist_content(cur);
411
412 mailimap_body_print(body);
413 }
414
415 printf("media-subtype { %s }\n", mpart->bd_media_subtype);
416
417 if (mpart->bd_ext_mpart)
418 mailimap_body_ext_mpart(mpart->bd_ext_mpart);
419
420 unindent();
421 print_indent();
422 printf("}\n");
423}
424
425
426static void mailimap_body_print(struct mailimap_body * body)
427{
428 print_indent();
429 printf("body {\n");
430 indent();
431
432 switch (body->bd_type) {
433 case MAILIMAP_BODY_1PART:
434 mailimap_body_type_1part_print(body->bd_data.bd_body_1part);
435 break;
436 case MAILIMAP_BODY_MPART:
437 mailimap_body_type_mpart_print(body->bd_data.bd_body_mpart);
438 break;
439 }
440
441 unindent();
442 print_indent();
443 printf("}\n");
444}
445
446static void mailimap_date_time_print(struct mailimap_date_time * date_time)
447{
448 print_indent();
449 printf("date-time { %i/%i/%i - %i:%i:%i %i }\n",
450 date_time->dt_day, date_time->dt_month, date_time->dt_year,
451 date_time->dt_hour, date_time->dt_min, date_time->dt_month,
452 date_time->dt_zone);
453}
454
455static void mailimap_address_print(struct mailimap_address * address)
456{
457 print_indent();
458 printf("address { name: %s, addr: %s, mailbox: %s, host: %s) }\n",
459 address->ad_personal_name, address->ad_source_route,
460 address->ad_mailbox_name, address->ad_host_name);
461}
462
463static void mailimap_envelope_address_list_print(clist * address)
464{
465 clistiter * cur;
466
467 print_indent();
468 printf("envelope-address-list {\n");
469 indent();
470
471 for(cur = clist_begin(address) ; cur != NULL ;
472 cur = clist_next(cur)) {
473 struct mailimap_address * addr;
474
475 addr = clist_content(cur);
476
477 mailimap_address_print(addr);
478 }
479
480 unindent();
481 print_indent();
482 printf("}\n");
483}
484
485static void mailimap_envelope_print(struct mailimap_envelope * env)
486{
487 print_indent();
488 printf("envelope {\n");
489 indent();
490
491 print_indent();
492 printf("date { %s }\n", env->env_date);
493
494 print_indent();
495 printf("subject { %s }\n", env->env_subject);
496
497 print_indent();
498 printf("from {\n");
499 indent();
500 mailimap_envelope_address_list_print(env->env_from->frm_list);
501 unindent();
502 print_indent();
503 printf("}\n");
504
505 print_indent();
506 printf("sender {\n");
507 indent();
508 mailimap_envelope_address_list_print(env->env_sender->snd_list);
509 unindent();
510 print_indent();
511 printf("}\n");
512
513 print_indent();
514 printf("reply-to {\n");
515 indent();
516 mailimap_envelope_address_list_print(env->env_reply_to->rt_list);
517 unindent();
518 print_indent();
519 printf("}\n");
520
521 print_indent();
522 printf("to {\n");
523 indent();
524 mailimap_envelope_address_list_print(env->env_to->to_list);
525 unindent();
526 print_indent();
527 printf("}\n");
528
529 print_indent();
530 printf("cc {\n");
531 indent();
532 mailimap_envelope_address_list_print(env->env_cc->cc_list);
533 unindent();
534 print_indent();
535 printf("}\n");
536
537 print_indent();
538 printf("bcc {\n");
539 indent();
540 mailimap_envelope_address_list_print(env->env_bcc->bcc_list);
541 unindent();
542 print_indent();
543 printf("}\n");
544
545 printf("in-reply-to { %s }\n", env->env_in_reply_to);
546 printf("message-id { %s }\n", env->env_message_id);
547
548 unindent();
549 print_indent();
550 printf("}\n");
551}
552
553static void mailimap_header_list_print(struct mailimap_header_list *
554 header_list)
555{
556 clistiter * cur;
557
558 print_indent();
559 printf("header-list { ");
560 for(cur = clist_begin(header_list->hdr_list) ; cur != NULL ;
561 cur = clist_next(cur))
562 printf("%s ", (char *) clist_content(cur));
563 printf("}\n");
564}
565
566static void mailimap_section_msgtext_print(struct mailimap_section_msgtext *
567 section_msgtext)
568{
569 print_indent();
570 printf("section-msgtext {\n");
571 indent();
572
573 switch(section_msgtext->sec_type) {
574 case MAILIMAP_SECTION_MSGTEXT_HEADER:
575 print_indent();
576 printf("header\n");
577 break;
578
579 case MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS:
580 print_indent();
581 printf("header fields {");
582 indent();
583 mailimap_header_list_print(section_msgtext->sec_header_list);
584 unindent();
585 print_indent();
586 printf("}\n");
587 break;
588
589 case MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS_NOT:
590 print_indent();
591 printf("header fields not {");
592 indent();
593 mailimap_header_list_print(section_msgtext->sec_header_list);
594 unindent();
595 print_indent();
596 printf("}\n");
597 break;
598
599 case MAILIMAP_SECTION_MSGTEXT_TEXT:
600 print_indent();
601 printf("text\n");
602 break;
603 }
604
605 unindent();
606 print_indent();
607 printf("}\n");
608}
609
610static void mailimap_section_part_print(struct mailimap_section_part *
611 section_part)
612{
613 clistiter * cur;
614
615 print_indent();
616 printf("section-part { ");
617
618 for(cur = clist_begin(section_part->sec_id) ;
619 cur != NULL ; cur = clist_next(cur)) {
620 printf("%i", * ((uint32_t *) clist_content(cur)));
621 if (clist_next(cur) != NULL)
622 printf(".");
623 }
624 printf(" }\n");
625}
626
627static void mailimap_section_text_print(struct mailimap_section_text *
628 section_text)
629{
630 print_indent();
631 printf("section-text {\n");
632 indent();
633
634 switch (section_text->sec_type) {
635 case MAILIMAP_SECTION_TEXT_MIME:
636 print_indent();
637 printf("MIME");
638 break;
639 case MAILIMAP_SECTION_TEXT_SECTION_MSGTEXT:
640 mailimap_section_msgtext_print(section_text->sec_msgtext);
641 break;
642 }
643
644 unindent();
645 print_indent();
646 printf("}\n");
647}
648
649static void mailimap_section_spec_print(struct mailimap_section_spec *
650 section_spec)
651{
652 print_indent();
653 printf("section-spec {");
654 indent();
655
656 switch(section_spec->sec_type) {
657 case MAILIMAP_SECTION_SPEC_SECTION_MSGTEXT:
658 mailimap_section_msgtext_print(section_spec->sec_data.sec_msgtext);
659 break;
660 case MAILIMAP_SECTION_SPEC_SECTION_PART:
661 mailimap_section_part_print(section_spec->sec_data.sec_part);
662 if (section_spec->sec_text != NULL)
663 mailimap_section_text_print(section_spec->sec_text);
664 break;
665 }
666
667 unindent();
668 print_indent();
669 printf("}\n");
670}
671
672static void mailimap_section_print(struct mailimap_section * section)
673{
674 print_indent();
675 printf("section {\n");
676 indent();
677
678 if (section != NULL)
679 if (section->sec_spec != NULL)
680 mailimap_section_spec_print(section->sec_spec);
681
682 unindent();
683 print_indent();
684 printf("}\n");
685}
686
687static void mailimap_msg_att_body_section_print(struct
688 mailimap_msg_att_body_section *
689 msg_att_body_section)
690{
691 print_indent();
692 printf("msg-att-body-section {\n");
693 indent();
694
695 mailimap_section_print(msg_att_body_section->sec_section);
696 printf("origin-octet: %i\n", msg_att_body_section->sec_origin_octet);
697 printf("body-part: %s\n", msg_att_body_section->sec_body_part);
698
699 unindent();
700 print_indent();
701 printf("}\n");
702}
703
704
705static void mailimap_msg_att_static_print(struct mailimap_msg_att_static *
706 msg_att_static)
707{
708 print_indent();
709 printf("msg-att-static {\n");
710 indent();
711
712 switch (msg_att_static->att_type) {
713
714 case MAILIMAP_MSG_ATT_ENVELOPE:
715 print_indent();
716 printf("envelope {\n");
717 indent();
718 print_indent();
719 mailimap_envelope_print(msg_att_static->att_data.att_env);
720 unindent();
721 print_indent();
722 printf("}\n");
723 break;
724
725 case MAILIMAP_MSG_ATT_INTERNALDATE:
726 print_indent();
727 printf("internaldate {\n");
728 indent();
729 print_indent();
730 mailimap_date_time_print(msg_att_static->att_data.att_internal_date);
731 unindent();
732 print_indent();
733 printf("}\n");
734 break;
735
736 case MAILIMAP_MSG_ATT_RFC822:
737 print_indent();
738 printf("rfc822 {\n");
739 printf("%s\n", msg_att_static->att_data.att_rfc822.att_content);
740 print_indent();
741 printf("}\n");
742 break;
743
744 case MAILIMAP_MSG_ATT_RFC822_HEADER:
745 print_indent();
746 printf("rfc822-header {\n");
747 printf("%s\n", msg_att_static->att_data.att_rfc822_header.att_content);
748 print_indent();
749 printf("}\n");
750 break;
751
752 case MAILIMAP_MSG_ATT_RFC822_TEXT:
753 print_indent();
754 printf("rfc822-text {\n");
755 printf("%s\n", msg_att_static->att_data.att_rfc822_text.att_content);
756 print_indent();
757 printf("}\n");
758 break;
759
760 case MAILIMAP_MSG_ATT_RFC822_SIZE:
761 print_indent();
762 printf("rfc822-size { %i }\n", msg_att_static->att_data.att_rfc822_size);
763 break;
764
765 case MAILIMAP_MSG_ATT_BODY:
766 print_indent();
767 printf("body {\n");
768 indent();
769 print_indent();
770 mailimap_body_print(msg_att_static->att_data.att_body);
771 unindent();
772 print_indent();
773 printf("}\n");
774 break;
775
776 case MAILIMAP_MSG_ATT_BODYSTRUCTURE:
777 print_indent();
778 printf("bodystructure {\n");
779 indent();
780 print_indent();
781 mailimap_body_print(msg_att_static->att_data.att_bodystructure);
782 unindent();
783 print_indent();
784 printf("}\n");
785 break;
786
787 case MAILIMAP_MSG_ATT_BODY_SECTION:
788 print_indent();
789 printf("body-section {\n");
790 indent();
791 print_indent();
792 mailimap_msg_att_body_section_print(msg_att_static->att_data.att_body_section);
793 unindent();
794 print_indent();
795 printf("}\n");
796 break;
797
798 case MAILIMAP_MSG_ATT_UID:
799 printf("uid { %i }\n", msg_att_static->att_data.att_uid);
800 break;
801 }
802
803 unindent();
804 print_indent();
805 printf("}\n");
806}
807
808static void mailimap_flag_print(struct mailimap_flag * flag);
809
810static void mailimap_flag_fetch_print(struct mailimap_flag_fetch * flag)
811{
812 print_indent();
813 printf("flag fetch {\n");
814 indent();
815
816 switch (flag->fl_type) {
817 case MAILIMAP_FLAG_FETCH_RECENT:
818 printf("recent\n");
819 break;
820 case MAILIMAP_FLAG_FETCH_OTHER:
821 print_indent();
822 printf("flag {\n");
823 indent();
824 mailimap_flag_print(flag->fl_flag);
825 unindent();
826 print_indent();
827 printf("}\n");
828 break;
829 }
830
831 unindent();
832 print_indent();
833 printf("}\n");
834}
835
836static void mailimap_msg_att_dynamic_print(struct mailimap_msg_att_dynamic *
837 dynamic)
838{
839 clistiter * cur;
840
841 print_indent();
842 printf("msg-att-dynamic {\n");
843 indent();
844
845 for(cur = clist_begin(dynamic->att_list) ; cur != NULL ;
846 cur = clist_next(cur)) {
847 struct mailimap_flag_fetch * flag;
848
849 flag = (struct mailimap_flag_fetch *) clist_content(cur);
850 mailimap_flag_fetch_print(flag);
851 }
852
853 unindent();
854 print_indent();
855 printf("}\n");
856}
857
858static void mailimap_msg_att_item_print(struct mailimap_msg_att_item * item)
859{
860 print_indent();
861 printf("msg-att-item {\n");
862 indent();
863
864 switch (item->att_type) {
865 case MAILIMAP_MSG_ATT_ITEM_DYNAMIC:
866 mailimap_msg_att_dynamic_print(item->att_data.att_dyn);
867 break;
868 case MAILIMAP_MSG_ATT_ITEM_STATIC:
869 mailimap_msg_att_static_print(item->att_data.att_static);
870 break;
871 }
872
873 unindent();
874 print_indent();
875 printf("}\n");
876}
877
878static void mailimap_msg_att_print(struct mailimap_msg_att * msg_att)
879{
880 clistiter * cur;
881
882 print_indent();
883 printf("msg-att {\n");
884 indent();
885
886 for(cur = clist_begin(msg_att->att_list) ; cur != NULL ;
887 cur = clist_next(cur)) {
888 struct mailimap_msg_att_item * item;
889
890 item = clist_content(cur);
891
892 mailimap_msg_att_item_print(item);
893 }
894
895 unindent();
896 print_indent();
897 printf("}\n");
898}
899
900static void mailimap_message_data_print(struct mailimap_message_data *
901 msg_data)
902{
903 print_indent();
904 printf("message-data {\n");
905 indent();
906
907 switch (msg_data->mdt_type) {
908 case MAILIMAP_MESSAGE_DATA_EXPUNGE:
909 print_indent();
910 printf("expunged { %i }\n", msg_data->mdt_number);
911 break;
912 case MAILIMAP_MESSAGE_DATA_FETCH:
913 print_indent();
914 printf("message-number { %i }\n", msg_data->mdt_number);
915 mailimap_msg_att_print(msg_data->mdt_msg_att);
916 break;
917 }
918
919 unindent();
920 print_indent();
921 printf("}\n");
922}
923
924static void mailimap_status_att_print(int status_att)
925{
926 print_indent();
927 printf("status-att { ");
928
929 switch(status_att) {
930 case MAILIMAP_STATUS_ATT_MESSAGES:
931 printf("messages");
932 break;
933 case MAILIMAP_STATUS_ATT_RECENT:
934 printf("recent");
935 break;
936 case MAILIMAP_STATUS_ATT_UIDNEXT:
937 printf("uidnext");
938 break;
939 case MAILIMAP_STATUS_ATT_UIDVALIDITY:
940 printf("status att uidvalidity");
941 break;
942 case MAILIMAP_STATUS_ATT_UNSEEN:
943 printf("status att unseen");
944 break;
945 }
946
947 printf(" \n");
948}
949
950static void
951mailimap_status_info_print(struct mailimap_status_info * info)
952{
953 print_indent();
954 printf("status-info {\n");
955 indent();
956
957 mailimap_status_att_print(info->st_att);
958
959 print_indent();
960 printf("value { %i }\n", info->st_value);
961
962 unindent();
963 print_indent();
964 printf("}\n");
965}
966
967static void
968mailimap_mailbox_data_status_print(struct mailimap_mailbox_data_status *
969 mb_data_status)
970{
971 clistiter * cur;
972
973 print_indent();
974 printf("mailbox-data-status {\n");
975 indent();
976
977 print_indent();
978 printf("mailbox { %s }\n", mb_data_status->st_mailbox);
979
980 for(cur = clist_begin(mb_data_status->st_info_list) ;
981 cur != NULL ; cur = clist_next(cur)) {
982 struct mailimap_status_info * info;
983
984 info = clist_content(cur);
985
986 mailimap_status_info_print(info);
987 }
988
989 unindent();
990 print_indent();
991 printf("}\n");
992}
993
994static void mailimap_mbx_list_oflag_print(struct mailimap_mbx_list_oflag *
995 oflag)
996{
997 print_indent();
998 printf("mbx-list-oflag { ");
999
1000 switch (oflag->of_type) {
1001 case MAILIMAP_MBX_LIST_OFLAG_NOINFERIORS:
1002 printf("noinferiors");
1003 break;
1004 case MAILIMAP_MBX_LIST_OFLAG_FLAG_EXT:
1005 printf("%s", oflag->of_flag_ext);
1006 break;
1007 }
1008
1009 printf(" }\n");
1010}
1011
1012static void mailimap_mbx_list_sflag_print(int sflag)
1013{
1014 print_indent();
1015 printf("mbx-list-sflag { ");
1016
1017 switch (sflag) {
1018 case MAILIMAP_MBX_LIST_SFLAG_MARKED:
1019 printf("marked");
1020 break;
1021 case MAILIMAP_MBX_LIST_SFLAG_NOSELECT:
1022 printf("noselected");
1023 break;
1024 case MAILIMAP_MBX_LIST_SFLAG_UNMARKED:
1025 printf("unmarked");
1026 break;
1027 }
1028
1029 printf(" }\n");
1030}
1031
1032static void mailimap_mbx_list_flags_print(struct mailimap_mbx_list_flags *
1033 mbx_list_flags)
1034{
1035 clistiter * cur;
1036
1037 print_indent();
1038 printf("mbx-list-flags {");
1039 indent();
1040
1041 if (mbx_list_flags->mbf_type == MAILIMAP_MBX_LIST_FLAGS_SFLAG)
1042 mailimap_mbx_list_sflag_print(mbx_list_flags->mbf_sflag);
1043
1044 for(cur = clist_begin(mbx_list_flags->mbf_oflags) ; cur != NULL ;
1045 cur = clist_next(cur)) {
1046 struct mailimap_mbx_list_oflag * oflag;
1047
1048 oflag = clist_content(cur);
1049
1050 mailimap_mbx_list_oflag_print(oflag);
1051 }
1052
1053 unindent();
1054 print_indent();
1055 printf("}\n");
1056}
1057
1058static void mailimap_mailbox_list_print(struct mailimap_mailbox_list * mb_list)
1059{
1060 print_indent();
1061 printf("mailbox-list {\n");
1062 indent();
1063
1064 mailimap_mbx_list_flags_print(mb_list->mb_flag);
1065 printf("dir-separator { %c }\n", mb_list->mb_delimiter);
1066 printf("mailbox { %s }\n", mb_list->mb_name);
1067
1068 unindent();
1069 print_indent();
1070 printf("}\n");
1071}
1072
1073static void mailimap_flag_list_print(struct mailimap_flag_list * flag_list)
1074{
1075 clistiter * cur;
1076
1077 print_indent();
1078 printf("flag-list {\n");
1079 indent();
1080
1081 for(cur = clist_begin(flag_list->fl_list) ; cur != NULL ;
1082 cur = clist_next(cur)) {
1083 struct mailimap_flag * flag;
1084
1085 flag = clist_content(cur);
1086
1087 print_indent();
1088 mailimap_flag_print(flag);
1089 printf("\n");
1090 }
1091
1092 unindent();
1093 print_indent();
1094 printf("}\n");
1095}
1096
1097
1098static void mailimap_mailbox_data_print(struct mailimap_mailbox_data * mb_data)
1099{
1100 clistiter * cur;
1101
1102 print_indent();
1103 printf("mailbox-data {\n");
1104 indent();
1105
1106 switch (mb_data->mbd_type) {
1107 case MAILIMAP_MAILBOX_DATA_FLAGS:
1108 print_indent();
1109 printf("flags {\n");
1110 indent();
1111 mailimap_flag_list_print(mb_data->mbd_data.mbd_flags);
1112 unindent();
1113 print_indent();
1114 printf("}\n");
1115 break;
1116
1117 case MAILIMAP_MAILBOX_DATA_LIST:
1118 print_indent();
1119 printf("list {\n");
1120 indent();
1121 mailimap_mailbox_list_print(mb_data->mbd_data.mbd_list);
1122 unindent();
1123 print_indent();
1124 printf("}\n");
1125 break;
1126
1127 case MAILIMAP_MAILBOX_DATA_LSUB:
1128 print_indent();
1129 printf("lsub {\n");
1130 indent();
1131 mailimap_mailbox_list_print(mb_data->mbd_data.mbd_lsub);
1132 unindent();
1133 print_indent();
1134 printf("}\n");
1135 break;
1136
1137 case MAILIMAP_MAILBOX_DATA_SEARCH:
1138 print_indent();
1139 printf("search { ");
1140 for(cur = clist_begin(mb_data->mbd_data.mbd_search) ;
1141 cur != NULL ; cur = clist_next(cur)) {
1142 uint32_t * id;
1143
1144 id = clist_content(cur);
1145 printf("%i ", * id);
1146 }
1147 printf(" }\n");
1148 break;
1149
1150 case MAILIMAP_MAILBOX_DATA_STATUS:
1151 print_indent();
1152 printf("status {\n");
1153 indent();
1154 mailimap_mailbox_data_status_print(mb_data->mbd_data.mbd_status);
1155 unindent();
1156 print_indent();
1157 printf("}\n");
1158 break;
1159
1160 case MAILIMAP_MAILBOX_DATA_EXISTS:
1161 print_indent();
1162 printf("exists { %i }\n", mb_data->mbd_data.mbd_exists);
1163 break;
1164
1165 case MAILIMAP_MAILBOX_DATA_RECENT:
1166 print_indent();
1167 printf("recent { %i }\n", mb_data->mbd_data.mbd_recent);
1168 break;
1169 }
1170
1171 unindent();
1172 print_indent();
1173 printf("}\n");
1174}
1175
1176static void
1177mailimap_resp_text_code_print(struct mailimap_resp_text_code * text_code);
1178
1179static void mailimap_resp_text_print(struct mailimap_resp_text * resp_text);
1180
1181static void mailimap_resp_cond_bye_print(struct mailimap_resp_cond_bye *
1182 resp_cond_bye)
1183{
1184 print_indent();
1185 printf("resp-cond-bye {\n");
1186 indent();
1187 mailimap_resp_text_print(resp_cond_bye->rsp_text);
1188 unindent();
1189 print_indent();
1190 printf("}\n");
1191}
1192
1193static void mailimap_resp_cond_state_print(struct mailimap_resp_cond_state *
1194 resp_cond_state)
1195{
1196 print_indent();
1197 printf("resp-cond-state {\n");
1198 indent();
1199
1200 switch(resp_cond_state->rsp_type) {
1201 case MAILIMAP_RESP_COND_STATE_OK:
1202 print_indent();
1203 printf("OK\n");
1204 break;
1205 case MAILIMAP_RESP_COND_STATE_NO:
1206 print_indent();
1207 printf("NO\n");
1208 break;
1209 case MAILIMAP_RESP_COND_STATE_BAD:
1210 print_indent();
1211 printf("BAD\n");
1212 break;
1213 }
1214
1215 mailimap_resp_text_print(resp_cond_state->rsp_text);
1216
1217 unindent();
1218 print_indent();
1219 printf("}\n");
1220}
1221
1222static void mailimap_capability_data_print(struct mailimap_capability_data *
1223 cap_data);
1224
1225static void mailimap_response_data_print(struct mailimap_response_data *
1226 resp_data)
1227{
1228 print_indent();
1229 printf("response-data {\n");
1230 indent();
1231
1232 switch (resp_data->rsp_type) {
1233 case MAILIMAP_RESP_DATA_TYPE_COND_STATE:
1234 mailimap_resp_cond_state_print(resp_data->rsp_data.rsp_cond_state);
1235 break;
1236 case MAILIMAP_RESP_DATA_TYPE_COND_BYE:
1237 mailimap_resp_cond_bye_print(resp_data->rsp_data.rsp_bye);
1238 break;
1239 case MAILIMAP_RESP_DATA_TYPE_MAILBOX_DATA:
1240 mailimap_mailbox_data_print(resp_data->rsp_data.rsp_mailbox_data);
1241 break;
1242 case MAILIMAP_RESP_DATA_TYPE_MESSAGE_DATA:
1243 mailimap_message_data_print(resp_data->rsp_data.rsp_message_data);
1244 break;
1245 case MAILIMAP_RESP_DATA_TYPE_CAPABILITY_DATA:
1246 mailimap_capability_data_print(resp_data->rsp_data.rsp_capability_data);
1247 break;
1248 }
1249
1250 unindent();
1251 print_indent();
1252 printf("}\n");
1253}
1254
1255static void mailimap_flag_print(struct mailimap_flag * flag)
1256{
1257 printf("flag { ");
1258
1259 switch (flag->fl_type) {
1260 case MAILIMAP_FLAG_ANSWERED:
1261 printf("answered");
1262 break;
1263
1264 case MAILIMAP_FLAG_FLAGGED:
1265 printf("flagged");
1266 break;
1267
1268 case MAILIMAP_FLAG_DELETED:
1269 printf("deleted");
1270 break;
1271
1272 case MAILIMAP_FLAG_SEEN:
1273 printf("seen");
1274 break;
1275
1276 case MAILIMAP_FLAG_DRAFT:
1277 printf("flag draft");
1278 break;
1279
1280 case MAILIMAP_FLAG_KEYWORD:
1281 printf("keyword { %s }", flag->fl_data.fl_keyword);
1282 break;
1283
1284 case MAILIMAP_FLAG_EXTENSION:
1285 printf("extention { %s }", flag->fl_data.fl_extension);
1286 break;
1287 }
1288
1289 printf(" }");
1290}
1291
1292static void mailimap_flag_perm_print(struct mailimap_flag_perm * flag_perm)
1293{
1294 print_indent();
1295 printf("flag-perm { ");
1296
1297 switch (flag_perm->fl_type) {
1298 case MAILIMAP_FLAG_PERM_FLAG:
1299 mailimap_flag_print(flag_perm->fl_flag);
1300 break;
1301
1302 case MAILIMAP_FLAG_PERM_ALL:
1303 printf("all");
1304 break;
1305 }
1306
1307 printf(" }\n");
1308}
1309
1310static void mailimap_capability_print(struct mailimap_capability * cap)
1311{
1312 print_indent();
1313 printf("capability { ");
1314
1315 switch (cap->cap_type) {
1316 case MAILIMAP_CAPABILITY_AUTH_TYPE:
1317 printf("auth { %s }", cap->cap_data.cap_auth_type);
1318 break;
1319 case MAILIMAP_CAPABILITY_NAME:
1320 printf("atom { %s }", cap->cap_data.cap_name);
1321 break;
1322 }
1323
1324 printf(" }\n");
1325}
1326
1327static void mailimap_capability_data_print(struct mailimap_capability_data *
1328 cap_data)
1329{
1330 clistiter * cur;
1331
1332 print_indent();
1333 printf("capability-data {\n");
1334 indent();
1335
1336 for(cur = clist_begin(cap_data->cap_list) ; cur != NULL ;
1337 cur = clist_next(cur)) {
1338 struct mailimap_capability * cap;
1339
1340 cap = clist_content(cur);
1341
1342 mailimap_capability_print(cap);
1343 }
1344
1345 unindent();
1346 print_indent();
1347 printf("}\n");
1348}
1349
1350static void
1351mailimap_resp_text_code_print(struct mailimap_resp_text_code * text_code)
1352{
1353 clistiter * cur;
1354
1355 print_indent();
1356 printf("resp-text-code {\n");
1357 indent();
1358
1359 switch (text_code->rc_type) {
1360 case MAILIMAP_RESP_TEXT_CODE_BADCHARSET:
1361 print_indent();
1362 printf("badcharset { ");
1363 for(cur = clist_begin(text_code->rc_data.rc_badcharset) ; cur != NULL ;
1364 cur = clist_next(cur))
1365 printf("%s ", (char *) clist_content(cur));
1366 printf("}\n");
1367 break;
1368
1369 case MAILIMAP_RESP_TEXT_CODE_CAPABILITY_DATA:
1370 print_indent();
1371 printf("capability {\n");
1372 indent();
1373 mailimap_capability_data_print(text_code->rc_data.rc_cap_data);
1374 unindent();
1375 print_indent();
1376 printf("}\n");
1377 break;
1378
1379 case MAILIMAP_RESP_TEXT_CODE_PERMANENTFLAGS:
1380 print_indent();
1381 printf("permanent-flags {\n");
1382 indent();
1383 cur = clist_begin(text_code->rc_data.rc_perm_flags);
1384 while (cur != NULL) {
1385 mailimap_flag_perm_print(clist_content(cur));
1386 cur = clist_next(cur);
1387 }
1388 unindent();
1389 print_indent();
1390 printf("}\n");
1391 break;
1392
1393 case MAILIMAP_RESP_TEXT_CODE_READ_ONLY:
1394 print_indent();
1395 printf("readonly\n");
1396 break;
1397
1398 case MAILIMAP_RESP_TEXT_CODE_READ_WRITE:
1399 print_indent();
1400 printf("readwrite\n");
1401 break;
1402
1403 case MAILIMAP_RESP_TEXT_CODE_TRY_CREATE:
1404 print_indent();
1405 printf("trycreate\n");
1406 break;
1407
1408 case MAILIMAP_RESP_TEXT_CODE_UIDNEXT:
1409 print_indent();
1410 printf("uidnext { %i }\n", text_code->rc_data.rc_uidnext);
1411 break;
1412
1413 case MAILIMAP_RESP_TEXT_CODE_UIDVALIDITY:
1414 print_indent();
1415 printf("uidvalidity { %i }\n", text_code->rc_data.rc_uidvalidity);
1416 break;
1417
1418 case MAILIMAP_RESP_TEXT_CODE_UNSEEN:
1419 print_indent();
1420 printf("unseen { %i }\n", text_code->rc_data.rc_first_unseen);
1421 break;
1422
1423 case MAILIMAP_RESP_TEXT_CODE_OTHER:
1424 print_indent();
1425 printf("other { %s = %s }\n",
1426 text_code->rc_data.rc_atom.atom_name,
1427 text_code->rc_data.rc_atom.atom_value);
1428 break;
1429 }
1430
1431 unindent();
1432 print_indent();
1433 printf("}\n");
1434}
1435
1436static void mailimap_resp_text_print(struct mailimap_resp_text * resp_text)
1437{
1438 print_indent();
1439 printf("resp-text {\n");
1440 indent();
1441
1442 if (resp_text->rsp_code)
1443 mailimap_resp_text_code_print(resp_text->rsp_code);
1444 print_indent();
1445 printf("text { %s }\n", resp_text->rsp_text);
1446
1447 unindent();
1448 print_indent();
1449 printf("}\n");
1450}
1451
1452static void mailimap_continue_req_print(struct mailimap_continue_req *
1453 cont_req)
1454{
1455 print_indent();
1456 printf("continue-req {\n");
1457 indent();
1458
1459 switch (cont_req->cr_type) {
1460 case MAILIMAP_CONTINUE_REQ_TEXT:
1461 print_indent();
1462 printf("resp-text {\n");
1463 indent();
1464 mailimap_resp_text_print(cont_req->cr_data.cr_text);
1465 unindent();
1466 print_indent();
1467 printf("}\n");
1468 break;
1469 case MAILIMAP_CONTINUE_REQ_BASE64:
1470 printf("base64 { %s }\n", cont_req->cr_data.cr_base64);
1471 break;
1472 }
1473
1474 unindent();
1475 print_indent();
1476 printf("}\n");
1477}
1478
1479static void mailimap_cont_req_or_resp_data_print(struct mailimap_cont_req_or_resp_data * cont_req_or_resp_data)
1480{
1481 print_indent();
1482 printf("cont-req-or-resp-data {\n");
1483 indent();
1484
1485 switch (cont_req_or_resp_data->rsp_type) {
1486 case MAILIMAP_RESP_CONT_REQ:
1487 mailimap_continue_req_print(cont_req_or_resp_data->rsp_data.rsp_cont_req);
1488 break;
1489 case MAILIMAP_RESP_RESP_DATA:
1490 mailimap_response_data_print(cont_req_or_resp_data->rsp_data.rsp_resp_data);
1491 break;
1492 }
1493
1494 unindent();
1495 print_indent();
1496 printf("}\n");
1497}
1498
1499static void mailimap_response_tagged_print(struct mailimap_response_tagged *
1500 tagged)
1501{
1502 print_indent();
1503 printf("response-tagged {\n");
1504 indent();
1505
1506 print_indent();
1507 printf("tag { %s }\n", tagged->rsp_tag);
1508 mailimap_resp_cond_state_print(tagged->rsp_cond_state);
1509
1510 unindent();
1511 print_indent();
1512 printf("}\n");
1513}
1514
1515static void mailimap_response_fatal_print(struct mailimap_response_fatal *
1516 fatal)
1517{
1518 print_indent();
1519 printf("response-fatal {\n");
1520 indent();
1521
1522 mailimap_resp_cond_bye_print(fatal->rsp_bye);
1523
1524 unindent();
1525 print_indent();
1526 printf("}\n");
1527}
1528
1529static void mailimap_response_done_print(struct mailimap_response_done *
1530 resp_done)
1531{
1532 print_indent();
1533 printf("response-done {\n");
1534 indent();
1535
1536 switch (resp_done->rsp_type) {
1537 case MAILIMAP_RESP_DONE_TYPE_TAGGED:
1538 mailimap_response_tagged_print(resp_done->rsp_data.rsp_tagged);
1539 break;
1540 case MAILIMAP_RESP_DONE_TYPE_FATAL:
1541 mailimap_response_fatal_print(resp_done->rsp_data.rsp_fatal);
1542 break;
1543 }
1544
1545 unindent();
1546 print_indent();
1547 printf("}\n");
1548}
1549
1550void mailimap_response_print(struct mailimap_response * resp)
1551{
1552 clistiter * cur;
1553
1554 print_indent();
1555 printf("response {\n");
1556 indent();
1557
1558 for(cur = clist_begin(resp->rsp_cont_req_or_resp_data_list) ; cur != NULL ;
1559 cur = clist_next(cur)) {
1560 struct mailimap_cont_req_or_resp_data * resp;
1561
1562 resp = clist_content(cur);
1563
1564 mailimap_cont_req_or_resp_data_print(resp);
1565 }
1566
1567 mailimap_response_done_print(resp->rsp_resp_done);
1568
1569 unindent();
1570 print_indent();
1571 printf("}\n");
1572}
1573
1574static void mailimap_resp_cond_auth_print(struct mailimap_resp_cond_auth *
1575 cond_auth)
1576{
1577 print_indent();
1578 printf("resp-cond-auth {\n");
1579 indent();
1580
1581 switch (cond_auth->rsp_type) {
1582 case MAILIMAP_RESP_COND_AUTH_OK:
1583 print_indent();
1584 printf("OK\n");
1585 case MAILIMAP_RESP_COND_AUTH_PREAUTH:
1586 print_indent();
1587 printf("PREAUTH\n");
1588 }
1589 mailimap_resp_text_print(cond_auth->rsp_text);
1590
1591 unindent();
1592 print_indent();
1593 printf("}\n");
1594}
1595
1596void mailimap_greeting_print(struct mailimap_greeting * greeting)
1597{
1598 print_indent();
1599 printf("greeting {\n");
1600 indent();
1601
1602 switch(greeting->gr_type) {
1603 case MAILIMAP_GREETING_RESP_COND_AUTH:
1604 mailimap_resp_cond_auth_print(greeting->gr_data.gr_auth);
1605 break;
1606 case MAILIMAP_GREETING_RESP_COND_BYE:
1607 mailimap_resp_cond_bye_print(greeting->gr_data.gr_bye);
1608 break;
1609 }
1610
1611 unindent();
1612 print_indent();
1613 printf("}\n");
1614}
1615#endif
diff --git a/libetpan/src/low-level/imap/mailimap_print.h b/libetpan/src/low-level/imap/mailimap_print.h
new file mode 100644
index 0000000..b617cca
--- a/dev/null
+++ b/libetpan/src/low-level/imap/mailimap_print.h
@@ -0,0 +1,54 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILIMAP_PRINT_H
37
38#define MAILIMAP_PRINT_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include "mailimap_types.h"
45
46void mailimap_response_print(struct mailimap_response * resp);
47
48void mailimap_greeting_print(struct mailimap_greeting * greeting);
49
50#ifdef __cplusplus
51}
52#endif
53
54#endif
diff --git a/libetpan/src/low-level/imap/mailimap_sender.c b/libetpan/src/low-level/imap/mailimap_sender.c
new file mode 100644
index 0000000..caf86e5
--- a/dev/null
+++ b/libetpan/src/low-level/imap/mailimap_sender.c
@@ -0,0 +1,2742 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailstream.h"
37#include "mailimap_keywords.h"
38#include "mailimap_sender.h"
39#include "clist.h"
40#include "mail.h"
41#include <string.h>
42
43#include <stdio.h>
44#include <ctype.h>
45
46/*
47 TODO :
48 implement progression for literal
49*/
50
51/* ************************************************************************* */
52/* ************************************************************************* */
53/* ************************************************************************* */
54/* ************************************************************************* */
55/* ************************************************************************* */
56/* ************************************************************************* */
57
58
59
60
61static int mailimap_atom_send(mailstream * fd, const char * atom);
62
63static int mailimap_auth_type_send(mailstream * fd, const char * auth_type);
64
65static int mailimap_base64_send(mailstream * fd, const char * base64);
66
67
68static int mailimap_date_send(mailstream * fd,
69 struct mailimap_date * date);
70
71static int mailimap_date_day_send(mailstream * fd, int day);
72
73static int mailimap_date_month_send(mailstream * fd, int month);
74
75
76/*
77static gboolean mailimap_date_text_send(mailstream * fd,
78 struct mailimap_date_text * date_text);
79*/
80
81
82static int mailimap_date_year_send(mailstream *fd, int year);
83
84static int
85mailimap_date_time_send(mailstream * fd,
86 struct mailimap_date_time * date_time);
87
88static int mailimap_digit_send(mailstream * fd, int digit);
89
90
91
92static int
93mailimap_fetch_type_send(mailstream * fd,
94 struct mailimap_fetch_type * fetch_type);
95
96
97static int mailimap_fetch_att_send(mailstream * fd,
98 struct mailimap_fetch_att * fetch_att);
99
100
101static int mailimap_flag_send(mailstream * fd,
102 struct mailimap_flag * flag);
103
104
105static int mailimap_flag_extension_send(mailstream * fd,
106 const char * flag_extension);
107
108
109static int mailimap_flag_keyword_send(mailstream * fd,
110 const char * flag_keyword);
111
112
113static int mailimap_flag_list_send(mailstream * fd,
114 struct mailimap_flag_list * flag_list);
115
116
117
118static int mailimap_header_fld_name_send(mailstream * fd, const char * header);
119
120
121static int
122mailimap_header_list_send(mailstream * fd,
123 struct mailimap_header_list * header_list);
124
125static int
126mailimap_list_mailbox_send(mailstream * fd, const char * pattern);
127
128
129static int mailimap_mailbox_send(mailstream * fd, const char * mb);
130
131static int mailimap_number_send(mailstream * fd, uint32_t number);
132
133static int mailimap_password_send(mailstream * fd, const char * pass);
134
135static int mailimap_quoted_char_send(mailstream * fd, char ch);
136
137static int mailimap_quoted_send(mailstream * fd, const char * quoted);
138
139
140static int mailimap_search_key_send(mailstream * fd,
141 struct mailimap_search_key * key);
142
143static int
144mailimap_section_send(mailstream * fd,
145 struct mailimap_section * section);
146
147static int
148mailimap_section_msgtext_send(mailstream * fd,
149 struct mailimap_section_msgtext *
150 section_msgtext);
151
152
153static int
154mailimap_section_part_send(mailstream * fd,
155 struct mailimap_section_part * section);
156
157
158static int
159mailimap_section_spec_send(mailstream * fd,
160 struct mailimap_section_spec * section_spec);
161
162
163static int
164mailimap_section_text_send(mailstream * fd,
165 struct mailimap_section_text * section_text);
166
167
168static int
169mailimap_sequence_num_send(mailstream * fd, uint32_t sequence_num);
170
171
172static int mailimap_set_item_send(mailstream * fd,
173 struct mailimap_set_item * item);
174
175
176static int mailimap_set_send(mailstream * fd,
177 struct mailimap_set * set);
178
179
180
181static int mailimap_status_att_send(mailstream * fd, int * status_att);
182
183
184
185static int
186mailimap_store_att_flags_send(mailstream * fd,
187 struct mailimap_store_att_flags * store_flags);
188
189
190static int mailimap_userid_send(mailstream * fd, const char * user);
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205/* ************************************************************************* */
206/* ************************************************************************* */
207/* ************************************************************************* */
208/* ************************************************************************* */
209/* ************************************************************************* */
210/* ************************************************************************* */
211
212
213
214
215
216static inline int mailimap_sized_token_send(mailstream * fd, const char * atom,
217 size_t len)
218{
219 if (mailstream_send_data_crlf(fd, atom, len, 0, NULL) == -1)
220 return MAILIMAP_ERROR_STREAM;
221
222 return MAILIMAP_NO_ERROR;
223}
224
225static int mailimap_token_send(mailstream * fd, const char * atom)
226{
227 return mailimap_sized_token_send(fd, atom, strlen(atom));
228}
229
230static int mailimap_char_send(mailstream * fd, char ch)
231{
232 if (mailstream_write(fd, &ch, 1) == -1)
233 return MAILIMAP_ERROR_STREAM;
234
235 return MAILIMAP_NO_ERROR;
236}
237
238typedef int mailimap_struct_sender(mailstream * fd, void * data);
239
240static int
241mailimap_struct_list_send(mailstream * fd, clist * list,
242 char symbol,
243 mailimap_struct_sender * sender)
244{
245 clistiter * cur;
246 void * elt;
247 int r;
248
249 cur = clist_begin(list);
250
251 if (cur == NULL)
252 return MAILIMAP_NO_ERROR;
253
254 elt = clist_content(cur);
255 r = (* sender)(fd, elt);
256 if (r != MAILIMAP_NO_ERROR)
257 return r;
258 cur = clist_next(cur);
259
260 while (cur != NULL) {
261 r = mailimap_char_send(fd, symbol);
262 if (r != MAILIMAP_NO_ERROR)
263 return r;
264 elt = clist_content(cur);
265 r = (* sender)(fd, elt);
266 if (r != MAILIMAP_NO_ERROR)
267 return r;
268 cur = clist_next(cur);
269 }
270
271 return MAILIMAP_NO_ERROR;
272}
273
274
275static int
276mailimap_struct_spaced_list_send(mailstream * fd, clist * list,
277 mailimap_struct_sender * sender)
278{
279 return mailimap_struct_list_send(fd, list, ' ', sender);
280}
281
282int mailimap_space_send(mailstream * fd)
283{
284 return mailimap_char_send(fd, ' ');
285}
286
287int mailimap_crlf_send(mailstream * fd)
288{
289 int r;
290
291 r = mailimap_char_send(fd, '\r');
292 if (r != MAILIMAP_NO_ERROR)
293 return r;
294 r = mailimap_char_send(fd, '\n');
295 if (r != MAILIMAP_NO_ERROR)
296 return r;
297
298 return MAILIMAP_NO_ERROR;
299}
300
301static int mailimap_oparenth_send(mailstream * fd)
302{
303 return mailimap_char_send(fd, '(');
304}
305
306static int mailimap_cparenth_send(mailstream * fd)
307{
308 return mailimap_char_send(fd, ')');
309}
310
311static int mailimap_dquote_send(mailstream * fd)
312{
313 return mailimap_char_send(fd, '"');
314}
315
316/*
317 address = "(" addr-name SP addr-adl SP addr-mailbox SP
318 addr-host ")"
319
320 addr-adl = nstring
321 ; Holds route from [RFC-822] route-addr if
322 ; non-NIL
323
324 addr-host = nstring
325 ; NIL indicates [RFC-822] group syntax.
326 ; Otherwise, holds [RFC-822] domain name
327
328 addr-mailbox = nstring
329 ; NIL indicates end of [RFC-822] group; if
330 ; non-NIL and addr-host is NIL, holds
331 ; [RFC-822] group name.
332 ; Otherwise, holds [RFC-822] local-part
333 ; after removing [RFC-822] quoting
334
335 addr-name = nstring
336 ; If non-NIL, holds phrase from [RFC-822]
337 ; mailbox after removing [RFC-822] quoting
338*/
339
340/*
341=> append = "APPEND" SP mailbox [SP flag-list] [SP date-time] SP
342 literal
343*/
344
345int mailimap_append_send(mailstream * fd,
346 const char * mailbox,
347 struct mailimap_flag_list * flag_list,
348 struct mailimap_date_time * date_time,
349 size_t literal_size)
350{
351 int r;
352
353 r = mailimap_token_send(fd, "APPEND");
354 if (r != MAILIMAP_NO_ERROR)
355 return r;
356 r = mailimap_space_send(fd);
357 if (r != MAILIMAP_NO_ERROR)
358 return r;
359 r = mailimap_mailbox_send(fd, mailbox);
360 if (r != MAILIMAP_NO_ERROR)
361 return r;
362 if (flag_list != NULL) {
363 r = mailimap_space_send(fd);
364 if (r != MAILIMAP_NO_ERROR)
365 return r;
366 r = mailimap_flag_list_send(fd, flag_list);
367 if (r != MAILIMAP_NO_ERROR)
368 return r;
369 }
370 if (date_time != NULL) {
371 r = mailimap_space_send(fd);
372 if (r != MAILIMAP_NO_ERROR)
373 return r;
374 r = mailimap_date_time_send(fd, date_time);
375 if (r != MAILIMAP_NO_ERROR)
376 return r;
377 }
378
379 r = mailimap_space_send(fd);
380 if (r != MAILIMAP_NO_ERROR)
381 return r;
382 r = mailimap_literal_count_send(fd, literal_size);
383 if (r != MAILIMAP_NO_ERROR)
384 return r;
385
386 return MAILIMAP_NO_ERROR;
387}
388
389/*
390 astring = 1*ASTRING-CHAR / string
391
392=> ASTRING-CHAR = ATOM-CHAR / resp-specials
393*/
394
395static int is_atom(const char * str)
396{
397 if (* str == '\0')
398 return 0;
399
400 while (* str != '\0') {
401 unsigned char uch = (unsigned char) * str;
402
403 if (!isalnum(uch))
404 return 0;
405
406 str ++;
407 }
408
409 return 1;
410}
411
412static int mailimap_astring_send(mailstream * fd, const char * astring)
413{
414 /*
415 workaround for buggy Courier-IMAP that does not accept
416 quoted-strings for fields name but prefer atoms.
417 */
418 if (is_atom(astring))
419 return mailimap_atom_send(fd, astring);
420 else
421 return mailimap_quoted_send(fd, astring);
422}
423
424/*
425=> atom = 1*ATOM-CHAR
426*/
427
428static int mailimap_atom_send(mailstream * fd, const char * atom)
429{
430 return mailimap_token_send(fd, atom);
431}
432
433/*
434=> ATOM-CHAR = <any CHAR except atom-specials>
435*/
436
437/*
438=> atom-specials = "(" / ")" / "{" / SP / CTL / list-wildcards /
439 quoted-specials / resp-specials
440*/
441
442/*
443=> authenticate = "AUTHENTICATE" SP auth-type *(CRLF base64)
444*/
445
446int mailimap_authenticate_send(mailstream * fd,
447 const char * auth_type)
448{
449 int r;
450
451 r = mailimap_token_send(fd, "AUTHENTICATE");
452 if (r != MAILIMAP_NO_ERROR)
453 return r;
454 r = mailimap_space_send(fd);
455 if (r != MAILIMAP_NO_ERROR)
456 return r;
457 r = mailimap_auth_type_send(fd, auth_type);
458 if (r != MAILIMAP_NO_ERROR)
459 return r;
460
461 return MAILIMAP_NO_ERROR;
462}
463
464int mailimap_authenticate_resp_send(mailstream * fd,
465 const char * base64)
466{
467 int r;
468
469 r = mailimap_base64_send(fd, base64);
470 if (r != MAILIMAP_NO_ERROR)
471 return r;
472
473 return MAILIMAP_NO_ERROR;
474}
475
476/*
477=> auth-type = atom
478 ; Defined by [SASL]
479*/
480
481static int mailimap_auth_type_send(mailstream * fd, const char * auth_type)
482{
483 return mailimap_atom_send(fd, auth_type);
484}
485
486
487/*
488=> base64 = *(4base64-char) [base64-terminal]
489*/
490
491static int mailimap_base64_send(mailstream * fd, const char * base64)
492{
493 return mailimap_token_send(fd, base64);
494}
495
496/*
497=> base64-char = ALPHA / DIGIT / "+" / "/"
498 ; Case-sensitive
499
500 base64-terminal = (2base64-char "==") / (3base64-char "=")
501
502 body = "(" (body-type-1part / body-type-mpart) ")"
503
504 body-extension = nstring / number /
505 "(" body-extension *(SP body-extension) ")"
506 ; Future expansion. Client implementations
507 ; MUST accept body-extension fields. Server
508 ; implementations MUST NOT generate
509 ; body-extension fields except as defined by
510 ; future standard or standards-track
511 ; revisions of this specification.
512
513 body-ext-1part = body-fld-md5 [SP body-fld-dsp [SP body-fld-lang
514 *(SP body-extension)]]
515 ; MUST NOT be returned on non-extensible
516 ; "BODY" fetch
517
518 body-ext-mpart = body-fld-param [SP body-fld-dsp [SP body-fld-lang
519 *(SP body-extension)]]
520 ; MUST NOT be returned on non-extensible
521 ; "BODY" fetch
522
523 body-fields = body-fld-param SP body-fld-id SP body-fld-desc SP
524 body-fld-enc SP body-fld-octets
525
526 body-fld-desc = nstring
527
528 body-fld-dsp = "(" string SP body-fld-param ")" / nil
529
530 body-fld-enc = (DQUOTE ("7BIT" / "8BIT" / "BINARY" / "BASE64"/
531 "QUOTED-PRINTABLE") DQUOTE) / string
532
533 body-fld-id = nstring
534
535 body-fld-lang = nstring / "(" string *(SP string) ")"
536
537 body-fld-lines = number
538
539 body-fld-md5 = nstring
540
541 body-fld-octets = number
542
543 body-fld-param = "(" string SP string *(SP string SP string) ")" / nil
544
545 body-type-1part = (body-type-basic / body-type-msg / body-type-text)
546 [SP body-ext-1part]
547
548 body-type-basic = media-basic SP body-fields
549 ; MESSAGE subtype MUST NOT be "RFC822"
550
551 body-type-mpart = 1*body SP media-subtype
552 [SP body-ext-mpart]
553
554 body-type-msg = media-message SP body-fields SP envelope
555 SP body SP body-fld-lines
556
557 body-type-text = media-text SP body-fields SP body-fld-lines
558
559 capability = ("AUTH=" auth-type) / atom
560 ; New capabilities MUST begin with "X" or be
561 ; registered with IANA as standard or
562 ; standards-track
563
564 capability-data = "CAPABILITY" *(SP capability) SP "IMAP4rev1"
565 *(SP capability)
566 ; IMAP4rev1 servers which offer RFC 1730
567 ; compatibility MUST list "IMAP4" as the first
568 ; capability.
569
570 CHAR8 = %x01-ff
571 ; any OCTET except NUL, %x00
572*/
573
574/*
575=> command = tag SP (command-any / command-auth / command-nonauth /
576 command-select) CRLF
577 ; Modal based on state
578*/
579
580/*
581=> command-any = "CAPABILITY" / "LOGOUT" / "NOOP" / x-command
582 ; Valid in all states
583*/
584
585int mailimap_capability_send(mailstream * fd)
586{
587 int r;
588
589 r = mailimap_token_send(fd, "CAPABILITY");
590 if (r != MAILIMAP_NO_ERROR)
591 return r;
592
593 return MAILIMAP_NO_ERROR;
594}
595
596int mailimap_logout_send(mailstream * fd)
597{
598 int r;
599
600 r = mailimap_token_send(fd, "LOGOUT");
601 if (r != MAILIMAP_NO_ERROR)
602 return r;
603
604 return MAILIMAP_NO_ERROR;
605}
606
607int mailimap_noop_send(mailstream * fd)
608{
609 int r;
610
611 r = mailimap_token_send(fd, "NOOP");
612 if (r != MAILIMAP_NO_ERROR)
613 return r;
614
615 return MAILIMAP_NO_ERROR;
616}
617
618/*
619=> command-auth = append / create / delete / examine / list / lsub /
620 rename / select / status / subscribe / unsubscribe
621 ; Valid only in Authenticated or Selected state
622*/
623
624/*
625=> command-nonauth = login / authenticate
626 ; Valid only when in Not Authenticated state
627*/
628
629/*
630=> command-select = "CHECK" / "CLOSE" / "EXPUNGE" / copy / fetch / store /
631 uid / search
632 ; Valid only when in Selected state
633*/
634
635int mailimap_check_send(mailstream * fd)
636{
637 int r;
638
639 r = mailimap_token_send(fd, "CHECK");
640 if (r != MAILIMAP_NO_ERROR)
641 return r;
642
643 return MAILIMAP_NO_ERROR;
644}
645
646int mailimap_close_send(mailstream * fd)
647{
648 int r;
649
650 r = mailimap_token_send(fd, "CLOSE");
651 if (r != MAILIMAP_NO_ERROR)
652 return r;
653
654 return MAILIMAP_NO_ERROR;
655}
656
657int mailimap_expunge_send(mailstream * fd)
658{
659 int r;
660
661 r = mailimap_token_send(fd, "EXPUNGE");
662 if (r != MAILIMAP_NO_ERROR)
663 return r;
664
665 return MAILIMAP_NO_ERROR;
666}
667
668/*
669 continue-req = "+" SP (resp-text / base64) CRLF
670*/
671
672/*
673=> copy = "COPY" SP set SP mailbox
674*/
675
676int mailimap_copy_send(mailstream * fd,
677 struct mailimap_set * set,
678 const char * mb)
679{
680 int r;
681
682 r = mailimap_token_send(fd, "COPY");
683 if (r != MAILIMAP_NO_ERROR)
684 return r;
685
686 r = mailimap_space_send(fd);
687 if (r != MAILIMAP_NO_ERROR)
688 return r;
689
690 r = mailimap_set_send(fd, set);
691 if (r != MAILIMAP_NO_ERROR)
692 return r;
693
694 r = mailimap_space_send(fd);
695 if (r != MAILIMAP_NO_ERROR)
696 return r;
697
698 r = mailimap_mailbox_send(fd, mb);
699 if (r != MAILIMAP_NO_ERROR)
700 return r;
701
702 return MAILIMAP_NO_ERROR;
703}
704
705int mailimap_uid_copy_send(mailstream * fd,
706 struct mailimap_set * set,
707 const char * mb)
708{
709 int r;
710
711 r = mailimap_token_send(fd, "UID");
712 if (r != MAILIMAP_NO_ERROR)
713 return r;
714
715 r = mailimap_space_send(fd);
716 if (r != MAILIMAP_NO_ERROR)
717 return r;
718
719 return mailimap_copy_send(fd, set, mb);
720}
721
722/*
723=> create = "CREATE" SP mailbox
724 ; Use of INBOX gives a NO error
725*/
726
727int mailimap_create_send(mailstream * fd,
728 const char * mb)
729{
730 int r;
731
732 r = mailimap_token_send(fd, "CREATE");
733 if (r != MAILIMAP_NO_ERROR)
734 return r;
735
736 r = mailimap_space_send(fd);
737 if (r != MAILIMAP_NO_ERROR)
738 return r;
739
740 r = mailimap_mailbox_send(fd, mb);
741 if (r != MAILIMAP_NO_ERROR)
742 return r;
743
744 return MAILIMAP_NO_ERROR;
745}
746
747/*
748=> date = date-text / DQUOTE date-text DQUOTE
749*/
750
751static int mailimap_date_send(mailstream * fd,
752 struct mailimap_date * date)
753{
754 int r;
755
756 r = mailimap_date_day_send(fd, date->dt_day);
757 if (r != MAILIMAP_NO_ERROR)
758 return r;
759
760 r = mailimap_char_send(fd, '-');
761 if (r != MAILIMAP_NO_ERROR)
762 return r;
763
764 r = mailimap_date_month_send(fd, date->dt_month);
765 if (r != MAILIMAP_NO_ERROR)
766 return r;
767
768 r = mailimap_char_send(fd, '-');
769 if (r != MAILIMAP_NO_ERROR)
770 return r;
771
772 r = mailimap_date_year_send(fd, date->dt_year);
773 if (r != MAILIMAP_NO_ERROR)
774 return r;
775
776 return MAILIMAP_NO_ERROR;
777}
778
779/*
780=> date-day = 1*2DIGIT
781 ; Day of month
782*/
783
784static int mailimap_date_day_send(mailstream * fd, int day)
785{
786 return mailimap_number_send(fd, day);
787}
788
789/*
790=> date-day-fixed = (SP DIGIT) / 2DIGIT
791 ; Fixed-format version of date-day
792*/
793
794static int mailimap_date_day_fixed_send(mailstream * fd, int day)
795{
796 int r;
797
798 if (day < 10) {
799 r = mailimap_space_send(fd);
800 if (r != MAILIMAP_NO_ERROR)
801 return r;
802
803 r = mailimap_number_send(fd, day);
804 if (r != MAILIMAP_NO_ERROR)
805 return r;
806
807 return MAILIMAP_NO_ERROR;
808 }
809 else
810 return mailimap_number_send(fd, day);
811}
812
813/*
814=> date-month = "Jan" / "Feb" / "Mar" / "Apr" / "May" / "Jun" /
815 "Jul" / "Aug" / "Sep" / "Oct" / "Nov" / "Dec"
816*/
817
818static int mailimap_date_month_send(mailstream * fd, int month)
819{
820 const char * name;
821 int r;
822
823 name = mailimap_month_get_token_str(month);
824
825 if (name == NULL)
826 return MAILIMAP_ERROR_INVAL;
827
828 r = mailimap_token_send(fd, name);
829 if (r != MAILIMAP_NO_ERROR)
830 return r;
831
832 return MAILIMAP_NO_ERROR;
833}
834
835/*
836=> date-text = date-day "-" date-month "-" date-year
837*/
838
839/*
840static gboolean mailimap_date_text_send(mailstream * fd,
841 struct mailimap_date_text * date_text)
842{
843 if (!mailimap_date_day_send(fd, date_text->day))
844 return FALSE;
845 if (!mailimap_char_send(fd, '-'))
846 return FALSE;
847 if (!mailimap_date_month_send(fd, date_text->month))
848 return FALSE;
849 if (!mailimap_char_send(fd, '-'))
850 return FALSE;
851 if (!mailimap_date_year_send(fd, date_text->year))
852 return FALSE;
853
854 return TRUE;
855}
856*/
857
858/*
859=> date-year = 4DIGIT
860*/
861
862static int mailimap_fixed_digit_send(mailstream * fd,
863 int num, int count)
864{
865 int r;
866
867 r = mailimap_fixed_digit_send(fd, num / 10, count);
868 if (r != MAILIMAP_NO_ERROR)
869 return r;
870
871 r = mailimap_digit_send(fd, num % 10);
872 if (r != MAILIMAP_NO_ERROR)
873 return r;
874
875 return MAILIMAP_NO_ERROR;
876}
877
878static int mailimap_date_year_send(mailstream *fd, int year)
879{
880 int r;
881
882 r = mailimap_fixed_digit_send(fd, year, 4);
883 if (r != MAILIMAP_NO_ERROR)
884 return r;
885
886 return MAILIMAP_NO_ERROR;
887}
888
889/*
890=> date-time = DQUOTE date-day-fixed "-" date-month "-" date-year
891 SP time SP zone DQUOTE
892*/
893
894static int
895mailimap_date_time_send(mailstream * fd,
896 struct mailimap_date_time * date_time)
897{
898 int r;
899
900 r = mailimap_date_day_fixed_send(fd, date_time->dt_day);
901 if (r != MAILIMAP_NO_ERROR)
902 return r;
903
904 r = mailimap_char_send(fd, '-');
905 if (r != MAILIMAP_NO_ERROR)
906 return r;
907
908 r = mailimap_date_month_send(fd, date_time->dt_month);
909 if (r != MAILIMAP_NO_ERROR)
910 return r;
911
912 r = mailimap_char_send(fd, '-');
913 if (r != MAILIMAP_NO_ERROR)
914 return r;
915
916 r = mailimap_date_year_send(fd, date_time->dt_month);
917 if (r != MAILIMAP_NO_ERROR)
918 return r;
919
920 r = mailimap_space_send(fd);
921 if (r != MAILIMAP_NO_ERROR)
922 return r;
923
924 r = mailimap_fixed_digit_send(fd, date_time->dt_hour, 2);
925 if (r != MAILIMAP_NO_ERROR)
926 return r;
927
928 r = mailimap_char_send(fd, ':');
929 if (r != MAILIMAP_NO_ERROR)
930 return r;
931
932 r = mailimap_fixed_digit_send(fd, date_time->dt_min, 2);
933 if (r != MAILIMAP_NO_ERROR)
934 return r;
935
936 r = mailimap_char_send(fd, ':');
937 if (r != MAILIMAP_NO_ERROR)
938 return r;
939
940 r = mailimap_fixed_digit_send(fd, date_time->dt_sec, 2);
941 if (r != MAILIMAP_NO_ERROR)
942 return r;
943
944 return MAILIMAP_NO_ERROR;
945}
946
947/*
948=> delete = "DELETE" SP mailbox
949 ; Use of INBOX gives a NO error
950*/
951
952int mailimap_delete_send(mailstream * fd, const char * mb)
953{
954 int r;
955
956 r = mailimap_token_send(fd, "DELETE");
957 if (r != MAILIMAP_NO_ERROR)
958 return r;
959
960 r = mailimap_space_send(fd);
961 if (r != MAILIMAP_NO_ERROR)
962 return r;
963
964 r = mailimap_mailbox_send(fd, mb);
965 if (r != MAILIMAP_NO_ERROR)
966 return r;
967
968 return MAILIMAP_NO_ERROR;
969}
970
971/*
972
973digit
974
975digit-nz = %x31-39
976 ; 1-9
977*/
978
979static int mailimap_digit_send(mailstream * fd, int digit)
980{
981 return mailimap_char_send(fd, digit + '0');
982}
983
984
985/*
986 envelope = "(" env-date SP env-subject SP env-from SP env-sender SP
987 env-reply-to SP env-to SP env-cc SP env-bcc SP
988 env-in-reply-to SP env-message-id ")"
989
990 env-bcc = "(" 1*address ")" / nil
991
992 env-cc = "(" 1*address ")" / nil
993
994 env-date = nstring
995
996 env-from = "(" 1*address ")" / nil
997
998 env-in-reply-to = nstring
999
1000 env-message-id = nstring
1001
1002 env-reply-to = "(" 1*address ")" / nil
1003
1004 env-sender = "(" 1*address ")" / nil
1005
1006 env-subject = nstring
1007
1008 env-to = "(" 1*address ")" / nil
1009*/
1010
1011/*
1012=> examine = "EXAMINE" SP mailbox
1013*/
1014
1015int mailimap_examine_send(mailstream * fd, const char * mb)
1016{
1017 int r;
1018
1019 r = mailimap_token_send(fd, "EXAMINE");
1020 if (r != MAILIMAP_NO_ERROR)
1021 return r;
1022
1023 r = mailimap_space_send(fd);
1024 if (r != MAILIMAP_NO_ERROR)
1025 return r;
1026
1027 r = mailimap_mailbox_send(fd, mb);
1028 if (r != MAILIMAP_NO_ERROR)
1029 return r;
1030
1031 return MAILIMAP_NO_ERROR;
1032}
1033
1034/*
1035=> fetch = "FETCH" SP set SP ("ALL" / "FULL" / "FAST" / fetch-att /
1036 "(" fetch-att *(SP fetch-att) ")")
1037*/
1038
1039static int
1040mailimap_fetch_att_list_send(mailstream * fd, clist * fetch_att_list);
1041
1042static int
1043mailimap_fetch_type_send(mailstream * fd,
1044 struct mailimap_fetch_type * fetch_type)
1045{
1046 switch (fetch_type->ft_type) {
1047 case MAILIMAP_FETCH_TYPE_ALL:
1048 return mailimap_token_send(fd, "ALL");
1049 case MAILIMAP_FETCH_TYPE_FULL:
1050 return mailimap_token_send(fd, "FULL");
1051 case MAILIMAP_FETCH_TYPE_FAST:
1052 return mailimap_token_send(fd, "FAST");
1053 case MAILIMAP_FETCH_TYPE_FETCH_ATT:
1054 return mailimap_fetch_att_send(fd, fetch_type->ft_data.ft_fetch_att);
1055 case MAILIMAP_FETCH_TYPE_FETCH_ATT_LIST:
1056 return mailimap_fetch_att_list_send(fd,
1057 fetch_type->ft_data.ft_fetch_att_list);
1058 default:
1059 /* should not happen */
1060 return MAILIMAP_ERROR_INVAL;
1061 }
1062}
1063
1064int mailimap_fetch_send(mailstream * fd,
1065 struct mailimap_set * set,
1066 struct mailimap_fetch_type * fetch_type)
1067{
1068 int r;
1069
1070 r = mailimap_token_send(fd, "FETCH");
1071 if (r != MAILIMAP_NO_ERROR)
1072 return r;
1073
1074 r = mailimap_space_send(fd);
1075 if (r != MAILIMAP_NO_ERROR)
1076 return r;
1077
1078 r = mailimap_set_send(fd, set);
1079 if (r != MAILIMAP_NO_ERROR)
1080 return r;
1081
1082 r = mailimap_space_send(fd);
1083 if (r != MAILIMAP_NO_ERROR)
1084 return r;
1085
1086 r = mailimap_fetch_type_send(fd, fetch_type);
1087 if (r != MAILIMAP_NO_ERROR)
1088 return r;
1089
1090 return MAILIMAP_NO_ERROR;
1091}
1092
1093int
1094mailimap_uid_fetch_send(mailstream * fd,
1095 struct mailimap_set * set,
1096 struct mailimap_fetch_type * fetch_type)
1097{
1098 int r;
1099
1100 r = mailimap_token_send(fd, "UID");
1101 if (r != MAILIMAP_NO_ERROR)
1102 return r;
1103
1104 r = mailimap_space_send(fd);
1105 if (r != MAILIMAP_NO_ERROR)
1106 return r;
1107
1108 return mailimap_fetch_send(fd, set, fetch_type);
1109}
1110
1111/* currently porting */
1112
1113static int
1114mailimap_fetch_att_list_send(mailstream * fd, clist * fetch_att_list)
1115{
1116 int r;
1117
1118 r = mailimap_oparenth_send(fd);
1119 if (r != MAILIMAP_NO_ERROR)
1120 return r;
1121
1122 r = mailimap_struct_spaced_list_send(fd, fetch_att_list,
1123 (mailimap_struct_sender *)
1124 mailimap_fetch_att_send);
1125 if (r != MAILIMAP_NO_ERROR)
1126 return r;
1127
1128 r = mailimap_cparenth_send(fd);
1129 if (r != MAILIMAP_NO_ERROR)
1130 return r;
1131
1132 return MAILIMAP_NO_ERROR;
1133}
1134
1135/*
1136=> fetch-att = "ENVELOPE" / "FLAGS" / "INTERNALDATE" /
1137 "RFC822" [".HEADER" / ".SIZE" / ".TEXT"] /
1138 "BODY" ["STRUCTURE"] / "UID" /
1139 "BODY" [".PEEK"] section ["<" number "." nz-number ">"]
1140*/
1141
1142static int mailimap_fetch_att_send(mailstream * fd,
1143 struct mailimap_fetch_att * fetch_att)
1144{
1145 int r;
1146
1147 switch(fetch_att->att_type) {
1148 case MAILIMAP_FETCH_ATT_ENVELOPE:
1149 return mailimap_token_send(fd, "ENVELOPE");
1150
1151 case MAILIMAP_FETCH_ATT_FLAGS:
1152 return mailimap_token_send(fd, "FLAGS");
1153
1154 case MAILIMAP_FETCH_ATT_INTERNALDATE:
1155 return mailimap_token_send(fd, "INTERNALDATE");
1156
1157 case MAILIMAP_FETCH_ATT_RFC822:
1158 return mailimap_token_send(fd, "RFC822");
1159
1160 case MAILIMAP_FETCH_ATT_RFC822_HEADER:
1161 return mailimap_token_send(fd, "RFC822.HEADER");
1162
1163 case MAILIMAP_FETCH_ATT_RFC822_SIZE:
1164 return mailimap_token_send(fd, "RFC822.SIZE");
1165
1166 case MAILIMAP_FETCH_ATT_RFC822_TEXT:
1167 return mailimap_token_send(fd, "RFC822.TEXT");
1168
1169 case MAILIMAP_FETCH_ATT_BODY:
1170 return mailimap_token_send(fd, "BODY");
1171
1172 case MAILIMAP_FETCH_ATT_BODYSTRUCTURE:
1173 return mailimap_token_send(fd, "BODYSTRUCTURE");
1174
1175 case MAILIMAP_FETCH_ATT_UID:
1176 return mailimap_token_send(fd, "UID");
1177
1178 case MAILIMAP_FETCH_ATT_BODY_SECTION:
1179
1180 r = mailimap_token_send(fd, "BODY");
1181 if (r != MAILIMAP_NO_ERROR)
1182 return r;
1183 r = mailimap_section_send(fd, fetch_att->att_section);
1184 if (r != MAILIMAP_NO_ERROR)
1185 return r;
1186 if (fetch_att->att_size != 0) {
1187 r = mailimap_char_send(fd, '<');
1188 if (r != MAILIMAP_NO_ERROR)
1189 return r;
1190 r = mailimap_number_send(fd, fetch_att->att_offset);
1191 if (r != MAILIMAP_NO_ERROR)
1192 return r;
1193 r = mailimap_char_send(fd, '.');
1194 if (r != MAILIMAP_NO_ERROR)
1195 return r;
1196 r = mailimap_number_send(fd, fetch_att->att_size);
1197 if (r != MAILIMAP_NO_ERROR)
1198 return r;
1199 r = mailimap_char_send(fd, '>');
1200 if (r != MAILIMAP_NO_ERROR)
1201 return r;
1202 }
1203
1204 return MAILIMAP_NO_ERROR;
1205
1206 case MAILIMAP_FETCH_ATT_BODY_PEEK_SECTION:
1207 r = mailimap_token_send(fd, "BODY.PEEK");
1208 if (r != MAILIMAP_NO_ERROR)
1209 return r;
1210 r = mailimap_section_send(fd, fetch_att->att_section);
1211 if (r != MAILIMAP_NO_ERROR)
1212 return r;
1213 if (fetch_att->att_size != 0) {
1214 r = mailimap_char_send(fd, '<');
1215 if (r != MAILIMAP_NO_ERROR)
1216 return r;
1217 r = mailimap_number_send(fd, fetch_att->att_offset);
1218 if (r != MAILIMAP_NO_ERROR)
1219 return r;
1220 r = mailimap_char_send(fd, '.');
1221 if (r != MAILIMAP_NO_ERROR)
1222 return r;
1223 r = mailimap_number_send(fd, fetch_att->att_size);
1224 if (r != MAILIMAP_NO_ERROR)
1225 return r;
1226 r = mailimap_char_send(fd, '>');
1227 if (r != MAILIMAP_NO_ERROR)
1228 return r;
1229 }
1230 return MAILIMAP_NO_ERROR;
1231
1232 default:
1233 /* should not happen */
1234 return MAILIMAP_ERROR_INVAL;
1235 }
1236}
1237
1238/*
1239=> flag = "\Answered" / "\Flagged" / "\Deleted" /
1240 "\Seen" / "\Draft" / flag-keyword / flag-extension
1241 ; Does not include "\Recent"
1242*/
1243
1244/*
1245enum {
1246 FLAG_ANSWERED,
1247 FLAG_FLAGGED,
1248 FLAG_DELETED,
1249 FLAG_SEEN,
1250 FLAG_DRAFT,
1251 FLAG_KEYWORD,
1252 FLAG_EXTENSION
1253};
1254
1255struct mailimap_flag {
1256 gint type;
1257 gchar * flag_keyword;
1258 gchar * flag_extension;
1259};
1260*/
1261
1262static int mailimap_flag_send(mailstream * fd,
1263 struct mailimap_flag * flag)
1264{
1265 switch(flag->fl_type) {
1266 case MAILIMAP_FLAG_ANSWERED:
1267 return mailimap_token_send(fd, "\\Answered");
1268 case MAILIMAP_FLAG_FLAGGED:
1269 return mailimap_token_send(fd, "\\Flagged");
1270 case MAILIMAP_FLAG_DELETED:
1271 return mailimap_token_send(fd, "\\Deleted");
1272 case MAILIMAP_FLAG_SEEN:
1273 return mailimap_token_send(fd, "\\Seen");
1274 case MAILIMAP_FLAG_DRAFT:
1275 return mailimap_token_send(fd, "\\Draft");
1276 case MAILIMAP_FLAG_KEYWORD:
1277 return mailimap_flag_keyword_send(fd, flag->fl_data.fl_keyword);
1278 case MAILIMAP_FLAG_EXTENSION:
1279 return mailimap_flag_extension_send(fd, flag->fl_data.fl_extension);
1280 default:
1281 /* should not happen */
1282 return MAILIMAP_ERROR_INVAL;
1283 }
1284}
1285
1286
1287/*
1288=> flag-extension = "\" atom
1289 ; Future expansion. Client implementations
1290 ; MUST accept flag-extension flags. Server
1291 ; implementations MUST NOT generate
1292 ; flag-extension flags except as defined by
1293 ; future standard or standards-track
1294 ; revisions of this specification.
1295*/
1296
1297static int mailimap_flag_extension_send(mailstream * fd,
1298 const char * flag_extension)
1299{
1300 int r;
1301
1302 r = mailimap_char_send(fd, '\\');
1303 if (r != MAILIMAP_NO_ERROR)
1304 return r;
1305
1306 r = mailimap_atom_send(fd, flag_extension);
1307 if (r != MAILIMAP_NO_ERROR)
1308 return r;
1309
1310 return MAILIMAP_NO_ERROR;
1311}
1312
1313/*
1314 flag-fetch = flag / "\Recent"
1315*/
1316
1317/*
1318=> flag-keyword = atom
1319*/
1320
1321static int mailimap_flag_keyword_send(mailstream * fd,
1322 const char * flag_keyword)
1323{
1324 return mailimap_token_send(fd, flag_keyword);
1325}
1326
1327/*
1328=> flag-list = "(" [flag *(SP flag)] ")"
1329*/
1330
1331static int mailimap_flag_list_send(mailstream * fd,
1332 struct mailimap_flag_list * flag_list)
1333{
1334 int r;
1335
1336 r = mailimap_oparenth_send(fd);
1337 if (r != MAILIMAP_NO_ERROR)
1338 return r;
1339
1340 if (flag_list->fl_list != NULL) {
1341 r = mailimap_struct_spaced_list_send(fd, flag_list->fl_list,
1342 (mailimap_struct_sender *) mailimap_flag_send);
1343 if (r != MAILIMAP_NO_ERROR)
1344 return r;
1345 }
1346
1347 r = mailimap_cparenth_send(fd);
1348 if (r != MAILIMAP_NO_ERROR)
1349 return r;
1350
1351 return MAILIMAP_NO_ERROR;
1352}
1353
1354/*
1355 flag-perm = flag / "\*"
1356
1357 greeting = "*" SP (resp-cond-auth / resp-cond-bye) CRLF
1358*/
1359
1360/*
1361=> header-fld-name = astring
1362*/
1363
1364static int mailimap_header_fld_name_send(mailstream * fd, const char * header)
1365{
1366 return mailimap_astring_send(fd, header);
1367}
1368
1369/*
1370=> header-list = "(" header-fld-name *(SP header-fld-name) ")"
1371*/
1372
1373static int
1374mailimap_header_list_send(mailstream * fd,
1375 struct mailimap_header_list * header_list)
1376{
1377 int r;
1378
1379 r = mailimap_oparenth_send(fd);
1380 if (r != MAILIMAP_NO_ERROR)
1381 return r;
1382
1383 r = mailimap_struct_spaced_list_send(fd, header_list->hdr_list,
1384 (mailimap_struct_sender *) mailimap_header_fld_name_send);
1385 if (r != MAILIMAP_NO_ERROR)
1386 return r;
1387
1388 r = mailimap_cparenth_send(fd);
1389 if (r != MAILIMAP_NO_ERROR)
1390 return r;
1391
1392 return MAILIMAP_NO_ERROR;
1393}
1394
1395/*
1396=> list = "LIST" SP mailbox SP list-mailbox
1397*/
1398
1399int mailimap_list_send(mailstream * fd,
1400 const char * mb,
1401 const char * list_mb)
1402{
1403 int r;
1404
1405 r = mailimap_token_send(fd, "LIST");
1406 if (r != MAILIMAP_NO_ERROR)
1407 return r;
1408
1409 r = mailimap_space_send(fd);
1410 if (r != MAILIMAP_NO_ERROR)
1411 return r;
1412
1413 r = mailimap_mailbox_send(fd, mb);
1414 if (r != MAILIMAP_NO_ERROR)
1415 return r;
1416
1417 r = mailimap_space_send(fd);
1418 if (r != MAILIMAP_NO_ERROR)
1419 return r;
1420
1421 r = mailimap_list_mailbox_send(fd, list_mb);
1422 if (r != MAILIMAP_NO_ERROR)
1423 return r;
1424
1425 return MAILIMAP_NO_ERROR;
1426}
1427
1428/*
1429=> list-mailbox = 1*list-char / string
1430*/
1431
1432static int
1433mailimap_list_mailbox_send(mailstream * fd, const char * pattern)
1434{
1435 return mailimap_quoted_send(fd, pattern);
1436}
1437
1438/*
1439 list-char = ATOM-CHAR / list-wildcards / resp-specials
1440
1441 list-wildcards = "%" / "*"
1442*/
1443
1444/*
1445=> literal = "{" number "}" CRLF *CHAR8
1446 ; Number represents the number of CHAR8s
1447*/
1448
1449int
1450mailimap_literal_send(mailstream * fd, const char * literal,
1451 size_t progr_rate,
1452 progress_function * progr_fun)
1453{
1454 size_t len;
1455 uint32_t literal_len;
1456 int r;
1457
1458 len = strlen(literal);
1459 literal_len = mailstream_get_data_crlf_size(literal, len);
1460
1461 r = mailimap_literal_count_send(fd, literal_len);
1462 if (r != MAILIMAP_NO_ERROR)
1463 return r;
1464 r = mailimap_literal_data_send(fd, literal, len, progr_rate, progr_fun);
1465 if (r != MAILIMAP_NO_ERROR)
1466 return r;
1467
1468 return MAILIMAP_NO_ERROR;
1469}
1470
1471/*
1472 "{" number "}" CRLF
1473*/
1474
1475int
1476mailimap_literal_count_send(mailstream * fd, uint32_t count)
1477{
1478 int r;
1479
1480 r = mailimap_char_send(fd, '{');
1481 if (r != MAILIMAP_NO_ERROR)
1482 return r;
1483
1484 r = mailimap_number_send(fd, count);
1485 if (r != MAILIMAP_NO_ERROR)
1486 return r;
1487
1488 r = mailimap_char_send(fd, '}');
1489 if (r != MAILIMAP_NO_ERROR)
1490 return r;
1491
1492 r = mailimap_crlf_send(fd);
1493 if (r != MAILIMAP_NO_ERROR)
1494 return r;
1495
1496 return MAILIMAP_NO_ERROR;
1497}
1498
1499/*
1500 *CHAR8
1501*/
1502
1503int
1504mailimap_literal_data_send(mailstream * fd, const char * literal, uint32_t len,
1505 size_t progr_rate,
1506 progress_function * progr_fun)
1507{
1508 int r;
1509
1510 r = mailimap_sized_token_send(fd, literal, len);
1511 if (r != MAILIMAP_NO_ERROR)
1512 return r;
1513
1514 return MAILIMAP_NO_ERROR;
1515}
1516
1517
1518/*
1519=> login = "LOGIN" SP userid SP password
1520*/
1521
1522int mailimap_login_send(mailstream * fd,
1523 const char * userid, const char * password)
1524{
1525 int r;
1526
1527 r = mailimap_token_send(fd, "LOGIN");
1528 if (r != MAILIMAP_NO_ERROR)
1529 return r;
1530
1531 r = mailimap_space_send(fd);
1532 if (r != MAILIMAP_NO_ERROR)
1533 return r;
1534
1535 r = mailimap_userid_send(fd, userid);
1536 if (r != MAILIMAP_NO_ERROR)
1537 return r;
1538
1539 r = mailimap_space_send(fd);
1540 if (r != MAILIMAP_NO_ERROR)
1541 return r;
1542
1543 r = mailimap_password_send(fd, password);
1544 if (r != MAILIMAP_NO_ERROR)
1545 return r;
1546
1547 return MAILIMAP_NO_ERROR;
1548}
1549
1550/*
1551=> lsub = "LSUB" SP mailbox SP list-mailbox
1552*/
1553
1554int mailimap_lsub_send(mailstream * fd,
1555 const char * mb, const char * list_mb)
1556{
1557 int r;
1558
1559 r = mailimap_token_send(fd, "LSUB");
1560 if (r != MAILIMAP_NO_ERROR)
1561 return r;
1562
1563 r = mailimap_space_send(fd);
1564 if (r != MAILIMAP_NO_ERROR)
1565 return r;
1566
1567 r = mailimap_mailbox_send(fd, mb);
1568 if (r != MAILIMAP_NO_ERROR)
1569 return r;
1570
1571 r = mailimap_space_send(fd);
1572 if (r != MAILIMAP_NO_ERROR)
1573 return r;
1574
1575 r = mailimap_list_mailbox_send(fd, list_mb);
1576 if (r != MAILIMAP_NO_ERROR)
1577 return r;
1578
1579 return MAILIMAP_NO_ERROR;
1580}
1581
1582/*
1583 mailbox = "INBOX" / astring
1584 ; INBOX is case-insensitive. All case variants of
1585 ; INBOX (e.g. "iNbOx") MUST be interpreted as INBOX
1586 ; not as an astring. An astring which consists of
1587 ; the case-insensitive sequence "I" "N" "B" "O" "X"
1588 ; is considered to be INBOX and not an astring.
1589 ; Refer to section 5.1 for further
1590 ; semantic details of mailbox names.
1591*/
1592
1593static int mailimap_mailbox_send(mailstream * fd, const char * mb)
1594{
1595 return mailimap_astring_send(fd, mb);
1596}
1597
1598/*
1599 mailbox-data = "FLAGS" SP flag-list / "LIST" SP mailbox-list /
1600 "LSUB" SP mailbox-list / "SEARCH" *(SP nz-number) /
1601 "STATUS" SP mailbox SP "("
1602 [status-att SP number *(SP status-att SP number)] ")" /
1603 number SP "EXISTS" / number SP "RECENT"
1604
1605 mailbox-list = "(" [mbx-list-flags] ")" SP
1606 (DQUOTE QUOTED-CHAR DQUOTE / nil) SP mailbox
1607
1608 mbx-list-flags = *(mbx-list-oflag SP) mbx-list-sflag
1609 *(SP mbx-list-oflag) /
1610 mbx-list-oflag *(SP mbx-list-oflag)
1611
1612 mbx-list-oflag = "\Noinferiors" / flag-extension
1613 ; Other flags; multiple possible per LIST response
1614
1615 mbx-list-sflag = "\Noselect" / "\Marked" / "\Unmarked"
1616 ; Selectability flags; only one per LIST response
1617
1618 media-basic = ((DQUOTE ("APPLICATION" / "AUDIO" / "IMAGE" / "MESSAGE" /
1619 "VIDEO") DQUOTE) / string) SP media-subtype
1620 ; Defined in [MIME-IMT]
1621
1622 media-message = DQUOTE "MESSAGE" DQUOTE SP DQUOTE "RFC822" DQUOTE
1623 ; Defined in [MIME-IMT]
1624
1625 media-subtype = string
1626 ; Defined in [MIME-IMT]
1627
1628 media-text = DQUOTE "TEXT" DQUOTE SP media-subtype
1629 ; Defined in [MIME-IMT]
1630
1631 message-data = nz-number SP ("EXPUNGE" / ("FETCH" SP msg-att))
1632
1633 msg-att = "(" (msg-att-dynamic / msg-att-static)
1634 *(SP (msg-att-dynamic / msg-att-static)) ")"
1635
1636 msg-att-dynamic = "FLAGS" SP "(" [flag-fetch *(SP flag-fetch)] ")"
1637 ; MAY change for a message
1638
1639 msg-att-static = "ENVELOPE" SP envelope / "INTERNALDATE" SP date-time /
1640 "RFC822" [".HEADER" / ".TEXT"] SP nstring /
1641 "RFC822.SIZE" SP number / "BODY" ["STRUCTURE"] SP body /
1642 "BODY" section ["<" number ">"] SP nstring /
1643 "UID" SP uniqueid
1644 ; MUST NOT change for a message
1645
1646 nil = "NIL"
1647
1648 nstring = string / nil
1649*/
1650
1651/*
1652=> number = 1*DIGIT
1653 ; Unsigned 32-bit integer
1654 ; (0 <= n < 4,294,967,296)
1655*/
1656
1657/*
1658 nz-number = digit-nz *DIGIT
1659 ; Non-zero unsigned 32-bit integer
1660 ; (0 < n < 4,294,967,296)
1661*/
1662
1663static int mailimap_number_send(mailstream * fd, uint32_t number)
1664{
1665 int r;
1666
1667 if (number / 10 != 0) {
1668 r = mailimap_number_send(fd, number / 10);
1669 if (r != MAILIMAP_NO_ERROR)
1670 return r;
1671 }
1672
1673 r = mailimap_digit_send(fd, number % 10);
1674 if (r != MAILIMAP_NO_ERROR)
1675 return r;
1676
1677 return MAILIMAP_NO_ERROR;
1678}
1679
1680/*
1681=> password = astring
1682*/
1683
1684static int mailimap_password_send(mailstream * fd, const char * pass)
1685{
1686 return mailimap_astring_send(fd, pass);
1687}
1688
1689/*
1690=> quoted = DQUOTE *QUOTED-CHAR DQUOTE
1691
1692=> QUOTED-CHAR = <any TEXT-CHAR except quoted-specials> /
1693 "\" quoted-specials
1694
1695=> quoted-specials = DQUOTE / "\"
1696*/
1697
1698static int is_quoted_specials(char ch)
1699{
1700 return (ch == '\"') || (ch == '\\');
1701}
1702
1703static int mailimap_quoted_char_send(mailstream * fd, char ch)
1704{
1705 int r;
1706
1707 if (is_quoted_specials(ch)) {
1708 r = mailimap_char_send(fd, '\\');
1709 if (r != MAILIMAP_NO_ERROR)
1710 return r;
1711 r = mailimap_char_send(fd, ch);
1712 if (r != MAILIMAP_NO_ERROR)
1713 return r;
1714
1715 return MAILIMAP_NO_ERROR;
1716 }
1717 else
1718 return mailimap_char_send(fd, ch);
1719}
1720
1721static int mailimap_quoted_send(mailstream * fd, const char * quoted)
1722{
1723 const char * pos;
1724 int r;
1725
1726 pos = quoted;
1727
1728 r = mailimap_dquote_send(fd);
1729 if (r != MAILIMAP_NO_ERROR)
1730 return r;
1731
1732 while (* pos != 0) {
1733 r = mailimap_quoted_char_send(fd, * pos);
1734 if (r != MAILIMAP_NO_ERROR)
1735 return r;
1736 pos ++;
1737 }
1738
1739 r = mailimap_dquote_send(fd);
1740 if (r != MAILIMAP_NO_ERROR)
1741 return r;
1742
1743 return MAILIMAP_NO_ERROR;
1744}
1745
1746/*
1747=> rename = "RENAME" SP mailbox SP mailbox
1748 ; Use of INBOX as a destination gives a NO error
1749*/
1750
1751int mailimap_rename_send(mailstream * fd, const char * mb,
1752 const char * new_name)
1753{
1754 int r;
1755
1756 r = mailimap_token_send(fd, "RENAME");
1757 if (r != MAILIMAP_NO_ERROR)
1758 return r;
1759 r = mailimap_space_send(fd);
1760 if (r != MAILIMAP_NO_ERROR)
1761 return r;
1762 r = mailimap_mailbox_send(fd, mb);
1763 if (r != MAILIMAP_NO_ERROR)
1764 return r;
1765 r = mailimap_space_send(fd);
1766 if (r != MAILIMAP_NO_ERROR)
1767 return r;
1768 r = mailimap_mailbox_send(fd, new_name);
1769 if (r != MAILIMAP_NO_ERROR)
1770 return r;
1771
1772 return MAILIMAP_NO_ERROR;
1773}
1774
1775/*
1776 response = *(continue-req / response-data) response-done
1777
1778 response-data = "*" SP (resp-cond-state / resp-cond-bye /
1779 mailbox-data / message-data / capability-data) CRLF
1780
1781 response-done = response-tagged / response-fatal
1782
1783 response-fatal = "*" SP resp-cond-bye CRLF
1784 ; Server closes connection immediately
1785
1786 response-tagged = tag SP resp-cond-state CRLF
1787
1788 resp-cond-auth = ("OK" / "PREAUTH") SP resp-text
1789 ; Authentication condition
1790
1791 resp-cond-bye = "BYE" SP resp-text
1792
1793 resp-cond-state = ("OK" / "NO" / "BAD") SP resp-text
1794 ; Status condition
1795
1796 resp-specials = "]"
1797
1798 resp-text = ["[" resp-text-code "]" SP] text
1799
1800 resp-text-code = "ALERT" /
1801 "BADCHARSET" [SP "(" astring *(SP astring) ")" ] /
1802 capability-data / "PARSE" /
1803 "PERMANENTFLAGS" SP "(" [flag-perm *(SP flag-perm)] ")" /
1804 "READ-ONLY" / "READ-WRITE" / "TRYCREATE" /
1805 "UIDNEXT" SP nz-number / "UIDVALIDITY" SP nz-number /
1806 "UNSEEN" SP nz-number /
1807 atom [SP 1*<any TEXT-CHAR except "]">]
1808*/
1809
1810/*
1811=> search = "SEARCH" [SP "CHARSET" SP astring] 1*(SP search-key)
1812 ; CHARSET argument to MUST be registered with IANA
1813*/
1814
1815int
1816mailimap_search_send(mailstream * fd, const char * charset,
1817 struct mailimap_search_key * key)
1818{
1819 int r;
1820
1821 r = mailimap_token_send(fd, "SEARCH");
1822 if (r != MAILIMAP_NO_ERROR)
1823 return r;
1824
1825 if (charset != NULL) {
1826 r = mailimap_space_send(fd);
1827 if (r != MAILIMAP_NO_ERROR)
1828 return r;
1829
1830 r = mailimap_token_send(fd, "CHARSET");
1831 if (r != MAILIMAP_NO_ERROR)
1832 return r;
1833 r = mailimap_space_send(fd);
1834 if (r != MAILIMAP_NO_ERROR)
1835 return r;
1836 r = mailimap_astring_send(fd, charset);
1837 if (r != MAILIMAP_NO_ERROR)
1838 return r;
1839 }
1840
1841 r = mailimap_space_send(fd);
1842 if (r != MAILIMAP_NO_ERROR)
1843 return r;
1844
1845 r = mailimap_search_key_send(fd, key);
1846 if (r != MAILIMAP_NO_ERROR)
1847 return r;
1848
1849 return MAILIMAP_NO_ERROR;
1850}
1851
1852int
1853mailimap_uid_search_send(mailstream * fd, const char * charset,
1854 struct mailimap_search_key * key)
1855{
1856 int r;
1857
1858 r = mailimap_token_send(fd, "UID");
1859 if (r != MAILIMAP_NO_ERROR)
1860 return r;
1861
1862 r = mailimap_space_send(fd);
1863 if (r != MAILIMAP_NO_ERROR)
1864 return r;
1865
1866 return mailimap_search_send(fd, charset, key);
1867}
1868
1869
1870/*
1871=> search-key = "ALL" / "ANSWERED" / "BCC" SP astring /
1872 "BEFORE" SP date / "BODY" SP astring /
1873 "CC" SP astring / "DELETED" / "FLAGGED" /
1874 "FROM" SP astring / "KEYWORD" SP flag-keyword / "NEW" /
1875 "OLD" / "ON" SP date / "RECENT" / "SEEN" /
1876 "SINCE" SP date / "SUBJECT" SP astring /
1877 "TEXT" SP astring / "TO" SP astring /
1878 "UNANSWERED" / "UNDELETED" / "UNFLAGGED" /
1879 "UNKEYWORD" SP flag-keyword / "UNSEEN" /
1880 ; Above this line were in [IMAP2]
1881 "DRAFT" / "HEADER" SP header-fld-name SP astring /
1882 "LARGER" SP number / "NOT" SP search-key /
1883 "OR" SP search-key SP search-key /
1884 "SENTBEFORE" SP date / "SENTON" SP date /
1885 "SENTSINCE" SP date / "SMALLER" SP number /
1886 "UID" SP set / "UNDRAFT" / set /
1887 "(" search-key *(SP search-key) ")"
1888*/
1889
1890
1891static int mailimap_search_key_send(mailstream * fd,
1892 struct mailimap_search_key * key)
1893{
1894 int r;
1895
1896 switch (key->sk_type) {
1897
1898 case MAILIMAP_SEARCH_KEY_ALL:
1899 return mailimap_token_send(fd, "ALL");
1900
1901 case MAILIMAP_SEARCH_KEY_ANSWERED:
1902 return mailimap_token_send(fd, "ANSWERED");
1903
1904 case MAILIMAP_SEARCH_KEY_BCC:
1905 r = mailimap_token_send(fd, "BCC");
1906 if (r != MAILIMAP_NO_ERROR)
1907 return r;
1908 r = mailimap_space_send(fd);
1909 if (r != MAILIMAP_NO_ERROR)
1910 return r;
1911 r = mailimap_astring_send(fd, key->sk_data.sk_bcc);
1912 if (r != MAILIMAP_NO_ERROR)
1913 return r;
1914 return MAILIMAP_NO_ERROR;
1915
1916 case MAILIMAP_SEARCH_KEY_BEFORE:
1917 r = mailimap_token_send(fd, "BEFORE");
1918 if (r != MAILIMAP_NO_ERROR)
1919 return r;
1920 r = mailimap_space_send(fd);
1921 if (r != MAILIMAP_NO_ERROR)
1922 return r;
1923 r = mailimap_date_send(fd, key->sk_data.sk_before);
1924 if (r != MAILIMAP_NO_ERROR)
1925 return r;
1926 return MAILIMAP_NO_ERROR;
1927
1928 case MAILIMAP_SEARCH_KEY_BODY:
1929 r = mailimap_token_send(fd, "BODY");
1930 if (r != MAILIMAP_NO_ERROR)
1931 return r;
1932 r = mailimap_space_send(fd);
1933 if (r != MAILIMAP_NO_ERROR)
1934 return r;
1935 r = mailimap_astring_send(fd, key->sk_data.sk_body);
1936 if (r != MAILIMAP_NO_ERROR)
1937 return r;
1938 return MAILIMAP_NO_ERROR;
1939
1940 case MAILIMAP_SEARCH_KEY_CC:
1941 r = mailimap_token_send(fd, "CC");
1942 if (r != MAILIMAP_NO_ERROR)
1943 return r;
1944 r = mailimap_space_send(fd);
1945 if (r != MAILIMAP_NO_ERROR)
1946 return r;
1947 r = mailimap_astring_send(fd, key->sk_data.sk_cc);
1948 if (r != MAILIMAP_NO_ERROR)
1949 return r;
1950 return MAILIMAP_NO_ERROR;
1951
1952 case MAILIMAP_SEARCH_KEY_DELETED:
1953 return mailimap_token_send(fd, "DELETED");
1954
1955 case MAILIMAP_SEARCH_KEY_FLAGGED:
1956 return mailimap_token_send(fd, "FLAGGED");
1957
1958 case MAILIMAP_SEARCH_KEY_FROM:
1959 r = mailimap_token_send(fd, "FROM");
1960 if (r != MAILIMAP_NO_ERROR)
1961 return r;
1962 r = mailimap_space_send(fd);
1963 if (r != MAILIMAP_NO_ERROR)
1964 return r;
1965 r = mailimap_astring_send(fd, key->sk_data.sk_from);
1966 if (r != MAILIMAP_NO_ERROR)
1967 return r;
1968 return MAILIMAP_NO_ERROR;
1969
1970 case MAILIMAP_SEARCH_KEY_KEYWORD:
1971 r = mailimap_token_send(fd, "KEYWORD");
1972 if (r != MAILIMAP_NO_ERROR)
1973 return r;
1974 r = mailimap_space_send(fd);
1975 if (r != MAILIMAP_NO_ERROR)
1976 return r;
1977 r = mailimap_flag_keyword_send(fd, key->sk_data.sk_keyword);
1978 if (r != MAILIMAP_NO_ERROR)
1979 return r;
1980 return MAILIMAP_NO_ERROR;
1981
1982 case MAILIMAP_SEARCH_KEY_NEW:
1983 return mailimap_token_send(fd, "NEW");
1984
1985 case MAILIMAP_SEARCH_KEY_OLD:
1986 return mailimap_token_send(fd, "OLD");
1987
1988 case MAILIMAP_SEARCH_KEY_ON:
1989 r = mailimap_token_send(fd, "ON");
1990 if (r != MAILIMAP_NO_ERROR)
1991 return r;
1992 r = mailimap_space_send(fd);
1993 if (r != MAILIMAP_NO_ERROR)
1994 return r;
1995 r = mailimap_date_send(fd, key->sk_data.sk_on);
1996 if (r != MAILIMAP_NO_ERROR)
1997 return r;
1998 return MAILIMAP_NO_ERROR;
1999
2000 case MAILIMAP_SEARCH_KEY_RECENT:
2001 return mailimap_token_send(fd, "RECENT");
2002
2003 case MAILIMAP_SEARCH_KEY_SEEN:
2004 return mailimap_token_send(fd, "SEEN");
2005
2006 case MAILIMAP_SEARCH_KEY_SINCE:
2007 r = mailimap_token_send(fd, "SINCE");
2008 if (r != MAILIMAP_NO_ERROR)
2009 return r;
2010 r = mailimap_space_send(fd);
2011 if (r != MAILIMAP_NO_ERROR)
2012 return r;
2013 r = mailimap_date_send(fd, key->sk_data.sk_since);
2014 if (r != MAILIMAP_NO_ERROR)
2015 return r;
2016 return MAILIMAP_NO_ERROR;
2017
2018 case MAILIMAP_SEARCH_KEY_SUBJECT:
2019 r = mailimap_token_send(fd, "SUBJECT");
2020 if (r != MAILIMAP_NO_ERROR)
2021 return r;
2022 r = mailimap_space_send(fd);
2023 if (r != MAILIMAP_NO_ERROR)
2024 return r;
2025 r = mailimap_astring_send(fd, key->sk_data.sk_subject);
2026 if (r != MAILIMAP_NO_ERROR)
2027 return r;
2028 return MAILIMAP_NO_ERROR;
2029
2030 case MAILIMAP_SEARCH_KEY_TEXT:
2031 r = mailimap_token_send(fd, "TEXT");
2032 if (r != MAILIMAP_NO_ERROR)
2033 return r;
2034 r = mailimap_space_send(fd);
2035 if (r != MAILIMAP_NO_ERROR)
2036 return r;
2037 r = mailimap_astring_send(fd, key->sk_data.sk_text);
2038 if (r != MAILIMAP_NO_ERROR)
2039 return r;
2040 return MAILIMAP_NO_ERROR;
2041
2042 case MAILIMAP_SEARCH_KEY_TO:
2043 r = mailimap_token_send(fd, "TO");
2044 if (r != MAILIMAP_NO_ERROR)
2045 return r;
2046 r = mailimap_space_send(fd);
2047 if (r != MAILIMAP_NO_ERROR)
2048 return r;
2049 r = mailimap_astring_send(fd, key->sk_data.sk_text);
2050 if (r != MAILIMAP_NO_ERROR)
2051 return r;
2052 return MAILIMAP_NO_ERROR;
2053
2054 case MAILIMAP_SEARCH_KEY_UNANSWERED:
2055 return mailimap_token_send(fd, "UNANSWERED");
2056
2057 case MAILIMAP_SEARCH_KEY_UNDELETED:
2058 return mailimap_token_send(fd, "UNDELETED");
2059
2060 case MAILIMAP_SEARCH_KEY_UNFLAGGED:
2061 return mailimap_token_send(fd, "UNFLAGGED");
2062
2063 case MAILIMAP_SEARCH_KEY_UNKEYWORD:
2064 r = mailimap_token_send(fd, "UNKEYWORD");
2065 if (r != MAILIMAP_NO_ERROR)
2066 return r;
2067 r = mailimap_space_send(fd);
2068 if (r != MAILIMAP_NO_ERROR)
2069 return r;
2070 r = mailimap_flag_keyword_send(fd, key->sk_data.sk_keyword);
2071 if (r != MAILIMAP_NO_ERROR)
2072 return r;
2073 return MAILIMAP_NO_ERROR;
2074
2075 case MAILIMAP_SEARCH_KEY_UNSEEN:
2076 return mailimap_token_send(fd, "UNSEEN");
2077
2078 case MAILIMAP_SEARCH_KEY_DRAFT:
2079 return mailimap_token_send(fd, "DRAFT");
2080
2081 case MAILIMAP_SEARCH_KEY_HEADER:
2082 r = mailimap_token_send(fd, "HEADER");
2083 if (r != MAILIMAP_NO_ERROR)
2084 return r;
2085 r = mailimap_space_send(fd);
2086 if (r != MAILIMAP_NO_ERROR)
2087 return r;
2088 r = mailimap_header_fld_name_send(fd,
2089 key->sk_data.sk_header.sk_header_name);
2090 if (r != MAILIMAP_NO_ERROR)
2091 return r;
2092 r = mailimap_space_send(fd);
2093 if (r != MAILIMAP_NO_ERROR)
2094 return r;
2095 r = mailimap_astring_send(fd,
2096 key->sk_data.sk_header.sk_header_value);
2097 if (r != MAILIMAP_NO_ERROR)
2098 return r;
2099 return MAILIMAP_NO_ERROR;
2100
2101 case MAILIMAP_SEARCH_KEY_LARGER:
2102 r = mailimap_token_send(fd, "LARGER");
2103 if (r != MAILIMAP_NO_ERROR)
2104 return r;
2105 r = mailimap_space_send(fd);
2106 if (r != MAILIMAP_NO_ERROR)
2107 return r;
2108 r = mailimap_number_send(fd, key->sk_data.sk_larger);
2109 if (r != MAILIMAP_NO_ERROR)
2110 return r;
2111 return MAILIMAP_NO_ERROR;
2112
2113 case MAILIMAP_SEARCH_KEY_NOT:
2114 r = mailimap_token_send(fd, "NOT");
2115 if (r != MAILIMAP_NO_ERROR)
2116 return r;
2117 r = mailimap_space_send(fd);
2118 if (r != MAILIMAP_NO_ERROR)
2119 return r;
2120 r = mailimap_search_key_send(fd, key->sk_data.sk_not);
2121 if (r != MAILIMAP_NO_ERROR)
2122 return r;
2123 return MAILIMAP_NO_ERROR;
2124
2125 case MAILIMAP_SEARCH_KEY_OR:
2126 r = mailimap_token_send(fd, "OR");
2127 if (r != MAILIMAP_NO_ERROR)
2128 return r;
2129 r = mailimap_space_send(fd);
2130 if (r != MAILIMAP_NO_ERROR)
2131 return r;
2132 r = mailimap_search_key_send(fd, key->sk_data.sk_or.sk_or1);
2133 if (r != MAILIMAP_NO_ERROR)
2134 return r;
2135 r = mailimap_space_send(fd);
2136 if (r != MAILIMAP_NO_ERROR)
2137 return r;
2138 r = mailimap_search_key_send(fd, key->sk_data.sk_or.sk_or2);
2139 if (r != MAILIMAP_NO_ERROR)
2140 return r;
2141 return TRUE;
2142
2143 case MAILIMAP_SEARCH_KEY_SENTBEFORE:
2144 r = mailimap_token_send(fd, "SENTBEFORE");
2145 if (r != MAILIMAP_NO_ERROR)
2146 return r;
2147 r = mailimap_space_send(fd);
2148 if (r != MAILIMAP_NO_ERROR)
2149 return r;
2150 r = mailimap_date_send(fd, key->sk_data.sk_sentbefore);
2151 if (r != MAILIMAP_NO_ERROR)
2152 return r;
2153 return MAILIMAP_NO_ERROR;
2154
2155 case MAILIMAP_SEARCH_KEY_SENTON:
2156 r = mailimap_token_send(fd, "SENTON");
2157 if (r != MAILIMAP_NO_ERROR)
2158 return r;
2159 r = mailimap_space_send(fd);
2160 if (r != MAILIMAP_NO_ERROR)
2161 return r;
2162 r = mailimap_date_send(fd, key->sk_data.sk_senton);
2163 if (r != MAILIMAP_NO_ERROR)
2164 return r;
2165 return MAILIMAP_NO_ERROR;
2166
2167 case MAILIMAP_SEARCH_KEY_SENTSINCE:
2168 r = mailimap_token_send(fd, "SENTSINCE");
2169 if (r != MAILIMAP_NO_ERROR)
2170 return r;
2171 r = mailimap_space_send(fd);
2172 if (r != MAILIMAP_NO_ERROR)
2173 return r;
2174 r = mailimap_date_send(fd, key->sk_data.sk_sentsince);
2175 if (r != MAILIMAP_NO_ERROR)
2176 return r;
2177 return MAILIMAP_NO_ERROR;
2178
2179 case MAILIMAP_SEARCH_KEY_SMALLER:
2180 r = mailimap_token_send(fd, "SMALLER");
2181 if (r != MAILIMAP_NO_ERROR)
2182 return r;
2183 r = mailimap_space_send(fd);
2184 if (r != MAILIMAP_NO_ERROR)
2185 return r;
2186 r = mailimap_number_send(fd, key->sk_data.sk_smaller);
2187 if (r != MAILIMAP_NO_ERROR)
2188 return r;
2189 return MAILIMAP_NO_ERROR;
2190
2191 case MAILIMAP_SEARCH_KEY_UID:
2192 r = mailimap_token_send(fd, "UID");
2193 if (r != MAILIMAP_NO_ERROR)
2194 return r;
2195 r = mailimap_space_send(fd);
2196 if (r != MAILIMAP_NO_ERROR)
2197 return r;
2198 r = mailimap_set_send(fd, key->sk_data.sk_set);
2199 if (r != MAILIMAP_NO_ERROR)
2200 return r;
2201 return MAILIMAP_NO_ERROR;
2202
2203 case MAILIMAP_SEARCH_KEY_UNDRAFT:
2204 return mailimap_token_send(fd, "UNDRAFT");
2205
2206 case MAILIMAP_SEARCH_KEY_SET:
2207 return mailimap_set_send(fd, key->sk_data.sk_set);
2208
2209 case MAILIMAP_SEARCH_KEY_MULTIPLE:
2210 r = mailimap_oparenth_send(fd);
2211 if (r != MAILIMAP_NO_ERROR)
2212 return r;
2213
2214 r = mailimap_struct_spaced_list_send(fd, key->sk_data.sk_multiple,
2215 (mailimap_struct_sender *)
2216 mailimap_search_key_send);
2217 if (r != MAILIMAP_NO_ERROR)
2218 return r;
2219
2220 r = mailimap_cparenth_send(fd);
2221 if (r != MAILIMAP_NO_ERROR)
2222 return r;
2223
2224 return MAILIMAP_NO_ERROR;
2225 default:
2226 /* should not happend */
2227 return MAILIMAP_ERROR_INVAL;
2228 }
2229}
2230
2231/*
2232=> section = "[" [section-spec] "]"
2233*/
2234
2235static int
2236mailimap_section_send(mailstream * fd,
2237 struct mailimap_section * section)
2238{
2239 int r;
2240
2241 r = mailimap_char_send(fd, '[');
2242 if (r != MAILIMAP_NO_ERROR)
2243 return r;
2244
2245 if (section != NULL) {
2246 if (section->sec_spec != NULL) {
2247 r = mailimap_section_spec_send(fd, section->sec_spec);
2248 if (r != MAILIMAP_NO_ERROR)
2249 return r;
2250 }
2251 }
2252
2253 r = mailimap_char_send(fd, ']');
2254 if (r != MAILIMAP_NO_ERROR)
2255 return r;
2256
2257 return MAILIMAP_NO_ERROR;
2258}
2259
2260/*
2261=> section-msgtext = "HEADER" / "HEADER.FIELDS" [".NOT"] SP header-list /
2262 "TEXT"
2263 ; top-level or MESSAGE/RFC822 part
2264*/
2265
2266static int
2267mailimap_section_msgtext_send(mailstream * fd,
2268 struct mailimap_section_msgtext *
2269 section_msgtext)
2270{
2271 int r;
2272
2273 switch (section_msgtext->sec_type) {
2274 case MAILIMAP_SECTION_MSGTEXT_HEADER:
2275 return mailimap_token_send(fd, "HEADER");
2276
2277 case MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS:
2278 r = mailimap_token_send(fd, "HEADER.FIELDS");
2279 if (r != MAILIMAP_NO_ERROR)
2280 return r;
2281 r = mailimap_space_send(fd);
2282 if (r != MAILIMAP_NO_ERROR)
2283 return r;
2284 r = mailimap_header_list_send(fd, section_msgtext->sec_header_list);
2285 if (r != MAILIMAP_NO_ERROR)
2286 return r;
2287 return MAILIMAP_NO_ERROR;
2288
2289 case MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS_NOT:
2290 r = mailimap_token_send(fd, "HEADER.FIELDS.NOT");
2291 if (r != MAILIMAP_NO_ERROR)
2292 return r;
2293 r = mailimap_space_send(fd);
2294 if (r != MAILIMAP_NO_ERROR)
2295 return r;
2296 r = mailimap_header_list_send(fd, section_msgtext->sec_header_list);
2297 if (r != MAILIMAP_NO_ERROR)
2298 return r;
2299 return MAILIMAP_NO_ERROR;
2300
2301 case MAILIMAP_SECTION_MSGTEXT_TEXT:
2302 return mailimap_token_send(fd, "TEXT");
2303
2304 default:
2305 /* should not happend */
2306 return MAILIMAP_ERROR_INVAL;
2307 }
2308}
2309
2310/*
2311=> section-part = nz-number *("." nz-number)
2312 ; body part nesting
2313*/
2314
2315static int
2316mailimap_pnumber_send(mailstream * fd, uint32_t * pnumber)
2317{
2318 return mailimap_number_send(fd, * pnumber);
2319}
2320
2321static int
2322mailimap_section_part_send(mailstream * fd,
2323 struct mailimap_section_part * section)
2324{
2325 int r;
2326
2327 r = mailimap_struct_list_send(fd, section->sec_id, '.',
2328 (mailimap_struct_sender *) mailimap_pnumber_send);
2329 if (r != MAILIMAP_NO_ERROR)
2330 return r;
2331
2332 return MAILIMAP_NO_ERROR;
2333}
2334
2335/*
2336=> section-spec = section-msgtext / (section-part ["." section-text])
2337*/
2338
2339static int
2340mailimap_section_spec_send(mailstream * fd,
2341 struct mailimap_section_spec * section_spec)
2342{
2343 int r;
2344
2345 switch (section_spec->sec_type) {
2346 case MAILIMAP_SECTION_SPEC_SECTION_MSGTEXT:
2347 return mailimap_section_msgtext_send(fd,
2348 section_spec->sec_data.sec_msgtext);
2349
2350 case MAILIMAP_SECTION_SPEC_SECTION_PART:
2351 r = mailimap_section_part_send(fd, section_spec->sec_data.sec_part);
2352 if (r != MAILIMAP_NO_ERROR)
2353 return r;
2354
2355 if (section_spec->sec_text != NULL) {
2356 r = mailimap_char_send(fd, '.');
2357 if (r != MAILIMAP_NO_ERROR)
2358 return r;
2359 r = mailimap_section_text_send(fd,
2360 section_spec->sec_text);
2361 if (r != MAILIMAP_NO_ERROR)
2362 return r;
2363 }
2364
2365 return MAILIMAP_NO_ERROR;
2366
2367 default:
2368 /* should not happen */
2369 return MAILIMAP_ERROR_INVAL;
2370 }
2371}
2372
2373/*
2374=> section-text = section-msgtext / "MIME"
2375 ; text other than actual body part (headers, etc.)
2376*/
2377
2378static int
2379mailimap_section_text_send(mailstream * fd,
2380 struct mailimap_section_text * section_text)
2381{
2382 switch (section_text->sec_type) {
2383 case MAILIMAP_SECTION_TEXT_SECTION_MSGTEXT:
2384 return mailimap_section_msgtext_send(fd, section_text->sec_msgtext);
2385
2386 case MAILIMAP_SECTION_TEXT_MIME:
2387 return mailimap_token_send(fd, "MIME");
2388
2389 default:
2390 /* should not happen */
2391 return MAILIMAP_NO_ERROR;
2392 }
2393}
2394
2395/*
2396=> select = "SELECT" SP mailbox
2397*/
2398
2399int
2400mailimap_select_send(mailstream * fd, const char * mb)
2401{
2402 int r;
2403
2404 r = mailimap_token_send(fd, "SELECT");
2405 if (r != MAILIMAP_NO_ERROR)
2406 return r;
2407 r = mailimap_space_send(fd);
2408 if (r != MAILIMAP_NO_ERROR)
2409 return r;
2410 r = mailimap_mailbox_send(fd, mb);
2411 if (r != MAILIMAP_NO_ERROR)
2412 return r;
2413
2414 return MAILIMAP_NO_ERROR;
2415}
2416
2417/*
2418=> sequence-num = nz-number / "*"
2419 ; * is the largest number in use. For message
2420 ; sequence numbers, it is the number of messages
2421 ; in the mailbox. For unique identifiers, it is
2422 ; the unique identifier of the last message in
2423 ; the mailbox.
2424*/
2425
2426/* if sequence_num == 0 then "*" */
2427
2428static int
2429mailimap_sequence_num_send(mailstream * fd, uint32_t sequence_num)
2430{
2431 if (sequence_num == 0)
2432 return mailimap_char_send(fd, '*');
2433 else
2434 return mailimap_number_send(fd, sequence_num);
2435}
2436
2437/*
2438=> set = sequence-num / (sequence-num ":" sequence-num) /
2439 (set "," set)
2440 ; Identifies a set of messages. For message
2441 ; sequence numbers, these are consecutive
2442 ; numbers from 1 to the number of messages in
2443 ; the mailbox
2444 ; Comma delimits individual numbers, colon
2445 ; delimits between two numbers inclusive.
2446 ; Example: 2,4:7,9,12:* is 2,4,5,6,7,9,12,13,
2447 ; 14,15 for a mailbox with 15 messages.
2448*/
2449
2450static int mailimap_set_item_send(mailstream * fd,
2451 struct mailimap_set_item * item)
2452{
2453 int r;
2454
2455 if (item->set_first == item->set_last)
2456 return mailimap_sequence_num_send(fd, item->set_first);
2457 else {
2458 r = mailimap_sequence_num_send(fd, item->set_first);
2459 if (r != MAILIMAP_NO_ERROR)
2460 return r;
2461 r = mailimap_char_send(fd, ':');
2462 if (r != MAILIMAP_NO_ERROR)
2463 return r;
2464 r = mailimap_sequence_num_send(fd, item->set_last);
2465 if (r != MAILIMAP_NO_ERROR)
2466 return r;
2467 return MAILIMAP_NO_ERROR;
2468 }
2469}
2470
2471static int mailimap_set_send(mailstream * fd,
2472 struct mailimap_set * set)
2473{
2474 return mailimap_struct_list_send(fd, set->set_list, ',',
2475 (mailimap_struct_sender *) mailimap_set_item_send);
2476}
2477
2478/*
2479=> status = "STATUS" SP mailbox SP "(" status-att *(SP status-att) ")"
2480*/
2481
2482static int
2483mailimap_status_att_list_send(mailstream * fd,
2484 struct mailimap_status_att_list * status_att_list)
2485{
2486 return mailimap_struct_spaced_list_send(fd, status_att_list->att_list,
2487 (mailimap_struct_sender *) mailimap_status_att_send);
2488}
2489
2490int
2491mailimap_status_send(mailstream * fd, const char * mb,
2492 struct mailimap_status_att_list * status_att_list)
2493{
2494 int r;
2495
2496 r = mailimap_token_send(fd, "STATUS");
2497 if (r != MAILIMAP_NO_ERROR)
2498 return r;
2499
2500 r = mailimap_space_send(fd);
2501 if (r != MAILIMAP_NO_ERROR)
2502 return r;
2503
2504 r = mailimap_mailbox_send(fd, mb);
2505 if (r != MAILIMAP_NO_ERROR)
2506 return r;
2507
2508 r = mailimap_space_send(fd);
2509 if (r != MAILIMAP_NO_ERROR)
2510 return r;
2511
2512 r = mailimap_char_send(fd, '(');
2513 if (r != MAILIMAP_NO_ERROR)
2514 return r;
2515
2516 r = mailimap_status_att_list_send(fd, status_att_list);
2517 if (r != MAILIMAP_NO_ERROR)
2518 return r;
2519
2520 r = mailimap_char_send(fd, ')');
2521 if (r != MAILIMAP_NO_ERROR)
2522 return r;
2523
2524 return MAILIMAP_NO_ERROR;
2525}
2526
2527/*
2528=> status-att = "MESSAGES" / "RECENT" / "UIDNEXT" / "UIDVALIDITY" /
2529 "UNSEEN"
2530*/
2531
2532
2533static int mailimap_status_att_send(mailstream * fd, int * status_att)
2534{
2535 const char * token;
2536
2537 token = mailimap_status_att_get_token_str(* status_att);
2538 if (token == NULL) {
2539 /* should not happen */
2540 return MAILIMAP_ERROR_INVAL;
2541 }
2542
2543 return mailimap_token_send(fd, token);
2544}
2545
2546/*
2547=> store = "STORE" SP set SP store-att-flags
2548*/
2549
2550int
2551mailimap_store_send(mailstream * fd,
2552 struct mailimap_set * set,
2553 struct mailimap_store_att_flags * store_att_flags)
2554{
2555 int r;
2556
2557 r = mailimap_token_send(fd, "STORE");
2558 if (r != MAILIMAP_NO_ERROR)
2559 return r;
2560 r = mailimap_space_send(fd);
2561 if (r != MAILIMAP_NO_ERROR)
2562 return r;
2563 r = mailimap_set_send(fd, set);
2564 if (r != MAILIMAP_NO_ERROR)
2565 return r;
2566 r = mailimap_space_send(fd);
2567 if (r != MAILIMAP_NO_ERROR)
2568 return r;
2569
2570 r = mailimap_store_att_flags_send(fd, store_att_flags);
2571 if (r != MAILIMAP_NO_ERROR)
2572 return r;
2573
2574 return MAILIMAP_NO_ERROR;
2575}
2576
2577int
2578mailimap_uid_store_send(mailstream * fd,
2579 struct mailimap_set * set,
2580 struct mailimap_store_att_flags * store_att_flags)
2581{
2582 int r;
2583
2584 r = mailimap_token_send(fd, "UID");
2585 if (r != MAILIMAP_NO_ERROR)
2586 return r;
2587 r = mailimap_space_send(fd);
2588 if (r != MAILIMAP_NO_ERROR)
2589 return r;
2590
2591 return mailimap_store_send(fd, set, store_att_flags);
2592}
2593
2594/*
2595=> store-att-flags = (["+" / "-"] "FLAGS" [".SILENT"]) SP
2596 (flag-list / (flag *(SP flag)))
2597*/
2598
2599static int
2600mailimap_store_att_flags_send(mailstream * fd,
2601 struct mailimap_store_att_flags * store_flags)
2602{
2603 int r;
2604
2605 switch (store_flags->fl_sign) {
2606 case 1:
2607 r = mailimap_char_send(fd, '+');
2608 if (r != MAILIMAP_NO_ERROR)
2609 return r;
2610 case -1:
2611 r = mailimap_char_send(fd, '-');
2612 if (r != MAILIMAP_NO_ERROR)
2613 return r;
2614 }
2615
2616 r = mailimap_token_send(fd, "FLAGS");
2617 if (r != MAILIMAP_NO_ERROR)
2618 return r;
2619
2620 if (store_flags->fl_silent) {
2621 r = mailimap_token_send(fd, ".SILENT");
2622 if (r != MAILIMAP_NO_ERROR)
2623 return r;
2624 }
2625
2626 r = mailimap_space_send(fd);
2627 if (r != MAILIMAP_NO_ERROR)
2628 return r;
2629
2630 r = mailimap_flag_list_send(fd, store_flags->fl_flag_list);
2631 if (r != MAILIMAP_NO_ERROR)
2632 return r;
2633
2634 return MAILIMAP_NO_ERROR;
2635}
2636
2637/*
2638 string = quoted / literal
2639*/
2640
2641/*
2642=> subscribe = "SUBSCRIBE" SP mailbox
2643*/
2644
2645int mailimap_subscribe_send(mailstream * fd, const char * mb)
2646{
2647 int r;
2648
2649 r = mailimap_token_send(fd, "SUBSCRIBE");
2650 if (r != MAILIMAP_NO_ERROR)
2651 return r;
2652
2653 r = mailimap_space_send(fd);
2654 if (r != MAILIMAP_NO_ERROR)
2655 return r;
2656
2657 r = mailimap_mailbox_send(fd, mb);
2658 if (r != MAILIMAP_NO_ERROR)
2659 return r;
2660
2661 return MAILIMAP_NO_ERROR;
2662}
2663
2664/*
2665=> tag = 1*<any ASTRING-CHAR except "+">
2666*/
2667
2668int mailimap_tag_send(mailstream * fd, const char * tag)
2669{
2670 return mailimap_token_send(fd, tag);
2671}
2672
2673/*
2674 text = 1*TEXT-CHAR
2675
2676 TEXT-CHAR = <any CHAR except CR and LF>
2677
2678 time = 2DIGIT ":" 2DIGIT ":" 2DIGIT
2679 ; Hours minutes seconds
2680*/
2681
2682/*
2683=> uid = "UID" SP (copy / fetch / search / store)
2684 ; Unique identifiers used instead of message
2685 ; sequence numbers
2686
2687functions uid_copy, uid_fetch ...
2688*/
2689
2690
2691/*
2692 uniqueid = nz-number
2693 ; Strictly ascending
2694*/
2695
2696/*
2697=> unsubscribe = "UNSUBSCRIBE" SP mailbox
2698*/
2699
2700int mailimap_unsubscribe_send(mailstream * fd,
2701 const char * mb)
2702{
2703 int r;
2704
2705 r = mailimap_token_send(fd, "UNSUBSCRIBE");
2706 if (r != MAILIMAP_NO_ERROR)
2707 return r;
2708 r = mailimap_space_send(fd);
2709 if (r != MAILIMAP_NO_ERROR)
2710 return r;
2711 r = mailimap_mailbox_send(fd, mb);
2712 if (r != MAILIMAP_NO_ERROR)
2713 return r;
2714
2715 return MAILIMAP_NO_ERROR;
2716}
2717
2718int mailimap_starttls_send(mailstream * fd)
2719{
2720 return mailimap_token_send(fd, "STARTTLS");
2721}
2722
2723/*
2724=> userid = astring
2725*/
2726
2727static int mailimap_userid_send(mailstream * fd, const char * user)
2728{
2729 return mailimap_astring_send(fd, user);
2730}
2731
2732/*
2733 x-command = "X" atom <experimental command arguments>
2734
2735 zone = ("+" / "-") 4DIGIT
2736 ; Signed four-digit value of hhmm representing
2737 ; hours and minutes east of Greenwich (that is,
2738 ; the amount that the given time differs from
2739 ; Universal Time). Subtracting the timezone
2740 ; from the given time will give the UT form.
2741 ; The Universal Time zone is "+0000".
2742*/
diff --git a/libetpan/src/low-level/imap/mailimap_sender.h b/libetpan/src/low-level/imap/mailimap_sender.h
new file mode 100644
index 0000000..34661f5
--- a/dev/null
+++ b/libetpan/src/low-level/imap/mailimap_sender.h
@@ -0,0 +1,164 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILIMAP_SENDER_H
37
38#define MAILIMAP_SENDER_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include "mailimap_types.h"
45
46int mailimap_append_send(mailstream * fd,
47 const char * mailbox,
48 struct mailimap_flag_list * flag_list,
49 struct mailimap_date_time * date_time,
50 size_t literal_size);
51
52int mailimap_authenticate_send(mailstream * fd,
53 const char * auth_type);
54
55int mailimap_authenticate_resp_send(mailstream * fd,
56 const char * base64);
57
58int mailimap_noop_send(mailstream * fd);
59
60int mailimap_logout_send(mailstream * fd);
61
62int mailimap_capability_send(mailstream * fd);
63
64int mailimap_check_send(mailstream * fd);
65
66int mailimap_close_send(mailstream * fd);
67
68int mailimap_expunge_send(mailstream * fd);
69
70int mailimap_copy_send(mailstream * fd,
71 struct mailimap_set * set,
72 const char * mb);
73
74int mailimap_uid_copy_send(mailstream * fd,
75 struct mailimap_set * set,
76 const char * mb);
77
78int mailimap_create_send(mailstream * fd,
79 const char * mb);
80
81
82int mailimap_delete_send(mailstream * fd, const char * mb);
83
84int mailimap_examine_send(mailstream * fd, const char * mb);
85
86int
87mailimap_fetch_send(mailstream * fd,
88 struct mailimap_set * set,
89 struct mailimap_fetch_type * fetch_type);
90
91int
92mailimap_uid_fetch_send(mailstream * fd,
93 struct mailimap_set * set,
94 struct mailimap_fetch_type * fetch_type);
95
96int mailimap_list_send(mailstream * fd,
97 const char * mb, const char * list_mb);
98
99int mailimap_login_send(mailstream * fd,
100 const char * userid, const char * password);
101
102int mailimap_lsub_send(mailstream * fd,
103 const char * mb, const char * list_mb);
104
105int mailimap_rename_send(mailstream * fd, const char * mb,
106 const char * new_name);
107
108int
109mailimap_search_send(mailstream * fd, const char * charset,
110 struct mailimap_search_key * key);
111
112int
113mailimap_uid_search_send(mailstream * fd, const char * charset,
114 struct mailimap_search_key * key);
115
116int
117mailimap_select_send(mailstream * fd, const char * mb);
118
119int
120mailimap_status_send(mailstream * fd, const char * mb,
121 struct mailimap_status_att_list * status_att_list);
122
123int
124mailimap_store_send(mailstream * fd,
125 struct mailimap_set * set,
126 struct mailimap_store_att_flags * store_att_flags);
127
128int
129mailimap_uid_store_send(mailstream * fd,
130 struct mailimap_set * set,
131 struct mailimap_store_att_flags * store_att_flags);
132
133int mailimap_subscribe_send(mailstream * fd, const char * mb);
134
135
136int mailimap_tag_send(mailstream * fd, const char * tag);
137
138int mailimap_unsubscribe_send(mailstream * fd,
139 const char * mb);
140
141int mailimap_crlf_send(mailstream * fd);
142
143int mailimap_space_send(mailstream * fd);
144
145int
146mailimap_literal_send(mailstream * fd, const char * literal,
147 size_t progr_rate,
148 progress_function * progr_fun);
149
150int
151mailimap_literal_count_send(mailstream * fd, uint32_t count);
152
153int
154mailimap_literal_data_send(mailstream * fd, const char * literal, uint32_t len,
155 size_t progr_rate,
156 progress_function * progr_fun);
157
158int mailimap_starttls_send(mailstream * fd);
159
160#ifdef __cplusplus
161}
162#endif
163
164#endif
diff --git a/libetpan/src/low-level/imap/mailimap_socket.c b/libetpan/src/low-level/imap/mailimap_socket.c
new file mode 100644
index 0000000..01070b1
--- a/dev/null
+++ b/libetpan/src/low-level/imap/mailimap_socket.c
@@ -0,0 +1,73 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailimap_socket.h"
37
38#include "mailimap.h"
39
40#include "connect.h"
41#include <netinet/in.h>
42#include <unistd.h>
43
44#define DEFAULT_IMAP_PORT 143
45#define SERVICE_NAME_IMAP "imap2"
46#define SERVICE_TYPE_TCP "tcp"
47
48int mailimap_socket_connect(mailimap * f, const char * server, uint16_t port)
49{
50 int s;
51 mailstream * stream;
52
53 if (port == 0) {
54 port = mail_get_service_port(SERVICE_NAME_IMAP, SERVICE_TYPE_TCP);
55 if (port == 0)
56 port = DEFAULT_IMAP_PORT;
57 port = ntohs(port);
58 }
59
60 /* Connection */
61
62 s = mail_tcp_connect(server, port);
63 if (s == -1)
64 return MAILIMAP_ERROR_CONNECTION_REFUSED;
65
66 stream = mailstream_socket_open(s);
67 if (stream == NULL) {
68 close(s);
69 return MAILIMAP_ERROR_MEMORY;
70 }
71
72 return mailimap_connect(f, stream);
73}
diff --git a/libetpan/src/low-level/imap/mailimap_socket.h b/libetpan/src/low-level/imap/mailimap_socket.h
new file mode 100644
index 0000000..ed8f369
--- a/dev/null
+++ b/libetpan/src/low-level/imap/mailimap_socket.h
@@ -0,0 +1,54 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILIMAP_SOCKET_H
37
38#define MAILIMAP_SOCKET_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <inttypes.h>
45
46#include <libetpan/mailimap_types.h>
47
48int mailimap_socket_connect(mailimap * f, const char * server, uint16_t port);
49
50#ifdef __cplusplus
51}
52#endif
53
54#endif
diff --git a/libetpan/src/low-level/imap/mailimap_ssl.c b/libetpan/src/low-level/imap/mailimap_ssl.c
new file mode 100644
index 0000000..44ae36e
--- a/dev/null
+++ b/libetpan/src/low-level/imap/mailimap_ssl.c
@@ -0,0 +1,73 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailimap_ssl.h"
37
38#include "mailimap.h"
39
40#include "connect.h"
41#include <netinet/in.h>
42#include <unistd.h>
43
44#define DEFAULT_IMAPS_PORT 993
45#define SERVICE_NAME_IMAPS "imaps"
46#define SERVICE_TYPE_TCP "tcp"
47
48int mailimap_ssl_connect(mailimap * f, const char * server, uint16_t port)
49{
50 int s;
51 mailstream * stream;
52
53 if (port == 0) {
54 port = mail_get_service_port(SERVICE_NAME_IMAPS, SERVICE_TYPE_TCP);
55 if (port == 0)
56 port = DEFAULT_IMAPS_PORT;
57 port = ntohs(port);
58 }
59
60 /* Connection */
61
62 s = mail_tcp_connect(server, port);
63 if (s == -1)
64 return MAILIMAP_ERROR_CONNECTION_REFUSED;
65
66 stream = mailstream_ssl_open(s);
67 if (stream == NULL) {
68 close(s);
69 return MAILIMAP_ERROR_CONNECTION_REFUSED;
70 }
71
72 return mailimap_connect(f, stream);
73}
diff --git a/libetpan/src/low-level/imap/mailimap_ssl.h b/libetpan/src/low-level/imap/mailimap_ssl.h
new file mode 100644
index 0000000..4d5146c
--- a/dev/null
+++ b/libetpan/src/low-level/imap/mailimap_ssl.h
@@ -0,0 +1,54 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILIMAP_SSL_H
37
38#define MAILIMAP_SSL_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <inttypes.h>
45
46#include <libetpan/mailimap_types.h>
47
48int mailimap_ssl_connect(mailimap * f, const char * server, uint16_t port);
49
50#ifdef __cplusplus
51}
52#endif
53
54#endif
diff --git a/libetpan/src/low-level/imap/mailimap_types.c b/libetpan/src/low-level/imap/mailimap_types.c
new file mode 100644
index 0000000..5889f32
--- a/dev/null
+++ b/libetpan/src/low-level/imap/mailimap_types.c
@@ -0,0 +1,2961 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailimap_types.h"
37#include "mmapstring.h"
38#include "mail.h"
39
40#include <stdlib.h>
41
42/* ************************************************************************* */
43/* ************************************************************************* */
44/* ************************************************************************* */
45/* ************************************************************************* */
46/* ************************************************************************* */
47/* ************************************************************************* */
48
49
50
51
52
53
54/* from parser */
55
56
57uint32_t * mailimap_number_alloc_new(uint32_t number)
58{
59 uint32_t * pnumber;
60
61 pnumber = malloc(sizeof(* pnumber));
62 if (pnumber == NULL)
63 return NULL;
64
65 * pnumber = number;
66
67 return pnumber;
68}
69
70void mailimap_number_alloc_free(uint32_t * pnumber)
71{
72 free(pnumber);
73}
74
75
76/* ************************************************************************* */
77
78
79struct mailimap_address *
80mailimap_address_new(char * ad_personal_name, char * ad_source_route,
81 char * ad_mailbox_name, char * ad_host_name)
82{
83 struct mailimap_address * addr;
84
85 addr = malloc(sizeof(* addr));
86 if (addr == NULL)
87 return NULL;
88
89 addr->ad_personal_name = ad_personal_name;
90 addr->ad_source_route = ad_source_route;
91 addr->ad_mailbox_name = ad_mailbox_name;
92 addr->ad_host_name = ad_host_name;
93
94 return addr;
95}
96
97void mailimap_address_free(struct mailimap_address * addr)
98{
99 mailimap_addr_host_free(addr->ad_host_name);
100 mailimap_addr_mailbox_free(addr->ad_mailbox_name);
101 mailimap_addr_adl_free(addr->ad_source_route);
102 mailimap_addr_name_free(addr->ad_personal_name);
103 free(addr);
104}
105
106void mailimap_addr_host_free(char * addr_host)
107{
108 mailimap_nstring_free(addr_host);
109}
110
111void mailimap_addr_mailbox_free(char * addr_mailbox)
112{
113 mailimap_nstring_free(addr_mailbox);
114}
115
116void mailimap_addr_adl_free(char * addr_adl)
117{
118 mailimap_nstring_free(addr_adl);
119}
120
121void mailimap_addr_name_free(char * addr_name)
122{
123 mailimap_nstring_free(addr_name);
124}
125
126
127
128
129
130/*
131struct mailimap_astring *
132mailimap_astring_new(gint type,
133 gchar * atom_astring,
134 gchar * string)
135{
136 struct mailimap_astring * astring;
137
138 astring = g_new(struct mailimap_astring, 1);
139 if (astring == NULL)
140 return FALSE;
141
142 astring->type = type;
143 astring->atom_astring = atom_astring;
144 astring->string = string;
145
146 return astring;
147}
148
149void mailimap_astring_free(struct mailimap_astring * astring)
150{
151 if (astring->atom_astring)
152 mailimap_atom_astring_free(astring->atom_astring);
153 if (astring->string)
154 mailimap_string_free(astring->string);
155 free(astring);
156}
157*/
158
159void mailimap_astring_free(char * astring)
160{
161 if (mmap_string_unref(astring) != 0)
162 free(astring);
163}
164
165static void mailimap_custom_string_free(char * str)
166{
167 free(str);
168}
169
170
171void mailimap_atom_free(char * atom)
172{
173 free(atom);
174}
175
176
177
178
179void mailimap_auth_type_free(char * auth_type)
180{
181 mailimap_atom_free(auth_type);
182}
183
184
185
186
187
188void mailimap_base64_free(char * base64)
189{
190 free(base64);
191}
192
193
194
195
196struct mailimap_body *
197mailimap_body_new(int bd_type,
198 struct mailimap_body_type_1part * bd_body_1part,
199 struct mailimap_body_type_mpart * bd_body_mpart)
200{
201 struct mailimap_body * body;
202
203 body = malloc(sizeof(* body));
204 if (body == NULL)
205 return NULL;
206
207 body->bd_type = bd_type;
208 switch (bd_type) {
209 case MAILIMAP_BODY_1PART:
210 body->bd_data.bd_body_1part = bd_body_1part;
211 break;
212 case MAILIMAP_BODY_MPART:
213 body->bd_data.bd_body_mpart = bd_body_mpart;
214 break;
215 }
216
217 return body;
218}
219
220void mailimap_body_free(struct mailimap_body * body)
221{
222 switch (body->bd_type) {
223 case MAILIMAP_BODY_1PART:
224 mailimap_body_type_1part_free(body->bd_data.bd_body_1part);
225 break;
226 case MAILIMAP_BODY_MPART:
227 mailimap_body_type_mpart_free(body->bd_data.bd_body_mpart);
228 break;
229 }
230 free(body);
231}
232
233
234struct mailimap_body_extension *
235mailimap_body_extension_new(int ext_type, char * ext_nstring,
236 uint32_t ext_number,
237 clist * ext_body_extension_list)
238{
239 struct mailimap_body_extension * body_extension;
240
241 body_extension = malloc(sizeof(* body_extension));
242 if (body_extension == NULL)
243 return NULL;
244
245 body_extension->ext_type = ext_type;
246 switch (ext_type) {
247 case MAILIMAP_BODY_EXTENSION_NSTRING:
248 body_extension->ext_data.ext_nstring = ext_nstring;
249 break;
250 case MAILIMAP_BODY_EXTENSION_NUMBER:
251 body_extension->ext_data.ext_number = ext_number;
252 break;
253 case MAILIMAP_BODY_EXTENSION_LIST:
254 body_extension->ext_data.ext_body_extension_list = ext_body_extension_list;
255 break;
256 }
257
258 return body_extension;
259}
260
261static void
262mailimap_body_ext_list_free(clist * body_ext_list);
263
264void mailimap_body_extension_free(struct mailimap_body_extension * be)
265{
266 switch (be->ext_type) {
267 case MAILIMAP_BODY_EXTENSION_NSTRING:
268 mailimap_nstring_free(be->ext_data.ext_nstring);
269 break;
270 case MAILIMAP_BODY_EXTENSION_LIST:
271 mailimap_body_ext_list_free(be->ext_data.ext_body_extension_list);
272 break;
273 }
274
275 free(be);
276}
277
278
279static void
280mailimap_body_ext_list_free(clist * body_ext_list)
281{
282 clist_foreach(body_ext_list, (clist_func) mailimap_body_extension_free,
283 NULL);
284 clist_free(body_ext_list);
285}
286
287
288struct mailimap_body_ext_1part *
289mailimap_body_ext_1part_new(char * bd_md5,
290 struct mailimap_body_fld_dsp * bd_disposition,
291 struct mailimap_body_fld_lang * bd_language,
292 clist * bd_extension_list)
293{
294 struct mailimap_body_ext_1part * body_ext_1part;
295
296 body_ext_1part = malloc(sizeof(* body_ext_1part));
297 if (body_ext_1part == NULL)
298 return NULL;
299
300 body_ext_1part->bd_md5 = bd_md5;
301 body_ext_1part->bd_disposition = bd_disposition;
302 body_ext_1part->bd_language = bd_language;
303 body_ext_1part->bd_extension_list = bd_extension_list;
304
305 return body_ext_1part;
306}
307
308void
309mailimap_body_ext_1part_free(struct mailimap_body_ext_1part * body_ext_1part)
310{
311 mailimap_body_fld_md5_free(body_ext_1part->bd_md5);
312 if (body_ext_1part->bd_disposition)
313 mailimap_body_fld_dsp_free(body_ext_1part->bd_disposition);
314 if (body_ext_1part->bd_language)
315 mailimap_body_fld_lang_free(body_ext_1part->bd_language);
316 if (body_ext_1part->bd_extension_list)
317 mailimap_body_ext_list_free(body_ext_1part->bd_extension_list);
318
319 free(body_ext_1part);
320}
321
322struct mailimap_body_ext_mpart *
323mailimap_body_ext_mpart_new(struct mailimap_body_fld_param * bd_parameter,
324 struct mailimap_body_fld_dsp * bd_disposition,
325 struct mailimap_body_fld_lang * bd_language,
326 clist * bd_extension_list)
327{
328 struct mailimap_body_ext_mpart * body_ext_mpart;
329
330 body_ext_mpart = malloc(sizeof(* body_ext_mpart));
331 if (body_ext_mpart == NULL)
332 return NULL;
333
334 body_ext_mpart->bd_parameter = bd_parameter;
335 body_ext_mpart->bd_disposition = bd_disposition;
336 body_ext_mpart->bd_language = bd_language;
337 body_ext_mpart->bd_extension_list = bd_extension_list;
338
339 return body_ext_mpart;
340}
341
342void
343mailimap_body_ext_mpart_free(struct mailimap_body_ext_mpart * body_ext_mpart)
344{
345 if (body_ext_mpart->bd_parameter != NULL)
346 mailimap_body_fld_param_free(body_ext_mpart->bd_parameter);
347 if (body_ext_mpart->bd_disposition)
348 mailimap_body_fld_dsp_free(body_ext_mpart->bd_disposition);
349 if (body_ext_mpart->bd_language)
350 mailimap_body_fld_lang_free(body_ext_mpart->bd_language);
351 if (body_ext_mpart->bd_extension_list)
352 mailimap_body_ext_list_free(body_ext_mpart->bd_extension_list);
353 free(body_ext_mpart);
354}
355
356
357struct mailimap_body_fields *
358mailimap_body_fields_new(struct mailimap_body_fld_param * bd_parameter,
359 char * bd_id,
360 char * bd_description,
361 struct mailimap_body_fld_enc * bd_encoding,
362 uint32_t bd_size)
363{
364 struct mailimap_body_fields * body_fields;
365
366 body_fields = malloc(sizeof(* body_fields));
367 if (body_fields == NULL)
368 return NULL;
369 body_fields->bd_parameter = bd_parameter;
370 body_fields->bd_id = bd_id;
371 body_fields->bd_description = bd_description;
372 body_fields->bd_encoding = bd_encoding;
373 body_fields->bd_size = bd_size;
374
375 return body_fields;
376}
377
378void
379mailimap_body_fields_free(struct mailimap_body_fields * body_fields)
380{
381 if (body_fields->bd_parameter != NULL)
382 mailimap_body_fld_param_free(body_fields->bd_parameter);
383 mailimap_body_fld_id_free(body_fields->bd_id);
384 mailimap_body_fld_desc_free(body_fields->bd_description);
385 mailimap_body_fld_enc_free(body_fields->bd_encoding);
386 free(body_fields);
387}
388
389
390
391
392
393
394void mailimap_body_fld_desc_free(char * body_fld_desc)
395{
396 mailimap_nstring_free(body_fld_desc);
397}
398
399
400
401
402struct mailimap_body_fld_dsp *
403mailimap_body_fld_dsp_new(char * dsp_type,
404 struct mailimap_body_fld_param * dsp_attributes)
405{
406 struct mailimap_body_fld_dsp * body_fld_dsp;
407
408 body_fld_dsp = malloc(sizeof(* body_fld_dsp));
409 if (body_fld_dsp == NULL)
410 return NULL;
411
412 body_fld_dsp->dsp_type = dsp_type;
413 body_fld_dsp->dsp_attributes = dsp_attributes;
414
415 return body_fld_dsp;
416}
417
418void mailimap_body_fld_dsp_free(struct mailimap_body_fld_dsp * bfd)
419{
420 if (bfd->dsp_type != NULL)
421 mailimap_string_free(bfd->dsp_type);
422 if (bfd->dsp_attributes != NULL)
423 mailimap_body_fld_param_free(bfd->dsp_attributes);
424 free(bfd);
425}
426
427
428
429struct mailimap_body_fld_enc *
430mailimap_body_fld_enc_new(int enc_type, char * enc_value)
431{
432 struct mailimap_body_fld_enc * body_fld_enc;
433
434 body_fld_enc = malloc(sizeof(* body_fld_enc));
435 if (body_fld_enc == NULL)
436 return NULL;
437
438 body_fld_enc->enc_type = enc_type;
439 body_fld_enc->enc_value = enc_value;
440
441 return body_fld_enc;
442}
443
444void mailimap_body_fld_enc_free(struct mailimap_body_fld_enc * bfe)
445{
446 if (bfe->enc_value)
447 mailimap_string_free(bfe->enc_value);
448 free(bfe);
449}
450
451
452
453void mailimap_body_fld_id_free(char * body_fld_id)
454{
455 mailimap_nstring_free(body_fld_id);
456}
457
458
459
460struct mailimap_body_fld_lang *
461mailimap_body_fld_lang_new(int lg_type, char * lg_single, clist * lg_list)
462{
463 struct mailimap_body_fld_lang * fld_lang;
464
465 fld_lang = malloc(sizeof(* fld_lang));
466 if (fld_lang == NULL)
467 return NULL;
468
469 fld_lang->lg_type = lg_type;
470 switch (lg_type) {
471 case MAILIMAP_BODY_FLD_LANG_SINGLE:
472 fld_lang->lg_data.lg_single = lg_single;
473 break;
474 case MAILIMAP_BODY_FLD_LANG_LIST:
475 fld_lang->lg_data.lg_list = lg_list;
476 break;
477 }
478
479 return fld_lang;
480}
481
482void
483mailimap_body_fld_lang_free(struct mailimap_body_fld_lang * fld_lang)
484{
485 switch (fld_lang->lg_type) {
486 case MAILIMAP_BODY_FLD_LANG_SINGLE:
487 mailimap_nstring_free(fld_lang->lg_data.lg_single);
488 break;
489 case MAILIMAP_BODY_FLD_LANG_LIST:
490 clist_foreach(fld_lang->lg_data.lg_list,
491 (clist_func) mailimap_string_free, NULL);
492 clist_free(fld_lang->lg_data.lg_list);
493 break;
494 }
495 free(fld_lang);
496}
497
498
499
500void mailimap_body_fld_md5_free(char * body_fld_md5)
501{
502 mailimap_nstring_free(body_fld_md5);
503}
504
505
506
507struct mailimap_single_body_fld_param *
508mailimap_single_body_fld_param_new(char * pa_name, char * pa_value)
509{
510 struct mailimap_single_body_fld_param * param;
511
512 param = malloc(sizeof(* param));
513 if (param == NULL)
514 return NULL;
515 param->pa_name = pa_name;
516 param->pa_value = pa_value;
517
518 return param;
519}
520
521void
522mailimap_single_body_fld_param_free(struct mailimap_single_body_fld_param * p)
523{
524 mailimap_string_free(p->pa_name);
525 mailimap_string_free(p->pa_value);
526 free(p);
527}
528
529
530struct mailimap_body_fld_param *
531mailimap_body_fld_param_new(clist * pa_list)
532{
533 struct mailimap_body_fld_param * fld_param;
534
535 fld_param = malloc(sizeof(* fld_param));
536 if (fld_param == NULL)
537 return NULL;
538 fld_param->pa_list = pa_list;
539
540 return fld_param;
541}
542
543void
544mailimap_body_fld_param_free(struct mailimap_body_fld_param * fld_param)
545{
546 clist_foreach(fld_param->pa_list,
547 (clist_func) mailimap_single_body_fld_param_free, NULL);
548 clist_free(fld_param->pa_list);
549 free(fld_param);
550}
551
552
553struct mailimap_body_type_1part *
554mailimap_body_type_1part_new(int bd_type,
555 struct mailimap_body_type_basic * bd_type_basic,
556 struct mailimap_body_type_msg * bd_type_msg,
557 struct mailimap_body_type_text * bd_type_text,
558 struct mailimap_body_ext_1part * bd_ext_1part)
559{
560 struct mailimap_body_type_1part * body_type_1part;
561
562 body_type_1part = malloc(sizeof(* body_type_1part));
563 if (body_type_1part == NULL)
564 return NULL;
565
566 body_type_1part->bd_type = bd_type;
567 switch (bd_type) {
568 case MAILIMAP_BODY_TYPE_1PART_BASIC:
569 body_type_1part->bd_data.bd_type_basic = bd_type_basic;
570 break;
571 case MAILIMAP_BODY_TYPE_1PART_MSG:
572 body_type_1part->bd_data.bd_type_msg = bd_type_msg;
573 break;
574 case MAILIMAP_BODY_TYPE_1PART_TEXT:
575 body_type_1part->bd_data.bd_type_text = bd_type_text;
576 break;
577 }
578 body_type_1part->bd_ext_1part = bd_ext_1part;
579
580 return body_type_1part;
581}
582
583void
584mailimap_body_type_1part_free(struct mailimap_body_type_1part * bt1p)
585{
586 switch (bt1p->bd_type) {
587 case MAILIMAP_BODY_TYPE_1PART_BASIC:
588 mailimap_body_type_basic_free(bt1p->bd_data.bd_type_basic);
589 break;
590 case MAILIMAP_BODY_TYPE_1PART_MSG:
591 mailimap_body_type_msg_free(bt1p->bd_data.bd_type_msg);
592 break;
593 case MAILIMAP_BODY_TYPE_1PART_TEXT:
594 mailimap_body_type_text_free(bt1p->bd_data.bd_type_text);
595 break;
596 }
597 if (bt1p->bd_ext_1part)
598 mailimap_body_ext_1part_free(bt1p->bd_ext_1part);
599
600 free(bt1p);
601}
602
603
604
605struct mailimap_body_type_basic *
606mailimap_body_type_basic_new(struct mailimap_media_basic * bd_media_basic,
607 struct mailimap_body_fields * bd_fields)
608{
609 struct mailimap_body_type_basic * body_type_basic;
610
611 body_type_basic = malloc(sizeof(* body_type_basic));
612 if (body_type_basic == NULL)
613 return NULL;
614
615 body_type_basic->bd_media_basic = bd_media_basic;
616 body_type_basic->bd_fields = bd_fields;
617
618 return body_type_basic;
619}
620
621void mailimap_body_type_basic_free(struct mailimap_body_type_basic *
622 body_type_basic)
623{
624 mailimap_media_basic_free(body_type_basic->bd_media_basic);
625 mailimap_body_fields_free(body_type_basic->bd_fields);
626 free(body_type_basic);
627}
628
629
630struct mailimap_body_type_mpart *
631mailimap_body_type_mpart_new(clist * bd_list, char * bd_media_subtype,
632 struct mailimap_body_ext_mpart * bd_ext_mpart)
633{
634 struct mailimap_body_type_mpart * body_type_mpart;
635
636 body_type_mpart = malloc(sizeof(* body_type_mpart));
637 if (body_type_mpart == NULL)
638 return NULL;
639
640 body_type_mpart->bd_list = bd_list;
641 body_type_mpart->bd_media_subtype = bd_media_subtype;
642 body_type_mpart->bd_ext_mpart = bd_ext_mpart;
643
644 return body_type_mpart;
645}
646
647void mailimap_body_type_mpart_free(struct mailimap_body_type_mpart *
648 body_type_mpart)
649{
650 clist_foreach(body_type_mpart->bd_list,
651 (clist_func) mailimap_body_free, NULL);
652 clist_free(body_type_mpart->bd_list);
653 mailimap_media_subtype_free(body_type_mpart->bd_media_subtype);
654 if (body_type_mpart->bd_ext_mpart)
655 mailimap_body_ext_mpart_free(body_type_mpart->bd_ext_mpart);
656
657 free(body_type_mpart);
658}
659
660
661struct mailimap_body_type_msg *
662mailimap_body_type_msg_new(struct mailimap_body_fields * bd_fields,
663 struct mailimap_envelope * bd_envelope,
664 struct mailimap_body * bd_body,
665 uint32_t bd_lines)
666{
667 struct mailimap_body_type_msg * body_type_msg;
668
669 body_type_msg = malloc(sizeof(* body_type_msg));
670 if (body_type_msg == NULL)
671 return NULL;
672
673 body_type_msg->bd_fields = bd_fields;
674 body_type_msg->bd_envelope = bd_envelope;
675 body_type_msg->bd_body = bd_body;
676 body_type_msg->bd_lines = bd_lines;
677
678 return body_type_msg;
679}
680
681void
682mailimap_body_type_msg_free(struct mailimap_body_type_msg * body_type_msg)
683{
684 mailimap_body_fields_free(body_type_msg->bd_fields);
685 mailimap_envelope_free(body_type_msg->bd_envelope);
686 mailimap_body_free(body_type_msg->bd_body);
687 free(body_type_msg);
688}
689
690
691
692struct mailimap_body_type_text *
693mailimap_body_type_text_new(char * bd_media_text,
694 struct mailimap_body_fields * bd_fields,
695 uint32_t bd_lines)
696{
697 struct mailimap_body_type_text * body_type_text;
698
699 body_type_text = malloc(sizeof(* body_type_text));
700 if (body_type_text == NULL)
701 return NULL;
702
703 body_type_text->bd_media_text = bd_media_text;
704 body_type_text->bd_fields = bd_fields;
705 body_type_text->bd_lines = bd_lines;
706
707 return body_type_text;
708}
709
710void
711mailimap_body_type_text_free(struct mailimap_body_type_text * body_type_text)
712{
713 mailimap_media_text_free(body_type_text->bd_media_text);
714 mailimap_body_fields_free(body_type_text->bd_fields);
715 free(body_type_text);
716}
717
718
719
720struct mailimap_capability *
721mailimap_capability_new(int cap_type, char * cap_auth_type, char * cap_name)
722{
723 struct mailimap_capability * cap;
724
725 cap = malloc(sizeof(* cap));
726 if (cap == NULL)
727 return NULL;
728 cap->cap_type = cap_type;
729 switch (cap_type) {
730 case MAILIMAP_CAPABILITY_AUTH_TYPE:
731 cap->cap_data.cap_auth_type = cap_auth_type;
732 break;
733 case MAILIMAP_CAPABILITY_NAME:
734 cap->cap_data.cap_name = cap_name;
735 break;
736 }
737
738 return cap;
739}
740
741void mailimap_capability_free(struct mailimap_capability * c)
742{
743 switch (c->cap_type) {
744 case MAILIMAP_CAPABILITY_AUTH_TYPE:
745 free(c->cap_data.cap_auth_type);
746 break;
747 case MAILIMAP_CAPABILITY_NAME:
748 free(c->cap_data.cap_name);
749 break;
750 }
751 free(c);
752}
753
754
755struct mailimap_capability_data *
756mailimap_capability_data_new(clist * cap_list)
757{
758 struct mailimap_capability_data * cap_data;
759
760 cap_data = malloc(sizeof(* cap_data));
761 if (cap_data == NULL)
762 return NULL;
763
764 cap_data->cap_list = cap_list;
765
766 return cap_data;
767}
768
769void
770mailimap_capability_data_free(struct mailimap_capability_data * cap_data)
771{
772 if (cap_data->cap_list) {
773 clist_foreach(cap_data->cap_list,
774 (clist_func) mailimap_capability_free, NULL);
775 clist_free(cap_data->cap_list);
776 }
777 free(cap_data);
778}
779
780
781
782
783struct mailimap_continue_req *
784mailimap_continue_req_new(int cr_type, struct mailimap_resp_text * cr_text,
785 char * cr_base64)
786{
787 struct mailimap_continue_req * cont_req;
788
789 cont_req = malloc(sizeof(* cont_req));
790 if (cont_req == NULL)
791 return NULL;
792 cont_req->cr_type = cr_type;
793 switch (cr_type) {
794 case MAILIMAP_CONTINUE_REQ_TEXT:
795 cont_req->cr_data.cr_text = cr_text;
796 break;
797 case MAILIMAP_CONTINUE_REQ_BASE64:
798 cont_req->cr_data.cr_base64 = cr_base64;
799 break;
800 }
801
802 return cont_req;
803}
804
805void mailimap_continue_req_free(struct mailimap_continue_req * cont_req)
806{
807 switch (cont_req->cr_type) {
808 case MAILIMAP_CONTINUE_REQ_TEXT:
809 mailimap_resp_text_free(cont_req->cr_data.cr_text);
810 break;
811 case MAILIMAP_CONTINUE_REQ_BASE64:
812 mailimap_base64_free(cont_req->cr_data.cr_base64);
813 break;
814 }
815 free(cont_req);
816}
817
818struct mailimap_date_time *
819mailimap_date_time_new(int dt_day, int dt_month, int dt_year, int dt_hour,
820 int dt_min, int dt_sec, int dt_zone)
821{
822 struct mailimap_date_time * date_time;
823
824 date_time = malloc(sizeof(* date_time));
825 if (date_time == NULL)
826 return NULL;
827
828 date_time->dt_day = dt_day;
829 date_time->dt_month = dt_month;
830 date_time->dt_year = dt_year;
831 date_time->dt_hour = dt_hour;
832 date_time->dt_min = dt_min;
833 date_time->dt_day = dt_sec;
834 date_time->dt_zone = dt_zone;
835
836 return date_time;
837}
838
839void mailimap_date_time_free(struct mailimap_date_time * date_time)
840{
841 free(date_time);
842}
843
844
845
846struct mailimap_envelope *
847mailimap_envelope_new(char * env_date, char * env_subject,
848 struct mailimap_env_from * env_from,
849 struct mailimap_env_sender * env_sender,
850 struct mailimap_env_reply_to * env_reply_to,
851 struct mailimap_env_to * env_to,
852 struct mailimap_env_cc* env_cc,
853 struct mailimap_env_bcc * env_bcc,
854 char * env_in_reply_to, char * env_message_id)
855{
856 struct mailimap_envelope * env;
857
858 env = malloc(sizeof(* env));
859 if (env == NULL)
860 return NULL;
861
862 env->env_date = env_date;
863 env->env_subject = env_subject;
864 env->env_from = env_from;
865 env->env_sender = env_sender;
866 env->env_reply_to = env_reply_to;
867 env->env_to = env_to;
868 env->env_cc = env_cc;
869 env->env_bcc = env_bcc;
870 env->env_in_reply_to = env_in_reply_to;
871 env->env_message_id = env_message_id;
872
873 return env;
874}
875
876
877void mailimap_envelope_free(struct mailimap_envelope * env)
878{
879 if (env->env_date)
880 mailimap_env_date_free(env->env_date);
881 if (env->env_subject)
882 mailimap_env_subject_free(env->env_subject);
883 if (env->env_from)
884 mailimap_env_from_free(env->env_from);
885 if (env->env_sender)
886 mailimap_env_sender_free(env->env_sender);
887 if (env->env_reply_to)
888 mailimap_env_reply_to_free(env->env_reply_to);
889 if (env->env_to)
890 mailimap_env_to_free(env->env_to);
891 if (env->env_cc)
892 mailimap_env_cc_free(env->env_cc);
893 if (env->env_bcc)
894 mailimap_env_bcc_free(env->env_bcc);
895 if (env->env_in_reply_to)
896 mailimap_env_in_reply_to_free(env->env_in_reply_to);
897 if (env->env_message_id)
898 mailimap_env_message_id_free(env->env_message_id);
899
900 free(env);
901}
902
903
904static void mailimap_address_list_free(clist * addr_list)
905{
906 if (addr_list != NULL) {
907 clist_foreach(addr_list, (clist_func) mailimap_address_free, NULL);
908 clist_free(addr_list);
909 }
910}
911
912
913struct mailimap_env_bcc * mailimap_env_bcc_new(clist * bcc_list)
914{
915 struct mailimap_env_bcc * env_bcc;
916
917 env_bcc = malloc(sizeof(* env_bcc));
918 if (env_bcc == NULL)
919 return NULL;
920 env_bcc->bcc_list = bcc_list;
921
922 return env_bcc;
923}
924
925void mailimap_env_bcc_free(struct mailimap_env_bcc * env_bcc)
926{
927 mailimap_address_list_free(env_bcc->bcc_list);
928 free(env_bcc);
929}
930
931
932struct mailimap_env_cc * mailimap_env_cc_new(clist * cc_list)
933{
934 struct mailimap_env_cc * env_cc;
935
936 env_cc = malloc(sizeof(* env_cc));
937 if (env_cc == NULL)
938 return NULL;
939 env_cc->cc_list = cc_list;
940
941 return env_cc;
942}
943
944void mailimap_env_cc_free(struct mailimap_env_cc * env_cc)
945{
946 mailimap_address_list_free(env_cc->cc_list);
947 free(env_cc);
948}
949
950
951void mailimap_env_date_free(char * date)
952{
953 mailimap_nstring_free(date);
954}
955
956
957struct mailimap_env_from * mailimap_env_from_new(clist * frm_list)
958{
959 struct mailimap_env_from * env_from;
960
961 env_from = malloc(sizeof(* env_from));
962 if (env_from == NULL)
963 return NULL;
964 env_from->frm_list = frm_list;
965
966 return env_from;
967}
968
969void mailimap_env_from_free(struct mailimap_env_from * env_from)
970{
971 mailimap_address_list_free(env_from->frm_list);
972 free(env_from);
973}
974
975
976void mailimap_env_in_reply_to_free(char * in_reply_to)
977{
978 mailimap_nstring_free(in_reply_to);
979}
980
981void mailimap_env_message_id_free(char * message_id)
982{
983 mailimap_nstring_free(message_id);
984}
985
986struct mailimap_env_reply_to * mailimap_env_reply_to_new(clist * rt_list)
987{
988 struct mailimap_env_reply_to * env_reply_to;
989
990 env_reply_to = malloc(sizeof(* env_reply_to));
991 if (env_reply_to == NULL)
992 return NULL;
993 env_reply_to->rt_list = rt_list;
994
995 return env_reply_to;
996}
997
998void
999mailimap_env_reply_to_free(struct mailimap_env_reply_to * env_reply_to)
1000{
1001 mailimap_address_list_free(env_reply_to->rt_list);
1002 free(env_reply_to);
1003}
1004
1005struct mailimap_env_sender * mailimap_env_sender_new(clist * snd_list)
1006{
1007 struct mailimap_env_sender * env_sender;
1008
1009 env_sender = malloc(sizeof(* env_sender));
1010 if (env_sender == NULL)
1011 return NULL;
1012 env_sender->snd_list = snd_list;
1013
1014 return env_sender;
1015}
1016
1017void mailimap_env_sender_free(struct mailimap_env_sender * env_sender)
1018{
1019 mailimap_address_list_free(env_sender->snd_list);
1020 free(env_sender);
1021}
1022
1023void mailimap_env_subject_free(char * subject)
1024{
1025 mailimap_nstring_free(subject);
1026}
1027
1028struct mailimap_env_to * mailimap_env_to_new(clist * to_list)
1029{
1030 struct mailimap_env_to * env_to;
1031
1032 env_to = malloc(sizeof(* env_to));
1033 if (env_to == NULL)
1034 return NULL;
1035 env_to->to_list = to_list;
1036
1037 return env_to;
1038}
1039
1040void mailimap_env_to_free(struct mailimap_env_to * env_to)
1041{
1042 mailimap_address_list_free(env_to->to_list);
1043 free(env_to);
1044}
1045
1046
1047
1048struct mailimap_flag * mailimap_flag_new(int fl_type,
1049 char * fl_keyword, char * fl_extension)
1050{
1051 struct mailimap_flag * f;
1052
1053 f = malloc(sizeof(* f));
1054 if (f == NULL)
1055 return NULL;
1056 f->fl_type = fl_type;
1057 switch (fl_type) {
1058 case MAILIMAP_FLAG_KEYWORD:
1059 f->fl_data.fl_keyword = fl_keyword;
1060 break;
1061 case MAILIMAP_FLAG_EXTENSION:
1062 f->fl_data.fl_extension = fl_extension;
1063 break;
1064 }
1065
1066 return f;
1067}
1068
1069void mailimap_flag_free(struct mailimap_flag * f)
1070{
1071 switch (f->fl_type) {
1072 case MAILIMAP_FLAG_KEYWORD:
1073 mailimap_flag_keyword_free(f->fl_data.fl_keyword);
1074 break;
1075 case MAILIMAP_FLAG_EXTENSION:
1076 mailimap_flag_extension_free(f->fl_data.fl_extension);
1077 break;
1078 }
1079 free(f);
1080}
1081
1082
1083
1084void mailimap_flag_extension_free(char * flag_extension)
1085{
1086 mailimap_atom_free(flag_extension);
1087}
1088
1089
1090
1091struct mailimap_flag_fetch *
1092mailimap_flag_fetch_new(int fl_type, struct mailimap_flag * fl_flag)
1093{
1094 struct mailimap_flag_fetch * flag_fetch;
1095
1096 flag_fetch = malloc(sizeof(* flag_fetch));
1097 if (flag_fetch == NULL)
1098 return NULL;
1099
1100 flag_fetch->fl_type = fl_type;
1101 flag_fetch->fl_flag = fl_flag;
1102
1103 return flag_fetch;
1104}
1105
1106void mailimap_flag_fetch_free(struct mailimap_flag_fetch * flag_fetch)
1107{
1108 if (flag_fetch->fl_flag)
1109 mailimap_flag_free(flag_fetch->fl_flag);
1110 free(flag_fetch);
1111}
1112
1113
1114
1115void mailimap_flag_keyword_free(char * flag_keyword)
1116{
1117 mailimap_atom_free(flag_keyword);
1118}
1119
1120
1121
1122
1123struct mailimap_flag_list *
1124mailimap_flag_list_new(clist * fl_list)
1125{
1126 struct mailimap_flag_list * flag_list;
1127
1128 flag_list = malloc(sizeof(* flag_list));
1129 if (flag_list == NULL)
1130 return NULL;
1131 flag_list->fl_list = fl_list;
1132
1133 return flag_list;
1134}
1135
1136void mailimap_flag_list_free(struct mailimap_flag_list * flag_list)
1137{
1138 clist_foreach(flag_list->fl_list, (clist_func) mailimap_flag_free, NULL);
1139 clist_free(flag_list->fl_list);
1140 free(flag_list);
1141}
1142
1143
1144
1145
1146
1147struct mailimap_flag_perm *
1148mailimap_flag_perm_new(int fl_type, struct mailimap_flag * fl_flag)
1149{
1150 struct mailimap_flag_perm * flag_perm;
1151
1152 flag_perm = malloc(sizeof(* flag_perm));
1153 if (flag_perm == NULL)
1154 return NULL;
1155
1156 flag_perm->fl_type = fl_type;
1157 flag_perm->fl_flag = fl_flag;
1158
1159 return flag_perm;
1160}
1161
1162void mailimap_flag_perm_free(struct mailimap_flag_perm * flag_perm)
1163{
1164 if (flag_perm->fl_flag != NULL)
1165 mailimap_flag_free(flag_perm->fl_flag);
1166 free(flag_perm);
1167}
1168
1169
1170
1171
1172struct mailimap_greeting *
1173mailimap_greeting_new(int gr_type,
1174 struct mailimap_resp_cond_auth * gr_auth,
1175 struct mailimap_resp_cond_bye * gr_bye)
1176{
1177 struct mailimap_greeting * greeting;
1178
1179 greeting = malloc(sizeof(* greeting));
1180 if (greeting == NULL)
1181 return NULL;
1182 greeting->gr_type = gr_type;
1183 switch (gr_type) {
1184 case MAILIMAP_GREETING_RESP_COND_AUTH:
1185 greeting->gr_data.gr_auth = gr_auth;
1186 break;
1187 case MAILIMAP_GREETING_RESP_COND_BYE:
1188 greeting->gr_data.gr_bye = gr_bye;
1189 break;
1190 }
1191
1192 return greeting;
1193}
1194
1195void mailimap_greeting_free(struct mailimap_greeting * greeting)
1196{
1197 switch (greeting->gr_type) {
1198 case MAILIMAP_GREETING_RESP_COND_AUTH:
1199 mailimap_resp_cond_auth_free(greeting->gr_data.gr_auth);
1200 break;
1201 case MAILIMAP_GREETING_RESP_COND_BYE:
1202 mailimap_resp_cond_bye_free(greeting->gr_data.gr_bye);
1203 break;
1204 }
1205 free(greeting);
1206}
1207
1208
1209
1210void
1211mailimap_header_fld_name_free(char * header_fld_name)
1212{
1213 mailimap_astring_free(header_fld_name);
1214}
1215
1216
1217
1218struct mailimap_header_list *
1219mailimap_header_list_new(clist * hdr_list)
1220{
1221 struct mailimap_header_list * header_list;
1222
1223 header_list = malloc(sizeof(* header_list));
1224 if (header_list == NULL)
1225 return NULL;
1226
1227 header_list->hdr_list = hdr_list;
1228
1229 return header_list;
1230}
1231
1232void
1233mailimap_header_list_free(struct mailimap_header_list * header_list)
1234{
1235 clist_foreach(header_list->hdr_list,
1236 (clist_func) mailimap_header_fld_name_free,
1237 NULL);
1238 clist_free(header_list->hdr_list);
1239 free(header_list);
1240}
1241
1242
1243
1244void mailimap_literal_free(char * literal)
1245{
1246 /* free(literal); */
1247 mmap_string_unref(literal);
1248}
1249
1250void mailimap_mailbox_free(char * mb)
1251{
1252 mailimap_astring_free(mb);
1253}
1254
1255
1256
1257
1258struct mailimap_status_info *
1259mailimap_status_info_new(int st_att, uint32_t st_value)
1260{
1261 struct mailimap_status_info * info;
1262
1263 info = malloc(sizeof(* info));
1264 if (info == NULL)
1265 return NULL;
1266 info->st_att = st_att;
1267 info->st_value = st_value;
1268
1269 return info;
1270}
1271
1272void mailimap_status_info_free(struct mailimap_status_info * info)
1273{
1274 free(info);
1275}
1276
1277
1278
1279struct mailimap_mailbox_data_status *
1280mailimap_mailbox_data_status_new(char * st_mailbox,
1281 clist * st_info_list)
1282{
1283 struct mailimap_mailbox_data_status * mb_data_status;
1284
1285 mb_data_status = malloc(sizeof(* mb_data_status));
1286 if (mb_data_status == NULL)
1287 return NULL;
1288 mb_data_status->st_mailbox = st_mailbox;
1289 mb_data_status->st_info_list = st_info_list;
1290
1291 return mb_data_status;
1292}
1293
1294void
1295mailimap_mailbox_data_search_free(clist * data_search)
1296{
1297 clist_foreach(data_search, (clist_func) mailimap_number_alloc_free, NULL);
1298 clist_free(data_search);
1299}
1300
1301void
1302mailimap_mailbox_data_status_free(struct mailimap_mailbox_data_status * info)
1303{
1304 mailimap_mailbox_free(info->st_mailbox);
1305 clist_foreach(info->st_info_list, (clist_func) mailimap_status_info_free,
1306 NULL);
1307 clist_free(info->st_info_list);
1308 free(info);
1309}
1310
1311
1312static void
1313mailimap_mailbox_data_flags_free(struct mailimap_flag_list * flag_list)
1314{
1315 mailimap_flag_list_free(flag_list);
1316}
1317
1318static void
1319mailimap_mailbox_data_list_free(struct mailimap_mailbox_list * mb_list)
1320{
1321 mailimap_mailbox_list_free(mb_list);
1322}
1323
1324static void
1325mailimap_mailbox_data_lsub_free(struct mailimap_mailbox_list * mb_lsub)
1326{
1327 mailimap_mailbox_list_free(mb_lsub);
1328}
1329
1330
1331
1332
1333
1334
1335struct mailimap_mailbox_data *
1336mailimap_mailbox_data_new(int mbd_type, struct mailimap_flag_list * mbd_flags,
1337 struct mailimap_mailbox_list * mbd_list,
1338 struct mailimap_mailbox_list * mbd_lsub,
1339 clist * mbd_search,
1340 struct mailimap_mailbox_data_status * mbd_status,
1341 uint32_t mbd_exists,
1342 uint32_t mbd_recent)
1343{
1344 struct mailimap_mailbox_data * data;
1345
1346 data = malloc(sizeof(* data));
1347 if (data == NULL)
1348 return NULL;
1349
1350 data->mbd_type = mbd_type;
1351 switch (mbd_type) {
1352 case MAILIMAP_MAILBOX_DATA_FLAGS:
1353 data->mbd_data.mbd_flags = mbd_flags;
1354 break;
1355 case MAILIMAP_MAILBOX_DATA_LIST:
1356 data->mbd_data.mbd_list = mbd_list;
1357 break;
1358 case MAILIMAP_MAILBOX_DATA_LSUB:
1359 data->mbd_data.mbd_lsub = mbd_lsub;
1360 break;
1361 case MAILIMAP_MAILBOX_DATA_SEARCH:
1362 data->mbd_data.mbd_search = mbd_search;
1363 break;
1364 case MAILIMAP_MAILBOX_DATA_STATUS:
1365 data->mbd_data.mbd_status = mbd_status;
1366 break;
1367 case MAILIMAP_MAILBOX_DATA_EXISTS:
1368 data->mbd_data.mbd_exists = mbd_exists;
1369 break;
1370 case MAILIMAP_MAILBOX_DATA_RECENT:
1371 data->mbd_data.mbd_recent = mbd_recent;
1372 break;
1373 }
1374
1375 return data;
1376}
1377
1378void
1379mailimap_mailbox_data_free(struct mailimap_mailbox_data * mb_data)
1380{
1381 switch (mb_data->mbd_type) {
1382 case MAILIMAP_MAILBOX_DATA_FLAGS:
1383 if (mb_data->mbd_data.mbd_flags != NULL)
1384 mailimap_mailbox_data_flags_free(mb_data->mbd_data.mbd_flags);
1385 break;
1386 case MAILIMAP_MAILBOX_DATA_LIST:
1387 if (mb_data->mbd_data.mbd_list != NULL)
1388 mailimap_mailbox_data_list_free(mb_data->mbd_data.mbd_list);
1389 break;
1390 case MAILIMAP_MAILBOX_DATA_LSUB:
1391 if (mb_data->mbd_data.mbd_lsub != NULL)
1392 mailimap_mailbox_data_lsub_free(mb_data->mbd_data.mbd_lsub);
1393 break;
1394 case MAILIMAP_MAILBOX_DATA_SEARCH:
1395 if (mb_data->mbd_data.mbd_search != NULL)
1396 mailimap_mailbox_data_search_free(mb_data->mbd_data.mbd_search);
1397 break;
1398 case MAILIMAP_MAILBOX_DATA_STATUS:
1399 if (mb_data->mbd_data.mbd_status != NULL)
1400 mailimap_mailbox_data_status_free(mb_data->mbd_data.mbd_status);
1401 break;
1402 }
1403 free(mb_data);
1404}
1405
1406
1407
1408
1409
1410struct mailimap_mbx_list_flags *
1411mailimap_mbx_list_flags_new(int mbf_type, clist * mbf_oflags,
1412 int mbf_sflag)
1413{
1414 struct mailimap_mbx_list_flags * mbx_list_flags;
1415
1416 mbx_list_flags = malloc(sizeof(* mbx_list_flags));
1417 if (mbx_list_flags == NULL)
1418 return NULL;
1419
1420 mbx_list_flags->mbf_type = mbf_type;
1421 mbx_list_flags->mbf_oflags = mbf_oflags;
1422 mbx_list_flags->mbf_sflag = mbf_sflag;
1423
1424 return mbx_list_flags;
1425}
1426
1427void
1428mailimap_mbx_list_flags_free(struct mailimap_mbx_list_flags * mbx_list_flags)
1429{
1430 clist_foreach(mbx_list_flags->mbf_oflags,
1431 (clist_func) mailimap_mbx_list_oflag_free,
1432 NULL);
1433 clist_free(mbx_list_flags->mbf_oflags);
1434
1435 free(mbx_list_flags);
1436}
1437
1438
1439struct mailimap_mbx_list_oflag *
1440mailimap_mbx_list_oflag_new(int of_type, char * of_flag_ext)
1441{
1442 struct mailimap_mbx_list_oflag * oflag;
1443
1444 oflag = malloc(sizeof(* oflag));
1445 if (oflag == NULL)
1446 return NULL;
1447
1448 oflag->of_type = of_type;
1449 oflag->of_flag_ext = of_flag_ext;
1450
1451 return oflag;
1452}
1453
1454void
1455mailimap_mbx_list_oflag_free(struct mailimap_mbx_list_oflag * oflag)
1456{
1457 if (oflag->of_flag_ext != NULL)
1458 mailimap_flag_extension_free(oflag->of_flag_ext);
1459 free(oflag);
1460}
1461
1462
1463
1464struct mailimap_mailbox_list *
1465mailimap_mailbox_list_new(struct mailimap_mbx_list_flags * mbx_flags,
1466 char mb_delimiter, char * mb_name)
1467{
1468 struct mailimap_mailbox_list * mb_list;
1469
1470 mb_list = malloc(sizeof(* mb_list));
1471 if (mb_list == NULL)
1472 return NULL;
1473
1474 mb_list->mb_flag = mbx_flags;
1475 mb_list->mb_delimiter = mb_delimiter;
1476 mb_list->mb_name = mb_name;
1477
1478 return mb_list;
1479}
1480
1481void
1482mailimap_mailbox_list_free(struct mailimap_mailbox_list * mb_list)
1483{
1484 if (mb_list->mb_flag != NULL)
1485 mailimap_mbx_list_flags_free(mb_list->mb_flag);
1486 if (mb_list->mb_name != NULL)
1487 mailimap_mailbox_free(mb_list->mb_name);
1488 free(mb_list);
1489}
1490
1491
1492
1493struct mailimap_media_basic *
1494mailimap_media_basic_new(int med_type,
1495 char * med_basic_type, char * med_subtype)
1496{
1497 struct mailimap_media_basic * media_basic;
1498
1499 media_basic = malloc(sizeof(* media_basic));
1500 if (media_basic == NULL)
1501 return NULL;
1502 media_basic->med_type = med_type;
1503 media_basic->med_basic_type = med_basic_type;
1504 media_basic->med_subtype = med_subtype;
1505
1506 return media_basic;
1507}
1508
1509void
1510mailimap_media_basic_free(struct mailimap_media_basic * media_basic)
1511{
1512 mailimap_string_free(media_basic->med_basic_type);
1513 mailimap_media_subtype_free(media_basic->med_subtype);
1514 free(media_basic);
1515}
1516
1517
1518
1519void mailimap_media_subtype_free(char * media_subtype)
1520{
1521 mmap_string_unref(media_subtype);
1522}
1523
1524
1525void mailimap_media_text_free(char * media_text)
1526{
1527 mailimap_media_subtype_free(media_text);
1528}
1529
1530
1531
1532struct mailimap_message_data *
1533mailimap_message_data_new(uint32_t mdt_number, int mdt_type,
1534 struct mailimap_msg_att * mdt_msg_att)
1535{
1536 struct mailimap_message_data * msg_data;
1537
1538 msg_data = malloc(sizeof(* msg_data));
1539 if (msg_data == NULL)
1540 free(msg_data);
1541
1542 msg_data->mdt_number = mdt_number;
1543 msg_data->mdt_type = mdt_type;
1544 msg_data->mdt_msg_att = mdt_msg_att;
1545
1546 return msg_data;
1547}
1548
1549void
1550mailimap_message_data_free(struct mailimap_message_data * msg_data)
1551{
1552 if (msg_data->mdt_msg_att != NULL)
1553 mailimap_msg_att_free(msg_data->mdt_msg_att);
1554 free(msg_data);
1555}
1556
1557
1558
1559
1560struct mailimap_msg_att_item *
1561mailimap_msg_att_item_new(int att_type,
1562 struct mailimap_msg_att_dynamic * att_dyn,
1563 struct mailimap_msg_att_static * att_static)
1564{
1565 struct mailimap_msg_att_item * item;
1566
1567 item = malloc(sizeof(* item));
1568 if (item == NULL)
1569 return item;
1570
1571 item->att_type = att_type;
1572 switch (att_type) {
1573 case MAILIMAP_MSG_ATT_ITEM_DYNAMIC:
1574 item->att_data.att_dyn = att_dyn;
1575 break;
1576 case MAILIMAP_MSG_ATT_ITEM_STATIC:
1577 item->att_data.att_static = att_static;
1578 break;
1579 }
1580
1581 return item;
1582}
1583
1584void
1585mailimap_msg_att_item_free(struct mailimap_msg_att_item * item)
1586{
1587 switch (item->att_type) {
1588 case MAILIMAP_MSG_ATT_ITEM_DYNAMIC:
1589 mailimap_msg_att_dynamic_free(item->att_data.att_dyn);
1590 break;
1591 case MAILIMAP_MSG_ATT_ITEM_STATIC:
1592 mailimap_msg_att_static_free(item->att_data.att_static);
1593 break;
1594 }
1595 free(item);
1596}
1597
1598
1599struct mailimap_msg_att *
1600mailimap_msg_att_new(clist * att_list)
1601{
1602 struct mailimap_msg_att * msg_att;
1603
1604 msg_att = malloc(sizeof(* msg_att));
1605 if (msg_att == NULL)
1606 return NULL;
1607
1608 msg_att->att_list = att_list;
1609 msg_att->att_number = 0;
1610
1611 return msg_att;
1612}
1613
1614void mailimap_msg_att_free(struct mailimap_msg_att * msg_att)
1615{
1616 clist_foreach(msg_att->att_list,
1617 (clist_func) mailimap_msg_att_item_free, NULL);
1618 clist_free(msg_att->att_list);
1619 free(msg_att);
1620}
1621
1622
1623
1624struct mailimap_msg_att_dynamic *
1625mailimap_msg_att_dynamic_new(clist * att_list)
1626{
1627 struct mailimap_msg_att_dynamic * msg_att_dyn;
1628
1629 msg_att_dyn = malloc(sizeof(* msg_att_dyn));
1630 if (msg_att_dyn == NULL)
1631 return NULL;
1632
1633 msg_att_dyn->att_list = att_list;
1634
1635 return msg_att_dyn;
1636}
1637
1638void
1639mailimap_msg_att_dynamic_free(struct mailimap_msg_att_dynamic * msg_att_dyn)
1640{
1641 if (msg_att_dyn->att_list != NULL) {
1642 clist_foreach(msg_att_dyn->att_list,
1643 (clist_func) mailimap_flag_fetch_free,
1644 NULL);
1645 clist_free(msg_att_dyn->att_list);
1646 }
1647 free(msg_att_dyn);
1648}
1649
1650
1651struct mailimap_msg_att_body_section *
1652mailimap_msg_att_body_section_new(struct mailimap_section * sec_section,
1653 uint32_t sec_origin_octet,
1654 char * sec_body_part,
1655 size_t sec_length)
1656{
1657 struct mailimap_msg_att_body_section * msg_att_body_section;
1658
1659 msg_att_body_section = malloc(sizeof(* msg_att_body_section));
1660 if (msg_att_body_section == NULL)
1661 return NULL;
1662
1663 msg_att_body_section->sec_section = sec_section;
1664 msg_att_body_section->sec_origin_octet = sec_origin_octet;
1665 msg_att_body_section->sec_body_part = sec_body_part;
1666 msg_att_body_section->sec_length = sec_length;
1667
1668 return msg_att_body_section;
1669}
1670
1671void
1672mailimap_msg_att_body_section_free(struct mailimap_msg_att_body_section *
1673 msg_att_body_section)
1674{
1675 if (msg_att_body_section->sec_section != NULL)
1676 mailimap_section_free(msg_att_body_section->sec_section);
1677 if (msg_att_body_section->sec_body_part != NULL)
1678 mailimap_nstring_free(msg_att_body_section->sec_body_part);
1679 free(msg_att_body_section);
1680}
1681
1682
1683
1684
1685
1686
1687void mailimap_msg_att_envelope_free(struct mailimap_envelope * env)
1688{
1689 mailimap_envelope_free(env);
1690}
1691
1692void
1693mailimap_msg_att_internaldate_free(struct mailimap_date_time * date_time)
1694{
1695 mailimap_date_time_free(date_time);
1696}
1697
1698void
1699mailimap_msg_att_rfc822_free(char * str)
1700{
1701 mailimap_nstring_free(str);
1702}
1703
1704
1705void
1706mailimap_msg_att_rfc822_header_free(char * str)
1707{
1708 mailimap_nstring_free(str);
1709}
1710
1711void
1712mailimap_msg_att_rfc822_text_free(char * str)
1713{
1714 mailimap_nstring_free(str);
1715}
1716
1717void
1718mailimap_msg_att_body_free(struct mailimap_body * body)
1719{
1720 mailimap_body_free(body);
1721}
1722
1723void
1724mailimap_msg_att_bodystructure_free(struct mailimap_body * body)
1725{
1726 mailimap_body_free(body);
1727}
1728
1729
1730
1731struct mailimap_msg_att_static *
1732mailimap_msg_att_static_new(int att_type, struct mailimap_envelope * att_env,
1733 struct mailimap_date_time * att_internal_date,
1734 char * att_rfc822,
1735 char * att_rfc822_header,
1736 char * att_rfc822_text,
1737 size_t att_length,
1738 uint32_t att_rfc822_size,
1739 struct mailimap_body * att_bodystructure,
1740 struct mailimap_body * att_body,
1741 struct mailimap_msg_att_body_section * att_body_section,
1742 uint32_t att_uid)
1743{
1744 struct mailimap_msg_att_static * item;
1745
1746 item = malloc(sizeof(* item));
1747 if (item == NULL)
1748 return FALSE;
1749
1750 item->att_type = att_type;
1751 switch (att_type) {
1752 case MAILIMAP_MSG_ATT_ENVELOPE:
1753 item->att_data.att_env = att_env;
1754 break;
1755 case MAILIMAP_MSG_ATT_INTERNALDATE:
1756 item->att_data.att_internal_date = att_internal_date;
1757 break;
1758 case MAILIMAP_MSG_ATT_RFC822:
1759 item->att_data.att_rfc822.att_content = att_rfc822;
1760 item->att_data.att_rfc822.att_length = att_length;
1761 break;
1762 case MAILIMAP_MSG_ATT_RFC822_HEADER:
1763 item->att_data.att_rfc822_header.att_content = att_rfc822_header;
1764 item->att_data.att_rfc822_header.att_length = att_length;
1765 break;
1766 case MAILIMAP_MSG_ATT_RFC822_TEXT:
1767 item->att_data.att_rfc822_text.att_content = att_rfc822_text;
1768 item->att_data.att_rfc822_text.att_length = att_length;
1769 break;
1770 case MAILIMAP_MSG_ATT_RFC822_SIZE:
1771 item->att_data.att_rfc822_size = att_rfc822_size;
1772 break;
1773 case MAILIMAP_MSG_ATT_BODY:
1774 item->att_data.att_body = att_body;
1775 break;
1776 case MAILIMAP_MSG_ATT_BODYSTRUCTURE:
1777 item->att_data.att_bodystructure = att_bodystructure;
1778 break;
1779 case MAILIMAP_MSG_ATT_BODY_SECTION:
1780 item->att_data.att_body_section = att_body_section;
1781 break;
1782 case MAILIMAP_MSG_ATT_UID:
1783 item->att_data.att_uid = att_uid;
1784 break;
1785 }
1786
1787 return item;
1788}
1789
1790void
1791mailimap_msg_att_static_free(struct mailimap_msg_att_static * item)
1792{
1793 switch (item->att_type) {
1794 case MAILIMAP_MSG_ATT_ENVELOPE:
1795 if (item->att_data.att_env != NULL)
1796 mailimap_msg_att_envelope_free(item->att_data.att_env);
1797 break;
1798 case MAILIMAP_MSG_ATT_INTERNALDATE:
1799 if (item->att_data.att_internal_date != NULL)
1800 mailimap_msg_att_internaldate_free(item->att_data.att_internal_date);
1801 break;
1802 case MAILIMAP_MSG_ATT_RFC822:
1803 if (item->att_data.att_rfc822.att_content != NULL)
1804 mailimap_msg_att_rfc822_free(item->att_data.att_rfc822.att_content);
1805 break;
1806 case MAILIMAP_MSG_ATT_RFC822_HEADER:
1807 if (item->att_data.att_rfc822_header.att_content != NULL)
1808 mailimap_msg_att_rfc822_header_free(item->att_data.att_rfc822_header.att_content);
1809 break;
1810 case MAILIMAP_MSG_ATT_RFC822_TEXT:
1811 if (item->att_data.att_rfc822_text.att_content != NULL)
1812 mailimap_msg_att_rfc822_text_free(item->att_data.att_rfc822_text.att_content);
1813 break;
1814 case MAILIMAP_MSG_ATT_BODYSTRUCTURE:
1815 if (item->att_data.att_bodystructure != NULL)
1816 mailimap_msg_att_bodystructure_free(item->att_data.att_bodystructure);
1817 break;
1818 case MAILIMAP_MSG_ATT_BODY:
1819 if (item->att_data.att_body != NULL)
1820 mailimap_msg_att_body_free(item->att_data.att_body);
1821 break;
1822 case MAILIMAP_MSG_ATT_BODY_SECTION:
1823 if (item->att_data.att_body_section != NULL)
1824 mailimap_msg_att_body_section_free(item->att_data.att_body_section);
1825 break;
1826 }
1827 free(item);
1828}
1829
1830
1831
1832
1833void mailimap_nstring_free(char * str)
1834{
1835 if (str != NULL)
1836 mailimap_string_free(str);
1837}
1838
1839
1840
1841
1842
1843
1844
1845struct mailimap_cont_req_or_resp_data *
1846mailimap_cont_req_or_resp_data_new(int rsp_type,
1847 struct mailimap_continue_req * rsp_cont_req,
1848 struct mailimap_response_data * rsp_resp_data)
1849{
1850 struct mailimap_cont_req_or_resp_data * cont_req_or_resp_data;
1851
1852 cont_req_or_resp_data = malloc(sizeof(* cont_req_or_resp_data));
1853 if (cont_req_or_resp_data == NULL)
1854 return NULL;
1855
1856 cont_req_or_resp_data->rsp_type = rsp_type;
1857 switch (rsp_type) {
1858 case MAILIMAP_RESP_CONT_REQ:
1859 cont_req_or_resp_data->rsp_data.rsp_cont_req = rsp_cont_req;
1860 break;
1861 case MAILIMAP_RESP_RESP_DATA:
1862 cont_req_or_resp_data->rsp_data.rsp_resp_data = rsp_resp_data;
1863 break;
1864 }
1865
1866 return cont_req_or_resp_data;
1867}
1868
1869void
1870mailimap_cont_req_or_resp_data_free(struct mailimap_cont_req_or_resp_data *
1871 cont_req_or_resp_data)
1872{
1873 switch (cont_req_or_resp_data->rsp_type) {
1874 case MAILIMAP_RESP_CONT_REQ:
1875 if (cont_req_or_resp_data->rsp_data.rsp_cont_req != NULL)
1876 mailimap_continue_req_free(cont_req_or_resp_data->rsp_data.rsp_cont_req);
1877 break;
1878 case MAILIMAP_RESP_RESP_DATA:
1879 if (cont_req_or_resp_data->rsp_data.rsp_resp_data != NULL)
1880 mailimap_response_data_free(cont_req_or_resp_data->rsp_data.rsp_resp_data);
1881 break;
1882 }
1883 free(cont_req_or_resp_data);
1884}
1885
1886
1887
1888
1889struct mailimap_response *
1890mailimap_response_new(clist * rsp_cont_req_or_resp_data_list,
1891 struct mailimap_response_done * rsp_resp_done)
1892{
1893 struct mailimap_response * resp;
1894
1895 resp = malloc(sizeof(* resp));
1896 if (resp == NULL)
1897 return NULL;
1898
1899 resp->rsp_cont_req_or_resp_data_list = rsp_cont_req_or_resp_data_list;
1900 resp->rsp_resp_done = rsp_resp_done;
1901
1902 return resp;
1903}
1904
1905void
1906mailimap_response_free(struct mailimap_response * resp)
1907{
1908 if (resp->rsp_cont_req_or_resp_data_list != NULL) {
1909 clist_foreach(resp->rsp_cont_req_or_resp_data_list,
1910 (clist_func) mailimap_cont_req_or_resp_data_free, NULL);
1911 clist_free(resp->rsp_cont_req_or_resp_data_list);
1912 }
1913 mailimap_response_done_free(resp->rsp_resp_done);
1914 free(resp);
1915}
1916
1917
1918
1919struct mailimap_response_data *
1920mailimap_response_data_new(int rsp_type,
1921 struct mailimap_resp_cond_state * rsp_cond_state,
1922 struct mailimap_resp_cond_bye * rsp_bye,
1923 struct mailimap_mailbox_data * rsp_mailbox_data,
1924 struct mailimap_message_data * rsp_message_data,
1925 struct mailimap_capability_data * rsp_capability_data)
1926{
1927 struct mailimap_response_data * resp_data;
1928
1929 resp_data = malloc(sizeof(* resp_data));
1930 if (resp_data == NULL)
1931 return NULL;
1932 resp_data->rsp_type = rsp_type;
1933
1934 switch (rsp_type) {
1935 case MAILIMAP_RESP_DATA_TYPE_COND_STATE:
1936 resp_data->rsp_data.rsp_cond_state = rsp_cond_state;
1937 break;
1938 case MAILIMAP_RESP_DATA_TYPE_COND_BYE:
1939 resp_data->rsp_data.rsp_bye = rsp_bye;
1940 break;
1941 case MAILIMAP_RESP_DATA_TYPE_MAILBOX_DATA:
1942 resp_data->rsp_data.rsp_mailbox_data = rsp_mailbox_data;
1943 break;
1944 case MAILIMAP_RESP_DATA_TYPE_MESSAGE_DATA:
1945 resp_data->rsp_data.rsp_message_data = rsp_message_data;
1946 break;
1947 case MAILIMAP_RESP_DATA_TYPE_CAPABILITY_DATA:
1948 resp_data->rsp_data.rsp_capability_data = rsp_capability_data;
1949 break;
1950 }
1951
1952 return resp_data;
1953}
1954
1955void
1956mailimap_response_data_free(struct mailimap_response_data * resp_data)
1957{
1958 switch (resp_data->rsp_type) {
1959 case MAILIMAP_RESP_DATA_TYPE_COND_STATE:
1960 if (resp_data->rsp_data.rsp_cond_state != NULL)
1961 mailimap_resp_cond_state_free(resp_data->rsp_data.rsp_cond_state);
1962 break;
1963 case MAILIMAP_RESP_DATA_TYPE_COND_BYE:
1964 if (resp_data->rsp_data.rsp_bye != NULL)
1965 mailimap_resp_cond_bye_free(resp_data->rsp_data.rsp_bye);
1966 break;
1967 case MAILIMAP_RESP_DATA_TYPE_MAILBOX_DATA:
1968 if (resp_data->rsp_data.rsp_mailbox_data != NULL)
1969 mailimap_mailbox_data_free(resp_data->rsp_data.rsp_mailbox_data);
1970 break;
1971 case MAILIMAP_RESP_DATA_TYPE_MESSAGE_DATA:
1972 if (resp_data->rsp_data.rsp_message_data != NULL)
1973 mailimap_message_data_free(resp_data->rsp_data.rsp_message_data);
1974 break;
1975 case MAILIMAP_RESP_DATA_TYPE_CAPABILITY_DATA:
1976 if (resp_data->rsp_data.rsp_capability_data != NULL)
1977 mailimap_capability_data_free(resp_data->rsp_data.rsp_capability_data);
1978 break;
1979 }
1980 free(resp_data);
1981}
1982
1983
1984
1985struct mailimap_response_done *
1986mailimap_response_done_new(int rsp_type,
1987 struct mailimap_response_tagged * rsp_tagged,
1988 struct mailimap_response_fatal * rsp_fatal)
1989{
1990 struct mailimap_response_done * resp_done;
1991
1992 resp_done = malloc(sizeof(* resp_done));
1993 if (resp_done == NULL)
1994 return NULL;
1995
1996 resp_done->rsp_type = rsp_type;
1997 switch (rsp_type) {
1998 case MAILIMAP_RESP_DONE_TYPE_TAGGED:
1999 resp_done->rsp_data.rsp_tagged = rsp_tagged;
2000 break;
2001 case MAILIMAP_RESP_DONE_TYPE_FATAL:
2002 resp_done->rsp_data.rsp_fatal = rsp_fatal;
2003 break;
2004 }
2005
2006 return resp_done;
2007}
2008
2009void mailimap_response_done_free(struct mailimap_response_done *
2010 resp_done)
2011{
2012 switch (resp_done->rsp_type) {
2013 case MAILIMAP_RESP_DONE_TYPE_TAGGED:
2014 mailimap_response_tagged_free(resp_done->rsp_data.rsp_tagged);
2015 break;
2016 case MAILIMAP_RESP_DONE_TYPE_FATAL:
2017 mailimap_response_fatal_free(resp_done->rsp_data.rsp_fatal);
2018 break;
2019 }
2020 free(resp_done);
2021}
2022
2023struct mailimap_response_fatal *
2024mailimap_response_fatal_new(struct mailimap_resp_cond_bye * rsp_bye)
2025{
2026 struct mailimap_response_fatal * resp_fatal;
2027
2028 resp_fatal = malloc(sizeof(* resp_fatal));
2029 if (resp_fatal == NULL)
2030 return NULL;
2031
2032 resp_fatal->rsp_bye = rsp_bye;
2033
2034 return NULL;
2035}
2036
2037void mailimap_response_fatal_free(struct mailimap_response_fatal * resp_fatal)
2038{
2039 mailimap_resp_cond_bye_free(resp_fatal->rsp_bye);
2040 free(resp_fatal);
2041}
2042
2043struct mailimap_response_tagged *
2044mailimap_response_tagged_new(char * rsp_tag,
2045 struct mailimap_resp_cond_state * rsp_cond_state)
2046{
2047 struct mailimap_response_tagged * resp_tagged;
2048
2049 resp_tagged = malloc(sizeof(* resp_tagged));
2050 if (resp_tagged == NULL)
2051 return NULL;
2052
2053 resp_tagged->rsp_tag = rsp_tag;
2054 resp_tagged->rsp_cond_state = rsp_cond_state;
2055
2056 return resp_tagged;
2057}
2058
2059void
2060mailimap_response_tagged_free(struct mailimap_response_tagged * tagged)
2061{
2062 mailimap_tag_free(tagged->rsp_tag);
2063 mailimap_resp_cond_state_free(tagged->rsp_cond_state);
2064 free(tagged);
2065}
2066
2067
2068
2069struct mailimap_resp_cond_auth *
2070mailimap_resp_cond_auth_new(int rsp_type,
2071 struct mailimap_resp_text * rsp_text)
2072{
2073 struct mailimap_resp_cond_auth * cond_auth;
2074
2075 cond_auth = malloc(sizeof(* cond_auth));
2076 if (cond_auth == NULL)
2077 return NULL;
2078
2079 cond_auth->rsp_type = rsp_type;
2080 cond_auth->rsp_text = rsp_text;
2081
2082 return cond_auth;
2083}
2084
2085void
2086mailimap_resp_cond_auth_free(struct mailimap_resp_cond_auth * cond_auth)
2087{
2088 mailimap_resp_text_free(cond_auth->rsp_text);
2089 free(cond_auth);
2090}
2091
2092
2093
2094struct mailimap_resp_cond_bye *
2095mailimap_resp_cond_bye_new(struct mailimap_resp_text * rsp_text)
2096{
2097 struct mailimap_resp_cond_bye * cond_bye;
2098
2099 cond_bye = malloc(sizeof(* cond_bye));
2100 if (cond_bye == NULL)
2101 return NULL;
2102
2103 cond_bye->rsp_text = rsp_text;
2104
2105 return cond_bye;
2106}
2107
2108
2109void
2110mailimap_resp_cond_bye_free(struct mailimap_resp_cond_bye * cond_bye)
2111{
2112 mailimap_resp_text_free(cond_bye->rsp_text);
2113 free(cond_bye);
2114}
2115
2116
2117struct mailimap_resp_cond_state *
2118mailimap_resp_cond_state_new(int rsp_type,
2119 struct mailimap_resp_text * rsp_text)
2120{
2121 struct mailimap_resp_cond_state * cond_state;
2122
2123 cond_state = malloc(sizeof(* cond_state));
2124 if (cond_state == NULL)
2125 return NULL;
2126
2127 cond_state->rsp_type = rsp_type;
2128 cond_state->rsp_text = rsp_text;
2129
2130 return cond_state;
2131}
2132
2133void
2134mailimap_resp_cond_state_free(struct mailimap_resp_cond_state * cond_state)
2135{
2136 mailimap_resp_text_free(cond_state->rsp_text);
2137 free(cond_state);
2138}
2139
2140
2141struct mailimap_resp_text *
2142mailimap_resp_text_new(struct mailimap_resp_text_code * rsp_code,
2143 char * rsp_text)
2144{
2145 struct mailimap_resp_text * resp_text;
2146
2147 resp_text = malloc(sizeof(* resp_text));
2148 if (resp_text == NULL)
2149 return NULL;
2150
2151 resp_text->rsp_code = rsp_code;
2152 resp_text->rsp_text = rsp_text;
2153
2154 return resp_text;
2155}
2156
2157void mailimap_resp_text_free(struct mailimap_resp_text * resp_text)
2158{
2159 if (resp_text->rsp_code)
2160 mailimap_resp_text_code_free(resp_text->rsp_code);
2161 if (resp_text->rsp_text)
2162 mailimap_text_free(resp_text->rsp_text);
2163 free(resp_text);
2164}
2165
2166
2167
2168
2169struct mailimap_resp_text_code *
2170mailimap_resp_text_code_new(int rc_type, clist * rc_badcharset,
2171 struct mailimap_capability_data * rc_cap_data,
2172 clist * rc_perm_flags,
2173 uint32_t rc_uidnext, uint32_t rc_uidvalidity,
2174 uint32_t rc_first_unseen, char * rc_atom, char * rc_atom_value)
2175{
2176 struct mailimap_resp_text_code * resp_text_code;
2177
2178 resp_text_code = malloc(sizeof(* resp_text_code));
2179 if (resp_text_code == NULL)
2180 return NULL;
2181
2182 resp_text_code->rc_type = rc_type;
2183 switch (rc_type) {
2184 case MAILIMAP_RESP_TEXT_CODE_BADCHARSET:
2185 resp_text_code->rc_data.rc_badcharset = rc_badcharset;
2186 break;
2187 case MAILIMAP_RESP_TEXT_CODE_CAPABILITY_DATA:
2188 resp_text_code->rc_data.rc_cap_data = rc_cap_data;
2189 break;
2190 case MAILIMAP_RESP_TEXT_CODE_PERMANENTFLAGS:
2191 resp_text_code->rc_data.rc_perm_flags = rc_perm_flags;
2192 break;
2193 case MAILIMAP_RESP_TEXT_CODE_UIDNEXT:
2194 resp_text_code->rc_data.rc_uidnext = rc_uidnext;
2195 break;
2196 case MAILIMAP_RESP_TEXT_CODE_UIDVALIDITY:
2197 resp_text_code->rc_data.rc_uidvalidity = rc_uidvalidity;
2198 break;
2199 case MAILIMAP_RESP_TEXT_CODE_UNSEEN:
2200 resp_text_code->rc_data.rc_first_unseen = rc_first_unseen;
2201 break;
2202 case MAILIMAP_RESP_TEXT_CODE_OTHER:
2203 resp_text_code->rc_data.rc_atom.atom_name = rc_atom;
2204 resp_text_code->rc_data.rc_atom.atom_value = rc_atom_value;
2205 break;
2206 }
2207
2208 return resp_text_code;
2209}
2210
2211void
2212mailimap_resp_text_code_free(struct mailimap_resp_text_code * resp_text_code)
2213{
2214 switch (resp_text_code->rc_type) {
2215 case MAILIMAP_RESP_TEXT_CODE_BADCHARSET:
2216 if (resp_text_code->rc_data.rc_badcharset != NULL) {
2217 clist_foreach(resp_text_code->rc_data.rc_badcharset,
2218 (clist_func) mailimap_astring_free,
2219 NULL);
2220 clist_free(resp_text_code->rc_data.rc_badcharset);
2221 }
2222 break;
2223 case MAILIMAP_RESP_TEXT_CODE_CAPABILITY_DATA:
2224 if (resp_text_code->rc_data.rc_cap_data != NULL)
2225 mailimap_capability_data_free(resp_text_code->rc_data.rc_cap_data);
2226 break;
2227 case MAILIMAP_RESP_TEXT_CODE_PERMANENTFLAGS:
2228 if (resp_text_code->rc_data.rc_perm_flags != NULL) {
2229 clist_foreach(resp_text_code->rc_data.rc_perm_flags,
2230 (clist_func) mailimap_flag_perm_free, NULL);
2231 clist_free(resp_text_code->rc_data.rc_perm_flags);
2232 }
2233 break;
2234 case MAILIMAP_RESP_TEXT_CODE_OTHER:
2235 if (resp_text_code->rc_data.rc_atom.atom_name != NULL)
2236 mailimap_atom_free(resp_text_code->rc_data.rc_atom.atom_name);
2237 if (resp_text_code->rc_data.rc_atom.atom_value != NULL)
2238 mailimap_custom_string_free(resp_text_code->rc_data.rc_atom.atom_value);
2239 break;
2240 }
2241 free(resp_text_code);
2242}
2243
2244
2245struct mailimap_section *
2246mailimap_section_new(struct mailimap_section_spec * sec_spec)
2247{
2248 struct mailimap_section * section;
2249
2250 section = malloc(sizeof(* section));
2251 if (section == NULL)
2252 return NULL;
2253
2254 section->sec_spec = sec_spec;
2255
2256 return section;
2257}
2258
2259void mailimap_section_free(struct mailimap_section * section)
2260{
2261 if (section->sec_spec != NULL)
2262 mailimap_section_spec_free(section->sec_spec);
2263 free(section);
2264}
2265
2266
2267
2268struct mailimap_section_msgtext *
2269mailimap_section_msgtext_new(int sec_type,
2270 struct mailimap_header_list * sec_header_list)
2271{
2272 struct mailimap_section_msgtext * msgtext;
2273
2274 msgtext = malloc(sizeof(* msgtext));
2275 if (msgtext == NULL)
2276 return FALSE;
2277
2278 msgtext->sec_type = sec_type;
2279 msgtext->sec_header_list = sec_header_list;
2280
2281 return msgtext;
2282}
2283
2284void
2285mailimap_section_msgtext_free(struct mailimap_section_msgtext * msgtext)
2286{
2287 if (msgtext->sec_header_list != NULL)
2288 mailimap_header_list_free(msgtext->sec_header_list);
2289 free(msgtext);
2290}
2291
2292
2293struct mailimap_section_part *
2294mailimap_section_part_new(clist * sec_id)
2295{
2296 struct mailimap_section_part * section_part;
2297
2298 section_part = malloc(sizeof(* section_part));
2299 if (section_part == NULL)
2300 return NULL;
2301
2302 section_part->sec_id = sec_id;
2303
2304 return section_part;
2305}
2306
2307void
2308mailimap_section_part_free(struct mailimap_section_part * section_part)
2309{
2310 clist_foreach(section_part->sec_id,
2311 (clist_func) mailimap_number_alloc_free, NULL);
2312 clist_free(section_part->sec_id);
2313 free(section_part);
2314}
2315
2316
2317struct mailimap_section_spec *
2318mailimap_section_spec_new(int sec_type,
2319 struct mailimap_section_msgtext * sec_msgtext,
2320 struct mailimap_section_part * sec_part,
2321 struct mailimap_section_text * sec_text)
2322{
2323 struct mailimap_section_spec * section_spec;
2324
2325 section_spec = malloc(sizeof(* section_spec));
2326 if (section_spec == NULL)
2327 return NULL;
2328
2329 section_spec->sec_type = sec_type;
2330 switch (sec_type) {
2331 case MAILIMAP_SECTION_SPEC_SECTION_MSGTEXT:
2332 section_spec->sec_data.sec_msgtext = sec_msgtext;
2333 break;
2334 case MAILIMAP_SECTION_SPEC_SECTION_PART:
2335 section_spec->sec_data.sec_part = sec_part;
2336 break;
2337 }
2338 section_spec->sec_text = sec_text;
2339
2340 return section_spec;
2341}
2342
2343void
2344mailimap_section_spec_free(struct mailimap_section_spec * section_spec)
2345{
2346 if (section_spec->sec_text)
2347 mailimap_section_text_free(section_spec->sec_text);
2348
2349 switch (section_spec->sec_type) {
2350 case MAILIMAP_SECTION_SPEC_SECTION_PART:
2351 if (section_spec->sec_data.sec_part != NULL)
2352 mailimap_section_part_free(section_spec->sec_data.sec_part);
2353 break;
2354 case MAILIMAP_SECTION_SPEC_SECTION_MSGTEXT:
2355 /* handle case where it can be detached */
2356 if (section_spec->sec_data.sec_msgtext != NULL)
2357 mailimap_section_msgtext_free(section_spec->sec_data.sec_msgtext);
2358 break;
2359 }
2360 free(section_spec);
2361}
2362
2363
2364struct mailimap_section_text *
2365mailimap_section_text_new(int sec_type,
2366 struct mailimap_section_msgtext * sec_msgtext)
2367{
2368 struct mailimap_section_text * section_text;
2369
2370 section_text = malloc(sizeof(* section_text));
2371 if (section_text == NULL)
2372 return NULL;
2373
2374 section_text->sec_type = sec_type;
2375 section_text->sec_msgtext = sec_msgtext;
2376
2377 return section_text;
2378}
2379
2380void
2381mailimap_section_text_free(struct mailimap_section_text * section_text)
2382{
2383 if (section_text->sec_msgtext != NULL)
2384 mailimap_section_msgtext_free(section_text->sec_msgtext);
2385 free(section_text);
2386}
2387
2388
2389
2390
2391void
2392mailimap_string_free(char * str)
2393{
2394 mmap_string_unref(str);
2395}
2396
2397
2398
2399
2400
2401void mailimap_tag_free(char * tag)
2402{
2403 mailimap_custom_string_free(tag);
2404}
2405
2406
2407void mailimap_text_free(char * text)
2408{
2409 mailimap_custom_string_free(text);
2410}
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433/* ************************************************************************* */
2434/* ************************************************************************* */
2435/* ************************************************************************* */
2436/* ************************************************************************* */
2437/* ************************************************************************* */
2438/* ************************************************************************* */
2439
2440
2441
2442
2443
2444
2445/* sender only */
2446
2447
2448/* COPY FETCH SEARCH STORE */
2449/* set */
2450
2451struct mailimap_set_item *
2452mailimap_set_item_new(uint32_t set_first, uint32_t set_last)
2453{
2454 struct mailimap_set_item * item;
2455
2456 item = malloc(sizeof(* item));
2457 if (item == NULL)
2458 return NULL;
2459
2460 item->set_first = set_first;
2461 item->set_last = set_last;
2462
2463 return item;
2464}
2465
2466void mailimap_set_item_free(struct mailimap_set_item * set_item)
2467{
2468 free(set_item);
2469}
2470
2471struct mailimap_set * mailimap_set_new(clist * set_list)
2472{
2473 struct mailimap_set * set;
2474
2475 set = malloc(sizeof(* set));
2476 if (set == NULL)
2477 return NULL;
2478
2479 set->set_list = set_list;
2480
2481 return set;
2482}
2483
2484void mailimap_set_free(struct mailimap_set * set)
2485{
2486 clist_foreach(set->set_list, (clist_func) mailimap_set_item_free, NULL);
2487 clist_free(set->set_list);
2488 free(set);
2489}
2490
2491/* SEARCH with date key */
2492/* date */
2493
2494struct mailimap_date *
2495mailimap_date_new(int dt_day, int dt_month, int dt_year)
2496{
2497 struct mailimap_date * date;
2498
2499 date = malloc(sizeof(* date));
2500 if (date == NULL)
2501 return NULL;
2502
2503 date->dt_day = dt_day;
2504 date->dt_month = dt_month;
2505 date->dt_year = dt_year;
2506
2507 return date;
2508}
2509
2510void mailimap_date_free(struct mailimap_date * date)
2511{
2512 free(date);
2513}
2514
2515
2516
2517struct mailimap_fetch_att *
2518mailimap_fetch_att_new(int att_type, struct mailimap_section * att_section,
2519 uint32_t att_offset, uint32_t att_size)
2520{
2521 struct mailimap_fetch_att * fetch_att;
2522
2523 fetch_att = malloc(sizeof(* fetch_att));
2524 if (fetch_att == NULL)
2525 return NULL;
2526 fetch_att->att_type = att_type;
2527 fetch_att->att_section = att_section;
2528 fetch_att->att_offset = att_offset;
2529 fetch_att->att_size = att_size;
2530
2531 return fetch_att;
2532}
2533
2534void mailimap_fetch_att_free(struct mailimap_fetch_att * fetch_att)
2535{
2536 if (fetch_att->att_section != NULL)
2537 mailimap_section_free(fetch_att->att_section);
2538 free(fetch_att);
2539}
2540
2541
2542
2543struct mailimap_fetch_type *
2544mailimap_fetch_type_new(int ft_type,
2545 struct mailimap_fetch_att * ft_fetch_att,
2546 clist * ft_fetch_att_list)
2547{
2548 struct mailimap_fetch_type * fetch_type;
2549
2550 fetch_type = malloc(sizeof(* fetch_type));
2551 if (fetch_type == NULL)
2552 return NULL;
2553 fetch_type->ft_type = ft_type;
2554 switch (ft_type) {
2555 case MAILIMAP_FETCH_TYPE_FETCH_ATT:
2556 fetch_type->ft_data.ft_fetch_att = ft_fetch_att;
2557 break;
2558 case MAILIMAP_FETCH_TYPE_FETCH_ATT_LIST:
2559 fetch_type->ft_data.ft_fetch_att_list = ft_fetch_att_list;
2560 break;
2561 }
2562
2563 return fetch_type;
2564}
2565
2566void mailimap_fetch_type_free(struct mailimap_fetch_type * fetch_type)
2567{
2568 switch (fetch_type->ft_type) {
2569 case MAILIMAP_FETCH_TYPE_FETCH_ATT:
2570 mailimap_fetch_att_free(fetch_type->ft_data.ft_fetch_att);
2571 break;
2572 case MAILIMAP_FETCH_TYPE_FETCH_ATT_LIST:
2573 clist_foreach(fetch_type->ft_data.ft_fetch_att_list,
2574 (clist_func) mailimap_fetch_att_free, NULL);
2575 clist_free(fetch_type->ft_data.ft_fetch_att_list);
2576 break;
2577 }
2578 free(fetch_type);
2579}
2580
2581
2582
2583
2584struct mailimap_store_att_flags *
2585mailimap_store_att_flags_new(int fl_sign, int fl_silent,
2586 struct mailimap_flag_list * fl_flag_list)
2587{
2588 struct mailimap_store_att_flags * store_att_flags;
2589
2590 store_att_flags = malloc(sizeof(* store_att_flags));
2591 if (store_att_flags == NULL)
2592 return NULL;
2593
2594 store_att_flags->fl_sign = fl_sign;
2595 store_att_flags->fl_silent = fl_silent;
2596 store_att_flags->fl_flag_list = fl_flag_list;
2597
2598 return store_att_flags;
2599}
2600
2601void mailimap_store_att_flags_free(struct mailimap_store_att_flags *
2602 store_att_flags)
2603{
2604 mailimap_flag_list_free(store_att_flags->fl_flag_list);
2605 free(store_att_flags);
2606}
2607
2608
2609struct mailimap_search_key *
2610mailimap_search_key_new(int sk_type,
2611 char * sk_bcc, struct mailimap_date * sk_before, char * sk_body,
2612 char * sk_cc, char * sk_from, char * sk_keyword,
2613 struct mailimap_date * sk_on, struct mailimap_date * sk_since,
2614 char * sk_subject, char * sk_text, char * sk_to,
2615 char * sk_unkeyword, char * sk_header_name,
2616 char * sk_header_value, uint32_t sk_larger,
2617 struct mailimap_search_key * sk_not,
2618 struct mailimap_search_key * sk_or1,
2619 struct mailimap_search_key * sk_or2,
2620 struct mailimap_date * sk_sentbefore,
2621 struct mailimap_date * sk_senton,
2622 struct mailimap_date * sk_sentsince,
2623 uint32_t sk_smaller, struct mailimap_set * sk_uid,
2624 struct mailimap_set * sk_set, clist * sk_multiple)
2625{
2626 struct mailimap_search_key * key;
2627
2628 key = malloc(sizeof(* key));
2629 if (key == NULL)
2630 return NULL;
2631
2632 key->sk_type = sk_type;
2633 switch (sk_type) {
2634 case MAILIMAP_SEARCH_KEY_BCC:
2635 key->sk_data.sk_bcc = sk_bcc;
2636 break;
2637 case MAILIMAP_SEARCH_KEY_BEFORE:
2638 key->sk_data.sk_before = sk_before;
2639 break;
2640 case MAILIMAP_SEARCH_KEY_BODY:
2641 key->sk_data.sk_body = sk_body;
2642 break;
2643 case MAILIMAP_SEARCH_KEY_CC:
2644 key->sk_data.sk_cc = sk_cc;
2645 break;
2646 case MAILIMAP_SEARCH_KEY_FROM:
2647 key->sk_data.sk_from = sk_from;
2648 break;
2649 case MAILIMAP_SEARCH_KEY_KEYWORD:
2650 key->sk_data.sk_keyword = sk_keyword;
2651 break;
2652 case MAILIMAP_SEARCH_KEY_ON:
2653 key->sk_data.sk_on = sk_on;
2654 break;
2655 case MAILIMAP_SEARCH_KEY_SINCE:
2656 key->sk_data.sk_since = sk_since;
2657 break;
2658 case MAILIMAP_SEARCH_KEY_SUBJECT:
2659 key->sk_data.sk_subject = sk_subject;
2660 break;
2661 case MAILIMAP_SEARCH_KEY_TEXT:
2662 key->sk_data.sk_text = sk_text;
2663 break;
2664 case MAILIMAP_SEARCH_KEY_TO:
2665 key->sk_data.sk_to = sk_to;
2666 break;
2667 case MAILIMAP_SEARCH_KEY_UNKEYWORD:
2668 key->sk_data.sk_unkeyword = sk_unkeyword;
2669 break;
2670 case MAILIMAP_SEARCH_KEY_HEADER:
2671 key->sk_data.sk_header.sk_header_name = sk_header_name;
2672 key->sk_data.sk_header.sk_header_value = sk_header_value;
2673 break;
2674 case MAILIMAP_SEARCH_KEY_LARGER:
2675 key->sk_data.sk_larger = sk_larger;
2676 break;
2677 case MAILIMAP_SEARCH_KEY_NOT:
2678 key->sk_data.sk_not = sk_not;
2679 break;
2680 case MAILIMAP_SEARCH_KEY_OR:
2681 key->sk_data.sk_or.sk_or1 = sk_or1;
2682 key->sk_data.sk_or.sk_or2 = sk_or2;
2683 break;
2684 case MAILIMAP_SEARCH_KEY_SENTBEFORE:
2685 key->sk_data.sk_sentbefore = sk_sentbefore;
2686 break;
2687 case MAILIMAP_SEARCH_KEY_SENTON:
2688 key->sk_data.sk_senton = sk_senton;
2689 break;
2690 case MAILIMAP_SEARCH_KEY_SENTSINCE:
2691 key->sk_data.sk_sentsince = sk_sentsince;
2692 break;
2693 case MAILIMAP_SEARCH_KEY_SMALLER:
2694 key->sk_data.sk_smaller = sk_smaller;
2695 break;
2696 case MAILIMAP_SEARCH_KEY_UID:
2697 key->sk_data.sk_uid = sk_uid;
2698 break;
2699 case MAILIMAP_SEARCH_KEY_SET:
2700 key->sk_data.sk_set = sk_set;
2701 break;
2702 case MAILIMAP_SEARCH_KEY_MULTIPLE:
2703 key->sk_data.sk_multiple = sk_multiple;
2704 break;
2705 }
2706 return key;
2707}
2708
2709
2710void mailimap_search_key_free(struct mailimap_search_key * key)
2711{
2712 switch (key->sk_type) {
2713 case MAILIMAP_SEARCH_KEY_BCC:
2714 mailimap_astring_free(key->sk_data.sk_bcc);
2715 break;
2716 case MAILIMAP_SEARCH_KEY_BEFORE:
2717 mailimap_date_free(key->sk_data.sk_before);
2718 break;
2719 case MAILIMAP_SEARCH_KEY_BODY:
2720 mailimap_astring_free(key->sk_data.sk_body);
2721 break;
2722 case MAILIMAP_SEARCH_KEY_CC:
2723 mailimap_astring_free(key->sk_data.sk_cc);
2724 break;
2725 case MAILIMAP_SEARCH_KEY_FROM:
2726 mailimap_astring_free(key->sk_data.sk_from);
2727 break;
2728 case MAILIMAP_SEARCH_KEY_KEYWORD:
2729 mailimap_flag_keyword_free(key->sk_data.sk_keyword);
2730 break;
2731 case MAILIMAP_SEARCH_KEY_ON:
2732 mailimap_date_free(key->sk_data.sk_on);
2733 break;
2734 case MAILIMAP_SEARCH_KEY_SINCE:
2735 mailimap_date_free(key->sk_data.sk_since);
2736 break;
2737 case MAILIMAP_SEARCH_KEY_SUBJECT:
2738 mailimap_astring_free(key->sk_data.sk_subject);
2739 break;
2740 case MAILIMAP_SEARCH_KEY_TEXT:
2741 mailimap_astring_free(key->sk_data.sk_text);
2742 break;
2743 case MAILIMAP_SEARCH_KEY_TO:
2744 mailimap_astring_free(key->sk_data.sk_to);
2745 break;
2746 case MAILIMAP_SEARCH_KEY_UNKEYWORD:
2747 mailimap_flag_keyword_free(key->sk_data.sk_unkeyword);
2748 break;
2749 case MAILIMAP_SEARCH_KEY_HEADER:
2750 mailimap_header_fld_name_free(key->sk_data.sk_header.sk_header_name);
2751 mailimap_astring_free(key->sk_data.sk_header.sk_header_value);
2752 break;
2753 case MAILIMAP_SEARCH_KEY_NOT:
2754 mailimap_search_key_free(key->sk_data.sk_not);
2755 break;
2756 case MAILIMAP_SEARCH_KEY_OR:
2757 mailimap_search_key_free(key->sk_data.sk_or.sk_or1);
2758 mailimap_search_key_free(key->sk_data.sk_or.sk_or2);
2759 break;
2760 case MAILIMAP_SEARCH_KEY_SENTBEFORE:
2761 mailimap_date_free(key->sk_data.sk_sentbefore);
2762 break;
2763 case MAILIMAP_SEARCH_KEY_SENTON:
2764 mailimap_date_free(key->sk_data.sk_senton);
2765 break;
2766 case MAILIMAP_SEARCH_KEY_SENTSINCE:
2767 mailimap_date_free(key->sk_data.sk_sentsince);
2768 break;
2769 case MAILIMAP_SEARCH_KEY_UID:
2770 mailimap_set_free(key->sk_data.sk_uid);
2771 break;
2772 case MAILIMAP_SEARCH_KEY_SET:
2773 mailimap_set_free(key->sk_data.sk_set);
2774 break;
2775 case MAILIMAP_SEARCH_KEY_MULTIPLE:
2776 clist_foreach(key->sk_data.sk_multiple,
2777 (clist_func) mailimap_search_key_free, NULL);
2778 clist_free(key->sk_data.sk_multiple);
2779 break;
2780 }
2781
2782 free(key);
2783}
2784
2785
2786
2787
2788
2789
2790
2791
2792struct mailimap_status_att_list *
2793mailimap_status_att_list_new(clist * att_list)
2794{
2795 struct mailimap_status_att_list * status_att_list;
2796
2797 status_att_list = malloc(sizeof(* status_att_list));
2798 if (status_att_list == NULL)
2799 return NULL;
2800 status_att_list->att_list = att_list;
2801
2802 return status_att_list;
2803}
2804
2805void mailimap_status_att_list_free(struct mailimap_status_att_list *
2806 status_att_list)
2807{
2808 clist_foreach(status_att_list->att_list, (clist_func) free, NULL);
2809 clist_free(status_att_list->att_list);
2810 free(status_att_list);
2811}
2812
2813
2814
2815
2816/* main */
2817
2818
2819struct mailimap_selection_info *
2820mailimap_selection_info_new(void)
2821{
2822 struct mailimap_selection_info * sel_info;
2823
2824 sel_info = malloc(sizeof(* sel_info));
2825 if (sel_info == NULL)
2826 return NULL;
2827
2828 sel_info->sel_perm_flags = NULL;
2829 sel_info->sel_perm = MAILIMAP_MAILBOX_READWRITE;
2830 sel_info->sel_uidnext = 0;
2831 sel_info->sel_uidvalidity = 0;
2832 sel_info->sel_first_unseen = 0;
2833 sel_info->sel_flags = NULL;
2834 sel_info->sel_exists = 0;
2835 sel_info->sel_recent = 0;
2836 sel_info->sel_unseen = 0;
2837
2838 return sel_info;
2839}
2840
2841void
2842mailimap_selection_info_free(struct mailimap_selection_info * sel_info)
2843{
2844 if (sel_info->sel_perm_flags != NULL) {
2845 clist_foreach(sel_info->sel_perm_flags,
2846 (clist_func) mailimap_flag_perm_free, NULL);
2847 clist_free(sel_info->sel_perm_flags);
2848 }
2849 if (sel_info->sel_flags)
2850 mailimap_flag_list_free(sel_info->sel_flags);
2851
2852 free(sel_info);
2853}
2854
2855struct mailimap_connection_info *
2856mailimap_connection_info_new(void)
2857{
2858 struct mailimap_connection_info * conn_info;
2859
2860 conn_info = malloc(sizeof(* conn_info));
2861 if (conn_info == NULL)
2862 return NULL;
2863
2864 conn_info->imap_capability = NULL;
2865
2866 return conn_info;
2867}
2868
2869void
2870mailimap_connection_info_free(struct mailimap_connection_info * conn_info)
2871{
2872 if (conn_info->imap_capability != NULL)
2873 mailimap_capability_data_free(conn_info->imap_capability);
2874 free(conn_info);
2875}
2876
2877struct mailimap_response_info *
2878mailimap_response_info_new(void)
2879{
2880 struct mailimap_response_info * resp_info;
2881
2882 resp_info = malloc(sizeof(* resp_info));
2883 if (resp_info == NULL)
2884 goto err;
2885
2886 resp_info->rsp_alert = NULL;
2887 resp_info->rsp_parse = NULL;
2888 resp_info->rsp_badcharset = NULL;
2889 resp_info->rsp_trycreate = FALSE;
2890 resp_info->rsp_mailbox_list = clist_new();
2891 if (resp_info->rsp_mailbox_list == NULL)
2892 goto free;
2893 resp_info->rsp_mailbox_lsub = clist_new();
2894 if (resp_info->rsp_mailbox_lsub == NULL)
2895 goto free_mb_list;
2896 resp_info->rsp_search_result = clist_new();
2897 if (resp_info->rsp_search_result == NULL)
2898 goto free_mb_lsub;
2899 resp_info->rsp_status = NULL;
2900 resp_info->rsp_expunged = clist_new();
2901 if (resp_info->rsp_expunged == NULL)
2902 goto free_search_result;
2903 resp_info->rsp_fetch_list = clist_new();
2904 if (resp_info->rsp_fetch_list == NULL)
2905 goto free_expunged;
2906
2907 return resp_info;
2908
2909 free_expunged:
2910 clist_free(resp_info->rsp_expunged);
2911 free_search_result:
2912 clist_free(resp_info->rsp_search_result);
2913 free_mb_lsub:
2914 clist_free(resp_info->rsp_mailbox_lsub);
2915 free_mb_list:
2916 clist_free(resp_info->rsp_mailbox_list);
2917 free:
2918 free(resp_info);
2919 err:
2920 return NULL;
2921}
2922
2923void
2924mailimap_response_info_free(struct mailimap_response_info * resp_info)
2925{
2926 if (resp_info->rsp_alert != NULL)
2927 free(resp_info->rsp_alert);
2928 if (resp_info->rsp_parse != NULL)
2929 free(resp_info->rsp_parse);
2930 if (resp_info->rsp_badcharset != NULL) {
2931 clist_foreach(resp_info->rsp_badcharset,
2932 (clist_func) mailimap_astring_free, NULL);
2933 clist_free(resp_info->rsp_badcharset);
2934 }
2935 if (resp_info->rsp_mailbox_list != NULL) {
2936 clist_foreach(resp_info->rsp_mailbox_list,
2937 (clist_func) mailimap_mailbox_list_free, NULL);
2938 clist_free(resp_info->rsp_mailbox_list);
2939 }
2940 if (resp_info->rsp_mailbox_lsub != NULL) {
2941 clist_foreach(resp_info->rsp_mailbox_lsub,
2942 (clist_func) mailimap_mailbox_list_free, NULL);
2943 clist_free(resp_info->rsp_mailbox_lsub);
2944 }
2945 if (resp_info->rsp_search_result != NULL)
2946 mailimap_mailbox_data_search_free(resp_info->rsp_search_result);
2947 if (resp_info->rsp_status != NULL)
2948 mailimap_mailbox_data_status_free(resp_info->rsp_status);
2949 if (resp_info->rsp_expunged != NULL) {
2950 clist_foreach(resp_info->rsp_expunged,
2951 (clist_func) mailimap_number_alloc_free, NULL);
2952 clist_free(resp_info->rsp_expunged);
2953 }
2954 if (resp_info->rsp_fetch_list != NULL) {
2955 clist_foreach(resp_info->rsp_fetch_list,
2956 (clist_func) mailimap_msg_att_free, NULL);
2957 clist_free(resp_info->rsp_fetch_list);
2958 }
2959
2960 free(resp_info);
2961}
diff --git a/libetpan/src/low-level/imap/mailimap_types.h b/libetpan/src/low-level/imap/mailimap_types.h
new file mode 100644
index 0000000..532d2c0
--- a/dev/null
+++ b/libetpan/src/low-level/imap/mailimap_types.h
@@ -0,0 +1,3274 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36/*
37 IMAP4rev1 grammar
38
39 address = "(" addr-name SP addr-adl SP addr-mailbox SP
40 addr-host ")"
41
42 addr-adl = nstring
43 ; Holds route from [RFC-822] route-addr if
44 ; non-NIL
45
46 addr-host = nstring
47 ; NIL indicates [RFC-822] group syntax.
48 ; Otherwise, holds [RFC-822] domain name
49
50 addr-mailbox = nstring
51 ; NIL indicates end of [RFC-822] group; if
52 ; non-NIL and addr-host is NIL, holds
53 ; [RFC-822] group name.
54 ; Otherwise, holds [RFC-822] local-part
55 ; after removing [RFC-822] quoting
56
57
58
59 addr-name = nstring
60 ; If non-NIL, holds phrase from [RFC-822]
61 ; mailbox after removing [RFC-822] quoting
62
63 append = "APPEND" SP mailbox [SP flag-list] [SP date-time] SP
64 literal
65
66 astring = 1*ASTRING-CHAR / string
67
68 ASTRING-CHAR = ATOM-CHAR / resp-specials
69
70 atom = 1*ATOM-CHAR
71
72 ATOM-CHAR = <any CHAR except atom-specials>
73
74 atom-specials = "(" / ")" / "{" / SP / CTL / list-wildcards /
75 quoted-specials / resp-specials
76
77 authenticate = "AUTHENTICATE" SP auth-type *(CRLF base64)
78
79 auth-type = atom
80 ; Defined by [SASL]
81
82 base64 = *(4base64-char) [base64-terminal]
83
84 base64-char = ALPHA / DIGIT / "+" / "/"
85 ; Case-sensitive
86
87 base64-terminal = (2base64-char "==") / (3base64-char "=")
88
89 body = "(" (body-type-1part / body-type-mpart) ")"
90
91 body-extension = nstring / number /
92 "(" body-extension *(SP body-extension) ")"
93 ; Future expansion. Client implementations
94 ; MUST accept body-extension fields. Server
95 ; implementations MUST NOT generate
96 ; body-extension fields except as defined by
97 ; future standard or standards-track
98 ; revisions of this specification.
99
100 body-ext-1part = body-fld-md5 [SP body-fld-dsp [SP body-fld-lang
101 *(SP body-extension)]]
102 ; MUST NOT be returned on non-extensible
103 ; "BODY" fetch
104
105
106 body-ext-mpart = body-fld-param [SP body-fld-dsp [SP body-fld-lang
107 *(SP body-extension)]]
108 ; MUST NOT be returned on non-extensible
109 ; "BODY" fetch
110
111 body-fields = body-fld-param SP body-fld-id SP body-fld-desc SP
112 body-fld-enc SP body-fld-octets
113
114 body-fld-desc = nstring
115
116 body-fld-dsp = "(" string SP body-fld-param ")" / nil
117
118 body-fld-enc = (DQUOTE ("7BIT" / "8BIT" / "BINARY" / "BASE64"/
119 "QUOTED-PRINTABLE") DQUOTE) / string
120
121 body-fld-id = nstring
122
123 body-fld-lang = nstring / "(" string *(SP string) ")"
124
125 body-fld-lines = number
126
127 body-fld-md5 = nstring
128
129 body-fld-octets = number
130
131 body-fld-param = "(" string SP string *(SP string SP string) ")" / nil
132
133 body-type-1part = (body-type-basic / body-type-msg / body-type-text)
134 [SP body-ext-1part]
135
136 body-type-basic = media-basic SP body-fields
137 ; MESSAGE subtype MUST NOT be "RFC822"
138
139 body-type-mpart = 1*body SP media-subtype
140 [SP body-ext-mpart]
141
142 body-type-msg = media-message SP body-fields SP envelope
143 SP body SP body-fld-lines
144
145 body-type-text = media-text SP body-fields SP body-fld-lines
146
147 capability = ("AUTH=" auth-type) / atom
148 ; New capabilities MUST begin with "X" or be
149 ; registered with IANA as standard or
150 ; standards-track
151
152
153 capability-data = "CAPABILITY" *(SP capability) SP "IMAP4rev1"
154 *(SP capability)
155 ; IMAP4rev1 servers which offer RFC 1730
156 ; compatibility MUST list "IMAP4" as the first
157 ; capability.
158
159 CHAR8 = %x01-ff
160 ; any OCTET except NUL, %x00
161
162 command = tag SP (command-any / command-auth / command-nonauth /
163 command-select) CRLF
164 ; Modal based on state
165
166 command-any = "CAPABILITY" / "LOGOUT" / "NOOP" / x-command
167 ; Valid in all states
168
169 command-auth = append / create / delete / examine / list / lsub /
170 rename / select / status / subscribe / unsubscribe
171 ; Valid only in Authenticated or Selected state
172
173 command-nonauth = login / authenticate
174 ; Valid only when in Not Authenticated state
175
176 command-select = "CHECK" / "CLOSE" / "EXPUNGE" / copy / fetch / store /
177 uid / search
178 ; Valid only when in Selected state
179
180 continue-req = "+" SP (resp-text / base64) CRLF
181
182 copy = "COPY" SP set SP mailbox
183
184 create = "CREATE" SP mailbox
185 ; Use of INBOX gives a NO error
186
187 date = date-text / DQUOTE date-text DQUOTE
188
189 date-day = 1*2DIGIT
190 ; Day of month
191
192 date-day-fixed = (SP DIGIT) / 2DIGIT
193 ; Fixed-format version of date-day
194
195 date-month = "Jan" / "Feb" / "Mar" / "Apr" / "May" / "Jun" /
196 "Jul" / "Aug" / "Sep" / "Oct" / "Nov" / "Dec"
197
198 date-text = date-day "-" date-month "-" date-year
199
200 date-year = 4DIGIT
201
202 date-time = DQUOTE date-day-fixed "-" date-month "-" date-year
203 SP time SP zone DQUOTE
204
205 delete = "DELETE" SP mailbox
206 ; Use of INBOX gives a NO error
207
208 digit-nz = %x31-39
209 ; 1-9
210
211 envelope = "(" env-date SP env-subject SP env-from SP env-sender SP
212 env-reply-to SP env-to SP env-cc SP env-bcc SP
213 env-in-reply-to SP env-message-id ")"
214
215 env-bcc = "(" 1*address ")" / nil
216
217 env-cc = "(" 1*address ")" / nil
218
219 env-date = nstring
220
221 env-from = "(" 1*address ")" / nil
222
223 env-in-reply-to = nstring
224
225 env-message-id = nstring
226
227 env-reply-to = "(" 1*address ")" / nil
228
229 env-sender = "(" 1*address ")" / nil
230
231 env-subject = nstring
232
233 env-to = "(" 1*address ")" / nil
234
235 examine = "EXAMINE" SP mailbox
236
237 fetch = "FETCH" SP set SP ("ALL" / "FULL" / "FAST" / fetch-att /
238 "(" fetch-att *(SP fetch-att) ")")
239
240 fetch-att = "ENVELOPE" / "FLAGS" / "INTERNALDATE" /
241 "RFC822" [".HEADER" / ".SIZE" / ".TEXT"] /
242 "BODY" ["STRUCTURE"] / "UID" /
243 "BODY" [".PEEK"] section ["<" number "." nz-number ">"]
244
245 flag = "\Answered" / "\Flagged" / "\Deleted" /
246 "\Seen" / "\Draft" / flag-keyword / flag-extension
247 ; Does not include "\Recent"
248
249 flag-extension = "\" atom
250 ; Future expansion. Client implementations
251 ; MUST accept flag-extension flags. Server
252 ; implementations MUST NOT generate
253 ; flag-extension flags except as defined by
254 ; future standard or standards-track
255 ; revisions of this specification.
256
257 flag-fetch = flag / "\Recent"
258
259 flag-keyword = atom
260
261 flag-list = "(" [flag *(SP flag)] ")"
262
263 flag-perm = flag / "\*"
264
265 greeting = "*" SP (resp-cond-auth / resp-cond-bye) CRLF
266
267 header-fld-name = astring
268
269 header-list = "(" header-fld-name *(SP header-fld-name) ")"
270
271 list = "LIST" SP mailbox SP list-mailbox
272
273 list-mailbox = 1*list-char / string
274
275 list-char = ATOM-CHAR / list-wildcards / resp-specials
276
277 list-wildcards = "%" / "*"
278
279 literal = "{" number "}" CRLF *CHAR8
280 ; Number represents the number of CHAR8s
281
282 login = "LOGIN" SP userid SP password
283
284 lsub = "LSUB" SP mailbox SP list-mailbox
285
286 mailbox = "INBOX" / astring
287 ; INBOX is case-insensitive. All case variants of
288 ; INBOX (e.g. "iNbOx") MUST be interpreted as INBOX
289 ; not as an astring. An astring which consists of
290 ; the case-insensitive sequence "I" "N" "B" "O" "X"
291 ; is considered to be INBOX and not an astring.
292 ; Refer to section 5.1 for further
293 ; semantic details of mailbox names.
294
295 mailbox-data = "FLAGS" SP flag-list / "LIST" SP mailbox-list /
296 "LSUB" SP mailbox-list / "SEARCH" *(SP nz-number) /
297 "STATUS" SP mailbox SP "("
298 [status-att SP number *(SP status-att SP number)] ")" /
299 number SP "EXISTS" / number SP "RECENT"
300
301 mailbox-list = "(" [mbx-list-flags] ")" SP
302 (DQUOTE QUOTED-CHAR DQUOTE / nil) SP mailbox
303
304 mbx-list-flags = *(mbx-list-oflag SP) mbx-list-sflag
305 *(SP mbx-list-oflag) /
306 mbx-list-oflag *(SP mbx-list-oflag)
307
308 mbx-list-oflag = "\Noinferiors" / flag-extension
309 ; Other flags; multiple possible per LIST response
310
311 mbx-list-sflag = "\Noselect" / "\Marked" / "\Unmarked"
312 ; Selectability flags; only one per LIST response
313
314 media-basic = ((DQUOTE ("APPLICATION" / "AUDIO" / "IMAGE" / "MESSAGE" /
315 "VIDEO") DQUOTE) / string) SP media-subtype
316 ; Defined in [MIME-IMT]
317
318 media-message = DQUOTE "MESSAGE" DQUOTE SP DQUOTE "RFC822" DQUOTE
319 ; Defined in [MIME-IMT]
320
321 media-subtype = string
322 ; Defined in [MIME-IMT]
323
324 media-text = DQUOTE "TEXT" DQUOTE SP media-subtype
325 ; Defined in [MIME-IMT]
326
327 message-data = nz-number SP ("EXPUNGE" / ("FETCH" SP msg-att))
328
329 msg-att = "(" (msg-att-dynamic / msg-att-static)
330 *(SP (msg-att-dynamic / msg-att-static)) ")"
331
332 msg-att-dynamic = "FLAGS" SP "(" [flag-fetch *(SP flag-fetch)] ")"
333 ; MAY change for a message
334
335 msg-att-static = "ENVELOPE" SP envelope / "INTERNALDATE" SP date-time /
336 "RFC822" [".HEADER" / ".TEXT"] SP nstring /
337 "RFC822.SIZE" SP number / "BODY" ["STRUCTURE"] SP body /
338 "BODY" section ["<" number ">"] SP nstring /
339 "UID" SP uniqueid
340 ; MUST NOT change for a message
341
342 nil = "NIL"
343
344 nstring = string / nil
345
346 number = 1*DIGIT
347 ; Unsigned 32-bit integer
348 ; (0 <= n < 4,294,967,296)
349
350 nz-number = digit-nz *DIGIT
351 ; Non-zero unsigned 32-bit integer
352 ; (0 < n < 4,294,967,296)
353
354 password = astring
355
356 quoted = DQUOTE *QUOTED-CHAR DQUOTE
357
358 QUOTED-CHAR = <any TEXT-CHAR except quoted-specials> /
359 "\" quoted-specials
360
361 quoted-specials = DQUOTE / "\"
362
363 rename = "RENAME" SP mailbox SP mailbox
364 ; Use of INBOX as a destination gives a NO error
365
366 response = *(continue-req / response-data) response-done
367
368 response-data = "*" SP (resp-cond-state / resp-cond-bye /
369 mailbox-data / message-data / capability-data) CRLF
370
371 response-done = response-tagged / response-fatal
372
373 response-fatal = "*" SP resp-cond-bye CRLF
374 ; Server closes connection immediately
375
376 response-tagged = tag SP resp-cond-state CRLF
377
378 resp-cond-auth = ("OK" / "PREAUTH") SP resp-text
379 ; Authentication condition
380
381 resp-cond-bye = "BYE" SP resp-text
382
383 resp-cond-state = ("OK" / "NO" / "BAD") SP resp-text
384 ; Status condition
385
386 resp-specials = "]"
387
388 resp-text = ["[" resp-text-code "]" SP] text
389
390 resp-text-code = "ALERT" /
391 "BADCHARSET" [SP "(" astring *(SP astring) ")" ] /
392 capability-data / "PARSE" /
393 "PERMANENTFLAGS" SP "(" [flag-perm *(SP flag-perm)] ")" /
394 "READ-ONLY" / "READ-WRITE" / "TRYCREATE" /
395 "UIDNEXT" SP nz-number / "UIDVALIDITY" SP nz-number /
396 "UNSEEN" SP nz-number /
397 atom [SP 1*<any TEXT-CHAR except "]">]
398
399 search = "SEARCH" [SP "CHARSET" SP astring] 1*(SP search-key)
400 ; CHARSET argument to MUST be registered with IANA
401
402 search-key = "ALL" / "ANSWERED" / "BCC" SP astring /
403 "BEFORE" SP date / "BODY" SP astring /
404 "CC" SP astring / "DELETED" / "FLAGGED" /
405 "FROM" SP astring / "KEYWORD" SP flag-keyword / "NEW" /
406 "OLD" / "ON" SP date / "RECENT" / "SEEN" /
407 "SINCE" SP date / "SUBJECT" SP astring /
408 "TEXT" SP astring / "TO" SP astring /
409 "UNANSWERED" / "UNDELETED" / "UNFLAGGED" /
410 "UNKEYWORD" SP flag-keyword / "UNSEEN" /
411 ; Above this line were in [IMAP2]
412 "DRAFT" / "HEADER" SP header-fld-name SP astring /
413 "LARGER" SP number / "NOT" SP search-key /
414 "OR" SP search-key SP search-key /
415 "SENTBEFORE" SP date / "SENTON" SP date /
416 "SENTSINCE" SP date / "SMALLER" SP number /
417 "UID" SP set / "UNDRAFT" / set /
418 "(" search-key *(SP search-key) ")"
419
420 section = "[" [section-spec] "]"
421
422 section-msgtext = "HEADER" / "HEADER.FIELDS" [".NOT"] SP header-list /
423 "TEXT"
424 ; top-level or MESSAGE/RFC822 part
425
426 section-part = nz-number *("." nz-number)
427 ; body part nesting
428
429 section-spec = section-msgtext / (section-part ["." section-text])
430
431 section-text = section-msgtext / "MIME"
432 ; text other than actual body part (headers, etc.)
433
434 select = "SELECT" SP mailbox
435
436 sequence-num = nz-number / "*"
437 ; * is the largest number in use. For message
438 ; sequence numbers, it is the number of messages
439 ; in the mailbox. For unique identifiers, it is
440 ; the unique identifier of the last message in
441 ; the mailbox.
442
443 set = sequence-num / (sequence-num ":" sequence-num) /
444 (set "," set)
445 ; Identifies a set of messages. For message
446 ; sequence numbers, these are consecutive
447 ; numbers from 1 to the number of messages in
448 ; the mailbox
449 ; Comma delimits individual numbers, colon
450 ; delimits between two numbers inclusive.
451 ; Example: 2,4:7,9,12:* is 2,4,5,6,7,9,12,13,
452 ; 14,15 for a mailbox with 15 messages.
453
454
455 status = "STATUS" SP mailbox SP "(" status-att *(SP status-att) ")"
456
457 status-att = "MESSAGES" / "RECENT" / "UIDNEXT" / "UIDVALIDITY" /
458 "UNSEEN"
459
460 store = "STORE" SP set SP store-att-flags
461
462 store-att-flags = (["+" / "-"] "FLAGS" [".SILENT"]) SP
463 (flag-list / (flag *(SP flag)))
464
465 string = quoted / literal
466
467 subscribe = "SUBSCRIBE" SP mailbox
468
469 tag = 1*<any ASTRING-CHAR except "+">
470
471 text = 1*TEXT-CHAR
472
473 TEXT-CHAR = <any CHAR except CR and LF>
474
475 time = 2DIGIT ":" 2DIGIT ":" 2DIGIT
476 ; Hours minutes seconds
477
478 uid = "UID" SP (copy / fetch / search / store)
479 ; Unique identifiers used instead of message
480 ; sequence numbers
481
482 uniqueid = nz-number
483 ; Strictly ascending
484
485 unsubscribe = "UNSUBSCRIBE" SP mailbox
486
487 userid = astring
488
489 x-command = "X" atom <experimental command arguments>
490
491 zone = ("+" / "-") 4DIGIT
492 ; Signed four-digit value of hhmm representing
493 ; hours and minutes east of Greenwich (that is,
494 ; the amount that the given time differs from
495 ; Universal Time). Subtracting the timezone
496 ; from the given time will give the UT form.
497 ; The Universal Time zone is "+0000".
498*/
499
500
501#ifndef MAILIMAP_TYPES_H
502
503#define MAILIMAP_TYPES_H
504
505#ifdef __cplusplus
506extern "C" {
507#endif
508
509#include <inttypes.h>
510#include <libetpan/mailstream.h>
511#include <libetpan/clist.h>
512
513
514/*
515 IMPORTANT NOTE:
516
517 All allocation functions will take as argument allocated data
518 and will store these data in the structure they will allocate.
519 Data should be persistant during all the use of the structure
520 and will be freed by the free function of the structure
521
522 allocation functions will return NULL on failure
523*/
524
525
526/*
527 mailimap_address represents a mail address
528
529 - personal_name is the name to display in an address
530 '"name"' in '"name" <address@domain>', should be allocated
531 with a malloc()
532
533 - source_route is the source-route information in the
534 mail address (RFC 822), should be allocated with a malloc()
535
536 - mailbox_name is the name of the mailbox 'address' in
537 '"name" <address@domain>', should be allocated with a malloc()
538
539 - host_name is the name of the host 'domain' in
540 '"name" <address@domain>', should be allocated with a malloc()
541
542 if mailbox_name is not NULL and host_name is NULL, this is the name
543 of a group, the next addresses in the list are elements of the group
544 until we reach an address with a NULL mailbox_name.
545*/
546
547struct mailimap_address {
548 char * ad_personal_name; /* can be NULL */
549 char * ad_source_route; /* can be NULL */
550 char * ad_mailbox_name; /* can be NULL */
551 char * ad_host_name; /* can be NULL */
552};
553
554
555struct mailimap_address *
556mailimap_address_new(char * ad_personal_name, char * ad_source_route,
557 char * ad_mailbox_name, char * ad_host_name);
558
559void mailimap_address_free(struct mailimap_address * addr);
560
561
562/* this is the type of MIME body parsed by IMAP server */
563
564enum {
565 MAILIMAP_BODY_ERROR,
566 MAILIMAP_BODY_1PART, /* single part */
567 MAILIMAP_BODY_MPART, /* multi-part */
568};
569
570/*
571 mailimap_body represent a MIME body parsed by IMAP server
572
573 - type is the type of the MIME part (single part or multipart)
574
575 - body_1part is defined if this is a single part
576
577 - body_mpart is defined if this is a multipart
578*/
579
580struct mailimap_body {
581 int bd_type;
582 /* can be MAILIMAP_BODY_1PART or MAILIMAP_BODY_MPART */
583 union {
584 struct mailimap_body_type_1part * bd_body_1part; /* can be NULL */
585 struct mailimap_body_type_mpart * bd_body_mpart; /* can be NULL */
586 } bd_data;
587};
588
589
590struct mailimap_body *
591mailimap_body_new(int bd_type,
592 struct mailimap_body_type_1part * bd_body_1part,
593 struct mailimap_body_type_mpart * bd_body_mpart);
594
595void mailimap_body_free(struct mailimap_body * body);
596
597
598
599/*
600 this is the type of MIME body extension
601*/
602
603enum {
604 MAILIMAP_BODY_EXTENSION_ERROR,
605 MAILIMAP_BODY_EXTENSION_NSTRING, /* string */
606 MAILIMAP_BODY_EXTENSION_NUMBER, /* number */
607 MAILIMAP_BODY_EXTENSION_LIST, /* list of
608 (struct mailimap_body_extension *) */
609};
610
611/*
612 mailimap_body_extension is a future extension header field value
613
614 - type is the type of the body extension (string, number or
615 list of extension)
616
617 - nstring is a string value if the type is string
618
619 - number is a integer value if the type is number
620
621 - list is a list of body extension if the type is a list
622*/
623
624struct mailimap_body_extension {
625 int ext_type;
626 /*
627 can be MAILIMAP_BODY_EXTENSION_NSTRING, MAILIMAP_BODY_EXTENSION_NUMBER
628 or MAILIMAP_BODY_EXTENSION_LIST
629 */
630 union {
631 char * ext_nstring; /* can be NULL */
632 uint32_t ext_number;
633 clist * ext_body_extension_list;
634 /* list of (struct mailimap_body_extension *) */
635 /* can be NULL */
636 } ext_data;
637};
638
639struct mailimap_body_extension *
640mailimap_body_extension_new(int ext_type, char * ext_nstring,
641 uint32_t ext_number,
642 clist * ext_body_extension_list);
643
644void mailimap_body_extension_free(struct mailimap_body_extension * be);
645
646
647/*
648 mailimap_body_ext_1part is the extended result part of a single part
649 bodystructure.
650
651 - body_md5 is the value of the Content-MD5 header field, should be
652 allocated with malloc()
653
654 - body_disposition is the value of the Content-Disposition header field
655
656 - body_language is the value of the Content-Language header field
657
658 - body_extension_list is the list of extension fields value.
659*/
660
661struct mailimap_body_ext_1part {
662 char * bd_md5; /* != NULL */
663 struct mailimap_body_fld_dsp * bd_disposition; /* can be NULL */
664 struct mailimap_body_fld_lang * bd_language; /* can be NULL */
665
666 clist * bd_extension_list; /* list of (struct mailimap_body_extension *) */
667 /* can be NULL */
668};
669
670struct mailimap_body_ext_1part *
671mailimap_body_ext_1part_new(char * bd_md5,
672 struct mailimap_body_fld_dsp * bd_disposition,
673 struct mailimap_body_fld_lang * bd_language,
674 clist * bd_extension_list);
675
676
677void
678mailimap_body_ext_1part_free(struct mailimap_body_ext_1part * body_ext_1part);
679
680
681/*
682 mailimap_body_ext_mpart is the extended result part of a multipart
683 bodystructure.
684
685 - body_parameter is the list of parameters of Content-Type header field
686
687 - body_disposition is the value of Content-Disposition header field
688
689 - body_language is the value of Content-Language header field
690
691 - body_extension_list is the list of extension fields value.
692*/
693
694struct mailimap_body_ext_mpart {
695 struct mailimap_body_fld_param * bd_parameter; /* != NULL */
696 struct mailimap_body_fld_dsp * bd_disposition; /* can be NULL */
697 struct mailimap_body_fld_lang * bd_language; /* can be NULL */
698 clist * bd_extension_list; /* list of (struct mailimap_body_extension *) */
699 /* can be NULL */
700};
701
702struct mailimap_body_ext_mpart *
703mailimap_body_ext_mpart_new(struct mailimap_body_fld_param * bd_parameter,
704 struct mailimap_body_fld_dsp * bd_disposition,
705 struct mailimap_body_fld_lang * bd_language,
706 clist * bd_extension_list);
707
708void
709mailimap_body_ext_mpart_free(struct mailimap_body_ext_mpart * body_ext_mpart);
710
711
712/*
713 mailimap_body_fields is the MIME fields of a MIME part.
714
715 - body_parameter is the list of parameters of Content-Type header field
716
717 - body_id is the value of Content-ID header field, should be allocated
718 with malloc()
719
720 - body_description is the value of Content-Description header field,
721 should be allocated with malloc()
722
723 - body_encoding is the value of Content-Transfer-Encoding header field
724
725 - body_disposition is the value of Content-Disposition header field
726
727 - body_size is the size of the MIME part
728*/
729
730struct mailimap_body_fields {
731 struct mailimap_body_fld_param * bd_parameter; /* != NULL */
732 char * bd_id; /* can be NULL */
733 char * bd_description; /* can be NULL */
734 struct mailimap_body_fld_enc * bd_encoding; /* != NULL */
735 uint32_t bd_size;
736};
737
738struct mailimap_body_fields *
739mailimap_body_fields_new(struct mailimap_body_fld_param * bd_parameter,
740 char * bd_id,
741 char * bd_description,
742 struct mailimap_body_fld_enc * bd_encoding,
743 uint32_t bd_size);
744
745void
746mailimap_body_fields_free(struct mailimap_body_fields * body_fields);
747
748
749
750/*
751 mailimap_body_fld_dsp is the parsed value of the Content-Disposition field
752
753 - disposition_type is the type of Content-Disposition
754 (usually attachment or inline), should be allocated with malloc()
755
756 - attributes is the list of Content-Disposition attributes
757*/
758
759struct mailimap_body_fld_dsp {
760 char * dsp_type; /* != NULL */
761 struct mailimap_body_fld_param * dsp_attributes; /* != NULL */
762};
763
764struct mailimap_body_fld_dsp *
765mailimap_body_fld_dsp_new(char * dsp_type,
766 struct mailimap_body_fld_param * dsp_attributes);
767
768void mailimap_body_fld_dsp_free(struct mailimap_body_fld_dsp * bfd);
769
770
771
772/* these are the different parsed values for Content-Transfer-Encoding */
773
774enum {
775 MAILIMAP_BODY_FLD_ENC_7BIT, /* 7bit */
776 MAILIMAP_BODY_FLD_ENC_8BIT, /* 8bit */
777 MAILIMAP_BODY_FLD_ENC_BINARY, /* binary */
778 MAILIMAP_BODY_FLD_ENC_BASE64, /* base64 */
779 MAILIMAP_BODY_FLD_ENC_QUOTED_PRINTABLE, /* quoted-printable */
780 MAILIMAP_BODY_FLD_ENC_OTHER, /* other */
781};
782
783/*
784 mailimap_body_fld_enc is a parsed value for Content-Transfer-Encoding
785
786 - type is the kind of Content-Transfer-Encoding, this can be
787 MAILIMAP_BODY_FLD_ENC_7BIT, MAILIMAP_BODY_FLD_ENC_8BIT,
788 MAILIMAP_BODY_FLD_ENC_BINARY, MAILIMAP_BODY_FLD_ENC_BASE64,
789 MAILIMAP_BODY_FLD_ENC_QUOTED_PRINTABLE or MAILIMAP_BODY_FLD_ENC_OTHER
790
791 - in case of MAILIMAP_BODY_FLD_ENC_OTHER, this value is defined,
792 should be allocated with malloc()
793*/
794
795struct mailimap_body_fld_enc {
796 int enc_type;
797 char * enc_value; /* can be NULL */
798};
799
800struct mailimap_body_fld_enc *
801mailimap_body_fld_enc_new(int enc_type, char * enc_value);
802
803void mailimap_body_fld_enc_free(struct mailimap_body_fld_enc * bfe);
804
805
806/* this is the type of Content-Language header field value */
807
808enum {
809 MAILIMAP_BODY_FLD_LANG_ERROR, /* error parse */
810 MAILIMAP_BODY_FLD_LANG_SINGLE, /* single value */
811 MAILIMAP_BODY_FLD_LANG_LIST /* list of values */
812};
813
814/*
815 mailimap_body_fld_lang is the parsed value of the Content-Language field
816
817 - type is the type of content, this can be MAILIMAP_BODY_FLD_LANG_SINGLE
818 if this is a single value or MAILIMAP_BODY_FLD_LANG_LIST if there are
819 several values
820
821 - single is the single value if the type is MAILIMAP_BODY_FLD_LANG_SINGLE,
822 should be allocated with malloc()
823
824 - list is the list of value if the type is MAILIMAP_BODY_FLD_LANG_LIST,
825 all elements of the list should be allocated with malloc()
826*/
827
828struct mailimap_body_fld_lang {
829 int lg_type;
830 union {
831 char * lg_single; /* can be NULL */
832 clist * lg_list; /* list of string (char *), can be NULL */
833 } lg_data;
834};
835
836struct mailimap_body_fld_lang *
837mailimap_body_fld_lang_new(int lg_type, char * lg_single, clist * lg_list);
838
839void
840mailimap_body_fld_lang_free(struct mailimap_body_fld_lang * fld_lang);
841
842
843
844/*
845 mailimap_single_body_fld_param is a body field parameter
846
847 - name is the name of the parameter, should be allocated with malloc()
848
849 - value is the value of the parameter, should be allocated with malloc()
850*/
851
852struct mailimap_single_body_fld_param {
853 char * pa_name; /* != NULL */
854 char * pa_value; /* != NULL */
855};
856
857struct mailimap_single_body_fld_param *
858mailimap_single_body_fld_param_new(char * pa_name, char * pa_value);
859
860void
861mailimap_single_body_fld_param_free(struct mailimap_single_body_fld_param * p);
862
863
864/*
865 mailmap_body_fld_param is a list of parameters
866
867 - list is the list of parameters.
868*/
869
870struct mailimap_body_fld_param {
871 clist * pa_list; /* list of (struct mailimap_single_body_fld_param *) */
872 /* != NULL */
873};
874
875struct mailimap_body_fld_param *
876mailimap_body_fld_param_new(clist * pa_list);
877
878void
879mailimap_body_fld_param_free(struct mailimap_body_fld_param * fld_param);
880
881
882/*
883 this is the kind of single part: a text part
884 (when Content-Type is text/xxx), a message part (when Content-Type is
885 message/rfc2822) or a basic part (others than multpart/xxx)
886*/
887
888enum {
889 MAILIMAP_BODY_TYPE_1PART_ERROR, /* parse error */
890 MAILIMAP_BODY_TYPE_1PART_BASIC, /* others then multipart/xxx */
891 MAILIMAP_BODY_TYPE_1PART_MSG, /* message/rfc2822 */
892 MAILIMAP_BODY_TYPE_1PART_TEXT /* text/xxx */
893};
894
895
896/*
897 mailimap_body_type_1part is
898
899 - type is the kind of single part, this can be
900 MAILIMAP_BODY_TYPE_1PART_BASIC, MAILIMAP_BODY_TYPE_1PART_MSG or
901 MAILIMAP_BODY_TYPE_1PART_TEXT.
902
903 - body_type_basic is the basic part when type is
904 MAILIMAP_BODY_TYPE_1PART_BASIC
905
906 - body_type_msg is the message part when type is
907 MAILIMAP_BODY_TYPE_1PART_MSG
908
909 - body_type_text is the text part when type is
910 MAILIMAP_BODY_TYPE_1PART_TEXT
911*/
912
913struct mailimap_body_type_1part {
914 int bd_type;
915 union {
916 struct mailimap_body_type_basic * bd_type_basic; /* can be NULL */
917 struct mailimap_body_type_msg * bd_type_msg; /* can be NULL */
918 struct mailimap_body_type_text * bd_type_text; /* can be NULL */
919 } bd_data;
920 struct mailimap_body_ext_1part * bd_ext_1part; /* can be NULL */
921};
922
923struct mailimap_body_type_1part *
924mailimap_body_type_1part_new(int bd_type,
925 struct mailimap_body_type_basic * bd_type_basic,
926 struct mailimap_body_type_msg * bd_type_msg,
927 struct mailimap_body_type_text * bd_type_text,
928 struct mailimap_body_ext_1part * bd_ext_1part);
929
930void
931mailimap_body_type_1part_free(struct mailimap_body_type_1part * bt1p);
932
933
934
935/*
936 mailimap_body_type_basic is a basic field (with Content-Type other
937 than multipart/xxx, message/rfc2822 and text/xxx
938
939 - media_basic will be the MIME type of the part
940
941 - body_fields will be the parsed fields of the MIME part
942*/
943
944struct mailimap_body_type_basic {
945 struct mailimap_media_basic * bd_media_basic; /* != NULL */
946 struct mailimap_body_fields * bd_fields; /* != NULL */
947};
948
949struct mailimap_body_type_basic *
950mailimap_body_type_basic_new(struct mailimap_media_basic * bd_media_basic,
951 struct mailimap_body_fields * bd_fields);
952
953void mailimap_body_type_basic_free(struct mailimap_body_type_basic *
954 body_type_basic);
955
956/*
957 mailimap_body_type_mpart is a MIME multipart.
958
959 - body_list is the list of sub-parts.
960
961 - media_subtype is the subtype of the multipart (for example
962 in multipart/alternative, this is "alternative")
963
964 - body_ext_mpart is the extended fields of the MIME multipart
965*/
966
967struct mailimap_body_type_mpart {
968 clist * bd_list; /* list of (struct mailimap_body *) */
969 /* != NULL */
970 char * bd_media_subtype; /* != NULL */
971 struct mailimap_body_ext_mpart * bd_ext_mpart; /* can be NULL */
972};
973
974struct mailimap_body_type_mpart *
975mailimap_body_type_mpart_new(clist * bd_list, char * bd_media_subtype,
976 struct mailimap_body_ext_mpart * bd_ext_mpart);
977
978void mailimap_body_type_mpart_free(struct mailimap_body_type_mpart *
979 body_type_mpart);
980
981/*
982 mailimap_body_type_msg is a MIME message part
983
984 - body_fields is the MIME fields of the MIME message part
985
986 - envelope is the list of parsed RFC 822 fields of the MIME message
987
988 - body is the sub-part of the message
989
990 - body_lines is the number of lines of the message part
991*/
992
993struct mailimap_body_type_msg {
994 struct mailimap_body_fields * bd_fields; /* != NULL */
995 struct mailimap_envelope * bd_envelope; /* != NULL */
996 struct mailimap_body * bd_body; /* != NULL */
997 uint32_t bd_lines;
998};
999
1000struct mailimap_body_type_msg *
1001mailimap_body_type_msg_new(struct mailimap_body_fields * bd_fields,
1002 struct mailimap_envelope * bd_envelope,
1003 struct mailimap_body * bd_body,
1004 uint32_t bd_lines);
1005
1006void
1007mailimap_body_type_msg_free(struct mailimap_body_type_msg * body_type_msg);
1008
1009
1010
1011/*
1012 mailimap_body_type_text is a single MIME part where Content-Type is text/xxx
1013
1014 - media-text is the subtype of the text part (for example, in "text/plain",
1015 this is "plain", should be allocated with malloc()
1016
1017 - body_fields is the MIME fields of the MIME message part
1018
1019 - body_lines is the number of lines of the message part
1020*/
1021
1022struct mailimap_body_type_text {
1023 char * bd_media_text; /* != NULL */
1024 struct mailimap_body_fields * bd_fields; /* != NULL */
1025 uint32_t bd_lines;
1026};
1027
1028struct mailimap_body_type_text *
1029mailimap_body_type_text_new(char * bd_media_text,
1030 struct mailimap_body_fields * bd_fields,
1031 uint32_t bd_lines);
1032
1033void
1034mailimap_body_type_text_free(struct mailimap_body_type_text * body_type_text);
1035
1036
1037
1038/* this is the type of capability field */
1039
1040enum {
1041 MAILIMAP_CAPABILITY_AUTH_TYPE, /* when the capability is an
1042 authentication type */
1043 MAILIMAP_CAPABILITY_NAME, /* other type of capability */
1044};
1045
1046/*
1047 mailimap_capability is a capability of the IMAP server
1048
1049 - type is the type of capability, this is either a authentication type
1050 (MAILIMAP_CAPABILITY_AUTH_TYPE) or an other type of capability
1051 (MAILIMAP_CAPABILITY_NAME)
1052
1053 - auth_type is a type of authentication "name" in "AUTH=name",
1054 auth_type can be for example "PLAIN", when this is an authentication type,
1055 should be allocated with malloc()
1056
1057 - name is a type of capability when this is not an authentication type,
1058 should be allocated with malloc()
1059*/
1060
1061struct mailimap_capability {
1062 int cap_type;
1063 union {
1064 char * cap_auth_type; /* can be NULL */
1065 char * cap_name; /* can be NULL */
1066 } cap_data;
1067};
1068
1069struct mailimap_capability *
1070mailimap_capability_new(int cap_type, char * cap_auth_type, char * cap_name);
1071
1072void mailimap_capability_free(struct mailimap_capability * c);
1073
1074
1075
1076
1077/*
1078 mailimap_capability_data is a list of capability
1079
1080 - list is the list of capability
1081*/
1082
1083struct mailimap_capability_data {
1084 clist * cap_list; /* list of (struct mailimap_capability *), != NULL */
1085};
1086
1087struct mailimap_capability_data *
1088mailimap_capability_data_new(clist * cap_list);
1089
1090void
1091mailimap_capability_data_free(struct mailimap_capability_data * cap_data);
1092
1093
1094
1095/* this is the type of continue request data */
1096
1097enum {
1098 MAILIMAP_CONTINUE_REQ_ERROR, /* on parse error */
1099 MAILIMAP_CONTINUE_REQ_TEXT, /* when data is a text response */
1100 MAILIMAP_CONTINUE_REQ_BASE64, /* when data is a base64 response */
1101};
1102
1103/*
1104 mailimap_continue_req is a continue request (a response prefixed by "+")
1105
1106 - type is the type of continue request response
1107 MAILIMAP_CONTINUE_REQ_TEXT (when information data is text),
1108 MAILIMAP_CONTINUE_REQ_BASE64 (when information data is base64)
1109
1110 - text is the information of type text in case of text data
1111
1112 - base64 is base64 encoded data in the other case, should be allocated
1113 with malloc()
1114*/
1115
1116struct mailimap_continue_req {
1117 int cr_type;
1118 union {
1119 struct mailimap_resp_text * cr_text; /* can be NULL */
1120 char * cr_base64; /* can be NULL */
1121 } cr_data;
1122};
1123
1124struct mailimap_continue_req *
1125mailimap_continue_req_new(int cr_type, struct mailimap_resp_text * cr_text,
1126 char * cr_base64);
1127
1128void mailimap_continue_req_free(struct mailimap_continue_req * cont_req);
1129
1130
1131/*
1132 mailimap_date_time is a date
1133
1134 - day is the day of month (1 to 31)
1135
1136 - month (1 to 12)
1137
1138 - year (4 digits)
1139
1140 - hour (0 to 23)
1141
1142 - min (0 to 59)
1143
1144 - sec (0 to 59)
1145
1146 - zone (this is the decimal value that we can read, for example:
1147 for "-0200", the value is -200)
1148*/
1149
1150struct mailimap_date_time {
1151 int dt_day;
1152 int dt_month;
1153 int dt_year;
1154 int dt_hour;
1155 int dt_min;
1156 int dt_sec;
1157 int dt_zone;
1158};
1159
1160struct mailimap_date_time *
1161mailimap_date_time_new(int dt_day, int dt_month, int dt_year, int dt_hour,
1162 int dt_min, int dt_sec, int dt_zone);
1163
1164void mailimap_date_time_free(struct mailimap_date_time * date_time);
1165
1166
1167
1168/*
1169 mailimap_envelope is the list of fields that can be parsed by
1170 the IMAP server.
1171
1172 - date is the (non-parsed) content of the "Date" header field,
1173 should be allocated with malloc()
1174
1175 - subject is the subject of the message, should be allocated with
1176 malloc()
1177
1178 - sender is the the parsed content of the "Sender" field
1179
1180 - reply-to is the parsed content of the "Reply-To" field
1181
1182 - to is the parsed content of the "To" field
1183
1184 - cc is the parsed content of the "Cc" field
1185
1186 - bcc is the parsed content of the "Bcc" field
1187
1188 - in_reply_to is the content of the "In-Reply-To" field,
1189 should be allocated with malloc()
1190
1191 - message_id is the content of the "Message-ID" field,
1192 should be allocated with malloc()
1193*/
1194
1195struct mailimap_envelope {
1196 char * env_date; /* can be NULL */
1197 char * env_subject; /* can be NULL */
1198 struct mailimap_env_from * env_from; /* can be NULL */
1199 struct mailimap_env_sender * env_sender; /* can be NULL */
1200 struct mailimap_env_reply_to * env_reply_to; /* can be NULL */
1201 struct mailimap_env_to * env_to; /* can be NULL */
1202 struct mailimap_env_cc * env_cc; /* can be NULL */
1203 struct mailimap_env_bcc * env_bcc; /* can be NULL */
1204 char * env_in_reply_to; /* can be NULL */
1205 char * env_message_id; /* can be NULL */
1206};
1207
1208struct mailimap_envelope *
1209mailimap_envelope_new(char * env_date, char * env_subject,
1210 struct mailimap_env_from * env_from,
1211 struct mailimap_env_sender * env_sender,
1212 struct mailimap_env_reply_to * env_reply_to,
1213 struct mailimap_env_to * env_to,
1214 struct mailimap_env_cc* env_cc,
1215 struct mailimap_env_bcc * env_bcc,
1216 char * env_in_reply_to, char * env_message_id);
1217
1218void mailimap_envelope_free(struct mailimap_envelope * env);
1219
1220
1221
1222/*
1223 mailimap_env_bcc is the parsed "Bcc" field
1224
1225 - list is the list of addresses
1226*/
1227
1228struct mailimap_env_bcc {
1229 clist * bcc_list; /* list of (struct mailimap_address *), != NULL */
1230};
1231
1232struct mailimap_env_bcc * mailimap_env_bcc_new(clist * bcc_list);
1233
1234void mailimap_env_bcc_free(struct mailimap_env_bcc * env_bcc);
1235
1236
1237/*
1238 mailimap_env_cc is the parsed "Cc" field
1239
1240 - list is the list of addresses
1241*/
1242
1243struct mailimap_env_cc {
1244 clist * cc_list; /* list of (struct mailimap_address *), != NULL */
1245};
1246
1247struct mailimap_env_cc * mailimap_env_cc_new(clist * cc_list);
1248
1249void mailimap_env_cc_free(struct mailimap_env_cc * env_cc);
1250
1251
1252
1253/*
1254 mailimap_env_from is the parsed "From" field
1255
1256 - list is the list of addresses
1257*/
1258
1259struct mailimap_env_from {
1260 clist * frm_list; /* list of (struct mailimap_address *) */
1261 /* != NULL */
1262};
1263
1264struct mailimap_env_from * mailimap_env_from_new(clist * frm_list);
1265
1266void mailimap_env_from_free(struct mailimap_env_from * env_from);
1267
1268
1269
1270/*
1271 mailimap_env_reply_to is the parsed "Reply-To" field
1272
1273 - list is the list of addresses
1274*/
1275
1276struct mailimap_env_reply_to {
1277 clist * rt_list; /* list of (struct mailimap_address *), != NULL */
1278};
1279
1280struct mailimap_env_reply_to * mailimap_env_reply_to_new(clist * rt_list);
1281
1282void
1283mailimap_env_reply_to_free(struct mailimap_env_reply_to * env_reply_to);
1284
1285
1286
1287/*
1288 mailimap_env_sender is the parsed "Sender" field
1289
1290 - list is the list of addresses
1291*/
1292
1293struct mailimap_env_sender {
1294 clist * snd_list; /* list of (struct mailimap_address *), != NULL */
1295};
1296
1297struct mailimap_env_sender * mailimap_env_sender_new(clist * snd_list);
1298
1299void mailimap_env_sender_free(struct mailimap_env_sender * env_sender);
1300
1301
1302
1303/*
1304 mailimap_env_to is the parsed "To" field
1305
1306 - list is the list of addresses
1307*/
1308
1309struct mailimap_env_to {
1310 clist * to_list; /* list of (struct mailimap_address *), != NULL */
1311};
1312
1313struct mailimap_env_to * mailimap_env_to_new(clist * to_list);
1314
1315void mailimap_env_to_free(struct mailimap_env_to * env_to);
1316
1317
1318/* this is the type of flag */
1319
1320enum {
1321 MAILIMAP_FLAG_ANSWERED, /* \Answered flag */
1322 MAILIMAP_FLAG_FLAGGED, /* \Flagged flag */
1323 MAILIMAP_FLAG_DELETED, /* \Deleted flag */
1324 MAILIMAP_FLAG_SEEN, /* \Seen flag */
1325 MAILIMAP_FLAG_DRAFT, /* \Draft flag */
1326 MAILIMAP_FLAG_KEYWORD, /* keyword flag */
1327 MAILIMAP_FLAG_EXTENSION, /* \extension flag */
1328};
1329
1330
1331/*
1332 mailimap_flag is a message flag (that we can associate with a message)
1333
1334 - type is the type of the flag, MAILIMAP_FLAG_XXX
1335
1336 - keyword is the flag when the flag is of keyword type,
1337 should be allocated with malloc()
1338
1339 - extension is the flag when the flag is of extension type, should be
1340 allocated with malloc()
1341*/
1342
1343struct mailimap_flag {
1344 int fl_type;
1345 union {
1346 char * fl_keyword; /* can be NULL */
1347 char * fl_extension; /* can be NULL */
1348 } fl_data;
1349};
1350
1351struct mailimap_flag * mailimap_flag_new(int fl_type,
1352 char * fl_keyword, char * fl_extension);
1353
1354void mailimap_flag_free(struct mailimap_flag * f);
1355
1356
1357
1358
1359/* this is the type of flag */
1360
1361enum {
1362 MAILIMAP_FLAG_FETCH_ERROR, /* on parse error */
1363 MAILIMAP_FLAG_FETCH_RECENT, /* \Recent flag */
1364 MAILIMAP_FLAG_FETCH_OTHER, /* other type of flag */
1365};
1366
1367/*
1368 mailimap_flag_fetch is a message flag (when we fetch it)
1369
1370 - type is the type of flag fetch
1371
1372 - flag is the flag when this is not a \Recent flag
1373*/
1374
1375struct mailimap_flag_fetch {
1376 int fl_type;
1377 struct mailimap_flag * fl_flag; /* can be NULL */
1378};
1379
1380struct mailimap_flag_fetch *
1381mailimap_flag_fetch_new(int fl_type, struct mailimap_flag * fl_flag);
1382
1383void mailimap_flag_fetch_free(struct mailimap_flag_fetch * flag_fetch);
1384
1385
1386
1387
1388/* this is the type of flag */
1389
1390enum {
1391 MAILIMAP_FLAG_PERM_ERROR, /* on parse error */
1392 MAILIMAP_FLAG_PERM_FLAG, /* to specify that usual flags can be changed */
1393 MAILIMAP_FLAG_PERM_ALL /* to specify that new flags can be created */
1394};
1395
1396
1397/*
1398 mailimap_flag_perm is a flag returned in case of PERMANENTFLAGS response
1399
1400 - type is the type of returned PERMANENTFLAGS, it can be
1401 MAILIMAP_FLAG_PERM_FLAG (the given flag can be changed permanently) or
1402 MAILIMAP_FLAG_PERM_ALL (new flags can be created)
1403
1404 - flag is the given flag when type is MAILIMAP_FLAG_PERM_FLAG
1405*/
1406
1407struct mailimap_flag_perm {
1408 int fl_type;
1409 struct mailimap_flag * fl_flag; /* can be NULL */
1410};
1411
1412struct mailimap_flag_perm *
1413mailimap_flag_perm_new(int fl_type, struct mailimap_flag * fl_flag);
1414
1415void mailimap_flag_perm_free(struct mailimap_flag_perm * flag_perm);
1416
1417
1418/*
1419 mailimap_flag_list is a list of flags
1420
1421 - list is a list of flags
1422*/
1423
1424struct mailimap_flag_list {
1425 clist * fl_list; /* list of (struct mailimap_flag *), != NULL */
1426};
1427
1428struct mailimap_flag_list *
1429mailimap_flag_list_new(clist * fl_list);
1430
1431void mailimap_flag_list_free(struct mailimap_flag_list * flag_list);
1432
1433
1434
1435
1436/* this is the type of greeting response */
1437
1438enum {
1439 MAILIMAP_GREETING_RESP_COND_ERROR, /* on parse error */
1440 MAILIMAP_GREETING_RESP_COND_AUTH, /* when connection is accepted */
1441 MAILIMAP_GREETING_RESP_COND_BYE, /* when connection is refused */
1442};
1443
1444/*
1445 mailimap_greeting is the response returned on connection
1446
1447 - type is the type of response on connection, either
1448 MAILIMAP_GREETING_RESP_COND_AUTH if connection is accepted or
1449 MAIMIMAP_GREETING_RESP_COND_BYE if connection is refused
1450*/
1451
1452struct mailimap_greeting {
1453 int gr_type;
1454 union {
1455 struct mailimap_resp_cond_auth * gr_auth; /* can be NULL */
1456 struct mailimap_resp_cond_bye * gr_bye; /* can be NULL */
1457 } gr_data;
1458};
1459
1460struct mailimap_greeting *
1461mailimap_greeting_new(int gr_type,
1462 struct mailimap_resp_cond_auth * gr_auth,
1463 struct mailimap_resp_cond_bye * gr_bye);
1464
1465void mailimap_greeting_free(struct mailimap_greeting * greeting);
1466
1467
1468/*
1469 mailimap_header_list is a list of headers that can be specified when
1470 we want to fetch fields
1471
1472 - list is a list of header names, each header name should be allocated
1473 with malloc()
1474*/
1475
1476struct mailimap_header_list {
1477 clist * hdr_list; /* list of astring (char *), != NULL */
1478};
1479
1480struct mailimap_header_list *
1481mailimap_header_list_new(clist * hdr_list);
1482
1483void
1484mailimap_header_list_free(struct mailimap_header_list * header_list);
1485
1486
1487
1488/* this is the type of mailbox STATUS that can be returned */
1489
1490enum {
1491 MAILIMAP_STATUS_ATT_MESSAGES, /* when requesting the number of
1492 messages */
1493 MAILIMAP_STATUS_ATT_RECENT, /* when requesting the number of
1494 recent messages */
1495 MAILIMAP_STATUS_ATT_UIDNEXT, /* when requesting the next unique
1496 identifier */
1497 MAILIMAP_STATUS_ATT_UIDVALIDITY, /* when requesting the validity of
1498 message unique identifiers*/
1499 MAILIMAP_STATUS_ATT_UNSEEN, /* when requesting the number of
1500 unseen messages */
1501};
1502
1503/*
1504 mailimap_status_info is a returned information when a STATUS of
1505 a mailbox is requested
1506
1507 - att is the type of mailbox STATUS, the value can be
1508 MAILIMAP_STATUS_ATT_MESSAGES, MAILIMAP_STATUS_ATT_RECENT,
1509 MAILIMAP_STATUS_ATT_UIDNEXT, MAILIMAP_STATUS_ATT_UIDVALIDITY or
1510 MAILIMAP_STATUS_ATT_UNSEEN
1511
1512 - value is the value of the given information
1513*/
1514
1515struct mailimap_status_info {
1516 int st_att;
1517 uint32_t st_value;
1518};
1519
1520struct mailimap_status_info *
1521mailimap_status_info_new(int st_att, uint32_t st_value);
1522
1523void mailimap_status_info_free(struct mailimap_status_info * info);
1524
1525
1526
1527/*
1528 mailimap_mailbox_data_status is the list of information returned
1529 when a STATUS of a mailbox is requested
1530
1531 - mailbox is the name of the mailbox, should be allocated with malloc()
1532
1533 - status_info_list is the list of information returned
1534*/
1535
1536struct mailimap_mailbox_data_status {
1537 char * st_mailbox;
1538 clist * st_info_list; /* list of (struct mailimap_status_info *) */
1539 /* can be NULL */
1540};
1541
1542struct mailimap_mailbox_data_status *
1543mailimap_mailbox_data_status_new(char * st_mailbox,
1544 clist * st_info_list);
1545
1546void
1547mailimap_mailbox_data_status_free(struct mailimap_mailbox_data_status * info);
1548
1549
1550
1551/* this is the type of mailbox information that is returned */
1552
1553enum {
1554 MAILIMAP_MAILBOX_DATA_ERROR, /* on parse error */
1555 MAILIMAP_MAILBOX_DATA_FLAGS, /* flag that are applicable to the mailbox */
1556 MAILIMAP_MAILBOX_DATA_LIST, /* this is a mailbox in the list of mailboxes
1557 returned on LIST command*/
1558 MAILIMAP_MAILBOX_DATA_LSUB, /* this is a mailbox in the list of
1559 subscribed mailboxes returned on LSUB
1560 command */
1561 MAILIMAP_MAILBOX_DATA_SEARCH, /* this is a list of messages numbers or
1562 unique identifiers returned
1563 on a SEARCH command*/
1564 MAILIMAP_MAILBOX_DATA_STATUS, /* this is the list of information returned
1565 on a STATUS command */
1566 MAILIMAP_MAILBOX_DATA_EXISTS, /* this is the number of messages in the
1567 mailbox */
1568 MAILIMAP_MAILBOX_DATA_RECENT, /* this is the number of recent messages
1569 in the mailbox */
1570};
1571
1572/*
1573 mailimap_mailbox_data is an information related to a mailbox
1574
1575 - type is the type of mailbox_data that is filled, the value of this field
1576 can be MAILIMAP_MAILBOX_DATA_FLAGS, MAILIMAP_MAILBOX_DATA_LIST,
1577 MAILIMAP_MAILBOX_DATA_LSUB, MAILIMAP_MAILBOX_DATA_SEARCH,
1578 MAILIMAP_MAILBOX_DATA_STATUS, MAILIMAP_MAILBOX_DATA_EXISTS
1579 or MAILIMAP_MAILBOX_DATA_RECENT.
1580
1581 - flags is the flags that are applicable to the mailbox when
1582 type is MAILIMAP_MAILBOX_DATA_FLAGS
1583
1584 - list is a mailbox in the list of mailboxes returned on LIST command
1585 when type is MAILIMAP_MAILBOX_DATA_LIST
1586
1587 - lsub is a mailbox in the list of subscribed mailboxes returned on
1588 LSUB command when type is MAILIMAP_MAILBOX_DATA_LSUB
1589
1590 - search is a list of messages numbers or unique identifiers returned
1591 on SEARCH command when type MAILIMAP_MAILBOX_DATA_SEARCH, each element
1592 should be allocated with malloc()
1593
1594 - status is a list of information returned on STATUS command when
1595 type is MAILIMAP_MAILBOX_DATA_STATUS
1596
1597 - exists is the number of messages in the mailbox when type
1598 is MAILIMAP_MAILBOX_DATA_EXISTS
1599
1600 - recent is the number of recent messages in the mailbox when type
1601 is MAILIMAP_MAILBOX_DATA_RECENT
1602*/
1603
1604struct mailimap_mailbox_data {
1605 int mbd_type;
1606 union {
1607 struct mailimap_flag_list * mbd_flags; /* can be NULL */
1608 struct mailimap_mailbox_list * mbd_list; /* can be NULL */
1609 struct mailimap_mailbox_list * mbd_lsub; /* can be NULL */
1610 clist * mbd_search; /* list of nz-number (uint32_t *), can be NULL */
1611 struct mailimap_mailbox_data_status * mbd_status; /* can be NULL */
1612 uint32_t mbd_exists;
1613 uint32_t mbd_recent;
1614 } mbd_data;
1615};
1616
1617struct mailimap_mailbox_data *
1618mailimap_mailbox_data_new(int mbd_type, struct mailimap_flag_list * mbd_flags,
1619 struct mailimap_mailbox_list * mbd_list,
1620 struct mailimap_mailbox_list * mbd_lsub,
1621 clist * mbd_search,
1622 struct mailimap_mailbox_data_status * mbd_status,
1623 uint32_t mbd_exists,
1624 uint32_t mbd_recent);
1625
1626void
1627mailimap_mailbox_data_free(struct mailimap_mailbox_data * mb_data);
1628
1629
1630
1631/* this is the type of mailbox flags */
1632
1633enum {
1634 MAILIMAP_MBX_LIST_FLAGS_SFLAG, /* mailbox single flag - a flag in
1635 {\NoSelect, \Marked, \Unmarked} */
1636 MAILIMAP_MBX_LIST_FLAGS_NO_SFLAG, /* mailbox other flag - mailbox flag
1637 other than \NoSelect \Marked and
1638 \Unmarked) */
1639};
1640
1641/* this is a single flag type */
1642
1643enum {
1644 MAILIMAP_MBX_LIST_SFLAG_ERROR,
1645 MAILIMAP_MBX_LIST_SFLAG_MARKED,
1646 MAILIMAP_MBX_LIST_SFLAG_NOSELECT,
1647 MAILIMAP_MBX_LIST_SFLAG_UNMARKED
1648};
1649
1650/*
1651 mailimap_mbx_list_flags is a mailbox flag
1652
1653 - type is the type of mailbox flag, it can be MAILIMAP_MBX_LIST_FLAGS_SFLAG,
1654 or MAILIMAP_MBX_LIST_FLAGS_NO_SFLAG.
1655
1656 - oflags is a list of "mailbox other flag"
1657
1658 - sflag is a mailbox single flag
1659*/
1660
1661struct mailimap_mbx_list_flags {
1662 int mbf_type;
1663 clist * mbf_oflags; /* list of
1664 (struct mailimap_mbx_list_oflag *), != NULL */
1665 int mbf_sflag;
1666};
1667
1668struct mailimap_mbx_list_flags *
1669mailimap_mbx_list_flags_new(int mbf_type,
1670 clist * mbf_oflags, int mbf_sflag);
1671
1672void
1673mailimap_mbx_list_flags_free(struct mailimap_mbx_list_flags * mbx_list_flags);
1674
1675
1676
1677/* this is the type of the mailbox other flag */
1678
1679enum {
1680 MAILIMAP_MBX_LIST_OFLAG_ERROR, /* on parse error */
1681 MAILIMAP_MBX_LIST_OFLAG_NOINFERIORS, /* \NoInferior flag */
1682 MAILIMAP_MBX_LIST_OFLAG_FLAG_EXT /* other flag */
1683};
1684
1685/*
1686 mailimap_mbx_list_oflag is a mailbox other flag
1687
1688 - type can be MAILIMAP_MBX_LIST_OFLAG_NOINFERIORS when this is
1689 a \NoInferior flag or MAILIMAP_MBX_LIST_OFLAG_FLAG_EXT
1690
1691 - flag_ext is set when MAILIMAP_MBX_LIST_OFLAG_FLAG_EXT and is
1692 an extension flag, should be allocated with malloc()
1693*/
1694
1695struct mailimap_mbx_list_oflag {
1696 int of_type;
1697 char * of_flag_ext; /* can be NULL */
1698};
1699
1700struct mailimap_mbx_list_oflag *
1701mailimap_mbx_list_oflag_new(int of_type, char * of_flag_ext);
1702
1703void
1704mailimap_mbx_list_oflag_free(struct mailimap_mbx_list_oflag * oflag);
1705
1706
1707
1708/*
1709 mailimap_mailbox_list is a list of mailbox flags
1710
1711 - mb_flag is a list of mailbox flags
1712
1713 - delimiter is the delimiter of the mailbox path
1714
1715 - mb is the name of the mailbox, should be allocated with malloc()
1716*/
1717
1718struct mailimap_mailbox_list {
1719 struct mailimap_mbx_list_flags * mb_flag; /* can be NULL */
1720 char mb_delimiter;
1721 char * mb_name; /* != NULL */
1722};
1723
1724struct mailimap_mailbox_list *
1725mailimap_mailbox_list_new(struct mailimap_mbx_list_flags * mbx_flags,
1726 char mb_delimiter, char * mb_name);
1727
1728void
1729mailimap_mailbox_list_free(struct mailimap_mailbox_list * mb_list);
1730
1731
1732
1733/* this is the MIME type */
1734
1735enum {
1736 MAILIMAP_MEDIA_BASIC_APPLICATION, /* application/xxx */
1737 MAILIMAP_MEDIA_BASIC_AUDIO, /* audio/xxx */
1738 MAILIMAP_MEDIA_BASIC_IMAGE, /* image/xxx */
1739 MAILIMAP_MEDIA_BASIC_MESSAGE, /* message/xxx */
1740 MAILIMAP_MEDIA_BASIC_VIDEO, /* video/xxx */
1741 MAILIMAP_MEDIA_BASIC_OTHER, /* for all other cases */
1742};
1743
1744
1745/*
1746 mailimap_media_basic is the MIME type
1747
1748 - type can be MAILIMAP_MEDIA_BASIC_APPLICATION, MAILIMAP_MEDIA_BASIC_AUDIO,
1749 MAILIMAP_MEDIA_BASIC_IMAGE, MAILIMAP_MEDIA_BASIC_MESSAGE,
1750 MAILIMAP_MEDIA_BASIC_VIDEO or MAILIMAP_MEDIA_BASIC_OTHER
1751
1752 - basic_type is defined when type is MAILIMAP_MEDIA_BASIC_OTHER, should
1753 be allocated with malloc()
1754
1755 - subtype is the subtype of the MIME type, for example, this is
1756 "data" in "application/data", should be allocated with malloc()
1757*/
1758
1759struct mailimap_media_basic {
1760 int med_type;
1761 char * med_basic_type; /* can be NULL */
1762 char * med_subtype; /* != NULL */
1763};
1764
1765struct mailimap_media_basic *
1766mailimap_media_basic_new(int med_type,
1767 char * med_basic_type, char * med_subtype);
1768
1769void
1770mailimap_media_basic_free(struct mailimap_media_basic * media_basic);
1771
1772
1773
1774/* this is the type of message data */
1775
1776enum {
1777 MAILIMAP_MESSAGE_DATA_ERROR,
1778 MAILIMAP_MESSAGE_DATA_EXPUNGE,
1779 MAILIMAP_MESSAGE_DATA_FETCH
1780};
1781
1782/*
1783 mailimap_message_data is an information related to a message
1784
1785 - number is the number or the unique identifier of the message
1786
1787 - type is the type of information, this value can be
1788 MAILIMAP_MESSAGE_DATA_EXPUNGE or MAILIMAP_MESSAGE_DATA_FETCH
1789
1790 - msg_att is the message data
1791*/
1792
1793struct mailimap_message_data {
1794 uint32_t mdt_number;
1795 int mdt_type;
1796 struct mailimap_msg_att * mdt_msg_att; /* can be NULL */
1797 /* if type = EXPUNGE, can be NULL */
1798};
1799
1800struct mailimap_message_data *
1801mailimap_message_data_new(uint32_t mdt_number, int mdt_type,
1802 struct mailimap_msg_att * mdt_msg_att);
1803
1804void
1805mailimap_message_data_free(struct mailimap_message_data * msg_data);
1806
1807
1808
1809/* this the type of the message attributes */
1810
1811enum {
1812 MAILIMAP_MSG_ATT_ITEM_ERROR, /* on parse error */
1813 MAILIMAP_MSG_ATT_ITEM_DYNAMIC, /* dynamic message attributes (flags) */
1814 MAILIMAP_MSG_ATT_ITEM_STATIC, /* static messages attributes
1815 (message content) */
1816};
1817
1818/*
1819 mailimap_msg_att_item is a message attribute
1820
1821 - type is the type of message attribute, the value can be
1822 MAILIMAP_MSG_ATT_ITEM_DYNAMIC or MAILIMAP_MSG_ATT_ITEM_STATIC
1823
1824 - msg_att_dyn is a dynamic message attribute when type is
1825 MAILIMAP_MSG_ATT_ITEM_DYNAMIC
1826
1827 - msg_att_static is a static message attribute when type is
1828 MAILIMAP_MSG_ATT_ITEM_STATIC
1829*/
1830
1831struct mailimap_msg_att_item {
1832 int att_type;
1833 union {
1834 struct mailimap_msg_att_dynamic * att_dyn; /* can be NULL */
1835 struct mailimap_msg_att_static * att_static; /* can be NULL */
1836 } att_data;
1837};
1838
1839struct mailimap_msg_att_item *
1840mailimap_msg_att_item_new(int att_type,
1841 struct mailimap_msg_att_dynamic * att_dyn,
1842 struct mailimap_msg_att_static * att_static);
1843
1844void
1845mailimap_msg_att_item_free(struct mailimap_msg_att_item * item);
1846
1847
1848/*
1849 mailimap_msg_att is a list of attributes
1850
1851 - list is a list of message attributes
1852
1853 - number is the message number or unique identifier, this field
1854 has been added for implementation purpose
1855*/
1856
1857struct mailimap_msg_att {
1858 clist * att_list; /* list of (struct mailimap_msg_att_item *) */
1859 /* != NULL */
1860 uint32_t att_number; /* extra field to store the message number,
1861 used for mailimap */
1862};
1863
1864struct mailimap_msg_att * mailimap_msg_att_new(clist * att_list);
1865
1866void mailimap_msg_att_free(struct mailimap_msg_att * msg_att);
1867
1868
1869/*
1870 mailimap_msg_att_dynamic is a dynamic message attribute
1871
1872 - list is a list of flags (that have been fetched)
1873*/
1874
1875struct mailimap_msg_att_dynamic {
1876 clist * att_list; /* list of (struct mailimap_flag_fetch *) */
1877 /* can be NULL */
1878};
1879
1880struct mailimap_msg_att_dynamic *
1881mailimap_msg_att_dynamic_new(clist * att_list);
1882
1883void
1884mailimap_msg_att_dynamic_free(struct mailimap_msg_att_dynamic * msg_att_dyn);
1885
1886
1887
1888/*
1889 mailimap_msg_att_body_section is a MIME part content
1890
1891 - section is the location of the MIME part in the message
1892
1893 - origin_octet is the offset of the requested part of the MIME part
1894
1895 - body_part is the content or partial content of the MIME part,
1896 should be allocated through a MMAPString
1897
1898 - length is the size of the content
1899*/
1900
1901struct mailimap_msg_att_body_section {
1902 struct mailimap_section * sec_section; /* != NULL */
1903 uint32_t sec_origin_octet;
1904 char * sec_body_part; /* can be NULL */
1905 size_t sec_length;
1906};
1907
1908struct mailimap_msg_att_body_section *
1909mailimap_msg_att_body_section_new(struct mailimap_section * section,
1910 uint32_t sec_origin_octet,
1911 char * sec_body_part,
1912 size_t sec_length);
1913
1914void
1915mailimap_msg_att_body_section_free(struct mailimap_msg_att_body_section *
1916 msg_att_body_section);
1917
1918
1919
1920/*
1921 this is the type of static message attribute
1922*/
1923
1924enum {
1925 MAILIMAP_MSG_ATT_ERROR, /* on parse error */
1926 MAILIMAP_MSG_ATT_ENVELOPE, /* this is the fields that can be
1927 parsed by the server */
1928 MAILIMAP_MSG_ATT_INTERNALDATE, /* this is the message date kept
1929 by the server */
1930 MAILIMAP_MSG_ATT_RFC822, /* this is the message content
1931 (header and body) */
1932 MAILIMAP_MSG_ATT_RFC822_HEADER, /* this is the message header */
1933 MAILIMAP_MSG_ATT_RFC822_TEXT, /* this is the message text part */
1934 MAILIMAP_MSG_ATT_RFC822_SIZE, /* this is the size of the message content */
1935 MAILIMAP_MSG_ATT_BODY, /* this is the MIME description of
1936 the message */
1937 MAILIMAP_MSG_ATT_BODYSTRUCTURE, /* this is the MIME description of the
1938 message with additional information */
1939 MAILIMAP_MSG_ATT_BODY_SECTION, /* this is a MIME part content */
1940 MAILIMAP_MSG_ATT_UID, /* this is the message unique identifier */
1941};
1942
1943/*
1944 mailimap_msg_att_static is a given part of the message
1945
1946 - type is the type of the static message attribute, the value can be
1947 MAILIMAP_MSG_ATT_ENVELOPE, MAILIMAP_MSG_ATT_INTERNALDATE,
1948 MAILIMAP_MSG_ATT_RFC822, MAILIMAP_MSG_ATT_RFC822_HEADER,
1949 MAILIMAP_MSG_ATT_RFC822_TEXT, MAILIMAP_MSG_ATT_RFC822_SIZE,
1950 MAILIMAP_MSG_ATT_BODY, MAILIMAP_MSG_ATT_BODYSTRUCTURE,
1951 MAILIMAP_MSG_ATT_BODY_SECTION, MAILIMAP_MSG_ATT_UID
1952
1953 - env is the headers parsed by the server if type is
1954 MAILIMAP_MSG_ATT_ENVELOPE
1955
1956 - internal_date is the date of message kept by the server if type is
1957 MAILIMAP_MSG_ATT_INTERNALDATE
1958
1959 - rfc822 is the message content if type is MAILIMAP_MSG_ATT_RFC822,
1960 should be allocated through a MMAPString
1961
1962 - rfc822_header is the message header if type is
1963 MAILIMAP_MSG_ATT_RFC822_HEADER, should be allocated through a MMAPString
1964
1965 - rfc822_text is the message text part if type is
1966 MAILIMAP_MSG_ATT_RFC822_TEXT, should be allocated through a MMAPString
1967
1968 - rfc822_size is the message size if type is MAILIMAP_MSG_ATT_SIZE
1969
1970 - body is the MIME description of the message
1971
1972 - bodystructure is the MIME description of the message with additional
1973 information
1974
1975 - body_section is a MIME part content
1976
1977 - uid is a unique message identifier
1978*/
1979
1980struct mailimap_msg_att_static {
1981 int att_type;
1982 union {
1983 struct mailimap_envelope * att_env; /* can be NULL */
1984 struct mailimap_date_time * att_internal_date; /* can be NULL */
1985 struct {
1986 char * att_content; /* can be NULL */
1987 size_t att_length;
1988 } att_rfc822;
1989 struct {
1990 char * att_content; /* can be NULL */
1991 size_t att_length;
1992 } att_rfc822_header;
1993 struct {
1994 char * att_content; /* can be NULL */
1995 size_t att_length;
1996 } att_rfc822_text;
1997 uint32_t att_rfc822_size;
1998 struct mailimap_body * att_bodystructure; /* can be NULL */
1999 struct mailimap_body * att_body; /* can be NULL */
2000 struct mailimap_msg_att_body_section * att_body_section; /* can be NULL */
2001 uint32_t att_uid;
2002 } att_data;
2003};
2004
2005struct mailimap_msg_att_static *
2006mailimap_msg_att_static_new(int att_type, struct mailimap_envelope * att_env,
2007 struct mailimap_date_time * att_internal_date,
2008 char * att_rfc822,
2009 char * att_rfc822_header,
2010 char * att_rfc822_text,
2011 size_t att_length,
2012 uint32_t att_rfc822_size,
2013 struct mailimap_body * att_bodystructure,
2014 struct mailimap_body * att_body,
2015 struct mailimap_msg_att_body_section * att_body_section,
2016 uint32_t att_uid);
2017
2018void
2019mailimap_msg_att_static_free(struct mailimap_msg_att_static * item);
2020
2021
2022
2023/* this is the type of a response element */
2024
2025enum {
2026 MAILIMAP_RESP_ERROR, /* on parse error */
2027 MAILIMAP_RESP_CONT_REQ, /* continuation request */
2028 MAILIMAP_RESP_RESP_DATA, /* response data */
2029};
2030
2031/*
2032 mailimap_cont_req_or_resp_data is a response element
2033
2034 - type is the type of response, the value can be MAILIMAP_RESP_CONT_REQ
2035 or MAILIMAP_RESP_RESP_DATA
2036
2037 - cont_req is a continuation request
2038
2039 - resp_data is a reponse data
2040*/
2041
2042struct mailimap_cont_req_or_resp_data {
2043 int rsp_type;
2044 union {
2045 struct mailimap_continue_req * rsp_cont_req; /* can be NULL */
2046 struct mailimap_response_data * rsp_resp_data; /* can be NULL */
2047 } rsp_data;
2048};
2049
2050struct mailimap_cont_req_or_resp_data *
2051mailimap_cont_req_or_resp_data_new(int rsp_type,
2052 struct mailimap_continue_req * rsp_cont_req,
2053 struct mailimap_response_data * rsp_resp_data);
2054
2055void
2056mailimap_cont_req_or_resp_data_free(struct mailimap_cont_req_or_resp_data *
2057 cont_req_or_resp_data);
2058
2059
2060/*
2061 mailimap_response is a list of response elements
2062
2063 - cont_req_or_resp_data_list is a list of response elements
2064
2065 - resp_done is an ending response element
2066*/
2067
2068struct mailimap_response {
2069 clist * rsp_cont_req_or_resp_data_list;
2070 /* list of (struct mailiap_cont_req_or_resp_data *) */
2071 /* can be NULL */
2072 struct mailimap_response_done * rsp_resp_done; /* != NULL */
2073};
2074
2075struct mailimap_response *
2076mailimap_response_new(clist * rsp_cont_req_or_resp_data_list,
2077 struct mailimap_response_done * rsp_resp_done);
2078
2079void
2080mailimap_response_free(struct mailimap_response * resp);
2081
2082
2083
2084/* this is the type of an untagged response */
2085
2086enum {
2087 MAILIMAP_RESP_DATA_TYPE_ERROR, /* on parse error */
2088 MAILIMAP_RESP_DATA_TYPE_COND_STATE, /* condition state response */
2089 MAILIMAP_RESP_DATA_TYPE_COND_BYE, /* BYE response (server is about
2090 to close the connection) */
2091 MAILIMAP_RESP_DATA_TYPE_MAILBOX_DATA, /* response related to a mailbox */
2092 MAILIMAP_RESP_DATA_TYPE_MESSAGE_DATA, /* response related to a message */
2093 MAILIMAP_RESP_DATA_TYPE_CAPABILITY_DATA, /* capability information */
2094};
2095
2096/*
2097 mailimap_reponse_data is an untagged response
2098
2099 - type is the type of the untagged response, it can be
2100 MAILIMAP_RESP_DATA_COND_STATE, MAILIMAP_RESP_DATA_COND_BYE,
2101 MAILIMAP_RESP_DATA_MAILBOX_DATA, MAILIMAP_RESP_DATA_MESSAGE_DATA
2102 or MAILIMAP_RESP_DATA_CAPABILITY_DATA
2103
2104 - cond_state is a condition state response
2105
2106 - bye is a BYE response (server is about to close the connection)
2107
2108 - mailbox_data is a response related to a mailbox
2109
2110 - message_data is a response related to a message
2111
2112 - capability is information about capabilities
2113*/
2114
2115struct mailimap_response_data {
2116 int rsp_type;
2117 union {
2118 struct mailimap_resp_cond_state * rsp_cond_state; /* can be NULL */
2119 struct mailimap_resp_cond_bye * rsp_bye; /* can be NULL */
2120 struct mailimap_mailbox_data * rsp_mailbox_data; /* can be NULL */
2121 struct mailimap_message_data * rsp_message_data; /* can be NULL */
2122 struct mailimap_capability_data * rsp_capability_data; /* can be NULL */
2123 } rsp_data;
2124};
2125
2126struct mailimap_response_data *
2127mailimap_response_data_new(int rsp_type,
2128 struct mailimap_resp_cond_state * rsp_cond_state,
2129 struct mailimap_resp_cond_bye * rsp_bye,
2130 struct mailimap_mailbox_data * rsp_mailbox_data,
2131 struct mailimap_message_data * rsp_message_data,
2132 struct mailimap_capability_data * rsp_capability_data);
2133
2134void
2135mailimap_response_data_free(struct mailimap_response_data * resp_data);
2136
2137
2138
2139/* this is the type of an ending response */
2140
2141enum {
2142 MAILIMAP_RESP_DONE_TYPE_ERROR, /* on parse error */
2143 MAILIMAP_RESP_DONE_TYPE_TAGGED, /* tagged response */
2144 MAILIMAP_RESP_DONE_TYPE_FATAL, /* fatal error response */
2145};
2146
2147/*
2148 mailimap_response_done is an ending response
2149
2150 - type is the type of the ending response
2151
2152 - tagged is a tagged response
2153
2154 - fatal is a fatal error response
2155*/
2156
2157struct mailimap_response_done {
2158 int rsp_type;
2159 union {
2160 struct mailimap_response_tagged * rsp_tagged; /* can be NULL */
2161 struct mailimap_response_fatal * rsp_fatal; /* can be NULL */
2162 } rsp_data;
2163};
2164
2165struct mailimap_response_done *
2166mailimap_response_done_new(int rsp_type,
2167 struct mailimap_response_tagged * rsp_tagged,
2168 struct mailimap_response_fatal * rsp_fatal);
2169
2170void mailimap_response_done_free(struct mailimap_response_done *
2171 resp_done);
2172
2173
2174/*
2175 mailimap_response_fatal is a fatal error response
2176
2177 - bye is a BYE response text
2178*/
2179
2180struct mailimap_response_fatal {
2181 struct mailimap_resp_cond_bye * rsp_bye; /* != NULL */
2182};
2183
2184struct mailimap_response_fatal *
2185mailimap_response_fatal_new(struct mailimap_resp_cond_bye * rsp_bye);
2186
2187void mailimap_response_fatal_free(struct mailimap_response_fatal * resp_fatal);
2188
2189
2190
2191/*
2192 mailimap_response_tagged is a tagged response
2193
2194 - tag is the sent tag, should be allocated with malloc()
2195
2196 - cond_state is a condition state response
2197*/
2198
2199struct mailimap_response_tagged {
2200 char * rsp_tag; /* != NULL */
2201 struct mailimap_resp_cond_state * rsp_cond_state; /* != NULL */
2202};
2203
2204struct mailimap_response_tagged *
2205mailimap_response_tagged_new(char * rsp_tag,
2206 struct mailimap_resp_cond_state * rsp_cond_state);
2207
2208void
2209mailimap_response_tagged_free(struct mailimap_response_tagged * tagged);
2210
2211
2212/* this is the type of an authentication condition response */
2213
2214enum {
2215 MAILIMAP_RESP_COND_AUTH_ERROR, /* on parse error */
2216 MAILIMAP_RESP_COND_AUTH_OK, /* authentication is needed */
2217 MAILIMAP_RESP_COND_AUTH_PREAUTH, /* authentication is not needed */
2218};
2219
2220/*
2221 mailimap_resp_cond_auth is an authentication condition response
2222
2223 - type is the type of the authentication condition response,
2224 the value can be MAILIMAP_RESP_COND_AUTH_OK or
2225 MAILIMAP_RESP_COND_AUTH_PREAUTH
2226
2227 - text is a text response
2228*/
2229
2230struct mailimap_resp_cond_auth {
2231 int rsp_type;
2232 struct mailimap_resp_text * rsp_text; /* != NULL */
2233};
2234
2235struct mailimap_resp_cond_auth *
2236mailimap_resp_cond_auth_new(int rsp_type,
2237 struct mailimap_resp_text * rsp_text);
2238
2239void
2240mailimap_resp_cond_auth_free(struct mailimap_resp_cond_auth * cond_auth);
2241
2242
2243
2244/*
2245 mailimap_resp_cond_bye is a BYE response
2246
2247 - text is a text response
2248*/
2249
2250struct mailimap_resp_cond_bye {
2251 struct mailimap_resp_text * rsp_text; /* != NULL */
2252};
2253
2254struct mailimap_resp_cond_bye *
2255mailimap_resp_cond_bye_new(struct mailimap_resp_text * rsp_text);
2256
2257void
2258mailimap_resp_cond_bye_free(struct mailimap_resp_cond_bye * cond_bye);
2259
2260
2261
2262/* this is the type of a condition state response */
2263
2264enum {
2265 MAILIMAP_RESP_COND_STATE_OK,
2266 MAILIMAP_RESP_COND_STATE_NO,
2267 MAILIMAP_RESP_COND_STATE_BAD
2268};
2269
2270/*
2271 mailimap_resp_cond_state is a condition state reponse
2272
2273 - type is the type of the condition state response
2274
2275 - text is a text response
2276*/
2277
2278struct mailimap_resp_cond_state {
2279 int rsp_type;
2280 struct mailimap_resp_text * rsp_text; /* can be NULL */
2281};
2282
2283struct mailimap_resp_cond_state *
2284mailimap_resp_cond_state_new(int rsp_type,
2285 struct mailimap_resp_text * rsp_text);
2286
2287void
2288mailimap_resp_cond_state_free(struct mailimap_resp_cond_state * cond_state);
2289
2290
2291
2292/*
2293 mailimap_resp_text is a text response
2294
2295 - resp_code is a response code
2296
2297 - text is a human readable text, should be allocated with malloc()
2298*/
2299
2300struct mailimap_resp_text {
2301 struct mailimap_resp_text_code * rsp_code; /* can be NULL */
2302 char * rsp_text; /* can be NULL */
2303};
2304
2305struct mailimap_resp_text *
2306mailimap_resp_text_new(struct mailimap_resp_text_code * resp_code,
2307 char * rsp_text);
2308
2309void mailimap_resp_text_free(struct mailimap_resp_text * resp_text);
2310
2311
2312
2313/* this is the type of the response code */
2314
2315enum {
2316 MAILIMAP_RESP_TEXT_CODE_ALERT, /* ALERT response */
2317 MAILIMAP_RESP_TEXT_CODE_BADCHARSET, /* BADCHARSET response */
2318 MAILIMAP_RESP_TEXT_CODE_CAPABILITY_DATA, /* CAPABILITY response */
2319 MAILIMAP_RESP_TEXT_CODE_PARSE, /* PARSE response */
2320 MAILIMAP_RESP_TEXT_CODE_PERMANENTFLAGS, /* PERMANENTFLAGS response */
2321 MAILIMAP_RESP_TEXT_CODE_READ_ONLY, /* READONLY response */
2322 MAILIMAP_RESP_TEXT_CODE_READ_WRITE, /* READWRITE response */
2323 MAILIMAP_RESP_TEXT_CODE_TRY_CREATE, /* TRYCREATE response */
2324 MAILIMAP_RESP_TEXT_CODE_UIDNEXT, /* UIDNEXT response */
2325 MAILIMAP_RESP_TEXT_CODE_UIDVALIDITY, /* UIDVALIDITY response */
2326 MAILIMAP_RESP_TEXT_CODE_UNSEEN, /* UNSEEN response */
2327 MAILIMAP_RESP_TEXT_CODE_OTHER, /* other type of response */
2328};
2329
2330/*
2331 mailimap_resp_text_code is a response code
2332
2333 - type is the type of the response code, the value can be
2334 MAILIMAP_RESP_TEXT_CODE_ALERT, MAILIMAP_RESP_TEXT_CODE_BADCHARSET,
2335 MAILIMAP_RESP_TEXT_CODE_CAPABILITY_DATA, MAILIMAP_RESP_TEXT_CODE_PARSE,
2336 MAILIMAP_RESP_TEXT_CODE_PERMANENTFLAGS, MAILIMAP_RESP_TEXT_CODE_READ_ONLY,
2337 MAILIMAP_RESP_TEXT_CODE_READ_WRITE, MAILIMAP_RESP_TEXT_CODE_TRY_CREATE,
2338 MAILIMAP_RESP_TEXT_CODE_UIDNEXT, MAILIMAP_RESP_TEXT_CODE_UIDVALIDITY,
2339 MAILIMAP_RESP_TEXT_CODE_UNSEEN or MAILIMAP_RESP_TEXT_CODE_OTHER
2340
2341 - badcharset is a list of charsets if type
2342 is MAILIMAP_RESP_TEXT_CODE_BADCHARSET, each element should be
2343 allocated with malloc()
2344
2345 - cap_data is a list of capabilities
2346
2347 - perm_flags is a list of flags, this is the flags that can be changed
2348 permanently on the messages of the mailbox.
2349
2350 - uidnext is the next unique identifier of a message
2351
2352 - uidvalidity is the unique identifier validity value
2353
2354 - first_unseen is the number of the first message without the \Seen flag
2355
2356 - atom is a keyword for an extension response code, should be allocated
2357 with malloc()
2358
2359 - atom_value is the data related with the extension response code,
2360 should be allocated with malloc()
2361*/
2362
2363struct mailimap_resp_text_code {
2364 int rc_type;
2365 union {
2366 clist * rc_badcharset; /* list of astring (char *) */
2367 /* can be NULL */
2368 struct mailimap_capability_data * rc_cap_data; /* != NULL */
2369 clist * rc_perm_flags; /* list of (struct mailimap_flag_perm *) */
2370 /* can be NULL */
2371 uint32_t rc_uidnext;
2372 uint32_t rc_uidvalidity;
2373 uint32_t rc_first_unseen;
2374 struct {
2375 char * atom_name; /* can be NULL */
2376 char * atom_value; /* can be NULL */
2377 } rc_atom;
2378 } rc_data;
2379};
2380
2381struct mailimap_resp_text_code *
2382mailimap_resp_text_code_new(int rc_type, clist * rc_badcharset,
2383 struct mailimap_capability_data * rc_cap_data,
2384 clist * rc_perm_flags,
2385 uint32_t rc_uidnext, uint32_t rc_uidvalidity,
2386 uint32_t rc_first_unseen, char * rc_atom, char * rc_atom_value);
2387
2388void
2389mailimap_resp_text_code_free(struct mailimap_resp_text_code * resp_text_code);
2390
2391
2392/*
2393 mailimap_section is a MIME part section identifier
2394
2395 section_spec is the MIME section identifier
2396*/
2397
2398struct mailimap_section {
2399 struct mailimap_section_spec * sec_spec; /* can be NULL */
2400};
2401
2402struct mailimap_section *
2403mailimap_section_new(struct mailimap_section_spec * sec_spec);
2404
2405void mailimap_section_free(struct mailimap_section * section);
2406
2407
2408/* this is the type of the message/rfc822 part description */
2409
2410enum {
2411 MAILIMAP_SECTION_MSGTEXT_HEADER, /* header fields part of the
2412 message */
2413 MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS, /* given header fields of the
2414 message */
2415 MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS_NOT, /* header fields of the
2416 message except the given */
2417 MAILIMAP_SECTION_MSGTEXT_TEXT, /* text part */
2418};
2419
2420/*
2421 mailimap_section_msgtext is a message/rfc822 part description
2422
2423 - type is the type of the content part and the value can be
2424 MAILIMAP_SECTION_MSGTEXT_HEADER, MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS,
2425 MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS_NOT
2426 or MAILIMAP_SECTION_MSGTEXT_TEXT
2427
2428 - header_list is the list of headers when type is
2429 MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS or
2430 MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS_NOT
2431*/
2432
2433struct mailimap_section_msgtext {
2434 int sec_type;
2435 struct mailimap_header_list * sec_header_list; /* can be NULL */
2436};
2437
2438struct mailimap_section_msgtext *
2439mailimap_section_msgtext_new(int sec_type,
2440 struct mailimap_header_list * sec_header_list);
2441
2442void
2443mailimap_section_msgtext_free(struct mailimap_section_msgtext * msgtext);
2444
2445
2446
2447/*
2448 mailimap_section_part is the MIME part location in a message
2449
2450 - section_id is a list of number index of the sub-part in the mail structure,
2451 each element should be allocated with malloc()
2452
2453*/
2454
2455struct mailimap_section_part {
2456 clist * sec_id; /* list of nz-number (uint32_t *) */
2457 /* != NULL */
2458};
2459
2460struct mailimap_section_part *
2461mailimap_section_part_new(clist * sec_id);
2462
2463void
2464mailimap_section_part_free(struct mailimap_section_part * section_part);
2465
2466
2467
2468/* this is the type of section specification */
2469
2470enum {
2471 MAILIMAP_SECTION_SPEC_SECTION_MSGTEXT, /* if requesting data of the root
2472 MIME message/rfc822 part */
2473 MAILIMAP_SECTION_SPEC_SECTION_PART, /* location of the MIME part
2474 in the message */
2475};
2476
2477/*
2478 mailimap_section_spec is a section specification
2479
2480 - type is the type of the section specification, the value can be
2481 MAILIMAP_SECTION_SPEC_SECTION_MSGTEXT or
2482 MAILIMAP_SECTION_SPEC_SECTION_PART
2483
2484 - section_msgtext is a message/rfc822 part description if type is
2485 MAILIMAP_SECTION_SPEC_SECTION_MSGTEXT
2486
2487 - section_part is a body part location in the message if type is
2488 MAILIMAP_SECTION_SPEC_SECTION_PART
2489
2490 - section_text is a body part location for a given MIME part,
2491 this can be NULL if the body of the part is requested (and not
2492 the MIME header).
2493*/
2494
2495struct mailimap_section_spec {
2496 int sec_type;
2497 union {
2498 struct mailimap_section_msgtext * sec_msgtext; /* can be NULL */
2499 struct mailimap_section_part * sec_part; /* can be NULL */
2500 } sec_data;
2501 struct mailimap_section_text * sec_text; /* can be NULL */
2502};
2503
2504struct mailimap_section_spec *
2505mailimap_section_spec_new(int sec_type,
2506 struct mailimap_section_msgtext * sec_msgtext,
2507 struct mailimap_section_part * sec_part,
2508 struct mailimap_section_text * sec_text);
2509
2510void
2511mailimap_section_spec_free(struct mailimap_section_spec * section_spec);
2512
2513
2514
2515/* this is the type of body part location for a given MIME part */
2516
2517enum {
2518 MAILIMAP_SECTION_TEXT_ERROR, /* on parse error **/
2519 MAILIMAP_SECTION_TEXT_SECTION_MSGTEXT, /* if the MIME type is
2520 message/rfc822, headers or text
2521 can be requested */
2522 MAILIMAP_SECTION_TEXT_MIME, /* for all MIME types,
2523 MIME headers can be requested */
2524};
2525
2526/*
2527 mailimap_section_text is the body part location for a given MIME part
2528
2529 - type can be MAILIMAP_SECTION_TEXT_SECTION_MSGTEXT or
2530 MAILIMAP_SECTION_TEXT_MIME
2531
2532 - section_msgtext is the part of the MIME part when MIME type is
2533 message/rfc822 than can be requested, when type is
2534 MAILIMAP_TEXT_SECTION_MSGTEXT
2535*/
2536
2537struct mailimap_section_text {
2538 int sec_type;
2539 struct mailimap_section_msgtext * sec_msgtext; /* can be NULL */
2540};
2541
2542struct mailimap_section_text *
2543mailimap_section_text_new(int sec_type,
2544 struct mailimap_section_msgtext * sec_msgtext);
2545
2546void
2547mailimap_section_text_free(struct mailimap_section_text * section_text);
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558/* ************************************************************************* */
2559/* the following part concerns only the IMAP command that are sent */
2560
2561
2562/*
2563 mailimap_set_item is a message set
2564
2565 - first is the first message of the set
2566 - last is the last message of the set
2567
2568 this can be message numbers of message unique identifiers
2569*/
2570
2571struct mailimap_set_item {
2572 uint32_t set_first;
2573 uint32_t set_last;
2574};
2575
2576struct mailimap_set_item *
2577mailimap_set_item_new(uint32_t set_first, uint32_t set_last);
2578
2579void mailimap_set_item_free(struct mailimap_set_item * set_item);
2580
2581
2582
2583/*
2584 set is a list of message sets
2585
2586 - list is a list of message sets
2587*/
2588
2589struct mailimap_set {
2590 clist * set_list; /* list of (struct mailimap_set_item *) */
2591};
2592
2593struct mailimap_set * mailimap_set_new(clist * list);
2594
2595void mailimap_set_free(struct mailimap_set * set);
2596
2597
2598/*
2599 mailimap_date is a date
2600
2601 - day is the day in the month (1 to 31)
2602
2603 - month (1 to 12)
2604
2605 - year (4 digits)
2606*/
2607
2608struct mailimap_date {
2609 int dt_day;
2610 int dt_month;
2611 int dt_year;
2612};
2613
2614struct mailimap_date *
2615mailimap_date_new(int dt_day, int dt_month, int dt_year);
2616
2617void mailimap_date_free(struct mailimap_date * date);
2618
2619
2620
2621
2622/* this is the type of fetch attribute for a given message */
2623
2624enum {
2625 MAILIMAP_FETCH_ATT_ENVELOPE, /* to fetch the headers parsed by
2626 the IMAP server */
2627 MAILIMAP_FETCH_ATT_FLAGS, /* to fetch the flags */
2628 MAILIMAP_FETCH_ATT_INTERNALDATE, /* to fetch the date of the message
2629 kept by the server */
2630 MAILIMAP_FETCH_ATT_RFC822, /* to fetch the entire message */
2631 MAILIMAP_FETCH_ATT_RFC822_HEADER, /* to fetch the headers */
2632 MAILIMAP_FETCH_ATT_RFC822_SIZE, /* to fetch the size */
2633 MAILIMAP_FETCH_ATT_RFC822_TEXT, /* to fetch the text part */
2634 MAILIMAP_FETCH_ATT_BODY, /* to fetch the MIME structure */
2635 MAILIMAP_FETCH_ATT_BODYSTRUCTURE, /* to fetch the MIME structure with
2636 additional information */
2637 MAILIMAP_FETCH_ATT_UID, /* to fetch the unique identifier */
2638 MAILIMAP_FETCH_ATT_BODY_SECTION, /* to fetch a given part */
2639 MAILIMAP_FETCH_ATT_BODY_PEEK_SECTION, /* to fetch a given part without
2640 marking the message as read */
2641};
2642
2643
2644/*
2645 mailimap_fetch_att is the description of the fetch attribute
2646
2647 - type is the type of fetch attribute, the value can be
2648 MAILIMAP_FETCH_ATT_ENVELOPE, MAILIMAP_FETCH_ATT_FLAGS,
2649 MAILIMAP_FETCH_ATT_INTERNALDATE, MAILIMAP_FETCH_ATT_RFC822,
2650 MAILIMAP_FETCH_ATT_RFC822_HEADER, MAILIMAP_FETCH_ATT_RFC822_SIZE,
2651 MAILIMAP_FETCH_ATT_RFC822_TEXT, MAILIMAP_FETCH_ATT_BODY,
2652 MAILIMAP_FETCH_ATT_BODYSTRUCTURE, MAILIMAP_FETCH_ATT_UID,
2653 MAILIMAP_FETCH_ATT_BODY_SECTION or MAILIMAP_FETCH_ATT_BODY_PEEK_SECTION
2654
2655 - section is the location of the part to fetch if type is
2656 MAILIMAP_FETCH_ATT_BODY_SECTION or MAILIMAP_FETCH_ATT_BODY_PEEK_SECTION
2657
2658 - offset is the first byte to fetch in the given part
2659
2660 - size is the maximum size of the part to fetch
2661*/
2662
2663struct mailimap_fetch_att {
2664 int att_type;
2665 struct mailimap_section * att_section;
2666 uint32_t att_offset;
2667 uint32_t att_size;
2668};
2669
2670struct mailimap_fetch_att *
2671mailimap_fetch_att_new(int att_type, struct mailimap_section * att_section,
2672 uint32_t att_offset, uint32_t att_size);
2673
2674
2675void mailimap_fetch_att_free(struct mailimap_fetch_att * fetch_att);
2676
2677
2678/* this is the type of a FETCH operation */
2679
2680enum {
2681 MAILIMAP_FETCH_TYPE_ALL, /* equivalent to (FLAGS INTERNALDATE
2682 RFC822.SIZE ENVELOPE) */
2683 MAILIMAP_FETCH_TYPE_FULL, /* equivalent to (FLAGS INTERNALDATE
2684 RFC822.SIZE ENVELOPE BODY) */
2685 MAILIMAP_FETCH_TYPE_FAST, /* equivalent to (FLAGS INTERNALDATE
2686 RFC822.SIZE) */
2687 MAILIMAP_FETCH_TYPE_FETCH_ATT, /* when there is only of fetch
2688 attribute */
2689 MAILIMAP_FETCH_TYPE_FETCH_ATT_LIST, /* when there is a list of fetch
2690 attributes */
2691};
2692
2693/*
2694 mailimap_fetch_type is the description of the FETCH operation
2695
2696 - type can be MAILIMAP_FETCH_TYPE_ALL, MAILIMAP_FETCH_TYPE_FULL,
2697 MAILIMAP_FETCH_TYPE_FAST, MAILIMAP_FETCH_TYPE_FETCH_ATT or
2698 MAILIMAP_FETCH_TYPE_FETCH_ATT_LIST
2699
2700 - fetch_att is a fetch attribute if type is MAILIMAP_FETCH_TYPE_FETCH_ATT
2701
2702 - fetch_att_list is a list of fetch attributes if type is
2703 MAILIMAP_FETCH_TYPE_FETCH_ATT_LIST
2704*/
2705
2706struct mailimap_fetch_type {
2707 int ft_type;
2708 union {
2709 struct mailimap_fetch_att * ft_fetch_att;
2710 clist * ft_fetch_att_list; /* list of (struct mailimap_fetch_att *) */
2711 } ft_data;
2712};
2713
2714struct mailimap_fetch_type *
2715mailimap_fetch_type_new(int ft_type,
2716 struct mailimap_fetch_att * ft_fetch_att,
2717 clist * ft_fetch_att_list);
2718
2719
2720void mailimap_fetch_type_free(struct mailimap_fetch_type * fetch_type);
2721
2722
2723
2724/*
2725 mailimap_store_att_flags is the description of the STORE operation
2726 (change flags of a message)
2727
2728 - sign can be 0 (set flag), +1 (add flag) or -1 (remove flag)
2729
2730 - silent has a value of 1 if the flags are changed with no server
2731 response
2732
2733 - flag_list is the list of flags to change
2734*/
2735
2736struct mailimap_store_att_flags {
2737 int fl_sign;
2738 int fl_silent;
2739 struct mailimap_flag_list * fl_flag_list;
2740};
2741
2742struct mailimap_store_att_flags *
2743mailimap_store_att_flags_new(int fl_sign, int fl_silent,
2744 struct mailimap_flag_list * fl_flag_list);
2745
2746void mailimap_store_att_flags_free(struct mailimap_store_att_flags *
2747 store_att_flags);
2748
2749
2750
2751/* this is the condition of the SEARCH operation */
2752
2753enum {
2754 MAILIMAP_SEARCH_KEY_ALL, /* all messages */
2755 MAILIMAP_SEARCH_KEY_ANSWERED, /* messages with the flag \Answered */
2756 MAILIMAP_SEARCH_KEY_BCC, /* messages whose Bcc field contains the
2757 given string */
2758 MAILIMAP_SEARCH_KEY_BEFORE, /* messages whose internal date is earlier
2759 than the specified date */
2760 MAILIMAP_SEARCH_KEY_BODY, /* message that contains the given string
2761 (in header and text parts) */
2762 MAILIMAP_SEARCH_KEY_CC, /* messages whose Cc field contains the
2763 given string */
2764 MAILIMAP_SEARCH_KEY_DELETED, /* messages with the flag \Deleted */
2765 MAILIMAP_SEARCH_KEY_FLAGGED, /* messages with the flag \Flagged */
2766 MAILIMAP_SEARCH_KEY_FROM, /* messages whose From field contains the
2767 given string */
2768 MAILIMAP_SEARCH_KEY_KEYWORD, /* messages with the flag keyword set */
2769 MAILIMAP_SEARCH_KEY_NEW, /* messages with the flag \Recent and not
2770 the \Seen flag */
2771 MAILIMAP_SEARCH_KEY_OLD, /* messages that do not have the
2772 \Recent flag set */
2773 MAILIMAP_SEARCH_KEY_ON, /* messages whose internal date is the
2774 specified date */
2775 MAILIMAP_SEARCH_KEY_RECENT, /* messages with the flag \Recent */
2776 MAILIMAP_SEARCH_KEY_SEEN, /* messages with the flag \Seen */
2777 MAILIMAP_SEARCH_KEY_SINCE, /* messages whose internal date is later
2778 than specified date */
2779 MAILIMAP_SEARCH_KEY_SUBJECT, /* messages whose Subject field contains the
2780 given string */
2781 MAILIMAP_SEARCH_KEY_TEXT, /* messages whose text part contains the
2782 given string */
2783 MAILIMAP_SEARCH_KEY_TO, /* messages whose To field contains the
2784 given string */
2785 MAILIMAP_SEARCH_KEY_UNANSWERED, /* messages with no flag \Answered */
2786 MAILIMAP_SEARCH_KEY_UNDELETED, /* messages with no flag \Deleted */
2787 MAILIMAP_SEARCH_KEY_UNFLAGGED, /* messages with no flag \Flagged */
2788 MAILIMAP_SEARCH_KEY_UNKEYWORD, /* messages with no flag keyword */
2789 MAILIMAP_SEARCH_KEY_UNSEEN, /* messages with no flag \Seen */
2790 MAILIMAP_SEARCH_KEY_DRAFT, /* messages with no flag \Draft */
2791 MAILIMAP_SEARCH_KEY_HEADER, /* messages whose given field
2792 contains the given string */
2793 MAILIMAP_SEARCH_KEY_LARGER, /* messages whose size is larger then
2794 the given size */
2795 MAILIMAP_SEARCH_KEY_NOT, /* not operation of the condition */
2796 MAILIMAP_SEARCH_KEY_OR, /* or operation between two conditions */
2797 MAILIMAP_SEARCH_KEY_SENTBEFORE, /* messages whose date given in Date header
2798 is earlier than the specified date */
2799 MAILIMAP_SEARCH_KEY_SENTON, /* messages whose date given in Date header
2800 is the specified date */
2801 MAILIMAP_SEARCH_KEY_SENTSINCE, /* messages whose date given in Date header
2802 is later than specified date */
2803 MAILIMAP_SEARCH_KEY_SMALLER, /* messages whose size is smaller than
2804 the given size */
2805 MAILIMAP_SEARCH_KEY_UID, /* messages whose unique identifiers are
2806 in the given range */
2807 MAILIMAP_SEARCH_KEY_UNDRAFT, /* messages with no flag \Draft */
2808 MAILIMAP_SEARCH_KEY_SET, /* messages whose number (or unique
2809 identifiers in case of UID SEARCH) are
2810 in the given range */
2811 MAILIMAP_SEARCH_KEY_MULTIPLE, /* the boolean operator between the
2812 conditions is AND */
2813};
2814
2815/*
2816 mailimap_search_key is the condition on the messages to return
2817
2818 - type is the type of the condition
2819
2820 - bcc is the text to search in the Bcc field when type is
2821 MAILIMAP_SEARCH_KEY_BCC, should be allocated with malloc()
2822
2823 - before is a date when type is MAILIMAP_SEARCH_KEY_BEFORE
2824
2825 - body is the text to search in the message when type is
2826 MAILIMAP_SEARCH_KEY_BODY, should be allocated with malloc()
2827
2828 - cc is the text to search in the Cc field when type is
2829 MAILIMAP_SEARCH_KEY_CC, should be allocated with malloc()
2830
2831 - from is the text to search in the From field when type is
2832 MAILIMAP_SEARCH_KEY_FROM, should be allocated with malloc()
2833
2834 - keyword is the keyword flag name when type is MAILIMAP_SEARCH_KEY_KEYWORD,
2835 should be allocated with malloc()
2836
2837 - on is a date when type is MAILIMAP_SEARCH_KEY_ON
2838
2839 - since is a date when type is MAILIMAP_SEARCH_KEY_SINCE
2840
2841 - subject is the text to search in the Subject field when type is
2842 MAILIMAP_SEARCH_KEY_SUBJECT, should be allocated with malloc()
2843
2844 - text is the text to search in the text part of the message when
2845 type is MAILIMAP_SEARCH_KEY_TEXT, should be allocated with malloc()
2846
2847 - to is the text to search in the To field when type is
2848 MAILIMAP_SEARCH_KEY_TO, should be allocated with malloc()
2849
2850 - unkeyword is the keyword flag name when type is
2851 MAILIMAP_SEARCH_KEY_UNKEYWORD, should be allocated with malloc()
2852
2853 - header_name is the header name when type is MAILIMAP_SEARCH_KEY_HEADER,
2854 should be allocated with malloc()
2855
2856 - header_value is the text to search in the given header when type is
2857 MAILIMAP_SEARCH_KEY_HEADER, should be allocated with malloc()
2858
2859 - larger is a size when type is MAILIMAP_SEARCH_KEY_LARGER
2860
2861 - not is a condition when type is MAILIMAP_SEARCH_KEY_NOT
2862
2863 - or1 is a condition when type is MAILIMAP_SEARCH_KEY_OR
2864
2865 - or2 is a condition when type is MAILIMAP_SEARCH_KEY_OR
2866
2867 - sentbefore is a date when type is MAILIMAP_SEARCH_KEY_SENTBEFORE
2868
2869 - senton is a date when type is MAILIMAP_SEARCH_KEY_SENTON
2870
2871 - sentsince is a date when type is MAILIMAP_SEARCH_KEY_SENTSINCE
2872
2873 - smaller is a size when type is MAILIMAP_SEARCH_KEY_SMALLER
2874
2875 - uid is a set of messages when type is MAILIMAP_SEARCH_KEY_UID
2876
2877 - set is a set of messages when type is MAILIMAP_SEARCH_KEY_SET
2878
2879 - multiple is a set of message when type is MAILIMAP_SEARCH_KEY_MULTIPLE
2880*/
2881
2882struct mailimap_search_key {
2883 int sk_type;
2884 union {
2885 char * sk_bcc;
2886 struct mailimap_date * sk_before;
2887 char * sk_body;
2888 char * sk_cc;
2889 char * sk_from;
2890 char * sk_keyword;
2891 struct mailimap_date * sk_on;
2892 struct mailimap_date * sk_since;
2893 char * sk_subject;
2894 char * sk_text;
2895 char * sk_to;
2896 char * sk_unkeyword;
2897 struct {
2898 char * sk_header_name;
2899 char * sk_header_value;
2900 } sk_header;
2901 uint32_t sk_larger;
2902 struct mailimap_search_key * sk_not;
2903 struct {
2904 struct mailimap_search_key * sk_or1;
2905 struct mailimap_search_key * sk_or2;
2906 } sk_or;
2907 struct mailimap_date * sk_sentbefore;
2908 struct mailimap_date * sk_senton;
2909 struct mailimap_date * sk_sentsince;
2910 uint32_t sk_smaller;
2911 struct mailimap_set * sk_uid;
2912 struct mailimap_set * sk_set;
2913 clist * sk_multiple; /* list of (struct mailimap_search_key *) */
2914 } sk_data;
2915};
2916
2917struct mailimap_search_key *
2918mailimap_search_key_new(int sk_type,
2919 char * sk_bcc, struct mailimap_date * sk_before, char * sk_body,
2920 char * sk_cc, char * sk_from, char * sk_keyword,
2921 struct mailimap_date * sk_on, struct mailimap_date * sk_since,
2922 char * sk_subject, char * sk_text, char * sk_to,
2923 char * sk_unkeyword, char * sk_header_name,
2924 char * sk_header_value, uint32_t sk_larger,
2925 struct mailimap_search_key * sk_not,
2926 struct mailimap_search_key * sk_or1,
2927 struct mailimap_search_key * sk_or2,
2928 struct mailimap_date * sk_sentbefore,
2929 struct mailimap_date * sk_senton,
2930 struct mailimap_date * sk_sentsince,
2931 uint32_t sk_smaller, struct mailimap_set * sk_uid,
2932 struct mailimap_set * sk_set, clist * sk_multiple);
2933
2934
2935void mailimap_search_key_free(struct mailimap_search_key * key);
2936
2937
2938/*
2939 mailimap_status_att_list is a list of mailbox STATUS request type
2940
2941 - list is a list of mailbox STATUS request type
2942 (value of elements in the list can be MAILIMAP_STATUS_ATT_MESSAGES,
2943 MAILIMAP_STATUS_ATT_RECENT, MAILIMAP_STATUS_ATT_UIDNEXT,
2944 MAILIMAP_STATUS_ATT_UIDVALIDITY or MAILIMAP_STATUS_ATT_UNSEEN),
2945 each element should be allocated with malloc()
2946*/
2947
2948struct mailimap_status_att_list {
2949 clist * att_list; /* list of (uint32_t *) */
2950};
2951
2952struct mailimap_status_att_list *
2953mailimap_status_att_list_new(clist * att_list);
2954
2955void mailimap_status_att_list_free(struct mailimap_status_att_list *
2956 status_att_list);
2957
2958
2959
2960
2961/* internal use functions */
2962
2963
2964uint32_t * mailimap_number_alloc_new(uint32_t number);
2965
2966void mailimap_number_alloc_free(uint32_t * pnumber);
2967
2968
2969void mailimap_addr_host_free(char * addr_host);
2970
2971void mailimap_addr_mailbox_free(char * addr_mailbox);
2972
2973void mailimap_addr_adl_free(char * addr_adl);
2974
2975void mailimap_addr_name_free(char * addr_name);
2976
2977void mailimap_astring_free(char * astring);
2978
2979void mailimap_atom_free(char * atom);
2980
2981void mailimap_auth_type_free(char * auth_type);
2982
2983void mailimap_base64_free(char * base64);
2984
2985void mailimap_body_fld_desc_free(char * body_fld_desc);
2986
2987void mailimap_body_fld_id_free(char * body_fld_id);
2988
2989void mailimap_body_fld_md5_free(char * body_fld_md5);
2990
2991void mailimap_env_date_free(char * date);
2992
2993void mailimap_env_in_reply_to_free(char * in_reply_to);
2994
2995void mailimap_env_message_id_free(char * message_id);
2996
2997void mailimap_env_subject_free(char * subject);
2998
2999void mailimap_flag_extension_free(char * flag_extension);
3000
3001void mailimap_flag_keyword_free(char * flag_keyword);
3002
3003void
3004mailimap_header_fld_name_free(char * header_fld_name);
3005
3006void mailimap_literal_free(char * literal);
3007
3008void mailimap_mailbox_free(char * mailbox);
3009
3010void
3011mailimap_mailbox_data_search_free(clist * data_search);
3012
3013void mailimap_media_subtype_free(char * media_subtype);
3014
3015void mailimap_media_text_free(char * media_text);
3016
3017void mailimap_msg_att_envelope_free(struct mailimap_envelope * env);
3018
3019void
3020mailimap_msg_att_internaldate_free(struct mailimap_date_time * date_time);
3021
3022void
3023mailimap_msg_att_rfc822_free(char * str);
3024
3025void
3026mailimap_msg_att_rfc822_header_free(char * str);
3027
3028void
3029mailimap_msg_att_rfc822_text_free(char * str);
3030
3031void
3032mailimap_msg_att_body_free(struct mailimap_body * body);
3033
3034void
3035mailimap_msg_att_bodystructure_free(struct mailimap_body * body);
3036
3037void mailimap_nstring_free(char * str);
3038
3039void
3040mailimap_string_free(char * str);
3041
3042void mailimap_tag_free(char * tag);
3043
3044void mailimap_text_free(char * text);
3045
3046
3047
3048
3049
3050/* IMAP connection */
3051
3052/* this is the state of the IMAP connection */
3053
3054enum {
3055 MAILIMAP_STATE_DISCONNECTED,
3056 MAILIMAP_STATE_NON_AUTHENTICATED,
3057 MAILIMAP_STATE_AUTHENTICATED,
3058 MAILIMAP_STATE_SELECTED,
3059 MAILIMAP_STATE_LOGOUT
3060};
3061
3062/*
3063 mailimap is an IMAP connection
3064
3065 - response is a human readable message returned with a reponse,
3066 must be accessed read-only
3067
3068 - stream is the connection with the IMAP server
3069
3070 - stream_buffer is the buffer where the data to parse are stored
3071
3072 - state is the state of IMAP connection
3073
3074 - tag is the current tag being used in IMAP connection
3075
3076 - response_buffer is the buffer for response messages
3077
3078 - connection_info is the information returned in response
3079 for the last command about the connection
3080
3081 - selection_info is the information returned in response
3082 for the last command about the current selected mailbox
3083
3084 - response_info is the other information returned in response
3085 for the last command
3086*/
3087
3088struct mailimap {
3089 char * imap_response;
3090
3091 /* internals */
3092 mailstream * imap_stream;
3093
3094 size_t imap_progr_rate;
3095 progress_function * imap_progr_fun;
3096
3097 MMAPString * imap_stream_buffer;
3098 MMAPString * imap_response_buffer;
3099
3100 int imap_state;
3101 int imap_tag;
3102
3103 struct mailimap_connection_info * imap_connection_info;
3104 struct mailimap_selection_info * imap_selection_info;
3105 struct mailimap_response_info * imap_response_info;
3106};
3107
3108typedef struct mailimap mailimap;
3109
3110
3111/*
3112 mailimap_connection_info is the information about the connection
3113
3114 - capability is the list of capability of the IMAP server
3115*/
3116
3117struct mailimap_connection_info {
3118 struct mailimap_capability_data * imap_capability;
3119};
3120
3121struct mailimap_connection_info *
3122mailimap_connection_info_new(void);
3123
3124void
3125mailimap_connection_info_free(struct mailimap_connection_info * conn_info);
3126
3127
3128/* this is the type of mailbox access */
3129
3130enum {
3131 MAILIMAP_MAILBOX_READONLY,
3132 MAILIMAP_MAILBOX_READWRITE
3133};
3134
3135/*
3136 mailimap_selection_info is information about the current selected mailbox
3137
3138 - perm_flags is a list of flags that can be changed permanently on the
3139 messages of the mailbox
3140
3141 - perm is the access on the mailbox, value can be
3142 MAILIMAP_MAILBOX_READONLY or MAILIMAP_MAILBOX_READWRITE
3143
3144 - uidnext is the next unique identifier
3145
3146 - uidvalidity is the unique identifiers validity
3147
3148 - first_unseen is the number of the first unseen message
3149
3150 - flags is a list of flags that can be used on the messages of
3151 the mailbox
3152
3153 - exists is the number of messages in the mailbox
3154
3155 - recent is the number of recent messages in the mailbox
3156
3157 - unseen is the number of unseen messages in the mailbox
3158*/
3159
3160struct mailimap_selection_info {
3161 clist * sel_perm_flags; /* list of (struct flag_perm *) */
3162 int sel_perm;
3163 uint32_t sel_uidnext;
3164 uint32_t sel_uidvalidity;
3165 uint32_t sel_first_unseen;
3166 struct mailimap_flag_list * sel_flags;
3167 uint32_t sel_exists;
3168 uint32_t sel_recent;
3169 uint32_t sel_unseen;
3170};
3171
3172struct mailimap_selection_info *
3173mailimap_selection_info_new(void);
3174
3175void
3176mailimap_selection_info_free(struct mailimap_selection_info * sel_info);
3177
3178
3179/*
3180 mailimap_response_info is the other information returned in the
3181 response for a command
3182
3183 - alert is the human readable text returned with ALERT response
3184
3185 - parse is the human readable text returned with PARSE response
3186
3187 - badcharset is a list of charset returned with a BADCHARSET response
3188
3189 - trycreate is set to 1 if a trycreate response was returned
3190
3191 - mailbox_list is a list of mailboxes
3192
3193 - mailbox_lsub is a list of subscribed mailboxes
3194
3195 - search_result is a list of message numbers or unique identifiers
3196
3197 - status is a STATUS response
3198
3199 - expunged is a list of message numbers
3200
3201 - fetch_list is a list of fetch response
3202*/
3203
3204struct mailimap_response_info {
3205 char * rsp_alert;
3206 char * rsp_parse;
3207 clist * rsp_badcharset; /* list of (char *) */
3208 int rsp_trycreate;
3209 clist * rsp_mailbox_list; /* list of (struct mailimap_mailbox_list *) */
3210 clist * rsp_mailbox_lsub; /* list of (struct mailimap_mailbox_list *) */
3211 clist * rsp_search_result; /* list of (uint32_t *) */
3212 struct mailimap_mailbox_data_status * rsp_status;
3213 clist * rsp_expunged; /* list of (uint32_t 32 *) */
3214 clist * rsp_fetch_list; /* list of (struct mailimap_msg_att *) */
3215};
3216
3217struct mailimap_response_info *
3218mailimap_response_info_new(void);
3219
3220void
3221mailimap_response_info_free(struct mailimap_response_info * resp_info);
3222
3223
3224/* these are the possible returned error codes */
3225
3226enum {
3227 MAILIMAP_NO_ERROR = 0,
3228 MAILIMAP_NO_ERROR_AUTHENTICATED = 1,
3229 MAILIMAP_NO_ERROR_NON_AUTHENTICATED = 2,
3230 MAILIMAP_ERROR_BAD_STATE,
3231 MAILIMAP_ERROR_STREAM,
3232 MAILIMAP_ERROR_PARSE,
3233 MAILIMAP_ERROR_CONNECTION_REFUSED,
3234 MAILIMAP_ERROR_MEMORY,
3235 MAILIMAP_ERROR_FATAL,
3236 MAILIMAP_ERROR_PROTOCOL,
3237 MAILIMAP_ERROR_DONT_ACCEPT_CONNECTION,
3238 MAILIMAP_ERROR_APPEND,
3239 MAILIMAP_ERROR_NOOP,
3240 MAILIMAP_ERROR_LOGOUT,
3241 MAILIMAP_ERROR_CAPABILITY,
3242 MAILIMAP_ERROR_CHECK,
3243 MAILIMAP_ERROR_CLOSE,
3244 MAILIMAP_ERROR_EXPUNGE,
3245 MAILIMAP_ERROR_COPY,
3246 MAILIMAP_ERROR_UID_COPY,
3247 MAILIMAP_ERROR_CREATE,
3248 MAILIMAP_ERROR_DELETE,
3249 MAILIMAP_ERROR_EXAMINE,
3250 MAILIMAP_ERROR_FETCH,
3251 MAILIMAP_ERROR_UID_FETCH,
3252 MAILIMAP_ERROR_LIST,
3253 MAILIMAP_ERROR_LOGIN,
3254 MAILIMAP_ERROR_LSUB,
3255 MAILIMAP_ERROR_RENAME,
3256 MAILIMAP_ERROR_SEARCH,
3257 MAILIMAP_ERROR_UID_SEARCH,
3258 MAILIMAP_ERROR_SELECT,
3259 MAILIMAP_ERROR_STATUS,
3260 MAILIMAP_ERROR_STORE,
3261 MAILIMAP_ERROR_UID_STORE,
3262 MAILIMAP_ERROR_SUBSCRIBE,
3263 MAILIMAP_ERROR_UNSUBSCRIBE,
3264 MAILIMAP_ERROR_STARTTLS,
3265 MAILIMAP_ERROR_INVAL,
3266};
3267
3268
3269#ifdef __cplusplus
3270}
3271#endif
3272
3273#endif
3274
diff --git a/libetpan/src/low-level/imap/mailimap_types_helper.c b/libetpan/src/low-level/imap/mailimap_types_helper.c
new file mode 100644
index 0000000..574897b
--- a/dev/null
+++ b/libetpan/src/low-level/imap/mailimap_types_helper.c
@@ -0,0 +1,1269 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailimap_types.h"
37#include "mail.h"
38
39#include <stdlib.h>
40
41/* ************************************************************************* */
42/* ************************************************************************* */
43/* ************************************************************************* */
44/* ************************************************************************* */
45/* ************************************************************************* */
46/* ************************************************************************* */
47
48/* in helper */
49
50
51
52
53struct mailimap_set_item * mailimap_set_item_new_single(uint32_t index)
54{
55 return mailimap_set_item_new(index, index);
56}
57
58struct mailimap_set *
59mailimap_set_new_single_item(struct mailimap_set_item * item)
60{
61 struct mailimap_set * set;
62 clist * list;
63 int r;
64
65 list = clist_new();
66 if (list == NULL)
67 return NULL;
68
69 r = clist_append(list, item);
70 if (r < 0) {
71 clist_free(list);
72 return NULL;
73 }
74
75 set = mailimap_set_new(list);
76 if (set == NULL) {
77 clist_free(list);
78 return NULL;
79 }
80
81 return set;
82}
83
84struct mailimap_set * mailimap_set_new_interval(uint32_t first, uint32_t last)
85{
86 struct mailimap_set_item * item;
87 struct mailimap_set * set;
88
89 item = mailimap_set_item_new(first, last);
90 if (item == NULL)
91 return NULL;
92
93 set = mailimap_set_new_single_item(item);
94 if (set == NULL) {
95 mailimap_set_item_free(item);
96 return NULL;
97 }
98
99 return set;
100}
101
102struct mailimap_set * mailimap_set_new_single(uint32_t index)
103{
104 return mailimap_set_new_interval(index, index);
105}
106
107
108struct mailimap_set * mailimap_set_new_empty(void)
109{
110 clist * list;
111
112 list = clist_new();
113 if (list == NULL)
114 return NULL;
115
116 return mailimap_set_new(list);
117}
118
119int mailimap_set_add(struct mailimap_set * set,
120 struct mailimap_set_item * set_item)
121{
122 int r;
123
124 r = clist_append(set->set_list, set_item);
125 if (r < 0)
126 return MAILIMAP_ERROR_MEMORY;
127
128 return MAILIMAP_NO_ERROR;
129}
130
131int mailimap_set_add_interval(struct mailimap_set * set,
132 uint32_t first, uint32_t last)
133{
134 struct mailimap_set_item * item;
135 int r;
136
137 item = mailimap_set_item_new(first, last);
138 if (item == NULL)
139 return MAILIMAP_ERROR_MEMORY;
140
141 r = mailimap_set_add(set, item);
142 if (r != MAILIMAP_NO_ERROR) {
143 mailimap_set_item_free(item);
144 return r;
145 }
146 else
147 return MAILIMAP_NO_ERROR;
148}
149
150int mailimap_set_add_single(struct mailimap_set * set,
151 uint32_t index)
152{
153 return mailimap_set_add_interval(set, index, index);
154}
155
156/* CHECK */
157/* no args */
158
159/* CLOSE */
160/* no args */
161
162/* EXPUNGE */
163/* no args */
164
165/* COPY */
166/* set and gchar */
167
168/* FETCH */
169/* set and gchar fetch_type */
170
171
172
173/* section */
174
175#if 0
176/* not correct XXX */
177
178struct mailimap_section * mailimap_section_new_empty(void)
179{
180 clist * list;
181
182 list = clist_new();
183 if (list == NULL)
184 return NULL;
185
186 return mailimap_section_new(list);
187}
188#endif
189
190static struct mailimap_section *
191mailimap_section_new_msgtext(struct mailimap_section_msgtext * msgtext)
192{
193 struct mailimap_section_spec * spec;
194 struct mailimap_section * section;
195
196 spec = mailimap_section_spec_new(MAILIMAP_SECTION_SPEC_SECTION_MSGTEXT,
197 msgtext, NULL, NULL);
198 if (spec == NULL)
199 return NULL;
200
201 section = mailimap_section_new(spec);
202 if (section == NULL) {
203 /* detach section_msgtext so that it will not be freed */
204 spec->sec_data.sec_msgtext = NULL;
205 mailimap_section_spec_free(spec);
206 return NULL;
207 }
208
209 return section;
210}
211
212static struct mailimap_section *
213mailimap_section_new_part_msgtext(struct mailimap_section_part * part,
214 struct mailimap_section_msgtext * msgtext)
215{
216 struct mailimap_section_spec * spec;
217 struct mailimap_section * section;
218 struct mailimap_section_text * text;
219
220 text = mailimap_section_text_new(MAILIMAP_SECTION_TEXT_SECTION_MSGTEXT,
221 msgtext);
222 if (text == NULL)
223 return NULL;
224
225 spec = mailimap_section_spec_new(MAILIMAP_SECTION_SPEC_SECTION_PART,
226 NULL, part, text);
227 if (spec == NULL) {
228 /* detach section_msgtext so that it will not be freed */
229 text->sec_msgtext = NULL;
230 mailimap_section_text_free(text);
231 return NULL;
232 }
233
234 section = mailimap_section_new(spec);
235 if (section == NULL) {
236 /* detach section_msgtext so that it will not be freed */
237 text->sec_msgtext = NULL;
238 mailimap_section_spec_free(spec);
239 return NULL;
240 }
241
242 return section;
243}
244
245/*
246HEADER
247HEADER.FIELDS fields
248HEADER.FIELDS.NOT fields
249TEXT
250*/
251
252struct mailimap_section * mailimap_section_new_header(void)
253{
254 struct mailimap_section_msgtext * msgtext;
255 struct mailimap_section * section;
256
257 msgtext = mailimap_section_msgtext_new(MAILIMAP_SECTION_MSGTEXT_HEADER,
258 NULL);
259 if (msgtext == NULL)
260 return NULL;
261
262 section = mailimap_section_new_msgtext(msgtext);
263 if (section == NULL) {
264 mailimap_section_msgtext_free(msgtext);
265 return NULL;
266 }
267
268 return section;
269}
270
271struct mailimap_section *
272mailimap_section_new_header_fields(struct mailimap_header_list * header_list)
273{
274 struct mailimap_section * section;
275 struct mailimap_section_msgtext * msgtext;
276
277 msgtext =
278 mailimap_section_msgtext_new(MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS,
279 header_list);
280 if (msgtext == NULL)
281 return NULL;
282
283 section = mailimap_section_new_msgtext(msgtext);
284 if (section == NULL) {
285 /* detach header_list so that it will not be freed */
286 msgtext->sec_header_list = NULL;
287 mailimap_section_msgtext_free(msgtext);
288 return NULL;
289 }
290
291 return section;
292}
293
294struct mailimap_section *
295mailimap_section_new_header_fields_not(struct mailimap_header_list * header_list)
296{
297 struct mailimap_section * section;
298 struct mailimap_section_msgtext * msgtext;
299
300 msgtext =
301 mailimap_section_msgtext_new(MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS_NOT,
302 header_list);
303 if (msgtext == NULL)
304 return NULL;
305
306 section = mailimap_section_new_msgtext(msgtext);
307 if (section == NULL) {
308 /* detach header_list so that it will not be freed */
309 msgtext->sec_header_list = NULL;
310 mailimap_section_msgtext_free(msgtext);
311 return NULL;
312 }
313
314 return section;
315}
316
317struct mailimap_section * mailimap_section_new_text(void)
318{
319 struct mailimap_section * section;
320 struct mailimap_section_msgtext * msgtext;
321
322 msgtext = mailimap_section_msgtext_new(MAILIMAP_SECTION_MSGTEXT_TEXT, NULL);
323 if (msgtext == NULL)
324 return NULL;
325
326 section = mailimap_section_new_msgtext(msgtext);
327 if (section == NULL) {
328 mailimap_section_msgtext_free(msgtext);
329 return NULL;
330 }
331
332 return section;
333}
334
335/*
336section-part
337section-part . MIME
338section-part . HEADER
339section-part . HEADER.FIELDS fields
340section-part . HEADER.FIELDS.NOT fields
341section-part . TEXT
342*/
343
344struct mailimap_section *
345mailimap_section_new_part(struct mailimap_section_part * part)
346{
347 struct mailimap_section_spec * spec;
348 struct mailimap_section * section;
349
350 spec = mailimap_section_spec_new(MAILIMAP_SECTION_SPEC_SECTION_PART,
351 NULL, part, NULL);
352 if (spec == NULL)
353 return NULL;
354
355 section = mailimap_section_new(spec);
356 if (section == NULL) {
357 /* detach section_part so that it will not be freed */
358 spec->sec_data.sec_part = NULL;
359 mailimap_section_spec_free(spec);
360 return NULL;
361 }
362
363 return section;
364}
365
366struct mailimap_section *
367mailimap_section_new_part_mime(struct mailimap_section_part * part)
368{
369 struct mailimap_section_spec * spec;
370 struct mailimap_section * section;
371 struct mailimap_section_text * text;
372
373 text = mailimap_section_text_new(MAILIMAP_SECTION_TEXT_MIME, NULL);
374 if (text == NULL)
375 return NULL;
376
377 spec = mailimap_section_spec_new(MAILIMAP_SECTION_SPEC_SECTION_PART,
378 NULL, part, text);
379 if (spec == NULL) {
380 mailimap_section_text_free(text);
381 return NULL;
382 }
383
384 section = mailimap_section_new(spec);
385 if (section == NULL) {
386 /* detach section_part so that it will not be freed */
387 spec->sec_data.sec_part = NULL;
388 mailimap_section_spec_free(spec);
389 return NULL;
390 }
391
392 return section;
393}
394
395struct mailimap_section *
396mailimap_section_new_part_header(struct mailimap_section_part * part)
397{
398 struct mailimap_section_msgtext * msgtext;
399 struct mailimap_section * section;
400
401 msgtext = mailimap_section_msgtext_new(MAILIMAP_SECTION_MSGTEXT_HEADER,
402 NULL);
403 if (msgtext == NULL)
404 return NULL;
405
406 section = mailimap_section_new_part_msgtext(part, msgtext);
407 if (section == NULL) {
408 mailimap_section_msgtext_free(msgtext);
409 return NULL;
410 }
411
412 return section;
413}
414
415struct mailimap_section *
416mailimap_section_new_part_header_fields(struct mailimap_section_part *
417 part,
418 struct mailimap_header_list *
419 header_list)
420{
421 struct mailimap_section * section;
422 struct mailimap_section_msgtext * msgtext;
423
424 msgtext =
425 mailimap_section_msgtext_new(MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS,
426 header_list);
427 if (msgtext == NULL)
428 return NULL;
429
430 section = mailimap_section_new_part_msgtext(part, msgtext);
431 if (section == NULL) {
432 /* detach header_list so that it will not be freed */
433 msgtext->sec_header_list = NULL;
434 mailimap_section_msgtext_free(msgtext);
435 return NULL;
436 }
437
438 return section;
439}
440
441struct mailimap_section *
442mailimap_section_new_part_header_fields_not(struct mailimap_section_part
443 * part,
444 struct mailimap_header_list
445 * header_list)
446{
447 struct mailimap_section * section;
448 struct mailimap_section_msgtext * msgtext;
449
450 msgtext =
451 mailimap_section_msgtext_new(MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS_NOT,
452 header_list);
453 if (msgtext == NULL)
454 return NULL;
455
456 section = mailimap_section_new_part_msgtext(part, msgtext);
457 if (section == NULL) {
458 /* detach header_list so that it will not be freed */
459 msgtext->sec_header_list = NULL;
460 mailimap_section_msgtext_free(msgtext);
461 return NULL;
462 }
463
464 return section;
465}
466
467struct mailimap_section *
468mailimap_section_new_part_text(struct mailimap_section_part * part)
469{
470 struct mailimap_section * section;
471 struct mailimap_section_msgtext * msgtext;
472
473 msgtext = mailimap_section_msgtext_new(MAILIMAP_SECTION_MSGTEXT_TEXT, NULL);
474 if (msgtext == NULL)
475 return NULL;
476
477 section = mailimap_section_new_part_msgtext(part, msgtext);
478 if (section == NULL) {
479 mailimap_section_msgtext_free(msgtext);
480 return NULL;
481 }
482
483 return section;
484}
485
486/* end of section */
487
488
489
490
491
492
493struct mailimap_fetch_att *
494mailimap_fetch_att_new_envelope(void)
495{
496 return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_ENVELOPE, NULL, 0, 0);
497}
498
499struct mailimap_fetch_att *
500mailimap_fetch_att_new_flags(void)
501{
502 return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_FLAGS, NULL, 0, 0);
503}
504
505struct mailimap_fetch_att *
506mailimap_fetch_att_new_internaldate(void)
507{
508 return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_INTERNALDATE, NULL, 0, 0);
509}
510
511struct mailimap_fetch_att *
512mailimap_fetch_att_new_rfc822(void)
513{
514 return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_RFC822, NULL, 0, 0);
515}
516
517struct mailimap_fetch_att *
518mailimap_fetch_att_new_rfc822_header(void)
519{
520 return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_RFC822_HEADER, NULL, 0, 0);
521}
522
523struct mailimap_fetch_att *
524mailimap_fetch_att_new_rfc822_size(void)
525{
526 return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_RFC822_SIZE, NULL, 0, 0);
527}
528
529struct mailimap_fetch_att *
530mailimap_fetch_att_new_rfc822_text(void)
531{
532 return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_RFC822_TEXT, NULL, 0, 0);
533}
534
535struct mailimap_fetch_att *
536mailimap_fetch_att_new_body(void)
537{
538 return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_BODY, NULL, 0, 0);
539}
540
541struct mailimap_fetch_att *
542mailimap_fetch_att_new_bodystructure(void)
543{
544 return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_BODYSTRUCTURE, NULL, 0, 0);
545}
546
547struct mailimap_fetch_att *
548mailimap_fetch_att_new_uid(void)
549{
550 return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_UID, NULL, 0, 0);
551}
552
553struct mailimap_fetch_att *
554mailimap_fetch_att_new_body_section(struct mailimap_section * section)
555{
556 return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_BODY_SECTION, section, 0, 0);
557}
558
559struct mailimap_fetch_att *
560mailimap_fetch_att_new_body_peek_section(struct mailimap_section * section)
561{
562 return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_BODY_PEEK_SECTION, section, 0, 0);
563}
564
565struct mailimap_fetch_att *
566mailimap_fetch_att_new_body_section_partial(struct mailimap_section * section,
567 uint32_t offset, uint32_t size)
568{
569 return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_BODY_SECTION, section,
570 offset, size);
571}
572
573struct mailimap_fetch_att *
574mailimap_fetch_att_new_body_peek_section_partial(struct mailimap_section * section,
575 uint32_t offset, uint32_t size)
576{
577 return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_BODY_PEEK_SECTION, section,
578 offset, size);
579}
580
581
582
583struct mailimap_fetch_type *
584mailimap_fetch_type_new_all(void)
585{
586 return mailimap_fetch_type_new(MAILIMAP_FETCH_TYPE_ALL, NULL, NULL);
587}
588
589struct mailimap_fetch_type *
590mailimap_fetch_type_new_full(void)
591{
592 return mailimap_fetch_type_new(MAILIMAP_FETCH_TYPE_FULL, NULL, NULL);
593}
594
595struct mailimap_fetch_type *
596mailimap_fetch_type_new_fast(void)
597{
598 return mailimap_fetch_type_new(MAILIMAP_FETCH_TYPE_FAST, NULL, NULL);
599}
600
601struct mailimap_fetch_type *
602mailimap_fetch_type_new_fetch_att(struct mailimap_fetch_att * fetch_att)
603{
604 return mailimap_fetch_type_new(MAILIMAP_FETCH_TYPE_FETCH_ATT, fetch_att, NULL);
605}
606
607struct mailimap_fetch_type *
608mailimap_fetch_type_new_fetch_att_list(clist * fetch_att_list)
609{
610 return mailimap_fetch_type_new(MAILIMAP_FETCH_TYPE_FETCH_ATT_LIST,
611 NULL, fetch_att_list);
612}
613
614struct mailimap_fetch_type *
615mailimap_fetch_type_new_fetch_att_list_empty(void)
616{
617 clist * list;
618
619 list = clist_new();
620 if (list == NULL)
621 return NULL;
622
623 return mailimap_fetch_type_new(MAILIMAP_FETCH_TYPE_FETCH_ATT_LIST,
624 NULL, list);
625}
626
627int
628mailimap_fetch_type_new_fetch_att_list_add(struct mailimap_fetch_type *
629 fetch_type,
630 struct mailimap_fetch_att * fetch_att)
631{
632 int r;
633
634 r = clist_append(fetch_type->ft_data.ft_fetch_att_list, fetch_att);
635 if (r < 0)
636 return MAILIMAP_ERROR_MEMORY;
637
638 return MAILIMAP_NO_ERROR;
639}
640
641
642
643/* STORE */
644/* set and store_att_flags */
645
646struct mailimap_store_att_flags *
647mailimap_store_att_flags_new_set_flags(struct mailimap_flag_list * flags)
648{
649 return mailimap_store_att_flags_new(0, FALSE, flags);
650}
651
652struct mailimap_store_att_flags *
653mailimap_store_att_flags_new_set_flags_silent(struct mailimap_flag_list *
654 flags)
655{
656 return mailimap_store_att_flags_new(0, TRUE, flags);
657}
658
659struct mailimap_store_att_flags *
660mailimap_store_att_flags_new_add_flags(struct mailimap_flag_list * flags)
661{
662 return mailimap_store_att_flags_new(1, FALSE, flags);
663}
664
665struct mailimap_store_att_flags *
666mailimap_store_att_flags_new_add_flags_silent(struct mailimap_flag_list *
667 flags)
668{
669 return mailimap_store_att_flags_new(1, TRUE, flags);
670}
671
672struct mailimap_store_att_flags *
673mailimap_store_att_flags_new_remove_flags(struct mailimap_flag_list * flags)
674{
675 return mailimap_store_att_flags_new(-1, FALSE, flags);
676}
677
678struct mailimap_store_att_flags *
679mailimap_store_att_flags_new_remove_flags_silent(struct mailimap_flag_list *
680 flags)
681{
682 return mailimap_store_att_flags_new(-1, TRUE, flags);
683}
684
685/* SEARCH */
686/* date search-key set */
687
688/*
689 return mailimap_search_key_new(type, bcc, before,
690 body, cc, from, keyword, on, since,
691 subject, text, to, unkeyword, header_name,
692 header_value, larger, not,
693 or1, or2, sentbefore, senton, sentsince,
694 smaller, uid, set, multiple);
695*/
696
697struct mailimap_search_key *
698mailimap_search_key_new_all(void)
699{
700 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_ALL, NULL, NULL,
701 NULL, NULL, NULL, NULL, NULL, NULL,
702 NULL, NULL, NULL, NULL, NULL,
703 NULL, 0, NULL,
704 NULL, NULL, NULL, NULL, NULL,
705 0, NULL, NULL, NULL);
706}
707
708struct mailimap_search_key *
709mailimap_search_key_new_bcc(char * sk_bcc)
710{
711 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_BCC, sk_bcc, NULL,
712 NULL, NULL, NULL, NULL, NULL, NULL,
713 NULL, NULL, NULL, NULL, NULL,
714 NULL, 0, NULL,
715 NULL, NULL, NULL, NULL, NULL,
716 0, NULL, NULL, NULL);
717}
718
719struct mailimap_search_key *
720mailimap_search_key_new_before(struct mailimap_date * sk_before)
721{
722 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_BEFORE, NULL, sk_before,
723 NULL, NULL, NULL, NULL, NULL, NULL,
724 NULL, NULL, NULL, NULL, NULL,
725 NULL, 0, NULL,
726 NULL, NULL, NULL, NULL, NULL,
727 0, NULL, NULL, NULL);
728}
729
730struct mailimap_search_key *
731mailimap_search_key_new_body(char * sk_body)
732{
733 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_BODY, NULL, NULL,
734 sk_body, NULL, NULL, NULL, NULL, NULL,
735 NULL, NULL, NULL, NULL, NULL,
736 NULL, 0, NULL,
737 NULL, NULL, NULL, NULL, NULL,
738 0, NULL, NULL, NULL);
739}
740
741struct mailimap_search_key *
742mailimap_search_key_new_cc(char * sk_cc)
743{
744 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_CC, NULL, NULL,
745 NULL, sk_cc, NULL, NULL, NULL, NULL,
746 NULL, NULL, NULL, NULL, NULL,
747 NULL, 0, NULL,
748 NULL, NULL, NULL, NULL, NULL,
749 0, NULL, NULL, NULL);
750}
751
752struct mailimap_search_key *
753mailimap_search_key_new_from(char * sk_from)
754{
755 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_FROM, NULL, NULL,
756 NULL, NULL, sk_from, NULL, NULL, NULL,
757 NULL, NULL, NULL, NULL, NULL,
758 NULL, 0, NULL,
759 NULL, NULL, NULL, NULL, NULL,
760 0, NULL, NULL, NULL);
761}
762
763struct mailimap_search_key *
764mailimap_search_key_new_keyword(char * sk_keyword)
765{
766 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_FROM, NULL, NULL,
767 NULL, NULL, NULL, sk_keyword, NULL, NULL,
768 NULL, NULL, NULL, NULL, NULL,
769 NULL, 0, NULL,
770 NULL, NULL, NULL, NULL, NULL,
771 0, NULL, NULL, NULL);
772}
773
774struct mailimap_search_key *
775mailimap_search_key_new_on(struct mailimap_date * sk_on)
776{
777 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_ON, NULL, NULL,
778 NULL, NULL, NULL, NULL, sk_on, NULL,
779 NULL, NULL, NULL, NULL, NULL,
780 NULL, 0, NULL,
781 NULL, NULL, NULL, NULL, NULL,
782 0, NULL, NULL, NULL);
783}
784
785struct mailimap_search_key *
786mailimap_search_key_new_since(struct mailimap_date * sk_since)
787{
788 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_SINCE, NULL, NULL,
789 NULL, NULL, NULL, NULL, NULL, sk_since,
790 NULL, NULL, NULL, NULL, NULL,
791 NULL, 0, NULL,
792 NULL, NULL, NULL, NULL, NULL,
793 0, NULL, NULL, NULL);
794}
795
796struct mailimap_search_key *
797mailimap_search_key_new_subject(char * sk_subject)
798{
799 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_SINCE, NULL, NULL,
800 NULL, NULL, NULL, NULL, NULL, NULL,
801 sk_subject, NULL, NULL, NULL, NULL,
802 NULL, 0, NULL,
803 NULL, NULL, NULL, NULL, NULL,
804 0, NULL, NULL, NULL);
805}
806
807struct mailimap_search_key *
808mailimap_search_key_new_text(char * sk_text)
809{
810 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_TEXT, NULL, NULL,
811 NULL, NULL, NULL, NULL, NULL, NULL,
812 NULL, sk_text, NULL, NULL, NULL,
813 NULL, 0, NULL,
814 NULL, NULL, NULL, NULL, NULL,
815 0, NULL, NULL, NULL);
816}
817
818struct mailimap_search_key *
819mailimap_search_key_new_to(char * sk_to)
820{
821 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_TO, NULL, NULL,
822 NULL, NULL, NULL, NULL, NULL, NULL,
823 NULL, NULL, sk_to, NULL, NULL,
824 NULL, 0, NULL,
825 NULL, NULL, NULL, NULL, NULL,
826 0, NULL, NULL, NULL);
827}
828
829struct mailimap_search_key *
830mailimap_search_key_new_unkeyword(char * sk_unkeyword)
831{
832 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_UNKEYWORD, NULL, NULL,
833 NULL, NULL, NULL, NULL, NULL, NULL,
834 NULL, NULL, NULL, sk_unkeyword, NULL,
835 NULL, 0, NULL,
836 NULL, NULL, NULL, NULL, NULL,
837 0, NULL, NULL, NULL);
838}
839
840struct mailimap_search_key *
841mailimap_search_key_new_header(char * sk_header_name, char * sk_header_value)
842{
843 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_HEADER, NULL, NULL,
844 NULL, NULL, NULL, NULL, NULL, NULL,
845 NULL, NULL, NULL, NULL, sk_header_name,
846 sk_header_value, 0, NULL,
847 NULL, NULL, NULL, NULL, NULL,
848 0, NULL, NULL, NULL);
849}
850
851struct mailimap_search_key *
852mailimap_search_key_new_larger(uint32_t sk_larger)
853{
854 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_LARGER, NULL, NULL,
855 NULL, NULL, NULL, NULL, NULL, NULL,
856 NULL, NULL, NULL, NULL, NULL,
857 NULL, sk_larger, NULL,
858 NULL, NULL, NULL, NULL, NULL,
859 0, NULL, NULL, NULL);
860}
861
862struct mailimap_search_key *
863mailimap_search_key_new_not(struct mailimap_search_key * sk_not)
864{
865 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_NOT, NULL, NULL,
866 NULL, NULL, NULL, NULL, NULL, NULL,
867 NULL, NULL, NULL, NULL, NULL,
868 NULL, 0, sk_not,
869 NULL, NULL, NULL, NULL, NULL,
870 0, NULL, NULL, NULL);
871}
872
873struct mailimap_search_key *
874mailimap_search_key_new_or(struct mailimap_search_key * sk_or1,
875 struct mailimap_search_key * sk_or2)
876{
877 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_OR, NULL, NULL,
878 NULL, NULL, NULL, NULL, NULL, NULL,
879 NULL, NULL, NULL, NULL, NULL,
880 NULL, 0, NULL,
881 sk_or1, sk_or2, NULL, NULL, NULL,
882 0, NULL, NULL, NULL);
883}
884
885struct mailimap_search_key *
886mailimap_search_key_new_sentbefore(struct mailimap_date * sk_sentbefore)
887{
888 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_NOT, NULL, NULL,
889 NULL, NULL, NULL, NULL, NULL, NULL,
890 NULL, NULL, NULL, NULL, NULL,
891 NULL, 0, NULL,
892 NULL, NULL, sk_sentbefore, NULL, NULL,
893 0, NULL, NULL, NULL);
894}
895
896struct mailimap_search_key *
897mailimap_search_key_new_senton(struct mailimap_date * sk_senton)
898{
899 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_SENTON, NULL, NULL,
900 NULL, NULL, NULL, NULL, NULL, NULL,
901 NULL, NULL, NULL, NULL, NULL,
902 NULL, 0, NULL,
903 NULL, NULL, NULL, sk_senton, NULL,
904 0, NULL, NULL, NULL);
905}
906
907struct mailimap_search_key *
908mailimap_search_key_new_sentsince(struct mailimap_date * sk_sentsince)
909{
910 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_SENTSINCE, NULL, NULL,
911 NULL, NULL, NULL, NULL, NULL, NULL,
912 NULL, NULL, NULL, NULL, NULL,
913 NULL, 0, NULL,
914 NULL, NULL, NULL, NULL, sk_sentsince,
915 0, NULL, NULL, NULL);
916}
917
918struct mailimap_search_key *
919mailimap_search_key_new_smaller(uint32_t sk_smaller)
920{
921 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_SMALLER, NULL, NULL,
922 NULL, NULL, NULL, NULL, NULL, NULL,
923 NULL, NULL, NULL, NULL, NULL,
924 NULL, 0, NULL,
925 NULL, NULL, NULL, NULL, NULL,
926 sk_smaller, NULL, NULL, NULL);
927}
928
929struct mailimap_search_key *
930mailimap_search_key_new_uid(struct mailimap_set * sk_uid)
931{
932 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_UID, NULL, NULL,
933 NULL, NULL, NULL, NULL, NULL, NULL,
934 NULL, NULL, NULL, NULL, NULL,
935 NULL, 0, NULL,
936 NULL, NULL, NULL, NULL, NULL,
937 0, sk_uid, NULL, NULL);
938}
939
940struct mailimap_search_key *
941mailimap_search_key_new_set(struct mailimap_set * sk_set)
942{
943 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_SET, NULL, NULL,
944 NULL, NULL, NULL, NULL, NULL, NULL,
945 NULL, NULL, NULL, NULL, NULL,
946 NULL, 0, NULL,
947 NULL, NULL, NULL, NULL, NULL,
948 0, NULL, sk_set, NULL);
949}
950
951struct mailimap_search_key *
952mailimap_search_key_new_multiple(clist * sk_multiple)
953{
954 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_MULTIPLE, NULL, NULL,
955 NULL, NULL, NULL, NULL, NULL, NULL,
956 NULL, NULL, NULL, NULL, NULL,
957 NULL, 0, NULL,
958 NULL, NULL, NULL, NULL, NULL,
959 0, NULL, NULL, sk_multiple);
960}
961
962struct mailimap_search_key *
963mailimap_search_key_new_multiple_empty(void)
964{
965 clist * list;
966
967 list = clist_new();
968 if (list == NULL)
969 return NULL;
970
971 return mailimap_search_key_new_multiple(list);
972}
973
974int
975mailimap_search_key_multiple_add(struct mailimap_search_key * keys,
976 struct mailimap_search_key * key_item)
977{
978 int r;
979
980 r = clist_append(keys->sk_data.sk_multiple, key_item);
981 if (r < 0)
982 return MAILIMAP_ERROR_MEMORY;
983
984 return MAILIMAP_NO_ERROR;
985}
986
987
988
989/* CAPABILITY */
990/* no args */
991
992/* LOGOUT */
993/* no args */
994
995/* NOOP */
996/* no args */
997
998/* APPEND */
999/* gchar flag_list date_time gchar */
1000
1001struct mailimap_flag_list *
1002mailimap_flag_list_new_empty(void)
1003{
1004 clist * list;
1005
1006 list = clist_new();
1007 if (list == NULL)
1008 return NULL;
1009
1010 return mailimap_flag_list_new(list);
1011}
1012
1013int mailimap_flag_list_add(struct mailimap_flag_list * flag_list,
1014 struct mailimap_flag * f)
1015{
1016 int r;
1017
1018 r = clist_append(flag_list->fl_list, f);
1019 if (r < 0)
1020 return MAILIMAP_ERROR_MEMORY;
1021
1022 return MAILIMAP_NO_ERROR;
1023}
1024
1025struct mailimap_flag * mailimap_flag_new_answered(void)
1026{
1027 return mailimap_flag_new(MAILIMAP_FLAG_ANSWERED, NULL, NULL);
1028}
1029
1030struct mailimap_flag * mailimap_flag_new_flagged(void)
1031{
1032 return mailimap_flag_new(MAILIMAP_FLAG_FLAGGED, NULL, NULL);
1033}
1034
1035struct mailimap_flag * mailimap_flag_new_deleted(void)
1036{
1037 return mailimap_flag_new(MAILIMAP_FLAG_DELETED, NULL, NULL);
1038}
1039
1040struct mailimap_flag * mailimap_flag_new_seen(void)
1041{
1042 return mailimap_flag_new(MAILIMAP_FLAG_SEEN, NULL, NULL);
1043}
1044
1045struct mailimap_flag * mailimap_flag_new_draft(void)
1046{
1047 return mailimap_flag_new(MAILIMAP_FLAG_DRAFT, NULL, NULL);
1048}
1049
1050struct mailimap_flag * mailimap_flag_new_flag_keyword(char * flag_keyword)
1051{
1052 return mailimap_flag_new(MAILIMAP_FLAG_KEYWORD, flag_keyword, NULL);
1053}
1054
1055struct mailimap_flag * mailimap_flag_new_flag_extension(char * flag_extension)
1056{
1057 return mailimap_flag_new(MAILIMAP_FLAG_EXTENSION, NULL, flag_extension);
1058}
1059
1060
1061
1062
1063/* CREATE */
1064/* gchar */
1065
1066/* DELETE */
1067/* gchar */
1068
1069/* EXAMINE */
1070/* gchar */
1071
1072/* LIST */
1073/* gchar gchar */
1074
1075/* LSUB */
1076/* gchar gchar */
1077
1078/* RENAME */
1079/* gchar gchar */
1080
1081/* SELECT */
1082/* gchar */
1083
1084/* STATUS */
1085/* gchar GList of status_att */
1086
1087struct mailimap_status_att_list * mailimap_status_att_list_new_empty(void)
1088{
1089 clist * list;
1090
1091 list = clist_new();
1092 if (list == NULL)
1093 return NULL;
1094
1095 return mailimap_status_att_list_new(list);
1096}
1097
1098int
1099mailimap_status_att_list_add(struct mailimap_status_att_list * sa_list,
1100 int status_att)
1101{
1102 int * pstatus_att;
1103 int r;
1104
1105 pstatus_att = malloc(sizeof(* pstatus_att));
1106 * pstatus_att = status_att;
1107
1108 r = clist_append(sa_list->att_list, pstatus_att);
1109 if (r < 0) {
1110 free(pstatus_att);
1111 return MAILIMAP_ERROR_MEMORY;
1112 }
1113
1114 return MAILIMAP_NO_ERROR;
1115}
1116
1117/* SUBSCRIBE */
1118/* gchar */
1119
1120/* UNSUBSCRIBE */
1121/* gchar */
1122
1123/* LOGIN */
1124/* gchar gchar */
1125
1126/* AUTHENTICATE */
1127/* gchar */
1128
1129
1130static int recursive_build_path(struct mailimap_body * root_part,
1131 struct mailimap_body * part,
1132 clist ** result);
1133
1134static int try_build_part(struct mailimap_body * root_part,
1135 struct mailimap_body * part, uint32_t count,
1136 clist ** result)
1137{
1138 int r;
1139 clist * imap_id_list;
1140 uint32_t * id;
1141
1142 r = recursive_build_path(root_part, part, &imap_id_list);
1143 if (r != MAILIMAP_NO_ERROR)
1144 return r;
1145
1146 id = malloc(sizeof(* id));
1147 if (id == NULL) {
1148 clist_free(imap_id_list);
1149 return MAILIMAP_ERROR_MEMORY;
1150 }
1151
1152 * id = count;
1153
1154 r = clist_prepend(imap_id_list, id);
1155 if (r < 0) {
1156 free(id);
1157 clist_free(imap_id_list);
1158 return MAILIMAP_ERROR_MEMORY;
1159 }
1160
1161 * result = imap_id_list;
1162
1163 return MAILIMAP_NO_ERROR;
1164}
1165
1166
1167static int recursive_build_path(struct mailimap_body * root_part,
1168 struct mailimap_body * part,
1169 clist ** result)
1170{
1171 clistiter * cur;
1172 uint32_t count;
1173 int r;
1174 clist * imap_id_list;
1175
1176 if (part == root_part) {
1177 imap_id_list = clist_new();
1178 if (imap_id_list == NULL) {
1179 return MAILIMAP_ERROR_MEMORY;
1180 }
1181
1182 * result = imap_id_list;
1183
1184 return MAILIMAP_NO_ERROR;
1185 }
1186
1187 switch (root_part->bd_type) {
1188 case MAILIMAP_BODY_MPART:
1189 count = 0;
1190 for(cur = clist_begin(root_part->bd_data.bd_body_mpart->bd_list) ;
1191 cur != NULL ; cur = clist_next(cur)) {
1192 struct mailimap_body * current_part;
1193
1194 current_part = clist_content(cur);
1195 count ++;
1196
1197 r = try_build_part(current_part, part, count, &imap_id_list);
1198 if (r == MAILIMAP_ERROR_INVAL) {
1199 continue;
1200 } if (r != MAILIMAP_NO_ERROR) {
1201 return r;
1202 }
1203 else {
1204 * result = imap_id_list;
1205 return MAILIMAP_NO_ERROR;
1206 }
1207 }
1208 return MAILIMAP_ERROR_INVAL;
1209
1210 case MAILIMAP_BODY_1PART:
1211 if (root_part->bd_data.bd_body_1part->bd_type ==
1212 MAILIMAP_BODY_TYPE_1PART_MSG) {
1213 struct mailimap_body * current_part;
1214
1215 current_part =
1216 root_part->bd_data.bd_body_1part->bd_data.bd_type_msg->bd_body;
1217
1218 r = try_build_part(current_part, part, 1, &imap_id_list);
1219 if (r != MAILIMAP_NO_ERROR) {
1220 return r;
1221 }
1222 else {
1223 * result = imap_id_list;
1224 return MAILIMAP_NO_ERROR;
1225 }
1226 }
1227 else {
1228 return MAILIMAP_ERROR_INVAL;
1229 }
1230 break;
1231
1232 default:
1233 return MAILIMAP_ERROR_INVAL;
1234 }
1235}
1236
1237/* return mailimap_section_part from a given mailimap_body */
1238
1239int mailimap_get_section_part_from_body(struct mailimap_body * root_part,
1240 struct mailimap_body * part,
1241 struct mailimap_section_part ** result)
1242{
1243 struct mailimap_section_part * section_part;
1244 clist * id_list;
1245 int r;
1246 int res;
1247
1248 r = recursive_build_path(root_part, part, &id_list);
1249 if (r != MAILIMAP_NO_ERROR) {
1250 res = r;
1251 goto err;
1252 }
1253
1254 section_part = mailimap_section_part_new(id_list);
1255 if (section_part == NULL) {
1256 res = MAILIMAP_ERROR_MEMORY;
1257 goto free_list;
1258 }
1259
1260 * result = section_part;
1261
1262 return MAILIMAP_NO_ERROR;
1263
1264 free_list:
1265 clist_foreach(id_list, (clist_func) free, NULL);
1266 clist_free(id_list);
1267 err:
1268 return res;
1269}
diff --git a/libetpan/src/low-level/imap/mailimap_types_helper.h b/libetpan/src/low-level/imap/mailimap_types_helper.h
new file mode 100644
index 0000000..10905d4
--- a/dev/null
+++ b/libetpan/src/low-level/imap/mailimap_types_helper.h
@@ -0,0 +1,758 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILIMAP_TYPES_HELPER_H
37
38#define MAILIMAP_TYPES_HELPER_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mailimap_types.h>
45
46/*
47 IMPORTANT NOTE:
48
49 All allocation functions will take as argument allocated data
50 and will store these data in the structure they will allocate.
51 Data should be persistant during all the use of the structure
52 and will be freed by the free function of the structure
53
54 allocation functions will return NULL on failure
55*/
56
57/*
58 this function creates a new set item with a single message
59 given by index
60*/
61
62struct mailimap_set_item * mailimap_set_item_new_single(uint32_t index);
63
64/*
65 this function creates a new set with one set item
66 */
67
68struct mailimap_set *
69mailimap_set_new_single_item(struct mailimap_set_item * item);
70
71/*
72 this function creates a set with a single interval
73*/
74
75struct mailimap_set * mailimap_set_new_interval(uint32_t first, uint32_t last);
76
77/*
78 this function creates a set with a single message
79*/
80
81struct mailimap_set * mailimap_set_new_single(uint32_t index);
82
83/*
84 this function creates an empty set of messages
85*/
86
87struct mailimap_set * mailimap_set_new_empty(void);
88
89/*
90 this function adds a set item to the set of messages
91
92 @return MAILIMAP_NO_ERROR will be returned on success,
93 other code will be returned otherwise
94*/
95
96int mailimap_set_add(struct mailimap_set * set,
97 struct mailimap_set_item * set_item);
98
99/*
100 this function adds an interval to the set
101
102 @return MAILIMAP_NO_ERROR will be returned on success,
103 other code will be returned otherwise
104*/
105
106int mailimap_set_add_interval(struct mailimap_set * set,
107 uint32_t first, uint32_t last);
108
109/*
110 this function adds a single message to the set
111
112 @return MAILIMAP_NO_ERROR will be returned on success,
113 other code will be returned otherwise
114*/
115
116int mailimap_set_add_single(struct mailimap_set * set,
117 uint32_t index);
118
119/*
120 this function creates a mailimap_section structure to request
121 the header of a message
122*/
123
124struct mailimap_section * mailimap_section_new_header(void);
125
126/*
127 this functions creates a mailimap_section structure to describe
128 a list of headers
129*/
130
131struct mailimap_section *
132mailimap_section_new_header_fields(struct mailimap_header_list * header_list);
133
134/*
135 this functions creates a mailimap_section structure to describe headers
136 other than those given
137*/
138
139struct mailimap_section *
140mailimap_section_new_header_fields_not(struct mailimap_header_list * header_list);
141
142/*
143 this function creates a mailimap_section structure to describe the
144 text of a message
145 */
146
147struct mailimap_section * mailimap_section_new_text(void);
148
149/*
150 this function creates a mailimap_section structure to describe the
151 content of a MIME part
152*/
153
154struct mailimap_section *
155mailimap_section_new_part(struct mailimap_section_part * part);
156
157/*
158 this function creates a mailimap_section structure to describe the
159 MIME fields of a MIME part
160*/
161
162struct mailimap_section *
163mailimap_section_new_part_mime(struct mailimap_section_part * part);
164
165/*
166 this function creates a mailimap_section structure to describe the
167 headers of a MIME part if the MIME type is a message/rfc822
168*/
169
170struct mailimap_section *
171mailimap_section_new_part_header(struct mailimap_section_part * part);
172
173/*
174 this function creates a mailimap_section structure to describe
175 a list of headers of a MIME part if the MIME type is a message/rfc822
176*/
177
178struct mailimap_section *
179mailimap_section_new_part_header_fields(struct mailimap_section_part *
180 part,
181 struct mailimap_header_list *
182 header_list);
183
184/*
185 this function creates a mailimap_section structure to describe
186 headers of a MIME part other than those given if the MIME type
187 is a message/rfc822
188*/
189
190struct mailimap_section *
191mailimap_section_new_part_header_fields_not(struct mailimap_section_part
192 * part,
193 struct mailimap_header_list
194 * header_list);
195
196/*
197 this function creates a mailimap_section structure to describe
198 text part of message if the MIME type is a message/rfc822
199*/
200
201struct mailimap_section *
202mailimap_section_new_part_text(struct mailimap_section_part * part);
203
204
205/*
206 this function creates a mailimap_fetch_att structure to request
207 envelope of a message
208*/
209
210struct mailimap_fetch_att *
211mailimap_fetch_att_new_envelope(void);
212
213
214/*
215 this function creates a mailimap_fetch_att structure to request
216 flags of a message
217*/
218
219struct mailimap_fetch_att *
220mailimap_fetch_att_new_flags(void);
221
222/*
223 this function creates a mailimap_fetch_att structure to request
224 internal date of a message
225*/
226
227struct mailimap_fetch_att *
228mailimap_fetch_att_new_internaldate(void);
229
230
231/*
232 this function creates a mailimap_fetch_att structure to request
233 text part of a message
234*/
235
236struct mailimap_fetch_att *
237mailimap_fetch_att_new_rfc822(void);
238
239
240/*
241 this function creates a mailimap_fetch_att structure to request
242 header of a message
243*/
244
245struct mailimap_fetch_att *
246mailimap_fetch_att_new_rfc822_header(void);
247
248/*
249 this function creates a mailimap_fetch_att structure to request
250 size of a message
251*/
252
253struct mailimap_fetch_att *
254mailimap_fetch_att_new_rfc822_size(void);
255
256/*
257 this function creates a mailimap_fetch_att structure to request
258 envelope of a message
259*/
260
261struct mailimap_fetch_att *
262mailimap_fetch_att_new_rfc822_text(void);
263
264/*
265 this function creates a mailimap_fetch_att structure to request
266 the MIME structure of a message
267*/
268
269struct mailimap_fetch_att *
270mailimap_fetch_att_new_body(void);
271
272/*
273 this function creates a mailimap_fetch_att structure to request
274 the MIME structure of a message and additional MIME information
275*/
276
277struct mailimap_fetch_att *
278mailimap_fetch_att_new_bodystructure(void);
279
280/*
281 this function creates a mailimap_fetch_att structure to request
282 unique identifier of a message
283*/
284
285struct mailimap_fetch_att *
286mailimap_fetch_att_new_uid(void);
287
288/*
289 this function creates a mailimap_fetch_att structure to request
290 a given section of a message
291*/
292
293struct mailimap_fetch_att *
294mailimap_fetch_att_new_body_section(struct mailimap_section * section);
295
296/*
297 this function creates a mailimap_fetch_att structure to request
298 a given section of a message without marking it as read
299*/
300
301struct mailimap_fetch_att *
302mailimap_fetch_att_new_body_peek_section(struct mailimap_section * section);
303
304/*
305 this function creates a mailimap_fetch_att structure to request
306 a part of a section of a message
307*/
308
309struct mailimap_fetch_att *
310mailimap_fetch_att_new_body_section_partial(struct mailimap_section * section,
311 uint32_t offset, uint32_t size);
312
313/*
314 this function creates a mailimap_fetch_att structure to request
315 a part of a section of a message without marking it as read
316*/
317
318struct mailimap_fetch_att *
319mailimap_fetch_att_new_body_peek_section_partial(struct mailimap_section * section,
320 uint32_t offset, uint32_t size);
321
322/*
323 this function creates a mailimap_fetch_type structure to request
324 (FLAGS INTERNALDATE RFC822.SIZE ENVELOPE) of a message
325*/
326
327struct mailimap_fetch_type *
328mailimap_fetch_type_new_all(void);
329
330/*
331 this function creates a mailimap_fetch_type structure to request
332 (FLAGS INTERNALDATE RFC822.SIZE ENVELOPE BODY)
333*/
334
335struct mailimap_fetch_type *
336mailimap_fetch_type_new_full(void);
337
338/*
339 this function creates a mailimap_fetch_type structure to request
340 (FLAGS INTERNALDATE RFC822.SIZE)
341*/
342
343struct mailimap_fetch_type *
344mailimap_fetch_type_new_fast(void);
345
346/*
347 this function creates a mailimap_fetch_type structure to request
348 the given fetch attribute
349*/
350
351struct mailimap_fetch_type *
352mailimap_fetch_type_new_fetch_att(struct mailimap_fetch_att * fetch_att);
353
354/*
355 this function creates a mailimap_fetch_type structure to request
356 the list of fetch attributes
357*/
358
359struct mailimap_fetch_type *
360mailimap_fetch_type_new_fetch_att_list(clist * fetch_att_list);
361
362/*
363 this function creates a mailimap_fetch_type structure
364*/
365
366struct mailimap_fetch_type *
367mailimap_fetch_type_new_fetch_att_list_empty(void);
368
369/*
370 this function adds a given fetch attribute to the mailimap_fetch
371 structure
372
373 @return MAILIMAP_NO_ERROR will be returned on success,
374 other code will be returned otherwise
375*/
376
377int
378mailimap_fetch_type_new_fetch_att_list_add(struct mailimap_fetch_type *
379 fetch_type,
380 struct mailimap_fetch_att *
381 fetch_att);
382
383/*
384 this function creates a store attribute to set the given flags
385*/
386
387struct mailimap_store_att_flags *
388mailimap_store_att_flags_new_set_flags(struct mailimap_flag_list * flags);
389
390/*
391 this function creates a store attribute to silently set the given flags
392*/
393
394struct mailimap_store_att_flags *
395mailimap_store_att_flags_new_set_flags_silent(struct mailimap_flag_list *
396 flags);
397
398/*
399 this function creates a store attribute to add the given flags
400*/
401
402struct mailimap_store_att_flags *
403mailimap_store_att_flags_new_add_flags(struct mailimap_flag_list * flags);
404
405/*
406 this function creates a store attribute to add silently the given flags
407*/
408
409struct mailimap_store_att_flags *
410mailimap_store_att_flags_new_add_flags_silent(struct mailimap_flag_list *
411 flags);
412
413/*
414 this function creates a store attribute to remove the given flags
415*/
416
417struct mailimap_store_att_flags *
418mailimap_store_att_flags_new_remove_flags(struct mailimap_flag_list * flags);
419
420/*
421 this function creates a store attribute to remove silently the given flags
422*/
423
424struct mailimap_store_att_flags *
425mailimap_store_att_flags_new_remove_flags_silent(struct mailimap_flag_list *
426 flags);
427
428
429/*
430 this function creates a condition structure to match all messages
431*/
432
433struct mailimap_search_key *
434mailimap_search_key_new_all(void);
435
436/*
437 this function creates a condition structure to match messages with Bcc field
438
439 @param bcc this is the content of Bcc to match, it should be allocated
440 with malloc()
441*/
442
443struct mailimap_search_key *
444mailimap_search_key_new_bcc(char * sk_bcc);
445
446/*
447 this function creates a condition structure to match messages with
448 internal date
449*/
450
451struct mailimap_search_key *
452mailimap_search_key_new_before(struct mailimap_date * sk_before);
453
454/*
455 this function creates a condition structure to match messages with
456 message content
457
458 @param body this is the content of the message to match, it should
459 be allocated with malloc()
460*/
461
462struct mailimap_search_key *
463mailimap_search_key_new_body(char * sk_body);
464
465/*
466 this function creates a condition structure to match messages with
467 Cc field
468
469
470 @param cc this is the content of Cc to match, it should be allocated
471 with malloc()
472*/
473
474struct mailimap_search_key *
475mailimap_search_key_new_cc(char * sk_cc);
476
477/*
478 this function creates a condition structure to match messages with
479 From field
480
481 @param from this is the content of From to match, it should be allocated
482 with malloc()
483*/
484
485struct mailimap_search_key *
486mailimap_search_key_new_from(char * sk_from);
487
488/*
489 this function creates a condition structure to match messages with
490 a flag given by keyword
491*/
492
493struct mailimap_search_key *
494mailimap_search_key_new_keyword(char * sk_keyword);
495
496/*
497 this function creates a condition structure to match messages with
498 internal date
499*/
500
501struct mailimap_search_key *
502mailimap_search_key_new_on(struct mailimap_date * sk_on);
503
504/*
505 this function creates a condition structure to match messages with
506 internal date
507*/
508
509struct mailimap_search_key *
510mailimap_search_key_new_since(struct mailimap_date * sk_since);
511
512/*
513 this function creates a condition structure to match messages with
514 Subject field
515
516 @param subject this is the content of Subject to match, it should
517 be allocated with malloc()
518*/
519
520struct mailimap_search_key *
521mailimap_search_key_new_subject(char * sk_subject);
522
523/*
524 this function creates a condition structure to match messages with
525 message text part
526
527 @param text this is the message text to match, it should
528 be allocated with malloc()
529*/
530
531struct mailimap_search_key *
532mailimap_search_key_new_text(char * sk_text);
533
534/*
535 this function creates a condition structure to match messages with
536 To field
537
538 @param to this is the content of To to match, it should be allocated
539 with malloc()
540*/
541
542struct mailimap_search_key *
543mailimap_search_key_new_to(char * sk_to);
544
545/*
546 this function creates a condition structure to match messages with
547 no a flag given by unkeyword
548*/
549
550struct mailimap_search_key *
551mailimap_search_key_new_unkeyword(char * sk_unkeyword);
552
553/*
554 this function creates a condition structure to match messages with
555 the given field
556
557 @param header_name this is the name of the field to match, it
558 should be allocated with malloc()
559
560 @param header_value this is the content, it should be allocated
561 with malloc()
562*/
563
564struct mailimap_search_key *
565mailimap_search_key_new_header(char * sk_header_name, char * sk_header_value);
566
567
568/*
569 this function creates a condition structure to match messages with size
570*/
571
572struct mailimap_search_key *
573mailimap_search_key_new_larger(uint32_t sk_larger);
574
575/*
576 this function creates a condition structure to match messages that
577 do not match the given condition
578*/
579
580struct mailimap_search_key *
581mailimap_search_key_new_not(struct mailimap_search_key * sk_not);
582
583/*
584 this function creates a condition structure to match messages that
585 match one of the given conditions
586*/
587
588struct mailimap_search_key *
589mailimap_search_key_new_or(struct mailimap_search_key * sk_or1,
590 struct mailimap_search_key * sk_or2);
591
592/*
593 this function creates a condition structure to match messages
594 with Date field
595*/
596
597struct mailimap_search_key *
598mailimap_search_key_new_sentbefore(struct mailimap_date * sk_sentbefore);
599
600/*
601 this function creates a condition structure to match messages
602 with Date field
603*/
604
605struct mailimap_search_key *
606mailimap_search_key_new_senton(struct mailimap_date * sk_senton);
607
608/*
609 this function creates a condition structure to match messages
610 with Date field
611*/
612
613struct mailimap_search_key *
614mailimap_search_key_new_sentsince(struct mailimap_date * sk_sentsince);
615
616/*
617 this function creates a condition structure to match messages with size
618*/
619
620struct mailimap_search_key *
621mailimap_search_key_new_smaller(uint32_t sk_smaller);
622
623/*
624 this function creates a condition structure to match messages with unique
625 identifier
626*/
627
628struct mailimap_search_key *
629mailimap_search_key_new_uid(struct mailimap_set * sk_uid);
630
631/*
632 this function creates a condition structure to match messages with number
633 or unique identifier (depending whether SEARCH or UID SEARCH is used)
634*/
635
636struct mailimap_search_key *
637mailimap_search_key_new_set(struct mailimap_set * sk_set);
638
639/*
640 this function creates a condition structure to match messages that match
641 all the conditions given in the list
642*/
643
644struct mailimap_search_key *
645mailimap_search_key_new_multiple(clist * sk_multiple);
646
647
648/*
649 same as previous but the list is empty
650*/
651
652struct mailimap_search_key *
653mailimap_search_key_new_multiple_empty(void);
654
655/*
656 this function adds a condition to the condition list
657
658 @return MAILIMAP_NO_ERROR will be returned on success,
659 other code will be returned otherwise
660*/
661
662int
663mailimap_search_key_multiple_add(struct mailimap_search_key * keys,
664 struct mailimap_search_key * key_item);
665
666
667/*
668 this function creates an empty list of flags
669*/
670
671struct mailimap_flag_list *
672mailimap_flag_list_new_empty(void);
673
674/*
675 this function adds a flag to the list of flags
676
677 @return MAILIMAP_NO_ERROR will be returned on success,
678 other code will be returned otherwise
679*/
680
681int mailimap_flag_list_add(struct mailimap_flag_list * flag_list,
682 struct mailimap_flag * f);
683
684/*
685 this function creates a \Answered flag
686*/
687
688struct mailimap_flag * mailimap_flag_new_answered(void);
689
690/*
691 this function creates a \Flagged flag
692*/
693
694struct mailimap_flag * mailimap_flag_new_flagged(void);
695
696/*
697 this function creates a \Deleted flag
698*/
699
700struct mailimap_flag * mailimap_flag_new_deleted(void);
701
702/*
703 this function creates a \Seen flag
704*/
705
706struct mailimap_flag * mailimap_flag_new_seen(void);
707
708/*
709 this function creates a \Draft flag
710*/
711
712struct mailimap_flag * mailimap_flag_new_draft(void);
713
714/*
715 this function creates a keyword flag
716
717 @param flag_keyword this should be allocated with malloc()
718*/
719
720struct mailimap_flag * mailimap_flag_new_flag_keyword(char * flag_keyword);
721
722
723/*
724 this function creates an extension flag
725
726 @param flag_extension this should be allocated with malloc()
727*/
728
729struct mailimap_flag * mailimap_flag_new_flag_extension(char * flag_extension);
730
731/*
732 this function creates an empty list of status attributes
733*/
734
735struct mailimap_status_att_list * mailimap_status_att_list_new_empty(void);
736
737/*
738 this function adds status attributes to the list
739
740 @return MAILIMAP_NO_ERROR will be returned on success,
741 other code will be returned otherwise
742*/
743
744int
745mailimap_status_att_list_add(struct mailimap_status_att_list * sa_list,
746 int status_att);
747
748/* return mailimap_section_part from a given mailimap_body */
749
750int mailimap_get_section_part_from_body(struct mailimap_body * root_part,
751 struct mailimap_body * part,
752 struct mailimap_section_part ** result);
753
754#ifdef __cplusplus
755}
756#endif
757
758#endif