Beispiel #1
0
static void wd_cmd_pass(wi_array_t *arguments) {
	wd_client_t		*client = wd_client();
	wi_string_t		*password;
	wd_chat_t		*chat;

	if(client->state != WD_CLIENT_STATE_GAVE_USER)
		return;
	
	client->account = wi_retain(wd_accounts_read_user_and_group(client->login));
	
	if(!client->account) {
		wd_reply(510, WI_STR("Login Failed"));
		wi_log_info(WI_STR("Login from %@/%@/%@ failed: %@"),
			client->nick, client->login, client->ip,
			WI_STR("No such account"));

		return;
	}
	
	password = WI_ARRAY(arguments, 0);
	
	if(!wi_is_equal(client->account->password, password)) {
		wd_reply(510, WI_STR("Login Failed"));
		wi_log_info(WI_STR("Login from %@/%@/%@ failed: %@"),
			client->nick, client->login, client->ip,
			WI_STR("Wrong password"));

		return;
	}
	
	wi_log_info(WI_STR("Login from %@/%@/%@ succeeded"),
	   client->nick, client->login, client->ip);

	wi_lock_lock(client->flag_lock);
	client->admin = (client->account->kick_users || client->account->ban_users);
	client->state = WD_CLIENT_STATE_LOGGED_IN;
	wi_lock_unlock(client->flag_lock);

	wi_lock_lock(wd_status_lock);
	wd_current_users++;
	wd_total_users++;
	wd_write_status(true);
	wi_lock_unlock(wd_status_lock);

	wd_reply(201, WI_STR("%u"), client->uid);
	
	chat = wd_chat_with_cid(WD_PUBLIC_CID);
	wd_chat_add_client(chat, client);
}
Beispiel #2
0
void wd_transfer_loop(wd_transfer_t *transfer) {
	if(transfer->timer)
		wd_transfer_remove_timer(transfer);
	
	wi_condition_lock_lock(transfer->state_lock);

	if(transfer->state == WD_TRANSFER_WAITING) {
		transfer->state = WD_TRANSFER_RUNNING;
		wi_condition_lock_unlock_with_condition(transfer->state_lock, transfer->state);

		if(transfer->type == WD_TRANSFER_DOWNLOAD)
			wd_transfer_download(transfer);
		else
			wd_transfer_upload(transfer);
	} else {
		wi_condition_lock_unlock(transfer->state_lock);
	}

	wi_lock_lock(wd_transfers_update_queue_lock);

	wi_array_wrlock(wd_transfers);
	wi_mutable_array_remove_data(wd_transfers, transfer);
	wi_array_unlock(wd_transfers);

	wd_transfers_update_queue();

	wi_lock_unlock(wd_transfers_update_queue_lock);
}
Beispiel #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);
}
Beispiel #4
0
void wd_transfers_queue_download(wi_string_t *path, wi_file_offset_t offset) {
	wd_user_t			*user = wd_users_user_for_thread();
	wi_string_t			*realpath;
	wd_transfer_t		*transfer;
	wi_fs_stat_t		sb;
	
	realpath = wi_string_by_resolving_aliases_in_path(wd_files_real_path(path));
	
	if(!wi_fs_stat_path(realpath, &sb)) {
		wi_log_err(WI_STR("Could not open %@: %m"), realpath);
		wd_reply_error();

		return;
	}
	
	transfer				= wi_autorelease(wd_transfer_init_download_with_user(wd_transfer_alloc(), user));
	transfer->path			= wi_retain(path);
	transfer->realpath		= wi_retain(realpath);
	transfer->size			= sb.size;
	transfer->offset		= offset;
	transfer->transferred	= offset;
	
	wi_lock_lock(wd_transfers_update_queue_lock);
	
	wi_array_wrlock(wd_transfers);
	wi_mutable_array_add_data(wd_transfers, transfer);
	wi_array_unlock(wd_transfers);
	
	wd_transfers_update_queue();

	wi_lock_unlock(wd_transfers_update_queue_lock);
}
Beispiel #5
0
static void wd_transfers_note_statistics(wd_transfer_type_t type, wd_transfers_statistics_type_t statistics, wi_file_offset_t bytes) {
	wi_lock_lock(wd_status_lock);

	if(type == WD_TRANSFER_DOWNLOAD) {
		if(statistics == WD_TRANSFER_STATISTICS_ADD) {
			wd_current_downloads++;
			wd_total_downloads++;
		}
		else if(statistics == WD_TRANSFER_STATISTICS_REMOVE) {
			wd_current_downloads--;
		}
		
		wd_downloads_traffic += bytes;
	} else {
		if(statistics == WD_TRANSFER_STATISTICS_ADD) {
			wd_current_uploads++;
			wd_total_uploads++;
		}
		else if(statistics == WD_TRANSFER_STATISTICS_REMOVE) {
			wd_current_uploads--;
		}
		
		wd_uploads_traffic += bytes;
	}

	wd_write_status((statistics != WD_TRANSFER_STATISTICS_DATA));
	
	wi_lock_unlock(wd_status_lock);
}
Beispiel #6
0
void wt_write_servers(void) {
	static char				magic[] = WT_SERVER_MAGIC;
	static uint32_t			version = WT_SERVER_VERSION;
	FILE					*fp;
	wi_list_node_t			*node;
	wt_server_t				*server;
	wt_server_packed_t		server_packed;

	wi_lock_lock(wt_servers_lock);
	fp = fopen(wi_string_cstring(wt_settings.servers), "w");

	if(!fp) {
		wi_log_warn(WI_STR("Could not open %@: %s"),
			wt_settings.servers, strerror(errno));

		goto end;
	}

	fwrite(magic, 4, 1, fp);
	fwrite(&version, 4, 1, fp);

	wi_list_rdlock(wt_servers);
	WI_LIST_FOREACH(wt_servers, node, server) {
		server_packed = wt_server_packed(server);
		fwrite(&server_packed, sizeof(wt_server_packed_t), 1, fp);
	}
Beispiel #7
0
static void _wi_pool_add_poolstack(_wi_pool_stack_t *stack) {
	uint32_t		index, capacity, length;
	
	index = wi_hash_pointer(stack->thread) % _WI_POOL_STACKS_BUCKETS;
	
	wi_lock_lock(_wi_pool_stacks_lock);
	
	capacity	= _wi_pool_stacks_capacities[index];
	length		= _wi_pool_stacks_lengths[index];
	
	if(length >= capacity) {
		capacity += capacity;
		
		if(capacity < _WI_POOL_STACKS_INITIAL_SIZE)
			capacity = _WI_POOL_STACKS_INITIAL_SIZE;
		
		_wi_pool_stacks[index] = wi_realloc(_wi_pool_stacks[index], capacity * sizeof(_wi_pool_stack_t));
		_wi_pool_stacks_capacities[index] = capacity;
	}
	
	_wi_pool_stacks[index][length] = stack;
	_wi_pool_stacks_lengths[index] = ++length;
	
	wi_lock_unlock(_wi_pool_stacks_lock);
}
Beispiel #8
0
static void _wi_pool_remove_poolstack(_wi_pool_stack_t *stack, uint32_t stack_index) {
	_wi_pool_stack_t		**stacks;
	uint32_t				index, length;
	
	index = wi_hash_pointer(wi_thread_current_thread()) % _WI_POOL_STACKS_BUCKETS;

	wi_lock_lock(_wi_pool_stacks_lock);
	
	length = _wi_pool_stacks_lengths[index] - 1;
	stacks = _wi_pool_stacks[index];
	
	stacks[stack_index] = NULL;
	_wi_pool_stacks_lengths[index] = length;
	
	if(stack_index < length) {
		memmove(&stacks[stack_index],
				&stacks[stack_index + 1],
				sizeof(_wi_pool_stack_t **) * length);
	}
	
	if(stack->pools)
		wi_free(stack->pools);
	
	wi_free(stack);
	
	wi_lock_unlock(_wi_pool_stacks_lock);
}
Beispiel #9
0
void wt_server_stats_remove(wt_server_t *server) {
	wi_lock_lock(wt_status_lock);
	wt_current_servers--;
	wt_current_users -= server->users;
	wt_current_files -= server->files;
	wt_current_size -= server->size;
	wi_lock_unlock(wt_status_lock);
}
Beispiel #10
0
void wt_server_stats_add(wt_server_t *server) {
	wi_lock_lock(wt_status_lock);
	wt_current_servers++;
	wt_current_users += server->users;
	wt_current_files += server->files;
	wt_current_size += server->size;
	wi_lock_unlock(wt_status_lock);
}
Beispiel #11
0
static void _wi_log_vlog(int priority, wi_string_t *fmt, va_list ap) {
	wi_string_t		*string;
	FILE			*fp;
	const char		*cstring, *name, *path;
	char			date[_WI_LOG_DATE_SIZE];
	
	string = wi_string_init_with_format_and_arguments(wi_string_alloc(), fmt, ap);
	cstring = wi_string_cstring(string);

	wi_lock_lock(_wi_log_lock);
	
	name = wi_string_cstring(wi_process_name(wi_process()));
	
	_wi_log_date(date);

	if(wi_log_stdout || wi_log_stderr)
		fprintf(wi_log_stdout ? stdout : stderr, "%s %s[%d]: %s\n", date, name, getpid(), cstring);
	else if(wi_log_startup && priority < LOG_INFO)
		fprintf(stderr, "%s: %s\n", name, cstring);
	else if(wi_log_tool)
		fprintf((priority < LOG_INFO) ? stderr : stdout, "%s: %s\n", name, cstring);

	if(wi_log_syslog)
		syslog(priority, "%s", cstring);

	if(wi_log_file && wi_log_path) {
		path = wi_string_cstring(wi_full_path(wi_log_path));

		fp = fopen(path, "a");

		if(fp) {
			fprintf(fp, "%s %s[%d]: %s\n", date, name, getpid(), cstring);
			fclose(fp);
			
			if(_wi_log_lines > 0 && wi_log_limit > 0) {
				if(_wi_log_lines % (int) ((float) wi_log_limit / 10.0f) == 0) {
					_wi_log_truncate(path);
					
					_wi_log_lines = wi_log_limit;
				}
			}
			
			_wi_log_lines++;
		} else {
			fprintf(stderr, "%s: %s: %s\n", name, path, strerror(errno));
		}
	}

	if(wi_log_callback)
		(*wi_log_callback)(string);

	if(wi_log_startup && priority == LOG_ERR)
		exit(1);

	wi_lock_unlock(_wi_log_lock);
	
	wi_release(string);
}
Beispiel #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;
}
Beispiel #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;
}
Beispiel #14
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;
}
Beispiel #15
0
static void wd_transfer_accept_thread(wi_runtime_instance_t *argument) {
	wi_pool_t			*pool;
	wi_socket_t			*socket = argument;
	wi_array_t			*arguments;
	wi_string_t			*ip, *string, *command;
	wd_transfer_t		*transfer;
	
	pool = wi_pool_init(wi_pool_alloc());
	
	ip = wi_address_string(wi_socket_address(socket));
	
	if(!wi_socket_accept_tls(socket, wd_transfer_socket_tls, 30.0)) {
		wi_log_err(WI_STR("Could not accept a connection for %@: %m"), ip);
		
		goto end;
	}
	
	if(!wi_socket_set_timeout(socket, 30.0))
		wi_log_warn(WI_STR("Could not set timeout for %@: %m"), ip);
	
	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);
		
		goto end;
	}
	
	wi_parse_wired_command(string, &command, &arguments);
	
	if(wi_is_equal(command, WI_STR("TRANSFER")) && wi_array_count(arguments) >= 1) {
		transfer = wd_transfers_transfer_with_hash(WI_ARRAY(arguments, 0));
		
		if(!transfer)
			goto end;
		
		if(!wi_is_equal(ip, wd_user_ip(transfer->user)))
			goto end;
		
		wi_lock_lock(transfer->socket_lock);
		
		if(!transfer->socket) {
			transfer->socket = wi_retain(socket);
			wi_lock_unlock(transfer->socket_lock);
		
			wd_transfer_loop(transfer);
		} else {
			wi_lock_unlock(transfer->socket_lock);
		}
	}

end:
	wi_socket_close(socket);

	wi_release(pool);
}
Beispiel #16
0
static void wt_cmd_servers(wi_array_t *arguments) {
	/* reply all servers */
	wt_servers_reply_server_list();

	/* update status */
	wi_lock_lock(wt_status_lock);
	wt_total_clients++;
	wt_write_status(true);
	wi_lock_unlock(wt_status_lock);
}
Beispiel #17
0
static void _wi_socket_ssl_locking_function(int mode, int n, const char *file, int line) {
	wi_lock_t		*lock;
	
	lock = WI_ARRAY(_wi_socket_ssl_locks, n);
	
	if(mode & CRYPTO_LOCK)
		wi_lock_lock(lock);
	else
		wi_lock_unlock(lock);
}
Beispiel #18
0
static wd_uid_t wd_user_next_id(void) {
	wd_uid_t	id;
	
	wi_lock_lock(wd_users_id_lock);
	
	id = ++wd_users_current_id;

	wi_lock_unlock(wd_users_id_lock);

	return id;
}
Beispiel #19
0
wt_server_t * wt_server_init(wt_server_t *server) {
	wi_list_wrlock(wt_servers);
	wi_list_append_data(wt_servers, server);
	wi_list_unlock(wt_servers);
	
	wi_lock_lock(wt_status_lock);
	wt_current_servers++;
	wt_write_status(true);
	wi_lock_unlock(wt_status_lock);
	
	return server;
}
Beispiel #20
0
void wd_transfers_queue_upload(wi_string_t *path, wi_file_offset_t size, wi_string_t *checksum) {
	wd_user_t			*user = wd_users_user_for_thread();
	wi_string_t			*realpath, *filechecksum;
	wd_transfer_t		*transfer;
	wi_file_offset_t	offset;
	wi_fs_stat_t		sb;
	
	realpath = wi_string_by_resolving_aliases_in_path(wd_files_real_path(path));
	
	if(wi_fs_stat_path(realpath, &sb)) {
		wd_reply(521, WI_STR("File or Directory Exists"));

		return;
	}
	
	if(!wi_string_has_suffix(realpath, WI_STR(WD_TRANSFERS_PARTIAL_EXTENSION)))
		realpath = wi_string_by_appending_path_extension(realpath, WI_STR(WD_TRANSFERS_PARTIAL_EXTENSION));
	
	if(!wi_fs_stat_path(realpath, &sb)) {
		offset = 0;
	} else {
		offset = sb.size;
		
		if(sb.size >= WD_FILES_CHECKSUM_SIZE) {
			filechecksum = wi_fs_sha1_for_path(realpath, WD_FILES_CHECKSUM_SIZE);
			
			if(!wi_is_equal(filechecksum, checksum)) {
				wd_reply(522, WI_STR("Checksum Mismatch"));
				
				return;
			}
		}
	}
	
	transfer				= wi_autorelease(wd_transfer_init_upload_with_user(wd_transfer_alloc(), user));
	transfer->path			= wi_retain(path);
	transfer->realpath		= wi_retain(realpath);
	transfer->size			= size;
	transfer->offset		= offset;
	transfer->transferred	= offset;
	
	wi_lock_lock(wd_transfers_update_queue_lock);

	wi_array_wrlock(wd_transfers);
	wi_mutable_array_add_data(wd_transfers, transfer);
	wi_array_unlock(wd_transfers);
	
	wd_transfers_update_queue();

	wi_lock_unlock(wd_transfers_update_queue_lock);
}
Beispiel #21
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);
}
Beispiel #22
0
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);
}
Beispiel #23
0
static wd_uid_t wd_user_next_uid(void) {
	wd_uid_t	uid;
	
	wi_lock_lock(wd_users_uid_lock);
	wi_dictionary_rdlock(wd_users);
	
	if(wi_dictionary_count(wd_users) == 0)
		wd_users_current_uid = 0;
	
	uid = ++wd_users_current_uid;

	wi_dictionary_unlock(wd_users);
	wi_lock_unlock(wd_users_uid_lock);

	return uid;
}
Beispiel #24
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;
}
Beispiel #25
0
void wd_transfers_remove_user(wd_user_t *user) {
	wd_transfer_t			*transfer;
	wi_boolean_t			update = false;
	wi_uinteger_t			i, count;
	wd_transfer_state_t		state;

	wi_lock_lock(wd_transfers_update_queue_lock);
	wi_array_wrlock(wd_transfers);
	
	count = wi_array_count(wd_transfers);
	
	for(i = 0; i < count; i++) {
		transfer = WI_ARRAY(wd_transfers, i);
		
		if(transfer->user == user) {
			state = wd_transfer_state(transfer);
			
			if(state == WD_TRANSFER_RUNNING) {
				wi_array_unlock(wd_transfers);
				
				wd_transfer_set_state(transfer, WD_TRANSFER_STOP);
				
				wi_condition_lock_lock_when_condition(transfer->state_lock, WD_TRANSFER_STOPPED, 1.0);
				wi_condition_lock_unlock(transfer->state_lock);
				
				wi_array_wrlock(wd_transfers);
			}
			else if(state == WD_TRANSFER_QUEUED || state == WD_TRANSFER_WAITING) {
				if(transfer->timer)
					wd_transfer_remove_timer(transfer);
				
				wi_mutable_array_remove_data_at_index(wd_transfers, i);

				count--;
				i--;
				update = true;
			}
		}
	}
	
	wi_array_unlock(wd_transfers);
	
	if(update)
		wd_transfers_update_queue();

	wi_lock_unlock(wd_transfers_update_queue_lock);
}
Beispiel #26
0
static void wd_transfer_expire_timer(wi_timer_t *timer) {
	wd_transfer_t		*transfer;
	
	transfer = wi_timer_data(timer);
	
	wi_lock_lock(wd_transfers_update_queue_lock);
	
	wi_array_wrlock(wd_transfers);
	wi_mutable_array_remove_data(wd_transfers, transfer);
	wi_array_unlock(wd_transfers);
	
	wd_transfers_update_queue();
	
	wi_lock_unlock(wd_transfers_update_queue_lock);

	wi_release(transfer);
}
Beispiel #27
0
static void wd_cmd_ban(wi_array_t *arguments) {
	wd_client_t		*client = wd_client();
	wd_client_t		*peer;
	wd_uid_t		uid;
	
	if(!client->account->ban_users) {
		wd_reply(516, WI_STR("Permission Denied"));
		
		return;
	}

	uid = wi_string_uint32(WI_ARRAY(arguments, 0));
	peer = wd_client_with_uid(uid);

	if(!peer) {
		wd_reply(512, WI_STR("Client Not Found"));

		return;
	}

	if(peer->account->cannot_be_kicked) {
		wd_reply(515, WI_STR("Cannot Be Disconnected"));

		return;
	}

	wd_broadcast_lock();
	wd_broadcast(WD_PUBLIC_CID, 307, WI_STR("%u%c%u%c%#@"),
				 peer->uid,		WD_FIELD_SEPARATOR,
				 client->uid,	WD_FIELD_SEPARATOR,
				 WI_ARRAY(arguments, 1));
	wd_broadcast_unlock();

	wi_log_ll(WI_STR("%@/%@/%@ banned %@/%@/%@"),
		client->nick, client->login, client->ip,
		peer->nick, peer->login, peer->ip);

	wd_tempban(peer->ip);

	wi_lock_lock(peer->flag_lock);
	peer->state = WD_CLIENT_STATE_DISCONNECTED;
	wi_lock_unlock(peer->flag_lock);
}
Beispiel #28
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();
	}
}
Beispiel #29
0
void wt_servers_write_file(void) {
	static char				magic[] = WT_SERVER_MAGIC;
	static uint32_t			version = WT_SERVER_VERSION;
	FILE					*fp;
	wi_enumerator_t			*enumerator;
	wt_server_t				*server;
	wt_server_packed_t		server_packed;

	wi_lock_lock(wt_servers_lock);
	fp = fopen(wi_string_cstring(wt_settings.servers), "w");

	if(!fp) {
		wi_log_warn(WI_STR("Could not open %@: %s"),
			wt_settings.servers, strerror(errno));

		goto end;
	}

	fwrite(magic, 4, 1, fp);
	fwrite(&version, 4, 1, fp);

	wi_dictionary_rdlock(wt_servers);
	
	enumerator = wi_dictionary_data_enumerator(wt_servers);
	
	while((server = wi_enumerator_next_data(enumerator))) {
		server_packed = wt_server_packed(server);
		fwrite(&server_packed, sizeof(wt_server_packed_t), 1, fp);
	}

	wi_dictionary_unlock(wt_servers);

	fclose(fp);

end:
	wi_lock_unlock(wt_servers_lock);
}
Beispiel #30
0
void wi_array_sort(wi_array_t *array, wi_compare_func_t *compare) {
	void			**data;
	wi_uinteger_t	i;
	
	if(array->data_count == 0)
		return;
	
	data = wi_malloc(sizeof(void *) * array->data_count);
	wi_array_get_data(array, data);

#ifdef HAVE_QSORT_R
	qsort_r(data, array->data_count, sizeof(void *), compare, _wi_array_compare_data);
#else
	wi_lock_lock(_wi_array_sort_lock);
	_wi_array_sort_function = compare;
	qsort(data, array->data_count, sizeof(void *), _wi_array_compare_data);
	wi_lock_unlock(_wi_array_sort_lock);
#endif
	
	for(i = 0; i < array->data_count; i++)
		array->items[i]->data = data[i];
	
	wi_free(data);
}