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: mailimap_types_helper.c,v 1.15 2010/09/15 16:26:12 hoa Exp $
34  */
35 
36 #ifdef HAVE_CONFIG_H
37 #	include <config.h>
38 #endif
39 
40 #include "mailimap_types.h"
41 #include "mail.h"
42 
43 #include <stdlib.h>
44 
45 /* ************************************************************************* */
46 /* ************************************************************************* */
47 /* ************************************************************************* */
48 /* ************************************************************************* */
49 /* ************************************************************************* */
50 /* ************************************************************************* */
51 
52 /* in helper */
53 
54 
55 
56 
57 LIBETPAN_EXPORT
mailimap_set_item_new_single(uint32_t indx)58 struct mailimap_set_item * mailimap_set_item_new_single(uint32_t indx)
59 {
60   return mailimap_set_item_new(indx, indx);
61 }
62 
63 LIBETPAN_EXPORT
64 struct mailimap_set *
mailimap_set_new_single_item(struct mailimap_set_item * item)65 mailimap_set_new_single_item(struct mailimap_set_item * item)
66 {
67   struct mailimap_set * set;
68   clist * list;
69   int r;
70 
71   list = clist_new();
72   if (list == NULL)
73     return NULL;
74 
75   r = clist_append(list, item);
76   if (r < 0) {
77     clist_free(list);
78     return NULL;
79   }
80 
81   set = mailimap_set_new(list);
82   if (set == NULL) {
83     clist_free(list);
84     return NULL;
85   }
86 
87   return set;
88 }
89 
90 LIBETPAN_EXPORT
mailimap_set_new_interval(uint32_t first,uint32_t last)91 struct mailimap_set * mailimap_set_new_interval(uint32_t first, uint32_t last)
92 {
93   struct mailimap_set_item * item;
94   struct mailimap_set * set;
95 
96   item = mailimap_set_item_new(first, last);
97   if (item == NULL)
98     return NULL;
99 
100   set = mailimap_set_new_single_item(item);
101   if (set == NULL) {
102     mailimap_set_item_free(item);
103     return NULL;
104   }
105 
106   return set;
107 }
108 
109 LIBETPAN_EXPORT
mailimap_set_new_single(uint32_t indx)110 struct mailimap_set * mailimap_set_new_single(uint32_t indx)
111 {
112   return mailimap_set_new_interval(indx, indx);
113 }
114 
115 
116 LIBETPAN_EXPORT
mailimap_set_new_empty(void)117 struct mailimap_set * mailimap_set_new_empty(void)
118 {
119   clist * list;
120 
121   list = clist_new();
122   if (list == NULL)
123     return NULL;
124 
125   return mailimap_set_new(list);
126 }
127 
128 LIBETPAN_EXPORT
mailimap_set_add(struct mailimap_set * set,struct mailimap_set_item * set_item)129 int mailimap_set_add(struct mailimap_set * set,
130                      struct mailimap_set_item * set_item)
131 {
132   int r;
133 
134   r = clist_append(set->set_list, set_item);
135   if (r < 0)
136     return MAILIMAP_ERROR_MEMORY;
137 
138   return MAILIMAP_NO_ERROR;
139 }
140 
141 LIBETPAN_EXPORT
mailimap_set_add_interval(struct mailimap_set * set,uint32_t first,uint32_t last)142 int mailimap_set_add_interval(struct mailimap_set * set,
143 			      uint32_t first, uint32_t last)
144 {
145   struct mailimap_set_item * item;
146   int r;
147 
148   item = mailimap_set_item_new(first, last);
149   if (item == NULL)
150     return MAILIMAP_ERROR_MEMORY;
151 
152   r = mailimap_set_add(set, item);
153   if (r != MAILIMAP_NO_ERROR) {
154     mailimap_set_item_free(item);
155     return r;
156   }
157   else
158     return MAILIMAP_NO_ERROR;
159 }
160 
161 LIBETPAN_EXPORT
mailimap_set_add_single(struct mailimap_set * set,uint32_t indx)162 int mailimap_set_add_single(struct mailimap_set * set,
163            		    uint32_t indx)
164 {
165   return mailimap_set_add_interval(set, indx, indx);
166 }
167 
168 /* CHECK */
169 /* no args */
170 
171 /* CLOSE */
172 /* no args */
173 
174 /* EXPUNGE */
175 /* no args */
176 
177 /* COPY */
178 /* set and gchar */
179 
180 /* FETCH */
181 /* set and gchar fetch_type */
182 
183 
184 
185 /* section */
186 
187 static struct mailimap_section *
mailimap_section_new_msgtext(struct mailimap_section_msgtext * msgtext)188 mailimap_section_new_msgtext(struct mailimap_section_msgtext * msgtext)
189 {
190   struct mailimap_section_spec * spec;
191   struct mailimap_section * section;
192 
193   spec = mailimap_section_spec_new(MAILIMAP_SECTION_SPEC_SECTION_MSGTEXT,
194 				   msgtext, NULL, NULL);
195   if (spec == NULL)
196     return NULL;
197 
198   section = mailimap_section_new(spec);
199   if (section == NULL) {
200     /* detach section_msgtext so that it will not be freed */
201     spec->sec_data.sec_msgtext = NULL;
202     mailimap_section_spec_free(spec);
203     return NULL;
204   }
205 
206   return section;
207 }
208 
209 static struct mailimap_section *
mailimap_section_new_part_msgtext(struct mailimap_section_part * part,struct mailimap_section_msgtext * msgtext)210 mailimap_section_new_part_msgtext(struct mailimap_section_part * part,
211     struct mailimap_section_msgtext * msgtext)
212 {
213   struct mailimap_section_spec * spec;
214   struct mailimap_section * section;
215   struct mailimap_section_text * text;
216 
217   text = mailimap_section_text_new(MAILIMAP_SECTION_TEXT_SECTION_MSGTEXT,
218       msgtext);
219   if (text == NULL)
220     return NULL;
221 
222   spec = mailimap_section_spec_new(MAILIMAP_SECTION_SPEC_SECTION_PART,
223 				   NULL, part, text);
224   if (spec == NULL) {
225     /* detach section_msgtext so that it will not be freed */
226     text->sec_msgtext = NULL;
227     mailimap_section_text_free(text);
228     return NULL;
229   }
230 
231   section = mailimap_section_new(spec);
232   if (section == NULL) {
233     /* detach section_msgtext so that it will not be freed */
234     text->sec_msgtext = NULL;
235     mailimap_section_spec_free(spec);
236     return NULL;
237   }
238 
239   return section;
240 }
241 
242 /*
243 HEADER
244 HEADER.FIELDS fields
245 HEADER.FIELDS.NOT fields
246 TEXT
247 */
248 
249 LIBETPAN_EXPORT
mailimap_section_new_header(void)250 struct mailimap_section * mailimap_section_new_header(void)
251 {
252   struct mailimap_section_msgtext * msgtext;
253   struct mailimap_section * section;
254 
255   msgtext = mailimap_section_msgtext_new(MAILIMAP_SECTION_MSGTEXT_HEADER,
256 					 NULL);
257   if (msgtext == NULL)
258     return NULL;
259 
260   section = mailimap_section_new_msgtext(msgtext);
261   if (section == NULL) {
262     mailimap_section_msgtext_free(msgtext);
263     return NULL;
264   }
265 
266   return section;
267 }
268 
269 LIBETPAN_EXPORT
270 struct mailimap_section *
mailimap_section_new_header_fields(struct mailimap_header_list * header_list)271 mailimap_section_new_header_fields(struct mailimap_header_list * header_list)
272 {
273   struct mailimap_section * section;
274   struct mailimap_section_msgtext * msgtext;
275 
276   msgtext =
277     mailimap_section_msgtext_new(MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS,
278 				 header_list);
279   if (msgtext == NULL)
280     return NULL;
281 
282   section = mailimap_section_new_msgtext(msgtext);
283   if (section == NULL) {
284     /* detach header_list so that it will not be freed */
285     msgtext->sec_header_list = NULL;
286     mailimap_section_msgtext_free(msgtext);
287     return NULL;
288   }
289 
290   return section;
291 }
292 
293 LIBETPAN_EXPORT
294 struct mailimap_section *
mailimap_section_new_header_fields_not(struct mailimap_header_list * header_list)295 mailimap_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 
317 LIBETPAN_EXPORT
mailimap_section_new_text(void)318 struct mailimap_section * mailimap_section_new_text(void)
319 {
320   struct mailimap_section * section;
321   struct mailimap_section_msgtext * msgtext;
322 
323   msgtext = mailimap_section_msgtext_new(MAILIMAP_SECTION_MSGTEXT_TEXT, NULL);
324   if (msgtext == NULL)
325     return NULL;
326 
327   section = mailimap_section_new_msgtext(msgtext);
328   if (section == NULL) {
329     mailimap_section_msgtext_free(msgtext);
330     return NULL;
331   }
332 
333   return section;
334 }
335 
336 /*
337 section-part
338 section-part . MIME
339 section-part . HEADER
340 section-part . HEADER.FIELDS fields
341 section-part . HEADER.FIELDS.NOT fields
342 section-part . TEXT
343 */
344 
345 LIBETPAN_EXPORT
346 struct mailimap_section *
mailimap_section_new_part(struct mailimap_section_part * part)347 mailimap_section_new_part(struct mailimap_section_part * part)
348 {
349   struct mailimap_section_spec * spec;
350   struct mailimap_section * section;
351 
352   spec = mailimap_section_spec_new(MAILIMAP_SECTION_SPEC_SECTION_PART,
353 				   NULL, part, NULL);
354   if (spec == NULL)
355     return NULL;
356 
357   section = mailimap_section_new(spec);
358   if (section == NULL) {
359     /* detach section_part so that it will not be freed */
360     spec->sec_data.sec_part = NULL;
361     mailimap_section_spec_free(spec);
362     return NULL;
363   }
364 
365   return section;
366 }
367 
368 LIBETPAN_EXPORT
369 struct mailimap_section *
mailimap_section_new_part_mime(struct mailimap_section_part * part)370 mailimap_section_new_part_mime(struct mailimap_section_part * part)
371 {
372   struct mailimap_section_spec * spec;
373   struct mailimap_section * section;
374   struct mailimap_section_text * text;
375 
376   text = mailimap_section_text_new(MAILIMAP_SECTION_TEXT_MIME, NULL);
377   if (text == NULL)
378     return NULL;
379 
380   spec = mailimap_section_spec_new(MAILIMAP_SECTION_SPEC_SECTION_PART,
381 				   NULL, part, text);
382   if (spec == NULL) {
383     mailimap_section_text_free(text);
384     return NULL;
385   }
386 
387   section = mailimap_section_new(spec);
388   if (section == NULL) {
389     /* detach section_part so that it will not be freed */
390     spec->sec_data.sec_part = NULL;
391     mailimap_section_spec_free(spec);
392     return NULL;
393   }
394 
395   return section;
396 }
397 
398 LIBETPAN_EXPORT
399 struct mailimap_section *
mailimap_section_new_part_header(struct mailimap_section_part * part)400 mailimap_section_new_part_header(struct mailimap_section_part * part)
401 {
402   struct mailimap_section_msgtext * msgtext;
403   struct mailimap_section * section;
404 
405   msgtext = mailimap_section_msgtext_new(MAILIMAP_SECTION_MSGTEXT_HEADER,
406 					 NULL);
407   if (msgtext == NULL)
408     return NULL;
409 
410   section = mailimap_section_new_part_msgtext(part, msgtext);
411   if (section == NULL) {
412     mailimap_section_msgtext_free(msgtext);
413     return NULL;
414   }
415 
416   return section;
417 }
418 
419 LIBETPAN_EXPORT
420 struct mailimap_section *
mailimap_section_new_part_header_fields(struct mailimap_section_part * part,struct mailimap_header_list * header_list)421 mailimap_section_new_part_header_fields(struct mailimap_section_part *
422 					part,
423 					struct mailimap_header_list *
424 					header_list)
425 {
426   struct mailimap_section * section;
427   struct mailimap_section_msgtext * msgtext;
428 
429   msgtext =
430     mailimap_section_msgtext_new(MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS,
431 				 header_list);
432   if (msgtext == NULL)
433     return NULL;
434 
435   section = mailimap_section_new_part_msgtext(part, msgtext);
436   if (section == NULL) {
437     /* detach header_list so that it will not be freed */
438     msgtext->sec_header_list = NULL;
439     mailimap_section_msgtext_free(msgtext);
440     return NULL;
441   }
442 
443   return section;
444 }
445 
446 LIBETPAN_EXPORT
447 struct mailimap_section *
mailimap_section_new_part_header_fields_not(struct mailimap_section_part * part,struct mailimap_header_list * header_list)448 mailimap_section_new_part_header_fields_not(struct mailimap_section_part
449 					    * part,
450 					    struct mailimap_header_list
451 					    * header_list)
452 {
453   struct mailimap_section * section;
454   struct mailimap_section_msgtext * msgtext;
455 
456   msgtext =
457     mailimap_section_msgtext_new(MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS_NOT,
458 				 header_list);
459   if (msgtext == NULL)
460     return NULL;
461 
462   section = mailimap_section_new_part_msgtext(part, msgtext);
463   if (section == NULL) {
464     /* detach header_list so that it will not be freed */
465     msgtext->sec_header_list = NULL;
466     mailimap_section_msgtext_free(msgtext);
467     return NULL;
468   }
469 
470   return section;
471 }
472 
473 LIBETPAN_EXPORT
474 struct mailimap_section *
mailimap_section_new_part_text(struct mailimap_section_part * part)475 mailimap_section_new_part_text(struct mailimap_section_part * part)
476 {
477   struct mailimap_section * section;
478   struct mailimap_section_msgtext * msgtext;
479 
480   msgtext = mailimap_section_msgtext_new(MAILIMAP_SECTION_MSGTEXT_TEXT, NULL);
481   if (msgtext == NULL)
482     return NULL;
483 
484   section = mailimap_section_new_part_msgtext(part, msgtext);
485   if (section == NULL) {
486     mailimap_section_msgtext_free(msgtext);
487     return NULL;
488   }
489 
490   return section;
491 }
492 
493 /* end of section */
494 
495 
496 
497 
498 
499 
500 LIBETPAN_EXPORT
501 struct mailimap_fetch_att *
mailimap_fetch_att_new_envelope(void)502 mailimap_fetch_att_new_envelope(void)
503 {
504   return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_ENVELOPE, NULL, 0, 0, NULL);
505 }
506 
507 LIBETPAN_EXPORT
508 struct mailimap_fetch_att *
mailimap_fetch_att_new_flags(void)509 mailimap_fetch_att_new_flags(void)
510 {
511   return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_FLAGS, NULL, 0, 0, NULL);
512 }
513 
514 LIBETPAN_EXPORT
515 struct mailimap_fetch_att *
mailimap_fetch_att_new_internaldate(void)516 mailimap_fetch_att_new_internaldate(void)
517 {
518   return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_INTERNALDATE, NULL, 0, 0, NULL);
519 }
520 
521 LIBETPAN_EXPORT
522 struct mailimap_fetch_att *
mailimap_fetch_att_new_rfc822(void)523 mailimap_fetch_att_new_rfc822(void)
524 {
525   return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_RFC822, NULL, 0, 0, NULL);
526 }
527 
528 LIBETPAN_EXPORT
529 struct mailimap_fetch_att *
mailimap_fetch_att_new_rfc822_header(void)530 mailimap_fetch_att_new_rfc822_header(void)
531 {
532   return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_RFC822_HEADER, NULL, 0, 0, NULL);
533 }
534 
535 LIBETPAN_EXPORT
536 struct mailimap_fetch_att *
mailimap_fetch_att_new_rfc822_size(void)537 mailimap_fetch_att_new_rfc822_size(void)
538 {
539   return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_RFC822_SIZE, NULL, 0, 0, NULL);
540 }
541 
542 LIBETPAN_EXPORT
543 struct mailimap_fetch_att *
mailimap_fetch_att_new_rfc822_text(void)544 mailimap_fetch_att_new_rfc822_text(void)
545 {
546   return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_RFC822_TEXT, NULL, 0, 0, NULL);
547 }
548 
549 LIBETPAN_EXPORT
550 struct mailimap_fetch_att *
mailimap_fetch_att_new_body(void)551 mailimap_fetch_att_new_body(void)
552 {
553   return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_BODY, NULL, 0, 0, NULL);
554 }
555 
556 LIBETPAN_EXPORT
557 struct mailimap_fetch_att *
mailimap_fetch_att_new_bodystructure(void)558 mailimap_fetch_att_new_bodystructure(void)
559 {
560   return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_BODYSTRUCTURE, NULL, 0, 0, NULL);
561 }
562 
563 LIBETPAN_EXPORT
564 struct mailimap_fetch_att *
mailimap_fetch_att_new_uid(void)565 mailimap_fetch_att_new_uid(void)
566 {
567   return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_UID, NULL, 0, 0, NULL);
568 }
569 
570 LIBETPAN_EXPORT
571 struct mailimap_fetch_att *
mailimap_fetch_att_new_body_section(struct mailimap_section * section)572 mailimap_fetch_att_new_body_section(struct mailimap_section * section)
573 {
574   return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_BODY_SECTION, section, 0, 0, NULL);
575 }
576 
577 LIBETPAN_EXPORT
578 struct mailimap_fetch_att *
mailimap_fetch_att_new_body_peek_section(struct mailimap_section * section)579 mailimap_fetch_att_new_body_peek_section(struct mailimap_section * section)
580 {
581   return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_BODY_PEEK_SECTION, section, 0, 0, NULL);
582 }
583 
584 LIBETPAN_EXPORT
585 struct mailimap_fetch_att *
mailimap_fetch_att_new_body_section_partial(struct mailimap_section * section,uint32_t offset,uint32_t size)586 mailimap_fetch_att_new_body_section_partial(struct mailimap_section * section,
587 					    uint32_t offset, uint32_t size)
588 {
589   return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_BODY_SECTION, section,
590 				offset, size, NULL);
591 }
592 
593 LIBETPAN_EXPORT
594 struct mailimap_fetch_att *
mailimap_fetch_att_new_body_peek_section_partial(struct mailimap_section * section,uint32_t offset,uint32_t size)595 mailimap_fetch_att_new_body_peek_section_partial(struct mailimap_section * section,
596 						 uint32_t offset, uint32_t size)
597 {
598   return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_BODY_PEEK_SECTION, section,
599 				offset, size, NULL);
600 }
601 
602 LIBETPAN_EXPORT
603 struct mailimap_fetch_att *
mailimap_fetch_att_new_extension(char * ext_keyword)604 mailimap_fetch_att_new_extension(char * ext_keyword)
605 {
606   return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_EXTENSION, NULL, 0, 0, ext_keyword);
607 }
608 
609 
610 LIBETPAN_EXPORT
611 struct mailimap_fetch_type *
mailimap_fetch_type_new_all(void)612 mailimap_fetch_type_new_all(void)
613 {
614   return mailimap_fetch_type_new(MAILIMAP_FETCH_TYPE_ALL, NULL, NULL);
615 }
616 
617 LIBETPAN_EXPORT
618 struct mailimap_fetch_type *
mailimap_fetch_type_new_full(void)619 mailimap_fetch_type_new_full(void)
620 {
621   return mailimap_fetch_type_new(MAILIMAP_FETCH_TYPE_FULL, NULL, NULL);
622 }
623 
624 LIBETPAN_EXPORT
625 struct mailimap_fetch_type *
mailimap_fetch_type_new_fast(void)626 mailimap_fetch_type_new_fast(void)
627 {
628   return mailimap_fetch_type_new(MAILIMAP_FETCH_TYPE_FAST, NULL, NULL);
629 }
630 
631 LIBETPAN_EXPORT
632 struct mailimap_fetch_type *
mailimap_fetch_type_new_fetch_att(struct mailimap_fetch_att * fetch_att)633 mailimap_fetch_type_new_fetch_att(struct mailimap_fetch_att * fetch_att)
634 {
635   return mailimap_fetch_type_new(MAILIMAP_FETCH_TYPE_FETCH_ATT, fetch_att, NULL);
636 }
637 
638 LIBETPAN_EXPORT
639 struct mailimap_fetch_type *
mailimap_fetch_type_new_fetch_att_list(clist * fetch_att_list)640 mailimap_fetch_type_new_fetch_att_list(clist * fetch_att_list)
641 {
642   return mailimap_fetch_type_new(MAILIMAP_FETCH_TYPE_FETCH_ATT_LIST,
643 				 NULL, fetch_att_list);
644 }
645 
646 LIBETPAN_EXPORT
647 struct mailimap_fetch_type *
mailimap_fetch_type_new_fetch_att_list_empty(void)648 mailimap_fetch_type_new_fetch_att_list_empty(void)
649 {
650   clist * list;
651 
652   list = clist_new();
653   if (list == NULL)
654     return NULL;
655 
656   return mailimap_fetch_type_new(MAILIMAP_FETCH_TYPE_FETCH_ATT_LIST,
657 				 NULL, list);
658 }
659 
660 LIBETPAN_EXPORT
661 int
mailimap_fetch_type_new_fetch_att_list_add(struct mailimap_fetch_type * fetch_type,struct mailimap_fetch_att * fetch_att)662 mailimap_fetch_type_new_fetch_att_list_add(struct mailimap_fetch_type *
663     fetch_type,
664     struct mailimap_fetch_att * fetch_att)
665 {
666   int r;
667 
668   r = clist_append(fetch_type->ft_data.ft_fetch_att_list, fetch_att);
669   if (r < 0)
670     return MAILIMAP_ERROR_MEMORY;
671 
672   return MAILIMAP_NO_ERROR;
673 }
674 
675 
676 
677 /* STORE */
678 /* set and store_att_flags */
679 
680 LIBETPAN_EXPORT
681 struct mailimap_store_att_flags *
mailimap_store_att_flags_new_set_flags(struct mailimap_flag_list * flags)682 mailimap_store_att_flags_new_set_flags(struct mailimap_flag_list * flags)
683 {
684   return mailimap_store_att_flags_new(0, FALSE, flags);
685 }
686 
687 LIBETPAN_EXPORT
688 struct mailimap_store_att_flags *
mailimap_store_att_flags_new_set_flags_silent(struct mailimap_flag_list * flags)689 mailimap_store_att_flags_new_set_flags_silent(struct mailimap_flag_list *
690 					      flags)
691 {
692   return mailimap_store_att_flags_new(0, TRUE, flags);
693 }
694 
695 LIBETPAN_EXPORT
696 struct mailimap_store_att_flags *
mailimap_store_att_flags_new_add_flags(struct mailimap_flag_list * flags)697 mailimap_store_att_flags_new_add_flags(struct mailimap_flag_list * flags)
698 {
699   return mailimap_store_att_flags_new(1, FALSE, flags);
700 }
701 
702 LIBETPAN_EXPORT
703 struct mailimap_store_att_flags *
mailimap_store_att_flags_new_add_flags_silent(struct mailimap_flag_list * flags)704 mailimap_store_att_flags_new_add_flags_silent(struct mailimap_flag_list *
705 					      flags)
706 {
707   return mailimap_store_att_flags_new(1, TRUE, flags);
708 }
709 
710 LIBETPAN_EXPORT
711 struct mailimap_store_att_flags *
mailimap_store_att_flags_new_remove_flags(struct mailimap_flag_list * flags)712 mailimap_store_att_flags_new_remove_flags(struct mailimap_flag_list * flags)
713 {
714   return mailimap_store_att_flags_new(-1, FALSE, flags);
715 }
716 
717 LIBETPAN_EXPORT
718 struct mailimap_store_att_flags *
mailimap_store_att_flags_new_remove_flags_silent(struct mailimap_flag_list * flags)719 mailimap_store_att_flags_new_remove_flags_silent(struct mailimap_flag_list *
720 						 flags)
721 {
722   return mailimap_store_att_flags_new(-1, TRUE, flags);
723 }
724 
725 /* SEARCH */
726 /* date search-key set */
727 
728 /*
729   return mailimap_search_key_new(type, bcc, before,
730 				 body, cc, from, keyword, on, since,
731 				 subject, text, to, unkeyword, header_name,
732 				 header_value, larger, not,
733 				 or1, or2, sentbefore, senton, sentsince,
734 				 smaller, uid, set, multiple);
735 */
736 
737 LIBETPAN_EXPORT
738 struct mailimap_search_key *
mailimap_search_key_new_all(void)739 mailimap_search_key_new_all(void)
740 {
741   return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_ALL, NULL, NULL,
742 				 NULL, NULL, NULL, NULL, NULL, NULL,
743 				 NULL, NULL, NULL, NULL, NULL,
744 				 NULL, 0, NULL,
745 				 NULL, NULL, NULL, NULL, NULL,
746 				 0, NULL, NULL, NULL);
747 }
748 
749 LIBETPAN_EXPORT
750 struct mailimap_search_key *
mailimap_search_key_new_bcc(char * sk_bcc)751 mailimap_search_key_new_bcc(char * sk_bcc)
752 {
753   return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_BCC, sk_bcc, NULL,
754 				 NULL, NULL, NULL, NULL, NULL, NULL,
755 				 NULL, NULL, NULL, NULL, NULL,
756 				 NULL, 0, NULL,
757 				 NULL, NULL, NULL, NULL, NULL,
758 				 0, NULL, NULL, NULL);
759 }
760 
761 LIBETPAN_EXPORT
762 struct mailimap_search_key *
mailimap_search_key_new_before(struct mailimap_date * sk_before)763 mailimap_search_key_new_before(struct mailimap_date * sk_before)
764 {
765   return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_BEFORE, NULL, sk_before,
766 				 NULL, NULL, NULL, NULL, NULL, NULL,
767 				 NULL, NULL, NULL, NULL, NULL,
768 				 NULL, 0, NULL,
769 				 NULL, NULL, NULL, NULL, NULL,
770 				 0, NULL, NULL, NULL);
771 }
772 
773 LIBETPAN_EXPORT
774 struct mailimap_search_key *
mailimap_search_key_new_body(char * sk_body)775 mailimap_search_key_new_body(char * sk_body)
776 {
777   return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_BODY, NULL, NULL,
778 				 sk_body, NULL, NULL, NULL, NULL, NULL,
779 				 NULL, NULL, NULL, NULL, NULL,
780 				 NULL, 0, NULL,
781 				 NULL, NULL, NULL, NULL, NULL,
782 				 0, NULL, NULL, NULL);
783 }
784 
785 LIBETPAN_EXPORT
786 struct mailimap_search_key *
mailimap_search_key_new_cc(char * sk_cc)787 mailimap_search_key_new_cc(char * sk_cc)
788 {
789   return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_CC, NULL, NULL,
790 				 NULL, sk_cc, NULL, NULL, NULL, NULL,
791 				 NULL, NULL, NULL, NULL, NULL,
792 				 NULL, 0, NULL,
793 				 NULL, NULL, NULL, NULL, NULL,
794 				 0, NULL, NULL, NULL);
795 }
796 
797 LIBETPAN_EXPORT
798 struct mailimap_search_key *
mailimap_search_key_new_from(char * sk_from)799 mailimap_search_key_new_from(char * sk_from)
800 {
801   return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_FROM, NULL, NULL,
802 				 NULL, NULL, sk_from, NULL, NULL, NULL,
803 				 NULL, NULL, NULL, NULL, NULL,
804 				 NULL, 0, NULL,
805 				 NULL, NULL, NULL, NULL, NULL,
806 				 0, NULL, NULL, NULL);
807 }
808 
809 LIBETPAN_EXPORT
810 struct mailimap_search_key *
mailimap_search_key_new_keyword(char * sk_keyword)811 mailimap_search_key_new_keyword(char * sk_keyword)
812 {
813   return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_KEYWORD, NULL, NULL,
814 				 NULL, NULL, NULL, sk_keyword, NULL, NULL,
815 				 NULL, NULL, NULL, NULL, NULL,
816 				 NULL, 0, NULL,
817 				 NULL, NULL, NULL, NULL, NULL,
818 				 0, NULL, NULL, NULL);
819 }
820 
821 LIBETPAN_EXPORT
822 struct mailimap_search_key *
mailimap_search_key_new_on(struct mailimap_date * sk_on)823 mailimap_search_key_new_on(struct mailimap_date * sk_on)
824 {
825   return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_ON, NULL, NULL,
826 				 NULL, NULL, NULL, NULL, sk_on, NULL,
827 				 NULL, NULL, NULL, NULL, NULL,
828 				 NULL, 0, NULL,
829 				 NULL, NULL, NULL, NULL, NULL,
830 				 0, NULL, NULL, NULL);
831 }
832 
833 LIBETPAN_EXPORT
834 struct mailimap_search_key *
mailimap_search_key_new_since(struct mailimap_date * sk_since)835 mailimap_search_key_new_since(struct mailimap_date * sk_since)
836 {
837   return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_SINCE, NULL, NULL,
838 				 NULL, NULL, NULL, NULL, NULL, sk_since,
839 				 NULL, NULL, NULL, NULL, NULL,
840 				 NULL, 0, NULL,
841 				 NULL, NULL, NULL, NULL, NULL,
842 				 0, NULL, NULL, NULL);
843 }
844 
845 LIBETPAN_EXPORT
846 struct mailimap_search_key *
mailimap_search_key_new_subject(char * sk_subject)847 mailimap_search_key_new_subject(char * sk_subject)
848 {
849   return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_SUBJECT, NULL, NULL,
850 				 NULL, NULL, NULL, NULL, NULL, NULL,
851 				 sk_subject, NULL, NULL, NULL, NULL,
852 				 NULL, 0, NULL,
853 				 NULL, NULL, NULL, NULL, NULL,
854 				 0, NULL, NULL, NULL);
855 }
856 
857 LIBETPAN_EXPORT
858 struct mailimap_search_key *
mailimap_search_key_new_text(char * sk_text)859 mailimap_search_key_new_text(char * sk_text)
860 {
861   return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_TEXT, NULL, NULL,
862 				 NULL, NULL, NULL, NULL, NULL, NULL,
863 				 NULL, sk_text, NULL, NULL, NULL,
864 				 NULL, 0, NULL,
865 				 NULL, NULL, NULL, NULL, NULL,
866 				 0, NULL, NULL, NULL);
867 }
868 
869 LIBETPAN_EXPORT
870 struct mailimap_search_key *
mailimap_search_key_new_to(char * sk_to)871 mailimap_search_key_new_to(char * sk_to)
872 {
873   return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_TO, NULL, NULL,
874 				 NULL, NULL, NULL, NULL, NULL, NULL,
875 				 NULL, NULL, sk_to, NULL, NULL,
876 				 NULL, 0, NULL,
877 				 NULL, NULL, NULL, NULL, NULL,
878 				 0, NULL, NULL, NULL);
879 }
880 
881 LIBETPAN_EXPORT
882 struct mailimap_search_key *
mailimap_search_key_new_unkeyword(char * sk_unkeyword)883 mailimap_search_key_new_unkeyword(char * sk_unkeyword)
884 {
885   return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_UNKEYWORD, NULL, NULL,
886 				 NULL, NULL, NULL, NULL, NULL, NULL,
887 				 NULL, NULL, NULL, sk_unkeyword, NULL,
888 				 NULL, 0, NULL,
889 				 NULL, NULL, NULL, NULL, NULL,
890 				 0, NULL, NULL, NULL);
891 }
892 
893 LIBETPAN_EXPORT
894 struct mailimap_search_key *
mailimap_search_key_new_header(char * sk_header_name,char * sk_header_value)895 mailimap_search_key_new_header(char * sk_header_name, char * sk_header_value)
896 {
897   return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_HEADER, NULL, NULL,
898 				 NULL, NULL, NULL, NULL, NULL, NULL,
899 				 NULL, NULL, NULL, NULL, sk_header_name,
900 				 sk_header_value, 0, NULL,
901 				 NULL, NULL, NULL, NULL, NULL,
902 				 0, NULL, NULL, NULL);
903 }
904 
905 LIBETPAN_EXPORT
906 struct mailimap_search_key *
mailimap_search_key_new_larger(uint32_t sk_larger)907 mailimap_search_key_new_larger(uint32_t sk_larger)
908 {
909   return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_LARGER, NULL, NULL,
910 				 NULL, NULL, NULL, NULL, NULL, NULL,
911 				 NULL, NULL, NULL, NULL, NULL,
912 				 NULL, sk_larger, NULL,
913 				 NULL, NULL, NULL, NULL, NULL,
914 				 0, NULL, NULL, NULL);
915 }
916 
917 LIBETPAN_EXPORT
918 struct mailimap_search_key *
mailimap_search_key_new_not(struct mailimap_search_key * sk_not)919 mailimap_search_key_new_not(struct mailimap_search_key * sk_not)
920 {
921   return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_NOT, NULL, NULL,
922 				 NULL, NULL, NULL, NULL, NULL, NULL,
923 				 NULL, NULL, NULL, NULL, NULL,
924 				 NULL, 0, sk_not,
925 				 NULL, NULL, NULL, NULL, NULL,
926 				 0, NULL, NULL, NULL);
927 }
928 
929 LIBETPAN_EXPORT
930 struct mailimap_search_key *
mailimap_search_key_new_or(struct mailimap_search_key * sk_or1,struct mailimap_search_key * sk_or2)931 mailimap_search_key_new_or(struct mailimap_search_key * sk_or1,
932 			   struct mailimap_search_key * sk_or2)
933 {
934   return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_OR, NULL, NULL,
935 				 NULL, NULL, NULL, NULL, NULL, NULL,
936 				 NULL, NULL, NULL, NULL, NULL,
937 				 NULL, 0, NULL,
938 				 sk_or1, sk_or2, NULL, NULL, NULL,
939 				 0, NULL, NULL, NULL);
940 }
941 
942 LIBETPAN_EXPORT
943 struct mailimap_search_key *
mailimap_search_key_new_sentbefore(struct mailimap_date * sk_sentbefore)944 mailimap_search_key_new_sentbefore(struct mailimap_date * sk_sentbefore)
945 {
946   return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_SENTBEFORE, NULL, NULL,
947 				 NULL, NULL, NULL, NULL, NULL, NULL,
948 				 NULL, NULL, NULL, NULL, NULL,
949 				 NULL, 0, NULL,
950 				 NULL, NULL, sk_sentbefore, NULL, NULL,
951 				 0, NULL, NULL, NULL);
952 }
953 
954 LIBETPAN_EXPORT
955 struct mailimap_search_key *
mailimap_search_key_new_senton(struct mailimap_date * sk_senton)956 mailimap_search_key_new_senton(struct mailimap_date * sk_senton)
957 {
958   return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_SENTON, NULL, NULL,
959 				 NULL, NULL, NULL, NULL, NULL, NULL,
960 				 NULL, NULL, NULL, NULL, NULL,
961 				 NULL, 0, NULL,
962 				 NULL, NULL, NULL, sk_senton, NULL,
963 				 0, NULL, NULL, NULL);
964 }
965 
966 LIBETPAN_EXPORT
967 struct mailimap_search_key *
mailimap_search_key_new_sentsince(struct mailimap_date * sk_sentsince)968 mailimap_search_key_new_sentsince(struct mailimap_date * sk_sentsince)
969 {
970   return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_SENTSINCE, NULL, NULL,
971 				 NULL, NULL, NULL, NULL, NULL, NULL,
972 				 NULL, NULL, NULL, NULL, NULL,
973 				 NULL, 0, NULL,
974 				 NULL, NULL, NULL, NULL, sk_sentsince,
975 				 0, NULL, NULL, NULL);
976 }
977 
978 LIBETPAN_EXPORT
979 struct mailimap_search_key *
mailimap_search_key_new_smaller(uint32_t sk_smaller)980 mailimap_search_key_new_smaller(uint32_t sk_smaller)
981 {
982   return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_SMALLER, NULL, NULL,
983 				 NULL, NULL, NULL, NULL, NULL, NULL,
984 				 NULL, NULL, NULL, NULL, NULL,
985 				 NULL, 0, NULL,
986 				 NULL, NULL, NULL, NULL, NULL,
987 				 sk_smaller, NULL, NULL, NULL);
988 }
989 
990 LIBETPAN_EXPORT
991 struct mailimap_search_key *
mailimap_search_key_new_uid(struct mailimap_set * sk_uid)992 mailimap_search_key_new_uid(struct mailimap_set * sk_uid)
993 {
994   return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_UID, NULL, NULL,
995 				 NULL, NULL, NULL, NULL, NULL, NULL,
996 				 NULL, NULL, NULL, NULL, NULL,
997 				 NULL, 0, NULL,
998 				 NULL, NULL, NULL, NULL, NULL,
999 				 0, sk_uid, NULL, NULL);
1000 }
1001 
1002 LIBETPAN_EXPORT
1003 struct mailimap_search_key *
mailimap_search_key_new_set(struct mailimap_set * sk_set)1004 mailimap_search_key_new_set(struct mailimap_set * sk_set)
1005 {
1006   return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_SET, NULL, NULL,
1007 				 NULL, NULL, NULL, NULL, NULL, NULL,
1008 				 NULL, NULL, NULL, NULL, NULL,
1009 				 NULL, 0, NULL,
1010 				 NULL, NULL, NULL, NULL, NULL,
1011 				 0, NULL, sk_set, NULL);
1012 }
1013 
1014 LIBETPAN_EXPORT
1015 struct mailimap_search_key *
mailimap_search_key_new_multiple(clist * sk_multiple)1016 mailimap_search_key_new_multiple(clist * sk_multiple)
1017 {
1018   return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_MULTIPLE, NULL, NULL,
1019 				 NULL, NULL, NULL, NULL, NULL, NULL,
1020 				 NULL, NULL, NULL, NULL, NULL,
1021 				 NULL, 0, NULL,
1022 				 NULL, NULL, NULL, NULL, NULL,
1023 				 0, NULL, NULL, sk_multiple);
1024 }
1025 
1026 LIBETPAN_EXPORT
1027 struct mailimap_search_key *
mailimap_search_key_new_multiple_empty(void)1028 mailimap_search_key_new_multiple_empty(void)
1029 {
1030   clist * list;
1031 
1032   list = clist_new();
1033   if (list == NULL)
1034     return NULL;
1035 
1036   return mailimap_search_key_new_multiple(list);
1037 }
1038 
1039 LIBETPAN_EXPORT
1040 int
mailimap_search_key_multiple_add(struct mailimap_search_key * keys,struct mailimap_search_key * key_item)1041 mailimap_search_key_multiple_add(struct mailimap_search_key * keys,
1042 				 struct mailimap_search_key * key_item)
1043 {
1044   int r;
1045 
1046   r = clist_append(keys->sk_data.sk_multiple, key_item);
1047   if (r < 0)
1048     return MAILIMAP_ERROR_MEMORY;
1049 
1050   return MAILIMAP_NO_ERROR;
1051 }
1052 
1053 
1054 
1055 /* CAPABILITY */
1056 /* no args */
1057 
1058 /* LOGOUT */
1059 /* no args */
1060 
1061 /* NOOP */
1062 /* no args */
1063 
1064 /* APPEND */
1065 /* gchar flag_list date_time gchar */
1066 
1067 LIBETPAN_EXPORT
1068 struct mailimap_flag_list *
mailimap_flag_list_new_empty(void)1069 mailimap_flag_list_new_empty(void)
1070 {
1071   clist * list;
1072 
1073   list = clist_new();
1074   if (list == NULL)
1075     return NULL;
1076 
1077   return mailimap_flag_list_new(list);
1078 }
1079 
1080 LIBETPAN_EXPORT
mailimap_flag_list_add(struct mailimap_flag_list * flag_list,struct mailimap_flag * f)1081 int mailimap_flag_list_add(struct mailimap_flag_list * flag_list,
1082 		struct mailimap_flag * f)
1083 {
1084   int r;
1085 
1086   r = clist_append(flag_list->fl_list, f);
1087   if (r < 0)
1088     return MAILIMAP_ERROR_MEMORY;
1089 
1090   return MAILIMAP_NO_ERROR;
1091 }
1092 
1093 LIBETPAN_EXPORT
mailimap_flag_new_answered(void)1094 struct mailimap_flag * mailimap_flag_new_answered(void)
1095 {
1096   return mailimap_flag_new(MAILIMAP_FLAG_ANSWERED, NULL, NULL);
1097 }
1098 
1099 LIBETPAN_EXPORT
mailimap_flag_new_flagged(void)1100 struct mailimap_flag * mailimap_flag_new_flagged(void)
1101 {
1102   return mailimap_flag_new(MAILIMAP_FLAG_FLAGGED, NULL, NULL);
1103 }
1104 
1105 LIBETPAN_EXPORT
mailimap_flag_new_deleted(void)1106 struct mailimap_flag * mailimap_flag_new_deleted(void)
1107 {
1108   return mailimap_flag_new(MAILIMAP_FLAG_DELETED, NULL, NULL);
1109 }
1110 
1111 LIBETPAN_EXPORT
mailimap_flag_new_seen(void)1112 struct mailimap_flag * mailimap_flag_new_seen(void)
1113 {
1114   return mailimap_flag_new(MAILIMAP_FLAG_SEEN, NULL, NULL);
1115 }
1116 
1117 LIBETPAN_EXPORT
mailimap_flag_new_draft(void)1118 struct mailimap_flag * mailimap_flag_new_draft(void)
1119 {
1120   return mailimap_flag_new(MAILIMAP_FLAG_DRAFT, NULL, NULL);
1121 }
1122 
1123 LIBETPAN_EXPORT
mailimap_flag_new_flag_keyword(char * flag_keyword)1124 struct mailimap_flag * mailimap_flag_new_flag_keyword(char * flag_keyword)
1125 {
1126   return mailimap_flag_new(MAILIMAP_FLAG_KEYWORD, flag_keyword, NULL);
1127 }
1128 
1129 LIBETPAN_EXPORT
mailimap_flag_new_flag_extension(char * flag_extension)1130 struct mailimap_flag * mailimap_flag_new_flag_extension(char * flag_extension)
1131 {
1132   return mailimap_flag_new(MAILIMAP_FLAG_EXTENSION, NULL, flag_extension);
1133 }
1134 
1135 
1136 
1137 
1138 /* CREATE */
1139 /* gchar */
1140 
1141 /* DELETE */
1142 /* gchar */
1143 
1144 /* EXAMINE */
1145 /* gchar */
1146 
1147 /* LIST  */
1148 /* gchar gchar */
1149 
1150 /* LSUB */
1151 /* gchar gchar */
1152 
1153 /* RENAME */
1154 /* gchar gchar */
1155 
1156 /* SELECT */
1157 /* gchar */
1158 
1159 /* STATUS */
1160 /* gchar GList of status_att */
1161 
1162 LIBETPAN_EXPORT
mailimap_status_att_list_new_empty(void)1163 struct mailimap_status_att_list * mailimap_status_att_list_new_empty(void)
1164 {
1165   clist * list;
1166 
1167   list = clist_new();
1168   if (list == NULL)
1169     return NULL;
1170 
1171   return mailimap_status_att_list_new(list);
1172 }
1173 
1174 LIBETPAN_EXPORT
1175 int
mailimap_status_att_list_add(struct mailimap_status_att_list * sa_list,int status_att)1176 mailimap_status_att_list_add(struct mailimap_status_att_list * sa_list,
1177 			     int status_att)
1178 {
1179   int * pstatus_att;
1180   int r;
1181 
1182   pstatus_att = malloc(sizeof(* pstatus_att));
1183   * pstatus_att = status_att;
1184 
1185   r = clist_append(sa_list->att_list, pstatus_att);
1186   if (r < 0) {
1187     free(pstatus_att);
1188     return MAILIMAP_ERROR_MEMORY;
1189   }
1190 
1191   return MAILIMAP_NO_ERROR;
1192 }
1193 
1194 /* SUBSCRIBE */
1195 /* gchar */
1196 
1197 /* UNSUBSCRIBE */
1198 /* gchar */
1199 
1200 /* LOGIN */
1201 /* gchar gchar */
1202 
1203 /* AUTHENTICATE */
1204 /* gchar */
1205 
1206 
1207 static int recursive_build_path(struct mailimap_body * root_part,
1208     struct mailimap_body * part,
1209     clist ** result);
1210 
try_build_part(struct mailimap_body * root_part,struct mailimap_body * part,uint32_t count,clist ** result)1211 static int try_build_part(struct mailimap_body * root_part,
1212     struct mailimap_body * part, uint32_t count,
1213     clist ** result)
1214 {
1215   int r;
1216   clist * imap_id_list;
1217   uint32_t * id;
1218 
1219   r = recursive_build_path(root_part, part, &imap_id_list);
1220   if (r != MAILIMAP_NO_ERROR)
1221     return r;
1222 
1223   id = malloc(sizeof(* id));
1224   if (id == NULL) {
1225     clist_free(imap_id_list);
1226     return MAILIMAP_ERROR_MEMORY;
1227   }
1228 
1229   * id = count;
1230 
1231   r = clist_prepend(imap_id_list, id);
1232   if (r < 0) {
1233     free(id);
1234     clist_free(imap_id_list);
1235     return MAILIMAP_ERROR_MEMORY;
1236   }
1237 
1238   * result = imap_id_list;
1239 
1240   return MAILIMAP_NO_ERROR;
1241 }
1242 
1243 
recursive_build_path(struct mailimap_body * root_part,struct mailimap_body * part,clist ** result)1244 static int recursive_build_path(struct mailimap_body * root_part,
1245     struct mailimap_body * part,
1246     clist ** result)
1247 {
1248   clistiter * cur;
1249   uint32_t count;
1250   int r;
1251   clist * imap_id_list;
1252 
1253   if (part == root_part) {
1254     imap_id_list = clist_new();
1255     if (imap_id_list == NULL) {
1256       return MAILIMAP_ERROR_MEMORY;
1257     }
1258 
1259     * result = imap_id_list;
1260 
1261     return MAILIMAP_NO_ERROR;
1262   }
1263 
1264   switch (root_part->bd_type) {
1265   case MAILIMAP_BODY_MPART:
1266     count = 0;
1267     for(cur = clist_begin(root_part->bd_data.bd_body_mpart->bd_list) ;
1268         cur != NULL ; cur = clist_next(cur)) {
1269       struct mailimap_body * current_part;
1270 
1271       current_part = clist_content(cur);
1272       count ++;
1273 
1274       r = try_build_part(current_part, part, count, &imap_id_list);
1275       if (r == MAILIMAP_ERROR_INVAL) {
1276         continue;
1277       }
1278       else if (r != MAILIMAP_NO_ERROR) {
1279         return r;
1280       }
1281       else {
1282         * result = imap_id_list;
1283         return MAILIMAP_NO_ERROR;
1284       }
1285     }
1286     return MAILIMAP_ERROR_INVAL;
1287 
1288   case MAILIMAP_BODY_1PART:
1289     if (root_part->bd_data.bd_body_1part->bd_type ==
1290         MAILIMAP_BODY_TYPE_1PART_MSG) {
1291       struct mailimap_body * current_part;
1292 
1293       current_part =
1294         root_part->bd_data.bd_body_1part->bd_data.bd_type_msg->bd_body;
1295 
1296       r = try_build_part(current_part, part, 1, &imap_id_list);
1297       if (r != MAILIMAP_NO_ERROR) {
1298         return r;
1299       }
1300       else {
1301         * result = imap_id_list;
1302         return MAILIMAP_NO_ERROR;
1303       }
1304     }
1305     else {
1306       return MAILIMAP_ERROR_INVAL;
1307     }
1308     break;
1309 
1310   default:
1311     return MAILIMAP_ERROR_INVAL;
1312   }
1313 }
1314 
1315 /* return mailimap_section_part from a given mailimap_body */
1316 
1317 LIBETPAN_EXPORT
mailimap_get_section_part_from_body(struct mailimap_body * root_part,struct mailimap_body * part,struct mailimap_section_part ** result)1318 int mailimap_get_section_part_from_body(struct mailimap_body * root_part,
1319     struct mailimap_body * part,
1320     struct mailimap_section_part ** result)
1321 {
1322   struct mailimap_section_part * section_part;
1323   clist * id_list;
1324   int r;
1325   int res;
1326 
1327   r = recursive_build_path(root_part, part, &id_list);
1328   if (r != MAILIMAP_NO_ERROR) {
1329     res = r;
1330     goto err;
1331   }
1332 
1333   section_part = mailimap_section_part_new(id_list);
1334   if (section_part == NULL) {
1335     res = MAILIMAP_ERROR_MEMORY;
1336     goto free_list;
1337   }
1338 
1339   * result = section_part;
1340 
1341   return MAILIMAP_NO_ERROR;
1342 
1343  free_list:
1344   clist_foreach(id_list, (clist_func) free, NULL);
1345   clist_free(id_list);
1346  err:
1347   return res;
1348 }
1349