コード例 #1
0
ファイル: wi-sqlite3.c プロジェクト: ProfDrLuigi/zanka
wi_sqlite3_statement_t * wi_sqlite3_prepare_statement(wi_sqlite3_database_t *database, wi_string_t *query, ...) {
	wi_sqlite3_statement_t		*statement;
	va_list						ap;
	
	statement				= wi_autorelease(wi_runtime_create_instance(_wi_sqlite3_statement_runtime_id, sizeof(wi_sqlite3_statement_t)));
	statement->query		= wi_retain(query);
	
	wi_recursive_lock_lock(database->lock);
	
	if(
#ifdef HAVE_SQLITE3_PREPARE_V2
	   sqlite3_prepare_v2
#else
	   sqlite3_prepare
#endif
	   (database->database, wi_string_cstring(query), wi_string_length(query), &statement->statement, NULL) == SQLITE_OK) {
		va_start(ap, query);
		_wi_sqlite3_bind_statement(statement, ap);
		va_end(ap);
	} else {
		wi_error_set_sqlite3_error_with_description(database->database, wi_description(statement));
		
		statement = NULL;
	}
	
	wi_recursive_lock_unlock(database->lock);
	
	return statement;
}
コード例 #2
0
ファイル: users.c プロジェクト: ProfDrLuigi/wired
void wd_user_unsubscribe_paths(wd_user_t *user) {
	wi_enumerator_t		*enumerator;
	wi_string_t			*path;
	
	wi_recursive_lock_lock(user->user_lock);

	enumerator = wi_array_data_enumerator(wi_set_all_data(user->subscribed_paths));
		
	while((path = wi_enumerator_next_data(enumerator))) {
		wi_retain(path);

		while(wi_set_contains_data(user->subscribed_paths, path)) {
			if(wd_files_fsevents)
				wi_fsevents_remove_path(wd_files_fsevents, path);

			wi_mutable_set_remove_data(user->subscribed_paths, path);
		}
			
		wi_release(path);
	}
	
	wi_mutable_dictionary_remove_all_data(user->subscribed_virtualpaths);
		
	wi_recursive_lock_unlock(user->user_lock);
}
コード例 #3
0
ファイル: chats.c プロジェクト: ProfDrLuigi/zanka
void wd_chat_set_topic(wd_chat_t *chat, wd_topic_t *topic) {
	wi_recursive_lock_lock(chat->lock);
	wi_retain(topic);
	wi_release(chat->topic);
	chat->topic = topic;
	wi_recursive_lock_unlock(chat->lock);
}
コード例 #4
0
ファイル: users.c プロジェクト: ProfDrLuigi/zanka
static void wd_users_update_idle(wi_timer_t *timer) {
	wi_enumerator_t		*enumerator;
	wd_user_t			*user;
	wi_time_interval_t	interval;

	wi_dictionary_rdlock(wd_users);

	if(wi_dictionary_count(wd_users) > 0) {
		interval = wi_time_interval();

		enumerator = wi_dictionary_data_enumerator(wd_users);
		
		while((user = wi_enumerator_next_data(enumerator))) {
			wi_recursive_lock_lock(user->user_lock);
			
			if(user->state == WD_USER_LOGGED_IN && !user->idle &&
			   user->idle_time + wd_settings.idletime < interval) {
				user->idle = true;

				wd_user_broadcast_status(user);
			}

			wi_recursive_lock_unlock(user->user_lock);
		}
	}
		
	wi_dictionary_unlock(wd_users);
}
コード例 #5
0
ファイル: users.c プロジェクト: ProfDrLuigi/wired
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;
}
コード例 #6
0
ファイル: chats.c プロジェクト: ProfDrLuigi/zanka
wd_topic_t * wd_chat_topic(wd_chat_t *chat) {
	wd_topic_t		*topic;
	
	wi_recursive_lock_lock(chat->lock);
	topic = wi_autorelease(wi_retain(chat->topic));
	wi_recursive_lock_unlock(chat->lock);
	
	return topic;
}
コード例 #7
0
ファイル: users.c プロジェクト: ProfDrLuigi/zanka
wi_string_t * wd_user_identifier(wd_user_t *user) {
	wi_string_t		*identifier;
	
	wi_recursive_lock_lock(user->user_lock);
	identifier = wi_string_with_format(WI_STR("%@/%@/%@"), user->nick, user->login, user->ip);
	wi_recursive_lock_unlock(user->user_lock);
	
	return identifier;
}
コード例 #8
0
ファイル: users.c プロジェクト: ProfDrLuigi/wired
void wd_users_reply_users(wd_user_t *user, wi_p7_message_t *message) {
	wi_enumerator_t				*enumerator;
	wi_p7_message_t				*reply;
	wd_user_t					*peer;
	wd_user_protocol_state_t	state;
	
	wi_dictionary_rdlock(wd_users);

	enumerator = wi_dictionary_data_enumerator(wd_users);
	
	while((peer = wi_enumerator_next_data(enumerator))) {
		wi_recursive_lock_lock(peer->user_lock);
		
		switch(user->state) {
			default:
			case WD_USER_CONNECTED:			state = WD_USER_PROTOCOL_CONNECTED;		break;
			case WD_USER_GAVE_CLIENT_INFO:	state = WD_USER_PROTOCOL_LOGGING_IN;	break;
			case WD_USER_SAID_HELLO:		state = WD_USER_PROTOCOL_LOGGING_IN;	break;
			case WD_USER_GAVE_USER:			state = WD_USER_PROTOCOL_LOGGING_IN;	break;
			case WD_USER_LOGGED_IN:			state = WD_USER_PROTOCOL_LOGGED_IN;		break;
			case WD_USER_DISCONNECTED:		state = WD_USER_PROTOCOL_DISCONNECTING;	break;
		}
		
		reply = wi_p7_message_with_name(WI_STR("wired.user.user_list"), wd_p7_spec);
		wi_p7_message_set_uint32_for_name(reply, peer->id, WI_STR("wired.user.id"));
		wi_p7_message_set_bool_for_name(reply, peer->idle, WI_STR("wired.user.idle"));
		wi_p7_message_set_string_for_name(reply, peer->nick, WI_STR("wired.user.nick"));
		wi_p7_message_set_string_for_name(reply, peer->status, WI_STR("wired.user.status"));
		wi_p7_message_set_data_for_name(reply, peer->icon, WI_STR("wired.user.icon"));
		wi_p7_message_set_enum_for_name(reply, peer->color, WI_STR("wired.account.color"));
		wi_p7_message_set_date_for_name(reply, peer->idle_time, WI_STR("wired.user.idle_time"));
		
		if(peer->transfer) {
			state = WD_USER_PROTOCOL_TRANSFERRING;
			
			wi_p7_message_set_enum_for_name(reply, peer->transfer->type, WI_STR("wired.transfer.type"));
			wi_p7_message_set_string_for_name(reply, peer->transfer->path, WI_STR("wired.file.path"));
			wi_p7_message_set_uint64_for_name(reply, peer->transfer->datasize, WI_STR("wired.transfer.data_size"));
			wi_p7_message_set_uint64_for_name(reply, peer->transfer->rsrcsize, WI_STR("wired.transfer.rsrc_size"));
			wi_p7_message_set_uint64_for_name(reply, peer->transfer->transferred, WI_STR("wired.transfer.transferred"));
			wi_p7_message_set_uint32_for_name(reply, peer->transfer->speed, WI_STR("wired.transfer.speed"));
			wi_p7_message_set_uint32_for_name(reply, peer->transfer->queue, WI_STR("wired.transfer.queue_position"));
		}

		wi_p7_message_set_enum_for_name(reply, state, WI_STR("wired.user.state"));

		wi_recursive_lock_unlock(peer->user_lock);

		wd_user_reply_message(user, reply, message);
	}
	
	wi_dictionary_unlock(wd_users);
	
	reply = wi_p7_message_with_name(WI_STR("wired.user.user_list.done"), wd_p7_spec);
	wd_user_reply_message(user, reply, message);
}
コード例 #9
0
void wi_test_recursive_lock_locking(void) {
#ifdef WI_PTHREADS
    wi_recursive_lock_t     *lock;
    wi_boolean_t            result;
    
    lock = wi_autorelease(wi_recursive_lock_init(wi_recursive_lock_alloc()));
    
    wi_recursive_lock_lock(lock);
    wi_recursive_lock_lock(lock);
    wi_recursive_lock_unlock(lock);
    wi_recursive_lock_unlock(lock);
    
    result = wi_recursive_lock_try_lock(lock);
    
    WI_TEST_ASSERT_TRUE(result, "");
    
    result = wi_recursive_lock_try_lock(lock);
    
    WI_TEST_ASSERT_TRUE(result, "");
    
    wi_recursive_lock_unlock(lock);
    wi_recursive_lock_unlock(lock);
#endif
}
コード例 #10
0
ファイル: users.c プロジェクト: ProfDrLuigi/wired
void wd_user_broadcast_icon(wd_user_t *user) {
	wi_enumerator_t		*enumerator;
	wi_p7_message_t		*message;
	wd_chat_t			*chat;
	
	enumerator = wi_array_data_enumerator(wd_chats_chats_with_user(user));

	wi_recursive_lock_lock(user->user_lock);
	
	while((chat = wi_enumerator_next_data(enumerator))) {
		message = wi_p7_message_with_name(WI_STR("wired.chat.user_icon"), wd_p7_spec);
		wi_p7_message_set_uint32_for_name(message, user->id, WI_STR("wired.user.id"));
		wi_p7_message_set_uint32_for_name(message, wd_chat_id(chat), WI_STR("wired.chat.id"));
		wi_p7_message_set_data_for_name(message, user->icon, WI_STR("wired.user.icon"));
		
		wd_chat_broadcast_message(chat, message);
	}
	
	wi_recursive_lock_unlock(user->user_lock);
}
コード例 #11
0
ファイル: users.c プロジェクト: ProfDrLuigi/wired
void wd_user_unsubscribe_path(wd_user_t *user, wi_string_t *realpath) {
	wi_string_t		*metapath;
	
	wi_recursive_lock_lock(user->user_lock);
		
	wi_mutable_set_remove_data(user->subscribed_paths, realpath);

	if(wd_files_fsevents)
		wi_fsevents_remove_path(wd_files_fsevents, realpath);
		
	metapath = wi_string_by_appending_path_component(realpath, WI_STR(WD_FILES_META_PATH));
		
	wi_mutable_set_add_data(user->subscribed_paths, metapath);

	if(wd_files_fsevents)
		wi_fsevents_add_path(wd_files_fsevents, metapath);

	wi_mutable_dictionary_remove_data_for_key(user->subscribed_virtualpaths, realpath);
	
	wi_recursive_lock_unlock(user->user_lock);
}
コード例 #12
0
ファイル: users.c プロジェクト: ProfDrLuigi/wired
void wd_user_reply_user_info(wd_user_t *peer, wd_user_t *user, wi_p7_message_t *message) {
	wi_p7_message_t		*reply;
	wi_cipher_t			*cipher;
	
	wi_recursive_lock_lock(peer->user_lock);
	
	reply = wi_p7_message_with_name(WI_STR("wired.user.info"), wd_p7_spec);
	wi_p7_message_set_uint32_for_name(reply, peer->id, WI_STR("wired.user.id"));
	wi_p7_message_set_bool_for_name(reply, peer->idle, WI_STR("wired.user.idle"));
	wi_p7_message_set_string_for_name(reply, peer->login, WI_STR("wired.user.login"));
	wi_p7_message_set_string_for_name(reply, peer->nick, WI_STR("wired.user.nick"));
	wi_p7_message_set_string_for_name(reply, peer->status, WI_STR("wired.user.status"));
	wi_p7_message_set_data_for_name(reply, peer->icon, WI_STR("wired.user.icon"));
	wi_p7_message_set_enum_for_name(reply, peer->color, WI_STR("wired.account.color"));
	wi_p7_message_set_string_for_name(reply, peer->ip, WI_STR("wired.user.ip"));
	wi_p7_message_set_string_for_name(reply, peer->host, WI_STR("wired.user.host"));
	wi_p7_message_set_date_for_name(reply, peer->login_time, WI_STR("wired.user.login_time"));
	wi_p7_message_set_date_for_name(reply, peer->idle_time, WI_STR("wired.user.idle_time"));
	
	cipher = wi_p7_socket_cipher(peer->p7_socket);
	
	if(cipher) {
		wi_p7_message_set_string_for_name(reply, wi_cipher_name(cipher), WI_STR("wired.user.cipher.name"));
		wi_p7_message_set_uint32_for_name(reply, wi_cipher_bits(cipher), WI_STR("wired.user.cipher.bits"));
	}
	
	wi_p7_message_set_string_for_name(reply, peer->client_info->application_name, WI_STR("wired.info.application.name"));
	wi_p7_message_set_string_for_name(reply, peer->client_info->application_version, WI_STR("wired.info.application.version"));
	
	if(wi_string_length(peer->client_info->application_build) > 0)
		wi_p7_message_set_string_for_name(reply, peer->client_info->application_build, WI_STR("wired.info.application.build"));
	
	wi_p7_message_set_string_for_name(reply, peer->client_info->os_name, WI_STR("wired.info.os.name"));
	wi_p7_message_set_string_for_name(reply, peer->client_info->os_version, WI_STR("wired.info.os.version"));
	wi_p7_message_set_string_for_name(reply, peer->client_info->arch, WI_STR("wired.info.arch"));

	wi_recursive_lock_unlock(peer->user_lock);

	wd_user_reply_message(user, reply, message);
}
コード例 #13
0
ファイル: users.c プロジェクト: ProfDrLuigi/wired
void wd_user_broadcast_status(wd_user_t *user) {
	wi_enumerator_t		*enumerator;
	wi_p7_message_t		*message;
	wd_chat_t			*chat;
	
	enumerator = wi_array_data_enumerator(wd_chats_chats_with_user(user));

	wi_recursive_lock_lock(user->user_lock);
	
	while((chat = wi_enumerator_next_data(enumerator))) {
		message = wi_p7_message_with_name(WI_STR("wired.chat.user_status"), wd_p7_spec);
		wi_p7_message_set_uint32_for_name(message, wd_chat_id(chat), WI_STR("wired.chat.id"));
		wi_p7_message_set_uint32_for_name(message, user->id, WI_STR("wired.user.id"));
		wi_p7_message_set_bool_for_name(message, user->idle, WI_STR("wired.user.idle"));
		wi_p7_message_set_string_for_name(message, user->nick, WI_STR("wired.user.nick"));
		wi_p7_message_set_string_for_name(message, user->status, WI_STR("wired.user.status"));
		wi_p7_message_set_enum_for_name(message, user->color, WI_STR("wired.account.color"));
		wi_p7_message_set_date_for_name(message, user->idle_time, WI_STR("wired.user.idle_time"));

		wd_chat_broadcast_message(chat, message);
	}

	wi_recursive_lock_unlock(user->user_lock);
}
コード例 #14
0
ファイル: wi-sqlite3.c プロジェクト: ProfDrLuigi/zanka
void wi_sqlite3_rollback_transaction(wi_sqlite3_database_t *database) {
	if(!wi_sqlite3_execute_statement(database, WI_STR("ROLLBACK TRANSACTION"), NULL))
		WI_ASSERT(0, "Could not execute database statement: %m");

	wi_recursive_lock_unlock(database->lock);
}
コード例 #15
0
ファイル: wi-log.c プロジェクト: ProfDrLuigi/zanka
static void _wi_log_vlog(wi_log_level_t level, wi_string_t *fmt, va_list ap) {
	wi_string_t		*string;
	FILE			*fp = NULL;
	const char		*cstring, *name, *path, *prefix;
	char			date[_WI_LOG_DATE_SIZE];
	int				priority;
	
	if(_wi_log_in_callback)
		return;
	
	string = wi_string_init_with_format_and_arguments(wi_string_alloc(), fmt, ap);
	cstring = wi_string_cstring(string);
	name = wi_string_cstring(wi_process_name(wi_process()));
	
	_wi_log_date(date);
	
	switch(level) {
		default:
		case WI_LOG_INFO:
			priority = LOG_INFO;
			prefix = "Info";
			break;
			
		case WI_LOG_WARN:
			priority = LOG_WARNING;
			prefix = "Warning";
			break;
			
		case WI_LOG_ERR:
			priority = LOG_ERR;
			prefix = "Error";
			break;
			
		case WI_LOG_DEBUG:
			priority = LOG_DEBUG;
			prefix = "Debug";
			break;
	}

	if(wi_log_stdout || wi_log_stderr) {
		fp = wi_log_stdout ? stdout : stderr;

		fprintf(fp, "%s %s[%u]: %s: %s\n", date, name, (uint32_t) getpid(), prefix, cstring);
	}
	else if(wi_log_startup && level < WI_LOG_INFO) {
		fp = stderr;

		fprintf(fp, "%s: %s\n", name, cstring);
	}
	else if(wi_log_tool) {
		fp = (level < WI_LOG_INFO) ? stderr : stdout;

		fprintf(fp, "%s: %s\n", name, cstring);
	}
	else if(wi_log_plain) {
		fp = (level < WI_LOG_INFO) ? stderr : stdout;

		fprintf(fp, "%s\n", cstring);
	}

	if(fp)
		fflush(fp);

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

	if(wi_log_file && wi_log_path) {
		wi_recursive_lock_lock(_wi_log_lock);

		path = wi_string_cstring(wi_log_path);

		fp = fopen(path, "a");

		if(fp) {
			fprintf(fp, "%s %s[%u]: %s: %s\n", date, name, (uint32_t) getpid(), prefix, 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));
		}

		wi_recursive_lock_unlock(_wi_log_lock);
	}

	if(wi_log_callback) {
		_wi_log_in_callback = true;
		(*wi_log_callback)(level, string);
		_wi_log_in_callback = false;
	}

	if((wi_log_startup || wi_log_tool) && level == WI_LOG_ERR)
		exit(1);

	wi_release(string);
}
コード例 #16
0
ファイル: users.c プロジェクト: ProfDrLuigi/wired
void wd_user_unlock_socket(wd_user_t *user) {
	wi_recursive_lock_unlock(user->socket_lock);
}
コード例 #17
0
ファイル: wi-sqlite3.c プロジェクト: ProfDrLuigi/zanka
wi_dictionary_t * wi_sqlite3_fetch_statement_results(wi_sqlite3_database_t *database, wi_sqlite3_statement_t *statement) {
	wi_mutable_dictionary_t		*results;
	wi_runtime_instance_t		*instance;
	int							i, count, length, result;
	
	wi_recursive_lock_lock(database->lock);
	
	result = sqlite3_step(statement->statement);
	
	switch(result) {
		case SQLITE_DONE:
			results = wi_dictionary();

			sqlite3_finalize(statement->statement);
			statement->statement = NULL;
			break;
			
		case SQLITE_ROW:
			results			= wi_mutable_dictionary();
			count			= sqlite3_column_count(statement->statement);
			
			for(i = 0; i < count; i++) {
				switch(sqlite3_column_type(statement->statement, i)) {
					case SQLITE_INTEGER:
						instance	= wi_number_with_int64(sqlite3_column_int64(statement->statement, i));
						break;
						
					case SQLITE_FLOAT:
						instance	= wi_number_with_double(sqlite3_column_double(statement->statement, i));
						break;
						
					case SQLITE_TEXT:
						instance	= wi_string_with_cstring((const char *) sqlite3_column_text(statement->statement, i));
						break;
						
					case SQLITE_BLOB:
						length		= sqlite3_column_bytes(statement->statement, i);
						instance	= wi_data_with_bytes(sqlite3_column_blob(statement->statement, i), length);
						break;
						
					case SQLITE_NULL:
						instance	= wi_null();
						break;
					
					default:
						instance	= NULL;
						break;
				}
				
				if(instance)
					wi_mutable_dictionary_set_data_for_key(results, instance, wi_string_with_cstring(sqlite3_column_name(statement->statement, i)));
			}
	
			wi_runtime_make_immutable(results);
			break;
			
		default:
			wi_error_set_sqlite3_error_with_description(database->database, wi_description(statement));

			sqlite3_finalize(statement->statement);
			statement->statement = NULL;

			results = NULL;
			break;
	}
	
	wi_recursive_lock_unlock(database->lock);
		
	return results;
}