Mercurial > dovecot > original-hg > dovecot-1.2
changeset 6280:eb7c9d8ece54 HEAD
mail_*() APIs changed to return int and return the actual data as pointer.
Changed some code to do error handling a bit better.
line wrap: on
line diff
--- a/src/deliver/deliver.c Sun Aug 12 18:16:40 2007 +0300 +++ b/src/deliver/deliver.c Sun Aug 12 19:40:54 2007 +0300 @@ -152,8 +152,10 @@ else ret = mailbox_transaction_commit(&t, 0); - msgid = mail_get_first_header(mail, "Message-ID"); - msgid = msgid == NULL ? "" : str_sanitize(msgid, 80); + if (mail_get_first_header(mail, "Message-ID", &msgid) <= 0) + msgid = ""; + else + msgid = str_sanitize(msgid, 80); mailbox_name = str_sanitize(mailbox_get_name(box), 80); if (ret == 0) { @@ -175,11 +177,11 @@ struct message_address *addr; const char *str; - str = mail_get_first_header(mail, "Return-Path"); - addr = str == NULL ? NULL : - message_address_parse(pool_datastack_create(), - (const unsigned char *)str, - strlen(str), 1, FALSE); + if (mail_get_first_header(mail, "Return-Path", &str) <= 0) + return NULL; + addr = message_address_parse(pool_datastack_create(), + (const unsigned char *)str, + strlen(str), 1, FALSE); return addr == NULL || addr->mailbox == NULL || addr->domain == NULL || *addr->mailbox == '\0' || *addr->domain == '\0' ? NULL : t_strconcat(addr->mailbox, "@", addr->domain, NULL); @@ -799,9 +801,9 @@ return EX_TEMPFAIL; } - msgid = mail_get_first_header(mail, "Message-ID"); - i_info("msgid=%s: Rejected: %s", - msgid == NULL ? "" : str_sanitize(msgid, 80), + if (mail_get_first_header(mail, "Message-ID", &msgid) <= 0) + msgid = ""; + i_info("msgid=%s: Rejected: %s", str_sanitize(msgid, 80), str_sanitize(error_string, 512)); /* we'll have to reply with permanent failure */
--- a/src/deliver/mail-send.c Sun Aug 12 18:16:40 2007 +0300 +++ b/src/deliver/mail-send.c Sun Aug 12 19:40:54 2007 +0300 @@ -31,13 +31,16 @@ { '\0', NULL } }; struct var_expand_table *tab; + const char *subject; tab = t_malloc(sizeof(static_tab)); memcpy(tab, static_tab, sizeof(static_tab)); tab[0].value = "\r\n"; tab[1].value = reason; - tab[2].value = str_sanitize(mail_get_first_header(mail, "Subject"), 80); + if (mail_get_first_header(mail, "Subject", &subject) <= 0) + subject = ""; + tab[2].value = str_sanitize(subject, 80); tab[3].value = recipient; return tab; @@ -57,7 +60,8 @@ size_t size; int ret; - orig_msgid = mail_get_first_header(mail, "Message-ID"); + if (mail_get_first_header(mail, "Message-ID", &orig_msgid) < 0) + orig_msgid = NULL; return_addr = deliver_get_return_address(mail); if (return_addr == NULL) { i_info("msgid=%s: Return-Path missing, rejection reason: %s", @@ -102,9 +106,8 @@ boundary); fprintf(f, "Reporting-UA: %s; Dovecot Mail Delivery Agent\r\n", deliver_set->hostname); - str = mail_get_first_header(mail, "Original-Recipient"); - if (str != NULL) - fprintf(f, "Original-Recipient: rfc822; %s\r\n", str); + if (mail_get_first_header(mail, "Original-Recipient", &str) > 0) + fprintf(f, "Original-Recipient: rfc822; %s\r\n", str); fprintf(f, "Final-Recipient: rfc822; %s\r\n", recipient); if (orig_msgid != NULL) @@ -116,8 +119,7 @@ /* original message's headers */ fprintf(f, "--%s\r\nContent-Type: message/rfc822\r\n\r\n", boundary); - input = mail_get_stream(mail, &hdr_size, NULL); - if (input != NULL) { + if (mail_get_stream(mail, &hdr_size, NULL, &input) == 0) { /* Note: If you add more headers, they need to be sorted. We'll drop Content-Type because we're not including the message body, and having a multipart Content-Type may confuse some @@ -155,16 +157,16 @@ struct smtp_client *smtp_client; FILE *f; const unsigned char *data; + const char *return_path; size_t size; int ret; - input = mail_get_stream(mail, NULL, NULL); - if (input == NULL) + if (mail_get_stream(mail, NULL, NULL, &input) < 0) return -1; - smtp_client = smtp_client_open(forwardto, - mail_get_first_header(mail, "Return-Path"), - &f); + if (mail_get_first_header(mail, "Return-Path", &return_path) <= 0) + return_path = ""; + smtp_client = smtp_client_open(forwardto, return_path, &f); input = i_stream_create_header_filter(input, HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR, hide_headers,
--- a/src/imap/imap-fetch-body.c Sun Aug 12 18:16:40 2007 +0300 +++ b/src/imap/imap-fetch-body.c Sun Aug 12 19:40:54 2007 +0300 @@ -325,10 +325,9 @@ const struct message_size *fetch_size; struct message_size hdr_size, body_size; - ctx->cur_input = - mail_get_stream(mail, &hdr_size, - body->section[0] == 'H' ? NULL : &body_size); - if (ctx->cur_input == NULL) + if (mail_get_stream(mail, &hdr_size, + body->section[0] == 'H' ? NULL : &body_size, + &ctx->cur_input) < 0) return -1; i_stream_ref(ctx->cur_input); @@ -416,8 +415,7 @@ fetch_body_header_partial(struct imap_fetch_context *ctx, struct mail *mail, const struct imap_fetch_body_data *body) { - ctx->cur_input = mail_get_stream(mail, NULL, NULL); - if (ctx->cur_input == NULL) + if (mail_get_stream(mail, NULL, NULL, &ctx->cur_input) < 0) return -1; i_stream_ref(ctx->cur_input); @@ -439,8 +437,7 @@ return 0; } - ctx->cur_input = mail_get_header_stream(mail, body->header_ctx); - if (ctx->cur_input == NULL) + if (mail_get_header_stream(mail, body->header_ctx, &ctx->cur_input) < 0) return -1; i_stream_ref(ctx->cur_input); @@ -466,8 +463,7 @@ const char *path; unsigned int num; - part = mail_get_parts(mail); - if (part == NULL) + if (mail_get_parts(mail, &part) < 0) return -1; path = body->section; @@ -527,8 +523,7 @@ return 1; } - ctx->cur_input = mail_get_stream(mail, NULL, NULL); - if (ctx->cur_input == NULL) + if (mail_get_stream(mail, NULL, NULL, &ctx->cur_input) < 0) return -1; i_stream_ref(ctx->cur_input); @@ -861,8 +856,7 @@ { uoff_t size; - size = mail_get_virtual_size(mail); - if (size == (uoff_t)-1) + if (mail_get_virtual_size(mail, &size) < 0) return -1; str_printfa(ctx->cur_str, "RFC822.SIZE %"PRIuUOFF_T" ", size); @@ -875,8 +869,7 @@ struct message_size hdr_size, body_size; const char *str; - ctx->cur_input = mail_get_stream(mail, &hdr_size, &body_size); - if (ctx->cur_input == NULL) + if (mail_get_stream(mail, &hdr_size, &body_size, &ctx->cur_input) < 0) return -1; i_stream_ref(ctx->cur_input); @@ -904,8 +897,7 @@ struct message_size hdr_size; const char *str; - ctx->cur_input = mail_get_stream(mail, &hdr_size, NULL); - if (ctx->cur_input == NULL) + if (mail_get_stream(mail, &hdr_size, NULL, &ctx->cur_input) < 0) return -1; i_stream_ref(ctx->cur_input); @@ -929,8 +921,7 @@ struct message_size hdr_size, body_size; const char *str; - ctx->cur_input = mail_get_stream(mail, &hdr_size, &body_size); - if (ctx->cur_input == NULL) + if (mail_get_stream(mail, &hdr_size, &body_size, &ctx->cur_input) < 0) return -1; i_stream_ref(ctx->cur_input);
--- a/src/imap/imap-fetch.c Sun Aug 12 18:16:40 2007 +0300 +++ b/src/imap/imap-fetch.c Sun Aug 12 19:40:54 2007 +0300 @@ -403,8 +403,7 @@ { const char *body; - body = mail_get_special(mail, MAIL_FETCH_IMAP_BODY); - if (body == NULL) + if (mail_get_special(mail, MAIL_FETCH_IMAP_BODY, &body) < 0) return -1; if (ctx->first) @@ -438,8 +437,8 @@ { const char *bodystructure; - bodystructure = mail_get_special(mail, MAIL_FETCH_IMAP_BODYSTRUCTURE); - if (bodystructure == NULL) + if (mail_get_special(mail, MAIL_FETCH_IMAP_BODYSTRUCTURE, + &bodystructure) < 0) return -1; if (ctx->first) @@ -473,8 +472,7 @@ { const char *envelope; - envelope = mail_get_special(mail, MAIL_FETCH_IMAP_ENVELOPE); - if (envelope == NULL) + if (mail_get_special(mail, MAIL_FETCH_IMAP_ENVELOPE, &envelope) < 0) return -1; if (ctx->first) @@ -538,14 +536,13 @@ static int fetch_internaldate(struct imap_fetch_context *ctx, struct mail *mail, void *context __attr_unused__) { - time_t time; + time_t date; - time = mail_get_received_date(mail); - if (time == (time_t)-1) + if (mail_get_received_date(mail, &date) < 0) return -1; str_printfa(ctx->cur_str, "INTERNALDATE \"%s\" ", - imap_to_datetime(time)); + imap_to_datetime(date)); return 1; }
--- a/src/imap/imap-thread.c Sun Aug 12 18:16:40 2007 +0300 +++ b/src/imap/imap-thread.c Sun Aug 12 19:40:54 2007 +0300 @@ -446,19 +446,24 @@ t_push(); - sent_date = mail_get_date(mail, NULL); - if (sent_date == (time_t)-1) + if (mail_get_date(mail, &sent_date, NULL) < 0) sent_date = 0; - message_id = mail_get_first_header(mail, "message-id"); + if (mail_get_first_header(mail, "message-id", &message_id) < 0) + message_id = NULL; node = update_message(ctx, get_msgid(&message_id), sent_date, ctx->id_is_uid ? mail->uid : mail->seq); /* link references */ - references = mail_get_first_header(mail, "references"); + if (mail_get_first_header(mail, "references", &references) < 0) + references = NULL; + if (!link_references(ctx, node, references)) { - in_reply_to = mail_get_first_header(mail, "in-reply-to"); - refid = in_reply_to == NULL ? NULL : get_msgid(&in_reply_to); + if (mail_get_first_header(mail, "in-reply-to", + &in_reply_to) <= 0) + refid = NULL; + else + refid = get_msgid(&in_reply_to); if (refid != NULL) link_node(ctx, refid, node, TRUE); @@ -694,8 +699,9 @@ if (seq != 0) { mail_set_seq(ctx->mail, seq); t_push(); - subject = mail_get_first_header(ctx->mail, "subject"); - add_base_subject(ctx, subject, node); + if (mail_get_first_header(ctx->mail, "subject", + &subject) > 0) + add_base_subject(ctx, subject, node); t_pop(); } }
--- a/src/lib-storage/index/cydir/cydir-mail.c Sun Aug 12 18:16:40 2007 +0300 +++ b/src/lib-storage/index/cydir/cydir-mail.c Sun Aug 12 19:40:54 2007 +0300 @@ -35,66 +35,69 @@ return 0; } -static time_t cydir_mail_get_received_date(struct mail *_mail) +static int cydir_mail_get_received_date(struct mail *_mail, time_t *date_r) { struct index_mail *mail = (struct index_mail *)_mail; struct index_mail_data *data = &mail->data; struct stat st; uint32_t t; - (void)index_mail_get_received_date(_mail); - if (data->received_date != (time_t)-1) - return data->received_date; + (void)index_mail_get_received_date(_mail, date_r); + if (*date_r != (time_t)-1) + return 0; if (cydir_mail_stat(_mail, &st) < 0) - return (time_t)-1; + return -1; data->received_date = t = st.st_mtime; index_mail_cache_add(mail, MAIL_CACHE_RECEIVED_DATE, &t, sizeof(t)); - return data->received_date; + *date_r = data->received_date; + return 0; } -static time_t cydir_mail_get_save_date(struct mail *_mail) +static int cydir_mail_get_save_date(struct mail *_mail, time_t *date_r) { struct index_mail *mail = (struct index_mail *)_mail; struct index_mail_data *data = &mail->data; struct stat st; uint32_t t; - (void)index_mail_get_save_date(_mail); - if (data->save_date != (time_t)-1) - return data->save_date; + (void)index_mail_get_save_date(_mail, date_r); + if (*date_r != (time_t)-1) + return 0; if (cydir_mail_stat(_mail, &st) < 0) return (time_t)-1; data->save_date = t = st.st_ctime; index_mail_cache_add(mail, MAIL_CACHE_SAVE_DATE, &t, sizeof(t)); - return data->save_date; + *date_r = data->save_date; + return 0; } -static uoff_t cydir_mail_get_physical_size(struct mail *_mail) +static int cydir_mail_get_physical_size(struct mail *_mail, uoff_t *size_r) { struct index_mail *mail = (struct index_mail *)_mail; struct index_mail_data *data = &mail->data; struct stat st; - (void)index_mail_get_physical_size(_mail); - if (data->physical_size != (uoff_t)-1) - return data->physical_size; + (void)index_mail_get_physical_size(_mail, size_r); + if (*size_r != (uoff_t)-1) + return 0; if (cydir_mail_stat(_mail, &st) < 0) - return (uoff_t)-1; + return -1; data->physical_size = data->virtual_size = st.st_size; index_mail_cache_add(mail, MAIL_CACHE_PHYSICAL_FULL_SIZE, &data->physical_size, sizeof(data->physical_size)); - return data->physical_size; + *size_r = data->physical_size; + return 0; } -static struct istream * +static int cydir_mail_get_stream(struct mail *_mail, struct message_size *hdr_size, - struct message_size *body_size) + struct message_size *body_size, struct istream **stream_r) { struct index_mail *mail = (struct index_mail *)_mail; const char *path; @@ -110,13 +113,13 @@ mail_storage_set_critical(_mail->box->storage, "open(%s) failed: %m", path); } - return NULL; + return -1; } mail->data.stream = i_stream_create_fd(fd, MAIL_READ_BLOCK_SIZE, TRUE); } - return index_mail_init_stream(mail, hdr_size, body_size); + return index_mail_init_stream(mail, hdr_size, body_size, stream_r); } struct mail_vfuncs cydir_mail_vfuncs = {
--- a/src/lib-storage/index/dbox/dbox-mail.c Sun Aug 12 18:16:40 2007 +0300 +++ b/src/lib-storage/index/dbox/dbox-mail.c Sun Aug 12 19:40:54 2007 +0300 @@ -144,16 +144,16 @@ return -1; } -static time_t dbox_mail_get_received_date(struct mail *_mail) +static int dbox_mail_get_received_date(struct mail *_mail, time_t *date_r) { struct index_mail *mail = (struct index_mail *)_mail; struct index_mail_data *data = &mail->data; uoff_t offset; uint32_t t; - (void)index_mail_get_received_date(_mail); - if (data->received_date != (time_t)-1) - return data->received_date; + (void)index_mail_get_received_date(_mail, date_r); + if (*date_r != (time_t)-1) + return 0; if (dbox_mail_open(mail, &offset) <= 0) return (time_t)-1; @@ -165,21 +165,22 @@ t = data->received_date; index_mail_cache_add(mail, MAIL_CACHE_RECEIVED_DATE, &t, sizeof(t)); - return data->received_date; + *date_r = data->received_date; + return 0; } -static time_t dbox_mail_get_save_date(struct mail *_mail) +static int dbox_mail_get_save_date(struct mail *_mail, time_t *date_r) { struct index_mail *mail = (struct index_mail *)_mail; struct index_mail_data *data = &mail->data; uoff_t offset; - (void)index_mail_get_save_date(_mail); - if (data->save_date != (time_t)-1) - return data->save_date; + (void)index_mail_get_save_date(_mail, date_r); + if (*date_r != (time_t)-1) + return 0; if (dbox_mail_open(mail, &offset) <= 0) - return (time_t)-1; + return -1; if (data->save_date == (time_t)-1) { /* it's broken and conflicts with our "not found" return value. change it. */ @@ -188,32 +189,34 @@ index_mail_cache_add(mail, MAIL_CACHE_SAVE_DATE, &data->save_date, sizeof(data->save_date)); - return data->save_date; + *date_r = data->save_date; + return 0; } -static uoff_t dbox_mail_get_physical_size(struct mail *_mail) +static int dbox_mail_get_physical_size(struct mail *_mail, uoff_t *size_r) { struct index_mail *mail = (struct index_mail *)_mail; struct index_mail_data *data = &mail->data; uoff_t offset; - (void)index_mail_get_physical_size(_mail); - if (data->physical_size != (uoff_t)-1) - return data->physical_size; + (void)index_mail_get_physical_size(_mail, size_r); + if (*size_r != (uoff_t)-1) + return 0; if (dbox_mail_open(mail, &offset) <= 0) - return (uoff_t)-1; + return -1; index_mail_cache_add(mail, MAIL_CACHE_PHYSICAL_FULL_SIZE, &data->physical_size, sizeof(data->physical_size)); - return data->physical_size; + *size_r = data->physical_size; + return 0; } -static struct istream * -dbox_mail_get_stream(struct mail *_mail, - struct message_size *hdr_size, - struct message_size *body_size) +static int dbox_mail_get_stream(struct mail *_mail, + struct message_size *hdr_size, + struct message_size *body_size, + struct istream **stream_r) { struct index_mail *mail = (struct index_mail *)_mail; struct dbox_mailbox *mbox = (struct dbox_mailbox *)mail->ibox; @@ -221,7 +224,7 @@ if (mail->data.stream == NULL) { if (dbox_mail_open(mail, &offset) <= 0) - return NULL; + return -1; offset += mbox->file->mail_header_size; mail->data.stream = @@ -229,7 +232,7 @@ mbox->file->seeked_mail_size); } - return index_mail_init_stream(mail, hdr_size, body_size); + return index_mail_init_stream(mail, hdr_size, body_size, stream_r); } struct mail_vfuncs dbox_mail_vfuncs = {
--- a/src/lib-storage/index/index-mail-headers.c Sun Aug 12 18:16:40 2007 +0300 +++ b/src/lib-storage/index/index-mail-headers.c Sun Aug 12 19:40:54 2007 +0300 @@ -387,11 +387,12 @@ struct mailbox_header_lookup_ctx *headers) { struct index_mail_data *data = &mail->data; + struct istream *input; uoff_t old_offset; old_offset = data->stream == NULL ? 0 : data->stream->v_offset; - if (mail_get_stream(&mail->mail.mail, NULL, NULL) == NULL) + if (mail_get_stream(&mail->mail.mail, NULL, NULL, &input) < 0) return -1; index_mail_parse_header_init(mail, headers); @@ -427,7 +428,7 @@ index_mail_parse_finish_imap_envelope(mail); } -void index_mail_headers_get_envelope(struct index_mail *mail) +int index_mail_headers_get_envelope(struct index_mail *mail) { struct mailbox_header_lookup_ctx *header_ctx; struct istream *stream; @@ -439,7 +440,9 @@ mail->data.save_envelope = TRUE; header_ctx = mailbox_header_lookup_init(&mail->ibox->box, imap_envelope_headers); - stream = mail_get_header_stream(&mail->mail.mail, header_ctx); + if (mail_get_header_stream(&mail->mail.mail, header_ctx, &stream) < 0) + return -1; + if (mail->data.envelope == NULL && stream != NULL) { /* we got the headers from cache - parse them to get the envelope */ @@ -451,6 +454,7 @@ if (mail->data.stream != NULL) i_stream_seek(mail->data.stream, old_offset); + return 0; } static size_t get_header_size(buffer_t *buffer, size_t pos) @@ -548,8 +552,9 @@ return array_idx(&header_values, 0); } -static const char *const * -index_mail_get_raw_headers(struct index_mail *mail, const char *field) +static int +index_mail_get_raw_headers(struct index_mail *mail, const char *field, + const char *const **value_r) { const char *headers[2], *value; struct mailbox_header_lookup_ctx *headers_ctx; @@ -569,34 +574,32 @@ mail->data.seq, &field_idx, 1) <= 0) { /* not in cache / error - first see if it's already parsed */ p_free(mail->data_pool, dest); - if (mail->header_seq == mail->data.seq) { - ret = index_mail_header_is_parsed(mail, field_idx); - if (ret != -1) { - return ret == 0 ? NULL : - index_mail_get_parsed_header(mail, - field_idx); - } + if (mail->header_seq != mail->data.seq) { + /* parse */ + headers[0] = field; headers[1] = NULL; + headers_ctx = mailbox_header_lookup_init( + &mail->ibox->box, headers); + ret = index_mail_parse_headers(mail, headers_ctx); + mailbox_header_lookup_deinit(&headers_ctx); + if (ret < 0) + return -1; } - /* parse */ - headers[0] = field; headers[1] = NULL; - headers_ctx = mailbox_header_lookup_init(&mail->ibox->box, - headers); - ret = index_mail_parse_headers(mail, headers_ctx); - mailbox_header_lookup_deinit(&headers_ctx); - if (ret < 0) - return NULL; - - ret = index_mail_header_is_parsed(mail, field_idx); - i_assert(ret != -1); - return ret == 0 ? NULL : - index_mail_get_parsed_header(mail, field_idx); + if ((ret = index_mail_header_is_parsed(mail, field_idx)) <= 0) { + /* not found */ + i_assert(ret != -1); + *value_r = p_new(mail->data_pool, const char *, 1); + return 0; + } + *value_r = index_mail_get_parsed_header(mail, field_idx); + return 0; } data = buffer_get_modifiable_data(dest, &len); if (len == 0) { /* cached as non-existing. */ - return p_new(mail->data_pool, const char *, 1); + *value_r = p_new(mail->data_pool, const char *, 1); + return 0; } p_array_init(&header_values, mail->data_pool, 4); @@ -618,7 +621,8 @@ value = NULL; array_append(&header_values, &value, sizeof(value)); - return array_idx(&header_values, 0); + *value_r = array_idx(&header_values, 0); + return 0; } static const char *const * @@ -651,32 +655,32 @@ return decoded_list; } -const char *const *index_mail_get_headers(struct mail *_mail, const char *field, - bool decode_to_utf8) +int index_mail_get_headers(struct mail *_mail, const char *field, + bool decode_to_utf8, const char *const **value_r) +{ + struct index_mail *mail = (struct index_mail *)_mail; + + if (index_mail_get_raw_headers(mail, field, value_r) < 0) + return -1; + if (!decode_to_utf8 || **value_r == NULL) + return 0; + + *value_r = index_mail_headers_decode(mail, *value_r, (unsigned int)-1); + return 0; +} + +int index_mail_get_first_header(struct mail *_mail, const char *field, + bool decode_to_utf8, const char **value_r) { struct index_mail *mail = (struct index_mail *)_mail; const char *const *list; - list = index_mail_get_raw_headers(mail, field); - if (!decode_to_utf8 || list == NULL || *list == NULL) - return list; - - return index_mail_headers_decode(mail, list, (unsigned int)-1); -} - -const char *index_mail_get_first_header(struct mail *_mail, const char *field, - bool decode_to_utf8) -{ - struct index_mail *mail = (struct index_mail *)_mail; - const char *const *list; - - list = index_mail_get_raw_headers(mail, field); - if (list == NULL || *list == NULL) - return NULL; - - if (decode_to_utf8) + if (index_mail_get_raw_headers(mail, field, &list) < 0) + return -1; + if (decode_to_utf8 && list[0] != NULL) list = index_mail_headers_decode(mail, list, 1); - return list[0]; + *value_r = list[0]; + return list[0] != NULL ? 1 : 0; } static void header_cache_callback(struct message_header_line *hdr, @@ -688,19 +692,20 @@ index_mail_parse_header(NULL, hdr, mail); } -struct istream * -index_mail_get_header_stream(struct mail *_mail, - struct mailbox_header_lookup_ctx *_headers) +int index_mail_get_header_stream(struct mail *_mail, + struct mailbox_header_lookup_ctx *_headers, + struct istream **stream_r) { struct index_mail *mail = (struct index_mail *)_mail; struct index_header_lookup_ctx *headers = (struct index_header_lookup_ctx *)_headers; + struct istream *input; string_t *dest; if (mail->data.save_bodystructure_header) { /* we have to parse the header. */ if (index_mail_parse_headers(mail, _headers) < 0) - return NULL; + return -1; } dest = str_new(mail->data_pool, 256); @@ -712,13 +717,14 @@ mail->data.filter_stream = i_stream_create_from_data(str_data(dest), str_len(dest)); - return mail->data.filter_stream; + *stream_r = mail->data.filter_stream; + return 0; } /* not in cache / error */ p_free(mail->data_pool, dest); - if (mail_get_stream(&mail->mail.mail, NULL, NULL) == NULL) - return NULL; + if (mail_get_stream(&mail->mail.mail, NULL, NULL, &input) < 0) + return -1; if (mail->data.filter_stream != NULL) i_stream_destroy(&mail->data.filter_stream); @@ -730,7 +736,8 @@ HEADER_FILTER_HIDE_BODY, headers->name, headers->count, header_cache_callback, mail); - return mail->data.filter_stream; + *stream_r = mail->data.filter_stream; + return 0; } struct mailbox_header_lookup_ctx *
--- a/src/lib-storage/index/index-mail.c Sun Aug 12 18:16:40 2007 +0300 +++ b/src/lib-storage/index/index-mail.c Sun Aug 12 19:40:54 2007 +0300 @@ -34,8 +34,8 @@ { "mime.parts", 0, MAIL_CACHE_FIELD_VARIABLE_SIZE, 0, 0 } }; -static void index_mail_parse_body(struct index_mail *mail, - enum index_cache_field field); +static int index_mail_parse_body(struct index_mail *mail, + enum index_cache_field field); static bool get_cached_parts(struct index_mail *mail) { @@ -98,22 +98,17 @@ return ret; } -uoff_t index_mail_get_cached_uoff_t(struct index_mail *mail, - enum index_cache_field field) +bool index_mail_get_cached_uoff_t(struct index_mail *mail, + enum index_cache_field field, uoff_t *size_r) { - uoff_t uoff; - - if (!index_mail_get_fixed_field(mail, - mail->ibox->cache_fields[field].idx, - &uoff, sizeof(uoff))) - uoff = (uoff_t)-1; - - return uoff; + return index_mail_get_fixed_field(mail, + mail->ibox->cache_fields[field].idx, + size_r, sizeof(*size_r)); } enum mail_flags index_mail_get_flags(struct mail *_mail) { - struct index_mail *mail = (struct index_mail *) _mail; + struct index_mail *mail = (struct index_mail *)_mail; struct index_mail_data *data = &mail->data; if (index_mailbox_is_recent(mail->ibox, _mail->uid)) @@ -125,7 +120,7 @@ const char *const *index_mail_get_keywords(struct mail *_mail) { static const char *const no_keywords[] = { NULL }; - struct index_mail *mail = (struct index_mail *) _mail; + struct index_mail *mail = (struct index_mail *)_mail; struct index_mail_data *data = &mail->data; ARRAY_TYPE(keyword_indexes) keyword_indexes_arr; const char *const *names; @@ -163,77 +158,79 @@ return array_idx(&data->keywords, 0); } -const struct message_part *index_mail_get_parts(struct mail *_mail) +int index_mail_get_parts(struct mail *_mail, + const struct message_part **parts_r) { - struct index_mail *mail = (struct index_mail *) _mail; + struct index_mail *mail = (struct index_mail *)_mail; struct index_mail_data *data = &mail->data; - if (data->parts != NULL) - return data->parts; - - if (get_cached_parts(mail)) - return data->parts; + if (data->parts != NULL || get_cached_parts(mail)) { + *parts_r = data->parts; + return 0; + } if (data->parser_ctx == NULL) { if (index_mail_parse_headers(mail, NULL) < 0) - return NULL; + return -1; } data->save_message_parts = TRUE; - index_mail_parse_body(mail, 0); + if (index_mail_parse_body(mail, 0) < 0) + return -1; - return data->parts; + *parts_r = data->parts; + return 0; } -time_t index_mail_get_received_date(struct mail *_mail) +int index_mail_get_received_date(struct mail *_mail, time_t *date_r) { - struct index_mail *mail = (struct index_mail *) _mail; + struct index_mail *mail = (struct index_mail *)_mail; struct index_mail_data *data = &mail->data; if (data->received_date == (time_t)-1) { uint32_t t; - if (!index_mail_get_fixed_field(mail, MAIL_CACHE_RECEIVED_DATE, + if (index_mail_get_fixed_field(mail, MAIL_CACHE_RECEIVED_DATE, &t, sizeof(t))) - return (time_t)-1; - - data->received_date = t; + data->received_date = t; } - return data->received_date; + *date_r = data->received_date; + return 0; } -time_t index_mail_get_save_date(struct mail *_mail) +int index_mail_get_save_date(struct mail *_mail, time_t *date_r) { - struct index_mail *mail = (struct index_mail *) _mail; + struct index_mail *mail = (struct index_mail *)_mail; struct index_mail_data *data = &mail->data; if (data->save_date == (time_t)-1) { uint32_t t; - if (!index_mail_get_fixed_field(mail, MAIL_CACHE_SAVE_DATE, - &t, sizeof(t))) - return (time_t)-1; - - data->save_date = t; + if (index_mail_get_fixed_field(mail, MAIL_CACHE_SAVE_DATE, + &t, sizeof(t))) + data->save_date = t; } - return data->save_date; + *date_r = data->save_date; + return 0; } -static void index_mail_cache_sent_date(struct index_mail *mail) +static int index_mail_cache_sent_date(struct index_mail *mail) { struct index_mail_data *data = &mail->data; const char *str; time_t t; - int tz; + int ret, tz; if (data->sent_date.time != (uint32_t)-1) - return; + return 0; - str = mail_get_first_header(&mail->mail.mail, "Date"); - if (str == NULL || !message_date_parse((const unsigned char *)str, - strlen(str), &t, &tz)) { + if ((ret = mail_get_first_header(&mail->mail.mail, "Date", &str)) <= 0) + return ret; + + if (!message_date_parse((const unsigned char *)str, + strlen(str), &t, &tz)) { /* 0 = not found / invalid */ t = 0; tz = 0; @@ -242,27 +239,29 @@ data->sent_date.timezone = tz; index_mail_cache_add(mail, MAIL_CACHE_SENT_DATE, &data->sent_date, sizeof(data->sent_date)); + return 0; } -time_t index_mail_get_date(struct mail *_mail, int *timezone) +int index_mail_get_date(struct mail *_mail, time_t *date_r, int *timezone_r) { - struct index_mail *mail = (struct index_mail *) _mail; + struct index_mail *mail = (struct index_mail *)_mail; struct index_mail_data *data = &mail->data; if (data->sent_date.time != (uint32_t)-1) { - if (timezone != NULL) - *timezone = data->sent_date.timezone; - return data->sent_date.time; + *date_r = data->sent_date.time; + return 0; } (void)index_mail_get_fixed_field(mail, MAIL_CACHE_SENT_DATE, &data->sent_date, sizeof(data->sent_date)); - index_mail_cache_sent_date(mail); - if (timezone != NULL) - *timezone = data->sent_date.timezone; - return data->sent_date.time; + if (index_mail_cache_sent_date(mail) < 0) + return -1; + + *timezone_r = data->sent_date.timezone; + *date_r = data->sent_date.time; + return 0; } static bool get_cached_msgpart_sizes(struct index_mail *mail) @@ -286,58 +285,56 @@ return data->parts != NULL; } -uoff_t index_mail_get_cached_virtual_size(struct index_mail *mail) +bool index_mail_get_cached_virtual_size(struct index_mail *mail, uoff_t *size_r) { - uoff_t size; - - if (mail->data.virtual_size != (uoff_t)-1) - return mail->data.virtual_size; - - size = index_mail_get_cached_uoff_t(mail, MAIL_CACHE_VIRTUAL_FULL_SIZE); - if (size != (uoff_t)-1) - mail->data.virtual_size = size; - else - (void)get_cached_msgpart_sizes(mail); - return mail->data.virtual_size; + if (mail->data.virtual_size == (uoff_t)-1) { + if (!index_mail_get_cached_uoff_t(mail, + MAIL_CACHE_VIRTUAL_FULL_SIZE, + &mail->data.virtual_size)) { + if (!get_cached_msgpart_sizes(mail)) + return FALSE; + } + } + *size_r = mail->data.virtual_size; + return TRUE; } -uoff_t index_mail_get_virtual_size(struct mail *_mail) +int index_mail_get_virtual_size(struct mail *_mail, uoff_t *size_r) { - struct index_mail *mail = (struct index_mail *) _mail; + struct index_mail *mail = (struct index_mail *)_mail; struct index_mail_data *data = &mail->data; struct message_size hdr_size, body_size; + struct istream *input; uoff_t old_offset; - if (index_mail_get_cached_virtual_size(mail) != (uoff_t)-1) - return data->virtual_size; + if (index_mail_get_cached_virtual_size(mail, size_r)) + return 0; old_offset = data->stream == NULL ? 0 : data->stream->v_offset; - if (mail_get_stream(_mail, &hdr_size, &body_size) == NULL) - return (uoff_t)-1; + if (mail_get_stream(_mail, &hdr_size, &body_size, &input) < 0) + return -1; i_stream_seek(data->stream, old_offset); i_assert(data->virtual_size != (uoff_t)-1); index_mail_cache_add(mail, MAIL_CACHE_VIRTUAL_FULL_SIZE, &data->virtual_size, sizeof(data->virtual_size)); - return data->virtual_size; + *size_r = data->virtual_size; + return 0; } -uoff_t index_mail_get_physical_size(struct mail *_mail) +int index_mail_get_physical_size(struct mail *_mail, uoff_t *size_r) { - struct index_mail *mail = (struct index_mail *) _mail; + struct index_mail *mail = (struct index_mail *)_mail; struct index_mail_data *data = &mail->data; - uoff_t size; - if (data->physical_size != (uoff_t)-1) - return data->physical_size; - - size = index_mail_get_cached_uoff_t(mail, - MAIL_CACHE_PHYSICAL_FULL_SIZE); - if (size != (uoff_t)-1) - data->physical_size = size; - else - (void)get_cached_msgpart_sizes(mail); - return data->physical_size; + if (data->physical_size == (uoff_t)-1) { + if (!index_mail_get_cached_uoff_t(mail, + MAIL_CACHE_PHYSICAL_FULL_SIZE, + &data->physical_size)) + (void)get_cached_msgpart_sizes(mail); + } + *size_r = data->physical_size; + return 0; } void index_mail_cache_add(struct index_mail *mail, enum index_cache_field field, @@ -606,11 +603,23 @@ index_mail_body_parsed_cache_sizes(mail); } -static void index_mail_parse_body(struct index_mail *mail, - enum index_cache_field field) +static int index_mail_stream_check_failure(struct index_mail *mail) +{ + if (mail->data.stream->stream_errno == 0) + return 0; + + errno = mail->data.stream->stream_errno; + mail_storage_set_critical(mail->mail.mail.box->storage, + "read(mail, uid=%u) failed: %m", mail->mail.mail.uid); + return -1; +} + +static int index_mail_parse_body(struct index_mail *mail, + enum index_cache_field field) { struct index_mail_data *data = &mail->data; uoff_t old_offset; + int ret; i_assert(data->parser_ctx != NULL); @@ -630,16 +639,19 @@ message_parser_parse_body(data->parser_ctx, null_message_part_header_callback, NULL); } + ret = index_mail_stream_check_failure(mail); index_mail_parse_body_finish(mail, field, FALSE); i_stream_seek(data->stream, old_offset); + return ret; } -struct istream *index_mail_init_stream(struct index_mail *_mail, - struct message_size *hdr_size, - struct message_size *body_size) +int index_mail_init_stream(struct index_mail *_mail, + struct message_size *hdr_size, + struct message_size *body_size, + struct istream **stream_r) { - struct index_mail *mail = (struct index_mail *) _mail; + struct index_mail *mail = (struct index_mail *)_mail; struct index_mail_data *data = &mail->data; if (hdr_size != NULL || body_size != NULL) @@ -651,7 +663,7 @@ if ((data->access_part & PARSE_HDR) != 0) { (void)get_cached_parts(mail); if (index_mail_parse_headers(mail, NULL) < 0) - return NULL; + return -1; } else { message_get_header_size(data->stream, &data->hdr_size, NULL); @@ -666,9 +678,10 @@ if (body_size != NULL) { i_stream_seek(data->stream, data->hdr_size.physical_size); if (!data->body_size_set) { - if ((data->access_part & PARSE_BODY) != 0) - index_mail_parse_body(mail, 0); - else { + if ((data->access_part & PARSE_BODY) != 0) { + if (index_mail_parse_body(mail, 0) < 0) + return -1; + } else { message_get_body_size(data->stream, &data->body_size, NULL); data->body_size_set = TRUE; @@ -686,11 +699,12 @@ } i_stream_seek(data->stream, 0); - return data->stream; + *stream_r = data->stream; + return 0; } -static void index_mail_parse_bodystructure(struct index_mail *mail, - enum index_cache_field field) +static int index_mail_parse_bodystructure(struct index_mail *mail, + enum index_cache_field field) { struct index_mail_data *data = &mail->data; @@ -698,7 +712,7 @@ /* we have everything parsed already, but just not written to a string */ index_mail_body_parsed_cache_bodystructure(mail, field); - return; + return 0; } if (data->save_bodystructure_header || @@ -708,10 +722,10 @@ data->save_bodystructure_body = TRUE; (void)get_cached_parts(mail); if (index_mail_parse_headers(mail, NULL) < 0) - return; + return -1; } - index_mail_parse_body(mail, field); + return index_mail_parse_body(mail, field); } static void @@ -725,10 +739,10 @@ str_append(str, " NIL NIL NIL"); } -const char *index_mail_get_special(struct mail *_mail, - enum mail_fetch_field field) +int index_mail_get_special(struct mail *_mail, + enum mail_fetch_field field, const char **value_r) { - struct index_mail *mail = (struct index_mail *) _mail; + struct index_mail *mail = (struct index_mail *)_mail; struct index_mail_data *data = &mail->data; struct mail_cache_field *cache_fields = mail->ibox->cache_fields; string_t *str; @@ -740,8 +754,11 @@ cache_fields[MAIL_CACHE_IMAP_BODY].idx; unsigned int bodystructure_cache_field = cache_fields[MAIL_CACHE_IMAP_BODYSTRUCTURE].idx; - if (data->body != NULL) - return data->body; + + if (data->body != NULL) { + *value_r = data->body; + return 0; + } /* 1) use plain-7bit-ascii flag if it exists 2) get BODY if it exists @@ -754,82 +771,90 @@ MAIL_CACHE_FLAG_TEXT_PLAIN_7BIT_ASCII) != 0 && get_cached_parts(mail)) { index_mail_get_plain_bodystructure(mail, str, FALSE); - return str_c(str); - } - - if (mail_cache_lookup_field(mail->trans->cache_view, str, - mail->data.seq, body_cache_field) > 0) { + data->body = str_c(str); + } else if (mail_cache_lookup_field(mail->trans->cache_view, str, + mail->data.seq, body_cache_field) > 0) data->body = str_c(str); - return data->body; - } - if (mail_cache_lookup_field(mail->trans->cache_view, str, - mail->data.seq, - bodystructure_cache_field) > 0) { + else if (mail_cache_lookup_field(mail->trans->cache_view, str, + mail->data.seq, + bodystructure_cache_field) > 0) { data->bodystructure = p_strdup(mail->data_pool, str_c(str)); str_truncate(str, 0); if (imap_body_parse_from_bodystructure( - data->bodystructure, str)) { + data->bodystructure, str)) data->body = str_c(str); - return data->body; + else { + /* broken, continue.. */ + mail_cache_set_corrupted(mail->ibox->cache, + "Corrupted BODYSTRUCTURE for mail %u", + mail->mail.mail.uid); + data->bodystructure = NULL; } + } - /* broken, continue.. */ - mail_cache_set_corrupted(mail->ibox->cache, - "Corrupted BODYSTRUCTURE for mail %u", - mail->mail.mail.uid); - data->bodystructure = NULL; + if (data->body == NULL) { + str_free(&str); + if (index_mail_parse_bodystructure(mail, + MAIL_CACHE_IMAP_BODY) < 0) + return -1; } - str_free(&str); - - index_mail_parse_bodystructure(mail, MAIL_CACHE_IMAP_BODY); - return data->body; + *value_r = data->body; + return 0; } case MAIL_FETCH_IMAP_BODYSTRUCTURE: { unsigned int bodystructure_cache_field = cache_fields[MAIL_CACHE_IMAP_BODYSTRUCTURE].idx; - if (data->bodystructure != NULL) - return data->bodystructure; + if (data->bodystructure != NULL) { + *value_r = data->bodystructure; + return 0; + } str = str_new(mail->data_pool, 128); if ((mail->data.cache_flags & MAIL_CACHE_FLAG_TEXT_PLAIN_7BIT_ASCII) != 0 && get_cached_parts(mail)) { index_mail_get_plain_bodystructure(mail, str, TRUE); - return str_c(str); - } - - if (mail_cache_lookup_field(mail->trans->cache_view, str, - mail->data.seq, - bodystructure_cache_field) > 0) { + data->bodystructure = str_c(str); + } else if (mail_cache_lookup_field(mail->trans->cache_view, str, + mail->data.seq, + bodystructure_cache_field) > 0) { data->bodystructure = str_c(str); - return data->bodystructure; + } else { + str_free(&str); + if (index_mail_parse_bodystructure(mail, + MAIL_CACHE_IMAP_BODYSTRUCTURE) < 0) + return -1; } - str_free(&str); - - index_mail_parse_bodystructure(mail, - MAIL_CACHE_IMAP_BODYSTRUCTURE); - return data->bodystructure; + *value_r = data->bodystructure; + return 0; } case MAIL_FETCH_IMAP_ENVELOPE: - if (data->envelope == NULL) - index_mail_headers_get_envelope(mail); - return data->envelope; + if (data->envelope == NULL) { + if (index_mail_headers_get_envelope(mail) < 0) + return -1; + } + *value_r = data->envelope; + return 0; case MAIL_FETCH_FROM_ENVELOPE: case MAIL_FETCH_UIDL_FILE_NAME: - return NULL; + *value_r = ""; + return 0; case MAIL_FETCH_HEADER_MD5: mail_index_lookup_ext(mail->trans->trans_view, data->seq, mail->ibox->md5hdr_ext_idx, &ext_data, NULL); - if (ext_data == NULL) - return NULL; - return binary_to_hex(ext_data, 16); + if (ext_data == NULL) { + *value_r = ""; + return 0; + } + *value_r = binary_to_hex(ext_data, 16); + return 0; default: i_unreached(); - return NULL; + return -1; } } @@ -930,6 +955,7 @@ struct mail_cache_field *cache_fields = mail->ibox->cache_fields; struct mail_cache_view *cache_view = mail->trans->cache_view; const struct mail_index_record *rec; + struct istream *input; if (data->seq == seq) return; @@ -1031,7 +1057,7 @@ if ((mail->wanted_fields & MAIL_FETCH_STREAM_BODY) != 0) data->access_part |= READ_BODY; - (void)mail_get_stream(_mail, NULL, NULL); + (void)mail_get_stream(_mail, NULL, NULL, &input); } } @@ -1121,7 +1147,7 @@ cache_field = mail->ibox->cache_fields[MAIL_CACHE_SENT_DATE].idx; if (mail_cache_field_want_add(mail->trans->cache_trans, mail->data.seq, cache_field)) - index_mail_cache_sent_date(mail); + (void)index_mail_cache_sent_date(mail); } void index_mail_cache_parse_deinit(struct mail *_mail, time_t received_date)
--- a/src/lib-storage/index/index-mail.h Sun Aug 12 18:16:40 2007 +0300 +++ b/src/lib-storage/index/index-mail.h Sun Aug 12 19:40:54 2007 +0300 @@ -143,30 +143,31 @@ struct index_mail *mail); int index_mail_parse_headers(struct index_mail *mail, struct mailbox_header_lookup_ctx *headers); -void index_mail_headers_get_envelope(struct index_mail *mail); +int index_mail_headers_get_envelope(struct index_mail *mail); -const char *index_mail_get_first_header(struct mail *_mail, const char *field, - bool decode_to_utf8); -const char *const * -index_mail_get_headers(struct mail *_mail, const char *field, - bool decode_to_utf8); -struct istream * -index_mail_get_header_stream(struct mail *_mail, - struct mailbox_header_lookup_ctx *headers); +int index_mail_get_first_header(struct mail *_mail, const char *field, + bool decode_to_utf8, const char **value_r); +int index_mail_get_headers(struct mail *_mail, const char *field, + bool decode_to_utf8, const char *const **value_r); +int index_mail_get_header_stream(struct mail *_mail, + struct mailbox_header_lookup_ctx *headers, + struct istream **stream_r); enum mail_flags index_mail_get_flags(struct mail *_mail); const char *const *index_mail_get_keywords(struct mail *_mail); -const struct message_part *index_mail_get_parts(struct mail *_mail); -time_t index_mail_get_received_date(struct mail *_mail); -time_t index_mail_get_save_date(struct mail *_mail); -time_t index_mail_get_date(struct mail *_mail, int *timezone); -uoff_t index_mail_get_virtual_size(struct mail *mail); -uoff_t index_mail_get_physical_size(struct mail *mail); -struct istream *index_mail_init_stream(struct index_mail *mail, - struct message_size *hdr_size, - struct message_size *body_size); -const char *index_mail_get_special(struct mail *_mail, - enum mail_fetch_field field); +int index_mail_get_parts(struct mail *_mail, + const struct message_part **parts_r); +int index_mail_get_received_date(struct mail *_mail, time_t *date_r); +int index_mail_get_save_date(struct mail *_mail, time_t *date_r); +int index_mail_get_date(struct mail *_mail, time_t *date_r, int *timezone_r); +int index_mail_get_virtual_size(struct mail *mail, uoff_t *size_r); +int index_mail_get_physical_size(struct mail *mail, uoff_t *size_r); +int index_mail_init_stream(struct index_mail *mail, + struct message_size *hdr_size, + struct message_size *body_size, + struct istream **stream_r); +int index_mail_get_special(struct mail *_mail, enum mail_fetch_field field, + const char **value_r); void index_mail_update_flags(struct mail *mail, enum modify_type modify_type, enum mail_flags flags); @@ -174,9 +175,10 @@ struct mail_keywords *keywords); void index_mail_expunge(struct mail *mail); -uoff_t index_mail_get_cached_uoff_t(struct index_mail *mail, - enum index_cache_field field); -uoff_t index_mail_get_cached_virtual_size(struct index_mail *mail); +bool index_mail_get_cached_uoff_t(struct index_mail *mail, + enum index_cache_field field, uoff_t *size_r); +bool index_mail_get_cached_virtual_size(struct index_mail *mail, + uoff_t *size_r); void index_mail_cache_add(struct index_mail *mail, enum index_cache_field field, const void *data, size_t data_size);
--- a/src/lib-storage/index/index-search.c Sun Aug 12 18:16:40 2007 +0300 +++ b/src/lib-storage/index/index-search.c Sun Aug 12 19:40:54 2007 +0300 @@ -187,8 +187,7 @@ case SEARCH_BEFORE: case SEARCH_ON: case SEARCH_SINCE: - date = mail_get_received_date(ctx->mail); - if (date == (time_t)-1) + if (mail_get_received_date(ctx->mail, &date) < 0) return -1; switch (arg->type) { @@ -210,8 +209,7 @@ case SEARCH_SENTSINCE: /* NOTE: RFC-3501 specifies that timezone is ignored in searches. date is returned as UTC, so change it. */ - date = mail_get_date(ctx->mail, &timezone_offset); - if (date == (time_t)-1) + if (mail_get_date(ctx->mail, &date, &timezone_offset) < 0) return -1; date += timezone_offset * 60; @@ -231,8 +229,7 @@ /* sizes */ case SEARCH_SMALLER: case SEARCH_LARGER: - virtual_size = mail_get_virtual_size(ctx->mail); - if (virtual_size == (uoff_t)-1) + if (mail_get_virtual_size(ctx->mail, &virtual_size) < 0) return -1; search_size = str_to_uoff_t(arg->value.str); @@ -513,8 +510,7 @@ if (headers == NULL) { headers_ctx = NULL; - input = mail_get_stream(ctx->mail, NULL, NULL); - if (input == NULL) + if (mail_get_stream(ctx->mail, NULL, NULL, &input) < 0) return FALSE; } else { /* FIXME: do this once in init */ @@ -522,8 +518,8 @@ headers_ctx = mailbox_header_lookup_init(&ctx->ibox->box, headers); - input = mail_get_header_stream(ctx->mail, headers_ctx); - if (input == NULL) { + if (mail_get_header_stream(ctx->mail, headers_ctx, + &input) < 0) { mailbox_header_lookup_deinit(&headers_ctx); return FALSE; } @@ -545,8 +541,7 @@ } else { struct message_size hdr_size; - input = mail_get_stream(ctx->mail, &hdr_size, NULL); - if (input == NULL) + if (mail_get_stream(ctx->mail, &hdr_size, NULL, &input) < 0) return FALSE; i_stream_seek(input, hdr_size.physical_size); @@ -558,7 +553,7 @@ memset(&body_ctx, 0, sizeof(body_ctx)); body_ctx.index_ctx = ctx; body_ctx.input = input; - body_ctx.part = mail_get_parts(ctx->mail); + (void)mail_get_parts(ctx->mail, &body_ctx.part); mail_search_args_foreach(args, search_body, &body_ctx); }
--- a/src/lib-storage/index/index-sort.c Sun Aug 12 18:16:40 2007 +0300 +++ b/src/lib-storage/index/index-sort.c Sun Aug 12 19:40:54 2007 +0300 @@ -158,8 +158,7 @@ struct message_address *addr; const char *str; - str = mail_get_first_header_utf8(mail, header); - if (str == NULL) + if (mail_get_first_header_utf8(mail, header, &str) <= 0) return ""; addr = message_address_parse(pool_datastack_create(), @@ -177,10 +176,10 @@ mail_set_seq(mail, seq); switch (sort_type & MAIL_SORT_MASK) { case MAIL_SORT_SUBJECT: - str = mail_get_first_header(mail, "Subject"); - return str == NULL ? "" : - imap_get_base_subject_cased(pool_datastack_create(), - str, NULL); + if (mail_get_first_header(mail, "Subject", &str) <= 0) + return ""; + return imap_get_base_subject_cased(pool_datastack_create(), + str, NULL); case MAIL_SORT_CC: str = get_first_mailbox(mail, "Cc"); break; @@ -230,13 +229,13 @@ time1 = ctx->cache_time; else { mail_set_seq(ctx->mail, n1->seq); - time1 = mail_get_received_date(ctx->mail); - if (time1 == (time_t)-1) time1 = 0; + if (mail_get_received_date(ctx->mail, &time1) < 0) + time1 = 0; } mail_set_seq(ctx->mail, n2->seq); - time2 = mail_get_received_date(ctx->mail); - if (time2 == (time_t)-1) time2 = 0; + if (mail_get_received_date(ctx->mail, &time2) < 0) + time2 = 0; ret = time1 < time2 ? -1 : (time1 > time2 ? 1 : 0); @@ -246,13 +245,13 @@ time1 = ctx->cache_time; else { mail_set_seq(ctx->mail, n1->seq); - time1 = mail_get_date(ctx->mail, NULL); - if (time1 == (time_t)-1) time1 = 0; + if (mail_get_date(ctx->mail, &time1, NULL) < 0) + time1 = 0; } mail_set_seq(ctx->mail, n2->seq); - time2 = mail_get_date(ctx->mail, NULL); - if (time2 == (time_t)-1) time2 = 0; + if (mail_get_date(ctx->mail, &time2, NULL) < 0) + time2 = 0; ret = time1 < time2 ? -1 : (time1 > time2 ? 1 : 0); @@ -262,13 +261,13 @@ size1 = ctx->cache_size; else { mail_set_seq(ctx->mail, n1->seq); - size1 = mail_get_virtual_size(ctx->mail); - if (size1 == (uoff_t)-1) size1 = 0; + if (mail_get_virtual_size(ctx->mail, &size1) < 0) + size1 = 0; } mail_set_seq(ctx->mail, n2->seq); - size2 = mail_get_virtual_size(ctx->mail); - if (size2 == (uoff_t)-1) size2 = 0; + if (mail_get_virtual_size(ctx->mail, &size2) < 0) + size2 = 0; ret = size1 < size2 ? -1 : (size1 > size2 ? 1 : 0); @@ -469,24 +468,25 @@ { time_t time; - time = mail_get_received_date(mail); - return time == (time_t)-1 ? 0 : time; + if (mail_get_received_date(mail, &time) < 0) + return 0; + return time; } static uint32_t get_sort_id_date(struct mail *mail) { time_t time; - time = mail_get_date(mail, NULL); - return time == (time_t)-1 ? 0 : time; + if (mail_get_date(mail, &time, NULL) < 0) + return 0; + return time; } static uint32_t get_sort_id_size(struct mail *mail) { uoff_t size; - size = mail_get_virtual_size(mail); - if (size == (uoff_t)-1) + if (mail_get_virtual_size(mail, &size) < 0) return 0; /* FIXME: elsewhere we support 64bit message sizes, but here @@ -494,7 +494,7 @@ to support 64bit here currently, so until such messages actually start showing up somewhere, 32bit is enough */ i_assert(size <= (uint32_t)-1); - return size == size; + return size; } static void index_sort_preset_sort_ids(struct mail_search_sort_program *program,
--- a/src/lib-storage/index/maildir/maildir-mail.c Sun Aug 12 18:16:40 2007 +0300 +++ b/src/lib-storage/index/maildir/maildir-mail.c Sun Aug 12 19:40:54 2007 +0300 @@ -74,7 +74,9 @@ if (data->access_part != 0 && data->stream == NULL) { /* we're going to open the mail anyway */ - (void)mail_get_stream(mail, NULL, NULL); + struct istream *input; + + (void)mail_get_stream(mail, NULL, NULL, &input); } if (data->stream != NULL) { @@ -95,46 +97,49 @@ } } else { path = maildir_save_file_get_path(mail->transaction, mail->seq); - if (do_stat(mbox, path, st) <= 0) + if (stat(path, st) < 0) { + mail_storage_set_critical(mail->box->storage, + "stat(%s) failed: %m", path); return -1; + } } return 0; } -static time_t maildir_mail_get_received_date(struct mail *_mail) +static int maildir_mail_get_received_date(struct mail *_mail, time_t *date_r) { struct index_mail *mail = (struct index_mail *)_mail; struct index_mail_data *data = &mail->data; struct stat st; uint32_t t; - (void)index_mail_get_received_date(_mail); - if (data->received_date != (time_t)-1) - return data->received_date; + (void)index_mail_get_received_date(_mail, date_r); + if (*date_r != (time_t)-1) + return 0; if (maildir_mail_stat(_mail, &st) < 0) - return (time_t)-1; + return -1; - data->received_date = t = st.st_mtime; + *date_r = data->received_date = t = st.st_mtime; index_mail_cache_add(mail, MAIL_CACHE_RECEIVED_DATE, &t, sizeof(t)); - return data->received_date; + return 0; } -static time_t maildir_mail_get_save_date(struct mail *_mail) +static int maildir_mail_get_save_date(struct mail *_mail, time_t *date_r) { struct index_mail *mail = (struct index_mail *)_mail; struct index_mail_data *data = &mail->data; struct stat st; uint32_t t; - (void)index_mail_get_save_date(_mail); - if (data->save_date != (time_t)-1) - return data->save_date; + (void)index_mail_get_save_date(_mail, date_r); + if (*date_r != (time_t)-1) + return 0; if (maildir_mail_stat(_mail, &st) < 0) - return (time_t)-1; + return -1; - data->save_date = t = st.st_ctime; + *date_r = data->save_date = t = st.st_ctime; index_mail_cache_add(mail, MAIL_CACHE_SAVE_DATE, &t, sizeof(t)); return data->save_date; } @@ -210,22 +215,23 @@ return mail->pop3_state; } -static uoff_t maildir_mail_get_virtual_size(struct mail *_mail) +static int maildir_mail_get_virtual_size(struct mail *_mail, uoff_t *size_r) { struct index_mail *mail = (struct index_mail *)_mail; struct maildir_mailbox *mbox = (struct maildir_mailbox *)mail->ibox; struct index_mail_data *data = &mail->data; struct message_size hdr_size, body_size; + struct istream *input; const char *path, *fname, *value; - uoff_t old_offset; + uoff_t old_offset, size; int pop3_state; - if (index_mail_get_cached_virtual_size(mail) != (uoff_t)-1) - return data->virtual_size; + if (index_mail_get_cached_virtual_size(mail, size_r)) + return 0; if (_mail->uid != 0) { if (!maildir_mail_get_fname(mbox, _mail, &fname)) - return (uoff_t)-1; + return -1; } else { path = maildir_save_file_get_path(_mail->transaction, _mail->seq); @@ -235,8 +241,10 @@ /* size can be included in filename */ if (maildir_filename_get_size(fname, MAILDIR_EXTRA_VIRTUAL_SIZE, - &data->virtual_size)) - return data->virtual_size; + &data->virtual_size)) { + *size_r = data->virtual_size; + return 0; + } /* size can be included in uidlist entry */ if (_mail->uid != 0) { @@ -245,16 +253,18 @@ if (value != NULL) { char *p; - data->virtual_size = strtoull(value, &p, 10); - if (*p == '\0') - return data->virtual_size; + size = strtoull(value, &p, 10); + if (*p == '\0') { + data->virtual_size = *size_r = size; + return 0; + } } } /* fallback to reading the file */ old_offset = data->stream == NULL ? 0 : data->stream->v_offset; - if (mail_get_stream(_mail, &hdr_size, &body_size) == NULL) - return (uoff_t)-1; + if (mail_get_stream(_mail, &hdr_size, &body_size, &input) < 0) + return -1; i_stream_seek(data->stream, old_offset); i_assert(data->virtual_size != (uoff_t)-1); @@ -272,11 +282,13 @@ MAILDIR_UIDLIST_REC_EXT_VSIZE, dec2str(data->virtual_size)); } - return data->virtual_size; + *size_r = data->virtual_size; + return 0; } -static const char * -maildir_mail_get_special(struct mail *_mail, enum mail_fetch_field field) +static int +maildir_mail_get_special(struct mail *_mail, enum mail_fetch_field field, + const char **value_r) { struct index_mail *mail = (struct index_mail *)_mail; struct maildir_mailbox *mbox = (struct maildir_mailbox *)mail->ibox; @@ -285,7 +297,7 @@ if (field == MAIL_FETCH_UIDL_FILE_NAME) { if (_mail->uid != 0) { if (!maildir_mail_get_fname(mbox, _mail, &fname)) - return NULL; + return -1; } else { path = maildir_save_file_get_path(_mail->transaction, _mail->seq); @@ -293,13 +305,14 @@ fname = fname != NULL ? fname + 1 : path; } end = strchr(fname, MAILDIR_INFO_SEP); - return end == NULL ? fname : t_strdup_until(fname, end); + *value_r = end == NULL ? fname : t_strdup_until(fname, end); + return 0; } - return index_mail_get_special(_mail, field); + return index_mail_get_special(_mail, field, value_r); } -static uoff_t maildir_mail_get_physical_size(struct mail *_mail) +static int maildir_mail_get_physical_size(struct mail *_mail, uoff_t *size_r) { struct index_mail *mail = (struct index_mail *)_mail; struct maildir_mailbox *mbox = (struct maildir_mailbox *)mail->ibox; @@ -309,13 +322,13 @@ uoff_t size; int ret; - size = index_mail_get_physical_size(_mail); - if (size != (uoff_t)-1) - return size; + (void)index_mail_get_physical_size(_mail, size_r); + if (*size_r != (uoff_t)-1) + return 0; if (_mail->uid != 0) { if (!maildir_mail_get_fname(mbox, _mail, &fname)) - return (uoff_t)-1; + return -1; path = NULL; } else { path = maildir_save_file_get_path(_mail->transaction, @@ -331,12 +344,15 @@ if (ret <= 0) { if (ret == 0) mail_set_expunged(_mail); - return (uoff_t)-1; + return -1; } } else { /* saved mail which hasn't been committed yet */ - if (do_stat(mbox, path, &st) <= 0) - return (uoff_t)-1; + if (stat(path, &st) < 0) { + mail_storage_set_critical(_mail->box->storage, + "stat(%s) failed: %m", path); + return -1; + } } size = st.st_size; } @@ -344,12 +360,14 @@ index_mail_cache_add(mail, MAIL_CACHE_PHYSICAL_FULL_SIZE, &size, sizeof(size)); data->physical_size = size; - return size; + *size_r = size; + return 0; } -static struct istream *maildir_mail_get_stream(struct mail *_mail, - struct message_size *hdr_size, - struct message_size *body_size) +static int maildir_mail_get_stream(struct mail *_mail, + struct message_size *hdr_size, + struct message_size *body_size, + struct istream **stream_r) { struct index_mail *mail = (struct index_mail *)_mail; struct maildir_mailbox *mbox = (struct maildir_mailbox *)mail->ibox; @@ -361,11 +379,11 @@ if (data->stream == NULL) { if (deleted) mail_set_expunged(_mail); - return NULL; + return -1; } } - return index_mail_init_stream(mail, hdr_size, body_size); + return index_mail_init_stream(mail, hdr_size, body_size, stream_r); } struct mail_vfuncs maildir_mail_vfuncs = {
--- a/src/lib-storage/index/maildir/maildir-save.c Sun Aug 12 18:16:40 2007 +0300 +++ b/src/lib-storage/index/maildir/maildir-save.c Sun Aug 12 19:40:54 2007 +0300 @@ -484,8 +484,10 @@ /* remember the size in case we want to add it to filename */ ctx->file_last->size = ctx->output->offset; - ctx->file_last->vsize = ctx->cur_dest_mail == NULL ? (uoff_t)-1 : - mail_get_virtual_size(ctx->cur_dest_mail); + if (ctx->cur_dest_mail == NULL || + mail_get_virtual_size(ctx->cur_dest_mail, + &ctx->file_last->vsize) < 0) + ctx->file_last->vsize = (uoff_t)-1; output_errno = ctx->output->stream_errno; o_stream_destroy(&ctx->output);
--- a/src/lib-storage/index/mbox/mbox-mail.c Sun Aug 12 18:16:40 2007 +0300 +++ b/src/lib-storage/index/mbox/mbox-mail.c Sun Aug 12 19:40:54 2007 +0300 @@ -91,19 +91,19 @@ return 0; } -static time_t mbox_mail_get_received_date(struct mail *_mail) +static int mbox_mail_get_received_date(struct mail *_mail, time_t *date_r) { struct index_mail *mail = (struct index_mail *)_mail; struct index_mail_data *data = &mail->data; struct mbox_mailbox *mbox = (struct mbox_mailbox *)mail->ibox; uint32_t t; - (void)index_mail_get_received_date(_mail); - if (data->received_date != (time_t)-1) - return data->received_date; + (void)index_mail_get_received_date(_mail, date_r); + if (*date_r != (time_t)-1) + return 0; if (mbox_mail_seek(mail) < 0) - return (time_t)-1; + return -1; data->received_date = istream_raw_mbox_get_received_time(mbox->mbox_stream); if (data->received_date == (time_t)-1) { @@ -114,17 +114,18 @@ t = data->received_date; index_mail_cache_add(mail, MAIL_CACHE_RECEIVED_DATE, &t, sizeof(t)); - return data->received_date; + *date_r = data->received_date; + return 0; } -static time_t mbox_mail_get_save_date(struct mail *_mail) +static int mbox_mail_get_save_date(struct mail *_mail, time_t *date_r) { struct index_mail *mail = (struct index_mail *)_mail; struct index_mail_data *data = &mail->data; - (void)index_mail_get_save_date(_mail); - if (data->save_date != (time_t)-1) - return data->save_date; + (void)index_mail_get_save_date(_mail, date_r); + if (*date_r != (time_t)-1) + return 0; /* no way to know this. save the current time into cache and use that from now on. this works only as long as the index files @@ -132,27 +133,30 @@ data->save_date = ioloop_time; index_mail_cache_add(mail, MAIL_CACHE_SAVE_DATE, &data->save_date, sizeof(data->save_date)); - return data->save_date; + *date_r = data->save_date; + return 0; } -static const char * -mbox_mail_get_special(struct mail *_mail, enum mail_fetch_field field) +static int +mbox_mail_get_special(struct mail *_mail, enum mail_fetch_field field, + const char **value_r) { #define EMPTY_MD5_SUM "00000000000000000000000000000000" struct index_mail *mail = (struct index_mail *)_mail; struct mbox_mailbox *mbox = (struct mbox_mailbox *)mail->ibox; - const char *value; switch (field) { case MAIL_FETCH_FROM_ENVELOPE: if (mbox_mail_seek(mail) < 0) - return NULL; + return -1; - return istream_raw_mbox_get_sender(mbox->mbox_stream); + *value_r = istream_raw_mbox_get_sender(mbox->mbox_stream); + return 0; case MAIL_FETCH_HEADER_MD5: - value = index_mail_get_special(_mail, field); - if (value != NULL && strcmp(value, EMPTY_MD5_SUM) != 0) - return value; + if (index_mail_get_special(_mail, field, value_r) < 0) + return -1; + if (**value_r != '\0' && strcmp(*value_r, EMPTY_MD5_SUM) != 0) + return 0; /* i guess in theory the EMPTY_MD5_SUM is valid and can happen, but it's almost guaranteed that it means the MD5 sum is @@ -160,16 +164,16 @@ mbox->mbox_save_md5 = TRUE; mbox_prepare_resync(mail); if (mbox_sync(mbox, MBOX_SYNC_FORCE_SYNC) < 0) - return NULL; + return -1; break; default: break; } - return index_mail_get_special(_mail, field); + return index_mail_get_special(_mail, field, value_r); } -static uoff_t mbox_mail_get_physical_size(struct mail *_mail) +static int mbox_mail_get_physical_size(struct mail *_mail, uoff_t *size_r) { struct index_mail *mail = (struct index_mail *)_mail; struct index_mail_data *data = &mail->data; @@ -178,24 +182,28 @@ uoff_t hdr_offset, body_offset, body_size; if (mbox_mail_seek(mail) < 0) - return (uoff_t)-1; + return -1; /* our header size varies, so don't do any caching */ stream = mbox->mbox_stream; hdr_offset = istream_raw_mbox_get_header_offset(stream); body_offset = istream_raw_mbox_get_body_offset(stream); - if (body_offset == (uoff_t)-1) - return (uoff_t)-1; + if (body_offset == (uoff_t)-1) { + mail_storage_set_critical(_mail->box->storage, + "Couldn't get mbox size"); + return -1; + } body_size = istream_raw_mbox_get_body_size(stream, (uoff_t)-1); data->physical_size = (body_offset - hdr_offset) + body_size; - return data->physical_size; - + *size_r = data->physical_size; + return 0; } -static struct istream *mbox_mail_get_stream(struct mail *_mail, - struct message_size *hdr_size, - struct message_size *body_size) +static int mbox_mail_get_stream(struct mail *_mail, + struct message_size *hdr_size, + struct message_size *body_size, + struct istream **stream_r) { struct index_mail *mail = (struct index_mail *)_mail; struct index_mail_data *data = &mail->data; @@ -205,7 +213,7 @@ if (data->stream == NULL) { if (mbox_mail_seek(mail) < 0) - return NULL; + return -1; raw_stream = mbox->mbox_stream; offset = istream_raw_mbox_get_header_offset(raw_stream); @@ -219,7 +227,7 @@ i_stream_unref(&raw_stream); } - return index_mail_init_stream(mail, hdr_size, body_size); + return index_mail_init_stream(mail, hdr_size, body_size, stream_r); } struct mail_vfuncs mbox_mail_vfuncs = {
--- a/src/lib-storage/mail-copy.c Sun Aug 12 18:16:40 2007 +0300 +++ b/src/lib-storage/mail-copy.c Sun Aug 12 19:40:54 2007 +0300 @@ -12,15 +12,20 @@ struct mail_save_context *ctx; struct istream *input; const char *from_envelope; + time_t received_date; - input = mail_get_stream(mail, NULL, NULL); - if (input == NULL) + if (mail_get_stream(mail, NULL, NULL, &input) < 0) + return -1; + if (mail_get_received_date(mail, &received_date) < 0) + return -1; + if (mail_get_special(mail, MAIL_FETCH_FROM_ENVELOPE, + &from_envelope) < 0) return -1; - from_envelope = mail_get_special(mail, MAIL_FETCH_FROM_ENVELOPE); + if (*from_envelope == '\0') + from_envelope = NULL; - if (mailbox_save_init(t, flags, keywords, - mail_get_received_date(mail), + if (mailbox_save_init(t, flags, keywords, received_date, 0, from_envelope, input, dest_mail, &ctx) < 0) return -1;
--- a/src/lib-storage/mail-storage-private.h Sun Aug 12 18:16:40 2007 +0300 +++ b/src/lib-storage/mail-storage-private.h Sun Aug 12 19:40:54 2007 +0300 @@ -201,27 +201,28 @@ enum mail_flags (*get_flags)(struct mail *mail); const char *const *(*get_keywords)(struct mail *mail); - const struct message_part *(*get_parts)(struct mail *mail); - time_t (*get_date)(struct mail *mail, int *timezone); - time_t (*get_received_date)(struct mail *mail); - time_t (*get_save_date)(struct mail *mail); - uoff_t (*get_virtual_size)(struct mail *mail); - uoff_t (*get_physical_size)(struct mail *mail); + int (*get_parts)(struct mail *mail, + const struct message_part **parts_r); + int (*get_date)(struct mail *mail, time_t *date_r, int *timezone_r); + int (*get_received_date)(struct mail *mail, time_t *date_r); + int (*get_save_date)(struct mail *mail, time_t *date_r); + int (*get_virtual_size)(struct mail *mail, uoff_t *size_r); + int (*get_physical_size)(struct mail *mail, uoff_t *size_r); - const char *(*get_first_header)(struct mail *mail, const char *field, - bool decode_to_utf8); - const char *const *(*get_headers)(struct mail *mail, const char *field, - bool decode_to_utf8); - struct istream * - (*get_header_stream)(struct mail *mail, - struct mailbox_header_lookup_ctx *headers); - struct istream *(*get_stream)(struct mail *mail, - struct message_size *hdr_size, - struct message_size *body_size); + int (*get_first_header)(struct mail *mail, const char *field, + bool decode_to_utf8, const char **value_r); + int (*get_headers)(struct mail *mail, const char *field, + bool decode_to_utf8, const char *const **value_r); + int (*get_header_stream)(struct mail *mail, + struct mailbox_header_lookup_ctx *headers, + struct istream **stream_r); + int (*get_stream)(struct mail *mail, struct message_size *hdr_size, + struct message_size *body_size, + struct istream **stream_r); - const char *(*get_special)(struct mail *mail, - enum mail_fetch_field field); + int (*get_special)(struct mail *mail, enum mail_fetch_field field, + const char **value_r); void (*update_flags)(struct mail *mail, enum modify_type modify_type, enum mail_flags flags);
--- a/src/lib-storage/mail-storage.h Sun Aug 12 18:16:40 2007 +0300 +++ b/src/lib-storage/mail-storage.h Sun Aug 12 19:40:54 2007 +0300 @@ -143,6 +143,7 @@ MAILBOX_SYNC_TYPE_KEYWORDS = 0x04 }; +struct message_part; struct mail_namespace; struct mail_storage; struct mail_search_arg; @@ -390,13 +391,6 @@ do forced CLOSE. */ bool mailbox_is_inconsistent(struct mailbox *box); -/* Returns message's flags */ -enum mail_flags mail_get_flags(struct mail *mail); -/* Returns message's keywords */ -const char *const *mail_get_keywords(struct mail *mail); -/* Returns message's MIME parts */ -const struct message_part *mail_get_parts(struct mail *mail); - struct mail *mail_alloc(struct mailbox_transaction_context *t, enum mail_fetch_field wanted_fields, struct mailbox_header_lookup_ctx *wanted_headers); @@ -406,44 +400,54 @@ mail_*() functions shouldn't be called if FALSE is returned. */ bool mail_set_uid(struct mail *mail, uint32_t uid); -/* Get the Date-header of the mail. Timezone is in minutes. - Returns (time_t)-1 if error occurred, 0 if field wasn't found or - couldn't be parsed. */ -time_t mail_get_date(struct mail *mail, int *timezone); -/* Get the time when the mail was received (IMAP INTERNALDATE). - Returns (time_t)-1 if error occurred. */ -time_t mail_get_received_date(struct mail *mail); +/* Returns message's flags */ +enum mail_flags mail_get_flags(struct mail *mail); +/* Returns message's keywords */ +const char *const *mail_get_keywords(struct mail *mail); + +/* Returns message's MIME parts */ +int mail_get_parts(struct mail *mail, const struct message_part **parts_r); + +/* Get the Date-header of the mail. Timezone is in minutes. date=0 if it + wasn't found or it was invalid. */ +int mail_get_date(struct mail *mail, time_t *date_r, int *timezone_r); +/* Get the time when the mail was received (IMAP INTERNALDATE). */ +int mail_get_received_date(struct mail *mail, time_t *date_r); /* Get the time when the mail was saved into this mailbox. This time may not - always be entirely reliable. Returns (time_t)-1 if error occurred. */ -time_t mail_get_save_date(struct mail *mail); + always be entirely reliable. */ +int mail_get_save_date(struct mail *mail, time_t *date_r); /* Get the space used by the mail as seen by the reader. Linefeeds are always - counted as being CR+LF. Returns (uoff_t)-1 if error occurred */ -uoff_t mail_get_virtual_size(struct mail *mail); -/* Get the space used by the mail in disk. - Returns (uoff_t)-1 if error occurred */ -uoff_t mail_get_physical_size(struct mail *mail); + counted as being CR+LF. */ +int mail_get_virtual_size(struct mail *mail, uoff_t *size_r); +/* Get the space used by the mail in disk. */ +int mail_get_physical_size(struct mail *mail, uoff_t *size_r); -/* Get value for single header field */ -const char *mail_get_first_header(struct mail *mail, const char *field); +/* Get value for single header field, or NULL if header wasn't found. + Returns 1 if header was found, 0 if not, -1 if error. */ +int mail_get_first_header(struct mail *mail, const char *field, + const char **value_r); /* Like mail_get_first_header(), but decode MIME encoded words to UTF-8 */ -const char *mail_get_first_header_utf8(struct mail *mail, const char *field); +int mail_get_first_header_utf8(struct mail *mail, const char *field, + const char **value_r); /* Return a NULL-terminated list of values for each found field. */ -const char *const *mail_get_headers(struct mail *mail, const char *field); +int mail_get_headers(struct mail *mail, const char *field, + const char *const **value_r); /* Like mail_get_headers(), but decode MIME encoded words to UTF-8 */ -const char *const *mail_get_headers_utf8(struct mail *mail, const char *field); +int mail_get_headers_utf8(struct mail *mail, const char *field, + const char *const **value_r); /* Returns stream containing specified headers. */ -struct istream * -mail_get_header_stream(struct mail *mail, - struct mailbox_header_lookup_ctx *headers); +int mail_get_header_stream(struct mail *mail, + struct mailbox_header_lookup_ctx *headers, + struct istream **stream_r); /* Returns input stream pointing to beginning of message header. hdr_size and body_size are updated unless they're NULL. */ -struct istream *mail_get_stream(struct mail *mail, - struct message_size *hdr_size, - struct message_size *body_size); +int mail_get_stream(struct mail *mail, struct message_size *hdr_size, + struct message_size *body_size, struct istream **stream_r); /* Get any of the "special" fields. */ -const char *mail_get_special(struct mail *mail, enum mail_fetch_field field); +int mail_get_special(struct mail *mail, enum mail_fetch_field field, + const char **value_r); /* Update message flags. */ void mail_update_flags(struct mail *mail, enum modify_type modify_type,
--- a/src/lib-storage/mail.c Sun Aug 12 18:16:40 2007 +0300 +++ b/src/lib-storage/mail.c Sun Aug 12 19:40:54 2007 +0300 @@ -47,99 +47,107 @@ return p->v.get_keywords(mail); } -const struct message_part *mail_get_parts(struct mail *mail) +int mail_get_parts(struct mail *mail, const struct message_part **parts_r) { struct mail_private *p = (struct mail_private *)mail; - return p->v.get_parts(mail); + return p->v.get_parts(mail, parts_r); } -time_t mail_get_received_date(struct mail *mail) +int mail_get_date(struct mail *mail, time_t *date_r, int *timezone_r) { struct mail_private *p = (struct mail_private *)mail; + int tz; - return p->v.get_received_date(mail); + if (timezone_r == NULL) + timezone_r = &tz; + + return p->v.get_date(mail, date_r, timezone_r); } -time_t mail_get_save_date(struct mail *mail) +int mail_get_received_date(struct mail *mail, time_t *date_r) { struct mail_private *p = (struct mail_private *)mail; - return p->v.get_save_date(mail); + return p->v.get_received_date(mail, date_r); } -time_t mail_get_date(struct mail *mail, int *timezone) +int mail_get_save_date(struct mail *mail, time_t *date_r) { struct mail_private *p = (struct mail_private *)mail; - return p->v.get_date(mail, timezone); + return p->v.get_save_date(mail, date_r); } -uoff_t mail_get_virtual_size(struct mail *mail) +int mail_get_virtual_size(struct mail *mail, uoff_t *size_r) { struct mail_private *p = (struct mail_private *)mail; - return p->v.get_virtual_size(mail); + return p->v.get_virtual_size(mail, size_r); } -uoff_t mail_get_physical_size(struct mail *mail) +int mail_get_physical_size(struct mail *mail, uoff_t *size_r) { struct mail_private *p = (struct mail_private *)mail; - return p->v.get_physical_size(mail); + return p->v.get_physical_size(mail, size_r); } -const char *mail_get_first_header(struct mail *mail, const char *field) +int mail_get_first_header(struct mail *mail, const char *field, + const char **value_r) { struct mail_private *p = (struct mail_private *)mail; - return p->v.get_first_header(mail, field, FALSE); + return p->v.get_first_header(mail, field, FALSE, value_r); } -const char *mail_get_first_header_utf8(struct mail *mail, const char *field) +int mail_get_first_header_utf8(struct mail *mail, const char *field, + const char **value_r) { struct mail_private *p = (struct mail_private *)mail; - return p->v.get_first_header(mail, field, TRUE); + return p->v.get_first_header(mail, field, TRUE, value_r); } -const char *const *mail_get_headers(struct mail *mail, const char *field) +int mail_get_headers(struct mail *mail, const char *field, + const char *const **value_r) { struct mail_private *p = (struct mail_private *)mail; - return p->v.get_headers(mail, field, FALSE); + return p->v.get_headers(mail, field, FALSE, value_r); } -const char *const *mail_get_headers_utf8(struct mail *mail, const char *field) +int mail_get_headers_utf8(struct mail *mail, const char *field, + const char *const **value_r) { struct mail_private *p = (struct mail_private *)mail; - return p->v.get_headers(mail, field, TRUE); + return p->v.get_headers(mail, field, TRUE, value_r); } -struct istream * -mail_get_header_stream(struct mail *mail, - struct mailbox_header_lookup_ctx *headers) +int mail_get_header_stream(struct mail *mail, + struct mailbox_header_lookup_ctx *headers, + struct istream **stream_r) { struct mail_private *p = (struct mail_private *)mail; - return p->v.get_header_stream(mail, headers); + return p->v.get_header_stream(mail, headers, stream_r); } -struct istream *mail_get_stream(struct mail *mail, - struct message_size *hdr_size, - struct message_size *body_size) +int mail_get_stream(struct mail *mail, struct message_size *hdr_size, + struct message_size *body_size, struct istream **stream_r) { struct mail_private *p = (struct mail_private *)mail; - return p->v.get_stream(mail, hdr_size, body_size); + return p->v.get_stream(mail, hdr_size, body_size, stream_r); } -const char *mail_get_special(struct mail *mail, enum mail_fetch_field field) +int mail_get_special(struct mail *mail, enum mail_fetch_field field, + const char **value_r) { struct mail_private *p = (struct mail_private *)mail; - return p->v.get_special(mail, field); + return p->v.get_special(mail, field, value_r); } void mail_update_flags(struct mail *mail, enum modify_type modify_type,
--- a/src/plugins/expire/expire-plugin.c Sun Aug 12 18:16:40 2007 +0300 +++ b/src/plugins/expire/expire-plugin.c Sun Aug 12 19:40:54 2007 +0300 @@ -78,8 +78,7 @@ for (seq = 2; seq <= hdr->messages_count; seq++) { if (!mail_index_is_expunged(view, seq)) { mail_set_seq(xt->mail, seq); - *stamp_r = mail_get_save_date(xt->mail); - if (*stamp_r != (time_t)-1) + if (mail_get_save_date(xt->mail, stamp_r) == 0) return; } }
--- a/src/plugins/expire/expire-tool.c Sun Aug 12 18:16:40 2007 +0300 +++ b/src/plugins/expire/expire-tool.c Sun Aug 12 19:40:54 2007 +0300 @@ -91,8 +91,7 @@ now = time(NULL); while ((ret = mailbox_search_next(search_ctx, mail)) > 0) { - save_time = mail_get_save_date(mail); - if (save_time == (time_t)-1) { + if (mail_get_save_date(mail, &save_time) < 0) { /* maybe just got expunged. anyway try again later. */ ret = -1; break;
--- a/src/plugins/fts/fts-storage.c Sun Aug 12 18:16:40 2007 +0300 +++ b/src/plugins/fts/fts-storage.c Sun Aug 12 19:40:54 2007 +0300 @@ -163,8 +163,7 @@ ctx->uid = ctx->mail->uid; - input = mail_get_stream(ctx->mail, NULL, NULL); - if (input == NULL) + if (mail_get_stream(ctx->mail, NULL, NULL, &input) < 0) return -1; prev_part = skip_part = NULL;
--- a/src/plugins/mail-log/mail-log-plugin.c Sun Aug 12 18:16:40 2007 +0300 +++ b/src/plugins/mail-log/mail-log-plugin.c Sun Aug 12 19:40:54 2007 +0300 @@ -174,15 +174,13 @@ if ((mail_log_set.fields & MAIL_LOG_FIELD_PSIZE) != 0 && (event & (MAIL_LOG_EVENT_EXPUNGE | MAIL_LOG_EVENT_COPY)) != 0) { - size = mail_get_physical_size(mail); - if (size != (uoff_t)-1) + if (mail_get_physical_size(mail, &size) == 0) group->psize_total += size; } if ((mail_log_set.fields & MAIL_LOG_FIELD_VSIZE) != 0 && (event & (MAIL_LOG_EVENT_EXPUNGE | MAIL_LOG_EVENT_COPY)) != 0) { - size = mail_get_virtual_size(mail); - if (size != (uoff_t)-1) + if (mail_get_virtual_size(mail, &size) == 0) group->vsize_total += size; } } @@ -297,21 +295,20 @@ str_printfa(str, "dest=%s, ", data); if ((mail_log_set.fields & MAIL_LOG_FIELD_MSGID) != 0) { - msgid = mail_get_first_header(mail, "Message-ID"); - str_printfa(str, "msgid=%s, ", msgid == NULL ? "(null)" : + if (mail_get_first_header(mail, "Message-ID", &msgid) <= 0) + msgid = "(null"; + str_printfa(str, "msgid=%s, ", str_sanitize(msgid, MSGID_LOG_LEN)); } if ((mail_log_set.fields & MAIL_LOG_FIELD_PSIZE) != 0 && (event & (MAIL_LOG_EVENT_EXPUNGE | MAIL_LOG_EVENT_COPY)) != 0) { - size = mail_get_physical_size(mail); - if (size != (uoff_t)-1) + if (mail_get_physical_size(mail, &size) == 0) str_printfa(str, "size=%"PRIuUOFF_T", ", size); } if ((mail_log_set.fields & MAIL_LOG_FIELD_VSIZE) != 0 && (event & (MAIL_LOG_EVENT_EXPUNGE | MAIL_LOG_EVENT_COPY)) != 0) { - size = mail_get_virtual_size(mail); - if (size != (uoff_t)-1) + if (mail_get_virtual_size(mail, &size) == 0) str_printfa(str, "vsize=%"PRIuUOFF_T", ", size); } str_truncate(str, str_len(str)-2);
--- a/src/plugins/quota/quota-count.c Sun Aug 12 18:16:40 2007 +0300 +++ b/src/plugins/quota/quota-count.c Sun Aug 12 19:40:54 2007 +0300 @@ -29,8 +29,7 @@ ctx = mailbox_search_init(trans, NULL, &search_arg, NULL); mail = mail_alloc(trans, MAIL_FETCH_PHYSICAL_SIZE, NULL); while (mailbox_search_next(ctx, mail) > 0) { - size = mail_get_physical_size(mail); - if (size != (uoff_t)-1) + if (mail_get_physical_size(mail, &size) == 0) *bytes_r += size; *count_r += 1; }
--- a/src/plugins/quota/quota-storage.c Sun Aug 12 18:16:40 2007 +0300 +++ b/src/plugins/quota/quota-storage.c Sun Aug 12 19:40:54 2007 +0300 @@ -53,8 +53,7 @@ the mail at the same time. In here we'll just save the message's physical size and do the quota freeing later when the message was known to be expunged. */ - size = mail_get_physical_size(_mail); - if (size != (uoff_t)-1) { + if (mail_get_physical_size(_mail, &size) == 0) { if (!array_is_created(&qbox->expunge_uids)) { i_array_init(&qbox->expunge_uids, 64); i_array_init(&qbox->expunge_sizes, 64); @@ -318,12 +317,8 @@ mail_alloc(qbox->expunge_trans, MAIL_FETCH_PHYSICAL_SIZE, NULL); } - if (!mail_set_uid(qbox->expunge_qt->tmp_mail, uid)) - size = (uoff_t)-1; - else - size = mail_get_physical_size(qbox->expunge_qt->tmp_mail); - - if (size != (uoff_t)-1) + if (mail_set_uid(qbox->expunge_qt->tmp_mail, uid) && + mail_get_physical_size(qbox->expunge_qt->tmp_mail, &size) == 0) quota_free_bytes(qbox->expunge_qt, size); else { /* there's no way to get the size. recalculate the quota. */
--- a/src/plugins/quota/quota.c Sun Aug 12 18:16:40 2007 +0300 +++ b/src/plugins/quota/quota.c Sun Aug 12 19:40:54 2007 +0300 @@ -696,9 +696,13 @@ int quota_try_alloc(struct quota_transaction_context *ctx, struct mail *mail, bool *too_large_r) { + uoff_t size; int ret; - ret = quota_test_alloc(ctx, mail_get_physical_size(mail), too_large_r); + if (mail_get_physical_size(mail, &size) < 0) + return -1; + + ret = quota_test_alloc(ctx, size, too_large_r); if (ret <= 0) return ret; @@ -754,8 +758,7 @@ { uoff_t size; - size = mail_get_physical_size(mail); - if (size != (uoff_t)-1) + if (mail_get_physical_size(mail, &size) == 0) ctx->bytes_used += size; ctx->count_used++; @@ -765,8 +768,7 @@ { uoff_t size; - size = mail_get_physical_size(mail); - if (size == (uoff_t)-1) + if (mail_get_physical_size(mail, &size) < 0) quota_recalculate(ctx); else quota_free_bytes(ctx, size);
--- a/src/plugins/trash/trash-plugin.c Sun Aug 12 18:16:40 2007 +0300 +++ b/src/plugins/trash/trash-plugin.c Sun Aug 12 19:40:54 2007 +0300 @@ -91,7 +91,8 @@ trash->mail_set = TRUE; } - *received_time_r = mail_get_received_date(trash->mail); + if (mail_get_received_date(trash->mail, received_time_r) < 0) + return -1; return 1; } @@ -145,8 +146,8 @@ } if (oldest_idx < count) { - size = mail_get_physical_size(trashes[oldest_idx].mail); - if (size == (uoff_t)-1) { + if (mail_get_physical_size(trashes[oldest_idx].mail, + &size) < 0) { /* maybe expunged already? */ trashes[oldest_idx].mail_set = FALSE; continue;
--- a/src/pop3/client.c Sun Aug 12 18:16:40 2007 +0300 +++ b/src/pop3/client.c Sun Aug 12 19:40:54 2007 +0300 @@ -57,6 +57,7 @@ struct mailbox_status status; struct mail *mail; buffer_t *message_sizes_buf; + uoff_t size; int i; bool failed; @@ -82,9 +83,7 @@ failed = FALSE; mail = mail_alloc(t, MAIL_FETCH_VIRTUAL_SIZE, NULL); while (mailbox_search_next(ctx, mail) > 0) { - uoff_t size = mail_get_virtual_size(mail); - - if (size == (uoff_t)-1) { + if (mail_get_virtual_size(mail, &size) < 0) { failed = TRUE; break; }
--- a/src/pop3/commands.c Sun Aug 12 18:16:40 2007 +0300 +++ b/src/pop3/commands.c Sun Aug 12 19:40:54 2007 +0300 @@ -379,12 +379,8 @@ ctx->mail = mail_alloc(client->trans, MAIL_FETCH_STREAM_HEADER | MAIL_FETCH_STREAM_BODY, NULL); - if (mailbox_search_next(ctx->search_ctx, ctx->mail) <= 0) - ctx->stream = NULL; - else - ctx->stream = mail_get_stream(ctx->mail, NULL, NULL); - - if (ctx->stream == NULL) { + if (mailbox_search_next(ctx->search_ctx, ctx->mail) <= 0 || + mail_get_stream(ctx->mail, NULL, NULL, &ctx->stream) < 0) { client_send_line(client, "-ERR Message not found."); fetch_deinit(ctx); return; @@ -542,18 +538,18 @@ if ((uidl_keymask & UIDL_UID) != 0) tab[1].value = dec2str(ctx->mail->uid); if ((uidl_keymask & UIDL_MD5) != 0) { - tab[2].value = mail_get_special(ctx->mail, - MAIL_FETCH_HEADER_MD5); - if (tab[2].value == NULL) { + if (mail_get_special(ctx->mail, MAIL_FETCH_HEADER_MD5, + &tab[2].value) < 0 || + *tab[2].value == '\0') { /* broken */ i_fatal("UIDL: Header MD5 not found"); } } if ((uidl_keymask & UIDL_FILE_NAME) != 0) { - tab[3].value = - mail_get_special(ctx->mail, - MAIL_FETCH_UIDL_FILE_NAME); - if (tab[3].value == NULL) { + if (mail_get_special(ctx->mail, + MAIL_FETCH_UIDL_FILE_NAME, + &tab[3].value) < 0 || + *tab[3].value == '\0') { /* broken */ i_fatal("UIDL: File name not found"); } @@ -563,12 +559,11 @@ str_printfa(str, ctx->message == 0 ? "%u " : "+OK %u ", ctx->mail->seq); - uidl = !reuse_xuidl ? NULL : - mail_get_first_header(ctx->mail, "X-UIDL"); - if (uidl == NULL) + if (reuse_xuidl && + mail_get_first_header(ctx->mail, "X-UIDL", &uidl) > 0) + str_append(str, uidl); + else var_expand(str, uidl_format, tab); - else - str_append(str, uidl); ret = client_send_line(client, "%s", str_c(str)); t_pop();