8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen#ifndef ISTREAM_ATTACHMENT_H
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen#define ISTREAM_ATTACHMENT_H
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainenstruct istream_attachment_header {
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen struct message_part *part;
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen const char *content_type, *content_disposition;
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen};
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainenstruct istream_attachment_info {
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen const char *hash;
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen /* offset within input stream where the attachment starts */
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen uoff_t start_offset;
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen /* original (base64-encoded) size of the attachment */
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen uoff_t encoded_size;
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen unsigned int base64_blocks_per_line;
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen bool base64_have_crlf;
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen const struct message_part *part;
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen};
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainenstruct istream_attachment_settings {
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen /* Minimum size of of a MIME part to be saved separately. */
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen uoff_t min_size;
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen /* Format to use when calculating attachment's hash. */
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen struct hash_format *hash_format;
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen /* Set this to TRUE if parent stream can be read from as long as
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen wanted. This is useful when parsing attachments, which the extractor
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen hides from read() output, so they would return a lot of 0.
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen On the other hand if you have a tee-istream, it's not a good idea
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen to let it get to "buffer full" state. */
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen bool drain_parent_input;
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen /* Returns TRUE if message part is wanted to be stored as separate
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen attachment. If NULL, assume we want the attachment. */
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen bool (*want_attachment)(const struct istream_attachment_header *hdr,
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen void *context);
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen /* Create a temporary file. */
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen int (*open_temp_fd)(void *context);
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen /* Create output stream for attachment */
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen int (*open_attachment_ostream)(struct istream_attachment_info *info,
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen struct ostream **output_r,
0482d891a6669537e10a1abc9866b45f2fc55fccTimo Sirainen const char **error_r, void *context);
d3aecee1eb9c37db930a061695bb49efd2cd4abeTimo Sirainen /* Finish output stream. If success==FALSE, *error contains the error
d3aecee1eb9c37db930a061695bb49efd2cd4abeTimo Sirainen and the error shouldn't be replaced (other than maybe enhanced).
d3aecee1eb9c37db930a061695bb49efd2cd4abeTimo Sirainen Otherwise, if close_attachment_ostream() fails and returns -1, it
d3aecee1eb9c37db930a061695bb49efd2cd4abeTimo Sirainen should also set *error. */
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen int (*close_attachment_ostream)(struct ostream *output, bool success,
d3aecee1eb9c37db930a061695bb49efd2cd4abeTimo Sirainen const char **error, void *context);
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen};
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainenstruct istream *
8aeae03f9f447c8a792b215c9fb954468053c556Timo Siraineni_stream_create_attachment_extractor(struct istream *input,
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen struct istream_attachment_settings *set,
af5fc8ca268d69dd3ebbe0416ec6270f94121e39Timo Sirainen void *context) ATTR_NULL(3);
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen/* Returns TRUE if the last read returned 0 only because
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen drain_parent_input=FALSE and we didn't have anything to return, but
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen retrying a read from parent stream could give something the next time. */
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainenbool i_stream_attachment_extractor_can_retry(struct istream *input);
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen
8aeae03f9f447c8a792b215c9fb954468053c556Timo Sirainen#endif