summaryrefslogtreecommitdiffabout
path: root/libetpan/src/driver/tools/imfcache.c
Unidiff
Diffstat (limited to 'libetpan/src/driver/tools/imfcache.c') (more/less context) (ignore whitespace changes)
-rw-r--r--libetpan/src/driver/tools/imfcache.c1429
1 files changed, 1429 insertions, 0 deletions
diff --git a/libetpan/src/driver/tools/imfcache.c b/libetpan/src/driver/tools/imfcache.c
new file mode 100644
index 0000000..7c6a5be
--- a/dev/null
+++ b/libetpan/src/driver/tools/imfcache.c
@@ -0,0 +1,1429 @@
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 "imfcache.h"
37
38#include <stdlib.h>
39#include <string.h>
40
41static int mailimf_cache_field_write(MMAPString * mmapstr, size_t * index,
42 struct mailimf_field * field);
43static int mailimf_cache_orig_date_write(MMAPString * mmapstr, size_t * index,
44 struct mailimf_orig_date * date);
45static int mailimf_cache_date_time_write(MMAPString * mmapstr, size_t * index,
46 struct mailimf_date_time * date_time);
47static int mailimf_cache_from_write(MMAPString * mmapstr, size_t * index,
48 struct mailimf_from * from);
49static int mailimf_cache_sender_write(MMAPString * mmapstr, size_t * index,
50 struct mailimf_sender * sender);
51static int mailimf_cache_reply_to_write(MMAPString * mmapstr, size_t * index,
52 struct mailimf_reply_to * reply_to);
53static int mailimf_cache_to_write(MMAPString * mmapstr, size_t * index,
54 struct mailimf_to * to);
55static int mailimf_cache_cc_write(MMAPString * mmapstr, size_t * index,
56 struct mailimf_cc * to);
57static int mailimf_cache_bcc_write(MMAPString * mmapstr, size_t * index,
58 struct mailimf_bcc * to);
59static int mailimf_cache_message_id_write(MMAPString * mmapstr, size_t * index,
60 struct mailimf_message_id * message_id);
61static int mailimf_cache_msg_id_list_write(MMAPString * mmapstr, size_t * index,
62 clist * list);
63static int mailimf_cache_in_reply_to_write(MMAPString * mmapstr, size_t * index,
64 struct mailimf_in_reply_to *
65 in_reply_to);
66static int mailimf_cache_references_write(MMAPString * mmapstr, size_t * index,
67 struct mailimf_references * references);
68static int mailimf_cache_subject_write(MMAPString * mmapstr, size_t * index,
69 struct mailimf_subject * subject);
70static int mailimf_cache_address_list_write(MMAPString * mmapstr,
71 size_t * index,
72 struct mailimf_address_list *
73 addr_list);
74static int mailimf_cache_address_write(MMAPString * mmapstr, size_t * index,
75 struct mailimf_address * addr);
76static int mailimf_cache_group_write(MMAPString * mmapstr, size_t * index,
77 struct mailimf_group * group);
78static int mailimf_cache_mailbox_list_write(MMAPString * mmapstr,
79 size_t * index,
80 struct mailimf_mailbox_list * mb_list);
81static int mailimf_cache_mailbox_write(MMAPString * mmapstr, size_t * index,
82 struct mailimf_mailbox * mb);
83
84
85static int mailimf_cache_field_read(MMAPString * mmapstr, size_t * index,
86 struct mailimf_field ** result);
87static int mailimf_cache_orig_date_read(MMAPString * mmapstr, size_t * index,
88 struct mailimf_orig_date ** result);
89static int mailimf_cache_date_time_read(MMAPString * mmapstr, size_t * index,
90 struct mailimf_date_time ** result);
91static int mailimf_cache_from_read(MMAPString * mmapstr, size_t * index,
92 struct mailimf_from ** result);
93static int mailimf_cache_sender_read(MMAPString * mmapstr, size_t * index,
94 struct mailimf_sender ** result);
95static int mailimf_cache_reply_to_read(MMAPString * mmapstr, size_t * index,
96 struct mailimf_reply_to ** result);
97static int mailimf_cache_to_read(MMAPString * mmapstr, size_t * index,
98 struct mailimf_to ** result);
99static int mailimf_cache_cc_read(MMAPString * mmapstr, size_t * index,
100 struct mailimf_cc ** result);
101static int mailimf_cache_bcc_read(MMAPString * mmapstr, size_t * index,
102 struct mailimf_bcc ** result);
103static int mailimf_cache_message_id_read(MMAPString * mmapstr, size_t * index,
104 struct mailimf_message_id ** result);
105static int mailimf_cache_msg_id_list_read(MMAPString * mmapstr, size_t * index,
106 clist ** result);
107static int
108mailimf_cache_in_reply_to_read(MMAPString * mmapstr, size_t * index,
109 struct mailimf_in_reply_to ** result);
110
111static int mailimf_cache_references_read(MMAPString * mmapstr, size_t * index,
112 struct mailimf_references ** result);
113static int mailimf_cache_subject_read(MMAPString * mmapstr, size_t * index,
114 struct mailimf_subject ** result);
115static int mailimf_cache_address_list_read(MMAPString * mmapstr, size_t * index,
116 struct mailimf_address_list ** result);
117static int mailimf_cache_address_read(MMAPString * mmapstr, size_t * index,
118 struct mailimf_address ** result);
119static int mailimf_cache_group_read(MMAPString * mmapstr, size_t * index,
120 struct mailimf_group ** result);
121static int
122mailimf_cache_mailbox_list_read(MMAPString * mmapstr, size_t * index,
123 struct mailimf_mailbox_list ** result);
124static int mailimf_cache_mailbox_read(MMAPString * mmapstr, size_t * index,
125 struct mailimf_mailbox ** result);
126
127enum {
128 CACHE_NULL_POINTER = 0,
129 CACHE_NOT_NULL = 1,
130};
131
132int mail_serialize_clear(MMAPString * mmapstr, size_t * index)
133{
134 if (mmap_string_set_size(mmapstr, 0) == NULL)
135 return MAIL_ERROR_MEMORY;
136
137 * index = 0;
138
139 return MAIL_NO_ERROR;
140}
141
142int mail_serialize_write(MMAPString * mmapstr, size_t * index,
143 char * buf, size_t size)
144{
145 if (mmap_string_append_len(mmapstr, buf, size) == NULL)
146 return MAIL_ERROR_MEMORY;
147
148 * index = * index + size;
149
150 return MAIL_NO_ERROR;
151}
152
153int mail_serialize_read(MMAPString * mmapstr, size_t * index,
154 char * buf, size_t size)
155{
156 size_t cur_token;
157
158 cur_token = * index;
159
160 if (cur_token + size > mmapstr->len)
161 return MAIL_ERROR_STREAM;
162
163 memcpy(buf, mmapstr->str + cur_token, size);
164 * index = cur_token + size;
165
166 return MAIL_NO_ERROR;
167}
168
169int mailimf_cache_int_write(MMAPString * mmapstr, size_t * index,
170 uint32_t value)
171{
172 unsigned char ch;
173 int r;
174 int i;
175
176 for(i = 0 ; i < 4 ; i ++) {
177 ch = value % 256;
178
179 r = mail_serialize_write(mmapstr, index, &ch, 1);
180 if (r != MAIL_NO_ERROR)
181 return r;
182 value /= 256;
183 }
184
185 return MAIL_NO_ERROR;
186}
187
188int mailimf_cache_int_read(MMAPString * mmapstr, size_t * index,
189 uint32_t * result)
190{
191 unsigned char ch;
192 uint32_t value;
193 int i;
194 int r;
195
196 value = 0;
197 for(i = 0 ; i < 4 ; i ++) {
198 r = mail_serialize_read(mmapstr, index, &ch, 1);
199 if (r != MAIL_NO_ERROR)
200 return r;
201 value = value | ch << (i << 3);
202 }
203
204 * result = value;
205
206 return MAIL_NO_ERROR;
207}
208
209
210int mailimf_cache_string_write(MMAPString * mmapstr, size_t * index,
211 char * str, size_t length)
212{
213 int r;
214
215 if (str == NULL) {
216 r = mailimf_cache_int_write(mmapstr, index, CACHE_NULL_POINTER);
217 if (r != MAIL_NO_ERROR)
218 return r;
219 }
220 else {
221 r = mailimf_cache_int_write(mmapstr, index, CACHE_NOT_NULL);
222 if (r != MAIL_NO_ERROR)
223 return r;
224
225 r = mailimf_cache_int_write(mmapstr, index, length);
226 if (r != MAIL_NO_ERROR)
227 return r;
228
229 if (length != 0) {
230 r = mail_serialize_write(mmapstr, index, str, length);
231 if (r != MAIL_NO_ERROR)
232 return MAIL_ERROR_FILE;
233 }
234 }
235
236 return MAIL_NO_ERROR;
237}
238
239int mailimf_cache_string_read(MMAPString * mmapstr, size_t * index,
240 char ** result)
241{
242 int r;
243 uint32_t length;
244 char * str;
245 uint32_t type;
246
247 r = mailimf_cache_int_read(mmapstr, index, &type);
248 if (r != MAIL_NO_ERROR)
249 return r;
250
251 if (type == CACHE_NULL_POINTER) {
252 str = NULL;
253 }
254 else {
255 r = mailimf_cache_int_read(mmapstr, index, &length);
256 if (r != MAIL_NO_ERROR)
257 return r;
258
259 str = malloc(length + 1);
260 if (str == NULL)
261 return MAIL_ERROR_MEMORY;
262
263 r = mail_serialize_read(mmapstr, index, str, length);
264 if (r != MAIL_NO_ERROR)
265 return MAIL_ERROR_FILE;
266
267 str[length] = 0;
268 }
269
270 * result = str;
271
272 return MAIL_NO_ERROR;
273}
274
275int mailimf_cache_fields_write(MMAPString * mmapstr, size_t * index,
276 struct mailimf_fields * fields)
277{
278 clistiter * cur;
279 int r;
280
281 r = mailimf_cache_int_write(mmapstr, index,
282 clist_count(fields->fld_list));
283 if (r != MAIL_NO_ERROR)
284 return r;
285
286 for(cur = clist_begin(fields->fld_list) ; cur != NULL ;
287 cur = clist_next(cur)) {
288 r = mailimf_cache_field_write(mmapstr, index, clist_content(cur));
289 if (r != MAIL_NO_ERROR)
290 return r;
291 }
292
293 return MAIL_NO_ERROR;
294}
295
296int mailimf_cache_fields_read(MMAPString * mmapstr, size_t * index,
297 struct mailimf_fields ** result)
298{
299 clist * list;
300 int r;
301 uint32_t count;
302 uint32_t i;
303 struct mailimf_fields * fields;
304 int res;
305
306 r = mailimf_cache_int_read(mmapstr, index, &count);
307 if (r != MAIL_NO_ERROR) {
308 res = r;
309 goto err;
310 }
311
312 list = clist_new();
313 if (list == NULL) {
314 res = MAIL_ERROR_MEMORY;
315 goto err;
316 }
317
318 for(i = 0 ; i < count ; i++) {
319 struct mailimf_field * field;
320
321 r = mailimf_cache_field_read(mmapstr, index, &field);
322 if (r != MAIL_NO_ERROR) {
323 res = r;
324 goto free_list;
325 }
326
327 r = clist_append(list, field);
328 if (r < 0) {
329 mailimf_field_free(field);
330 res = MAIL_ERROR_MEMORY;
331 goto free_list;
332 }
333 }
334
335 fields = mailimf_fields_new(list);
336 if (fields == NULL) {
337 res = MAIL_ERROR_MEMORY;
338 goto free_list;
339 }
340
341 * result = fields;
342
343 return MAIL_NO_ERROR;
344
345 free_list:
346 clist_foreach(list, (clist_func) mailimf_field_free, NULL);
347 clist_free(list);
348 err:
349 return res;
350}
351
352
353static int mailimf_cache_field_write(MMAPString * mmapstr, size_t * index,
354 struct mailimf_field * field)
355{
356 int r;
357
358 r = mailimf_cache_int_write(mmapstr, index, field->fld_type);
359 if (r != MAIL_NO_ERROR)
360 return r;
361
362 switch (field->fld_type) {
363 case MAILIMF_FIELD_ORIG_DATE:
364 r = mailimf_cache_orig_date_write(mmapstr, index,
365 field->fld_data.fld_orig_date);
366 break;
367 case MAILIMF_FIELD_FROM:
368 r = mailimf_cache_from_write(mmapstr, index,
369 field->fld_data.fld_from);
370 break;
371 case MAILIMF_FIELD_SENDER:
372 r = mailimf_cache_sender_write(mmapstr, index,
373 field->fld_data.fld_sender);
374 break;
375 case MAILIMF_FIELD_REPLY_TO:
376 r = mailimf_cache_reply_to_write(mmapstr, index,
377 field->fld_data.fld_reply_to);
378 break;
379 case MAILIMF_FIELD_TO:
380 r = mailimf_cache_to_write(mmapstr, index,
381 field->fld_data.fld_to);
382 break;
383 case MAILIMF_FIELD_CC:
384 r = mailimf_cache_cc_write(mmapstr, index,
385 field->fld_data.fld_cc);
386 break;
387 case MAILIMF_FIELD_BCC:
388 r = mailimf_cache_bcc_write(mmapstr, index,
389 field->fld_data.fld_bcc);
390 break;
391 case MAILIMF_FIELD_MESSAGE_ID:
392 r = mailimf_cache_message_id_write(mmapstr, index,
393 field->fld_data.fld_message_id);
394 break;
395 case MAILIMF_FIELD_IN_REPLY_TO:
396 r = mailimf_cache_in_reply_to_write(mmapstr, index,
397 field->fld_data.fld_in_reply_to);
398 break;
399 case MAILIMF_FIELD_REFERENCES:
400 r = mailimf_cache_references_write(mmapstr, index,
401 field->fld_data.fld_references);
402 break;
403 case MAILIMF_FIELD_SUBJECT:
404 r = mailimf_cache_subject_write(mmapstr, index,
405 field->fld_data.fld_subject);
406 break;
407 default:
408 r = 0;
409 break;
410 }
411
412 if (r != MAIL_NO_ERROR)
413 return r;
414
415 return MAIL_NO_ERROR;
416}
417
418
419static int mailimf_cache_field_read(MMAPString * mmapstr, size_t * index,
420 struct mailimf_field ** result)
421{
422 int r;
423 uint32_t type;
424 struct mailimf_orig_date * orig_date;
425 struct mailimf_from * from;
426 struct mailimf_sender * sender;
427 struct mailimf_to * to;
428 struct mailimf_reply_to * reply_to;
429 struct mailimf_cc * cc;
430 struct mailimf_bcc * bcc;
431 struct mailimf_message_id * message_id;
432 struct mailimf_in_reply_to * in_reply_to;
433 struct mailimf_references * references;
434 struct mailimf_subject * subject;
435 struct mailimf_field * field;
436 int res;
437
438 orig_date = NULL;
439 from = NULL;
440 sender = NULL;
441 to = NULL;
442 reply_to = NULL;
443 cc = NULL;
444 bcc = NULL;
445 message_id = NULL;
446 in_reply_to = NULL;
447 references = NULL;
448 subject = NULL;
449 field = NULL;
450
451 r = mailimf_cache_int_read(mmapstr, index, &type);
452 if (r != MAIL_NO_ERROR) {
453 res = r;
454 goto err;
455 }
456
457 switch (type) {
458 case MAILIMF_FIELD_ORIG_DATE:
459 r = mailimf_cache_orig_date_read(mmapstr, index, &orig_date);
460 break;
461 case MAILIMF_FIELD_FROM:
462 r = mailimf_cache_from_read(mmapstr, index, &from);
463 break;
464 case MAILIMF_FIELD_SENDER:
465 r = mailimf_cache_sender_read(mmapstr, index, &sender);
466 break;
467 case MAILIMF_FIELD_REPLY_TO:
468 r = mailimf_cache_reply_to_read(mmapstr, index, &reply_to);
469 break;
470 case MAILIMF_FIELD_TO:
471 r = mailimf_cache_to_read(mmapstr, index, &to);
472 break;
473 case MAILIMF_FIELD_CC:
474 r = mailimf_cache_cc_read(mmapstr, index, &cc);
475 break;
476 case MAILIMF_FIELD_BCC:
477 r = mailimf_cache_bcc_read(mmapstr, index, &bcc);
478 break;
479 case MAILIMF_FIELD_MESSAGE_ID:
480 r = mailimf_cache_message_id_read(mmapstr, index, &message_id);
481 break;
482 case MAILIMF_FIELD_IN_REPLY_TO:
483 r = mailimf_cache_in_reply_to_read(mmapstr, index, &in_reply_to);
484 break;
485 case MAILIMF_FIELD_REFERENCES:
486 r = mailimf_cache_references_read(mmapstr, index, &references);
487 break;
488 case MAILIMF_FIELD_SUBJECT:
489 r = mailimf_cache_subject_read(mmapstr, index, &subject);
490 break;
491 default:
492 r = MAIL_ERROR_INVAL;
493 break;
494 }
495
496 if (r != MAIL_NO_ERROR) {
497 res = r;
498 goto free;
499 }
500
501 field = mailimf_field_new(type, NULL, NULL, NULL, NULL, NULL,
502 NULL, NULL, NULL, orig_date, from, sender, reply_to,
503 to, cc, bcc, message_id,
504 in_reply_to, references,
505 subject, NULL, NULL, NULL);
506 if (field == NULL) {
507 res = MAIL_ERROR_MEMORY;
508 goto free;
509 }
510
511 * result = field;
512
513 return MAIL_NO_ERROR;
514
515 free:
516 if (orig_date != NULL)
517 mailimf_orig_date_free(orig_date);
518 if (from != NULL)
519 mailimf_from_free(from);
520 if (sender != NULL)
521 mailimf_sender_free(sender);
522 if (reply_to != NULL)
523 mailimf_reply_to_free(reply_to);
524 if (to != NULL)
525 mailimf_to_free(to);
526 if (cc != NULL)
527 mailimf_cc_free(cc);
528 if (bcc != NULL)
529 mailimf_bcc_free(bcc);
530 if (message_id != NULL)
531 mailimf_message_id_free(message_id);
532 if (in_reply_to != NULL)
533 mailimf_in_reply_to_free(in_reply_to);
534 if (references != NULL)
535 mailimf_references_free(references);
536 if (subject != NULL)
537 mailimf_subject_free(subject);
538 err:
539 return res;
540}
541
542static int mailimf_cache_orig_date_write(MMAPString * mmapstr, size_t * index,
543 struct mailimf_orig_date * date)
544{
545 return mailimf_cache_date_time_write(mmapstr, index, date->dt_date_time);
546}
547
548static int mailimf_cache_orig_date_read(MMAPString * mmapstr, size_t * index,
549 struct mailimf_orig_date ** result)
550{
551 int r;
552 struct mailimf_date_time * date_time;
553 struct mailimf_orig_date * orig_date;
554
555 r = mailimf_cache_date_time_read(mmapstr, index, &date_time);
556 if (r != MAIL_NO_ERROR)
557 return r;
558
559 orig_date = mailimf_orig_date_new(date_time);
560 if (orig_date == NULL) {
561 mailimf_date_time_free(date_time);
562 return MAIL_ERROR_MEMORY;
563 }
564
565 * result = orig_date;
566
567 return MAIL_NO_ERROR;
568}
569
570static int mailimf_cache_date_time_write(MMAPString * mmapstr, size_t * index,
571 struct mailimf_date_time * date_time)
572{
573 int r;
574
575 r = mailimf_cache_int_write(mmapstr, index, date_time->dt_day);
576 if (r != MAIL_NO_ERROR)
577 return r;
578
579 r = mailimf_cache_int_write(mmapstr, index, date_time->dt_month);
580 if (r != MAIL_NO_ERROR)
581 return r;
582
583 r = mailimf_cache_int_write(mmapstr, index, date_time->dt_year);
584 if (r != MAIL_NO_ERROR)
585 return r;
586
587 r = mailimf_cache_int_write(mmapstr, index, date_time->dt_hour);
588 if (r != MAIL_NO_ERROR)
589 return r;
590
591 r = mailimf_cache_int_write(mmapstr, index, date_time->dt_min);
592 if (r != MAIL_NO_ERROR)
593 return r;
594
595 r = mailimf_cache_int_write(mmapstr, index, date_time->dt_sec);
596 if (r != MAIL_NO_ERROR)
597 return r;
598
599 r = mailimf_cache_int_write(mmapstr, index, date_time->dt_zone);
600 if (r != MAIL_NO_ERROR)
601 return r;
602
603 return MAIL_NO_ERROR;
604}
605
606static int mailimf_cache_date_time_read(MMAPString * mmapstr, size_t * index,
607 struct mailimf_date_time ** result)
608{
609 int r;
610 uint32_t day;
611 uint32_t month;
612 uint32_t year;
613 uint32_t hour;
614 uint32_t min;
615 uint32_t sec;
616 uint32_t zone;
617 struct mailimf_date_time * date_time;
618
619 r = mailimf_cache_int_read(mmapstr, index, &day);
620 if (r != MAIL_NO_ERROR)
621 return r;
622
623 r = mailimf_cache_int_read(mmapstr, index, &month);
624 if (r != MAIL_NO_ERROR)
625 return r;
626
627 r = mailimf_cache_int_read(mmapstr, index, &year);
628 if (r != MAIL_NO_ERROR)
629 return r;
630
631 r = mailimf_cache_int_read(mmapstr, index, &hour);
632 if (r != MAIL_NO_ERROR)
633 return r;
634
635 r = mailimf_cache_int_read(mmapstr, index, &min);
636 if (r != MAIL_NO_ERROR)
637 return r;
638
639 r = mailimf_cache_int_read(mmapstr, index, &sec);
640 if (r != MAIL_NO_ERROR)
641 return r;
642
643 r = mailimf_cache_int_read(mmapstr, index, &zone);
644 if (r != MAIL_NO_ERROR)
645 return r;
646
647 date_time = mailimf_date_time_new(day, month, year, hour, min, sec, zone);
648 if (date_time == NULL)
649 return MAIL_ERROR_MEMORY;
650
651 * result = date_time;
652
653 return MAIL_NO_ERROR;
654
655}
656
657
658static int mailimf_cache_from_write(MMAPString * mmapstr, size_t * index,
659 struct mailimf_from * from)
660{
661 return mailimf_cache_mailbox_list_write(mmapstr, index, from->frm_mb_list);
662}
663
664static int mailimf_cache_from_read(MMAPString * mmapstr, size_t * index,
665 struct mailimf_from ** result)
666{
667 struct mailimf_mailbox_list * mb_list;
668 struct mailimf_from * from;
669 int r;
670
671 r = mailimf_cache_mailbox_list_read(mmapstr, index, &mb_list);
672 if (r != MAIL_NO_ERROR)
673 return r;
674
675 from = mailimf_from_new(mb_list);
676 if (from == NULL) {
677 mailimf_mailbox_list_free(mb_list);
678 return MAIL_ERROR_MEMORY;
679 }
680
681 * result = from;
682
683 return MAIL_NO_ERROR;
684}
685
686static int mailimf_cache_sender_write(MMAPString * mmapstr, size_t * index,
687 struct mailimf_sender * sender)
688{
689 return mailimf_cache_mailbox_write(mmapstr, index, sender->snd_mb);
690}
691
692static int mailimf_cache_sender_read(MMAPString * mmapstr, size_t * index,
693 struct mailimf_sender ** result)
694{
695 int r;
696 struct mailimf_mailbox * mb;
697 struct mailimf_sender * sender;
698
699 r = mailimf_cache_mailbox_read(mmapstr, index, &mb);
700 if (r != MAIL_NO_ERROR)
701 return r;
702
703 sender = mailimf_sender_new(mb);
704 if (sender == NULL) {
705 mailimf_mailbox_free(mb);
706 return MAIL_ERROR_MEMORY;
707 }
708
709 * result = sender;
710
711 return MAIL_NO_ERROR;
712}
713
714static int mailimf_cache_reply_to_write(MMAPString * mmapstr, size_t * index,
715 struct mailimf_reply_to * reply_to)
716{
717 return mailimf_cache_address_list_write(mmapstr, index,
718 reply_to->rt_addr_list);
719}
720
721static int mailimf_cache_reply_to_read(MMAPString * mmapstr, size_t * index,
722 struct mailimf_reply_to ** result)
723{
724 int r;
725 struct mailimf_address_list * addr_list;
726 struct mailimf_reply_to * reply_to;
727
728 r = mailimf_cache_address_list_read(mmapstr, index, &addr_list);
729 if (r != MAIL_NO_ERROR)
730 return r;
731
732 reply_to = mailimf_reply_to_new(addr_list);
733 if (reply_to == NULL) {
734 mailimf_address_list_free(addr_list);
735 return MAIL_ERROR_MEMORY;
736 }
737
738 * result = reply_to;
739
740 return MAIL_NO_ERROR;
741}
742
743static int mailimf_cache_to_write(MMAPString * mmapstr, size_t * index,
744 struct mailimf_to * to)
745{
746 return mailimf_cache_address_list_write(mmapstr, index, to->to_addr_list);
747}
748
749static int mailimf_cache_to_read(MMAPString * mmapstr, size_t * index,
750 struct mailimf_to ** result)
751{
752 int r;
753 struct mailimf_address_list * addr_list;
754 struct mailimf_to * to;
755
756 r = mailimf_cache_address_list_read(mmapstr, index, &addr_list);
757 if (r != MAIL_NO_ERROR)
758 return r;
759
760 to = mailimf_to_new(addr_list);
761 if (to == NULL) {
762 mailimf_address_list_free(addr_list);
763 return MAIL_ERROR_MEMORY;
764 }
765
766 * result = to;
767
768 return MAIL_NO_ERROR;
769}
770
771static int mailimf_cache_cc_write(MMAPString * mmapstr, size_t * index,
772 struct mailimf_cc * cc)
773{
774 return mailimf_cache_address_list_write(mmapstr, index, cc->cc_addr_list);
775}
776
777static int mailimf_cache_cc_read(MMAPString * mmapstr, size_t * index,
778 struct mailimf_cc ** result)
779{
780 int r;
781 struct mailimf_address_list * addr_list;
782 struct mailimf_cc * cc;
783
784 r = mailimf_cache_address_list_read(mmapstr, index, &addr_list);
785 if (r != MAIL_NO_ERROR)
786 return r;
787
788 cc = mailimf_cc_new(addr_list);
789 if (cc == NULL) {
790 mailimf_address_list_free(addr_list);
791 return MAIL_ERROR_MEMORY;
792 }
793
794 * result = cc;
795
796 return MAIL_NO_ERROR;
797}
798
799static int mailimf_cache_bcc_write(MMAPString * mmapstr, size_t * index,
800 struct mailimf_bcc * bcc)
801{
802 return mailimf_cache_address_list_write(mmapstr, index, bcc->bcc_addr_list);
803}
804
805static int mailimf_cache_bcc_read(MMAPString * mmapstr, size_t * index,
806 struct mailimf_bcc ** result)
807{
808 int r;
809 struct mailimf_address_list * addr_list;
810 struct mailimf_bcc * bcc;
811
812 r = mailimf_cache_address_list_read(mmapstr, index, &addr_list);
813 if (r != MAIL_NO_ERROR)
814 return r;
815
816 bcc = mailimf_bcc_new(addr_list);
817 if (bcc == NULL) {
818 mailimf_address_list_free(addr_list);
819 return MAIL_ERROR_MEMORY;
820 }
821
822 * result = bcc;
823
824 return MAIL_NO_ERROR;
825}
826
827static int
828mailimf_cache_message_id_write(MMAPString * mmapstr, size_t * index,
829 struct mailimf_message_id * message_id)
830{
831 return mailimf_cache_string_write(mmapstr, index,
832 message_id->mid_value, strlen(message_id->mid_value));
833}
834
835static int mailimf_cache_message_id_read(MMAPString * mmapstr, size_t * index,
836 struct mailimf_message_id ** result)
837{
838 struct mailimf_message_id * message_id;
839 char * str;
840 int r;
841
842 r = mailimf_cache_string_read(mmapstr, index, &str);
843 if (r != MAIL_NO_ERROR)
844 return r;
845
846 message_id = mailimf_message_id_new(str);
847 if (message_id == NULL) {
848 free(str);
849 return MAIL_ERROR_MEMORY;
850 }
851
852 * result = message_id;
853
854 return MAIL_NO_ERROR;
855}
856
857static int
858mailimf_cache_msg_id_list_write(MMAPString * mmapstr, size_t * index,
859 clist * list)
860{
861 clistiter * cur;
862 int r;
863
864 r = mailimf_cache_int_write(mmapstr, index, clist_count(list));
865 if (r != MAIL_NO_ERROR)
866 return r;
867
868 for(cur = clist_begin(list) ; cur != NULL ; cur = clist_next(cur)) {
869 char * msgid;
870
871 msgid = clist_content(cur);
872
873 r = mailimf_cache_string_write(mmapstr, index, msgid, strlen(msgid));
874 if (r != MAIL_NO_ERROR)
875 return r;
876 }
877
878 return MAIL_NO_ERROR;
879}
880
881static int mailimf_cache_msg_id_list_read(MMAPString * mmapstr, size_t * index,
882 clist ** result)
883{
884 clist * list;
885 int r;
886 uint32_t count;
887 uint32_t i;
888 int res;
889
890 r = mailimf_cache_int_read(mmapstr, index, &count);
891 if (r != MAIL_NO_ERROR) {
892 res = r;
893 goto err;
894 }
895
896 list = clist_new();
897 if (list == NULL) {
898 res = MAIL_ERROR_MEMORY;
899 goto err;
900 }
901
902 for(i = 0 ; i < count ; i++) {
903 char * msgid;
904
905 r = mailimf_cache_string_read(mmapstr, index, &msgid);
906 if (r != MAIL_NO_ERROR) {
907 res = r;
908 goto err;
909 }
910
911 r = clist_append(list, msgid);
912 if (r < 0) {
913 free(msgid);
914 res = MAIL_ERROR_MEMORY;
915 goto free_list;
916 }
917 }
918
919 * result = list;
920
921 return MAIL_NO_ERROR;
922
923 free_list:
924 clist_foreach(list, (clist_func) free, NULL);
925 clist_free(list);
926 err:
927 return res;
928}
929
930static int
931mailimf_cache_in_reply_to_write(MMAPString * mmapstr, size_t * index,
932 struct mailimf_in_reply_to * in_reply_to)
933{
934 return mailimf_cache_msg_id_list_write(mmapstr, index,
935 in_reply_to->mid_list);
936}
937
938static int mailimf_cache_in_reply_to_read(MMAPString * mmapstr, size_t * index,
939 struct mailimf_in_reply_to ** result)
940{
941 int r;
942 clist * msg_id_list;
943 struct mailimf_in_reply_to * in_reply_to;
944
945 r = mailimf_cache_msg_id_list_read(mmapstr, index, &msg_id_list);
946 if (r != MAIL_NO_ERROR)
947 return r;
948
949 in_reply_to = mailimf_in_reply_to_new(msg_id_list);
950 if (in_reply_to == NULL) {
951 clist_foreach(msg_id_list, (clist_func) free, NULL);
952 clist_free(msg_id_list);
953 return MAIL_ERROR_MEMORY;
954 }
955
956 * result = in_reply_to;
957
958 return MAIL_NO_ERROR;
959}
960
961static int mailimf_cache_references_write(MMAPString * mmapstr, size_t * index,
962 struct mailimf_references * references)
963{
964 return mailimf_cache_msg_id_list_write(mmapstr, index,
965 references->mid_list);
966}
967
968static int mailimf_cache_references_read(MMAPString * mmapstr, size_t * index,
969 struct mailimf_references ** result)
970{
971 int r;
972 clist * msg_id_list;
973 struct mailimf_references * references;
974
975 r = mailimf_cache_msg_id_list_read(mmapstr, index, &msg_id_list);
976 if (r != MAIL_NO_ERROR)
977 return r;
978
979 references = mailimf_references_new(msg_id_list);
980 if (references == NULL) {
981 clist_foreach(msg_id_list, (clist_func) free, NULL);
982 clist_free(msg_id_list);
983 return MAIL_ERROR_MEMORY;
984 }
985
986 * result = references;
987
988 return MAIL_NO_ERROR;
989}
990
991
992static int mailimf_cache_subject_write(MMAPString * mmapstr, size_t * index,
993 struct mailimf_subject * subject)
994{
995 return mailimf_cache_string_write(mmapstr, index,
996 subject->sbj_value, strlen(subject->sbj_value));
997}
998
999static int mailimf_cache_subject_read(MMAPString * mmapstr, size_t * index,
1000 struct mailimf_subject ** result)
1001{
1002 char * str;
1003 struct mailimf_subject * subject;
1004 int r;
1005
1006 r = mailimf_cache_string_read(mmapstr, index, &str);
1007 if (r != MAIL_NO_ERROR)
1008 return r;
1009
1010 if (str == NULL) {
1011 str = strdup("");
1012 if (str == NULL)
1013 return MAIL_ERROR_MEMORY;
1014 }
1015
1016 subject = mailimf_subject_new(str);
1017 if (subject == NULL) {
1018 free(str);
1019 return MAIL_ERROR_MEMORY;
1020 }
1021
1022 * result = subject;
1023
1024 return MAIL_NO_ERROR;
1025}
1026
1027
1028static int
1029mailimf_cache_address_list_write(MMAPString * mmapstr, size_t * index,
1030 struct mailimf_address_list * addr_list)
1031{
1032 clistiter * cur;
1033 int r;
1034
1035 if (addr_list == NULL) {
1036 r = mailimf_cache_int_write(mmapstr, index, CACHE_NULL_POINTER);
1037 if (r != MAIL_NO_ERROR)
1038 return r;
1039 }
1040 else {
1041 r = mailimf_cache_int_write(mmapstr, index, CACHE_NOT_NULL);
1042 if (r != MAIL_NO_ERROR)
1043 return r;
1044
1045 r = mailimf_cache_int_write(mmapstr, index,
1046 clist_count(addr_list->ad_list));
1047 if (r != MAIL_NO_ERROR)
1048 return r;
1049
1050 for(cur = clist_begin(addr_list->ad_list) ; cur != NULL ;
1051 cur = clist_next(cur)) {
1052 struct mailimf_address * addr;
1053
1054 addr = clist_content(cur);
1055
1056 r = mailimf_cache_address_write(mmapstr, index, addr);
1057 if (r != MAIL_NO_ERROR)
1058 return r;
1059 }
1060 }
1061
1062 return MAIL_NO_ERROR;
1063}
1064
1065static int
1066mailimf_cache_address_list_read(MMAPString * mmapstr, size_t * index,
1067 struct mailimf_address_list ** result)
1068{
1069 struct mailimf_address_list * addr_list;
1070 uint32_t count;
1071 uint32_t i;
1072 int r;
1073 clist * list;
1074 int res;
1075 uint32_t type;
1076
1077 r = mailimf_cache_int_read(mmapstr, index, &type);
1078 if (r != MAIL_NO_ERROR) {
1079 res = r;
1080 goto err;
1081 }
1082
1083 if (type == CACHE_NULL_POINTER) {
1084 * result = NULL;
1085 return MAIL_NO_ERROR;
1086 }
1087
1088 r = mailimf_cache_int_read(mmapstr, index, &count);
1089 if (r != MAIL_NO_ERROR) {
1090 res = r;
1091 goto err;
1092 }
1093
1094 list = clist_new();
1095 if (list == NULL) {
1096 res = MAIL_ERROR_MEMORY;
1097 goto err;
1098 }
1099
1100 for(i = 0 ; i < count ; i++) {
1101 struct mailimf_address * addr;
1102
1103 r = mailimf_cache_address_read(mmapstr, index, &addr);
1104 if (r != MAIL_NO_ERROR) {
1105 res = r;
1106 goto free_list;
1107 }
1108
1109 r = clist_append(list, addr);
1110 if (r < 0) {
1111 mailimf_address_free(addr);
1112 res = MAIL_ERROR_MEMORY;
1113 goto free_list;
1114 }
1115 }
1116
1117 addr_list = mailimf_address_list_new(list);
1118 if (addr_list == NULL) {
1119 res = MAIL_ERROR_MEMORY;
1120 goto free_list;
1121 }
1122
1123 * result = addr_list;
1124
1125 return MAIL_NO_ERROR;
1126
1127 free_list:
1128 clist_foreach(list, (clist_func) mailimf_address_free, NULL);
1129 clist_free(list);
1130 err:
1131 return res;
1132}
1133
1134static int mailimf_cache_address_write(MMAPString * mmapstr, size_t * index,
1135 struct mailimf_address * addr)
1136{
1137 int r;
1138
1139 r = mailimf_cache_int_write(mmapstr, index, addr->ad_type);
1140 if (r != MAIL_NO_ERROR)
1141 return r;
1142
1143 switch(addr->ad_type) {
1144 case MAILIMF_ADDRESS_MAILBOX:
1145 r = mailimf_cache_mailbox_write(mmapstr, index, addr->ad_data.ad_mailbox);
1146 if (r != MAIL_NO_ERROR)
1147 return r;
1148
1149 break;
1150
1151 case MAILIMF_ADDRESS_GROUP:
1152 r = mailimf_cache_group_write(mmapstr, index, addr->ad_data.ad_group);
1153 if (r != MAIL_NO_ERROR)
1154 return r;
1155
1156 break;
1157 }
1158
1159 return MAIL_NO_ERROR;
1160}
1161
1162static int mailimf_cache_address_read(MMAPString * mmapstr, size_t * index,
1163 struct mailimf_address ** result)
1164{
1165 uint32_t type;
1166 int r;
1167 struct mailimf_mailbox * mailbox;
1168 struct mailimf_group * group;
1169 struct mailimf_address * addr;
1170
1171 r = mailimf_cache_int_read(mmapstr, index, &type);
1172 if (r != MAIL_NO_ERROR)
1173 return r;
1174
1175 mailbox = NULL;
1176 group = NULL;
1177
1178 switch (type) {
1179 case MAILIMF_ADDRESS_MAILBOX:
1180 r = mailimf_cache_mailbox_read(mmapstr, index, &mailbox);
1181 if (r != MAIL_NO_ERROR)
1182 return r;
1183
1184 break;
1185
1186 case MAILIMF_ADDRESS_GROUP:
1187 r = mailimf_cache_group_read(mmapstr, index, &group);
1188 if (r != MAIL_NO_ERROR)
1189 return r;
1190
1191 break;
1192 }
1193
1194 addr = mailimf_address_new(type, mailbox, group);
1195 if (addr == NULL)
1196 goto free;
1197
1198 * result = addr;
1199
1200 return MAIL_NO_ERROR;
1201
1202 free:
1203 if (mailbox != NULL)
1204 mailimf_mailbox_free(mailbox);
1205 if (group != NULL)
1206 mailimf_group_free(group);
1207 return MAIL_ERROR_MEMORY;
1208}
1209
1210static int mailimf_cache_group_write(MMAPString * mmapstr, size_t * index,
1211 struct mailimf_group * group)
1212{
1213 int r;
1214
1215 r = mailimf_cache_string_write(mmapstr, index, group->grp_display_name,
1216 strlen(group->grp_display_name));
1217 if (r != MAIL_NO_ERROR)
1218 return r;
1219
1220 r = mailimf_cache_mailbox_list_write(mmapstr, index, group->grp_mb_list);
1221 if (r != MAIL_NO_ERROR)
1222 return r;
1223
1224 return MAIL_NO_ERROR;
1225}
1226
1227static int mailimf_cache_group_read(MMAPString * mmapstr, size_t * index,
1228 struct mailimf_group ** result)
1229{
1230 int r;
1231 char * display_name;
1232 struct mailimf_mailbox_list * mb_list;
1233 struct mailimf_group * group;
1234 int res;
1235
1236 r = mailimf_cache_string_read(mmapstr, index, &display_name);
1237 if (r != MAIL_NO_ERROR) {
1238 res = r;
1239 goto err;
1240 }
1241
1242 r = mailimf_cache_mailbox_list_read(mmapstr, index, &mb_list);
1243 if (r != MAIL_NO_ERROR) {
1244 res = r;
1245 goto free_dsp_name;
1246 }
1247
1248 group = mailimf_group_new(display_name, mb_list);
1249 if (group == NULL) {
1250 res = MAIL_ERROR_MEMORY;
1251 goto free_mb_list;
1252 }
1253
1254 * result = group;
1255
1256 return MAIL_NO_ERROR;
1257
1258 free_mb_list:
1259 mailimf_mailbox_list_free(mb_list);
1260 free_dsp_name:
1261 free(display_name);
1262 err:
1263 return res;
1264}
1265
1266static int
1267mailimf_cache_mailbox_list_write(MMAPString * mmapstr, size_t * index,
1268 struct mailimf_mailbox_list * mb_list)
1269{
1270 clistiter * cur;
1271 int r;
1272
1273 if (mb_list == NULL) {
1274 r = mailimf_cache_int_write(mmapstr, index, CACHE_NULL_POINTER);
1275 if (r != MAIL_NO_ERROR)
1276 return r;
1277 }
1278 else {
1279 r = mailimf_cache_int_write(mmapstr, index, CACHE_NOT_NULL);
1280 if (r != MAIL_NO_ERROR)
1281 return r;
1282
1283 r = mailimf_cache_int_write(mmapstr, index,
1284 clist_count(mb_list->mb_list));
1285 if (r != MAIL_NO_ERROR)
1286 return r;
1287
1288 for(cur = clist_begin(mb_list->mb_list) ; cur != NULL ;
1289 cur = clist_next(cur)) {
1290 struct mailimf_mailbox * mb;
1291
1292 mb = clist_content(cur);
1293
1294 r = mailimf_cache_mailbox_write(mmapstr, index, mb);
1295 if (r != MAIL_NO_ERROR)
1296 return r;
1297 }
1298 }
1299
1300 return MAIL_NO_ERROR;
1301}
1302
1303static int
1304mailimf_cache_mailbox_list_read(MMAPString * mmapstr, size_t * index,
1305 struct mailimf_mailbox_list ** result)
1306{
1307 clist * list;
1308 int r;
1309 uint32_t count;
1310 uint32_t i;
1311 struct mailimf_mailbox_list * mb_list;
1312 int res;
1313 uint32_t type;
1314
1315 r = mailimf_cache_int_read(mmapstr, index, &type);
1316 if (r != MAIL_NO_ERROR) {
1317 res = r;
1318 goto err;
1319 }
1320
1321 if (type == CACHE_NULL_POINTER) {
1322 * result = NULL;
1323 return MAIL_NO_ERROR;
1324 }
1325
1326 r = mailimf_cache_int_read(mmapstr, index, &count);
1327 if (r != MAIL_NO_ERROR) {
1328 res = r;
1329 goto err;
1330 }
1331
1332 list = clist_new();
1333 if (list == NULL) {
1334 res = MAIL_ERROR_MEMORY;
1335 goto err;
1336 }
1337
1338 for(i = 0 ; i < count ; i++) {
1339 struct mailimf_mailbox * mb;
1340
1341 r = mailimf_cache_mailbox_read(mmapstr, index, &mb);
1342 if (r != MAIL_NO_ERROR) {
1343 res = r;
1344 goto free_list;
1345 }
1346
1347 r = clist_append(list, mb);
1348 if (r < 0) {
1349 mailimf_mailbox_free(mb);
1350 res = MAIL_ERROR_MEMORY;
1351 goto free_list;
1352 }
1353 }
1354
1355 mb_list = mailimf_mailbox_list_new(list);
1356 if (mb_list == NULL) {
1357 res = MAIL_ERROR_MEMORY;
1358 goto free_list;
1359 }
1360
1361 * result = mb_list;
1362
1363 return MAIL_NO_ERROR;
1364
1365 free_list:
1366 clist_foreach(list, (clist_func) mailimf_mailbox_free, NULL);
1367 clist_free(list);
1368 err:
1369 return res;
1370}
1371
1372static int mailimf_cache_mailbox_write(MMAPString * mmapstr, size_t * index,
1373 struct mailimf_mailbox * mb)
1374{
1375 int r;
1376
1377 if (mb->mb_display_name) {
1378 r = mailimf_cache_string_write(mmapstr, index,
1379 mb->mb_display_name, strlen(mb->mb_display_name));
1380 if (r != MAIL_NO_ERROR)
1381 return r;
1382 }
1383 else {
1384 r = mailimf_cache_string_write(mmapstr, index, NULL, 0);
1385 if (r != MAIL_NO_ERROR)
1386 return r;
1387 }
1388
1389 r = mailimf_cache_string_write(mmapstr, index,
1390 mb->mb_addr_spec, strlen(mb->mb_addr_spec));
1391 if (r != MAIL_NO_ERROR)
1392 return r;
1393
1394 return MAIL_NO_ERROR;
1395}
1396
1397static int mailimf_cache_mailbox_read(MMAPString * mmapstr, size_t * index,
1398 struct mailimf_mailbox ** result)
1399{
1400 int r;
1401 char * dsp_name;
1402 char * addr_spec;
1403 struct mailimf_mailbox * mb;
1404
1405 dsp_name = NULL;
1406
1407 r = mailimf_cache_string_read(mmapstr, index, &dsp_name);
1408 if (r != MAIL_NO_ERROR)
1409 return r;
1410
1411 r = mailimf_cache_string_read(mmapstr, index, &addr_spec);
1412 if (r != MAIL_NO_ERROR)
1413 goto free_dsp_name;
1414
1415 mb = mailimf_mailbox_new(dsp_name, addr_spec);
1416 if (mb == NULL)
1417 goto free_addr;
1418
1419 * result = mb;
1420
1421 return MAIL_NO_ERROR;
1422
1423 free_addr:
1424 free(addr_spec);
1425 free_dsp_name:
1426 if (dsp_name != NULL)
1427 free(dsp_name);
1428 return MAIL_ERROR_MEMORY;
1429}