libgnunetchat

library for GNUnet Messenger
Log | Files | Refs | README | LICENSE

commit 9cb19e10c1912fa3140098e86763ecd042997d03
parent 6bbc30ef71cf23267937a73e34e185410ed73a10
Author: TheJackiMonster <thejackimonster@gmail.com>
Date:   Sun, 19 Dec 2021 02:30:27 +0100

Fixed updating room and loading groups

Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>

Diffstat:
Minclude/gnunet_chat_lib.h | 19++++++++++++-------
Msrc/gnunet_chat_context.c | 83++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Msrc/gnunet_chat_context.h | 8++++++++
Msrc/gnunet_chat_handle.c | 122+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
Msrc/gnunet_chat_handle.h | 17++++++++++++++++-
Msrc/gnunet_chat_handle_intern.c | 16+++++++---------
Msrc/gnunet_chat_lib.c | 34++++++++++++++--------------------
Msrc/gnunet_chat_lib_intern.c | 21---------------------
Msrc/gnunet_chat_message.h | 3++-
Msrc/gnunet_chat_util.c | 14+++++++++-----
10 files changed, 237 insertions(+), 100 deletions(-)

diff --git a/include/gnunet_chat_lib.h b/include/gnunet_chat_lib.h @@ -55,39 +55,44 @@ enum GNUNET_CHAT_MessageKind GNUNET_CHAT_KIND_LOGIN = 2, /**< GNUNET_CHAT_KIND_LOGIN */ /** + * The kind to inform that a context was updated. + */ + GNUNET_CHAT_KIND_UPDATE = 3, /**< GNUNET_CHAT_KIND_UPDATE */ + + /** * The kind to inform that a contact has joined a chat. */ - GNUNET_CHAT_KIND_JOIN = 3, /**< GNUNET_CHAT_KIND_JOIN */ + GNUNET_CHAT_KIND_JOIN = 4, /**< GNUNET_CHAT_KIND_JOIN */ /** * The kind to inform that a contact has left a chat. */ - GNUNET_CHAT_KIND_LEAVE = 4, /**< GNUNET_CHAT_KIND_LEAVE */ + GNUNET_CHAT_KIND_LEAVE = 5, /**< GNUNET_CHAT_KIND_LEAVE */ /** * The kind to inform that a contact has changed. */ - GNUNET_CHAT_KIND_CONTACT = 5, /**< GNUNET_CHAT_KIND_CONTACT */ + GNUNET_CHAT_KIND_CONTACT = 6, /**< GNUNET_CHAT_KIND_CONTACT */ /** * The kind to describe an invitation to a different chat. */ - GNUNET_CHAT_KIND_INVITATION = 6, /**< GNUNET_CHAT_KIND_INVITATION */ + GNUNET_CHAT_KIND_INVITATION = 7, /**< GNUNET_CHAT_KIND_INVITATION */ /** * The kind to describe a text message. */ - GNUNET_CHAT_KIND_TEXT = 7, /**< GNUNET_CHAT_KIND_TEXT */ + GNUNET_CHAT_KIND_TEXT = 8, /**< GNUNET_CHAT_KIND_TEXT */ /** * The kind to describe a shared file. */ - GNUNET_CHAT_KIND_FILE = 8, /**< GNUNET_CHAT_KIND_FILE */ + GNUNET_CHAT_KIND_FILE = 9, /**< GNUNET_CHAT_KIND_FILE */ /** * The kind to inform about a deletion of a previous message. */ - GNUNET_CHAT_KIND_DELETION = 9, /**< GNUNET_CHAT_KIND_DELETION */ + GNUNET_CHAT_KIND_DELETION = 10, /**< GNUNET_CHAT_KIND_DELETION */ /** * An unknown kind of message. diff --git a/src/gnunet_chat_context.c b/src/gnunet_chat_context.c @@ -81,7 +81,7 @@ context_create_from_contact (struct GNUNET_CHAT_Handle *handle, } void -context_destroy (struct GNUNET_CHAT_Context* context) +context_destroy (struct GNUNET_CHAT_Context *context) { GNUNET_assert((context) && (context->timestamps) && @@ -113,6 +113,56 @@ context_destroy (struct GNUNET_CHAT_Context* context) } void +context_update_room (struct GNUNET_CHAT_Context *context, + struct GNUNET_MESSENGER_Room *room) +{ + GNUNET_assert(context); + + if (room == context->room) + return; + + GNUNET_CONTAINER_multishortmap_iterate( + context->timestamps, it_destroy_context_timestamps, NULL + ); + + GNUNET_CONTAINER_multihashmap_iterate( + context->messages, it_destroy_context_messages, NULL + ); + + GNUNET_CONTAINER_multihashmap_iterate( + context->invites, it_destroy_context_invites, NULL + ); + + GNUNET_CONTAINER_multishortmap_destroy(context->timestamps); + context->timestamps = GNUNET_CONTAINER_multishortmap_create(8, GNUNET_NO); + + GNUNET_CONTAINER_multihashmap_clear(context->messages); + GNUNET_CONTAINER_multihashmap_clear(context->invites); + GNUNET_CONTAINER_multihashmap_clear(context->files); + + context->room = room; +} + +void +context_update_nick (struct GNUNET_CHAT_Context *context, + const char *nick) +{ + GNUNET_assert(context); + + util_set_name_field(nick, &(context->nick)); + + if (!context->handle) + return; + + handle_send_internal_message( + context->handle, + context, + GNUNET_CHAT_FLAG_UPDATE, + NULL + ); +} + +void context_load_config (struct GNUNET_CHAT_Context *context) { GNUNET_assert((context) && @@ -143,11 +193,27 @@ context_load_config (struct GNUNET_CHAT_Context *context) if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string( config, "chat", "name", &name)) - util_set_name_field(name, &(context->nick)); + context_update_nick(context, name); if (name) GNUNET_free(name); + unsigned long long type_number; + + if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number( + config, "chat", "type", &type_number)) + switch (type_number) { + case GNUNET_CHAT_CONTEXT_TYPE_CONTACT: + context->type = GNUNET_CHAT_CONTEXT_TYPE_CONTACT; + break; + case GNUNET_CHAT_CONTEXT_TYPE_GROUP: + context->type = GNUNET_CHAT_CONTEXT_TYPE_GROUP; + break; + default: + context->type = GNUNET_CHAT_CONTEXT_TYPE_UNKNOWN; + break; + } + destroy_config: GNUNET_CONFIGURATION_destroy(config); @@ -183,6 +249,11 @@ context_save_config (const struct GNUNET_CHAT_Context *context) config, "chat", "name", context->nick ); + if (GNUNET_CHAT_CONTEXT_TYPE_UNKNOWN != context->type) + GNUNET_CONFIGURATION_set_value_number( + config, "chat", "type", context->type + ); + char* filename; util_get_filename(directory, "chats", key, &filename); @@ -219,9 +290,11 @@ callback_scan_for_configs (void *cls, 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 - ); + { + handle_send_room_name(handle, GNUNET_MESSENGER_enter_room( + handle->messenger, &door, &key + )); + } if (key_value) GNUNET_free(key_value); diff --git a/src/gnunet_chat_context.h b/src/gnunet_chat_context.h @@ -71,6 +71,14 @@ void context_destroy (struct GNUNET_CHAT_Context* context); void +context_update_room (struct GNUNET_CHAT_Context *context, + struct GNUNET_MESSENGER_Room *room); + +void +context_update_nick (struct GNUNET_CHAT_Context *context, + const char *nick); + +void context_load_config (struct GNUNET_CHAT_Context *context); void diff --git a/src/gnunet_chat_handle.c b/src/gnunet_chat_handle.c @@ -115,7 +115,7 @@ handle_update_key (struct GNUNET_CHAT_Handle *handle) } void -handle_destroy (struct GNUNET_CHAT_Handle* handle) +handle_destroy (struct GNUNET_CHAT_Handle *handle) { GNUNET_assert((handle) && (handle->groups) && @@ -165,6 +165,46 @@ handle_destroy (struct GNUNET_CHAT_Handle* handle) GNUNET_free(handle); } +void +handle_send_internal_message (struct GNUNET_CHAT_Handle *handle, + struct GNUNET_CHAT_Context *context, + enum GNUNET_CHAT_MessageFlag flag, + const char *warning) +{ + GNUNET_assert((handle) && (GNUNET_CHAT_FLAG_NONE != flag)); + + if (!handle->msg_cb) + return; + + struct GNUNET_CHAT_Message *msg = message_create_internally( + context, flag, warning + ); + + handle->msg_cb(handle->msg_cls, context, msg); + message_destroy(msg); +} + +void +handle_send_room_name (struct GNUNET_CHAT_Handle *handle, + struct GNUNET_MESSENGER_Room *room) +{ + GNUNET_assert((handle) && (handle->messenger) && (room)); + + const char *name = GNUNET_MESSENGER_get_name(handle->messenger); + + if (!name) + return; + + struct GNUNET_MESSENGER_Message msg; + + msg.header.kind = GNUNET_MESSENGER_KIND_NAME; + msg.body.name.name = GNUNET_strdup(name); + + GNUNET_MESSENGER_send_message(room, &msg, NULL); + + GNUNET_free(msg.body.name.name); +} + int handle_request_context_by_room (struct GNUNET_CHAT_Handle *handle, struct GNUNET_MESSENGER_Room *room) @@ -181,9 +221,7 @@ handle_request_context_by_room (struct GNUNET_CHAT_Handle *handle, struct GNUNET_CHAT_CheckHandleRoomMembers check; - if ((context) && (GNUNET_CHAT_CONTEXT_TYPE_GROUP != context->type)) - goto check_context_type; - else if (context) + if (context) return GNUNET_OK; context = context_create_from_room(handle, room); @@ -197,7 +235,9 @@ handle_request_context_by_room (struct GNUNET_CHAT_Handle *handle, return GNUNET_SYSERR; } -check_context_type: + if (GNUNET_CHAT_CONTEXT_TYPE_GROUP == context->type) + goto setup_group; + check.ignore_key = GNUNET_MESSENGER_get_key(handle->messenger); check.contact = NULL; @@ -205,13 +245,6 @@ check_context_type: 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, @@ -219,8 +252,9 @@ check_context_type: context->type = GNUNET_CHAT_CONTEXT_TYPE_CONTACT; else if (checks >= 2) { - if ((context->contact) && - (context->type = GNUNET_CHAT_CONTEXT_TYPE_CONTACT)) + context->type = GNUNET_CHAT_CONTEXT_TYPE_GROUP; + + if (context->contact) { struct GNUNET_CHAT_Contact *contact = handle_get_contact_from_messenger( handle, check.contact @@ -232,32 +266,42 @@ check_context_type: context->contact = NULL; } - context->type = GNUNET_CHAT_CONTEXT_TYPE_GROUP; + goto setup_group; + } - GNUNET_MESSENGER_iterate_members(room, scan_handle_room_members, handle); + return GNUNET_OK; - struct GNUNET_CHAT_Group *group = group_create_from_context( - handle, context - ); +setup_group: + GNUNET_MESSENGER_iterate_members(room, scan_handle_room_members, handle); - group_load_config(group); + struct GNUNET_CHAT_Group *group = group_create_from_context( + handle, context + ); - if (group->topic) - group_publish(group); + group_load_config(group); - if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put( - handle->groups, key, group, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) - return GNUNET_OK; + if (group->topic) + group_publish(group); - group_destroy(group); + if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put( + handle->groups, key, group, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) + { + handle_send_internal_message( + handle, + context, + GNUNET_CHAT_FLAG_UPDATE, + NULL + ); - GNUNET_CONTAINER_multihashmap_remove(handle->contexts, key, context); - context_destroy(context); - return GNUNET_SYSERR; + return GNUNET_OK; } - return GNUNET_OK; + group_destroy(group); + + GNUNET_CONTAINER_multihashmap_remove(handle->contexts, key, context); + context_destroy(context); + return GNUNET_SYSERR; } struct GNUNET_CHAT_Contact* @@ -273,3 +317,19 @@ handle_get_contact_from_messenger (const struct GNUNET_CHAT_Handle *handle, handle->contacts, &shorthash ); } + +struct GNUNET_CHAT_Group* +handle_get_group_from_messenger (const struct GNUNET_CHAT_Handle *handle, + const struct GNUNET_MESSENGER_Room *room) +{ + GNUNET_assert((handle) && (handle->groups) && (room)); + + const struct GNUNET_HashCode *key = GNUNET_MESSENGER_room_get_key(room); + + if (!key) + return NULL; + + return GNUNET_CONTAINER_multihashmap_get( + handle->groups, key + ); +} diff --git a/src/gnunet_chat_handle.h b/src/gnunet_chat_handle.h @@ -36,6 +36,7 @@ #include <gnunet/gnunet_util_lib.h> #include "gnunet_chat_lib.h" +#include "gnunet_chat_message.h" struct GNUNET_CHAT_Handle { @@ -71,7 +72,17 @@ void handle_update_key (struct GNUNET_CHAT_Handle *handle); void -handle_destroy (struct GNUNET_CHAT_Handle* handle); +handle_destroy (struct GNUNET_CHAT_Handle *handle); + +void +handle_send_internal_message (struct GNUNET_CHAT_Handle *handle, + struct GNUNET_CHAT_Context *context, + enum GNUNET_CHAT_MessageFlag flag, + const char *warning); + +void +handle_send_room_name (struct GNUNET_CHAT_Handle *handle, + struct GNUNET_MESSENGER_Room *room); int handle_request_context_by_room (struct GNUNET_CHAT_Handle *handle, @@ -81,4 +92,8 @@ struct GNUNET_CHAT_Contact* handle_get_contact_from_messenger (const struct GNUNET_CHAT_Handle *handle, const struct GNUNET_MESSENGER_Contact *contact); +struct GNUNET_CHAT_Group* +handle_get_group_from_messenger (const struct GNUNET_CHAT_Handle *handle, + const struct GNUNET_MESSENGER_Room *room); + #endif /* GNUNET_CHAT_HANDLE_H_ */ diff --git a/src/gnunet_chat_handle_intern.c b/src/gnunet_chat_handle_intern.c @@ -266,7 +266,8 @@ check_handle_room_members (void* cls, GNUNET_MESSENGER_contact_get_key(member) ); - if ((member_key) && (0 == GNUNET_memcmp(member_key, check->ignore_key))) + if ((member_key) && (check->ignore_key) && + (0 == GNUNET_memcmp(member_key, check->ignore_key))) return GNUNET_YES; if (check->contact) @@ -313,15 +314,12 @@ on_handle_identity(void *cls, GNUNET_assert(handle->messenger); context_scan_configs(handle); - if (!handle->msg_cb) - return; - - struct GNUNET_CHAT_Message *msg = message_create_internally( - NULL, GNUNET_CHAT_FLAG_LOGIN, NULL + handle_send_internal_message( + handle, + NULL, + GNUNET_CHAT_FLAG_LOGIN, + NULL ); - - handle->msg_cb(handle->msg_cls, NULL, msg); - message_destroy(msg); } void diff --git a/src/gnunet_chat_lib.c b/src/gnunet_chat_lib.c @@ -172,10 +172,10 @@ GNUNET_CHAT_group_create (struct GNUNET_CHAT_Handle *handle, if (!room) return NULL; - intern_room_send_name(handle->messenger, room); - struct GNUNET_CHAT_Context *context = context_create_from_room(handle, room); + handle_send_room_name(handle, room); + context->type = GNUNET_CHAT_CONTEXT_TYPE_GROUP; if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put( @@ -260,7 +260,7 @@ GNUNET_CHAT_contact_set_name (struct GNUNET_CHAT_Contact *contact, if ((!contact) || (!(contact->context))) return; - util_set_name_field(name, &(contact->context->nick)); + context_update_nick(contact->context, name); } @@ -425,7 +425,7 @@ GNUNET_CHAT_group_invite_contact (struct GNUNET_CHAT_Group *group, group->context->room ); - intern_room_send_name(group->handle->messenger, GNUNET_MESSENGER_open_room( + handle_send_room_name(group->handle, GNUNET_MESSENGER_open_room( group->handle->messenger, key )); @@ -519,7 +519,8 @@ GNUNET_CHAT_context_request (struct GNUNET_CHAT_Context *context) if (!room) return; - intern_room_send_name(handle->messenger, room); + context_update_room(context, room); + handle_send_room_name(handle, room); struct GNUNET_MESSENGER_Message msg; msg.header.kind = GNUNET_MESSENGER_KIND_INVITE; @@ -527,7 +528,6 @@ GNUNET_CHAT_context_request (struct GNUNET_CHAT_Context *context) GNUNET_memcpy(&(msg.body.invite.key), &key, sizeof(msg.body.invite.key)); GNUNET_MESSENGER_send_message(other->room, &msg, context->contact); - context->room = room; } @@ -546,13 +546,13 @@ GNUNET_CHAT_context_get_contact (const struct GNUNET_CHAT_Context *context) find.ignore_key = GNUNET_MESSENGER_get_key(context->handle->messenger); find.contact = NULL; - GNUNET_MESSENGER_iterate_members( + int member_count = GNUNET_MESSENGER_iterate_members( room, it_room_find_contact, &find ); - if (!find.contact) + if ((!find.contact) || (member_count > 2)) return NULL; return handle_get_contact_from_messenger(context->handle, find.contact); @@ -565,19 +565,10 @@ GNUNET_CHAT_context_get_group (const struct GNUNET_CHAT_Context *context) if ((!context) || (GNUNET_CHAT_CONTEXT_TYPE_GROUP != context->type)) return NULL; - const struct GNUNET_MESSENGER_Room *room = context->room; - const struct GNUNET_HashCode *key = GNUNET_MESSENGER_room_get_key(room); - - if (!key) + if (!context->room) return NULL; - const struct GNUNET_CHAT_Group *group; - group = GNUNET_CONTAINER_multihashmap_get( - context->handle->groups, key - ); - - GNUNET_assert((group == NULL) || (group->context == context)); - return group; + return handle_get_group_from_messenger(context->handle, context->room); } @@ -770,6 +761,8 @@ GNUNET_CHAT_message_get_kind (const struct GNUNET_CHAT_Message *message) return GNUNET_CHAT_KIND_WARNING; case GNUNET_CHAT_FLAG_LOGIN: return GNUNET_CHAT_KIND_LOGIN; + case GNUNET_CHAT_FLAG_UPDATE: + return GNUNET_CHAT_KIND_UPDATE; default: break; } @@ -814,7 +807,8 @@ GNUNET_CHAT_message_get_timestamp (const struct GNUNET_CHAT_Message *message) struct GNUNET_CHAT_Contact* GNUNET_CHAT_message_get_sender (const struct GNUNET_CHAT_Message *message) { - if ((!message) || (!(message->context))) + if ((!message) || (GNUNET_CHAT_FLAG_NONE != message->flag) || + (!message->context) || (!message->context->room)) return NULL; const struct GNUNET_MESSENGER_Contact *sender = GNUNET_MESSENGER_get_sender( diff --git a/src/gnunet_chat_lib_intern.c b/src/gnunet_chat_lib_intern.c @@ -48,27 +48,6 @@ it_handle_iterate_contacts (void *cls, return it->cb(it->cls, it->handle, contact); } -void -intern_room_send_name (struct GNUNET_MESSENGER_Handle *handle, - struct GNUNET_MESSENGER_Room *room) -{ - GNUNET_assert((handle) && (room)); - - const char *name = GNUNET_MESSENGER_get_name(handle); - - if (!name) - return; - - struct GNUNET_MESSENGER_Message msg; - - msg.header.kind = GNUNET_MESSENGER_KIND_NAME; - msg.body.name.name = GNUNET_strdup(name); - - GNUNET_MESSENGER_send_message(room, &msg, NULL); - - GNUNET_free(msg.body.name.name); -} - struct GNUNET_CHAT_HandleIterateGroups { struct GNUNET_CHAT_Handle *handle; diff --git a/src/gnunet_chat_message.h b/src/gnunet_chat_message.h @@ -45,7 +45,8 @@ enum GNUNET_CHAT_MessageFlag { GNUNET_CHAT_FLAG_NONE = 0, GNUNET_CHAT_FLAG_WARNING = 1, - GNUNET_CHAT_FLAG_LOGIN = 2 + GNUNET_CHAT_FLAG_LOGIN = 2, + GNUNET_CHAT_FLAG_UPDATE = 3 }; struct GNUNET_CHAT_Message diff --git a/src/gnunet_chat_util.c b/src/gnunet_chat_util.c @@ -213,13 +213,17 @@ util_get_filename (const char *directory, (subdir) && (hash)); - return GNUNET_asprintf ( + char* dirname; + util_get_dirname(directory, subdir, &dirname); + + int result = GNUNET_asprintf ( filename, - "%s%c%s%c%s", - directory, - DIR_SEPARATOR, - subdir, + "%s%c%s", + dirname, DIR_SEPARATOR, GNUNET_h2s_full(hash) ); + + GNUNET_free(dirname); + return result; }