aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/setup/Makefile.am2
-rw-r--r--src/setup/gnunet-setup-dns-exit.c749
-rw-r--r--src/setup/gnunet-setup-gns.c1718
-rw-r--r--src/setup/gnunet-setup-namestore-config.c112
-rw-r--r--src/setup/gnunet-setup-namestore-plugins.c67
-rw-r--r--src/setup/gnunet-setup-options.c800
-rw-r--r--src/setup/gnunet-setup.c68
-rw-r--r--src/setup/gnunet-setup.h12
8 files changed, 2790 insertions, 738 deletions
diff --git a/src/setup/Makefile.am b/src/setup/Makefile.am
index d66e9edb..bce82e78 100644
--- a/src/setup/Makefile.am
+++ b/src/setup/Makefile.am
@@ -27,6 +27,8 @@ gnunet_setup_SOURCES = \
27 gnunet-setup-datastore-config.c \ 27 gnunet-setup-datastore-config.c \
28 gnunet-setup-datacache-plugins.c \ 28 gnunet-setup-datacache-plugins.c \
29 gnunet-setup-datacache-config.c \ 29 gnunet-setup-datacache-config.c \
30 gnunet-setup-namestore-plugins.c \
31 gnunet-setup-namestore-config.c \
30 gnunet-setup-hostlist-editing.c \ 32 gnunet-setup-hostlist-editing.c \
31 gnunet-setup-hostlist-server.c 33 gnunet-setup-hostlist-server.c
32gnunet_setup_LDADD = \ 34gnunet_setup_LDADD = \
diff --git a/src/setup/gnunet-setup-dns-exit.c b/src/setup/gnunet-setup-dns-exit.c
new file mode 100644
index 00000000..131f0b07
--- /dev/null
+++ b/src/setup/gnunet-setup-dns-exit.c
@@ -0,0 +1,749 @@
1/*
2 This file is part of GNUnet.
3 (C) 2010, 2011, 2012 Christian Grothoff (and other contributing authors)
4
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
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file src/setup/gnunet-setup-dns-exit.c
23 * @brief code for the dialog to configure GNS-EXIT records
24 * @author Christian Grothoff
25 */
26#include "gnunet-setup.h"
27#include <gnunet/gnunet_util_lib.h>
28#include <gdk/gdkkeysyms.h>
29
30
31/**
32 * Check if the section represents a DNS entry and then update the
33 * GtkListStore accordingly.
34 *
35 * @param cls the list store to modify
36 * @param section name of the section
37 */
38static void
39add_dns_entry_to_list_store (void *cls, const char *section)
40{
41 GtkListStore *ls = cls;
42 GtkTreeIter iter;
43 char *sld;
44 char *hostname;
45 char *hostport;
46 char *redirect;
47 char *cpy;
48 gboolean udp;
49
50 if (NULL == section)
51 {
52 gtk_list_store_insert_with_values (ls, &iter, G_MAXINT,
53 GNUNET_GTK_SETUP_GNS_MC_HOSTNAME, "",
54 GNUNET_GTK_SETUP_GNS_MC_SOURCEPORT,
55 (guint) 80,
56 GNUNET_GTK_SETUP_GNS_MC_TARGETPORT,
57 (guint) 8080,
58 GNUNET_GTK_SETUP_GNS_MC_HOSTNAME,
59 "localhost4",
60 GNUNET_GTK_SETUP_GNS_MC_ISUDP, "tcp",
61 -1);
62 return;
63 }
64
65 if ((8 > strlen (section)) ||
66 (0 != strcmp (".gnunet.", section + ((strlen (section) - 8)))))
67 return;
68 sld = GNUNET_strdup (section);
69 sld[strlen (section) - 8] = '\0';
70 udp = FALSE;
71 do
72 {
73 if (GNUNET_OK ==
74 GNUNET_CONFIGURATION_get_value_string (cfg, section,
75 (TRUE ==
76 udp) ? "UDP_REDIRECTS" :
77 "TCP_REDIRECTS", &cpy))
78 {
79 for (redirect = strtok (cpy, " "); redirect != NULL;
80 redirect = strtok (NULL, " "))
81 {
82 if (NULL == (hostname = strstr (redirect, ":")))
83 {
84 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
85 _("Option `%s' is not formatted correctly!\n"), redirect);
86 continue;
87 }
88 hostname[0] = '\0';
89 hostname++;
90 if (NULL == (hostport = strstr (hostname, ":")))
91 {
92 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
93 _("Option `%s' is not formatted correctly!\n"), redirect);
94 continue;
95 }
96 hostport[0] = '\0';
97 hostport++;
98
99 int local_port = atoi (redirect);
100
101 if (!((local_port > 0) && (local_port < 65536)))
102 {
103 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
104 _("`%s' is not a valid port number!\n"), redirect);
105 continue;
106 }
107 int host_port = atoi (hostport);
108
109 if (!((host_port > 0) && (host_port < 65536)))
110 {
111 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
112 _("`%s' is not a valid port number!\n"), hostport);
113 continue;
114 }
115 gtk_list_store_insert_with_values (ls, &iter, 0,
116 GNUNET_GTK_SETUP_GNS_MC_HOSTNAME,
117 sld,
118 GNUNET_GTK_SETUP_GNS_MC_SOURCEPORT,
119 (guint) local_port,
120 GNUNET_GTK_SETUP_GNS_MC_TARGETPORT,
121 (guint) host_port,
122 GNUNET_GTK_SETUP_GNS_MC_TARGETHOSTNAME,
123 hostname,
124 GNUNET_GTK_SETUP_GNS_MC_ISUDP,
125 (TRUE == udp) ? "udp" : "tcp", -1);
126 }
127 GNUNET_free (cpy);
128 }
129 udp = !udp;
130 }
131 while (udp != FALSE);
132 GNUNET_free (sld);
133}
134
135
136/**
137 * Initialize the GtkListModel with the VPN's DNS service specification.
138 *
139 * @param cls NULL
140 * @param section section with the value (NULL)
141 * @param option option name (NULL)
142 * @param value value as a string (NULL)
143 * @param widget widget to initialize (the GtkTreeView)
144 * @param cfg configuration handle
145 * @return GNUNET_OK on success, GNUNET_SYSERR if there was a problem
146 */
147static int
148load_vpn_dns_configuration (const void *cls, const char *section,
149 const char *option, const char *value,
150 GObject * widget,
151 const struct GNUNET_CONFIGURATION_Handle *cfg)
152{
153 GtkTreeView *tv;
154 GtkListStore *ls;
155
156 tv = GTK_TREE_VIEW (widget);
157 if (tv == NULL)
158 {
159 GNUNET_break (0);
160 return GNUNET_SYSERR;
161 }
162 ls = GTK_LIST_STORE (gtk_tree_view_get_model (tv));
163 GNUNET_CONFIGURATION_iterate_sections (cfg, &add_dns_entry_to_list_store, ls);
164 /* finally, add empty entry */
165 add_dns_entry_to_list_store (ls, NULL);
166 return GNUNET_OK;
167}
168
169
170/**
171 * Records we use to build DNS information lists.
172 */
173struct DnsInfo
174{
175 struct DnsInfo *next;
176 char *section;
177 char *altnames;
178 char *tcpred;
179 char *udpred;
180 unsigned long long ttl;
181};
182
183
184/**
185 * Function called for each section in the configuration.
186 * Gather existing ttl, section names and altnames.
187 *
188 * @param cls 'struct DnsInfo**' to create
189 * @param section name of a section in the configuration
190 */
191static void
192collect_dns_sections (void *cls, const char *section)
193{
194 struct DnsInfo **base = cls;
195 struct DnsInfo *pos;
196
197 if ((8 > strlen (section)) ||
198 (0 != strcmp (".gnunet.", section + ((strlen (section) - 8)))))
199 return;
200 pos = GNUNET_malloc (sizeof (struct DnsInfo));
201 pos->section = GNUNET_strdup (section);
202 if (GNUNET_OK !=
203 GNUNET_CONFIGURATION_get_value_number (cfg, section, "TTL", &pos->ttl))
204 pos->ttl = 3600000;
205 if (GNUNET_OK !=
206 GNUNET_CONFIGURATION_get_value_string (cfg, section, "ALTERNATIVE_NAMES",
207 &pos->altnames))
208 pos->altnames = NULL;
209 pos->tcpred = GNUNET_strdup ("");
210 pos->udpred = GNUNET_strdup ("");
211 pos->next = *base;
212 *base = pos;
213}
214
215
216/**
217 * Function called for each section in the configuration.
218 * Removes those ending in '.gnunet.'.
219 *
220 * @param cls unused
221 * @param section name of a section in the configuration
222 */
223static void
224remove_dns_sections (void *cls, const char *section)
225{
226 if ((8 > strlen (section)) ||
227 (0 != strcmp (".gnunet.", section + ((strlen (section) - 8)))))
228 return;
229 GNUNET_CONFIGURATION_remove_section (cfg, section);
230}
231
232
233/**
234 * Given the list store and the data in it, update the
235 * configuration file accordingly.
236 *
237 * @param tm model to use
238 */
239static void
240update_vpn_dns_configuration (GtkTreeModel * tm)
241{
242 GtkTreeIter iter;
243 gchar *hostname;
244 guint srcport;
245 guint targetport;
246 gchar *targethost;
247 gchar *tcpudp;
248 char *tmp;
249 struct DnsInfo *head;
250 struct DnsInfo *pos;
251
252 head = NULL;
253 GNUNET_CONFIGURATION_iterate_sections (cfg, &collect_dns_sections, &head);
254 if (TRUE == gtk_tree_model_get_iter_first (tm, &iter))
255 do
256 {
257 gtk_tree_model_get (tm, &iter,
258 GNUNET_GTK_SETUP_GNS_MC_HOSTNAME, &hostname,
259 GNUNET_GTK_SETUP_GNS_MC_SOURCEPORT, &srcport,
260 GNUNET_GTK_SETUP_GNS_MC_TARGETPORT, &targetport,
261 GNUNET_GTK_SETUP_GNS_MC_TARGETHOSTNAME, &targethost,
262 GNUNET_GTK_SETUP_GNS_MC_ISUDP, &tcpudp,
263 -1);
264 if (0 != strlen (hostname))
265 {
266 pos = head;
267 GNUNET_asprintf (&tmp, "%s.gnunet.", hostname);
268 while ((NULL != pos) && (0 != strcasecmp (tmp, pos->section)))
269 pos = pos->next;
270 if (pos == NULL)
271 {
272 pos = GNUNET_malloc (sizeof (struct DnsInfo));
273 pos->section = tmp;
274 pos->ttl = 3600000;
275 pos->altnames = NULL;
276 pos->tcpred = GNUNET_strdup ("");
277 pos->udpred = GNUNET_strdup ("");
278 pos->next = head;
279 head = pos;
280 }
281 else
282 {
283 GNUNET_free (tmp);
284 }
285 GNUNET_asprintf (&tmp, "%u:%s:%u %s", srcport, targethost, targetport,
286 (0 ==
287 strcasecmp ("tcp",
288 tcpudp)) ? pos->tcpred : pos->udpred);
289 if (0 == strcasecmp ("tcp", tcpudp))
290 {
291 GNUNET_free (pos->tcpred);
292 pos->tcpred = tmp;
293 }
294 else
295 {
296 GNUNET_free (pos->udpred);
297 pos->udpred = tmp;
298 }
299 }
300 g_free (tcpudp);
301 g_free (hostname);
302 g_free (targethost);
303 }
304 while (TRUE == gtk_tree_model_iter_next (tm, &iter));
305 GNUNET_CONFIGURATION_iterate_sections (cfg, &remove_dns_sections, NULL);
306 while (NULL != head)
307 {
308 pos = head;
309 head = pos->next;
310 if (pos->altnames != NULL)
311 GNUNET_CONFIGURATION_set_value_string (cfg, pos->section,
312 "ALTERNATIVE_NAMES",
313 pos->altnames);
314 if (strlen (pos->udpred) > 0)
315 GNUNET_CONFIGURATION_set_value_string (cfg, pos->section, "UDP_REDIRECTS",
316 pos->udpred);
317 if (strlen (pos->tcpred) > 0)
318 GNUNET_CONFIGURATION_set_value_string (cfg, pos->section, "TCP_REDIRECTS",
319 pos->tcpred);
320 if ((strlen (pos->udpred) > 0) || (strlen (pos->tcpred) > 0))
321 GNUNET_CONFIGURATION_set_value_number (cfg, pos->section, "TTL",
322 pos->ttl);
323 GNUNET_free_non_null (pos->altnames);
324 GNUNET_free (pos->tcpred);
325 GNUNET_free (pos->udpred);
326 GNUNET_free (pos->section);
327 GNUNET_free (pos);
328 }
329}
330
331
332/**
333 * The user has edited the DNS name of a service we're offering.
334 * Update the GtkTreeModel (at the given path) and update the
335 * respective service entry in the configuration file. Finally,
336 * if the edited path is for a "fresh" entry, create another empty
337 * one at the bottom. If the hostname was set to empty, remove
338 * the entire entry from the configuration and the model.
339 *
340 * @param renderer GtkCellRendererText that changed
341 * @param path GtkTreePath identifying where in the Model the change is
342 * @param new_text the new text that was stored in the line
343 * @param user_data NULL
344 */
345static void
346save_vpn_dns_service_dnsname (GtkCellRendererText * renderer, gchar * path,
347 gchar * new_text, gpointer user_data)
348{
349 GtkTreeModel *tm;
350 GtkListStore *ls;
351 GtkTreeIter iter;
352 gchar *old;
353
354 tm = GTK_TREE_MODEL (GNUNET_SETUP_get_object ("GNUNET_setup_gns_liststore"));
355 if (NULL == tm)
356 {
357 GNUNET_break (0);
358 return;
359 }
360 ls = GTK_LIST_STORE (tm);
361 if (NULL == ls)
362 {
363 GNUNET_break (0);
364 return;
365 }
366 if (TRUE != gtk_tree_model_get_iter_from_string (tm, &iter, path))
367 {
368 GNUNET_break (0);
369 return;
370 }
371 gtk_tree_model_get (tm, &iter, GNUNET_GTK_SETUP_GNS_MC_HOSTNAME, &old, -1);
372 if ((0 != strlen (old)) && (0 == strlen (new_text)))
373 {
374 /* deletion */
375 gtk_list_store_remove (ls, &iter);
376 g_free (old);
377 /* update configuration */
378 update_vpn_dns_configuration (tm);
379 return;
380 }
381 /* update model */
382 gtk_list_store_set (ls, &iter,
383 GNUNET_GTK_SETUP_GNS_MC_HOSTNAME, new_text, -1);
384 /* update configuration */
385 update_vpn_dns_configuration (tm);
386 if ((0 == strlen (old)) && (0 != strlen (new_text)))
387 {
388 /* need another empty entry at the end for future expansion */
389 add_dns_entry_to_list_store (GTK_LIST_STORE (tm), NULL);
390 }
391 g_free (old);
392}
393
394
395/**
396 * Initialize the GtkListModel with the VPN's DNS service specification.
397 *
398 * @param cls NULL
399 * @param section section with the value (NULL)
400 * @param option option name (NULL)
401 * @param widget widget to initialize (the GtkTreeView)
402 * @param cfg configuration handle
403 * @return GNUNET_OK on success, GNUNET_SYSERR if there was a problem
404 */
405static int
406gns_name_install_edited_handler (const void *cls,
407 const char *section,
408 const char *option,
409 GObject * widget,
410 struct
411 GNUNET_CONFIGURATION_Handle
412 *cfg)
413{
414 static int once;
415 GtkCellRendererText *rt;
416
417 rt = GTK_CELL_RENDERER_TEXT (widget);
418 if (NULL == rt)
419 return GNUNET_SYSERR;
420 if (0 != once++)
421 return GNUNET_OK;
422 g_signal_connect (rt, "edited", G_CALLBACK (&save_vpn_dns_service_dnsname),
423 NULL);
424 return GNUNET_OK;
425}
426
427
428/**
429 * The user has edited the DNS name of a service we're offering.
430 * Update the GtkTreeModel (at the given path) and update the
431 * respective service entry in the configuration file. Finally,
432 * if the edited path is for a "fresh" entry, create another empty
433 * one at the bottom. If the hostname was set to empty, remove
434 * the entire entry from the configuration and the model.
435 *
436 * @param renderer GtkCellRendererText that changed
437 * @param path GtkTreePath identifying where in the Model the change is
438 * @param new_text the new text that was stored in the line
439 * @param user_data NULL
440 */
441static void
442save_vpn_dns_service_tcpudp (GtkCellRendererText * renderer, gchar * path,
443 gchar * new_text, gpointer user_data)
444{
445 GtkTreeModel *tm;
446 GtkListStore *ls;
447 GtkTreeIter iter;
448
449 if ((0 != strcasecmp ("tcp", new_text)) &&
450 (0 != strcasecmp ("udp", new_text)))
451 {
452 /* FIXME: warn... */
453 return;
454 }
455 tm = GTK_TREE_MODEL (GNUNET_SETUP_get_object ("GNUNET_setup_gns_liststore"));
456 if (NULL == tm)
457 {
458 GNUNET_break (0);
459 return;
460 }
461 ls = GTK_LIST_STORE (tm);
462 if (NULL == ls)
463 {
464 GNUNET_break (0);
465 return;
466 }
467 if (TRUE != gtk_tree_model_get_iter_from_string (tm, &iter, path))
468 {
469 GNUNET_break (0);
470 return;
471 }
472 /* update model */
473 gtk_list_store_set (ls, &iter, GNUNET_GTK_SETUP_GNS_MC_ISUDP, new_text, -1);
474 /* update configuration */
475 update_vpn_dns_configuration (tm);
476}
477
478
479/**
480 * Initialize the GtkListModel with the VPN's DNS service specification.
481 *
482 * @param cls NULL
483 * @param section section with the value (NULL)
484 * @param option option name (NULL)
485 * @param widget widget to initialize (the GtkTreeView)
486 * @param cfg configuration handle
487 * @return GNUNET_OK on success, GNUNET_SYSERR if there was a problem
488 */
489static int
490gns_type_install_edited_handler (const void *cls,
491 const char *section,
492 const char *option,
493 GObject * widget,
494 struct
495 GNUNET_CONFIGURATION_Handle *cfg)
496{
497 static int once;
498 GtkCellRendererText *rt;
499
500 rt = GTK_CELL_RENDERER_TEXT (widget);
501 if (NULL == rt)
502 return GNUNET_SYSERR;
503 if (0 != once++)
504 return GNUNET_OK;
505 g_signal_connect (rt, "edited", G_CALLBACK (&save_vpn_dns_service_tcpudp),
506 NULL);
507 return GNUNET_OK;
508}
509
510
511/**
512 * The user has edited the DNS name of a service we're offering.
513 * Update the GtkTreeModel (at the given path) and update the
514 * respective service entry in the configuration file. Finally,
515 * if the edited path is for a "fresh" entry, create another empty
516 * one at the bottom. If the hostname was set to empty, remove
517 * the entire entry from the configuration and the model.
518 *
519 * @param renderer GtkCellRendererText that changed
520 * @param path GtkTreePath identifying where in the Model the change is
521 * @param new_text the new text that was stored in the line
522 * @param user_data NULL
523 */
524static void
525save_vpn_dns_service_sourceport (GtkCellRendererText * renderer, gchar * path,
526 gchar * new_text, gpointer user_data)
527{
528 GtkTreeModel *tm;
529 GtkListStore *ls;
530 GtkTreeIter iter;
531 int port;
532
533 port = atoi (new_text);
534 if ((port < 1) || (port > UINT16_MAX))
535 {
536 /* invalid port, FIXME: warn */
537 return;
538 }
539 tm = GTK_TREE_MODEL (GNUNET_SETUP_get_object ("GNUNET_setup_gns_liststore"));
540 if (NULL == tm)
541 {
542 GNUNET_break (0);
543 return;
544 }
545 ls = GTK_LIST_STORE (tm);
546 if (NULL == ls)
547 {
548 GNUNET_break (0);
549 return;
550 }
551 if (TRUE != gtk_tree_model_get_iter_from_string (tm, &iter, path))
552 {
553 GNUNET_break (0);
554 return;
555 }
556 /* update model */
557 gtk_list_store_set (ls, &iter,
558 GNUNET_GTK_SETUP_GNS_MC_SOURCEPORT, (guint) port, -1);
559 /* update configuration */
560 update_vpn_dns_configuration (tm);
561}
562
563
564/**
565 * Initialize the GtkListModel with the VPN's DNS service specification.
566 *
567 * @param cls NULL
568 * @param section section with the value (NULL)
569 * @param option option name (NULL)
570 * @param widget widget to initialize (the GtkTreeView)
571 * @param cfg configuration handle
572 * @return GNUNET_OK on success, GNUNET_SYSERR if there was a problem
573 */
574static int
575gns_ttl_install_edited_handler (const void *cls,
576 const char *section,
577 const char *option,
578 GObject * widget,
579 struct
580 GNUNET_CONFIGURATION_Handle
581 *cfg)
582{
583 static int once;
584 GtkCellRendererText *rt;
585
586 rt = GTK_CELL_RENDERER_TEXT (widget);
587 if (NULL == rt)
588 return GNUNET_SYSERR;
589 if (0 != once++)
590 return GNUNET_OK;
591 g_signal_connect (rt, "edited", G_CALLBACK (&save_vpn_dns_service_sourceport),
592 NULL);
593 return GNUNET_OK;
594}
595
596
597/**
598 * The user has edited the DNS name of a service we're offering.
599 * Update the GtkTreeModel (at the given path) and update the
600 * respective service entry in the configuration file. Finally,
601 * if the edited path is for a "fresh" entry, create another empty
602 * one at the bottom. If the hostname was set to empty, remove
603 * the entire entry from the configuration and the model.
604 *
605 * @param renderer GtkCellRendererText that changed
606 * @param path GtkTreePath identifying where in the Model the change is
607 * @param new_text the new text that was stored in the line
608 * @param user_data NULL
609 */
610static void
611save_vpn_dns_service_targethostname (GtkCellRendererText * renderer,
612 gchar * path, gchar * new_text,
613 gpointer user_data)
614{
615 GtkTreeModel *tm;
616 GtkListStore *ls;
617 GtkTreeIter iter;
618
619 tm = GTK_TREE_MODEL (GNUNET_SETUP_get_object ("GNUNET_setup_gns_liststore"));
620 if (NULL == tm)
621 {
622 GNUNET_break (0);
623 return;
624 }
625 ls = GTK_LIST_STORE (tm);
626 if (NULL == ls)
627 {
628 GNUNET_break (0);
629 return;
630 }
631 if (TRUE != gtk_tree_model_get_iter_from_string (tm, &iter, path))
632 {
633 GNUNET_break (0);
634 return;
635 }
636 /* update model */
637 gtk_list_store_set (ls, &iter,
638 GNUNET_GTK_SETUP_GNS_MC_TARGETHOSTNAME, new_text, -1);
639 /* update configuration */
640 update_vpn_dns_configuration (tm);
641}
642
643
644/**
645 * Initialize the GtkListModel with the VPN's DNS service specification.
646 *
647 * @param cls NULL
648 * @param section section with the value (NULL)
649 * @param option option name (NULL)
650 * @param widget widget to initialize (the GtkTreeView)
651 * @param cfg configuration handle
652 * @return GNUNET_OK on success, GNUNET_SYSERR if there was a problem
653 */
654static int
655gns_value_install_edited_handler (const void *cls,
656 const char *section,
657 const char *option,
658 GObject * widget,
659 struct
660 GNUNET_CONFIGURATION_Handle
661 *cfg)
662{
663 static int once;
664 GtkCellRendererText *rt;
665
666 rt = GTK_CELL_RENDERER_TEXT (widget);
667 if (NULL == rt)
668 return GNUNET_SYSERR;
669 if (0 != once++)
670 return GNUNET_OK;
671 g_signal_connect (rt, "edited",
672 G_CALLBACK (&save_vpn_dns_service_targethostname), NULL);
673 return GNUNET_OK;
674}
675
676
677#if 0
678 {
679 "GNUNET_setup_gns_treeview",
680 NULL,
681 NULL,
682 NULL,
683 gettext_noop
684 ("Specification of .gnunet TLD"),
685 "https://gnunet.org/configuration-dns",
686 &load_vpn_dns_configuration,
687 NULL, NULL,
688 NULL, NULL,
689 NULL},
690
691 {
692 "GNUNET_setup_gns_name_cellrenderertext",
693 "editing-started",
694 NULL,
695 NULL,
696 NULL,
697 "https://gnunet.org/configuration-dns",
698 NULL,
699 &gns_name_install_edited_handler,
700 NULL,
701 NULL,
702 NULL,
703 NULL},
704
705 {
706 "GNUNET_setup_gns_type_cellrenderertext",
707 "editing-started",
708 NULL,
709 NULL,
710 NULL,
711 "https://gnunet.org/configuration-dns",
712 NULL,
713 &gns_type_install_edited_handler,
714 NULL,
715 NULL,
716 NULL,
717 NULL},
718
719 {
720 "GNUNET_setup_gns_ttl_cellrenderertext",
721 "editing-started",
722 NULL,
723 NULL,
724 NULL,
725 "https://gnunet.org/configuration-dns",
726 NULL,
727 &gns_ttl_install_edited_handler,
728 NULL,
729 NULL,
730 NULL,
731 NULL},
732
733 {
734 "GNUNET_setup_gns_value_cellrenderertext",
735 "editing-started",
736 NULL,
737 NULL,
738 NULL,
739 "https://gnunet.org/configuration-dns",
740 NULL,
741 &gns_value_install_edited_handler,
742 NULL,
743 NULL,
744 NULL,
745 NULL},
746
747#endif
748
749/* end of gnunet-setup-dns-exit.c */
diff --git a/src/setup/gnunet-setup-gns.c b/src/setup/gnunet-setup-gns.c
new file mode 100644
index 00000000..83a49e89
--- /dev/null
+++ b/src/setup/gnunet-setup-gns.c
@@ -0,0 +1,1718 @@
1/*
2 This file is part of GNUnet
3 (C) 2012 Christian Grothoff (and other contributing authors)
4
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
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file src/setup/gnunet-setup-gns.c
23 * @author Christian Grothoff
24 * @brief everything releated to the main GNS zone tree view
25 */
26#include "gnunet_gtk.h"
27#include "gnunet-gns-gtk.h"
28
29
30/**
31 * Columns in the gns model.
32 */
33enum GNSTreestoreColumn
34{
35 /**
36 * A gchararray
37 */
38 GNS_TREESTORE_COL_NAME = 0,
39
40 /**
41 * A gboolean
42 */
43 GNS_TREESTORE_COL_IS_PUBLIC,
44
45 /**
46 * A guint
47 */
48 GNS_TREESTORE_COL_RECORD_TYPE,
49
50 /**
51 * A gchararray
52 */
53 GNS_TREESTORE_COL_RECORD_TYPE_AS_STR,
54
55 /**
56 * A guint64
57 */
58 GNS_TREESTORE_COL_EXP_TIME,
59
60 /**
61 * A gboolean
62 */
63 GNS_TREESTORE_COL_EXP_TIME_IS_REL,
64
65 /**
66 * A gchararray
67 */
68 GNS_TREESTORE_COL_EXP_TIME_AS_STR,
69
70 /**
71 * A gchararray
72 */
73 GNS_TREESTORE_COL_VAL_AS_STR,
74
75 /**
76 * A gchararray
77 */
78 GNS_TREESTORE_COL_VAL_COLOR,
79
80 /**
81 * A gboolean
82 */
83 GNS_TREESTORE_COL_NAME_IS_VISIBLE,
84
85 /**
86 * A gboolean
87 */
88 GNS_TREESTORE_COL_IS_RECORD_ROW,
89
90 /**
91 * A gboolean
92 */
93 GNS_TREESTORE_COL_NOT_DUMMY_ROW,
94
95 /**
96 * A gchararray
97 */
98 GNS_TREESTORE_COL_EXP_TIME_COLOR,
99
100 /**
101 * A gchararray
102 */
103 GNS_TREESTORE_COL_NAME_COLOR
104};
105
106
107/**
108 * Columns in the gns type model.
109 */
110enum LIST_COLUMNS
111{
112
113 /**
114 * A guint
115 */
116 GNS_TYPE_TO_NAME_LISTSTORE_COLUMN_TYPE = 0,
117
118
119 /**
120 * A gchararray
121 */
122 GNS_TYPE_TO_NAME_LISTSTORE_COLUMN_TYPENAME
123};
124
125
126/**
127 *
128 */
129struct UpdateContext
130{
131 /**
132 *
133 */
134 struct GNUNET_GNS_Context *gns;
135
136 /**
137 *
138 */
139 struct GNUNET_NAMESTORE_RecordData *rd;
140
141 /**
142 *
143 */
144 char * name;
145
146 /**
147 *
148 */
149 unsigned int rd_count;
150};
151
152
153/**
154 * Name of our zone as a string.
155 */
156static char *zone_as_string;
157
158/**
159 * Default directory of zone files as a string.
160 */
161static char *zonekey_directory;
162
163
164struct GNUNET_GNS_Context
165{
166 /**
167 * Handle to the namestore.
168 */
169 struct GNUNET_NAMESTORE_Handle *ns;
170
171 GtkCheckMenuItem *shorten_menu;
172
173 GtkTreeStore *ts;
174 GtkListStore *ls;
175 GtkTreeModel *tm;
176 GtkTreeView *tv;
177
178 struct GNUNET_CRYPTO_RsaPrivateKey *pkey;
179 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey;
180
181 struct GNUNET_CRYPTO_ShortHashCode zone;
182 int iteration;
183};
184
185
186static void
187check_name_validity_and_commit_remove_proc (void *cls,
188 int32_t success,
189 const char *emsg)
190{
191 struct UpdateContext * uc = cls;
192 unsigned int c;
193 if ((GNUNET_OK == success) || (GNUNET_NO == success))
194 {
195 for (c = 0; c < uc->rd_count; c++)
196 {
197 GNUNET_NAMESTORE_record_create(uc->gns->ns, uc->gns->pkey,
198 uc->name, &uc->rd[c],NULL, NULL);
199 GNUNET_free ((void *) uc->rd[c].data);
200 }
201 GNUNET_free (uc->rd);
202 GNUNET_free (uc->name);
203 GNUNET_free (uc);
204 }
205 else if (GNUNET_SYSERR == success)
206 {
207 for (c = 0; c < uc->rd_count; c++)
208 GNUNET_free ((void *) uc->rd[c].data);
209 GNUNET_free (uc->rd);
210 GNUNET_free (uc->name);
211 GNUNET_free (uc);
212 }
213 else
214 {
215 GNUNET_break (0);
216 GNUNET_free (uc);
217 }
218}
219
220
221static void
222check_name_validity_and_commit (struct GNUNET_GNS_Context *gns, gchar *path, char * oldname)
223{
224 GtkTreeIter it;
225 GtkTreeIter parent;
226 int records;
227 int children;
228 int append_pseu;
229 int c;
230 int valid = GNUNET_YES;
231 char * name;
232 void * data;
233 size_t data_size;
234 const gchar * pseu;
235
236 char *n_name;
237 int n_type;
238 gboolean n_public;
239 char *n_exp_color;
240 guint64 n_exp_time;
241 char *n_exp_str;
242 gboolean n_is_relative;
243 char *n_value;
244 char *n_value_color;
245
246
247 gtk_tree_model_get_iter_from_string(gns->tm, &it, path);
248
249 if (FALSE == gtk_tree_model_iter_parent (gns->tm, &parent, &it))
250 parent = it;
251
252 children = gtk_tree_model_iter_n_children (gns->tm, &parent);
253 if (children < 1)
254 {
255 return;
256 }
257
258 gtk_tree_model_get(gns->tm, &parent,
259 GNS_TREESTORE_COL_NAME, &name,
260 -1);
261
262 if (0 == strcmp (name, ROOT_STR))
263 {
264 /* We have to append PSEU RECORD */
265 append_pseu = GNUNET_YES;
266 records = children + 1;
267 }
268 else
269 {
270 append_pseu = GNUNET_NO;
271 records = children;
272 }
273
274 struct GNUNET_NAMESTORE_RecordData *rd = GNUNET_malloc (records * sizeof (struct GNUNET_NAMESTORE_RecordData));
275
276 if (FALSE == gtk_tree_model_iter_children (gns->tm, &it, &parent))
277 return;
278
279 for (c = 0; c < children; c++)
280 {
281 gtk_tree_model_get(gns->tm, &it,
282 GNS_TREESTORE_COL_NAME, &n_name,
283 GNS_TREESTORE_COL_RECORD_TYPE, &n_type,
284 GNS_TREESTORE_COL_IS_PUBLIC, &n_public,
285 GNS_TREESTORE_COL_EXP_TIME_COLOR, &n_exp_color,
286 GNS_TREESTORE_COL_EXP_TIME, &n_exp_time,
287 GNS_TREESTORE_COL_EXP_TIME_IS_REL, &n_is_relative,
288 GNS_TREESTORE_COL_EXP_TIME_AS_STR, &n_exp_str,
289 GNS_TREESTORE_COL_VAL_AS_STR, &n_value,
290 GNS_TREESTORE_COL_VAL_COLOR, &n_value_color,
291 -1);
292 /* valid name */
293 if (NULL == n_name)
294 valid = GNUNET_NO;
295 else
296 {
297 if (GNUNET_SYSERR == GNUNET_NAMESTORE_check_name (n_name))
298 valid = GNUNET_NO;
299 }
300
301 /* valid record type */
302 if (0 == n_type)
303 valid = GNUNET_NO;
304
305 /* valid expiration */
306 if ((n_exp_color != NULL) || (NULL == n_exp_str) || (0 == n_exp_time))
307 valid = GNUNET_NO;
308
309 /* valid value */
310 if ((n_value_color != NULL) || (NULL == n_value))
311 valid = GNUNET_NO;
312 if (NULL != n_value)
313 {
314 if (GNUNET_OK != GNUNET_NAMESTORE_string_to_value(n_type, n_value, &data, &data_size))
315 valid = GNUNET_NO;
316 }
317
318 if (GNUNET_YES == valid)
319 {
320 if (FALSE == n_public)
321 rd[c].flags = GNUNET_NAMESTORE_RF_AUTHORITY | GNUNET_NAMESTORE_RF_PRIVATE;
322 else
323 rd[c].flags = GNUNET_NAMESTORE_RF_AUTHORITY | GNUNET_NAMESTORE_RF_NONE;
324 rd[c].record_type = n_type;
325 rd[c].expiration_time = n_exp_time;
326 rd[c].data_size = data_size;
327 rd[c].data = GNUNET_malloc(data_size);
328 memcpy ((void *) rd[c].data, data, data_size);
329 }
330 g_free (n_name);
331 g_free (n_exp_color);
332 g_free (n_exp_str);
333 g_free (n_value);
334 g_free (n_value_color);
335
336 if (FALSE == gtk_tree_model_iter_next (gns->tm, &it))
337 break;
338 }
339
340 if (GNUNET_NO == valid)
341 {
342 for (c = 0; c < children; c++)
343 GNUNET_free_non_null ((void *) rd[c].data);
344 GNUNET_free_non_null (rd);
345 }
346 else
347 {
348
349 if (GNUNET_YES == append_pseu)
350 {
351 GNUNET_assert (children == (records -1));
352
353 /* Append PSEU record */
354 GtkEntry * entry = GTK_ENTRY (gtk_builder_get_object (gns->builder, "GNUNET_GNS_GTK_pseu_entry"));
355 pseu = gtk_entry_get_text (GTK_ENTRY(entry));
356 if ((NULL != pseu) && (0 != strcmp (PSEU_EMPTY_STR, pseu)) && (0 != strcmp ("", pseu)))
357 {
358 if (GNUNET_OK != GNUNET_NAMESTORE_string_to_value(GNUNET_NAMESTORE_TYPE_PSEU,
359 pseu,
360 (void **) &rd[records - 1].data,
361 &rd[records - 1].data_size))
362 {
363 GNUNET_break (0);
364 for (c = 0; c < records; c++)
365 GNUNET_free_non_null ((void *) rd[c].data);
366 GNUNET_free_non_null (rd);
367 }
368 rd[records - 1].record_type = GNUNET_NAMESTORE_TYPE_PSEU;
369 rd[records - 1].expiration_time = UINT64_MAX;
370 rd[records - 1].flags = GNUNET_NAMESTORE_RF_AUTHORITY | GNUNET_NAMESTORE_RF_NONE;
371 }
372 else
373 {
374 GNUNET_break (0);
375 }
376 }
377
378 /* Remove old entries */
379 struct UpdateContext * uc = GNUNET_malloc (sizeof (struct UpdateContext));
380 uc->gns = gns;
381 uc->rd = rd;
382 uc->rd_count = records;
383 uc->name = strdup (name);
384 if (oldname != NULL)
385 GNUNET_NAMESTORE_record_remove(gns->ns, gns->pkey, oldname, NULL, &check_name_validity_and_commit_remove_proc, uc);
386 else
387 GNUNET_NAMESTORE_record_remove(gns->ns, gns->pkey, name, NULL, &check_name_validity_and_commit_remove_proc, uc);
388 g_free (name);
389 }
390}
391
392
393/**
394 *
395 */
396struct Remove_Context
397{
398
399 /**
400 *
401 */
402 struct GNUNET_GNS_Context *gns;
403
404 /**
405 *
406 */
407 char *path;
408};
409
410
411static void
412check_name_validity_and_remove_proc (void *cls,
413 int32_t success,
414 const char *emsg)
415{
416 struct Remove_Context *rcc = cls;
417 GtkDialog *dialog;
418 GtkTreeIter it;
419 if (GNUNET_SYSERR == success)
420 {
421 char * message = _("Record could not be deleted:");
422 dialog = GTK_DIALOG(gtk_message_dialog_new (GTK_WINDOW (rcc->gns->main_window),
423 GTK_DIALOG_DESTROY_WITH_PARENT,
424 GTK_MESSAGE_ERROR,
425 GTK_BUTTONS_CLOSE,
426 _("%s\n%s\n"),
427 message,
428 emsg));
429
430 g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), rcc->gns);
431 gtk_widget_show_all (GTK_WIDGET(dialog));
432 }
433 else
434 {
435 gtk_tree_model_get_iter_from_string(rcc->gns->tm, &it, rcc->path);
436 gtk_tree_store_remove (rcc->gns->ts, &it);
437 }
438 GNUNET_free (rcc->path);
439 GNUNET_free (rcc);
440}
441
442
443static void
444check_name_validity_and_remove (struct GNUNET_GNS_Context *gns, gchar *path)
445{
446 GtkTreeIter it;
447 GtkTreeIter parent;
448 char *name;
449 int valid = GNUNET_YES;
450 struct GNUNET_NAMESTORE_RecordData rd;
451 struct Remove_Context *rcc;
452
453 char *n_name;
454 int n_type;
455 gboolean n_public;
456 char *n_exp_color;
457 guint64 n_exp_time;
458 char *n_exp_str;
459 gboolean n_is_relative;
460 char *n_value;
461 char *n_value_color;
462
463 gtk_tree_model_get_iter_from_string(gns->tm, &it, path);
464 gtk_tree_model_get(gns->tm, &it,
465 GNS_TREESTORE_COL_NAME, &name,
466 -1);
467
468 if (TRUE == gtk_tree_model_iter_parent (gns->tm, &parent, &it))
469 {
470 /* Removing a single record */
471 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
472 "Removing single record for name `%s'\n", name);
473
474 gtk_tree_model_get(gns->tm, &it,
475 GNS_TREESTORE_COL_NAME, &n_name,
476 GNS_TREESTORE_COL_RECORD_TYPE, &n_type,
477 GNS_TREESTORE_COL_IS_PUBLIC, &n_public,
478 GNS_TREESTORE_COL_EXP_TIME_COLOR, &n_exp_color,
479 GNS_TREESTORE_COL_EXP_TIME, &n_exp_time,
480 GNS_TREESTORE_COL_EXP_TIME_IS_REL, &n_is_relative,
481 GNS_TREESTORE_COL_EXP_TIME_AS_STR, &n_exp_str,
482 GNS_TREESTORE_COL_VAL_AS_STR, &n_value,
483 GNS_TREESTORE_COL_VAL_COLOR, &n_value_color,
484 -1);
485
486 /* valid name */
487 if (NULL == n_name)
488 valid = GNUNET_NO;
489
490 /* valid record type */
491 if (0 == n_type)
492 valid = GNUNET_NO;
493
494 /* valid expiration */
495 if ((n_exp_color != NULL) || (NULL == n_exp_str) || (0 == n_exp_time))
496 valid = GNUNET_NO;
497
498 /* valid value */
499 if ((n_value_color != NULL) || (NULL == n_value))
500 valid = GNUNET_NO;
501
502 if (GNUNET_YES == valid)
503 {
504 if (FALSE == n_public)
505 rd.flags = GNUNET_NAMESTORE_RF_AUTHORITY | GNUNET_NAMESTORE_RF_PRIVATE;
506 else
507 rd.flags = GNUNET_NAMESTORE_RF_AUTHORITY | GNUNET_NAMESTORE_RF_NONE;
508 rd.record_type = n_type;
509 rd.expiration_time = n_exp_time;
510 rd.data_size = strlen (n_value) + 1;
511 rd.data = GNUNET_malloc(rd.data_size);
512 memcpy ((void *) rd.data, n_value, rd.data_size);
513
514 rcc = GNUNET_malloc(sizeof (struct Remove_Context));
515 rcc->gns = gns;
516 rcc->path = strdup (path);
517 GNUNET_NAMESTORE_record_remove(gns->ns, gns->pkey, name, &rd, &check_name_validity_and_remove_proc, rcc);
518 GNUNET_free ((void *) rd.data);
519 }
520 else
521 {
522 gtk_tree_model_get_iter_from_string(gns->tm, &it, path);
523 gtk_tree_store_remove (gns->ts, &it);
524 }
525 g_free (n_name);
526 g_free (n_exp_color);
527 g_free (n_exp_str);
528 g_free (n_value);
529 g_free (n_value_color);
530 }
531 else if (0 != strcmp (name, ROOT_STR))
532 {
533 /* Removing the whole name record */
534 rcc = GNUNET_malloc(sizeof (struct Remove_Context));
535 rcc->gns = gns;
536 rcc->path = strdup (path);
537 GNUNET_NAMESTORE_record_remove(gns->ns, gns->pkey, name, NULL, &check_name_validity_and_remove_proc, rcc);
538 }
539 g_free (name);
540}
541
542
543/**
544 * The user has selected a new record type. Update the
545 * model, possibly invalidating (marking 'red') the existing
546 * value.
547 *
548 * @param renderer updated renderer
549 * @param path the path identifying the edited cell
550 * @param new_iter selected cell in the combo's model (with the record type)
551 * @param user_data unused
552 */
553void
554GNUNET_GNS_GTK_type_cellrenderercombo_changed_cb (GtkCellRendererCombo *combo,
555 gchar *path,
556 GtkTreeIter *new_iter,
557 gpointer user_data)
558{
559 struct GNUNET_GNS_Context *gns = user_data;
560 GtkTreeIter it;
561 GtkTreeIter child;
562 guint type;
563 int record_row;
564 char *type_str;
565 char *value_str;
566 char *name_str;
567 void *data;
568 size_t data_size;
569
570 gtk_tree_model_get(GTK_TREE_MODEL(gns->ls), new_iter, 0, &type, -1);
571 gtk_tree_model_get(GTK_TREE_MODEL(gns->ls), new_iter, GNS_TYPE_TO_NAME_LISTSTORE_COLUMN_TYPENAME, &type_str, -1);
572
573
574 /* check if this is a new record */
575 gtk_tree_model_get_iter_from_string(gns->tm, &it, path);
576 gtk_tree_model_get(gns->tm, &it, GNS_TREESTORE_COL_IS_RECORD_ROW, &record_row, -1);
577 gtk_tree_model_get(gns->tm, &it, GNS_TREESTORE_COL_NAME, &name_str, -1);
578
579 if (GNUNET_YES == record_row)
580 {
581 /* Updating an existing record */
582 gtk_tree_store_set(gns->ts, &it,
583 GNS_TREESTORE_COL_RECORD_TYPE, type,
584 GNS_TREESTORE_COL_RECORD_TYPE_AS_STR, type_str,
585 -1);
586 }
587 else if ((NULL != name_str) && (0 != strcmp (NEW_NAME_STR, name_str)))
588 {
589 /* Adding a new record */
590
591 gtk_tree_store_insert_with_values(gns->ts, &child , &it, 0,
592 GNS_TREESTORE_COL_NAME, name_str,
593 GNS_TREESTORE_COL_NAME_IS_VISIBLE, FALSE,
594 GNS_TREESTORE_COL_RECORD_TYPE, type,
595 GNS_TREESTORE_COL_RECORD_TYPE_AS_STR, type_str,
596 GNS_TREESTORE_COL_EXP_TIME_AS_STR, EXPIRE_NEVER_STRING,
597 GNS_TREESTORE_COL_EXP_TIME, GNUNET_TIME_UNIT_FOREVER_ABS,
598 GNS_TREESTORE_COL_EXP_TIME_IS_REL, FALSE,
599 GNS_TREESTORE_COL_IS_RECORD_ROW, GNUNET_YES,
600 GNS_TREESTORE_COL_NOT_DUMMY_ROW, GNUNET_YES,
601 -1);
602 gtk_tree_view_expand_row (gns->tv, gtk_tree_model_get_path(gns->tm, &it), 0);
603
604 }
605 GNUNET_free (type_str);
606
607 /* check if value is still valid */
608 gtk_tree_model_get(gns->tm, &it, GNS_TREESTORE_COL_VAL_AS_STR, &value_str, -1);
609 if (NULL != value_str)
610 {
611 if (GNUNET_OK != GNUNET_NAMESTORE_string_to_value (type,
612 value_str,
613 &data,
614 &data_size))
615 gtk_tree_store_set (gns->ts, &it, GNS_TREESTORE_COL_VAL_COLOR, "red", -1);
616 else
617 gtk_tree_store_set (gns->ts, &it, GNS_TREESTORE_COL_VAL_COLOR, NULL, -1);
618 GNUNET_free (value_str);
619 }
620 else if (NULL == value_str)
621 {
622 /* Empty value field */
623 if (GNUNET_YES == record_row)
624 gtk_tree_store_set (gns->ts, &it, GNS_TREESTORE_COL_VAL_COLOR, "red", -1);
625 else
626 gtk_tree_store_set (gns->ts, &child, GNS_TREESTORE_COL_VAL_COLOR, "red", -1);
627 }
628
629 check_name_validity_and_commit (gns, path, NULL);
630 GNUNET_free_non_null (name_str);
631}
632
633
634/**
635 * The user has toggled the 'public' checkmark of a cell. Update the
636 * model.
637 *
638 * @param renderer updated renderer
639 * @param path the path identifying the edited cell
640 * @param user_data unused
641 */
642void
643GNUNET_GNS_GTK_ispublic_cellrenderertoggle_toggled_cb (GtkCellRendererToggle *cell_renderer,
644 gchar *path,
645 gpointer user_data)
646{
647 struct GNUNET_GNS_Context *gns = user_data;
648 GtkTreeIter it;
649 gboolean value;
650
651 gtk_tree_model_get_iter_from_string(gns->tm, &it, path);
652 gtk_tree_model_get(gns->tm, &it, GNS_TREESTORE_COL_IS_PUBLIC, &value, -1);
653 gtk_tree_store_set(gns->ts, &it, GNS_TREESTORE_COL_IS_PUBLIC, !value, -1);
654
655 check_name_validity_and_commit (gns, path, NULL);
656}
657
658
659static char *
660convert_time_to_string (struct GNUNET_TIME_Absolute t)
661{
662 time_t tt;
663 struct tm *time;
664 char *ret;
665
666 if (t.abs_value == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value)
667 return GNUNET_strdup (_(EXPIRE_NEVER_STRING));
668 if (t.abs_value == GNUNET_TIME_UNIT_ZERO_ABS.abs_value)
669 return GNUNET_strdup (_(EXPIRE_INVALID_STRING));
670
671 tt = t.abs_value / 1000;
672 time = localtime (&tt);
673
674 GNUNET_asprintf(&ret, "%02u/%02u/%04u %02u:%02u",time->tm_mon, time->tm_mday, 1900 + time->tm_year, time->tm_hour, time->tm_min);
675 return ret;
676}
677
678
679static int
680check_time (const char * text)
681{
682 unsigned int t_mon;
683 unsigned int t_day;
684 unsigned int t_year;
685 unsigned int t_hrs;
686 unsigned int t_min;
687
688 int count = SSCANF (text, "%02u/%02u/%04u %02u:%02u", &t_mon, &t_day, &t_year, &t_hrs, &t_min);
689 if ((EOF == count) || (5 != count))
690 return GNUNET_SYSERR;
691
692 if (t_mon > 12)
693 return GNUNET_SYSERR;
694 if (t_day > 31)
695 return GNUNET_SYSERR;
696 if (t_hrs > 24)
697 return GNUNET_SYSERR;
698 if (t_min > 59)
699 return GNUNET_SYSERR;
700
701 return GNUNET_OK;
702}
703
704
705static const struct GNUNET_TIME_Absolute
706convert_string_to_abs_time (const char * text)
707{
708 static struct GNUNET_TIME_Absolute abs_t;
709 struct tm time;
710 time_t t;
711
712 int t_mon;
713 int t_day;
714 int t_year;
715 int t_hrs;
716 int t_min;
717
718 GNUNET_assert (NULL != text);
719
720 if (0 == strcmp(text, EXPIRE_NEVER_STRING))
721 return GNUNET_TIME_UNIT_FOREVER_ABS;
722
723 memset (&time, '\0', sizeof (struct tm));
724
725 if (GNUNET_SYSERR == check_time(text))
726 {
727 GNUNET_break (0);
728 return GNUNET_TIME_UNIT_ZERO_ABS;
729 }
730
731 int count = SSCANF (text, "%02d/%02d/%04d %02d:%02d", &t_mon, &t_day, &t_year, &t_hrs, &t_min);
732 if ((EOF == count) || (5 != count))
733 return GNUNET_TIME_UNIT_ZERO_ABS;
734
735 time.tm_mon = (t_mon - 1);
736 time.tm_mday = t_day;
737 time.tm_year = t_year - 1900;
738 time.tm_hour = (t_hrs);
739 time.tm_min = t_min;
740
741 t = mktime (&time);
742 if (-1 == t)
743 return GNUNET_TIME_UNIT_ZERO_ABS;
744
745 abs_t.abs_value = t * 1000;
746
747 return abs_t;
748}
749
750
751/**
752 * The user has edited a 'expiration' cell. Update the model.
753 *
754 * @param renderer updated renderer
755 * @param path the path identifying the edited cell
756 * @param new_text the new expiration time
757 * @param user_data unused
758 */
759void
760GNUNET_GNS_GTK_expiration_cellrenderertext_edited_cb (GtkCellRendererText *renderer,
761 gchar *path,
762 gchar *new_text,
763 gpointer user_data)
764{
765 struct GNUNET_GNS_Context * gns = user_data;
766 GtkTreeIter it;
767 struct GNUNET_TIME_Absolute abstime;
768 gboolean is_rel;
769 char *old_text;
770
771 if ((NULL != new_text))
772 {
773 gtk_tree_model_get_iter_from_string(gns->tm, &it, path);
774 gtk_tree_model_get(gns->tm, &it,
775 GNS_TREESTORE_COL_EXP_TIME_AS_STR, &old_text,
776 GNS_TREESTORE_COL_EXP_TIME_IS_REL, &is_rel,
777 -1);
778 if (0 == strcmp(new_text, old_text))
779 return;
780
781 if ((0 == strcmp(new_text,"")) || (0 == strcmp(new_text,EXPIRE_NEVER_STRING)))
782 {
783 new_text = EXPIRE_NEVER_STRING;
784 abstime = GNUNET_TIME_UNIT_FOREVER_ABS;
785 }
786 else
787 {
788 if (GNUNET_SYSERR == check_time(new_text))
789 {
790 gtk_tree_store_set (gns->ts, &it,
791 GNS_TREESTORE_COL_EXP_TIME_AS_STR, new_text,
792 GNS_TREESTORE_COL_EXP_TIME_COLOR, "red",
793 GNS_TREESTORE_COL_EXP_TIME, 0,
794 -1);
795 abstime = GNUNET_TIME_UNIT_ZERO_ABS;
796 return;
797 }
798 /* TODO: fix this when we have relative time */
799 if (TRUE == is_rel)
800 {
801 abstime = convert_string_to_abs_time(new_text);
802 }
803 else
804 {
805 abstime = convert_string_to_abs_time(new_text);
806 }
807 }
808 gtk_tree_store_set (gns->ts, &it,
809 GNS_TREESTORE_COL_EXP_TIME_AS_STR, new_text,
810 GNS_TREESTORE_COL_EXP_TIME, abstime.abs_value,
811 GNS_TREESTORE_COL_EXP_TIME_COLOR, NULL,
812 -1);
813 check_name_validity_and_commit (gns, path, NULL);
814 }
815}
816
817
818/**
819 * The user has edited a 'value' cell. Update the model,
820 * including the status on the consistency of the value with
821 * the type.
822 *
823 * @param renderer updated renderer
824 * @param path the path identifying the edited cell
825 * @param new_text the new value
826 * @param user_data unused
827 */
828void
829GNUNET_GNS_GTK_value_cellrenderertext_edited_cb (GtkCellRendererText *renderer,
830 gchar *path,
831 gchar *new_text,
832 gpointer user_data)
833{
834 struct GNUNET_GNS_Context *gns = user_data;
835 GtkTreeModel *tm = GTK_TREE_MODEL(gns->ts);
836 GtkTreeIter it;
837 size_t data_size;
838 void * data;
839 int type;
840 gchar * old_value;
841
842 if (0 != strcmp(new_text,""))
843 {
844 gtk_tree_model_get_iter_from_string(tm, &it, path);
845 gtk_tree_model_get(tm, &it,
846 GNS_TREESTORE_COL_RECORD_TYPE, &type,
847 GNS_TREESTORE_COL_VAL_AS_STR, &old_value,
848 -1);
849
850 if (old_value != NULL)
851 {
852 if (0 == strcmp(new_text, old_value))
853 {
854 GNUNET_free (old_value);
855 return;
856 }
857 GNUNET_free (old_value);
858 }
859
860 if (GNUNET_OK == GNUNET_NAMESTORE_string_to_value (type,
861 new_text,
862 &data,
863 &data_size))
864 {
865 gtk_tree_store_set (gns->ts, &it, GNS_TREESTORE_COL_VAL_COLOR, NULL, -1);
866 gtk_tree_store_set (gns->ts, &it, GNS_TREESTORE_COL_VAL_AS_STR, new_text, -1);
867 check_name_validity_and_commit (gns, path, NULL);
868 }
869 else
870 {
871 gtk_tree_store_set (gns->ts, &it, GNS_TREESTORE_COL_VAL_COLOR, "red", -1);
872 gtk_tree_store_set (gns->ts, &it, GNS_TREESTORE_COL_VAL_AS_STR, new_text, -1);
873 }
874 }
875}
876
877
878/**
879 * The user has edited a 'name' cell. Update the model (and if needed
880 * create another fresh line for additional records).
881 *
882 * @param renderer updated renderer
883 * @param path the path identifying the edited cell
884 * @param new_text the new name
885 * @param user_data unused
886 */
887void
888GNUNET_GNS_GTK_name_cellrenderertext_edited_cb (GtkCellRendererText *renderer,
889 gchar *path,
890 gchar *new_text,
891 gpointer user_data)
892{
893 struct GNUNET_GNS_Context *gns = user_data;
894 GtkTreeIter it;
895 GtkTreeIter child;
896 GtkTreeModel *tm = GTK_TREE_MODEL(gns->ts);
897 int not_dummy;
898 char *name;
899
900 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New text for `%s' is `%s'\n", path, new_text);
901 if ((0 == strcmp (new_text, NEW_NAME_STR)) || (0 == strcmp (new_text, "")))
902 return;
903
904 gtk_tree_model_get_iter_from_string(tm, &it, path);
905 gtk_tree_model_get(tm, &it, GNS_TREESTORE_COL_NOT_DUMMY_ROW, &not_dummy, -1);
906 gtk_tree_model_get(tm, &it, GNS_TREESTORE_COL_NAME, &name, -1);
907
908 if (not_dummy == GNUNET_NO)
909 {
910 /* update name */
911 gtk_tree_store_set (gns->ts, &it,
912 GNS_TREESTORE_COL_NAME, new_text,
913 GNS_TREESTORE_COL_RECORD_TYPE, 0,
914 GNS_TREESTORE_COL_RECORD_TYPE_AS_STR, _(NEW_RECORD_STR),
915 GNS_TREESTORE_COL_NOT_DUMMY_ROW, GNUNET_YES,
916 -1);
917 check_name_validity_and_commit (gns, gtk_tree_model_get_string_from_iter(gns->tm, &it), name);
918
919 /* add a new dummy line */
920 gtk_tree_store_insert_with_values (gns->ts, &it,NULL, 0,
921 GNS_TREESTORE_COL_NAME, _(NEW_NAME_STR),
922 GNS_TREESTORE_COL_NAME_IS_VISIBLE, TRUE,
923 GNS_TREESTORE_COL_RECORD_TYPE, 1,
924 GNS_TREESTORE_COL_NOT_DUMMY_ROW, GNUNET_NO,
925 GNS_TREESTORE_COL_IS_RECORD_ROW, GNUNET_NO,
926 -1);
927 }
928 else
929 {
930 /* update name */
931 gtk_tree_store_set (gns->ts, &it, GNS_TREESTORE_COL_NAME, new_text, -1);
932
933 if (TRUE == gtk_tree_model_iter_children (gns->tm, &child, &it))
934 {
935 do
936 {
937 gtk_tree_store_set (gns->ts, &child,
938 GNS_TREESTORE_COL_NAME, &new_text,
939 -1);
940 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New text for `%s' is `%s'\n", path, new_text);
941 }
942 while (TRUE == gtk_tree_model_iter_next (gns->tm, &child));
943 }
944
945 check_name_validity_and_commit (gns, gtk_tree_model_get_string_from_iter(gns->tm, &it), name);
946 }
947
948 if (GNUNET_SYSERR == GNUNET_NAMESTORE_check_name (new_text))
949 {
950 gtk_tree_store_set (gns->ts, &it,
951 GNS_TREESTORE_COL_NAME_COLOR, "red",
952 -1);
953 }
954 else
955 {
956 gtk_tree_store_set (gns->ts, &it,
957 GNS_TREESTORE_COL_NAME_COLOR, NULL,
958 -1);
959 }
960}
961
962
963/**
964 * The zone treeview pop up menu is supposed to be created.
965 * (Note: this is not the only method that might need to be
966 * written to handle events to create pop up menus; right-clicks
967 * might need to be managed separately).
968 *
969 * @param widget the widget
970 * @param user_data unused
971 * @return TRUE if a menu was activated
972 */
973gboolean
974GNUNET_GNS_GTK_main_treeview_popup_menu_cb (GtkWidget *widget,
975 gpointer user_data)
976{
977 struct GNUNET_GNS_Context *gns = user_data;
978 GtkTreeModel *tm;
979 GtkTreeIter it;
980 GtkMenu *popup;
981 GtkTreeSelection * ts;
982 int not_dummy;
983
984 ts = gtk_tree_view_get_selection(gns->tv);
985 if (! gtk_tree_selection_get_selected (ts, &tm, &it))
986 return TRUE;
987 gtk_tree_model_get(gns->tm, &it, GNS_TREESTORE_COL_NOT_DUMMY_ROW, &not_dummy, -1);
988 if (GNUNET_NO == not_dummy)
989 return TRUE;
990
991 popup = GTK_MENU(gtk_builder_get_object (gns->builder, "GNUNET_GNS_GTK_delete_popup_menu"));
992 gtk_widget_show_all (GTK_WIDGET(popup));
993 gtk_menu_popup(popup, NULL, NULL, NULL, NULL, 0, 0);
994 return TRUE;
995}
996
997
998static void
999set_relative_expiration_time (struct GNUNET_GNS_Context *gns, struct GNUNET_TIME_Relative reltime)
1000{
1001 GtkTreeIter it;
1002 GtkTreeIter parent;
1003 GtkCellRendererText *renderer;
1004 GtkTreeModel *tm;
1005 GtkTreeSelection * ts = gtk_tree_view_get_selection(gns->tv);
1006 gboolean has_parent;
1007 struct GNUNET_TIME_Absolute abstime;
1008 char *path;
1009 int not_dummy;
1010
1011 if (! gtk_tree_selection_get_selected (ts, &tm, &it))
1012 return;
1013
1014 gtk_tree_model_get(tm, &it, GNS_TREESTORE_COL_NOT_DUMMY_ROW, &not_dummy, -1);
1015 if (GNUNET_NO == not_dummy)
1016 return;
1017
1018 /* Has parent? */
1019 has_parent = gtk_tree_model_iter_parent (tm, &parent, &it);
1020
1021 if (FALSE == has_parent)
1022 return;
1023
1024 abstime = GNUNET_TIME_absolute_add(GNUNET_TIME_absolute_get(), reltime);
1025
1026 /* this is a single record */
1027 renderer = GTK_CELL_RENDERER_TEXT((gtk_builder_get_object (gns->builder, "GNUNET_GNS_GTK_name_cellrenderertext")));
1028 path = gtk_tree_model_get_string_from_iter (tm, &it);
1029 GNUNET_GNS_GTK_expiration_cellrenderertext_edited_cb (renderer,
1030 path,
1031 convert_time_to_string (abstime),
1032 gns);
1033}
1034
1035
1036gboolean
1037GNUNET_GNS_GTK_main_treeview_popup_menu_exp1d_cb (GtkWidget *widget,
1038 gpointer user_data)
1039{
1040 set_relative_expiration_time (user_data, GNUNET_TIME_UNIT_DAYS);
1041 return TRUE;
1042}
1043
1044
1045gboolean
1046GNUNET_GNS_GTK_main_treeview_popup_menu_exp1w_cb (GtkWidget *widget,
1047 gpointer user_data)
1048{
1049 set_relative_expiration_time (user_data, GNUNET_TIME_UNIT_WEEKS);
1050 return TRUE;
1051}
1052
1053
1054gboolean
1055GNUNET_GNS_GTK_main_treeview_popup_menu_exp1y_cb (GtkWidget *widget,
1056 gpointer user_data)
1057{
1058 set_relative_expiration_time (user_data, GNUNET_TIME_UNIT_YEARS);
1059 return TRUE;
1060}
1061
1062
1063gboolean
1064GNUNET_GNS_GTK_main_treeview_popup_menu_expinf_cb (GtkWidget *widget,
1065 gpointer user_data)
1066{
1067 set_relative_expiration_time (user_data, GNUNET_TIME_UNIT_FOREVER_REL);
1068 return TRUE;
1069}
1070
1071
1072gboolean
1073GNUNET_GNS_GTK_main_treeview_button_press_popup_menu_cb (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
1074{
1075 /* Check for right click*/
1076 if (NULL == widget)
1077 return FALSE;
1078 if (event->type == GDK_BUTTON_PRESS && event->button == 3)
1079 GNUNET_GNS_GTK_main_treeview_popup_menu_cb (widget, user_data);
1080 return FALSE;
1081}
1082
1083
1084gboolean
1085GNUNET_GNS_GTK_main_treeview_key_press_popup_menu_cb (GtkWidget *widget, GdkEventKey *event, gpointer user_data)
1086{
1087 /* Check for delete key */
1088 if ((event->type == GDK_KEY_PRESS) && (GDK_KEY_Delete == event->keyval))
1089 GNUNET_GNS_GTK_main_treeview_popup_menu_cb (widget, user_data);
1090 return FALSE;
1091}
1092
1093
1094struct ZoneIteration_Context
1095{
1096 struct GNUNET_GNS_Context *gns;
1097 struct GNUNET_CRYPTO_ShortHashCode zone;
1098 struct GNUNET_NAMESTORE_ZoneIterator * it;
1099 char *label;
1100};
1101
1102
1103void
1104GNUNET_GNS_GTK_delete_popup_menu_delete_cb (GtkMenuItem *menuitem,
1105 gpointer user_data)
1106{
1107 struct GNUNET_GNS_Context *gns = user_data;
1108 GtkTreeIter it;
1109 GtkTreeModel *tm;
1110 GtkTreeSelection * ts;
1111 int not_dummy;
1112 char *path;
1113
1114 ts = gtk_tree_view_get_selection(gns->tv);
1115 if (gtk_tree_selection_get_selected (ts, &tm, &it))
1116 {
1117 gtk_tree_model_get(tm, &it, GNS_TREESTORE_COL_NOT_DUMMY_ROW, &not_dummy, -1);
1118 if (GNUNET_NO == not_dummy)
1119 return; /* do not delete the dummy line */
1120
1121 path = gtk_tree_model_get_string_from_iter (gns->tm, &it);
1122 check_name_validity_and_remove(gns, path);
1123 g_free (path);
1124 }
1125}
1126
1127
1128static void
1129zone_iteration_proc (void *cls,
1130 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
1131 struct GNUNET_TIME_Absolute expire,
1132 const char *name,
1133 unsigned int rd_count,
1134 const struct GNUNET_NAMESTORE_RecordData *rd,
1135 const struct GNUNET_CRYPTO_RsaSignature *signature)
1136{
1137 struct ZoneIteration_Context * zc_ctx = cls;
1138 GtkTreeIter iter_name;
1139 GtkTreeIter iter_record;
1140 GtkEntry *pseu_entry;
1141 int c;
1142 int time_is_relative;
1143
1144 char *exp;
1145 char *val;
1146 char * type_str;
1147 int public;
1148 guint64 exp_t;
1149
1150 GNUNET_assert (zc_ctx != NULL);
1151 if ((NULL == zone_key) && (NULL == name))
1152 {
1153 struct GNUNET_CRYPTO_ShortHashAsciiEncoded shenc;
1154 GNUNET_CRYPTO_short_hash_to_enc(&zc_ctx->zone, &shenc);
1155 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Zone `%s 'iteration done\n", &shenc);
1156 pseu_entry = GTK_ENTRY((gtk_builder_get_object (zc_ctx->gns->builder, "GNUNET_GNS_GTK_pseu_entry")));
1157 if (zc_ctx->label == NULL)
1158 GNUNET_asprintf(&zc_ctx->label, "%s", PSEU_EMPTY_STR);
1159 gtk_entry_set_text (pseu_entry, zc_ctx->label);
1160 zc_ctx->gns->iteration = GNUNET_NO;
1161 GNUNET_free (zc_ctx->label);
1162 GNUNET_free (zc_ctx);
1163 return;
1164 }
1165
1166
1167 struct GNUNET_CRYPTO_ShortHashAsciiEncoded shenc;
1168 GNUNET_CRYPTO_short_hash_to_enc(&zc_ctx->zone, &shenc);
1169 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Zone `%s' iteration result `%s', %u records\n",
1170 &shenc, name, rd_count);
1171
1172 GNUNET_assert(GTK_IS_TREE_STORE(zc_ctx->gns->ts));
1173 gtk_tree_store_append(zc_ctx->gns->ts, &iter_name, NULL);
1174 gtk_tree_store_set(zc_ctx->gns->ts, &iter_name,
1175 GNS_TREESTORE_COL_NAME, name,
1176 GNS_TREESTORE_COL_NAME_IS_VISIBLE, TRUE,
1177 GNS_TREESTORE_COL_RECORD_TYPE, 0,
1178 GNS_TREESTORE_COL_RECORD_TYPE_AS_STR, _(NEW_RECORD_STR),
1179 GNS_TREESTORE_COL_IS_RECORD_ROW, GNUNET_NO,
1180 GNS_TREESTORE_COL_NOT_DUMMY_ROW, GNUNET_YES,
1181 -1);
1182
1183 if (GNUNET_SYSERR == GNUNET_NAMESTORE_check_name (name))
1184 {
1185 gtk_tree_store_set (zc_ctx->gns->ts, &iter_name,
1186 GNS_TREESTORE_COL_NAME_COLOR, "red",
1187 -1);
1188 }
1189 /* Append elements for records */
1190 for (c = 0; c < rd_count; c ++)
1191 {
1192 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record %u: type %u flags %u expiration %llu data_size %u\n",
1193 c, rd[c].record_type, rd[c].flags, rd[c].expiration_time, rd[c].data_size);
1194
1195 /* Set public toggle */
1196 if ((rd[c].flags & GNUNET_NAMESTORE_RF_PRIVATE) == GNUNET_NAMESTORE_RF_PRIVATE)
1197 {
1198 public = GNUNET_NO;
1199 }
1200 else
1201 {
1202 public = GNUNET_YES;
1203 }
1204
1205 /* Expiration time */
1206 time_is_relative = GNUNET_NO;
1207
1208 if (GNUNET_YES == time_is_relative)
1209 {
1210 /* TODO: FIX THIS WHEN WE HAVE RELATIVE TIME */
1211 struct GNUNET_TIME_Relative rel_time = GNUNET_TIME_UNIT_ZERO;
1212 struct GNUNET_TIME_Absolute exp_abs;
1213 exp_abs = GNUNET_TIME_absolute_add(GNUNET_TIME_absolute_get(), rel_time);
1214 exp_t = exp_abs.abs_value;
1215 exp = convert_time_to_string (exp_abs);
1216 }
1217 else
1218 {
1219 struct GNUNET_TIME_Absolute exp_abs;
1220
1221 exp_abs.abs_value = rd[c].expiration_time;
1222 exp_t = exp_abs.abs_value;
1223 exp = convert_time_to_string (exp_abs);
1224 }
1225 /* value */
1226 val = GNUNET_NAMESTORE_value_to_string (rd[c].record_type,
1227 rd[c].data,
1228 rd[c].data_size);
1229 if (NULL == val)
1230 GNUNET_asprintf(&val, "%s", EXPIRE_INVALID_STRING);
1231
1232 if (NULL != GNUNET_NAMESTORE_number_to_typename(rd[c].record_type))
1233 type_str = strdup (GNUNET_NAMESTORE_number_to_typename(rd[c].record_type));
1234 else
1235 GNUNET_asprintf(&type_str, "%s", EXPIRE_INVALID_STRING);
1236
1237 if ((0 ==strcmp (name, ROOT_STR)) && (GNUNET_NAMESTORE_TYPE_PSEU == rd[c].record_type))
1238 {
1239 zc_ctx->label = strdup(val);
1240 zc_ctx->gns->iteration = GNUNET_YES;
1241 }
1242 else
1243 {
1244 gtk_tree_store_insert_with_values(zc_ctx->gns->ts, &iter_record , &iter_name, 0,
1245 GNS_TREESTORE_COL_NAME, name,
1246 GNS_TREESTORE_COL_NAME_IS_VISIBLE, FALSE,
1247 GNS_TREESTORE_COL_RECORD_TYPE, rd[c].record_type,
1248 GNS_TREESTORE_COL_RECORD_TYPE_AS_STR, type_str,
1249 GNS_TREESTORE_COL_IS_PUBLIC, public,
1250 GNS_TREESTORE_COL_EXP_TIME, exp_t,
1251 GNS_TREESTORE_COL_EXP_TIME_AS_STR, exp,
1252 GNS_TREESTORE_COL_EXP_TIME_IS_REL, time_is_relative,
1253 GNS_TREESTORE_COL_VAL_AS_STR, val,
1254 GNS_TREESTORE_COL_IS_RECORD_ROW, GNUNET_YES,
1255 GNS_TREESTORE_COL_NOT_DUMMY_ROW, GNUNET_YES,
1256 -1);
1257 }
1258 GNUNET_free (type_str);
1259 GNUNET_free (exp);
1260 GNUNET_free (val);
1261 }
1262
1263 GNUNET_NAMESTORE_zone_iterator_next(zc_ctx->it);
1264}
1265
1266
1267/**
1268 * The zone treeview was realized. Setup the model.
1269 *
1270 * @param widget the widget
1271 * @param user_data unused
1272 */
1273void
1274GNUNET_GNS_GTK_main_treeview_realize_cb (GtkWidget *widget,
1275 gpointer user_data)
1276{
1277 struct GNUNET_GNS_Context *gns = user_data;
1278 struct ZoneIteration_Context *zc_ctx;
1279 GtkTreeIter toplevel;
1280
1281 /* Append a top level row and leave it empty */
1282 gtk_tree_store_insert_with_values(gns->ts, &toplevel, NULL, 0,
1283 GNS_TREESTORE_COL_NAME, _(NEW_NAME_STR),
1284 GNS_TREESTORE_COL_NAME_IS_VISIBLE, TRUE,
1285 GNS_TREESTORE_COL_RECORD_TYPE, 1,
1286 GNS_TREESTORE_COL_IS_RECORD_ROW, GNUNET_NO,
1287 GNS_TREESTORE_COL_NOT_DUMMY_ROW, GNUNET_NO,
1288 -1);
1289
1290 zc_ctx = GNUNET_malloc (sizeof (struct ZoneIteration_Context));
1291 zc_ctx->gns = user_data;
1292 zc_ctx->zone = gns->zone;
1293 zc_ctx->it = GNUNET_NAMESTORE_zone_iteration_start(gns->ns, &gns->zone,
1294 GNUNET_NAMESTORE_RF_NONE,
1295 GNUNET_NAMESTORE_RF_NONE,
1296 &zone_iteration_proc,
1297 zc_ctx);
1298}
1299
1300
1301
1302static void
1303pseu_change_cont (void *cls,
1304 int32_t success,
1305 const char *emsg)
1306{
1307 struct GNUNET_GNS_Context *gns = cls;
1308 GtkWidget *dialog;
1309 if (GNUNET_SYSERR == success)
1310 {
1311 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("New Pseudonym could not be set: `%s'\n"), emsg);
1312 dialog = gtk_message_dialog_new (GTK_WINDOW (gns->main_window),
1313 GTK_DIALOG_DESTROY_WITH_PARENT,
1314 GTK_MESSAGE_ERROR,
1315 GTK_BUTTONS_CLOSE,
1316 _("New Pseudonym could not be set: `%s'\n"),
1317 emsg);
1318 g_signal_connect_swapped (dialog, "response",
1319 G_CALLBACK (gtk_widget_destroy),
1320 dialog);
1321 gtk_widget_show_all (dialog);
1322 }
1323}
1324
1325
1326/**
1327 * Task run on shutdown.
1328 *
1329 * @param cls unused
1330 * @param tc scheduler context, unused
1331 */
1332static void
1333shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1334{
1335
1336 struct GNUNET_GNS_Context *gns = cls;
1337 if (NULL == gns)
1338 return;
1339 if (NULL != gns->ns)
1340 {
1341 GNUNET_NAMESTORE_disconnect (gns->ns, GNUNET_NO);
1342 gns->ns = NULL;
1343 }
1344 if (NULL != gns->pkey)
1345 {
1346 GNUNET_CRYPTO_rsa_key_free (gns->pkey);
1347 gns->pkey = NULL;
1348 }
1349 if (NULL != zonekey_directory)
1350 {
1351 GNUNET_free (zonekey_directory);
1352 zonekey_directory = NULL;
1353 }
1354 GNUNET_free (gns);
1355}
1356
1357
1358
1359gboolean
1360GNUNET_GNS_GTK_pseu_entry_enter_cb (GtkWidget *widget,
1361 GdkEvent *event,
1362 gpointer user_data)
1363{
1364 const gchar * pseu;
1365
1366 pseu = gtk_entry_get_text (GTK_ENTRY(widget));
1367
1368 if ((pseu == NULL) || (0 == strcmp (pseu, "")))
1369 {
1370 //gtk_entry_set_text (GTK_ENTRY(widget), PSEU_EMPTY_STR);
1371 }
1372 return FALSE;
1373}
1374
1375
1376
1377
1378/**
1379 * The user edited the preferred name (PSEU) of this namespace.
1380 * Push the update to the namestore.
1381 *
1382 * @param editable the edited widget
1383 * @param user_data unused
1384 */
1385void
1386GNUNET_GNS_GTK_pseu_entry_changed_cb (GtkEditable *editable,
1387 gpointer user_data)
1388{
1389 struct GNUNET_GNS_Context *gns = user_data;
1390 struct GNUNET_NAMESTORE_RecordData rd;
1391 const gchar * pseu;
1392
1393 pseu = gtk_entry_get_text (GTK_ENTRY(editable));
1394 if ((pseu != NULL) && (0 != strcmp (pseu, PSEU_EMPTY_STR)) && (0 != strcmp ("", pseu)) && (GNUNET_NO == gns->iteration))
1395 {
1396
1397 rd.record_type = GNUNET_NAMESTORE_TYPE_PSEU;
1398 rd.expiration_time = UINT64_MAX;
1399 rd.flags = GNUNET_NAMESTORE_RF_AUTHORITY;
1400 rd.data_size = strlen (pseu) + 1;
1401 rd.data = strdup (pseu);
1402 GNUNET_NAMESTORE_record_create(gns->ns, gns->pkey, "+", &rd, pseu_change_cont, gns);
1403 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New Pseudonym is `%s' %u\n", (char *) rd.data, rd.data_size);
1404 }
1405 else if ((0 != strcmp (pseu, PSEU_EMPTY_STR)) && ((pseu == NULL) || (0 == strcmp ("", pseu))))
1406 {
1407 gtk_entry_set_text (GTK_ENTRY(editable), PSEU_EMPTY_STR);
1408 }
1409
1410}
1411
1412/**
1413 * The user toggled the 'autoshort' option. Update the configuration.
1414 *
1415 * @param checkmenuitem the menu item
1416 * @param user_data unused
1417 */
1418void
1419GNUNET_GNS_GTK_autoshort_imagemenuitem_toggled_cb (GtkCheckMenuItem *checkmenuitem,
1420 gpointer user_data)
1421{
1422 struct GNUNET_GNS_Context *gns = user_data;
1423 GtkWidget *dialog;
1424 struct GNUNET_CONFIGURATION_Handle *cfg = (struct GNUNET_CONFIGURATION_Handle *) get_configuration();
1425
1426 gboolean state = gtk_check_menu_item_get_active (gns->shorten_menu);
1427 if (TRUE == state)
1428 GNUNET_CONFIGURATION_set_value_string(cfg,"gns", "AUTO_IMPORT_PKEY","YES");
1429 else
1430 GNUNET_CONFIGURATION_set_value_string(cfg,"gns", "AUTO_IMPORT_PKEY","NO");
1431
1432 char * cfgfile = strdup (GNUNET_GTK_main_loop_get_configuration_file(ml));
1433 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_write(cfg, cfgfile))
1434 {
1435 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Changes to autoshorten could not be written to configuration file: `%s'\n"), cfgfile);
1436 dialog = gtk_message_dialog_new (GTK_WINDOW (gns->main_window),
1437 GTK_DIALOG_DESTROY_WITH_PARENT,
1438 GTK_MESSAGE_ERROR,
1439 GTK_BUTTONS_CLOSE,
1440 _("Changes to autoshorten option could not be written to configuration file: `%s'\n"),
1441 cfgfile);
1442 g_signal_connect_swapped (dialog, "response",
1443 G_CALLBACK (gtk_widget_destroy),
1444 dialog);
1445 gtk_widget_show_all (dialog);
1446 }
1447 GNUNET_free (cfgfile);
1448}
1449
1450
1451/**
1452 * The user selected 'NEW' in the menu. Open a dialog to enter a filename
1453 * to create a new zone (for editing).
1454 *
1455 * @param checkmenuitem the menu item
1456 * @param user_data unused
1457 */
1458void
1459GNUNET_GNS_GTK_new_imagemenuitem_activate_cb (GtkMenuItem *menuitem,
1460 gpointer user_data)
1461{
1462 GNUNET_break (0); // FIXME, not implemented
1463}
1464
1465
1466/**
1467 * Function called from the open-directory dialog upon completion.
1468 *
1469 * @param dialog the pseudonym selection dialog
1470 * @param response_id response code from the dialog
1471 * @param user_data the builder of the dialog
1472 */
1473void
1474GNUNET_GNS_GTK_zone_open_dialog_response_cb (GtkDialog * dialog,
1475 gint response_id,
1476 gpointer user_data)
1477{
1478 char *filename;
1479
1480 if (GTK_RESPONSE_OK != response_id)
1481 {
1482 gtk_widget_destroy (GTK_WIDGET (dialog));
1483 g_object_unref (G_OBJECT (dialog));
1484 return;
1485 }
1486 filename = GNUNET_GTK_filechooser_get_filename_utf8 (GTK_FILE_CHOOSER (dialog));
1487 gtk_widget_destroy (GTK_WIDGET (dialog));
1488 g_object_unref (G_OBJECT (dialog));
1489
1490 /* FIXME: move to new zone 'filename' */
1491 fprintf (stderr, "Got zone `%s'\n", filename);
1492 GNUNET_free (filename);
1493}
1494
1495
1496/**
1497 * The user selected 'OPEN' in the menu. Open a dialog to select
1498 * a different zonefile (for editing).
1499 *
1500 * @param checkmenuitem the menu item
1501 * @param user_data unused
1502 */
1503void
1504GNUNET_GNS_GTK_open_imagemenuitem_activate_cb (GtkMenuItem *menuitem,
1505 gpointer user_data)
1506{
1507 GtkWidget *ad;
1508 GtkBuilder *builder;
1509 GtkWidget *toplevel;
1510 GtkFileFilter *ff;
1511 GtkFileChooser *fc;
1512
1513 builder =
1514 GNUNET_GTK_get_new_builder ("gnunet_gns_gtk_zone_open.glade", NULL);
1515 if (NULL == builder)
1516 {
1517 GNUNET_break (0);
1518 return;
1519 }
1520 /* This file filter could be set with glade if we use gtk3
1521 * With gtk2 we have to set it manually */
1522 ff = GTK_FILE_FILTER (gtk_builder_get_object
1523 (builder, "GNUNET_GNS_GTK_zone_open_filefilter"));
1524 gtk_file_filter_add_pattern (ff, "*.zkey");
1525
1526 ad = GTK_WIDGET (gtk_builder_get_object
1527 (builder, "GNUNET_GNS_GTK_zone_open_filechooserdialog"));
1528
1529 if (GTK_IS_FILE_CHOOSER(ad))
1530 {
1531 fc = GTK_FILE_CHOOSER(ad);
1532 if (NULL != fc)
1533 gtk_file_chooser_set_current_folder(fc, zonekey_directory);
1534 }
1535
1536 toplevel = gtk_widget_get_toplevel (GTK_WIDGET (menuitem));
1537 if (GTK_IS_WINDOW (toplevel))
1538 gtk_window_set_transient_for (GTK_WINDOW (ad), GTK_WINDOW (toplevel));
1539 gtk_window_present (GTK_WINDOW (ad));
1540}
1541
1542
1543/**
1544 * The user clicked on the 'copy' button. Copy the full string
1545 * with the hash of our public key to the clipboard.
1546 *
1547 * @param button the button that was clicked
1548 * @param user_data unused
1549 */
1550void
1551GNUNET_GNS_GTK_public_key_copy_button_clicked_cb (GtkButton *button,
1552 gpointer user_data)
1553{
1554 GtkClipboard *cb;
1555
1556 cb = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
1557 gtk_clipboard_set_text (cb, zone_as_string, -1);
1558}
1559
1560
1561
1562/**
1563 * Callback invoked if the application is supposed to exit (via menu).
1564 *
1565 * @param menuitem the quit menu
1566 * @param user_data unused
1567 */
1568void
1569GNUNET_GNS_GTK_quit_imagemenuitem_activate_cb (GtkMenuItem *menuitem,
1570 gpointer user_data)
1571{
1572 GNUNET_GTK_tray_icon_destroy ();
1573 GNUNET_GTK_main_loop_quit (ml);
1574 GNUNET_SCHEDULER_add_now (&shutdown_task, user_data);
1575}
1576
1577
1578/**
1579 * Callback invoked if the application is supposed to exit (via window-close).
1580 *
1581 * @param widget the main window
1582 * @param event deletion event
1583 * @param user_data unused
1584 */
1585void
1586GNUNET_GNS_GTK_main_window_delete_event_cb (GtkWidget *widget,
1587 GdkEvent *event,
1588 gpointer user_data)
1589{
1590 GNUNET_GTK_tray_icon_destroy ();
1591 GNUNET_GTK_main_loop_quit (ml);
1592 GNUNET_SCHEDULER_add_now (&shutdown_task, user_data);
1593}
1594
1595
1596static void
1597close_error_box (GtkDialog *dialog,
1598 gint response_id,
1599 gpointer user_data)
1600{
1601 gtk_widget_destroy (GTK_WIDGET(dialog));
1602 GNUNET_GNS_GTK_shutdown (user_data);
1603}
1604
1605
1606static void
1607namestore_service_check (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1608{
1609 struct GNUNET_GNS_Context *gns = NULL;
1610 struct GNUNET_CRYPTO_ShortHashAsciiEncoded shenc;
1611 GtkWidget *dialog;
1612 char *label;
1613 char *keyfile;
1614 char *servicehome;
1615
1616 gns = GNUNET_malloc (sizeof (struct GNUNET_GNS_Context));
1617
1618 if ((tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT) != 0)
1619 {
1620 char * message = _("Namestore service is not running!\n");
1621 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, message);
1622 dialog = gtk_message_dialog_new (GTK_WINDOW (gns->main_window),
1623 GTK_DIALOG_DESTROY_WITH_PARENT,
1624 GTK_MESSAGE_ERROR,
1625 GTK_BUTTONS_CLOSE,
1626 "%s",
1627 message);
1628
1629 g_signal_connect (dialog, "response", G_CALLBACK(close_error_box), gns);
1630 gtk_widget_show_all (dialog);
1631 return;
1632 }
1633
1634 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (get_configuration (),
1635 "PATHS",
1636 "SERVICEHOME",
1637 &servicehome))
1638 {
1639 GNUNET_asprintf(&zonekey_directory, "");
1640 }
1641 else
1642 {
1643 GNUNET_asprintf(&zonekey_directory, "%s%s%s",servicehome, DIR_SEPARATOR_STR, "gns");
1644 GNUNET_free (servicehome);
1645 }
1646
1647 /* setup crypto keys */
1648 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (get_configuration (),
1649 "gns",
1650 "ZONEKEY",
1651 &keyfile))
1652 {
1653 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1654 _("Option `%s' missing in section `%s'\n"), "ZONEKEY", "gns");
1655 return;
1656 }
1657 else
1658 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using `%s'\n", keyfile);
1659 gns->pkey = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
1660 GNUNET_free (keyfile);
1661 keyfile = NULL;
1662 if (NULL == gns->pkey)
1663 {
1664 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1665 _("Failed to read or create private zone key\n"));
1666 return;
1667 }
1668 GNUNET_CRYPTO_rsa_key_get_public (gns->pkey, &gns->pubkey);
1669 GNUNET_CRYPTO_short_hash (&gns->pubkey,
1670 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
1671 &gns->zone);
1672 GNUNET_CRYPTO_short_hash_to_enc(&gns->zone, &shenc);
1673
1674 /* connect to namestore */
1675 gns->ns = GNUNET_NAMESTORE_connect (get_configuration ());
1676 if (NULL == gns->ns)
1677 {
1678 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1679 _("Failed to connect to namestore\n"));
1680 return;
1681 }
1682
1683 /* setup gui */
1684 if (GNUNET_OK != GNUNET_GTK_main_loop_build_window (ml, gns))
1685 {
1686 GNUNET_break (0);
1687 GNUNET_SCHEDULER_add_now (&shutdown_task, gns);
1688 return;
1689 }
1690 gns->builder = GNUNET_GTK_main_loop_get_builder(ml);
1691 gns->main_window = GTK_WIDGET (get_object ("GNUNET_GNS_GTK_main_window"));
1692 gns->ts = GTK_TREE_STORE (gtk_builder_get_object (gns->builder, "GNUNET_GNS_GTK_treestore"));
1693 gns->ls = GTK_LIST_STORE (gtk_builder_get_object (gns->builder, "GNUNET_GNS_GTK_type_liststore"));
1694 gns->tv = GTK_TREE_VIEW (gtk_builder_get_object (gns->builder, "GNUNET_GNS_GTK_main_treeview"));
1695 gns->tm = GTK_TREE_MODEL(gns->ts);
1696 gns->shorten_menu = GTK_CHECK_MENU_ITEM(gtk_builder_get_object (gns->builder, "GNUNET_GNS_GTK_autoshort_imagemenuitem"));
1697 if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (get_configuration (),
1698 "gns",
1699 "AUTO_IMPORT_PKEY"))
1700 gtk_check_menu_item_set_active (gns->shorten_menu, TRUE);
1701 else
1702 gtk_check_menu_item_set_active (gns->shorten_menu, FALSE);
1703
1704 /* TODO: implements menus */
1705 gtk_widget_set_visible (GTK_WIDGET (gtk_builder_get_object (gns->builder, "GNUNET_GNS_GTK_new_imagemenuitem")), FALSE);
1706 gtk_widget_set_visible (GTK_WIDGET (gtk_builder_get_object (gns->builder, "GNUNET_GNS_GTK_open_imagemenuitem")), FALSE);
1707
1708 zone_as_string = GNUNET_strdup ((char *) &shenc);
1709 label = g_markup_printf_escaped (_("<b>Editing zone %s</b>"),
1710 zone_as_string);
1711 gtk_label_set_markup (GTK_LABEL (get_object ("GNUNET_GNS_GTK_zone_label")),
1712 label);
1713 g_free (label);
1714
1715}
1716
1717
1718/* end of gnunet-setup-gns.c */
diff --git a/src/setup/gnunet-setup-namestore-config.c b/src/setup/gnunet-setup-namestore-config.c
new file mode 100644
index 00000000..986a94b3
--- /dev/null
+++ b/src/setup/gnunet-setup-namestore-config.c
@@ -0,0 +1,112 @@
1/*
2 This file is part of GNUnet.
3 (C) 2010, 2012 Christian Grothoff (and other contributing authors)
4
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
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file src/gnunet-setup-namestore-config.c
23 * @brief test datastore configuration
24 * @author Christian Grothoff
25 */
26#include "gnunet-setup.h"
27#include <gnunet/gnunet_namestore_plugin.h>
28
29
30/**
31 * Test if the configuration works for the given plugin.
32 *
33 * @param name name of the plugin to check
34 * @return GNUNET_OK on success, GNUNET_SYSERR if the config is wrong
35 */
36static int
37test_config (const char *name)
38{
39 void *ret;
40
41 ret = GNUNET_PLUGIN_load (name, cfg);
42 if (NULL == ret)
43 return GNUNET_SYSERR;
44 GNUNET_PLUGIN_unload (name, ret);
45 return GNUNET_OK;
46}
47
48
49static void
50show (const char *name)
51{
52 gtk_widget_show (GTK_WIDGET (GNUNET_SETUP_get_object (name)));
53}
54
55
56static void
57hide (const char *name)
58{
59 gtk_widget_hide (GTK_WIDGET (GNUNET_SETUP_get_object (name)));
60}
61
62
63void
64GNUNET_setup_namestore_postgres_invalidate_cb ()
65{
66 hide ("GNUNET_setup_namestore_postgres_tab_ok_image");
67 hide ("GNUNET_setup_namestore_postgres_tab_error_image");
68}
69
70
71void
72GNUNET_setup_namestore_postgres_tab_test_button_clicked_cb (GtkWidget * widget,
73 gpointer user_data)
74{
75 if (GNUNET_OK == test_config ("libgnunet_plugin_namestore_postgres"))
76 {
77 show ("GNUNET_setup_namestore_postgres_tab_ok_image");
78 hide ("GNUNET_setup_namestore_postgres_tab_error_image");
79 }
80 else
81 {
82 hide ("GNUNET_setup_namestore_postgres_tab_ok_image");
83 show ("GNUNET_setup_namestore_postgres_tab_error_image");
84 }
85}
86
87
88static void
89restart_namestore ()
90{
91 GNUNET_SCHEDULER_add_now (&GNUNET_SETUP_restart_namestore,
92 NULL);
93}
94
95
96void
97GNUNET_setup_namestore_sqlite_radiobutton_toggled_cb (GtkToggleButton *tb,
98 gpointer user_data)
99{
100 restart_namestore ();
101}
102
103
104void
105GNUNET_setup_namestore_postgres_radiobutton_toggled_cb (GtkToggleButton *tb,
106 gpointer user_data)
107{
108 restart_namestore ();
109}
110
111
112/* end of gnunet-setup-namestore-config.c */
diff --git a/src/setup/gnunet-setup-namestore-plugins.c b/src/setup/gnunet-setup-namestore-plugins.c
new file mode 100644
index 00000000..74be3658
--- /dev/null
+++ b/src/setup/gnunet-setup-namestore-plugins.c
@@ -0,0 +1,67 @@
1/*
2 This file is part of GNUnet.
3 (C) 2012 Christian Grothoff (and other contributing authors)
4
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
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file src/gnunet-setup-namestore-plugins.c
23 * @brief (de)sensitize namestore plugin buttons based on plugin availability
24 * @author Christian Grothoff
25 */
26#include "gnunet-setup.h"
27
28/**
29 * Test if the given plugin exists and change the sensitivity
30 * of the widget accordingly.
31 *
32 * @param widget widget to update
33 * @param name name of the plugin to check
34 */
35static void
36test_plugin (GtkWidget * widget, const char *name)
37{
38 if (GNUNET_YES == GNUNET_PLUGIN_test (name))
39 {
40 gtk_widget_set_sensitive (widget, TRUE);
41 }
42 else
43 {
44 gtk_widget_set_sensitive (widget, FALSE);
45 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), FALSE);
46 }
47}
48
49
50void
51GNUNET_setup_namestore_sqlite_radiobutton_realize_cb (GtkWidget * widget,
52 gpointer user_data)
53{
54 test_plugin (widget, "libgnunet_plugin_namestore_sqlite");
55}
56
57
58void
59GNUNET_setup_namestore_postgres_radiobutton_realize_cb (GtkWidget * widget,
60 gpointer user_data)
61{
62 test_plugin (widget, "libgnunet_plugin_namestore_postgres");
63}
64
65
66
67/* end of gnunet-setup-namestore-plugins.c */
diff --git a/src/setup/gnunet-setup-options.c b/src/setup/gnunet-setup-options.c
index 6f116402..f2783222 100644
--- a/src/setup/gnunet-setup-options.c
+++ b/src/setup/gnunet-setup-options.c
@@ -717,659 +717,11 @@ save_string_list_store (const void *cls, const char *section,
717 717
718 718
719/** 719/**
720 * Check if the section represents a DNS entry and then update the
721 * GtkListStore accordingly.
722 *
723 * @param cls the list store to modify
724 * @param section name of the section
725 */
726static void
727add_dns_entry_to_list_store (void *cls, const char *section)
728{
729 GtkListStore *ls = cls;
730 GtkTreeIter iter;
731 char *sld;
732 char *hostname;
733 char *hostport;
734 char *redirect;
735 char *cpy;
736 gboolean udp;
737
738 if (NULL == section)
739 {
740 gtk_list_store_insert_with_values (ls, &iter, G_MAXINT,
741 GNUNET_GTK_SETUP_GNS_MC_HOSTNAME, "",
742 GNUNET_GTK_SETUP_GNS_MC_SOURCEPORT,
743 (guint) 80,
744 GNUNET_GTK_SETUP_GNS_MC_TARGETPORT,
745 (guint) 8080,
746 GNUNET_GTK_SETUP_GNS_MC_HOSTNAME,
747 "localhost4",
748 GNUNET_GTK_SETUP_GNS_MC_ISUDP, "tcp",
749 -1);
750 return;
751 }
752
753 if ((8 > strlen (section)) ||
754 (0 != strcmp (".gnunet.", section + ((strlen (section) - 8)))))
755 return;
756 sld = GNUNET_strdup (section);
757 sld[strlen (section) - 8] = '\0';
758 udp = FALSE;
759 do
760 {
761 if (GNUNET_OK ==
762 GNUNET_CONFIGURATION_get_value_string (cfg, section,
763 (TRUE ==
764 udp) ? "UDP_REDIRECTS" :
765 "TCP_REDIRECTS", &cpy))
766 {
767 for (redirect = strtok (cpy, " "); redirect != NULL;
768 redirect = strtok (NULL, " "))
769 {
770 if (NULL == (hostname = strstr (redirect, ":")))
771 {
772 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
773 _("Option `%s' is not formatted correctly!\n"), redirect);
774 continue;
775 }
776 hostname[0] = '\0';
777 hostname++;
778 if (NULL == (hostport = strstr (hostname, ":")))
779 {
780 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
781 _("Option `%s' is not formatted correctly!\n"), redirect);
782 continue;
783 }
784 hostport[0] = '\0';
785 hostport++;
786
787 int local_port = atoi (redirect);
788
789 if (!((local_port > 0) && (local_port < 65536)))
790 {
791 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
792 _("`%s' is not a valid port number!\n"), redirect);
793 continue;
794 }
795 int host_port = atoi (hostport);
796
797 if (!((host_port > 0) && (host_port < 65536)))
798 {
799 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
800 _("`%s' is not a valid port number!\n"), hostport);
801 continue;
802 }
803 gtk_list_store_insert_with_values (ls, &iter, 0,
804 GNUNET_GTK_SETUP_GNS_MC_HOSTNAME,
805 sld,
806 GNUNET_GTK_SETUP_GNS_MC_SOURCEPORT,
807 (guint) local_port,
808 GNUNET_GTK_SETUP_GNS_MC_TARGETPORT,
809 (guint) host_port,
810 GNUNET_GTK_SETUP_GNS_MC_TARGETHOSTNAME,
811 hostname,
812 GNUNET_GTK_SETUP_GNS_MC_ISUDP,
813 (TRUE == udp) ? "udp" : "tcp", -1);
814 }
815 GNUNET_free (cpy);
816 }
817 udp = !udp;
818 }
819 while (udp != FALSE);
820 GNUNET_free (sld);
821}
822
823
824/**
825 * Initialize the GtkListModel with the VPN's DNS service specification.
826 *
827 * @param cls NULL
828 * @param section section with the value (NULL)
829 * @param option option name (NULL)
830 * @param value value as a string (NULL)
831 * @param widget widget to initialize (the GtkTreeView)
832 * @param cfg configuration handle
833 * @return GNUNET_OK on success, GNUNET_SYSERR if there was a problem
834 */
835static int
836load_vpn_dns_configuration (const void *cls, const char *section,
837 const char *option, const char *value,
838 GObject * widget,
839 const struct GNUNET_CONFIGURATION_Handle *cfg)
840{
841 GtkTreeView *tv;
842 GtkListStore *ls;
843
844 tv = GTK_TREE_VIEW (widget);
845 if (tv == NULL)
846 {
847 GNUNET_break (0);
848 return GNUNET_SYSERR;
849 }
850 ls = GTK_LIST_STORE (gtk_tree_view_get_model (tv));
851 GNUNET_CONFIGURATION_iterate_sections (cfg, &add_dns_entry_to_list_store, ls);
852 /* finally, add empty entry */
853 add_dns_entry_to_list_store (ls, NULL);
854 return GNUNET_OK;
855}
856
857
858/**
859 * Records we use to build DNS information lists.
860 */
861struct DnsInfo
862{
863 struct DnsInfo *next;
864 char *section;
865 char *altnames;
866 char *tcpred;
867 char *udpred;
868 unsigned long long ttl;
869};
870
871
872/**
873 * Function called for each section in the configuration.
874 * Gather existing ttl, section names and altnames.
875 *
876 * @param cls 'struct DnsInfo**' to create
877 * @param section name of a section in the configuration
878 */
879static void
880collect_dns_sections (void *cls, const char *section)
881{
882 struct DnsInfo **base = cls;
883 struct DnsInfo *pos;
884
885 if ((8 > strlen (section)) ||
886 (0 != strcmp (".gnunet.", section + ((strlen (section) - 8)))))
887 return;
888 pos = GNUNET_malloc (sizeof (struct DnsInfo));
889 pos->section = GNUNET_strdup (section);
890 if (GNUNET_OK !=
891 GNUNET_CONFIGURATION_get_value_number (cfg, section, "TTL", &pos->ttl))
892 pos->ttl = 3600000;
893 if (GNUNET_OK !=
894 GNUNET_CONFIGURATION_get_value_string (cfg, section, "ALTERNATIVE_NAMES",
895 &pos->altnames))
896 pos->altnames = NULL;
897 pos->tcpred = GNUNET_strdup ("");
898 pos->udpred = GNUNET_strdup ("");
899 pos->next = *base;
900 *base = pos;
901}
902
903
904/**
905 * Function called for each section in the configuration.
906 * Removes those ending in '.gnunet.'.
907 *
908 * @param cls unused
909 * @param section name of a section in the configuration
910 */
911static void
912remove_dns_sections (void *cls, const char *section)
913{
914 if ((8 > strlen (section)) ||
915 (0 != strcmp (".gnunet.", section + ((strlen (section) - 8)))))
916 return;
917 GNUNET_CONFIGURATION_remove_section (cfg, section);
918}
919
920
921/**
922 * Given the list store and the data in it, update the
923 * configuration file accordingly.
924 *
925 * @param tm model to use
926 */
927static void
928update_vpn_dns_configuration (GtkTreeModel * tm)
929{
930 GtkTreeIter iter;
931 gchar *hostname;
932 guint srcport;
933 guint targetport;
934 gchar *targethost;
935 gchar *tcpudp;
936 char *tmp;
937 struct DnsInfo *head;
938 struct DnsInfo *pos;
939
940 head = NULL;
941 GNUNET_CONFIGURATION_iterate_sections (cfg, &collect_dns_sections, &head);
942 if (TRUE == gtk_tree_model_get_iter_first (tm, &iter))
943 do
944 {
945 gtk_tree_model_get (tm, &iter,
946 GNUNET_GTK_SETUP_GNS_MC_HOSTNAME, &hostname,
947 GNUNET_GTK_SETUP_GNS_MC_SOURCEPORT, &srcport,
948 GNUNET_GTK_SETUP_GNS_MC_TARGETPORT, &targetport,
949 GNUNET_GTK_SETUP_GNS_MC_TARGETHOSTNAME, &targethost,
950 GNUNET_GTK_SETUP_GNS_MC_ISUDP, &tcpudp,
951 -1);
952 if (0 != strlen (hostname))
953 {
954 pos = head;
955 GNUNET_asprintf (&tmp, "%s.gnunet.", hostname);
956 while ((NULL != pos) && (0 != strcasecmp (tmp, pos->section)))
957 pos = pos->next;
958 if (pos == NULL)
959 {
960 pos = GNUNET_malloc (sizeof (struct DnsInfo));
961 pos->section = tmp;
962 pos->ttl = 3600000;
963 pos->altnames = NULL;
964 pos->tcpred = GNUNET_strdup ("");
965 pos->udpred = GNUNET_strdup ("");
966 pos->next = head;
967 head = pos;
968 }
969 else
970 {
971 GNUNET_free (tmp);
972 }
973 GNUNET_asprintf (&tmp, "%u:%s:%u %s", srcport, targethost, targetport,
974 (0 ==
975 strcasecmp ("tcp",
976 tcpudp)) ? pos->tcpred : pos->udpred);
977 if (0 == strcasecmp ("tcp", tcpudp))
978 {
979 GNUNET_free (pos->tcpred);
980 pos->tcpred = tmp;
981 }
982 else
983 {
984 GNUNET_free (pos->udpred);
985 pos->udpred = tmp;
986 }
987 }
988 g_free (tcpudp);
989 g_free (hostname);
990 g_free (targethost);
991 }
992 while (TRUE == gtk_tree_model_iter_next (tm, &iter));
993 GNUNET_CONFIGURATION_iterate_sections (cfg, &remove_dns_sections, NULL);
994 while (NULL != head)
995 {
996 pos = head;
997 head = pos->next;
998 if (pos->altnames != NULL)
999 GNUNET_CONFIGURATION_set_value_string (cfg, pos->section,
1000 "ALTERNATIVE_NAMES",
1001 pos->altnames);
1002 if (strlen (pos->udpred) > 0)
1003 GNUNET_CONFIGURATION_set_value_string (cfg, pos->section, "UDP_REDIRECTS",
1004 pos->udpred);
1005 if (strlen (pos->tcpred) > 0)
1006 GNUNET_CONFIGURATION_set_value_string (cfg, pos->section, "TCP_REDIRECTS",
1007 pos->tcpred);
1008 if ((strlen (pos->udpred) > 0) || (strlen (pos->tcpred) > 0))
1009 GNUNET_CONFIGURATION_set_value_number (cfg, pos->section, "TTL",
1010 pos->ttl);
1011 GNUNET_free_non_null (pos->altnames);
1012 GNUNET_free (pos->tcpred);
1013 GNUNET_free (pos->udpred);
1014 GNUNET_free (pos->section);
1015 GNUNET_free (pos);
1016 }
1017}
1018
1019
1020/**
1021 * The user has edited the DNS name of a service we're offering.
1022 * Update the GtkTreeModel (at the given path) and update the
1023 * respective service entry in the configuration file. Finally,
1024 * if the edited path is for a "fresh" entry, create another empty
1025 * one at the bottom. If the hostname was set to empty, remove
1026 * the entire entry from the configuration and the model.
1027 *
1028 * @param renderer GtkCellRendererText that changed
1029 * @param path GtkTreePath identifying where in the Model the change is
1030 * @param new_text the new text that was stored in the line
1031 * @param user_data NULL
1032 */
1033static void
1034save_vpn_dns_service_dnsname (GtkCellRendererText * renderer, gchar * path,
1035 gchar * new_text, gpointer user_data)
1036{
1037 GtkTreeModel *tm;
1038 GtkListStore *ls;
1039 GtkTreeIter iter;
1040 gchar *old;
1041
1042 tm = GTK_TREE_MODEL (GNUNET_SETUP_get_object ("GNUNET_setup_gns_liststore"));
1043 if (NULL == tm)
1044 {
1045 GNUNET_break (0);
1046 return;
1047 }
1048 ls = GTK_LIST_STORE (tm);
1049 if (NULL == ls)
1050 {
1051 GNUNET_break (0);
1052 return;
1053 }
1054 if (TRUE != gtk_tree_model_get_iter_from_string (tm, &iter, path))
1055 {
1056 GNUNET_break (0);
1057 return;
1058 }
1059 gtk_tree_model_get (tm, &iter, GNUNET_GTK_SETUP_GNS_MC_HOSTNAME, &old, -1);
1060 if ((0 != strlen (old)) && (0 == strlen (new_text)))
1061 {
1062 /* deletion */
1063 gtk_list_store_remove (ls, &iter);
1064 g_free (old);
1065 /* update configuration */
1066 update_vpn_dns_configuration (tm);
1067 return;
1068 }
1069 /* update model */
1070 gtk_list_store_set (ls, &iter,
1071 GNUNET_GTK_SETUP_GNS_MC_HOSTNAME, new_text, -1);
1072 /* update configuration */
1073 update_vpn_dns_configuration (tm);
1074 if ((0 == strlen (old)) && (0 != strlen (new_text)))
1075 {
1076 /* need another empty entry at the end for future expansion */
1077 add_dns_entry_to_list_store (GTK_LIST_STORE (tm), NULL);
1078 }
1079 g_free (old);
1080}
1081
1082
1083/**
1084 * Initialize the GtkListModel with the VPN's DNS service specification.
1085 *
1086 * @param cls NULL
1087 * @param section section with the value (NULL)
1088 * @param option option name (NULL)
1089 * @param widget widget to initialize (the GtkTreeView)
1090 * @param cfg configuration handle
1091 * @return GNUNET_OK on success, GNUNET_SYSERR if there was a problem
1092 */
1093static int
1094gns_name_install_edited_handler (const void *cls,
1095 const char *section,
1096 const char *option,
1097 GObject * widget,
1098 struct
1099 GNUNET_CONFIGURATION_Handle
1100 *cfg)
1101{
1102 static int once;
1103 GtkCellRendererText *rt;
1104
1105 rt = GTK_CELL_RENDERER_TEXT (widget);
1106 if (NULL == rt)
1107 return GNUNET_SYSERR;
1108 if (0 != once++)
1109 return GNUNET_OK;
1110 g_signal_connect (rt, "edited", G_CALLBACK (&save_vpn_dns_service_dnsname),
1111 NULL);
1112 return GNUNET_OK;
1113}
1114
1115
1116/**
1117 * The user has edited the DNS name of a service we're offering.
1118 * Update the GtkTreeModel (at the given path) and update the
1119 * respective service entry in the configuration file. Finally,
1120 * if the edited path is for a "fresh" entry, create another empty
1121 * one at the bottom. If the hostname was set to empty, remove
1122 * the entire entry from the configuration and the model.
1123 *
1124 * @param renderer GtkCellRendererText that changed
1125 * @param path GtkTreePath identifying where in the Model the change is
1126 * @param new_text the new text that was stored in the line
1127 * @param user_data NULL
1128 */
1129static void
1130save_vpn_dns_service_tcpudp (GtkCellRendererText * renderer, gchar * path,
1131 gchar * new_text, gpointer user_data)
1132{
1133 GtkTreeModel *tm;
1134 GtkListStore *ls;
1135 GtkTreeIter iter;
1136
1137 if ((0 != strcasecmp ("tcp", new_text)) &&
1138 (0 != strcasecmp ("udp", new_text)))
1139 {
1140 /* FIXME: warn... */
1141 return;
1142 }
1143 tm = GTK_TREE_MODEL (GNUNET_SETUP_get_object ("GNUNET_setup_gns_liststore"));
1144 if (NULL == tm)
1145 {
1146 GNUNET_break (0);
1147 return;
1148 }
1149 ls = GTK_LIST_STORE (tm);
1150 if (NULL == ls)
1151 {
1152 GNUNET_break (0);
1153 return;
1154 }
1155 if (TRUE != gtk_tree_model_get_iter_from_string (tm, &iter, path))
1156 {
1157 GNUNET_break (0);
1158 return;
1159 }
1160 /* update model */
1161 gtk_list_store_set (ls, &iter, GNUNET_GTK_SETUP_GNS_MC_ISUDP, new_text, -1);
1162 /* update configuration */
1163 update_vpn_dns_configuration (tm);
1164}
1165
1166
1167/**
1168 * Initialize the GtkListModel with the VPN's DNS service specification.
1169 *
1170 * @param cls NULL
1171 * @param section section with the value (NULL)
1172 * @param option option name (NULL)
1173 * @param widget widget to initialize (the GtkTreeView)
1174 * @param cfg configuration handle
1175 * @return GNUNET_OK on success, GNUNET_SYSERR if there was a problem
1176 */
1177static int
1178gns_type_install_edited_handler (const void *cls,
1179 const char *section,
1180 const char *option,
1181 GObject * widget,
1182 struct
1183 GNUNET_CONFIGURATION_Handle *cfg)
1184{
1185 static int once;
1186 GtkCellRendererText *rt;
1187
1188 rt = GTK_CELL_RENDERER_TEXT (widget);
1189 if (NULL == rt)
1190 return GNUNET_SYSERR;
1191 if (0 != once++)
1192 return GNUNET_OK;
1193 g_signal_connect (rt, "edited", G_CALLBACK (&save_vpn_dns_service_tcpudp),
1194 NULL);
1195 return GNUNET_OK;
1196}
1197
1198
1199/**
1200 * The user has edited the DNS name of a service we're offering.
1201 * Update the GtkTreeModel (at the given path) and update the
1202 * respective service entry in the configuration file. Finally,
1203 * if the edited path is for a "fresh" entry, create another empty
1204 * one at the bottom. If the hostname was set to empty, remove
1205 * the entire entry from the configuration and the model.
1206 *
1207 * @param renderer GtkCellRendererText that changed
1208 * @param path GtkTreePath identifying where in the Model the change is
1209 * @param new_text the new text that was stored in the line
1210 * @param user_data NULL
1211 */
1212static void
1213save_vpn_dns_service_sourceport (GtkCellRendererText * renderer, gchar * path,
1214 gchar * new_text, gpointer user_data)
1215{
1216 GtkTreeModel *tm;
1217 GtkListStore *ls;
1218 GtkTreeIter iter;
1219 int port;
1220
1221 port = atoi (new_text);
1222 if ((port < 1) || (port > UINT16_MAX))
1223 {
1224 /* invalid port, FIXME: warn */
1225 return;
1226 }
1227 tm = GTK_TREE_MODEL (GNUNET_SETUP_get_object ("GNUNET_setup_gns_liststore"));
1228 if (NULL == tm)
1229 {
1230 GNUNET_break (0);
1231 return;
1232 }
1233 ls = GTK_LIST_STORE (tm);
1234 if (NULL == ls)
1235 {
1236 GNUNET_break (0);
1237 return;
1238 }
1239 if (TRUE != gtk_tree_model_get_iter_from_string (tm, &iter, path))
1240 {
1241 GNUNET_break (0);
1242 return;
1243 }
1244 /* update model */
1245 gtk_list_store_set (ls, &iter,
1246 GNUNET_GTK_SETUP_GNS_MC_SOURCEPORT, (guint) port, -1);
1247 /* update configuration */
1248 update_vpn_dns_configuration (tm);
1249}
1250
1251
1252/**
1253 * Initialize the GtkListModel with the VPN's DNS service specification.
1254 *
1255 * @param cls NULL
1256 * @param section section with the value (NULL)
1257 * @param option option name (NULL)
1258 * @param widget widget to initialize (the GtkTreeView)
1259 * @param cfg configuration handle
1260 * @return GNUNET_OK on success, GNUNET_SYSERR if there was a problem
1261 */
1262static int
1263gns_ttl_install_edited_handler (const void *cls,
1264 const char *section,
1265 const char *option,
1266 GObject * widget,
1267 struct
1268 GNUNET_CONFIGURATION_Handle
1269 *cfg)
1270{
1271 static int once;
1272 GtkCellRendererText *rt;
1273
1274 rt = GTK_CELL_RENDERER_TEXT (widget);
1275 if (NULL == rt)
1276 return GNUNET_SYSERR;
1277 if (0 != once++)
1278 return GNUNET_OK;
1279 g_signal_connect (rt, "edited", G_CALLBACK (&save_vpn_dns_service_sourceport),
1280 NULL);
1281 return GNUNET_OK;
1282}
1283
1284
1285/**
1286 * The user has edited the DNS name of a service we're offering.
1287 * Update the GtkTreeModel (at the given path) and update the
1288 * respective service entry in the configuration file. Finally,
1289 * if the edited path is for a "fresh" entry, create another empty
1290 * one at the bottom. If the hostname was set to empty, remove
1291 * the entire entry from the configuration and the model.
1292 *
1293 * @param renderer GtkCellRendererText that changed
1294 * @param path GtkTreePath identifying where in the Model the change is
1295 * @param new_text the new text that was stored in the line
1296 * @param user_data NULL
1297 */
1298static void
1299save_vpn_dns_service_targethostname (GtkCellRendererText * renderer,
1300 gchar * path, gchar * new_text,
1301 gpointer user_data)
1302{
1303 GtkTreeModel *tm;
1304 GtkListStore *ls;
1305 GtkTreeIter iter;
1306
1307 tm = GTK_TREE_MODEL (GNUNET_SETUP_get_object ("GNUNET_setup_gns_liststore"));
1308 if (NULL == tm)
1309 {
1310 GNUNET_break (0);
1311 return;
1312 }
1313 ls = GTK_LIST_STORE (tm);
1314 if (NULL == ls)
1315 {
1316 GNUNET_break (0);
1317 return;
1318 }
1319 if (TRUE != gtk_tree_model_get_iter_from_string (tm, &iter, path))
1320 {
1321 GNUNET_break (0);
1322 return;
1323 }
1324 /* update model */
1325 gtk_list_store_set (ls, &iter,
1326 GNUNET_GTK_SETUP_GNS_MC_TARGETHOSTNAME, new_text, -1);
1327 /* update configuration */
1328 update_vpn_dns_configuration (tm);
1329}
1330
1331
1332/**
1333 * Initialize the GtkListModel with the VPN's DNS service specification.
1334 *
1335 * @param cls NULL
1336 * @param section section with the value (NULL)
1337 * @param option option name (NULL)
1338 * @param widget widget to initialize (the GtkTreeView)
1339 * @param cfg configuration handle
1340 * @return GNUNET_OK on success, GNUNET_SYSERR if there was a problem
1341 */
1342static int
1343gns_value_install_edited_handler (const void *cls,
1344 const char *section,
1345 const char *option,
1346 GObject * widget,
1347 struct
1348 GNUNET_CONFIGURATION_Handle
1349 *cfg)
1350{
1351 static int once;
1352 GtkCellRendererText *rt;
1353
1354 rt = GTK_CELL_RENDERER_TEXT (widget);
1355 if (NULL == rt)
1356 return GNUNET_SYSERR;
1357 if (0 != once++)
1358 return GNUNET_OK;
1359 g_signal_connect (rt, "edited",
1360 G_CALLBACK (&save_vpn_dns_service_targethostname), NULL);
1361 return GNUNET_OK;
1362}
1363
1364
1365
1366/**
1367 * Hide "min connected friends" option if in F2F-only mode. 720 * Hide "min connected friends" option if in F2F-only mode.
1368 */ 721 */
1369static struct GNUNET_SETUP_VisibilitySpecification hide_min_connected_friends[] 722static struct GNUNET_SETUP_VisibilitySpecification hide_min_connected_friends[] = {
1370 = { 723 {"GNUNET_setup_minimum_friends_label", NULL, REX_YES },
1371 {"GNUNET_setup_minimum_friends_label", NULL, REX_YES}, 724 {"GNUNET_setup_minimum_friends_spinbutton", NULL, REX_YES },
1372 {"GNUNET_setup_minimum_friends_spinbutton", NULL, REX_YES},
1373 {NULL, NULL, NULL} 725 {NULL, NULL, NULL}
1374}; 726};
1375 727
@@ -1411,7 +763,7 @@ static struct GNUNET_SETUP_VisibilitySpecification
1411 763
1412 764
1413/** 765/**
1414 * Hide "fs tab" if FS not active. 766 * Hide "fs" tab if FS not active.
1415 */ 767 */
1416static struct GNUNET_SETUP_VisibilitySpecification hide_fs_tab[] = { 768static struct GNUNET_SETUP_VisibilitySpecification hide_fs_tab[] = {
1417 {"GNUNET_setup_fs_main_vbox", "(^| )fs($| )", NULL}, 769 {"GNUNET_setup_fs_main_vbox", "(^| )fs($| )", NULL},
@@ -1420,7 +772,7 @@ static struct GNUNET_SETUP_VisibilitySpecification hide_fs_tab[] = {
1420 772
1421 773
1422/** 774/**
1423 * Hide "vpn tab" if VPN not active. 775 * Hide "vpn" tab if VPN not active.
1424 */ 776 */
1425static struct GNUNET_SETUP_VisibilitySpecification hide_vpn_tab[] = { 777static struct GNUNET_SETUP_VisibilitySpecification hide_vpn_tab[] = {
1426 {"GNUNET_setup_vpn_vbox", "(^| )pt($| )", NULL}, 778 {"GNUNET_setup_vpn_vbox", "(^| )pt($| )", NULL},
@@ -1429,16 +781,17 @@ static struct GNUNET_SETUP_VisibilitySpecification hide_vpn_tab[] = {
1429 781
1430 782
1431/** 783/**
1432 * Hide "gns tab" if GNS not active. 784 * Hide "gns" and "namestore" tabs if GNS not active.
1433 */ 785 */
1434static struct GNUNET_SETUP_VisibilitySpecification hide_gns_tab[] = { 786static struct GNUNET_SETUP_VisibilitySpecification hide_gns_tab[] = {
1435 {"GNUNET_setup_gns_vbox", "(^| )gns($| )", NULL}, 787 {"GNUNET_setup_gns_vbox", "(^| )gns($| )", NULL},
788 {"GNUNET_setup_namestore_vbox", "(^| )gns($| )", NULL},
1436 {NULL, NULL, NULL} 789 {NULL, NULL, NULL}
1437}; 790};
1438 791
1439 792
1440/** 793/**
1441 * Hide "tcp tab" if TCP not active. 794 * Hide "tcp" tab if TCP not active.
1442 */ 795 */
1443static struct GNUNET_SETUP_VisibilitySpecification hide_tcp_tab[] = { 796static struct GNUNET_SETUP_VisibilitySpecification hide_tcp_tab[] = {
1444 {"GNUNET_setup_transport_tcp_vbox", "(^| )tcp($| )", NULL}, 797 {"GNUNET_setup_transport_tcp_vbox", "(^| )tcp($| )", NULL},
@@ -1447,7 +800,7 @@ static struct GNUNET_SETUP_VisibilitySpecification hide_tcp_tab[] = {
1447 800
1448 801
1449/** 802/**
1450 * Hide "udp tab" if UDP not active. 803 * Hide "udp" tab if UDP not active.
1451 */ 804 */
1452static struct GNUNET_SETUP_VisibilitySpecification hide_udp_tab[] = { 805static struct GNUNET_SETUP_VisibilitySpecification hide_udp_tab[] = {
1453 {"GNUNET_setup_transport_udp_vbox", "(^| )udp($| )", NULL}, 806 {"GNUNET_setup_transport_udp_vbox", "(^| )udp($| )", NULL},
@@ -1456,7 +809,7 @@ static struct GNUNET_SETUP_VisibilitySpecification hide_udp_tab[] = {
1456 809
1457 810
1458/** 811/**
1459 * Hide "http tab" if HTTP not active. 812 * Hide "http" tab if HTTP not active.
1460 */ 813 */
1461static struct GNUNET_SETUP_VisibilitySpecification hide_http_tab[] = { 814static struct GNUNET_SETUP_VisibilitySpecification hide_http_tab[] = {
1462 {"GNUNET_setup_transport_http_vbox", "(^| )http($| )", NULL}, 815 {"GNUNET_setup_transport_http_vbox", "(^| )http($| )", NULL},
@@ -1465,7 +818,7 @@ static struct GNUNET_SETUP_VisibilitySpecification hide_http_tab[] = {
1465 818
1466 819
1467/** 820/**
1468 * Hide "https tab" if HTTPS not active. 821 * Hide "https" tab if HTTPS not active.
1469 */ 822 */
1470static struct GNUNET_SETUP_VisibilitySpecification hide_https_tab[] = { 823static struct GNUNET_SETUP_VisibilitySpecification hide_https_tab[] = {
1471 {"GNUNET_setup_transport_https_vbox", "(^| )https($| )", NULL}, 824 {"GNUNET_setup_transport_https_vbox", "(^| )https($| )", NULL},
@@ -1474,7 +827,7 @@ static struct GNUNET_SETUP_VisibilitySpecification hide_https_tab[] = {
1474 827
1475 828
1476/** 829/**
1477 * Hide "dv tab" if DV not active. 830 * Hide "dv" tab if DV not active.
1478 */ 831 */
1479static struct GNUNET_SETUP_VisibilitySpecification hide_dv_tab[] = { 832static struct GNUNET_SETUP_VisibilitySpecification hide_dv_tab[] = {
1480 {"GNUNET_setup_transport_dv_vbox", "(^| )dv($| )", NULL}, 833 {"GNUNET_setup_transport_dv_vbox", "(^| )dv($| )", NULL},
@@ -1483,7 +836,7 @@ static struct GNUNET_SETUP_VisibilitySpecification hide_dv_tab[] = {
1483 836
1484 837
1485/** 838/**
1486 * Hide "wlan tab" if WLAN not active. 839 * Hide "wlan" tab if WLAN not active.
1487 */ 840 */
1488static struct GNUNET_SETUP_VisibilitySpecification hide_wlan_tab[] = { 841static struct GNUNET_SETUP_VisibilitySpecification hide_wlan_tab[] = {
1489 {"GNUNET_setup_transport_wlan_vbox", "(^| )wlan($| )", NULL}, 842 {"GNUNET_setup_transport_wlan_vbox", "(^| )wlan($| )", NULL},
@@ -1548,6 +901,24 @@ static struct GNUNET_SETUP_VisibilitySpecification hide_postgres_datacache_tab[]
1548 901
1549 902
1550/** 903/**
904 * Hide "sqlite namestore" tab if sqlite not active.
905 */
906static struct GNUNET_SETUP_VisibilitySpecification hide_sqlite_namestore_tab[] = {
907 {"GNUNET_setup_namestore_sqlite_label", "^sqlite$", NULL},
908 {NULL, NULL, NULL}
909};
910
911
912/**
913 * Hide "postgres datastore" tab if postgres not active.
914 */
915static struct GNUNET_SETUP_VisibilitySpecification hide_postgres_namestore_tab[] = {
916 {"GNUNET_setup_namestore_postgres_hbox", "^postgres$", NULL},
917 {NULL, NULL, NULL}
918};
919
920
921/**
1551 * Hide advertised TCP port if port is zero. 922 * Hide advertised TCP port if port is zero.
1552 */ 923 */
1553static struct GNUNET_SETUP_VisibilitySpecification hide_all_tcp_options[] = { 924static struct GNUNET_SETUP_VisibilitySpecification hide_all_tcp_options[] = {
@@ -2541,88 +1912,58 @@ const struct GNUNET_SETUP_OptionSpecification option_specifications[] = {
2541 NULL, NULL, 1912 NULL, NULL,
2542 NULL}, 1913 NULL},
2543 1914
2544 /* GNS treeview */ 1915
1916 /* Namestore TAB */
2545 1917
2546 { 1918 {
2547 "GNUNET_setup_general_services_gns_checkbutton", 1919 "GNUNET_setup_namestore_sqlite_radiobutton",
2548 "toggled", 1920 "toggled",
2549 "arm", 1921 "namestore",
2550 "DEFAULTSERVICES", 1922 "DATABASE",
2551 gettext_noop ("Should the GNS be started automatically on startup?"), 1923 gettext_noop ("Use sqLite to store names"),
2552 "https://gnunet.org/configuration-gns", 1924 "https://gnunet.org/configuration-namestore",
2553 &load_option_list, 1925 &load_option_list /* abuse! */ ,
2554 &save_option_list, "gns", 1926 &save_option_list /* abuse! */ , "sqlite",
2555 NULL, NULL, 1927 NULL, NULL,
2556 hide_gns_tab}, 1928 hide_sqlite_namestore_tab},
2557 1929
2558 { 1930 {
2559 "GNUNET_setup_gns_treeview", 1931 "GNUNET_setup_namestore_postgres_radiobutton",
2560 NULL, 1932 "toggled",
2561 NULL, 1933 "namestore",
2562 NULL, 1934 "DATABASE",
2563 gettext_noop 1935 gettext_noop ("Use PostGres to store names"),
2564 ("Specification of .gnunet TLD"), 1936 "https://gnunet.org/configuration-namestore",
2565 "https://gnunet.org/configuration-dns", 1937 &load_option_list /* abuse! */ ,
2566 &load_vpn_dns_configuration, 1938 &save_option_list /* abuse! */ , "postgres",
2567 NULL, NULL,
2568 NULL, NULL, 1939 NULL, NULL,
2569 NULL}, 1940 hide_postgres_namestore_tab},
2570
2571 {
2572 "GNUNET_setup_gns_name_cellrenderertext",
2573 "editing-started",
2574 NULL,
2575 NULL,
2576 NULL,
2577 "https://gnunet.org/configuration-dns",
2578 NULL,
2579 &gns_name_install_edited_handler,
2580 NULL,
2581 NULL,
2582 NULL,
2583 NULL},
2584 1941
2585 { 1942 {
2586 "GNUNET_setup_gns_type_cellrenderertext", 1943 "GNUNET_setup_namestore_postgres_config_entry",
2587 "editing-started", 1944 "changed",
2588 NULL, 1945 "namestore-postgres",
2589 NULL, 1946 "CONFIG",
2590 NULL, 1947 gettext_noop ("Configuration for Postgres (passed to PQconnectdb)"),
2591 "https://gnunet.org/configuration-dns", 1948 "http://www.postgresql.org/docs/8.1/static/libpq.html#LIBPQ-CONNECT",
2592 NULL, 1949 &load_text,
2593 &gns_type_install_edited_handler, 1950 &save_text, NULL,
2594 NULL, 1951 NULL, NULL,
2595 NULL,
2596 NULL,
2597 NULL}, 1952 NULL},
2598 1953
2599 { 1954 /* GNS treeview */
2600 "GNUNET_setup_gns_ttl_cellrenderertext",
2601 "editing-started",
2602 NULL,
2603 NULL,
2604 NULL,
2605 "https://gnunet.org/configuration-dns",
2606 NULL,
2607 &gns_ttl_install_edited_handler,
2608 NULL,
2609 NULL,
2610 NULL,
2611 NULL},
2612 1955
2613 { 1956 {
2614 "GNUNET_setup_gns_value_cellrenderertext", 1957 "GNUNET_setup_general_services_gns_checkbutton",
2615 "editing-started", 1958 "toggled",
2616 NULL, 1959 "arm",
2617 NULL, 1960 "DEFAULTSERVICES",
2618 NULL, 1961 gettext_noop ("Should the GNS be started automatically on startup?"),
2619 "https://gnunet.org/configuration-dns", 1962 "https://gnunet.org/configuration-gns",
2620 NULL, 1963 &load_option_list,
2621 &gns_value_install_edited_handler, 1964 &save_option_list, "gns",
2622 NULL, 1965 NULL, NULL,
2623 NULL, 1966 hide_gns_tab},
2624 NULL,
2625 NULL},
2626 1967
2627 /* END of list */ 1968 /* END of list */
2628 1969
@@ -2631,4 +1972,5 @@ const struct GNUNET_SETUP_OptionSpecification option_specifications[] = {
2631 NULL} 1972 NULL}
2632}; 1973};
2633 1974
1975
2634/* end of gnunet-setup-options.c */ 1976/* end of gnunet-setup-options.c */
diff --git a/src/setup/gnunet-setup.c b/src/setup/gnunet-setup.c
index 506a861f..f93cb853 100644
--- a/src/setup/gnunet-setup.c
+++ b/src/setup/gnunet-setup.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2010 Christian Grothoff (and other contributing authors) 3 (C) 2010, 2011, 2012 Christian Grothoff (and other contributing authors)
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
@@ -53,7 +53,12 @@ static int gret;
53/** 53/**
54 * Resolver process handle. 54 * Resolver process handle.
55 */ 55 */
56struct GNUNET_OS_Process *resolver; 56static struct GNUNET_OS_Process *resolver;
57
58/**
59 * Namestore process handle.
60 */
61static struct GNUNET_OS_Process *namestore;
57 62
58 63
59/** 64/**
@@ -278,6 +283,25 @@ load_options ()
278 283
279 284
280/** 285/**
286 * Write final configuration to disk.
287 *
288 * @return GNUNET_OK on success
289 */
290static int
291write_configuration ()
292{
293 struct GNUNET_CONFIGURATION_Handle *cfgDefault;
294 int ret;
295
296 cfgDefault = GNUNET_CONFIGURATION_create ();
297 (void) GNUNET_CONFIGURATION_load (cfgDefault, NULL); /* load defaults only */
298 ret = GNUNET_CONFIGURATION_write_diffs (cfgDefault, cfg, cfgName);
299 GNUNET_CONFIGURATION_destroy (cfgDefault);
300 return ret;
301}
302
303
304/**
281 * Actual main method that sets up the configuration window. 305 * Actual main method that sets up the configuration window.
282 * 306 *
283 * @param cls the main loop handle 307 * @param cls the main loop handle
@@ -286,8 +310,6 @@ load_options ()
286static void 310static void
287cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 311cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
288{ 312{
289 struct GNUNET_CONFIGURATION_Handle *cfgDefault;
290
291 if (NULL == ml) 313 if (NULL == ml)
292 { 314 {
293 GNUNET_break (0); 315 GNUNET_break (0);
@@ -295,12 +317,8 @@ cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
295 } 317 }
296 GNUNET_GTK_main_loop_quit (ml); 318 GNUNET_GTK_main_loop_quit (ml);
297 ml = NULL; 319 ml = NULL;
298 cfgDefault = GNUNET_CONFIGURATION_create (); 320 if (GNUNET_OK != write_configuration ())
299 (void) GNUNET_CONFIGURATION_load (cfgDefault, NULL); /* load defaults only */
300 if (GNUNET_OK != GNUNET_CONFIGURATION_write_diffs (cfgDefault, cfg, cfgName))
301 gret = 1; 321 gret = 1;
302 GNUNET_CONFIGURATION_destroy (cfgDefault);
303 GNUNET_CONFIGURATION_destroy (cfg);
304 cfg = NULL; 322 cfg = NULL;
305 if (NULL != resolver) 323 if (NULL != resolver)
306 { 324 {
@@ -308,6 +326,38 @@ cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
308 GNUNET_OS_process_destroy (resolver); 326 GNUNET_OS_process_destroy (resolver);
309 resolver = NULL; 327 resolver = NULL;
310 } 328 }
329 if (NULL != namestore)
330 {
331 GNUNET_break (0 == GNUNET_OS_process_kill (namestore, SIGTERM));
332 GNUNET_OS_process_destroy (namestore);
333 namestore = NULL;
334 }
335}
336
337
338/**
339 * Write configuration to dis, (re)start the namestore process and
340 * reload the namestore models.
341 *
342 *
343 * @param cls closure (unused)
344 * @param tc scheduler context (unused)
345 */
346void
347GNUNET_SETUP_restart_namestore (void *cls,
348 const struct GNUNET_SCHEDULER_TaskContext *tc)
349{
350 if (GNUNET_OK != write_configuration ())
351 return; /* no point in re-starting namestore ... */
352 if (NULL != namestore)
353 {
354 GNUNET_break (0 == GNUNET_OS_process_kill (namestore, SIGTERM));
355 GNUNET_OS_process_destroy (namestore);
356 namestore = NULL;
357 }
358 /* FIXME: start namestore */
359 /* FIXME: refresh namestore model! */
360 GNUNET_break (0); // not implemented...
311} 361}
312 362
313 363
diff --git a/src/setup/gnunet-setup.h b/src/setup/gnunet-setup.h
index 4864c902..0a7b8e26 100644
--- a/src/setup/gnunet-setup.h
+++ b/src/setup/gnunet-setup.h
@@ -93,6 +93,18 @@ GNUNET_SETUP_get_object (const char *name);
93 93
94 94
95/** 95/**
96 * Write configuration to dis, (re)start the namestore process and
97 * reload the namestore models.
98 *
99 *
100 * @param cls closure (unused)
101 * @param tc scheduler context (unused)
102 */
103void
104GNUNET_SETUP_restart_namestore (void *cls,
105 const struct GNUNET_SCHEDULER_TaskContext *tc);
106
107/**
96 * Our configuration. 108 * Our configuration.
97 */ 109 */
98extern struct GNUNET_CONFIGURATION_Handle *cfg; 110extern struct GNUNET_CONFIGURATION_Handle *cfg;