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;
}
Esempio n. 2
0
static int
pop3c_client_read_line(struct pop3c_client *client,
		       const char **line_r, const char **error_r)
{
	i_assert(client->io == NULL);
	i_assert(client->input_line == NULL);

	client->io = io_add(client->fd, IO_READ,
			    pop3c_client_input_reply, client);
	pop3c_client_input_reply(client);
	if (client->input_line == NULL && client->input != NULL)
		pop3c_client_run(client);

	if (client->input_line == NULL) {
		i_assert(client->io == NULL);
		*error_r = "Disconnected";
		return -1;
	}

	io_remove(&client->io);
	*line_r = t_strdup(client->input_line);
	client->input_line = NULL;
	return 0;
}