Beispiel #1
0
static int
i_stream_file_stat(struct istream_private *stream, bool exact ATTR_UNUSED)
{
	struct file_istream *fstream = (struct file_istream *) stream;
	const char *name = i_stream_get_name(&stream->istream);

	if (!fstream->file) {
		/* return defaults */
	} else if (stream->fd != -1) {
		if (fstat(stream->fd, &stream->statbuf) < 0) {
			stream->istream.stream_errno = errno;
			io_stream_set_error(&stream->iostream,
				"file_istream.fstat(%s) failed: %m", name);
			i_error("%s", i_stream_get_error(&stream->istream));
			return -1;
		}
	} else {
		if (stat(name, &stream->statbuf) < 0) {
			stream->istream.stream_errno = errno;
			io_stream_set_error(&stream->iostream,
				"file_istream.stat(%s) failed: %m", name);
			i_error("%s", i_stream_get_error(&stream->istream));
			return -1;
		}
	}
	return 0;
}
static int server_connection_send_cmd_input_more(struct server_connection *conn)
{
    off_t ret;

    /* ostream-dot writes only up to max buffer size, so keep it non-zero */
    o_stream_set_max_buffer_size(conn->cmd_output, IO_BLOCK_SIZE);
    ret = o_stream_send_istream(conn->cmd_output, conn->cmd_input);
    o_stream_set_max_buffer_size(conn->cmd_output, (size_t)-1);

    if (ret >= 0 && i_stream_have_bytes_left(conn->cmd_input)) {
        o_stream_set_flush_pending(conn->cmd_output, TRUE);
        return 0;
    }
    if (conn->cmd_input->stream_errno != 0) {
        i_error("read(%s) failed: %s",
                i_stream_get_name(conn->cmd_input),
                i_stream_get_error(conn->cmd_input));
    } else if (conn->cmd_output->stream_errno != 0 ||
               o_stream_flush(conn->cmd_output) < 0) {
        i_error("write(%s) failed: %s",
                o_stream_get_name(conn->cmd_output),
                o_stream_get_error(conn->cmd_output));
    }

    i_stream_destroy(&conn->cmd_input);
    o_stream_destroy(&conn->cmd_output);
    return ret < 0 ? -1 : 1;
}
Beispiel #3
0
static void proxy_client_input(struct login_proxy *proxy)
{
	const unsigned char *data;
	size_t size;
	ssize_t ret;

	proxy->last_io = ioloop_time;
	if (o_stream_get_buffer_used_size(proxy->server_output) >
	    OUTBUF_THRESHOLD) {
		/* proxy's output buffer is already quite full.
		   don't send more until we're below threshold. */
		io_remove(&proxy->client_io);
		return;
	}

	if (i_stream_read_data(proxy->client_input, &data, &size, 0) < 0) {
		const char *errstr = i_stream_get_error(proxy->client_input);
		login_proxy_free_errstr(&proxy, errstr, FALSE);
		return;
	}
	o_stream_cork(proxy->server_output);
	ret = o_stream_send(proxy->server_output, data, size);
	o_stream_uncork(proxy->server_output);
	if (ret != (ssize_t)size)
		login_proxy_free_ostream(&proxy, proxy->server_output, TRUE);
	else
		i_stream_skip(proxy->client_input, ret);
}
Beispiel #4
0
static
void test_static_v1_input_short(void)
{
	ssize_t siz;
	const struct hash_method *hash = hash_method_lookup("sha256");
	unsigned char hash_ctx[hash->context_size];
	unsigned char hash_dgst[hash->digest_size];
	hash->init(hash_ctx);

	test_begin("test_static_v1_input_short");

	struct istream *is_1 = i_stream_create_file(DCRYPT_SRC_DIR"/sample-v1_short.asc", IO_BLOCK_SIZE);
	struct istream *is_2 = i_stream_create_base64_decoder(is_1);
	i_stream_unref(&is_1);
	struct istream *is_3 = i_stream_create_decrypt(is_2, test_v1_kp.priv);
	i_stream_unref(&is_2);
	struct istream *is_4 = i_stream_create_hash(is_3, hash, hash_ctx);
	i_stream_unref(&is_3);

	while((siz = i_stream_read(is_4))>0) { i_stream_skip(is_4, siz); }

	if (is_4->stream_errno != 0)
		i_debug("error: %s", i_stream_get_error(is_4));

	test_assert(is_4->stream_errno == 0);

	i_stream_unref(&is_4);

	hash->result(hash_ctx, hash_dgst);

	test_assert(strcmp(test_sample_v1_short_hash, binary_to_hex(hash_dgst, sizeof(hash_dgst))) == 0);

	test_end();
}
Beispiel #5
0
void http_client_request_set_payload(struct http_client_request *req,
				     struct istream *input, bool sync)
{
	int ret;

	i_assert(req->state == HTTP_REQUEST_STATE_NEW);
	i_assert(req->payload_input == NULL);

	i_stream_ref(input);
	req->payload_input = input;
	if ((ret = i_stream_get_size(input, TRUE, &req->payload_size)) <= 0) {
		if (ret < 0) {
			i_error("i_stream_get_size(%s) failed: %s",
				i_stream_get_name(input),
				i_stream_get_error(input));
		}
		req->payload_size = 0;
		req->payload_chunked = TRUE;
	}
	req->payload_offset = input->v_offset;

	/* prepare request payload sync using 100 Continue response from server */
	if ((req->payload_chunked || req->payload_size > 0) && sync)
		req->payload_sync = TRUE;
}
int sieve_file_storage_save_continue
(struct sieve_storage_save_context *sctx)
{
	struct sieve_file_save_context *fsctx =
		(struct sieve_file_save_context *)sctx;

	switch (o_stream_send_istream(fsctx->output, sctx->input)) {
	case OSTREAM_SEND_ISTREAM_RESULT_FINISHED:
	case OSTREAM_SEND_ISTREAM_RESULT_WAIT_INPUT:
		return 0;
	case OSTREAM_SEND_ISTREAM_RESULT_WAIT_OUTPUT:
		i_unreached();
	case OSTREAM_SEND_ISTREAM_RESULT_ERROR_INPUT:
		sieve_storage_set_critical(sctx->storage,
			"save: read(%s) failed: %s",
			i_stream_get_name(sctx->input),
			i_stream_get_error(sctx->input));
		return -1;
	case OSTREAM_SEND_ISTREAM_RESULT_ERROR_OUTPUT:
		sieve_storage_set_critical(sctx->storage,
			"save: write(%s) failed: %s", fsctx->tmp_path,
			o_stream_get_error(fsctx->output));
		return -1;
	}
	return 0;
}
static int fts_filter_stopwords_read_list(struct fts_filter_stopwords *filter,
					  const char **error_r)
{
	struct istream *input;
	const char *line, **words, *path;
	int ret = 0;

	path = t_strdup_printf(STOPWORDS_FILE_FORMAT,
			       filter->stopwords_dir, filter->lang->name);

	input = i_stream_create_file(path, IO_BLOCK_SIZE);
	while ((line = i_stream_read_next_line(input)) != NULL) T_BEGIN {
		line = t_strcut(line, STOPWORDS_COMMENT_CHAR1);
		line = t_strcut(line, STOPWORDS_COMMENT_CHAR2);

		words = t_strsplit_spaces(line, " \t");
		for (; *words != NULL; words++) {
			const char *word = p_strdup(filter->pool, *words);
			hash_table_insert(filter->stopwords, word, word);
		}
	} T_END;

	if (input->stream_errno != 0) {
		*error_r = t_strdup_printf("Failed to read stopword list %s: %s",
					   path, i_stream_get_error(input));
		ret = -1;
	}
	i_stream_destroy(&input);
	return ret;
}
Beispiel #8
0
int json_parser_deinit(struct json_parser **_parser, const char **error_r)
{
	struct json_parser *parser = *_parser;

	*_parser = NULL;

	if (parser->error != NULL) {
		/* actual parser error */
		*error_r = parser->error;
	} else if (parser->input->stream_errno != 0) {
		*error_r = t_strdup_printf("read(%s) failed: %s",
					   i_stream_get_name(parser->input),
					   i_stream_get_error(parser->input));
	} else if (parser->data == parser->end &&
		   !i_stream_have_bytes_left(parser->input) &&
		   parser->state != JSON_STATE_DONE) {
		*error_r = "Missing '}'";
	} else {
		*error_r = NULL;
	}
	
	i_stream_unref(&parser->input);
	array_free(&parser->nesting);
	str_free(&parser->value);
	i_free(parser);
	return *error_r != NULL ? -1 : 0;
}
Beispiel #9
0
static void login_connection_authreply_input(struct login_connection *conn)
{
	const char *line;

	while ((line = i_stream_read_next_line(conn->input)) != NULL) T_BEGIN {
		if (!conn->handshaked) {
			if (!version_string_verify(line, "director-authreply-client",
						   AUTHREPLY_PROTOCOL_MAJOR_VERSION)) {
				i_error("authreply client sent invalid handshake: %s", line);
				login_connection_deinit(&conn);
				return;
			}
			conn->handshaked = TRUE;
		} else {
			auth_input_line(line, conn);
		}
	} T_END;
	if (conn->input->eof) {
		if (conn->input->stream_errno != 0 &&
		    conn->input->stream_errno != ECONNRESET) {
			i_error("read(authreply connection) failed: %s",
				i_stream_get_error(conn->input));
		}
		login_connection_deinit(&conn);
	}
}
Beispiel #10
0
static int
cmd_save_to_mailbox(struct save_cmd_context *ctx, struct mailbox *box,
		    struct istream *input)
{
	struct mail_storage *storage = mailbox_get_storage(box);
	struct mailbox_transaction_context *trans;
	struct mail_save_context *save_ctx;
	ssize_t ret;
	bool save_failed = FALSE;

	if (mailbox_open(box) < 0) {
		i_error("Failed to open mailbox %s: %s",
			mailbox_get_vname(box), mailbox_get_last_error(box, NULL));
		doveadm_mail_failed_storage(&ctx->ctx, storage);
		return -1;
	}

	trans = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_EXTERNAL);
	save_ctx = mailbox_save_alloc(trans);
	if (mailbox_save_begin(&save_ctx, input) < 0) {
		i_error("Saving failed: %s", mailbox_get_last_error(box, NULL));
		doveadm_mail_failed_storage(&ctx->ctx, storage);
		mailbox_transaction_rollback(&trans);
		return -1;
	}
	while ((ret = i_stream_read(input)) > 0 || ret == -2) {
		if (mailbox_save_continue(save_ctx) < 0) {
			save_failed = TRUE;
			ret = -1;
			break;
		}
	}
	i_assert(ret == -1);

	if (input->stream_errno != 0) {
		i_error("read(msg input) failed: %s", i_stream_get_error(input));
		doveadm_mail_failed_error(&ctx->ctx, MAIL_ERROR_TEMP);
	} else if (save_failed) {
		i_error("Saving failed: %s", mailbox_get_last_error(box, NULL));
		doveadm_mail_failed_storage(&ctx->ctx, storage);
	} else if (mailbox_save_finish(&save_ctx) < 0) {
		i_error("Saving failed: %s",
			mailbox_get_last_error(box, NULL));
		doveadm_mail_failed_storage(&ctx->ctx, storage);
	} else if (mailbox_transaction_commit(&trans) < 0) {
		i_error("Save transaction commit failed: %s",
			mailbox_get_last_error(box, NULL));
		doveadm_mail_failed_storage(&ctx->ctx, storage);
	} else {
		ret = 0;
	}
	if (save_ctx != NULL)
		mailbox_save_cancel(&save_ctx);
	if (trans != NULL)
		mailbox_transaction_rollback(&trans);
	i_assert(input->eof);
	return ret < 0 ? -1 : 0;
}
Beispiel #11
0
static int copy_to_temp_file(struct seekable_istream *sstream)
{
	struct istream_private *stream = &sstream->istream;
	const char *path;
	const unsigned char *buffer;
	size_t size;
	int fd;

	fd = sstream->fd_callback(&path, sstream->context);
	if (fd == -1)
		return -1;

	/* copy our currently read buffer to it */
	i_assert(stream->pos <= sstream->buffer_peak);
	if (write_full(fd, stream->buffer, sstream->buffer_peak) < 0) {
		if (!ENOSPACE(errno))
			i_error("istream-seekable: write_full(%s) failed: %m", path);
		i_close_fd(&fd);
		return -1;
	}
	sstream->temp_path = i_strdup(path);
	sstream->write_peak = sstream->buffer_peak;

	sstream->fd = fd;
	sstream->fd_input = i_stream_create_fd_autoclose(&fd,
		I_MAX(stream->pos, sstream->istream.max_buffer_size));
	i_stream_set_name(sstream->fd_input, t_strdup_printf(
		"(seekable temp-istream for: %s)", i_stream_get_name(&stream->istream)));

	/* read back the data we just had in our buffer */
	for (;;) {
		buffer = i_stream_get_data(sstream->fd_input, &size);
		if (size >= stream->pos)
			break;

		ssize_t ret;
		if ((ret = i_stream_read_memarea(sstream->fd_input)) <= 0) {
			i_assert(ret != 0);
			i_assert(ret != -2);
			i_error("istream-seekable: Couldn't read back "
				"in-memory input %s: %s",
				i_stream_get_name(&stream->istream),
				i_stream_get_error(sstream->fd_input));
			i_stream_destroy(&sstream->fd_input);
			i_close_fd(&sstream->fd);
			return -1;
		}
	}
	/* Set the max buffer size only after we've already read everything
	   into memory. For example with istream-data it's possible that
	   more data exists in buffer than max_buffer_size. */
	i_stream_set_max_buffer_size(sstream->fd_input,
				     sstream->istream.max_buffer_size);
	stream->buffer = buffer;
	i_stream_free_buffer(&sstream->istream);
	return 0;
}
Beispiel #12
0
static
void test_static_v2_input(void)
{
	test_begin("test_static_v2_input");

	ssize_t amt;
	const struct hash_method *hash = hash_method_lookup("sha256");
	unsigned char hash_ctx[hash->context_size];
	unsigned char hash_dgst[hash->digest_size];
	hash->init(hash_ctx);

	struct istream *is_1 = i_stream_create_file(DCRYPT_SRC_DIR"/sample-v2.asc", IO_BLOCK_SIZE);
	struct istream *is_2 = i_stream_create_base64_decoder(is_1);
	i_stream_unref(&is_1);
	struct istream *is_3 = i_stream_create_decrypt(is_2, test_v2_kp.priv);
	i_stream_unref(&is_2);
	struct istream *is_4 = i_stream_create_hash(is_3, hash, hash_ctx);
	i_stream_unref(&is_3);

	while((amt = i_stream_read(is_4))>0) { i_stream_skip(is_4, amt); }

	if (is_4->stream_errno != 0)
		i_debug("error: %s", i_stream_get_error(is_4));

	test_assert(is_4->stream_errno == 0);

	i_stream_unref(&is_4);

	hash->result(hash_ctx, hash_dgst);

	test_assert(strcmp(test_sample_v2_hash, binary_to_hex(hash_dgst, sizeof(hash_dgst))) == 0);

	test_end();

/** this code is left here to show how the sample file is created
	struct istream *is = i_stream_create_file("../lib-fts/udhr_fra.txt", 8192);
	struct istream *is_2 = i_stream_create_hash(is, hash, hash_ctx);
	int fd = open("sample-v2.bin", O_CREAT|O_TRUNC|O_WRONLY, S_IRWXU);
	struct ostream *os = o_stream_create_fd_file(fd, 0, TRUE);
	struct ostream *os_2 = o_stream_create_encrypt(os, "aes-256-gcm-sha256", test_v2_kp.pub, IO_STREAM_ENC_INTEGRITY_AEAD);
	const unsigned char *ptr;
	size_t siz;

	while(i_stream_read_data(is_2, &ptr, &siz, 0)>0) {
		o_stream_nsend(os_2, ptr, siz);
		i_stream_skip(is_2, siz);
	}

	i_assert(o_stream_nfinish(os_2)==0);

	o_stream_close(os_2);
	i_stream_close(is_2);

	hash->result(hash_ctx, hash_dgst);
	printf("%s\n", binary_to_hex(hash_dgst, sizeof(hash_dgst)));
*/
}
Beispiel #13
0
static void fetch_read_error(struct imap_fetch_context *ctx)
{
	struct imap_fetch_state *state = &ctx->state;

	errno = state->cur_input->stream_errno;
	mail_storage_set_critical(state->cur_mail->box->storage,
		"read(%s) failed: %s (FETCH %s for mailbox %s UID %u)",
		i_stream_get_name(state->cur_input),
		i_stream_get_error(state->cur_input),
		state->cur_human_name,
		mailbox_get_vname(state->cur_mail->box), state->cur_mail->uid);
}
Beispiel #14
0
static const char *client_get_disconnect_reason(struct client *client)
{
	errno = client->input->stream_errno != 0 ?
		client->input->stream_errno :
		client->output->stream_errno;
	if (errno == 0 || errno == EPIPE)
		return "Connection closed";
	return t_strdup_printf("Connection closed: %s",
			       client->input->stream_errno != 0 ?
			       i_stream_get_error(client->input) :
			       o_stream_get_error(client->output));
}
Beispiel #15
0
void test_istream_failure_at(void)
{
	struct istream *input, *data_input;
	unsigned char test_data[TEST_DATA_LENGTH];
	unsigned int i;
	ssize_t ret;

	test_begin("istream failure at");
	for (i = 0; i < sizeof(test_data); i++)
		test_data[i] = i;
	data_input = i_stream_create_from_data(test_data, sizeof(test_data));
	for (i = 0; i < TEST_DATA_LENGTH; i++) {
		i_stream_seek(data_input, 0);
		input = i_stream_create_failure_at(data_input, i, EIO, TEST_ERRMSG);
		while ((ret = i_stream_read(input)) > 0)
			i_stream_skip(input, ret);
		test_assert_idx(ret == -1 && input->v_offset == i &&
				input->stream_errno == EIO &&
				strcmp(i_stream_get_error(input), TEST_ERRMSG) == 0, i);
		i_stream_destroy(&input);
	}
	/* shouldn't fail */
	i_stream_seek(data_input, 0);
	input = i_stream_create_failure_at(data_input, TEST_DATA_LENGTH, EIO, TEST_ERRMSG);
	while ((ret = i_stream_read(input)) > 0)
		i_stream_skip(input, ret);
	test_assert(ret == -1 && input->stream_errno == 0);
	i_stream_destroy(&input);
	/* fail at EOF */
	i_stream_seek(data_input, 0);
	input = i_stream_create_failure_at_eof(data_input, EIO, TEST_ERRMSG);
	while ((ret = i_stream_read(input)) > 0)
		i_stream_skip(input, ret);
	test_assert_idx(ret == -1 && input->v_offset == TEST_DATA_LENGTH &&
			input->stream_errno == EIO &&
			strcmp(i_stream_get_error(input), TEST_ERRMSG) == 0, i);
	i_stream_destroy(&input);
	i_stream_destroy(&data_input);
	test_end();
}
Beispiel #16
0
static
void test_write_read_v2(void)
{
	test_begin("test_write_read_v2");
	unsigned char payload[IO_BLOCK_SIZE*10];
	const unsigned char *ptr;
	size_t pos = 0, siz;
	random_fill_weak(payload, IO_BLOCK_SIZE*10);

	buffer_t *buf = buffer_create_dynamic(default_pool, sizeof(payload));
	struct ostream *os = o_stream_create_buffer(buf);
	struct ostream *os_2 = o_stream_create_encrypt(os, "aes-256-gcm-sha256", test_v1_kp.pub, IO_STREAM_ENC_INTEGRITY_AEAD);
	o_stream_nsend(os_2, payload, sizeof(payload));
	test_assert(o_stream_nfinish(os_2) == 0);
	if (os_2->stream_errno != 0)
		i_debug("error: %s", o_stream_get_error(os_2));

	o_stream_unref(&os);
	o_stream_unref(&os_2);

	struct istream *is = test_istream_create_data(buf->data, buf->used);
	/* test regression where read fails due to incorrect behaviour
	   when buffer is full before going to decrypt code */
	i_stream_set_max_buffer_size(is, 8192);
	i_stream_read(is);
	struct istream *is_2 = i_stream_create_decrypt(is, test_v1_kp.priv);

	size_t offset = 0;
	test_istream_set_size(is, 0);
	test_istream_set_allow_eof(is, FALSE);
	while(i_stream_read_data(is_2, &ptr, &siz, 0)>=0) {
		if (offset == buf->used)
			test_istream_set_allow_eof(is, TRUE);
		else
			test_istream_set_size(is, ++offset);

		test_assert_idx(pos + siz <= sizeof(payload), pos);
		if (pos + siz > sizeof(payload)) break;
		test_assert_idx(siz == 0 || memcmp(ptr, payload + pos, siz) == 0, pos);
		i_stream_skip(is_2, siz); pos += siz;
	}

	test_assert(is_2->stream_errno == 0);
	if (is_2->stream_errno != 0)
		i_debug("error: %s", i_stream_get_error(is_2));

	i_stream_unref(&is);
	i_stream_unref(&is_2);
	buffer_free(&buf);

	test_end();
}
static int
config_read_reply_header(struct istream *istream, const char *path, pool_t pool,
			 const struct master_service_settings_input *input,
			 struct master_service_settings_output *output_r,
			 const char **error_r)
{
	const char *line;
	ssize_t ret;

	while ((ret = i_stream_read(istream)) > 0) {
		line = i_stream_next_line(istream);
		if (line != NULL)
			break;
	}
	if (ret <= 0) {
		if (ret == 0)
			return 1;
		*error_r = istream->stream_errno != 0 ?
			t_strdup_printf("read(%s) failed: %s", path,
					i_stream_get_error(istream)) :
			t_strdup_printf("read(%s) failed: EOF", path);
		return -1;
	}

	T_BEGIN {
		const char *const *arg = t_strsplit_tabescaped(line);
		ARRAY_TYPE(const_string) services;

		p_array_init(&services, pool, 8);
		for (; *arg != NULL; arg++) {
			if (strcmp(*arg, "service-uses-local") == 0)
				output_r->service_uses_local = TRUE;
			else if (strcmp(*arg, "service-uses-remote") == 0)
				output_r->service_uses_remote = TRUE;
			if (strcmp(*arg, "used-local") == 0)
				output_r->used_local = TRUE;
			else if (strcmp(*arg, "used-remote") == 0)
				output_r->used_remote = TRUE;
			else if (strncmp(*arg, "service=", 8) == 0) {
				const char *name = p_strdup(pool, *arg + 8);
				array_append(&services, &name, 1);
			 }
		}
		if (input->service == NULL) {
			array_append_zero(&services);
			output_r->specific_services = array_idx(&services, 0);
		}
	} T_END;
	return 0;
}
Beispiel #18
0
static
void test_write_read_v2_short(void)
{
	test_begin("test_write_read_v2_short");
	unsigned char payload[1];
	const unsigned char *ptr;
	size_t pos = 0, siz;
	random_fill_weak(payload, 1);

	buffer_t *buf = buffer_create_dynamic(default_pool, 64);
	struct ostream *os = o_stream_create_buffer(buf);
	struct ostream *os_2 = o_stream_create_encrypt(os, "aes-256-gcm-sha256", test_v1_kp.pub, IO_STREAM_ENC_INTEGRITY_AEAD);
	o_stream_nsend(os_2, payload, sizeof(payload));
	test_assert(o_stream_nfinish(os_2) == 0);
	if (os_2->stream_errno != 0)
		i_debug("error: %s", o_stream_get_error(os_2));

	o_stream_unref(&os);
	o_stream_unref(&os_2);

	struct istream *is = test_istream_create_data(buf->data, buf->used);
	struct istream *is_2 = i_stream_create_decrypt(is, test_v1_kp.priv);

	size_t offset = 0;
	test_istream_set_allow_eof(is, FALSE);
	test_istream_set_size(is, 0);
	while(i_stream_read_data(is_2, &ptr, &siz, 0)>=0) {
		if (offset == buf->used)
			test_istream_set_allow_eof(is, TRUE);
		test_istream_set_size(is, ++offset);

		test_assert_idx(pos + siz <= sizeof(payload), pos);
		if (pos + siz > sizeof(payload)) break;
		test_assert_idx(siz == 0 || memcmp(ptr, payload + pos, siz) == 0, pos);
		i_stream_skip(is_2, siz); pos += siz;
	}

	test_assert(is_2->stream_errno == 0);
	if (is_2->stream_errno != 0)
		i_debug("error: %s", i_stream_get_error(is_2));

	i_stream_unref(&is);
	i_stream_unref(&is_2);
	buffer_free(&buf);

	test_end();
}
Beispiel #19
0
static void fetch_read_error(struct imap_fetch_context *ctx,
			     const char **disconnect_reason_r)
{
	struct imap_fetch_state *state = &ctx->state;

	if (state->cur_input->stream_errno == ENOENT) {
		if (state->cur_mail->expunged) {
			*disconnect_reason_r = "Mail expunged while it was being FETCHed";
			return;
		}
	}
	mail_storage_set_critical(state->cur_mail->box->storage,
		"read(%s) failed: %s (FETCH %s for mailbox %s UID %u)",
		i_stream_get_name(state->cur_input),
		i_stream_get_error(state->cur_input),
		state->cur_human_name,
		mailbox_get_vname(state->cur_mail->box), state->cur_mail->uid);
	*disconnect_reason_r = "FETCH read() failed";
}
Beispiel #20
0
static int fts_indexer_input(struct fts_indexer_context *ctx)
{
	const char *line;
	int percentage;

	while ((line = i_stream_read_next_line(ctx->input)) != NULL) {
		/* initial reply: <tag> \t OK
		   following: <tag> \t <percentage> */
		if (strncmp(line, "1\t", 2) != 0) {
			i_error("indexer sent invalid reply: %s", line);
			return -1;
		}
		line += 2;
		if (strcmp(line, "OK") == 0)
			continue;
		if (str_to_int(line, &percentage) < 0 || percentage > 100) {
			i_error("indexer sent invalid percentage: %s", line);
			return -1;
		}
		if (percentage < 0) {
			/* indexing failed */
			i_error("indexer failed to index mailbox %s",
				ctx->box->vname);
			return -1;
		}
		ctx->percentage = percentage;
		if (percentage == 100) {
			/* finished */
			return 1;
		}
	}
	if (ctx->input->stream_errno != 0) {
		i_error("indexer read(%s) failed: %s",
			i_stream_get_name(ctx->input),
			i_stream_get_error(ctx->input));
		return -1;
	}
	if (ctx->input->eof) {
		i_error("indexer disconnected unexpectedly");
		return -1;
	}
	return 0;
}
Beispiel #21
0
static int server_connection_send_cmd_input_more(struct server_connection *conn)
{
	enum ostream_send_istream_result res;
	int ret = -1;

	/* ostream-dot writes only up to max buffer size, so keep it non-zero */
	o_stream_set_max_buffer_size(conn->cmd_output, IO_BLOCK_SIZE);
	res = o_stream_send_istream(conn->cmd_output, conn->cmd_input);
	o_stream_set_max_buffer_size(conn->cmd_output, (size_t)-1);

	switch (res) {
	case OSTREAM_SEND_ISTREAM_RESULT_FINISHED:
		break;
	case OSTREAM_SEND_ISTREAM_RESULT_WAIT_INPUT:
		return 1;
	case OSTREAM_SEND_ISTREAM_RESULT_WAIT_OUTPUT:
		return 0;
	case OSTREAM_SEND_ISTREAM_RESULT_ERROR_INPUT:
		i_error("read(%s) failed: %s",
			i_stream_get_name(conn->cmd_input),
			i_stream_get_error(conn->cmd_input));
		break;
	case OSTREAM_SEND_ISTREAM_RESULT_ERROR_OUTPUT:
		i_error("write(%s) failed: %s",
			o_stream_get_name(conn->cmd_output),
			o_stream_get_error(conn->cmd_output));
		break;
	}
	if (res == OSTREAM_SEND_ISTREAM_RESULT_FINISHED) {
		if ((ret = o_stream_flush(conn->cmd_output)) == 0)
			return 0;
		else if (ret < 0) {
			i_error("write(%s) failed: %s",
				o_stream_get_name(conn->cmd_output),
				o_stream_get_error(conn->cmd_output));
		}
	}

	i_stream_destroy(&conn->cmd_input);
	o_stream_destroy(&conn->cmd_output);
	return ret;
}
Beispiel #22
0
static void stats_dump(const char *path, const char *cmd)
{
	struct istream *input;
	const char *const *args;
	unsigned int i;
	int fd;

	fd = doveadm_connect(path);
	net_set_nonblock(fd, FALSE);
	if (write_full(fd, cmd, strlen(cmd)) < 0)
		i_fatal("write(%s) failed: %m", path);

	input = i_stream_create_fd_autoclose(&fd, (size_t)-1);

	/* read header */
	args = read_next_line(input);
	if (args == NULL)
		i_fatal("read(%s) unexpectedly disconnected", path);
	if (*args == NULL)
		i_info("no statistics available");
	else {
		for (; *args != NULL; args++)
			doveadm_print_header_simple(*args);

		/* read lines */
		do {
			T_BEGIN {
				args = read_next_line(input);
				if (args != NULL && args[0] == NULL)
					args = NULL;
				if (args != NULL) {
					for (i = 0; args[i] != NULL; i++)
						doveadm_print(args[i]);
				}
			} T_END;
		} while (args != NULL);
	}
	if (input->stream_errno != 0)
		i_fatal("read(%s) failed: %s", path, i_stream_get_error(input));
	i_stream_destroy(&input);
}
Beispiel #23
0
static
void test_write_read_v1_empty(void)
{
	const unsigned char *ptr;
	size_t siz;
	test_begin("test_write_read_v1_empty");
	buffer_t *buf = buffer_create_dynamic(default_pool, 64);
	struct ostream *os = o_stream_create_buffer(buf);
	struct ostream *os_2 = o_stream_create_encrypt(os, "<unused>", test_v1_kp.pub, IO_STREAM_ENC_VERSION_1);
	test_assert(o_stream_nfinish(os_2) == 0);
	if (os_2->stream_errno != 0)
		i_debug("error: %s", o_stream_get_error(os_2));

	o_stream_unref(&os);
	o_stream_unref(&os_2);
	/* this should've been enough */

	struct istream *is = test_istream_create_data(buf->data, buf->used);
	struct istream *is_2 = i_stream_create_decrypt(is, test_v1_kp.priv);

	/* read should not fail */
	test_istream_set_allow_eof(is, FALSE);
	test_istream_set_size(is, 0);
	size_t offset = 0;
	ssize_t ret;
	while ((ret = i_stream_read_data(is_2, &ptr, &siz, 0)) >= 0) {
		test_assert(ret == 0);
		if (offset == buf->used)
			test_istream_set_allow_eof(is, TRUE);
		else
			test_istream_set_size(is, ++offset);
	};

	test_assert(is_2->stream_errno == 0);
	if (is_2->stream_errno != 0)
		i_debug("error: %s", i_stream_get_error(is_2));
	i_stream_unref(&is);
	i_stream_unref(&is_2);
	buffer_free(&buf);
	test_end();
}
Beispiel #24
0
static void server_input(struct client *client)
{
	const unsigned char *data;
	size_t size;

	if (i_stream_read(client->input) == -1) {
		if (client->input->stream_errno != 0) {
			i_fatal("read(server) failed: %s",
				i_stream_get_error(client->input));
		}

		i_info("Server disconnected");
		master_service_stop(master_service);
		return;
	}

	data = i_stream_get_data(client->input, &size);
	if (write(STDOUT_FILENO, data, size) < 0)
		i_fatal("write(stdout) failed: %m");
	i_stream_skip(client->input, size);
}
Beispiel #25
0
static int fs_crypt_read_file(const char *set_name, const char *path,
			      char **key_data_r, const char **error_r)
{
	struct istream *input;
	int ret;

	input = i_stream_create_file(path, (size_t)-1);
	while (i_stream_read(input) > 0) ;
	if (input->stream_errno != 0) {
		*error_r = t_strdup_printf("%s: read(%s) failed: %s",
			set_name, path, i_stream_get_error(input));
		ret = -1;
	} else {
		size_t size;
		const unsigned char *data = i_stream_get_data(input, &size);
		*key_data_r = i_strndup(data, size);
		ret = 0;
	}
	i_stream_unref(&input);
	return ret;
}
Beispiel #26
0
const char *io_stream_get_disconnect_reason(struct istream *input,
					    struct ostream *output)
{
	const char *errstr;

	if (input != NULL && input->stream_errno != 0) {
		errno = input->stream_errno;
		errstr = i_stream_get_error(input);
	} else if (output != NULL && output->stream_errno != 0) {
		errno = output->stream_errno;
		errstr = o_stream_get_error(output);
	} else {
		errno = 0;
		errstr = "";
	}

	if (errno == 0 || errno == EPIPE)
		return "Connection closed";
	else
		return t_strdup_printf("Connection closed: %s", errstr);
}
Beispiel #27
0
static ssize_t read_more(struct seekable_istream *sstream)
{
	size_t size;
	ssize_t ret;

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

	while ((ret = i_stream_read_memarea(sstream->cur_input)) == -1) {
		if (sstream->cur_input->stream_errno != 0) {
			io_stream_set_error(&sstream->istream.iostream,
				"read(%s) failed: %s",
				i_stream_get_name(sstream->cur_input),
				i_stream_get_error(sstream->cur_input));
			sstream->istream.istream.eof = TRUE;
			sstream->istream.istream.stream_errno =
				sstream->cur_input->stream_errno;
			return -1;
		}

		/* go to next stream */
		sstream->cur_input = sstream->input[sstream->cur_idx++];
		if (sstream->cur_input == NULL) {
			/* last one, EOF */
			sstream->size = sstream->istream.istream.v_offset;
			sstream->istream.istream.eof = TRUE;
			unref_streams(sstream);
			return -1;
		}

		/* see if stream has pending data */
		size = i_stream_get_data_size(sstream->cur_input);
		if (size != 0)
			return size;
	}
	return ret;
}
Beispiel #28
0
static int
mail_storage_try_copy(struct mail_save_context **_ctx, struct mail *mail)
{
	struct mail_save_context *ctx = *_ctx;
	struct mail_private *pmail = (struct mail_private *)mail;
	struct istream *input;

	ctx->copying_via_save = TRUE;

	/* we need to open the file in any case. caching metadata is unlikely
	   to help anything. */
	pmail->v.set_uid_cache_updates(mail, TRUE);

	if (mail_get_stream_because(mail, NULL, NULL, "copying", &input) < 0) {
		mail_copy_set_failed(ctx, mail, "stream");
		return -1;
	}
	if (mail_save_copy_default_metadata(ctx, mail) < 0)
		return -1;

	if (mailbox_save_begin(_ctx, input) < 0)
		return -1;

	ssize_t ret;
	do {
		if (mailbox_save_continue(ctx) < 0)
			break;
		ret = i_stream_read(input);
		i_assert(ret != 0);
	} while (ret != -1);

	if (input->stream_errno != 0) {
		mail_storage_set_critical(ctx->transaction->box->storage,
			"copy: i_stream_read(%s) failed: %s",
			i_stream_get_name(input), i_stream_get_error(input));
		return -1;
	}
	return 0;
}
Beispiel #29
0
static bool cmd_getscript_continue(struct client_command_context *cmd)
{
	struct client *client = cmd->client;
	struct cmd_getscript_context *ctx = cmd->context;

	switch (o_stream_send_istream(client->output, ctx->script_stream)) {
	case OSTREAM_SEND_ISTREAM_RESULT_FINISHED:
		if ( ctx->script_stream->v_offset != ctx->script_size && !ctx->failed ) {
			/* Input stream gave less data than expected */
			sieve_storage_set_critical(ctx->storage,
				"GETSCRIPT for script `%s' from %s got too little data: "
				"%"PRIuUOFF_T" vs %"PRIuUOFF_T, sieve_script_name(ctx->script),
				sieve_script_location(ctx->script), ctx->script_stream->v_offset, ctx->script_size);

			client_disconnect(ctx->client, "GETSCRIPT failed");
			ctx->failed = TRUE;
		}
		break;
	case OSTREAM_SEND_ISTREAM_RESULT_WAIT_INPUT:
		i_unreached();
	case OSTREAM_SEND_ISTREAM_RESULT_WAIT_OUTPUT:
		return FALSE;
	case OSTREAM_SEND_ISTREAM_RESULT_ERROR_INPUT:
		sieve_storage_set_critical(ctx->storage,
			"o_stream_send_istream() failed for script `%s' from %s: %s",
			sieve_script_name(ctx->script),
			sieve_script_location(ctx->script),
			i_stream_get_error(ctx->script_stream));
		ctx->failed = TRUE;
		break;
	case OSTREAM_SEND_ISTREAM_RESULT_ERROR_OUTPUT:
		client_disconnect(ctx->client,
			io_stream_get_disconnect_reason(client->input, client->output));
		ctx->failed = TRUE;
		break;
	}
	return cmd_getscript_finish(ctx);
}
Beispiel #30
0
static void lmtp_client_input(struct lmtp_client *client)
{
	const char *line;
	int ret;

	lmtp_client_ref(client);
	o_stream_cork(client->output);
	while ((line = i_stream_read_next_line(client->input)) != NULL) {
		T_BEGIN {
			ret = lmtp_client_input_line(client, line);
		} T_END;
		if (ret < 0) {
			o_stream_uncork(client->output);
			lmtp_client_unref(&client);
			return;
		}
		if (ret > 0)
			str_truncate(client->input_multiline, 0);
	}

	if (client->input->stream_errno == ENOBUFS) {
		lmtp_client_fail(client,
				 "501 5.5.4 Command reply line too long");
	} else if (client->input->stream_errno != 0) {
		i_error("lmtp client: read() failed: %s",
			i_stream_get_error(client->input));
		lmtp_client_fail(client, ERRSTR_TEMP_REMOTE_FAILURE
				 " (read failure)");
	} else if (client->input->eof) {
		lmtp_client_fail(client, ERRSTR_TEMP_REMOTE_FAILURE
				 " (disconnected in input)");
	}
	o_stream_uncork(client->output);
	if (client->to != NULL)
		timeout_reset(client->to);
	lmtp_client_unref(&client);
}