예제 #1
0
static ssize_t
i_stream_mail_read(struct istream_private *stream)
{
	struct mail_istream *mstream = (struct mail_istream *)stream;
	size_t size;
	ssize_t ret;

	i_stream_seek(stream->parent, stream->parent_start_offset +
		      stream->istream.v_offset);

	ret = i_stream_read_copy_from_parent(&stream->istream);
	size = i_stream_get_data_size(&stream->istream);
	if (ret > 0) {
		mstream->mail->transaction->stats.files_read_bytes += ret;
		if (!mstream->files_read_increased) {
			mstream->files_read_increased = TRUE;
			mstream->mail->transaction->stats.files_read_count++;
		}
		if (mstream->expected_size < stream->istream.v_offset + size) {
			i_stream_mail_set_size_corrupted(mstream, size);
			return -1;
		}
	} else if (ret == -1 && stream->istream.eof) {
		if (!mstream->input_has_body) {
			/* trying to read past the header, but this stream
			   doesn't have the body */
			return -1;
		}
		if (stream->istream.stream_errno != 0) {
			if (stream->istream.stream_errno == ENOENT) {
				/* update mail's expunged-flag if needed */
				index_mail_refresh_expunged(mstream->mail);
			}
			return -1;
		}
		if (i_stream_mail_try_get_cached_size(mstream) &&
		    mstream->expected_size > stream->istream.v_offset + size) {
			i_stream_mail_set_size_corrupted(mstream, size);
			return -1;
		}
	}
	return ret;
}
예제 #2
0
struct istream *i_stream_create_mail(struct mail *mail, struct istream *input,
				     bool input_has_body)
{
	struct mail_istream *mstream;

	mstream = i_new(struct mail_istream, 1);
	mstream->mail = mail;
	mstream->input_has_body = input_has_body;
	mstream->expected_size = (uoff_t)-1;
	(void)i_stream_mail_try_get_cached_size(mstream);
	mstream->istream.max_buffer_size = input->real_stream->max_buffer_size;
	mstream->istream.stream_size_passthrough = TRUE;

	mstream->istream.read = i_stream_mail_read;

	mstream->istream.istream.blocking = input->blocking;
	mstream->istream.istream.seekable = input->seekable;
	return i_stream_create(&mstream->istream, input,
			       i_stream_get_fd(input));
}