static void stream_add_data(struct attachment_istream *astream,
			    const void *data, size_t size)
{
	if (size > 0) {
		memcpy(i_stream_alloc(&astream->istream, size), data, size);
		astream->istream.pos += size;
	}
}
Esempio n. 2
0
static int i_stream_seekable_write_failed(struct seekable_istream *sstream)
{
	struct istream_private *stream = &sstream->istream;
	void *data;

	i_assert(sstream->fd != -1);

	stream->max_buffer_size = (size_t)-1;
	data = i_stream_alloc(stream, sstream->write_peak);

	if (pread_full(sstream->fd, data, sstream->write_peak, 0) < 0) {
		i_error("istream-seekable: read(%s) failed: %m", sstream->temp_path);
		memarea_unref(&stream->memarea);
		return -1;
	}
	i_stream_destroy(&sstream->fd_input);
	i_close_fd(&sstream->fd);

	i_free_and_null(sstream->temp_path);
	return 0;
}
Esempio n. 3
0
static ssize_t i_stream_ssl_read_real(struct istream_private *stream)
{
	struct ssl_istream *sstream = (struct ssl_istream *)stream;
	struct ssl_iostream *ssl_io = sstream->ssl_io;
	unsigned char buffer[IO_BLOCK_SIZE];
	size_t max_buffer_size = i_stream_get_max_buffer_size(&stream->istream);
	size_t orig_max_buffer_size = stream->max_buffer_size;
	size_t size;
	ssize_t ret, total_ret;

	if (sstream->seen_eof) {
		stream->istream.eof = TRUE;
		return -1;
	}

	if (stream->pos >= max_buffer_size) {
		i_stream_compress(stream);
		if (stream->pos >= max_buffer_size)
			return -2;
	}

	ret = openssl_iostream_more(ssl_io);
	if (ret <= 0) {
		if (ret < 0) {
			/* handshake failed */
			i_assert(errno != 0);
			io_stream_set_error(&stream->iostream,
					    "%s", ssl_io->last_error);
			stream->istream.stream_errno = errno;
		}
		return ret;
	}

	if (!i_stream_try_alloc(stream, 1, &size))
		i_unreached();
	if (stream->pos + size > max_buffer_size) {
		i_assert(max_buffer_size > stream->pos);
		size = max_buffer_size - stream->pos;
	}

	while ((ret = SSL_read(ssl_io->ssl,
			       stream->w_buffer + stream->pos, size)) <= 0) {
		/* failed to read anything */
		ret = openssl_iostream_handle_error(ssl_io, ret, "SSL_read");
		if (ret <= 0) {
			if (ret == 0)
				return 0;
			if (ssl_io->last_error != NULL) {
				io_stream_set_error(&stream->iostream,
						    "%s", ssl_io->last_error);
			}
			if (errno != EPIPE)
				stream->istream.stream_errno = errno;
			stream->istream.eof = TRUE;
			sstream->seen_eof = TRUE;
			return -1;
		}
		/* we did some BIO I/O, try reading again */
	}
	stream->pos += ret;
	total_ret = ret;

	/* now make sure that we read everything already buffered in OpenSSL
	   into the stream (without reading anything more). this makes I/O loop
	   behave similary for ssl-istream as file-istream. */
	sstream->ssl_io->input_handler = FALSE;
	stream->max_buffer_size = (size_t)-1;
	while ((ret = SSL_read(ssl_io->ssl, buffer, sizeof(buffer))) > 0) {
		memcpy(i_stream_alloc(stream, ret), buffer, ret);
		stream->pos += ret;
		total_ret += ret;
	}
	stream->max_buffer_size = orig_max_buffer_size;
	return total_ret;
}