Esempio n. 1
0
static bool
proxy_client_worker_next_msg_get(struct proxy_client_dsync_worker *worker,
                                 const struct proxy_client_request *request,
                                 const char *line)
{
    enum dsync_msg_get_result result = DSYNC_MSG_GET_RESULT_FAILED;
    const char *p, *error;
    uint32_t uid;

    p_clear(worker->msg_get_pool);
    switch (line[0]) {
    case '1':
        /* ok */
        if (line[1] != '\t')
            break;
        line += 2;

        if ((p = strchr(line, '\t')) == NULL)
            break;
        uid = strtoul(t_strcut(line, '\t'), NULL, 10);
        line = p + 1;

        if (uid != request->uid) {
            i_error("msg-get returned invalid uid: %u != %u",
                    uid, request->uid);
            proxy_client_fail(worker);
            return FALSE;
        }

        if (dsync_proxy_msg_static_import(worker->msg_get_pool,
                                          line, &worker->msg_get_data,
                                          &error) < 0) {
            i_error("Invalid msg-get static input: %s", error);
            proxy_client_fail(worker);
            return FALSE;
        }
        worker->msg_get_data.input =
            i_stream_create_dot(worker->input, FALSE);
        i_stream_set_destroy_callback(worker->msg_get_data.input,
                                      proxy_client_worker_msg_get_done,
                                      worker);
        io_remove(&worker->io);
        result = DSYNC_MSG_GET_RESULT_SUCCESS;
        break;
    case '0':
        /* expunged */
        result = DSYNC_MSG_GET_RESULT_EXPUNGED;
        break;
    default:
        /* failure */
        break;
    }

    request->callback.get(result, &worker->msg_get_data, request->context);
    return worker->io != NULL && worker->msg_get_data.input == NULL;
}
Esempio n. 2
0
static void test_istream_dot_error(const char *input_str, bool test_bufsize)
{
	struct istream *test_input, *input;
	unsigned int i;
	size_t outsize, input_len;
	uoff_t offset;
	int ret;

	test_input = test_istream_create(input_str);
	input = i_stream_create_dot(test_input, FALSE);

	input_len = strlen(input_str);

	if (!test_bufsize) {
		outsize = 1; i = 0;
		i_stream_set_max_buffer_size(input, outsize);
		test_istream_set_size(test_input, 1);
		while ((ret = i_stream_read(input)) != -1) {
			switch (ret) {
			case -2:
				i_stream_set_max_buffer_size(input, ++outsize);
				offset = test_input->v_offset;
				/* seek one byte backwards so stream gets
				   reset */
				i_stream_seek(test_input, offset - 1);
				/* go back to original position */
				test_istream_set_size(test_input, offset);
				i_stream_skip(test_input, 1);
				/* and finally allow reading one more byte */
				test_istream_set_size(test_input, offset + 1);
				break;
			case 0:
				test_istream_set_size(test_input, ++i);
				break;
			default:
				test_assert(ret > 0);
			}
		}
		test_istream_set_size(test_input, input_len);
		(void)i_stream_read(test_input);
	} else {
		test_istream_set_size(test_input, input_len);
		for (i = 1; i <= input_len; i++) {
			i_stream_set_max_buffer_size(input, i);
			(void)i_stream_read(input);
			(void)i_stream_read(input);
		}
		i_stream_set_max_buffer_size(input, i+1);
		(void)i_stream_read(input);
	}
	test_assert(input->stream_errno == EPIPE);

	i_stream_unref(&test_input);
	i_stream_unref(&input);
}
Esempio n. 3
0
static void
proxy_client_worker_msg_get_done(struct proxy_client_dsync_worker *worker)
{
    struct istream *input = worker->msg_get_data.input;

    i_assert(worker->io == NULL);

    if (input->eof)
        proxy_client_worker_msg_get_finish(worker);
    else {
        /* saving read the message only partially. we'll need to read
           the input until EOF or we'll start treating the input as
           commands. */
        worker->io = io_add(worker->fd_in, IO_READ,
                            proxy_client_worker_read_to_eof, worker);
        worker->msg_get_data.input =
            i_stream_create_dot(worker->input, FALSE);
    }
}
int pop3c_client_cmd_stream(struct pop3c_client *client, const char *cmd,
			    struct istream **input_r, const char **error_r)
{
	struct istream *inputs[2];

	*input_r = NULL;

	/* read the +OK / -ERR */
	if (pop3c_client_cmd_line(client, cmd, error_r) < 0)
		return -1;
	/* read the stream */
	inputs[0] = i_stream_create_dot(client->input, TRUE);
	inputs[1] = NULL;
	client->dot_input =
		i_stream_create_seekable(inputs, POP3C_MAX_INBUF_SIZE,
					 seekable_fd_callback, client);
	i_stream_unref(&inputs[0]);

	i_assert(client->io == NULL);
	client->io = io_add(client->fd, IO_READ,
			    pop3c_client_dot_input, client);
	/* read any pending data from the stream */
	pop3c_client_dot_input(client);
	if (!client->dot_input->eof)
		pop3c_client_run(client);

	if (client->input == NULL) {
		i_assert(client->io == NULL);
		i_stream_destroy(&client->dot_input);
		*error_r = "Disconnected";
		return -1;
	}
	io_remove(&client->io);
	i_stream_seek(client->dot_input, 0);
	/* if this stream is used by some filter stream, make the filter
	   stream blocking */
	client->dot_input->blocking = TRUE;

	*input_r = client->dot_input;
	client->dot_input = NULL;
	return 0;
}
static void test_istream_dot_one(const struct dot_test *test,
				 bool send_last_lf, bool test_bufsize)
{
	struct istream *test_input, *input;
	const unsigned char *data;
	size_t size;
	unsigned int i, outsize, input_len, output_len;
	string_t *str;
	uoff_t offset;
	int ret;

	test_input = test_istream_create(test->input);
	input = i_stream_create_dot(test_input, send_last_lf);

	input_len = strlen(test->input);
	output_len = strlen(test->output);
	if (!send_last_lf &&
	    (test->input[input_len-1] == '\n' ||
	     strstr(test->input, "\n.\n") != NULL ||
	     strstr(test->input, "\n.\r\n") != NULL)) {
		if (test->output[output_len-1] == '\n') {
			output_len--;
			if (output_len > 0 &&
			    test->output[output_len-1] == '\r')
				output_len--;
		}
	}

	str = t_str_new(256);
	if (!test_bufsize) {
		outsize = 1; i = 0;
		i_stream_set_max_buffer_size(input, outsize);
		test_istream_set_size(test_input, 1);
		while ((ret = i_stream_read(input)) != -1) {
			switch (ret) {
			case -2:
				i_stream_set_max_buffer_size(input, ++outsize);
				offset = test_input->v_offset;
				/* seek one byte backwards so stream gets
				   reset */
				i_stream_seek(test_input, offset - 1);
				/* go back to original position */
				test_istream_set_size(test_input, offset);
				i_stream_skip(test_input, 1);
				/* and finally allow reading one more byte */
				test_istream_set_size(test_input, offset + 1);
				break;
			case 0:
				test_istream_set_size(test_input, ++i);
				break;
			default:
				test_assert(ret > 0);

				data = i_stream_get_data(input, &size);
				str_append_n(str, data, size);
				i_stream_skip(input, size);
			}
		}
		test_istream_set_size(test_input, input_len);
		(void)i_stream_read(test_input);
	} else {
		test_istream_set_size(test_input, input_len);
		size = 0;
		for (i = 1; i < output_len; i++) {
			i_stream_set_max_buffer_size(input, i);
			test_assert(i_stream_read(input) == 1);
			test_assert(i_stream_read(input) == -2);
			data = i_stream_get_data(input, &size);
			test_assert(memcmp(data, test->output, size) == 0);
		}
		i_stream_set_max_buffer_size(input, i+2);
		if (size < output_len)
			test_assert(i_stream_read(input) == 1);
		test_assert(i_stream_read(input) == -1);

		data = i_stream_get_data(input, &size);
		str_append_n(str, data, size);
	}
	test_assert(str_len(str) == output_len);
	test_assert(memcmp(str_data(str), test->output, output_len) == 0);

	data = i_stream_get_data(test_input, &size);
	test_assert(size == strlen(test->parent_input));
	test_assert(memcmp(data, test->parent_input, size) == 0);

	i_stream_unref(&test_input);
	i_stream_unref(&input);
}