libgnunetchat

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

gnunet_chat_lib_uml.c (6669B)


      1 /*
      2    This file is part of GNUnet.
      3    Copyright (C) 2024 GNUnet e.V.
      4 
      5    GNUnet is free software: you can redistribute it and/or modify it
      6    under the terms of the GNU Affero General Public License as published
      7    by the Free Software Foundation, either version 3 of the License,
      8    or (at your option) any later version.
      9 
     10    GNUnet is distributed in the hope that it will be useful, but
     11    WITHOUT ANY WARRANTY; without even the implied warranty of
     12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13    Affero General Public License for more details.
     14 
     15    You should have received a copy of the GNU Affero General Public License
     16    along with this program.  If not, see <http://www.gnu.org/licenses/>.
     17 
     18    SPDX-License-Identifier: AGPL3.0-or-later
     19  */
     20 /*
     21  * @author Tobias Frisch
     22  * @file gnunet_chat_lib_uml.c
     23  */
     24 
     25 #include "gnunet/gnunet_chat_lib.h"
     26 #include <gnunet/gnunet_common.h>
     27 #include <gnunet/gnunet_scheduler_lib.h>
     28 #include <gnunet/gnunet_time_lib.h>
     29 #include <string.h>
     30 
     31 struct GNUNET_CHAT_Tool
     32 {
     33   struct GNUNET_CHAT_Handle *handle;
     34   struct GNUNET_SCHEDULER_Task *task;
     35   char *account_name;
     36   char *group_name;
     37   char *contact_name;
     38   bool quit;
     39 };
     40 
     41 static enum GNUNET_GenericReturnValue
     42 accounts_iterate (void *cls,
     43                   struct GNUNET_CHAT_Handle *handle,
     44                   struct GNUNET_CHAT_Account *account)
     45 {
     46   struct GNUNET_CHAT_Tool *tool = cls;
     47 
     48   const char *account_name = GNUNET_CHAT_account_get_name(account);
     49 
     50   if (0 == strcmp(tool->account_name, account_name))
     51   {
     52     GNUNET_CHAT_connect(tool->handle, account);
     53     return GNUNET_NO;
     54   }
     55 
     56   return GNUNET_YES;
     57 }
     58 
     59 static void
     60 idle (void *cls)
     61 {
     62   struct GNUNET_CHAT_Tool *tool = cls;
     63 
     64   tool->task = NULL;
     65   tool->quit = true;
     66 
     67   GNUNET_CHAT_stop(tool->handle);
     68 }
     69 
     70 static enum GNUNET_GenericReturnValue
     71 chat_message (void *cls,
     72               struct GNUNET_CHAT_Context *context,
     73               struct GNUNET_CHAT_Message *message)
     74 {
     75   struct GNUNET_CHAT_Tool *tool = cls;
     76 
     77   if (tool->task)
     78   {
     79     GNUNET_SCHEDULER_cancel(tool->task);
     80     tool->task = NULL;
     81   }
     82 
     83   const char *kind_name = "UNKNOWN";
     84   enum GNUNET_CHAT_MessageKind kind = GNUNET_CHAT_message_get_kind(
     85     message
     86   );
     87 
     88   switch (kind)
     89   {
     90     case GNUNET_CHAT_KIND_WARNING:
     91       kind_name = "WARNING";
     92       break;
     93     case GNUNET_CHAT_KIND_REFRESH:
     94       kind_name = "REFRESH";
     95       break;
     96     case GNUNET_CHAT_KIND_LOGIN:
     97       kind_name = "LOGIN";
     98       break;
     99     case GNUNET_CHAT_KIND_LOGOUT:
    100       kind_name = "LOGOUT";
    101       break;
    102     case GNUNET_CHAT_KIND_CREATED_ACCOUNT:
    103       kind_name = "CREATED_ACCOUNT";
    104       break;
    105     case GNUNET_CHAT_KIND_DELETED_ACCOUNT:
    106       kind_name = "DELETED_ACCOUNT";
    107       break;
    108     case GNUNET_CHAT_KIND_UPDATE_ACCOUNT:
    109       kind_name = "UPDATE_ACCOUNT";
    110       break;
    111     case GNUNET_CHAT_KIND_UPDATE_CONTEXT:
    112       kind_name = "UPDATE_CONTEXT";
    113       break;
    114     case GNUNET_CHAT_KIND_JOIN:
    115       kind_name = "JOIN";
    116       break;
    117     case GNUNET_CHAT_KIND_LEAVE:
    118       kind_name = "LEAVE";
    119       break;
    120     case GNUNET_CHAT_KIND_CONTACT:
    121       kind_name = "CONTACT";
    122       break;
    123     case GNUNET_CHAT_KIND_INVITATION:
    124       kind_name = "INVITATION";
    125       break;
    126     case GNUNET_CHAT_KIND_TEXT:
    127       kind_name = "TEXT";
    128       break;
    129     case GNUNET_CHAT_KIND_FILE:
    130       kind_name = "FILE";
    131       break;
    132     case GNUNET_CHAT_KIND_DELETION:
    133       kind_name = "DELETION";
    134       break;
    135     case GNUNET_CHAT_KIND_TAG:
    136       kind_name = "TAG";
    137       break;
    138     case GNUNET_CHAT_KIND_ATTRIBUTES:
    139       kind_name = "ATTRIBUTES";
    140       break;
    141     case GNUNET_CHAT_KIND_SHARED_ATTRIBUTES:
    142       kind_name = "SHARED_ATTRIBUTES";
    143       break;
    144     default:
    145       break;
    146   }
    147 
    148   const struct GNUNET_CHAT_Group *group = GNUNET_CHAT_context_get_group(context);
    149   const struct GNUNET_CHAT_Contact *contact = GNUNET_CHAT_context_get_contact(context);
    150 
    151   bool ignore = true;
    152 
    153   if (group)
    154   {
    155     const char *group_name = GNUNET_CHAT_group_get_name(group);
    156 
    157     if ((group_name) && (tool->group_name) && (0 == strcmp(tool->group_name, group_name)))
    158       ignore = false;
    159   }
    160   
    161   if (contact)
    162   {
    163     const char *contact_name = GNUNET_CHAT_contact_get_name(contact);
    164 
    165     if ((contact_name) && (tool->contact_name) && (0 == strcmp(tool->contact_name, contact_name)))
    166       ignore = false;
    167   }
    168 
    169   if (!ignore)
    170   {
    171     const struct GNUNET_CHAT_Contact *sender = GNUNET_CHAT_message_get_sender(message);
    172     const struct GNUNET_CHAT_Contact *recipient = GNUNET_CHAT_message_get_recipient(message);
    173 
    174     const char *sender_name = GNUNET_CHAT_contact_get_name(sender);
    175     const char *text = GNUNET_CHAT_message_get_text(message);
    176 
    177     printf(
    178       "%llx -> %llx: %s",
    179       (unsigned long long) sender,
    180       (unsigned long long) recipient,
    181       kind_name
    182     );
    183 
    184     if (sender_name)
    185       printf("\\n%s", sender_name);
    186 
    187     if (text)
    188       printf("\\n%s", text);
    189 
    190     printf("\n");
    191   }
    192 
    193   if (GNUNET_CHAT_KIND_REFRESH == kind)
    194     GNUNET_CHAT_iterate_accounts(
    195       tool->handle,
    196       accounts_iterate,
    197       tool
    198     );
    199 
    200   if ((!(tool->quit)) && (!(tool->task)))
    201     tool->task = GNUNET_SCHEDULER_add_delayed_with_priority(
    202       GNUNET_TIME_relative_get_second_(),
    203       GNUNET_SCHEDULER_PRIORITY_IDLE,
    204       idle,
    205       tool
    206     );
    207 
    208   return GNUNET_YES;
    209 }
    210 
    211 static void
    212 run (void *cls,
    213      char* const* args,
    214      const char *cfgfile,
    215      const struct GNUNET_CONFIGURATION_Handle *cfg)
    216 {
    217   struct GNUNET_CHAT_Tool *tool = cls;
    218 
    219   if (!(tool->account_name))
    220     return;
    221 
    222   tool->handle = GNUNET_CHAT_start(
    223     cfg,
    224     chat_message,
    225     tool
    226   );
    227 }
    228 
    229 int
    230 main (int argc,
    231       char* const* argv)
    232 {
    233   struct GNUNET_CHAT_Tool tool;
    234   memset(&tool, 0, sizeof(tool));
    235 
    236   const struct GNUNET_OS_ProjectData *data;
    237   data = GNUNET_OS_project_data_gnunet ();
    238 
    239   struct GNUNET_GETOPT_CommandLineOption options[] = {
    240     GNUNET_GETOPT_option_string(
    241       'a',
    242       "account",
    243       "ACCOUNT_NAME",
    244       "name of account to read messages from",
    245       &(tool.account_name)
    246     ),
    247     GNUNET_GETOPT_option_string(
    248       'c',
    249       "contact",
    250       "CONTACT_NAME",
    251       "name of contact chat to read messages from",
    252       &(tool.contact_name)
    253     ),
    254     GNUNET_GETOPT_option_string(
    255       'g',
    256       "group",
    257       "GROUP_NAME",
    258       "name of group chat to read messages from",
    259       &(tool.group_name)
    260     ),
    261     GNUNET_GETOPT_OPTION_END
    262   };
    263 
    264   printf("@startuml\n");
    265 
    266   enum GNUNET_GenericReturnValue result = GNUNET_PROGRAM_run(
    267     data,
    268     argc,
    269     argv,
    270     "libgnunetchat_uml",
    271     gettext_noop("A tool to debug the Messenger service of GNUnet."),
    272     options,
    273     &run,
    274     &tool
    275   );
    276 
    277   printf("@enduml\n");
    278 
    279   return GNUNET_OK == result? 0 : 1;
    280 }