#ifndef IMAP_MSGPART_H #define IMAP_MSGPART_H struct imap_msgpart; struct imap_msgpart_open_result { /* message contents with CRLF linefeeds */ struct istream *input; /* size of input */ uoff_t size; /* if size was looked up using cache and it ends up being wrong, this field can be used to log about cache corruption */ enum mail_fetch_field size_field; /* TRUE if BINARY decoded content contains NUL characters */ bool binary_decoded_input_has_nuls; }; struct imap_msgpart *imap_msgpart_full(void); struct imap_msgpart *imap_msgpart_header(void); struct imap_msgpart *imap_msgpart_body(void); /* Parse section into imap_msgpart. Returns 0 and msgpart_r on success, -1 if the section isn't valid. The same imap_msgpart can be used to open multiple messages. */ int imap_msgpart_parse(const char *section, struct imap_msgpart **msgpart_r); void imap_msgpart_free(struct imap_msgpart **msgpart); /* Returns TRUE if the msgpart might return at least part of the message body. Or alternatively: If FALSE is returned, the msgpart will never return anything except (part of) the message header. MIME headers are counted as part of the message body. */ bool imap_msgpart_contains_body(const struct imap_msgpart *msgpart); /* Decode MIME parts with Content-Transfer-Encoding: base64/quoted-printable to binary data (IMAP BINARY extension). If something can't be decoded, fails with storage error set to MAIL_ERROR_CONVERSION. */ void imap_msgpart_set_decode_to_binary(struct imap_msgpart *msgpart); /* Set the fetch to be partial. For unlimited size use UOFF_T_MAX. */ void imap_msgpart_set_partial(struct imap_msgpart *msgpart, uoff_t offset, uoff_t size); uoff_t imap_msgpart_get_partial_offset(struct imap_msgpart *msgpart); uoff_t imap_msgpart_get_partial_size(struct imap_msgpart *msgpart); /* Return wanted_fields mask. */ enum mail_fetch_field imap_msgpart_get_fetch_data(struct imap_msgpart *msgpart); /* Append all the specifically requested headers to the headers array (no deduplication is done) */ void imap_msgpart_get_wanted_headers(struct imap_msgpart *msgpart, ARRAY_TYPE(const_string) *headers); /* Open message part refenced by IMAP section as istream. Returns 0 if successful, -1 if storage error. Returned istream is initially referenced, so i_stream_unref() must be called for it. */ int imap_msgpart_open(struct mail *mail, struct imap_msgpart *msgpart, struct imap_msgpart_open_result *result_r); /* Return msgpart's size without actually opening the stream (if possible). */ int imap_msgpart_size(struct mail *mail, struct imap_msgpart *msgpart, uoff_t *size_r); /* Return msgpart's IMAP BODYPARTSTRUCTURE */ int imap_msgpart_bodypartstructure(struct mail *mail, struct imap_msgpart *msgpart, const char **bpstruct_r); /* Header context is automatically created by imap_msgpart_open() and destroyed by imap_msgpart_free(), but if you want to use the same imap_msgpart across multiple mailboxes, you need to close the part before closing the mailbox. */ void imap_msgpart_close_mailbox(struct imap_msgpart *msgpart); #endif