static void o_stream_escaped_destroy(struct iostream_private *stream) { struct escaped_ostream *estream = (struct escaped_ostream *)stream; str_free(&estream->buf); o_stream_unref(&estream->ostream.parent); }
static void http_client_request_finish_payload_out(struct http_client_request *req) { i_assert(req->conn != NULL); /* drop payload output stream */ if (req->payload_output != NULL) { o_stream_unref(&req->payload_output); req->payload_output = NULL; } /* advance state only when request didn't get aborted in the mean time */ if (req->state != HTTP_REQUEST_STATE_ABORTED) { i_assert(req->state == HTTP_REQUEST_STATE_PAYLOAD_OUT); /* we're now waiting for a response from the server */ req->state = HTTP_REQUEST_STATE_WAITING; http_client_connection_start_request_timeout(req->conn); } /* release connection */ req->conn->output_locked = FALSE; http_client_request_debug(req, "Finished sending%s payload", (req->state == HTTP_REQUEST_STATE_ABORTED ? " aborted" : "")); }
void http_client_request_resubmit(struct http_client_request *req) { i_assert(!req->payload_wait); http_client_request_debug(req, "Resubmitting request"); /* rewind payload stream */ if (req->payload_input != NULL && req->payload_size > 0) { if (req->payload_input->v_offset != req->payload_offset && !req->payload_input->seekable) { http_client_request_error(&req, HTTP_CLIENT_REQUEST_ERROR_ABORTED, "Resubmission failed: Cannot resend payload; stream is not seekable"); return; } else { i_stream_seek(req->payload_input, req->payload_offset); } } /* drop payload output stream from previous attempt */ if (req->payload_output != NULL) o_stream_unref(&req->payload_output); req->conn = NULL; req->peer = NULL; req->state = HTTP_REQUEST_STATE_QUEUED; http_client_host_submit_request(req->host, req); }
static void client_input(struct client *client) { struct istream *input; struct ostream *output; unsigned char buf[1024]; ssize_t ret; ret = read(STDIN_FILENO, buf, sizeof(buf)); if (ret == 0) { if (client->compressed) { master_service_stop(master_service); return; } /* start compression */ i_info("<Compression started>"); input = i_stream_create_deflate(client->input, TRUE); output = o_stream_create_deflate(client->output, 6); i_stream_unref(&client->input); o_stream_unref(&client->output); client->input = input; client->output = output; client->compressed = TRUE; return; } if (ret < 0) i_fatal("read(stdin) failed: %m"); o_stream_nsend(client->output, buf, ret); }
static void o_stream_default_destroy(struct iostream_private *stream) { struct ostream_private *_stream = (struct ostream_private *)stream; if (_stream->parent != NULL) o_stream_unref(&_stream->parent); }
bool client_unref(struct client **_client) { struct client *client = *_client; i_assert(client->refcount > 0); if (--client->refcount > 0) return TRUE; *_client = NULL; i_assert(client->destroyed); i_assert(client->ssl_proxy == NULL); i_assert(client->login_proxy == NULL); if (client->input != NULL) i_stream_unref(&client->input); if (client->output != NULL) o_stream_unref(&client->output); i_free(client->proxy_user); i_free(client->proxy_master_user); i_free(client->virtual_user); i_free(client->auth_mech_name); pool_unref(&client->pool); i_assert(clients_count > 0); clients_count--; master_service_client_connection_destroyed(master_service); login_refresh_proctitle(); return FALSE; }
static void client_start_tls(struct client *client) { int fd_ssl; client_ref(client); if (!client_unref(&client) || client->destroyed) return; fd_ssl = ssl_proxy_alloc(client->fd, &client->ip, client->pool, client->set, client->ssl_set, &client->ssl_proxy); if (fd_ssl == -1) { client_notify_disconnect(client, CLIENT_DISCONNECT_INTERNAL_ERROR, "TLS initialization failed."); client_destroy(client, "Disconnected: TLS initialization failed."); return; } ssl_proxy_set_client(client->ssl_proxy, client); ssl_proxy_start(client->ssl_proxy); client->starttls = TRUE; client->tls = TRUE; client->secured = TRUE; login_refresh_proctitle(); client->fd = fd_ssl; client->io = io_add(client->fd, IO_READ, client_input, client); i_stream_unref(&client->input); o_stream_unref(&client->output); client_open_streams(client); client->v.starttls(client); }
static void test_write_read_v2_short(void) { test_begin("test_write_read_v2_short"); unsigned char payload[1]; const unsigned char *ptr; size_t pos = 0, siz; random_fill_weak(payload, 1); buffer_t *buf = buffer_create_dynamic(default_pool, 64); struct ostream *os = o_stream_create_buffer(buf); struct ostream *os_2 = o_stream_create_encrypt(os, "aes-256-gcm-sha256", test_v1_kp.pub, IO_STREAM_ENC_INTEGRITY_AEAD); o_stream_nsend(os_2, payload, sizeof(payload)); test_assert(o_stream_nfinish(os_2) == 0); if (os_2->stream_errno != 0) i_debug("error: %s", o_stream_get_error(os_2)); o_stream_unref(&os); o_stream_unref(&os_2); struct istream *is = test_istream_create_data(buf->data, buf->used); struct istream *is_2 = i_stream_create_decrypt(is, test_v1_kp.priv); size_t offset = 0; test_istream_set_allow_eof(is, FALSE); test_istream_set_size(is, 0); while(i_stream_read_data(is_2, &ptr, &siz, 0)>=0) { if (offset == buf->used) test_istream_set_allow_eof(is, TRUE); test_istream_set_size(is, ++offset); test_assert_idx(pos + siz <= sizeof(payload), pos); if (pos + siz > sizeof(payload)) break; test_assert_idx(siz == 0 || memcmp(ptr, payload + pos, siz) == 0, pos); i_stream_skip(is_2, siz); pos += siz; } test_assert(is_2->stream_errno == 0); if (is_2->stream_errno != 0) i_debug("error: %s", i_stream_get_error(is_2)); i_stream_unref(&is); i_stream_unref(&is_2); buffer_free(&buf); test_end(); }
void program_client_set_output_seekable (struct program_client *pclient, const char *temp_prefix) { if ( pclient->output != NULL ) o_stream_unref(&pclient->output); pclient->temp_prefix = i_strdup(temp_prefix); pclient->output_seekable = TRUE; }
static void o_stream_failure_at_destroy(struct iostream_private *stream) { struct failure_at_ostream *fstream = (struct failure_at_ostream *)stream; i_free(fstream->error_string); o_stream_unref(&fstream->ostream.parent); }
static void proxy_input(struct client *client) { struct istream *input; struct ostream *output; const char *line; unsigned int duration; if (client->login_proxy == NULL) { /* we're just freeing the proxy */ return; } input = login_proxy_get_istream(client->login_proxy); if (input == NULL) { if (client->destroyed) { /* we came here from client_destroy() */ return; } /* failed for some reason, probably server disconnected */ client_proxy_failed(client, TRUE); return; } i_assert(!client->destroyed); switch (i_stream_read(input)) { case -2: client_log_err(client, "proxy: Remote input buffer full"); client_proxy_failed(client, TRUE); return; case -1: line = i_stream_next_line(input); duration = ioloop_time - client->created; client_log_err(client, t_strdup_printf( "proxy: Remote %s:%u disconnected: %s " "(state=%u, duration=%us)%s", login_proxy_get_host(client->login_proxy), login_proxy_get_port(client->login_proxy), get_disconnect_reason(input), client->proxy_state, duration, line == NULL ? "" : t_strdup_printf( " - BUG: line not read: %s", line))); client_proxy_failed(client, TRUE); return; } output = client->output; o_stream_ref(output); o_stream_cork(output); while ((line = i_stream_next_line(input)) != NULL) { if (client->v.proxy_parse_line(client, line) != 0) break; } o_stream_uncork(output); o_stream_unref(&output); }
void script_client_set_output (struct script_client *sclient, struct ostream *output) { if ( sclient->output ) o_stream_unref(&sclient->output); if ( output != NULL ) o_stream_ref(output); sclient->output = output; }
static void openssl_iostream_free(struct ssl_iostream *ssl_io) { i_stream_unref(&ssl_io->plain_input); o_stream_unref(&ssl_io->plain_output); BIO_free(ssl_io->bio_ext); SSL_free(ssl_io->ssl); i_free(ssl_io->last_error); i_free(ssl_io->source); i_free(ssl_io); }
void program_client_set_output (struct program_client *pclient, struct ostream *output) { if ( pclient->output != NULL ) o_stream_unref(&pclient->output); if ( output != NULL ) o_stream_ref(output); pclient->output = output; pclient->output_seekable = FALSE; i_free(pclient->temp_prefix); }
static void o_stream_zlib_close(struct iostream_private *stream) { struct zlib_ostream *zstream = (struct zlib_ostream *)stream; if (zstream->output == NULL) return; o_stream_flush(&zstream->ostream.ostream); o_stream_unref(&zstream->output); (void)deflateEnd(&zstream->zs); }
static void test_write_read_v1_empty(void) { const unsigned char *ptr; size_t siz; test_begin("test_write_read_v1_empty"); buffer_t *buf = buffer_create_dynamic(default_pool, 64); struct ostream *os = o_stream_create_buffer(buf); struct ostream *os_2 = o_stream_create_encrypt(os, "<unused>", test_v1_kp.pub, IO_STREAM_ENC_VERSION_1); test_assert(o_stream_nfinish(os_2) == 0); if (os_2->stream_errno != 0) i_debug("error: %s", o_stream_get_error(os_2)); o_stream_unref(&os); o_stream_unref(&os_2); /* this should've been enough */ struct istream *is = test_istream_create_data(buf->data, buf->used); struct istream *is_2 = i_stream_create_decrypt(is, test_v1_kp.priv); /* read should not fail */ test_istream_set_allow_eof(is, FALSE); test_istream_set_size(is, 0); size_t offset = 0; ssize_t ret; while ((ret = i_stream_read_data(is_2, &ptr, &siz, 0)) >= 0) { test_assert(ret == 0); if (offset == buf->used) test_istream_set_allow_eof(is, TRUE); else test_istream_set_size(is, ++offset); }; test_assert(is_2->stream_errno == 0); if (is_2->stream_errno != 0) i_debug("error: %s", i_stream_get_error(is_2)); i_stream_unref(&is); i_stream_unref(&is_2); buffer_free(&buf); test_end(); }
static void auth_client_connection_unref(struct auth_client_connection **_conn) { struct auth_client_connection *conn = *_conn; *_conn = NULL; if (--conn->refcount > 0) return; i_stream_unref(&conn->input); o_stream_unref(&conn->output); i_free(conn); }
void auth_worker_client_unref(struct auth_worker_client **_client) { struct auth_worker_client *client = *_client; *_client = NULL; if (--client->refcount > 0) return; i_stream_unref(&client->input); o_stream_unref(&client->output); i_free(client); }
static void http_client_request_finish_payload_out(struct http_client_request *req) { i_assert(req->conn != NULL); if (req->payload_output != NULL) { o_stream_unref(&req->payload_output); req->payload_output = NULL; } req->state = HTTP_REQUEST_STATE_WAITING; req->conn->output_locked = FALSE; http_client_request_debug(req, "Finished sending payload"); }
static void test_ostream_dot_one(const struct dot_test *test) { struct istream *test_input; struct ostream *output, *test_output; buffer_t *output_data; const unsigned char *data; size_t size; ssize_t ret; test_input = test_istream_create(test->input); output_data = t_buffer_create(1024); test_output = o_stream_create_buffer(output_data); output = o_stream_create_dot(test_output, FALSE); while ((ret = i_stream_read(test_input)) > 0 || ret == -2) { data = i_stream_get_data(test_input, &size); ret = o_stream_send(output, data, size); test_assert(ret >= 0); if (ret <= 0) break; i_stream_skip(test_input, ret); } test_assert(test_input->eof); test_assert(o_stream_finish(output) > 0); test_assert(output->offset == strlen(test->input)); test_assert(test_output->offset == strlen(test->output)); o_stream_unref(&output); o_stream_unref(&test_output); test_assert(strcmp(str_c(output_data), test->output) == 0); i_stream_unref(&test_input); }
void notify_connection_unref(struct notify_connection **_conn) { struct notify_connection *conn = *_conn; i_assert(conn->refcount > 0); *_conn = NULL; if (--conn->refcount > 0) return; notify_connection_destroy(conn); i_stream_unref(&conn->input); o_stream_unref(&conn->output); i_free(conn); }
static void client_add_input(struct client *client, const buffer_t *buf) { struct ostream *output; if (buf != NULL && buf->used > 0) { if (!i_stream_add_data(client->input, buf->data, buf->used)) i_panic("Couldn't add client input to stream"); } output = client->output; o_stream_ref(output); o_stream_cork(output); (void)client_handle_input(client); o_stream_uncork(output); o_stream_unref(&output); }
void iostream_pump_destroy(struct iostream_pump **_pump) { i_assert(_pump != NULL); struct iostream_pump *pump = *_pump; if (pump == NULL) return; *_pump = NULL; iostream_pump_stop(pump); o_stream_unref(&pump->output); i_stream_unref(&pump->input); iostream_pump_unref(&pump); }
static void auth_postfix_connection_unref(struct auth_postfix_connection **_conn) { struct auth_postfix_connection *conn = *_conn; *_conn = NULL; i_assert(conn->refcount > 0); if (--conn->refcount > 0) return; if (conn->input != NULL) i_stream_unref(&conn->input); if (conn->output != NULL) o_stream_unref(&conn->output); i_free(conn); }
static void lmtp_client_unref(struct lmtp_client **_client) { struct lmtp_client *client = *_client; *_client = NULL; i_assert(client->refcount > 0); if (--client->refcount > 0) return; i_assert(client->finish_called); if (client->input != NULL) i_stream_unref(&client->input); if (client->output != NULL) o_stream_unref(&client->output); pool_unref(&client->pool); }
static void test_ostream_file_random(void) { struct ostream *output; string_t *path = t_str_new(128); char buf[MAX_BUFSIZE*4], buf2[MAX_BUFSIZE*4], randbuf[MAX_BUFSIZE]; unsigned int i, offset, size; ssize_t ret; int fd; memset(buf, 0, sizeof(buf)); fd = safe_mkstemp(path, 0600, (uid_t)-1, (gid_t)-1); if (fd == -1) i_fatal("safe_mkstemp(%s) failed: %m", str_c(path)); if (unlink(str_c(path)) < 0) i_fatal("unlink(%s) failed: %m", str_c(path)); output = o_stream_create_fd(fd, MAX_BUFSIZE, FALSE); o_stream_cork(output); size = (rand() % MAX_BUFSIZE) + 1; random_fill_weak(randbuf, size); memcpy(buf, randbuf, size); test_assert(o_stream_send(output, buf, size) > 0); for (i = 0; i < 10; i++) { offset = rand() % (MAX_BUFSIZE*3); size = (rand() % MAX_BUFSIZE) + 1; random_fill_weak(randbuf, size); memcpy(buf + offset, randbuf, size); test_assert(o_stream_pwrite(output, randbuf, size, offset) == 0); if (rand() % 10 == 0) test_assert(o_stream_flush(output) > 0); } test_assert(o_stream_flush(output) > 0); o_stream_uncork(output); ret = pread(fd, buf2, sizeof(buf2), 0); if (ret < 0) i_fatal("pread() failed: %m"); else { i_assert(ret > 0); test_assert(memcmp(buf, buf2, ret) == 0); } o_stream_unref(&output); i_close_fd(&fd); }
static int fs_crypt_write_stream_finish(struct fs_file *_file, bool success) { struct crypt_fs_file *file = (struct crypt_fs_file *)_file; struct istream *input; int ret; if (_file->output != NULL) { if (_file->output == file->super_output) _file->output = NULL; else o_stream_unref(&_file->output); } if (!success) { if (file->super_output != NULL) { /* no encryption */ i_assert(file->temp_output == NULL); fs_write_stream_abort_error(_file->parent, &file->super_output, "write(%s) failed: %s", o_stream_get_name(file->super_output), o_stream_get_error(file->super_output)); } else if (file->temp_output != NULL) { o_stream_destroy(&file->temp_output); } return -1; } if (file->super_output != NULL) { /* no encrypt */ i_assert(file->temp_output == NULL); return fs_write_stream_finish(_file->parent, &file->super_output); } if (file->temp_output == NULL) { /* finishing up */ i_assert(file->super_output == NULL); return fs_write_stream_finish_async(_file->parent); } /* finish writing the temporary file */ input = iostream_temp_finish(&file->temp_output, IO_BLOCK_SIZE); file->super_output = fs_write_stream(_file->parent); o_stream_nsend_istream(file->super_output, input); ret = fs_write_stream_finish(_file->parent, &file->super_output); i_stream_unref(&input); return ret; }
int mbox_move(struct mbox_sync_context *sync_ctx, uoff_t dest, uoff_t source, uoff_t size) { struct istream *input; struct ostream *output; off_t ret; i_assert(size < OFF_T_MAX); if (size == 0 || source == dest) return 0; i_stream_sync(sync_ctx->input); output = o_stream_create_fd_file(sync_ctx->write_fd, (uoff_t)-1, FALSE); i_stream_seek(sync_ctx->file_input, source); if (o_stream_seek(output, dest) < 0) { mbox_set_syscall_error(sync_ctx->mbox, "o_stream_seek()"); o_stream_unref(&output); return -1; } input = i_stream_create_limit(sync_ctx->file_input, size); ret = o_stream_send_istream(output, input); i_stream_unref(&input); if (ret == (off_t)size) ret = 0; else if (ret >= 0) { mbox_sync_set_critical(sync_ctx, "mbox_move(%"PRIuUOFF_T", %"PRIuUOFF_T", %"PRIuUOFF_T ") moved only %"PRIuUOFF_T" bytes", dest, source, size, (uoff_t)ret); ret = -1; } else if (ret < 0) { errno = output->stream_errno; mbox_set_syscall_error(sync_ctx->mbox, "o_stream_send_istream()"); } mbox_sync_file_updated(sync_ctx, FALSE); o_stream_destroy(&output); return (int)ret; }
void script_client_destroy(struct script_client **_sclient) { struct script_client *sclient = *_sclient; script_client_disconnect(sclient, TRUE); if ( sclient->input != NULL ) i_stream_unref(&sclient->input); if ( sclient->output != NULL ) o_stream_unref(&sclient->output); if ( sclient->io != NULL ) io_remove(&sclient->io); if ( sclient->ioloop != NULL ) io_loop_destroy(&sclient->ioloop); pool_unref(&sclient->pool); *_sclient = NULL; }
void client_input(struct client *client) { struct client_command_context *cmd; struct ostream *output = client->output; ssize_t bytes; i_assert(client->io != NULL); client->last_input = ioloop_time; timeout_reset(client->to_idle); if (client->to_delayed_input != NULL) timeout_remove(&client->to_delayed_input); bytes = i_stream_read(client->input); if (bytes == -1) { /* disconnected */ client_destroy(client, NULL); return; } o_stream_ref(output); o_stream_cork(output); if (!client_handle_input(client) && bytes == -2) { /* parameter word is longer than max. input buffer size. this is most likely an error, so skip the new data until newline is found. */ client->input_skip_line = TRUE; cmd = client->input_lock != NULL ? client->input_lock : client_command_new(client); cmd->param_error = TRUE; client_send_command_error(cmd, "Too long argument."); client_command_free(&cmd); } o_stream_uncork(output); o_stream_unref(&output); imap_refresh_proctitle(); if (client->disconnected) client_destroy(client, NULL); else client_continue_pending_input(client); }