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:
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_ */