From 6bbc30ef71cf23267937a73e34e185410ed73a10 Mon Sep 17 00:00:00 2001 From: TheJackiMonster Date: Sat, 18 Dec 2021 22:32:59 +0100 Subject: Fixed problems loading configurations but still inconsistencies Signed-off-by: TheJackiMonster --- src/gnunet_chat_context.c | 74 +++++++++++++++++++++- src/gnunet_chat_context.h | 3 + src/gnunet_chat_group.c | 12 ++-- src/gnunet_chat_handle.c | 119 +++++++++++++++++++++++++++++++---- src/gnunet_chat_handle.h | 4 ++ src/gnunet_chat_handle_intern.c | 134 ++++------------------------------------ src/gnunet_chat_util.c | 18 ++++++ src/gnunet_chat_util.h | 8 ++- 8 files changed, 228 insertions(+), 144 deletions(-) diff --git a/src/gnunet_chat_context.c b/src/gnunet_chat_context.c index a95c869..f2fadc3 100644 --- a/src/gnunet_chat_context.c +++ b/src/gnunet_chat_context.c @@ -136,7 +136,7 @@ context_load_config (struct GNUNET_CHAT_Context *context) struct GNUNET_CONFIGURATION_Handle *config = GNUNET_CONFIGURATION_create(); - if (GNUNET_OK != GNUNET_CONFIGURATION_load(config, directory)) + if (GNUNET_OK != GNUNET_CONFIGURATION_load(config, filename)) goto destroy_config; char* name = NULL; @@ -167,19 +167,24 @@ context_save_config (const struct GNUNET_CHAT_Context *context) if (!directory) return; - const struct GNUNET_HashCode *hash = GNUNET_MESSENGER_room_get_key( + const struct GNUNET_HashCode *key = GNUNET_MESSENGER_room_get_key( context->room ); struct GNUNET_CONFIGURATION_Handle *config = GNUNET_CONFIGURATION_create(); + if (context->room) + GNUNET_CONFIGURATION_set_value_string( + config, "chat", "key", GNUNET_h2s_full(key) + ); + if (context->nick) GNUNET_CONFIGURATION_set_value_string( config, "chat", "name", context->nick ); char* filename; - util_get_filename(directory, "chats", hash, &filename); + util_get_filename(directory, "chats", key, &filename); if (GNUNET_OK == GNUNET_DISK_directory_create_for_file(filename)) GNUNET_CONFIGURATION_write(config, filename); @@ -188,3 +193,66 @@ context_save_config (const struct GNUNET_CHAT_Context *context) GNUNET_free(filename); } + +enum GNUNET_GenericReturnValue +callback_scan_for_configs (void *cls, + const char *filename) +{ + struct GNUNET_CHAT_Handle *handle = (struct GNUNET_CHAT_Handle*) cls; + struct GNUNET_PeerIdentity door; + struct GNUNET_HashCode key; + + memset(&door, 0, sizeof(door)); + memset(&key, 0, sizeof(key)); + + if ((!filename) || + (GNUNET_OK != GNUNET_CRYPTO_get_peer_identity(handle->cfg, &door))) + return GNUNET_YES; + + struct GNUNET_CONFIGURATION_Handle *config = GNUNET_CONFIGURATION_create(); + + if (GNUNET_OK != GNUNET_CONFIGURATION_load(config, filename)) + goto destroy_config; + + char* key_value = NULL; + + if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_string( + config, "chat", "key", &key_value)) && + (GNUNET_OK == GNUNET_CRYPTO_hash_from_string(key_value, &key))) + GNUNET_MESSENGER_enter_room( + handle->messenger, &door, &key + ); + + if (key_value) + GNUNET_free(key_value); + +destroy_config: + GNUNET_CONFIGURATION_destroy(config); + return GNUNET_YES; +} + +void +context_scan_configs (struct GNUNET_CHAT_Handle *handle) +{ + GNUNET_assert((handle) && (handle->messenger)); + + const char *directory = handle->directory; + + if (!directory) + return; + + char* dirname; + util_get_dirname(handle->directory, "chats", &dirname); + + if (GNUNET_YES != GNUNET_DISK_directory_test(dirname, GNUNET_YES)) + goto free_dirname; + + GNUNET_DISK_directory_scan( + dirname, + callback_scan_for_configs, + handle + ); + +free_dirname: + GNUNET_free(dirname); +} diff --git a/src/gnunet_chat_context.h b/src/gnunet_chat_context.h index 9830233..7880e1a 100644 --- a/src/gnunet_chat_context.h +++ b/src/gnunet_chat_context.h @@ -76,4 +76,7 @@ context_load_config (struct GNUNET_CHAT_Context *context); void context_save_config (const struct GNUNET_CHAT_Context *context); +void +context_scan_configs (struct GNUNET_CHAT_Handle *handle); + #endif /* GNUNET_CHAT_CONTEXT_H_ */ diff --git a/src/gnunet_chat_group.c b/src/gnunet_chat_group.c index 6091203..979af18 100644 --- a/src/gnunet_chat_group.c +++ b/src/gnunet_chat_group.c @@ -109,19 +109,19 @@ group_load_config (struct GNUNET_CHAT_Group *group) if ((!directory) || (!(group->context))) return; - const struct GNUNET_HashCode *hash = GNUNET_MESSENGER_room_get_key( + const struct GNUNET_HashCode *key = GNUNET_MESSENGER_room_get_key( group->context->room ); char* filename; - util_get_filename(directory, "groups", hash, &filename); + util_get_filename(directory, "groups", key, &filename); if (GNUNET_YES != GNUNET_DISK_file_test(filename)) goto free_filename; struct GNUNET_CONFIGURATION_Handle *config = GNUNET_CONFIGURATION_create(); - if (GNUNET_OK != GNUNET_CONFIGURATION_load(config, directory)) + if (GNUNET_OK != GNUNET_CONFIGURATION_load(config, filename)) goto destroy_config; char* name = NULL; @@ -150,7 +150,7 @@ group_save_config (const struct GNUNET_CHAT_Group *group) if ((!directory) || (!(group->context))) return; - const struct GNUNET_HashCode *hash = GNUNET_MESSENGER_room_get_key( + const struct GNUNET_HashCode *key = GNUNET_MESSENGER_room_get_key( group->context->room ); @@ -161,14 +161,14 @@ group_save_config (const struct GNUNET_CHAT_Group *group) struct GNUNET_HashCode topic_hash; GNUNET_CRYPTO_hash(group->topic, strlen(group->topic), &topic_hash); - if (0 == GNUNET_memcmp(hash, &topic_hash)) + if (0 == GNUNET_memcmp(key, &topic_hash)) GNUNET_CONFIGURATION_set_value_string( config, "group", "topic", group->topic ); } char* filename; - util_get_filename(directory, "groups", hash, &filename); + util_get_filename(directory, "groups", key, &filename); if (GNUNET_OK == GNUNET_DISK_directory_create_for_file(filename)) GNUNET_CONFIGURATION_write(config, filename); diff --git a/src/gnunet_chat_handle.c b/src/gnunet_chat_handle.c index 668aeec..03d2e26 100644 --- a/src/gnunet_chat_handle.c +++ b/src/gnunet_chat_handle.c @@ -126,18 +126,6 @@ handle_destroy (struct GNUNET_CHAT_Handle* handle) if (handle->shutdown_hook) GNUNET_SCHEDULER_cancel(handle->shutdown_hook); - if (handle->public_key) - GNUNET_free(handle->public_key); - - if (handle->messenger) - GNUNET_MESSENGER_disconnect(handle->messenger); - - if (handle->files) - GNUNET_FS_stop(handle->fs); - - if (handle->arm) - GNUNET_ARM_disconnect(handle->arm); - GNUNET_CONTAINER_multihashmap_iterate( handle->groups, it_destroy_handle_groups, NULL ); @@ -150,6 +138,18 @@ handle_destroy (struct GNUNET_CHAT_Handle* handle) handle->contexts, it_destroy_handle_contexts, NULL ); + if (handle->public_key) + GNUNET_free(handle->public_key); + + if (handle->messenger) + GNUNET_MESSENGER_disconnect(handle->messenger); + + if (handle->files) + GNUNET_FS_stop(handle->fs); + + if (handle->arm) + GNUNET_ARM_disconnect(handle->arm); + GNUNET_CONTAINER_multihashmap_iterate( handle->files, it_destroy_handle_files, NULL ); @@ -165,6 +165,101 @@ handle_destroy (struct GNUNET_CHAT_Handle* handle) GNUNET_free(handle); } +int +handle_request_context_by_room (struct GNUNET_CHAT_Handle *handle, + struct GNUNET_MESSENGER_Room *room) +{ + GNUNET_assert((handle) && + (handle->contexts) && + (room)); + + const struct GNUNET_HashCode *key = GNUNET_MESSENGER_room_get_key(room); + + struct GNUNET_CHAT_Context *context = GNUNET_CONTAINER_multihashmap_get( + handle->contexts, key + ); + + struct GNUNET_CHAT_CheckHandleRoomMembers check; + + if ((context) && (GNUNET_CHAT_CONTEXT_TYPE_GROUP != context->type)) + goto check_context_type; + else if (context) + return GNUNET_OK; + + context = context_create_from_room(handle, room); + context_load_config(context); + + if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put( + handle->contexts, key, context, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) + { + context_destroy(context); + return GNUNET_SYSERR; + } + +check_context_type: + check.ignore_key = GNUNET_MESSENGER_get_key(handle->messenger); + check.contact = NULL; + + const int checks = GNUNET_MESSENGER_iterate_members( + room, check_handle_room_members, &check + ); + + if (GNUNET_SYSERR == checks) + { + GNUNET_CONTAINER_multihashmap_remove(handle->contexts, key, context); + context_destroy(context); + return GNUNET_SYSERR; + } + + if ((check.contact) && + (GNUNET_OK == intern_provide_contact_for_member(handle, + check.contact, + context))) + context->type = GNUNET_CHAT_CONTEXT_TYPE_CONTACT; + else if (checks >= 2) + { + if ((context->contact) && + (context->type = GNUNET_CHAT_CONTEXT_TYPE_CONTACT)) + { + struct GNUNET_CHAT_Contact *contact = handle_get_contact_from_messenger( + handle, check.contact + ); + + if ((contact) && (contact->context == context)) + contact->context = NULL; + + context->contact = NULL; + } + + context->type = GNUNET_CHAT_CONTEXT_TYPE_GROUP; + + GNUNET_MESSENGER_iterate_members(room, scan_handle_room_members, handle); + + struct GNUNET_CHAT_Group *group = group_create_from_context( + handle, context + ); + + group_load_config(group); + + if (group->topic) + group_publish(group); + + if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put( + handle->groups, key, group, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) + return GNUNET_OK; + + group_destroy(group); + + GNUNET_CONTAINER_multihashmap_remove(handle->contexts, key, context); + context_destroy(context); + return GNUNET_SYSERR; + } + + return GNUNET_OK; +} + struct GNUNET_CHAT_Contact* handle_get_contact_from_messenger (const struct GNUNET_CHAT_Handle *handle, const struct GNUNET_MESSENGER_Contact *contact) diff --git a/src/gnunet_chat_handle.h b/src/gnunet_chat_handle.h index c8afb0a..399de6b 100644 --- a/src/gnunet_chat_handle.h +++ b/src/gnunet_chat_handle.h @@ -73,6 +73,10 @@ handle_update_key (struct GNUNET_CHAT_Handle *handle); void handle_destroy (struct GNUNET_CHAT_Handle* handle); +int +handle_request_context_by_room (struct GNUNET_CHAT_Handle *handle, + struct GNUNET_MESSENGER_Room *room); + struct GNUNET_CHAT_Contact* handle_get_contact_from_messenger (const struct GNUNET_CHAT_Handle *handle, const struct GNUNET_MESSENGER_Contact *contact); diff --git a/src/gnunet_chat_handle_intern.c b/src/gnunet_chat_handle_intern.c index d804545..70e4da4 100644 --- a/src/gnunet_chat_handle_intern.c +++ b/src/gnunet_chat_handle_intern.c @@ -217,7 +217,10 @@ intern_provide_contact_for_member(struct GNUNET_CHAT_Handle *handle, if (contact) { if ((context) && (NULL == contact->context)) + { contact->context = context; + context->contact = member; + } return GNUNET_OK; } @@ -227,13 +230,19 @@ intern_provide_contact_for_member(struct GNUNET_CHAT_Handle *handle, ); if (context) + { contact->context = context; + context->contact = member; + } if (GNUNET_OK == GNUNET_CONTAINER_multishortmap_put( handle->contacts, &shorthash, contact, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) return GNUNET_OK; + if (context) + context->contact = NULL; + contact_destroy(contact); return GNUNET_SYSERR; } @@ -257,7 +266,7 @@ check_handle_room_members (void* cls, GNUNET_MESSENGER_contact_get_key(member) ); - if (0 == GNUNET_memcmp(member_key, check->ignore_key)) + if ((member_key) && (0 == GNUNET_memcmp(member_key, check->ignore_key))) return GNUNET_YES; if (check->contact) @@ -270,94 +279,6 @@ check_handle_room_members (void* cls, return GNUNET_YES; } -int -request_handle_context_by_room (struct GNUNET_CHAT_Handle *handle, - struct GNUNET_MESSENGER_Room *room) -{ - GNUNET_assert((handle) && - (handle->contexts) && - (room)); - - const struct GNUNET_HashCode *key = GNUNET_MESSENGER_room_get_key(room); - - struct GNUNET_CHAT_Context *context = GNUNET_CONTAINER_multihashmap_get( - handle->contexts, key - ); - - struct GNUNET_CHAT_CheckHandleRoomMembers check; - - if ((context) && (GNUNET_CHAT_CONTEXT_TYPE_UNKNOWN == context->type)) - goto check_context_type; - else if (context) - return GNUNET_OK; - - context = context_create_from_room(handle, room); - context_load_config(context); - - if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put( - handle->contexts, key, context, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) - { - context_destroy(context); - return GNUNET_SYSERR; - } - -check_context_type: - check.ignore_key = GNUNET_MESSENGER_get_key(handle->messenger); - check.contact = NULL; - - const int checks = GNUNET_MESSENGER_iterate_members( - room, check_handle_room_members, &check - ); - - if ((check.contact) && - (GNUNET_OK == intern_provide_contact_for_member(handle, - check.contact, - context))) - context->type = GNUNET_CHAT_CONTEXT_TYPE_CONTACT; - else if (checks >= 2) - { - context->type = GNUNET_CHAT_CONTEXT_TYPE_GROUP; - - struct GNUNET_CHAT_Group *group = group_create_from_context( - handle, context - ); - - group_load_config(group); - - if (group->topic) - group_publish(group); - - if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put( - handle->groups, key, group, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) - return GNUNET_OK; - - group_destroy(group); - - GNUNET_CONTAINER_multihashmap_remove(handle->contexts, key, context); - context_destroy(context); - return GNUNET_SYSERR; - } - - return GNUNET_OK; -} - -int -find_handle_rooms (void *cls, - struct GNUNET_MESSENGER_Room *room, - GNUNET_UNUSED const struct GNUNET_MESSENGER_Contact *member) -{ - struct GNUNET_CHAT_Handle *handle = cls; - - GNUNET_assert((handle) && (room)); - - if (GNUNET_OK != request_handle_context_by_room(handle, room)) - return GNUNET_NO; - - return GNUNET_YES; -} - int scan_handle_room_members (void* cls, GNUNET_UNUSED struct GNUNET_MESSENGER_Room *room, @@ -371,30 +292,6 @@ scan_handle_room_members (void* cls, return GNUNET_NO; } -int -scan_handle_rooms (void *cls, - struct GNUNET_MESSENGER_Room *room, - GNUNET_UNUSED const struct GNUNET_MESSENGER_Contact *member) -{ - struct GNUNET_CHAT_Handle *handle = cls; - - GNUNET_assert((handle) && - (handle->groups) && - (room)); - - const struct GNUNET_HashCode *key = GNUNET_MESSENGER_room_get_key(room); - - struct GNUNET_CHAT_Group *group = GNUNET_CONTAINER_multihashmap_get( - handle->groups, key - ); - - if (!group) - return GNUNET_YES; - - GNUNET_MESSENGER_iterate_members(room, scan_handle_room_members, handle); - return GNUNET_YES; -} - void on_handle_identity(void *cls, GNUNET_UNUSED struct GNUNET_MESSENGER_Handle *messenger) @@ -414,14 +311,7 @@ on_handle_identity(void *cls, return; GNUNET_assert(handle->messenger); - - GNUNET_MESSENGER_find_rooms( - handle->messenger, NULL, find_handle_rooms, handle - ); - - GNUNET_MESSENGER_find_rooms( - handle->messenger, NULL, scan_handle_rooms, handle - ); + context_scan_configs(handle); if (!handle->msg_cb) return; @@ -449,7 +339,7 @@ on_handle_message (void *cls, (msg) && (hash)); - if ((GNUNET_OK != request_handle_context_by_room(handle, room)) || + if ((GNUNET_OK != handle_request_context_by_room(handle, room)) || (GNUNET_OK != intern_provide_contact_for_member(handle, sender, NULL))) return; diff --git a/src/gnunet_chat_util.c b/src/gnunet_chat_util.c index 810c4f3..f8d98f2 100644 --- a/src/gnunet_chat_util.c +++ b/src/gnunet_chat_util.c @@ -184,6 +184,24 @@ util_decrypt_file (const char *filename, return GNUNET_OK; } +int +util_get_dirname (const char *directory, + const char *subdir, + char **filename) +{ + GNUNET_assert((filename) && + (directory) && + (subdir)); + + return GNUNET_asprintf ( + filename, + "%s%c%s", + directory, + DIR_SEPARATOR, + subdir + ); +} + int util_get_filename (const char *directory, const char *subdir, diff --git a/src/gnunet_chat_util.h b/src/gnunet_chat_util.h index 1a958d8..7497b67 100644 --- a/src/gnunet_chat_util.h +++ b/src/gnunet_chat_util.h @@ -51,7 +51,13 @@ util_decrypt_file (const char *filename, const struct GNUNET_CRYPTO_SymmetricSessionKey *key); int -util_get_filename (const char *directory, const char *subdir, +util_get_dirname (const char *directory, + const char *subdir, + char **filename); + +int +util_get_filename (const char *directory, + const char *subdir, const struct GNUNET_HashCode *hash, char **filename); -- cgit v1.2.3