libgnunetchat

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

commit e068078b3ae07d67e9d4b75574075773a88c4a3d
parent ea62f25fccb6c10d5f4a32a8d259116c51d94ee3
Author: TheJackiMonster <thejackimonster@gmail.com>
Date:   Sun, 25 Jul 2021 00:12:24 +0200

Included usage of message flags and added per chat config io

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

Diffstat:
MMakefile | 1-
Minclude/gnunet_chat_lib.h | 18++++++++++++++++++
Dsrc/gnunet_chat_config.c | 27---------------------------
Dsrc/gnunet_chat_config.h | 30------------------------------
Msrc/gnunet_chat_context.c | 69+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/gnunet_chat_context.h | 7+++++++
Msrc/gnunet_chat_handle_intern.c | 6++++--
Msrc/gnunet_chat_lib.c | 47+++++++++++++++++++++++++++++++++++++++++------
Msrc/gnunet_chat_message.c | 11+++++++++++
Msrc/gnunet_chat_message.h | 14++++++++++++++
Asrc/gnunet_chat_message_intern.c | 135+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/gnunet_chat_util.c | 5+++--
Msrc/gnunet_chat_util.h | 3++-
13 files changed, 304 insertions(+), 69 deletions(-)

diff --git a/Makefile b/Makefile @@ -5,7 +5,6 @@ INSTALL_DIR = /usr/local/ LIBRARY = libgnunetchat.so SOURCES = gnunet_chat_lib.c\ - gnunet_chat_config.c\ gnunet_chat_contact.c\ gnunet_chat_context.c\ gnunet_chat_file.c\ diff --git a/include/gnunet_chat_lib.h b/include/gnunet_chat_lib.h @@ -559,6 +559,24 @@ GNUNET_CHAT_message_get_sender (const struct GNUNET_CHAT_Message *message); * TODO * * @param message + * @return + */ +int +GNUNET_CHAT_message_is_sent (const struct GNUNET_CHAT_Message *message); + +/** + * TODO + * + * @param message + * @return + */ +int +GNUNET_CHAT_message_is_private (const struct GNUNET_CHAT_Message *message); + +/** + * TODO + * + * @param message * @param callback * @param cls * @return diff --git a/src/gnunet_chat_config.c b/src/gnunet_chat_config.c @@ -1,27 +0,0 @@ -/* - This file is part of GNUnet. - Copyright (C) 2021 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_config.c - */ - -#include "gnunet_chat_config.h" - - diff --git a/src/gnunet_chat_config.h b/src/gnunet_chat_config.h @@ -1,30 +0,0 @@ -/* - This file is part of GNUnet. - Copyright (C) 2021 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_config.h - */ - -#ifndef GNUNET_CHAT_CONFIG_H_ -#define GNUNET_CHAT_CONFIG_H_ - - - -#endif /* GNUNET_CHAT_CONFIG_H_ */ diff --git a/src/gnunet_chat_context.c b/src/gnunet_chat_context.c @@ -23,6 +23,8 @@ */ #include "gnunet_chat_context.h" +#include "gnunet_chat_handle.h" +#include "gnunet_chat_util.h" #include "gnunet_chat_context_intern.c" @@ -68,3 +70,70 @@ context_destroy (struct GNUNET_CHAT_Context* context) GNUNET_free(context); } + +void +context_load_config (struct GNUNET_CHAT_Context *context) +{ + const char *directory = context->handle->directory; + + if (!directory) + return; + + const struct GNUNET_HashCode *hash = GNUNET_MESSENGER_room_get_key( + context->room + ); + + char* filename; + util_get_filename(directory, "chats", hash, &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)) + goto destroy_config; + + char* name = NULL; + + if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string( + config, "chat", "name", &name)) + util_set_name_field(name, &(context->nick)); + + if (name) + GNUNET_free(name); + +destroy_config: + GNUNET_CONFIGURATION_destroy(config); + +free_filename: + GNUNET_free(filename); +} + +void +context_save_config (const struct GNUNET_CHAT_Context *context) +{ + const char *directory = context->handle->directory; + + if (!directory) + return; + + const struct GNUNET_HashCode *hash = GNUNET_MESSENGER_room_get_key( + context->room + ); + + struct GNUNET_CONFIGURATION_Handle *config = GNUNET_CONFIGURATION_create(); + + if (context->nick) + GNUNET_CONFIGURATION_set_value_string( + config, "chat", "name", context->nick + ); + + char* filename; + util_get_filename(directory, "chats", hash, &filename); + + GNUNET_CONFIGURATION_write(config, filename); + GNUNET_CONFIGURATION_destroy(config); + + GNUNET_free(filename); +} diff --git a/src/gnunet_chat_context.h b/src/gnunet_chat_context.h @@ -27,6 +27,7 @@ #include <gnunet/platform.h> #include <gnunet/gnunet_common.h> +#include <gnunet/gnunet_configuration_lib.h> #include <gnunet/gnunet_container_lib.h> #include <gnunet/gnunet_messenger_service.h> #include <gnunet/gnunet_util_lib.h> @@ -63,4 +64,10 @@ context_create_from_room (struct GNUNET_CHAT_Handle *handle, void context_destroy (struct GNUNET_CHAT_Context* context); +void +context_load_config (struct GNUNET_CHAT_Context *context); + +void +context_save_config (const struct GNUNET_CHAT_Context *context); + #endif /* GNUNET_CHAT_CONTEXT_H_ */ diff --git a/src/gnunet_chat_handle_intern.c b/src/gnunet_chat_handle_intern.c @@ -183,6 +183,7 @@ request_handle_context_by_room (struct GNUNET_CHAT_Handle *handle, return context; context = context_create_from_room(handle, room); + context_load_config(context); if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put( handle->contexts, key, context, @@ -267,7 +268,7 @@ on_handle_message (void *cls, GNUNET_UNUSED const struct GNUNET_MESSENGER_Contact *sender, const struct GNUNET_MESSENGER_Message *msg, const struct GNUNET_HashCode *hash, - GNUNET_UNUSED enum GNUNET_MESSENGER_MessageFlags flags) + enum GNUNET_MESSENGER_MessageFlags flags) { struct GNUNET_CHAT_Handle *handle = cls; @@ -285,7 +286,7 @@ on_handle_message (void *cls, if (message) return; - message = message_create_from_msg(context, hash, msg); + message = message_create_from_msg(context, hash, flags, msg); switch (msg->header.kind) { @@ -360,6 +361,7 @@ it_destroy_handle_contexts (GNUNET_UNUSED void *cls, void *value) { struct GNUNET_CHAT_Context *context = value; + context_save_config(context); context_destroy(context); return GNUNET_YES; } diff --git a/src/gnunet_chat_lib.c b/src/gnunet_chat_lib.c @@ -26,7 +26,6 @@ #include <limits.h> -#include "gnunet_chat_config.h" #include "gnunet_chat_contact.h" #include "gnunet_chat_context.h" #include "gnunet_chat_file.h" @@ -489,7 +488,9 @@ GNUNET_CHAT_context_send_file (struct GNUNET_CHAT_Context *context, return GNUNET_SYSERR; char *filename; - util_get_filename (context->handle->directory, &hash, &filename); + util_get_filename ( + context->handle->directory, "files", &hash, &filename + ); if ((GNUNET_OK != GNUNET_DISK_directory_create_for_file(filename)) || (GNUNET_OK != GNUNET_DISK_file_copy(path, filename))) @@ -670,6 +671,32 @@ GNUNET_CHAT_message_get_sender (const struct GNUNET_CHAT_Message *message) int +GNUNET_CHAT_message_is_sent (const struct GNUNET_CHAT_Message *message) +{ + if (!message) + return GNUNET_SYSERR; + + if (message->flags & GNUNET_MESSENGER_FLAG_SENT) + return GNUNET_YES; + else + return GNUNET_NO; +} + + +int +GNUNET_CHAT_message_is_private (const struct GNUNET_CHAT_Message *message) +{ + if (!message) + return GNUNET_SYSERR; + + if (message->flags & GNUNET_MESSENGER_FLAG_PRIVATE) + return GNUNET_YES; + else + return GNUNET_NO; +} + + +int GNUNET_CHAT_message_get_read_receipt (const struct GNUNET_CHAT_Message *message, GNUNET_CHAT_MessageReadReceiptCallback callback, void *cls) @@ -765,7 +792,9 @@ GNUNET_CHAT_file_get_size (const struct GNUNET_CHAT_File *file) return GNUNET_FS_uri_chk_get_file_size(file->uri); char *filename; - util_get_filename (file->handle->directory, &(file->hash), &filename); + util_get_filename ( + file->handle->directory, "files", &(file->hash), &filename + ); uint64_t size; if (GNUNET_OK != GNUNET_DISK_file_size(filename, &size, GNUNET_NO, GNUNET_YES)) @@ -783,7 +812,9 @@ GNUNET_CHAT_file_is_local (const struct GNUNET_CHAT_File *file) return GNUNET_SYSERR; char *filename; - util_get_filename (file->handle->directory, &(file->hash), &filename); + util_get_filename ( + file->handle->directory, "files", &(file->hash), &filename + ); int result = GNUNET_DISK_file_test(filename); @@ -809,7 +840,9 @@ GNUNET_CHAT_file_start_download (struct GNUNET_CHAT_File *file, const uint64_t size = GNUNET_FS_uri_chk_get_file_size(file->uri); char *filename; - util_get_filename (file->handle->directory, &(file->hash), &filename); + util_get_filename ( + file->handle->directory, "files", &(file->hash), &filename + ); uint64_t offset; if (GNUNET_OK != GNUNET_DISK_file_size(filename, &offset, GNUNET_NO, GNUNET_YES)) @@ -890,7 +923,9 @@ GNUNET_CHAT_file_unindex (struct GNUNET_CHAT_File *file) return GNUNET_OK; char *filename; - util_get_filename (file->handle->directory, &(file->hash), &filename); + util_get_filename ( + file->handle->directory, "files", &(file->hash), &filename + ); file->unindex = GNUNET_FS_unindex_start( file->handle->fs, filename, file diff --git a/src/gnunet_chat_message.c b/src/gnunet_chat_message.c @@ -24,9 +24,12 @@ #include "gnunet_chat_message.h" +#include "gnunet_chat_message_intern.c" + struct GNUNET_CHAT_Message* message_create_from_msg (struct GNUNET_CHAT_Context *context, const struct GNUNET_HashCode *hash, + enum GNUNET_MESSENGER_MessageFlags flags, const struct GNUNET_MESSENGER_Message *msg) { struct GNUNET_CHAT_Message *message = GNUNET_new(struct GNUNET_CHAT_Message); @@ -34,14 +37,22 @@ message_create_from_msg (struct GNUNET_CHAT_Context *context, message->context = context; GNUNET_memcpy(&(message->hash), hash, sizeof(message->hash)); + message->flags = flags; + + message->head = NULL; + message->tail = NULL; message->msg = msg; + link_message_parent(message); + return message; } void message_destroy (struct GNUNET_CHAT_Message* message) { + unlink_message_parent(message); + clear_message_children(message); GNUNET_free(message); } diff --git a/src/gnunet_chat_message.h b/src/gnunet_chat_message.h @@ -31,12 +31,25 @@ #include <gnunet/gnunet_util_lib.h> struct GNUNET_CHAT_Context; +struct GNUNET_CHAT_Message; + +struct GNUNET_CHAT_MessageList +{ + struct GNUNET_CHAT_Message *message; + + struct GNUNET_CHAT_MessageList *prev; + struct GNUNET_CHAT_MessageList *next; +}; struct GNUNET_CHAT_Message { struct GNUNET_CHAT_Context *context; struct GNUNET_HashCode hash; + enum GNUNET_MESSENGER_MessageFlags flags; + + struct GNUNET_CHAT_MessageList *head; + struct GNUNET_CHAT_MessageList *tail; const struct GNUNET_MESSENGER_Message *msg; }; @@ -44,6 +57,7 @@ struct GNUNET_CHAT_Message struct GNUNET_CHAT_Message* message_create_from_msg (struct GNUNET_CHAT_Context *context, const struct GNUNET_HashCode *hash, + enum GNUNET_MESSENGER_MessageFlags flags, const struct GNUNET_MESSENGER_Message *msg); void diff --git a/src/gnunet_chat_message_intern.c b/src/gnunet_chat_message_intern.c @@ -0,0 +1,135 @@ +/* + This file is part of GNUnet. + Copyright (C) 2021 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_message_intern.c + */ + +#include <gnunet/gnunet_container_lib.h> + +#include "gnunet_chat_context.h" + +void +link_message_parent (struct GNUNET_CHAT_Message *message) +{ + struct GNUNET_CHAT_Context *context = message->context; + + struct GNUNET_CHAT_Message *prev = GNUNET_CONTAINER_multihashmap_get( + context->messages, &(message->msg->header.previous) + ); + + if (prev) + { + struct GNUNET_CHAT_MessageList *list = GNUNET_new( + struct GNUNET_CHAT_MessageList + ); + + list->message = message; + + GNUNET_CONTAINER_DLL_insert(prev->head, prev->tail, list); + } + + if (GNUNET_MESSENGER_KIND_MERGE != message->msg->header.kind) + return; + + prev = GNUNET_CONTAINER_multihashmap_get( + context->messages, &(message->msg->body.merge.previous) + ); + + if (prev) + { + struct GNUNET_CHAT_MessageList *list = GNUNET_new( + struct GNUNET_CHAT_MessageList + ); + + list->message = message; + + GNUNET_CONTAINER_DLL_insert(prev->head, prev->tail, list); + } +} + +void +unlink_message_parent (struct GNUNET_CHAT_Message *message) +{ + struct GNUNET_CHAT_Context *context = message->context; + + struct GNUNET_CHAT_Message *prev = GNUNET_CONTAINER_multihashmap_get( + context->messages, &(message->msg->header.previous) + ); + + if (prev) + { + struct GNUNET_CHAT_MessageList *list = prev->head; + + while (list) + { + if (list->message == message) + break; + + list = list->next; + } + + if (list) + { + GNUNET_CONTAINER_DLL_remove(prev->head, prev->tail, list); + GNUNET_free(list); + } + } + + if (GNUNET_MESSENGER_KIND_MERGE != message->msg->header.kind) + return; + + prev = GNUNET_CONTAINER_multihashmap_get( + context->messages, &(message->msg->body.merge.previous) + ); + + if (prev) + { + struct GNUNET_CHAT_MessageList *list = prev->head; + + while (list) + { + if (list->message == message) + break; + + list = list->next; + } + + if (list) + { + GNUNET_CONTAINER_DLL_remove(prev->head, prev->tail, list); + GNUNET_free(list); + } + } +} + +void +clear_message_children (struct GNUNET_CHAT_Message *message) +{ + struct GNUNET_CHAT_MessageList *list = message->tail; + + while (list) + { + GNUNET_CONTAINER_DLL_remove(message->head, message->tail, list); + GNUNET_free(list); + + list = message->tail; + } +} diff --git a/src/gnunet_chat_util.c b/src/gnunet_chat_util.c @@ -175,14 +175,15 @@ util_decrypt_file (const char *filename, } int -util_get_filename (const char *directory, const struct GNUNET_HashCode *hash, +util_get_filename (const char *directory, const char *subdir, + const struct GNUNET_HashCode *hash, char **filename) { return GNUNET_asprintf ( filename, "%s%s%c%s", directory, - "files", + subdir, DIR_SEPARATOR, GNUNET_h2s_full(hash) ); diff --git a/src/gnunet_chat_util.h b/src/gnunet_chat_util.h @@ -51,7 +51,8 @@ util_decrypt_file (const char *filename, const struct GNUNET_CRYPTO_SymmetricSessionKey *key); int -util_get_filename (const char *directory, const struct GNUNET_HashCode *hash, +util_get_filename (const char *directory, const char *subdir, + const struct GNUNET_HashCode *hash, char **filename); #endif /* GNUNET_CHAT_UTIL_H_ */