Ejemplo n.º 1
0
void wr_transfer_download_add_file(wr_transfer_t *transfer, wr_file_t *file, wi_boolean_t recursive) {
    
	wi_string_t		*remote_path, *local_path, *parent_path;
	
	remote_path = wr_file_path(file);
	
	if(recursive) {
		local_path = wi_string_by_appending_path_component(transfer->name,
                                                           wi_string_substring_from_index(remote_path, wi_string_length(transfer->master_path)));
	} else {
		local_path = wi_string_last_path_component(remote_path);
	}
	
	local_path = wi_string_by_appending_path_component(wi_string_by_normalizing_path(wr_download_path), local_path);
	parent_path = wi_string_by_deleting_last_path_component(local_path);
	
	wi_fs_create_directory(parent_path, 0755);
    
	if(wr_file_type(file) == WR_FILE_FILE) {
		wi_mutable_array_add_data(transfer->remote_paths, remote_path);
		wi_mutable_array_add_data(transfer->local_paths, local_path);
		wi_mutable_array_add_data(transfer->files, file);
		
		transfer->total_size += wr_file_size(file);
	} else {
		if(!wi_fs_path_exists(local_path, NULL)) {
			if(!wi_fs_create_directory(local_path, 0755)) {
				wr_printf_prefix(WI_STR("get: Unable to create directory at %@: %m"),
                                 local_path);
			}
		}
	}
     
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
0
static wi_mutable_array_t * _wi_terminal_buffer_lines_for_string(wi_terminal_buffer_t *buffer, wi_string_t *string) {
	wi_enumerator_t			*enumerator;
	wi_mutable_array_t		*array;
	wi_mutable_string_t		*newstring;
 	wi_string_t				*line, *subline;
	wi_size_t				size;
	wi_uinteger_t			index;
	
	array		= wi_array_init(wi_mutable_array_alloc());
	size		= wi_terminal_size(buffer->terminal);
	enumerator	= wi_array_data_enumerator(wi_string_components_separated_by_string(string, WI_STR("\n")));
	
	while((line = wi_enumerator_next_data(enumerator))) {
		if(wi_terminal_width_of_string(buffer->terminal, line) < size.width) {
			wi_mutable_array_add_data(array, line);
		} else {
			newstring = wi_mutable_copy(line);
			
			do {
				index		= wi_terminal_index_of_string_for_width(buffer->terminal, newstring, size.width);
				subline		= wi_string_substring_to_index(newstring, index);

				wi_mutable_array_add_data(array, subline);
				wi_mutable_string_delete_characters_to_index(newstring, wi_string_length(subline));
			} while(wi_terminal_width_of_string(buffer->terminal, newstring) >= size.width);
			
			wi_mutable_array_add_data(array, newstring);
			wi_release(newstring);
		}
	}
	
	return wi_autorelease(array);
}
void wi_test_directory_enumerator(void) {
    wi_directory_enumerator_t           *enumerator;
    wi_mutable_array_t                  *contents;
    wi_string_t                         *path, *subpath;
    wi_boolean_t                        result;
    wi_directory_enumerator_status_t    status;
    
    path = wi_filesystem_temporary_path_with_template(WI_STR("/tmp/libwired-test-directory-enumerator.XXXXXXX"));
    path = wi_string_by_resolving_symbolic_links_in_path(path);
    result = wi_filesystem_create_directory_at_path(path);
    
    WI_TEST_ASSERT_TRUE(result, "");
    
    enumerator = wi_filesystem_directory_enumerator_at_path(path);
    
    WI_TEST_ASSERT_NOT_NULL(enumerator, "");
    
    contents = wi_mutable_array();
    
    while((status = wi_directory_enumerator_get_next_path(enumerator, &subpath)) == WI_DIRECTORY_ENUMERATOR_PATH)
        wi_mutable_array_add_data(contents, subpath);
    
    WI_TEST_ASSERT_EQUALS(status, WI_DIRECTORY_ENUMERATOR_EOF, "");
    WI_TEST_ASSERT_EQUALS(wi_array_count(contents), 0U, "");
    
    result = wi_filesystem_change_current_directory_to_path(path);
    
    WI_TEST_ASSERT_TRUE(result, "");

    result = wi_filesystem_create_directory_at_path(WI_STR("foo"));
    
    WI_TEST_ASSERT_TRUE(result, "");
    
    result = wi_filesystem_create_directory_at_path(WI_STR("foo/bar"));
    
    WI_TEST_ASSERT_TRUE(result, "");
    
    result = wi_filesystem_create_directory_at_path(WI_STR("foo/bar/baz"));
    
    WI_TEST_ASSERT_TRUE(result, "");
    
    enumerator = wi_filesystem_directory_enumerator_at_path(path);
    
    WI_TEST_ASSERT_NOT_NULL(enumerator, "");
    
    while((status = wi_directory_enumerator_get_next_path(enumerator, &subpath)) == WI_DIRECTORY_ENUMERATOR_PATH)
        wi_mutable_array_add_data(contents, subpath);
    
    WI_TEST_ASSERT_EQUALS(status, WI_DIRECTORY_ENUMERATOR_EOF, "");
    WI_TEST_ASSERT_EQUALS(wi_array_count(contents), 3U, "");
    WI_TEST_ASSERT_EQUAL_INSTANCES(wi_array_data_at_index(contents, 0), wi_string_by_appending_path_component(path, WI_STR("foo")), "");
    WI_TEST_ASSERT_EQUAL_INSTANCES(wi_array_data_at_index(contents, 1), wi_string_by_appending_path_component(path, WI_STR("foo/bar")), "");
    WI_TEST_ASSERT_EQUAL_INSTANCES(wi_array_data_at_index(contents, 2), wi_string_by_appending_path_component(path, WI_STR("foo/bar/baz")), "");
    
    wi_filesystem_delete_path(path);
}
Ejemplo n.º 5
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);
}
Ejemplo n.º 6
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);
}
Ejemplo n.º 7
0
static void wr_command_ignore(wi_array_t *arguments) {
	wi_enumerator_t	*enumerator;
	wi_string_t		*string;
	wr_ignore_t		*ignore;

	if(wi_array_count(arguments) > 0) {
		string = WI_ARRAY(arguments, 0);
		ignore = wr_ignore_init_with_string(wr_ignore_alloc(), string);

		if(ignore) {
			wr_printf_prefix(WI_STR("Ignoring \"%@\""),
				wr_ignore_string(ignore));
			
			wi_mutable_array_add_data(wr_ignores, ignore);
			wi_release(ignore);
		} else {
			wr_printf_prefix(WI_STR("ignore: Could not compile regular expression \"%@\": %m"),
				string);
		}
	} else {
		wr_printf_prefix(WI_STR("Ignores:"));

		if(wi_array_count(wr_ignores) == 0) {
			wr_printf_block(WI_STR("(none)"));
		} else {
			enumerator = wi_array_data_enumerator(wr_ignores);
			
			while((ignore = wi_enumerator_next_data(enumerator)))
				wr_printf_block(WI_STR("%u: %@"), wr_ignore_id(ignore), wr_ignore_string(ignore));
		}
	}
}
Ejemplo n.º 8
0
void wr_transfers_upload(wi_string_t *path) {
	wr_transfer_t		*transfer;
	wr_file_t			*file;
	
	transfer = wi_autorelease(wr_transfer_init_upload(wr_transfer_alloc()));
	transfer->name = wi_retain(wi_string_last_path_component(path));
	transfer->master_path = wi_retain(wr_files_full_path(transfer->name));
	transfer->source_path = wi_retain(wi_string_by_normalizing_path(path));
	
	file = wi_autorelease(wr_file_init_with_local_path(wr_file_alloc(), transfer->source_path));
	
	if(!file) {
		wr_printf_prefix(WI_STR("put: Could not open %@: %m"),
                         transfer->source_path);
		
		return;
	}
	
	if(!wr_transfer_upload_add_file(transfer, file)) {
		wr_printf_prefix(WI_STR("put: Could not add files from %@: %m"),
                         transfer->source_path);
		
		return;
	}
	
	wi_mutable_array_add_data(wr_transfers, transfer);
	
	if(transfer->tid == 1)
		wr_transfer_start(transfer);
}
Ejemplo n.º 9
0
static void wr_msg_420(wi_array_t *arguments) {
	wr_file_t		*file;

	file = wr_file_init_with_arguments(wr_file_alloc(), arguments);
	wi_mutable_array_add_data(wr_files, file);
	wi_release(file);
}
Ejemplo n.º 10
0
wi_array_t * wi_p7_message_list_for_name(wi_p7_message_t *p7_message, wi_string_t *field_name) {
	wi_p7_spec_field_t		*field;
	wi_p7_spec_type_t		*listtype;
	wi_array_t				*list;
	wi_runtime_instance_t	*instance;
	unsigned char			*binary;
	wi_p7_type_t			listtype_id;
	uint32_t				field_size, list_size, string_size;
	
	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_list_for_name: %m"));
		
		return NULL;
	}
	
	listtype		= wi_p7_spec_field_listtype(field);
	listtype_id		= wi_p7_spec_type_id(listtype);

	if(listtype_id != WI_P7_STRING) {
		wi_error_set_libwired_error_with_format(WI_ERROR_P7_UNKNOWNFIELD,
			WI_STR("Unhandled type %@ in list"), wi_p7_spec_type_name(listtype));
		
		if(wi_p7_message_debug)
			wi_log_debug(WI_STR("wi_p7_message_list_for_name: %m"));
		
		return NULL;
	}
	
	list = wi_mutable_array();
		
	if(!_wi_p7_message_get_binary_buffer_for_reading_for_name(p7_message, field_name, &binary, &field_size))
		return NULL;
	
	list_size = 0;
	
	while(list_size < field_size) {
		if(listtype_id == WI_P7_STRING) {
			string_size = wi_read_swap_big_to_host_int32(binary, list_size);
			
			list_size += 4;
			
			instance = wi_string_with_bytes(binary + list_size, string_size - 1);
			
			list_size += string_size;
		}
		
		wi_mutable_array_add_data(list, instance);
	}
	
	wi_runtime_make_immutable(list);
	
	return list;
}
Ejemplo n.º 11
0
static wi_boolean_t _wi_plist_read_node_to_instance(xmlNodePtr content_node, wi_runtime_instance_t *collection) {
	xmlNodePtr				node;
	wi_string_t				*key = NULL;
	wi_runtime_instance_t	*instance = NULL;
	wi_boolean_t			dictionary;
	
	dictionary = (wi_runtime_id(collection) == wi_dictionary_runtime_id());
	
	for(node = content_node->children; node != NULL; node = node->next) {
		if(node->type == XML_ELEMENT_NODE) {
			if(strcmp((const char *) node->name, "key") == 0)
				key = wi_xml_node_content(node);
			else if(strcmp((const char *) node->name, "string") == 0)
				instance = wi_xml_node_content(node);
			else if(strcmp((const char *) node->name, "integer") == 0)
				instance = wi_number_with_integer(wi_string_integer(wi_xml_node_content(node)));
			else if(strcmp((const char *) node->name, "real") == 0)
				instance = wi_number_with_double(wi_string_double(wi_xml_node_content(node)));
			else if(strcmp((const char *) node->name, "true") == 0)
				instance = wi_number_with_bool(true);
			else if(strcmp((const char *) node->name, "false") == 0)
				instance = wi_number_with_bool(false);
			else if(strcmp((const char *) node->name, "date") == 0)
				instance = wi_date_with_rfc3339_string(wi_xml_node_content(node));
			else if(strcmp((const char *) node->name, "data") == 0)
				instance = wi_data_with_base64(wi_xml_node_content(node));
			else if(strcmp((const char *) node->name, "dict") == 0) {
				instance = wi_mutable_dictionary();
				
				if(!_wi_plist_read_node_to_instance(node, instance))
					return false;
			}
			else if(strcmp((const char *) node->name, "array") == 0) {
				instance = wi_mutable_array();
				
				if(!_wi_plist_read_node_to_instance(node, instance))
					return false;
			}
			else {
				wi_error_set_libwired_error_with_format(WI_ERROR_PLIST_READFAILED,
					WI_STR("Unhandled node \"%s\""), node->name);
				
				return false;
			}
		}
			
		if(instance) {
			if(dictionary)
				wi_mutable_dictionary_set_data_for_key(collection, instance, key);
			else
				wi_mutable_array_add_data(collection, instance);
			
			instance = NULL;
			key = NULL;
		}
	}
	
	return true;
}
Ejemplo n.º 12
0
void wr_transfers_download(wi_string_t *path) {
	wr_transfer_t		*transfer;
	
	transfer = wi_autorelease(wr_transfer_init_download(wr_transfer_alloc()));
	transfer->name = wi_retain(wi_string_last_path_component(path));
	transfer->master_path = wi_retain(path);
	
	wi_mutable_array_add_data(wr_transfers, transfer);
	
	if(transfer->tid == 1)
		wr_transfer_start(transfer);
}
Ejemplo n.º 13
0
void wr_windows_add_window(wr_window_t *window) {
	wi_mutable_array_add_data(wr_windows, window);
	wi_terminal_add_buffer(wr_terminal, window->buffer);

	if(wr_window_is_private_chat(window) || wr_window_is_user(window)) {
		if(wr_window_is_user(window))
			wr_wprintf_prefix(window, WI_STR("Opened new window for private messages with %@"), wr_user_nick(window->user));
		else
			wr_wprintf_prefix(window, WI_STR("Opened new window for private chat"));
		
		wr_wprintf_prefix(window, WI_STR("Use ctrl-N/ctrl-P to cycle windows, and /close to exit"));
	}
}
Ejemplo n.º 14
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);
}
Ejemplo n.º 15
0
void wd_chat_add_user_and_broadcast(wd_chat_t *chat, wd_user_t *user) {
	wd_broadcast(chat, 302, WI_STR("%u%c%u%c%u%c%u%c%u%c%#@%c%#@%c%#@%c%#@%c%#@%c%#@"),
				 chat->cid,					WD_FIELD_SEPARATOR,
				 wd_user_uid(user),			WD_FIELD_SEPARATOR,
				 wd_user_is_idle(user),		WD_FIELD_SEPARATOR,
				 wd_user_is_admin(user),	WD_FIELD_SEPARATOR,
				 wd_user_icon(user),		WD_FIELD_SEPARATOR,
				 wd_user_nick(user),		WD_FIELD_SEPARATOR,
				 wd_user_login(user),		WD_FIELD_SEPARATOR,
				 wd_user_ip(user),			WD_FIELD_SEPARATOR,
				 wd_user_host(user),		WD_FIELD_SEPARATOR,
				 wd_user_status(user),		WD_FIELD_SEPARATOR,
				 wd_user_image(user));
	
	wi_array_wrlock(chat->users);
	wi_mutable_array_add_data(chat->users, user);
	wi_array_unlock(chat->users);
}
Ejemplo n.º 16
0
wi_boolean_t wd_transfers_run_transfer(wd_transfer_t *transfer, wd_user_t *user, wi_p7_message_t *message) {
	wi_boolean_t		result = false;
	
	wi_array_wrlock(wd_transfers);
	wi_mutable_array_add_data(wd_transfers, transfer);
	wi_array_unlock(wd_transfers);
	
	wi_condition_lock_lock(wd_transfers_queue_lock);
	wi_condition_lock_unlock_with_condition(wd_transfers_queue_lock, 1);
	
	if(wd_transfers_wait_until_ready(transfer, user, message)) {
		wi_condition_lock_lock(transfer->queue_lock);
		transfer->state = WD_TRANSFER_RUNNING;
		wi_condition_lock_unlock(transfer->queue_lock);
		
		if(transfer->type == WD_TRANSFER_DOWNLOAD)
			result = wd_transfers_run_download(transfer, user, message);
		else
			result = wd_transfers_run_upload(transfer, user, message);
			
		wi_condition_lock_lock(transfer->finished_lock);
		wi_condition_lock_unlock_with_condition(transfer->finished_lock, 1);
	} else {
		wi_log_error(WI_STR("Could not process %@ for %@: %m"),
			(transfer->type == WD_TRANSFER_DOWNLOAD)
				? WI_STR("download")
				: WI_STR("upload"),
			wd_user_identifier(user));
	}
	
	if(transfer->queue == 0)
		wd_transfers_add_or_remove_transfer(transfer, false);

	wi_array_wrlock(wd_transfers);
	wi_mutable_array_remove_data(wd_transfers, transfer);
	wi_array_unlock(wd_transfers);
	
	wi_condition_lock_lock(wd_transfers_queue_lock);
	wi_condition_lock_unlock_with_condition(wd_transfers_queue_lock, 1);
	
	return result;
}
Ejemplo n.º 17
0
wi_array_t * wd_users_users_with_login(wi_string_t *name) {
	wi_enumerator_t			*enumerator;
	wi_mutable_array_t		*users;
	wd_user_t				*user;
	
	users = wi_mutable_array();

	wi_dictionary_rdlock(wd_users);
	
	enumerator = wi_dictionary_data_enumerator(wd_users);
	
	while((user = wi_enumerator_next_data(enumerator))) {
		if(wi_is_equal(wd_user_login(user), name))
			wi_mutable_array_add_data(users, user);
	}

	wi_dictionary_unlock(wd_users);
	
	return users;
}
Ejemplo n.º 18
0
wi_array_t * wi_set_all_data(wi_set_t *set) {
	wi_array_t				*array;
	_wi_set_bucket_t		*bucket;
	wi_array_callbacks_t	callbacks;
	wi_uinteger_t			i;
	
	callbacks.retain		= set->callbacks.retain;
	callbacks.release		= set->callbacks.release;
	callbacks.is_equal		= set->callbacks.is_equal;
	callbacks.description	= set->callbacks.description;
	array					= wi_array_init_with_capacity_and_callbacks(wi_mutable_array_alloc(), set->data_count, callbacks);

	for(i = 0; i < set->buckets_count; i++) {
		for(bucket = set->buckets[i]; bucket; bucket = bucket->next)
			wi_mutable_array_add_data(array, bucket->data);
	}
	
	wi_runtime_make_immutable(array);

	return wi_autorelease(array);
}
Ejemplo n.º 19
0
wi_array_t * wi_dictionary_all_values(wi_dictionary_t *dictionary) {
    wi_array_t                  *array;
    _wi_dictionary_bucket_t     *bucket;
    wi_array_callbacks_t        callbacks;
    wi_uinteger_t               i;

    callbacks.retain            = dictionary->value_callbacks.retain;
    callbacks.release           = dictionary->value_callbacks.release;
    callbacks.is_equal          = dictionary->value_callbacks.is_equal;
    callbacks.description       = dictionary->value_callbacks.description;
    array                       = 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(array, bucket->data);
    }

    wi_runtime_make_immutable(array);

    return wi_autorelease(array);
}
Ejemplo n.º 20
0
static wb_command_t * _wb_command_load_with_node(wb_command_t *command, xmlNodePtr node) {
	wi_string_t 			*permissions, *activated, *name;
	wb_output_t 			*output;
	xmlNodePtr				sub_node, next_node;
	
	// get command name
	name = wi_xml_node_attribute_with_name(node, WI_STR("name"));
	if(name)
		command->name = wi_retain(name);

	// get command permissions
	permissions = wi_xml_node_attribute_with_name(node, WI_STR("permissions"));
	if(permissions)
		command->permissions = wi_retain(permissions);
		
	// is an activated command ?
	activated = wi_xml_node_attribute_with_name(node, WI_STR("activated"));
	if(activated)
		command->activated = wi_is_equal(activated, WI_STR("true")) ? true : false;

	// get rule children: outputs 
	for(sub_node = node->children; sub_node != NULL; sub_node = next_node) {
		next_node = sub_node->next;
		
		if(sub_node->type == XML_ELEMENT_NODE) {

			if(strcmp((const char *) sub_node->name, "output") == 0) {
				
				output = wb_output_init(wb_output_alloc(), sub_node);
				if(output)
					wi_mutable_array_add_data(command->outputs, output);

				wi_release(output);
			}
		}
	}

	return command;
}
Ejemplo n.º 21
0
wi_array_t * wi_backtrace(void) {
#ifdef HAVE_BACKTRACE
    wi_mutable_array_t  *array;
    void                *callstack[128];
    char                **symbols;
    int                 i, frames;
    
    frames      = backtrace(callstack, sizeof(callstack));
    symbols     = backtrace_symbols(callstack, frames);
    array       = wi_array_init_with_capacity(wi_mutable_array_alloc(), frames);
    
    for(i = 0; i < frames; i++)
        wi_mutable_array_add_data(array, wi_string_with_utf8_string(symbols[i]));
    
    free(symbols);
    
    wi_runtime_make_immutable(array);
    
    return wi_autorelease(array);
#else
    return NULL;
#endif
}
Ejemplo n.º 22
0
void wi_socket_initialize(void) {
#ifdef HAVE_OPENSSL_SSL_H
#ifdef WI_PTHREADS
	wi_lock_t		*lock;
	wi_uinteger_t	i, count;
#endif

	SSL_library_init();

#ifdef WI_PTHREADS
	count = CRYPTO_num_locks();
	_wi_socket_ssl_locks = wi_array_init_with_capacity(wi_mutable_array_alloc(), count);
	
	for(i = 0; i < count; i++) {
		lock = wi_lock_init(wi_lock_alloc());
		wi_mutable_array_add_data(_wi_socket_ssl_locks, lock);
		wi_release(lock);
	}

	CRYPTO_set_id_callback(_wi_socket_ssl_id_function);
	CRYPTO_set_locking_callback(_wi_socket_ssl_locking_function);
#endif
#endif
}
Ejemplo n.º 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);
}
Ejemplo n.º 24
0
wi_boolean_t wr_transfer_upload_add_file(wr_transfer_t *transfer, wr_file_t *file) {
	WI_FTS			*fts = NULL;
	WI_FTSENT		*p;
	wi_string_t		*local_path, *remote_path;
	wr_file_t		*fts_file;
	char			*paths[2];
	
	if(wr_file_type(file) == WR_FILE_FILE) {
		wi_mutable_array_add_data(transfer->local_paths, wr_file_path(file));
		wi_mutable_array_add_data(transfer->remote_paths, wr_files_full_path(transfer->name));
		wi_mutable_array_add_data(transfer->files, file);
		
		transfer->total_size += wr_file_size(file);
	} else {
		wr_transfers_recursive_upload = true;
		transfer->recursive = true;
        
		paths[0] = (char *) wi_string_cstring(wr_file_path(file));
		paths[1] = NULL;
		
		errno = 0;
		fts = wi_fts_open(paths, WI_FTS_NOSTAT | WI_FTS_LOGICAL, NULL);
		
		if(!fts)
			return false;
		
		if(fts && errno != 0) {
			wi_fts_close(fts);
			
			return false;
		}
		
		while((p = wi_fts_read(fts))) {
			if(p->fts_level > 10) {
				wi_fts_set(fts, p, WI_FTS_SKIP);
				
				continue;
			}
			
			switch(p->fts_info) {
				case WI_FTS_DC:
					errno = ELOOP;
					
					wr_printf_prefix(WI_STR("put: Could not read %s: %s"),
                                     strerror(errno));
					
					continue;
					break;
					
				case WI_FTS_DP:
					continue;
					break;
					
				case WI_FTS_DNR:
				case WI_FTS_ERR:
					wr_printf_prefix(WI_STR("put: Could not read %s: %s"),
                                     strerror(p->fts_errno));
					
					continue;
					break;
			}
			
			if(p->fts_name[0] == '.') {
				wi_fts_set(fts, p, WI_FTS_SKIP);
				
				continue;
			}
			
			local_path = wi_string_with_cstring(p->fts_path);
			remote_path = wi_string_by_normalizing_path(wi_string_by_appending_path_component(transfer->master_path,
                                                                                              wi_string_substring_from_index(local_path, wi_string_length(transfer->source_path))));
			
			if(p->fts_info == WI_FTS_D) {
				// wr_send_command(WI_STR("FOLDER %#@"), remote_path);
			} else {
				wi_mutable_array_add_data(transfer->local_paths, local_path);
				wi_mutable_array_add_data(transfer->remote_paths, remote_path);
                
				fts_file = wr_file_init_with_local_path(wr_file_alloc(), local_path);
				transfer->total_size += wr_file_size(fts_file);
				wi_mutable_array_add_data(transfer->files, fts_file);
				wi_release(fts_file);
			}
		}
		
		wi_fts_close(fts);
	}
	
	return true;
}
Ejemplo n.º 25
0
static void wd_transfers_update_queue(void) {
	wi_mutable_set_t		*users;
	wi_mutable_array_t		*sorted_users, *transfers_queue, *failed_transfers;
	wd_transfer_t			*transfer;
	wd_user_t				*user;
	wi_uinteger_t			position;
	wi_uinteger_t			i, count;
	wi_uinteger_t			total_downloads, total_uploads, user_downloads, user_uploads, active_downloads, active_uploads;
	wi_boolean_t			queue;
	
	wi_array_rdlock(wd_transfers);
	
	total_downloads		= wd_settings.totaldownloads;
	user_downloads		= wd_settings.clientdownloads;
	total_uploads		= wd_settings.totaluploads;
	user_uploads		= wd_settings.clientuploads;
	active_downloads	= 0;
	active_uploads		= 0;
	
	failed_transfers	= wi_array_init(wi_mutable_array_alloc());

	users				= wi_set_init(wi_mutable_set_alloc());
	count				= wi_array_count(wd_transfers);
	
	for(i = 0; i < count; i++) {
		transfer = WI_ARRAY(wd_transfers, i);
		
		if(wd_transfer_state(transfer) == WD_TRANSFER_QUEUED) {
			wi_mutable_array_add_data(wd_user_transfers_queue(transfer->user), transfer);
			wi_mutable_set_add_data(users, transfer->user);
		}
		
		wd_user_clear_downloads(transfer->user);
		wd_user_clear_uploads(transfer->user);
	}
	
	for(i = 0; i < count; i++) {
		transfer = WI_ARRAY(wd_transfers, i);
		
		if(wd_transfer_state(transfer) == WD_TRANSFER_RUNNING) {
			if(transfer->type == WD_TRANSFER_DOWNLOAD) {
				active_downloads++;
				wd_user_increase_downloads(transfer->user);
			} else {
				active_uploads++;
				wd_user_increase_uploads(transfer->user);
			}
		}
	}

	count = wi_set_count(users);
	
	if(count > 0) {
		sorted_users = wi_autorelease(wi_mutable_copy(wi_set_all_data(users)));
		
		wi_mutable_array_sort(sorted_users, wd_transfers_compare_user);
		
		position = 1;
		
		while(count > 0) {
			for(i = 0; i < count; i++) {
				user = WI_ARRAY(sorted_users, i);
				transfers_queue = wd_user_transfers_queue(user);
				transfer = WI_ARRAY(transfers_queue, 0);
				
				if(transfer->type == WD_TRANSFER_DOWNLOAD) {
					queue = ((total_downloads > 0 && active_downloads >= total_downloads) ||
							 (user_downloads > 0 && wd_user_downloads(transfer->user) >= user_downloads));
				} else {
					queue = ((total_uploads > 0 && active_uploads >= total_uploads) ||
							 (user_uploads > 0 && wd_user_uploads(transfer->user) >= user_uploads));
				}
				
				if(queue) {
					if(transfer->queue != position) {
						transfer->queue = position;
						
						wd_user_lock_socket(transfer->user);
						wd_sreply(wd_user_socket(transfer->user), 401, WI_STR("%#@%c%u"),
								  transfer->path,	WD_FIELD_SEPARATOR,
								  transfer->queue);
						wd_user_unlock_socket(transfer->user);
					}

					position++;
				} else {
					transfer->queue = 0;
					transfer->waiting_time = wi_time_interval();
					
					wd_transfer_set_state(transfer, WD_TRANSFER_WAITING);
					
					if(wd_transfer_open(transfer)) {
						wd_transfer_create_timer(transfer);
						
						wd_user_lock_socket(transfer->user);
						wd_sreply(wd_user_socket(transfer->user), 400, WI_STR("%#@%c%llu%c%#@"),
								  transfer->path,		WD_FIELD_SEPARATOR,
								  transfer->offset,		WD_FIELD_SEPARATOR,
								  transfer->hash);
						wd_user_unlock_socket(transfer->user);
					} else {
						wd_user_lock_socket(transfer->user);
						wd_sreply(wd_user_socket(transfer->user), 500, WI_STR("Command Failed"));
						wd_user_unlock_socket(transfer->user);
						
						wi_mutable_array_add_data(failed_transfers, transfer);
					}
				}
				
				wi_mutable_array_remove_data_at_index(transfers_queue, 0);
				
				if(wi_array_count(transfers_queue) == 0) {
					wi_mutable_array_remove_data_at_index(sorted_users, i);
					
					i--;
					count--;
				}
			}
		}
	}
	
	wi_mutable_array_remove_data_in_array(wd_transfers, failed_transfers);
	wi_array_unlock(wd_transfers);
	
	wi_release(users);
	wi_release(failed_transfers);
}
Ejemplo n.º 26
0
void wi_terminal_add_buffer(wi_terminal_t *terminal, wi_terminal_buffer_t *buffer) {
	wi_mutable_array_add_data(terminal->buffers, buffer);
}
Ejemplo n.º 27
0
int main(int argc, const char **argv) {
	wi_mutable_array_t		*arguments;
	wi_pool_t				*pool;
	wi_string_t				*string, *root_path;
	int						ch, facility;
	wi_boolean_t			test_config, daemonize, change_directory, switch_user;

	/* init libwired */
	wi_initialize();
	wi_load(argc, argv);
	
	pool					= wi_pool_init(wi_pool_alloc());
	wi_log_syslog			= true;
	wi_log_syslog_facility	= LOG_DAEMON;

	/* init core systems */
	wt_version_init();
	wt_status_lock			= wi_lock_init(wi_lock_alloc());
	wt_start_date			= wi_date_init(wi_date_alloc());
	
	/* set defaults */
	root_path				= WI_STR(WT_ROOT);
	wi_settings_config_path	= wi_string_init_with_cstring(wi_string_alloc(), WT_CONFIG_PATH);
	test_config				= false;
	daemonize				= true;
	change_directory		= true;
	switch_user				= true;

	/* init reexec argument list */
	arguments				= wi_array_init(wi_mutable_array_alloc());

	/* parse command line switches */
	while((ch = getopt(argc, (char * const *) argv, "46Dd:f:hi:L:ls:tuVvXx")) != -1) {
		switch(ch) {
			case '4':
				wt_address_family = WI_ADDRESS_IPV4;
				break;

			case '6':
				wt_address_family = WI_ADDRESS_IPV6;
				break;

			case 'D':
				daemonize = false;
				wi_log_stderr = true;
				break;

			case 'd':
				root_path = wi_string_with_cstring(optarg);
				break;

			case 'f':
				wi_release(wi_settings_config_path);
				wi_settings_config_path = wi_string_init_with_cstring(wi_string_alloc(), optarg);
				break;

			case 'i':
				wi_log_limit = wi_string_uint32(wi_string_with_cstring(optarg));
				break;

			case 'L':
				wi_log_syslog = false;
				wi_log_file = true;

				wi_release(wi_log_path);
				wi_log_path = wi_string_init_with_cstring(wi_string_alloc(), optarg);
				break;

			case 'l':
				wi_log_level++;
				break;

			case 's':
				string = wi_string_with_cstring(optarg);
				facility = wi_log_syslog_facility_with_name(string);
				
				if(facility < 0)
					wi_log_fatal(WI_STR("Could not find syslog facility \"%@\": %m"), string);
				
				wi_log_syslog_facility = facility;
				break;

			case 't':
				test_config = true;
				break;

			case 'u':
				break;

			case 'V':
			case 'v':
				wt_version();
				break;
				
			case 'X':
				daemonize = false;
				break;
				
			case 'x':
				daemonize = false;
				change_directory = false;
				switch_user = false;
				break;
			
			case '?':
			case 'h':
			default:
				wt_usage();
				break;
		}
		
		wi_mutable_array_add_data(arguments, wi_string_with_format(WI_STR("-%c"), ch));
		
		if(optarg)
			wi_mutable_array_add_data(arguments, wi_string_with_cstring(optarg));
	}
	
	/* detach */
	if(daemonize) {
		wi_mutable_array_add_data(arguments, WI_STR("-X"));
		
		switch(wi_fork()) {
			case -1:
				wi_log_fatal(WI_STR("Could not fork: %m"));
				break;
				
			case 0:
				if(!wi_execv(wi_string_with_cstring(argv[0]), arguments))
					wi_log_fatal(WI_STR("Could not execute %s: %m"), argv[0]);
				break;
				
				default:
				_exit(0);
				break;
		}
	}
	
	wi_release(arguments);
	
	/* change directory */
	if(change_directory) {
		if(!wi_fs_change_directory(root_path))
			wi_log_error(WI_STR("Could not change directory to %@: %m"), root_path);
	}
	
	/* open log */
	wi_log_open();

	/* init subsystems */
	wt_ssl_init();
	wt_clients_init();
	wt_servers_init();

	/* read the config file */
	wt_settings_init();

	if(!wt_settings_read_config())
		exit(1);

	/* apply settings */
	wt_settings_apply_settings();

	if(test_config) {
		printf("Config OK\n");

		exit(0);
	}

	/* dump command line */
	wi_log_info(WI_STR("Started as %@ %@"),
		wi_process_path(wi_process()),
		wi_array_components_joined_by_string(wi_process_arguments(wi_process()), WI_STR(" ")));

	/* init tracker */
	wi_log_info(WI_STR("Starting Wired Tracker version %@"), wt_version_string);
	wt_tracker_init();

	/* switch user/group */
	if(switch_user)
		wi_switch_user(wt_settings.user, wt_settings.group);
		
	/* create tracker threads after privilege drop */
	wt_signals_init();
	wt_block_signals();
	wt_servers_schedule();
	wt_tracker_create_threads();
	wt_write_pid();
	wt_write_status(true);
	
	/* clean up pool after startup */
	wi_pool_drain(pool);
	
	/* enter the signal handling thread in the main thread */
	wt_signal_thread(NULL);

	/* dropped out */
	wt_cleanup();
	wi_log_close();
	wi_release(pool);

	return 0;
}
Ejemplo n.º 28
0
void wd_server_init(void) {
	wi_enumerator_t			*enumerator;
	wi_array_t				*array, *addresses;
	wi_address_t			*address;
	wi_socket_t				*control_socket, *transfer_socket;
	wi_string_t				*ip, *string;
	wi_address_family_t		family;
	
	wd_control_sockets	= wi_array_init(wi_mutable_array_alloc());
	wd_transfer_sockets	= wi_array_init(wi_mutable_array_alloc());
	addresses			= wi_array_init(wi_mutable_array_alloc());

	if(wi_array_count(wd_settings.address) > 0) {
		/* listen on configured addresses */
		wi_array_rdlock(wd_settings.address);
		
		enumerator = wi_array_data_enumerator(wd_settings.address);
		
		while((string = wi_enumerator_next_data(enumerator))) {
			array = wi_host_addresses(wi_host_with_string(string));

			if(array)
				wi_mutable_array_add_data_from_array(addresses, array);
			else
				wi_log_err(WI_STR("Could not resolve \"%@\": %m"), string);
		}
		
		wi_array_unlock(wd_settings.address);
	} else {
		/* add wildcard addresses */
		wi_mutable_array_add_data(addresses, wi_address_wildcard_for_family(WI_ADDRESS_IPV6));
		wi_mutable_array_add_data(addresses, wi_address_wildcard_for_family(WI_ADDRESS_IPV4));
	}
	
	enumerator = wi_array_data_enumerator(addresses);
	
	while((address = wi_enumerator_next_data(enumerator))) {
		ip		= wi_address_string(address);
		family	= wi_address_family(address);

		/* force address family? */
		if(wd_address_family != WI_ADDRESS_NULL && family != wd_address_family)
			continue;
		
		/* create sockets */
		wi_address_set_port(address, wd_settings.port);
		control_socket = wi_autorelease(wi_socket_init_with_address(wi_socket_alloc(), address, WI_SOCKET_TCP));

		wi_address_set_port(address, wd_settings.port + 1);
		transfer_socket = wi_autorelease(wi_socket_init_with_address(wi_socket_alloc(), address, WI_SOCKET_TCP));
	
		if(!control_socket || !transfer_socket) {
			wi_log_warn(WI_STR("Could not create socket for %@: %m"), ip);
			
			continue;
		}

		/* listen on sockets */
		if(!wi_socket_listen(control_socket)) {
			wi_log_warn(WI_STR("Could not listen on %@ port %u: %m"),
				ip, wi_address_port(wi_socket_address(control_socket)));
			
			continue;
		}

		if(!wi_socket_listen(transfer_socket)) {
			wi_log_warn(WI_STR("Could not listen on %@ port %u: %m"),
				ip, wi_address_port(wi_socket_address(transfer_socket)));
			
			continue;
		}
		
		wi_socket_set_interactive(control_socket, true);
		wi_socket_set_interactive(transfer_socket, false);

		/* add to list of sockets */
		wi_mutable_array_add_data(wd_control_sockets, control_socket);
		wi_mutable_array_add_data(wd_transfer_sockets, transfer_socket);

		wi_log_info(WI_STR("Listening on %@ ports %d-%d"),
			ip, wd_settings.port, wd_settings.port + 1);
	}

	if(wi_array_count(wd_control_sockets) == 0 || wi_array_count(wd_transfer_sockets) == 0)
		wi_log_fatal(WI_STR("No addresses available for listening"));
	
	wi_release(addresses);
	
#ifdef HAVE_DNS_SD_H
	if(wd_settings.zeroconf)
		wd_server_register_dnssd();
#endif
}
Ejemplo n.º 29
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;
}
Ejemplo n.º 30
0
void wd_trackers_apply_settings(void) {
	wi_enumerator_t		*enumerator, *address_enumerator;
	wi_string_t			*string, *path;
	wi_url_t			*url;
	wi_address_t		*address;
	wd_tracker_t		*tracker;
	wi_uinteger_t		port;
	
	wi_array_wrlock(wd_trackers);
	wi_mutable_array_remove_all_data(wd_trackers);
	
	enumerator = wi_array_data_enumerator(wd_settings.tracker);
	
	while((string = wi_enumerator_next_data(enumerator))) {
		tracker	= wi_autorelease(wd_tracker_init(wd_tracker_alloc()));
		url		= wi_autorelease(wi_url_init_with_string(wi_url_alloc(), string));
		
		if(!wi_url_is_valid(url)) {
			wi_log_warn(WI_STR("Could not parse tracker URL \"%@\""),
				string);
			
			continue;
		}

		tracker->tls = wi_socket_tls_init_with_type(wi_socket_tls_alloc(), WI_SOCKET_TLS_CLIENT);
		
		if(!tracker->tls) {
			wi_log_warn(WI_STR("Could not create TLS context: %m"));
			
			continue;
		}

		if(wd_settings.controlcipher) {
			if(!wi_socket_tls_set_ciphers(tracker->tls, wd_settings.controlcipher)) {
				wi_log_err(WI_STR("Could not set TLS cipher list \"%@\": %m"),
					wd_settings.controlcipher);
				
				continue;
			}
		}

		path = wi_url_path(url);

		if(!path || wi_string_length(path) == 0)
			path = WI_STR("/");

		tracker->host		= wi_retain(wi_url_host(url));
		tracker->category	= wi_retain(wi_string_substring_from_index(path, 1));
		tracker->addresses	= wi_retain(wi_host_addresses(wi_host_with_string(tracker->host)));

		if(!tracker->addresses) {
			wi_log_warn(WI_STR("Could not resolve \"%@\": %m"), tracker->host);
			
			continue;
		}
		
		port = wi_url_port(url);

		if(port == 0)
			port = WD_TRACKER_PORT;

		address_enumerator = wi_array_data_enumerator(tracker->addresses);
		
		while((address = wi_enumerator_next_data(address_enumerator)))
			wi_address_set_port(address, port);
		
		wi_mutable_array_add_data(wd_trackers, tracker);
	}
	
	wi_array_unlock(wd_trackers);
}