Diffstat (limited to 'kmicromail/libetpan/generic/imfcache.c') (more/less context) (ignore whitespace changes)
-rw-r--r-- | kmicromail/libetpan/generic/imfcache.c | 1429 |
1 files changed, 1429 insertions, 0 deletions
diff --git a/kmicromail/libetpan/generic/imfcache.c b/kmicromail/libetpan/generic/imfcache.c new file mode 100644 index 0000000..64983f4 --- a/dev/null +++ b/kmicromail/libetpan/generic/imfcache.c @@ -0,0 +1,1429 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#include "imfcache.h" + +#include <stdlib.h> +#include <string.h> + +static int mailimf_cache_field_write(MMAPString * mmapstr, size_t * index, + struct mailimf_field * field); +static int mailimf_cache_orig_date_write(MMAPString * mmapstr, size_t * index, + struct mailimf_orig_date * date); +static int mailimf_cache_date_time_write(MMAPString * mmapstr, size_t * index, + struct mailimf_date_time * date_time); +static int mailimf_cache_from_write(MMAPString * mmapstr, size_t * index, + struct mailimf_from * from); +static int mailimf_cache_sender_write(MMAPString * mmapstr, size_t * index, + struct mailimf_sender * sender); +static int mailimf_cache_reply_to_write(MMAPString * mmapstr, size_t * index, + struct mailimf_reply_to * reply_to); +static int mailimf_cache_to_write(MMAPString * mmapstr, size_t * index, + struct mailimf_to * to); +static int mailimf_cache_cc_write(MMAPString * mmapstr, size_t * index, + struct mailimf_cc * to); +static int mailimf_cache_bcc_write(MMAPString * mmapstr, size_t * index, + struct mailimf_bcc * to); +static int mailimf_cache_message_id_write(MMAPString * mmapstr, size_t * index, + struct mailimf_message_id * message_id); +static int mailimf_cache_msg_id_list_write(MMAPString * mmapstr, size_t * index, + clist * list); +static int mailimf_cache_in_reply_to_write(MMAPString * mmapstr, size_t * index, + struct mailimf_in_reply_to * + in_reply_to); +static int mailimf_cache_references_write(MMAPString * mmapstr, size_t * index, + struct mailimf_references * references); +static int mailimf_cache_subject_write(MMAPString * mmapstr, size_t * index, + struct mailimf_subject * subject); +static int mailimf_cache_address_list_write(MMAPString * mmapstr, + size_t * index, + struct mailimf_address_list * + addr_list); +static int mailimf_cache_address_write(MMAPString * mmapstr, size_t * index, + struct mailimf_address * addr); +static int mailimf_cache_group_write(MMAPString * mmapstr, size_t * index, + struct mailimf_group * group); +static int mailimf_cache_mailbox_list_write(MMAPString * mmapstr, + size_t * index, + struct mailimf_mailbox_list * mb_list); +static int mailimf_cache_mailbox_write(MMAPString * mmapstr, size_t * index, + struct mailimf_mailbox * mb); + + +static int mailimf_cache_field_read(MMAPString * mmapstr, size_t * index, + struct mailimf_field ** result); +static int mailimf_cache_orig_date_read(MMAPString * mmapstr, size_t * index, + struct mailimf_orig_date ** result); +static int mailimf_cache_date_time_read(MMAPString * mmapstr, size_t * index, + struct mailimf_date_time ** result); +static int mailimf_cache_from_read(MMAPString * mmapstr, size_t * index, + struct mailimf_from ** result); +static int mailimf_cache_sender_read(MMAPString * mmapstr, size_t * index, + struct mailimf_sender ** result); +static int mailimf_cache_reply_to_read(MMAPString * mmapstr, size_t * index, + struct mailimf_reply_to ** result); +static int mailimf_cache_to_read(MMAPString * mmapstr, size_t * index, + struct mailimf_to ** result); +static int mailimf_cache_cc_read(MMAPString * mmapstr, size_t * index, + struct mailimf_cc ** result); +static int mailimf_cache_bcc_read(MMAPString * mmapstr, size_t * index, + struct mailimf_bcc ** result); +static int mailimf_cache_message_id_read(MMAPString * mmapstr, size_t * index, + struct mailimf_message_id ** result); +static int mailimf_cache_msg_id_list_read(MMAPString * mmapstr, size_t * index, + clist ** result); +static int +mailimf_cache_in_reply_to_read(MMAPString * mmapstr, size_t * index, + struct mailimf_in_reply_to ** result); + +static int mailimf_cache_references_read(MMAPString * mmapstr, size_t * index, + struct mailimf_references ** result); +static int mailimf_cache_subject_read(MMAPString * mmapstr, size_t * index, + struct mailimf_subject ** result); +static int mailimf_cache_address_list_read(MMAPString * mmapstr, size_t * index, + struct mailimf_address_list ** result); +static int mailimf_cache_address_read(MMAPString * mmapstr, size_t * index, + struct mailimf_address ** result); +static int mailimf_cache_group_read(MMAPString * mmapstr, size_t * index, + struct mailimf_group ** result); +static int +mailimf_cache_mailbox_list_read(MMAPString * mmapstr, size_t * index, + struct mailimf_mailbox_list ** result); +static int mailimf_cache_mailbox_read(MMAPString * mmapstr, size_t * index, + struct mailimf_mailbox ** result); + +enum { + CACHE_NULL_POINTER = 0, + CACHE_NOT_NULL = 1, +}; + +int mail_serialize_clear(MMAPString * mmapstr, size_t * index) +{ + if (mmap_string_set_size(mmapstr, 0) == NULL) + return MAIL_ERROR_MEMORY; + + * index = 0; + + return MAIL_NO_ERROR; +} + +int mail_serialize_write(MMAPString * mmapstr, size_t * index, + char * buf, size_t size) +{ + if (mmap_string_append_len(mmapstr, buf, size) == NULL) + return MAIL_ERROR_MEMORY; + + * index = * index + size; + + return MAIL_NO_ERROR; +} + +int mail_serialize_read(MMAPString * mmapstr, size_t * index, + char * buf, size_t size) +{ + size_t cur_token; + + cur_token = * index; + + if (cur_token + size > mmapstr->len) + return MAIL_ERROR_STREAM; + + memcpy(buf, mmapstr->str + cur_token, size); + * index = cur_token + size; + + return MAIL_NO_ERROR; +} + +int mailimf_cache_int_write(MMAPString * mmapstr, size_t * index, + uint32_t value) +{ + unsigned char ch; + int r; + int i; + + for(i = 0 ; i < 4 ; i ++) { + ch = value % 256; + + r = mail_serialize_write(mmapstr, index, &ch, 1); + if (r != MAIL_NO_ERROR) + return r; + value /= 256; + } + + return MAIL_NO_ERROR; +} + +int mailimf_cache_int_read(MMAPString * mmapstr, size_t * index, + uint32_t * result) +{ + unsigned char ch; + uint32_t value; + int i; + int r; + + value = 0; + for(i = 0 ; i < 4 ; i ++) { + r = mail_serialize_read(mmapstr, index, &ch, 1); + if (r != MAIL_NO_ERROR) + return r; + value = value | ch << (i << 3); + } + + * result = value; + + return MAIL_NO_ERROR; +} + + +int mailimf_cache_string_write(MMAPString * mmapstr, size_t * index, + char * str, size_t length) +{ + int r; + + if (str == NULL) { + r = mailimf_cache_int_write(mmapstr, index, CACHE_NULL_POINTER); + if (r != MAIL_NO_ERROR) + return r; + } + else { + r = mailimf_cache_int_write(mmapstr, index, CACHE_NOT_NULL); + if (r != MAIL_NO_ERROR) + return r; + + r = mailimf_cache_int_write(mmapstr, index, length); + if (r != MAIL_NO_ERROR) + return r; + + if (length != 0) { + r = mail_serialize_write(mmapstr, index, str, length); + if (r != MAIL_NO_ERROR) + return MAIL_ERROR_FILE; + } + } + + return MAIL_NO_ERROR; +} + +int mailimf_cache_string_read(MMAPString * mmapstr, size_t * index, + char ** result) +{ + int r; + uint32_t length; + char * str; + uint32_t type; + + r = mailimf_cache_int_read(mmapstr, index, &type); + if (r != MAIL_NO_ERROR) + return r; + + if (type == CACHE_NULL_POINTER) { + str = NULL; + } + else { + r = mailimf_cache_int_read(mmapstr, index, &length); + if (r != MAIL_NO_ERROR) + return r; + + str = malloc(length + 1); + if (str == NULL) + return MAIL_ERROR_MEMORY; + + r = mail_serialize_read(mmapstr, index, str, length); + if (r != MAIL_NO_ERROR) + return MAIL_ERROR_FILE; + + str[length] = 0; + } + + * result = str; + + return MAIL_NO_ERROR; +} + +int mailimf_cache_fields_write(MMAPString * mmapstr, size_t * index, + struct mailimf_fields * fields) +{ + clistiter * cur; + int r; + + r = mailimf_cache_int_write(mmapstr, index, + clist_count(fields->fld_list)); + if (r != MAIL_NO_ERROR) + return r; + + for(cur = clist_begin(fields->fld_list) ; cur != NULL ; + cur = clist_next(cur)) { + r = mailimf_cache_field_write(mmapstr, index, clist_content(cur)); + if (r != MAIL_NO_ERROR) + return r; + } + + return MAIL_NO_ERROR; +} + +int mailimf_cache_fields_read(MMAPString * mmapstr, size_t * index, + struct mailimf_fields ** result) +{ + clist * list; + int r; + uint32_t count; + uint32_t i; + struct mailimf_fields * fields; + int res; + + r = mailimf_cache_int_read(mmapstr, index, &count); + if (r != MAIL_NO_ERROR) { + res = r; + goto err; + } + + list = clist_new(); + if (list == NULL) { + res = MAIL_ERROR_MEMORY; + goto err; + } + + for(i = 0 ; i < count ; i++) { + struct mailimf_field * field; + + r = mailimf_cache_field_read(mmapstr, index, &field); + if (r != MAIL_NO_ERROR) { + res = r; + goto free_list; + } + + r = clist_append(list, field); + if (r < 0) { + mailimf_field_free(field); + res = MAIL_ERROR_MEMORY; + goto free_list; + } + } + + fields = mailimf_fields_new(list); + if (fields == NULL) { + res = MAIL_ERROR_MEMORY; + goto free_list; + } + + * result = fields; + + return MAIL_NO_ERROR; + + free_list: + clist_foreach(list, (clist_func) mailimf_field_free, NULL); + clist_free(list); + err: + return res; +} + + +static int mailimf_cache_field_write(MMAPString * mmapstr, size_t * index, + struct mailimf_field * field) +{ + int r; + + r = mailimf_cache_int_write(mmapstr, index, field->fld_type); + if (r != MAIL_NO_ERROR) + return r; + + switch (field->fld_type) { + case MAILIMF_FIELD_ORIG_DATE: + r = mailimf_cache_orig_date_write(mmapstr, index, + field->fld_data.fld_orig_date); + break; + case MAILIMF_FIELD_FROM: + r = mailimf_cache_from_write(mmapstr, index, + field->fld_data.fld_from); + break; + case MAILIMF_FIELD_SENDER: + r = mailimf_cache_sender_write(mmapstr, index, + field->fld_data.fld_sender); + break; + case MAILIMF_FIELD_REPLY_TO: + r = mailimf_cache_reply_to_write(mmapstr, index, + field->fld_data.fld_reply_to); + break; + case MAILIMF_FIELD_TO: + r = mailimf_cache_to_write(mmapstr, index, + field->fld_data.fld_to); + break; + case MAILIMF_FIELD_CC: + r = mailimf_cache_cc_write(mmapstr, index, + field->fld_data.fld_cc); + break; + case MAILIMF_FIELD_BCC: + r = mailimf_cache_bcc_write(mmapstr, index, + field->fld_data.fld_bcc); + break; + case MAILIMF_FIELD_MESSAGE_ID: + r = mailimf_cache_message_id_write(mmapstr, index, + field->fld_data.fld_message_id); + break; + case MAILIMF_FIELD_IN_REPLY_TO: + r = mailimf_cache_in_reply_to_write(mmapstr, index, + field->fld_data.fld_in_reply_to); + break; + case MAILIMF_FIELD_REFERENCES: + r = mailimf_cache_references_write(mmapstr, index, + field->fld_data.fld_references); + break; + case MAILIMF_FIELD_SUBJECT: + r = mailimf_cache_subject_write(mmapstr, index, + field->fld_data.fld_subject); + break; + default: + r = 0; + break; + } + + if (r != MAIL_NO_ERROR) + return r; + + return MAIL_NO_ERROR; +} + + +static int mailimf_cache_field_read(MMAPString * mmapstr, size_t * index, + struct mailimf_field ** result) +{ + int r; + uint32_t type; + struct mailimf_orig_date * orig_date; + struct mailimf_from * from; + struct mailimf_sender * sender; + struct mailimf_to * to; + struct mailimf_reply_to * reply_to; + struct mailimf_cc * cc; + struct mailimf_bcc * bcc; + struct mailimf_message_id * message_id; + struct mailimf_in_reply_to * in_reply_to; + struct mailimf_references * references; + struct mailimf_subject * subject; + struct mailimf_field * field; + int res; + + orig_date = NULL; + from = NULL; + sender = NULL; + to = NULL; + reply_to = NULL; + cc = NULL; + bcc = NULL; + message_id = NULL; + in_reply_to = NULL; + references = NULL; + subject = NULL; + field = NULL; + + r = mailimf_cache_int_read(mmapstr, index, &type); + if (r != MAIL_NO_ERROR) { + res = r; + goto err; + } + + switch (type) { + case MAILIMF_FIELD_ORIG_DATE: + r = mailimf_cache_orig_date_read(mmapstr, index, &orig_date); + break; + case MAILIMF_FIELD_FROM: + r = mailimf_cache_from_read(mmapstr, index, &from); + break; + case MAILIMF_FIELD_SENDER: + r = mailimf_cache_sender_read(mmapstr, index, &sender); + break; + case MAILIMF_FIELD_REPLY_TO: + r = mailimf_cache_reply_to_read(mmapstr, index, &reply_to); + break; + case MAILIMF_FIELD_TO: + r = mailimf_cache_to_read(mmapstr, index, &to); + break; + case MAILIMF_FIELD_CC: + r = mailimf_cache_cc_read(mmapstr, index, &cc); + break; + case MAILIMF_FIELD_BCC: + r = mailimf_cache_bcc_read(mmapstr, index, &bcc); + break; + case MAILIMF_FIELD_MESSAGE_ID: + r = mailimf_cache_message_id_read(mmapstr, index, &message_id); + break; + case MAILIMF_FIELD_IN_REPLY_TO: + r = mailimf_cache_in_reply_to_read(mmapstr, index, &in_reply_to); + break; + case MAILIMF_FIELD_REFERENCES: + r = mailimf_cache_references_read(mmapstr, index, &references); + break; + case MAILIMF_FIELD_SUBJECT: + r = mailimf_cache_subject_read(mmapstr, index, &subject); + break; + default: + r = MAIL_ERROR_INVAL; + break; + } + + if (r != MAIL_NO_ERROR) { + res = r; + goto free; + } + + field = mailimf_field_new(type, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, orig_date, from, sender, reply_to, + to, cc, bcc, message_id, + in_reply_to, references, + subject, NULL, NULL, NULL); + if (field == NULL) { + res = MAIL_ERROR_MEMORY; + goto free; + } + + * result = field; + + return MAIL_NO_ERROR; + + free: + if (orig_date != NULL) + mailimf_orig_date_free(orig_date); + if (from != NULL) + mailimf_from_free(from); + if (sender != NULL) + mailimf_sender_free(sender); + if (reply_to != NULL) + mailimf_reply_to_free(reply_to); + if (to != NULL) + mailimf_to_free(to); + if (cc != NULL) + mailimf_cc_free(cc); + if (bcc != NULL) + mailimf_bcc_free(bcc); + if (message_id != NULL) + mailimf_message_id_free(message_id); + if (in_reply_to != NULL) + mailimf_in_reply_to_free(in_reply_to); + if (references != NULL) + mailimf_references_free(references); + if (subject != NULL) + mailimf_subject_free(subject); + err: + return res; +} + +static int mailimf_cache_orig_date_write(MMAPString * mmapstr, size_t * index, + struct mailimf_orig_date * date) +{ + return mailimf_cache_date_time_write(mmapstr, index, date->dt_date_time); +} + +static int mailimf_cache_orig_date_read(MMAPString * mmapstr, size_t * index, + struct mailimf_orig_date ** result) +{ + int r; + struct mailimf_date_time * date_time; + struct mailimf_orig_date * orig_date; + + r = mailimf_cache_date_time_read(mmapstr, index, &date_time); + if (r != MAIL_NO_ERROR) + return r; + + orig_date = mailimf_orig_date_new(date_time); + if (orig_date == NULL) { + mailimf_date_time_free(date_time); + return MAIL_ERROR_MEMORY; + } + + * result = orig_date; + + return MAIL_NO_ERROR; +} + +static int mailimf_cache_date_time_write(MMAPString * mmapstr, size_t * index, + struct mailimf_date_time * date_time) +{ + int r; + + r = mailimf_cache_int_write(mmapstr, index, date_time->dt_day); + if (r != MAIL_NO_ERROR) + return r; + + r = mailimf_cache_int_write(mmapstr, index, date_time->dt_month); + if (r != MAIL_NO_ERROR) + return r; + + r = mailimf_cache_int_write(mmapstr, index, date_time->dt_year); + if (r != MAIL_NO_ERROR) + return r; + + r = mailimf_cache_int_write(mmapstr, index, date_time->dt_hour); + if (r != MAIL_NO_ERROR) + return r; + + r = mailimf_cache_int_write(mmapstr, index, date_time->dt_min); + if (r != MAIL_NO_ERROR) + return r; + + r = mailimf_cache_int_write(mmapstr, index, date_time->dt_sec); + if (r != MAIL_NO_ERROR) + return r; + + r = mailimf_cache_int_write(mmapstr, index, date_time->dt_zone); + if (r != MAIL_NO_ERROR) + return r; + + return MAIL_NO_ERROR; +} + +static int mailimf_cache_date_time_read(MMAPString * mmapstr, size_t * index, + struct mailimf_date_time ** result) +{ + int r; + uint32_t day; + uint32_t month; + uint32_t year; + uint32_t hour; + uint32_t min; + uint32_t sec; + uint32_t zone; + struct mailimf_date_time * date_time; + + r = mailimf_cache_int_read(mmapstr, index, &day); + if (r != MAIL_NO_ERROR) + return r; + + r = mailimf_cache_int_read(mmapstr, index, &month); + if (r != MAIL_NO_ERROR) + return r; + + r = mailimf_cache_int_read(mmapstr, index, &year); + if (r != MAIL_NO_ERROR) + return r; + + r = mailimf_cache_int_read(mmapstr, index, &hour); + if (r != MAIL_NO_ERROR) + return r; + + r = mailimf_cache_int_read(mmapstr, index, &min); + if (r != MAIL_NO_ERROR) + return r; + + r = mailimf_cache_int_read(mmapstr, index, &sec); + if (r != MAIL_NO_ERROR) + return r; + + r = mailimf_cache_int_read(mmapstr, index, &zone); + if (r != MAIL_NO_ERROR) + return r; + + date_time = mailimf_date_time_new(day, month, year, hour, min, sec, zone); + if (date_time == NULL) + return MAIL_ERROR_MEMORY; + + * result = date_time; + + return MAIL_NO_ERROR; + +} + + +static int mailimf_cache_from_write(MMAPString * mmapstr, size_t * index, + struct mailimf_from * from) +{ + return mailimf_cache_mailbox_list_write(mmapstr, index, from->frm_mb_list); +} + +static int mailimf_cache_from_read(MMAPString * mmapstr, size_t * index, + struct mailimf_from ** result) +{ + struct mailimf_mailbox_list * mb_list; + struct mailimf_from * from; + int r; + + r = mailimf_cache_mailbox_list_read(mmapstr, index, &mb_list); + if (r != MAIL_NO_ERROR) + return r; + + from = mailimf_from_new(mb_list); + if (from == NULL) { + mailimf_mailbox_list_free(mb_list); + return MAIL_ERROR_MEMORY; + } + + * result = from; + + return MAIL_NO_ERROR; +} + +static int mailimf_cache_sender_write(MMAPString * mmapstr, size_t * index, + struct mailimf_sender * sender) +{ + return mailimf_cache_mailbox_write(mmapstr, index, sender->snd_mb); +} + +static int mailimf_cache_sender_read(MMAPString * mmapstr, size_t * index, + struct mailimf_sender ** result) +{ + int r; + struct mailimf_mailbox * mb; + struct mailimf_sender * sender; + + r = mailimf_cache_mailbox_read(mmapstr, index, &mb); + if (r != MAIL_NO_ERROR) + return r; + + sender = mailimf_sender_new(mb); + if (sender == NULL) { + mailimf_mailbox_free(mb); + return MAIL_ERROR_MEMORY; + } + + * result = sender; + + return MAIL_NO_ERROR; +} + +static int mailimf_cache_reply_to_write(MMAPString * mmapstr, size_t * index, + struct mailimf_reply_to * reply_to) +{ + return mailimf_cache_address_list_write(mmapstr, index, + reply_to->rt_addr_list); +} + +static int mailimf_cache_reply_to_read(MMAPString * mmapstr, size_t * index, + struct mailimf_reply_to ** result) +{ + int r; + struct mailimf_address_list * addr_list; + struct mailimf_reply_to * reply_to; + + r = mailimf_cache_address_list_read(mmapstr, index, &addr_list); + if (r != MAIL_NO_ERROR) + return r; + + reply_to = mailimf_reply_to_new(addr_list); + if (reply_to == NULL) { + mailimf_address_list_free(addr_list); + return MAIL_ERROR_MEMORY; + } + + * result = reply_to; + + return MAIL_NO_ERROR; +} + +static int mailimf_cache_to_write(MMAPString * mmapstr, size_t * index, + struct mailimf_to * to) +{ + return mailimf_cache_address_list_write(mmapstr, index, to->to_addr_list); +} + +static int mailimf_cache_to_read(MMAPString * mmapstr, size_t * index, + struct mailimf_to ** result) +{ + int r; + struct mailimf_address_list * addr_list; + struct mailimf_to * to; + + r = mailimf_cache_address_list_read(mmapstr, index, &addr_list); + if (r != MAIL_NO_ERROR) + return r; + + to = mailimf_to_new(addr_list); + if (to == NULL) { + mailimf_address_list_free(addr_list); + return MAIL_ERROR_MEMORY; + } + + * result = to; + + return MAIL_NO_ERROR; +} + +static int mailimf_cache_cc_write(MMAPString * mmapstr, size_t * index, + struct mailimf_cc * cc) +{ + return mailimf_cache_address_list_write(mmapstr, index, cc->cc_addr_list); +} + +static int mailimf_cache_cc_read(MMAPString * mmapstr, size_t * index, + struct mailimf_cc ** result) +{ + int r; + struct mailimf_address_list * addr_list; + struct mailimf_cc * cc; + + r = mailimf_cache_address_list_read(mmapstr, index, &addr_list); + if (r != MAIL_NO_ERROR) + return r; + + cc = mailimf_cc_new(addr_list); + if (cc == NULL) { + mailimf_address_list_free(addr_list); + return MAIL_ERROR_MEMORY; + } + + * result = cc; + + return MAIL_NO_ERROR; +} + +static int mailimf_cache_bcc_write(MMAPString * mmapstr, size_t * index, + struct mailimf_bcc * bcc) +{ + return mailimf_cache_address_list_write(mmapstr, index, bcc->bcc_addr_list); +} + +static int mailimf_cache_bcc_read(MMAPString * mmapstr, size_t * index, + struct mailimf_bcc ** result) +{ + int r; + struct mailimf_address_list * addr_list; + struct mailimf_bcc * bcc; + + r = mailimf_cache_address_list_read(mmapstr, index, &addr_list); + if (r != MAIL_NO_ERROR) + return r; + + bcc = mailimf_bcc_new(addr_list); + if (bcc == NULL) { + mailimf_address_list_free(addr_list); + return MAIL_ERROR_MEMORY; + } + + * result = bcc; + + return MAIL_NO_ERROR; +} + +static int +mailimf_cache_message_id_write(MMAPString * mmapstr, size_t * index, + struct mailimf_message_id * message_id) +{ + return mailimf_cache_string_write(mmapstr, index, + message_id->mid_value, strlen(message_id->mid_value)); +} + +static int mailimf_cache_message_id_read(MMAPString * mmapstr, size_t * index, + struct mailimf_message_id ** result) +{ + struct mailimf_message_id * message_id; + char * str; + int r; + + r = mailimf_cache_string_read(mmapstr, index, &str); + if (r != MAIL_NO_ERROR) + return r; + + message_id = mailimf_message_id_new(str); + if (message_id == NULL) { + free(str); + return MAIL_ERROR_MEMORY; + } + + * result = message_id; + + return MAIL_NO_ERROR; +} + +static int +mailimf_cache_msg_id_list_write(MMAPString * mmapstr, size_t * index, + clist * list) +{ + clistiter * cur; + int r; + + r = mailimf_cache_int_write(mmapstr, index, clist_count(list)); + if (r != MAIL_NO_ERROR) + return r; + + for(cur = clist_begin(list) ; cur != NULL ; cur = clist_next(cur)) { + char * msgid; + + msgid = clist_content(cur); + + r = mailimf_cache_string_write(mmapstr, index, msgid, strlen(msgid)); + if (r != MAIL_NO_ERROR) + return r; + } + + return MAIL_NO_ERROR; +} + +static int mailimf_cache_msg_id_list_read(MMAPString * mmapstr, size_t * index, + clist ** result) +{ + clist * list; + int r; + uint32_t count; + uint32_t i; + int res; + + r = mailimf_cache_int_read(mmapstr, index, &count); + if (r != MAIL_NO_ERROR) { + res = r; + goto err; + } + + list = clist_new(); + if (list == NULL) { + res = MAIL_ERROR_MEMORY; + goto err; + } + + for(i = 0 ; i < count ; i++) { + char * msgid; + + r = mailimf_cache_string_read(mmapstr, index, &msgid); + if (r != MAIL_NO_ERROR) { + res = r; + goto err; + } + + r = clist_append(list, msgid); + if (r < 0) { + free(msgid); + res = MAIL_ERROR_MEMORY; + goto free_list; + } + } + + * result = list; + + return MAIL_NO_ERROR; + + free_list: + clist_foreach(list, (clist_func) free, NULL); + clist_free(list); + err: + return res; +} + +static int +mailimf_cache_in_reply_to_write(MMAPString * mmapstr, size_t * index, + struct mailimf_in_reply_to * in_reply_to) +{ + return mailimf_cache_msg_id_list_write(mmapstr, index, + in_reply_to->mid_list); +} + +static int mailimf_cache_in_reply_to_read(MMAPString * mmapstr, size_t * index, + struct mailimf_in_reply_to ** result) +{ + int r; + clist * msg_id_list; + struct mailimf_in_reply_to * in_reply_to; + + r = mailimf_cache_msg_id_list_read(mmapstr, index, &msg_id_list); + if (r != MAIL_NO_ERROR) + return r; + + in_reply_to = mailimf_in_reply_to_new(msg_id_list); + if (in_reply_to == NULL) { + clist_foreach(msg_id_list, (clist_func) free, NULL); + clist_free(msg_id_list); + return MAIL_ERROR_MEMORY; + } + + * result = in_reply_to; + + return MAIL_NO_ERROR; +} + +static int mailimf_cache_references_write(MMAPString * mmapstr, size_t * index, + struct mailimf_references * references) +{ + return mailimf_cache_msg_id_list_write(mmapstr, index, + references->mid_list); +} + +static int mailimf_cache_references_read(MMAPString * mmapstr, size_t * index, + struct mailimf_references ** result) +{ + int r; + clist * msg_id_list; + struct mailimf_references * references; + + r = mailimf_cache_msg_id_list_read(mmapstr, index, &msg_id_list); + if (r != MAIL_NO_ERROR) + return r; + + references = mailimf_references_new(msg_id_list); + if (references == NULL) { + clist_foreach(msg_id_list, (clist_func) free, NULL); + clist_free(msg_id_list); + return MAIL_ERROR_MEMORY; + } + + * result = references; + + return MAIL_NO_ERROR; +} + + +static int mailimf_cache_subject_write(MMAPString * mmapstr, size_t * index, + struct mailimf_subject * subject) +{ + return mailimf_cache_string_write(mmapstr, index, + subject->sbj_value, strlen(subject->sbj_value)); +} + +static int mailimf_cache_subject_read(MMAPString * mmapstr, size_t * index, + struct mailimf_subject ** result) +{ + char * str; + struct mailimf_subject * subject; + int r; + + r = mailimf_cache_string_read(mmapstr, index, &str); + if (r != MAIL_NO_ERROR) + return r; + + if (str == NULL) { + str = strdup(""); + if (str == NULL) + return MAIL_ERROR_MEMORY; + } + + subject = mailimf_subject_new(str); + if (subject == NULL) { + free(str); + return MAIL_ERROR_MEMORY; + } + + * result = subject; + + return MAIL_NO_ERROR; +} + + +static int +mailimf_cache_address_list_write(MMAPString * mmapstr, size_t * index, + struct mailimf_address_list * addr_list) +{ + clistiter * cur; + int r; + + if (addr_list == NULL) { + r = mailimf_cache_int_write(mmapstr, index, CACHE_NULL_POINTER); + if (r != MAIL_NO_ERROR) + return r; + } + else { + r = mailimf_cache_int_write(mmapstr, index, CACHE_NOT_NULL); + if (r != MAIL_NO_ERROR) + return r; + + r = mailimf_cache_int_write(mmapstr, index, + clist_count(addr_list->ad_list)); + if (r != MAIL_NO_ERROR) + return r; + + for(cur = clist_begin(addr_list->ad_list) ; cur != NULL ; + cur = clist_next(cur)) { + struct mailimf_address * addr; + + addr = clist_content(cur); + + r = mailimf_cache_address_write(mmapstr, index, addr); + if (r != MAIL_NO_ERROR) + return r; + } + } + + return MAIL_NO_ERROR; +} + +static int +mailimf_cache_address_list_read(MMAPString * mmapstr, size_t * index, + struct mailimf_address_list ** result) +{ + struct mailimf_address_list * addr_list; + uint32_t count; + uint32_t i; + int r; + clist * list; + int res; + uint32_t type; + + r = mailimf_cache_int_read(mmapstr, index, &type); + if (r != MAIL_NO_ERROR) { + res = r; + goto err; + } + + if (type == CACHE_NULL_POINTER) { + * result = NULL; + return MAIL_NO_ERROR; + } + + r = mailimf_cache_int_read(mmapstr, index, &count); + if (r != MAIL_NO_ERROR) { + res = r; + goto err; + } + + list = clist_new(); + if (list == NULL) { + res = MAIL_ERROR_MEMORY; + goto err; + } + + for(i = 0 ; i < count ; i++) { + struct mailimf_address * addr; + + r = mailimf_cache_address_read(mmapstr, index, &addr); + if (r != MAIL_NO_ERROR) { + res = r; + goto free_list; + } + + r = clist_append(list, addr); + if (r < 0) { + mailimf_address_free(addr); + res = MAIL_ERROR_MEMORY; + goto free_list; + } + } + + addr_list = mailimf_address_list_new(list); + if (addr_list == NULL) { + res = MAIL_ERROR_MEMORY; + goto free_list; + } + + * result = addr_list; + + return MAIL_NO_ERROR; + + free_list: + clist_foreach(list, (clist_func) mailimf_address_free, NULL); + clist_free(list); + err: + return res; +} + +static int mailimf_cache_address_write(MMAPString * mmapstr, size_t * index, + struct mailimf_address * addr) +{ + int r; + + r = mailimf_cache_int_write(mmapstr, index, addr->ad_type); + if (r != MAIL_NO_ERROR) + return r; + + switch(addr->ad_type) { + case MAILIMF_ADDRESS_MAILBOX: + r = mailimf_cache_mailbox_write(mmapstr, index, addr->ad_data.ad_mailbox); + if (r != MAIL_NO_ERROR) + return r; + + break; + + case MAILIMF_ADDRESS_GROUP: + r = mailimf_cache_group_write(mmapstr, index, addr->ad_data.ad_group); + if (r != MAIL_NO_ERROR) + return r; + + break; + } + + return MAIL_NO_ERROR; +} + +static int mailimf_cache_address_read(MMAPString * mmapstr, size_t * index, + struct mailimf_address ** result) +{ + uint32_t type; + int r; + struct mailimf_mailbox * mailbox; + struct mailimf_group * group; + struct mailimf_address * addr; + + r = mailimf_cache_int_read(mmapstr, index, &type); + if (r != MAIL_NO_ERROR) + return r; + + mailbox = NULL; + group = NULL; + + switch (type) { + case MAILIMF_ADDRESS_MAILBOX: + r = mailimf_cache_mailbox_read(mmapstr, index, &mailbox); + if (r != MAIL_NO_ERROR) + return r; + + break; + + case MAILIMF_ADDRESS_GROUP: + r = mailimf_cache_group_read(mmapstr, index, &group); + if (r != MAIL_NO_ERROR) + return r; + + break; + } + + addr = mailimf_address_new(type, mailbox, group); + if (addr == NULL) + goto free; + + * result = addr; + + return MAIL_NO_ERROR; + + free: + if (mailbox != NULL) + mailimf_mailbox_free(mailbox); + if (group != NULL) + mailimf_group_free(group); + return MAIL_ERROR_MEMORY; +} + +static int mailimf_cache_group_write(MMAPString * mmapstr, size_t * index, + struct mailimf_group * group) +{ + int r; + + r = mailimf_cache_string_write(mmapstr, index, group->grp_display_name, + strlen(group->grp_display_name)); + if (r != MAIL_NO_ERROR) + return r; + + r = mailimf_cache_mailbox_list_write(mmapstr, index, group->grp_mb_list); + if (r != MAIL_NO_ERROR) + return r; + + return MAIL_NO_ERROR; +} + +static int mailimf_cache_group_read(MMAPString * mmapstr, size_t * index, + struct mailimf_group ** result) +{ + int r; + char * display_name; + struct mailimf_mailbox_list * mb_list; + struct mailimf_group * group; + int res; + + r = mailimf_cache_string_read(mmapstr, index, &display_name); + if (r != MAIL_NO_ERROR) { + res = r; + goto err; + } + + r = mailimf_cache_mailbox_list_read(mmapstr, index, &mb_list); + if (r != MAIL_NO_ERROR) { + res = r; + goto free_dsp_name; + } + + group = mailimf_group_new(display_name, mb_list); + if (group == NULL) { + res = MAIL_ERROR_MEMORY; + goto free_mb_list; + } + + * result = group; + + return MAIL_NO_ERROR; + + free_mb_list: + mailimf_mailbox_list_free(mb_list); + free_dsp_name: + free(display_name); + err: + return res; +} + +static int +mailimf_cache_mailbox_list_write(MMAPString * mmapstr, size_t * index, + struct mailimf_mailbox_list * mb_list) +{ + clistiter * cur; + int r; + + if (mb_list == NULL) { + r = mailimf_cache_int_write(mmapstr, index, CACHE_NULL_POINTER); + if (r != MAIL_NO_ERROR) + return r; + } + else { + r = mailimf_cache_int_write(mmapstr, index, CACHE_NOT_NULL); + if (r != MAIL_NO_ERROR) + return r; + + r = mailimf_cache_int_write(mmapstr, index, + clist_count(mb_list->mb_list)); + if (r != MAIL_NO_ERROR) + return r; + + for(cur = clist_begin(mb_list->mb_list) ; cur != NULL ; + cur = clist_next(cur)) { + struct mailimf_mailbox * mb; + + mb = clist_content(cur); + + r = mailimf_cache_mailbox_write(mmapstr, index, mb); + if (r != MAIL_NO_ERROR) + return r; + } + } + + return MAIL_NO_ERROR; +} + +static int +mailimf_cache_mailbox_list_read(MMAPString * mmapstr, size_t * index, + struct mailimf_mailbox_list ** result) +{ + clist * list; + int r; + uint32_t count; + uint32_t i; + struct mailimf_mailbox_list * mb_list; + int res; + uint32_t type; + + r = mailimf_cache_int_read(mmapstr, index, &type); + if (r != MAIL_NO_ERROR) { + res = r; + goto err; + } + + if (type == CACHE_NULL_POINTER) { + * result = NULL; + return MAIL_NO_ERROR; + } + + r = mailimf_cache_int_read(mmapstr, index, &count); + if (r != MAIL_NO_ERROR) { + res = r; + goto err; + } + + list = clist_new(); + if (list == NULL) { + res = MAIL_ERROR_MEMORY; + goto err; + } + + for(i = 0 ; i < count ; i++) { + struct mailimf_mailbox * mb; + + r = mailimf_cache_mailbox_read(mmapstr, index, &mb); + if (r != MAIL_NO_ERROR) { + res = r; + goto free_list; + } + + r = clist_append(list, mb); + if (r < 0) { + mailimf_mailbox_free(mb); + res = MAIL_ERROR_MEMORY; + goto free_list; + } + } + + mb_list = mailimf_mailbox_list_new(list); + if (mb_list == NULL) { + res = MAIL_ERROR_MEMORY; + goto free_list; + } + + * result = mb_list; + + return MAIL_NO_ERROR; + + free_list: + clist_foreach(list, (clist_func) mailimf_mailbox_free, NULL); + clist_free(list); + err: + return res; +} + +static int mailimf_cache_mailbox_write(MMAPString * mmapstr, size_t * index, + struct mailimf_mailbox * mb) +{ + int r; + + if (mb->mb_display_name) { + r = mailimf_cache_string_write(mmapstr, index, + mb->mb_display_name, strlen(mb->mb_display_name)); + if (r != MAIL_NO_ERROR) + return r; + } + else { + r = mailimf_cache_string_write(mmapstr, index, NULL, 0); + if (r != MAIL_NO_ERROR) + return r; + } + + r = mailimf_cache_string_write(mmapstr, index, + mb->mb_addr_spec, strlen(mb->mb_addr_spec)); + if (r != MAIL_NO_ERROR) + return r; + + return MAIL_NO_ERROR; +} + +static int mailimf_cache_mailbox_read(MMAPString * mmapstr, size_t * index, + struct mailimf_mailbox ** result) +{ + int r; + char * dsp_name; + char * addr_spec; + struct mailimf_mailbox * mb; + + dsp_name = NULL; + + r = mailimf_cache_string_read(mmapstr, index, &dsp_name); + if (r != MAIL_NO_ERROR) + return r; + + r = mailimf_cache_string_read(mmapstr, index, &addr_spec); + if (r != MAIL_NO_ERROR) + goto free_dsp_name; + + mb = mailimf_mailbox_new(dsp_name, addr_spec); + if (mb == NULL) + goto free_addr; + + * result = mb; + + return MAIL_NO_ERROR; + + free_addr: + free(addr_spec); + free_dsp_name: + if (dsp_name != NULL) + free(dsp_name); + return MAIL_ERROR_MEMORY; +} |