imap-msgpart.c revision d65184737a0465602db98e103f9097b1a1ea9564
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* "" for root, otherwise e.g. "1.2.3". the .MIME, .HEADER, etc.
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch suffix not included */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* HEADER.FIELDS[.NOT] (list of headers) */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch const char *const *headers;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* which part of the message part to fetch (default: 0..(uoff_t)-1) */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* from matching message_part, set after opening: */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschstatic struct imap_msgpart *imap_msgpart_type(enum fetch_type fetch_type)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch pool = pool_alloconly_create("imap msgpart", sizeof(*msgpart)+32);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch msgpart = p_new(pool, struct imap_msgpart, 1);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (fetch_type == FETCH_HEADER || fetch_type == FETCH_FULL)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch msgpart->wanted_fields |= MAIL_FETCH_STREAM_HEADER;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (fetch_type == FETCH_BODY || fetch_type == FETCH_FULL)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch msgpart->wanted_fields |= MAIL_FETCH_STREAM_BODY;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschimap_msgpart_find(struct message_part *parts, const char *section)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch unsigned int num;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch while (*path >= '0' && *path <= '9' && part != NULL) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* get part number, we have already verified its validity */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if ((part->flags & MESSAGE_PART_FLAG_MULTIPART) != 0) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* find the part */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* only 1 allowed with non-multipart messages.
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if the child isn't message/rfc822, the path must be
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch finished after this. */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch (part->flags & MESSAGE_PART_FLAG_MESSAGE_RFC822) == 0)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch (part->flags & MESSAGE_PART_FLAG_MESSAGE_RFC822) != 0 &&
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* if we continue inside the message/rfc822, skip this
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschimap_msgpart_get_header_fields(pool_t pool, const char *header_list,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch unsigned int i;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch input = i_stream_create_from_data(header_list, strlen(header_list));
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch parser = imap_parser_create(input, NULL, (size_t)-1);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (imap_parser_finish_line(parser, 0, 0, &args) > 0 &&
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch imap_arg_get_list_full(args, &hdr_list, &list_count) &&
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch for (i = 0; i < list_count; i++) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (!imap_arg_get_astring(&hdr_list[i], &value)) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* istream-header-filter requires headers to be sorted */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschimap_msgpart_parse_header_fields(struct imap_msgpart *msgpart,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* HEADER.FIELDS (list), HEADER.FIELDS.NOT (list) */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (imap_msgpart_get_header_fields(msgpart->pool, header_list,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschint imap_msgpart_parse(const char *section, struct imap_msgpart **msgpart_r)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch unsigned int i;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch pool = pool_alloconly_create("imap msgpart", 1024);
ca4526e3b5fbf5ea3dd477a2098522a44c9ac52cTimo Sirainen msgpart = *msgpart_r = p_new(pool, struct imap_msgpart, 1);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* get the section number */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch } else if (!next_digit && section[i] == '.') {
ca4526e3b5fbf5ea3dd477a2098522a44c9ac52cTimo Sirainen if (i == 0) {
ca4526e3b5fbf5ea3dd477a2098522a44c9ac52cTimo Sirainen /* [], [HEADER], etc. */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* [1.2.3] */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch msgpart->section_number = p_strdup(pool, section);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* [1.2.3.MIME], [1.2.3.HEADER], etc */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch msgpart->section_number = p_strndup(pool, section, i-1);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch msgpart->wanted_fields |= MAIL_FETCH_STREAM_BODY;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* BODY[] - header+body */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch msgpart->wanted_fields |= MAIL_FETCH_STREAM_HEADER;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* BODY[1] - body only */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch msgpart->wanted_fields |= MAIL_FETCH_STREAM_BODY;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* body (for root or for message/rfc822) */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch msgpart->wanted_fields |= MAIL_FETCH_STREAM_BODY;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch } else if (strncmp(section, "HEADER", 6) == 0) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* header (for root or for message/rfc822) */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch } else if (strncmp(section, "HEADER.FIELDS ", 14) == 0) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch ret = imap_msgpart_parse_header_fields(msgpart,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch } else if (strncmp(section, "HEADER.FIELDS.NOT ", 18) == 0) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch msgpart->fetch_type = FETCH_HEADER_FIELDS_NOT;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch ret = imap_msgpart_parse_header_fields(msgpart,
3858a7a5da361c35f1e6e50c8e3214dc0cf379d6Phil Carmody if (msgpart->fetch_type == FETCH_HEADER_FIELDS) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* we may be able to get this from cache, don't give a
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch wanted_fields hint */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch msgpart->wanted_fields |= MAIL_FETCH_STREAM_HEADER;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch msgpart->wanted_fields |= MAIL_FETCH_STREAM_BODY;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschvoid imap_msgpart_free(struct imap_msgpart **_msgpart)
4fa772eefd5a22a597601488be44997e788cb60dStephan Boschvoid imap_msgpart_set_decode_to_binary(struct imap_msgpart *msgpart)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschvoid imap_msgpart_set_partial(struct imap_msgpart *msgpart,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschuoff_t imap_msgpart_get_partial_offset(struct imap_msgpart *msgpart)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschenum mail_fetch_field imap_msgpart_get_fetch_data(struct imap_msgpart *msgpart)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschimap_msgpart_get_partial_header(struct mail *mail, struct istream *mail_input,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch const char *const *hdr_fields = msgpart->headers;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch unsigned int hdr_count = str_array_length(hdr_fields);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (msgpart->fetch_type == FETCH_HEADER_FIELDS) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch input = i_stream_create_header_filter(mail_input,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch i_assert(msgpart->fetch_type == FETCH_HEADER_FIELDS_NOT);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch input = i_stream_create_header_filter(mail_input,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (message_get_header_size(input, hdr_size_r, &has_nuls) < 0) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch "read(%s) failed: %m", i_stream_get_name(mail_input));
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschskip_using_parts(struct mail *mail, struct istream *input,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch mail->lookup_abort = MAIL_LOOKUP_ABORT_NOT_IN_CACHE;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch for (part = parts, vpos = 0; part != NULL; ) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (vpos + part->header_size.virtual_size > *virtual_skip)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* skip header */
2d72e8492960794037a1ca90df34f7ab2a170a81Timo Sirainen *virtual_skip -= part->header_size.virtual_size;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch i_stream_seek(input, physical_start + part->physical_pos +
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (vpos + part->body_size.virtual_size <= *virtual_skip) {
2d72e8492960794037a1ca90df34f7ab2a170a81Timo Sirainen /* skip body */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch *virtual_skip -= part->body_size.virtual_size;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* maybe we have a child and can skip using it? */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschstatic struct istream *
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschimap_msgpart_crlf_seek(struct mail *mail, struct istream *input,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch struct mail_msgpart_partial_cache *cache = &mail->box->partial_cache;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch const unsigned char *data;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch uoff_t virtual_skip = msgpart->partial_offset;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch i_assert(msgpart->headers == NULL); /* HEADER.FIELDS returns CRLFs */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* no need to seek */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* use cache */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch i_stream_seek(input, physical_start + cache->physical_pos);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* can't use cache, but maybe we can skip faster using the
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch message parts. */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch skip_using_parts(mail, input, physical_start, &virtual_skip);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch i_stream_read_data(input, &data, &size, 0) > 0) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* update cache */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* the physical_pos points to virtual CRLF, but
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch virtual_pos already skipped CR. that can't work,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch so seek back the virtual CR */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschimap_msgpart_get_partial(struct mail *mail, const struct imap_msgpart *msgpart,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* input is already seeked to the beginning of the wanted data */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (msgpart->partial_offset >= part_size->virtual_size) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* can't seek past the MIME part */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch result->input = i_stream_create_from_data("", 0);
4fa772eefd5a22a597601488be44997e788cb60dStephan Bosch if (part_size->virtual_size == part_size->physical_size) {
4fa772eefd5a22a597601488be44997e788cb60dStephan Bosch /* input has CRLF linefeeds, we can quickly seek to
9008daea438f0e389b37aabbbde62a1f02725e32Timo Sirainen wanted position */
4fa772eefd5a22a597601488be44997e788cb60dStephan Bosch i_stream_skip(result->input, msgpart->partial_offset);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* input has LF linefeeds. it can be slow to seek to wanted
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch position, so try to do caching whenever possible */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch result->input = imap_msgpart_crlf_seek(mail, result->input,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch bytes_left = part_size->virtual_size - msgpart->partial_offset;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* limit output to specified number of bytes */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* send all bytes */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* IMAP literals must not contain NULs. change them to
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch 0x80 characters. */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch input2 = i_stream_create_nonuls(result->input, 0x80);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch input2 = i_stream_create_limit(result->input, result->size);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschimap_msgpart_find_part(struct mail *mail, const struct imap_msgpart *msgpart,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch part = imap_msgpart_find(parts, msgpart->section_number);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* MIME part not found. */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* What to do if this is a message/rfc822? Does it have
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch MIME headers or not? Possibilities are: a) no, return
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch empty string (UW-IMAP does this), b) return the same as
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch HEADER. Dovecot has done b) for a long time and it's not
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch very clear which one is correct, so we'll just continue
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* fetching message/rfc822 part's header/body */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if ((part->flags & MESSAGE_PART_FLAG_MESSAGE_RFC822) == 0) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschimap_msgpart_open_normal(struct mail *mail, struct imap_msgpart *msgpart,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* find the MIME part */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (mail_get_stream(mail, NULL, NULL, &input) < 0)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* fetch the whole message */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (mail_get_stream(mail, NULL, NULL, &input) < 0 ||
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch mail_get_virtual_size(mail, &body_size.virtual_size) < 0 ||
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch mail_get_physical_size(mail, &body_size.physical_size) < 0)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch result_r->size_field = MAIL_FETCH_VIRTUAL_SIZE;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* fetch the message's header */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (mail_get_hdr_stream(mail, &hdr_size, &input) < 0)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch result_r->size_field = MAIL_FETCH_MESSAGE_PARTS;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* try to lookup the headers from cache */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (mail_get_header_stream(mail, msgpart->header_ctx,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* fetch the message's body */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (mail_get_stream(mail, &hdr_size, &body_size, &input) < 0)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch result_r->size_field = MAIL_FETCH_MESSAGE_PARTS;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* return specific headers */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch return imap_msgpart_get_partial_header(mail, input, msgpart,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch part_size_r->physical_size += body_size.physical_size;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch part_size_r->virtual_size += body_size.virtual_size;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* fall through */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch part_size_r->physical_size += hdr_size.physical_size;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch part_size_r->virtual_size += hdr_size.virtual_size;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch part_size_r->physical_size += body_size.physical_size;
6541da94741ea43514cdac3dd2ebbcf839ffb783Stephan Bosch part_size_r->virtual_size += body_size.virtual_size;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschint imap_msgpart_open(struct mail *mail, struct imap_msgpart *msgpart,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if ((ret = imap_msgpart_find_part(mail, msgpart, &part)) < 0)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* MIME part not found. return an empty part. */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch result_r->input = i_stream_create_from_data("", 0);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* binary fetch */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch include_hdr = msgpart->fetch_type == FETCH_FULL;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (mail_get_binary_stream(mail, part, include_hdr, &size,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (imap_msgpart_open_normal(mail, msgpart, part, &part_size,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch result_r->binary_decoded_input_has_nuls = TRUE;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch imap_msgpart_get_partial(mail, msgpart, !binary, use_partial_cache,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschint imap_msgpart_size(struct mail *mail, struct imap_msgpart *msgpart,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* generic implementation */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (imap_msgpart_open(mail, msgpart, &result) < 0)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* binary-optimized implementation: */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if ((ret = imap_msgpart_find_part(mail, msgpart, &part)) < 0)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* MIME part not found. return an empty part. */
4fa772eefd5a22a597601488be44997e788cb60dStephan Bosch include_hdr = msgpart->fetch_type == FETCH_FULL;
4fa772eefd5a22a597601488be44997e788cb60dStephan Bosch return mail_get_binary_size(mail, part, include_hdr, size_r);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschimap_msgpart_parse_bodystructure(struct mail *mail,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch struct mail_private *pmail = (struct mail_private *)mail;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (mail_get_special(mail, MAIL_FETCH_IMAP_BODYSTRUCTURE,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* we just parsed the bodystructure */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (imap_bodystructure_parse(bodystructure, pmail->data_pool,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch "Invalid message_part/BODYSTRUCTURE %s: %s",
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch mail_set_cache_corrupted(mail, MAIL_FETCH_MESSAGE_PARTS);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch mail_set_cache_corrupted(mail, MAIL_FETCH_IMAP_BODYSTRUCTURE);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschimap_msgpart_vsizes_to_binary(struct mail *mail, const struct message_part *part,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (mail_get_binary_size(mail, part, FALSE, &size) < 0)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch for (part = part->children; part != NULL; part = part->next) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (imap_msgpart_vsizes_to_binary(mail, part, pos) < 0)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschint imap_msgpart_bodypartstructure(struct mail *mail,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* if we start parsing the body in here, make sure we also parse the
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch BODYSTRUCTURE */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch mail_add_temp_wanted_fields(mail, MAIL_FETCH_IMAP_BODYSTRUCTURE, NULL);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if ((ret = imap_msgpart_find_part(mail, msgpart, &part)) < 0)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* MIME part not found. */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (imap_msgpart_parse_bodystructure(mail, all_parts) < 0)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch ret = imap_msgpart_vsizes_to_binary(mail, part, &part);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch imap_bodystructure_write(part, bpstruct, TRUE);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschvoid imap_msgpart_close_mailbox(struct imap_msgpart *msgpart)