static void wr_command_privchat(wi_array_t *arguments) { wi_p7_message_t *message; wi_string_t *nick; wr_user_t *user; if(wi_array_count(arguments) > 0) { nick = WI_ARRAY(arguments, 0); user = wr_chat_user_with_nick(wr_public_chat, nick); if(!user) { wr_printf_prefix(WI_STR("privchat: %@: Client not found"), nick); return; } wr_private_chat_invite_uid = wr_user_id(user); } message = wi_p7_message_with_name(WI_STR("wired.chat.create_chat"), wr_p7_spec); wr_commands_send_message(message, WI_STR("privchat")); }
void wr_transfer_start(wr_transfer_t *transfer) { if(transfer->state == WR_TRANSFER_WAITING) { if(transfer->type == WR_TRANSFER_DOWNLOAD) { wr_stat_state = WR_STAT_TRANSFER; if(wi_array_count(transfer->remote_paths) == 0) { // wr_send_command(WI_STR("STAT %#@"), transfer->master_path); } else { // wr_send_command(WI_STR("STAT %#@"), wi_array_first_data(transfer->remote_paths)); } } else { if(transfer->recursive && !transfer->listed) { wr_ls_state = WR_LS_TRANSFER; wr_files_clear(); // wr_send_command(WI_STR("LISTRECURSIVE %#@"), transfer->master_path); } else { wr_transfer_request(transfer); } } } }
static wi_boolean_t _wi_settings_parse_setting(wi_settings_t *settings, wi_string_t *string) { wi_array_t *array; wi_string_t *name, *value; wi_boolean_t result = false; array = wi_string_components_separated_by_string(string, WI_STR("=")); if(wi_array_count(array) != 2) { wi_error_set_lib_error(WI_ERROR_SETTINGS_SYNTAXERROR); _wi_settings_log_error(settings, string); return false; } name = wi_string_by_deleting_surrounding_whitespace(WI_ARRAY(array, 0)); value = wi_string_by_deleting_surrounding_whitespace(WI_ARRAY(array, 1)); result = _wi_settings_set_value(settings, name, value); if(!result) _wi_settings_log_error(settings, name); return result; }
static void wd_transfers_update_queue(void) { wi_mutable_set_t *users; wi_mutable_array_t *sorted_users, *transfers_queue, *failed_transfers; wd_transfer_t *transfer; wd_user_t *user; wi_uinteger_t position; wi_uinteger_t i, count; wi_uinteger_t total_downloads, total_uploads, user_downloads, user_uploads, active_downloads, active_uploads; wi_boolean_t queue; wi_array_rdlock(wd_transfers); total_downloads = wd_settings.totaldownloads; user_downloads = wd_settings.clientdownloads; total_uploads = wd_settings.totaluploads; user_uploads = wd_settings.clientuploads; active_downloads = 0; active_uploads = 0; failed_transfers = wi_array_init(wi_mutable_array_alloc()); users = wi_set_init(wi_mutable_set_alloc()); count = wi_array_count(wd_transfers); for(i = 0; i < count; i++) { transfer = WI_ARRAY(wd_transfers, i); if(wd_transfer_state(transfer) == WD_TRANSFER_QUEUED) { wi_mutable_array_add_data(wd_user_transfers_queue(transfer->user), transfer); wi_mutable_set_add_data(users, transfer->user); } wd_user_clear_downloads(transfer->user); wd_user_clear_uploads(transfer->user); } for(i = 0; i < count; i++) { transfer = WI_ARRAY(wd_transfers, i); if(wd_transfer_state(transfer) == WD_TRANSFER_RUNNING) { if(transfer->type == WD_TRANSFER_DOWNLOAD) { active_downloads++; wd_user_increase_downloads(transfer->user); } else { active_uploads++; wd_user_increase_uploads(transfer->user); } } } count = wi_set_count(users); if(count > 0) { sorted_users = wi_autorelease(wi_mutable_copy(wi_set_all_data(users))); wi_mutable_array_sort(sorted_users, wd_transfers_compare_user); position = 1; while(count > 0) { for(i = 0; i < count; i++) { user = WI_ARRAY(sorted_users, i); transfers_queue = wd_user_transfers_queue(user); transfer = WI_ARRAY(transfers_queue, 0); if(transfer->type == WD_TRANSFER_DOWNLOAD) { queue = ((total_downloads > 0 && active_downloads >= total_downloads) || (user_downloads > 0 && wd_user_downloads(transfer->user) >= user_downloads)); } else { queue = ((total_uploads > 0 && active_uploads >= total_uploads) || (user_uploads > 0 && wd_user_uploads(transfer->user) >= user_uploads)); } if(queue) { if(transfer->queue != position) { transfer->queue = position; wd_user_lock_socket(transfer->user); wd_sreply(wd_user_socket(transfer->user), 401, WI_STR("%#@%c%u"), transfer->path, WD_FIELD_SEPARATOR, transfer->queue); wd_user_unlock_socket(transfer->user); } position++; } else { transfer->queue = 0; transfer->waiting_time = wi_time_interval(); wd_transfer_set_state(transfer, WD_TRANSFER_WAITING); if(wd_transfer_open(transfer)) { wd_transfer_create_timer(transfer); wd_user_lock_socket(transfer->user); wd_sreply(wd_user_socket(transfer->user), 400, WI_STR("%#@%c%llu%c%#@"), transfer->path, WD_FIELD_SEPARATOR, transfer->offset, WD_FIELD_SEPARATOR, transfer->hash); wd_user_unlock_socket(transfer->user); } else { wd_user_lock_socket(transfer->user); wd_sreply(wd_user_socket(transfer->user), 500, WI_STR("Command Failed")); wd_user_unlock_socket(transfer->user); wi_mutable_array_add_data(failed_transfers, transfer); } } wi_mutable_array_remove_data_at_index(transfers_queue, 0); if(wi_array_count(transfers_queue) == 0) { wi_mutable_array_remove_data_at_index(sorted_users, i); i--; count--; } } } } wi_mutable_array_remove_data_in_array(wd_transfers, failed_transfers); wi_array_unlock(wd_transfers); wi_release(users); wi_release(failed_transfers); }
uint32_t wi_terminal_buffer_lines(wi_terminal_buffer_t *buffer) { return wi_array_count(buffer->linebuffer); }
void wd_transfers_remove_user(wd_user_t *user, wi_boolean_t removingallusers) { wi_enumerator_t *enumerator; wi_string_t *key; wd_user_t *each_user; wd_transfer_t *transfer; wi_uinteger_t i, count; wi_boolean_t update = false, present = false; key = wd_transfers_transfer_key_for_user(user); if(!key) return; if(!removingallusers) { wi_dictionary_rdlock(wd_users); enumerator = wi_dictionary_data_enumerator(wd_users); while((each_user = wi_enumerator_next_data(enumerator))) { if(wd_user_state(each_user) == WD_USER_LOGGED_IN && wi_is_equal(wd_transfers_transfer_key_for_user(each_user), key)) { present = true; break; } } wi_dictionary_unlock(wd_users); } if(!present) { wi_array_wrlock(wd_transfers); count = wi_array_count(wd_transfers); for(i = 0; i < count; i++) { transfer = WI_ARRAY(wd_transfers, i); if(wi_is_equal(key, transfer->key)) { wd_user_set_state(transfer->user, WD_USER_DISCONNECTED); if(transfer->state == WD_TRANSFER_RUNNING) { if(wi_condition_lock_lock_when_condition(transfer->finished_lock, 1, 1.0)) wi_condition_lock_unlock(transfer->finished_lock); } else { wi_mutable_array_remove_data_at_index(wd_transfers, i); i--; count--; update = true; } } } if(update) { wi_condition_lock_lock(wd_transfers_queue_lock); wi_condition_lock_unlock_with_condition(wd_transfers_queue_lock, 1); } wi_array_unlock(wd_transfers); } }
static void wd_transfers_queue_thread(wi_runtime_instance_t *argument) { wi_pool_t *pool; wi_enumerator_t *enumerator; wi_mutable_dictionary_t *key_queues; wi_mutable_array_t *key_queue, *keys; wi_string_t *key; wd_transfer_t *transfer; wd_account_t *account; wi_uinteger_t user_downloads, user_uploads, user_transfers; wi_uinteger_t new_position, position, queue, i, count, longest_queue; pool = wi_pool_init(wi_pool_alloc()); key_queues = wi_dictionary_init(wi_mutable_dictionary_alloc()); while(true) { wi_mutable_dictionary_remove_all_data(key_queues); wi_condition_lock_lock_when_condition(wd_transfers_queue_lock, 1, 0.0); wi_array_rdlock(wd_transfers); longest_queue = 0; enumerator = wi_array_data_enumerator(wd_transfers); while((transfer = wi_enumerator_next_data(enumerator))) { wi_condition_lock_lock(transfer->queue_lock); if(transfer->state == WD_TRANSFER_QUEUED && transfer->queue != 0) { key_queue = wi_dictionary_data_for_key(key_queues, transfer->key); if(!key_queue) { key_queue = wi_mutable_array(); wi_mutable_dictionary_set_data_for_key(key_queues, key_queue, transfer->key); } wi_mutable_array_add_data(key_queue, transfer); if(wi_array_count(key_queue) > longest_queue) longest_queue = wi_array_count(key_queue); } wi_condition_lock_unlock(transfer->queue_lock); } keys = wi_autorelease(wi_mutable_copy(wi_dictionary_keys_sorted_by_value(key_queues, wd_transfers_queue_compare))); position = 1; count = wi_array_count(keys); while(longest_queue > 0) { for(i = 0; i < count; i++) { key = WI_ARRAY(keys, i); key_queue = wi_dictionary_data_for_key(key_queues, key); if(wi_array_count(key_queue) > 0) { transfer = WI_ARRAY(key_queue, 0); account = wd_user_account(transfer->user); wi_lock_lock(wd_transfers_status_lock); if(transfer->type == WD_TRANSFER_DOWNLOAD) { wi_dictionary_rdlock(wd_transfers_user_downloads); user_downloads = wd_account_transfer_download_limit(account); user_transfers = (wi_integer_t) wi_dictionary_data_for_key(wd_transfers_user_downloads, transfer->key); queue = ((wd_transfers_total_downloads > 0 && wd_transfers_active_downloads >= wd_transfers_total_downloads) || (user_downloads > 0 && user_transfers >= user_downloads)); wi_dictionary_unlock(wd_transfers_user_downloads); } else { wi_dictionary_rdlock(wd_transfers_user_uploads); user_uploads = wd_account_transfer_upload_limit(account); user_transfers = (wi_integer_t) wi_dictionary_data_for_key(wd_transfers_user_uploads, transfer->key); queue = ((wd_transfers_total_uploads > 0 && wd_transfers_active_uploads >= wd_transfers_total_uploads) || (user_uploads > 0 && user_transfers >= user_uploads)); wi_dictionary_unlock(wd_transfers_user_uploads); } wi_lock_unlock(wd_transfers_status_lock); if(queue) new_position = position++; else new_position = 0; if(new_position != (wi_uinteger_t) transfer->queue) { if(new_position == 0) wd_transfers_add_or_remove_transfer(transfer, true); wi_condition_lock_lock(transfer->queue_lock); transfer->queue = new_position; wi_condition_lock_unlock_with_condition(transfer->queue_lock, 1); } wi_mutable_array_remove_data_at_index(key_queue, 0); } } longest_queue--; } wi_array_unlock(wd_transfers); wi_condition_lock_unlock_with_condition(wd_transfers_queue_lock, 0); wi_pool_drain(pool); } wi_release(key_queues); wi_release(pool); }
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 }
static void wd_transfer_listen_thread(wi_runtime_instance_t *argument) { wi_pool_t *pool; wi_socket_t *socket; wi_address_t *address; wi_array_t *arguments; wi_string_t *ip, *string, *command; wd_transfer_t *transfer; pool = wi_pool_init(wi_pool_alloc()); while(wd_running) { wi_pool_drain(pool); /* accept new connection */ socket = wi_socket_accept_multiple(wd_transfer_sockets, wd_transfer_socket_context, 30.0, &address); if(!address) { wi_log_err(WI_STR("Could not accept a connection: %m")); continue; } ip = wi_address_string(address); if(!socket) { wi_log_err(WI_STR("Could not accept a connection for %@: %m"), ip); continue; } 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); continue; } /* parse command */ wi_parse_wired_command(string, &command, &arguments); if(wi_is_equal(command, WI_STR("TRANSFER")) && wi_array_count(arguments) >= 1) { /* get transfer by identifier */ transfer = wd_transfers_transfer_with_hash(WI_ARRAY(arguments, 0)); if(!transfer) continue; if(!wi_is_equal(ip, wd_user_ip(transfer->user))) continue; transfer->socket = wi_retain(socket); /* spawn a transfer thread */ if(!wi_thread_create_thread(wd_transfer_thread, transfer)) wi_log_err(WI_STR("Could not create a thread for %@: %m"), ip); } } wi_release(pool); }
wi_boolean_t wi_p7_message_set_list_for_name(wi_p7_message_t *p7_message, wi_array_t *list, wi_string_t *field_name) { wi_runtime_instance_t *instance; unsigned char *binary; wi_runtime_id_t first_id, id; wi_uinteger_t i, count, offset; uint32_t field_id, field_size, string_size; count = wi_array_count(list); field_size = 0; if(count > 0) { first_id = wi_runtime_id(wi_array_first_data(list)); for(i = 0; i < count; i++) { instance = WI_ARRAY(list, i); id = wi_runtime_id(instance); if(id != first_id) { wi_error_set_libwired_error_with_format(WI_ERROR_P7_UNKNOWNFIELD, WI_STR("Mixed types in list")); return false; } if(id == wi_string_runtime_id()) { field_size += 4 + wi_string_length(instance) + 1; } else { wi_error_set_libwired_error_with_format(WI_ERROR_P7_UNKNOWNFIELD, WI_STR("Unhandled type %@ in list"), wi_runtime_class_name(instance)); return false; } } } if(!_wi_p7_message_get_binary_buffer_for_writing_for_name(p7_message, field_name, field_size, &binary, &field_id)) return false; wi_write_swap_host_to_big_int32(binary, 0, field_id); wi_write_swap_host_to_big_int32(binary, 4, field_size); offset = 8; for(i = 0; i < count; i++) { instance = WI_ARRAY(list, i); if(wi_runtime_id(instance) == wi_string_runtime_id()) { string_size = wi_string_length(instance) + 1; wi_write_swap_host_to_big_int32(binary, offset, string_size); offset += 4; memcpy(binary + offset, wi_string_cstring(instance), string_size); offset += string_size; } } return true; }
static void wr_msg_308(wi_array_t *arguments) { wi_enumerator_t *enumerator; wi_date_t *date; wi_array_t *array, *transfers; wi_string_t *string, *interval, *name, *transferred, *size, *speed; wi_uinteger_t n; wi_boolean_t first; wr_printf_prefix(WI_STR("User info:"), WI_ARRAY(arguments, 4)); wr_printf_block(WI_STR("Nick: %@"), WI_ARRAY(arguments, 4)); if(wr_server->protocol >= 1.1) wr_printf_block(WI_STR("Status: %@"), WI_ARRAY(arguments, 15)); wr_printf_block(WI_STR("Login: %@"), WI_ARRAY(arguments, 5)); wr_printf_block(WI_STR("ID: %@"), WI_ARRAY(arguments, 0)); wr_printf_block(WI_STR("Address: %@"), WI_ARRAY(arguments, 6)); wr_printf_block(WI_STR("Host: %@"), WI_ARRAY(arguments, 7)); wr_printf_block(WI_STR("Client: %@"), WI_ARRAY(arguments, 8)); wr_printf_block(WI_STR("Cipher: %@/%@ bits"), WI_ARRAY(arguments, 9), WI_ARRAY(arguments, 10)); date = wi_date_with_rfc3339_string(WI_ARRAY(arguments, 11)); interval = wi_time_interval_string(wi_date_time_interval_since_now(date)); string = wi_date_string_with_format(date, WI_STR("%a %b %e %T %Y")); wr_printf_block(WI_STR("Login Time: %@, since %@"), interval, string); date = wi_date_with_rfc3339_string(WI_ARRAY(arguments, 12)); interval = wi_time_interval_string(wi_date_time_interval_since_now(date)); string = wi_date_string_with_format(date, WI_STR("%a %b %e %T %Y")); wr_printf_block(WI_STR("Idle Time: %@, since %@"), interval, string); for(n = WR_TRANSFER_DOWNLOAD; n <= WR_TRANSFER_UPLOAD; n++) { string = WI_ARRAY(arguments, (n == WR_TRANSFER_DOWNLOAD) ? 13 : 14); transfers = wi_string_components_separated_by_string(string, WI_STR(WR_GROUP_SEPARATOR_STR)); enumerator = wi_array_data_enumerator(transfers); first = true; while((string = wi_enumerator_next_data(enumerator))) { array = wi_string_components_separated_by_string(string, WI_STR(WR_RECORD_SEPARATOR_STR)); if(wi_array_count(array) == 4) { name = wi_string_last_path_component(WI_ARRAY(array, 0)); transferred = wr_files_string_for_size(wi_string_uint64(WI_ARRAY(array, 1))); size = wr_files_string_for_size(wi_string_uint64(WI_ARRAY(array, 2))); speed = wr_files_string_for_size(wi_string_uint32(WI_ARRAY(array, 3))); if(first) { if(n == WR_TRANSFER_DOWNLOAD) { wr_printf_block(WI_STR("Downloads: %@, %@ of %@, %@/s"), name, transferred, size, speed); } else { wr_printf_block(WI_STR("Uploads: %@, %@ of %@, %@/s"), name, transferred, size, speed); } } else { wr_printf_block(WI_STR(" %@, %@ of %@, %@/s"), name, transferred, size, speed); } } first = false; } } }
static void wr_command_open(wi_array_t *arguments) { wi_mutable_array_t *argv; wi_string_t *login, *password, *host; wi_url_t *url; const char **xargv; wi_uinteger_t port; int ch; url = NULL; login = NULL; password = NULL; port = 0; argv = wi_autorelease(wi_mutable_copy(arguments)); wi_mutable_array_insert_data_at_index(argv, WI_STR("open"), 0); xargv = wi_array_create_argv(argv); wi_getopt_reset(); while((ch = getopt(wi_array_count(argv), (char **) xargv, "hl:P:p:")) != -1) { switch(ch) { case 'l': login = wi_string_with_cstring(optarg); break; case 'P': port = wi_string_uinteger(wi_string_with_cstring(optarg)); break; case 'p': password = wi_string_with_cstring(optarg); break; case '?': case 'h': default: wr_commands_print_usage_for_command(WI_STR("open")); return; break; } } wi_array_destroy_argv(wi_array_count(argv), xargv); if((wi_uinteger_t) optind >= wi_array_count(argv)) { wr_commands_print_usage_for_command(WI_STR("open")); return; } url = wi_autorelease(wi_url_init_with_string(wi_url_alloc(), WI_ARRAY(argv, optind))); host = wi_url_host(url); if(port == 0) port = wi_url_port(url); if(wi_string_length(host) == 0) { wr_commands_print_usage_for_command(WI_STR("open")); return; } wr_client_connect(host, port, login, password); }
static void wr_command_timestamp(wi_array_t *arguments) { if(wi_array_count(arguments) == 0) wr_windows_set_timestamp_format(WI_STR("")); else wr_windows_set_timestamp_format(WI_ARRAY(arguments, 0)); }
void wr_transfer_request(wr_transfer_t *transfer) { wi_string_t *local_path; wi_fs_stat_t sb; if(wi_array_count(transfer->local_paths) == 0) { wr_transfer_start_next_or_stop(transfer); return; } if(transfer->type == WR_TRANSFER_DOWNLOAD) { local_path = wi_array_first_data(transfer->local_paths); if(wi_fs_stat_path(local_path, &sb)) { if(!transfer->recursive) { wr_printf_prefix(WI_STR("get: File already exists at %@"), local_path); } wr_transfer_close(transfer); if(transfer->recursive) { transfer->total_transferred += sb.size; wr_transfer_start_next_or_stop(transfer); } return; } if(!wi_string_has_suffix(local_path, WI_STR(WR_TRANSFERS_SUFFIX))) { local_path = wi_string_by_appending_string(local_path, WI_STR(WR_TRANSFERS_SUFFIX)); wi_mutable_array_replace_data_at_index(transfer->local_paths, local_path, 0); } if(wi_fs_stat_path(local_path, &sb)) { transfer->file_offset = sb.size; if(sb.size >= WR_CHECKSUM_SIZE) transfer->checksum = wi_retain(wi_fs_sha1_for_path(local_path, WR_CHECKSUM_SIZE)); } transfer->file = wi_retain(wi_file_for_updating(local_path)); if(!transfer->file) { wr_printf_prefix(WI_STR("get: Could not open %@: %m"), local_path); wr_transfer_close(transfer); if(transfer->recursive) wr_transfer_start_next_or_stop(transfer); return; } transfer->file_size = wr_file_size(wi_array_first_data(transfer->files)); // wr_send_command(WI_STR("GET %#@%c%llu"), // wi_array_first_data(transfer->remote_paths), WR_FIELD_SEPARATOR, // transfer->file_offset); } else { local_path = wi_array_first_data(transfer->local_paths); transfer->file = wi_retain(wi_file_for_reading(local_path)); if(!transfer->file) { wr_printf_prefix(WI_STR("put: Could not open %@: %m"), local_path); wr_transfer_close(transfer); if(transfer->recursive) wr_transfer_start_next_or_stop(transfer); return; } if(!wi_fs_stat_path(local_path, &sb)) { wr_printf_prefix(WI_STR("put: Could not open %@: %m"), local_path); wr_transfer_close(transfer); if(transfer->recursive) wr_transfer_start_next_or_stop(transfer); return; } transfer->file_size = sb.size; transfer->checksum = wi_retain(wi_fs_sha1_for_path(local_path, WR_CHECKSUM_SIZE)); // wr_send_command(WI_STR("PUT %#@%c%llu%c%#@"), // wi_array_first_data(transfer->remote_paths), WR_FIELD_SEPARATOR, // transfer->file_size, WR_FIELD_SEPARATOR, // transfer->checksum); } }
void wr_draw_divider(void) { wi_enumerator_t *enumerator; wi_mutable_string_t *string, *action; wi_string_t *position; wr_window_t *window; wi_size_t size; wi_range_t scroll; wi_point_t location; const char *color; wi_uinteger_t users, line, lines, windows; string = wi_mutable_string_with_format(WI_STR("%s%@"), WR_PREFIX, wr_nick); if(wr_connected && wr_server) { users = wi_array_count(wr_chat_users(wr_console_window->chat)); wi_mutable_string_append_format(string, WI_STR(" - %@ - %u %@"), wr_server_name(wr_server), users, users == 1 ? WI_STR("user") : WI_STR("users")); } action = wi_mutable_string(); windows = 0; enumerator = wi_array_data_enumerator(wr_windows); while((window = wi_enumerator_next_data(enumerator))) { switch(window->status) { case WR_WINDOW_STATUS_ACTION: color = WR_INTERFACE_COLOR; break; case WR_WINDOW_STATUS_CHAT: color = WR_STATUS_COLOR; break; case WR_WINDOW_STATUS_HIGHLIGHT: color = WR_HIGHLIGHT_COLOR; break; default: color = NULL; break; } if(color) { if(windows > 0) wi_mutable_string_append_string(action, WI_STR(",")); wi_mutable_string_append_format(action, WI_STR("%s%s%s%u%s%s"), WR_TERMINATE_COLOR, WR_INTERFACE_COLOR, color, window->wid, WR_TERMINATE_COLOR, WR_INTERFACE_COLOR); windows++; } } if(windows > 0) wi_mutable_string_append_format(string, WI_STR(" [%@]"), action); line = wi_terminal_buffer_current_line(wr_current_window->buffer); lines = wi_terminal_buffer_lines(wr_current_window->buffer); scroll = wi_terminal_scroll(wr_terminal); if(lines == 0 || line == lines) position = NULL; else if(line <= scroll.length) position = wi_string_with_cstring("TOP"); else position = wi_string_with_format(WI_STR("%.0f%%"), 100 * ((double) (line - scroll.length) / (double) lines)); wi_terminal_adjust_string_to_fit_width(wr_terminal, string); if(position) { wi_mutable_string_delete_characters_from_index(string, wi_string_length(string) - wi_string_length(position)); wi_mutable_string_append_string(string, position); } size = wi_terminal_size(wr_terminal); location = wi_terminal_location(wr_terminal); wi_terminal_move_printf(wr_terminal, wi_make_point(0, size.height - 3), WI_STR("%s%@%s"), WR_INTERFACE_COLOR, string, WR_TERMINATE_COLOR); wi_terminal_move(wr_terminal, location); }
static void wd_tracker_register(wd_tracker_t *tracker) { wi_enumerator_t *enumerator; wi_address_t *address; wi_array_t *arguments; wi_string_t *ip, *string; uint32_t message; wi_boolean_t fatal = false; if(!wi_lock_trylock(tracker->register_lock)) return; enumerator = wi_array_data_enumerator(tracker->addresses); while((address = wi_enumerator_next_data(enumerator))) { tracker->active = false; tracker->address = NULL; ip = wi_address_string(address); wi_log_info(WI_STR("Trying %@ for tracker %@..."), ip, tracker->host); tracker->socket = wi_autorelease(wi_socket_init_with_address(wi_socket_alloc(), address, WI_SOCKET_TCP)); if(!tracker->socket) { wi_log_err(WI_STR("Could not create socket for tracker %@: %m"), tracker->host); continue; } if(!wi_socket_connect(tracker->socket, 30.0)) { wi_log_err(WI_STR("Could not connect to tracker %@: %m"), tracker->host); continue; } if(!wi_socket_connect_tls(tracker->socket, tracker->tls, 30.0)) { wi_log_err(WI_STR("Could not connect to tracker %@: %m"), tracker->host); continue; } if(!wd_tracker_write(tracker, WI_STR("HELLO"))) continue; if(!wd_tracker_read(tracker, &message, &arguments)) continue; if(message != 200) { string = wi_array_components_joined_by_string(arguments, WI_STR(" ")); wi_log_err(WI_STR("Could not register with tracker %@: Unexpected reply \"%u %@\""), tracker->host, message, string); fatal = true; continue; } if(!wd_tracker_write(tracker, WI_STR("CLIENT %#@"), wd_server_version_string)) continue; if(!wd_tracker_write(tracker, WI_STR("REGISTER %#@%c%#@%c%#@%c%u%c%#@"), tracker->category, WD_FIELD_SEPARATOR, wd_settings.url, WD_FIELD_SEPARATOR, wd_settings.name, WD_FIELD_SEPARATOR, wd_settings.bandwidth, WD_FIELD_SEPARATOR, wd_settings.description)) continue; if(!wd_tracker_read(tracker, &message, &arguments)) continue; if(message != 700 || wi_array_count(arguments) < 1) { string = wi_array_components_joined_by_string(arguments, WI_STR(" ")); wi_log_err(WI_STR("Could not register with tracker %@: Unexpected reply \"%u %@\""), tracker->host, message, string); break; } wi_release(tracker->key); tracker->key = wi_retain(WI_ARRAY(arguments, 0)); tracker->public_key = wi_retain(wi_socket_ssl_public_key(tracker->socket)); if(!tracker->public_key) { wi_log_err(WI_STR("Could not get public key from the tracker %@: %m"), tracker->host); break; } wi_log_info(WI_STR("Registered with the tracker %@"), tracker->host); tracker->active = true; tracker->address = address; break; } wi_lock_unlock(tracker->register_lock); }
static wi_boolean_t _wi_config_write_setting_to_file(wi_config_t *config, wi_string_t *name, wi_file_t *file) { wi_runtime_instance_t *value; wi_config_type_t type; struct passwd *user; struct group *group; wi_uinteger_t i, count; if(!wi_dictionary_contains_key(config->types, name)) { wi_error_set_libwired_error(WI_ERROR_SETTINGS_UNKNOWNSETTING); return false; } type = wi_number_int32(wi_dictionary_data_for_key(config->types, name)); value = wi_dictionary_data_for_key(config->values, name); if(!value) return false; switch(type) { case WI_CONFIG_INTEGER: wi_file_write_format(file, WI_STR("%@ = %d\n"), name, wi_number_integer(value)); break; case WI_CONFIG_BOOL: wi_file_write_format(file, WI_STR("%@ = %@\n"), name, wi_number_bool(value) ? WI_STR("yes") : WI_STR("no")); break; case WI_CONFIG_STRING: wi_file_write_format(file, WI_STR("%@ = %@\n"), name, value); break; case WI_CONFIG_STRINGLIST: count = wi_array_count(value); for(i = 0; i < count; i++) wi_file_write_format(file, WI_STR("%@ = %@\n"), name, WI_ARRAY(value, i)); break; case WI_CONFIG_PATH: wi_file_write_format(file, WI_STR("%@ = %@\n"), name, value); break; case WI_CONFIG_USER: user = getpwuid(wi_number_int32(value)); if(user) wi_file_write_format(file, WI_STR("%@ = %s\n"), name, user->pw_name); else wi_file_write_format(file, WI_STR("%@ = %d\n"), name, wi_number_int32(value)); break; case WI_CONFIG_GROUP: group = getgrgid(wi_number_int32(value)); if(group) wi_file_write_format(file, WI_STR("%@ = %s\n"), name, group->gr_name); else wi_file_write_format(file, WI_STR("%@ = %d\n"), name, wi_number_int32(value)); break; case WI_CONFIG_PORT: wi_file_write_format(file, WI_STR("%@ = %d\n"), name, wi_number_int32(value)); break; case WI_CONFIG_REGEXP: wi_file_write_format(file, WI_STR("%@ = %@\n"), name, wi_regexp_string(value)); break; case WI_CONFIG_TIME_INTERVAL: wi_file_write_format(file, WI_STR("%@ = %.2f\n"), name, wi_number_double(value)); break; } return true; }
void wi_p7_message_serialize(wi_p7_message_t *p7_message, wi_p7_serialization_t serialization) { xmlDocPtr doc; xmlNsPtr ns; xmlNodePtr root_node, list_node, item_node; wi_p7_spec_field_t *field; wi_p7_spec_type_t *type; wi_runtime_instance_t *instance; wi_string_t *field_name, *field_value; unsigned char *buffer, *start; wi_uuid_t *uuid; wi_date_t *date; wi_p7_boolean_t p7_bool; wi_p7_int32_t p7_int32; wi_p7_uint32_t p7_uint32; wi_p7_int64_t p7_int64; wi_p7_uint64_t p7_uint64; wi_p7_double_t p7_double; wi_p7_oobdata_t p7_oobdata; wi_string_t *string; wi_data_t *data; wi_array_t *list; wi_uinteger_t i, count; uint32_t message_size, field_id, field_size; if(serialization == WI_P7_XML && !p7_message->xml_buffer) { doc = xmlNewDoc((xmlChar *) "1.0"); root_node = xmlNewNode(NULL, (xmlChar *) "message"); xmlDocSetRootElement(doc, root_node); ns = xmlNewNs(root_node, (xmlChar *) "http://www.zankasoftware.com/P7/Message", (xmlChar *) "p7"); xmlSetNs(root_node, ns); xmlSetProp(root_node, (xmlChar *) "name", (xmlChar *) wi_string_cstring(p7_message->name)); message_size = p7_message->binary_size - WI_P7_MESSAGE_BINARY_HEADER_SIZE; buffer = start = p7_message->binary_buffer + WI_P7_MESSAGE_BINARY_HEADER_SIZE; while((uint32_t) (buffer - start) < message_size) { field_id = wi_read_swap_big_to_host_int32(buffer, 0); buffer += sizeof(field_id); field = wi_p7_spec_field_with_id(p7_message->spec, field_id); if(!field) continue; field_size = wi_p7_spec_field_size(field); if(field_size == 0) { field_size = wi_read_swap_big_to_host_int32(buffer, 0); buffer += sizeof(field_size); } field_name = wi_p7_spec_field_name(field); field_value = NULL; type = wi_p7_spec_field_type(field); switch(wi_p7_spec_type_id(type)) { case WI_P7_BOOL: if(wi_p7_message_get_bool_for_name(p7_message, &p7_bool, field_name)) field_value = wi_string_with_format(WI_STR("%u"), p7_bool ? 1 : 0); break; case WI_P7_ENUM: string = wi_p7_message_enum_name_for_name(p7_message, field_name); if(string) field_value = string; break; case WI_P7_INT32: if(wi_p7_message_get_int32_for_name(p7_message, &p7_int32, field_name)) field_value = wi_string_with_format(WI_STR("%u"), p7_int32); break; case WI_P7_UINT32: if(wi_p7_message_get_uint32_for_name(p7_message, &p7_uint32, field_name)) field_value = wi_string_with_format(WI_STR("%u"), p7_uint32); break; case WI_P7_INT64: if(wi_p7_message_get_int64_for_name(p7_message, &p7_int64, field_name)) field_value = wi_string_with_format(WI_STR("%lld"), p7_int64); break; case WI_P7_UINT64: if(wi_p7_message_get_uint64_for_name(p7_message, &p7_uint64, field_name)) field_value = wi_string_with_format(WI_STR("%llu"), p7_uint64); break; case WI_P7_DOUBLE: if(wi_p7_message_get_double_for_name(p7_message, &p7_double, field_name)) field_value = wi_string_with_format(WI_STR("%f"), p7_double); break; case WI_P7_STRING: string = wi_p7_message_string_for_name(p7_message, field_name); if(string) field_value = string; break; case WI_P7_UUID: uuid = wi_p7_message_uuid_for_name(p7_message, field_name); if(uuid) field_value = wi_uuid_string(uuid); break; case WI_P7_DATE: date = wi_p7_message_date_for_name(p7_message, field_name); if(date) field_value = wi_string_with_format(WI_STR("%f"), wi_date_time_interval(date)); break; case WI_P7_DATA: data = wi_p7_message_data_for_name(p7_message, field_name); if(data) field_value = wi_data_base64(data); break; case WI_P7_OOBDATA: if(wi_p7_message_get_oobdata_for_name(p7_message, &p7_oobdata, field_name)) field_value = wi_string_with_format(WI_STR("%llu"), p7_oobdata); break; case WI_P7_LIST: list = wi_p7_message_list_for_name(p7_message, field_name); if(list) { list_node = wi_xml_node_child_with_name(root_node, field_name); if(!list_node) { list_node = xmlNewNode(ns, (xmlChar *) "field"); xmlSetProp(list_node, (xmlChar *) "name", (xmlChar *) wi_string_cstring(field_name)); xmlAddChild(root_node, list_node); } count = wi_array_count(list); for(i = 0; i < count; i++) { item_node = xmlNewNode(ns, (xmlChar *) "item"); instance = WI_ARRAY(list, i); if(wi_runtime_id(instance) == wi_string_runtime_id()) xmlNodeSetContent(item_node, (xmlChar *) wi_string_cstring(instance)); xmlAddChild(list_node, item_node); } } break; } if(field_value) { item_node = wi_xml_node_child_with_name(root_node, field_name); if(!item_node) { item_node = xmlNewNode(ns, (xmlChar *) "field"); xmlSetProp(item_node, (xmlChar *) "name", (xmlChar *) wi_string_cstring(field_name)); xmlAddChild(root_node, item_node); } xmlNodeSetContent(item_node, (xmlChar *) wi_string_cstring(field_value)); } buffer += field_size; } xmlDocDumpMemoryEnc(doc, &p7_message->xml_buffer, &p7_message->xml_length, "UTF-8"); xmlFreeDoc(doc); } }
static wi_boolean_t _wi_plist_write_instance_to_node(wi_runtime_instance_t *instance, xmlNodePtr node) { wi_enumerator_t *enumerator; wi_mutable_array_t *keys; wi_runtime_instance_t *value; xmlNodePtr child_node; void *key; wi_runtime_id_t id; wi_number_type_t type; wi_uinteger_t i, count; id = wi_runtime_id(instance); if(id == wi_string_runtime_id()) { wi_xml_node_new_child(node, WI_STR("string"), instance); } else if(id == wi_number_runtime_id()) { type = wi_number_type(instance); if(type == WI_NUMBER_BOOL) { if(wi_number_bool(instance)) wi_xml_node_new_child(node, WI_STR("true"), NULL); else wi_xml_node_new_child(node, WI_STR("false"), NULL); } else { if(type == WI_NUMBER_FLOAT || type == WI_NUMBER_DOUBLE) wi_xml_node_new_child(node, WI_STR("real"), wi_number_string(instance)); else wi_xml_node_new_child(node, WI_STR("integer"), wi_number_string(instance)); } } else if(id == wi_data_runtime_id()) { wi_xml_node_new_child(node, WI_STR("data"), wi_data_base64(instance)); } else if(id == wi_date_runtime_id()) { wi_xml_node_new_child(node, WI_STR("date"), wi_date_string_with_format(instance, WI_STR("%Y-%m-%dT%H:%M:%SZ"))); } else if(id == wi_dictionary_runtime_id()) { child_node = wi_xml_node_new_child(node, WI_STR("dict"), NULL); keys = wi_mutable_array(); enumerator = wi_dictionary_key_enumerator(instance); while((key = wi_enumerator_next_data(enumerator))) wi_mutable_array_add_data_sorted(keys, key, wi_string_compare); count = wi_array_count(keys); for(i = 0; i < count; i++) { key = WI_ARRAY(keys, i); value = wi_dictionary_data_for_key(instance, key); wi_xml_node_new_child(child_node, WI_STR("key"), key); if(!_wi_plist_write_instance_to_node(value, child_node)) return false; } } else if(id == wi_array_runtime_id()) { child_node = wi_xml_node_new_child(node, WI_STR("array"), NULL); xmlAddChild(node, child_node); enumerator = wi_array_data_enumerator(instance); while((value = wi_enumerator_next_data(enumerator))) { if(!_wi_plist_write_instance_to_node(value, child_node)) return false; } } else { wi_error_set_libwired_error_with_format(WI_ERROR_PLIST_WRITEFAILED, WI_STR("Unhandled class %@"), wi_runtime_class_name(instance)); return false; } return true; }