diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/setup/Makefile.am | 2 | ||||
-rw-r--r-- | src/setup/gnunet-setup-dns-exit.c | 749 | ||||
-rw-r--r-- | src/setup/gnunet-setup-gns.c | 1718 | ||||
-rw-r--r-- | src/setup/gnunet-setup-namestore-config.c | 112 | ||||
-rw-r--r-- | src/setup/gnunet-setup-namestore-plugins.c | 67 | ||||
-rw-r--r-- | src/setup/gnunet-setup-options.c | 800 | ||||
-rw-r--r-- | src/setup/gnunet-setup.c | 68 | ||||
-rw-r--r-- | src/setup/gnunet-setup.h | 12 |
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 |
32 | gnunet_setup_LDADD = \ | 34 | gnunet_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 | */ | ||
38 | static void | ||
39 | add_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 | */ | ||
147 | static int | ||
148 | load_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 | */ | ||
173 | struct 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 | */ | ||
191 | static void | ||
192 | collect_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 | */ | ||
223 | static void | ||
224 | remove_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 | */ | ||
239 | static void | ||
240 | update_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 | */ | ||
345 | static void | ||
346 | save_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 | */ | ||
405 | static int | ||
406 | gns_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 | */ | ||
441 | static void | ||
442 | save_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 | */ | ||
489 | static int | ||
490 | gns_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 | */ | ||
524 | static void | ||
525 | save_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 | */ | ||
574 | static int | ||
575 | gns_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 | */ | ||
610 | static void | ||
611 | save_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 | */ | ||
654 | static int | ||
655 | gns_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 | */ | ||
33 | enum 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 | */ | ||
110 | enum 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 | */ | ||
129 | struct 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 | */ | ||
156 | static char *zone_as_string; | ||
157 | |||
158 | /** | ||
159 | * Default directory of zone files as a string. | ||
160 | */ | ||
161 | static char *zonekey_directory; | ||
162 | |||
163 | |||
164 | struct 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 | |||
186 | static void | ||
187 | check_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 | |||
221 | static void | ||
222 | check_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 | */ | ||
396 | struct Remove_Context | ||
397 | { | ||
398 | |||
399 | /** | ||
400 | * | ||
401 | */ | ||
402 | struct GNUNET_GNS_Context *gns; | ||
403 | |||
404 | /** | ||
405 | * | ||
406 | */ | ||
407 | char *path; | ||
408 | }; | ||
409 | |||
410 | |||
411 | static void | ||
412 | check_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 | |||
443 | static void | ||
444 | check_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 | */ | ||
553 | void | ||
554 | GNUNET_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 | */ | ||
642 | void | ||
643 | GNUNET_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 | |||
659 | static char * | ||
660 | convert_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 | |||
679 | static int | ||
680 | check_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 | |||
705 | static const struct GNUNET_TIME_Absolute | ||
706 | convert_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 | */ | ||
759 | void | ||
760 | GNUNET_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 | */ | ||
828 | void | ||
829 | GNUNET_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 | */ | ||
887 | void | ||
888 | GNUNET_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, ¬_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 | */ | ||
973 | gboolean | ||
974 | GNUNET_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, ¬_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 | |||
998 | static void | ||
999 | set_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, ¬_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 | |||
1036 | gboolean | ||
1037 | GNUNET_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 | |||
1045 | gboolean | ||
1046 | GNUNET_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 | |||
1054 | gboolean | ||
1055 | GNUNET_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 | |||
1063 | gboolean | ||
1064 | GNUNET_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 | |||
1072 | gboolean | ||
1073 | GNUNET_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 | |||
1084 | gboolean | ||
1085 | GNUNET_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 | |||
1094 | struct 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 | |||
1103 | void | ||
1104 | GNUNET_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, ¬_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 | |||
1128 | static void | ||
1129 | zone_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 | */ | ||
1273 | void | ||
1274 | GNUNET_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 | |||
1302 | static void | ||
1303 | pseu_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 | */ | ||
1332 | static void | ||
1333 | shutdown_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 | |||
1359 | gboolean | ||
1360 | GNUNET_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 | */ | ||
1385 | void | ||
1386 | GNUNET_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 | */ | ||
1418 | void | ||
1419 | GNUNET_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 | */ | ||
1458 | void | ||
1459 | GNUNET_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 | */ | ||
1473 | void | ||
1474 | GNUNET_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 | */ | ||
1503 | void | ||
1504 | GNUNET_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 | */ | ||
1550 | void | ||
1551 | GNUNET_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 | */ | ||
1568 | void | ||
1569 | GNUNET_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 | */ | ||
1585 | void | ||
1586 | GNUNET_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 | |||
1596 | static void | ||
1597 | close_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 | |||
1606 | static void | ||
1607 | namestore_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 | */ | ||
36 | static int | ||
37 | test_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 | |||
49 | static void | ||
50 | show (const char *name) | ||
51 | { | ||
52 | gtk_widget_show (GTK_WIDGET (GNUNET_SETUP_get_object (name))); | ||
53 | } | ||
54 | |||
55 | |||
56 | static void | ||
57 | hide (const char *name) | ||
58 | { | ||
59 | gtk_widget_hide (GTK_WIDGET (GNUNET_SETUP_get_object (name))); | ||
60 | } | ||
61 | |||
62 | |||
63 | void | ||
64 | GNUNET_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 | |||
71 | void | ||
72 | GNUNET_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 | |||
88 | static void | ||
89 | restart_namestore () | ||
90 | { | ||
91 | GNUNET_SCHEDULER_add_now (&GNUNET_SETUP_restart_namestore, | ||
92 | NULL); | ||
93 | } | ||
94 | |||
95 | |||
96 | void | ||
97 | GNUNET_setup_namestore_sqlite_radiobutton_toggled_cb (GtkToggleButton *tb, | ||
98 | gpointer user_data) | ||
99 | { | ||
100 | restart_namestore (); | ||
101 | } | ||
102 | |||
103 | |||
104 | void | ||
105 | GNUNET_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 | */ | ||
35 | static void | ||
36 | test_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 | |||
50 | void | ||
51 | GNUNET_setup_namestore_sqlite_radiobutton_realize_cb (GtkWidget * widget, | ||
52 | gpointer user_data) | ||
53 | { | ||
54 | test_plugin (widget, "libgnunet_plugin_namestore_sqlite"); | ||
55 | } | ||
56 | |||
57 | |||
58 | void | ||
59 | GNUNET_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 | */ | ||
726 | static void | ||
727 | add_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 | */ | ||
835 | static int | ||
836 | load_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 | */ | ||
861 | struct 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 | */ | ||
879 | static void | ||
880 | collect_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 | */ | ||
911 | static void | ||
912 | remove_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 | */ | ||
927 | static void | ||
928 | update_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 | */ | ||
1033 | static void | ||
1034 | save_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 | */ | ||
1093 | static int | ||
1094 | gns_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 | */ | ||
1129 | static void | ||
1130 | save_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 | */ | ||
1177 | static int | ||
1178 | gns_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 | */ | ||
1212 | static void | ||
1213 | save_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 | */ | ||
1262 | static int | ||
1263 | gns_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 | */ | ||
1298 | static void | ||
1299 | save_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 | */ | ||
1342 | static int | ||
1343 | gns_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 | */ |
1369 | static struct GNUNET_SETUP_VisibilitySpecification hide_min_connected_friends[] | 722 | static 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 | */ |
1416 | static struct GNUNET_SETUP_VisibilitySpecification hide_fs_tab[] = { | 768 | static 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 | */ |
1425 | static struct GNUNET_SETUP_VisibilitySpecification hide_vpn_tab[] = { | 777 | static 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 | */ |
1434 | static struct GNUNET_SETUP_VisibilitySpecification hide_gns_tab[] = { | 786 | static 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 | */ |
1443 | static struct GNUNET_SETUP_VisibilitySpecification hide_tcp_tab[] = { | 796 | static 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 | */ |
1452 | static struct GNUNET_SETUP_VisibilitySpecification hide_udp_tab[] = { | 805 | static 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 | */ |
1461 | static struct GNUNET_SETUP_VisibilitySpecification hide_http_tab[] = { | 814 | static 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 | */ |
1470 | static struct GNUNET_SETUP_VisibilitySpecification hide_https_tab[] = { | 823 | static 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 | */ |
1479 | static struct GNUNET_SETUP_VisibilitySpecification hide_dv_tab[] = { | 832 | static 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 | */ |
1488 | static struct GNUNET_SETUP_VisibilitySpecification hide_wlan_tab[] = { | 841 | static 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 | */ | ||
906 | static 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 | */ | ||
915 | static 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 | */ |
1553 | static struct GNUNET_SETUP_VisibilitySpecification hide_all_tcp_options[] = { | 924 | static 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 | */ |
56 | struct GNUNET_OS_Process *resolver; | 56 | static struct GNUNET_OS_Process *resolver; |
57 | |||
58 | /** | ||
59 | * Namestore process handle. | ||
60 | */ | ||
61 | static 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 | */ | ||
290 | static int | ||
291 | write_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 () | |||
286 | static void | 310 | static void |
287 | cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 311 | cleanup_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 | */ | ||
346 | void | ||
347 | GNUNET_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 | */ | ||
103 | void | ||
104 | GNUNET_SETUP_restart_namestore (void *cls, | ||
105 | const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
106 | |||
107 | /** | ||
96 | * Our configuration. | 108 | * Our configuration. |
97 | */ | 109 | */ |
98 | extern struct GNUNET_CONFIGURATION_Handle *cfg; | 110 | extern struct GNUNET_CONFIGURATION_Handle *cfg; |