bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2015-2018 Dovecot authors, see the included COPYING file */
289bb39856d74484c1622d096922acf126dd90fcTimo Sirainenstatic void i_stream_failure_at_destroy(struct iostream_private *stream)
289bb39856d74484c1622d096922acf126dd90fcTimo Siraineni_stream_failure_at_read(struct istream_private *stream)
289bb39856d74484c1622d096922acf126dd90fcTimo Sirainen struct failure_at_istream *fstream = (struct failure_at_istream *)stream;
289bb39856d74484c1622d096922acf126dd90fcTimo Sirainen i_stream_seek(stream->parent, stream->parent_start_offset +
289bb39856d74484c1622d096922acf126dd90fcTimo Sirainen ret = i_stream_read_copy_from_parent(&stream->istream);
289bb39856d74484c1622d096922acf126dd90fcTimo Sirainen new_offset = stream->istream.v_offset + (stream->pos - stream->skip);
289bb39856d74484c1622d096922acf126dd90fcTimo Sirainen if (ret >= 0 && new_offset >= fstream->failure_offset) {
289bb39856d74484c1622d096922acf126dd90fcTimo Sirainen if (stream->istream.v_offset >= fstream->failure_offset) {
289bb39856d74484c1622d096922acf126dd90fcTimo Sirainen /* we already passed the wanted failure offset,
289bb39856d74484c1622d096922acf126dd90fcTimo Sirainen return error immediately. */
289bb39856d74484c1622d096922acf126dd90fcTimo Sirainen /* return data up to the wanted failure offset and
289bb39856d74484c1622d096922acf126dd90fcTimo Sirainen on the next read() call return failure */
289bb39856d74484c1622d096922acf126dd90fcTimo Sirainen } else if (ret < 0 && stream->istream.stream_errno == 0 &&
289bb39856d74484c1622d096922acf126dd90fcTimo Sirainen /* failure at EOF */
289bb39856d74484c1622d096922acf126dd90fcTimo Siraineni_stream_create_failure_at(struct istream *input, uoff_t failure_offset,
289bb39856d74484c1622d096922acf126dd90fcTimo Sirainen fstream = i_new(struct failure_at_istream, 1);
289bb39856d74484c1622d096922acf126dd90fcTimo Sirainen fstream->istream.max_buffer_size = input->real_stream->max_buffer_size;
289bb39856d74484c1622d096922acf126dd90fcTimo Sirainen fstream->istream.stream_size_passthrough = TRUE;
289bb39856d74484c1622d096922acf126dd90fcTimo Sirainen fstream->istream.read = i_stream_failure_at_read;
289bb39856d74484c1622d096922acf126dd90fcTimo Sirainen fstream->istream.iostream.destroy = i_stream_failure_at_destroy;
25fb397382c6f7d39bfeee85774e7675f02bfb3cTimo Sirainen fstream->istream.istream.readable_fd = input->readable_fd;
289bb39856d74484c1622d096922acf126dd90fcTimo Sirainen fstream->istream.istream.blocking = input->blocking;
289bb39856d74484c1622d096922acf126dd90fcTimo Sirainen fstream->istream.istream.seekable = input->seekable;
289bb39856d74484c1622d096922acf126dd90fcTimo Sirainen fstream->error_string = i_strdup(error_string);
289bb39856d74484c1622d096922acf126dd90fcTimo Sirainen return i_stream_create(&fstream->istream, input,
a4985564b81d51caaddd38376792432428fd449bStephan Boschi_stream_create_failure_at_eof(struct istream *input, int stream_errno,