aboutsummaryrefslogtreecommitdiff
path: root/src/messenger/gnunet-messenger.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/messenger/gnunet-messenger.c')
-rw-r--r--src/messenger/gnunet-messenger.c409
1 files changed, 0 insertions, 409 deletions
diff --git a/src/messenger/gnunet-messenger.c b/src/messenger/gnunet-messenger.c
deleted file mode 100644
index 79c0d0b1e..000000000
--- a/src/messenger/gnunet-messenger.c
+++ /dev/null
@@ -1,409 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2020--2023 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 src/messenger/gnunet-messenger.c
23 * @brief Print information about messenger groups.
24 */
25
26#include "platform.h"
27#include <stdio.h>
28
29#include "gnunet_util_lib.h"
30#include "gnunet_messenger_service.h"
31
32const struct GNUNET_CONFIGURATION_Handle *config;
33struct GNUNET_MESSENGER_Handle *messenger;
34
35/**
36 * Function called whenever a message is received or sent.
37 *
38 * @param[in,out] cls Closure
39 * @param[in] room Room
40 * @param[in] sender Sender of message
41 * @param[in] message Message
42 * @param[in] hash Hash of message
43 * @param[in] flags Flags of message
44 */
45void
46on_message (void *cls,
47 struct GNUNET_MESSENGER_Room *room,
48 const struct GNUNET_MESSENGER_Contact *sender,
49 const struct GNUNET_MESSENGER_Message *message,
50 const struct GNUNET_HashCode *hash,
51 enum GNUNET_MESSENGER_MessageFlags flags)
52{
53 const char *sender_name = GNUNET_MESSENGER_contact_get_name (sender);
54
55 if (! sender_name)
56 sender_name = "anonymous";
57
58 printf ("[%s ->", GNUNET_h2s (&(message->header.previous)));
59 printf (" %s]", GNUNET_h2s (hash));
60 printf ("[%s] ", GNUNET_sh2s (&(message->header.sender_id)));
61
62 if (flags & GNUNET_MESSENGER_FLAG_PRIVATE)
63 printf ("*");
64
65 switch (message->header.kind)
66 {
67 case GNUNET_MESSENGER_KIND_JOIN:
68 {
69 printf ("* '%s' joined the room!\n", sender_name);
70 break;
71 }
72 case GNUNET_MESSENGER_KIND_NAME:
73 {
74 printf ("* '%s' gets renamed to '%s'\n", sender_name,
75 message->body.name.name);
76 break;
77 }
78 case GNUNET_MESSENGER_KIND_LEAVE:
79 {
80 printf ("* '%s' leaves the room!\n", sender_name);
81 break;
82 }
83 case GNUNET_MESSENGER_KIND_PEER:
84 {
85 printf ("* '%s' opened the room on: %s\n", sender_name,
86 GNUNET_i2s_full (&(message->body.peer.peer)));
87 break;
88 }
89 case GNUNET_MESSENGER_KIND_TEXT:
90 {
91 if (flags & GNUNET_MESSENGER_FLAG_SENT)
92 printf (">");
93 else
94 printf ("<");
95
96 printf (" '%s' says: \"%s\"\n", sender_name, message->body.text.text);
97 break;
98 }
99 default:
100 {
101 printf ("~ message: %s\n",
102 GNUNET_MESSENGER_name_of_kind (message->header.kind));
103 break;
104 }
105 }
106
107 if ((GNUNET_MESSENGER_KIND_JOIN == message->header.kind) &&
108 (flags & GNUNET_MESSENGER_FLAG_SENT))
109 {
110 const char *name = GNUNET_MESSENGER_get_name (messenger);
111
112 if (! name)
113 return;
114
115 struct GNUNET_MESSENGER_Message response;
116 response.header.kind = GNUNET_MESSENGER_KIND_NAME;
117 response.body.name.name = GNUNET_strdup (name);
118
119 GNUNET_MESSENGER_send_message (room, &response, NULL);
120
121 GNUNET_free (response.body.name.name);
122 }
123}
124
125
126struct GNUNET_SCHEDULER_Task *read_task;
127struct GNUNET_IDENTITY_EgoLookup *ego_lookup;
128
129/**
130 * Task to shut down this application.
131 *
132 * @param[in,out] cls Closure
133 */
134static void
135shutdown_hook (void *cls)
136{
137 struct GNUNET_MESSENGER_Room *room = cls;
138
139 if (read_task)
140 GNUNET_SCHEDULER_cancel (read_task);
141
142 if (room)
143 GNUNET_MESSENGER_close_room (room);
144
145 if (messenger)
146 GNUNET_MESSENGER_disconnect (messenger);
147
148 if (ego_lookup)
149 GNUNET_IDENTITY_ego_lookup_cancel (ego_lookup);
150}
151
152
153static void
154listen_stdio (void *cls);
155
156#define MAX_BUFFER_SIZE 60000
157
158static int
159iterate_send_private_message (void *cls,
160 struct GNUNET_MESSENGER_Room *room,
161 const struct GNUNET_MESSENGER_Contact *contact)
162{
163 struct GNUNET_MESSENGER_Message *message = cls;
164
165 if (GNUNET_MESSENGER_contact_get_key (contact))
166 GNUNET_MESSENGER_send_message (room, message, contact);
167
168 return GNUNET_YES;
169}
170
171
172int private_mode;
173
174/**
175 * Task run in stdio mode, after some data is available at stdin.
176 *
177 * @param[in,out] cls Closure
178 */
179static void
180read_stdio (void *cls)
181{
182 read_task = NULL;
183
184 char buffer[MAX_BUFFER_SIZE];
185 ssize_t length;
186
187 length = read (0, buffer, MAX_BUFFER_SIZE);
188
189 if ((length <= 0) || (length >= MAX_BUFFER_SIZE))
190 {
191 GNUNET_SCHEDULER_shutdown ();
192 return;
193 }
194
195 if (buffer[length - 1] == '\n')
196 buffer[length - 1] = '\0';
197 else
198 buffer[length] = '\0';
199
200 struct GNUNET_MESSENGER_Room *room = cls;
201
202 struct GNUNET_MESSENGER_Message message;
203 message.header.kind = GNUNET_MESSENGER_KIND_TEXT;
204 message.body.text.text = buffer;
205
206 if (GNUNET_YES == private_mode)
207 GNUNET_MESSENGER_iterate_members (room, iterate_send_private_message,
208 &message);
209 else
210 GNUNET_MESSENGER_send_message (room, &message, NULL);
211
212 read_task = GNUNET_SCHEDULER_add_now (listen_stdio, cls);
213}
214
215
216/**
217 * Wait for input on STDIO and send it out over the #ch.
218 *
219 * @param[in,out] cls Closure
220 */
221static void
222listen_stdio (void *cls)
223{
224 read_task = NULL;
225
226 struct GNUNET_NETWORK_FDSet *rs = GNUNET_NETWORK_fdset_create ();
227
228 GNUNET_NETWORK_fdset_set_native (rs, 0);
229
230 read_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
231 GNUNET_TIME_UNIT_FOREVER_REL, rs,
232 NULL, &read_stdio, cls);
233
234 GNUNET_NETWORK_fdset_destroy (rs);
235}
236
237
238/**
239 * Initial task to startup application.
240 *
241 * @param[in,out] cls Closure
242 */
243static void
244idle (void *cls)
245{
246 struct GNUNET_MESSENGER_Room *room = cls;
247
248 printf ("* You joined the room.\n");
249
250 read_task = GNUNET_SCHEDULER_add_now (listen_stdio, room);
251}
252
253
254char *door_id;
255char *ego_name;
256char *room_key;
257
258struct GNUNET_SCHEDULER_Task *shutdown_task;
259
260/**
261 * Function called when an identity is retrieved.
262 *
263 * @param[in,out] cls Closure
264 * @param[in,out] handle Handle of messenger service
265 */
266static void
267on_identity (void *cls,
268 struct GNUNET_MESSENGER_Handle *handle)
269{
270 struct GNUNET_HashCode key;
271 memset (&key, 0, sizeof(key));
272
273 if (room_key)
274 GNUNET_CRYPTO_hash (room_key, strlen (room_key), &key);
275
276 struct GNUNET_PeerIdentity door_peer;
277 struct GNUNET_PeerIdentity *door = NULL;
278
279 if ((door_id) &&
280 (GNUNET_OK == GNUNET_CRYPTO_eddsa_public_key_from_string (door_id,
281 strlen (
282 door_id),
283 &(door_peer.
284 public_key))))
285 door = &door_peer;
286
287 const char *name = GNUNET_MESSENGER_get_name (handle);
288
289 if (! name)
290 name = "anonymous";
291
292 printf ("* Welcome to the messenger, '%s'!\n", name);
293
294 struct GNUNET_MESSENGER_Room *room;
295
296 if (door)
297 {
298 printf ("* You try to entry a room...\n");
299
300 room = GNUNET_MESSENGER_enter_room (messenger, door, &key);
301 }
302 else
303 {
304 printf ("* You try to open a room...\n");
305
306 room = GNUNET_MESSENGER_open_room (messenger, &key);
307 }
308
309 GNUNET_SCHEDULER_cancel (shutdown_task);
310
311 shutdown_task = GNUNET_SCHEDULER_add_shutdown (shutdown_hook, room);
312
313 if (! room)
314 GNUNET_SCHEDULER_shutdown ();
315 else
316 {
317 GNUNET_SCHEDULER_add_delayed_with_priority (
318 GNUNET_TIME_relative_get_zero_ (),
319 GNUNET_SCHEDULER_PRIORITY_IDLE,
320 idle, room);
321 }
322}
323
324
325static void
326on_ego_lookup (void *cls,
327 struct GNUNET_IDENTITY_Ego *ego)
328{
329 ego_lookup = NULL;
330
331 const struct GNUNET_IDENTITY_PrivateKey *key;
332 key = ego ? GNUNET_IDENTITY_ego_get_private_key (ego) : NULL;
333
334 messenger = GNUNET_MESSENGER_connect (config, ego_name, key, &on_message,
335 NULL);
336
337 on_identity (NULL, messenger);
338}
339
340
341/**
342 * Main function that will be run by the scheduler.
343 *
344 * @param[in/out] cls closure
345 * @param[in] args remaining command-line arguments
346 * @param[in] cfgfile name of the configuration file used (for saving, can be NULL!)
347 * @param[in] cfg configuration
348 */
349static void
350run (void *cls,
351 char *const *args,
352 const char *cfgfile,
353 const struct GNUNET_CONFIGURATION_Handle *cfg)
354{
355 config = cfg;
356
357 if (ego_name)
358 {
359 ego_lookup = GNUNET_IDENTITY_ego_lookup (cfg, ego_name, &on_ego_lookup,
360 NULL);
361 messenger = NULL;
362 }
363 else
364 {
365 ego_lookup = NULL;
366 messenger = GNUNET_MESSENGER_connect (cfg, NULL, NULL, &on_message, NULL);
367 }
368
369 shutdown_task = GNUNET_SCHEDULER_add_shutdown (shutdown_hook, NULL);
370
371 if (messenger)
372 on_identity (NULL, messenger);
373}
374
375
376/**
377 * The main function to obtain messenger information.
378 *
379 * @param[in] argc number of arguments from the command line
380 * @param[in] argv command line arguments
381 * @return #EXIT_SUCCESS ok, #EXIT_FAILURE on error
382 */
383int
384main (int argc,
385 char **argv)
386{
387 const char *description =
388 "Open and connect to rooms using the MESSENGER to chat.";
389
390 struct GNUNET_GETOPT_CommandLineOption options[] = {
391 GNUNET_GETOPT_option_string ('d', "door", "PEERIDENTITY",
392 "peer identity to entry into the room",
393 &door_id),
394 GNUNET_GETOPT_option_string ('e', "ego", "IDENTITY",
395 "identity to use for messaging",
396 &ego_name),
397 GNUNET_GETOPT_option_string ('r', "room", "ROOMKEY",
398 "key of the room to connect to",
399 &room_key),
400 GNUNET_GETOPT_option_flag ('p', "private", "flag to enable private mode",
401 &private_mode),
402 GNUNET_GETOPT_OPTION_END
403 };
404
405 return (GNUNET_OK == GNUNET_PROGRAM_run (argc, argv, "gnunet-messenger\0",
406 gettext_noop (description), options,
407 &run,
408 NULL) ? EXIT_SUCCESS : EXIT_FAILURE);
409}