Ejemplo n.º 1
0
static wd_topic_t * wd_topic_init_with_string(wd_topic_t *topic, wi_string_t *string) {
	wd_user_t	*user = wd_users_user_for_thread();
	
	topic->topic	= wi_retain(string);
	topic->date		= wi_date_init(wi_date_alloc());
	topic->nick		= wi_copy(wd_user_nick(user));
	topic->login	= wi_copy(wd_user_login(user));
	topic->ip		= wi_copy(wd_user_ip(user));
	
	return topic;
}
Ejemplo n.º 2
0
void wi_test_runtime_functions(void) {
	_wi_runtimetest_t			*runtimetest1, *runtimetest2;
	_wi_mutable_runtimetest_t	*runtimetest3;
	
	_wi_runtimetest_deallocs = 0;
	
	runtimetest1 = _wi_runtimetest_init_with_value(_wi_runtimetest_alloc(), 42);
	runtimetest2 = wi_copy(runtimetest1);
	
	WI_TEST_ASSERT_TRUE(runtimetest1 == runtimetest2, "");
	
	wi_release(runtimetest2);

	runtimetest3 = wi_mutable_copy(runtimetest1);
	
	WI_TEST_ASSERT_TRUE(runtimetest1 != runtimetest3, "");
	WI_TEST_ASSERT_EQUALS(runtimetest1->value, runtimetest3->value, "");
	WI_TEST_ASSERT_TRUE(wi_is_equal(runtimetest1, runtimetest3), "");
	
	runtimetest3->value++;
	
	WI_TEST_ASSERT_FALSE(wi_is_equal(runtimetest1, runtimetest3), "");
	
	wi_release(runtimetest3);
	
	WI_TEST_ASSERT_EQUALS(_wi_runtimetest_deallocs, 1U, "");
	WI_TEST_ASSERT_EQUAL_INSTANCES(wi_description(runtimetest1), WI_STR("value=42"), "");
	WI_TEST_ASSERT_EQUALS(wi_hash(runtimetest1), 42U, "");
	
	wi_release(runtimetest1);
}
Ejemplo n.º 3
0
static wi_p7_message_t * _wi_p7_socket_read_xml_message(wi_p7_socket_t *p7_socket, wi_time_interval_t timeout, wi_string_t *prefix) {
	wi_string_t			*string;
	wi_p7_message_t		*p7_message;
	
	p7_message = wi_autorelease(wi_p7_message_init(wi_p7_message_alloc(), p7_socket));
	
	while(true) {
		string = wi_socket_read_to_string(p7_socket->socket, timeout, WI_STR(">"));
		
		if(!string || wi_string_length(string) == 0)
			return NULL;
		
		wi_string_delete_surrounding_whitespace(string);
		
		if(!p7_message->xml_string)
			p7_message->xml_string = wi_copy(string);
		else
			wi_string_append_string(p7_message->xml_string, string);
		
		if(wi_string_has_suffix(string, WI_STR("</p7:message>")) ||
		   (wi_string_has_suffix(string, WI_STR("/>")) &&
			wi_string_has_prefix(string, WI_STR("<p7:message")))) {
			break;
		}
	}
	
	wi_retain(p7_message->xml_string);
	
	if(prefix)
		wi_string_insert_string_at_index(p7_message->xml_string, prefix, 0);

	wi_string_delete_surrounding_whitespace(p7_message->xml_string);
	
	return p7_message;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
wi_socket_t * wi_socket_init_with_address(wi_socket_t *_socket, wi_address_t *address, wi_socket_type_t type) {
	_socket->address	= wi_copy(address);
	_socket->close		= true;
	_socket->buffer		= wi_string_init_with_capacity(wi_string_alloc(), WI_SOCKET_BUFFER_SIZE);
	_socket->type		= type;

	_socket->sd			= socket(wi_address_family(_socket->address), _socket->type, 0);
	
	if(_socket->sd < 0) {
		wi_error_set_errno(errno);
		
		wi_release(_socket);
		
		return NULL;
	}
	
	if(!_wi_socket_set_option_int(_socket, SOL_SOCKET, SO_REUSEADDR, 1)) {
		wi_release(_socket);
		
		return NULL;
	}
	
#ifdef SO_REUSEPORT
	if(!_wi_socket_set_option_int(_socket, SOL_SOCKET, SO_REUSEPORT, 1)) {
		wi_release(_socket);
		
		return NULL;
	}
#endif

	return _socket;
}
Ejemplo n.º 6
0
static wi_array_t * _wi_terminal_buffer_lines_for_string(wi_terminal_buffer_t *buffer, wi_string_t *string) {
	wi_enumerator_t	*enumerator;
	wi_array_t		*array;
 	wi_string_t		*string_copy, *line, *subline;
	wi_size_t		size;
	wi_uinteger_t	index;
	
	array		= wi_array_init(wi_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_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 wi_autorelease(array);
}
Ejemplo n.º 7
0
wi_string_t * wi_terminal_string_by_adjusting_to_fit_width(wi_terminal_t *terminal, wi_string_t *string) {
	wi_string_t		*string_copy;
	
	string_copy = wi_copy(string);
	wi_terminal_adjust_string_to_fit_width(terminal, string_copy);
	
	return string_copy;
}
Ejemplo n.º 8
0
wi_array_t * wi_array_by_adding_data_from_array(wi_array_t *array, wi_array_t *otherarray) {
	wi_array_t		*newarray;
	
	newarray = wi_copy(array);
	wi_array_add_data_from_array(array, otherarray);
	
	return wi_autorelease(newarray);
}
Ejemplo n.º 9
0
wi_array_t * wi_array_by_adding_data(wi_array_t *array, void *data) {
	wi_array_t		*newarray;
	
	newarray = wi_copy(array);
	wi_array_add_data(array, data);
	
	return wi_autorelease(newarray);
}
Ejemplo n.º 10
0
wi_data_t * wi_data_by_appending_bytes(wi_data_t *data, const void *bytes, wi_uinteger_t length) {
	wi_mutable_data_t		*newdata;
	
	newdata = wi_copy(data);
	wi_mutable_data_append_bytes(newdata, bytes, length);
	
	wi_runtime_make_immutable(data);

	return wi_autorelease(newdata);
}
Ejemplo n.º 11
0
wi_url_t * wi_url_init_with_string(wi_url_t *url, wi_string_t *string) {
	wi_string_t		*userpassword;
	wi_range_t		range;
	
	range = wi_string_range_of_string(string, WI_STR("://"), 0);
	
	if(range.location != WI_NOT_FOUND) {
		url->scheme = wi_retain(wi_string_substring_to_index(string, range.location));
		
		if(range.location + range.length >= wi_string_length(string))
			goto end;
		else
			string = wi_string_substring_from_index(string, range.location + 3);
	}
	
	range = wi_string_range_of_string(string, WI_STR("/"), 0);
	
	if(range.location != WI_NOT_FOUND) {
		url->path	= wi_retain(wi_string_substring_from_index(string, range.location));
		string		= wi_string_substring_to_index(string, range.location);
	}
	
	range = wi_string_range_of_string(string, WI_STR("@"), 0);
	
	if(range.location != WI_NOT_FOUND) {
		userpassword = wi_string_substring_to_index(string, range.location);
		string = wi_string_substring_from_index(string, range.location + 1);

		range = wi_string_range_of_string(userpassword, WI_STR(":"), 0);
		
		if(range.location != WI_NOT_FOUND && range.location != wi_string_length(userpassword) - 1) {
			url->user = wi_retain(wi_string_substring_to_index(userpassword, range.location));
			url->password = wi_retain(wi_string_substring_from_index(userpassword, range.location + 1));
		} else {
			url->user = wi_retain(userpassword);
		}
	}
	
	range = wi_string_range_of_string(string, WI_STR(":"), 0);
	
	if(range.location == WI_NOT_FOUND ||
	   range.location + range.length >= wi_string_length(string) ||
	   wi_string_contains_string(wi_string_substring_from_index(string, range.location + 1), WI_STR(":"), 0)) {
		url->host = wi_copy(string);
	} else {
		url->host = wi_retain(wi_string_substring_to_index(string, range.location));
		url->port = wi_string_uint32(wi_string_substring_from_index(string, range.location + 1));
	}
	
end:
	_wi_url_regenerate_string(url);
	
	return url;
}
Ejemplo n.º 12
0
void wi_test_regexp_runtime_functions(void) {
    wi_regexp_t   *regexp1, *regexp2;
    
    regexp1 = wi_regexp_with_pattern(WI_STR("foobar"), 0);
    regexp2 = wi_autorelease(wi_copy(regexp1));
    
    WI_TEST_ASSERT_EQUAL_INSTANCES(regexp1, regexp2, "");
    WI_TEST_ASSERT_EQUALS(wi_hash(regexp1), wi_hash(regexp2), "");
    WI_TEST_ASSERT_EQUALS(wi_runtime_id(regexp1), wi_regexp_runtime_id(), "");
    WI_TEST_ASSERT_EQUALS(wi_runtime_id(regexp2), wi_regexp_runtime_id(), "");
    
    WI_TEST_ASSERT_NOT_EQUALS(wi_string_index_of_string(wi_description(regexp1), wi_regexp_pattern(regexp1), 0), WI_NOT_FOUND, "");
}
Ejemplo n.º 13
0
void wi_test_host_runtime_functions(void) {
    wi_host_t   *host1, *host2, *host3, *host4, *host5, *host6;
    
    host1 = wi_host();
    host2 = wi_autorelease(wi_copy(host1));
    host3 = wi_host_with_string(WI_STR("localhost"));
    host4 = wi_autorelease(wi_copy(host3));
    host5 = wi_host_with_string(WI_STR("aab119a592b9e23779b66649677b436d24b35aaa5ad5beadf4c2a945b70577e5.com"));
    host6 = wi_autorelease(wi_copy(host5));
    
    WI_TEST_ASSERT_EQUAL_INSTANCES(host1, host2, "");
    WI_TEST_ASSERT_EQUAL_INSTANCES(host3, host4, "");
    WI_TEST_ASSERT_EQUAL_INSTANCES(host5, host6, "");
    WI_TEST_ASSERT_NOT_EQUAL_INSTANCES(host1, host3, "");
    WI_TEST_ASSERT_NOT_EQUAL_INSTANCES(host2, host3, "");
    WI_TEST_ASSERT_NOT_EQUAL_INSTANCES(host1, host4, "");
    WI_TEST_ASSERT_NOT_EQUAL_INSTANCES(host2, host4, "");
    WI_TEST_ASSERT_NOT_EQUAL_INSTANCES(host1, host5, "");
    WI_TEST_ASSERT_NOT_EQUAL_INSTANCES(host2, host5, "");
    WI_TEST_ASSERT_NOT_EQUAL_INSTANCES(host1, host6, "");
    WI_TEST_ASSERT_NOT_EQUAL_INSTANCES(host2, host6, "");
    WI_TEST_ASSERT_EQUALS(wi_hash(host1), wi_hash(host2), "");
    WI_TEST_ASSERT_EQUALS(wi_hash(host3), wi_hash(host4), "");
    WI_TEST_ASSERT_EQUALS(wi_hash(host5), wi_hash(host6), "");
    WI_TEST_ASSERT_EQUALS(wi_runtime_id(host1), wi_host_runtime_id(), "");
    WI_TEST_ASSERT_EQUALS(wi_runtime_id(host2), wi_host_runtime_id(), "");
    WI_TEST_ASSERT_EQUALS(wi_runtime_id(host3), wi_host_runtime_id(), "");
    WI_TEST_ASSERT_EQUALS(wi_runtime_id(host4), wi_host_runtime_id(), "");
    WI_TEST_ASSERT_EQUALS(wi_runtime_id(host5), wi_host_runtime_id(), "");
    WI_TEST_ASSERT_EQUALS(wi_runtime_id(host6), wi_host_runtime_id(), "");
    
#ifdef HAVE_GETIFADDRS
    WI_TEST_ASSERT_NOT_EQUALS(wi_string_index_of_string(wi_description(host1), WI_STR("127.0.0.1"), 0), WI_NOT_FOUND, "");
#else
    WI_TEST_ASSERT_NOT_EQUALS(wi_string_index_of_string(wi_description(host1), WI_STR("0.0.0.0"), 0), WI_NOT_FOUND, "");
#endif

    WI_TEST_ASSERT_NOT_EQUALS(wi_string_index_of_string(wi_description(host3), WI_STR("127.0.0.1"), 0), WI_NOT_FOUND, "");
}
Ejemplo n.º 14
0
void wi_test_dsa_runtime_functions(void) {
#ifdef WI_DSA
    wi_dsa_t    *dsa1, *dsa2;
    
    dsa1 = wi_autorelease(wi_dsa_init_with_bits(wi_dsa_alloc(), 512));
    dsa2 = wi_autorelease(wi_copy(dsa1));
    
    WI_TEST_ASSERT_EQUAL_INSTANCES(wi_dsa_private_key(dsa1), wi_dsa_private_key(dsa2), "");
    WI_TEST_ASSERT_EQUALS(wi_runtime_id(dsa1), wi_dsa_runtime_id(), "");
    WI_TEST_ASSERT_EQUALS(wi_runtime_id(dsa2), wi_dsa_runtime_id(), "");
    WI_TEST_ASSERT_NOT_EQUALS(wi_string_index_of_string(wi_description(dsa1), WI_STR("384"), 0), WI_NOT_FOUND, "");
#endif
}
Ejemplo n.º 15
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);
}
Ejemplo n.º 16
0
static void wr_msg_400(wi_array_t *arguments) {
	wi_address_t		*address;
	wr_transfer_t		*transfer;

	transfer = wr_transfers_transfer_with_path(WI_ARRAY(arguments, 0));

	if(!transfer)
		return;
	
	address = wi_copy(wr_address);
	wi_address_set_port(address, wi_address_port(address) + 1);
	
	transfer->state			= WR_TRANSFER_RUNNING;
	transfer->offset		= wi_string_uint64(WI_ARRAY(arguments, 1));
	transfer->transferred	= transfer->offset;
	transfer->key			= wi_retain(WI_ARRAY(arguments, 2));
	transfer->start_time	= wi_time_interval();
	transfer->socket		= wi_socket_init_with_address(wi_socket_alloc(), address, WI_SOCKET_TCP);

	wi_socket_set_interactive(transfer->socket, false);
	
	if(!wi_socket_connect(transfer->socket, wr_socket_context, 15.0)) {
		wr_printf_prefix(WI_STR("Could not connect to %@: %m"), wi_address_string(address));
		
		wr_transfer_stop(transfer);

		goto end;
	}
	
	wi_file_seek(transfer->file, transfer->offset);

	if(transfer->type == WR_TRANSFER_DOWNLOAD) {
		wi_socket_set_direction(transfer->socket, WI_SOCKET_READ);
		wr_runloop_add_socket(transfer->socket, wr_runloop_download_callback);
	} else {
		wi_socket_set_direction(transfer->socket, WI_SOCKET_WRITE);
		wr_runloop_add_socket(transfer->socket, wr_runloop_upload_callback);
	}

	wr_send_command_on_socket(transfer->socket, WI_STR("TRANSFER %#@"), transfer->key);

	wr_printf_prefix(WI_STR("Starting transfer of \"%@\""), transfer->name);
	
	wr_draw_transfers(true);

end:
	wi_release(address);
}
Ejemplo n.º 17
0
void wi_parse_wire_command(wi_string_t *buffer, wi_string_t **out_command, wi_string_t **out_arguments) {
	wi_uinteger_t	index;
	
	index = wi_string_index_of_string(buffer, WI_STR(" "), 0);
	
	if(index != WI_NOT_FOUND) {
		*out_command	= wi_string_substring_to_index(buffer, index);
		*out_arguments	= wi_string_substring_from_index(buffer, index + 1);
	} else {
		*out_command	= wi_autorelease(wi_copy(buffer));
		*out_arguments	= wi_string();
	}
	
	if(wi_string_has_prefix(*out_command, WI_STR("/")))
		*out_command = wi_string_by_deleting_characters_to_index(*out_command, 1);
}
Ejemplo n.º 18
0
wi_string_encoding_t * wi_string_encoding_init_with_charset(wi_string_encoding_t *encoding, wi_string_t *charset, wi_string_encoding_options_t options) {
    encoding->charset           = wi_copy(charset);
    encoding->target_encoding   = wi_mutable_copy(charset);
    encoding->utf8_encoding     = wi_string_init_with_utf8_string(wi_mutable_string_alloc(), "UTF-8");
    encoding->options           = options;
    
    if(options & WI_STRING_ENCODING_IGNORE) {
        wi_mutable_string_append_string(encoding->target_encoding, WI_STR("//IGNORE"));
        wi_mutable_string_append_string(encoding->utf8_encoding, WI_STR("//IGNORE"));
    }
    
    if(options & WI_STRING_ENCODING_TRANSLITERATE) {
        wi_mutable_string_append_string(encoding->target_encoding, WI_STR("//TRANSLIT"));
        wi_mutable_string_append_string(encoding->utf8_encoding, WI_STR("//TRANSLIT"));
    }
    
    return encoding;
}
Ejemplo n.º 19
0
void wi_test_runtime_invalid(void) {
    WI_TEST_ASSERT_NULL(wi_runtime_class_with_name(WI_STR("foo")), "");
    WI_TEST_ASSERT_NULL(wi_runtime_class_with_id(1337), "");
    WI_TEST_ASSERT_EQUALS(wi_runtime_id_for_class(NULL), WI_RUNTIME_ID_NULL, "");
    
    WI_TEST_ASSERT_NULL(wi_runtime_class("foo"), "");
    WI_TEST_ASSERT_NULL(wi_runtime_class_name("foo"), "");
    WI_TEST_ASSERT_EQUALS(wi_runtime_id("foo"), WI_RUNTIME_ID_NULL, "");

    WI_TEST_ASSERT_NULL(wi_retain(NULL), "");
    WI_TEST_ASSERT_EQUALS(wi_retain_count(NULL), 0U, "");
    WI_TEST_ASSERT_NULL(wi_copy(NULL), "");
    WI_TEST_ASSERT_NULL(wi_mutable_copy(NULL), "");
    WI_TEST_ASSERT_TRUE(wi_is_equal(NULL, NULL), "");
    WI_TEST_ASSERT_FALSE(wi_is_equal(NULL, "foo"), "");
    WI_TEST_ASSERT_FALSE(wi_is_equal(wi_array(), wi_dictionary()), "");
    WI_TEST_ASSERT_NULL(wi_description(NULL), "");
    WI_TEST_ASSERT_EQUALS(wi_hash(NULL), 0U, "");
}
Ejemplo n.º 20
0
void wr_draw_header(void) {
	wi_string_t		*topic;
	wi_size_t		size;
	
	topic = wi_copy(wr_current_window->topic.topic);
	
	if(!topic)
		topic = wi_string_init(wi_string_alloc());

	wi_terminal_adjust_string_to_fit_width(wr_terminal, topic);
	
	size = wi_terminal_size(wr_terminal);
	
	wi_terminal_move_printf(wr_terminal, wi_make_point(0, 0), WI_STR("%s%@%s"),
	   WR_INTERFACE_COLOR,
	   topic,
	   WR_END_COLOR);
	wi_terminal_move(wr_terminal, wi_make_point(rl_point % size.width, size.height - 1));
	
	wi_release(topic);
}
Ejemplo n.º 21
0
void wi_parse_wired_command(wi_string_t *buffer, wi_string_t **out_command, wi_array_t **out_arguments) {
	wi_string_t		*string, *substring;
	wi_uinteger_t	index;
	
	index = wi_string_index_of_string(buffer, WI_STR(_WI_WIRED_MESSAGE_SEPARATOR), WI_STRING_BACKWARDS);
	
	if(index != WI_NOT_FOUND)
		string = wi_string_by_deleting_characters_from_index(buffer, index);
	else
		string = wi_autorelease(wi_copy(buffer));
	
	index = wi_string_index_of_string(string, WI_STR(" "), 0);
	
	if(index != WI_NOT_FOUND) {
		*out_command	= wi_string_substring_to_index(string, index);
		substring		= wi_string_substring_from_index(string, index + 1);
		*out_arguments	= wi_string_components_separated_by_string(substring, WI_STR(_WI_WIRED_FIELD_SEPARATOR));
	} else {
		*out_command	= string;
		*out_arguments	= wi_array();
	}
}
Ejemplo n.º 22
0
static void wt_cmd_register(wi_array_t *arguments) {
	wt_client_t					*client = wt_client();
	wi_enumerator_t				*enumerator;
	wi_array_t					*array;
	wi_address_t				*address, *hostaddress;
	wi_url_t					*url;
	wi_string_t					*hostname;
	wt_server_t					*server;
	wi_boolean_t				failed = false, passed;
	uint32_t					bandwidth;

	url			= wi_autorelease(wi_url_init_with_string(wi_url_alloc(), WI_ARRAY(arguments, 1)));
	hostname	= wi_url_host(url);
	address		= wi_socket_address(client->socket);
	
	if(!wi_url_is_valid(url)) {
		/* invalid URL */
		if(wt_settings.strictlookup) {
			wt_reply(503, WI_STR("Syntax Error"));
			wi_log_warn(WI_STR("Register from %@ as \"%@\" URL %@ aborted: %s"),
				client->ip, WI_ARRAY(arguments, 2), WI_ARRAY(arguments, 1),
				"Invalid URL");
			
			return;
		}
		
		failed = true;
		goto failed;
	}

	if(wi_ip_version(hostname) > 0) {
		/* hostname is numeric, compare with source address */
		if(!wi_is_equal(hostname, client->ip)) {
			/* IP mismatch */
			if(wt_settings.strictlookup) {
				wt_reply(530, WI_STR("Address Mismatch"));
				wi_log_warn(WI_STR("Register from %@ as \"%@\" URL %@ denied: %s"),
					client->ip, WI_ARRAY(arguments, 2), WI_ARRAY(arguments, 1),
					"IP mismatch");

				return;
			}

			failed = true;
			goto failed;
		}
	} else {
		/* hostname is symbolic */
		if(wt_settings.lookup) {
			/* look up and compare with source address */
			passed = false;
			array = wi_host_addresses(wi_host_with_string(hostname));
			
			if(array) {
				enumerator = wi_array_data_enumerator(array);
				
				while((hostaddress = wi_enumerator_next_data(enumerator))) {
					if(wi_is_equal(hostaddress, address)) {
						passed = true;
						
						break;
					}
				}
			}
			
			if(!passed) {
				/* lookup failed */
				if(wt_settings.strictlookup) {
					wt_reply(531, WI_STR("Address Mismatch"));
					wi_log_warn(WI_STR("Register from %@ as \"%@\" URL %@ denied: %s"),
						client->ip, WI_ARRAY(arguments, 2), WI_ARRAY(arguments, 1),
						"Lookup failed");
					
					return;
				}
				
				failed = true;
				goto failed;
			}
		}

		if(wt_settings.reverselookup) {
			/* reverse look up and compare to hostname */
			if(!wi_is_equal(wi_address_hostname(address), hostname)) {
				/* reverse lookup failed */
				if(wt_settings.strictlookup) {
					wt_reply(531, WI_STR("Address Mismatch"));
					wi_log_warn(WI_STR("Register from %@ as \"%@\" URL % denied: %@"),
						client->ip, WI_ARRAY(arguments, 2), WI_ARRAY(arguments, 1),
						"Reverse lookup failed");

					return;
				}

				failed = true;
				goto failed;
			}
		}
	}

failed:
	/* get bandwidth */
	bandwidth = wi_string_uint32(WI_ARRAY(arguments, 3));

	/* bandwidth too low? */
	if(wt_settings.minbandwidth > 0 && bandwidth < wt_settings.minbandwidth) {
		wt_reply(516, WI_STR("Permission Denied"));
		wi_log_warn(WI_STR("Register from %@ as \"%@\" URL %@ denied: Bandwidth %.0f Kbps considered too low"),
			client->ip, WI_ARRAY(arguments, 2), WI_ARRAY(arguments, 1), bandwidth / 128.0);

		return;
	}

	/* bandwidth too high? */
	if(wt_settings.maxbandwidth > 0 && bandwidth > wt_settings.maxbandwidth) {
		wt_reply(516, WI_STR("Permission Denied"));
		wi_log_warn(WI_STR("Register from %@ as \"%@\" URL %@ denied: Bandwidth %.0f Kbps considered too high"),
			client->ip, WI_ARRAY(arguments, 2), WI_ARRAY(arguments, 1), bandwidth / 128.0);

		return;
	}

	/* is there an existing server from this host? */
	server = wt_servers_server_with_ip(client->ip);

	if(server) {
		if(server->port == wi_url_port(url)) {
			/* remove existing server in preparation for re-registration */
			wt_servers_remove_stats_for_server(server);
			wt_servers_remove_server(server);
		} else {
			/* multiple servers from the same IP allowed? */
			if(!wt_settings.allowmultiple) {
				wt_reply(530, WI_STR("Address Registered"));
				wi_log_warn(WI_STR("Register from %@ as \"%@\" URL %@ denied: %s"),
					client->ip, WI_ARRAY(arguments, 2), WI_ARRAY(arguments, 1),
					"A server from the same address is already registered");
				
				return;
			}
		}
	}
	
	/* rewrite URL if host verification failed */
	if(failed) {
		wi_url_set_scheme(url, WI_STR("wired"));
		wi_url_set_host(url, client->ip);

		if(wi_string_length(WI_ARRAY(arguments, 1)) == 0)
			wi_log_info(WI_STR("Rewriting URL to %@"), wi_url_string(url));
		else
			wi_log_info(WI_STR("Rewriting URL from %@ to %@"), WI_ARRAY(arguments, 1), wi_url_string(url));
	}

	/* create new server */
	server					= wt_server_init(wt_server_alloc());
	server->key				= wi_retain(wi_string_sha1(wi_autorelease(wi_string_init_random_string_with_length(wi_string_alloc(), 1024))));
	server->port			= wi_url_port(url);
	server->bandwidth		= bandwidth;
	server->register_time	= wi_time_interval();
	server->update_time		= 0.0;
	server->ip				= wi_retain(client->ip);
	server->category		= wt_servers_category_is_valid(WI_ARRAY(arguments, 0))
		? wi_retain(WI_ARRAY(arguments, 0))
		: wi_string_init(wi_string_alloc());
	server->name			= wi_retain(WI_ARRAY(arguments, 2));
	server->description		= wi_retain(WI_ARRAY(arguments, 4));
	server->url				= wi_copy(wi_url_string(url));

	wt_servers_add_server(server);
	wt_servers_add_stats_for_server(server);
	
	/* reply 700 */
	wt_reply(700, WI_STR("%@"), server->key);
	wi_log_info(WI_STR("Registered \"%@\" with URL %@"), server->name, server->url);
	wt_servers_write_file();
	wi_release(server);
}