libgnunetchat

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

commit 0f10ebd9ccc82b3d4c4d0e155e3e3982963d4619
parent 9e578beeb63085bf51a0056a657f44ecea8c4d78
Author: Jacki <jacki@thejackimonster.de>
Date:   Thu, 22 Feb 2024 15:38:47 +0100

Implement tool to debug chat messages with plantuml output

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

Diffstat:
Mmeson.build | 2++
Atools/gnunet_chat_lib_uml.c | 263+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atools/meson.build | 27+++++++++++++++++++++++++++
3 files changed, 292 insertions(+), 0 deletions(-)

diff --git a/meson.build b/meson.build @@ -29,6 +29,7 @@ pkg = import('pkgconfig') src_include = include_directories('src', 'include/gnunet') tests_include = include_directories('tests', 'include') +tools_include = include_directories('include') gnunetchat_deps = [ dependency('gnunetarm'), @@ -60,6 +61,7 @@ pkg.generate( ) subdir('tests') +subdir('tools') run_target( 'docs', diff --git a/tools/gnunet_chat_lib_uml.c b/tools/gnunet_chat_lib_uml.c @@ -0,0 +1,263 @@ +/* + 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_lib_uml.c + */ + +#include "gnunet/gnunet_chat_lib.h" +#include <gnunet/gnunet_common.h> +#include <gnunet/gnunet_scheduler_lib.h> +#include <gnunet/gnunet_time_lib.h> +#include <string.h> + +struct GNUNET_CHAT_Tool +{ + struct GNUNET_CHAT_Handle *handle; + struct GNUNET_SCHEDULER_Task *task; + char *account_name; + char *group_name; + char *contact_name; + bool quit; +}; + +static enum GNUNET_GenericReturnValue +accounts_iterate (void *cls, + const struct GNUNET_CHAT_Handle *handle, + struct GNUNET_CHAT_Account *account) +{ + struct GNUNET_CHAT_Tool *tool = cls; + + const char *account_name = GNUNET_CHAT_account_get_name(account); + + if (0 == strcmp(tool->account_name, account_name)) + { + GNUNET_CHAT_connect(tool->handle, account); + return GNUNET_NO; + } + + return GNUNET_YES; +} + +static void +idle (void *cls) +{ + struct GNUNET_CHAT_Tool *tool = cls; + + tool->task = NULL; + tool->quit = true; + + GNUNET_CHAT_stop(tool->handle); +} + +static enum GNUNET_GenericReturnValue +chat_message (void *cls, + struct GNUNET_CHAT_Context *context, + const struct GNUNET_CHAT_Message *message) +{ + struct GNUNET_CHAT_Tool *tool = cls; + + if (tool->task) + { + GNUNET_SCHEDULER_cancel(tool->task); + tool->task = NULL; + } + + const char *kind_name = "UNKNOWN"; + enum GNUNET_CHAT_MessageKind kind = GNUNET_CHAT_message_get_kind( + message + ); + + switch (kind) + { + case GNUNET_CHAT_KIND_WARNING: + kind_name = "WARNING"; + break; + case GNUNET_CHAT_KIND_REFRESH: + kind_name = "REFRESH"; + break; + case GNUNET_CHAT_KIND_LOGIN: + kind_name = "LOGIN"; + break; + case GNUNET_CHAT_KIND_LOGOUT: + kind_name = "LOGOUT"; + break; + case GNUNET_CHAT_KIND_UPDATE: + kind_name = "UPDATE"; + break; + case GNUNET_CHAT_KIND_JOIN: + kind_name = "JOIN"; + break; + case GNUNET_CHAT_KIND_LEAVE: + kind_name = "LEAVE"; + break; + case GNUNET_CHAT_KIND_CONTACT: + kind_name = "CONTACT"; + break; + case GNUNET_CHAT_KIND_INVITATION: + kind_name = "INVITATION"; + break; + case GNUNET_CHAT_KIND_TEXT: + kind_name = "TEXT"; + break; + case GNUNET_CHAT_KIND_FILE: + kind_name = "FILE"; + break; + case GNUNET_CHAT_KIND_DELETION: + kind_name = "DELETION"; + break; + case GNUNET_CHAT_KIND_TAG: + kind_name = "TAG"; + break; + default: + break; + } + + const struct GNUNET_CHAT_Group *group = GNUNET_CHAT_context_get_group(context); + const struct GNUNET_CHAT_Contact *contact = GNUNET_CHAT_context_get_contact(context); + + bool ignore = true; + + if (group) + { + const char *group_name = GNUNET_CHAT_group_get_name(group); + + if ((group_name) && (tool->group_name) && (0 == strcmp(tool->group_name, group_name))) + ignore = false; + } + + if (contact) + { + const char *contact_name = GNUNET_CHAT_contact_get_name(contact); + + if ((contact_name) && (tool->contact_name) && (0 == strcmp(tool->contact_name, contact_name))) + ignore = false; + } + + if (!ignore) + { + const struct GNUNET_CHAT_Contact *sender = GNUNET_CHAT_message_get_sender(message); + const struct GNUNET_CHAT_Contact *recipient = GNUNET_CHAT_message_get_recipient(message); + + const char *sender_name = GNUNET_CHAT_contact_get_name(sender); + const char *text = GNUNET_CHAT_message_get_text(message); + + printf( + "%llx -> %llx: %s", + (unsigned long long) sender, + (unsigned long long) recipient, + kind_name + ); + + if (sender_name) + printf("\\n%s", sender_name); + + if (text) + printf("\\n%s", text); + + printf("\n"); + } + + if (GNUNET_CHAT_KIND_REFRESH == kind) + { + GNUNET_CHAT_iterate_accounts( + tool->handle, + accounts_iterate, + tool + ); + } + + if ((!(tool->quit)) && (!(tool->task))) + tool->task = GNUNET_SCHEDULER_add_delayed_with_priority( + GNUNET_TIME_relative_get_second_(), + GNUNET_SCHEDULER_PRIORITY_IDLE, + idle, + tool + ); + + return GNUNET_YES; +} + +static void +run (void *cls, + char* const* args, + const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + struct GNUNET_CHAT_Tool *tool = cls; + + if (!(tool->account_name)) + return; + + tool->handle = GNUNET_CHAT_start( + cfg, + chat_message, + tool + ); +} + +int +main (int argc, + char* const* argv) +{ + struct GNUNET_CHAT_Tool tool; + memset(&tool, 0, sizeof(tool)); + + struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_option_string( + 'a', + "account", + "ACCOUNT_NAME", + "name of account to read messages from", + &(tool.account_name) + ), + GNUNET_GETOPT_option_string( + 'c', + "contact", + "CONTACT_NAME", + "name of contact chat to read messages from", + &(tool.contact_name) + ), + GNUNET_GETOPT_option_string( + 'g', + "group", + "GROUP_NAME", + "name of group chat to read messages from", + &(tool.group_name) + ), + GNUNET_GETOPT_OPTION_END + }; + + printf("@startuml\n"); + + enum GNUNET_GenericReturnValue result = GNUNET_PROGRAM_run( + argc, + argv, + "libgnunetchat_uml", + gettext_noop("A tool to debug the Messenger service of GNUnet."), + options, + &run, + &tool + ); + + printf("@enduml\n"); + + return GNUNET_OK == result? 0 : 1; +} diff --git a/tools/meson.build b/tools/meson.build @@ -0,0 +1,27 @@ +# +# 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 +# + +libgnunetchat_uml = executable( + 'libgnunetchat_uml', + [ 'gnunet_chat_lib_uml.c' ], + dependencies: [ dependency('gnunetutil') ], + link_with: gnunetchat_lib, + include_directories: tools_include, +)