Exemple #1
0
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;
}
Exemple #2
0
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;
}
Exemple #3
0
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);
}
Exemple #4
0
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);
}
Exemple #5
0
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;
}
Exemple #6
0
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;
}
Exemple #7
0
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;
}
Exemple #8
0
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;
}
Exemple #9
0
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;
}
Exemple #10
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;
}
Exemple #11
0
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;
}
Exemple #12
0
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;
}
Exemple #13
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;
}
Exemple #14
0
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);
}
Exemple #15
0
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);
}
Exemple #16
0
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;
}
Exemple #17
0
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;
}
Exemple #18
0
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();
	}
}
Exemple #19
0
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);
}
Exemple #20
0
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);
}
Exemple #21
0
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;
}
Exemple #22
0
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;
}
Exemple #23
0
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);
}
Exemple #24
0
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;
}
Exemple #25
0
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;
}
Exemple #26
0
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;
}
Exemple #27
0
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;
}
Exemple #28
0
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;
}
Exemple #29
0
wd_user_t * wd_users_user_for_thread(void) {
	return wi_dictionary_data_for_key(wi_thread_dictionary(), WI_STR(WD_USERS_THREAD_KEY));
}
Exemple #30
0
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));
}