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