aboutsummaryrefslogtreecommitdiff
path: root/src/namestore/gnunet-namestore-gtk.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/namestore/gnunet-namestore-gtk.c')
-rw-r--r--src/namestore/gnunet-namestore-gtk.c1085
1 files changed, 755 insertions, 330 deletions
diff --git a/src/namestore/gnunet-namestore-gtk.c b/src/namestore/gnunet-namestore-gtk.c
index 0cec62b4..d6f6e53d 100644
--- a/src/namestore/gnunet-namestore-gtk.c
+++ b/src/namestore/gnunet-namestore-gtk.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet 2 This file is part of GNUnet
3 Copyright (C) 2012, 2013, 2014 GNUnet e.V. 3 Copyright (C) 2012, 2013, 2014, 2018 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -36,6 +36,12 @@
36 * Text we use for the 'name' entry for the user to select 36 * Text we use for the 'name' entry for the user to select
37 * for creating a new name. 37 * for creating a new name.
38 */ 38 */
39#define NEW_ZONE_STR gettext_noop ("<new zone>")
40
41/**
42 * Text we use for the 'name' entry for the user to select
43 * for creating a new name.
44 */
39#define NEW_NAME_STR gettext_noop ("<new name>") 45#define NEW_NAME_STR gettext_noop ("<new name>")
40 46
41/** 47/**
@@ -295,12 +301,12 @@ struct RecordInfo
295 void *data; 301 void *data;
296 302
297 /** 303 /**
298 * Number of bytes in 'data'. 304 * Number of bytes in @e data.
299 */ 305 */
300 size_t data_size; 306 size_t data_size;
301 307
302 /** 308 /**
303 * Number of records serialized in 'data'. 309 * Number of records serialized in @e data.
304 */ 310 */
305 unsigned int rd_count; 311 unsigned int rd_count;
306 312
@@ -308,6 +314,49 @@ struct RecordInfo
308 314
309 315
310/** 316/**
317 * Representation of a TLD, mapping the respective TLD string
318 * (i.e. ".gnu") to the respective public key of the zone.
319 */
320struct GNS_TopLevelDomain
321{
322
323 /**
324 * Kept in a DLL, as there are unlikely enough of these to
325 * warrant a hash map.
326 */
327 struct GNS_TopLevelDomain *next;
328
329 /**
330 * Kept in a DLL, as there are unlikely enough of these to
331 * warrant a hash map.
332 */
333 struct GNS_TopLevelDomain *prev;
334
335 /**
336 * Public key associated with the @a tld.
337 */
338 struct GNUNET_CRYPTO_EddsaPublicKey pkey;
339
340 /**
341 * Top-level domain as a string, including leading ".".
342 */
343 char *tld;
344
345};
346
347
348
349/**
350 * Head of DLL of TLDs we map to GNS zones.
351 */
352static struct GNS_TopLevelDomain *tld_head;
353
354/**
355 * Tail of DLL of TLDs we map to GNS zones.
356 */
357static struct GNS_TopLevelDomain *tld_tail;
358
359/**
311 * When do NICK records expire? 360 * When do NICK records expire?
312 */ 361 */
313static struct GNUNET_TIME_Relative nick_expiration_time; 362static struct GNUNET_TIME_Relative nick_expiration_time;
@@ -379,10 +428,9 @@ static struct GNUNET_CRYPTO_EcdsaPublicKey pubkey;
379static char *current_pseudonym; 428static char *current_pseudonym;
380 429
381/** 430/**
382 * Pointer to name of the configuration option that gives the 431 * Currently selected entry in #zone_liststore.
383 * zone key for the zone we are editing right now.
384 */ 432 */
385static char *current_zone_option; 433static GtkTreeIter zone_iter;
386 434
387/** 435/**
388 * List of all known zones/egos. 436 * List of all known zones/egos.
@@ -405,11 +453,26 @@ static struct GNUNET_GTK_MainLoop *ml;
405static GtkWidget *main_window; 453static GtkWidget *main_window;
406 454
407/** 455/**
456 * Status label in main window.
457 */
458static GtkLabel *status_label;
459
460/**
461 * Zone combo box in the main window.
462 */
463static GtkComboBox *zone_combo_box;
464
465/**
408 * Our configuration. 466 * Our configuration.
409 */ 467 */
410static const struct GNUNET_CONFIGURATION_Handle *cfg; 468static const struct GNUNET_CONFIGURATION_Handle *cfg;
411 469
412/** 470/**
471 * Ongoing identity operation.
472 */
473struct GNUNET_IDENTITY_Operation *iop;
474
475/**
413 * Global return value (for success/failure of gnunet-setup). 476 * Global return value (for success/failure of gnunet-setup).
414 */ 477 */
415static int gret; 478static int gret;
@@ -446,15 +509,9 @@ create_qrcode (unsigned int scale)
446 QRinput * qri; 509 QRinput * qri;
447 QRcode *qrc; 510 QRcode *qrc;
448 char *str; 511 char *str;
449 const gchar *pseu;
450 GtkEntry *entry;
451 GdkPixbuf *pb; 512 GdkPixbuf *pb;
452 unsigned int x;
453 unsigned int y;
454 unsigned int off;
455 guchar *pixels; 513 guchar *pixels;
456 int n_channels; 514 int n_channels;
457 int c;
458 const char *dir; 515 const char *dir;
459 char *fn; 516 char *fn;
460 unsigned int size; 517 unsigned int size;
@@ -467,12 +524,10 @@ create_qrcode (unsigned int scale)
467 "QRinput_new2"); 524 "QRinput_new2");
468 return NULL; 525 return NULL;
469 } 526 }
470 entry = GTK_ENTRY (get_object ("gnunet_namestore_gtk_pseu_entry"));
471 pseu = gtk_entry_get_text (GTK_ENTRY(entry));
472 GNUNET_asprintf (&str, 527 GNUNET_asprintf (&str,
473 "gnunet://gns/%s/%s", 528 "gnunet://gns/%s/%s",
474 GNUNET_GNSRECORD_z2s (&pubkey), 529 GNUNET_GNSRECORD_z2s (&pubkey),
475 pseu); 530 current_pseudonym);
476 upper = GNUNET_strdup (str); 531 upper = GNUNET_strdup (str);
477 GNUNET_STRINGS_utf8_toupper (str, 532 GNUNET_STRINGS_utf8_toupper (str,
478 upper); 533 upper);
@@ -521,17 +576,18 @@ create_qrcode (unsigned int scale)
521 GNUNET_free (fn); 576 GNUNET_free (fn);
522 if (NULL == pb) 577 if (NULL == pb)
523 { 578 {
579 QRcode_free (qrc);
524 QRinput_free (qri); 580 QRinput_free (qri);
525 return NULL; 581 return NULL;
526 } 582 }
527 pixels = gdk_pixbuf_get_pixels (pb); 583 pixels = gdk_pixbuf_get_pixels (pb);
528 n_channels = gdk_pixbuf_get_n_channels (pb); 584 n_channels = gdk_pixbuf_get_n_channels (pb);
529 for (x=0;x<size;x++) 585 for (unsigned int x=0;x<size;x++)
530 for (y=0;y<size;y++) 586 for (unsigned int y=0;y<size;y++)
531 { 587 {
532 off = (x * qrc->width / size) + 588 unsigned int off = (x * qrc->width / size) +
533 (y * qrc->width / size) * qrc->width; 589 (y * qrc->width / size) * qrc->width;
534 for (c = 0; c < n_channels; c++) 590 for (int c = 0; c < n_channels; c++)
535 pixels[(y * size + x) * n_channels + c] = (0 == (qrc->data[off] & 1)) ? 0xFF : 0; 591 pixels[(y * size + x) * n_channels + c] = (0 == (qrc->data[off] & 1)) ? 0xFF : 0;
536 } 592 }
537 QRcode_free (qrc); 593 QRcode_free (qrc);
@@ -627,12 +683,8 @@ gnunet_namestore_gtk_qr_saveas_button_clicked_cb (GtkButton *button,
627{ 683{
628 GtkBuilder *builder; 684 GtkBuilder *builder;
629 GtkWindow *dialog; 685 GtkWindow *dialog;
630 const gchar *pseu;
631 GtkEntry *entry;
632 char *suggestion; 686 char *suggestion;
633 687
634 entry = GTK_ENTRY (get_object ("gnunet_namestore_gtk_pseu_entry"));
635 pseu = gtk_entry_get_text (GTK_ENTRY(entry));
636 builder = 688 builder =
637 GNUNET_GTK_get_new_builder ("gnunet_namestore_gtk_qr_save_as_dialog.glade", 689 GNUNET_GTK_get_new_builder ("gnunet_namestore_gtk_qr_save_as_dialog.glade",
638 NULL); 690 NULL);
@@ -643,9 +695,10 @@ gnunet_namestore_gtk_qr_saveas_button_clicked_cb (GtkButton *button,
643 } 695 }
644 GNUNET_asprintf (&suggestion, 696 GNUNET_asprintf (&suggestion,
645 "%s.png", 697 "%s.png",
646 pseu); 698 current_pseudonym);
647 dialog = GTK_WINDOW (gtk_builder_get_object 699 dialog = GTK_WINDOW (gtk_builder_get_object
648 (builder, "gnunet_namestore_gtk_qr_save_as_dialog")); 700 (builder,
701 "gnunet_namestore_gtk_qr_save_as_dialog"));
649 gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), 702 gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog),
650 suggestion); 703 suggestion);
651 GNUNET_free (suggestion); 704 GNUNET_free (suggestion);
@@ -667,11 +720,10 @@ check_record_permitted (unsigned int rd_count,
667 const struct GNUNET_GNSRECORD_Data *rd, 720 const struct GNUNET_GNSRECORD_Data *rd,
668 gint n_type) 721 gint n_type)
669{ 722{
670 unsigned int i;
671 unsigned int nick; 723 unsigned int nick;
672 724
673 nick = 0; 725 nick = 0;
674 for (i=0;i<rd_count;i++) 726 for (unsigned int i=0;i<rd_count;i++)
675 { 727 {
676 switch (rd[i].record_type) 728 switch (rd[i].record_type)
677 { 729 {
@@ -747,7 +799,7 @@ operation_done_cont (void *cls,
747 * Release the record info. 799 * Release the record info.
748 * 800 *
749 * @param cls NULL 801 * @param cls NULL
750 * @param key unused 802 * @param key key for @a value in the #n2r map
751 * @param value a RecordInfo to release 803 * @param value a RecordInfo to release
752 * @return #GNUNET_OK (continue to iterate) 804 * @return #GNUNET_OK (continue to iterate)
753 */ 805 */
@@ -757,12 +809,15 @@ release_ri (void *cls,
757 void *value) 809 void *value)
758{ 810{
759 struct RecordInfo *ri = value; 811 struct RecordInfo *ri = value;
812 (void) cls;
760 813
761 gtk_tree_row_reference_free (ri->rr); 814 gtk_tree_row_reference_free (ri->rr);
762 GNUNET_free_non_null (ri->data); 815 GNUNET_free_non_null (ri->data);
763 GNUNET_free (ri->name); 816 GNUNET_free (ri->name);
764 GNUNET_break (GNUNET_YES == 817 GNUNET_break (GNUNET_YES ==
765 GNUNET_CONTAINER_multihashmap_remove (n2r, key, ri)); 818 GNUNET_CONTAINER_multihashmap_remove (n2r,
819 key,
820 ri));
766 GNUNET_free (ri); 821 GNUNET_free (ri);
767 return GNUNET_OK; 822 return GNUNET_OK;
768} 823}
@@ -774,24 +829,17 @@ release_ri (void *cls,
774static void 829static void
775clear_zone_view () 830clear_zone_view ()
776{ 831{
777 GtkEntry *pseu_entry;
778
779 pseu_entry = GTK_ENTRY((get_object ("gnunet_namestore_gtk_pseu_entry")));
780 gtk_entry_set_text (pseu_entry, "");
781 GNUNET_free_non_null (current_zone_option);
782 current_zone_option = NULL;
783 GNUNET_free_non_null (current_pseudonym); 832 GNUNET_free_non_null (current_pseudonym);
784 current_pseudonym = NULL; 833 current_pseudonym = NULL;
785 GNUNET_CONTAINER_multihashmap_iterate (n2r, 834 GNUNET_CONTAINER_multihashmap_iterate (n2r,
786 &release_ri, 835 &release_ri,
787 NULL); 836 NULL);
788 gtk_widget_hide (GTK_WIDGET (get_object ("gnunet_namestore_gtk_zone_combobox"))); 837 gtk_widget_hide (GTK_WIDGET (zone_combo_box));
789 gtk_widget_show (GTK_WIDGET (get_object ("gnunet_namestore_gtk_status_label"))); 838 gtk_widget_show (GTK_WIDGET (status_label));
790 gtk_widget_hide (GTK_WIDGET (get_object ("gnunet_namestore_gtk_scrolledwindow"))); 839 gtk_widget_hide (GTK_WIDGET (get_object ("gnunet_namestore_gtk_scrolledwindow")));
791 gtk_widget_hide (GTK_WIDGET (get_object ("gnunet_namestore_gtk_qr_image"))); 840 gtk_widget_hide (GTK_WIDGET (get_object ("gnunet_namestore_gtk_qr_image")));
792 gtk_widget_hide (GTK_WIDGET (get_object ("gnunet_namestore_gtk_qr_saveas_button"))); 841 gtk_widget_hide (GTK_WIDGET (get_object ("gnunet_namestore_gtk_qr_saveas_button")));
793 gtk_widget_hide (GTK_WIDGET (get_object ("gnunet_namestore_gtk_qr_vseparator"))); 842 gtk_widget_hide (GTK_WIDGET (get_object ("gnunet_namestore_gtk_qr_vseparator")));
794 gtk_widget_hide (GTK_WIDGET (get_object ("gnunet_namestore_gtk_pseu_hbox")));
795 gtk_tree_store_clear (ts); 843 gtk_tree_store_clear (ts);
796} 844}
797 845
@@ -816,7 +864,10 @@ show_error_message (const char *title,
816 _("%s\n%s\n"), 864 _("%s\n%s\n"),
817 title, 865 title,
818 emsg)); 866 emsg));
819 g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL); 867 g_signal_connect (dialog,
868 "response",
869 G_CALLBACK (gtk_widget_destroy),
870 NULL);
820 gtk_widget_show_all (GTK_WIDGET(dialog)); 871 gtk_widget_show_all (GTK_WIDGET(dialog));
821} 872}
822 873
@@ -853,9 +904,12 @@ merge_with_existing_records (void *cls,
853 struct GNUNET_GNSRECORD_Data rd_new[rd_count + 1]; 904 struct GNUNET_GNSRECORD_Data rd_new[rd_count + 1];
854 struct OperationContext *oc; 905 struct OperationContext *oc;
855 906
856 GNUNET_CONTAINER_DLL_remove (moc_head, moc_tail, moc); 907 GNUNET_CONTAINER_DLL_remove (moc_head,
908 moc_tail,
909 moc);
857 if (GNUNET_OK != 910 if (GNUNET_OK !=
858 check_record_permitted (rd_count, rd, 911 check_record_permitted (rd_count,
912 rd,
859 edc->record_type)) 913 edc->record_type))
860 { 914 {
861 show_error_message (_("Record combination not permitted"), 915 show_error_message (_("Record combination not permitted"),
@@ -866,17 +920,22 @@ merge_with_existing_records (void *cls,
866 return; 920 return;
867 } 921 }
868 922
869 memcpy (rd_new, rd, rd_count * sizeof (struct GNUNET_GNSRECORD_Data)); 923 memcpy (rd_new,
924 rd,
925 rd_count * sizeof (struct GNUNET_GNSRECORD_Data));
870 rd_new[rd_count] = moc->rd; 926 rd_new[rd_count] = moc->rd;
871 /* FIXME: sanity-check merge... */ 927 /* FIXME: sanity-check merge... */
872 oc = GNUNET_new (struct OperationContext); 928 oc = GNUNET_new (struct OperationContext);
873 GNUNET_CONTAINER_DLL_insert (oc_head, oc_tail, oc); 929 GNUNET_CONTAINER_DLL_insert (oc_head,
930 oc_tail,
931 oc);
874 oc->qe = GNUNET_NAMESTORE_records_store (namestore, 932 oc->qe = GNUNET_NAMESTORE_records_store (namestore,
875 &moc->pk, 933 &moc->pk,
876 edc->name, 934 edc->name,
877 rd_count + 1, 935 rd_count + 1,
878 rd_new, 936 rd_new,
879 &operation_done_cont, oc); 937 &operation_done_cont,
938 oc);
880 GNUNET_free (moc->data); 939 GNUNET_free (moc->data);
881 GNUNET_free (moc); 940 GNUNET_free (moc);
882 free_edit_dialog_context (edc); 941 free_edit_dialog_context (edc);
@@ -910,7 +969,9 @@ handle_records_for_merge (void *cls,
910 } 969 }
911 GNUNET_NAMESTORE_zone_iteration_stop (moc->it); 970 GNUNET_NAMESTORE_zone_iteration_stop (moc->it);
912 moc->it = NULL; 971 moc->it = NULL;
913 merge_with_existing_records (moc, rd_count, rd); 972 merge_with_existing_records (moc,
973 rd_count,
974 rd);
914} 975}
915 976
916 977
@@ -1025,12 +1086,17 @@ edit_dialog_continuation (struct GNUNET_GTK_NAMESTORE_PluginEnvironment *edc,
1025 struct GNUNET_GNSRECORD_Data rd_new[rd_count - 1]; 1086 struct GNUNET_GNSRECORD_Data rd_new[rd_count - 1];
1026 1087
1027 GNUNET_assert (NULL != ri); 1088 GNUNET_assert (NULL != ri);
1028 memcpy (rd_new, rd_old, (rd_count - 1) * sizeof (struct GNUNET_GNSRECORD_Data)); 1089 memcpy (rd_new,
1090 rd_old,
1091 (rd_count - 1) * sizeof (struct GNUNET_GNSRECORD_Data));
1029 rd_new[edc->off] = rd_old[rd_count - 1]; 1092 rd_new[edc->off] = rd_old[rd_count - 1];
1030 oc = GNUNET_new (struct OperationContext); 1093 oc = GNUNET_new (struct OperationContext);
1031 GNUNET_CONTAINER_DLL_insert (oc_head, oc_tail, oc); 1094 GNUNET_CONTAINER_DLL_insert (oc_head,
1095 oc_tail,
1096 oc);
1032 oc->qe = GNUNET_NAMESTORE_records_store (namestore, 1097 oc->qe = GNUNET_NAMESTORE_records_store (namestore,
1033 pkey, edc->name, 1098 pkey,
1099 edc->name,
1034 rd_count - 1, 1100 rd_count - 1,
1035 rd_new, 1101 rd_new,
1036 &operation_done_cont, oc); 1102 &operation_done_cont, oc);
@@ -1044,19 +1110,24 @@ edit_dialog_continuation (struct GNUNET_GTK_NAMESTORE_PluginEnvironment *edc,
1044 case GTK_RESPONSE_OK: 1110 case GTK_RESPONSE_OK:
1045 /* update model */ 1111 /* update model */
1046 if (0 == strcmp (edc->new_zone_option, 1112 if (0 == strcmp (edc->new_zone_option,
1047 current_zone_option)) 1113 current_pseudonym))
1048 { 1114 {
1049 if (GNUNET_YES == edc->old_record_in_namestore) 1115 if (GNUNET_YES == edc->old_record_in_namestore)
1050 { 1116 {
1051 struct GNUNET_GNSRECORD_Data rd_new[rd_count]; 1117 struct GNUNET_GNSRECORD_Data rd_new[rd_count];
1052 1118
1053 GNUNET_assert (NULL != ri); 1119 GNUNET_assert (NULL != ri);
1054 memcpy (rd_new, rd_old, rd_count * sizeof (struct GNUNET_GNSRECORD_Data)); 1120 memcpy (rd_new,
1121 rd_old,
1122 rd_count * sizeof (struct GNUNET_GNSRECORD_Data));
1055 rd_new[edc->off] = rd; 1123 rd_new[edc->off] = rd;
1056 oc = GNUNET_new (struct OperationContext); 1124 oc = GNUNET_new (struct OperationContext);
1057 GNUNET_CONTAINER_DLL_insert (oc_head, oc_tail, oc); 1125 GNUNET_CONTAINER_DLL_insert (oc_head,
1126 oc_tail,
1127 oc);
1058 oc->qe = GNUNET_NAMESTORE_records_store (namestore, 1128 oc->qe = GNUNET_NAMESTORE_records_store (namestore,
1059 pkey, edc->name, 1129 pkey,
1130 edc->name,
1060 rd_count, 1131 rd_count,
1061 rd_new, 1132 rd_new,
1062 &operation_done_cont, oc); 1133 &operation_done_cont, oc);
@@ -1065,12 +1136,17 @@ edit_dialog_continuation (struct GNUNET_GTK_NAMESTORE_PluginEnvironment *edc,
1065 { 1136 {
1066 struct GNUNET_GNSRECORD_Data rd_new[rd_count + 1]; 1137 struct GNUNET_GNSRECORD_Data rd_new[rd_count + 1];
1067 1138
1068 memcpy (rd_new, rd_old, rd_count * sizeof (struct GNUNET_GNSRECORD_Data)); 1139 memcpy (rd_new,
1140 rd_old,
1141 rd_count * sizeof (struct GNUNET_GNSRECORD_Data));
1069 rd_new[rd_count] = rd; 1142 rd_new[rd_count] = rd;
1070 oc = GNUNET_new (struct OperationContext); 1143 oc = GNUNET_new (struct OperationContext);
1071 GNUNET_CONTAINER_DLL_insert (oc_head, oc_tail, oc); 1144 GNUNET_CONTAINER_DLL_insert (oc_head,
1145 oc_tail,
1146 oc);
1072 oc->qe = GNUNET_NAMESTORE_records_store (namestore, 1147 oc->qe = GNUNET_NAMESTORE_records_store (namestore,
1073 pkey, edc->name, 1148 pkey,
1149 edc->name,
1074 rd_count + 1, 1150 rd_count + 1,
1075 rd_new, 1151 rd_new,
1076 &operation_done_cont, oc); 1152 &operation_done_cont, oc);
@@ -1094,7 +1170,9 @@ edit_dialog_continuation (struct GNUNET_GTK_NAMESTORE_PluginEnvironment *edc,
1094 moc->rd = rd; 1170 moc->rd = rd;
1095 moc->edc = edc; 1171 moc->edc = edc;
1096 moc->pk = *pk; 1172 moc->pk = *pk;
1097 GNUNET_CONTAINER_DLL_insert (moc_head, moc_tail, moc); 1173 GNUNET_CONTAINER_DLL_insert (moc_head,
1174 moc_tail,
1175 moc);
1098 moc->it = GNUNET_NAMESTORE_zone_iteration_start (namestore, 1176 moc->it = GNUNET_NAMESTORE_zone_iteration_start (namestore,
1099 pk, 1177 pk,
1100 &handle_records_for_merge_error, 1178 &handle_records_for_merge_error,
@@ -1110,12 +1188,17 @@ edit_dialog_continuation (struct GNUNET_GTK_NAMESTORE_PluginEnvironment *edc,
1110 struct GNUNET_GNSRECORD_Data rd_new[rd_count - 1]; 1188 struct GNUNET_GNSRECORD_Data rd_new[rd_count - 1];
1111 1189
1112 GNUNET_assert (NULL != ri); 1190 GNUNET_assert (NULL != ri);
1113 memcpy (rd_new, rd_old, (rd_count - 1) * sizeof (struct GNUNET_GNSRECORD_Data)); 1191 memcpy (rd_new,
1192 rd_old,
1193 (rd_count - 1) * sizeof (struct GNUNET_GNSRECORD_Data));
1114 rd_new[edc->off] = rd_old[rd_count - 1]; 1194 rd_new[edc->off] = rd_old[rd_count - 1];
1115 oc = GNUNET_new (struct OperationContext); 1195 oc = GNUNET_new (struct OperationContext);
1116 GNUNET_CONTAINER_DLL_insert (oc_head, oc_tail, oc); 1196 GNUNET_CONTAINER_DLL_insert (oc_head,
1197 oc_tail,
1198 oc);
1117 oc->qe = GNUNET_NAMESTORE_records_store (namestore, 1199 oc->qe = GNUNET_NAMESTORE_records_store (namestore,
1118 pkey, edc->name, 1200 pkey,
1201 edc->name,
1119 rd_count - 1, 1202 rd_count - 1,
1120 rd_new, 1203 rd_new,
1121 &operation_done_cont, oc); 1204 &operation_done_cont, oc);
@@ -1179,10 +1262,13 @@ check_validity (struct GNUNET_GTK_NAMESTORE_PluginEnvironment *edc)
1179 entry = GTK_EDITABLE (gtk_builder_get_object (edc->builder, 1262 entry = GTK_EDITABLE (gtk_builder_get_object (edc->builder,
1180 "edit_dialog_name_entry")); 1263 "edit_dialog_name_entry"));
1181 name = gtk_editable_get_chars (entry, 0, -1); 1264 name = gtk_editable_get_chars (entry, 0, -1);
1182 if ( (GNUNET_OK != edc->plugin->validate (edc->plugin->cls, 1265 if ( (GNUNET_OK !=
1183 edc->builder)) || 1266 edc->plugin->validate (edc->plugin->cls,
1184 ( (GNUNET_SYSERR == GNUNET_DNSPARSER_check_label (name)) && 1267 edc->builder)) ||
1185 (0 != strcmp (name, GNUNET_GNS_MASTERZONE_STR))) ) 1268 ( (GNUNET_SYSERR ==
1269 GNUNET_DNSPARSER_check_label (name)) &&
1270 (0 != strcmp (name,
1271 GNUNET_GNS_MASTERZONE_STR))) )
1186 { 1272 {
1187 edit_dialog_disable_save (edc); 1273 edit_dialog_disable_save (edc);
1188 return; 1274 return;
@@ -1298,9 +1384,11 @@ edit_dialog_setup_common_elements (struct GNUNET_GTK_NAMESTORE_PluginEnvironment
1298 ls = GTK_LIST_STORE (gtk_combo_box_get_model (cb)); 1384 ls = GTK_LIST_STORE (gtk_combo_box_get_model (cb));
1299 gtk_list_store_insert_with_values (ls, &iter, 1385 gtk_list_store_insert_with_values (ls, &iter,
1300 -1 /* position: append */, 1386 -1 /* position: append */,
1301 0, GNUNET_STRINGS_relative_time_to_string (rt, GNUNET_NO), 1387 0, GNUNET_STRINGS_relative_time_to_string (rt,
1388 GNUNET_NO),
1302 -1); 1389 -1);
1303 gtk_combo_box_set_active_iter (cb, &iter); 1390 gtk_combo_box_set_active_iter (cb,
1391 &iter);
1304 if ( (! edc->n_is_relative) && 1392 if ( (! edc->n_is_relative) &&
1305 (GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us != edc->n_exp_time) ) 1393 (GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us != edc->n_exp_time) )
1306 { 1394 {
@@ -1378,7 +1466,8 @@ edit_dialog_putes_common_elements (struct GNUNET_GTK_NAMESTORE_PluginEnvironment
1378 cb = GTK_COMBO_BOX (gtk_builder_get_object (edc->builder, 1466 cb = GTK_COMBO_BOX (gtk_builder_get_object (edc->builder,
1379 "edit_dialog_expiration_relative_combobox")); 1467 "edit_dialog_expiration_relative_combobox"));
1380 tm = gtk_combo_box_get_model (cb); 1468 tm = gtk_combo_box_get_model (cb);
1381 if (! gtk_combo_box_get_active_iter (cb, &iter)) 1469 if (! gtk_combo_box_get_active_iter (cb,
1470 &iter))
1382 { 1471 {
1383 GNUNET_break (0); 1472 GNUNET_break (0);
1384 return; 1473 return;
@@ -1435,7 +1524,8 @@ edit_dialog_putes_common_elements (struct GNUNET_GTK_NAMESTORE_PluginEnvironment
1435 cb = GTK_COMBO_BOX (gtk_builder_get_object (edc->builder, 1524 cb = GTK_COMBO_BOX (gtk_builder_get_object (edc->builder,
1436 "edit_dialog_zone_combobox")); 1525 "edit_dialog_zone_combobox"));
1437 tm = gtk_combo_box_get_model (cb); 1526 tm = gtk_combo_box_get_model (cb);
1438 if (! gtk_combo_box_get_active_iter (cb, &iter)) 1527 if (! gtk_combo_box_get_active_iter (cb,
1528 &iter))
1439 { 1529 {
1440 GNUNET_break (0); 1530 GNUNET_break (0);
1441 } 1531 }
@@ -1512,14 +1602,12 @@ add_symbols (GtkBuilder *builder,
1512 1602
1513{ 1603{
1514 struct GNUNET_GTK_NAMESTORE_PluginEnvironment *edc = user_data; 1604 struct GNUNET_GTK_NAMESTORE_PluginEnvironment *edc = user_data;
1515 unsigned int i;
1516 GCallback cb; 1605 GCallback cb;
1517 GModule *m;
1518 1606
1519 cb = NULL; 1607 cb = NULL;
1520 if (NULL != edc->plugin->symbols) 1608 if (NULL != edc->plugin->symbols)
1521 { 1609 {
1522 for (i=0; NULL != edc->plugin->symbols[i].name; i++) 1610 for (unsigned int i=0; NULL != edc->plugin->symbols[i].name; i++)
1523 { 1611 {
1524 if (0 == strcmp (handler_name, 1612 if (0 == strcmp (handler_name,
1525 edc->plugin->symbols[i].name)) 1613 edc->plugin->symbols[i].name))
@@ -1531,7 +1619,10 @@ add_symbols (GtkBuilder *builder,
1531 } 1619 }
1532 if (NULL == cb) 1620 if (NULL == cb)
1533 { 1621 {
1534 m = g_module_open (NULL, 0); 1622 GModule *m;
1623
1624 m = g_module_open (NULL,
1625 0);
1535 if (! g_module_symbol (m, 1626 if (! g_module_symbol (m,
1536 handler_name, 1627 handler_name,
1537 (void **) &cb)) 1628 (void **) &cb))
@@ -1586,7 +1677,7 @@ launch_edit_dialog (gint n_type,
1586{ 1677{
1587 struct GNUNET_GTK_NAMESTORE_PluginEnvironment *edc; 1678 struct GNUNET_GTK_NAMESTORE_PluginEnvironment *edc;
1588 1679
1589 if (NULL == current_zone_option) 1680 if (NULL == current_pseudonym)
1590 { 1681 {
1591 GNUNET_break (0); 1682 GNUNET_break (0);
1592 return; 1683 return;
@@ -1618,7 +1709,7 @@ launch_edit_dialog (gint n_type,
1618 edc->ri = ri; 1709 edc->ri = ri;
1619 edc->off = off; 1710 edc->off = off;
1620 edc->name = GNUNET_strdup (name); 1711 edc->name = GNUNET_strdup (name);
1621 edc->new_zone_option = g_strdup (current_zone_option); 1712 edc->new_zone_option = g_strdup (current_pseudonym);
1622 edc->zone_liststore = zone_liststore; 1713 edc->zone_liststore = zone_liststore;
1623 edc->check_validity = &check_validity; 1714 edc->check_validity = &check_validity;
1624 GNUNET_asprintf (&edc->liblow, 1715 GNUNET_asprintf (&edc->liblow,
@@ -1707,8 +1798,7 @@ check_permissions (struct RecordInfo *ri,
1707 1798
1708 1799
1709/** 1800/**
1710 * User selected 'edit' in the popup menu. Edit the 1801 * User selected 'edit' in the popup menu. Edit the selected row.
1711 * selected row.
1712 * 1802 *
1713 * @param widget the GtkTreeView 1803 * @param widget the GtkTreeView
1714 * @param user_data main window builder 1804 * @param user_data main window builder
@@ -1726,7 +1816,9 @@ gnunet_namestore_gtk_popup_edit_button_activate_cb (GtkWidget *widget,
1726 struct GNUNET_HashCode name_hash; 1816 struct GNUNET_HashCode name_hash;
1727 1817
1728 sel = gtk_tree_view_get_selection (tv); 1818 sel = gtk_tree_view_get_selection (tv);
1729 if (! gtk_tree_selection_get_selected (sel, NULL, &iter)) 1819 if (! gtk_tree_selection_get_selected (sel,
1820 NULL,
1821 &iter))
1730 { 1822 {
1731 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1823 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1732 "No row selected\n"); 1824 "No row selected\n");
@@ -1785,7 +1877,9 @@ gnunet_namestore_gtk_type_cellrenderercombo_changed_cb (GtkCellRendererText *tex
1785 GNS_TYPE_TO_NAME_LISTSTORE_COLUMN_TYPE, &type, 1877 GNS_TYPE_TO_NAME_LISTSTORE_COLUMN_TYPE, &type,
1786 -1); 1878 -1);
1787 /* check if this is a new record */ 1879 /* check if this is a new record */
1788 if (! gtk_tree_model_get_iter_from_string (tm, &it, path_string)) 1880 if (! gtk_tree_model_get_iter_from_string (tm,
1881 &it,
1882 path_string))
1789 { 1883 {
1790 GNUNET_break (0); 1884 GNUNET_break (0);
1791 return; 1885 return;
@@ -1798,11 +1892,18 @@ gnunet_namestore_gtk_type_cellrenderercombo_changed_cb (GtkCellRendererText *tex
1798 GNUNET_break (0); 1892 GNUNET_break (0);
1799 return; 1893 return;
1800 } 1894 }
1801 GNUNET_CRYPTO_hash (name_str, strlen (name_str), &name_hash); 1895 GNUNET_CRYPTO_hash (name_str,
1802 ri = GNUNET_CONTAINER_multihashmap_get (n2r, &name_hash); 1896 strlen (name_str),
1897 &name_hash);
1898 ri = GNUNET_CONTAINER_multihashmap_get (n2r,
1899 &name_hash);
1803 if ( (NULL == ri) || 1900 if ( (NULL == ri) ||
1804 (GNUNET_OK == check_permissions (ri, type)) ) 1901 (GNUNET_OK == check_permissions (ri,
1805 launch_edit_dialog (type, name_str, ri, UINT_MAX); 1902 type)) )
1903 launch_edit_dialog (type,
1904 name_str,
1905 ri,
1906 UINT_MAX);
1806 g_free (name_str); 1907 g_free (name_str);
1807} 1908}
1808 1909
@@ -1831,20 +1932,25 @@ gnunet_namestore_gtk_name_cellrenderertext_edited_cb (GtkCellRendererText *rende
1831 1932
1832 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1933 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1833 "New text for `%s' is `%s'\n", 1934 "New text for `%s' is `%s'\n",
1834 path, new_text); 1935 path,
1835 if ((0 == strcmp (new_text, NEW_NAME_STR)) || (0 == strcmp (new_text, ""))) 1936 new_text);
1937 if ((0 == strcmp (new_text,
1938 NEW_NAME_STR)) ||
1939 (0 == strcmp (new_text,
1940 "")))
1836 return; 1941 return;
1837 if ( (GNUNET_OK != 1942 if (GNUNET_OK !=
1838 GNUNET_DNSPARSER_check_label (new_text)) && 1943 GNUNET_DNSPARSER_check_label (new_text))
1839 (0 != strcmp (new_text, GNUNET_GNS_MASTERZONE_STR)) )
1840 { 1944 {
1841 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1945 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1842 _("Name `%s' invalid for GNS/DNS (too long for a DNS label?)\n"), 1946 _("Name `%s' invalid for GNS/DNS (too long for a DNS label?)\n"),
1843 new_text); 1947 new_text);
1844 gdk_beep (); 1948 gtk_widget_error_bell (GTK_WIDGET (main_window));
1845 return; 1949 return;
1846 } 1950 }
1847 if (! gtk_tree_model_get_iter_from_string (tm, &it, path)) 1951 if (! gtk_tree_model_get_iter_from_string (tm,
1952 &it,
1953 path))
1848 { 1954 {
1849 GNUNET_break (0); 1955 GNUNET_break (0);
1850 return; 1956 return;
@@ -1857,7 +1963,9 @@ gnunet_namestore_gtk_name_cellrenderertext_edited_cb (GtkCellRendererText *rende
1857 GNUNET_break (0 == strcmp (name, _(NEW_NAME_STR))); 1963 GNUNET_break (0 == strcmp (name, _(NEW_NAME_STR)));
1858 g_free (name); 1964 g_free (name);
1859 1965
1860 GNUNET_CRYPTO_hash (new_text, strlen (new_text), &name_hash); 1966 GNUNET_CRYPTO_hash (new_text,
1967 strlen (new_text),
1968 &name_hash);
1861 ri = GNUNET_CONTAINER_multihashmap_get (n2r, 1969 ri = GNUNET_CONTAINER_multihashmap_get (n2r,
1862 &name_hash); 1970 &name_hash);
1863 if (NULL != ri) 1971 if (NULL != ri)
@@ -1874,7 +1982,8 @@ gnunet_namestore_gtk_name_cellrenderertext_edited_cb (GtkCellRendererText *rende
1874 1982
1875 /* change dummy line to new name, then add new dummy */ 1983 /* change dummy line to new name, then add new dummy */
1876 ri = GNUNET_new (struct RecordInfo); 1984 ri = GNUNET_new (struct RecordInfo);
1877 gtk_tree_store_set (ts, &it, 1985 gtk_tree_store_set (ts,
1986 &it,
1878 GNS_TREESTORE_COL_NAME, new_text, 1987 GNS_TREESTORE_COL_NAME, new_text,
1879 GNS_TREESTORE_COL_NAME_IS_VISIBLE, TRUE, 1988 GNS_TREESTORE_COL_NAME_IS_VISIBLE, TRUE,
1880 GNS_TREESTORE_COL_RECORD_TYPE, 0, 1989 GNS_TREESTORE_COL_RECORD_TYPE, 0,
@@ -1897,7 +2006,10 @@ gnunet_namestore_gtk_name_cellrenderertext_edited_cb (GtkCellRendererText *rende
1897 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 2006 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1898 2007
1899 /* add a new dummy line */ 2008 /* add a new dummy line */
1900 gtk_tree_store_insert_with_values (ts, &it,NULL, 0, 2009 gtk_tree_store_insert_with_values (ts,
2010 &it,
2011 NULL,
2012 0,
1901 GNS_TREESTORE_COL_NAME, _(NEW_NAME_STR), 2013 GNS_TREESTORE_COL_NAME, _(NEW_NAME_STR),
1902 GNS_TREESTORE_COL_NAME_IS_VISIBLE, TRUE, 2014 GNS_TREESTORE_COL_NAME_IS_VISIBLE, TRUE,
1903 GNS_TREESTORE_COL_RECORD_TYPE, GNUNET_DNSPARSER_TYPE_A, 2015 GNS_TREESTORE_COL_RECORD_TYPE, GNUNET_DNSPARSER_TYPE_A,
@@ -1927,7 +2039,9 @@ create_popup_menu ()
1927 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2039 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1928 "Considering creating popup menu...\n"); 2040 "Considering creating popup menu...\n");
1929 sel = gtk_tree_view_get_selection (tv); 2041 sel = gtk_tree_view_get_selection (tv);
1930 if (! gtk_tree_selection_get_selected (sel, NULL, &it)) 2042 if (! gtk_tree_selection_get_selected (sel,
2043 NULL,
2044 &it))
1931 { 2045 {
1932 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2046 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1933 "No row selected\n"); 2047 "No row selected\n");
@@ -2037,7 +2151,9 @@ gnunet_namestore_gtk_treeview_key_press_event_cb (GtkWidget *widget,
2037 (GDK_KEY_Delete != event_key->keyval) ) 2151 (GDK_KEY_Delete != event_key->keyval) )
2038 return FALSE; 2152 return FALSE;
2039 sel = gtk_tree_view_get_selection (tv); 2153 sel = gtk_tree_view_get_selection (tv);
2040 if (! gtk_tree_selection_get_selected (sel, NULL, &iter)) 2154 if (! gtk_tree_selection_get_selected (sel,
2155 NULL,
2156 &iter))
2041 return TRUE; /* nothing selected */ 2157 return TRUE; /* nothing selected */
2042 gtk_tree_model_get (tm, &iter, 2158 gtk_tree_model_get (tm, &iter,
2043 GNS_TREESTORE_COL_NOT_DUMMY_ROW, &not_dummy, 2159 GNS_TREESTORE_COL_NOT_DUMMY_ROW, &not_dummy,
@@ -2048,12 +2164,16 @@ gnunet_namestore_gtk_treeview_key_press_event_cb (GtkWidget *widget,
2048 g_free (name); 2164 g_free (name);
2049 return TRUE; /* do not delete the dummy line */ 2165 return TRUE; /* do not delete the dummy line */
2050 } 2166 }
2051 GNUNET_CRYPTO_hash (name, strlen (name), &name_hash); 2167 GNUNET_CRYPTO_hash (name,
2168 strlen (name),
2169 &name_hash);
2052 ri = GNUNET_CONTAINER_multihashmap_get (n2r, 2170 ri = GNUNET_CONTAINER_multihashmap_get (n2r,
2053 &name_hash); 2171 &name_hash);
2054 GNUNET_assert (NULL != ri); 2172 GNUNET_assert (NULL != ri);
2055 2173
2056 if ( (gtk_tree_model_iter_parent (tm, &parent, &iter)) && 2174 if ( (gtk_tree_model_iter_parent (tm,
2175 &parent,
2176 &iter)) &&
2057 (ri->rd_count > 0) ) 2177 (ri->rd_count > 0) )
2058 { 2178 {
2059 struct GNUNET_GNSRECORD_Data rd_old[ri->rd_count]; 2179 struct GNUNET_GNSRECORD_Data rd_old[ri->rd_count];
@@ -2096,8 +2216,10 @@ gnunet_namestore_gtk_treeview_key_press_event_cb (GtkWidget *widget,
2096 rd.record_type = n_type; 2216 rd.record_type = n_type;
2097 rd.expiration_time = n_exp_time; 2217 rd.expiration_time = n_exp_time;
2098 if (GNUNET_OK != 2218 if (GNUNET_OK !=
2099 GNUNET_GNSRECORD_string_to_value (n_type, n_value, 2219 GNUNET_GNSRECORD_string_to_value (n_type,
2100 (void**)&rd.data, &rd.data_size)) 2220 n_value,
2221 (void**) &rd.data,
2222 &rd.data_size))
2101 { 2223 {
2102 /* can't remove, value invalid */ 2224 /* can't remove, value invalid */
2103 GNUNET_assert (0); 2225 GNUNET_assert (0);
@@ -2111,12 +2233,15 @@ gnunet_namestore_gtk_treeview_key_press_event_cb (GtkWidget *widget,
2111 &rd_old[off])) 2233 &rd_old[off]))
2112 break; 2234 break;
2113 GNUNET_assert (off != ri->rd_count); 2235 GNUNET_assert (off != ri->rd_count);
2114 memcpy (rd_new, rd_old, (ri->rd_count - 1) * sizeof (struct GNUNET_GNSRECORD_Data)); 2236 memcpy (rd_new,
2237 rd_old,
2238 (ri->rd_count - 1) * sizeof (struct GNUNET_GNSRECORD_Data));
2115 rd_new[off] = rd_old[ri->rd_count - 1]; 2239 rd_new[off] = rd_old[ri->rd_count - 1];
2116 oc = GNUNET_new (struct OperationContext); 2240 oc = GNUNET_new (struct OperationContext);
2117 GNUNET_CONTAINER_DLL_insert (oc_head, oc_tail, oc); 2241 GNUNET_CONTAINER_DLL_insert (oc_head, oc_tail, oc);
2118 oc->qe = GNUNET_NAMESTORE_records_store (namestore, 2242 oc->qe = GNUNET_NAMESTORE_records_store (namestore,
2119 pkey, name, 2243 pkey,
2244 name,
2120 ri->rd_count - 1, 2245 ri->rd_count - 1,
2121 rd_new, 2246 rd_new,
2122 &operation_done_cont, oc); 2247 &operation_done_cont, oc);
@@ -2127,7 +2252,8 @@ gnunet_namestore_gtk_treeview_key_press_event_cb (GtkWidget *widget,
2127 oc = GNUNET_new (struct OperationContext); 2252 oc = GNUNET_new (struct OperationContext);
2128 GNUNET_CONTAINER_DLL_insert (oc_head, oc_tail, oc); 2253 GNUNET_CONTAINER_DLL_insert (oc_head, oc_tail, oc);
2129 oc->qe = GNUNET_NAMESTORE_records_store (namestore, 2254 oc->qe = GNUNET_NAMESTORE_records_store (namestore,
2130 pkey, name, 2255 pkey,
2256 name,
2131 0, NULL, 2257 0, NULL,
2132 &operation_done_cont, oc); 2258 &operation_done_cont, oc);
2133 } 2259 }
@@ -2138,107 +2264,6 @@ gnunet_namestore_gtk_treeview_key_press_event_cb (GtkWidget *widget,
2138 2264
2139 2265
2140/** 2266/**
2141 * The user edited the preferred name (PSEU) of this namespace.
2142 * Push the update to the namestore.
2143 *
2144 * @param editable the edited widget
2145 * @param user_data unused
2146 */
2147void
2148gnunet_namestore_gtk_pseu_entry_changed_cb (GtkEditable *editable,
2149 gpointer user_data)
2150{
2151 const gchar *pseu;
2152 struct RecordInfo *ri;
2153 struct GNUNET_HashCode hc;
2154 unsigned int rd_count;
2155 struct OperationContext *oc;
2156
2157 if (NULL == namestore)
2158 return; /* during shutdown */
2159 pseu = gtk_entry_get_text (GTK_ENTRY (editable));
2160 if ( (NULL != current_pseudonym) &&
2161 (0 == strcmp (pseu,
2162 current_pseudonym)) )
2163 return;
2164 if (GNUNET_OK !=
2165 GNUNET_DNSPARSER_check_label (pseu))
2166 {
2167 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2168 _("Name `%s' invalid for GNS (too long for a DNS label?)\n"),
2169 pseu);
2170 gdk_beep ();
2171 gtk_entry_set_text (GTK_ENTRY (editable),
2172 current_pseudonym);
2173 return;
2174 }
2175 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2176 "New Pseudonym is `%s'\n",
2177 pseu);
2178 GNUNET_free_non_null (current_pseudonym);
2179 if ( (NULL != pseu) &&
2180 (0 != strlen (pseu)) )
2181 current_pseudonym = GNUNET_strdup (pseu);
2182 else
2183 current_pseudonym = NULL;
2184
2185 GNUNET_CRYPTO_hash ("+", 1, &hc);
2186 ri = GNUNET_CONTAINER_multihashmap_get (n2r, &hc);
2187 if (NULL == ri)
2188 rd_count = 0;
2189 else
2190 rd_count = ri->rd_count;
2191
2192 /* get old records, append new one or update/remove existing one */
2193 {
2194 struct GNUNET_GNSRECORD_Data rd_old[rd_count];
2195 struct GNUNET_GNSRECORD_Data rd_new[rd_count + 1];
2196 unsigned int off;
2197 unsigned int total;
2198
2199 total = rd_count;
2200 if (NULL != ri)
2201 GNUNET_break (GNUNET_OK ==
2202 GNUNET_GNSRECORD_records_deserialize (ri->data_size,
2203 ri->data,
2204 rd_count,
2205 rd_old));
2206 memcpy (rd_new, rd_old, sizeof (struct GNUNET_GNSRECORD_Data) * rd_count);
2207 for (off=0;off<rd_count;off++)
2208 if (GNUNET_GNSRECORD_TYPE_NICK == rd_new[off].record_type)
2209 break;
2210 if (off == rd_count)
2211 total++;
2212 if ( (NULL == pseu) ||
2213 (0 == strlen (pseu)) )
2214 {
2215 rd_new[off] = rd_new[rd_count - 1];
2216 total--;
2217 }
2218 else
2219 {
2220 rd_new[off].record_type = GNUNET_GNSRECORD_TYPE_NICK;
2221 rd_new[off].expiration_time = nick_expiration_time.rel_value_us;
2222 rd_new[off].flags = GNUNET_GNSRECORD_RF_PRIVATE | GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
2223 rd_new[off].data_size = strlen (pseu) + 1;
2224 rd_new[off].data = pseu;
2225 }
2226 oc = GNUNET_new (struct OperationContext);
2227 GNUNET_CONTAINER_DLL_insert (oc_head, oc_tail, oc);
2228 oc->qe = GNUNET_NAMESTORE_records_store (namestore,
2229 pkey,
2230 GNUNET_GNS_MASTERZONE_STR,
2231 total,
2232 rd_new,
2233 &operation_done_cont, oc);
2234 }
2235#if HAVE_QRENCODE_H
2236 setup_qrcode ();
2237#endif
2238}
2239
2240
2241/**
2242 * The user clicked on the 'copy' button. Copy the full string 2267 * The user clicked on the 'copy' button. Copy the full string
2243 * with the hash of our public key to the clipboard. 2268 * with the hash of our public key to the clipboard.
2244 * 2269 *
@@ -2247,7 +2272,7 @@ gnunet_namestore_gtk_pseu_entry_changed_cb (GtkEditable *editable,
2247 */ 2272 */
2248void 2273void
2249gnunet_namestore_gtk_public_key_copy_button_clicked_cb (GtkButton *button, 2274gnunet_namestore_gtk_public_key_copy_button_clicked_cb (GtkButton *button,
2250 gpointer user_data) 2275 gpointer user_data)
2251{ 2276{
2252 GtkClipboard *cb; 2277 GtkClipboard *cb;
2253 2278
@@ -2269,7 +2294,6 @@ gnunet_namestore_gtk_public_key_copy_button_clicked_cb (GtkButton *button,
2269static void 2294static void
2270zone_sync_proc (void *cls) 2295zone_sync_proc (void *cls)
2271{ 2296{
2272 gtk_widget_show (GTK_WIDGET (get_object ("gnunet_namestore_gtk_pseu_hbox")));
2273#if HAVE_QRENCODE_H 2297#if HAVE_QRENCODE_H
2274 setup_qrcode (); 2298 setup_qrcode ();
2275 gtk_widget_show (GTK_WIDGET (get_object ("gnunet_namestore_gtk_qr_image"))); 2299 gtk_widget_show (GTK_WIDGET (get_object ("gnunet_namestore_gtk_qr_image")));
@@ -2280,9 +2304,9 @@ zone_sync_proc (void *cls)
2280 gtk_widget_hide (GTK_WIDGET (get_object ("gnunet_namestore_gtk_qr_saveas_button"))); 2304 gtk_widget_hide (GTK_WIDGET (get_object ("gnunet_namestore_gtk_qr_saveas_button")));
2281 gtk_widget_hide (GTK_WIDGET (get_object ("gnunet_namestore_gtk_qr_vseparator"))); 2305 gtk_widget_hide (GTK_WIDGET (get_object ("gnunet_namestore_gtk_qr_vseparator")));
2282#endif 2306#endif
2283 gtk_widget_hide (GTK_WIDGET (get_object ("gnunet_namestore_gtk_status_label"))); 2307 gtk_widget_hide (GTK_WIDGET (status_label));
2284 gtk_widget_show (GTK_WIDGET (get_object ("gnunet_namestore_gtk_scrolledwindow"))); 2308 gtk_widget_show (GTK_WIDGET (get_object ("gnunet_namestore_gtk_scrolledwindow")));
2285 gtk_widget_show (GTK_WIDGET (get_object ("gnunet_namestore_gtk_zone_combobox"))); 2309 gtk_widget_show (GTK_WIDGET (zone_combo_box));
2286} 2310}
2287 2311
2288 2312
@@ -2296,7 +2320,6 @@ static void
2296zone_iteration_error (void *cls) 2320zone_iteration_error (void *cls)
2297{ 2321{
2298 clear_zone_view (); 2322 clear_zone_view ();
2299 gtk_widget_hide (GTK_WIDGET (get_object ("gnunet_namestore_gtk_pseu_hbox")));
2300#if HAVE_QRENCODE_H 2323#if HAVE_QRENCODE_H
2301 setup_qrcode (); 2324 setup_qrcode ();
2302 gtk_widget_hide (GTK_WIDGET (get_object ("gnunet_namestore_gtk_qr_image"))); 2325 gtk_widget_hide (GTK_WIDGET (get_object ("gnunet_namestore_gtk_qr_image")));
@@ -2307,9 +2330,38 @@ zone_iteration_error (void *cls)
2307 gtk_widget_show (GTK_WIDGET (get_object ("gnunet_namestore_gtk_qr_saveas_button"))); 2330 gtk_widget_show (GTK_WIDGET (get_object ("gnunet_namestore_gtk_qr_saveas_button")));
2308 gtk_widget_show (GTK_WIDGET (get_object ("gnunet_namestore_gtk_qr_vseparator"))); 2331 gtk_widget_show (GTK_WIDGET (get_object ("gnunet_namestore_gtk_qr_vseparator")));
2309#endif 2332#endif
2310 gtk_widget_show (GTK_WIDGET (get_object ("gnunet_namestore_gtk_status_label"))); 2333 gtk_widget_show (GTK_WIDGET (status_label));
2311 gtk_widget_hide (GTK_WIDGET (get_object ("gnunet_namestore_gtk_scrolledwindow"))); 2334 gtk_widget_hide (GTK_WIDGET (get_object ("gnunet_namestore_gtk_scrolledwindow")));
2312 gtk_widget_hide (GTK_WIDGET (get_object ("gnunet_namestore_gtk_zone_combobox"))); 2335 gtk_widget_hide (GTK_WIDGET (zone_combo_box));
2336}
2337
2338
2339/**
2340 * A set of records is completely empty, remove it
2341 * from the hashmap and free associated memory.
2342 *
2343 * @param ri record info to release
2344 */
2345static void
2346free_ri (struct RecordInfo *ri)
2347{
2348 GtkTreePath *path;
2349 GtkTreeIter iter_name;
2350 struct GNUNET_HashCode name_hash;
2351
2352 path = gtk_tree_row_reference_get_path (ri->rr);
2353 GNUNET_assert (gtk_tree_model_get_iter (tm,
2354 &iter_name,
2355 path));
2356 gtk_tree_path_free (path);
2357 gtk_tree_store_remove (ts,
2358 &iter_name);
2359 GNUNET_CRYPTO_hash (ri->name,
2360 strlen (ri->name),
2361 &name_hash);
2362 release_ri (NULL,
2363 &name_hash,
2364 ri);
2313} 2365}
2314 2366
2315 2367
@@ -2334,7 +2386,6 @@ zone_iteration_proc (void *cls,
2334 GtkTreePath *path; 2386 GtkTreePath *path;
2335 GtkTreeIter iter_name; 2387 GtkTreeIter iter_name;
2336 GtkTreeIter iter_record; 2388 GtkTreeIter iter_record;
2337 int c;
2338 const char *exp; 2389 const char *exp;
2339 char *val; 2390 char *val;
2340 char *type_str; 2391 char *type_str;
@@ -2342,7 +2393,6 @@ zone_iteration_proc (void *cls,
2342 gboolean is_public; 2393 gboolean is_public;
2343 gboolean is_shadow; 2394 gboolean is_shadow;
2344 guint64 exp_t; 2395 guint64 exp_t;
2345 GtkEntry *pseu_entry;
2346 struct GNUNET_HashCode name_hash; 2396 struct GNUNET_HashCode name_hash;
2347 struct RecordInfo *ri; 2397 struct RecordInfo *ri;
2348 GtkTreeSelection *sel; 2398 GtkTreeSelection *sel;
@@ -2365,11 +2415,14 @@ zone_iteration_proc (void *cls,
2365 strlen (name), 2415 strlen (name),
2366 &name_hash); 2416 &name_hash);
2367 sel = gtk_tree_view_get_selection (tv); 2417 sel = gtk_tree_view_get_selection (tv);
2368 if (gtk_tree_selection_get_selected (sel, NULL, &sel_iter)) 2418 if (gtk_tree_selection_get_selected (sel,
2419 NULL,
2420 &sel_iter))
2369 sel_path = gtk_tree_model_get_path (tm, &sel_iter); 2421 sel_path = gtk_tree_model_get_path (tm, &sel_iter);
2370 else 2422 else
2371 sel_path = NULL; 2423 sel_path = NULL;
2372 ri = GNUNET_CONTAINER_multihashmap_get (n2r, &name_hash); 2424 ri = GNUNET_CONTAINER_multihashmap_get (n2r,
2425 &name_hash);
2373 if (NULL != ri) 2426 if (NULL != ri)
2374 { 2427 {
2375 rr = ri->rr; 2428 rr = ri->rr;
@@ -2379,8 +2432,11 @@ zone_iteration_proc (void *cls,
2379 path)); 2432 path));
2380 gtk_tree_path_free (path); 2433 gtk_tree_path_free (path);
2381 /* remove all records, we'll re-add those that are left next */ 2434 /* remove all records, we'll re-add those that are left next */
2382 if (gtk_tree_model_iter_children (tm, &iter_record, &iter_name)) 2435 if (gtk_tree_model_iter_children (tm,
2383 while (gtk_tree_store_remove (ts, &iter_record)) ; 2436 &iter_record,
2437 &iter_name))
2438 while (gtk_tree_store_remove (ts,
2439 &iter_record)) ;
2384 } 2440 }
2385 else 2441 else
2386 { 2442 {
@@ -2415,27 +2471,24 @@ zone_iteration_proc (void *cls,
2415 if (0 == rd_count) 2471 if (0 == rd_count)
2416 { 2472 {
2417 /* all records removed, remove name as well */ 2473 /* all records removed, remove name as well */
2418 gtk_tree_store_remove (ts, &iter_name); 2474 free_ri (ri);
2419 GNUNET_assert (GNUNET_YES ==
2420 GNUNET_CONTAINER_multihashmap_remove (n2r, &name_hash, ri));
2421 gtk_tree_row_reference_free (rr);
2422 GNUNET_free (ri->name);
2423 GNUNET_free_non_null (ri->data);
2424 GNUNET_free (ri);
2425 return; 2475 return;
2426 } 2476 }
2427 /* update record info serialized version of the records */ 2477 /* update record info serialized version of the records */
2428 GNUNET_free_non_null (ri->data); 2478 GNUNET_free_non_null (ri->data);
2429 ri->rd_count = rd_count; 2479 ri->rd_count = rd_count;
2430 ri->data_size = GNUNET_GNSRECORD_records_get_size (rd_count, rd); 2480 ri->data_size = GNUNET_GNSRECORD_records_get_size (rd_count,
2481 rd);
2431 if (0 != ri->data_size) 2482 if (0 != ri->data_size)
2432 ri->data = GNUNET_malloc (ri->data_size); 2483 ri->data = GNUNET_malloc (ri->data_size);
2433 GNUNET_break (ri->data_size == 2484 GNUNET_break (ri->data_size ==
2434 GNUNET_GNSRECORD_records_serialize (rd_count, rd, 2485 GNUNET_GNSRECORD_records_serialize (rd_count,
2435 ri->data_size, ri->data)); 2486 rd,
2487 ri->data_size,
2488 ri->data));
2436 2489
2437 /* Append elements for records in tree view */ 2490 /* Append elements for records in tree view */
2438 for (c = 0; c < rd_count; c ++) 2491 for (unsigned int c = 0; c < rd_count; c ++)
2439 { 2492 {
2440 if (GNUNET_GNSRECORD_TYPE_NICK == rd[c].record_type) 2493 if (GNUNET_GNSRECORD_TYPE_NICK == rd[c].record_type)
2441 continue; 2494 continue;
@@ -2480,14 +2533,14 @@ zone_iteration_proc (void *cls,
2480 if (NULL != GNUNET_GNSRECORD_number_to_typename (rd[c].record_type)) 2533 if (NULL != GNUNET_GNSRECORD_number_to_typename (rd[c].record_type))
2481 type_str = strdup (GNUNET_GNSRECORD_number_to_typename (rd[c].record_type)); 2534 type_str = strdup (GNUNET_GNSRECORD_number_to_typename (rd[c].record_type));
2482 else 2535 else
2483 GNUNET_asprintf (&type_str, "%s", EXPIRE_INVALID_STRING); 2536 GNUNET_asprintf (&type_str,
2484 2537 "%s",
2485 if ( (0 == strcmp (name, GNUNET_GNS_MASTERZONE_STR)) && 2538 EXPIRE_INVALID_STRING);
2539 if ( (0 == strcmp (name,
2540 GNUNET_GNS_MASTERZONE_STR)) &&
2486 (GNUNET_GNSRECORD_TYPE_NICK == rd[c].record_type) && 2541 (GNUNET_GNSRECORD_TYPE_NICK == rd[c].record_type) &&
2487 (NULL == current_pseudonym) ) 2542 (NULL == current_pseudonym) )
2488 { 2543 {
2489 pseu_entry = GTK_ENTRY((get_object ("gnunet_namestore_gtk_pseu_entry")));
2490 gtk_entry_set_text (pseu_entry, val);
2491#if HAVE_QRENCODE_H 2544#if HAVE_QRENCODE_H
2492 setup_qrcode (); 2545 setup_qrcode ();
2493#endif 2546#endif
@@ -2523,34 +2576,6 @@ zone_iteration_proc (void *cls,
2523 2576
2524 2577
2525/** 2578/**
2526 * The user has selected a response in the dialog asking him
2527 * if we should run the import script. If the response was
2528 * positive, run the import script.
2529 *
2530 * @param dialog the dialog object, should be destroyed
2531 * @param response_id response in the dialog
2532 * @param user_data NULL
2533 */
2534static void
2535handle_import_dialog_response (GtkDialog *dialog,
2536 gint response_id,
2537 gpointer user_data)
2538{
2539 gtk_widget_destroy (GTK_WIDGET (dialog));
2540 switch (response_id)
2541 {
2542 case GTK_RESPONSE_YES:
2543 system ("gnunet-gns-import.sh");
2544 break;
2545 default:
2546 /* nothing */
2547 break;
2548 }
2549 gtk_widget_show (GTK_WIDGET (get_object ("gnunet_namestore_gtk_zone_combobox")));
2550}
2551
2552
2553/**
2554 * Method called to switch the model to a new zone. 2579 * Method called to switch the model to a new zone.
2555 * 2580 *
2556 * @param name name of the zone 2581 * @param name name of the zone
@@ -2570,36 +2595,16 @@ load_zone (const char *name,
2570 GNUNET_NAMESTORE_zone_monitor_stop (zmon); 2595 GNUNET_NAMESTORE_zone_monitor_stop (zmon);
2571 zmon = NULL; 2596 zmon = NULL;
2572 } 2597 }
2573 if (NULL == ego) 2598 GNUNET_free_non_null (current_pseudonym);
2574 { 2599 current_pseudonym = NULL;
2575 GtkDialog *diag; 2600 if (NULL == name)
2576 GtkWidget *dummy; 2601 return; /* empty zone */
2577 GtkWidget *toplevel; 2602 current_pseudonym = GNUNET_strdup (name);
2578
2579 diag = GTK_DIALOG (gtk_message_dialog_new (NULL,
2580 GTK_DIALOG_MODAL,
2581 GTK_MESSAGE_WARNING,
2582 GTK_BUTTONS_YES_NO,
2583 (NULL == name)
2584 ? _("No zones found. Should I run the import script?")
2585 : _("Zone `%s' not found. Should I run the import script?"),
2586 name));
2587 dummy = GTK_WIDGET (get_object ("gnunet_namestore_gtk_dialog"));
2588 toplevel = gtk_widget_get_toplevel (dummy);
2589 if (GTK_IS_WINDOW (toplevel))
2590 gtk_window_set_transient_for (GTK_WINDOW (diag), GTK_WINDOW (toplevel));
2591 gtk_window_set_modal (GTK_WINDOW (diag), TRUE);
2592 g_signal_connect (diag, "response",
2593 G_CALLBACK (handle_import_dialog_response),
2594 NULL);
2595 gtk_window_present (GTK_WINDOW (diag));
2596 return;
2597 }
2598 current_zone_option = GNUNET_strdup (name);
2599 pkey = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPrivateKey); 2603 pkey = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPrivateKey);
2600 *pkey = *GNUNET_IDENTITY_ego_get_private_key (ego); 2604 *pkey = *GNUNET_IDENTITY_ego_get_private_key (ego);
2601 GNUNET_CRYPTO_ecdsa_key_get_public (pkey, &pubkey); 2605 GNUNET_CRYPTO_ecdsa_key_get_public (pkey,
2602 label = g_markup_printf_escaped (_("<b>Editing zone %s</b>"), 2606 &pubkey);
2607 label = g_markup_printf_escaped ("<b>%s</b>",
2603 GNUNET_GNSRECORD_z2s (&pubkey)); 2608 GNUNET_GNSRECORD_z2s (&pubkey));
2604 gtk_label_set_markup (GTK_LABEL (get_object ("gnunet_namestore_gtk_zone_label")), 2609 gtk_label_set_markup (GTK_LABEL (get_object ("gnunet_namestore_gtk_zone_label")),
2605 label); 2610 label);
@@ -2622,7 +2627,8 @@ load_zone (const char *name,
2622#if HAVE_QRENCODE_H 2627#if HAVE_QRENCODE_H
2623 setup_qrcode (); 2628 setup_qrcode ();
2624#endif 2629#endif
2625 zmon = GNUNET_NAMESTORE_zone_monitor_start (cfg, pkey, 2630 zmon = GNUNET_NAMESTORE_zone_monitor_start (cfg,
2631 pkey,
2626 GNUNET_YES, 2632 GNUNET_YES,
2627 &zone_iteration_error, 2633 &zone_iteration_error,
2628 NULL, 2634 NULL,
@@ -2634,32 +2640,69 @@ load_zone (const char *name,
2634 2640
2635 2641
2636/** 2642/**
2637 * A different zone was selected in the zone toggle bar. Load the 2643 * Check if @a label is a valid label or is already used for the name
2638 * appropriate zone. 2644 * of any of our zones OR configured as a TLD in the configuration.
2639 * 2645 *
2640 * @param widget button that was toggled (could be to "on" or "off", we only react to "on") 2646 * @param label label to check
2641 * @param user_data builder, unused 2647 * @return NULL if label is fresh and valid
2648 * error message explaining why @a label is not valid
2642 */ 2649 */
2643void 2650static const char *
2644gnunet_namestore_gtk_zone_combobox_changed_cb (GtkComboBox *widget, 2651fresh_label (const char *label)
2645 gpointer user_data)
2646{ 2652{
2647 GtkTreeIter iter; 2653 GtkTreeIter iter;
2648 struct GNUNET_IDENTITY_Ego *ego; 2654 struct GNS_TopLevelDomain *tld;
2649 char *name;
2650 2655
2651 if (! gtk_combo_box_get_active_iter (widget, 2656 if ( (NULL == label) ||
2652 &iter)) 2657 (0 == strlen (label)) )
2653 { 2658 return _("Name must not be empty\n");
2654 load_zone (NULL, NULL); 2659 if (GNUNET_OK !=
2655 return; 2660 GNUNET_DNSPARSER_check_label (label))
2656 } 2661 return _("Name is not a syntactically valid DNS label\n");
2657 gtk_tree_model_get (GTK_TREE_MODEL (zone_liststore), 2662 if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (zone_liststore),
2658 &iter, 2663 &iter))
2659 ZONE_LS_NAME, &name, 2664 {
2660 ZONE_LS_EGO, &ego, 2665 do {
2661 -1); 2666 char *name;
2662 load_zone (name, ego); 2667
2668 gtk_tree_model_get (GTK_TREE_MODEL (zone_liststore),
2669 &iter,
2670 ZONE_LS_NAME, &name,
2671 -1);
2672 if (0 == strcasecmp (name,
2673 label))
2674 return _("Name already exists in the list\n");
2675 } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (zone_liststore),
2676 &iter));
2677 }
2678 for (tld = tld_head; NULL != tld; tld = tld->next)
2679 if (0 == strcasecmp (tld->tld,
2680 label))
2681 return _("Name is assigned in the configuration file (see [GNS] section)\n");
2682 return NULL;
2683}
2684
2685
2686/**
2687 * Continuation after identity operation. Makes the
2688 * main window sensitive again.
2689 *
2690 * @param cls NULL
2691 * @param emsg error message, used in status bar
2692 */
2693static void
2694iop_cont (void *cls,
2695 const char *emsg)
2696{
2697 GtkEntry *entry;
2698
2699 iop = NULL;
2700 entry = GTK_ENTRY (get_object ("gnunet_namestore_gtk_zone_entry"));
2701 gtk_widget_set_sensitive (main_window,
2702 TRUE);
2703 gtk_label_set_markup (status_label,
2704 emsg);
2705 gtk_entry_grab_focus_without_selecting (entry);
2663} 2706}
2664 2707
2665 2708
@@ -2673,6 +2716,7 @@ cleanup_task (void *cls)
2673{ 2716{
2674 struct OperationContext *oc; 2717 struct OperationContext *oc;
2675 struct MoveOperationContext *moc; 2718 struct MoveOperationContext *moc;
2719 struct GNS_TopLevelDomain *tld;
2676 2720
2677 if (NULL == ml) 2721 if (NULL == ml)
2678 { 2722 {
@@ -2680,9 +2724,7 @@ cleanup_task (void *cls)
2680 return; 2724 return;
2681 } 2725 }
2682 GNUNET_GTK_main_loop_quit (ml); 2726 GNUNET_GTK_main_loop_quit (ml);
2683 2727 gtk_widget_show (GTK_WIDGET (status_label));
2684
2685 gtk_widget_show (GTK_WIDGET (get_object ("gnunet_namestore_gtk_status_label")));
2686 gtk_widget_hide (GTK_WIDGET (get_object ("gnunet_namestore_gtk_scrolledwindow"))); 2728 gtk_widget_hide (GTK_WIDGET (get_object ("gnunet_namestore_gtk_scrolledwindow")));
2687 if (NULL != zmon) 2729 if (NULL != zmon)
2688 { 2730 {
@@ -2693,7 +2735,9 @@ cleanup_task (void *cls)
2693 { 2735 {
2694 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2736 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2695 _("A pending namestore operation was not transmitted to the namestore.\n")); 2737 _("A pending namestore operation was not transmitted to the namestore.\n"));
2696 GNUNET_CONTAINER_DLL_remove (oc_head, oc_tail, oc); 2738 GNUNET_CONTAINER_DLL_remove (oc_head,
2739 oc_tail,
2740 oc);
2697 GNUNET_NAMESTORE_cancel (oc->qe); 2741 GNUNET_NAMESTORE_cancel (oc->qe);
2698 GNUNET_free (oc); 2742 GNUNET_free (oc);
2699 } 2743 }
@@ -2701,7 +2745,9 @@ cleanup_task (void *cls)
2701 { 2745 {
2702 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2746 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2703 _("A pending namestore operation was not transmitted to the namestore.\n")); 2747 _("A pending namestore operation was not transmitted to the namestore.\n"));
2704 GNUNET_CONTAINER_DLL_remove (moc_head, moc_tail, moc); 2748 GNUNET_CONTAINER_DLL_remove (moc_head,
2749 moc_tail,
2750 moc);
2705 if (NULL != moc->it) 2751 if (NULL != moc->it)
2706 GNUNET_NAMESTORE_zone_iteration_stop (moc->it); 2752 GNUNET_NAMESTORE_zone_iteration_stop (moc->it);
2707 free_edit_dialog_context (moc->edc); 2753 free_edit_dialog_context (moc->edc);
@@ -2724,6 +2770,11 @@ cleanup_task (void *cls)
2724 GNUNET_free (current_pseudonym); 2770 GNUNET_free (current_pseudonym);
2725 current_pseudonym = NULL; 2771 current_pseudonym = NULL;
2726 } 2772 }
2773 if (NULL != iop)
2774 {
2775 GNUNET_IDENTITY_cancel (iop);
2776 iop = NULL;
2777 }
2727 if (NULL != identity) 2778 if (NULL != identity)
2728 { 2779 {
2729 GNUNET_IDENTITY_disconnect (identity); 2780 GNUNET_IDENTITY_disconnect (identity);
@@ -2737,6 +2788,14 @@ cleanup_task (void *cls)
2737 GNUNET_CONTAINER_multihashmap_destroy (n2r); 2788 GNUNET_CONTAINER_multihashmap_destroy (n2r);
2738 n2r = NULL; 2789 n2r = NULL;
2739 } 2790 }
2791 while (NULL != (tld = tld_head))
2792 {
2793 GNUNET_CONTAINER_DLL_remove (tld_head,
2794 tld_tail,
2795 tld);
2796 GNUNET_free (tld->tld);
2797 GNUNET_free (tld);
2798 }
2740} 2799}
2741 2800
2742 2801
@@ -2752,6 +2811,180 @@ gnunet_namestore_gtk_quit_cb (GObject * object,
2752 2811
2753 2812
2754/** 2813/**
2814 * Change the NICK record of the current zone to @a new_name.
2815 * Gets the old records, append new one or updates the existing one.
2816 *
2817 * @param new_name the new name (and hence nick) of the zone
2818 */
2819static void
2820update_nick_record (const char *new_name)
2821{
2822 struct RecordInfo *ri;
2823 struct GNUNET_HashCode hc;
2824 unsigned int rd_count;
2825 struct OperationContext *oc;
2826
2827 GNUNET_CRYPTO_hash ("+",
2828 1,
2829 &hc);
2830 ri = GNUNET_CONTAINER_multihashmap_get (n2r,
2831 &hc);
2832 if (NULL == ri)
2833 rd_count = 0;
2834 else
2835 rd_count = ri->rd_count;
2836
2837 {
2838 struct GNUNET_GNSRECORD_Data rd_old[rd_count];
2839 struct GNUNET_GNSRECORD_Data rd_new[rd_count + 1];
2840 unsigned int off;
2841 unsigned int total;
2842
2843 total = rd_count;
2844 if (NULL != ri)
2845 GNUNET_break (GNUNET_OK ==
2846 GNUNET_GNSRECORD_records_deserialize (ri->data_size,
2847 ri->data,
2848 rd_count,
2849 rd_old));
2850 memcpy (rd_new,
2851 rd_old,
2852 sizeof (struct GNUNET_GNSRECORD_Data) * rd_count);
2853 for (off=0;off<rd_count;off++)
2854 if (GNUNET_GNSRECORD_TYPE_NICK == rd_new[off].record_type)
2855 break;
2856 if (off == rd_count)
2857 total++;
2858 if ( (NULL == new_name) ||
2859 (0 == strlen (new_name)) )
2860 {
2861 rd_new[off] = rd_new[rd_count - 1];
2862 total--;
2863 }
2864 else
2865 {
2866 rd_new[off].record_type = GNUNET_GNSRECORD_TYPE_NICK;
2867 rd_new[off].expiration_time = nick_expiration_time.rel_value_us;
2868 rd_new[off].flags = GNUNET_GNSRECORD_RF_PRIVATE | GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
2869 rd_new[off].data_size = strlen (new_name) + 1;
2870 rd_new[off].data = new_name;
2871 }
2872 oc = GNUNET_new (struct OperationContext);
2873 GNUNET_CONTAINER_DLL_insert (oc_head,
2874 oc_tail,
2875 oc);
2876 oc->qe = GNUNET_NAMESTORE_records_store (namestore,
2877 pkey,
2878 GNUNET_GNS_MASTERZONE_STR,
2879 total,
2880 rd_new,
2881 &operation_done_cont,
2882 oc);
2883 }
2884}
2885
2886
2887/**
2888 * The user has edited the zone's name. Check if the new name is
2889 * valid (if not, warn) and update the NICK and rename the zone.
2890 */
2891static void
2892handle_zone_entry_edit ()
2893{
2894 /* user is editing label, or we removed the last entry in the list */
2895 const char *new_name;
2896 GtkEntry *entry;
2897 const char *emsg;
2898
2899 entry = GTK_ENTRY (get_object ("gnunet_namestore_gtk_zone_entry"));
2900 if (NULL == current_pseudonym)
2901 {
2902 gtk_entry_set_text (entry,
2903 "");
2904 return;
2905 }
2906 new_name = gtk_entry_get_text (entry);
2907 if (NULL != (emsg = fresh_label (new_name)))
2908 {
2909 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2910 "%s",
2911 emsg);
2912 gtk_widget_error_bell (GTK_WIDGET (entry));
2913 gtk_entry_set_icon_from_icon_name (entry,
2914 GTK_ENTRY_ICON_PRIMARY,
2915 "error");
2916 gtk_entry_set_icon_tooltip_text (entry,
2917 GTK_ENTRY_ICON_PRIMARY,
2918 emsg);
2919 return;
2920 }
2921 gtk_entry_set_icon_from_icon_name (entry,
2922 GTK_ENTRY_ICON_PRIMARY,
2923 NULL);
2924
2925 update_nick_record (new_name);
2926#if HAVE_QRENCODE_H
2927 setup_qrcode ();
2928#endif
2929 gtk_list_store_set (GTK_LIST_STORE (zone_liststore),
2930 &zone_iter,
2931 ZONE_LS_NAME, new_name,
2932 -1);
2933 gtk_label_set_markup (status_label,
2934 _("Renaming zone"));
2935 gtk_widget_set_sensitive (main_window,
2936 FALSE);
2937 GNUNET_assert (NULL == iop);
2938 iop = GNUNET_IDENTITY_rename (identity,
2939 current_pseudonym,
2940 new_name,
2941 &iop_cont,
2942 NULL);
2943 GNUNET_free (current_pseudonym);
2944 current_pseudonym = GNUNET_strdup (new_name);
2945}
2946
2947
2948/**
2949 * The user selected another zone in the combobox. Load it.
2950 *
2951 * @param widget the combo box where the selection was changed
2952 * @param user_data the builder, unused
2953 */
2954void
2955gnunet_namestore_gtk_zone_combobox_changed_cb (GtkComboBox *widget,
2956 gpointer user_data)
2957{
2958 GtkTreeIter iter;
2959 struct GNUNET_IDENTITY_Ego *ego;
2960 char *name;
2961 GtkEntry *entry;
2962
2963 (void) user_data;
2964 if (! gtk_combo_box_get_active_iter (zone_combo_box,
2965 &iter))
2966 {
2967 handle_zone_entry_edit ();
2968 return;
2969 }
2970 zone_iter = iter;
2971 entry = GTK_ENTRY (get_object ("gnunet_namestore_gtk_zone_entry"));
2972 gtk_entry_set_icon_from_icon_name (entry,
2973 GTK_ENTRY_ICON_PRIMARY,
2974 NULL);
2975 gtk_tree_model_get (GTK_TREE_MODEL (zone_liststore),
2976 &iter,
2977 ZONE_LS_NAME, &name,
2978 ZONE_LS_EGO, &ego,
2979 -1);
2980 gtk_widget_set_sensitive (GTK_WIDGET (get_object ("gnunet_namestore_gtk_zone_del_button")),
2981 TRUE);
2982 load_zone (name,
2983 ego);
2984}
2985
2986
2987/**
2755 * Method called to inform about the egos of this peer. Updates the 2988 * Method called to inform about the egos of this peer. Updates the
2756 * `zone_liststore`. 2989 * `zone_liststore`.
2757 * 2990 *
@@ -2798,31 +3031,33 @@ identity_cb (void *cls,
2798 { 3031 {
2799 /* end of initial iteration, trigger loading selected zone */ 3032 /* end of initial iteration, trigger loading selected zone */
2800 gnunet_namestore_gtk_zone_combobox_changed_cb 3033 gnunet_namestore_gtk_zone_combobox_changed_cb
2801 (GTK_COMBO_BOX (get_object ("gnunet_namestore_gtk_zone_combobox")), 3034 (zone_combo_box,
2802 ml); 3035 ml);
2803 return; 3036 return;
2804 } 3037 }
2805 rr = *ctx; 3038 rr = *ctx;
2806 if (NULL == rr) 3039 if (NULL == rr)
2807 { 3040 {
2808 /* new zone, add to list */ 3041 /* new identity, add to list */
2809 GNUNET_assert (NULL != name); 3042 GNUNET_assert (NULL != name);
2810 gtk_list_store_insert_with_values (zone_liststore, 3043 gtk_list_store_insert_with_values (zone_liststore,
2811 &iter, -1, 3044 &iter, 0,
2812 ZONE_LS_NAME, name, 3045 ZONE_LS_NAME, name,
2813 ZONE_LS_EGO, ego, 3046 ZONE_LS_EGO, ego,
2814 -1); 3047 -1);
3048 gtk_combo_box_set_active_iter
3049 (zone_combo_box,
3050 &iter);
3051 gtk_widget_set_sensitive (GTK_WIDGET (zone_combo_box),
3052 TRUE);
3053 gtk_widget_set_sensitive (GTK_WIDGET (get_object ("gnunet_namestore_gtk_zone_entry")),
3054 TRUE);
2815 path = gtk_tree_model_get_path (GTK_TREE_MODEL (zone_liststore), 3055 path = gtk_tree_model_get_path (GTK_TREE_MODEL (zone_liststore),
2816 &iter); 3056 &iter);
2817 rr = gtk_tree_row_reference_new (GTK_TREE_MODEL (zone_liststore), 3057 rr = gtk_tree_row_reference_new (GTK_TREE_MODEL (zone_liststore),
2818 path); 3058 path);
2819 *ctx = rr; 3059 *ctx = rr;
2820 gtk_tree_path_free (path); 3060 gtk_tree_path_free (path);
2821 if (0 == strcmp ("master-zone",
2822 name))
2823 gtk_combo_box_set_active_iter
2824 (GTK_COMBO_BOX (get_object ("gnunet_namestore_gtk_zone_combobox")),
2825 &iter);
2826 return; 3061 return;
2827 } 3062 }
2828 path = gtk_tree_row_reference_get_path (rr); 3063 path = gtk_tree_row_reference_get_path (rr);
@@ -2832,12 +3067,36 @@ identity_cb (void *cls,
2832 gtk_tree_path_free (path); 3067 gtk_tree_path_free (path);
2833 if (NULL == name) 3068 if (NULL == name)
2834 { 3069 {
2835 /* zone was removed, remove from list */ 3070 GtkTreeIter act_iter;
3071
3072 /* identity was removed, remove from list */
3073 GNUNET_free_non_null (current_pseudonym);
3074 current_pseudonym = NULL;
2836 gtk_list_store_remove (zone_liststore, 3075 gtk_list_store_remove (zone_liststore,
2837 &iter); 3076 &iter);
3077 if (! gtk_combo_box_get_active_iter (zone_combo_box,
3078 &act_iter))
3079 {
3080 if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (zone_liststore),
3081 &act_iter))
3082 {
3083 /* make sure combo box remains selected if possible */
3084 gtk_combo_box_set_active (zone_combo_box,
3085 0);
3086 }
3087 else
3088 {
3089 /* make combo box insensitive if nothing can be selected */
3090 gtk_widget_set_sensitive (GTK_WIDGET (zone_combo_box),
3091 FALSE);
3092 gtk_widget_set_sensitive (GTK_WIDGET (get_object ("gnunet_namestore_gtk_zone_entry")),
3093 FALSE);
3094 clear_zone_view ();
3095 }
3096 }
2838 return; 3097 return;
2839 } 3098 }
2840 /* zone was renamed, rename in model */ 3099 /* identity was renamed, rename in model */
2841 gtk_list_store_set (zone_liststore, 3100 gtk_list_store_set (zone_liststore,
2842 &iter, 3101 &iter,
2843 ZONE_LS_NAME, name, 3102 ZONE_LS_NAME, name,
@@ -2846,6 +3105,165 @@ identity_cb (void *cls,
2846 3105
2847 3106
2848/** 3107/**
3108 * The user clicked the "add" button for a new zone.
3109 * Obtain the label, create the new zone and reset
3110 * the entry to empty.
3111 *
3112 * @param button the "add" button
3113 * @param user_data the builder, unused
3114 */
3115void
3116gnunet_namestore_gtk_zone_add_button_clicked_cb (GtkButton *button,
3117 gpointer user_data)
3118{
3119 const char *label;
3120 GtkEntry *entry;
3121
3122 (void) user_data;
3123 entry = GTK_ENTRY (get_object ("gnunet_namestore_gtk_zone_add_entry"));
3124 label = gtk_entry_get_text (entry);
3125 gtk_label_set_markup (status_label,
3126 _("Creating zone"));
3127 gtk_widget_set_sensitive (main_window,
3128 FALSE);
3129 iop = GNUNET_IDENTITY_create (identity,
3130 label,
3131 &iop_cont,
3132 NULL);
3133 gtk_entry_set_text (entry,
3134 "");
3135}
3136
3137
3138/**
3139 * Delete all records of the current zone.
3140 *
3141 * @param cls NULL
3142 * @param key key of a record in the map to delete
3143 * @param value a `struct RecordInfo` to delete
3144 * @return #GNUNET_OK (continue to iterate)
3145 */
3146static int
3147delete_records (void *cls,
3148 const struct GNUNET_HashCode *key,
3149 void *value)
3150{
3151 struct RecordInfo *ri = value;
3152 struct OperationContext *oc;
3153
3154 if (0 != ri->rd_count)
3155 {
3156 oc = GNUNET_new (struct OperationContext);
3157 GNUNET_CONTAINER_DLL_insert (oc_head,
3158 oc_tail,
3159 oc);
3160 oc->qe = GNUNET_NAMESTORE_records_store (namestore,
3161 pkey,
3162 ri->name,
3163 0,
3164 NULL,
3165 &operation_done_cont,
3166 oc);
3167 }
3168 free_ri (ri);
3169 return GNUNET_OK;
3170}
3171
3172
3173/**
3174 * The user clicked the "del" button for an existing zone.
3175 * Obtain the label/ego and delete the zone.
3176 *
3177 * @param button the "del" button
3178 * @param user_data the builder, unused
3179 */
3180void
3181gnunet_namestore_gtk_zone_del_button_clicked_cb (GtkButton *button,
3182 gpointer user_data)
3183{
3184 char *pseu;
3185 (void) user_data;
3186
3187 pseu = current_pseudonym;
3188 current_pseudonym = NULL;
3189 GNUNET_CONTAINER_multihashmap_iterate (n2r,
3190 &delete_records,
3191 NULL);
3192 gtk_tree_store_clear (ts);
3193 gtk_widget_set_sensitive (GTK_WIDGET (get_object ("gnunet_namestore_gtk_zone_del_button")),
3194 FALSE);
3195 gtk_widget_set_sensitive (main_window,
3196 FALSE);
3197 iop = GNUNET_IDENTITY_delete (identity,
3198 pseu,
3199 &iop_cont,
3200 NULL);
3201 GNUNET_free (pseu);
3202}
3203
3204
3205/**
3206 * The user edited the zone label for 'adding' a new zone.
3207 * Check if the label is unique and well-formed and update
3208 * the sensitivity of the "add" button accordingly.
3209 *
3210 * @param editable the zone label that was changed
3211 * @param user_data the builder, unused
3212 */
3213void
3214gnunet_namestore_gtk_zone_add_entry_changed_cb (GtkEditable *editable,
3215 gpointer user_data)
3216{
3217 const char *label;
3218
3219 (void) user_data;
3220 label = gtk_entry_get_text (GTK_ENTRY (editable));
3221 gtk_widget_set_sensitive (GTK_WIDGET (get_object ("gnunet_namestore_gtk_zone_add_button")),
3222 NULL == fresh_label (label));
3223}
3224
3225
3226/**
3227 * Reads the configuration and populates TLDs
3228 *
3229 * @param cls unused
3230 * @param section name of section in config, always "gns"
3231 * @param option name of the option, TLDs start with "."
3232 * @param value value for the option, public key for TLDs
3233 */
3234static void
3235read_service_conf (void *cls,
3236 const char *section,
3237 const char *option,
3238 const char *value)
3239{
3240 struct GNUNET_CRYPTO_EddsaPublicKey pk;
3241 struct GNS_TopLevelDomain *tld;
3242
3243 if (option[0] != '.')
3244 return;
3245 if (GNUNET_OK !=
3246 GNUNET_STRINGS_string_to_data (value,
3247 strlen (value),
3248 &pk,
3249 sizeof (pk)))
3250 {
3251 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
3252 section,
3253 option,
3254 _("Properly base32-encoded public key required"));
3255 return;
3256 }
3257 tld = GNUNET_new (struct GNS_TopLevelDomain);
3258 tld->tld = GNUNET_strdup (&option[1]);
3259 tld->pkey = pk;
3260 GNUNET_CONTAINER_DLL_insert (tld_head,
3261 tld_tail,
3262 tld);
3263}
3264
3265
3266/**
2849 * Actual main method that sets up the configuration window. 3267 * Actual main method that sets up the configuration window.
2850 * 3268 *
2851 * @param cls the main loop handle 3269 * @param cls the main loop handle
@@ -2854,10 +3272,13 @@ static void
2854run (void *cls) 3272run (void *cls)
2855{ 3273{
2856 gchar *label; 3274 gchar *label;
2857 GtkLabel *status_label;
2858 3275
2859 ml = cls; 3276 ml = cls;
2860 cfg = GNUNET_GTK_main_loop_get_configuration (ml); 3277 cfg = GNUNET_GTK_main_loop_get_configuration (ml);
3278 GNUNET_CONFIGURATION_iterate_section_values (cfg,
3279 "gns",
3280 &read_service_conf,
3281 NULL);
2861 if (GNUNET_OK != 3282 if (GNUNET_OK !=
2862 GNUNET_CONFIGURATION_get_value_time (cfg, 3283 GNUNET_CONFIGURATION_get_value_time (cfg,
2863 "gnunet-namestore-gtk", 3284 "gnunet-namestore-gtk",
@@ -2871,7 +3292,8 @@ run (void *cls)
2871 return; 3292 return;
2872 } 3293 }
2873 if (GNUNET_OK != 3294 if (GNUNET_OK !=
2874 GNUNET_GTK_main_loop_build_window (ml, NULL)) 3295 GNUNET_GTK_main_loop_build_window (ml,
3296 NULL))
2875 return; 3297 return;
2876 GNUNET_GTK_set_icon_search_path (); 3298 GNUNET_GTK_set_icon_search_path ();
2877 GNUNET_GTK_setup_nls (); 3299 GNUNET_GTK_setup_nls ();
@@ -2879,13 +3301,14 @@ run (void *cls)
2879 main_window = GTK_WIDGET (get_object ("gnunet_namestore_gtk_dialog")); 3301 main_window = GTK_WIDGET (get_object ("gnunet_namestore_gtk_dialog"));
2880 main_window = GNUNET_GTK_plug_me ("GNUNET_NAMESTORE_GTK_PLUG", 3302 main_window = GNUNET_GTK_plug_me ("GNUNET_NAMESTORE_GTK_PLUG",
2881 main_window); 3303 main_window);
2882 3304 status_label = GTK_LABEL (get_object ("gnunet_namestore_gtk_status_label"));
3305 zone_combo_box = GTK_COMBO_BOX (get_object ("gnunet_namestore_gtk_zone_combobox"));
2883 namestore = GNUNET_NAMESTORE_connect (cfg); 3306 namestore = GNUNET_NAMESTORE_connect (cfg);
2884 if (NULL == namestore) 3307 if (NULL == namestore)
2885 { 3308 {
2886 status_label = GTK_LABEL (get_object ("gnunet_namestore_gtk_status_label"));
2887 label = g_markup_printf_escaped (_("<b><big>Failed to connect to namestore</b></big>")); 3309 label = g_markup_printf_escaped (_("<b><big>Failed to connect to namestore</b></big>"));
2888 gtk_label_set_markup (status_label, label); 3310 gtk_label_set_markup (status_label,
3311 label);
2889 g_free (label); 3312 g_free (label);
2890 return; 3313 return;
2891 } 3314 }
@@ -2893,13 +3316,15 @@ run (void *cls)
2893 tv = GTK_TREE_VIEW (get_object ("gnunet_namestore_gtk_treeview")); 3316 tv = GTK_TREE_VIEW (get_object ("gnunet_namestore_gtk_treeview"));
2894 zone_liststore = GTK_LIST_STORE (get_object ("zone_liststore")); 3317 zone_liststore = GTK_LIST_STORE (get_object ("zone_liststore"));
2895 tm = GTK_TREE_MODEL (ts); 3318 tm = GTK_TREE_MODEL (ts);
2896 n2r = GNUNET_CONTAINER_multihashmap_create (128, GNUNET_NO); 3319 n2r = GNUNET_CONTAINER_multihashmap_create (128,
3320 GNUNET_NO);
2897 identity = GNUNET_IDENTITY_connect (cfg, 3321 identity = GNUNET_IDENTITY_connect (cfg,
2898 &identity_cb, 3322 &identity_cb,
2899 NULL); 3323 NULL);
2900 gtk_widget_show (main_window); 3324 gtk_widget_show (main_window);
2901 gtk_window_present (GTK_WINDOW (main_window)); 3325 gtk_window_present (GTK_WINDOW (main_window));
2902 GNUNET_SCHEDULER_add_shutdown (&cleanup_task, NULL); 3326 GNUNET_SCHEDULER_add_shutdown (&cleanup_task,
3327 NULL);
2903} 3328}
2904 3329
2905 3330