Beispiel #1
0
static int
imap_master_client_input_line(struct connection *conn, const char *line)
{
	char *const *args;
	pool_t pool;
	int fd_client, ret;

	if (!conn->version_received) {
		if (connection_verify_version(conn, t_strsplit_tabescaped(line)) < 0)
			return -1;
		conn->version_received = TRUE;
		return 1;
	}

	fd_client = i_stream_unix_get_read_fd(conn->input);
	if (fd_client == -1) {
		i_error("imap-master: IMAP client fd not received");
		return -1;
	}

	if (imap_debug)
		i_debug("imap-master: Client input: %s", line);

	pool = pool_alloconly_create("imap master client cmd", 1024);
	args = p_strsplit_tabescaped(pool, line);
	ret = imap_master_client_input_args(conn, (void *)args, fd_client, pool);
	pool_unref(&pool);
	return ret;
}
Beispiel #2
0
static void
test_server_read_nofd(struct istream *input, unsigned int idx)
{
	const unsigned char *data;
	size_t size;

	test_assert_idx(i_stream_read_data(input, &data, &size, 0) == 1, idx);
	i_stream_skip(input, 1);
	test_assert_idx(i_stream_unix_get_read_fd(input) == -1, idx);
}
Beispiel #3
0
static void test_istream_unix_server(int fd)
{
	struct istream *input;
	const unsigned char *data;
	size_t size;

	input = i_stream_create_unix(fd, 1024);
	/* 1) simple read */
	test_server_read_nofd(input, 1);
	write_one(fd);

	/* 2) fd was sent but we won't get it */
	test_server_read_nofd(input, 2);
	/* we still shouldn't have the fd */
	fd_set_nonblock(fd, TRUE);
	i_stream_unix_set_read_fd(input);
	test_assert(i_stream_read_data(input, &data, &size, 0) == 0);
	test_assert(i_stream_unix_get_read_fd(input) == -1);
	fd_set_nonblock(fd, FALSE);
	write_one(fd);

	/* 3) the previous fd should be lost now */
	test_server_read_nofd(input, 3);
	write_one(fd);

	/* 4) we should get the fd now */
	test_server_read_fd(input, send_fd2, 4);
	write_one(fd);

	/* 5) the previous fd shouldn't be returned anymore */
	i_stream_unix_set_read_fd(input);
	test_server_read_nofd(input, 5);
	write_one(fd);

	/* 6) with i_stream_unix_unset_read_fd() we shouldn't get fd anymore */
	i_stream_unix_unset_read_fd(input);
	test_server_read_nofd(input, 6);
	write_one(fd);

	/* 7-8) two fds were sent, but we'll get only the first one */
	i_stream_unix_set_read_fd(input);
	test_server_read_fd(input, send_fd, 7);
	test_server_read_nofd(input, 8);
	write_one(fd);

	/* 9-10) two fds were sent, and we'll get them both */
	i_stream_unix_set_read_fd(input);
	test_server_read_fd(input, send_fd, 9);
	i_stream_unix_set_read_fd(input);
	test_server_read_fd(input, send_fd2, 10);
	write_one(fd);

	i_stream_destroy(&input);
	i_close_fd(&fd);
}
Beispiel #4
0
static void
test_server_read_fd(struct istream *input, int wanted_fd, unsigned int idx)
{
	struct stat st1, st2;
	const unsigned char *data;
	size_t size;
	int recv_fd;

	test_assert_idx(i_stream_read_data(input, &data, &size, 0) == 1, idx);
	i_stream_skip(input, 1);
	test_assert_idx((recv_fd = i_stream_unix_get_read_fd(input)) != -1, idx);
	if (recv_fd != -1) {
		if (fstat(recv_fd, &st1) < 0 || fstat(wanted_fd, &st2) < 0)
			i_fatal("fstat() failed: %m");
		test_assert_idx(st1.st_ino == st2.st_ino, idx);
		i_close_fd(&recv_fd);
	}
}
static int
imap_hibernate_client_input_line(struct connection *conn, const char *line)
{
	struct imap_hibernate_client *client =
		(struct imap_hibernate_client *)conn;
	int fd = -1, ret;

	if (!conn->version_received) {
		if (connection_verify_version(conn, t_strsplit_tabescaped(line)) < 0)
			return -1;
		conn->version_received = TRUE;
		return 1;
	}

	if (client->imap_client == NULL) {
		char *const *args;
		pool_t pool;

		fd = i_stream_unix_get_read_fd(conn->input);
		if (fd == -1) {
			i_error("IMAP client fd not received");
			return -1;
		}

		pool = pool_alloconly_create("client cmd", 1024);
		args = p_strsplit_tabescaped(pool, line);
		ret = imap_hibernate_client_input_args(conn, (void *)args, fd, pool);
		if (ret >= 0 && client->debug)
			i_debug("Create client with input: %s", line);
		pool_unref(&pool);
	} else {
		fd = i_stream_unix_get_read_fd(conn->input);
		if (fd == -1) {
			i_error("IMAP notify fd not received (input: %s)", line);
			ret = -1;
		} else if (line[0] != '\0') {
			i_error("Expected empty notify fd line from client, but got: %s", line);
			o_stream_send_str(conn->output,
					  "Expected empty notify fd line");
			ret = -1;
		} else {
			imap_client_add_notify_fd(client->imap_client, fd);
			ret = 1;
		}
	}

	if (ret < 0) {
		if (client->imap_client != NULL)
			imap_client_destroy(&client->imap_client, NULL);
		if (fd != -1)
			i_close_fd(&fd);
		return -1;
	} else if (ret == 0) {
		/* still need to read another fd */
		i_stream_unix_set_read_fd(conn->input);
		o_stream_send_str(conn->output, "+\n");
		return 1;
	} else {
		/* finished - always disconnect the hibernate client
		   afterwards */
		o_stream_send_str(conn->output, "+\n");
		imap_client_create_finish(client->imap_client);
		return -1;
	}
}