wr_transfer_t * wr_transfer_init(wr_transfer_t *transfer) { transfer->tid = wr_transfer_tid(); transfer->remote_paths = wi_array_init(wi_mutable_array_alloc()); transfer->local_paths = wi_array_init(wi_mutable_array_alloc()); transfer->files = wi_array_init(wi_mutable_array_alloc()); return transfer; }
static wi_array_t * _wi_terminal_buffer_lines_for_string(wi_terminal_buffer_t *buffer, wi_string_t *string) { wi_array_t *array, *linearray; wi_string_t *string_copy, *line, *subline; wi_size_t size; uint32_t i, count, index; array = wi_array_init(wi_array_alloc()); size = wi_terminal_size(buffer->terminal); linearray = wi_string_components_separated_by_string(string, WI_STR("\n")); count = wi_array_count(linearray); for(i = 0; i < count; i++) { line = WI_ARRAY(linearray, i); if(wi_terminal_width_of_string(buffer->terminal, line) < size.width) { wi_array_add_data(array, line); } else { string_copy = wi_copy(line); do { index = wi_terminal_index_of_string_for_width(buffer->terminal, string_copy, size.width); subline = wi_string_substring_to_index(string_copy, index); wi_array_add_data(array, subline); wi_string_delete_characters_to_index(string_copy, wi_string_length(subline)); } while(wi_terminal_width_of_string(buffer->terminal, string_copy) >= size.width); wi_array_add_data(array, string_copy); wi_release(string_copy); } } return array; }
static wi_mutable_array_t * _wi_terminal_buffer_lines_for_string(wi_terminal_buffer_t *buffer, wi_string_t *string) { wi_enumerator_t *enumerator; wi_mutable_array_t *array; wi_mutable_string_t *newstring; wi_string_t *line, *subline; wi_size_t size; wi_uinteger_t index; array = wi_array_init(wi_mutable_array_alloc()); size = wi_terminal_size(buffer->terminal); enumerator = wi_array_data_enumerator(wi_string_components_separated_by_string(string, WI_STR("\n"))); while((line = wi_enumerator_next_data(enumerator))) { if(wi_terminal_width_of_string(buffer->terminal, line) < size.width) { wi_mutable_array_add_data(array, line); } else { newstring = wi_mutable_copy(line); do { index = wi_terminal_index_of_string_for_width(buffer->terminal, newstring, size.width); subline = wi_string_substring_to_index(newstring, index); wi_mutable_array_add_data(array, subline); wi_mutable_string_delete_characters_to_index(newstring, wi_string_length(subline)); } while(wi_terminal_width_of_string(buffer->terminal, newstring) >= size.width); wi_mutable_array_add_data(array, newstring); wi_release(newstring); } } return wi_autorelease(array); }
void wd_transfers_init(void) { wd_transfer_runtime_id = wi_runtime_register_class(&wd_transfer_runtime_class); wd_transfers = wi_array_init(wi_mutable_array_alloc()); wd_transfers_update_queue_lock = wi_lock_init(wi_lock_alloc()); }
void wr_transfers_init(void) { wr_transfer_runtime_id = wi_runtime_register_class(&wr_transfer_runtime_class); wr_transfers = wi_array_init(wi_mutable_array_alloc()); wr_transfers_set_download_path(WI_STR("~")); }
wb_command_t * wb_command_init(wb_command_t *command, xmlNodePtr node) { command->activated = true; command->name = wi_retain(WI_STR("help")); command->permissions = wi_retain(WI_STR("any")); command->outputs = wi_array_init(wi_mutable_array_alloc()); return _wb_command_load_with_node(command, node); }
static wi_process_t * _wi_process_init_with_argv(wi_process_t *process, int argc, const char **argv) { wi_array_t *array; wi_string_t *string; struct utsname name; #if defined(HAVE_NXGETLOCALARCHINFO) const NXArchInfo *archinfo; cpu_type_t cputype; size_t cputypesize; #elif defined(HAVE_SYSINFO) && defined(SI_ARCHITECTURE) char buffer[SYS_NMLN]; #endif array = wi_array_init_with_argv(wi_array_alloc(), argc, argv); string = wi_array_first_data(array); if(string) { process->path = wi_retain(string); process->name = wi_retain(wi_string_last_path_component(process->path)); } else { process->path = wi_retain(WI_STR("unknown")); process->name = wi_retain(process->path); } if(wi_array_count(array) <= 1) process->arguments = wi_array_init(wi_array_alloc()); else process->arguments = wi_retain(wi_array_subarray_with_range(array, wi_make_range(1, wi_array_count(array) - 1))); wi_release(array); uname(&name); process->os_name = wi_string_init_with_cstring(wi_string_alloc(), name.sysname); process->os_release = wi_string_init_with_cstring(wi_string_alloc(), name.release); #if defined(HAVE_NXGETLOCALARCHINFO) cputypesize = sizeof(cputype); if(sysctlbyname("sysctl.proc_cputype", &cputype, &cputypesize, NULL, 0) < 0) cputype = NXGetLocalArchInfo()->cputype; archinfo = NXGetArchInfoFromCpuType(cputype, CPU_SUBTYPE_MULTIPLE); if(archinfo) process->arch = wi_string_init_with_cstring(wi_string_alloc(), archinfo->name); #elif defined(HAVE_SYSINFO) && defined(SI_ARCHITECTURE) if(sysinfo(SI_ARCHITECTURE, buffer, sizeof(buffer)) >= 0) process->arch = wi_string_init_with_cstring(wi_string_alloc(), buffer); #endif if(!process->arch) process->arch = wi_string_init_with_cstring(wi_string_alloc(), name.machine); return process; }
void wr_windows_initialize(void) { wr_window_runtime_id = wi_runtime_register_class(&wr_window_runtime_class); wr_windows = wi_array_init(wi_mutable_array_alloc()); wr_console_window = wr_window_init_with_chat(wr_window_alloc(), wr_public_chat); wr_windows_add_window(wr_console_window); wr_windows_show_window(wr_console_window); wr_windows_set_timestamp_format(WI_STR("%H:%M")); }
wi_array_t * wi_dictionary_keys_sorted_by_value(wi_dictionary_t *dictionary, wi_compare_func_t *compare) { wi_mutable_array_t *array, *buckets; _wi_dictionary_bucket_t *bucket; wi_array_callbacks_t callbacks; void **data; wi_uinteger_t i; if(dictionary->key_count == 0) return wi_autorelease(wi_array_init(wi_array_alloc())); callbacks.retain = NULL; callbacks.release = NULL; callbacks.is_equal = NULL; callbacks.description = NULL; buckets = wi_array_init_with_capacity_and_callbacks(wi_mutable_array_alloc(), dictionary->key_count, callbacks); for(i = 0; i < dictionary->buckets_count; i++) { for(bucket = dictionary->buckets[i]; bucket; bucket = bucket->next) wi_mutable_array_add_data(buckets, bucket); } data = wi_malloc(sizeof(void *) * dictionary->key_count); wi_array_get_data(buckets, data); #ifdef _WI_DICTIONARY_USE_QSORT_R qsort_r(data, dictionary->key_count, sizeof(void *), compare, _wi_dictionary_compare_buckets); #else wi_lock_lock(_wi_dictionary_sort_lock); _wi_dictionary_sort_function = compare; qsort(data, dictionary->key_count, sizeof(void *), _wi_dictionary_compare_buckets); wi_lock_unlock(_wi_dictionary_sort_lock); #endif callbacks.retain = dictionary->key_callbacks.retain; callbacks.release = dictionary->key_callbacks.release; callbacks.is_equal = dictionary->key_callbacks.is_equal; callbacks.description = dictionary->key_callbacks.description; array = wi_array_init_with_capacity_and_callbacks(wi_mutable_array_alloc(), dictionary->key_count, callbacks); for(i = 0; i < dictionary->key_count; i++) wi_mutable_array_add_data(array, ((_wi_dictionary_bucket_t *) data[i])->key); wi_free(data); wi_release(buckets); wi_runtime_make_immutable(array); return wi_autorelease(array); }
void wd_transfers_initialize(void) { wd_transfer_runtime_id = wi_runtime_register_class(&wd_transfer_runtime_class); wd_transfers = wi_array_init(wi_mutable_array_alloc()); wd_transfers_status_lock = wi_lock_init(wi_lock_alloc()); wd_transfers_user_downloads = wi_dictionary_init_with_capacity_and_callbacks(wi_mutable_dictionary_alloc(), 0, wi_dictionary_default_key_callbacks, wi_dictionary_null_value_callbacks); wd_transfers_user_uploads = wi_dictionary_init_with_capacity_and_callbacks(wi_mutable_dictionary_alloc(), 0, wi_dictionary_default_key_callbacks, wi_dictionary_null_value_callbacks); wd_transfers_queue_lock = wi_condition_lock_init_with_condition(wi_condition_lock_alloc(), 0); }
void wd_trackers_init(void) { wd_tracker_runtime_id = wi_runtime_register_class(&wd_tracker_runtime_class); wd_trackers = wi_array_init(wi_mutable_array_alloc()); wd_trackers_register_timer = wi_timer_init_with_function(wi_timer_alloc(), wd_trackers_register_with_timer, WD_TRACKERS_REGISTER_INTERVAL, true); wd_trackers_update_timer = wi_timer_init_with_function(wi_timer_alloc(), wd_trackers_update_with_timer, WD_TRACKERS_UPDATE_INTERVAL, true); }
static wi_process_t * _wi_process_init_with_argv(wi_process_t *process, int argc, const char **argv) { wi_array_t *array; wi_string_t *string; struct utsname name; #ifdef HAVE_MACH_O_ARCH_H const NXArchInfo *arch_info; #endif array = wi_array_init_with_argv(wi_array_alloc(), argc, argv); string = wi_array_first_data(array); if(string) { process->path = wi_retain(string); process->name = wi_retain(wi_string_last_path_component(process->path)); } else { process->path = wi_retain(WI_STR("unknown")); process->name = wi_retain(process->path); } if(wi_array_count(array) <= 1) process->arguments = wi_array_init(wi_array_alloc()); else process->arguments = wi_retain(wi_array_subarray_with_range(array, wi_make_range(1, wi_array_count(array) - 1))); wi_release(array); uname(&name); process->os_name = wi_string_init_with_cstring(wi_string_alloc(), name.sysname); process->os_release = wi_string_init_with_cstring(wi_string_alloc(), name.release); #ifdef HAVE_MACH_O_ARCH_H arch_info = NXGetArchInfoFromCpuType(NXGetLocalArchInfo()->cputype, CPU_SUBTYPE_MULTIPLE); process->arch = wi_string_init_with_cstring(wi_string_alloc(), arch_info->name); #else process->arch = wi_string_init_with_cstring(wi_string_alloc(), name.machine); #endif return process; }
static wd_user_t * wd_user_init_with_socket(wd_user_t *user, wi_socket_t *socket) { wi_address_t *address; user->uid = wd_user_next_uid(); user->socket = wi_retain(socket); user->state = WD_USER_CONNECTED; user->login_time = wi_time_interval(); user->idle_time = user->login_time; address = wi_socket_address(socket); user->ip = wi_retain(wi_address_string(address)); user->host = wi_retain(wi_address_hostname(address)); user->user_lock = wi_recursive_lock_init(wi_recursive_lock_alloc()); user->socket_lock = wi_lock_init(wi_lock_alloc()); user->transfers_queue = wi_array_init(wi_array_alloc()); return user; }
static wi_boolean_t _wi_plist_read_node_to_instance(xmlNodePtr content_node, wi_runtime_instance_t *collection) { xmlNodePtr node; wi_string_t *name, *key = NULL; wi_runtime_instance_t *instance = NULL; wi_boolean_t dictionary; dictionary = (wi_runtime_id(collection) == wi_dictionary_runtime_id()); for(node = content_node->children; node != NULL; node = node->next) { if(node->type == XML_ELEMENT_NODE) { name = wi_xml_node_name(node); if(wi_is_equal(name, WI_STR("key"))) key = wi_xml_node_content(node); else if(wi_is_equal(name, WI_STR("string"))) instance = wi_xml_node_content(node); else if(wi_is_equal(name, WI_STR("integer"))) instance = wi_number_with_integer(wi_string_integer(wi_xml_node_content(node))); else if(wi_is_equal(name, WI_STR("real"))) instance = wi_number_with_double(wi_string_double(wi_xml_node_content(node))); else if(wi_is_equal(name, WI_STR("true"))) instance = wi_number_with_bool(true); else if(wi_is_equal(name, WI_STR("false"))) instance = wi_number_with_bool(false); else if(wi_is_equal(name, WI_STR("date"))) instance = wi_date_with_rfc3339_string(wi_xml_node_content(node)); else if(wi_is_equal(name, WI_STR("data"))) instance = wi_data_with_base64(wi_xml_node_content(node)); else if(wi_is_equal(name, WI_STR("dict"))) { instance = wi_autorelease(wi_dictionary_init(wi_dictionary_alloc())); if(!_wi_plist_read_node_to_instance(node, instance)) return false; } else if(wi_is_equal(name, WI_STR("array"))) { instance = wi_autorelease(wi_array_init(wi_array_alloc())); if(!_wi_plist_read_node_to_instance(node, instance)) return false; } else { wi_error_set_libwired_error_with_format(WI_ERROR_PLIST_READFAILED, WI_STR("Unhandled node \"%@\""), name); return false; } } if(instance) { if(dictionary) wi_dictionary_set_data_for_key(collection, instance, key); else wi_array_add_data(collection, instance); instance = NULL; key = NULL; } } return true; }
wi_array_t * wi_array(void) { return wi_autorelease(wi_array_init(wi_array_alloc())); }
wr_chat_t * wr_chat_init(wr_chat_t *chat) { chat->users_array = wi_array_init(wi_array_alloc()); chat->users_hash = wi_hash_init(wi_hash_alloc()); return chat; }
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); }
static wd_chat_t * wd_chat_init(wd_chat_t *chat) { chat->users = wi_array_init(wi_mutable_array_alloc()); chat->lock = wi_recursive_lock_init(wi_recursive_lock_alloc()); return chat; }
static void _wi_settings_clear_string_array(wi_settings_t *settings, wi_uinteger_t index) { wi_array_t **array = (wi_array_t **) settings->spec[index].setting; wi_release(*array); *array = wi_array_init(wi_array_alloc()); }
void wi_timer_initialize(void) { _wi_timers = wi_array_init(wi_mutable_array_alloc()); _wi_timer_lock = wi_condition_lock_init_with_condition(wi_condition_lock_alloc(), 0); }
int main(int argc, const char **argv) { wi_mutable_array_t *arguments; wi_pool_t *pool; wi_string_t *string, *root_path; int ch, facility; wi_boolean_t test_config, daemonize, change_directory, switch_user; /* init libwired */ wi_initialize(); wi_load(argc, argv); pool = wi_pool_init(wi_pool_alloc()); wi_log_syslog = true; wi_log_syslog_facility = LOG_DAEMON; /* init core systems */ wt_version_init(); wt_status_lock = wi_lock_init(wi_lock_alloc()); wt_start_date = wi_date_init(wi_date_alloc()); /* set defaults */ root_path = WI_STR(WT_ROOT); wi_settings_config_path = wi_string_init_with_cstring(wi_string_alloc(), WT_CONFIG_PATH); test_config = false; daemonize = true; change_directory = true; switch_user = true; /* init reexec argument list */ arguments = wi_array_init(wi_mutable_array_alloc()); /* parse command line switches */ while((ch = getopt(argc, (char * const *) argv, "46Dd:f:hi:L:ls:tuVvXx")) != -1) { switch(ch) { case '4': wt_address_family = WI_ADDRESS_IPV4; break; case '6': wt_address_family = WI_ADDRESS_IPV6; break; case 'D': daemonize = false; wi_log_stderr = true; break; case 'd': root_path = wi_string_with_cstring(optarg); break; case 'f': wi_release(wi_settings_config_path); wi_settings_config_path = wi_string_init_with_cstring(wi_string_alloc(), optarg); break; case 'i': wi_log_limit = wi_string_uint32(wi_string_with_cstring(optarg)); break; case 'L': wi_log_syslog = false; wi_log_file = true; wi_release(wi_log_path); wi_log_path = wi_string_init_with_cstring(wi_string_alloc(), optarg); break; case 'l': wi_log_level++; break; case 's': string = wi_string_with_cstring(optarg); facility = wi_log_syslog_facility_with_name(string); if(facility < 0) wi_log_fatal(WI_STR("Could not find syslog facility \"%@\": %m"), string); wi_log_syslog_facility = facility; break; case 't': test_config = true; break; case 'u': break; case 'V': case 'v': wt_version(); break; case 'X': daemonize = false; break; case 'x': daemonize = false; change_directory = false; switch_user = false; break; case '?': case 'h': default: wt_usage(); break; } wi_mutable_array_add_data(arguments, wi_string_with_format(WI_STR("-%c"), ch)); if(optarg) wi_mutable_array_add_data(arguments, wi_string_with_cstring(optarg)); } /* detach */ if(daemonize) { wi_mutable_array_add_data(arguments, WI_STR("-X")); switch(wi_fork()) { case -1: wi_log_fatal(WI_STR("Could not fork: %m")); break; case 0: if(!wi_execv(wi_string_with_cstring(argv[0]), arguments)) wi_log_fatal(WI_STR("Could not execute %s: %m"), argv[0]); break; default: _exit(0); break; } } wi_release(arguments); /* change directory */ if(change_directory) { if(!wi_fs_change_directory(root_path)) wi_log_error(WI_STR("Could not change directory to %@: %m"), root_path); } /* open log */ wi_log_open(); /* init subsystems */ wt_ssl_init(); wt_clients_init(); wt_servers_init(); /* read the config file */ wt_settings_init(); if(!wt_settings_read_config()) exit(1); /* apply settings */ wt_settings_apply_settings(); if(test_config) { printf("Config OK\n"); exit(0); } /* dump command line */ wi_log_info(WI_STR("Started as %@ %@"), wi_process_path(wi_process()), wi_array_components_joined_by_string(wi_process_arguments(wi_process()), WI_STR(" "))); /* init tracker */ wi_log_info(WI_STR("Starting Wired Tracker version %@"), wt_version_string); wt_tracker_init(); /* switch user/group */ if(switch_user) wi_switch_user(wt_settings.user, wt_settings.group); /* create tracker threads after privilege drop */ wt_signals_init(); wt_block_signals(); wt_servers_schedule(); wt_tracker_create_threads(); wt_write_pid(); wt_write_status(true); /* clean up pool after startup */ wi_pool_drain(pool); /* enter the signal handling thread in the main thread */ wt_signal_thread(NULL); /* dropped out */ wt_cleanup(); wi_log_close(); wi_release(pool); return 0; }
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 }
wr_chat_t * wr_chat_init(wr_chat_t *chat) { chat->users_array = wi_array_init(wi_mutable_array_alloc()); chat->users_dictionary = wi_dictionary_init(wi_mutable_dictionary_alloc()); return chat; }