aboutsummaryrefslogtreecommitdiff
path: root/src/setup/gnunet-setup-gns.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/setup/gnunet-setup-gns.c')
-rw-r--r--src/setup/gnunet-setup-gns.c431
1 files changed, 237 insertions, 194 deletions
diff --git a/src/setup/gnunet-setup-gns.c b/src/setup/gnunet-setup-gns.c
index 3578a002..1ee8531d 100644
--- a/src/setup/gnunet-setup-gns.c
+++ b/src/setup/gnunet-setup-gns.c
@@ -153,7 +153,12 @@ enum GNSTreestoreColumn
153 /** 153 /**
154 * A gboolean; TRUE if the name is editable (dummy line). 154 * A gboolean; TRUE if the name is editable (dummy line).
155 */ 155 */
156 GNS_TREESTORE_COL_NAME_IS_EDITABLE 156 GNS_TREESTORE_COL_NAME_IS_EDITABLE,
157
158 /**
159 * A guint; offset of this record in the array.
160 */
161 GNS_TREESTORE_COL_RECORD_OFFSET
157}; 162};
158 163
159 164
@@ -568,7 +573,6 @@ clear_zone_view ()
568} 573}
569 574
570 575
571
572/** 576/**
573 * Load a particular zone into the main tree view. 577 * Load a particular zone into the main tree view.
574 * 578 *
@@ -593,7 +597,7 @@ show_error_message (const char *title,
593 GtkWindow *main_window; 597 GtkWindow *main_window;
594 GtkDialog *dialog; 598 GtkDialog *dialog;
595 599
596 /* FIXME: consider replacing with widget in the main window */ 600 /* TODO: consider replacing with widget in the main window */
597 main_window = GTK_WINDOW (GNUNET_SETUP_get_object ("GNUNET_setup_dialog")); 601 main_window = GTK_WINDOW (GNUNET_SETUP_get_object ("GNUNET_setup_dialog"));
598 dialog = GTK_DIALOG(gtk_message_dialog_new (main_window, 602 dialog = GTK_DIALOG(gtk_message_dialog_new (main_window,
599 GTK_DIALOG_DESTROY_WITH_PARENT, 603 GTK_DIALOG_DESTROY_WITH_PARENT,
@@ -608,157 +612,6 @@ show_error_message (const char *title,
608 612
609 613
610/** 614/**
611 * Remove selected record from the namestore.
612 *
613 * @param edc identifying record to remove
614 */
615static void
616remove_record_at_offset (struct EditDialogContext *edc)
617{
618 struct RecordInfo *ri = edc->ri;
619 struct OperationContext *oc;
620
621 if ( (NULL == ri) ||
622 (edc->off >= ri->rd_count) )
623 {
624 GNUNET_break (0);
625 return;
626 }
627
628 {
629 struct GNUNET_NAMESTORE_RecordData rd_old[ri->rd_count];
630 struct GNUNET_NAMESTORE_RecordData rd_new[ri->rd_count - 1];
631
632 /* Removing a single record */
633 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
634 "Removing single record for name `%s'\n",
635 edc->name);
636 GNUNET_break (GNUNET_OK ==
637 GNUNET_NAMESTORE_records_deserialize (ri->data_size,
638 ri->data,
639 ri->rd_count,
640 rd_old));
641 GNUNET_assert (edc->off < ri->rd_count);
642 memcpy (rd_new, rd_old, (ri->rd_count - 1) * sizeof (struct GNUNET_NAMESTORE_RecordData));
643 rd_new[edc->off] = rd_old[ri->rd_count - 1];
644 oc = GNUNET_new (struct OperationContext);
645 GNUNET_CONTAINER_DLL_insert (oc_head, oc_tail, oc);
646 oc->qe = GNUNET_NAMESTORE_record_put_by_authority (namestore,
647 pkey, edc->name,
648 ri->rd_count - 1,
649 rd_new,
650 &operation_done_cont, oc);
651 }
652}
653
654
655
656/**
657 * Remove a record from the model. If the given iter identifies an
658 * entire 'name', remove all records under that name.
659 *
660 * @param iter identifying record(s) to remove
661 */
662static void
663remove_records_by_iter (GtkTreeIter *iter)
664{
665 GtkTreeIter parent;
666 char *name;
667 struct GNUNET_HashCode name_hash;
668 struct RecordInfo *ri;
669 struct OperationContext *oc;
670
671 gtk_tree_model_get (tm, iter,
672 GNS_TREESTORE_COL_NAME, &name,
673 -1);
674 GNUNET_CRYPTO_hash (name, strlen (name), &name_hash);
675 ri = GNUNET_CONTAINER_multihashmap_get (n2r,
676 &name_hash);
677 GNUNET_assert (NULL != ri);
678
679 if ( (gtk_tree_model_iter_parent (tm, &parent, iter)) &&
680 (ri->rd_count > 0) )
681 {
682 struct GNUNET_NAMESTORE_RecordData rd_old[ri->rd_count];
683 struct GNUNET_NAMESTORE_RecordData rd_new[ri->rd_count - 1];
684 struct GNUNET_NAMESTORE_RecordData rd;
685 unsigned int off;
686 int n_type;
687 gboolean n_public;
688 guint64 n_exp_time;
689 gboolean n_is_relative;
690 gboolean n_is_shadow;
691 char *n_value;
692
693 /* Removing a single record */
694 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
695 "Removing single record for name `%s'\n",
696 name);
697 GNUNET_break (GNUNET_OK ==
698 GNUNET_NAMESTORE_records_deserialize (ri->data_size,
699 ri->data,
700 ri->rd_count,
701 rd_old));
702 gtk_tree_model_get (tm, iter,
703 GNS_TREESTORE_COL_RECORD_TYPE, &n_type,
704 GNS_TREESTORE_COL_IS_PUBLIC, &n_public,
705 GNS_TREESTORE_COL_EXP_TIME, &n_exp_time,
706 GNS_TREESTORE_COL_EXP_TIME_IS_REL, &n_is_relative,
707 GNS_TREESTORE_COL_IS_SHADOW, &n_is_shadow,
708 GNS_TREESTORE_COL_VAL_AS_STR, &n_value,
709 -1);
710 /* valid name */
711 if (n_public)
712 rd.flags = GNUNET_NAMESTORE_RF_AUTHORITY;
713 else
714 rd.flags = GNUNET_NAMESTORE_RF_AUTHORITY | GNUNET_NAMESTORE_RF_PRIVATE;
715 if (n_is_relative)
716 rd.flags |= GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION;
717 if (n_is_shadow)
718 rd.flags |= GNUNET_NAMESTORE_RF_SHADOW_RECORD;
719 rd.record_type = n_type;
720 rd.expiration_time = n_exp_time;
721 if (GNUNET_OK !=
722 GNUNET_NAMESTORE_string_to_value (n_type, n_value,
723 (void**)&rd.data, &rd.data_size))
724 {
725 /* can't remove, value invalid */
726 GNUNET_assert (0);
727 g_free (n_value);
728 g_free (name);
729 return;
730 }
731 for (off=0;off<ri->rd_count;off++)
732 if (GNUNET_YES ==
733 GNUNET_NAMESTORE_records_cmp (&rd,
734 &rd_old[off]))
735 break;
736 GNUNET_assert (off != ri->rd_count);
737 memcpy (rd_new, rd_old, (ri->rd_count - 1) * sizeof (struct GNUNET_NAMESTORE_RecordData));
738 rd_new[off] = rd_old[ri->rd_count - 1];
739 oc = GNUNET_new (struct OperationContext);
740 GNUNET_CONTAINER_DLL_insert (oc_head, oc_tail, oc);
741 oc->qe = GNUNET_NAMESTORE_record_put_by_authority (namestore,
742 pkey, name,
743 ri->rd_count - 1,
744 rd_new,
745 &operation_done_cont, oc);
746 g_free (n_value);
747 }
748 else
749 {
750 oc = GNUNET_new (struct OperationContext);
751 GNUNET_CONTAINER_DLL_insert (oc_head, oc_tail, oc);
752 oc->qe = GNUNET_NAMESTORE_record_put_by_authority (namestore,
753 pkey, name,
754 0, NULL,
755 &operation_done_cont, oc);
756 }
757 g_free (name);
758}
759
760
761/**
762 * Release resources of an edit dialog context. 615 * Release resources of an edit dialog context.
763 * 616 *
764 * @param edc resources to free 617 * @param edc resources to free
@@ -784,13 +637,68 @@ static void
784edit_dialog_continuation (struct EditDialogContext *edc, 637edit_dialog_continuation (struct EditDialogContext *edc,
785 GtkResponseType ret) 638 GtkResponseType ret)
786{ 639{
640 struct RecordInfo *ri = edc->ri;
641 unsigned int rd_count = (NULL == ri) ? 0 : ri->rd_count;
642 struct GNUNET_NAMESTORE_RecordData rd_old[rd_count];
643 struct GNUNET_NAMESTORE_RecordData rd;
644 void *data;
645 size_t data_size;
646 struct OperationContext *oc;
647
648 if ( (NULL != ri) &&
649 (GNUNET_OK !=
650 GNUNET_NAMESTORE_records_deserialize (ri->data_size,
651 ri->data,
652 ri->rd_count,
653 rd_old)) )
654 {
655 GNUNET_break (0);
656 free_edit_dialog_context (edc);
657 return;
658 }
659 if ( (GTK_RESPONSE_CANCEL == ret) ||
660 (GTK_RESPONSE_DELETE_EVENT == ret) )
661 {
662 free_edit_dialog_context (edc);
663 return;
664 }
665 if (GNUNET_OK != GNUNET_NAMESTORE_string_to_value (edc->record_type, edc->n_value,
666 &data, &data_size))
667 {
668 GNUNET_break (0);
669 free_edit_dialog_context (edc);
670 return;
671 }
672 if (edc->n_public)
673 rd.flags = GNUNET_NAMESTORE_RF_AUTHORITY;
674 else
675 rd.flags = GNUNET_NAMESTORE_RF_AUTHORITY | GNUNET_NAMESTORE_RF_PRIVATE;
676 if (edc->n_is_shadow)
677 rd.flags |= GNUNET_NAMESTORE_RF_SHADOW_RECORD;
678 rd.record_type = edc->record_type;
679 rd.expiration_time = edc->n_exp_time;
680 if (edc->n_is_relative)
681 rd.flags |= GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION;
682 rd.data_size = data_size;
683 rd.data = data;
787 switch (ret) 684 switch (ret)
788 { 685 {
789 case GTK_RESPONSE_REJECT: /* code for 'delete' */ 686 case GTK_RESPONSE_REJECT: /* code for 'delete' */
790 if (GNUNET_YES == edc->old_record_in_namestore) 687 if (GNUNET_YES == edc->old_record_in_namestore)
791 { 688 {
792 /* remove item from tree view and namestore */ 689 /* remove item from tree view and namestore */
793 remove_record_at_offset (edc); 690 struct GNUNET_NAMESTORE_RecordData rd_new[rd_count - 1];
691
692 GNUNET_assert (NULL != ri);
693 memcpy (rd_new, rd_old, (rd_count - 1) * sizeof (struct GNUNET_NAMESTORE_RecordData));
694 rd_new[edc->off] = rd_old[rd_count - 1];
695 oc = GNUNET_new (struct OperationContext);
696 GNUNET_CONTAINER_DLL_insert (oc_head, oc_tail, oc);
697 oc->qe = GNUNET_NAMESTORE_record_put_by_authority (namestore,
698 pkey, edc->name,
699 rd_count + 1,
700 rd_new,
701 &operation_done_cont, oc);
794 } 702 }
795 else 703 else
796 { 704 {
@@ -798,10 +706,6 @@ edit_dialog_continuation (struct EditDialogContext *edc,
798 GNUNET_break (0); 706 GNUNET_break (0);
799 } 707 }
800 break; 708 break;
801 case GTK_RESPONSE_CANCEL:
802 case GTK_RESPONSE_DELETE_EVENT: /* window deletion counts as 'cancel' */
803 /* do nothing */
804 break;
805 case GTK_RESPONSE_OK: 709 case GTK_RESPONSE_OK:
806 /* update model */ 710 /* update model */
807 if (0 == strcmp (edc->new_zone_option, 711 if (0 == strcmp (edc->new_zone_option,
@@ -809,13 +713,32 @@ edit_dialog_continuation (struct EditDialogContext *edc,
809 { 713 {
810 if (GNUNET_YES == edc->old_record_in_namestore) 714 if (GNUNET_YES == edc->old_record_in_namestore)
811 { 715 {
812 /* replace record in database with that from model */ 716 struct GNUNET_NAMESTORE_RecordData rd_new[rd_count];
813 GNUNET_break (0); // not implemented 717
718 GNUNET_assert (NULL != ri);
719 memcpy (rd_new, rd_old, rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData));
720 rd_new[edc->off] = rd;
721 oc = GNUNET_new (struct OperationContext);
722 GNUNET_CONTAINER_DLL_insert (oc_head, oc_tail, oc);
723 oc->qe = GNUNET_NAMESTORE_record_put_by_authority (namestore,
724 pkey, edc->name,
725 rd_count,
726 rd_new,
727 &operation_done_cont, oc);
814 } 728 }
815 else 729 else
816 { 730 {
817 /* add record in database based on model */ 731 struct GNUNET_NAMESTORE_RecordData rd_new[rd_count + 1];
818 GNUNET_break (0); // not implemented 732
733 memcpy (rd_new, rd_old, rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData));
734 rd_new[rd_count] = rd;
735 oc = GNUNET_new (struct OperationContext);
736 GNUNET_CONTAINER_DLL_insert (oc_head, oc_tail, oc);
737 oc->qe = GNUNET_NAMESTORE_record_put_by_authority (namestore,
738 pkey, edc->name,
739 rd_count + 1,
740 rd_new,
741 &operation_done_cont, oc);
819 } 742 }
820 } 743 }
821 else 744 else
@@ -826,8 +749,19 @@ edit_dialog_continuation (struct EditDialogContext *edc,
826 /* zone changed, remove record from old zone, add to new zone! */ 749 /* zone changed, remove record from old zone, add to new zone! */
827 if (GNUNET_YES == edc->old_record_in_namestore) 750 if (GNUNET_YES == edc->old_record_in_namestore)
828 { 751 {
829 /* remove item from tree view and namestore */ 752 /* remove item from tree view and namestore */
830 remove_record_at_offset (edc); 753 struct GNUNET_NAMESTORE_RecordData rd_new[rd_count - 1];
754
755 GNUNET_assert (NULL != ri);
756 memcpy (rd_new, rd_old, (rd_count - 1) * sizeof (struct GNUNET_NAMESTORE_RecordData));
757 rd_new[edc->off] = rd_old[rd_count - 1];
758 oc = GNUNET_new (struct OperationContext);
759 GNUNET_CONTAINER_DLL_insert (oc_head, oc_tail, oc);
760 oc->qe = GNUNET_NAMESTORE_record_put_by_authority (namestore,
761 pkey, edc->name,
762 rd_count + 1,
763 rd_new,
764 &operation_done_cont, oc);
831 } 765 }
832 766
833 /* now add item to target zone */ 767 /* now add item to target zone */
@@ -851,23 +785,23 @@ edit_dialog_continuation (struct EditDialogContext *edc,
851 { 785 {
852 show_error_message (_("Failed to load private key for target zone"), 786 show_error_message (_("Failed to load private key for target zone"),
853 NULL); 787 NULL);
854 return; 788 break;
855 } 789 }
856 GNUNET_break (0); // not implemented 790 GNUNET_break (0); // not implemented
857 /* FIXME: get target zone records, merge with new one, commit! */ 791 /* FIXME: get target zone records, merge with new one, commit! */
858 GNUNET_CRYPTO_ecc_key_free (pk); 792 GNUNET_CRYPTO_ecc_key_free (pk);
859 return; 793 break;
860 } 794 }
861 break; 795 break;
862 default: 796 default:
863 GNUNET_break (0); 797 GNUNET_break (0);
864 break; 798 break;
865 } 799 }
800 GNUNET_free (data);
866 free_edit_dialog_context (edc); 801 free_edit_dialog_context (edc);
867} 802}
868 803
869 804
870
871/** 805/**
872 * Launch a record editing dialog. 806 * Launch a record editing dialog.
873 * 807 *
@@ -974,13 +908,11 @@ GNUNET_setup_gns_popup_edit_button_activate_cb (GtkWidget *widget,
974 GtkTreeSelection *sel; 908 GtkTreeSelection *sel;
975 gint n_type; 909 gint n_type;
976 gchar *n_name; 910 gchar *n_name;
977 unsigned int off; 911 guint off;
978 struct RecordInfo *ri; 912 struct RecordInfo *ri;
979 GtkTreeIter iter; 913 GtkTreeIter iter;
914 struct GNUNET_HashCode name_hash;
980 915
981 /* FIXME: not this easy! Row may still be a 'fresh' row (user
982 can right-click anywhere, right? -- maybe suppress pop-up
983 in that case?? */
984 sel = gtk_tree_view_get_selection (tv); 916 sel = gtk_tree_view_get_selection (tv);
985 if (! gtk_tree_selection_get_selected (sel, NULL, &iter)) 917 if (! gtk_tree_selection_get_selected (sel, NULL, &iter))
986 { 918 {
@@ -991,18 +923,27 @@ GNUNET_setup_gns_popup_edit_button_activate_cb (GtkWidget *widget,
991 gtk_tree_model_get (tm, &iter, 923 gtk_tree_model_get (tm, &iter,
992 GNS_TREESTORE_COL_NAME, &n_name, 924 GNS_TREESTORE_COL_NAME, &n_name,
993 GNS_TREESTORE_COL_RECORD_TYPE, &n_type, 925 GNS_TREESTORE_COL_RECORD_TYPE, &n_type,
926 GNS_TREESTORE_COL_RECORD_OFFSET, &off,
994 -1); 927 -1);
995 // FIXME: determine 'off', 'ri', ... 928 if (NULL == n_name)
996 // Idea: simply store 'off' in model! 929 {
997 off = 42; 930 GNUNET_break (0);
998 ri = NULL; 931 return;
932 }
933 GNUNET_CRYPTO_hash (n_name, strlen (n_name), &name_hash);
934 ri = GNUNET_CONTAINER_multihashmap_get (n2r, &name_hash);
935 if ( (NULL == ri) ||
936 (off >= ri->rd_count) )
937 {
938 GNUNET_break (0);
939 return;
940 }
999 launch_edit_dialog (n_type, n_name, 941 launch_edit_dialog (n_type, n_name,
1000 ri, off); 942 ri, off);
1001 g_free (n_name); 943 g_free (n_name);
1002} 944}
1003 945
1004 946
1005
1006/** 947/**
1007 * The user has selected a new record type. Update the 948 * The user has selected a new record type. Update the
1008 * model and then start the 'edit' dialog. 949 * model and then start the 'edit' dialog.
@@ -1013,20 +954,28 @@ GNUNET_setup_gns_popup_edit_button_activate_cb (GtkWidget *widget,
1013 * @param user_data unused 954 * @param user_data unused
1014 */ 955 */
1015void 956void
1016GNUNET_setup_gns_type_cellrenderercombo_edited_cb (GtkCellRendererCombo *combo, 957GNUNET_setup_gns_type_cellrenderercombo_changed_cb (GtkCellRendererCombo *combo,
1017 gchar *path, 958 gchar *path_string,
1018 gchar *new_text, 959 GtkTreeIter *new_iter,
1019 gpointer user_data) 960 gpointer user_data)
1020{ 961{
962 GtkListStore *ls;
963 gchar *new_text;
1021 GtkTreeIter it; 964 GtkTreeIter it;
1022 guint type; 965 guint type;
1023 char *name_str; 966 char *name_str;
1024 struct GNUNET_HashCode name_hash; 967 struct GNUNET_HashCode name_hash;
1025 struct RecordInfo *ri; 968 struct RecordInfo *ri;
1026 969
970 ls = GTK_LIST_STORE (GNUNET_SETUP_get_object ("GNUNET_setup_gns_type_liststore"));
971 gtk_tree_model_get (GTK_TREE_MODEL (ls), new_iter,
972 1, &new_text,
973 -1);
974
1027 if (0 == strcmp (new_text, _(NEW_RECORD_STR))) 975 if (0 == strcmp (new_text, _(NEW_RECORD_STR)))
1028 { 976 {
1029 GNUNET_break (0); 977 GNUNET_break (0);
978 g_free (new_text);
1030 return; /* no record type was selected */ 979 return; /* no record type was selected */
1031 } 980 }
1032 type = GNUNET_NAMESTORE_typename_to_number (new_text); 981 type = GNUNET_NAMESTORE_typename_to_number (new_text);
@@ -1037,22 +986,25 @@ GNUNET_setup_gns_type_cellrenderercombo_edited_cb (GtkCellRendererCombo *combo,
1037 new_text); 986 new_text);
1038 show_error_message (_("Unsupported record type"), 987 show_error_message (_("Unsupported record type"),
1039 new_text); 988 new_text);
989 g_free (new_text);
1040 return; 990 return;
1041 } 991 }
1042 /* check if this is a new record */ 992 /* check if this is a new record */
1043 gtk_tree_model_get_iter_from_string (tm, &it, path); 993 gtk_tree_model_get_iter_from_string (tm, &it, path_string);
1044 gtk_tree_model_get (tm, &it, 994 gtk_tree_model_get (tm, &it,
1045 GNS_TREESTORE_COL_NAME, &name_str, 995 GNS_TREESTORE_COL_NAME, &name_str,
1046 -1); 996 -1);
1047 if (NULL == name_str) 997 if (NULL == name_str)
1048 { 998 {
1049 GNUNET_break (0); 999 GNUNET_break (0);
1000 g_free (new_text);
1050 return; 1001 return;
1051 } 1002 }
1052 GNUNET_CRYPTO_hash (name_str, strlen (name_str), &name_hash); 1003 GNUNET_CRYPTO_hash (name_str, strlen (name_str), &name_hash);
1053 ri = GNUNET_CONTAINER_multihashmap_get (n2r, &name_hash); 1004 ri = GNUNET_CONTAINER_multihashmap_get (n2r, &name_hash);
1054 launch_edit_dialog (type, name_str, ri, UINT_MAX); 1005 launch_edit_dialog (type, name_str, ri, UINT_MAX);
1055 g_free (name_str); 1006 g_free (name_str);
1007 g_free (new_text);
1056} 1008}
1057 1009
1058 1010
@@ -1119,6 +1071,7 @@ GNUNET_setup_gns_name_cellrenderertext_edited_cb (GtkCellRendererText *renderer,
1119 GNS_TREESTORE_COL_IS_RECORD_ROW, FALSE, 1071 GNS_TREESTORE_COL_IS_RECORD_ROW, FALSE,
1120 GNS_TREESTORE_COL_TYPE_IS_EDITABLE, FALSE, 1072 GNS_TREESTORE_COL_TYPE_IS_EDITABLE, FALSE,
1121 GNS_TREESTORE_COL_NAME_IS_EDITABLE, TRUE, 1073 GNS_TREESTORE_COL_NAME_IS_EDITABLE, TRUE,
1074 GNS_TREESTORE_COL_RECORD_OFFSET, UINT_MAX,
1122 -1); 1075 -1);
1123} 1076}
1124 1077
@@ -1218,23 +1171,116 @@ GNUNET_setup_gns_main_treeview_key_press_event_cb (GtkWidget *widget,
1218 GdkEventKey *event, 1171 GdkEventKey *event,
1219 gpointer user_data) 1172 gpointer user_data)
1220{ 1173{
1221 GtkTreeIter it; 1174 GtkTreeIter iter;
1222 GtkTreeSelection *sel; 1175 GtkTreeSelection *sel;
1223 int not_dummy; 1176 int not_dummy;
1177 GtkTreeIter parent;
1178 char *name;
1179 struct GNUNET_HashCode name_hash;
1180 struct RecordInfo *ri;
1181 struct OperationContext *oc;
1224 1182
1225 /* Check for delete key */ 1183 /* Check for delete key */
1226 if ( (GDK_KEY_PRESS != event->type) || 1184 if ( (GDK_KEY_PRESS != event->type) ||
1227 (GDK_KEY_Delete != event->keyval) ) 1185 (GDK_KEY_Delete != event->keyval) )
1228 return FALSE; 1186 return FALSE;
1229 sel = gtk_tree_view_get_selection(tv); 1187 sel = gtk_tree_view_get_selection(tv);
1230 if (! gtk_tree_selection_get_selected (sel, NULL, &it)) 1188 if (! gtk_tree_selection_get_selected (sel, NULL, &iter))
1231 return TRUE; /* nothing selected */ 1189 return TRUE; /* nothing selected */
1232 gtk_tree_model_get (tm, &it, 1190 gtk_tree_model_get (tm, &iter,
1233 GNS_TREESTORE_COL_NOT_DUMMY_ROW, &not_dummy, 1191 GNS_TREESTORE_COL_NOT_DUMMY_ROW, &not_dummy,
1192 GNS_TREESTORE_COL_NAME, &name,
1234 -1); 1193 -1);
1235 if (GNUNET_NO == not_dummy) 1194 if (GNUNET_NO == not_dummy)
1195 {
1196 g_free (name);
1236 return TRUE; /* do not delete the dummy line */ 1197 return TRUE; /* do not delete the dummy line */
1237 remove_records_by_iter (&it); 1198 }
1199 GNUNET_CRYPTO_hash (name, strlen (name), &name_hash);
1200 ri = GNUNET_CONTAINER_multihashmap_get (n2r,
1201 &name_hash);
1202 GNUNET_assert (NULL != ri);
1203
1204 if ( (gtk_tree_model_iter_parent (tm, &parent, &iter)) &&
1205 (ri->rd_count > 0) )
1206 {
1207 struct GNUNET_NAMESTORE_RecordData rd_old[ri->rd_count];
1208 struct GNUNET_NAMESTORE_RecordData rd_new[ri->rd_count - 1];
1209 struct GNUNET_NAMESTORE_RecordData rd;
1210 unsigned int off;
1211 int n_type;
1212 gboolean n_public;
1213 guint64 n_exp_time;
1214 gboolean n_is_relative;
1215 gboolean n_is_shadow;
1216 char *n_value;
1217
1218 /* Removing a single record */
1219 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1220 "Removing single record for name `%s'\n",
1221 name);
1222 GNUNET_break (GNUNET_OK ==
1223 GNUNET_NAMESTORE_records_deserialize (ri->data_size,
1224 ri->data,
1225 ri->rd_count,
1226 rd_old));
1227 gtk_tree_model_get (tm, &iter,
1228 GNS_TREESTORE_COL_RECORD_TYPE, &n_type,
1229 GNS_TREESTORE_COL_IS_PUBLIC, &n_public,
1230 GNS_TREESTORE_COL_EXP_TIME, &n_exp_time,
1231 GNS_TREESTORE_COL_EXP_TIME_IS_REL, &n_is_relative,
1232 GNS_TREESTORE_COL_IS_SHADOW, &n_is_shadow,
1233 GNS_TREESTORE_COL_VAL_AS_STR, &n_value,
1234 -1);
1235 /* valid name */
1236 if (n_public)
1237 rd.flags = GNUNET_NAMESTORE_RF_AUTHORITY;
1238 else
1239 rd.flags = GNUNET_NAMESTORE_RF_AUTHORITY | GNUNET_NAMESTORE_RF_PRIVATE;
1240 if (n_is_relative)
1241 rd.flags |= GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION;
1242 if (n_is_shadow)
1243 rd.flags |= GNUNET_NAMESTORE_RF_SHADOW_RECORD;
1244 rd.record_type = n_type;
1245 rd.expiration_time = n_exp_time;
1246 if (GNUNET_OK !=
1247 GNUNET_NAMESTORE_string_to_value (n_type, n_value,
1248 (void**)&rd.data, &rd.data_size))
1249 {
1250 /* can't remove, value invalid */
1251 GNUNET_assert (0);
1252 g_free (n_value);
1253 g_free (name);
1254 return TRUE;
1255 }
1256 for (off=0;off<ri->rd_count;off++)
1257 if (GNUNET_YES ==
1258 GNUNET_NAMESTORE_records_cmp (&rd,
1259 &rd_old[off]))
1260 break;
1261 GNUNET_assert (off != ri->rd_count);
1262 memcpy (rd_new, rd_old, (ri->rd_count - 1) * sizeof (struct GNUNET_NAMESTORE_RecordData));
1263 rd_new[off] = rd_old[ri->rd_count - 1];
1264 oc = GNUNET_new (struct OperationContext);
1265 GNUNET_CONTAINER_DLL_insert (oc_head, oc_tail, oc);
1266 oc->qe = GNUNET_NAMESTORE_record_put_by_authority (namestore,
1267 pkey, name,
1268 ri->rd_count - 1,
1269 rd_new,
1270 &operation_done_cont, oc);
1271 g_free (n_value);
1272 }
1273 else
1274 {
1275 oc = GNUNET_new (struct OperationContext);
1276 GNUNET_CONTAINER_DLL_insert (oc_head, oc_tail, oc);
1277 oc->qe = GNUNET_NAMESTORE_record_put_by_authority (namestore,
1278 pkey, name,
1279 0, NULL,
1280 &operation_done_cont, oc);
1281 }
1282 g_free (name);
1283
1238 return TRUE; 1284 return TRUE;
1239} 1285}
1240 1286
@@ -1450,13 +1496,7 @@ zone_iteration_proc (void *cls,
1450 gtk_tree_path_free (path); 1496 gtk_tree_path_free (path);
1451 /* remove all records, we'll re-add those that are left next */ 1497 /* remove all records, we'll re-add those that are left next */
1452 if (gtk_tree_model_iter_children (tm, &iter_record, &iter_name)) 1498 if (gtk_tree_model_iter_children (tm, &iter_record, &iter_name))
1453 { 1499 while (gtk_tree_store_remove (ts, &iter_record)) ;
1454 do
1455 {
1456 gtk_tree_store_remove (ts, &iter_record);
1457 }
1458 while (gtk_tree_model_iter_next (tm, &iter_record));
1459 }
1460 } 1500 }
1461 else 1501 else
1462 { 1502 {
@@ -1470,6 +1510,7 @@ zone_iteration_proc (void *cls,
1470 GNS_TREESTORE_COL_IS_RECORD_ROW, TRUE, 1510 GNS_TREESTORE_COL_IS_RECORD_ROW, TRUE,
1471 GNS_TREESTORE_COL_NOT_DUMMY_ROW, FALSE, 1511 GNS_TREESTORE_COL_NOT_DUMMY_ROW, FALSE,
1472 GNS_TREESTORE_COL_TYPE_IS_EDITABLE, TRUE, 1512 GNS_TREESTORE_COL_TYPE_IS_EDITABLE, TRUE,
1513 GNS_TREESTORE_COL_RECORD_OFFSET, UINT_MAX,
1473 -1); 1514 -1);
1474 1515
1475 path = gtk_tree_model_get_path (tm, 1516 path = gtk_tree_model_get_path (tm,
@@ -1503,7 +1544,7 @@ zone_iteration_proc (void *cls,
1503 ri->data_size = GNUNET_NAMESTORE_records_get_size (rd_count, rd); 1544 ri->data_size = GNUNET_NAMESTORE_records_get_size (rd_count, rd);
1504 if (0 != ri->data_size) 1545 if (0 != ri->data_size)
1505 ri->data = GNUNET_malloc (ri->data_size); 1546 ri->data = GNUNET_malloc (ri->data_size);
1506 GNUNET_break (GNUNET_OK == 1547 GNUNET_break (ri->data_size ==
1507 GNUNET_NAMESTORE_records_serialize (rd_count, rd, 1548 GNUNET_NAMESTORE_records_serialize (rd_count, rd,
1508 ri->data_size, ri->data)); 1549 ri->data_size, ri->data));
1509 1550
@@ -1570,6 +1611,7 @@ zone_iteration_proc (void *cls,
1570 GNS_TREESTORE_COL_VAL_AS_STR, val, 1611 GNS_TREESTORE_COL_VAL_AS_STR, val,
1571 GNS_TREESTORE_COL_IS_RECORD_ROW, TRUE, 1612 GNS_TREESTORE_COL_IS_RECORD_ROW, TRUE,
1572 GNS_TREESTORE_COL_NOT_DUMMY_ROW, TRUE, 1613 GNS_TREESTORE_COL_NOT_DUMMY_ROW, TRUE,
1614 GNS_TREESTORE_COL_RECORD_OFFSET, (guint) c,
1573 -1); 1615 -1);
1574 GNUNET_free (type_str); 1616 GNUNET_free (type_str);
1575 GNUNET_free (val); 1617 GNUNET_free (val);
@@ -1649,6 +1691,7 @@ load_zone (const char *zonename)
1649 GNS_TREESTORE_COL_NOT_DUMMY_ROW, FALSE, 1691 GNS_TREESTORE_COL_NOT_DUMMY_ROW, FALSE,
1650 GNS_TREESTORE_COL_TYPE_IS_EDITABLE, FALSE, 1692 GNS_TREESTORE_COL_TYPE_IS_EDITABLE, FALSE,
1651 GNS_TREESTORE_COL_NAME_IS_EDITABLE, TRUE, 1693 GNS_TREESTORE_COL_NAME_IS_EDITABLE, TRUE,
1694 GNS_TREESTORE_COL_RECORD_OFFSET, UINT_MAX,
1652 -1); 1695 -1);
1653 /* Load zone from namestore! */ 1696 /* Load zone from namestore! */
1654#if HAVE_QRENCODE_H 1697#if HAVE_QRENCODE_H