libgnunetchat

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

gnunet_chat_lib_uml.c (6919B)


      1 /*
      2    This file is part of GNUnet.
      3    Copyright (C) 2024--2026 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   char *secret;
     39   bool quit;
     40 };
     41 
     42 static enum GNUNET_GenericReturnValue
     43 accounts_iterate (void *cls,
     44                   struct GNUNET_CHAT_Handle *handle,
     45                   struct GNUNET_CHAT_Account *account)
     46 {
     47   struct GNUNET_CHAT_Tool *tool = cls;
     48 
     49   const char *account_name = GNUNET_CHAT_account_get_name(account);
     50 
     51   if (0 == strcmp(tool->account_name, account_name))
     52   {
     53     GNUNET_CHAT_connect(
     54       tool->handle,
     55       account,
     56       tool->secret,
     57       tool->secret? strlen(tool->secret) : 0
     58     );
     59 
     60     return GNUNET_NO;
     61   }
     62 
     63   return GNUNET_YES;
     64 }
     65 
     66 static void
     67 idle (void *cls)
     68 {
     69   struct GNUNET_CHAT_Tool *tool = cls;
     70 
     71   tool->task = NULL;
     72   tool->quit = true;
     73 
     74   GNUNET_CHAT_stop(tool->handle);
     75 }
     76 
     77 static enum GNUNET_GenericReturnValue
     78 chat_message (void *cls,
     79               struct GNUNET_CHAT_Context *context,
     80               struct GNUNET_CHAT_Message *message)
     81 {
     82   struct GNUNET_CHAT_Tool *tool = cls;
     83 
     84   if (tool->task)
     85   {
     86     GNUNET_SCHEDULER_cancel(tool->task);
     87     tool->task = NULL;
     88   }
     89 
     90   const char *kind_name = "UNKNOWN";
     91   enum GNUNET_CHAT_MessageKind kind = GNUNET_CHAT_message_get_kind(
     92     message
     93   );
     94 
     95   switch (kind)
     96   {
     97     case GNUNET_CHAT_KIND_WARNING:
     98       kind_name = "WARNING";
     99       break;
    100     case GNUNET_CHAT_KIND_REFRESH:
    101       kind_name = "REFRESH";
    102       break;
    103     case GNUNET_CHAT_KIND_LOGIN:
    104       kind_name = "LOGIN";
    105       break;
    106     case GNUNET_CHAT_KIND_LOGOUT:
    107       kind_name = "LOGOUT";
    108       break;
    109     case GNUNET_CHAT_KIND_CREATED_ACCOUNT:
    110       kind_name = "CREATED_ACCOUNT";
    111       break;
    112     case GNUNET_CHAT_KIND_DELETED_ACCOUNT:
    113       kind_name = "DELETED_ACCOUNT";
    114       break;
    115     case GNUNET_CHAT_KIND_UPDATE_ACCOUNT:
    116       kind_name = "UPDATE_ACCOUNT";
    117       break;
    118     case GNUNET_CHAT_KIND_UPDATE_CONTEXT:
    119       kind_name = "UPDATE_CONTEXT";
    120       break;
    121     case GNUNET_CHAT_KIND_JOIN:
    122       kind_name = "JOIN";
    123       break;
    124     case GNUNET_CHAT_KIND_LEAVE:
    125       kind_name = "LEAVE";
    126       break;
    127     case GNUNET_CHAT_KIND_CONTACT:
    128       kind_name = "CONTACT";
    129       break;
    130     case GNUNET_CHAT_KIND_INVITATION:
    131       kind_name = "INVITATION";
    132       break;
    133     case GNUNET_CHAT_KIND_TEXT:
    134       kind_name = "TEXT";
    135       break;
    136     case GNUNET_CHAT_KIND_FILE:
    137       kind_name = "FILE";
    138       break;
    139     case GNUNET_CHAT_KIND_DELETION:
    140       kind_name = "DELETION";
    141       break;
    142     case GNUNET_CHAT_KIND_TAG:
    143       kind_name = "TAG";
    144       break;
    145     case GNUNET_CHAT_KIND_ATTRIBUTES:
    146       kind_name = "ATTRIBUTES";
    147       break;
    148     case GNUNET_CHAT_KIND_SHARED_ATTRIBUTES:
    149       kind_name = "SHARED_ATTRIBUTES";
    150       break;
    151     default:
    152       break;
    153   }
    154 
    155   const struct GNUNET_CHAT_Group *group = GNUNET_CHAT_context_get_group(context);
    156   const struct GNUNET_CHAT_Contact *contact = GNUNET_CHAT_context_get_contact(context);
    157 
    158   bool ignore = true;
    159 
    160   if (group)
    161   {
    162     const char *group_name = GNUNET_CHAT_group_get_name(group);
    163 
    164     if ((group_name) && (tool->group_name) && (0 == strcmp(tool->group_name, group_name)))
    165       ignore = false;
    166   }
    167   
    168   if (contact)
    169   {
    170     const char *contact_name = GNUNET_CHAT_contact_get_name(contact);
    171 
    172     if ((contact_name) && (tool->contact_name) && (0 == strcmp(tool->contact_name, contact_name)))
    173       ignore = false;
    174   }
    175 
    176   if (!ignore)
    177   {
    178     const struct GNUNET_CHAT_Contact *sender = GNUNET_CHAT_message_get_sender(message);
    179     const struct GNUNET_CHAT_Contact *recipient = GNUNET_CHAT_message_get_recipient(message);
    180 
    181     const char *sender_name = GNUNET_CHAT_contact_get_name(sender);
    182     const char *text = GNUNET_CHAT_message_get_text(message);
    183 
    184     printf(
    185       "%llx -> %llx: %s",
    186       (unsigned long long) sender,
    187       (unsigned long long) recipient,
    188       kind_name
    189     );
    190 
    191     if (sender_name)
    192       printf("\\n%s", sender_name);
    193 
    194     if (text)
    195       printf("\\n%s", text);
    196 
    197     printf("\n");
    198   }
    199 
    200   if (GNUNET_CHAT_KIND_REFRESH == kind)
    201     GNUNET_CHAT_iterate_accounts(
    202       tool->handle,
    203       accounts_iterate,
    204       tool
    205     );
    206 
    207   if ((!(tool->quit)) && (!(tool->task)))
    208     tool->task = GNUNET_SCHEDULER_add_delayed_with_priority(
    209       GNUNET_TIME_relative_get_second_(),
    210       GNUNET_SCHEDULER_PRIORITY_IDLE,
    211       idle,
    212       tool
    213     );
    214 
    215   return GNUNET_YES;
    216 }
    217 
    218 static void
    219 run (void *cls,
    220      char* const* args,
    221      const char *cfgfile,
    222      const struct GNUNET_CONFIGURATION_Handle *cfg)
    223 {
    224   struct GNUNET_CHAT_Tool *tool = cls;
    225 
    226   if (!(tool->account_name))
    227     return;
    228 
    229   tool->handle = GNUNET_CHAT_start(
    230     cfg,
    231     chat_message,
    232     tool
    233   );
    234 }
    235 
    236 int
    237 main (int argc,
    238       char* const* argv)
    239 {
    240   struct GNUNET_CHAT_Tool tool;
    241   memset(&tool, 0, sizeof(tool));
    242 
    243   const struct GNUNET_OS_ProjectData *data;
    244   data = GNUNET_OS_project_data_gnunet ();
    245 
    246   struct GNUNET_GETOPT_CommandLineOption options[] = {
    247     GNUNET_GETOPT_option_string(
    248       'a',
    249       "account",
    250       "ACCOUNT_NAME",
    251       "name of account to read messages from",
    252       &(tool.account_name)
    253     ),
    254     GNUNET_GETOPT_option_string(
    255       'c',
    256       "contact",
    257       "CONTACT_NAME",
    258       "name of contact chat to read messages from",
    259       &(tool.contact_name)
    260     ),
    261     GNUNET_GETOPT_option_string(
    262       'g',
    263       "group",
    264       "GROUP_NAME",
    265       "name of group chat to read messages from",
    266       &(tool.group_name)
    267     ),
    268     GNUNET_GETOPT_option_string(
    269       'S',
    270       "secret",
    271       "SECRET",
    272       "storage secret for local keys",
    273       &(tool.secret)
    274     ),
    275     GNUNET_GETOPT_OPTION_END
    276   };
    277 
    278   printf("@startuml\n");
    279 
    280   enum GNUNET_GenericReturnValue result = GNUNET_PROGRAM_run(
    281     data,
    282     argc,
    283     argv,
    284     "libgnunetchat_uml",
    285     gettext_noop("A tool to debug the Messenger service of GNUnet."),
    286     options,
    287     &run,
    288     &tool
    289   );
    290 
    291   printf("@enduml\n");
    292 
    293   return GNUNET_OK == result? 0 : 1;
    294 }