diff options
Diffstat (limited to 'src/fs/gnunet-fs-gtk_main-window-search.c')
-rw-r--r-- | src/fs/gnunet-fs-gtk_main-window-search.c | 329 |
1 files changed, 312 insertions, 17 deletions
diff --git a/src/fs/gnunet-fs-gtk_main-window-search.c b/src/fs/gnunet-fs-gtk_main-window-search.c index 37bf81b1..4ba47f4c 100644 --- a/src/fs/gnunet-fs-gtk_main-window-search.c +++ b/src/fs/gnunet-fs-gtk_main-window-search.c | |||
@@ -307,28 +307,212 @@ abort_pseu_lookup (struct PseuLookupContext *lctx) | |||
307 | { | 307 | { |
308 | struct GNUNET_GTK_MainWindowContext *main_ctx = lctx->main_ctx; | 308 | struct GNUNET_GTK_MainWindowContext *main_ctx = lctx->main_ctx; |
309 | 309 | ||
310 | if (NULL != lctx->progress_dialog_builder) | ||
311 | { | ||
312 | gtk_widget_destroy (lctx->progress_dialog); | ||
313 | g_object_unref (G_OBJECT (lctx->progress_dialog_builder)); | ||
314 | lctx->progress_dialog_builder = NULL; | ||
315 | } | ||
316 | if (NULL != lctx->nick_dialog_builder) | ||
317 | { | ||
318 | gtk_widget_destroy (lctx->nick_dialog); | ||
319 | g_object_unref (G_OBJECT (lctx->nick_dialog_builder)); | ||
320 | lctx->nick_dialog_builder = NULL; | ||
321 | } | ||
322 | |||
310 | if (NULL != lctx->lr) | 323 | if (NULL != lctx->lr) |
311 | { | 324 | { |
312 | GNUNET_GNS_lookup_cancel (lctx->lr); | 325 | GNUNET_GNS_lookup_cancel (lctx->lr); |
313 | lctx->lr = NULL; | 326 | lctx->lr = NULL; |
314 | } | 327 | } |
328 | if (NULL != lctx->qe) | ||
329 | { | ||
330 | GNUNET_NAMESTORE_cancel (lctx->qe); | ||
331 | lctx->qe = NULL; | ||
332 | } | ||
333 | if (NULL != lctx->namestore) | ||
334 | { | ||
335 | GNUNET_NAMESTORE_disconnect (lctx->namestore); | ||
336 | lctx->namestore = NULL; | ||
337 | } | ||
315 | GNUNET_CONTAINER_DLL_remove (main_ctx->lctx_head, | 338 | GNUNET_CONTAINER_DLL_remove (main_ctx->lctx_head, |
316 | main_ctx->lctx_tail, | 339 | main_ctx->lctx_tail, |
317 | lctx); | 340 | lctx); |
341 | GNUNET_free_non_null (lctx->nick); | ||
318 | GNUNET_free (lctx); | 342 | GNUNET_free (lctx); |
319 | } | 343 | } |
320 | 344 | ||
321 | 345 | ||
322 | /** | 346 | /** |
347 | * Continuation called to notify client about result of the | ||
348 | * operation. | ||
349 | * | ||
350 | * @param cls closure | ||
351 | * @param success #GNUNET_SYSERR on failure (including timeout/queue drop/failure to validate) | ||
352 | * #GNUNET_NO if content was already there or not found | ||
353 | * #GNUNET_YES (or other positive value) on success | ||
354 | * @param emsg NULL on success, otherwise an error message | ||
355 | */ | ||
356 | static void | ||
357 | store_continuation (void *cls, | ||
358 | int32_t success, | ||
359 | const char *emsg) | ||
360 | { | ||
361 | struct PseuLookupContext *lctx = cls; | ||
362 | |||
363 | lctx->qe = NULL; | ||
364 | if (NULL != emsg) | ||
365 | { | ||
366 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
367 | _("Failed to save record: %s\n"), | ||
368 | emsg); | ||
369 | gdk_beep (); | ||
370 | } | ||
371 | abort_pseu_lookup (lctx); | ||
372 | } | ||
373 | |||
374 | |||
375 | /** | ||
376 | * Save the namespace under the given nickname. | ||
377 | * | ||
378 | * @param lctx namespace request we are processing | ||
379 | * @param nick nickname to store the namespace under | ||
380 | */ | ||
381 | static void | ||
382 | save_pseudonym_with_nick (struct PseuLookupContext *lctx, | ||
383 | const char *nick) | ||
384 | { | ||
385 | struct GNUNET_NAMESTORE_RecordData rd; | ||
386 | struct GNUNET_GTK_MainWindowContext *main_ctx; | ||
387 | |||
388 | GNUNET_break (NULL == lctx->nick); | ||
389 | lctx->nick = GNUNET_strdup (nick); | ||
390 | /* again, show progress indicator, this should be fast though... */ | ||
391 | lctx->progress_dialog_builder | ||
392 | = GNUNET_GTK_get_new_builder | ||
393 | ("gnunet_fs_gtk_pseu_progress_dialog.glade", | ||
394 | lctx); | ||
395 | lctx->progress_dialog | ||
396 | = GTK_WIDGET (gtk_builder_get_object | ||
397 | (lctx->progress_dialog_builder, | ||
398 | "GNUNET_FS_GTK_pseu_progress_dialog")); | ||
399 | /* show the window */ | ||
400 | gtk_window_present (GTK_WINDOW (lctx->progress_dialog)); | ||
401 | memset (&rd, 0, sizeof (rd)); | ||
402 | rd.data_size = sizeof (struct GNUNET_CRYPTO_EccPublicKey); | ||
403 | rd.data = &lctx->pkey; | ||
404 | rd.flags = GNUNET_NAMESTORE_RF_PRIVATE; | ||
405 | rd.expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us; | ||
406 | rd.record_type = GNUNET_NAMESTORE_TYPE_PKEY; | ||
407 | main_ctx = GNUNET_FS_GTK_get_main_context (); | ||
408 | lctx->namestore = GNUNET_NAMESTORE_connect (main_ctx->cfg); | ||
409 | GNUNET_assert (NULL != lctx->namestore); | ||
410 | lctx->qe = GNUNET_NAMESTORE_records_store (lctx->namestore, | ||
411 | main_ctx->sks_zone, | ||
412 | nick, | ||
413 | 1, &rd, | ||
414 | &store_continuation, lctx); | ||
415 | } | ||
416 | |||
417 | |||
418 | /** | ||
419 | * User clicked on the 'execute' button in nickname dialog. | ||
420 | * Store the selected namespace in the "sks-fs" zone under | ||
421 | * the given nickname. | ||
422 | * | ||
423 | * @param button the "execute" button | ||
424 | * @param user_data the `struct PseuLookupContext` | ||
425 | */ | ||
426 | void | ||
427 | GNUNET_GTK_enter_nick_window_execute_button_clicked_cb (GtkButton * button, | ||
428 | gpointer user_data) | ||
429 | { | ||
430 | struct PseuLookupContext *lctx = user_data; | ||
431 | GtkEntry *entry; | ||
432 | const char *nick; | ||
433 | |||
434 | entry = GTK_ENTRY (gtk_builder_get_object | ||
435 | (lctx->nick_dialog_builder, | ||
436 | "GNUNET_GTK_enter_nick_window_nick_entry")); | ||
437 | nick = gtk_entry_get_text (entry); | ||
438 | if ( (NULL == nick) || | ||
439 | (0 == strlen (nick) )) | ||
440 | { | ||
441 | GNUNET_break (0); | ||
442 | abort_pseu_lookup (lctx); | ||
443 | return; | ||
444 | } | ||
445 | save_pseudonym_with_nick (lctx, nick); | ||
446 | gtk_widget_destroy (lctx->nick_dialog); | ||
447 | g_object_unref (G_OBJECT (lctx->nick_dialog_builder)); | ||
448 | lctx->nick_dialog_builder = NULL; | ||
449 | } | ||
450 | |||
451 | |||
452 | /** | ||
453 | * User edited the nickname. Update sensitivity of the execute button. | ||
454 | * | ||
455 | * @param widget the entry that was changed | ||
456 | * @param user_data the `struct PseuLookupContext` | ||
457 | */ | ||
458 | void | ||
459 | GNUNET_GTK_enter_nick_window_nick_entry_changed_cb (GtkWidget *widget, | ||
460 | gpointer user_data) | ||
461 | { | ||
462 | struct PseuLookupContext *lctx = user_data; | ||
463 | const gchar *new_text; | ||
464 | GtkButton * button; | ||
465 | |||
466 | new_text = gtk_entry_get_text (GTK_ENTRY (widget)); | ||
467 | button = GTK_BUTTON (gtk_builder_get_object (lctx->nick_dialog_builder, | ||
468 | "GNUNET_GTK_enter_nick_window_execute_button")); | ||
469 | gtk_widget_set_sensitive (GTK_WIDGET (button), | ||
470 | (GNUNET_OK == GNUNET_DNSPARSER_check_label (new_text)) ? TRUE : FALSE); | ||
471 | } | ||
472 | |||
473 | |||
474 | /** | ||
475 | * User clicked on the 'cancel' button in nickname dialog. | ||
476 | * Abort the operation. | ||
477 | * | ||
478 | * @param button the "cancel" button | ||
479 | * @param user_data the `struct PseuLookupContext` | ||
480 | */ | ||
481 | void | ||
482 | GNUNET_GTK_enter_nick_window_cancel_button_clicked_cb (GtkButton * button, | ||
483 | gpointer user_data) | ||
484 | { | ||
485 | struct PseuLookupContext *lctx = user_data; | ||
486 | |||
487 | abort_pseu_lookup (lctx); | ||
488 | } | ||
489 | |||
490 | |||
491 | /** | ||
492 | * Run the dialog asking the user to specify a nickname for | ||
493 | * the namespace. | ||
494 | * | ||
495 | * @param lctx namespace request we are processing | ||
496 | */ | ||
497 | static void | ||
498 | ask_for_nickname (struct PseuLookupContext *lctx) | ||
499 | { | ||
500 | /* setup the dialog and get the widgets we need most */ | ||
501 | lctx->nick_dialog_builder = GNUNET_GTK_get_new_builder ("gnunet_fs_gtk_enter_nick_dialog.glade", | ||
502 | lctx); | ||
503 | lctx->progress_dialog = GTK_WIDGET (gtk_builder_get_object (lctx->progress_dialog_builder, | ||
504 | "GNUNET_GTK_enter_nick_window")); | ||
505 | /* show the window */ | ||
506 | gtk_window_present (GTK_WINDOW (lctx->progress_dialog)); | ||
507 | } | ||
508 | |||
509 | |||
510 | /** | ||
323 | * Iterator called on obtained result for a GNS lookup for | 511 | * Iterator called on obtained result for a GNS lookup for |
324 | * the PSEU lookup when "saving" a zone. The actual saving | 512 | * the PSEU lookup when "saving" a zone. The actual saving |
325 | * should already have happened via the shortening of GNS, | 513 | * should already have happened via the shortening of GNS, |
326 | * so we only need to clean up. | 514 | * so we only need to clean up. |
327 | * | 515 | * |
328 | * FIXME: this is a drastic simplification, as shortening | ||
329 | * may fail (name used, PSEU record not found); in those | ||
330 | * cases, we should _still_ do something here... | ||
331 | * | ||
332 | * @param cls closure with the `struct PseuLookupContext` | 516 | * @param cls closure with the `struct PseuLookupContext` |
333 | * @param rd_count number of records in @a rd | 517 | * @param rd_count number of records in @a rd |
334 | * @param rd the records in reply | 518 | * @param rd the records in reply |
@@ -339,10 +523,97 @@ lookup_finished (void *cls, | |||
339 | const struct GNUNET_NAMESTORE_RecordData *rd) | 523 | const struct GNUNET_NAMESTORE_RecordData *rd) |
340 | { | 524 | { |
341 | struct PseuLookupContext *lctx = cls; | 525 | struct PseuLookupContext *lctx = cls; |
526 | unsigned int i; | ||
527 | const char *nick; | ||
342 | 528 | ||
343 | /* FIXME: might want to give visual feedback to the user here */ | ||
344 | lctx->lr = NULL; | 529 | lctx->lr = NULL; |
345 | abort_pseu_lookup (lctx); | 530 | if (NULL != lctx->progress_dialog_builder) |
531 | { | ||
532 | gtk_widget_destroy (lctx->progress_dialog); | ||
533 | g_object_unref (G_OBJECT (lctx->progress_dialog_builder)); | ||
534 | lctx->progress_dialog_builder = NULL; | ||
535 | } | ||
536 | for (i=0;i<rd_count;i++) | ||
537 | { | ||
538 | if (GNUNET_NAMESTORE_TYPE_PSEU == rd[i].record_type) | ||
539 | { | ||
540 | nick = rd[i].data; | ||
541 | if ('\0' != nick[rd[i].data_size - 1]) | ||
542 | { | ||
543 | GNUNET_break (0); | ||
544 | continue; | ||
545 | } | ||
546 | save_pseudonym_with_nick (lctx, | ||
547 | nick); | ||
548 | return; | ||
549 | } | ||
550 | } | ||
551 | /* no valid PSEU record found */ | ||
552 | ask_for_nickname (lctx); | ||
553 | } | ||
554 | |||
555 | |||
556 | /** | ||
557 | * User clicked on the 'cancel' button of the progress dialog. | ||
558 | * Cancel the operation. | ||
559 | * | ||
560 | * @param button the cancel button | ||
561 | * @param user_data the `struct PseuLookupContext` of our window | ||
562 | */ | ||
563 | void | ||
564 | GNUNET_FS_GTK_pseu_progress_dialog_cancel_button_clicked_cb (GtkButton *button, | ||
565 | gpointer user_data) | ||
566 | { | ||
567 | struct PseuLookupContext *lctx = user_data; | ||
568 | |||
569 | if (NULL != lctx->progress_dialog_builder) | ||
570 | { | ||
571 | gtk_widget_destroy (lctx->progress_dialog); | ||
572 | g_object_unref (G_OBJECT (lctx->progress_dialog_builder)); | ||
573 | lctx->progress_dialog_builder = NULL; | ||
574 | } | ||
575 | if (NULL != lctx->nick) | ||
576 | abort_pseu_lookup (lctx); | ||
577 | else | ||
578 | ask_for_nickname (lctx); | ||
579 | } | ||
580 | |||
581 | |||
582 | /** | ||
583 | * User attempted to close the nick dialog. Refuse. | ||
584 | * | ||
585 | * @param widget the widget emitting the event | ||
586 | * @param event the event | ||
587 | * @param cls progress dialog context of our window | ||
588 | * @return TRUE to refuse to close | ||
589 | */ | ||
590 | gboolean | ||
591 | GNUNET_GTK_enter_nick_window_delete_event_cb (GtkWidget *widget, | ||
592 | GdkEvent * event, | ||
593 | void *cls) | ||
594 | { | ||
595 | /* Don't allow GTK to kill the window, user must click execute or cancel */ | ||
596 | gdk_beep (); | ||
597 | return TRUE; | ||
598 | } | ||
599 | |||
600 | |||
601 | /** | ||
602 | * User attempted to close the progress dialog. Refuse. | ||
603 | * | ||
604 | * @param widget the widget emitting the event | ||
605 | * @param event the event | ||
606 | * @param cls progress dialog context of our window | ||
607 | * @return TRUE to refuse to close | ||
608 | */ | ||
609 | gboolean | ||
610 | GNUNET_FS_GTK_pseu_progress_dialog_delete_event_cb (GtkWidget *widget, | ||
611 | GdkEvent * event, | ||
612 | void *cls) | ||
613 | { | ||
614 | /* Don't allow GTK to kill the window, until the search is finished */ | ||
615 | gdk_beep (); | ||
616 | return TRUE; | ||
346 | } | 617 | } |
347 | 618 | ||
348 | 619 | ||
@@ -353,7 +624,6 @@ lookup_finished (void *cls, | |||
353 | * @param button the "save" button | 624 | * @param button the "save" button |
354 | * @param user_data the main window context builder | 625 | * @param user_data the main window context builder |
355 | */ | 626 | */ |
356 | |||
357 | void | 627 | void |
358 | GNUNET_FS_GTK_save_button_clicked_cb (GtkButton * button, | 628 | GNUNET_FS_GTK_save_button_clicked_cb (GtkButton * button, |
359 | gpointer user_data) | 629 | gpointer user_data) |
@@ -364,12 +634,20 @@ GNUNET_FS_GTK_save_button_clicked_cb (GtkButton * button, | |||
364 | struct GNUNET_CRYPTO_EccPublicKey pkey; | 634 | struct GNUNET_CRYPTO_EccPublicKey pkey; |
365 | int ret; | 635 | int ret; |
366 | struct PseuLookupContext *lctx; | 636 | struct PseuLookupContext *lctx; |
637 | guint anonymity_level; | ||
367 | 638 | ||
368 | if (NULL == main_ctx->gns) | 639 | if (NULL == main_ctx->gns) |
369 | { | 640 | { |
370 | GNUNET_break (0); | 641 | GNUNET_break (0); |
371 | return; | 642 | return; |
372 | } | 643 | } |
644 | /* get anonymity level */ | ||
645 | if (!GNUNET_GTK_get_selected_anonymity_level | ||
646 | (main_ctx->builder, "main_window_search_anonymity_combobox", &anonymity_level)) | ||
647 | { | ||
648 | GNUNET_break (0); | ||
649 | return; | ||
650 | } | ||
373 | widget = GTK_COMBO_BOX (GNUNET_FS_GTK_get_main_window_object | 651 | widget = GTK_COMBO_BOX (GNUNET_FS_GTK_get_main_window_object |
374 | ("main_window_search_namespace_combobox")); | 652 | ("main_window_search_namespace_combobox")); |
375 | text = gtk_entry_get_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (widget)))); | 653 | text = gtk_entry_get_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (widget)))); |
@@ -380,20 +658,37 @@ GNUNET_FS_GTK_save_button_clicked_cb (GtkButton * button, | |||
380 | return; | 658 | return; |
381 | } | 659 | } |
382 | lctx = GNUNET_new (struct PseuLookupContext); | 660 | lctx = GNUNET_new (struct PseuLookupContext); |
661 | lctx->pkey = pkey; | ||
383 | lctx->main_ctx = main_ctx; | 662 | lctx->main_ctx = main_ctx; |
384 | GNUNET_CONTAINER_DLL_insert (main_ctx->lctx_head, | 663 | GNUNET_CONTAINER_DLL_insert (main_ctx->lctx_head, |
385 | main_ctx->lctx_tail, | 664 | main_ctx->lctx_tail, |
386 | lctx); | 665 | lctx); |
387 | lctx->lr = GNUNET_GNS_lookup (main_ctx->gns, | 666 | |
388 | GNUNET_GNS_MASTERZONE_STR, | 667 | if (0 == anonymity_level) |
389 | &pkey, | 668 | { |
390 | GNUNET_NAMESTORE_TYPE_PSEU, | 669 | /* setup the dialog and get the widgets we need most */ |
391 | GNUNET_NO, | 670 | lctx->progress_dialog_builder = GNUNET_GTK_get_new_builder ("gnunet_fs_gtk_pseu_progress_dialog.glade", |
392 | main_ctx->sks_zone /* FIXME: may want more explicit | 671 | lctx); |
393 | control than using shortening here */, | 672 | lctx->progress_dialog = GTK_WIDGET (gtk_builder_get_object (lctx->progress_dialog_builder, |
394 | &lookup_finished, | 673 | "GNUNET_FS_GTK_pseu_progress_dialog")); |
395 | lctx); | 674 | /* show the window */ |
396 | /* give visual feedback that something is happening */ | 675 | gtk_window_present (GTK_WINDOW (lctx->progress_dialog)); |
676 | lctx->lr = GNUNET_GNS_lookup (main_ctx->gns, | ||
677 | GNUNET_GNS_MASTERZONE_STR, | ||
678 | &pkey, | ||
679 | GNUNET_NAMESTORE_TYPE_PSEU, | ||
680 | GNUNET_NO, | ||
681 | NULL, | ||
682 | &lookup_finished, | ||
683 | lctx); | ||
684 | } | ||
685 | else | ||
686 | { | ||
687 | /* anonymous operation; cannot use GNS/DHT, so user | ||
688 | must make a suggestion himself */ | ||
689 | ask_for_nickname (lctx); | ||
690 | } | ||
691 | /* do not allow save again just yet */ | ||
397 | gtk_widget_set_sensitive (GTK_WIDGET (button), | 692 | gtk_widget_set_sensitive (GTK_WIDGET (button), |
398 | FALSE); | 693 | FALSE); |
399 | } | 694 | } |