diff options
Diffstat (limited to 'src/gnunet_chat_handle.c')
-rw-r--r-- | src/gnunet_chat_handle.c | 237 |
1 files changed, 170 insertions, 67 deletions
diff --git a/src/gnunet_chat_handle.c b/src/gnunet_chat_handle.c index c94b01b..f15259e 100644 --- a/src/gnunet_chat_handle.c +++ b/src/gnunet_chat_handle.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2021--2022 GNUnet e.V. | 3 | Copyright (C) 2021--2023 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 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 | 6 | under the terms of the GNU Affero General Public License as published |
@@ -185,6 +185,9 @@ handle_destroy (struct GNUNET_CHAT_Handle *handle) | |||
185 | accounts | 185 | accounts |
186 | ); | 186 | ); |
187 | 187 | ||
188 | if (accounts->identifier) | ||
189 | GNUNET_free(accounts->identifier); | ||
190 | |||
188 | GNUNET_free(accounts); | 191 | GNUNET_free(accounts); |
189 | } | 192 | } |
190 | 193 | ||
@@ -217,6 +220,48 @@ handle_destroy (struct GNUNET_CHAT_Handle *handle) | |||
217 | GNUNET_free(handle); | 220 | GNUNET_free(handle); |
218 | } | 221 | } |
219 | 222 | ||
223 | static void | ||
224 | handle_update_identity(struct GNUNET_CHAT_Handle *handle) | ||
225 | { | ||
226 | GNUNET_assert((handle) && | ||
227 | (handle->contexts) && | ||
228 | (handle->groups) && | ||
229 | (handle->contacts)); | ||
230 | |||
231 | handle_update_key(handle); | ||
232 | |||
233 | if ((0 < GNUNET_CONTAINER_multihashmap_size(handle->contexts)) || | ||
234 | (0 < GNUNET_CONTAINER_multihashmap_size(handle->groups)) || | ||
235 | (0 < GNUNET_CONTAINER_multishortmap_size(handle->contacts))) | ||
236 | return; | ||
237 | |||
238 | GNUNET_assert(handle->messenger); | ||
239 | |||
240 | handle_send_internal_message( | ||
241 | handle, | ||
242 | NULL, | ||
243 | GNUNET_CHAT_FLAG_LOGIN, | ||
244 | NULL | ||
245 | ); | ||
246 | |||
247 | const struct GNUNET_IDENTITY_PrivateKey *zone = handle_get_key(handle); | ||
248 | |||
249 | if ((!zone) || (handle->monitor)) | ||
250 | return; | ||
251 | |||
252 | handle->monitor = GNUNET_NAMESTORE_zone_monitor_start( | ||
253 | handle->cfg, | ||
254 | zone, | ||
255 | GNUNET_YES, | ||
256 | NULL, | ||
257 | NULL, | ||
258 | on_monitor_namestore_record, | ||
259 | handle, | ||
260 | NULL, | ||
261 | NULL | ||
262 | ); | ||
263 | } | ||
264 | |||
220 | void | 265 | void |
221 | handle_connect (struct GNUNET_CHAT_Handle *handle, | 266 | handle_connect (struct GNUNET_CHAT_Handle *handle, |
222 | const struct GNUNET_CHAT_Account *account) | 267 | const struct GNUNET_CHAT_Account *account) |
@@ -270,9 +315,7 @@ handle_connect (struct GNUNET_CHAT_Handle *handle, | |||
270 | ); | 315 | ); |
271 | 316 | ||
272 | handle->current = account; | 317 | handle->current = account; |
273 | handle_update_key(handle); | 318 | handle_update_identity(handle); |
274 | |||
275 | on_handle_identity(handle, handle->messenger); | ||
276 | } | 319 | } |
277 | 320 | ||
278 | void | 321 | void |
@@ -385,8 +428,8 @@ handle_disconnect (struct GNUNET_CHAT_Handle *handle) | |||
385 | handle_update_key(handle); | 428 | handle_update_key(handle); |
386 | } | 429 | } |
387 | 430 | ||
388 | int | 431 | static struct GNUNET_CHAT_InternalAccounts* |
389 | handle_create_account (struct GNUNET_CHAT_Handle *handle, | 432 | find_accounts_by_name (struct GNUNET_CHAT_Handle *handle, |
390 | const char *name) | 433 | const char *name) |
391 | { | 434 | { |
392 | GNUNET_assert((handle) && (name)); | 435 | GNUNET_assert((handle) && (name)); |
@@ -399,15 +442,74 @@ handle_create_account (struct GNUNET_CHAT_Handle *handle, | |||
399 | 442 | ||
400 | if ((accounts->account->name) && | 443 | if ((accounts->account->name) && |
401 | (0 == strcmp(accounts->account->name, name))) | 444 | (0 == strcmp(accounts->account->name, name))) |
402 | return GNUNET_NO; | 445 | break; |
403 | 446 | ||
404 | skip_account: | 447 | skip_account: |
405 | accounts = accounts->next; | 448 | accounts = accounts->next; |
406 | } | 449 | } |
407 | 450 | ||
408 | accounts = GNUNET_new(struct GNUNET_CHAT_InternalAccounts); | 451 | return accounts; |
409 | accounts->account = NULL; | 452 | } |
410 | accounts->handle = handle; | 453 | |
454 | static int | ||
455 | update_accounts_operation (struct GNUNET_CHAT_InternalAccounts **out_accounts, | ||
456 | struct GNUNET_CHAT_Handle *handle, | ||
457 | const char *name, | ||
458 | int wait_for_completion) | ||
459 | { | ||
460 | GNUNET_assert(handle); | ||
461 | |||
462 | struct GNUNET_CHAT_InternalAccounts *accounts = *out_accounts; | ||
463 | |||
464 | if (!accounts) | ||
465 | { | ||
466 | accounts = GNUNET_new(struct GNUNET_CHAT_InternalAccounts); | ||
467 | |||
468 | if (!accounts) | ||
469 | return GNUNET_SYSERR; | ||
470 | |||
471 | accounts->account = NULL; | ||
472 | accounts->handle = handle; | ||
473 | |||
474 | GNUNET_CONTAINER_DLL_insert_tail( | ||
475 | handle->accounts_head, | ||
476 | handle->accounts_tail, | ||
477 | accounts | ||
478 | ); | ||
479 | } | ||
480 | else | ||
481 | { | ||
482 | if (accounts->identifier) | ||
483 | GNUNET_free(accounts->identifier); | ||
484 | |||
485 | if (accounts->op) | ||
486 | GNUNET_IDENTITY_cancel(accounts->op); | ||
487 | } | ||
488 | |||
489 | accounts->identifier = name ? GNUNET_strdup(name) : NULL; | ||
490 | accounts->wait_for_completion = wait_for_completion; | ||
491 | |||
492 | *out_accounts = accounts; | ||
493 | |||
494 | return GNUNET_OK; | ||
495 | } | ||
496 | |||
497 | int | ||
498 | handle_create_account (struct GNUNET_CHAT_Handle *handle, | ||
499 | const char *name) | ||
500 | { | ||
501 | GNUNET_assert((handle) && (name)); | ||
502 | |||
503 | struct GNUNET_CHAT_InternalAccounts *accounts; | ||
504 | accounts = find_accounts_by_name(handle, name); | ||
505 | |||
506 | if (accounts) | ||
507 | return GNUNET_NO; | ||
508 | |||
509 | int result = update_accounts_operation(&accounts, handle, NULL, GNUNET_NO); | ||
510 | |||
511 | if (GNUNET_OK != result) | ||
512 | return result; | ||
411 | 513 | ||
412 | accounts->op = GNUNET_IDENTITY_create( | 514 | accounts->op = GNUNET_IDENTITY_create( |
413 | handle->identity, | 515 | handle->identity, |
@@ -418,21 +520,10 @@ handle_create_account (struct GNUNET_CHAT_Handle *handle, | |||
418 | accounts | 520 | accounts |
419 | ); | 521 | ); |
420 | 522 | ||
421 | if (!(accounts->op)) | 523 | if (!accounts->op) |
422 | { | ||
423 | GNUNET_free(accounts); | ||
424 | return GNUNET_SYSERR; | 524 | return GNUNET_SYSERR; |
425 | } | ||
426 | |||
427 | accounts->wait_for_completion = GNUNET_NO; | ||
428 | 525 | ||
429 | GNUNET_CONTAINER_DLL_insert_tail( | 526 | return result; |
430 | handle->accounts_head, | ||
431 | handle->accounts_tail, | ||
432 | accounts | ||
433 | ); | ||
434 | |||
435 | return GNUNET_OK; | ||
436 | } | 527 | } |
437 | 528 | ||
438 | int | 529 | int |
@@ -441,63 +532,54 @@ handle_delete_account (struct GNUNET_CHAT_Handle *handle, | |||
441 | { | 532 | { |
442 | GNUNET_assert((handle) && (name)); | 533 | GNUNET_assert((handle) && (name)); |
443 | 534 | ||
444 | struct GNUNET_CHAT_InternalAccounts *accounts = handle->accounts_head; | 535 | struct GNUNET_CHAT_InternalAccounts *accounts; |
445 | while (accounts) | 536 | accounts = find_accounts_by_name(handle, name); |
446 | { | ||
447 | if (!(accounts->account)) | ||
448 | goto skip_account; | ||
449 | 537 | ||
450 | if ((accounts->account->name) && | 538 | int result = update_accounts_operation(&accounts, handle, NULL, GNUNET_YES); |
451 | (0 == strcmp(accounts->account->name, name))) | ||
452 | break; | ||
453 | 539 | ||
454 | skip_account: | 540 | if (GNUNET_OK != result) |
455 | accounts = accounts->next; | 541 | return result; |
456 | } | ||
457 | 542 | ||
458 | if (!accounts) | 543 | accounts->op = GNUNET_IDENTITY_delete( |
459 | { | 544 | handle->identity, |
460 | accounts = GNUNET_new(struct GNUNET_CHAT_InternalAccounts); | 545 | name, |
461 | accounts->account = NULL; | 546 | cb_account_deletion, |
462 | accounts->handle = handle; | 547 | accounts |
548 | ); | ||
463 | 549 | ||
464 | accounts->op = GNUNET_IDENTITY_delete( | 550 | if (!accounts->op) |
465 | handle->identity, | 551 | return GNUNET_SYSERR; |
466 | name, | ||
467 | cb_account_deletion, | ||
468 | accounts | ||
469 | ); | ||
470 | 552 | ||
471 | if (!(accounts->op)) | 553 | return result; |
472 | { | 554 | } |
473 | GNUNET_free(accounts); | ||
474 | return GNUNET_SYSERR; | ||
475 | } | ||
476 | 555 | ||
477 | accounts->wait_for_completion = GNUNET_YES; | 556 | int |
557 | handle_rename_account (struct GNUNET_CHAT_Handle *handle, | ||
558 | const char *old_name, | ||
559 | const char *new_name) | ||
560 | { | ||
561 | GNUNET_assert((handle) && (old_name) && (new_name)); | ||
478 | 562 | ||
479 | GNUNET_CONTAINER_DLL_insert_tail( | 563 | struct GNUNET_CHAT_InternalAccounts *accounts; |
480 | handle->accounts_head, | 564 | accounts = find_accounts_by_name(handle, old_name); |
481 | handle->accounts_tail, | ||
482 | accounts | ||
483 | ); | ||
484 | 565 | ||
485 | return GNUNET_OK; | 566 | int result = update_accounts_operation(&accounts, handle, NULL, GNUNET_YES); |
486 | } | ||
487 | 567 | ||
488 | if (accounts->op) | 568 | if (GNUNET_OK != result) |
489 | GNUNET_IDENTITY_cancel(accounts->op); | 569 | return result; |
490 | 570 | ||
491 | accounts->op = GNUNET_IDENTITY_delete( | 571 | accounts->op = GNUNET_IDENTITY_rename( |
492 | handle->identity, | 572 | handle->identity, |
493 | name, | 573 | old_name, |
494 | cb_account_deletion, | 574 | new_name, |
575 | cb_account_rename, | ||
495 | accounts | 576 | accounts |
496 | ); | 577 | ); |
497 | 578 | ||
498 | accounts->wait_for_completion = GNUNET_YES; | 579 | if (!accounts->op) |
580 | return GNUNET_SYSERR; | ||
499 | 581 | ||
500 | return (accounts->op? GNUNET_OK : GNUNET_SYSERR); | 582 | return result; |
501 | } | 583 | } |
502 | 584 | ||
503 | const char* | 585 | const char* |
@@ -519,9 +601,30 @@ handle_update (struct GNUNET_CHAT_Handle *handle) | |||
519 | { | 601 | { |
520 | GNUNET_assert((handle) && (handle->current)); | 602 | GNUNET_assert((handle) && (handle->current)); |
521 | 603 | ||
522 | // TODO: Implement update function | 604 | const char *name = handle->current->name; |
523 | 605 | ||
524 | return GNUNET_SYSERR; | 606 | if (!name) |
607 | return GNUNET_SYSERR; | ||
608 | |||
609 | struct GNUNET_CHAT_InternalAccounts *accounts; | ||
610 | accounts = find_accounts_by_name(handle, name); | ||
611 | |||
612 | int result = update_accounts_operation(&accounts, handle, name, GNUNET_YES); | ||
613 | |||
614 | if (GNUNET_OK != result) | ||
615 | return result; | ||
616 | |||
617 | accounts->op = GNUNET_IDENTITY_delete( | ||
618 | handle->identity, | ||
619 | name, | ||
620 | cb_account_update, | ||
621 | accounts | ||
622 | ); | ||
623 | |||
624 | if (!accounts->op) | ||
625 | return GNUNET_SYSERR; | ||
626 | |||
627 | return result; | ||
525 | } | 628 | } |
526 | 629 | ||
527 | const struct GNUNET_IDENTITY_PrivateKey* | 630 | const struct GNUNET_IDENTITY_PrivateKey* |