static struct istream *mail_raw_create_stream (struct mail_user *ruser, int fd, time_t *mtime_r, const char **sender) { struct istream *input, *input2, *input_list[2]; const unsigned char *data; size_t i, size; int ret, tz; char *env_sender = NULL; *mtime_r = (time_t)-1; fd_set_nonblock(fd, FALSE); input = i_stream_create_fd(fd, 4096, FALSE); input->blocking = TRUE; /* If input begins with a From-line, drop it */ ret = i_stream_read_data(input, &data, &size, 5); if (ret > 0 && size >= 5 && memcmp(data, "From ", 5) == 0) { /* skip until the first LF */ i_stream_skip(input, 5); while ( i_stream_read_data(input, &data, &size, 0) > 0 ) { for (i = 0; i < size; i++) { if (data[i] == '\n') break; } if (i != size) { (void)mbox_from_parse(data, i, mtime_r, &tz, &env_sender); i_stream_skip(input, i + 1); break; } i_stream_skip(input, size); } } if (env_sender != NULL && sender != NULL) { *sender = t_strdup(env_sender); } i_free(env_sender); if (input->v_offset == 0) { input2 = input; i_stream_ref(input2); } else { input2 = i_stream_create_limit(input, (uoff_t)-1); } i_stream_unref(&input); input_list[0] = input2; input_list[1] = NULL; input = i_stream_create_seekable(input_list, MAIL_MAX_MEMORY_BUFFER, seekable_fd_callback, (void*)ruser); i_stream_unref(&input2); return input; }
void program_client_init_streams(struct program_client *pclient) { /* Create streams for normal program I/O */ if ( pclient->fd_out >= 0 ) { pclient->program_output = o_stream_create_fd(pclient->fd_out, MAX_OUTPUT_BUFFER_SIZE, FALSE); } if ( pclient->fd_in >= 0 ) { struct istream *input; input = i_stream_create_fd(pclient->fd_in, (size_t)-1, FALSE); if (pclient->output_seekable) { struct istream *input2 = input, *input_list[2]; input_list[0] = input2; input_list[1] = NULL; input = i_stream_create_seekable(input_list, MAX_OUTPUT_MEMORY_BUFFER, program_client_seekable_fd_callback, pclient); i_stream_unref(&input2); pclient->seekable_output = input; i_stream_ref(pclient->seekable_output); } pclient->program_input = input; pclient->io = io_add (pclient->fd_in, IO_READ, program_client_program_input, pclient); } /* Create streams for additional output through side-channel fds */ if ( array_is_created(&pclient->extra_fds) ) { struct program_client_extra_fd *efds = NULL; unsigned int count, i; efds = array_get_modifiable(&pclient->extra_fds, &count); for ( i = 0; i < count; i++ ) { i_assert( efds[i].parent_fd >= 0 ); efds[i].input = i_stream_create_fd (efds[i].parent_fd, (size_t)-1, FALSE); efds[i].io = io_add (efds[i].parent_fd, IO_READ, program_client_extra_fd_input, &efds[i]); } } }
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 mail_filter_istream_opened(struct mail *_mail, struct istream **stream) { struct mail_private *mail = (struct mail_private *)_mail; struct mail_user *user = _mail->box->storage->user; struct mail_filter_user *muser = MAIL_FILTER_USER_CONTEXT(user); union mail_module_context *mmail = MAIL_FILTER_MAIL_CONTEXT(mail); struct istream *input, *inputs[2]; input = *stream; *stream = i_stream_create_ext_filter(input, muser->socket_path, muser->args); i_stream_unref(&input); inputs[0] = *stream; inputs[1] = NULL; *stream = i_stream_create_seekable(inputs, MAIL_MAX_MEMORY_BUFFER, seekable_fd_callback, user); i_stream_unref(&inputs[0]); return mmail->super.istream_opened(_mail, stream); }