aboutsummaryrefslogtreecommitdiff
path: root/src/gnunet_chat_handle.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gnunet_chat_handle.c')
-rw-r--r--src/gnunet_chat_handle.c237
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
223static void
224handle_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
220void 265void
221handle_connect (struct GNUNET_CHAT_Handle *handle, 266handle_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
278void 321void
@@ -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
388int 431static struct GNUNET_CHAT_InternalAccounts*
389handle_create_account (struct GNUNET_CHAT_Handle *handle, 432find_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
454static int
455update_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
497int
498handle_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
438int 529int
@@ -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; 556int
557handle_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
503const char* 585const 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
527const struct GNUNET_IDENTITY_PrivateKey* 630const struct GNUNET_IDENTITY_PrivateKey*