libgnunetchat

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

commit 10bdc736a489383d5cee691f60ad5b1d19f8c39f
parent 0b6678f50cbed14b5ff6159845f6ee1289cb8f90
Author: Jacki <jacki@thejackimonster.de>
Date:   Sun, 28 Apr 2024 18:21:59 +0200

Adjust account operations to implement new separate message kinds

Signed-off-by: Jacki <jacki@thejackimonster.de>

Diffstat:
Minclude/gnunet/gnunet_chat_lib.h | 43+++++++++++++++++++++++++++++--------------
Msrc/gnunet_chat_account.c | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Msrc/gnunet_chat_account.h | 26++++++++++++++++++++++++++
Msrc/gnunet_chat_context.c | 2+-
Msrc/gnunet_chat_handle.c | 74+++++++++++++++++++++++++++++++++-----------------------------------------
Msrc/gnunet_chat_handle.h | 16++--------------
Msrc/gnunet_chat_handle_intern.c | 188+++++++++++++++++++++++++++----------------------------------------------------
Msrc/gnunet_chat_lib.c | 12+++++++++---
Msrc/gnunet_chat_lib_intern.c | 6+++---
Msrc/gnunet_chat_message.h | 9++++++---
Asrc/internal/gnunet_chat_accounts.c | 114+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/internal/gnunet_chat_accounts.h | 71+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/internal/meson.build | 23+++++++++++++++++++++++
Msrc/meson.build | 4+++-
Mtests/test_gnunet_chat_handle.c | 436+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Mtools/gnunet_chat_lib_uml.c | 19+++++++++++++++++--
16 files changed, 693 insertions(+), 418 deletions(-)

diff --git a/include/gnunet/gnunet_chat_lib.h b/include/gnunet/gnunet_chat_lib.h @@ -90,73 +90,88 @@ enum GNUNET_CHAT_MessageKind /** * The kind to inform that the application can be used. */ - GNUNET_CHAT_KIND_LOGIN = 3, /**< GNUNET_CHAT_KIND_LOGIN */ + GNUNET_CHAT_KIND_LOGIN = 3, /**< GNUNET_CHAT_KIND_LOGIN */ /** * The kind to inform that the application needs to cleanup * resources related to the currently connected account. */ - GNUNET_CHAT_KIND_LOGOUT = 4, /**< GNUNET_CHAT_KIND_LOGOUT */ + GNUNET_CHAT_KIND_LOGOUT = 4, /**< GNUNET_CHAT_KIND_LOGOUT */ + + /** + * The kind to inform that an account was successfully created. + */ + GNUNET_CHAT_KIND_CREATED_ACCOUNT = 5, /**< GNUNET_CHAT_KIND_CREATED_ACCOUNT */ + + /** + * The kind to inform that an account was successfully deleted. + */ + GNUNET_CHAT_KIND_DELETED_ACCOUNT = 6, /**< GNUNET_CHAT_KIND_DELETED_ACCOUNT */ + + /** + * The kind to inform that an account was updated. + */ + GNUNET_CHAT_KIND_UPDATE_ACCOUNT = 7, /**< GNUNET_CHAT_KIND_UPDATE_ACCOUNT */ /** * The kind to inform that a context was updated. */ - GNUNET_CHAT_KIND_UPDATE = 5, /**< GNUNET_CHAT_KIND_UPDATE */ + GNUNET_CHAT_KIND_UPDATE_CONTEXT = 8, /**< GNUNET_CHAT_KIND_UPDATE_CONTEXT */ /** * The kind to inform that a contact has joined a chat. */ - GNUNET_CHAT_KIND_JOIN = 6, /**< GNUNET_CHAT_KIND_JOIN */ + GNUNET_CHAT_KIND_JOIN = 9, /**< GNUNET_CHAT_KIND_JOIN */ /** * The kind to inform that a contact has left a chat. */ - GNUNET_CHAT_KIND_LEAVE = 7, /**< GNUNET_CHAT_KIND_LEAVE */ + GNUNET_CHAT_KIND_LEAVE = 10, /**< GNUNET_CHAT_KIND_LEAVE */ /** * The kind to inform that a contact has changed. */ - GNUNET_CHAT_KIND_CONTACT = 8, /**< GNUNET_CHAT_KIND_CONTACT */ + GNUNET_CHAT_KIND_CONTACT = 11, /**< GNUNET_CHAT_KIND_CONTACT */ /** * The kind to describe an invitation to a different chat. */ - GNUNET_CHAT_KIND_INVITATION = 9, /**< GNUNET_CHAT_KIND_INVITATION */ + GNUNET_CHAT_KIND_INVITATION = 12, /**< GNUNET_CHAT_KIND_INVITATION */ /** * The kind to describe a text message. */ - GNUNET_CHAT_KIND_TEXT = 10, /**< GNUNET_CHAT_KIND_TEXT */ + GNUNET_CHAT_KIND_TEXT = 13, /**< GNUNET_CHAT_KIND_TEXT */ /** * The kind to describe a shared file. */ - GNUNET_CHAT_KIND_FILE = 11, /**< GNUNET_CHAT_KIND_FILE */ + GNUNET_CHAT_KIND_FILE = 14, /**< GNUNET_CHAT_KIND_FILE */ /** * The kind to inform about a deletion of a previous message. */ - GNUNET_CHAT_KIND_DELETION = 12, /**< GNUNET_CHAT_KIND_DELETION */ + GNUNET_CHAT_KIND_DELETION = 15, /**< GNUNET_CHAT_KIND_DELETION */ /** * The kind to tag a previous message. */ - GNUNET_CHAT_KIND_TAG = 13, /**< GNUNET_CHAT_KIND_TAG */ + GNUNET_CHAT_KIND_TAG = 16, /**< GNUNET_CHAT_KIND_TAG */ /** * The kind to inform that attributes were updated. */ - GNUNET_CHAT_KIND_ATTRIBUTES = 14, + GNUNET_CHAT_KIND_ATTRIBUTES = 17, /**< GNUNET_CHAT_KIND_ATTRIBUTES */ /** * The kind to inform that attributes were shared. */ - GNUNET_CHAT_KIND_SHARED_ATTRIBUTES = 15, + GNUNET_CHAT_KIND_SHARED_ATTRIBUTES = 18, /**< GNUNET_CHAT_KIND_SHARED_ATTRIBUTES */ /** * An unknown kind of message. */ - GNUNET_CHAT_KIND_UNKNOWN = 0 /**< GNUNET_CHAT_KIND_UNKNOWN */ + GNUNET_CHAT_KIND_UNKNOWN = 0 /**< GNUNET_CHAT_KIND_UNKNOWN */ }; /** diff --git a/src/gnunet_chat_account.c b/src/gnunet_chat_account.c @@ -23,17 +23,21 @@ */ #include "gnunet_chat_account.h" +#include "gnunet_chat_handle.h" #include "gnunet_chat_util.h" +#include <gnunet/gnunet_common.h> +#include <gnunet/gnunet_identity_service.h> +#include <gnunet/gnunet_messenger_service.h> + struct GNUNET_CHAT_Account* -account_create_from_ego(struct GNUNET_IDENTITY_Ego *ego, - const char *name) +account_create(const char *name) { - GNUNET_assert((ego) && (name)); + GNUNET_assert(name); struct GNUNET_CHAT_Account *account = GNUNET_new(struct GNUNET_CHAT_Account); - account->ego = ego; + account->ego = NULL; account->directory = NULL; account->name = NULL; @@ -44,6 +48,19 @@ account_create_from_ego(struct GNUNET_IDENTITY_Ego *ego, return account; } +struct GNUNET_CHAT_Account* +account_create_from_ego(struct GNUNET_IDENTITY_Ego *ego, + const char *name) +{ + GNUNET_assert((ego) && (name)); + + struct GNUNET_CHAT_Account *account = account_create(name); + + account->ego = ego; + + return account; +} + void account_update_directory (struct GNUNET_CHAT_Account *account, const char *base_directory) @@ -53,6 +70,12 @@ account_update_directory (struct GNUNET_CHAT_Account *account, if (account->directory) GNUNET_free(account->directory); + if (!(account->ego)) + { + account->directory = NULL; + return; + } + struct GNUNET_CRYPTO_PublicKey key; GNUNET_IDENTITY_ego_get_public_key(account->ego, &key); @@ -82,6 +105,43 @@ account_get_key (const struct GNUNET_CHAT_Account *account) } void +account_update_ego(struct GNUNET_CHAT_Account *account, + struct GNUNET_CHAT_Handle *handle, + struct GNUNET_IDENTITY_Ego *ego) +{ + GNUNET_assert((account) && (handle) && (ego) && (account->ego != ego)); + + enum GNUNET_CHAT_MessageFlag flag; + if ((!(account->ego)) && (handle->current != account)) + flag = GNUNET_CHAT_FLAG_CREATE_ACCOUNT; + else + flag = GNUNET_CHAT_FLAG_UPDATE_ACCOUNT; + + account->ego = ego; + + if (handle->directory) + account_update_directory(account, handle->directory); + + if ((handle->current == account) && (handle->messenger)) + { + GNUNET_MESSENGER_set_key( + handle->messenger, + GNUNET_IDENTITY_ego_get_private_key(account->ego) + ); + + handle_update_key(handle); + } + + handle_send_internal_message( + handle, + account, + NULL, + flag, + NULL + ); +} + +void account_destroy(struct GNUNET_CHAT_Account *account) { GNUNET_assert(account); diff --git a/src/gnunet_chat_account.h b/src/gnunet_chat_account.h @@ -25,9 +25,12 @@ #ifndef GNUNET_CHAT_ACCOUNT_H_ #define GNUNET_CHAT_ACCOUNT_H_ +#include <gnunet/gnunet_common.h> #include <gnunet/gnunet_identity_service.h> #include <gnunet/gnunet_util_lib.h> +struct GNUNET_CHAT_Handle; + struct GNUNET_CHAT_Account { struct GNUNET_IDENTITY_Ego *ego; @@ -38,6 +41,15 @@ struct GNUNET_CHAT_Account }; /** + * Creates a chat account using a given <i>name</i>. + * + * @param[in] name Name + * @return New chat account + */ +struct GNUNET_CHAT_Account* +account_create(const char *name); + +/** * Creates a chat account using a given <i>ego</i> and * a matching <i>name</i>. * @@ -71,6 +83,20 @@ const struct GNUNET_CRYPTO_PrivateKey* account_get_key (const struct GNUNET_CHAT_Account *account); /** + * Updates the key from a given chat <i>account</i> using + * the chat <i>handle</i> and a specific <i>ego</i> matching + * the accounts name. + * + * @param[in,out] account Chat account + * @param[in,out] handle Chat handle + * @param[in] ego EGO + */ +void +account_update_ego(struct GNUNET_CHAT_Account *account, + struct GNUNET_CHAT_Handle *handle, + struct GNUNET_IDENTITY_Ego *ego); + +/** * Destroys a chat <i>account</i> and frees its memory. * * @param[in,out] account Chat account diff --git a/src/gnunet_chat_context.c b/src/gnunet_chat_context.c @@ -243,7 +243,7 @@ context_update_nick (struct GNUNET_CHAT_Context *context, context->handle, NULL, context, - GNUNET_CHAT_FLAG_UPDATE, + GNUNET_CHAT_FLAG_UPDATE_CONTEXT, NULL ); } diff --git a/src/gnunet_chat_handle.c b/src/gnunet_chat_handle.c @@ -25,9 +25,11 @@ #include "gnunet_chat_handle.h" #include "gnunet_chat_handle_intern.c" +#include "gnunet_chat_message.h" #include <gnunet/gnunet_arm_service.h> #include <gnunet/gnunet_common.h> #include <gnunet/gnunet_reclaim_service.h> +#include <gnunet/gnunet_scheduler_lib.h> static const unsigned int initial_map_size_of_handle = 8; static const unsigned int minimum_amount_of_other_members_in_group = 2; @@ -188,6 +190,8 @@ handle_destroy (struct GNUNET_CHAT_Handle *handle) if (handle->disconnection) GNUNET_SCHEDULER_cancel(handle->disconnection); + handle->disconnection = NULL; + if (handle->monitor) GNUNET_NAMESTORE_zone_monitor_stop(handle->monitor); @@ -209,22 +213,12 @@ handle_destroy (struct GNUNET_CHAT_Handle *handle) { accounts = handle->accounts_head; - if (accounts->op) - GNUNET_IDENTITY_cancel(accounts->op); + internal_accounts_stop_method(accounts); if (accounts->account) account_destroy(accounts->account); - GNUNET_CONTAINER_DLL_remove( - handle->accounts_head, - handle->accounts_tail, - accounts - ); - - if (accounts->identifier) - GNUNET_free(accounts->identifier); - - GNUNET_free(accounts); + internal_accounts_destroy(accounts); } if (handle->fs) @@ -525,7 +519,12 @@ handle_disconnect (struct GNUNET_CHAT_Handle *handle) handle->contacts = NULL; handle->groups = NULL; + if (handle->disconnection) + GNUNET_SCHEDULER_cancel(handle->disconnection); + handle->current = NULL; + handle->disconnection = NULL; + handle_update_key(handle); } @@ -556,39 +555,23 @@ static int update_accounts_operation (struct GNUNET_CHAT_InternalAccounts **out_accounts, struct GNUNET_CHAT_Handle *handle, const char *name, - int wait_for_completion) + enum GNUNET_CHAT_AccountMethod method) { GNUNET_assert(handle); struct GNUNET_CHAT_InternalAccounts *accounts = *out_accounts; - if (!accounts) + if (accounts) + internal_accounts_stop_method(accounts); + else { - accounts = GNUNET_new(struct GNUNET_CHAT_InternalAccounts); + accounts = internal_accounts_create(handle, NULL); if (!accounts) return GNUNET_SYSERR; - - accounts->account = NULL; - accounts->handle = handle; - - GNUNET_CONTAINER_DLL_insert_tail( - handle->accounts_head, - handle->accounts_tail, - accounts - ); - } - else - { - if (accounts->identifier) - GNUNET_free(accounts->identifier); - - if (accounts->op) - GNUNET_IDENTITY_cancel(accounts->op); } - accounts->identifier = name ? GNUNET_strdup(name) : NULL; - accounts->wait_for_completion = wait_for_completion; + internal_accounts_start_method(accounts, method, name); *out_accounts = accounts; @@ -605,13 +588,13 @@ handle_create_account (struct GNUNET_CHAT_Handle *handle, accounts = find_accounts_by_name(handle, name); if (accounts) - return GNUNET_NO; + return GNUNET_SYSERR; int result = update_accounts_operation( &accounts, handle, - NULL, - GNUNET_NO + name, + GNUNET_CHAT_ACCOUNT_CREATION ); if (GNUNET_OK != result) @@ -641,11 +624,14 @@ handle_delete_account (struct GNUNET_CHAT_Handle *handle, struct GNUNET_CHAT_InternalAccounts *accounts; accounts = find_accounts_by_name(handle, name); + if (!accounts) + return GNUNET_SYSERR; + int result = update_accounts_operation( &accounts, handle, NULL, - GNUNET_YES + GNUNET_CHAT_ACCOUNT_DELETION ); if (GNUNET_OK != result) @@ -674,11 +660,14 @@ handle_rename_account (struct GNUNET_CHAT_Handle *handle, struct GNUNET_CHAT_InternalAccounts *accounts; accounts = find_accounts_by_name(handle, old_name); + if (!accounts) + return GNUNET_SYSERR; + int result = update_accounts_operation( &accounts, handle, NULL, - GNUNET_YES + GNUNET_CHAT_ACCOUNT_RENAMING ); if (GNUNET_OK != result) @@ -744,11 +733,14 @@ handle_update (struct GNUNET_CHAT_Handle *handle) struct GNUNET_CHAT_InternalAccounts *accounts; accounts = find_accounts_by_name(handle, name); + if (!accounts) + return GNUNET_SYSERR; + int result = update_accounts_operation( &accounts, handle, name, - GNUNET_YES + GNUNET_CHAT_ACCOUNT_UPDATING ); if (GNUNET_OK != result) @@ -944,7 +936,7 @@ setup_group: handle, NULL, context, - GNUNET_CHAT_FLAG_UPDATE, + GNUNET_CHAT_FLAG_UPDATE_CONTEXT, NULL ); diff --git a/src/gnunet_chat_handle.h b/src/gnunet_chat_handle.h @@ -43,6 +43,8 @@ #include "gnunet_chat_message.h" #include "gnunet_chat_uri.h" +#include "internal/gnunet_chat_accounts.h" + struct GNUNET_CHAT_Handle; struct GNUNET_CHAT_InternalServices @@ -60,20 +62,6 @@ struct GNUNET_CHAT_InternalMessages struct GNUNET_CHAT_InternalMessages *prev; }; -struct GNUNET_CHAT_InternalAccounts -{ - struct GNUNET_CHAT_Account *account; - char *identifier; - - struct GNUNET_CHAT_Handle *handle; - struct GNUNET_IDENTITY_Operation *op; - - int wait_for_completion; - - struct GNUNET_CHAT_InternalAccounts *next; - struct GNUNET_CHAT_InternalAccounts *prev; -}; - struct GNUNET_CHAT_InternalLobbies { struct GNUNET_CHAT_Lobby *lobby; diff --git a/src/gnunet_chat_handle_intern.c b/src/gnunet_chat_handle_intern.c @@ -32,6 +32,7 @@ #include "gnunet_chat_tagging.h" #include "gnunet_chat_ticket.h" #include "gnunet_chat_util.h" +#include "internal/gnunet_chat_accounts.h" #include <gnunet/gnunet_arm_service.h> #include <gnunet/gnunet_common.h> @@ -284,10 +285,7 @@ on_handle_gnunet_identity (void *cls, struct GNUNET_CHAT_Handle* handle = cls; - if (!ctx) - return; - - if (!ego) + if ((!ctx) || (!ego)) goto send_refresh; struct GNUNET_CHAT_InternalAccounts *accounts = handle->accounts_head; @@ -304,47 +302,30 @@ on_handle_gnunet_identity (void *cls, { util_set_name_field(name, &(accounts->account->name)); - if (handle->current == accounts->account) - handle_send_internal_message( - handle, - accounts->account, - NULL, - GNUNET_CHAT_FLAG_LOGIN, - NULL - ); + handle_send_internal_message( + handle, + accounts->account, + NULL, + GNUNET_CHAT_FLAG_UPDATE_ACCOUNT, + NULL + ); } - else + else if (!(accounts->op)) { if (handle->current == accounts->account) handle_disconnect(handle); account_destroy(accounts->account); - - if (accounts->op) - { - accounts->account = NULL; - goto send_refresh; - } - - GNUNET_CONTAINER_DLL_remove( - handle->accounts_head, - handle->accounts_tail, - accounts - ); - - if (accounts->identifier) - GNUNET_free(accounts->identifier); - - GNUNET_free(accounts); + internal_accounts_destroy(accounts); } goto send_refresh; check_matching_name: - if ((name) && (accounts->account->name) && + if ((name) && (accounts->account->name) && (ego) && (0 == strcmp(accounts->account->name, name))) { - accounts->account->ego = ego; + account_update_ego(accounts->account, handle, ego); goto send_refresh; } @@ -355,23 +336,14 @@ skip_account: if (!name) return; - accounts = GNUNET_new(struct GNUNET_CHAT_InternalAccounts); - accounts->account = account_create_from_ego(ego, name); - - accounts->handle = handle; - accounts->op = NULL; - - accounts->wait_for_completion = GNUNET_NO; + accounts = internal_accounts_create( + handle, + account_create_from_ego(ego, name) + ); if (handle->directory) account_update_directory(accounts->account, handle->directory); - GNUNET_CONTAINER_DLL_insert_tail( - handle->accounts_head, - handle->accounts_tail, - accounts - ); - send_refresh: handle_send_internal_message( handle, @@ -393,40 +365,25 @@ cb_account_creation (void *cls, (struct GNUNET_CHAT_InternalAccounts*) cls ); - struct GNUNET_CHAT_Handle *handle = accounts->handle; - struct GNUNET_CHAT_Account *account = accounts->account; - - GNUNET_CONTAINER_DLL_remove( - handle->accounts_head, - handle->accounts_tail, - accounts - ); - - if (accounts->identifier) - GNUNET_free(accounts->identifier); - - GNUNET_free(accounts); + accounts->op = NULL; - if (GNUNET_EC_NONE != ec) - { - handle_send_internal_message( - handle, - account, - NULL, - GNUNET_CHAT_FLAG_WARNING, - GNUNET_ErrorCode_get_hint(ec) + if ((!(accounts->account)) && (accounts->identifier)) + accounts->account = account_create( + accounts->identifier ); - + + internal_accounts_stop_method(accounts); + + if (GNUNET_EC_NONE == ec) return; - } - else if (key) - handle_send_internal_message( - handle, - NULL, - NULL, - GNUNET_CHAT_FLAG_REFRESH, - NULL - ); + + handle_send_internal_message( + accounts->handle, + accounts->account, + NULL, + GNUNET_CHAT_FLAG_WARNING, + GNUNET_ErrorCode_get_hint(ec) + ); } void @@ -439,32 +396,32 @@ cb_account_deletion (void *cls, (struct GNUNET_CHAT_InternalAccounts*) cls ); - struct GNUNET_CHAT_Handle *handle = accounts->handle; - struct GNUNET_CHAT_Account *account = accounts->account; - - GNUNET_CONTAINER_DLL_remove( - handle->accounts_head, - handle->accounts_tail, - accounts - ); + accounts->op = NULL; - if (accounts->identifier) - GNUNET_free(accounts->identifier); + internal_accounts_stop_method(accounts); - GNUNET_free(accounts); + if (accounts->handle->current == accounts->account) + handle_disconnect(accounts->handle); if (GNUNET_EC_NONE != ec) - { handle_send_internal_message( - handle, - account, + accounts->handle, + accounts->account, NULL, GNUNET_CHAT_FLAG_WARNING, GNUNET_ErrorCode_get_hint(ec) ); + else + handle_send_internal_message( + accounts->handle, + accounts->account, + NULL, + GNUNET_CHAT_FLAG_DELETE_ACCOUNT, + NULL + ); - return; - } + account_destroy(accounts->account); + internal_accounts_destroy(accounts); } void @@ -477,32 +434,20 @@ cb_account_rename (void *cls, (struct GNUNET_CHAT_InternalAccounts*) cls ); - struct GNUNET_CHAT_Handle *handle = accounts->handle; - struct GNUNET_CHAT_Account *account = accounts->account; - - GNUNET_CONTAINER_DLL_remove( - handle->accounts_head, - handle->accounts_tail, - accounts - ); - - if (accounts->identifier) - GNUNET_free(accounts->identifier); - - GNUNET_free(accounts); + accounts->op = NULL; - if (GNUNET_EC_NONE != ec) - { - handle_send_internal_message( - handle, - account, - NULL, - GNUNET_CHAT_FLAG_WARNING, - GNUNET_ErrorCode_get_hint(ec) - ); + internal_accounts_stop_method(accounts); + if (GNUNET_EC_NONE == ec) return; - } + + handle_send_internal_message( + accounts->handle, + accounts->account, + NULL, + GNUNET_CHAT_FLAG_WARNING, + GNUNET_ErrorCode_get_hint(ec) + ); } static void @@ -516,10 +461,7 @@ cb_account_update_completion (void *cls, (struct GNUNET_CHAT_InternalAccounts*) cls ); - struct GNUNET_CHAT_Handle *handle = accounts->handle; - - if ((GNUNET_EC_NONE == ec) && (key)) - GNUNET_MESSENGER_set_key(handle->messenger, key); + accounts->op = NULL; cb_account_creation(cls, key, ec); } @@ -534,16 +476,14 @@ cb_account_update (void *cls, (struct GNUNET_CHAT_InternalAccounts*) cls ); - struct GNUNET_CHAT_Handle *handle = accounts->handle; - - if ((GNUNET_EC_NONE != ec) || (!accounts->identifier)) + if ((GNUNET_EC_NONE != ec) || (!(accounts->identifier))) { cb_account_deletion(cls, ec); return; } - + accounts->op = GNUNET_IDENTITY_create( - handle->identity, + accounts->handle->identity, accounts->identifier, NULL, GNUNET_PUBLIC_KEY_TYPE_ECDSA, diff --git a/src/gnunet_chat_lib.c b/src/gnunet_chat_lib.c @@ -2036,11 +2036,17 @@ GNUNET_CHAT_message_get_kind (const struct GNUNET_CHAT_Message *message) return GNUNET_CHAT_KIND_LOGIN; case GNUNET_CHAT_FLAG_LOGOUT: return GNUNET_CHAT_KIND_LOGOUT; - case GNUNET_CHAT_FLAG_UPDATE: - return GNUNET_CHAT_KIND_UPDATE; + case GNUNET_CHAT_FLAG_CREATE_ACCOUNT: + return GNUNET_CHAT_KIND_CREATED_ACCOUNT; + case GNUNET_CHAT_FLAG_DELETE_ACCOUNT: + return GNUNET_CHAT_KIND_DELETED_ACCOUNT; + case GNUNET_CHAT_FLAG_UPDATE_ACCOUNT: + return GNUNET_CHAT_KIND_UPDATE_ACCOUNT; + case GNUNET_CHAT_FLAG_UPDATE_CONTEXT: + return GNUNET_CHAT_KIND_UPDATE_CONTEXT; case GNUNET_CHAT_FLAG_ATTRIBUTES: return GNUNET_CHAT_KIND_ATTRIBUTES; - case GNUNET_CHAT_FLAG_SHARED_ATTRIBUTES: + case GNUNET_CHAT_FLAG_SHARE_ATTRIBUTES: return GNUNET_CHAT_KIND_SHARED_ATTRIBUTES; default: break; diff --git a/src/gnunet_chat_lib_intern.c b/src/gnunet_chat_lib_intern.c @@ -45,7 +45,7 @@ task_handle_destruction (void *cls) struct GNUNET_CHAT_InternalAccounts *accounts = handle->accounts_head; while (accounts) { - if ((accounts->op) && (GNUNET_YES == accounts->wait_for_completion)) + if ((accounts->op) && (GNUNET_CHAT_ACCOUNT_NONE != accounts->method)) break; accounts = accounts->next; @@ -77,8 +77,8 @@ task_handle_disconnection (void *cls) struct GNUNET_CHAT_Handle *handle = (struct GNUNET_CHAT_Handle*) cls; - handle_disconnect(handle); handle->disconnection = NULL; + handle_disconnect(handle); if (! handle->next) return; @@ -936,7 +936,7 @@ cont_revoke_ticket (void *cls, handle, NULL, NULL, - GNUNET_CHAT_FLAG_SHARED_ATTRIBUTES, + GNUNET_CHAT_FLAG_SHARE_ATTRIBUTES, NULL ); diff --git a/src/gnunet_chat_message.h b/src/gnunet_chat_message.h @@ -47,9 +47,12 @@ enum GNUNET_CHAT_MessageFlag GNUNET_CHAT_FLAG_REFRESH = 2, GNUNET_CHAT_FLAG_LOGIN = 3, GNUNET_CHAT_FLAG_LOGOUT = 4, - GNUNET_CHAT_FLAG_UPDATE = 5, - GNUNET_CHAT_FLAG_ATTRIBUTES = 6, - GNUNET_CHAT_FLAG_SHARED_ATTRIBUTES = 7 + GNUNET_CHAT_FLAG_CREATE_ACCOUNT = 5, + GNUNET_CHAT_FLAG_DELETE_ACCOUNT = 6, + GNUNET_CHAT_FLAG_UPDATE_ACCOUNT = 7, + GNUNET_CHAT_FLAG_UPDATE_CONTEXT = 8, + GNUNET_CHAT_FLAG_ATTRIBUTES = 9, + GNUNET_CHAT_FLAG_SHARE_ATTRIBUTES = 10 }; struct GNUNET_CHAT_Message diff --git a/src/internal/gnunet_chat_accounts.c b/src/internal/gnunet_chat_accounts.c @@ -0,0 +1,114 @@ +/* + This file is part of GNUnet. + Copyright (C) 2024 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/* + * @author Tobias Frisch + * @file gnunet_chat_accounts.c + */ + +#include "gnunet_chat_accounts.h" + +#include "../gnunet_chat_handle.h" + +#include <gnunet/gnunet_common.h> + +struct GNUNET_CHAT_InternalAccounts* +internal_accounts_create(struct GNUNET_CHAT_Handle *handle, + struct GNUNET_CHAT_Account *account) +{ + GNUNET_assert(handle); + + struct GNUNET_CHAT_InternalAccounts *accounts = GNUNET_new( + struct GNUNET_CHAT_InternalAccounts + ); + + if (!accounts) + return NULL; + + accounts->handle = handle; + accounts->account = account; + + accounts->identifier = NULL; + accounts->op = NULL; + accounts->method = GNUNET_CHAT_ACCOUNT_NONE; + + GNUNET_CONTAINER_DLL_insert( + accounts->handle->accounts_head, + accounts->handle->accounts_tail, + accounts + ); + + return accounts; +} + +void +internal_accounts_destroy(struct GNUNET_CHAT_InternalAccounts *accounts) +{ + GNUNET_assert((accounts) && (accounts->handle)); + + GNUNET_CONTAINER_DLL_remove( + accounts->handle->accounts_head, + accounts->handle->accounts_tail, + accounts + ); + + if (accounts->identifier) + GNUNET_free(accounts->identifier); + + if (accounts->op) + GNUNET_IDENTITY_cancel(accounts->op); + + GNUNET_free(accounts); +} + +void +internal_accounts_start_method(struct GNUNET_CHAT_InternalAccounts *accounts, + enum GNUNET_CHAT_AccountMethod method, + const char *identifier) +{ + GNUNET_assert( + (accounts) && + (GNUNET_CHAT_ACCOUNT_NONE == accounts->method) && + (!(accounts->identifier)) && + (!(accounts->op)) + ); + + accounts->identifier = identifier ? GNUNET_strdup(identifier) : NULL; + accounts->method = method; +} + +void +internal_accounts_stop_method(struct GNUNET_CHAT_InternalAccounts *accounts) +{ + GNUNET_assert(accounts); + + if (accounts->identifier) + { + GNUNET_free(accounts->identifier); + accounts->identifier = NULL; + } + + if (accounts->op) + { + GNUNET_IDENTITY_cancel(accounts->op); + accounts->op = NULL; + } + + accounts->method = GNUNET_CHAT_ACCOUNT_NONE; +} diff --git a/src/internal/gnunet_chat_accounts.h b/src/internal/gnunet_chat_accounts.h @@ -0,0 +1,71 @@ +/* + This file is part of GNUnet. + Copyright (C) 2024 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/* + * @author Tobias Frisch + * @file gnunet_chat_accounts.h + */ + +#ifndef GNUNET_CHAT_INTERNAL_ACCOUNTS_H_ +#define GNUNET_CHAT_INTERNAL_ACCOUNTS_H_ + +#include <gnunet/gnunet_identity_service.h> + +enum GNUNET_CHAT_AccountMethod +{ + GNUNET_CHAT_ACCOUNT_CREATION = 1, + GNUNET_CHAT_ACCOUNT_DELETION = 2, + GNUNET_CHAT_ACCOUNT_RENAMING = 3, + GNUNET_CHAT_ACCOUNT_UPDATING = 4, + + GNUNET_CHAT_ACCOUNT_NONE = 0 +}; + +struct GNUNET_CHAT_Handle; +struct GNUNET_CHAT_Account; + +struct GNUNET_CHAT_InternalAccounts +{ + struct GNUNET_CHAT_Handle *handle; + struct GNUNET_CHAT_Account *account; + + char *identifier; + struct GNUNET_IDENTITY_Operation *op; + enum GNUNET_CHAT_AccountMethod method; + + struct GNUNET_CHAT_InternalAccounts *next; + struct GNUNET_CHAT_InternalAccounts *prev; +}; + +struct GNUNET_CHAT_InternalAccounts* +internal_accounts_create(struct GNUNET_CHAT_Handle *handle, + struct GNUNET_CHAT_Account *account); + +void +internal_accounts_destroy(struct GNUNET_CHAT_InternalAccounts *accounts); + +void +internal_accounts_start_method(struct GNUNET_CHAT_InternalAccounts *accounts, + enum GNUNET_CHAT_AccountMethod method, + const char *identifier); + +void +internal_accounts_stop_method(struct GNUNET_CHAT_InternalAccounts *accounts); + +#endif /* GNUNET_CHAT_ACCOUNTS_H_ */ diff --git a/src/internal/meson.build b/src/internal/meson.build @@ -0,0 +1,23 @@ +# +# This file is part of GNUnet. +# Copyright (C) 2024 GNUnet e.V. +# +# GNUnet is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# GNUnet is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# SPDX-License-Identifier: AGPL3.0-or-later +# + +gnunetchat_internal_sources = files([ + 'gnunet_chat_accounts.c', 'gnunet_chat_accounts.h' +]) diff --git a/src/meson.build b/src/meson.build @@ -18,6 +18,8 @@ # SPDX-License-Identifier: AGPL3.0-or-later # +subdir('internal') + gnunetchat_sources = files([ 'gnunet_chat_account.c', 'gnunet_chat_account.h', 'gnunet_chat_contact.c', 'gnunet_chat_contact.h', @@ -33,7 +35,7 @@ gnunetchat_sources = files([ 'gnunet_chat_uri.c', 'gnunet_chat_uri.h', 'gnunet_chat_util.c', 'gnunet_chat_util.h', 'gnunet_chat_lib.c', -]) +]) + gnunetchat_internal_sources gnunetchat_internal = files([ 'gnunet_chat_contact_intern.c', diff --git a/tests/test_gnunet_chat_handle.c b/tests/test_gnunet_chat_handle.c @@ -23,7 +23,15 @@ */ #include "test_gnunet_chat.h" +#include <check.h> #include <gnunet/gnunet_chat_lib.h> +#include <string.h> + +#define TEST_ACCOUNTS_ID "gnunet_chat_handle_accounts" +#define TEST_CONNECTION_ID "gnunet_chat_handle_connection" +#define TEST_UPDATE_ID "gnunet_chat_handle_update" +#define TEST_RENAME_ID_A "gnunet_chat_handle_rename_a" +#define TEST_RENAME_ID_B "gnunet_chat_handle_rename_b" void call_gnunet_chat_handle_init(const struct GNUNET_CONFIGURATION_Handle *cfg) @@ -47,18 +55,22 @@ on_gnunet_chat_handle_accounts_it(void *cls, ck_assert_ptr_ne(handle, NULL); ck_assert_ptr_ne(account, NULL); + ck_assert_int_eq(*accounts_stage, 2); const char *name = GNUNET_CHAT_account_get_name(account); ck_assert_ptr_ne(name, NULL); - if (0 == strcmp(name, "gnunet_chat_handle_accounts")) - *accounts_stage |= 2; + if (0 == strcmp(name, TEST_ACCOUNTS_ID)) + { + *accounts_stage = 3; + return GNUNET_NO; + } return GNUNET_YES; } -int +enum GNUNET_GenericReturnValue on_gnunet_chat_handle_accounts_msg(void *cls, struct GNUNET_CHAT_Context *context, const struct GNUNET_CHAT_Message *message) @@ -69,38 +81,63 @@ on_gnunet_chat_handle_accounts_msg(void *cls, (struct GNUNET_CHAT_Handle**) cls ); - enum GNUNET_CHAT_MessageKind kind = GNUNET_CHAT_message_get_kind(message); - - ck_assert(kind == GNUNET_CHAT_KIND_REFRESH); ck_assert_ptr_ne(handle, NULL); ck_assert_ptr_eq(context, NULL); - GNUNET_CHAT_iterate_accounts( - handle, - on_gnunet_chat_handle_accounts_it, - &accounts_stage - ); + const struct GNUNET_CHAT_Account *account; + account = GNUNET_CHAT_message_get_account(message); - if (2 & accounts_stage) + switch (GNUNET_CHAT_message_get_kind(message)) { - if (3 == accounts_stage) - ck_assert_int_eq(GNUNET_CHAT_account_delete( - handle, - "gnunet_chat_handle_accounts" - ), GNUNET_OK); - - accounts_stage = 4; - } - else if (4 == accounts_stage) - GNUNET_CHAT_stop(handle); - else if (0 == accounts_stage) - { - ck_assert_int_eq(GNUNET_CHAT_account_create( - handle, - "gnunet_chat_handle_accounts" - ), GNUNET_OK); - - accounts_stage = 1; + case GNUNET_CHAT_KIND_REFRESH: + if (0 == accounts_stage) + { + ck_assert_int_eq(GNUNET_CHAT_account_create( + handle, + TEST_ACCOUNTS_ID + ), GNUNET_OK); + + accounts_stage = 1; + } else + if (2 == accounts_stage) + { + ck_assert_int_ge(GNUNET_CHAT_iterate_accounts( + handle, + on_gnunet_chat_handle_accounts_it, + &accounts_stage + ), 1); + } + + if (3 == accounts_stage) + { + ck_assert_int_eq(GNUNET_CHAT_account_delete( + handle, + TEST_ACCOUNTS_ID + ), GNUNET_OK); + + accounts_stage = 4; + } + + break; + case GNUNET_CHAT_KIND_CREATED_ACCOUNT: + ck_assert_ptr_ne(account, NULL); + + if (0 == strcmp(GNUNET_CHAT_account_get_name(account), + TEST_ACCOUNTS_ID)) + accounts_stage = 2; + + break; + case GNUNET_CHAT_KIND_DELETED_ACCOUNT: + ck_assert_int_eq(accounts_stage, 4); + + if (0 == strcmp(GNUNET_CHAT_account_get_name(account), + TEST_ACCOUNTS_ID)) + GNUNET_CHAT_stop(handle); + + break; + default: + ck_abort(); + break; } return GNUNET_YES; @@ -118,31 +155,6 @@ call_gnunet_chat_handle_accounts(const struct GNUNET_CONFIGURATION_Handle *cfg) CREATE_GNUNET_TEST(test_gnunet_chat_handle_accounts, call_gnunet_chat_handle_accounts) int -on_gnunet_chat_handle_connection_it(void *cls, - const struct GNUNET_CHAT_Handle *handle, - struct GNUNET_CHAT_Account *account) -{ - struct GNUNET_CHAT_Handle *chat = (struct GNUNET_CHAT_Handle*) cls; - - ck_assert_ptr_ne(chat, NULL); - ck_assert_ptr_eq(handle, chat); - ck_assert_ptr_ne(account, NULL); - - const char *name = GNUNET_CHAT_account_get_name(account); - - ck_assert_ptr_ne(name, NULL); - ck_assert_ptr_eq(GNUNET_CHAT_get_connected(handle), NULL); - - if (0 == strcmp(name, "gnunet_chat_handle_connection")) - { - GNUNET_CHAT_connect(chat, account); - return GNUNET_NO; - } - - return GNUNET_YES; -} - -int on_gnunet_chat_handle_connection_msg(void *cls, struct GNUNET_CHAT_Context *context, const struct GNUNET_CHAT_Message *message) @@ -155,27 +167,31 @@ on_gnunet_chat_handle_connection_msg(void *cls, ck_assert_ptr_eq(context, NULL); ck_assert_ptr_ne(message, NULL); - if (GNUNET_CHAT_KIND_LOGOUT == GNUNET_CHAT_message_get_kind(message)) + enum GNUNET_CHAT_MessageKind kind = GNUNET_CHAT_message_get_kind(message); + + if (GNUNET_CHAT_KIND_LOGOUT == kind) { ck_assert_int_eq(GNUNET_CHAT_account_delete( handle, - "gnunet_chat_handle_connection" + TEST_CONNECTION_ID ), GNUNET_OK); GNUNET_CHAT_stop(handle); return GNUNET_YES; } - if (GNUNET_CHAT_KIND_LOGIN == GNUNET_CHAT_message_get_kind(message)) - goto skip_iteration; + if (GNUNET_CHAT_KIND_CREATED_ACCOUNT == kind) + { + const struct GNUNET_CHAT_Account *account; + account = GNUNET_CHAT_message_get_account(message); - GNUNET_CHAT_iterate_accounts( - handle, - on_gnunet_chat_handle_connection_it, - handle - ); + ck_assert_ptr_ne(account, NULL); + + if (0 == strcmp(GNUNET_CHAT_account_get_name(account), + TEST_CONNECTION_ID)) + GNUNET_CHAT_connect(handle, account); + } -skip_iteration: if (!GNUNET_CHAT_get_connected(handle)) return GNUNET_YES; @@ -192,38 +208,13 @@ call_gnunet_chat_handle_connection(const struct GNUNET_CONFIGURATION_Handle *cfg ck_assert_ptr_ne(handle, NULL); ck_assert_int_eq(GNUNET_CHAT_account_create( handle, - "gnunet_chat_handle_connection" + TEST_CONNECTION_ID ), GNUNET_OK); } CREATE_GNUNET_TEST(test_gnunet_chat_handle_connection, call_gnunet_chat_handle_connection) int -on_gnunet_chat_handle_update_it(void *cls, - const struct GNUNET_CHAT_Handle *handle, - struct GNUNET_CHAT_Account *account) -{ - struct GNUNET_CHAT_Handle *chat = (struct GNUNET_CHAT_Handle*) cls; - - ck_assert_ptr_ne(chat, NULL); - ck_assert_ptr_eq(handle, chat); - ck_assert_ptr_ne(account, NULL); - - const char *name = GNUNET_CHAT_account_get_name(account); - - ck_assert_ptr_ne(name, NULL); - ck_assert_ptr_eq(GNUNET_CHAT_get_connected(handle), NULL); - - if (0 == strcmp(name, "gnunet_chat_handle_update")) - { - GNUNET_CHAT_connect(chat, account); - return GNUNET_NO; - } - - return GNUNET_YES; -} - -int on_gnunet_chat_handle_update_msg(void *cls, struct GNUNET_CHAT_Context *context, const struct GNUNET_CHAT_Message *message) @@ -238,65 +229,113 @@ on_gnunet_chat_handle_update_msg(void *cls, ck_assert_ptr_eq(context, NULL); ck_assert_ptr_ne(message, NULL); - enum GNUNET_CHAT_MessageKind kind = GNUNET_CHAT_message_get_kind(message); + const struct GNUNET_CHAT_Account *account; + account = GNUNET_CHAT_message_get_account(message); - if (GNUNET_CHAT_get_connected(handle)) - goto skip_search_account; + const char *key; + char *dup; - GNUNET_CHAT_iterate_accounts( - handle, - on_gnunet_chat_handle_update_it, - handle - ); + switch (GNUNET_CHAT_message_get_kind(message)) + { + case GNUNET_CHAT_KIND_REFRESH: + break; + case GNUNET_CHAT_KIND_LOGIN: + account = GNUNET_CHAT_get_connected(handle); - if (!GNUNET_CHAT_get_connected(handle)) - return GNUNET_YES; + ck_assert_ptr_ne(account, NULL); + ck_assert_str_eq( + GNUNET_CHAT_account_get_name(account), + TEST_UPDATE_ID + ); -skip_search_account: - if (GNUNET_CHAT_KIND_LOGOUT == kind) - { - if (update_stage < 2) - return GNUNET_YES; + key = GNUNET_CHAT_get_key(handle); + ck_assert_ptr_ne(key, NULL); - ck_assert_int_eq(GNUNET_CHAT_account_delete( - handle, - "gnunet_chat_handle_update" - ), GNUNET_OK); + dup = (char*) GNUNET_CHAT_get_user_pointer(handle); - GNUNET_CHAT_stop(handle); - return GNUNET_YES; - } + ck_assert_int_eq(update_stage, 1); - if (GNUNET_CHAT_KIND_LOGIN != kind) - return GNUNET_YES; + dup = GNUNET_strdup(key); - const char *key = GNUNET_CHAT_get_key(handle); - ck_assert_ptr_ne(key, NULL); + ck_assert_ptr_ne(dup, NULL); + ck_assert_str_eq(key, dup); - char *dup = (char*) GNUNET_CHAT_get_user_pointer(handle); + GNUNET_CHAT_set_user_pointer(handle, (void*) dup); + GNUNET_CHAT_update(handle); - if (!dup) - { - dup = GNUNET_strdup(key); + update_stage = 2; + break; + case GNUNET_CHAT_KIND_LOGOUT: + account = GNUNET_CHAT_get_connected(handle); - ck_assert_ptr_ne(dup, NULL); - ck_assert_str_eq(key, dup); + ck_assert_int_ge(update_stage, 2); + ck_assert_int_le(update_stage, 3); - GNUNET_CHAT_set_user_pointer(handle, (void*) dup); - GNUNET_CHAT_update(handle); + ck_assert_ptr_ne(account, NULL); + ck_assert_str_eq( + GNUNET_CHAT_account_get_name(account), + TEST_UPDATE_ID + ); - update_stage = 1; - } - else - { - ck_assert_ptr_ne(dup, NULL); - ck_assert_str_ne(key, dup); + if (update_stage == 3) + { + ck_assert_int_eq(GNUNET_CHAT_account_delete( + handle, + TEST_UPDATE_ID + ), GNUNET_OK); + + update_stage = 4; + } + + break; + case GNUNET_CHAT_KIND_CREATED_ACCOUNT: + ck_assert_ptr_ne(account, NULL); + + if ((0 != strcmp(GNUNET_CHAT_account_get_name(account), + TEST_UPDATE_ID))) + break; + + ck_assert_int_eq(update_stage, 0); + + update_stage = 1; + GNUNET_CHAT_connect(handle, account); + break; + case GNUNET_CHAT_KIND_DELETED_ACCOUNT: + ck_assert_ptr_ne(account, NULL); + + if ((0 != strcmp(GNUNET_CHAT_account_get_name(account), + TEST_UPDATE_ID))) + break; + + ck_assert_int_eq(update_stage, 4); + + GNUNET_CHAT_stop(handle); + break; + case GNUNET_CHAT_KIND_UPDATE_ACCOUNT: + ck_assert_ptr_ne(account, NULL); - GNUNET_free(dup); + if ((0 != strcmp(GNUNET_CHAT_account_get_name(account), + TEST_UPDATE_ID))) + break; + + key = GNUNET_CHAT_get_key(handle); + ck_assert_ptr_ne(key, NULL); - GNUNET_CHAT_disconnect(handle); + dup = (char*) GNUNET_CHAT_get_user_pointer(handle); - update_stage = 2; + ck_assert_int_eq(update_stage, 2); + ck_assert_ptr_ne(dup, NULL); + ck_assert_str_ne(key, dup); + + GNUNET_free(dup); + + GNUNET_CHAT_disconnect(handle); + + update_stage = 3; + break; + default: + ck_abort(); + break; } return GNUNET_YES; @@ -311,38 +350,13 @@ call_gnunet_chat_handle_update(const struct GNUNET_CONFIGURATION_Handle *cfg) ck_assert_ptr_ne(handle, NULL); ck_assert_int_eq(GNUNET_CHAT_account_create( handle, - "gnunet_chat_handle_update" + TEST_UPDATE_ID ), GNUNET_OK); } CREATE_GNUNET_TEST(test_gnunet_chat_handle_update, call_gnunet_chat_handle_update) int -on_gnunet_chat_handle_rename_it(void *cls, - const struct GNUNET_CHAT_Handle *handle, - struct GNUNET_CHAT_Account *account) -{ - struct GNUNET_CHAT_Handle *chat = (struct GNUNET_CHAT_Handle*) cls; - - ck_assert_ptr_ne(chat, NULL); - ck_assert_ptr_eq(handle, chat); - ck_assert_ptr_ne(account, NULL); - - const char *name = GNUNET_CHAT_account_get_name(account); - - ck_assert_ptr_ne(name, NULL); - ck_assert_ptr_eq(GNUNET_CHAT_get_connected(handle), NULL); - - if (0 == strcmp(name, "gnunet_chat_handle_rename_a")) - { - GNUNET_CHAT_connect(chat, account); - return GNUNET_NO; - } - - return GNUNET_YES; -} - -int on_gnunet_chat_handle_rename_msg(void *cls, struct GNUNET_CHAT_Context *context, const struct GNUNET_CHAT_Message *message) @@ -355,62 +369,68 @@ on_gnunet_chat_handle_rename_msg(void *cls, ck_assert_ptr_eq(context, NULL); ck_assert_ptr_ne(message, NULL); - enum GNUNET_CHAT_MessageKind kind = GNUNET_CHAT_message_get_kind(message); - - if (GNUNET_CHAT_get_connected(handle)) - goto skip_search_account; - - GNUNET_CHAT_iterate_accounts( - handle, - on_gnunet_chat_handle_rename_it, - handle - ); - - if (!GNUNET_CHAT_get_connected(handle)) - return GNUNET_YES; - -skip_search_account: - if (GNUNET_CHAT_KIND_LOGOUT == kind) - { - ck_assert_int_eq(GNUNET_CHAT_account_delete( - handle, - "gnunet_chat_handle_rename_b" - ), GNUNET_OK); - - GNUNET_CHAT_stop(handle); - return GNUNET_YES; - } - - if (GNUNET_CHAT_KIND_LOGIN != kind) - return GNUNET_YES; + const struct GNUNET_CHAT_Account *account; + account = GNUNET_CHAT_message_get_account(message); const char *name = GNUNET_CHAT_get_name(handle); - ck_assert_ptr_ne(name, NULL); - char *dup = (char*) GNUNET_CHAT_get_user_pointer(handle); - if (!dup) - { - dup = GNUNET_strdup(name); + printf("%d\n", (int) GNUNET_CHAT_message_get_kind(message)); - ck_assert_ptr_ne(dup, NULL); - ck_assert_str_eq(name, dup); + switch (GNUNET_CHAT_message_get_kind(message)) + { + case GNUNET_CHAT_KIND_REFRESH: + break; + case GNUNET_CHAT_KIND_LOGIN: + ck_assert_ptr_ne(account, NULL); + ck_assert_ptr_ne(name, NULL); + ck_assert_ptr_eq(dup, NULL); + ck_assert_str_eq(name, TEST_RENAME_ID_A); - GNUNET_CHAT_set_user_pointer(handle, (void*) dup); + dup = GNUNET_strdup(name); - ck_assert_int_eq(GNUNET_CHAT_set_name( - handle, - "gnunet_chat_handle_rename_b" - ), GNUNET_YES); - } - else if (0 != strcmp(name, dup)) - { - ck_assert_ptr_ne(dup, NULL); - ck_assert_str_ne(name, dup); + ck_assert_ptr_ne(dup, NULL); + ck_assert_str_eq(name, dup); - GNUNET_free(dup); + GNUNET_CHAT_set_user_pointer(handle, (void*) dup); - GNUNET_CHAT_disconnect(handle); + ck_assert_int_eq(GNUNET_CHAT_set_name( + handle, + TEST_RENAME_ID_B + ), GNUNET_YES); + break; + case GNUNET_CHAT_KIND_LOGOUT: + ck_assert_ptr_ne(account, NULL); + ck_assert_int_eq(GNUNET_CHAT_account_delete( + handle, + TEST_RENAME_ID_B + ), GNUNET_OK); + break; + case GNUNET_CHAT_KIND_CREATED_ACCOUNT: + ck_assert_ptr_ne(account, NULL); + + GNUNET_CHAT_connect(handle, account); + break; + case GNUNET_CHAT_KIND_DELETED_ACCOUNT: + ck_assert_ptr_ne(account, NULL); + + GNUNET_CHAT_stop(handle); + break; + case GNUNET_CHAT_KIND_UPDATE_ACCOUNT: + ck_assert_ptr_ne(account, NULL); + ck_assert_ptr_ne(name, NULL); + ck_assert_ptr_ne(dup, NULL); + ck_assert_str_ne(name, dup); + ck_assert_str_eq(name, TEST_RENAME_ID_B); + ck_assert_str_eq(dup, TEST_RENAME_ID_A); + + GNUNET_free(dup); + + GNUNET_CHAT_disconnect(handle); + break; + default: + ck_abort(); + break; } return GNUNET_YES; @@ -425,7 +445,7 @@ call_gnunet_chat_handle_rename(const struct GNUNET_CONFIGURATION_Handle *cfg) ck_assert_ptr_ne(handle, NULL); ck_assert_int_eq(GNUNET_CHAT_account_create( handle, - "gnunet_chat_handle_rename_a" + TEST_RENAME_ID_A ), GNUNET_OK); } diff --git a/tools/gnunet_chat_lib_uml.c b/tools/gnunet_chat_lib_uml.c @@ -99,8 +99,17 @@ chat_message (void *cls, case GNUNET_CHAT_KIND_LOGOUT: kind_name = "LOGOUT"; break; - case GNUNET_CHAT_KIND_UPDATE: - kind_name = "UPDATE"; + case GNUNET_CHAT_KIND_CREATED_ACCOUNT: + kind_name = "CREATED_ACCOUNT"; + break; + case GNUNET_CHAT_KIND_DELETED_ACCOUNT: + kind_name = "DELETED_ACCOUNT"; + break; + case GNUNET_CHAT_KIND_UPDATE_ACCOUNT: + kind_name = "UPDATE_ACCOUNT"; + break; + case GNUNET_CHAT_KIND_UPDATE_CONTEXT: + kind_name = "UPDATE_CONTEXT"; break; case GNUNET_CHAT_KIND_JOIN: kind_name = "JOIN"; @@ -126,6 +135,12 @@ chat_message (void *cls, case GNUNET_CHAT_KIND_TAG: kind_name = "TAG"; break; + case GNUNET_CHAT_KIND_ATTRIBUTES: + kind_name = "ATTRIBUTES"; + break; + case GNUNET_CHAT_KIND_SHARED_ATTRIBUTES: + kind_name = "SHARED_ATTRIBUTES"; + break; default: break; }