aboutsummaryrefslogtreecommitdiff
path: root/src/fs/gnunet-fs-gtk_main-window-search.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fs/gnunet-fs-gtk_main-window-search.c')
-rw-r--r--src/fs/gnunet-fs-gtk_main-window-search.c329
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 */
356static void
357store_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 */
381static void
382save_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 */
426void
427GNUNET_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 */
458void
459GNUNET_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 */
481void
482GNUNET_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 */
497static void
498ask_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 */
563void
564GNUNET_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 */
590gboolean
591GNUNET_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 */
609gboolean
610GNUNET_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
357void 627void
358GNUNET_FS_GTK_save_button_clicked_cb (GtkButton * button, 628GNUNET_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}