diff options
Diffstat (limited to 'src/messenger/gnunet-messenger.c')
-rw-r--r-- | src/messenger/gnunet-messenger.c | 409 |
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 | |||
32 | const struct GNUNET_CONFIGURATION_Handle *config; | ||
33 | struct 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 | */ | ||
45 | void | ||
46 | on_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 | |||
126 | struct GNUNET_SCHEDULER_Task *read_task; | ||
127 | struct GNUNET_IDENTITY_EgoLookup *ego_lookup; | ||
128 | |||
129 | /** | ||
130 | * Task to shut down this application. | ||
131 | * | ||
132 | * @param[in,out] cls Closure | ||
133 | */ | ||
134 | static void | ||
135 | shutdown_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 | |||
153 | static void | ||
154 | listen_stdio (void *cls); | ||
155 | |||
156 | #define MAX_BUFFER_SIZE 60000 | ||
157 | |||
158 | static int | ||
159 | iterate_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 | |||
172 | int 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 | */ | ||
179 | static void | ||
180 | read_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 | */ | ||
221 | static void | ||
222 | listen_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 | */ | ||
243 | static void | ||
244 | idle (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 | |||
254 | char *door_id; | ||
255 | char *ego_name; | ||
256 | char *room_key; | ||
257 | |||
258 | struct 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 | */ | ||
266 | static void | ||
267 | on_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 | |||
325 | static void | ||
326 | on_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 | */ | ||
349 | static void | ||
350 | run (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 | */ | ||
383 | int | ||
384 | main (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 | } | ||