aboutsummaryrefslogtreecommitdiff
path: root/src/messenger/gnunet-service-messenger_handle.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/messenger/gnunet-service-messenger_handle.c')
-rw-r--r--src/messenger/gnunet-service-messenger_handle.c711
1 files changed, 0 insertions, 711 deletions
diff --git a/src/messenger/gnunet-service-messenger_handle.c b/src/messenger/gnunet-service-messenger_handle.c
deleted file mode 100644
index a4fa81623..000000000
--- a/src/messenger/gnunet-service-messenger_handle.c
+++ /dev/null
@@ -1,711 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2020--2022 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-service-messenger_handle.c
23 * @brief GNUnet MESSENGER service
24 */
25
26#include "gnunet-service-messenger_handle.h"
27
28#include "gnunet-service-messenger.h"
29#include "gnunet-service-messenger_message_kind.h"
30
31#include "messenger_api_util.h"
32
33struct GNUNET_MESSENGER_SrvHandle*
34create_srv_handle (struct GNUNET_MESSENGER_Service *service,
35 struct GNUNET_MQ_Handle *mq)
36{
37 GNUNET_assert((service) && (mq));
38
39 struct GNUNET_MESSENGER_SrvHandle *handle = GNUNET_new(struct GNUNET_MESSENGER_SrvHandle);
40
41 handle->service = service;
42 handle->mq = mq;
43
44 handle->name = NULL;
45 handle->ego = NULL;
46
47 handle->member_ids = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO);
48
49 return handle;
50}
51
52int
53iterate_free_member_ids (void *cls,
54 const struct GNUNET_HashCode *key,
55 void *value)
56{
57 GNUNET_free(value);
58
59 return GNUNET_YES;
60}
61
62void
63destroy_srv_handle (struct GNUNET_MESSENGER_SrvHandle *handle)
64{
65 GNUNET_assert(handle);
66
67 if (handle->service->dir)
68 save_srv_handle_configuration (handle);
69
70 if (handle->name)
71 {
72 struct GNUNET_MESSENGER_EgoStore *store = get_service_ego_store(handle->service);
73
74 unbind_store_ego(store, handle->name, handle);
75
76 GNUNET_free(handle->name);
77 }
78
79 GNUNET_CONTAINER_multihashmap_iterate (handle->member_ids, iterate_free_member_ids, NULL);
80 GNUNET_CONTAINER_multihashmap_destroy (handle->member_ids);
81
82 GNUNET_free(handle);
83}
84
85void
86get_srv_handle_data_subdir (const struct GNUNET_MESSENGER_SrvHandle *handle,
87 const char *name,
88 char **dir)
89{
90 GNUNET_assert((handle) && (dir));
91
92 if (name)
93 GNUNET_asprintf (dir, "%s%s%c%s%c", handle->service->dir, "identities",
94 DIR_SEPARATOR, name, DIR_SEPARATOR);
95 else
96 GNUNET_asprintf (dir, "%s%s%c", handle->service->dir, "anonymous",
97 DIR_SEPARATOR);
98}
99
100static int
101create_handle_member_id (const struct GNUNET_MESSENGER_SrvHandle *handle,
102 const struct GNUNET_HashCode *key)
103{
104 GNUNET_assert((handle) && (key));
105
106 struct GNUNET_ShortHashCode *random_id = GNUNET_new(struct GNUNET_ShortHashCode);
107
108 if (!random_id)
109 return GNUNET_NO;
110
111 generate_free_member_id (random_id, NULL);
112
113 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (handle->member_ids, key, random_id,
114 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
115 {
116 GNUNET_free(random_id);
117 return GNUNET_NO;
118 }
119
120 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Created a new member id (%s) for room: %s\n", GNUNET_sh2s (random_id),
121 GNUNET_h2s (key));
122
123 return GNUNET_YES;
124}
125
126const struct GNUNET_ShortHashCode*
127get_srv_handle_member_id (const struct GNUNET_MESSENGER_SrvHandle *handle,
128 const struct GNUNET_HashCode *key)
129{
130 GNUNET_assert((handle) && (key));
131
132 return GNUNET_CONTAINER_multihashmap_get (handle->member_ids, key);
133}
134
135int
136change_srv_handle_member_id (struct GNUNET_MESSENGER_SrvHandle *handle,
137 const struct GNUNET_HashCode *key,
138 const struct GNUNET_ShortHashCode *unique_id)
139{
140 GNUNET_assert((handle) && (key) && (unique_id));
141
142 struct GNUNET_ShortHashCode *member_id = GNUNET_CONTAINER_multihashmap_get (handle->member_ids, key);
143
144 if (!member_id)
145 {
146 member_id = GNUNET_new(struct GNUNET_ShortHashCode);
147 GNUNET_memcpy(member_id, unique_id, sizeof(*member_id));
148
149 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (handle->member_ids, key, member_id,
150 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
151 {
152 GNUNET_free(member_id);
153 return GNUNET_SYSERR;
154 }
155 }
156
157 if (0 == GNUNET_memcmp(unique_id, member_id))
158 goto send_message_to_client;
159
160 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Change a member id (%s) for room (%s).\n", GNUNET_sh2s (member_id),
161 GNUNET_h2s (key));
162
163 GNUNET_memcpy(member_id, unique_id, sizeof(*unique_id));
164
165 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Member id changed to (%s).\n", GNUNET_sh2s (unique_id));
166
167 struct GNUNET_MESSENGER_MemberMessage *msg;
168 struct GNUNET_MQ_Envelope *env;
169
170send_message_to_client:
171
172 env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_MEMBER_ID);
173
174 GNUNET_memcpy(&(msg->key), key, sizeof(*key));
175 GNUNET_memcpy(&(msg->id), member_id, sizeof(*member_id));
176
177 GNUNET_MQ_send (handle->mq, env);
178 return GNUNET_OK;
179}
180
181static void
182change_handle_name (struct GNUNET_MESSENGER_SrvHandle *handle,
183 const char *name)
184{
185 GNUNET_assert(handle);
186
187 if (handle->name)
188 GNUNET_free(handle->name);
189
190 handle->name = name ? GNUNET_strdup(name) : NULL;
191
192 const uint16_t name_len = handle->name ? strlen (handle->name) : 0;
193
194 struct GNUNET_MESSENGER_NameMessage *msg;
195 struct GNUNET_MQ_Envelope *env;
196
197 env = GNUNET_MQ_msg_extra(msg, name_len + 1, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_GET_NAME);
198
199 char *extra = ((char*) msg) + sizeof(*msg);
200
201 if (name_len)
202 GNUNET_memcpy(extra, handle->name, name_len);
203
204 extra[name_len] = '\0';
205
206 GNUNET_MQ_send (handle->mq, env);
207}
208
209static void
210change_handle_ego (struct GNUNET_MESSENGER_SrvHandle *handle,
211 const struct GNUNET_MESSENGER_Ego *ego)
212{
213 GNUNET_assert(handle);
214
215 handle->ego = ego;
216
217 ego = get_srv_handle_ego (handle);
218
219 const uint16_t length = GNUNET_IDENTITY_key_get_length(&(ego->pub));
220
221 struct GNUNET_MESSENGER_KeyMessage *msg;
222 struct GNUNET_MQ_Envelope *env;
223
224 env = GNUNET_MQ_msg_extra(msg, length, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_GET_KEY);
225
226 char *extra = ((char*) msg) + sizeof(*msg);
227
228 if (GNUNET_IDENTITY_write_key_to_buffer(&(ego->pub), extra, length) < 0)
229 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Could not write key to buffer.\n");
230
231 GNUNET_MQ_send (handle->mq, env);
232}
233
234struct GNUNET_MESSENGER_MessageHandle
235{
236 struct GNUNET_MESSENGER_SrvHandle *handle;
237 struct GNUNET_MESSENGER_Message *message;
238};
239
240static int
241iterate_send_message (void *cls,
242 const struct GNUNET_HashCode *key,
243 void *value)
244{
245 struct GNUNET_MESSENGER_MessageHandle *msg_handle = cls;
246
247 send_srv_handle_message (msg_handle->handle, key, msg_handle->message);
248
249 return GNUNET_YES;
250}
251
252void
253set_srv_handle_ego (struct GNUNET_MESSENGER_SrvHandle *handle,
254 const struct GNUNET_MESSENGER_Ego *ego)
255{
256 GNUNET_assert((handle) && (ego));
257
258 struct GNUNET_MESSENGER_MessageHandle msg_handle;
259
260 msg_handle.handle = handle;
261 msg_handle.message = create_message_key (&(ego->priv));
262
263 GNUNET_CONTAINER_multihashmap_iterate (handle->member_ids, iterate_send_message, &msg_handle);
264
265 destroy_message (msg_handle.message);
266
267 change_handle_ego (handle, ego);
268}
269
270const struct GNUNET_MESSENGER_Ego*
271get_srv_handle_ego (const struct GNUNET_MESSENGER_SrvHandle *handle)
272{
273 GNUNET_assert(handle);
274
275 static struct GNUNET_MESSENGER_Ego anonymous;
276 static int read_keys = 0;
277
278 if (handle->ego)
279 return handle->ego;
280
281 if (!read_keys)
282 {
283 struct GNUNET_IDENTITY_Ego *ego = GNUNET_IDENTITY_ego_get_anonymous ();
284 GNUNET_memcpy(&(anonymous.priv), GNUNET_IDENTITY_ego_get_private_key (ego), sizeof(anonymous.priv));
285 GNUNET_IDENTITY_ego_get_public_key (ego, &(anonymous.pub));
286 read_keys = 1;
287 }
288
289 return &anonymous;
290}
291
292static void
293callback_setup_handle_name (void *cls,
294 const char *name,
295 const struct GNUNET_MESSENGER_Ego *ego)
296{
297 struct GNUNET_MESSENGER_SrvHandle *handle = cls;
298
299 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Setting up handle...\n");
300
301 change_handle_name (handle, name);
302 change_handle_ego (handle, ego);
303
304 if (handle->service->dir)
305 load_srv_handle_configuration (handle);
306}
307
308void
309setup_srv_handle_name (struct GNUNET_MESSENGER_SrvHandle *handle,
310 const char *name)
311{
312 GNUNET_assert(handle);
313
314 struct GNUNET_MESSENGER_EgoStore *store = get_service_ego_store(handle->service);
315
316 lookup_store_ego (store, name, callback_setup_handle_name, handle);
317}
318
319static void
320callback_update_handle (void *cls,
321 const char *name,
322 const struct GNUNET_MESSENGER_Ego *ego)
323{
324 struct GNUNET_MESSENGER_SrvHandle *handle = cls;
325
326 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating handle...\n");
327
328 struct GNUNET_MESSENGER_EgoStore *store = get_service_ego_store(handle->service);
329
330 bind_store_ego(store, handle->name, handle);
331
332 if (!ego)
333 create_store_ego (store, handle->name);
334 else
335 renew_store_ego (store, handle->name);
336}
337
338void
339update_srv_handle (struct GNUNET_MESSENGER_SrvHandle *handle)
340{
341 GNUNET_assert (handle);
342
343 if (!handle->name)
344 {
345 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Updating handle failed: Name is required!\n");
346 return;
347 }
348
349 struct GNUNET_MESSENGER_EgoStore *store = get_service_ego_store(handle->service);
350
351 lookup_store_ego (store, handle->name, callback_update_handle, handle);
352}
353
354static void
355callback_set_handle_name (void *cls,
356 const char *name,
357 const struct GNUNET_MESSENGER_Ego *ego)
358{
359 struct GNUNET_MESSENGER_SrvHandle *handle = cls;
360
361 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Renaming handle...\n");
362
363 if (ego)
364 {
365 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Renaming handle failed: Name is occupied! (%s)\n", name);
366 return;
367 }
368
369 struct GNUNET_MESSENGER_EgoStore *store = get_service_ego_store(handle->service);
370
371 char *old_dir;
372 get_srv_handle_data_subdir (handle, handle->name, &old_dir);
373
374 char *new_dir;
375 get_srv_handle_data_subdir (handle, name, &new_dir);
376
377 if ((GNUNET_YES == GNUNET_DISK_directory_test (new_dir, GNUNET_NO)) &&
378 (GNUNET_OK != GNUNET_DISK_directory_remove(new_dir)))
379 goto free_dirs;
380
381 if (GNUNET_YES == GNUNET_DISK_directory_test (old_dir, GNUNET_YES))
382 {
383 GNUNET_DISK_directory_create_for_file (new_dir);
384
385 if (0 != rename (old_dir, new_dir))
386 goto free_dirs;
387 }
388
389 if (handle->ego)
390 rename_store_ego(store, handle->name, name);
391
392 struct GNUNET_MESSENGER_MessageHandle msg_handle;
393 msg_handle.handle = handle;
394 msg_handle.message = create_message_name (name);
395
396 GNUNET_CONTAINER_multihashmap_iterate (handle->member_ids, iterate_send_message, &msg_handle);
397 destroy_message (msg_handle.message);
398 change_handle_name (handle, name);
399
400free_dirs:
401 GNUNET_free(old_dir);
402 GNUNET_free(new_dir);
403}
404
405void
406set_srv_handle_name (struct GNUNET_MESSENGER_SrvHandle *handle,
407 const char *name)
408{
409 GNUNET_assert(handle);
410
411 if (!name)
412 {
413 if (handle->ego)
414 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Renaming handle failed: Name is required!\n");
415 else
416 change_handle_name (handle, name);
417
418 return;
419 }
420
421 struct GNUNET_MESSENGER_EgoStore *store = get_service_ego_store(handle->service);
422
423 lookup_store_ego (store, name, callback_set_handle_name, handle);
424}
425
426int
427open_srv_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle,
428 const struct GNUNET_HashCode *key)
429{
430 GNUNET_assert((handle) && (key));
431
432 if ((!get_srv_handle_member_id (handle, key)) && (GNUNET_YES != create_handle_member_id (handle, key)))
433 return GNUNET_NO;
434
435 return open_service_room (handle->service, handle, key);
436}
437
438int
439entry_srv_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle,
440 const struct GNUNET_PeerIdentity *door,
441 const struct GNUNET_HashCode *key)
442{
443 GNUNET_assert((handle) && (door) && (key));
444
445 if ((!get_srv_handle_member_id (handle, key)) && (GNUNET_YES != create_handle_member_id (handle, key)))
446 return GNUNET_NO;
447
448 return entry_service_room (handle->service, handle, door, key);
449}
450
451int
452close_srv_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle,
453 const struct GNUNET_HashCode *key)
454{
455 GNUNET_assert((handle) && (key));
456
457 if (!get_srv_handle_member_id (handle, key))
458 return GNUNET_NO;
459
460 return close_service_room (handle->service, handle, key);
461}
462
463int
464send_srv_handle_message (struct GNUNET_MESSENGER_SrvHandle *handle,
465 const struct GNUNET_HashCode *key,
466 const struct GNUNET_MESSENGER_Message *message)
467{
468 GNUNET_assert((handle) && (key) && (message));
469
470 const struct GNUNET_ShortHashCode *id = get_srv_handle_member_id (handle, key);
471
472 if (!id)
473 {
474 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "It is required to be a member of a room to send messages!\n");
475 return GNUNET_NO;
476 }
477
478 struct GNUNET_MESSENGER_SrvRoom *room = get_service_room (handle->service, key);
479
480 if (!room)
481 {
482 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "The room (%s) is unknown!\n", GNUNET_h2s (key));
483 return GNUNET_NO;
484 }
485
486 struct GNUNET_MESSENGER_Message *msg = copy_message(message);
487
488 GNUNET_memcpy(&(msg->header.sender_id), id, sizeof(*id));
489
490 return send_srv_room_message (room, handle, msg);
491}
492
493static const struct GNUNET_HashCode*
494get_next_member_session_contect(const struct GNUNET_MESSENGER_MemberSession *session)
495{
496 if (session->next)
497 return get_next_member_session_contect (session->next);
498 else
499 return get_member_session_context(session);
500}
501
502static const struct GNUNET_MESSENGER_MemberSession*
503get_handle_member_session (struct GNUNET_MESSENGER_SrvHandle *handle,
504 struct GNUNET_MESSENGER_SrvRoom *room,
505 const struct GNUNET_HashCode *key)
506{
507 GNUNET_assert((handle) && (room) && (key) && (handle->service));
508
509 const struct GNUNET_ShortHashCode *id = get_srv_handle_member_id(handle, key);
510
511 if (!id)
512 return NULL;
513
514 struct GNUNET_MESSENGER_MemberStore *store = get_srv_room_member_store(room);
515 struct GNUNET_MESSENGER_Member *member = get_store_member(store, id);
516
517 const struct GNUNET_MESSENGER_Ego *ego = get_srv_handle_ego(handle);
518
519 if (!ego)
520 return NULL;
521
522 return get_member_session(member, &(ego->pub));
523}
524
525void
526notify_srv_handle_message (struct GNUNET_MESSENGER_SrvHandle *handle,
527 struct GNUNET_MESSENGER_SrvRoom *room,
528 const struct GNUNET_MESSENGER_MemberSession *session,
529 const struct GNUNET_MESSENGER_Message *message,
530 const struct GNUNET_HashCode *hash)
531{
532 GNUNET_assert((handle) && (room) && (session) && (message) && (hash));
533
534 const struct GNUNET_HashCode *key = get_srv_room_key(room);
535
536 if ((!handle->mq) || (!get_srv_handle_member_id (handle, key)))
537 {
538 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Notifying client about message requires membership!\n");
539 return;
540 }
541
542 const struct GNUNET_IDENTITY_PublicKey *pubkey = get_contact_key(session->contact);
543
544 struct GNUNET_HashCode sender;
545 GNUNET_CRYPTO_hash(pubkey, sizeof(*pubkey), &sender);
546
547 const struct GNUNET_HashCode *context = get_next_member_session_contect (session);
548
549 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Notifying client about message: %s\n", GNUNET_h2s (hash));
550
551 struct GNUNET_MESSENGER_Message *private_message = NULL;
552
553 if (GNUNET_MESSENGER_KIND_PRIVATE == message->header.kind)
554 {
555 private_message = copy_message(message);
556
557 if (GNUNET_YES != decrypt_message(private_message, &(get_srv_handle_ego(handle)->priv)))
558 {
559 destroy_message(private_message);
560 private_message = NULL;
561 }
562 else
563 message = private_message;
564 }
565
566 struct GNUNET_MESSENGER_RecvMessage *msg;
567 struct GNUNET_MQ_Envelope *env;
568
569 uint16_t length = get_message_size (message, GNUNET_YES);
570
571 env = GNUNET_MQ_msg_extra(msg, length, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_RECV_MESSAGE);
572
573 GNUNET_memcpy(&(msg->key), key, sizeof(msg->key));
574 GNUNET_memcpy(&(msg->sender), &sender, sizeof(msg->sender));
575 GNUNET_memcpy(&(msg->context), context, sizeof(msg->context));
576 GNUNET_memcpy(&(msg->hash), hash, sizeof(msg->hash));
577
578 msg->flags = (uint32_t) GNUNET_MESSENGER_FLAG_NONE;
579
580 if (get_handle_member_session(handle, room, key) == session)
581 msg->flags |= (uint32_t) GNUNET_MESSENGER_FLAG_SENT;
582
583 if (private_message)
584 msg->flags |= (uint32_t) GNUNET_MESSENGER_FLAG_PRIVATE;
585
586 char *buffer = ((char*) msg) + sizeof(*msg);
587 encode_message (message, length, buffer, GNUNET_YES);
588
589 if (private_message)
590 destroy_message(private_message);
591
592 GNUNET_MQ_send (handle->mq, env);
593}
594
595static int
596callback_scan_for_rooms (void *cls,
597 const char *filename)
598{
599 struct GNUNET_MESSENGER_SrvHandle *handle = cls;
600
601 if ((strlen(filename) <= 4) || (0 != strcmp(filename + strlen(filename) - 4, ".cfg")))
602 return GNUNET_OK;
603
604 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Load room configuration of handle: %s\n", filename);
605
606 struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_CONFIGURATION_create ();
607
608 if ((GNUNET_YES == GNUNET_DISK_file_test (filename)) && (GNUNET_OK == GNUNET_CONFIGURATION_parse (cfg, filename)))
609 {
610 struct GNUNET_HashCode key;
611 struct GNUNET_ShortHashCode member_id;
612
613 if ((GNUNET_OK == GNUNET_CONFIGURATION_get_data (cfg, "room", "key", &key, sizeof(key))) &&
614 (GNUNET_OK == GNUNET_CONFIGURATION_get_data (cfg, "room", "member_id", &member_id, sizeof(member_id))))
615 change_srv_handle_member_id (handle, &key, &member_id);
616 }
617
618 GNUNET_CONFIGURATION_destroy (cfg);
619 return GNUNET_OK;
620}
621
622void
623load_srv_handle_configuration (struct GNUNET_MESSENGER_SrvHandle *handle)
624{
625 GNUNET_assert(handle);
626
627 char *id_dir;
628 get_srv_handle_data_subdir (handle, handle->name, &id_dir);
629
630 if (GNUNET_YES == GNUNET_DISK_directory_test (id_dir, GNUNET_YES))
631 {
632 char *scan_dir;
633 GNUNET_asprintf (&scan_dir, "%s%s%c", id_dir, "rooms", DIR_SEPARATOR);
634
635 if (GNUNET_OK == GNUNET_DISK_directory_test (scan_dir, GNUNET_YES))
636 GNUNET_DISK_directory_scan (scan_dir, callback_scan_for_rooms, handle);
637
638 GNUNET_free(scan_dir);
639 }
640
641 GNUNET_free(id_dir);
642}
643
644static int
645iterate_save_rooms (void *cls,
646 const struct GNUNET_HashCode *key,
647 void *value)
648{
649 struct GNUNET_MESSENGER_SrvHandle *handle = cls;
650 struct GNUNET_ShortHashCode *member_id = value;
651
652 char *id_dir;
653 get_srv_handle_data_subdir (handle, handle->name, &id_dir);
654
655 char *filename;
656 GNUNET_asprintf (&filename, "%s%s%c%s.cfg", id_dir, "rooms", DIR_SEPARATOR, GNUNET_h2s (key));
657 GNUNET_free(id_dir);
658
659 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Save room configuration of handle: %s\n", filename);
660
661 struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_CONFIGURATION_create ();
662
663 char *key_data = GNUNET_STRINGS_data_to_string_alloc (key, sizeof(*key));
664
665 if (key_data)
666 {
667 GNUNET_CONFIGURATION_set_value_string (cfg, "room", "key", key_data);
668
669 GNUNET_free(key_data);
670 }
671
672 char *member_id_data = GNUNET_STRINGS_data_to_string_alloc (member_id, sizeof(*member_id));
673
674 if (member_id_data)
675 {
676 GNUNET_CONFIGURATION_set_value_string (cfg, "room", "member_id", member_id_data);
677
678 GNUNET_free(member_id_data);
679 }
680
681 GNUNET_CONFIGURATION_write (cfg, filename);
682 GNUNET_CONFIGURATION_destroy (cfg);
683
684 GNUNET_free(filename);
685
686 return GNUNET_YES;
687}
688
689void
690save_srv_handle_configuration (struct GNUNET_MESSENGER_SrvHandle *handle)
691{
692 GNUNET_assert(handle);
693
694 char *id_dir;
695 get_srv_handle_data_subdir (handle, handle->name, &id_dir);
696
697 if ((GNUNET_YES == GNUNET_DISK_directory_test (id_dir, GNUNET_NO)) || (GNUNET_OK
698 == GNUNET_DISK_directory_create (id_dir)))
699 {
700 char *save_dir;
701 GNUNET_asprintf (&save_dir, "%s%s%c", id_dir, "rooms", DIR_SEPARATOR);
702
703 if ((GNUNET_YES == GNUNET_DISK_directory_test (save_dir, GNUNET_NO)) ||
704 (GNUNET_OK == GNUNET_DISK_directory_create (save_dir)))
705 GNUNET_CONTAINER_multihashmap_iterate (handle->member_ids, iterate_save_rooms, handle);
706
707 GNUNET_free(save_dir);
708 }
709
710 GNUNET_free(id_dir);
711}