int script_client_run(struct script_client *sclient) { int ret; sclient->ioloop = io_loop_create(); if ( script_client_connect(sclient) >= 0 ) { /* run output */ ret = 1; if ( sclient->script_output != NULL && (ret=o_stream_flush(sclient->script_output)) == 0 ) { o_stream_set_flush_callback (sclient->script_output, script_client_script_output, sclient); } /* run i/o event loop */ if ( ret < 0 ) { sclient->error = SCRIPT_CLIENT_ERROR_IO; } else if ( sclient->io != NULL || ret == 0 ) { io_loop_run(sclient->ioloop); } /* finished */ script_client_disconnect(sclient, FALSE); } io_loop_destroy(&sclient->ioloop); if ( sclient->error != SCRIPT_CLIENT_ERROR_NONE ) return -1; return sclient->exit_code; }
void http_client_wait(struct http_client *client) { struct ioloop *prev_ioloop = current_ioloop; i_assert(client->ioloop == NULL); if (client->requests_count == 0) return; client->ioloop = io_loop_create(); http_client_switch_ioloop(client); if (client->set.dns_client != NULL) dns_client_switch_ioloop(client->set.dns_client); /* either we're waiting for network I/O or we're getting out of a callback using timeout_add_short(0) */ i_assert(io_loop_have_ios(client->ioloop) || io_loop_have_immediate_timeouts(client->ioloop)); do { http_client_debug(client, "Waiting for %d requests to finish", client->requests_count); io_loop_run(client->ioloop); } while (client->requests_count > 0); http_client_debug(client, "All requests finished"); io_loop_set_current(prev_ioloop); http_client_switch_ioloop(client); if (client->set.dns_client != NULL) dns_client_switch_ioloop(client->set.dns_client); io_loop_set_current(client->ioloop); io_loop_destroy(&client->ioloop); }
static int cmd_dsync_server_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user) { struct dsync_cmd_context *ctx = (struct dsync_cmd_context *)_ctx; struct dsync_ibc *ibc; struct dsync_brain *brain; string_t *temp_prefix, *state_str = NULL; enum dsync_brain_sync_type sync_type; const char *name; if (_ctx->conn != NULL) { /* doveadm-server connection. start with a success reply. after that follows the regular dsync protocol. */ ctx->fd_in = ctx->fd_out = -1; ctx->input = _ctx->conn->input; ctx->output = _ctx->conn->output; o_stream_nsend(ctx->output, "\n+\n", 3); i_set_failure_prefix("dsync-server(%s): ", user->username); name = i_stream_get_name(ctx->input); } else { /* the log messages go via stderr to the remote dsync, so the names are reversed */ i_set_failure_prefix("dsync-remote(%s): ", user->username); name = "local"; } doveadm_user_init_dsync(user); temp_prefix = t_str_new(64); mail_user_set_get_temp_prefix(temp_prefix, user->set); ibc = cmd_dsync_icb_stream_init(ctx, name, str_c(temp_prefix)); brain = dsync_brain_slave_init(user, ibc, FALSE); io_loop_run(current_ioloop); if (ctx->replicator_notify) { state_str = t_str_new(128); dsync_brain_get_state(brain, state_str); } sync_type = dsync_brain_get_sync_type(brain); if (dsync_brain_deinit(&brain) < 0) _ctx->exit_code = EX_TEMPFAIL; dsync_ibc_deinit(&ibc); if (_ctx->conn != NULL) { /* make sure nothing more is written by the generic doveadm connection code */ o_stream_close(_ctx->conn->output); } if (ctx->replicator_notify && _ctx->exit_code == 0) dsync_replicator_notify(ctx, sync_type, str_c(state_str)); return _ctx->exit_code == 0 ? 0 : -1; }
static void stats_top_start(struct top_context *ctx) { struct timeout *to; stats_top_output(ctx); to = timeout_add(1000, stats_top_output, ctx); io_loop_run(current_ioloop); timeout_remove(&to); }
static void fts_parser_tika_more(struct fts_parser *_parser, struct message_block *block) { struct tika_fts_parser *parser = (struct tika_fts_parser *)_parser; const unsigned char *data; size_t size; ssize_t ret; if (block->size > 0) { /* first we'll send everything to Tika */ if (!parser->failed && http_client_request_send_payload(&parser->http_req, block->data, block->size) < 0) parser->failed = TRUE; block->size = 0; return; } if (parser->payload == NULL) { /* read the result from Tika */ if (!parser->failed && http_client_request_finish_payload(&parser->http_req) < 0) parser->failed = TRUE; if (!parser->failed && parser->payload == NULL) http_client_wait(tika_http_client); if (parser->failed) return; i_assert(parser->payload != NULL); } /* continue returning data from Tika */ while ((ret = i_stream_read_data(parser->payload, &data, &size, 0)) == 0) { if (parser->failed) return; /* wait for more input from Tika */ if (parser->ioloop == NULL) { parser->ioloop = io_loop_create(); parser->io = io_add_istream(parser->payload, io_loop_stop, current_ioloop); } else { io_loop_set_current(parser->ioloop); } io_loop_run(current_ioloop); } if (size > 0) { i_assert(ret > 0); block->data = data; block->size = size; i_stream_skip(parser->payload, size); } else { /* finished */ i_assert(ret == -1); } }
int main(int argc, char **argv) { struct sigaction act; memset(&act, 0, sizeof(act)); act.sa_handler = sigint_handler; DIE_IF_ERR(io_loop_init(&loop)); DIE_IF_ERR(io_tcp_server(&loop, &server, "0.0.0.0", "5000")); DIE_IF_ERR(io_listen_start(&server, incoming_connection)); DIE_IF_ERR(sigaction(SIGINT, &act, NULL)); puts("echo server is up..."); DIE_IF_ERR(io_loop_run(&loop)); return 0; }
static void cmd_proxy_list(int argc, char *argv[]) { struct proxy_context *ctx; bool seen_header = FALSE; ctx = cmd_proxy_init(argc, argv, "a:", cmd_proxy_list); doveadm_print_init(DOVEADM_PRINT_TYPE_TABLE); io_loop_set_running(current_ioloop); ipc_client_cmd(ctx->ipc, "proxy\t*\tLIST-FULL", cmd_proxy_list_callback, &seen_header); if (io_loop_is_running(current_ioloop)) io_loop_run(current_ioloop); ipc_client_deinit(&ctx->ipc); }
void pop3c_client_run(struct pop3c_client *client) { struct ioloop *ioloop, *prev_ioloop = current_ioloop; bool timeout_added = FALSE, failed = FALSE; i_assert(client->fd != -1 || client->state == POP3C_CLIENT_STATE_CONNECTING); ioloop = io_loop_create(); pop3c_client_ioloop_changed(client); if (client->ip.family == 0) { /* we're connecting, start DNS lookup after our ioloop is created */ struct dns_lookup_settings dns_set; i_assert(client->state == POP3C_CLIENT_STATE_CONNECTING); memset(&dns_set, 0, sizeof(dns_set)); dns_set.dns_client_socket_path = client->set.dns_client_socket_path; dns_set.timeout_msecs = POP3C_DNS_LOOKUP_TIMEOUT_MSECS; if (dns_lookup(client->set.host, &dns_set, pop3c_dns_callback, client, &client->dns_lookup) < 0) failed = TRUE; } else if (client->to == NULL) { client->to = timeout_add(POP3C_COMMAND_TIMEOUT_MSECS, pop3c_client_timeout, client); timeout_added = TRUE; } if (!failed) { client->running = TRUE; io_loop_run(ioloop); client->running = FALSE; } if (timeout_added && client->to != NULL) timeout_remove(&client->to); current_ioloop = prev_ioloop; pop3c_client_ioloop_changed(client); current_ioloop = ioloop; io_loop_destroy(&ioloop); }
int main(int argc, char **argv) { struct sigaction act; io_handle_t serv1, serv2, serv3, servr, watcher; sdp_session_t *session; memset(&act, 0, sizeof(act)); act.sa_handler = sigint_handler; DIE_IF_ERR(storage_segregate(&storage, 12, 512)); DIE_IF_ERR(io_loop_init(&loop)); DIE_IF_ERR(io_file(&loop, &backup, "backup.txt", O_RDWR)); DIE_IF_ERR(io_inotify(&loop, &watcher)); DIE_IF_ERR(io_tcp_server(&loop, &serv1, "0.0.0.0", "3000")); DIE_IF_ERR(io_tcp_server(&loop, &serv2, "0.0.0.0", "4000")); DIE_IF_ERR(io_tcp_server(&loop, &serv3, "0.0.0.0", "5000")); DIE_IF_ERR(io_rfcomm_server(&loop, &servr, BDADDR_ANY, 4)); lseek(backup.fd, 0, SEEK_END); DIE_IF_ERR(io_watch_start(&watcher, "/dev", IN_CREATE | IN_DELETE, file_changed)); DIE_IF_ERR(io_channel(&channel)); DIE_IF_ERR(io_channel_join(&channel, &backup, backup_updated)); DIE_IF_ERR(io_channel_join(&channel, &tcp1, serl_updated)); if(try_serial(&loop, &serl) == -1) puts("warning: arduino not connected."); else DIE_IF_ERR(io_publish_start(&serl, &channel, data_published)); DIE_IF_ERR(io_listen_start(&serv1, new_tcp1_conn)); DIE_IF_ERR(io_listen_start(&serv2, new_tcp2_conn)); DIE_IF_ERR(io_listen_start(&serv3, new_tcp3_conn)); DIE_IF_ERR(io_listen_start(&servr, new_rfcm_conn)); session = io_rfcomm_advertise(4, name, desc, uuid128); DIE_IF_ERR(sigaction(SIGINT, &act, NULL)); puts("pi server is up..."); DIE_IF_ERR(io_loop_run(&loop)); io_channel_close(&channel); storage_collapse(&storage); io_rfcomm_unadvertise(session); return 0; }
static int fts_indexer_more_int(struct fts_indexer_context *ctx) { struct ioloop *ioloop; struct io *io; struct timeout *to; int ret; if ((ret = fts_indexer_input(ctx)) != 0) return ret; /* wait for a while for the reply. FIXME: once search API supports asynchronous waits, get rid of this wait and use the mail IO loop */ ioloop = io_loop_create(); io = io_add(ctx->fd, IO_READ, io_loop_stop, ioloop); to = timeout_add_short(INDEXER_WAIT_MSECS, io_loop_stop, ioloop); io_loop_run(ioloop); io_remove(&io); timeout_remove(&to); io_loop_destroy(&ioloop); return fts_indexer_input(ctx); }
int program_client_run(struct program_client *pclient) { int ret; /* reset */ pclient->disconnected = FALSE; pclient->exit_code = 1; pclient->error = PROGRAM_CLIENT_ERROR_NONE; pclient->ioloop = io_loop_create(); if ( (ret=program_client_connect(pclient)) >= 0 ) { /* run output */ if ( ret > 0 && pclient->program_output != NULL && (ret=o_stream_flush(pclient->program_output)) == 0 ) { o_stream_set_flush_callback (pclient->program_output, program_client_program_output, pclient); } /* run i/o event loop */ if ( ret < 0 ) { pclient->error = PROGRAM_CLIENT_ERROR_IO; } else if ( !pclient->disconnected && (ret == 0 || program_client_input_pending(pclient)) ) { io_loop_run(pclient->ioloop); } /* finished */ program_client_disconnect(pclient, FALSE); } io_loop_destroy(&pclient->ioloop); if ( pclient->error != PROGRAM_CLIENT_ERROR_NONE ) return -1; return pclient->exit_code; }
static void test_iostream_proxy_simple(void) { size_t bytes; test_begin("iostream_proxy"); int sfdl[2]; int sfdr[2]; int counter; test_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, sfdl) == 0); test_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, sfdr) == 0); fd_set_nonblock(sfdl[0], TRUE); fd_set_nonblock(sfdl[1], TRUE); fd_set_nonblock(sfdr[0], TRUE); fd_set_nonblock(sfdr[1], TRUE); struct ioloop *ioloop = io_loop_create(); struct istream *left_in = i_stream_create_fd(sfdl[1], IO_BLOCK_SIZE); struct ostream *left_out = o_stream_create_fd(sfdl[1], IO_BLOCK_SIZE); struct istream *right_in = i_stream_create_fd(sfdr[1], IO_BLOCK_SIZE); struct ostream *right_out = o_stream_create_fd(sfdr[1], IO_BLOCK_SIZE); struct iostream_proxy *proxy; proxy = iostream_proxy_create(left_in, left_out, right_in, right_out); i_stream_unref(&left_in); o_stream_unref(&left_out); i_stream_unref(&right_in); o_stream_unref(&right_out); iostream_proxy_set_completion_callback(proxy, completed, &counter); iostream_proxy_start(proxy); left_in = i_stream_create_fd(sfdl[0], IO_BLOCK_SIZE); left_out = o_stream_create_fd(sfdl[0], IO_BLOCK_SIZE); right_in = i_stream_create_fd(sfdr[0], IO_BLOCK_SIZE); right_out = o_stream_create_fd(sfdr[0], IO_BLOCK_SIZE); test_assert(proxy != NULL); test_assert(o_stream_send_str(left_out, "hello, world") > 0); o_stream_flush(left_out); o_stream_unref(&left_out); test_assert(shutdown(sfdl[0], SHUT_WR) == 0); counter = 1; io_loop_run(ioloop); i_stream_read(right_in); test_assert(strcmp((const char*)i_stream_get_data(right_in, &bytes), "hello, world") == 0); i_stream_skip(right_in, bytes); test_assert(o_stream_send_str(right_out, "hello, world") > 0); o_stream_flush(right_out); o_stream_unref(&right_out); test_assert(shutdown(sfdr[0], SHUT_WR) == 0); counter = 1; io_loop_run(ioloop); i_stream_read(left_in); test_assert(strcmp((const char*)i_stream_get_data(left_in, &bytes), "hello, world") == 0); i_stream_skip(left_in, bytes); iostream_proxy_unref(&proxy); io_loop_destroy(&ioloop); i_stream_unref(&left_in); i_stream_unref(&right_in); /* close fd */ close(sfdl[0]); close(sfdl[1]); close(sfdr[0]); close(sfdr[1]); test_end(); }
static void fts_parser_tika_more(struct fts_parser *_parser, struct message_block *block) { struct tika_fts_parser *parser = (struct tika_fts_parser *)_parser; struct ioloop *prev_ioloop = current_ioloop; const unsigned char *data; size_t size; ssize_t ret; if (block->size > 0) { /* first we'll send everything to Tika */ if (!parser->failed && http_client_request_send_payload(&parser->http_req, block->data, block->size) < 0) parser->failed = TRUE; block->size = 0; return; } if (parser->payload == NULL) { /* read the result from Tika */ if (!parser->failed && http_client_request_finish_payload(&parser->http_req) < 0) parser->failed = TRUE; if (!parser->failed && parser->payload == NULL) http_client_wait(tika_http_client); if (parser->failed) return; i_assert(parser->payload != NULL); } /* continue returning data from Tika. we'll create a new ioloop just for reading this one payload. */ while ((ret = i_stream_read_data(parser->payload, &data, &size, 0)) == 0) { if (parser->failed) break; /* wait for more input from Tika */ if (parser->ioloop == NULL) { parser->ioloop = io_loop_create(); parser->io = io_add_istream(parser->payload, io_loop_stop, current_ioloop); } else { io_loop_set_current(parser->ioloop); } io_loop_run(current_ioloop); } /* switch back to original ioloop. */ io_loop_set_current(prev_ioloop); if (parser->failed) ; else if (size > 0) { i_assert(ret > 0); block->data = data; block->size = size; i_stream_skip(parser->payload, size); } else { /* finished */ i_assert(ret == -1); if (parser->payload->stream_errno != 0) { i_error("read(%s) failed: %s", i_stream_get_name(parser->payload), i_stream_get_error(parser->payload)); parser->failed = TRUE; } } }
static int dsync_connect_tcp(struct dsync_cmd_context *ctx, const struct mail_storage_settings *mail_set, const char *target, bool ssl, const char **error_r) { struct doveadm_server *server; struct server_connection *conn; struct ioloop *ioloop; string_t *cmd; const char *error; server = p_new(ctx->ctx.pool, struct doveadm_server, 1); server->name = p_strdup(ctx->ctx.pool, target); if (ssl) { if (dsync_init_ssl_ctx(ctx, mail_set, &error) < 0) { *error_r = t_strdup_printf( "Couldn't initialize SSL context: %s", error); return -1; } server->ssl_ctx = ctx->ssl_ctx; } p_array_init(&server->connections, ctx->ctx.pool, 1); p_array_init(&server->queue, ctx->ctx.pool, 1); ioloop = io_loop_create(); if (server_connection_create(server, &conn) < 0) { *error_r = "Couldn't create server connection"; return -1; } /* <flags> <username> <command> [<args>] */ cmd = t_str_new(256); if (doveadm_debug) str_append_c(cmd, 'D'); str_append_c(cmd, '\t'); str_append_tabescaped(cmd, ctx->ctx.cur_username); str_append(cmd, "\tdsync-server\t-u"); str_append_tabescaped(cmd, ctx->ctx.cur_username); if (ctx->replicator_notify) str_append(cmd, "\t-U"); str_append_c(cmd, '\n'); ctx->tcp_conn = conn; server_connection_cmd(conn, str_c(cmd), dsync_connected_callback, ctx); io_loop_run(ioloop); ctx->tcp_conn = NULL; if (array_count(&server->connections) > 0) server_connection_destroy(&conn); io_loop_destroy(&ioloop); if (ctx->error != NULL) { *error_r = ctx->error; ctx->error = NULL; return -1; } ctx->run_type = DSYNC_RUN_TYPE_STREAM; return 0; }
static void cmd_dsync_run_remote(struct mail_user *user) { i_set_failure_prefix("dsync-local(%s): ", user->username); io_loop_run(current_ioloop); }
static int http_client_request_continue_payload(struct http_client_request **_req, const unsigned char *data, size_t size) { struct ioloop *prev_ioloop = current_ioloop; struct http_client_request *req = *_req; struct http_client_connection *conn = req->conn; struct http_client *client = req->client; int ret; i_assert(req->state == HTTP_REQUEST_STATE_NEW || req->state == HTTP_REQUEST_STATE_PAYLOAD_OUT); i_assert(req->payload_input == NULL); if (conn != NULL) http_client_connection_ref(conn); http_client_request_ref(req); req->payload_wait = TRUE; if (data == NULL) { req->payload_input = NULL; if (req->state == HTTP_REQUEST_STATE_PAYLOAD_OUT) http_client_request_finish_payload_out(req); } else { req->payload_input = i_stream_create_from_data(data, size); i_stream_set_name(req->payload_input, "<HTTP request payload>"); } req->payload_size = 0; req->payload_chunked = TRUE; if (req->state == HTTP_REQUEST_STATE_NEW) http_client_request_submit(req); /* Wait for payload data to be written */ i_assert(client->ioloop == NULL); client->ioloop = io_loop_create(); http_client_switch_ioloop(client); if (client->set.dns_client != NULL) dns_client_switch_ioloop(client->set.dns_client); while (req->state < HTTP_REQUEST_STATE_PAYLOAD_IN) { http_client_request_debug(req, "Waiting for request to finish"); if (req->state == HTTP_REQUEST_STATE_PAYLOAD_OUT) o_stream_set_flush_pending(req->payload_output, TRUE); io_loop_run(client->ioloop); if (req->state == HTTP_REQUEST_STATE_PAYLOAD_OUT && req->payload_input->eof) { i_stream_unref(&req->payload_input); req->payload_input = NULL; break; } } io_loop_set_current(prev_ioloop); http_client_switch_ioloop(client); if (client->set.dns_client != NULL) dns_client_switch_ioloop(client->set.dns_client); io_loop_set_current(client->ioloop); io_loop_destroy(&client->ioloop); switch (req->state) { case HTTP_REQUEST_STATE_PAYLOAD_IN: case HTTP_REQUEST_STATE_FINISHED: ret = 1; break; case HTTP_REQUEST_STATE_ABORTED: ret = -1; break; default: ret = 0; break; } req->payload_wait = FALSE; /* callback may have messed with our pointer, so unref using local variable */ if (!http_client_request_unref(&req)) *_req = NULL; if (conn != NULL) http_client_connection_unref(&conn); /* Return status */ return ret; }
static ssize_t http_server_istream_read(struct istream_private *stream) { struct http_server_istream *hsristream = (struct http_server_istream *)stream; struct http_server_request *req = hsristream->req; struct http_server *server; struct http_server_connection *conn; bool blocking = stream->istream.blocking; ssize_t ret; if (req == NULL) { /* request already gone (we shouldn't get here) */ stream->istream.stream_errno = EINVAL; return -1; } i_stream_seek(stream->parent, stream->parent_start_offset + stream->istream.v_offset); server = hsristream->req->server; conn = hsristream->req->conn; ret = i_stream_read_copy_from_parent(&stream->istream); if (ret == 0 && blocking) { struct ioloop *prev_ioloop = current_ioloop; struct io *io; http_server_connection_ref(conn); http_server_request_ref(req); i_assert(server->ioloop == NULL); server->ioloop = io_loop_create(); http_server_connection_switch_ioloop(conn); if (blocking && req->req.expect_100_continue && !req->sent_100_continue) http_server_connection_trigger_responses(conn); hsristream->read_status = 0; io = io_add_istream(&stream->istream, http_server_istream_read_any, hsristream); while (req->state < HTTP_SERVER_REQUEST_STATE_FINISHED && hsristream->read_status == 0) { io_loop_run(server->ioloop); } io_remove(&io); io_loop_set_current(prev_ioloop); http_server_connection_switch_ioloop(conn); io_loop_set_current(server->ioloop); io_loop_destroy(&server->ioloop); ret = hsristream->read_status; if (!http_server_request_unref(&req)) hsristream->req = NULL; http_server_connection_unref(&conn); } return ret; }