static void wd_control_accept_thread(wi_runtime_instance_t *argument) { wi_pool_t *pool; wi_socket_t *socket = argument; wi_string_t *ip; wd_user_t *user; pool = wi_pool_init(wi_pool_alloc()); ip = wi_address_string(wi_socket_address(socket)); if(!wi_socket_accept_tls(socket, wd_control_socket_tls, 30.0)) { wi_log_err(WI_STR("Could not accept a TLS connection for %@: %m"), ip); goto end; } if(!wi_socket_set_timeout(socket, 30.0)) wi_log_warn(WI_STR("Could not set timeout for %@: %m"), ip); wi_socket_set_direction(socket, WI_SOCKET_READ); wi_log_info(WI_STR("Connect from %@"), ip); user = wd_user_with_socket(socket); wd_users_add_user(user); wd_users_set_user_for_thread(user); wd_command_loop_for_user(user); end: wi_socket_close(socket); wi_release(pool); }
void wr_disconnect(void) { wr_runloop_remove_socket(wr_socket); wi_socket_close(wr_socket); wi_release(wr_socket); if(wr_connected) { wr_wprintf_prefix(wr_console_window, WI_STR("Connection to %@ closed"), wr_host); } wi_release(wr_server); wi_release(wr_host); wi_release(wr_login); wi_release(wr_password); wi_release(wr_address); wr_windows_clear(); wr_chats_clear(); wr_files_clear(); wr_transfers_clear(); wr_users_clear(); wr_connected = false; wr_logged_in = false; wr_draw_header(); wr_draw_divider(); }
void wr_transfer_close(wr_transfer_t *transfer) { wi_string_t *local_path, *path; if(transfer->type == WR_TRANSFER_DOWNLOAD && transfer->state == WR_TRANSFER_FINISHED) { local_path = wi_array_first_data(transfer->local_paths); path = wi_string_by_deleting_path_extension(local_path); wi_fs_rename_path(local_path, path); } wi_mutable_array_remove_data_at_index(transfer->remote_paths, 0); wi_mutable_array_remove_data_at_index(transfer->local_paths, 0); wi_mutable_array_remove_data_at_index(transfer->files, 0); if(transfer->file) { wi_file_close(transfer->file); wi_release(transfer->file); transfer->file = NULL; } wi_release(transfer->key); transfer->key = NULL; wi_release(transfer->checksum); transfer->checksum = NULL; if(transfer->socket) { wr_runloop_remove_socket(transfer->socket); wi_socket_close(transfer->socket); wi_release(transfer->socket); transfer->socket = NULL; } }
static void _wi_socket_dealloc(wi_runtime_instance_t *instance) { wi_socket_t *socket = instance; wi_socket_close(socket); wi_release(socket->address); wi_release(socket->buffer); }
static void wd_transfer_accept_thread(wi_runtime_instance_t *argument) { wi_pool_t *pool; wi_socket_t *socket = argument; wi_array_t *arguments; wi_string_t *ip, *string, *command; wd_transfer_t *transfer; pool = wi_pool_init(wi_pool_alloc()); ip = wi_address_string(wi_socket_address(socket)); if(!wi_socket_accept_tls(socket, wd_transfer_socket_tls, 30.0)) { wi_log_err(WI_STR("Could not accept a connection for %@: %m"), ip); goto end; } if(!wi_socket_set_timeout(socket, 30.0)) wi_log_warn(WI_STR("Could not set timeout for %@: %m"), ip); string = wi_socket_read_to_string(socket, 5.0, WI_STR(WD_MESSAGE_SEPARATOR_STR)); if(!string || wi_string_length(string) == 0) { if(!string) wi_log_warn(WI_STR("Could not read from %@: %m"), ip); goto end; } wi_parse_wired_command(string, &command, &arguments); if(wi_is_equal(command, WI_STR("TRANSFER")) && wi_array_count(arguments) >= 1) { transfer = wd_transfers_transfer_with_hash(WI_ARRAY(arguments, 0)); if(!transfer) goto end; if(!wi_is_equal(ip, wd_user_ip(transfer->user))) goto end; wi_lock_lock(transfer->socket_lock); if(!transfer->socket) { transfer->socket = wi_retain(socket); wi_lock_unlock(transfer->socket_lock); wd_transfer_loop(transfer); } else { wi_lock_unlock(transfer->socket_lock); } } end: wi_socket_close(socket); wi_release(pool); }
void wr_client_disconnect(void) { if(wr_connected) { wi_log_info(WI_STR("Connection to %@ closed"), wi_address_string(wi_socket_address(wr_socket))); wr_connected = false; } wr_runloop_remove_socket(wr_socket); wi_socket_close(wr_socket); wi_release(wr_p7_socket); wi_release(wr_socket); wi_release(wr_server); wi_release(wr_password); wr_chats_clear(); wr_users_clear(); }
void wr_client_disconnect(void) { if(wr_connected) { wr_wprintf_prefix(wr_console_window, WI_STR("Connection to %@ closed"), wi_address_string(wi_socket_address(wr_socket))); wr_connected = false; } wr_runloop_remove_socket(wr_socket); wi_socket_close(wr_socket); wi_release(wr_p7_socket); wi_release(wr_socket); wi_release(wr_server); wi_release(wr_password); wr_windows_clear(); wr_chats_clear(); wr_users_clear(); wr_draw_header(); wr_draw_divider(); }
void wd_control_thread(wi_runtime_instance_t *argument) { wi_pool_t *pool; wd_client_t *client = argument; wi_string_t *string; unsigned int i = 0; int state; pool = wi_pool_init(wi_pool_alloc()); wd_clients_add_client(client); wd_client_set(client); while(client->state <= WD_CLIENT_STATE_LOGGED_IN) { if(!pool) pool = wi_pool_init(wi_pool_alloc()); if(client->buffer_offset == 0) { do { state = wi_socket_wait(client->socket, 0.1); } while(state == 0 && client->state <= WD_CLIENT_STATE_LOGGED_IN); if(client->state > WD_CLIENT_STATE_LOGGED_IN) { /* invalid state */ break; } if(state < 0) { if(wi_error_code() == EINTR) { /* got a signal */ continue; } else { /* error in TCP communication */ wi_log_err(WI_STR("Could not read from %@: %m"), client->ip); break; } } } wd_client_lock_socket(client); string = wi_socket_read_to_string(client->socket, 0.0, WI_STR(WD_MESSAGE_SEPARATOR_STR)); wd_client_unlock_socket(client); if(!string || wi_string_length(string) == 0) { if(!string) wi_log_info(WI_STR("Could not read from %@: %m"), client->ip); break; } wd_parse_command(string); if(++i % 10 == 0) { wi_release(pool); pool = NULL; } } /* announce parting if client disconnected by itself */ if(client->state == WD_CLIENT_STATE_LOGGED_IN) { client->state = WD_CLIENT_STATE_DISCONNECTED; wd_broadcast_lock(); wd_client_broadcast_leave(client, WD_PUBLIC_CID); wd_broadcast_unlock(); } /* update status for clients logged in and above */ if(client->state >= WD_CLIENT_STATE_LOGGED_IN) { wi_lock_lock(wd_status_lock); wd_current_users--; wd_write_status(true); wi_lock_unlock(wd_status_lock); } wi_log_info(WI_STR("Disconnect from %@"), client->ip); wi_socket_close(client->socket); wd_clients_remove_client(client); wi_release(pool); }