diff options
Diffstat (limited to 'src/gnunet_chat_handle.c')
-rw-r--r-- | src/gnunet_chat_handle.c | 653 |
1 files changed, 42 insertions, 611 deletions
diff --git a/src/gnunet_chat_handle.c b/src/gnunet_chat_handle.c index 84539c5..11b57ac 100644 --- a/src/gnunet_chat_handle.c +++ b/src/gnunet_chat_handle.c | |||
@@ -22,642 +22,73 @@ | |||
22 | * @file gnunet_chat_handle.c | 22 | * @file gnunet_chat_handle.c |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "gnunet_chat_lib.h" | ||
26 | #include "gnunet_chat_handle.h" | 25 | #include "gnunet_chat_handle.h" |
27 | #include "gnunet_chat_group.h" | ||
28 | #include "gnunet_chat_contact.h" | ||
29 | #include "gnunet_chat_message.h" | ||
30 | #include "gnunet_chat_file.h" | ||
31 | 26 | ||
32 | static void* | 27 | #include "gnunet_chat_handle_intern.c" |
33 | handle_fs_progress(void* cls, const struct GNUNET_FS_ProgressInfo* info) | ||
34 | { | ||
35 | struct GNUNET_CHAT_Handle *chat = cls; | ||
36 | |||
37 | if (!chat) | ||
38 | return NULL; | ||
39 | |||
40 | switch (info->status) { | ||
41 | case GNUNET_FS_STATUS_PUBLISH_START: { | ||
42 | /*publication_t* publication = (publication_t*) info->value.publish.cctx; | ||
43 | publication->progress = 0.0f; | ||
44 | |||
45 | GNUNET_SCHEDULER_add_now(&CGTK_publication_progress, publication); | ||
46 | |||
47 | return publication;*/ | ||
48 | } case GNUNET_FS_STATUS_PUBLISH_PROGRESS: { | ||
49 | /*publication_t* publication = (publication_t*) info->value.publish.cctx; | ||
50 | publication->progress = 1.0f * info->value.publish.completed / info->value.publish.size; | ||
51 | |||
52 | GNUNET_SCHEDULER_add_now(&CGTK_publication_progress, publication); | ||
53 | |||
54 | return publication;*/ | ||
55 | } case GNUNET_FS_STATUS_PUBLISH_COMPLETED: { | ||
56 | /*publication_t* publication = (publication_t*) info->value.publish.cctx; | ||
57 | publication->uri = GNUNET_FS_uri_dup(info->value.publish.specifics.completed.chk_uri); | ||
58 | publication->progress = 1.0f; | ||
59 | |||
60 | GNUNET_SCHEDULER_add_now(&CGTK_publication_finish, publication);*/ | ||
61 | break; | ||
62 | } case GNUNET_FS_STATUS_PUBLISH_ERROR: { | ||
63 | /*publication_t* publication = (publication_t*) info->value.publish.cctx; | ||
64 | |||
65 | GNUNET_SCHEDULER_add_now(&CGTK_publication_error, publication);*/ | ||
66 | break; | ||
67 | } case GNUNET_FS_STATUS_DOWNLOAD_START: { | ||
68 | /*request_t* request = (request_t*) info->value.download.cctx; | ||
69 | request->progress = 0.0f; | ||
70 | |||
71 | return request;*/ | ||
72 | } case GNUNET_FS_STATUS_DOWNLOAD_ACTIVE: { | ||
73 | return info->value.download.cctx; | ||
74 | } case GNUNET_FS_STATUS_DOWNLOAD_INACTIVE: { | ||
75 | return info->value.download.cctx; | ||
76 | } case GNUNET_FS_STATUS_DOWNLOAD_PROGRESS: { | ||
77 | /*request_t* request = (request_t*) info->value.download.cctx; | ||
78 | request->progress = 1.0f * info->value.download.completed / info->value.download.size; | ||
79 | |||
80 | GNUNET_SCHEDULER_add_now(&CGTK_request_progress, request); | ||
81 | |||
82 | return request;*/ | ||
83 | } case GNUNET_FS_STATUS_DOWNLOAD_COMPLETED: { | ||
84 | /*request_t* request = (request_t*) info->value.download.cctx; | ||
85 | request->progress = 1.0f; | ||
86 | |||
87 | GNUNET_SCHEDULER_add_now(&CGTK_request_finish, request);*/ | ||
88 | break; | ||
89 | } case GNUNET_FS_STATUS_DOWNLOAD_ERROR: { | ||
90 | /*request_t *request = (request_t *) info->value.download.cctx; | ||
91 | |||
92 | GNUNET_SCHEDULER_add_now(&CGTK_request_error, request);*/ | ||
93 | break; | ||
94 | } case GNUNET_FS_STATUS_UNINDEX_START: { | ||
95 | /*publication_t* publication = (publication_t*) info->value.unindex.cctx; | ||
96 | publication->progress = 0.0f; | ||
97 | |||
98 | return publication;*/ | ||
99 | } case GNUNET_FS_STATUS_UNINDEX_PROGRESS: { | ||
100 | /*publication_t* publication = (publication_t*) info->value.unindex.cctx; | ||
101 | publication->progress = 1.0f * info->value.unindex.completed / info->value.unindex.size; | ||
102 | |||
103 | return publication;*/ | ||
104 | } case GNUNET_FS_STATUS_UNINDEX_COMPLETED: { | ||
105 | /*publication_t* publication = (publication_t*) info->value.unindex.cctx; | ||
106 | publication->progress = 1.0f; | ||
107 | |||
108 | GNUNET_SCHEDULER_add_now(&CGTK_publication_unindex_finish, publication);*/ | ||
109 | break; | ||
110 | } default: { | ||
111 | break; | ||
112 | } | ||
113 | } | ||
114 | |||
115 | return NULL; | ||
116 | } | ||
117 | |||
118 | static void | ||
119 | handle_on_message (void *cls, | ||
120 | GNUNET_UNUSED struct GNUNET_MESSENGER_Room *room, | ||
121 | GNUNET_UNUSED const struct GNUNET_MESSENGER_Contact *sender, | ||
122 | const struct GNUNET_MESSENGER_Message *message, | ||
123 | const struct GNUNET_HashCode *hash, | ||
124 | GNUNET_UNUSED enum GNUNET_MESSENGER_MessageFlags flags) | ||
125 | { | ||
126 | struct GNUNET_CHAT_Handle *chat = cls; | ||
127 | |||
128 | //TODO | ||
129 | |||
130 | struct GNUNET_CHAT_Message msg; | ||
131 | GNUNET_memcpy(&(msg.hash), hash, sizeof(msg.hash)); | ||
132 | msg.message = message; | ||
133 | |||
134 | if ((GNUNET_CHAT_KIND_UNKNOWN == GNUNET_CHAT_message_get_kind(&msg)) || | ||
135 | (!chat->msg_cb)) | ||
136 | return; | ||
137 | |||
138 | chat->msg_cb(chat->msg_cls, NULL /* TODO */, &msg); | ||
139 | } | ||
140 | |||
141 | struct GNUNET_CHAT_CheckRoomMembers | ||
142 | { | ||
143 | const struct GNUNET_IDENTITY_PublicKey *ignore_key; | ||
144 | const struct GNUNET_MESSENGER_Contact *contact; | ||
145 | }; | ||
146 | |||
147 | static int | ||
148 | handle_check_room_members (void* cls, | ||
149 | GNUNET_UNUSED struct GNUNET_MESSENGER_Room *room, | ||
150 | const struct GNUNET_MESSENGER_Contact *contact) | ||
151 | { | ||
152 | struct GNUNET_CHAT_CheckRoomMembers *check = cls; | ||
153 | const struct GNUNET_IDENTITY_PublicKey *contact_key = ( | ||
154 | GNUNET_MESSENGER_contact_get_key(contact) | ||
155 | ); | ||
156 | |||
157 | if (0 == GNUNET_memcmp(contact_key, check->ignore_key)) | ||
158 | return GNUNET_YES; | ||
159 | |||
160 | if (check->contact) | ||
161 | return GNUNET_NO; | ||
162 | |||
163 | check->contact = contact; | ||
164 | return GNUNET_YES; | ||
165 | } | ||
166 | |||
167 | static int | ||
168 | handle_initialize_context (void *cls, struct GNUNET_MESSENGER_Room *room, | ||
169 | GNUNET_UNUSED const struct GNUNET_MESSENGER_Contact *contact) | ||
170 | { | ||
171 | struct GNUNET_CHAT_Handle *chat = cls; | ||
172 | |||
173 | struct GNUNET_CHAT_CheckRoomMembers check; | ||
174 | check.ignore_key = GNUNET_CHAT_get_key(chat); | ||
175 | check.contact = NULL; | ||
176 | |||
177 | const int amount = GNUNET_MESSENGER_iterate_members( | ||
178 | room, handle_check_room_members, &check | ||
179 | ); | ||
180 | |||
181 | if (amount <= 1) | ||
182 | return GNUNET_YES; | ||
183 | |||
184 | const struct GNUNET_HashCode *key = GNUNET_MESSENGER_room_get_key(room); | ||
185 | struct GNUNET_CHAT_Context *context = handle_get_chat_context(chat, key); | ||
186 | enum GNUNET_CHAT_ContextType type = GNUNET_CHAT_CONTEXT_TYPE_UNKNOWN; | ||
187 | |||
188 | if (check.contact) | ||
189 | type = GNUNET_CHAT_CONTEXT_TYPE_CONTACT; | ||
190 | else | ||
191 | type = GNUNET_CHAT_CONTEXT_TYPE_GROUP; | ||
192 | |||
193 | if (!context) | ||
194 | context = context_create(chat, type, key); | ||
195 | else | ||
196 | context->type = type; | ||
197 | |||
198 | if (GNUNET_YES != handle_update_chat_context(chat, context, GNUNET_NO)) | ||
199 | context_destroy(context); | ||
200 | |||
201 | return GNUNET_YES; | ||
202 | } | ||
203 | |||
204 | static void | ||
205 | handle_on_identity(void *cls, struct GNUNET_MESSENGER_Handle *handle) | ||
206 | { | ||
207 | struct GNUNET_CHAT_Handle *chat = cls; | ||
208 | |||
209 | //TODO | ||
210 | |||
211 | GNUNET_MESSENGER_find_rooms( | ||
212 | chat->handles.messenger, NULL, handle_initialize_context, handle | ||
213 | ); | ||
214 | } | ||
215 | |||
216 | static void | ||
217 | handle_arm_connection(void *cls, int connected) | ||
218 | { | ||
219 | struct GNUNET_CHAT_Handle *chat = cls; | ||
220 | |||
221 | if (GNUNET_YES == connected) { | ||
222 | GNUNET_ARM_request_service_start(chat->handles.arm, "messenger", | ||
223 | GNUNET_OS_INHERIT_STD_NONE, NULL, NULL); | ||
224 | GNUNET_ARM_request_service_start(chat->handles.arm, "fs", | ||
225 | GNUNET_OS_INHERIT_STD_NONE, NULL, NULL); | ||
226 | } else { | ||
227 | GNUNET_ARM_request_service_start(chat->handles.arm, "arm", | ||
228 | GNUNET_OS_INHERIT_STD_NONE, NULL, NULL); | ||
229 | } | ||
230 | } | ||
231 | 28 | ||
232 | struct GNUNET_CHAT_Handle* | 29 | struct GNUNET_CHAT_Handle* |
233 | GNUNET_CHAT_start (const struct GNUNET_CONFIGURATION_Handle* cfg, | 30 | handle_create_from_config (const struct GNUNET_CONFIGURATION_Handle* cfg, |
234 | const char *name, | 31 | const char* name, |
235 | GNUNET_CHAT_WarningCallback warn_cb, | 32 | GNUNET_CHAT_ContextMessageCallback msg_cb, |
236 | void *warn_cls, | 33 | void *msg_cls, |
237 | GNUNET_CHAT_ContextMessageCallback msg_cb, | 34 | GNUNET_CHAT_WarningCallback warn_cb, |
238 | void *msg_cls) | 35 | void *warn_cls) |
239 | { | 36 | { |
240 | if (!cfg) | 37 | struct GNUNET_CHAT_Handle* handle = GNUNET_new(struct GNUNET_CHAT_Handle); |
241 | return NULL; | ||
242 | 38 | ||
243 | struct GNUNET_CHAT_Handle *chat = GNUNET_new(struct GNUNET_CHAT_Handle); | 39 | handle->cfg = cfg; |
244 | memset(chat, 0, sizeof(*chat)); | ||
245 | chat->cfg = cfg; | ||
246 | 40 | ||
247 | chat->warn_cb = warn_cb; | 41 | handle->msg_cb = msg_cb; |
248 | chat->warn_cls = warn_cls; | 42 | handle->msg_cls = msg_cls; |
249 | 43 | ||
250 | chat->handles.arm = GNUNET_ARM_connect(cfg, &handle_arm_connection, chat); | 44 | handle->warn_cb = warn_cb; |
45 | handle->warn_cls = warn_cls; | ||
251 | 46 | ||
252 | if (chat->handles.arm) | 47 | handle->files = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); |
253 | handle_arm_connection(chat, GNUNET_NO); | 48 | handle->contexts = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); |
49 | handle->contacts = GNUNET_CONTAINER_multishortmap_create(8, GNUNET_NO); | ||
50 | handle->groups = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); | ||
254 | 51 | ||
255 | chat->handles.messenger = GNUNET_MESSENGER_connect( | 52 | handle->arm = GNUNET_ARM_connect( |
256 | cfg, name, | 53 | handle->cfg, |
257 | handle_on_identity, chat, | 54 | on_handle_arm_connection, handle |
258 | handle_on_message, chat | ||
259 | ); | 55 | ); |
260 | 56 | ||
261 | if (!chat->handles.messenger) | 57 | if (handle->arm) |
262 | { | 58 | on_handle_arm_connection(handle, GNUNET_NO); |
263 | GNUNET_CHAT_stop(chat); | ||
264 | return NULL; | ||
265 | } | ||
266 | 59 | ||
267 | chat->handles.fs = GNUNET_FS_start( | 60 | handle->fs = GNUNET_FS_start( |
268 | cfg, | 61 | handle->cfg, name, // TODO: raw name? |
269 | name, | 62 | notify_handle_fs_progress, handle, |
270 | handle_fs_progress, | ||
271 | chat, | ||
272 | GNUNET_FS_FLAGS_NONE, | 63 | GNUNET_FS_FLAGS_NONE, |
273 | GNUNET_FS_OPTIONS_END | 64 | GNUNET_FS_OPTIONS_END |
274 | ); | 65 | ); |
275 | 66 | ||
276 | chat->contacts.short_map = GNUNET_CONTAINER_multishortmap_create(8, GNUNET_NO); | 67 | handle->messenger = GNUNET_MESSENGER_connect( |
277 | chat->contacts.hash_map = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); | 68 | handle->cfg, name, |
278 | 69 | on_handle_identity, handle, | |
279 | chat->groups = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); | 70 | on_handle_message, handle |
280 | chat->contexts = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); | 71 | ); |
281 | chat->files = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); | ||
282 | |||
283 | chat->msg_cb = msg_cb; | ||
284 | chat->msg_cls = msg_cls; | ||
285 | |||
286 | return chat; | ||
287 | } | ||
288 | |||
289 | static int | ||
290 | handle_iterate_destroy_contacts (GNUNET_UNUSED void *cls, | ||
291 | GNUNET_UNUSED const struct GNUNET_HashCode *key, | ||
292 | void *value) | ||
293 | { | ||
294 | struct GNUNET_CHAT_Contact *contact = value; | ||
295 | contact_destroy(contact); | ||
296 | return GNUNET_YES; | ||
297 | } | ||
298 | 72 | ||
299 | static int | 73 | return handle; |
300 | handle_iterate_destroy_groups (GNUNET_UNUSED void *cls, | ||
301 | GNUNET_UNUSED const struct GNUNET_HashCode *key, | ||
302 | void *value) | ||
303 | { | ||
304 | struct GNUNET_CHAT_Group *group = value; | ||
305 | group_destroy(group); | ||
306 | return GNUNET_YES; | ||
307 | } | 74 | } |
308 | 75 | ||
309 | void | 76 | void |
310 | GNUNET_CHAT_stop (struct GNUNET_CHAT_Handle *handle) | 77 | handle_destroy (struct GNUNET_CHAT_Handle* handle) |
311 | { | 78 | { |
312 | if (!handle) | 79 | if (handle->messenger) |
313 | return; | 80 | GNUNET_MESSENGER_disconnect(handle->messenger); |
314 | |||
315 | if (handle->handles.fs) | ||
316 | { | ||
317 | // TODO: stop each action | ||
318 | |||
319 | GNUNET_FS_stop(handle->handles.fs); | ||
320 | handle->handles.fs = NULL; | ||
321 | } | ||
322 | |||
323 | if (handle->handles.messenger) | ||
324 | { | ||
325 | // TODO: stop everything related | ||
326 | |||
327 | GNUNET_MESSENGER_disconnect(handle->handles.messenger); | ||
328 | handle->handles.messenger = NULL; | ||
329 | } | ||
330 | 81 | ||
331 | if (handle->groups) | 82 | if (handle->files) |
332 | { | 83 | GNUNET_FS_stop(handle->fs); |
333 | GNUNET_CONTAINER_multihashmap_iterate( | ||
334 | handle->groups, handle_iterate_destroy_groups, NULL | ||
335 | ); | ||
336 | 84 | ||
337 | GNUNET_CONTAINER_multihashmap_destroy(handle->groups); | 85 | if (handle->arm) |
338 | handle->groups = NULL; | 86 | GNUNET_ARM_disconnect(handle->arm); |
339 | } | ||
340 | 87 | ||
341 | if (handle->contacts.hash_map) | 88 | GNUNET_CONTAINER_multihashmap_destroy(handle->groups); |
342 | { | 89 | GNUNET_CONTAINER_multishortmap_destroy(handle->contacts); |
343 | GNUNET_CONTAINER_multihashmap_iterate( | 90 | GNUNET_CONTAINER_multihashmap_destroy(handle->contexts); |
344 | handle->contacts.hash_map, handle_iterate_destroy_contacts, NULL | 91 | GNUNET_CONTAINER_multihashmap_destroy(handle->files); |
345 | ); | ||
346 | |||
347 | GNUNET_CONTAINER_multihashmap_destroy(handle->contacts.hash_map); | ||
348 | handle->contacts.hash_map = NULL; | ||
349 | } | ||
350 | |||
351 | if (handle->contacts.short_map) | ||
352 | { | ||
353 | GNUNET_CONTAINER_multishortmap_destroy(handle->contacts.short_map); | ||
354 | handle->contacts.short_map = NULL; | ||
355 | } | ||
356 | |||
357 | if (handle->handles.arm) | ||
358 | { | ||
359 | //TODO: stop started services? | ||
360 | |||
361 | GNUNET_ARM_disconnect(handle->handles.arm); | ||
362 | handle->handles.arm = NULL; | ||
363 | } | ||
364 | 92 | ||
365 | GNUNET_free(handle); | 93 | GNUNET_free(handle); |
366 | } | 94 | } |
367 | |||
368 | int | ||
369 | GNUNET_CHAT_update (struct GNUNET_CHAT_Handle *handle) | ||
370 | { | ||
371 | if (!handle) | ||
372 | return GNUNET_SYSERR; | ||
373 | |||
374 | return GNUNET_MESSENGER_update(handle->handles.messenger); | ||
375 | } | ||
376 | |||
377 | int | ||
378 | GNUNET_CHAT_set_name (struct GNUNET_CHAT_Handle *handle, | ||
379 | const char *name) | ||
380 | { | ||
381 | if (!handle) | ||
382 | return GNUNET_SYSERR; | ||
383 | |||
384 | return GNUNET_MESSENGER_set_name(handle->handles.messenger, name); | ||
385 | } | ||
386 | |||
387 | const char* | ||
388 | GNUNET_CHAT_get_name (const struct GNUNET_CHAT_Handle *handle) | ||
389 | { | ||
390 | if (!handle) | ||
391 | return NULL; | ||
392 | |||
393 | return GNUNET_MESSENGER_get_name(handle->handles.messenger); | ||
394 | } | ||
395 | |||
396 | const struct GNUNET_IDENTITY_PublicKey* | ||
397 | GNUNET_CHAT_get_key (const struct GNUNET_CHAT_Handle *handle) | ||
398 | { | ||
399 | if (!handle) | ||
400 | return NULL; | ||
401 | |||
402 | return GNUNET_MESSENGER_get_key(handle->handles.messenger); | ||
403 | } | ||
404 | |||
405 | struct GNUNET_CHAT_IterateContacts | ||
406 | { | ||
407 | struct GNUNET_CHAT_Handle *handle; | ||
408 | GNUNET_CHAT_ContactCallback callback; | ||
409 | void *cls; | ||
410 | }; | ||
411 | |||
412 | static int | ||
413 | handle_iterate_contacts(void *cls, | ||
414 | GNUNET_UNUSED const struct GNUNET_HashCode *key, | ||
415 | void *value) | ||
416 | { | ||
417 | struct GNUNET_CHAT_IterateContacts *iterate = cls; | ||
418 | struct GNUNET_CHAT_Contact *contact = value; | ||
419 | |||
420 | if (!iterate->callback) | ||
421 | return GNUNET_YES; | ||
422 | |||
423 | return iterate->callback(iterate->cls, iterate->handle, contact); | ||
424 | } | ||
425 | |||
426 | int | ||
427 | GNUNET_CHAT_iterate_contacts (struct GNUNET_CHAT_Handle *handle, | ||
428 | GNUNET_CHAT_ContactCallback callback, | ||
429 | void *cls) | ||
430 | { | ||
431 | if (!handle) | ||
432 | return GNUNET_SYSERR; | ||
433 | |||
434 | struct GNUNET_CHAT_IterateContacts iterate; | ||
435 | iterate.handle = handle; | ||
436 | iterate.callback = callback; | ||
437 | iterate.cls = cls; | ||
438 | |||
439 | return GNUNET_CONTAINER_multihashmap_iterate(handle->contacts.hash_map, | ||
440 | handle_iterate_contacts, | ||
441 | &iterate); | ||
442 | } | ||
443 | |||
444 | struct GNUNET_CHAT_Group* | ||
445 | GNUNET_CHAT_group_create (struct GNUNET_CHAT_Handle *handle, | ||
446 | const char *topic) | ||
447 | { | ||
448 | if (!handle) | ||
449 | return NULL; | ||
450 | |||
451 | struct GNUNET_CHAT_Group *group = group_create(handle, topic); | ||
452 | |||
453 | if (!group) | ||
454 | return NULL; | ||
455 | |||
456 | if (GNUNET_YES != handle_update_chat_group(handle, group, GNUNET_NO)) | ||
457 | { | ||
458 | group_destroy(group); | ||
459 | return NULL; | ||
460 | } | ||
461 | |||
462 | return group; | ||
463 | } | ||
464 | |||
465 | struct GNUNET_CHAT_IterateGroups | ||
466 | { | ||
467 | struct GNUNET_CHAT_Handle *handle; | ||
468 | GNUNET_CHAT_GroupCallback callback; | ||
469 | void *cls; | ||
470 | }; | ||
471 | |||
472 | static int | ||
473 | handle_iterate_groups(void *cls, | ||
474 | GNUNET_UNUSED const struct GNUNET_HashCode *key, | ||
475 | void *value) | ||
476 | { | ||
477 | struct GNUNET_CHAT_IterateGroups *iterate = cls; | ||
478 | struct GNUNET_CHAT_Group *group = value; | ||
479 | |||
480 | if (!iterate->callback) | ||
481 | return GNUNET_YES; | ||
482 | |||
483 | return iterate->callback(iterate->cls, iterate->handle, group); | ||
484 | } | ||
485 | |||
486 | int | ||
487 | GNUNET_CHAT_iterate_groups (struct GNUNET_CHAT_Handle *handle, | ||
488 | GNUNET_CHAT_GroupCallback callback, | ||
489 | void *cls) | ||
490 | { | ||
491 | if (!handle) | ||
492 | return GNUNET_SYSERR; | ||
493 | |||
494 | struct GNUNET_CHAT_IterateGroups iterate; | ||
495 | iterate.handle = handle; | ||
496 | iterate.callback = callback; | ||
497 | iterate.cls = cls; | ||
498 | |||
499 | return GNUNET_CONTAINER_multihashmap_iterate(handle->groups, | ||
500 | handle_iterate_groups, | ||
501 | &iterate); | ||
502 | } | ||
503 | |||
504 | int | ||
505 | handle_update_chat_contact (struct GNUNET_CHAT_Handle *handle, | ||
506 | struct GNUNET_CHAT_Contact *chatContact, | ||
507 | int removeContact) | ||
508 | { | ||
509 | const struct GNUNET_HashCode *key = context_get_key(chatContact->context); | ||
510 | |||
511 | if (GNUNET_YES == removeContact) | ||
512 | { | ||
513 | const int result = GNUNET_CONTAINER_multihashmap_remove( | ||
514 | handle->contacts.hash_map, key, chatContact | ||
515 | ); | ||
516 | |||
517 | if (GNUNET_YES == result) | ||
518 | return handle_update_chat_context(handle, chatContact->context, | ||
519 | GNUNET_YES); | ||
520 | else | ||
521 | return GNUNET_NO; | ||
522 | } | ||
523 | else | ||
524 | { | ||
525 | const int result = GNUNET_CONTAINER_multihashmap_put( | ||
526 | handle->contacts.hash_map, key, chatContact, | ||
527 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY | ||
528 | ); | ||
529 | |||
530 | if (GNUNET_OK != result) | ||
531 | return GNUNET_NO; | ||
532 | else | ||
533 | return handle_update_chat_context(handle, chatContact->context, | ||
534 | GNUNET_NO); | ||
535 | } | ||
536 | } | ||
537 | |||
538 | int | ||
539 | handle_update_chat_group (struct GNUNET_CHAT_Handle *handle, | ||
540 | struct GNUNET_CHAT_Group *chatGroup, | ||
541 | int removeGroup) | ||
542 | { | ||
543 | const struct GNUNET_HashCode *key = context_get_key(chatGroup->context); | ||
544 | |||
545 | if (GNUNET_YES == removeGroup) | ||
546 | { | ||
547 | const int result = GNUNET_CONTAINER_multihashmap_remove( | ||
548 | handle->groups, key, chatGroup | ||
549 | ); | ||
550 | |||
551 | if (GNUNET_YES == result) | ||
552 | return handle_update_chat_context(handle, chatGroup->context, | ||
553 | GNUNET_YES); | ||
554 | else | ||
555 | return GNUNET_NO; | ||
556 | } | ||
557 | else | ||
558 | { | ||
559 | const int result = GNUNET_CONTAINER_multihashmap_put( | ||
560 | handle->groups, key, chatGroup, | ||
561 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY | ||
562 | ); | ||
563 | |||
564 | if (GNUNET_OK != result) | ||
565 | return GNUNET_NO; | ||
566 | else | ||
567 | return handle_update_chat_context(handle, chatGroup->context, | ||
568 | GNUNET_NO); | ||
569 | } | ||
570 | } | ||
571 | |||
572 | int | ||
573 | handle_update_chat_context (struct GNUNET_CHAT_Handle *handle, | ||
574 | struct GNUNET_CHAT_Context *context, | ||
575 | int removeContext) | ||
576 | { | ||
577 | const struct GNUNET_HashCode *key = context_get_key(context); | ||
578 | |||
579 | if (GNUNET_YES == removeContext) | ||
580 | return GNUNET_CONTAINER_multihashmap_remove( | ||
581 | handle->contexts, key, context | ||
582 | ); | ||
583 | else | ||
584 | { | ||
585 | const int result = GNUNET_CONTAINER_multihashmap_put( | ||
586 | handle->contexts, key, context, | ||
587 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY | ||
588 | ); | ||
589 | |||
590 | if (GNUNET_OK != result) | ||
591 | return GNUNET_NO; | ||
592 | else | ||
593 | return GNUNET_YES; | ||
594 | } | ||
595 | } | ||
596 | |||
597 | int | ||
598 | handle_update_chat_file (struct GNUNET_CHAT_Handle *handle, | ||
599 | struct GNUNET_CHAT_File *file, | ||
600 | int removeFile) | ||
601 | { | ||
602 | const struct GNUNET_HashCode *hash = GNUNET_CHAT_file_get_hash(file); | ||
603 | |||
604 | if (GNUNET_YES == removeFile) | ||
605 | return GNUNET_CONTAINER_multihashmap_remove( | ||
606 | handle->files, hash, file | ||
607 | ); | ||
608 | else | ||
609 | { | ||
610 | const int result = GNUNET_CONTAINER_multihashmap_put( | ||
611 | handle->files, hash, file, | ||
612 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY | ||
613 | ); | ||
614 | |||
615 | if (GNUNET_OK != result) | ||
616 | return GNUNET_NO; | ||
617 | else | ||
618 | return GNUNET_YES; | ||
619 | } | ||
620 | } | ||
621 | |||
622 | static void | ||
623 | handle_get_short_of_contact(struct GNUNET_ShortHashCode *shortHash, | ||
624 | const struct GNUNET_MESSENGER_Contact *contact) | ||
625 | { | ||
626 | memset(shortHash, 0, sizeof(*shortHash)); | ||
627 | GNUNET_memcpy(shortHash, &contact, sizeof(contact)); | ||
628 | } | ||
629 | |||
630 | struct GNUNET_CHAT_Contact* | ||
631 | handle_get_chat_contact (struct GNUNET_CHAT_Handle *handle, | ||
632 | const struct GNUNET_MESSENGER_Contact *contact) | ||
633 | { | ||
634 | struct GNUNET_ShortHashCode shortHash; | ||
635 | handle_get_short_of_contact (&shortHash, contact); | ||
636 | |||
637 | struct GNUNET_CHAT_Contact* chatContact = GNUNET_CONTAINER_multishortmap_get( | ||
638 | handle->contacts.short_map, &shortHash | ||
639 | ); | ||
640 | |||
641 | return chatContact; | ||
642 | } | ||
643 | |||
644 | void | ||
645 | handle_set_chat_contact (struct GNUNET_CHAT_Handle *handle, | ||
646 | const struct GNUNET_MESSENGER_Contact *contact, | ||
647 | struct GNUNET_CHAT_Contact *chatContact) | ||
648 | { | ||
649 | struct GNUNET_ShortHashCode shortHash; | ||
650 | handle_get_short_of_contact (&shortHash, contact); | ||
651 | |||
652 | if (chatContact) | ||
653 | { | ||
654 | GNUNET_CONTAINER_multishortmap_remove_all(handle->contacts.short_map, | ||
655 | &shortHash); | ||
656 | return; | ||
657 | } | ||
658 | |||
659 | GNUNET_CONTAINER_multishortmap_put( | ||
660 | handle->contacts.short_map, &shortHash, chatContact, | ||
661 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE | ||
662 | ); | ||
663 | } | ||