libgnunetchat

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

commit ccdeafaf88627aa274c2d6090e4231ed51b56c63
parent ffbadef904ae1e32eb54671647527b99e70d2266
Author: TheJackiMonster <thejackimonster@gmail.com>
Date:   Sun, 13 Feb 2022 17:35:32 +0100

Established accounts as selectable identities to use

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

Diffstat:
MMakefile | 3++-
Minclude/gnunet_chat_lib.h | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
Asrc/gnunet_chat_account.c | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/gnunet_chat_account.h | 45+++++++++++++++++++++++++++++++++++++++++++++
Msrc/gnunet_chat_handle.c | 185+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Msrc/gnunet_chat_handle.h | 24++++++++++++++++--------
Msrc/gnunet_chat_handle_intern.c | 18++++++++++--------
Msrc/gnunet_chat_lib.c | 76+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Msrc/gnunet_chat_message.h | 5+++--
9 files changed, 383 insertions(+), 111 deletions(-)

diff --git a/Makefile b/Makefile @@ -7,7 +7,8 @@ INSTALL_DIR ?= /usr/local/ LIBRARY = lib$(TARGET_NAME).so SOURCES = gnunet_chat_lib.c\ - gnunet_chat_contact.c\ + gnunet_chat_account.c\ + gnunet_chat_contact.c\ gnunet_chat_context.c\ gnunet_chat_file.c\ gnunet_chat_group.c\ diff --git a/include/gnunet_chat_lib.h b/include/gnunet_chat_lib.h @@ -50,49 +50,54 @@ enum GNUNET_CHAT_MessageKind GNUNET_CHAT_KIND_WARNING = 1, /**< GNUNET_CHAT_KIND_WARNING */ /** + * The kind to inform that the list of accounts was refreshed. + */ + GNUNET_CHAT_KIND_REFRESH = 2, /**< GNUNET_CHAT_KIND_REFRESH */ + + /** * The kind to inform that the application can be used. */ - GNUNET_CHAT_KIND_LOGIN = 2, /**< GNUNET_CHAT_KIND_LOGIN */ + GNUNET_CHAT_KIND_LOGIN = 3, /**< GNUNET_CHAT_KIND_LOGIN */ /** * The kind to inform that a context was updated. */ - GNUNET_CHAT_KIND_UPDATE = 3, /**< GNUNET_CHAT_KIND_UPDATE */ + GNUNET_CHAT_KIND_UPDATE = 4, /**< GNUNET_CHAT_KIND_UPDATE */ /** * The kind to inform that a contact has joined a chat. */ - GNUNET_CHAT_KIND_JOIN = 4, /**< GNUNET_CHAT_KIND_JOIN */ + GNUNET_CHAT_KIND_JOIN = 5, /**< GNUNET_CHAT_KIND_JOIN */ /** * The kind to inform that a contact has left a chat. */ - GNUNET_CHAT_KIND_LEAVE = 5, /**< GNUNET_CHAT_KIND_LEAVE */ + GNUNET_CHAT_KIND_LEAVE = 6, /**< GNUNET_CHAT_KIND_LEAVE */ /** * The kind to inform that a contact has changed. */ - GNUNET_CHAT_KIND_CONTACT = 6, /**< GNUNET_CHAT_KIND_CONTACT */ + GNUNET_CHAT_KIND_CONTACT = 7, /**< GNUNET_CHAT_KIND_CONTACT */ /** * The kind to describe an invitation to a different chat. */ - GNUNET_CHAT_KIND_INVITATION = 7, /**< GNUNET_CHAT_KIND_INVITATION */ + GNUNET_CHAT_KIND_INVITATION = 8, /**< GNUNET_CHAT_KIND_INVITATION */ /** * The kind to describe a text message. */ - GNUNET_CHAT_KIND_TEXT = 8, /**< GNUNET_CHAT_KIND_TEXT */ + GNUNET_CHAT_KIND_TEXT = 9, /**< GNUNET_CHAT_KIND_TEXT */ /** * The kind to describe a shared file. */ - GNUNET_CHAT_KIND_FILE = 9, /**< GNUNET_CHAT_KIND_FILE */ + GNUNET_CHAT_KIND_FILE = 10, /**< GNUNET_CHAT_KIND_FILE */ /** * The kind to inform about a deletion of a previous message. */ - GNUNET_CHAT_KIND_DELETION = 10, /**< GNUNET_CHAT_KIND_DELETION */ + GNUNET_CHAT_KIND_DELETION = 11, /**< GNUNET_CHAT_KIND_DELETION */ /** * An unknown kind of message. @@ -106,6 +111,11 @@ enum GNUNET_CHAT_MessageKind struct GNUNET_CHAT_Handle; /** + * Struct of a chat account. + */ +struct GNUNET_CHAT_Account; + +/** * Struct of a chat contact. */ struct GNUNET_CHAT_Contact; @@ -136,6 +146,19 @@ struct GNUNET_CHAT_File; struct GNUNET_CHAT_Invitation; /** + * Iterator over chat accounts of a specific chat handle. + * + * @param[in,out] cls Closure from #GNUNET_CHAT_iterate_accounts + * @param[in] handle Chat handle + * @param[in] account Chat account + * @return #GNUNET_YES if we should continue to iterate, #GNUNET_NO otherwise. + */ +typedef int +(*GNUNET_CHAT_AccountCallback) (void *cls, + const struct GNUNET_CHAT_Handle *handle, + const struct GNUNET_CHAT_Account *account); + +/** * Iterator over chat contacts of a specific chat handle. * * @param[in,out] cls Closure from #GNUNET_CHAT_iterate_contacts @@ -261,15 +284,14 @@ typedef void uint64_t size); /** - * Start a chat handle with a certain configuration, an application <i>directory</i> - * and a selected user <i>name</i>. + * Start a chat handle with a certain configuration and a selected application + * <i>directory</i>. * * A custom callback for warnings and message events can be provided optionally * together with their respective closures. * * @param[in] cfg Configuration * @param[in] directory Application directory path (optional) - * @param[in] name User name (optional) * @param[in] msg_cb Callback for message events (optional) * @param[in,out] msg_cls Closure for message events (optional) * @return Chat handle @@ -277,7 +299,6 @@ typedef void struct GNUNET_CHAT_Handle* GNUNET_CHAT_start (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *directory, - const char *name, GNUNET_CHAT_ContextMessageCallback msg_cb, void *msg_cls); /** @@ -290,6 +311,47 @@ void GNUNET_CHAT_stop (struct GNUNET_CHAT_Handle *handle); /** + * Iterates through the accounts of a given chat <i>handle</i> with a selected + * callback and custom closure. + * + * @param[in] handle Chat handle + * @param[in] callback Callback for account iteration (optional) + * @param[in,out] cls Closure for account iteration (optional) + * @return Amount of accounts iterated or #GNUNET_SYSERR on failure + */ +int +GNUNET_CHAT_iterate_accounts(const struct GNUNET_CHAT_Handle *handle, + GNUNET_CHAT_AccountCallback callback, + void *cls); + +/** + * Connects a chat <i>handle</i> to a selected chat <i>account</i>. + * + * @param[in] account Chat account + */ +void +GNUNET_CHAT_connect (struct GNUNET_CHAT_Handle *handle, + const struct GNUNET_CHAT_Account *account); + +/** + * Disconnects a chat <i>handle</i> from the current chat account. + * + * @param[in,out] handle Chat handle + */ +void +GNUNET_CHAT_disconnect (struct GNUNET_CHAT_Handle *handle); + +/** + * Returns the connected account of a chat <i>handle</i> for related + * communication or NULL if no account is set yet. + * + * @param handle Chat handle + * @return Account used by the handle or NULL + */ +const struct GNUNET_CHAT_Account* +GNUNET_CHAT_get_connected(const struct GNUNET_CHAT_Handle *handle); + +/** * Updates a chat handle to renew the used ego to sign sent messages in active * chats. * diff --git a/src/gnunet_chat_account.c b/src/gnunet_chat_account.c @@ -0,0 +1,50 @@ +/* + This file is part of GNUnet. + Copyright (C) 2022 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_account.c + */ + +#include "gnunet_chat_account.h" + +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 = GNUNET_new(struct GNUNET_CHAT_Account); + + account->ego = ego; + account->name = GNUNET_strdup(name); + + return account; +} + +void +account_destroy(struct GNUNET_CHAT_Account *account) +{ + GNUNET_assert(account); + + if (account->name) + GNUNET_free(account->name); + + GNUNET_free(account); +} diff --git a/src/gnunet_chat_account.h b/src/gnunet_chat_account.h @@ -0,0 +1,45 @@ +/* + This file is part of GNUnet. + Copyright (C) 2022 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_account.h + */ + +#ifndef GNUNET_CHAT_ACCOUNT_H_ +#define GNUNET_CHAT_ACCOUNT_H_ + +#include <gnunet/platform.h> +#include <gnunet/gnunet_common.h> +#include <gnunet/gnunet_identity_service.h> + +struct GNUNET_CHAT_Account +{ + struct GNUNET_IDENTITY_Ego *ego; + char *name; +}; + +struct GNUNET_CHAT_Account* +account_create_from_ego(struct GNUNET_IDENTITY_Ego *ego, + const char *name); + +void +account_destroy(struct GNUNET_CHAT_Account *account); + +#endif /* GNUNET_CHAT_ACCOUNT_H_ */ diff --git a/src/gnunet_chat_handle.c b/src/gnunet_chat_handle.c @@ -29,7 +29,6 @@ struct GNUNET_CHAT_Handle* handle_create_from_config (const struct GNUNET_CONFIGURATION_Handle* cfg, const char *directory, - const char *name, GNUNET_CHAT_ContextMessageCallback msg_cb, void *msg_cls) { @@ -54,13 +53,15 @@ handle_create_from_config (const struct GNUNET_CONFIGURATION_Handle* cfg, handle->msg_cb = msg_cb; handle->msg_cls = msg_cls; - handle->identities_head = NULL; - handle->identities_tail = NULL; + handle->accounts_head = NULL; + handle->accounts_tail = NULL; - handle->files = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); - handle->contexts = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); - handle->contacts = GNUNET_CONTAINER_multishortmap_create(8, GNUNET_NO); - handle->groups = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); + handle->current = NULL; + + handle->files = NULL; + handle->contexts = NULL; + handle->contacts = NULL; + handle->groups = NULL; handle->arm = GNUNET_ARM_connect( handle->cfg, @@ -70,39 +71,17 @@ handle_create_from_config (const struct GNUNET_CONFIGURATION_Handle* cfg, if (handle->arm) on_handle_arm_connection(handle, GNUNET_NO); - char* fs_client_name = NULL; - GNUNET_asprintf ( - &fs_client_name, - "GNUNET_CHAT_%s%s", - name? "_" : "anonymous", - name? name : "" - ); - - handle->fs = GNUNET_FS_start( - handle->cfg, fs_client_name, - notify_handle_fs_progress, handle, - GNUNET_FS_FLAGS_NONE, - GNUNET_FS_OPTIONS_END - ); - - GNUNET_free(fs_client_name); - handle->identity = GNUNET_IDENTITY_connect( handle->cfg, on_handle_gnunet_identity, handle ); - handle->messenger = GNUNET_MESSENGER_connect( - handle->cfg, name, - on_handle_identity, handle, - on_handle_message, handle - ); + handle->fs = NULL; + handle->messenger = NULL; handle->public_key = NULL; handle->user_pointer = NULL; - - handle_update_key(handle); return handle; } @@ -129,66 +108,35 @@ handle_update_key (struct GNUNET_CHAT_Handle *handle) void handle_destroy (struct GNUNET_CHAT_Handle *handle) { - GNUNET_assert((handle) && - (handle->groups) && - (handle->contacts) && - (handle->contexts) && - (handle->files)); + GNUNET_assert(handle); if (handle->shutdown_hook) GNUNET_SCHEDULER_cancel(handle->shutdown_hook); - GNUNET_CONTAINER_multihashmap_iterate( - handle->groups, it_destroy_handle_groups, NULL - ); - - GNUNET_CONTAINER_multishortmap_iterate( - handle->contacts, it_destroy_handle_contacts, NULL - ); - - GNUNET_CONTAINER_multihashmap_iterate( - 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->current) + handle_disconnect(handle); if (handle->identity) GNUNET_IDENTITY_disconnect(handle->identity); - if (handle->fs) - GNUNET_FS_stop(handle->fs); - if (handle->arm) GNUNET_ARM_disconnect(handle->arm); - GNUNET_CONTAINER_multihashmap_iterate( - handle->files, it_destroy_handle_files, NULL - ); - - GNUNET_CONTAINER_multihashmap_destroy(handle->groups); - GNUNET_CONTAINER_multishortmap_destroy(handle->contacts); - GNUNET_CONTAINER_multihashmap_destroy(handle->contexts); - GNUNET_CONTAINER_multihashmap_destroy(handle->files); - - struct GNUNET_CHAT_InternalIdentities *identities; - while (handle->identities_head) + struct GNUNET_CHAT_InternalAccounts *accounts; + while (handle->accounts_head) { - identities = handle->identities_head; + accounts = handle->accounts_head; - if (identities->name) - GNUNET_free(identities->name); + if (accounts->account) + account_destroy(accounts->account); GNUNET_CONTAINER_DLL_remove( - handle->identities_head, - handle->identities_tail, - identities + handle->accounts_head, + handle->accounts_tail, + accounts ); - GNUNET_free(identities); + GNUNET_free(accounts); } if (handle->directory) @@ -215,6 +163,95 @@ handle_destroy (struct GNUNET_CHAT_Handle *handle) } void +handle_connect (struct GNUNET_CHAT_Handle *handle, + const struct GNUNET_CHAT_Account *account) +{ + GNUNET_assert((handle) && (account) && + (!(handle->current)) && + (!(handle->groups)) && + (!(handle->contacts)) && + (!(handle->contexts)) && + (!(handle->files))); + + handle->files = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); + handle->contexts = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); + handle->contacts = GNUNET_CONTAINER_multishortmap_create(8, GNUNET_NO); + handle->groups = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); + + const char *name = account->name; + + char* fs_client_name = NULL; + GNUNET_asprintf ( + &fs_client_name, + "GNUNET_CHAT_%s%s", + name? "_" : "anonymous", + name? name : "" + ); + + handle->fs = GNUNET_FS_start( + handle->cfg, fs_client_name, + notify_handle_fs_progress, handle, + GNUNET_FS_FLAGS_NONE, + GNUNET_FS_OPTIONS_END + ); + + GNUNET_free(fs_client_name); + + handle->messenger = GNUNET_MESSENGER_connect( + handle->cfg, name, + on_handle_identity, handle, + on_handle_message, handle + ); + + handle->current = account; + handle_update_key(handle); +} + +void +handle_disconnect (struct GNUNET_CHAT_Handle *handle) +{ + GNUNET_assert((handle) && + (handle->current) && + (handle->groups) && + (handle->contacts) && + (handle->contexts) && + (handle->files)); + + GNUNET_CONTAINER_multihashmap_iterate( + handle->groups, it_destroy_handle_groups, NULL + ); + + GNUNET_CONTAINER_multishortmap_iterate( + handle->contacts, it_destroy_handle_contacts, NULL + ); + + GNUNET_CONTAINER_multihashmap_iterate( + handle->contexts, it_destroy_handle_contexts, NULL + ); + + if (handle->messenger) + GNUNET_MESSENGER_disconnect(handle->messenger); + + if (handle->fs) + GNUNET_FS_stop(handle->fs); + + GNUNET_CONTAINER_multihashmap_iterate( + handle->files, it_destroy_handle_files, NULL + ); + + handle->fs = NULL; + handle->messenger = NULL; + + GNUNET_CONTAINER_multihashmap_destroy(handle->groups); + GNUNET_CONTAINER_multishortmap_destroy(handle->contacts); + GNUNET_CONTAINER_multihashmap_destroy(handle->contexts); + GNUNET_CONTAINER_multihashmap_destroy(handle->files); + + handle->current = NULL; + handle_update_key(handle); +} + +void handle_send_internal_message (struct GNUNET_CHAT_Handle *handle, struct GNUNET_CHAT_Context *context, enum GNUNET_CHAT_MessageFlag flag, diff --git a/src/gnunet_chat_handle.h b/src/gnunet_chat_handle.h @@ -37,6 +37,7 @@ #include <gnunet/gnunet_util_lib.h> #include "gnunet_chat_lib.h" +#include "gnunet_chat_account.h" #include "gnunet_chat_message.h" struct GNUNET_CHAT_InternalMessages @@ -46,12 +47,11 @@ struct GNUNET_CHAT_InternalMessages struct GNUNET_CHAT_InternalMessages *prev; }; -struct GNUNET_CHAT_InternalIdentities +struct GNUNET_CHAT_InternalAccounts { - char *name; - struct GNUNET_IDENTITY_Ego *ego; - struct GNUNET_CHAT_InternalIdentities *next; - struct GNUNET_CHAT_InternalIdentities *prev; + struct GNUNET_CHAT_Account *account; + struct GNUNET_CHAT_InternalAccounts *next; + struct GNUNET_CHAT_InternalAccounts *prev; }; struct GNUNET_CHAT_Handle @@ -67,8 +67,10 @@ struct GNUNET_CHAT_Handle GNUNET_CHAT_ContextMessageCallback msg_cb; void *msg_cls; - struct GNUNET_CHAT_InternalIdentities *identities_head; - struct GNUNET_CHAT_InternalIdentities *identities_tail; + struct GNUNET_CHAT_InternalAccounts *accounts_head; + struct GNUNET_CHAT_InternalAccounts *accounts_tail; + + const struct GNUNET_CHAT_Account *current; struct GNUNET_CONTAINER_MultiHashMap *files; struct GNUNET_CONTAINER_MultiHashMap *contexts; @@ -87,7 +89,6 @@ struct GNUNET_CHAT_Handle struct GNUNET_CHAT_Handle* handle_create_from_config (const struct GNUNET_CONFIGURATION_Handle* cfg, const char *directory, - const char *name, GNUNET_CHAT_ContextMessageCallback msg_cb, void *msg_cls); @@ -98,6 +99,13 @@ void handle_destroy (struct GNUNET_CHAT_Handle *handle); void +handle_connect (struct GNUNET_CHAT_Handle *handle, + const struct GNUNET_CHAT_Account *account); + +void +handle_disconnect (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, diff --git a/src/gnunet_chat_handle_intern.c b/src/gnunet_chat_handle_intern.c @@ -206,20 +206,22 @@ on_handle_gnunet_identity(void *cls, { struct GNUNET_CHAT_Handle* handle = cls; - if (!name) + if ((!name) || (!ego)) + { + handle_send_internal_message(handle, NULL, GNUNET_CHAT_FLAG_REFRESH, NULL); return; + } - struct GNUNET_CHAT_InternalIdentities *identities = GNUNET_new( - struct GNUNET_CHAT_InternalIdentities + struct GNUNET_CHAT_InternalAccounts *accounts = GNUNET_new( + struct GNUNET_CHAT_InternalAccounts ); - identities->name = GNUNET_strdup(name); - identities->ego = ego; + accounts->account = account_create_from_ego(ego, name); GNUNET_CONTAINER_DLL_insert_tail( - handle->identities_head, - handle->identities_tail, - identities + handle->accounts_head, + handle->accounts_tail, + accounts ); } diff --git a/src/gnunet_chat_lib.c b/src/gnunet_chat_lib.c @@ -40,14 +40,13 @@ struct GNUNET_CHAT_Handle* GNUNET_CHAT_start (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *directory, - const char *name, GNUNET_CHAT_ContextMessageCallback msg_cb, void *msg_cls) { if (!cfg) return NULL; return handle_create_from_config( - cfg, directory, name, + cfg, directory, msg_cb, msg_cls ); } @@ -64,6 +63,71 @@ GNUNET_CHAT_stop (struct GNUNET_CHAT_Handle *handle) int +GNUNET_CHAT_iterate_accounts(const struct GNUNET_CHAT_Handle *handle, + GNUNET_CHAT_AccountCallback callback, + void *cls) +{ + if (!handle) + return GNUNET_SYSERR; + + int result = 0; + + struct GNUNET_CHAT_InternalAccounts *accounts = handle->accounts_head; + while (accounts) + { + if (!(accounts->account)) + return GNUNET_SYSERR; + + result++; + + if ((!callback) && (GNUNET_YES != callback(cls, handle, accounts->account))) + break; + + accounts = accounts->next; + } + + return result; +} + + +void +GNUNET_CHAT_connect (struct GNUNET_CHAT_Handle *handle, + const struct GNUNET_CHAT_Account *account) +{ + if (!handle) + return; + + if (handle->current) + handle_disconnect(handle); + + if (!account) + return; + + handle_connect(handle, account); +} + + +void +GNUNET_CHAT_disconnect (struct GNUNET_CHAT_Handle *handle) +{ + if ((!handle) || (!(handle->current))) + return; + + handle_disconnect(handle); +} + + +const struct GNUNET_CHAT_Account* +GNUNET_CHAT_get_connected(const struct GNUNET_CHAT_Handle *handle) +{ + if (!handle) + return NULL; + + return handle->current; +} + + +int GNUNET_CHAT_update (struct GNUNET_CHAT_Handle *handle) { if (!handle) @@ -133,7 +197,7 @@ GNUNET_CHAT_iterate_contacts (struct GNUNET_CHAT_Handle *handle, GNUNET_CHAT_ContactCallback callback, void *cls) { - if (!handle) + if ((!handle) || (!(handle->contacts))) return GNUNET_SYSERR; struct GNUNET_CHAT_HandleIterateContacts it; @@ -151,7 +215,7 @@ struct GNUNET_CHAT_Group * GNUNET_CHAT_group_create (struct GNUNET_CHAT_Handle *handle, const char* topic) { - if (!handle) + if ((!handle) || (!(handle->groups)) || (!(handle->contexts))) return NULL; struct GNUNET_HashCode key; @@ -210,7 +274,7 @@ GNUNET_CHAT_iterate_groups (struct GNUNET_CHAT_Handle *handle, GNUNET_CHAT_GroupCallback callback, void *cls) { - if (!handle) + if ((!handle) || (!(handle->groups))) return GNUNET_SYSERR; struct GNUNET_CHAT_HandleIterateGroups it; @@ -784,6 +848,8 @@ GNUNET_CHAT_message_get_kind (const struct GNUNET_CHAT_Message *message) { case GNUNET_CHAT_FLAG_WARNING: return GNUNET_CHAT_KIND_WARNING; + case GNUNET_CHAT_FLAG_REFRESH: + return GNUNET_CHAT_KIND_REFRESH; case GNUNET_CHAT_FLAG_LOGIN: return GNUNET_CHAT_KIND_LOGIN; case GNUNET_CHAT_FLAG_UPDATE: diff --git a/src/gnunet_chat_message.h b/src/gnunet_chat_message.h @@ -45,8 +45,9 @@ enum GNUNET_CHAT_MessageFlag { GNUNET_CHAT_FLAG_NONE = 0, GNUNET_CHAT_FLAG_WARNING = 1, - GNUNET_CHAT_FLAG_LOGIN = 2, - GNUNET_CHAT_FLAG_UPDATE = 3 + GNUNET_CHAT_FLAG_REFRESH = 2, + GNUNET_CHAT_FLAG_LOGIN = 3, + GNUNET_CHAT_FLAG_UPDATE = 4 }; struct GNUNET_CHAT_Message