コード例 #1
0
ファイル: istream-metawrap.c プロジェクト: damoxc/dovecot
static ssize_t i_stream_metawrap_read(struct istream_private *stream)
{
	struct metawrap_istream *mstream = (struct metawrap_istream *)stream;
	int ret;

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

	if (mstream->in_metadata) {
		ret = metadata_header_read(mstream);
		i_assert(stream->istream.v_offset == 0);
		mstream->start_offset = stream->parent->v_offset;
		if (ret <= 0)
			return ret;
		/* this stream is kind of silently skipping over the metadata */
		stream->abs_start_offset += mstream->start_offset;
		mstream->in_metadata = FALSE;
		if (mstream->pending_seek != 0) {
			i_stream_seek(&stream->istream, mstream->pending_seek);
			return i_stream_read(&stream->istream);
		}
	}
	/* after metadata header it's all just passthrough */
	return i_stream_read_copy_from_parent(&stream->istream);
}
コード例 #2
0
ファイル: istream-hash.c プロジェクト: LTD-Beget/dovecot
static ssize_t
i_stream_hash_read(struct istream_private *stream)
{
	struct hash_istream *hstream = (struct hash_istream *)stream;
	const unsigned char *data;
	size_t size;
	uoff_t skip;
	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);
	if (ret > 0 && hstream->hash_context != NULL) {
		data = i_stream_get_data(&stream->istream, &size);
		i_assert((size_t)ret <= size);

		i_assert(stream->istream.v_offset <= hstream->high_offset);
		skip = hstream->high_offset - stream->istream.v_offset;
		if (skip < (size_t)size) {
			hstream->high_offset += (size-skip);
			hstream->method->loop(hstream->hash_context,
					      data+skip, size-skip);
		}
	} else if (ret < 0) {
		/* we finished hashing it. don't access it anymore, because
		   the memory pointed by the hash may be freed before the
		   istream itself */
		hstream->hash_context = NULL;
	}
	return ret;
}
コード例 #3
0
ファイル: http-server-request.c プロジェクト: Raffprta/core
static void
http_server_istream_read_any(struct http_server_istream *hsristream)
{
	struct istream_private *stream = &hsristream->istream;
	struct http_server *server = hsristream->req->server;
	ssize_t ret;

	if ((ret=i_stream_read_copy_from_parent
		(&stream->istream)) > 0) {
		hsristream->read_status = ret;
		io_loop_stop(server->ioloop);
	}
}
コード例 #4
0
ファイル: istream-fs-file.c プロジェクト: manuelm/dovecot
static ssize_t i_stream_fs_file_read(struct istream_private *stream)
{
    struct fs_file_istream *fstream = (struct fs_file_istream *)stream;
    struct istream *input;

    if (fstream->istream.parent == NULL) {
        input = fs_read_stream(fstream->file,
                               i_stream_get_max_buffer_size(&stream->istream));
        i_stream_init_parent(stream, input);
        i_stream_unref(&input);
    }

    i_stream_seek(stream->parent, stream->parent_start_offset +
                  stream->istream.v_offset);
    return i_stream_read_copy_from_parent(&stream->istream);
}
コード例 #5
0
ファイル: istream-mail.c プロジェクト: bechtoldt/dovecot-core
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;
}
コード例 #6
0
ファイル: istream-mail-stats.c プロジェクト: aosm/dovecot
static ssize_t
i_stream_mail_stats_read_mail_stats(struct istream_private *stream)
{
	struct mail_stats_istream *mstream =
		(struct mail_stats_istream *)stream;
	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);
	if (ret > 0) {
		mstream->mail->stats_files_read_bytes += ret;
		if (!mstream->files_read_increased) {
			mstream->files_read_increased = TRUE;
			mstream->mail->stats_files_read_count++;
		}
	}
	return ret;
}
コード例 #7
0
static ssize_t
i_stream_failure_at_read(struct istream_private *stream)
{
	struct failure_at_istream *fstream = (struct failure_at_istream *)stream;
	uoff_t new_offset;
	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);
	new_offset = stream->istream.v_offset + (stream->pos - stream->skip);
	if (ret >= 0 && new_offset >= fstream->failure_offset) {
		if (stream->istream.v_offset >= fstream->failure_offset) {
			/* we already passed the wanted failure offset,
			   return error immediately. */
			stream->pos = stream->skip;
			stream->istream.stream_errno = errno = EIO;
			io_stream_set_error(&stream->iostream, "%s",
					    fstream->error_string);
			ret = -1;
		} else {
			/* return data up to the wanted failure offset and
			   on the next read() call return failure */
			size_t new_pos = fstream->failure_offset -
				stream->istream.v_offset + stream->skip;
			i_assert(new_pos >= stream->skip &&
				 stream->pos >= new_pos);
			ret -= stream->pos - new_pos;
			stream->pos = new_pos;
		}
	} else if (ret < 0 && stream->istream.stream_errno == 0 &&
		   fstream->failure_offset == (uoff_t)-1) {
		/* failure at EOF */
		stream->istream.stream_errno = errno = EIO;
		io_stream_set_error(&stream->iostream, "%s",
				    fstream->error_string);
	}
	return ret;
}
コード例 #8
0
ファイル: http-server-request.c プロジェクト: Raffprta/core
static ssize_t
http_server_istream_read(struct istream_private *stream)
{
	struct http_server_istream *hsristream =
		(struct http_server_istream *)stream;
	struct http_server_request *req = hsristream->req;
	struct http_server *server;
	struct http_server_connection *conn;
	bool blocking = stream->istream.blocking;
	ssize_t ret;

	if (req == NULL) {
		/* request already gone (we shouldn't get here) */
		stream->istream.stream_errno = EINVAL;
		return -1;
	}

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

	server = hsristream->req->server;
	conn = hsristream->req->conn;

	ret = i_stream_read_copy_from_parent(&stream->istream);
	if (ret == 0 && blocking) {
		struct ioloop *prev_ioloop = current_ioloop;
		struct io *io;

		http_server_connection_ref(conn);
		http_server_request_ref(req);

		i_assert(server->ioloop == NULL);
		server->ioloop = io_loop_create();
		http_server_connection_switch_ioloop(conn);

		if (blocking && req->req.expect_100_continue &&
			!req->sent_100_continue)
			http_server_connection_trigger_responses(conn);

		hsristream->read_status = 0;
		io = io_add_istream(&stream->istream,
			http_server_istream_read_any, hsristream);
		while (req->state < HTTP_SERVER_REQUEST_STATE_FINISHED &&
			hsristream->read_status == 0) {
			io_loop_run(server->ioloop);
		}
		io_remove(&io);

		io_loop_set_current(prev_ioloop);
		http_server_connection_switch_ioloop(conn);
		io_loop_set_current(server->ioloop);
		io_loop_destroy(&server->ioloop);

		ret = hsristream->read_status;

		if (!http_server_request_unref(&req))
			hsristream->req = NULL;
		http_server_connection_unref(&conn);
	}

	return ret;
}