static wi_boolean_t wd_transfers_run_download(wd_transfer_t *transfer, wd_user_t *user, wi_p7_message_t *message) { wi_p7_message_t *reply; wi_data_t *data; wi_p7_uint32_t transaction; wi_boolean_t result; data = wi_fs_finder_info_for_path(transfer->realdatapath); reply = wi_p7_message_with_name(WI_STR("wired.transfer.download"), wd_p7_spec); wi_p7_message_set_string_for_name(reply, transfer->path, WI_STR("wired.file.path")); wi_p7_message_set_oobdata_for_name(reply, transfer->remainingdatasize, WI_STR("wired.transfer.data")); wi_p7_message_set_oobdata_for_name(reply, transfer->remainingrsrcsize, WI_STR("wired.transfer.rsrc")); wi_p7_message_set_data_for_name(reply, data ? data : wi_data(), WI_STR("wired.transfer.finderinfo")); if(wi_p7_message_get_uint32_for_name(message, &transaction, WI_STR("wired.transaction"))) wi_p7_message_set_uint32_for_name(reply, transaction, WI_STR("wired.transaction")); if(!wd_user_write_message(user, 30.0, reply)) { wi_log_error(WI_STR("Could not write message \"%@\" to %@: %m"), wi_p7_message_name(reply), wd_user_identifier(user)); return false; } wi_socket_set_interactive(wd_user_socket(user), false); result = wd_transfer_download(transfer); wi_socket_set_interactive(wd_user_socket(user), true); if(transfer->transferred == transfer->datasize + transfer->rsrcsize) wd_accounts_add_download_statistics(wd_user_account(user), true, transfer->actualtransferred); else wd_accounts_add_download_statistics(wd_user_account(user), false, transfer->actualtransferred); return result; }
static void wr_msg_400(wi_array_t *arguments) { wi_address_t *address; wr_transfer_t *transfer; transfer = wr_transfers_transfer_with_path(WI_ARRAY(arguments, 0)); if(!transfer) return; address = wi_copy(wr_address); wi_address_set_port(address, wi_address_port(address) + 1); transfer->state = WR_TRANSFER_RUNNING; transfer->offset = wi_string_uint64(WI_ARRAY(arguments, 1)); transfer->transferred = transfer->offset; transfer->key = wi_retain(WI_ARRAY(arguments, 2)); transfer->start_time = wi_time_interval(); transfer->socket = wi_socket_init_with_address(wi_socket_alloc(), address, WI_SOCKET_TCP); wi_socket_set_interactive(transfer->socket, false); if(!wi_socket_connect(transfer->socket, wr_socket_context, 15.0)) { wr_printf_prefix(WI_STR("Could not connect to %@: %m"), wi_address_string(address)); wr_transfer_stop(transfer); goto end; } wi_file_seek(transfer->file, transfer->offset); if(transfer->type == WR_TRANSFER_DOWNLOAD) { wi_socket_set_direction(transfer->socket, WI_SOCKET_READ); wr_runloop_add_socket(transfer->socket, wr_runloop_download_callback); } else { wi_socket_set_direction(transfer->socket, WI_SOCKET_WRITE); wr_runloop_add_socket(transfer->socket, wr_runloop_upload_callback); } wr_send_command_on_socket(transfer->socket, WI_STR("TRANSFER %#@"), transfer->key); wr_printf_prefix(WI_STR("Starting transfer of \"%@\""), transfer->name); wr_draw_transfers(true); end: wi_release(address); }
static wi_boolean_t wd_transfers_run_upload(wd_transfer_t *transfer, wd_user_t *user, wi_p7_message_t *message) { wi_p7_message_t *reply; wi_string_t *path; wi_p7_uint32_t transaction; wi_boolean_t result; reply = wi_p7_message_with_name(WI_STR("wired.transfer.upload_ready"), wd_p7_spec); wi_p7_message_set_string_for_name(reply, transfer->path, WI_STR("wired.file.path")); wi_p7_message_set_oobdata_for_name(reply, transfer->dataoffset, WI_STR("wired.transfer.data_offset")); wi_p7_message_set_oobdata_for_name(reply, transfer->rsrcoffset, WI_STR("wired.transfer.rsrc_offset")); if(wi_p7_message_get_uint32_for_name(message, &transaction, WI_STR("wired.transaction"))) wi_p7_message_set_uint32_for_name(reply, transaction, WI_STR("wired.transaction")); if(!wd_user_write_message(user, 30.0, reply)) { wi_log_error(WI_STR("Could not write message \"%@\" to %@: %m"), wi_p7_message_name(reply), wd_user_identifier(user)); return false; } reply = wd_user_read_message(user, 30.0); if(!reply) { wi_log_warn(WI_STR("Could not read message from %@ while waiting for upload: %m"), wd_user_identifier(user)); return false; } if(!wi_p7_spec_verify_message(wd_p7_spec, reply)) { wi_log_error(WI_STR("Could not verify message from %@ while waiting for upload: %m"), wd_user_identifier(user)); wd_user_reply_error(user, WI_STR("wired.error.invalid_message"), reply); return false; } if(!wi_is_equal(wi_p7_message_name(reply), WI_STR("wired.transfer.upload"))) { wi_log_error(WI_STR("Could not accept message %@ from %@: Expected \"wired.transfer.upload\""), wi_p7_message_name(reply), wd_user_identifier(user)); wd_user_reply_error(user, WI_STR("wired.error.invalid_message"), reply); return false; } wi_p7_message_get_uint64_for_name(reply, &transfer->remainingdatasize, WI_STR("wired.transfer.data")); wi_p7_message_get_uint64_for_name(reply, &transfer->remainingrsrcsize, WI_STR("wired.transfer.rsrc")); transfer->finderinfo = wi_retain(wi_p7_message_data_for_name(reply, WI_STR("wired.transfer.finderinfo"))); wi_socket_set_interactive(wd_user_socket(user), false); result = wd_transfer_upload(transfer); wi_socket_set_interactive(wd_user_socket(user), true); if(transfer->transferred == transfer->datasize + transfer->rsrcsize) { path = wi_string_by_deleting_path_extension(transfer->realdatapath); if(wi_fs_rename_path(transfer->realdatapath, path)) { if(transfer->executable) { if(!wi_fs_set_mode_for_path(path, 0755)) wi_log_error(WI_STR("Could not set mode for \"%@\": %m"), path); } wd_files_move_comment(transfer->realdatapath, path, NULL, NULL); wd_files_move_label(transfer->realdatapath, path, NULL, NULL); if(wi_data_length(transfer->finderinfo) > 0) wi_fs_set_finder_info_for_path(transfer->finderinfo, path); wd_index_add_file(path); } else { wi_log_error(WI_STR("Could not move \"%@\" to \"%@\": %m"), transfer->realdatapath, path); } wd_accounts_add_upload_statistics(wd_user_account(user), true, transfer->actualtransferred); } else { wd_accounts_add_upload_statistics(wd_user_account(user), false, transfer->actualtransferred); } return result; }
void wd_server_init(void) { wi_enumerator_t *enumerator; wi_array_t *array, *addresses; wi_address_t *address; wi_socket_t *control_socket, *transfer_socket; wi_string_t *ip, *string; wi_address_family_t family; wd_control_sockets = wi_array_init(wi_mutable_array_alloc()); wd_transfer_sockets = wi_array_init(wi_mutable_array_alloc()); addresses = wi_array_init(wi_mutable_array_alloc()); if(wi_array_count(wd_settings.address) > 0) { /* listen on configured addresses */ wi_array_rdlock(wd_settings.address); enumerator = wi_array_data_enumerator(wd_settings.address); while((string = wi_enumerator_next_data(enumerator))) { array = wi_host_addresses(wi_host_with_string(string)); if(array) wi_mutable_array_add_data_from_array(addresses, array); else wi_log_err(WI_STR("Could not resolve \"%@\": %m"), string); } wi_array_unlock(wd_settings.address); } else { /* add wildcard addresses */ wi_mutable_array_add_data(addresses, wi_address_wildcard_for_family(WI_ADDRESS_IPV6)); wi_mutable_array_add_data(addresses, wi_address_wildcard_for_family(WI_ADDRESS_IPV4)); } enumerator = wi_array_data_enumerator(addresses); while((address = wi_enumerator_next_data(enumerator))) { ip = wi_address_string(address); family = wi_address_family(address); /* force address family? */ if(wd_address_family != WI_ADDRESS_NULL && family != wd_address_family) continue; /* create sockets */ wi_address_set_port(address, wd_settings.port); control_socket = wi_autorelease(wi_socket_init_with_address(wi_socket_alloc(), address, WI_SOCKET_TCP)); wi_address_set_port(address, wd_settings.port + 1); transfer_socket = wi_autorelease(wi_socket_init_with_address(wi_socket_alloc(), address, WI_SOCKET_TCP)); if(!control_socket || !transfer_socket) { wi_log_warn(WI_STR("Could not create socket for %@: %m"), ip); continue; } /* listen on sockets */ if(!wi_socket_listen(control_socket)) { wi_log_warn(WI_STR("Could not listen on %@ port %u: %m"), ip, wi_address_port(wi_socket_address(control_socket))); continue; } if(!wi_socket_listen(transfer_socket)) { wi_log_warn(WI_STR("Could not listen on %@ port %u: %m"), ip, wi_address_port(wi_socket_address(transfer_socket))); continue; } wi_socket_set_interactive(control_socket, true); wi_socket_set_interactive(transfer_socket, false); /* add to list of sockets */ wi_mutable_array_add_data(wd_control_sockets, control_socket); wi_mutable_array_add_data(wd_transfer_sockets, transfer_socket); wi_log_info(WI_STR("Listening on %@ ports %d-%d"), ip, wd_settings.port, wd_settings.port + 1); } if(wi_array_count(wd_control_sockets) == 0 || wi_array_count(wd_transfer_sockets) == 0) wi_log_fatal(WI_STR("No addresses available for listening")); wi_release(addresses); #ifdef HAVE_DNS_SD_H if(wd_settings.zeroconf) wd_server_register_dnssd(); #endif }
void wr_client_connect(wi_string_t *hostname, wi_uinteger_t port, wi_string_t *login, wi_string_t *password) { wi_enumerator_t *enumerator; wi_array_t *addresses; wi_address_t *address; wi_p7_socket_t *p7_socket; wi_p7_message_t *message; wi_socket_t *socket; wi_string_t *ip; wr_server_t *server; if(wr_connected) wr_client_disconnect(); wr_printf_prefix(WI_STR("Connecting to %@..."), hostname); if(port == 0) port = WR_PORT; if(!login) login = WI_STR("guest"); if(!password) password = WI_STR(""); addresses = wi_host_addresses(wi_host_with_string(hostname)); if(!addresses) { wr_printf_prefix(WI_STR("Could not resolve \"%@\": %m"), hostname); return; } enumerator = wi_array_data_enumerator(addresses); while((address = wi_enumerator_next_data(enumerator))) { ip = wi_address_string(address); wr_printf_prefix(WI_STR("Trying %@ at port %u..."), ip, port); wi_address_set_port(address, port); socket = wi_autorelease(wi_socket_init_with_address(wi_socket_alloc(), address, WI_SOCKET_TCP)); if(!socket) { wr_printf_prefix(WI_STR("Could not open a socket to %@: %m"), ip); continue; } wi_socket_set_interactive(socket, true); if(!wi_socket_connect(socket, 10.0)) { wr_printf_prefix(WI_STR("Could not connect to %@: %m"), ip); continue; } p7_socket = wi_autorelease(wi_p7_socket_init_with_socket(wi_p7_socket_alloc(), socket, wr_p7_spec)); if(!wi_p7_socket_connect(p7_socket, 10.0, WI_P7_COMPRESSION_DEFLATE | WI_P7_ENCRYPTION_RSA_AES256_SHA1 | WI_P7_CHECKSUM_SHA1, WI_P7_BINARY, login, wi_string_sha1(password))) { wr_printf_prefix(WI_STR("Could not connect to %@: %m"), ip); continue; } wr_printf_prefix(WI_STR("Connected using %@/%u bits, logging in..."), wi_cipher_name(wi_p7_socket_cipher(p7_socket)), wi_cipher_bits(wi_p7_socket_cipher(p7_socket))); server = wr_client_login(p7_socket, login, password); if(!server) break; wr_printf_prefix(WI_STR("Logged in, welcome to %@"), wr_server_name(server)); message = wi_p7_message_with_name(WI_STR("wired.chat.join_chat"), wr_p7_spec); wi_p7_message_set_uint32_for_name(message, wr_chat_id(wr_public_chat), WI_STR("wired.chat.id")); wr_client_write_message(p7_socket, message); wr_connected = true; wr_socket = wi_retain(socket); wr_p7_socket = wi_retain(p7_socket); wr_server = wi_retain(server); wr_password = wi_retain(password); wi_socket_set_direction(wr_socket, WI_SOCKET_READ); wr_runloop_add_socket(wr_socket, &wr_runloop_server_callback); break; } wr_draw_divider(); }
void wr_connect(wi_string_t *hostname, wi_uinteger_t port, wi_string_t *login, wi_string_t *password) { wi_enumerator_t *enumerator; wi_array_t *addresses; wi_address_t *address; wi_socket_t *socket; wi_string_t *ip; if(wr_connected) wr_disconnect(); wr_printf_prefix(WI_STR("Connecting to %@..."), hostname); if(port == 0) port = WR_CONTROL_PORT; addresses = wi_host_addresses(wi_host_with_string(hostname)); if(!addresses) { wr_printf_prefix(WI_STR("Could not resolve \"%@\": %m"), hostname); return; } enumerator = wi_array_data_enumerator(addresses); while((address = wi_enumerator_next_data(enumerator))) { ip = wi_address_string(address); wr_printf_prefix(WI_STR("Trying %@ at port %u..."), ip, port); wi_address_set_port(address, port); socket = wi_autorelease(wi_socket_init_with_address(wi_socket_alloc(), address, WI_SOCKET_TCP)); if(!socket) { wr_printf_prefix(WI_STR("Could not open a socket to %@: %m"), ip); continue; } wi_socket_set_interactive(socket, true); if(!wi_socket_connect(socket, 10.0)) { wr_printf_prefix(WI_STR("Could not connect to %@: %m"), ip); continue; } if(!wi_socket_connect_tls(socket, wr_socket_tls, 10.0)) { wr_printf_prefix(WI_STR("Could not connect to %@: %m"), ip); continue; } wr_printf_prefix(WI_STR("Connected using %@/%@/%u bits, logging in..."), wi_socket_cipher_version(socket), wi_socket_cipher_name(socket), wi_socket_cipher_bits(socket)); wr_connected = true; wr_host = wi_retain(hostname); wr_port = port; wr_login = wi_retain(login); wr_password = wi_retain(password); wr_socket = wi_retain(socket); wr_address = wi_retain(address); wr_runloop_add_socket(wr_socket, &wr_runloop_server_callback); wr_send_command(WI_STR("HELLO")); break; } if(wr_socket) wi_socket_set_direction(wr_socket, WI_SOCKET_READ); }
void wr_connect(wi_string_t *hostname, unsigned int port, wi_string_t *login, wi_string_t *password) { wi_list_t *addresses; wi_list_node_t *node; wi_address_t *address; wi_socket_t *socket; wi_string_t *ip; if(wr_connected) wr_disconnect(); wr_printf_prefix(WI_STR("Connecting to %@..."), hostname); if(port == 0) port = WR_CONTROL_PORT; addresses = wi_host_addresses(wi_host_with_string(hostname)); if(!addresses) { wr_printf_prefix(WI_STR("Could not resolve \"%@\": %m"), hostname); return; } WI_LIST_FOREACH(addresses, node, address) { ip = wi_address_string(address); wr_printf_prefix(WI_STR("Trying %@..."), ip); wi_address_set_port(address, port); socket = wi_socket_init_with_address(wi_socket_alloc(), address, WI_SOCKET_TCP); wi_socket_set_interactive(socket, true); if(!wi_socket_connect(socket, wr_socket_context, 10.0)) { wr_printf_prefix(WI_STR("Could not connect to %@: %m"), ip); goto next; } wr_printf_prefix(WI_STR("Connected using %@/%@/%u bits, logging in..."), wi_socket_cipher_version(socket), wi_socket_cipher_name(socket), wi_socket_cipher_bits(socket)); wr_connected = true; wr_host = wi_retain(hostname); wr_port = port; wr_login = wi_retain(login); wr_password = wi_retain(password); wr_socket = wi_retain(socket); wr_address = wi_retain(address); wr_runloop_add_socket(wr_socket, &wr_runloop_server_callback); wr_send_command(WI_STR("HELLO")); next: wi_release(socket); if(wr_connected) break; }