static void test_compress_file(const char *in_path, const char *out_path) { const struct compression_handler *handler; struct istream *input, *file_input; struct ostream *output, *file_output; int fd_in, fd_out; struct sha1_ctxt sha1; unsigned char output_sha1[SHA1_RESULTLEN], input_sha1[SHA1_RESULTLEN]; const unsigned char *data; size_t size; ssize_t ret; handler = compression_lookup_handler_from_ext(out_path); if (handler == NULL) i_fatal("Can't detect compression algorithm from path %s", out_path); if (handler->create_ostream == NULL) i_fatal("Support not compiled in for %s", handler->name); /* write the compressed output file */ fd_in = open(in_path, O_RDONLY); if (fd_in == -1) i_fatal("open(%s) failed: %m", in_path); fd_out = open(out_path, O_TRUNC | O_CREAT | O_RDWR, 0600); if (fd_out == -1) i_fatal("creat(%s) failed: %m", out_path); sha1_init(&sha1); file_output = o_stream_create_fd_file(fd_out, 0, FALSE); output = handler->create_ostream(file_output, 1); input = i_stream_create_fd_autoclose(&fd_in, IO_BLOCK_SIZE); while (i_stream_read_data(input, &data, &size, 0) > 0) { sha1_loop(&sha1, data, size); o_stream_nsend(output, data, size); i_stream_skip(input, size); } if (o_stream_nfinish(output) < 0) { i_fatal("write(%s) failed: %s", out_path, o_stream_get_error(output)); } i_stream_destroy(&input); o_stream_destroy(&output); o_stream_destroy(&file_output); sha1_result(&sha1, output_sha1); /* verify that we can read the compressed file */ sha1_init(&sha1); file_input = i_stream_create_fd(fd_out, IO_BLOCK_SIZE, FALSE); input = handler->create_istream(file_input, FALSE); while ((ret = i_stream_read_data(input, &data, &size, 0)) > 0) { sha1_loop(&sha1, data, size); i_stream_skip(input, size); } i_stream_destroy(&input); i_stream_destroy(&file_input); sha1_result(&sha1, input_sha1); if (memcmp(input_sha1, output_sha1, sizeof(input_sha1)) != 0) i_fatal("Decompression couldn't get the original input"); i_close_fd(&fd_out); }
static void client_destroy(struct client *client) { char **app; i_set_failure_prefix("imap-urlauth[%s](%s): ", my_pid, client->access_user); if (client->url != NULL) { /* deinitialize url */ i_stream_close(client->input); o_stream_close(client->output); (void)client_run_url(client); i_assert(client->url == NULL); } imap_urlauth_worker_client_count--; DLLIST_REMOVE(&imap_urlauth_worker_clients, client); if (client->urlauth_ctx != NULL) imap_urlauth_deinit(&client->urlauth_ctx); if (client->mail_user != NULL) mail_user_unref(&client->mail_user); if (client->io != NULL) io_remove(&client->io); if (client->ctrl_io != NULL) io_remove(&client->ctrl_io); if (client->to_idle != NULL) timeout_remove(&client->to_idle); if (client->input != NULL) i_stream_destroy(&client->input); if (client->output != NULL) o_stream_destroy(&client->output); if (client->ctrl_input != NULL) i_stream_destroy(&client->ctrl_input); if (client->ctrl_output != NULL) o_stream_destroy(&client->ctrl_output); if (client->fd_in >= 0) net_disconnect(client->fd_in); if (client->fd_out >= 0 && client->fd_in != client->fd_out) net_disconnect(client->fd_out); if (client->fd_ctrl >= 0) net_disconnect(client->fd_ctrl); if (client->service_user != NULL) mail_storage_service_user_free(&client->service_user); i_free(client->access_user); array_foreach_modifiable(&client->access_apps, app) i_free(*app); array_free(&client->access_apps); i_free(client); imap_urlauth_worker_refresh_proctitle(); master_service_client_connection_destroyed(master_service); }
static void test_istream_children(void) { struct istream *parent, *child1, *child2; const unsigned char *data; size_t size; test_begin("istream children"); parent = test_istream_create_data("123456789", 9); test_istream_set_max_buffer_size(parent, 3); child1 = i_stream_create_limit(parent, (uoff_t)-1); child2 = i_stream_create_limit(parent, (uoff_t)-1); /* child1 read beginning */ test_assert(i_stream_read(child1) == 3); data = i_stream_get_data(child1, &size); test_assert(size == 3 && memcmp(data, "123", 3) == 0); i_stream_skip(child1, 3); /* child1 read middle.. */ test_assert(i_stream_read(child1) == 3); data = i_stream_get_data(child1, &size); test_assert(size == 3 && memcmp(data, "456", 3) == 0); /* child2 read beginning.. */ test_assert(i_stream_read(child2) == 3); data = i_stream_get_data(child2, &size); test_assert(size == 3 && memcmp(data, "123", 3) == 0); /* child1 check middle again.. the parent has been modified, so it can't return the original data (without some code changes). */ data = i_stream_get_data(child1, &size); test_assert(size == 0); i_stream_skip(child1, 3); /* child1 read end */ test_assert(i_stream_read(child1) == 3); data = i_stream_get_data(child1, &size); test_assert(size == 3 && memcmp(data, "789", 3) == 0); i_stream_skip(child1, 3); test_assert(i_stream_read(child1) == -1); /* child2 check beginning again.. */ data = i_stream_get_data(child2, &size); test_assert(size == 0); i_stream_skip(child2, 3); /* child2 read middle */ test_assert(i_stream_read(child2) == 3); data = i_stream_get_data(child2, &size); test_assert(size == 3 && memcmp(data, "456", 3) == 0); i_stream_skip(child2, 3); i_stream_destroy(&child1); i_stream_destroy(&child2); i_stream_destroy(&parent); test_end(); }
void server_connection_destroy(struct server_connection **_conn) { struct server_connection *conn = *_conn; struct server_connection *const *conns; const char *error; unsigned int i, count; *_conn = NULL; conns = array_get(&conn->server->connections, &count); for (i = 0; i < count; i++) { if (conns[i] == conn) { array_delete(&conn->server->connections, i, 1); break; } } if (conn->callback != NULL) { error = conn->ssl_iostream == NULL ? NULL : ssl_iostream_get_last_error(conn->ssl_iostream); if (error == NULL) { error = conn->input->stream_errno == 0 ? "EOF" : strerror(conn->input->stream_errno); } server_connection_callback(conn, SERVER_EXIT_CODE_DISCONNECTED, error); } if (printing_conn == conn) print_connection_released(); if (conn->input != NULL) i_stream_destroy(&conn->input); if (conn->output != NULL) o_stream_destroy(&conn->output); if (conn->cmd_input != NULL) i_stream_destroy(&conn->cmd_input); /* close cmd_output after its parent, so the "." isn't sent */ if (conn->cmd_output != NULL) o_stream_destroy(&conn->cmd_output); if (conn->ssl_iostream != NULL) ssl_iostream_unref(&conn->ssl_iostream); if (conn->io != NULL) io_remove(&conn->io); if (conn->fd != -1) { if (close(conn->fd) < 0) i_error("close(server) failed: %m"); } pool_unref(&conn->pool); }
static void winbind_helper_disconnect(struct winbind_helper *winbind) { if (winbind->in_pipe != NULL) i_stream_destroy(&winbind->in_pipe); if (winbind->out_pipe != NULL) o_stream_destroy(&winbind->out_pipe); }
void auth_server_connection_disconnect(struct auth_server_connection *conn, const char *reason) { conn->handshake_received = FALSE; conn->version_received = FALSE; conn->has_plain_mech = FALSE; conn->server_pid = 0; conn->connect_uid = 0; conn->cookie = NULL; array_clear(&conn->available_auth_mechs); if (conn->to != NULL) timeout_remove(&conn->to); if (conn->io != NULL) io_remove(&conn->io); if (conn->fd != -1) { i_stream_destroy(&conn->input); o_stream_destroy(&conn->output); if (close(conn->fd) < 0) i_error("close(auth server connection) failed: %m"); conn->fd = -1; } auth_server_connection_remove_requests(conn, reason); if (conn->client->connect_notify_callback != NULL) { conn->client->connect_notify_callback(conn->client, FALSE, conn->client->connect_notify_context); } }
static void stats_top(const char *path, const char *sort_type) { struct top_context ctx; memset(&ctx, 0, sizeof(ctx)); ctx.path = path; ctx.fd = doveadm_connect(path); ctx.prev_pool = pool_alloconly_create("stats top", 1024*16); ctx.cur_pool = pool_alloconly_create("stats top", 1024*16); i_array_init(&ctx.lines, 128); hash_table_create(&ctx.sessions, default_pool, 0, str_hash, strcmp); net_set_nonblock(ctx.fd, FALSE); ctx.input = i_stream_create_fd(ctx.fd, (size_t)-1, TRUE); if (strstr(sort_type, "cpu") != NULL) ctx.lines_sort = sort_cpu; else ctx.lines_sort = sort_num; ctx.sort_type = sort_type; stats_top_start(&ctx); i_stream_destroy(&ctx.input); hash_table_destroy(&ctx.sessions); array_free(&ctx.lines); pool_unref(&ctx.prev_pool); pool_unref(&ctx.cur_pool); i_close_fd(&ctx.fd); }
static void mbox_mailbox_close(struct mailbox *box) { struct mbox_mailbox *mbox = (struct mbox_mailbox *)box; const struct mail_index_header *hdr; enum mbox_sync_flags sync_flags = 0; if (mbox->mbox_stream != NULL && istream_raw_mbox_is_corrupted(mbox->mbox_stream)) { /* clear the corruption by forcing a full resync */ sync_flags |= MBOX_SYNC_UNDIRTY | MBOX_SYNC_FORCE_SYNC; } if (box->view != NULL) { hdr = mail_index_get_header(box->view); if ((hdr->flags & MAIL_INDEX_HDR_FLAG_HAVE_DIRTY) != 0 && !mbox_is_backend_readonly(mbox)) { /* we've done changes to mbox which haven't been written yet. do it now. */ sync_flags |= MBOX_SYNC_REWRITE; } } if (sync_flags != 0 && !mbox->invalid_mbox_file) (void)mbox_sync(mbox, sync_flags); if (mbox->mbox_global_lock_id != 0) mbox_unlock(mbox, mbox->mbox_global_lock_id); if (mbox->keep_lock_to != NULL) timeout_remove(&mbox->keep_lock_to); mbox_file_close(mbox); if (mbox->mbox_file_stream != NULL) i_stream_destroy(&mbox->mbox_file_stream); index_storage_mailbox_close(box); }
void login_connection_deinit(struct login_connection **_conn) { struct login_connection *conn = *_conn; *_conn = NULL; if (conn->destroyed) return; conn->destroyed = TRUE; DLLIST_REMOVE(&login_connections, conn); io_remove(&conn->io); if (conn->input != NULL) i_stream_destroy(&conn->input); o_stream_destroy(&conn->output); if (close(conn->fd) < 0) i_error("close(login connection) failed: %m"); conn->fd = -1; if (conn->auth != NULL) auth_connection_deinit(&conn->auth); login_connection_unref(&conn); master_service_client_connection_destroyed(master_service); }
static void penalty_lookup(struct penalty_context *ctx) { #define ANVIL_HANDSHAKE "VERSION\tanvil\t1\t0\n" #define ANVIL_CMD ANVIL_HANDSHAKE"PENALTY-DUMP\n" struct istream *input; const char *line; int fd; fd = doveadm_connect(ctx->anvil_path); net_set_nonblock(fd, FALSE); if (write(fd, ANVIL_CMD, strlen(ANVIL_CMD)) < 0) i_fatal("write(%s) failed: %m", ctx->anvil_path); input = i_stream_create_fd_autoclose(&fd, (size_t)-1); while ((line = i_stream_read_next_line(input)) != NULL) { if (*line == '\0') break; T_BEGIN { struct penalty_line penalty_line; penalty_parse_line(line, &penalty_line); penalty_print_line(ctx, &penalty_line); } T_END; } if (input->stream_errno != 0) i_fatal("read(%s) failed: %m", ctx->anvil_path); i_stream_destroy(&input); }
static int server_connection_send_cmd_input_more(struct server_connection *conn) { off_t ret; /* ostream-dot writes only up to max buffer size, so keep it non-zero */ o_stream_set_max_buffer_size(conn->cmd_output, IO_BLOCK_SIZE); ret = o_stream_send_istream(conn->cmd_output, conn->cmd_input); o_stream_set_max_buffer_size(conn->cmd_output, (size_t)-1); if (ret >= 0 && i_stream_have_bytes_left(conn->cmd_input)) { o_stream_set_flush_pending(conn->cmd_output, TRUE); return 0; } if (conn->cmd_input->stream_errno != 0) { i_error("read(%s) failed: %s", i_stream_get_name(conn->cmd_input), i_stream_get_error(conn->cmd_input)); } else if (conn->cmd_output->stream_errno != 0 || o_stream_flush(conn->cmd_output) < 0) { i_error("write(%s) failed: %s", o_stream_get_name(conn->cmd_output), o_stream_get_error(conn->cmd_output)); } i_stream_destroy(&conn->cmd_input); o_stream_destroy(&conn->cmd_output); return ret < 0 ? -1 : 1; }
static void pop3c_client_disconnect(struct pop3c_client *client) { client->state = POP3C_CLIENT_STATE_DISCONNECTED; client->async_commands = 0; if (client->running) io_loop_stop(current_ioloop); if (client->dns_lookup != NULL) dns_lookup_abort(&client->dns_lookup); if (client->to != NULL) timeout_remove(&client->to); if (client->io != NULL) io_remove(&client->io); if (client->input != NULL) i_stream_destroy(&client->input); if (client->output != NULL) o_stream_destroy(&client->output); if (client->ssl_iostream != NULL) ssl_iostream_unref(&client->ssl_iostream); if (client->fd != -1) { if (close(client->fd) < 0) i_error("close(pop3c) failed: %m"); client->fd = -1; } client_login_callback(client, POP3C_COMMAND_STATE_DISCONNECTED, "Disconnected"); }
static void worker_connection_disconnect(struct worker_connection *conn) { unsigned int i, count = aqueue_count(conn->request_queue); if (conn->fd != -1) { io_remove(&conn->io); i_stream_destroy(&conn->input); o_stream_destroy(&conn->output); if (close(conn->fd) < 0) i_error("close(%s) failed: %m", conn->socket_path); conn->fd = -1; } /* cancel any pending requests */ if (count > 0) { i_error("Indexer worker disconnected, " "discarding %u requests for %s", count, conn->request_username); } /* conn->callback() can try to destroy us */ conn->refcount++; for (i = 0; i < count; i++) { void *const *contextp = array_idx(&conn->request_contexts, aqueue_idx(conn->request_queue, 0)); void *context = *contextp; aqueue_delete_tail(conn->request_queue); conn->callback(-1, context); } i_free_and_null(conn->request_username); worker_connection_unref(conn); }
static void login_proxy_free_final(struct login_proxy *proxy) { if (proxy->delayed_disconnect) { DLLIST_REMOVE(&login_proxies_disconnecting, proxy); i_assert(proxy->state_rec->num_delayed_client_disconnects > 0); if (--proxy->state_rec->num_delayed_client_disconnects == 0) proxy->state_rec->num_disconnects_since_ts = 0; timeout_remove(&proxy->to); } if (proxy->client_io != NULL) io_remove(&proxy->client_io); if (proxy->client_input != NULL) i_stream_destroy(&proxy->client_input); if (proxy->client_output != NULL) o_stream_destroy(&proxy->client_output); if (proxy->client_fd != -1) net_disconnect(proxy->client_fd); if (proxy->ssl_server_proxy != NULL) { ssl_proxy_destroy(proxy->ssl_server_proxy); ssl_proxy_free(&proxy->ssl_server_proxy); } i_free(proxy->host); i_free(proxy); }
static void test_dsync_proxy_msg_save(void) { static const char *input = "..dotty\n..behavior\nfrom you\n.\nstop"; struct test_dsync_msg_event event; const unsigned char *data; size_t size; test_begin("proxy server msg save"); server->input = i_stream_create_from_data(input, strlen(input)); test_assert(run_cmd("MSG-SAVE", "28492428", "pop3uidl", "saveguid", "874", "33982482882924", "\\Flagged bar \\Answered", "8294284", NULL) == 1); test_assert(test_dsync_worker_next_msg_event(test_worker, &event)); test_assert(event.type == LAST_MSG_TYPE_SAVE); test_assert(event.save_data.received_date == 28492428); test_assert(strcmp(event.save_data.pop3_uidl, "pop3uidl") == 0); test_assert(strcmp(event.save_body, ".dotty\n.behavior\nfrom you") == 0); test_assert(strcmp(event.msg.guid, "saveguid") == 0); test_assert(event.msg.uid == 874); test_assert(event.msg.modseq == 33982482882924); test_assert(event.msg.flags == (MAIL_FLAGGED | MAIL_ANSWERED)); test_assert(strcmp(event.msg.keywords[0], "bar") == 0); test_assert(event.msg.keywords[1] == NULL); test_assert(event.msg.save_date == 8294284); data = i_stream_get_data(server->input, &size); test_assert(size == 4 && memcmp(data, "stop", 4) == 0); i_stream_destroy(&server->input); test_end(); }
int login_proxy_starttls(struct login_proxy *proxy) { int fd; if (proxy->server_input != NULL) i_stream_destroy(&proxy->server_input); if (proxy->server_output != NULL) o_stream_destroy(&proxy->server_output); io_remove(&proxy->server_io); fd = ssl_proxy_client_alloc(proxy->server_fd, &proxy->client->ip, proxy->client->pool, proxy->client->set, proxy->client->ssl_set, login_proxy_ssl_handshaked, proxy, &proxy->ssl_server_proxy); if (fd < 0) { client_log_err(proxy->client, t_strdup_printf( "proxy: SSL handshake failed to %s:%u", proxy->host, proxy->port)); return -1; } ssl_proxy_set_client(proxy->ssl_server_proxy, proxy->client); ssl_proxy_start(proxy->ssl_server_proxy); proxy->server_fd = fd; proxy_plain_connected(proxy); return 0; }
static void login_proxy_disconnect(struct login_proxy *proxy) { if (proxy->to != NULL) timeout_remove(&proxy->to); if (proxy->to_notify != NULL) timeout_remove(&proxy->to_notify); if (!proxy->num_waiting_connections_updated) { i_assert(proxy->state_rec->num_waiting_connections > 0); proxy->state_rec->num_waiting_connections--; } if (proxy->connected) { i_assert(proxy->state_rec->num_proxying_connections > 0); proxy->state_rec->num_proxying_connections--; } if (proxy->server_io != NULL) io_remove(&proxy->server_io); if (proxy->server_input != NULL) i_stream_destroy(&proxy->server_input); if (proxy->server_output != NULL) o_stream_destroy(&proxy->server_output); if (proxy->server_fd != -1) net_disconnect(proxy->server_fd); }
void master_login_auth_disconnect(struct master_login_auth *auth) { struct master_login_auth_request *request; while (auth->request_head != NULL) { request = auth->request_head; DLLIST2_REMOVE(&auth->request_head, &auth->request_tail, request); request_internal_failure(request, "Disconnected from auth server, aborting"); i_free(request); } hash_table_clear(auth->requests, FALSE); if (auth->to != NULL) timeout_remove(&auth->to); if (auth->io != NULL) io_remove(&auth->io); if (auth->fd != -1) { i_stream_destroy(&auth->input); o_stream_destroy(&auth->output); net_disconnect(auth->fd); auth->fd = -1; } auth->version_received = FALSE; }
static int fts_filter_stopwords_read_list(struct fts_filter_stopwords *filter, const char **error_r) { struct istream *input; const char *line, **words, *path; int ret = 0; path = t_strdup_printf(STOPWORDS_FILE_FORMAT, filter->stopwords_dir, filter->lang->name); input = i_stream_create_file(path, IO_BLOCK_SIZE); while ((line = i_stream_read_next_line(input)) != NULL) T_BEGIN { line = t_strcut(line, STOPWORDS_COMMENT_CHAR1); line = t_strcut(line, STOPWORDS_COMMENT_CHAR2); words = t_strsplit_spaces(line, " \t"); for (; *words != NULL; words++) { const char *word = p_strdup(filter->pool, *words); hash_table_insert(filter->stopwords, word, word); } } T_END; if (input->stream_errno != 0) { *error_r = t_strdup_printf("Failed to read stopword list %s: %s", path, i_stream_get_error(input)); ret = -1; } i_stream_destroy(&input); return ret; }
static void director_disconnect(struct director_context *ctx) { if (ctx->input != NULL) { if (ctx->input->stream_errno != 0) i_fatal("read(%s) failed: %m", ctx->socket_path); i_stream_destroy(&ctx->input); } }
int pop3c_sync_get_uidls(struct pop3c_mailbox *mbox) { ARRAY_TYPE(const_string) uidls; struct istream *input; const char *error, *cline; char *line, *p; unsigned int seq, line_seq; if (mbox->msg_uidls != NULL) return 0; if ((pop3c_client_get_capabilities(mbox->client) & POP3C_CAPABILITY_UIDL) == 0) { mail_storage_set_error(mbox->box.storage, MAIL_ERROR_NOTPOSSIBLE, "UIDLs not supported by server"); return -1; } if (pop3c_client_cmd_stream(mbox->client, "UIDL\r\n", &input, &error) < 0) { mail_storage_set_critical(mbox->box.storage, "UIDL failed: %s", error); return -1; } mbox->uidl_pool = pool_alloconly_create("POP3 UIDLs", 1024*32); p_array_init(&uidls, mbox->uidl_pool, 64); seq = 0; while ((line = i_stream_read_next_line(input)) != NULL) { seq++; p = strchr(line, ' '); if (p == NULL) { mail_storage_set_critical(mbox->box.storage, "Invalid UIDL line: %s", line); break; } *p++ = '\0'; if (str_to_uint(line, &line_seq) < 0 || line_seq != seq) { mail_storage_set_critical(mbox->box.storage, "Unexpected UIDL seq: %s != %u", line, seq); break; } cline = p_strdup(mbox->uidl_pool, p); array_append(&uidls, &cline, 1); } i_stream_destroy(&input); if (line != NULL) { pool_unref(&mbox->uidl_pool); return -1; } if (seq == 0) { /* make msg_uidls non-NULL */ array_append_zero(&uidls); } mbox->msg_uidls = array_idx(&uidls, 0); mbox->msg_count = seq; return 0; }
void login_proxy_detach(struct login_proxy *proxy) { struct client *client = proxy->client; const unsigned char *data; size_t size; i_assert(proxy->client_fd == -1); i_assert(proxy->server_input != NULL); i_assert(proxy->server_output != NULL); if (proxy->to != NULL) timeout_remove(&proxy->to); proxy->client_fd = i_stream_get_fd(client->input); proxy->client_input = client->input; proxy->client_output = client->output; i_stream_set_persistent_buffers(client->input, FALSE); o_stream_set_max_buffer_size(client->output, (size_t)-1); o_stream_set_flush_callback(client->output, proxy_client_output, proxy); client->input = NULL; client->output = NULL; /* send all pending client input to proxy */ data = i_stream_get_data(proxy->client_input, &size); if (size != 0) o_stream_nsend(proxy->server_output, data, size); /* from now on, just do dummy proxying */ io_remove(&proxy->server_io); proxy->server_io = io_add(proxy->server_fd, IO_READ, server_input, proxy); proxy->client_io = io_add_istream(proxy->client_input, proxy_client_input, proxy); o_stream_set_flush_callback(proxy->server_output, server_output, proxy); i_stream_destroy(&proxy->server_input); if (proxy->notify_refresh_secs != 0) { proxy->to_notify = timeout_add(proxy->notify_refresh_secs * 1000, login_proxy_notify, proxy); } proxy->callback = NULL; if (login_proxy_ipc_server == NULL) { login_proxy_ipc_server = ipc_server_init(LOGIN_PROXY_IPC_PATH, LOGIN_PROXY_IPC_NAME, login_proxy_ipc_cmd); } DLLIST_REMOVE(&login_proxies_pending, proxy); DLLIST_PREPEND(&login_proxies, proxy); client->fd = -1; client->login_proxy = NULL; }
static int copy_to_temp_file(struct seekable_istream *sstream) { struct istream_private *stream = &sstream->istream; const char *path; const unsigned char *buffer; size_t size; int fd; fd = sstream->fd_callback(&path, sstream->context); if (fd == -1) return -1; /* copy our currently read buffer to it */ i_assert(stream->pos <= sstream->buffer_peak); if (write_full(fd, stream->buffer, sstream->buffer_peak) < 0) { if (!ENOSPACE(errno)) i_error("istream-seekable: write_full(%s) failed: %m", path); i_close_fd(&fd); return -1; } sstream->temp_path = i_strdup(path); sstream->write_peak = sstream->buffer_peak; sstream->fd = fd; sstream->fd_input = i_stream_create_fd_autoclose(&fd, I_MAX(stream->pos, sstream->istream.max_buffer_size)); i_stream_set_name(sstream->fd_input, t_strdup_printf( "(seekable temp-istream for: %s)", i_stream_get_name(&stream->istream))); /* read back the data we just had in our buffer */ for (;;) { buffer = i_stream_get_data(sstream->fd_input, &size); if (size >= stream->pos) break; ssize_t ret; if ((ret = i_stream_read_memarea(sstream->fd_input)) <= 0) { i_assert(ret != 0); i_assert(ret != -2); i_error("istream-seekable: Couldn't read back " "in-memory input %s: %s", i_stream_get_name(&stream->istream), i_stream_get_error(sstream->fd_input)); i_stream_destroy(&sstream->fd_input); i_close_fd(&sstream->fd); return -1; } } /* Set the max buffer size only after we've already read everything into memory. For example with istream-data it's possible that more data exists in buffer than max_buffer_size. */ i_stream_set_max_buffer_size(sstream->fd_input, sstream->istream.max_buffer_size); stream->buffer = buffer; i_stream_free_buffer(&sstream->istream); return 0; }
static void i_stream_fs_file_close(struct iostream_private *stream, bool close_parent ATTR_UNUSED) { struct fs_file_istream *fstream = (struct fs_file_istream *)stream; if (fstream->istream.parent != NULL) i_stream_destroy(&fstream->istream.parent); fs_file_deinit(&fstream->file); }
int pop3c_sync_get_sizes(struct pop3c_mailbox *mbox) { struct istream *input; const char *error; char *line, *p; unsigned int seq, line_seq; i_assert(mbox->msg_sizes == NULL); if (mbox->msg_uidls == NULL) { if (pop3c_sync_get_uidls(mbox) < 0) return -1; } if (mbox->msg_count == 0) { mbox->msg_sizes = i_new(uoff_t, 1); return 0; } if (pop3c_client_cmd_stream(mbox->client, "LIST\r\n", &input, &error) < 0) { mail_storage_set_critical(mbox->box.storage, "LIST failed: %s", error); return -1; } mbox->msg_sizes = i_new(uoff_t, mbox->msg_count); seq = 0; while ((line = i_stream_read_next_line(input)) != NULL) { if (++seq > mbox->msg_count) { mail_storage_set_critical(mbox->box.storage, "Too much data in LIST: %s", line); break; } p = strchr(line, ' '); if (p == NULL) { mail_storage_set_critical(mbox->box.storage, "Invalid LIST line: %s", line); break; } *p++ = '\0'; if (str_to_uint(line, &line_seq) < 0 || line_seq != seq) { mail_storage_set_critical(mbox->box.storage, "Unexpected LIST seq: %s != %u", line, seq); break; } if (str_to_uoff(p, &mbox->msg_sizes[seq-1]) < 0) { mail_storage_set_critical(mbox->box.storage, "Invalid LIST size: %s", p); break; } } i_stream_destroy(&input); if (line != NULL) { i_free_and_null(mbox->msg_sizes); return -1; } return 0; }
void mbox_file_close_stream(struct mbox_mailbox *mbox) { /* if we read anything, fix the atime if needed */ mbox_file_fix_atime(mbox); if (mbox->mbox_stream != NULL) i_stream_destroy(&mbox->mbox_stream); if (mbox->mbox_file_stream != NULL) { if (mbox->mbox_fd == -1) { /* read-only mbox stream */ i_assert(mbox_is_backend_readonly(mbox)); i_stream_seek(mbox->mbox_file_stream, 0); } else { i_stream_destroy(&mbox->mbox_file_stream); } } }
int subsfile_list_deinit(struct subsfile_list_context *ctx) { int ret = ctx->failed ? -1 : 0; if (ctx->input != NULL) i_stream_destroy(&ctx->input); i_free(ctx->path); i_free(ctx); return ret; }
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); }
static const char * file_lock_find_proc_locks(int lock_fd ATTR_UNUSED) { /* do anything except Linux support this? don't bother trying it for OSes we don't know about. */ #ifdef __linux__ static bool have_proc_locks = TRUE; struct stat st; char node_buf[MAX_INT_STRLEN*3 + 2 + 1]; struct istream *input; const char *line, *lock_type = ""; pid_t pid = 0; int fd; if (!have_proc_locks) return FALSE; if (fstat(lock_fd, &st) < 0) return ""; i_snprintf(node_buf, sizeof(node_buf), "%02x:%02x:%llu", major(st.st_dev), minor(st.st_dev), (unsigned long long)st.st_ino); fd = open("/proc/locks", O_RDONLY); if (fd == -1) { have_proc_locks = FALSE; return ""; } input = i_stream_create_fd_autoclose(&fd, 512); while (pid == 0 && (line = i_stream_read_next_line(input)) != NULL) T_BEGIN { const char *const *args = t_strsplit_spaces(line, " "); /* number: FLOCK/POSIX ADVISORY READ/WRITE pid major:minor:inode region-start region-end */ if (str_array_length(args) < 8) continue; if (strcmp(args[5], node_buf) == 0) { lock_type = strcmp(args[3], "READ") == 0 ? "READ" : "WRITE"; if (str_to_pid(args[4], &pid) < 0) pid = 0; } } T_END; i_stream_destroy(&input); if (pid == 0) { /* not found */ return ""; } if (pid == getpid()) return " (BUG: lock is held by our own process)"; return t_strdup_printf(" (%s lock held by pid %ld)", lock_type, (long)pid); #else return ""; #endif }
static void notify_connection_unref(struct notify_connection *conn) { i_assert(conn->refcount > 0); if (--conn->refcount > 0) return; i_stream_destroy(&conn->input); if (conn->output != NULL) o_stream_destroy(&conn->output); i_free(conn); }