diff options
Diffstat (limited to 'src/gnunet_chat_handle.c')
-rw-r--r-- | src/gnunet_chat_handle.c | 482 |
1 files changed, 447 insertions, 35 deletions
diff --git a/src/gnunet_chat_handle.c b/src/gnunet_chat_handle.c index 6e2f32e..84539c5 100644 --- a/src/gnunet_chat_handle.c +++ b/src/gnunet_chat_handle.c | |||
@@ -25,57 +25,285 @@ | |||
25 | #include "gnunet_chat_lib.h" | 25 | #include "gnunet_chat_lib.h" |
26 | #include "gnunet_chat_handle.h" | 26 | #include "gnunet_chat_handle.h" |
27 | #include "gnunet_chat_group.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" | ||
28 | 31 | ||
29 | static void handle_arm_connection(void* cls, int connected) { | 32 | static void* |
30 | struct GNUNET_CHAT_Handle *handle = cls; | 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; | ||
31 | 220 | ||
32 | if (GNUNET_YES == connected) { | 221 | if (GNUNET_YES == connected) { |
33 | GNUNET_ARM_request_service_start(handle->handles.arm, "messenger", GNUNET_OS_INHERIT_STD_NONE, NULL, NULL); | 222 | GNUNET_ARM_request_service_start(chat->handles.arm, "messenger", |
34 | GNUNET_ARM_request_service_start(handle->handles.arm, "fs", GNUNET_OS_INHERIT_STD_NONE, NULL, NULL); | 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); | ||
35 | } else { | 226 | } else { |
36 | GNUNET_ARM_request_service_start(handle->handles.arm, "arm", GNUNET_OS_INHERIT_STD_NONE, NULL, NULL); | 227 | GNUNET_ARM_request_service_start(chat->handles.arm, "arm", |
228 | GNUNET_OS_INHERIT_STD_NONE, NULL, NULL); | ||
37 | } | 229 | } |
38 | } | 230 | } |
39 | 231 | ||
40 | struct GNUNET_CHAT_Handle* | 232 | struct GNUNET_CHAT_Handle* |
41 | GNUNET_CHAT_start (const struct GNUNET_CONFIGURATION_Handle* cfg, | 233 | GNUNET_CHAT_start (const struct GNUNET_CONFIGURATION_Handle* cfg, |
42 | const char *name, | 234 | const char *name, |
43 | GNUNET_CHAT_WarningCallback warn_cb, | 235 | GNUNET_CHAT_WarningCallback warn_cb, |
44 | void *warn_cls) { | 236 | void *warn_cls, |
237 | GNUNET_CHAT_ContextMessageCallback msg_cb, | ||
238 | void *msg_cls) | ||
239 | { | ||
45 | if (!cfg) | 240 | if (!cfg) |
46 | return NULL; | 241 | return NULL; |
47 | 242 | ||
48 | struct GNUNET_CHAT_Handle *handle = GNUNET_new(struct GNUNET_CHAT_Handle); | 243 | struct GNUNET_CHAT_Handle *chat = GNUNET_new(struct GNUNET_CHAT_Handle); |
49 | memset(handle, 0, sizeof(*handle)); | 244 | memset(chat, 0, sizeof(*chat)); |
50 | handle->cfg = cfg; | 245 | chat->cfg = cfg; |
51 | 246 | ||
52 | handle->handles.arm = GNUNET_ARM_connect(cfg, &handle_arm_connection, handle); | 247 | chat->warn_cb = warn_cb; |
248 | chat->warn_cls = warn_cls; | ||
53 | 249 | ||
54 | if (handle->handles.arm) | 250 | chat->handles.arm = GNUNET_ARM_connect(cfg, &handle_arm_connection, chat); |
55 | handle_arm_connection(handle, GNUNET_NO); | 251 | |
252 | if (chat->handles.arm) | ||
253 | handle_arm_connection(chat, GNUNET_NO); | ||
56 | 254 | ||
57 | handle->handles.messenger = GNUNET_MESSENGER_connect( | 255 | chat->handles.messenger = GNUNET_MESSENGER_connect( |
58 | cfg, name, NULL, NULL, NULL, NULL //TODO | 256 | cfg, name, |
257 | handle_on_identity, chat, | ||
258 | handle_on_message, chat | ||
59 | ); | 259 | ); |
60 | 260 | ||
61 | if (!handle->handles.messenger) | 261 | if (!chat->handles.messenger) |
62 | { | 262 | { |
63 | GNUNET_CHAT_stop(handle); | 263 | GNUNET_CHAT_stop(chat); |
64 | return NULL; | 264 | return NULL; |
65 | } | 265 | } |
66 | 266 | ||
67 | handle->handles.fs = GNUNET_FS_start( | 267 | chat->handles.fs = GNUNET_FS_start( |
68 | cfg, | 268 | cfg, |
69 | NULL, //TODO | 269 | name, |
70 | NULL, | 270 | handle_fs_progress, |
271 | chat, | ||
71 | GNUNET_FS_FLAGS_NONE, | 272 | GNUNET_FS_FLAGS_NONE, |
72 | GNUNET_FS_OPTIONS_END | 273 | GNUNET_FS_OPTIONS_END |
73 | ); | 274 | ); |
74 | 275 | ||
75 | handle->contacts = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); | 276 | chat->contacts.short_map = GNUNET_CONTAINER_multishortmap_create(8, GNUNET_NO); |
76 | handle->groups = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); | 277 | chat->contacts.hash_map = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); |
278 | |||
279 | chat->groups = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); | ||
280 | chat->contexts = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); | ||
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 | } | ||
77 | 298 | ||
78 | return handle; | 299 | static int |
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; | ||
79 | } | 307 | } |
80 | 308 | ||
81 | void | 309 | void |
@@ -102,18 +330,28 @@ GNUNET_CHAT_stop (struct GNUNET_CHAT_Handle *handle) | |||
102 | 330 | ||
103 | if (handle->groups) | 331 | if (handle->groups) |
104 | { | 332 | { |
105 | // TODO: destroy each | 333 | GNUNET_CONTAINER_multihashmap_iterate( |
334 | handle->groups, handle_iterate_destroy_groups, NULL | ||
335 | ); | ||
106 | 336 | ||
107 | GNUNET_CONTAINER_multihashmap_destroy(handle->groups); | 337 | GNUNET_CONTAINER_multihashmap_destroy(handle->groups); |
108 | handle->groups = NULL; | 338 | handle->groups = NULL; |
109 | } | 339 | } |
110 | 340 | ||
111 | if (handle->contacts) | 341 | if (handle->contacts.hash_map) |
112 | { | 342 | { |
113 | // TODO: destroy each | 343 | GNUNET_CONTAINER_multihashmap_iterate( |
344 | handle->contacts.hash_map, handle_iterate_destroy_contacts, NULL | ||
345 | ); | ||
114 | 346 | ||
115 | GNUNET_CONTAINER_multihashmap_destroy(handle->contacts); | 347 | GNUNET_CONTAINER_multihashmap_destroy(handle->contacts.hash_map); |
116 | handle->contacts = NULL; | 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; | ||
117 | } | 355 | } |
118 | 356 | ||
119 | if (handle->handles.arm) | 357 | if (handle->handles.arm) |
@@ -172,7 +410,8 @@ struct GNUNET_CHAT_IterateContacts | |||
172 | }; | 410 | }; |
173 | 411 | ||
174 | static int | 412 | static int |
175 | handle_iterate_contacts(void *cls, const struct GNUNET_HashCode *key, | 413 | handle_iterate_contacts(void *cls, |
414 | GNUNET_UNUSED const struct GNUNET_HashCode *key, | ||
176 | void *value) | 415 | void *value) |
177 | { | 416 | { |
178 | struct GNUNET_CHAT_IterateContacts *iterate = cls; | 417 | struct GNUNET_CHAT_IterateContacts *iterate = cls; |
@@ -197,7 +436,7 @@ GNUNET_CHAT_iterate_contacts (struct GNUNET_CHAT_Handle *handle, | |||
197 | iterate.callback = callback; | 436 | iterate.callback = callback; |
198 | iterate.cls = cls; | 437 | iterate.cls = cls; |
199 | 438 | ||
200 | return GNUNET_CONTAINER_multihashmap_iterate(handle->contacts, | 439 | return GNUNET_CONTAINER_multihashmap_iterate(handle->contacts.hash_map, |
201 | handle_iterate_contacts, | 440 | handle_iterate_contacts, |
202 | &iterate); | 441 | &iterate); |
203 | } | 442 | } |
@@ -209,7 +448,18 @@ GNUNET_CHAT_group_create (struct GNUNET_CHAT_Handle *handle, | |||
209 | if (!handle) | 448 | if (!handle) |
210 | return NULL; | 449 | return NULL; |
211 | 450 | ||
212 | return group_create(handle, topic); | 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; | ||
213 | } | 463 | } |
214 | 464 | ||
215 | struct GNUNET_CHAT_IterateGroups | 465 | struct GNUNET_CHAT_IterateGroups |
@@ -220,8 +470,9 @@ struct GNUNET_CHAT_IterateGroups | |||
220 | }; | 470 | }; |
221 | 471 | ||
222 | static int | 472 | static int |
223 | handle_iterate_groups(void *cls, const struct GNUNET_HashCode *key, | 473 | handle_iterate_groups(void *cls, |
224 | void *value) | 474 | GNUNET_UNUSED const struct GNUNET_HashCode *key, |
475 | void *value) | ||
225 | { | 476 | { |
226 | struct GNUNET_CHAT_IterateGroups *iterate = cls; | 477 | struct GNUNET_CHAT_IterateGroups *iterate = cls; |
227 | struct GNUNET_CHAT_Group *group = value; | 478 | struct GNUNET_CHAT_Group *group = value; |
@@ -246,6 +497,167 @@ GNUNET_CHAT_iterate_groups (struct GNUNET_CHAT_Handle *handle, | |||
246 | iterate.cls = cls; | 497 | iterate.cls = cls; |
247 | 498 | ||
248 | return GNUNET_CONTAINER_multihashmap_iterate(handle->groups, | 499 | return GNUNET_CONTAINER_multihashmap_iterate(handle->groups, |
249 | handle_iterate_contacts, | 500 | handle_iterate_groups, |
250 | &iterate); | 501 | &iterate); |
251 | } | 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 | } | ||