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 }