wi_array_t * wd_user_subscribed_virtual_paths_for_path(wd_user_t *user, wi_string_t *path) { wi_mutable_array_t *array; wi_string_t *virtualpath; array = wi_mutable_array(); wi_recursive_lock_lock(user->user_lock); if(wi_is_equal(wi_string_last_path_component(path), WI_STR(WD_FILES_META_PATH))) { path = wi_string_by_deleting_last_path_component(path); virtualpath = wi_dictionary_data_for_key(user->subscribed_virtualpaths, path); if(virtualpath) wi_mutable_array_add_data(array, virtualpath); if(!wi_is_equal(path, WI_STR("/"))) { path = wi_string_by_deleting_last_path_component(path); virtualpath = wi_dictionary_data_for_key(user->subscribed_virtualpaths, path); if(virtualpath) wi_mutable_array_add_data(array, virtualpath); } } else { virtualpath = wi_dictionary_data_for_key(user->subscribed_virtualpaths, path); if(virtualpath) wi_mutable_array_add_data(array, virtualpath); } wi_recursive_lock_unlock(user->user_lock); return array; }
wi_boolean_t wd_banlist_ip_is_banned(wi_string_t *ip) { wi_file_t *file; wi_string_t *string; wi_boolean_t banned = false; wi_dictionary_rdlock(wd_tempbans); banned = (wi_dictionary_data_for_key(wd_tempbans, ip) != NULL); wi_dictionary_unlock(wd_tempbans); if(banned) return banned; if(wd_settings.banlist) { file = wi_file_for_reading(wd_settings.banlist); if(!file) { wi_log_err(WI_STR("Could not open %@: %m"), wd_settings.banlist); } else { while((string = wi_file_read_config_line(file))) { if(wi_ip_matches_string(ip, string)) { banned = true; break; } } } } return banned; }
static void wd_transfers_add_or_remove_transfer(wd_transfer_t *transfer, wi_boolean_t add) { wi_mutable_dictionary_t *dictionary; wi_integer_t number; wi_lock_lock(wd_transfers_status_lock); if(transfer->type == WD_TRANSFER_DOWNLOAD) wd_transfers_active_downloads += add ? 1 : -1; else wd_transfers_active_uploads += add ? 1 : -1; wi_lock_unlock(wd_transfers_status_lock); if(transfer->type == WD_TRANSFER_DOWNLOAD) dictionary = wd_transfers_user_downloads; else dictionary = wd_transfers_user_uploads; wi_dictionary_wrlock(dictionary); number = (wi_integer_t) wi_dictionary_data_for_key(dictionary, transfer->key); if(add) { wi_mutable_dictionary_set_data_for_key(dictionary, (void *) (number + 1), transfer->key); } else { if(number > 0) { wi_mutable_dictionary_set_data_for_key(dictionary, (void *) (number - 1), transfer->key); } else { wi_mutable_dictionary_remove_data_for_key(dictionary, transfer->key); } } wi_dictionary_unlock(dictionary); }
wi_boolean_t wi_p7_message_set_enum_name_for_name(wi_p7_message_t *p7_message, wi_string_t *enum_name, wi_string_t *field_name) { wi_p7_spec_field_t *field; wi_dictionary_t *enums; wi_p7_enum_t enum_value; field = wi_p7_spec_field_with_name(p7_message->spec, field_name); if(!field) { wi_error_set_libwired_error_with_format(WI_ERROR_P7_UNKNOWNFIELD, WI_STR("No id found for field \"%@\""), field_name); if(wi_p7_message_debug) wi_log_debug(WI_STR("wi_p7_message_set_enum_name_for_name: %m")); return false; } enums = wi_p7_spec_field_enums_by_name(field); if(!wi_dictionary_contains_key(enums, enum_name)) { wi_error_set_libwired_error_with_format(WI_ERROR_P7_UNKNOWNFIELD, WI_STR("No value found for enum \"%@\""), enum_name); if(wi_p7_message_debug) wi_log_debug(WI_STR("wi_p7_message_set_enum_name_for_name: %m")); return false; } enum_value = (wi_p7_enum_t) (intptr_t) wi_dictionary_data_for_key(enums, enum_name); return wi_p7_message_set_enum_for_name(p7_message, enum_value, field_name); }
static wi_string_t * _wi_p7_message_description(wi_runtime_instance_t *instance) { wi_p7_message_t *p7_message = instance; wi_enumerator_t *enumerator; wi_dictionary_t *fields; wi_mutable_string_t *string; wi_string_t *field_name, *field_value; string = wi_mutable_string_with_format(WI_STR("<%@ %p>{name = %@, buffer = %@, fields = (\n"), wi_runtime_class_name(p7_message), p7_message, p7_message->name, wi_data_with_bytes_no_copy(p7_message->binary_buffer, p7_message->binary_size, false)); fields = wi_p7_message_fields(p7_message); enumerator = wi_dictionary_key_enumerator(fields); while((field_name = wi_enumerator_next_data(enumerator))) { field_value = wi_dictionary_data_for_key(fields, field_name); wi_mutable_string_append_format(string, WI_STR(" %@ = %@\n"), field_name, field_value); } wi_mutable_string_append_string(string, WI_STR(")}")); wi_runtime_make_immutable(string); return string; }
wi_string_t * wr_commands_command_for_message(wi_p7_message_t *message) { wi_p7_uint32_t transaction; if(wi_p7_message_get_uint32_for_name(message, &transaction, WI_STR("wired.transaction"))) return wi_dictionary_data_for_key(wr_commands_transactions, WI_INT32(transaction)); return NULL; }
wd_chat_t * wd_chats_chat_with_cid(wd_cid_t cid) { wd_chat_t *chat; wi_dictionary_rdlock(wd_chats); chat = wi_autorelease(wi_retain(wi_dictionary_data_for_key(wd_chats, wi_number_with_int32(cid)))); wi_dictionary_unlock(wd_chats); return chat; }
wt_server_t * wt_servers_server_with_key(wi_string_t *key) { wt_server_t *server; wi_dictionary_rdlock(wt_servers); server = wi_autorelease(wi_retain(wi_dictionary_data_for_key(wt_servers, key))); wi_dictionary_unlock(wt_servers); return server; }
wi_uinteger_t wi_config_port_for_name(wi_config_t *config, wi_string_t *name) { wi_number_t *value; wi_lock_lock(config->lock); value = wi_autorelease(wi_retain(wi_dictionary_data_for_key(config->values, name))); wi_lock_unlock(config->lock); return value ? wi_number_integer(value) : 0; }
static wi_error_t * _wi_get_error(void) { wi_error_t *error; error = wi_dictionary_data_for_key(wi_thread_dictionary(), WI_STR(_WI_ERROR_THREAD_KEY)); WI_ASSERT(error != NULL, "no wi_error_t created for thread", 0); return error; }
wd_user_t * wd_users_user_with_uid(wd_uid_t uid) { wd_user_t *user; wi_dictionary_rdlock(wd_users); user = wi_autorelease(wi_retain(wi_dictionary_data_for_key(wd_users, wi_number_with_int32(uid)))); wi_dictionary_unlock(wd_users); return user; }
wi_time_interval_t wi_config_time_interval_for_name(wi_config_t *config, wi_string_t *name) { wi_number_t *value; wi_lock_lock(config->lock); value = wi_autorelease(wi_retain(wi_dictionary_data_for_key(config->values, name))); wi_lock_unlock(config->lock); return value ? wi_number_double(value) : 0.0; }
wi_regexp_t * wi_config_regexp_for_name(wi_config_t *config, wi_string_t *name) { wi_regexp_t *value; wi_lock_lock(config->lock); value = wi_autorelease(wi_retain(wi_dictionary_data_for_key(config->values, name))); wi_lock_unlock(config->lock); return value; }
void wi_config_set_instance_for_name(wi_config_t *config, wi_runtime_instance_t *instance, wi_string_t *name) { wi_runtime_instance_t *copy; wi_lock_lock(config->lock); if(!wi_is_equal(instance, wi_dictionary_data_for_key(config->values, name))) wi_mutable_set_add_data(config->changes, name); copy = wi_copy(instance); wi_mutable_dictionary_set_data_for_key(config->values, copy, name); wi_release(copy); wi_lock_unlock(config->lock); }
void wd_banlist_reply_bans(wd_user_t *user, wi_p7_message_t *message) { wi_sqlite3_statement_t *statement; wi_p7_message_t *reply; wi_dictionary_t *results; wi_runtime_instance_t *instance; statement = wi_sqlite3_prepare_statement(wd_database, WI_STR("SELECT ip, expiration_date FROM banlist"), NULL); if(!statement) { wi_log_error(WI_STR("Could not execute database statement: %m")); wd_user_reply_internal_error(user, wi_error_string(), message); return; } while((results = wi_sqlite3_fetch_statement_results(wd_database, statement)) && wi_dictionary_count(results) > 0) { reply = wi_p7_message_with_name(WI_STR("wired.banlist.list"), wd_p7_spec); wi_p7_message_set_string_for_name(reply, wi_dictionary_data_for_key(results, WI_STR("ip")), WI_STR("wired.banlist.ip")); instance = wi_dictionary_data_for_key(results, WI_STR("expiration_date")); if(instance != wi_null()) wi_p7_message_set_date_for_name(reply, wi_date_with_sqlite3_string(instance), WI_STR("wired.banlist.expiration_date")); wd_user_reply_message(user, reply, message); } if(!results) { wi_log_error(WI_STR("Could not execute database statement: %m")); wd_user_reply_internal_error(user, wi_error_string(), message); return; } reply = wi_p7_message_with_name(WI_STR("wired.banlist.list.done"), wd_p7_spec); wd_user_reply_message(user, reply, message); }
wi_string_t * _wi_string_constant_string(const char *cstring) { wi_string_t *string; wi_lock_lock(_wi_string_constant_string_lock); string = wi_dictionary_data_for_key(_wi_string_constant_string_table, (void *) cstring); if(!string) { string = wi_string_init_with_cstring(wi_string_alloc(), cstring); wi_mutable_dictionary_set_data_for_key(_wi_string_constant_string_table, string, (void *) cstring); wi_release(string); } wi_lock_unlock(_wi_string_constant_string_lock); return string; }
static wi_boolean_t _wi_dictionary_is_equal(wi_runtime_instance_t *instance1, wi_runtime_instance_t *instance2) { wi_dictionary_t *dictionary1 = instance1; wi_dictionary_t *dictionary2 = instance2; _wi_dictionary_bucket_t *bucket; wi_uinteger_t i; if(dictionary1->key_count != dictionary2->key_count) return false; if(dictionary1->value_callbacks.is_equal != dictionary2->value_callbacks.is_equal) return false; for(i = 0; i < dictionary1->buckets_count; i++) { for(bucket = dictionary1->buckets[i]; bucket; bucket = bucket->next) { if(!_WI_DICTIONARY_VALUE_IS_EQUAL(dictionary1, bucket->data, wi_dictionary_data_for_key(dictionary2, bucket->key))) return false; } } return true; }
static void wt_update_servers(wi_timer_t *timer) { wi_enumerator_t *enumerator; wt_server_t *server; void *key; wi_time_interval_t interval, update; wi_boolean_t changed = false; wi_dictionary_wrlock(wt_servers); if(wi_dictionary_count(wt_servers) > 0) { interval = wi_time_interval(); enumerator = wi_array_data_enumerator(wi_dictionary_all_keys(wt_servers)); while((key = wi_enumerator_next_data(enumerator))) { server = wi_dictionary_data_for_key(wt_servers, key); update = server->update_time > 0.0 ? server->update_time : server->register_time; if(interval - update > wt_settings.minupdatetime) { wi_log_warn(WI_STR("Deleting \"%@\" with URL %@: Last update %.0f seconds ago considered too slow"), server->name, server->url, interval - update); wt_servers_remove_stats_for_server(server); wi_dictionary_remove_data_for_key(wt_servers, key); changed = true; } } } wi_dictionary_unlock(wt_servers); if(changed) { wi_lock_lock(wt_status_lock); wt_write_status(true); wi_lock_unlock(wt_status_lock); wt_servers_write_file(); } }
void wd_chats_remove_user(wd_user_t *user) { wi_enumerator_t *enumerator; wd_chat_t *chat; void *key; wi_dictionary_wrlock(wd_chats); enumerator = wi_array_data_enumerator(wi_dictionary_all_keys(wd_chats)); while((key = wi_enumerator_next_data(enumerator))) { chat = wi_dictionary_data_for_key(wd_chats, key); wi_array_wrlock(chat->users); wi_mutable_array_remove_data(chat->users, user); wi_array_unlock(chat->users); if(chat != wd_public_chat && wi_array_count(chat->users) == 0) wi_mutable_dictionary_remove_data_for_key(wd_chats, key); } wi_dictionary_unlock(wd_chats); }
wi_string_t * wi_p7_message_enum_name_for_name(wi_p7_message_t *p7_message, wi_string_t *field_name) { wi_p7_spec_field_t *field; wi_dictionary_t *enums; wi_p7_enum_t enum_value; if(!wi_p7_message_get_enum_for_name(p7_message, &enum_value, field_name)) return NULL; field = wi_p7_spec_field_with_name(p7_message->spec, field_name); enums = wi_p7_spec_field_enums_by_value(field); if(!wi_dictionary_contains_key(enums, (void *) (intptr_t) enum_value)) { wi_error_set_libwired_error_with_format(WI_ERROR_P7_UNKNOWNFIELD, WI_STR("No name found for enum \"%u\""), enum_value); if(wi_p7_message_debug) wi_log_debug(WI_STR("wi_p7_message_enum_name_for_name: %m")); return NULL; } return wi_dictionary_data_for_key(enums, (void *) (intptr_t) enum_value); }
static wi_boolean_t wd_transfer_download(wd_transfer_t *transfer) { wi_pool_t *pool; wi_socket_t *socket; wi_p7_socket_t *p7_socket; wd_account_t *account; char buffer[WD_TRANSFER_BUFFER_SIZE]; wi_socket_state_t state; wi_time_interval_t timeout, interval, speedinterval, statusinterval, accountinterval; wi_file_offset_t sendbytes, speedbytes, statsbytes; wi_uinteger_t i, transfers; ssize_t readbytes; int sd; wi_boolean_t data, result; wd_user_state_t user_state; interval = wi_time_interval(); speedinterval = interval; statusinterval = interval; accountinterval = interval; speedbytes = 0; statsbytes = 0; i = 0; socket = wd_user_socket(transfer->user); sd = wi_socket_descriptor(socket); p7_socket = wd_user_p7_socket(transfer->user); account = wd_user_account(transfer->user); data = true; result = true; wd_transfers_note_statistics(WD_TRANSFER_DOWNLOAD, WD_TRANSFER_STATISTICS_ADD, 0); wi_dictionary_rdlock(wd_transfers_user_downloads); transfers = (wi_integer_t) wi_dictionary_data_for_key(wd_transfers_user_downloads, transfer->key); wi_dictionary_unlock(wd_transfers_user_downloads); pool = wi_pool_init(wi_pool_alloc()); wd_user_lock_socket(transfer->user); while(wd_user_state(transfer->user) == WD_USER_LOGGED_IN) { if(data && transfer->remainingdatasize == 0) data = false; if(!data && transfer->remainingrsrcsize == 0) break; readbytes = read(data ? transfer->datafd : transfer->rsrcfd, buffer, sizeof(buffer)); if(readbytes <= 0) { if(readbytes < 0) { wi_log_error(WI_STR("Could not read download from \"%@\": %m"), data ? transfer->realdatapath : transfer->realrsrcpath, strerror(errno)); } result = false; break; } timeout = wi_time_interval(); do { user_state = wd_user_state(transfer->user); state = wi_socket_wait_descriptor(sd, 0.1, false, true); if(state == WI_SOCKET_TIMEOUT) { if(wi_time_interval() - timeout >= 30.0) break; } } while(state == WI_SOCKET_TIMEOUT && user_state == WD_USER_LOGGED_IN); if(state == WI_SOCKET_ERROR || wi_time_interval() - timeout >= 30.0) { wi_log_error(WI_STR("Could not wait for download to %@: %@"), wd_user_identifier(transfer->user), (state == WI_SOCKET_ERROR) ? wi_error_string() : WI_STR("Timed out")); result = false; break; } if(user_state != WD_USER_LOGGED_IN) { result = false; break; } if(data) { sendbytes = (transfer->remainingdatasize < (wi_file_offset_t) readbytes) ? transfer->remainingdatasize : (wi_file_offset_t) readbytes; } else { sendbytes = (transfer->remainingrsrcsize < (wi_file_offset_t) readbytes) ? transfer->remainingrsrcsize : (wi_file_offset_t) readbytes; } if(!wi_p7_socket_write_oobdata(p7_socket, 30.0, buffer, sendbytes)) { wi_log_error(WI_STR("Could not write download to %@: %m"), wd_user_identifier(transfer->user)); result = false; break; } if(data) transfer->remainingdatasize -= sendbytes; else transfer->remainingrsrcsize -= sendbytes; interval = wi_time_interval(); transfer->transferred += sendbytes; transfer->actualtransferred += sendbytes; speedbytes += sendbytes; statsbytes += sendbytes; transfer->speed = speedbytes / (interval - speedinterval); wd_transfer_limit_speed(transfer, wd_transfers_total_download_speed, wd_account_transfer_download_speed_limit(account), wd_current_downloads, transfers, speedbytes, interval, speedinterval); if(interval - speedinterval > 30.0) { speedbytes = 0; speedinterval = interval; } if(interval - statusinterval > wd_current_downloads) { wd_transfers_note_statistics(WD_TRANSFER_DOWNLOAD, WD_TRANSFER_STATISTICS_DATA, statsbytes); statsbytes = 0; statusinterval = interval; } if(interval - accountinterval > 15.0) { account = wd_user_account(transfer->user); accountinterval = interval; wi_dictionary_rdlock(wd_transfers_user_downloads); transfers = (wi_integer_t) wi_dictionary_data_for_key(wd_transfers_user_downloads, transfer->key); wi_dictionary_unlock(wd_transfers_user_downloads); } if(++i % 1000 == 0) wi_pool_drain(pool); } wd_user_unlock_socket(transfer->user); wi_release(pool); wd_transfers_note_statistics(WD_TRANSFER_DOWNLOAD, WD_TRANSFER_STATISTICS_REMOVE, statsbytes); return result; }
static wi_runtime_instance_t * _wi_config_instance_for_setting(wi_config_t *config, wi_string_t *name, wi_string_t *value, wi_config_type_t *type) { struct passwd *user; struct group *group; struct servent *servent; wi_uinteger_t port; uint32_t uid, gid; if(!wi_dictionary_contains_key(config->types, name)) { wi_error_set_libwired_error(WI_ERROR_SETTINGS_UNKNOWNSETTING); return NULL; } *type = wi_number_int32(wi_dictionary_data_for_key(config->types, name)); switch(*type) { case WI_CONFIG_INTEGER: return wi_number_with_integer(wi_string_integer(value)); break; case WI_CONFIG_BOOL: return wi_number_with_bool(wi_string_bool(value)); break; case WI_CONFIG_STRING: case WI_CONFIG_STRINGLIST: case WI_CONFIG_PATH: return value; break; case WI_CONFIG_USER: user = getpwnam(wi_string_cstring(value)); if(!user) { uid = wi_string_uint32(value); if(uid != 0 || wi_is_equal(value, WI_STR("0"))) user = getpwuid(uid); } if(!user) { wi_error_set_libwired_error(WI_ERROR_SETTINGS_NOSUCHUSER); return NULL; } return wi_number_with_int32(user->pw_uid); break; case WI_CONFIG_GROUP: group = getgrnam(wi_string_cstring(value)); if(!group) { gid = wi_string_uint32(value); if(gid != 0 || wi_is_equal(value, WI_STR("0"))) group = getgrgid(gid); } if(!group) { wi_error_set_libwired_error(WI_ERROR_SETTINGS_NOSUCHGROUP); return NULL; } return wi_number_with_int32(group->gr_gid); break; case WI_CONFIG_PORT: port = wi_string_uinteger(value); if(port > 65535) { wi_error_set_libwired_error(WI_ERROR_SETTINGS_INVALIDPORT); return NULL; } if(port == 0) { servent = getservbyname(wi_string_cstring(value), "tcp"); if(!servent) { wi_error_set_libwired_error(WI_ERROR_SETTINGS_NOSUCHSERVICE); return NULL; } port = servent->s_port; } return wi_number_with_int32(port); break; case WI_CONFIG_REGEXP: return wi_autorelease(wi_regexp_init_with_string(wi_regexp_alloc(), value)); break; case WI_CONFIG_TIME_INTERVAL: return wi_number_with_double(wi_string_double(value)); break; } return NULL; }
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); }
static wi_boolean_t _wi_plist_write_instance_to_node(wi_runtime_instance_t *instance, xmlNodePtr node) { wi_enumerator_t *enumerator; wi_array_t *keys; wi_runtime_instance_t *value; xmlNodePtr child_node; void *key; wi_runtime_id_t id; wi_number_type_t type; 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_dictionary_all_keys(instance); wi_array_sort(keys, wi_string_compare); enumerator = wi_array_data_enumerator(keys); while((key = wi_enumerator_next_data(enumerator))) { 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; }
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; }
static wi_string_t * _wi_p7_message_field_string_value(wi_p7_message_t *p7_message, wi_p7_spec_field_t *field) { wi_string_t *field_name, *field_value = NULL; wi_uuid_t *uuid; wi_date_t *date; wi_p7_boolean_t p7_bool; wi_p7_enum_t p7_enum; 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; field_name = wi_p7_spec_field_name(field); switch(wi_p7_spec_type_id(wi_p7_spec_field_type(field))) { 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("%@"), p7_bool ? WI_STR("true") : WI_STR("false")); break; case WI_P7_ENUM: if(wi_p7_message_get_enum_for_name(p7_message, &p7_enum, field_name)) field_value = wi_dictionary_data_for_key(wi_p7_spec_field_enums_by_value(field), (void *) (intptr_t) p7_enum); 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("%d"), 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("%0.16f"), p7_double); break; case WI_P7_STRING: string = wi_p7_message_string_for_name(p7_message, field_name); if(string) field_value = wi_string_with_format(WI_STR("\"%@\""), string); break; case WI_P7_UUID: uuid = wi_p7_message_uuid_for_name(p7_message, field_name); if(uuid) field_value = wi_string_with_format(WI_STR("%@"), 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("%@"), wi_date_string_with_format(date, WI_STR("%Y-%m-%d %H:%M:%S %z"))); break; case WI_P7_DATA: data = wi_p7_message_data_for_name(p7_message, field_name); if(data) field_value = wi_string_with_format(WI_STR("%@"), 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) field_value = wi_array_components_joined_by_string(list, WI_STR(", ")); break; } return field_value; }
wi_boolean_t wd_banlist_ip_is_banned(wi_string_t *ip, wi_date_t **expiration_date) { wi_sqlite3_statement_t *statement; wi_dictionary_t *results; wi_runtime_instance_t *instance; wi_date_t *date; wi_boolean_t ret; // delete expired ban item if(!wi_sqlite3_execute_statement(wd_database, WI_STR("DELETE FROM banlist " "WHERE strftime('%%s', 'now') - STRFTIME('%%s', expiration_date) > 0"), NULL)) { wi_log_error(WI_STR("Could not execute database statement: %m")); } statement = wi_sqlite3_prepare_statement(wd_database, WI_STR("SELECT ip, expiration_date FROM banlist"), NULL); if(!statement) { wi_log_error(WI_STR("Could not execute database statement: %m")); return false; } ret = false; // check if the user IP exist in the database // if yes, verify the expiration_date while((results = wi_sqlite3_fetch_statement_results(wd_database, statement)) && wi_dictionary_count(results) > 0) { if(wi_ip_matches_string(wi_dictionary_data_for_key(results, WI_STR("ip")), ip)) { instance = wi_dictionary_data_for_key(results, WI_STR("expiration_date")); if(instance != wi_null()) { date = wi_date_with_sqlite3_string(instance); if(wi_date_valid_expiration_date(date)) { *expiration_date = date; ret = true; continue; } else { if(!wi_sqlite3_execute_statement(wd_database, WI_STR("DELETE FROM banlist WHERE ip = ?"), ip, NULL)) { wi_log_error(WI_STR("Could not execute database statement: %m")); } *expiration_date = NULL; ret = false; continue; } } ret = true; continue; } } if(!results) { wi_log_error(WI_STR("Could not execute database statement: %m")); return false; } return ret; }
wi_boolean_t wi_config_read_file(wi_config_t *config) { wi_enumerator_t *enumerator; wi_runtime_instance_t *instance; wi_file_t *file; wi_mutable_array_t *array; wi_mutable_dictionary_t *previous_values; wi_string_t *string, *name, *value; wi_config_type_t type; file = wi_file_for_reading(config->path); if(!file) { wi_log_err(WI_STR("Could not open %@: %m"), config->path); return false; } wi_log_info(WI_STR("Reading %@"), config->path); config->line = 0; wi_lock_lock(config->lock); previous_values = config->values; config->values = wi_dictionary_init(wi_mutable_dictionary_alloc()); if(config->defaults) { enumerator = wi_dictionary_key_enumerator(config->defaults); while((name = wi_enumerator_next_data(enumerator))) { // instance = wi_mutable_copy(wi_dictionary_data_for_key(config->defaults, name)); instance = wi_dictionary_data_for_key(config->defaults, name); if(wi_runtime_id(instance) == wi_array_runtime_id()) instance = wi_autorelease(wi_mutable_copy(instance)); wi_mutable_dictionary_set_data_for_key(config->values, instance, name); // wi_release(instance); } } while((string = wi_file_read_line(file))) { config->line++; if(wi_string_length(string) > 0 && !wi_string_has_prefix(string, WI_STR("#"))) { if(_wi_config_parse_string(config, string, &name, &value)) { instance = _wi_config_instance_for_setting(config, name, value, &type); if(instance) { wi_log_debug(WI_STR(" %@ = %@"), name, value); if(type == WI_CONFIG_STRINGLIST) { array = wi_dictionary_data_for_key(config->values, name); if(!array) { array = wi_mutable_array(); wi_mutable_dictionary_set_data_for_key(config->values, array, name); } wi_mutable_array_add_data(array, instance); } else { wi_mutable_dictionary_set_data_for_key(config->values, instance, name); } } else { _wi_config_log_error(config, name); } } else { wi_error_set_libwired_error(WI_ERROR_SETTINGS_SYNTAXERROR); _wi_config_log_error(config, string); } } } enumerator = wi_dictionary_key_enumerator(config->values); while((name = wi_enumerator_next_data(enumerator))) { instance = wi_dictionary_data_for_key(config->values, name); if(!previous_values || !wi_is_equal(instance, wi_dictionary_data_for_key(previous_values, name))) wi_mutable_set_add_data(config->changes, name); } wi_release(previous_values); wi_lock_unlock(config->lock); return true; }
wd_user_t * wd_users_user_for_thread(void) { return wi_dictionary_data_for_key(wi_thread_dictionary(), WI_STR(WD_USERS_THREAD_KEY)); }
wr_user_t * wr_chat_user_with_uid(wr_chat_t *chat, wr_uid_t uid) { return wi_dictionary_data_for_key(chat->users_dictionary, wi_number_with_integer(uid)); }