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 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; }