/* This file is part of GNUnet. (C) 2010, 2011, 2012 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNUnet; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /** * @file src/setup/gnunet-setup-options.c * @brief configuration details * @author Christian Grothoff */ #include "gnunet-setup.h" #include "gnunet-setup-options.h" #include #include /** * Regular expression for YES */ #define REX_YES "^YES$" /** * Regular expression for NO */ #define REX_NO "^NO$" /** * Color for marking invalid input */ #define INVALID_INPUT_COLOR "red" /** * Structs of this type specify connection between widgets storing * port numbers and widgets controlling status of respective transport. */ struct PortSpecification { /** * Name of the GtkSpinButton storing the port value. */ const char *spinbutton_name; /** * Name of the GtkCheckButton controlling whether the respective * transport/daemon is enabled. */ const char *checkbutton_name; /** * Name of the transport/daemon which owns this port. */ const char *owner_name; }; /** * Initialize a toggle button based on an options 'yes/no' value. * * @param cls closure * @param section section with the value * @param option option name * @param value value as a string * @param widget widget to initialize * @param cfg configuration handle * @return GNUNET_OK on success, GNUNET_SYSERR if there was a problem */ static int load_yes_no (const void *cls, const char *section, const char *option, const char *value, GObject * widget, const struct GNUNET_CONFIGURATION_Handle *cfg) { GtkToggleButton *button; button = GTK_TOGGLE_BUTTON (widget); if (button == NULL) return GNUNET_SYSERR; gtk_toggle_button_set_active (button, (0 == strcasecmp (value, "YES")) ? TRUE : FALSE); return GNUNET_OK; } /** * Set a yes/no option based on a toggle button. * * @param cls closure * @param section section with the value * @param option option name * @param widget widget to initialize * @param cfg configuration handle to update * @return GNUNET_OK on success, GNUNET_SYSERR if there was a problem */ static int save_yes_no (const void *cls, const char *section, const char *option, GObject * widget, struct GNUNET_CONFIGURATION_Handle *cfg) { GtkToggleButton *button; gboolean mode; button = GTK_TOGGLE_BUTTON (widget); if (button == NULL) return GNUNET_SYSERR; mode = gtk_toggle_button_get_active (button); GNUNET_CONFIGURATION_set_value_string (cfg, section, option, mode == TRUE ? "YES" : "NO"); return GNUNET_OK; } /** * Initialize a GtkFileChooser based on a filename option. * * @param cls closure * @param section section with the value * @param option option name * @param value value as a string * @param widget widget to initialize * @param cfg configuration handle * @return GNUNET_OK on success, GNUNET_SYSERR if there was a problem */ static int load_filename (const void *cls, const char *section, const char *option, const char *value, GObject * widget, const struct GNUNET_CONFIGURATION_Handle *cfg) { GtkFileChooser *chooser; chooser = GTK_FILE_CHOOSER (widget); if (chooser == NULL) return GNUNET_SYSERR; gtk_file_chooser_set_filename (chooser, value); return GNUNET_OK; } /** * Set filename option based on a file chooser. * * @param cls closure * @param section section with the value * @param option option name * @param widget widget to initialize * @param cfg configuration handle to update * @return GNUNET_OK on success, GNUNET_SYSERR if there was a problem */ static int save_filename (const void *cls, const char *section, const char *option, GObject * widget, struct GNUNET_CONFIGURATION_Handle *cfg) { GtkFileChooser *chooser; gchar *fn; chooser = GTK_FILE_CHOOSER (widget); if (chooser == NULL) return GNUNET_SYSERR; fn = gtk_file_chooser_get_filename (chooser); if (fn == NULL) fn = g_strdup (""); GNUNET_CONFIGURATION_set_value_string (cfg, section, option, fn); g_free (fn); return GNUNET_OK; } /** * Initialize a GtkEntry based on a text option. * * @param cls closure * @param section section with the value * @param option option name * @param value value as a string * @param widget widget to initialize * @param cfg configuration handle * @return GNUNET_OK on success, GNUNET_SYSERR if there was a problem */ static int load_text (const void *cls, const char *section, const char *option, const char *value, GObject * widget, const struct GNUNET_CONFIGURATION_Handle *cfg) { GtkEntry *entry; entry = GTK_ENTRY (widget); if (entry == NULL) return GNUNET_SYSERR; gtk_entry_set_text (entry, value); return GNUNET_OK; } /** * Set text option based on a GtkEntry. * * @param cls closure * @param section section with the value * @param option option name * @param widget widget to initialize * @param cfg configuration handle to update * @return GNUNET_OK on success, GNUNET_SYSERR if there was a problem */ static int save_text (const void *cls, const char *section, const char *option, GObject * widget, struct GNUNET_CONFIGURATION_Handle *cfg) { GtkEntry *entry; const gchar *txt; entry = GTK_ENTRY (widget); if (entry == NULL) return GNUNET_SYSERR; txt = gtk_entry_get_text (entry); GNUNET_CONFIGURATION_set_value_string (cfg, section, option, txt); return GNUNET_OK; } #if 0 /** * Initialize a GtkComboBox based on a text option. * * @param cls closure * @param section section with the value * @param option option name * @param value value as a string * @param widget widget to initialize * @param cfg configuration handle * @return GNUNET_OK on success, GNUNET_SYSERR if there was a problem */ static int load_combo_text (const void *cls, const char *section, const char *option, const char *value, GObject * widget, const struct GNUNET_CONFIGURATION_Handle *cfg) { GtkComboBoxText *cb; cb = GTK_COMBO_BOX_TEXT (widget); if (NULL == cb) return GNUNET_SYSERR; gtk_combo_box_text_append_text (cb, value); return GNUNET_OK; } /** * Set text option based on a GtkComboBox. * * @param cls closure * @param section section with the value * @param option option name * @param widget widget to initialize * @param cfg configuration handle to update * @return GNUNET_OK on success, GNUNET_SYSERR if there was a problem */ static int save_combo_text (const void *cls, const char *section, const char *option, GObject * widget, struct GNUNET_CONFIGURATION_Handle *cfg) { GtkComboBox *cb; gchar *c; cb = GTK_COMBO_BOX (widget); if (NULL == cb) return GNUNET_SYSERR; c = gtk_combo_box_get_active_text (cb); GNUNET_CONFIGURATION_set_value_string (cfg, section, option, c); g_free (c); return GNUNET_OK; } #endif /** * Initialize a GtkSpinButton based on a numeric option. * * @param cls closure * @param section section with the value * @param option option name * @param value value as a string * @param widget widget to initialize * @param cfg configuration handle * @return GNUNET_OK on success, GNUNET_SYSERR if there was a problem */ static int load_number (const void *cls, const char *section, const char *option, const char *value, GObject * widget, const struct GNUNET_CONFIGURATION_Handle *cfg) { GtkSpinButton *spin; unsigned int number; spin = GTK_SPIN_BUTTON (widget); if (spin == NULL) return GNUNET_SYSERR; if (1 != sscanf (value, "%u", &number)) return GNUNET_SYSERR; gtk_spin_button_set_value (spin, number); return GNUNET_OK; } /** * Set numeric option based on a spin button. * * @param cls closure * @param section section with the value * @param option option name * @param widget widget to initialize * @param cfg configuration handle to update * @return GNUNET_OK on success, GNUNET_SYSERR if there was a problem */ static int save_number (const void *cls, const char *section, const char *option, GObject * widget, struct GNUNET_CONFIGURATION_Handle *cfg) { GtkSpinButton *spin; spin = GTK_SPIN_BUTTON (widget); if (spin == NULL) return GNUNET_SYSERR; GNUNET_CONFIGURATION_set_value_number (cfg, section, option, gtk_spin_button_get_value_as_int (spin)); return GNUNET_OK; } /** * NULL-terminated list of port specifications, which should be checked * for collisions. */ static struct PortSpecification port_specifications[] = { { "GNUNET_setup_hostlist_server_port_spin_button", "GNUNET_setup_hostlist_offer_hostlist_checkbutton", gettext_noop ("the hostlist server"),}, { "GNUNET_setup_transport_tcp_port_spinbutton", "GNUNET_setup_transport_tcp_checkbutton", gettext_noop ("the TCP transport plugin"),}, { "GNUNET_setup_transport_http_port_spinbutton", "GNUNET_setup_transport_http_checkbutton", gettext_noop ("the HTTP transport plugin"),}, { "GNUNET_setup_transport_https_port_spinbutton", "GNUNET_setup_transport_https_checkbutton", gettext_noop ("the HTTPS transport plugin"),}, {NULL, NULL} }; /** * Find spinbutton associated with a port specification. * * @param i index of the respective port specification * @return spinbutton or NULL in case of an error or if respecitve transport is disabled */ static GtkSpinButton * get_port_spinbutton (unsigned int i) { const char *sb_name; const char *cb_name; GtkWidget *widget; GtkToggleButton *checkbt; GtkSpinButton *spinbt; gboolean mode; if (port_specifications[i].spinbutton_name == NULL || port_specifications[i].checkbutton_name == NULL) return NULL; cb_name = port_specifications[i].checkbutton_name; widget = GTK_WIDGET (GNUNET_SETUP_get_object (cb_name)); if (widget == NULL) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Widget `%s' not found\n"), cb_name); return NULL; } checkbt = GTK_TOGGLE_BUTTON (widget); if (checkbt == NULL) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Specified widget `%s' is not a checkbutton\n"), cb_name); return NULL; } mode = gtk_toggle_button_get_active (checkbt); if (TRUE != mode) return NULL; sb_name = port_specifications[i].spinbutton_name; widget = GTK_WIDGET (GNUNET_SETUP_get_object (sb_name)); if (widget == NULL) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Widget `%s' not found\n"), sb_name); return NULL; } spinbt = GTK_SPIN_BUTTON (widget); if (spinbt == NULL) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Specified widget `%s' is not a spinbutton\n"), sb_name); return NULL; } return spinbt; } /** * Check port numbers for collisions and highlight conflicting ports, if any. * * @param cls closure (unused) * @param widget widget whose state was changed (unused) */ static void highlight_port_collisions (const void *cls, GObject *widget) { unsigned int i; unsigned int j; unsigned int port; GtkSpinButton *spinbt_i; GtkSpinButton *spinbt_j; GdkColor color; GdkColor *pcolor; int found; char *tooltip; gdk_color_parse (INVALID_INPUT_COLOR, &color); for (i = 0; port_specifications[i].spinbutton_name != NULL; i++) { spinbt_i = get_port_spinbutton (i); if (spinbt_i == NULL) continue; else port = gtk_spin_button_get_value_as_int (spinbt_i); found = GNUNET_NO; for (j = 0; port_specifications[j].spinbutton_name != NULL; j++) { if (i == j) continue; spinbt_j = get_port_spinbutton (j); if (spinbt_j == NULL) continue; if (port == gtk_spin_button_get_value_as_int (spinbt_j)) { found = GNUNET_YES; break; } } if (GNUNET_YES == found) { pcolor = &color; GNUNET_asprintf (&tooltip, _("This port is already occupied by %s."), port_specifications[j].owner_name); } else { pcolor = NULL; tooltip = GNUNET_strdup (""); } gtk_widget_modify_text (GTK_WIDGET (spinbt_i), GTK_STATE_NORMAL, pcolor); gtk_widget_modify_text (GTK_WIDGET (spinbt_i), GTK_STATE_ACTIVE, pcolor); gtk_widget_modify_text (GTK_WIDGET (spinbt_i), GTK_STATE_SELECTED, pcolor); gtk_widget_set_tooltip_text (GTK_WIDGET (spinbt_i), tooltip); GNUNET_free (tooltip); } } /** * Initialize a toggle button based on the existence of a word * in an option value. * * @param cls word to test for (conat char *) * @param section section with the value * @param option option name * @param value value as a string * @param widget widget to initialize * @param cfg configuration handle * @return GNUNET_OK on success, GNUNET_SYSERR if there was a problem */ static int load_option_list (const void *cls, const char *section, const char *option, const char *value, GObject * widget, const struct GNUNET_CONFIGURATION_Handle *cfg) { const char *word = cls; char *t; char *w; GtkToggleButton *button; int found; button = GTK_TOGGLE_BUTTON (widget); if (button == NULL) return GNUNET_SYSERR; found = GNUNET_NO; t = GNUNET_strdup (value); w = strtok (t, " "); while (w != NULL) { if (0 == strcmp (w, word)) { found = GNUNET_YES; break; } w = strtok (NULL, " "); } GNUNET_free (t); gtk_toggle_button_set_active (button, found); return GNUNET_OK; } /** * Add or remove a word from a sentence based on a toggle button's yes/no value. * * @param cls word to add or remove for (conat char *) * @param section section with the value * @param option option name * @param widget widget to initialize * @param cfg configuration handle to update * @return GNUNET_OK on success, GNUNET_SYSERR if there was a problem */ static int save_option_list (const void *cls, const char *section, const char *option, GObject * widget, struct GNUNET_CONFIGURATION_Handle *cfg) { const char *word = cls; GtkToggleButton *button; gboolean mode; button = GTK_TOGGLE_BUTTON (widget); if (button == NULL) return GNUNET_SYSERR; mode = gtk_toggle_button_get_active (button); if (mode == TRUE) GNUNET_CONFIGURATION_append_value_filename (cfg, section, option, word); else GNUNET_CONFIGURATION_remove_value_filename (cfg, section, option, word); return GNUNET_OK; } /** * User pressed a key in a sensitive tree view with a list store. * Check if it was the 'delete' key and if so remove the selected * row. * * @param tv tree view emitting the signal * @param event key stroke data * @param user_data not used * @return TRUE to stop other handlers from being invoked */ gboolean GNUNET_setup_treeview_key_press_event_cb (GtkTreeView * tv, GdkEventKey * event, gpointer user_data) { GtkListStore *ls; GtkTreeModel *tm; GtkTreeSelection *sel; GtkTreeIter iter; gboolean editable; if ((event->type != GDK_KEY_PRESS) || (event->state != 0) || #ifdef GDK_Delete (event->keyval != GDK_Delete) #else (event->keyval != GDK_KEY_Delete) #endif ) return FALSE; ls = GTK_LIST_STORE (gtk_tree_view_get_model (tv)); if (ls == NULL) { GNUNET_break (0); return FALSE; } sel = gtk_tree_view_get_selection (tv); if (TRUE != gtk_tree_selection_get_selected (sel, &tm, &iter)) return FALSE; gtk_tree_model_get (tm, &iter, GNUNET_GTK_SETUP_HOSTLIST_URL_MC_EDITABLE, &editable, -1); if (TRUE == editable) return FALSE; /* likely currently editing... */ gtk_list_store_remove (ls, &iter); if (TRUE == gtk_tree_model_get_iter_first (tm, &iter)) gtk_tree_selection_select_iter (sel, &iter); return FALSE; } /** * Initialize a GtkListStore by tokenizing the value into strings. * * @param cls closure (unused) * @param section section with the value * @param option option name * @param value value as a string * @param widget widget to initialize * @param cfg configuration handle * @return GNUNET_OK on success, GNUNET_SYSERR if there was a problem */ static int load_string_list_store (const void *cls, const char *section, const char *option, const char *value, GObject * widget, const struct GNUNET_CONFIGURATION_Handle *cfg) { char *t; char *w; GtkListStore *ls; GtkTreeIter iter; ls = GTK_LIST_STORE (widget); if (ls == NULL) return GNUNET_SYSERR; t = GNUNET_strdup (value); for (w = strtok (t, " "); w != NULL; w = strtok (NULL, " ")) gtk_list_store_insert_with_values (ls, &iter, G_MAXINT, GNUNET_GTK_SETUP_HOSTLIST_URL_MC_URL, w, GNUNET_GTK_SETUP_HOSTLIST_URL_MC_EDITABLE, FALSE, -1); GNUNET_free (t); gtk_list_store_insert_with_values (ls, &iter, G_MAXINT, GNUNET_GTK_SETUP_HOSTLIST_URL_MC_URL, "", GNUNET_GTK_SETUP_HOSTLIST_URL_MC_EDITABLE, TRUE, -1); return GNUNET_OK; } /** * The GtkCellRenderer has emmited the 'edited' signal. * * * @param cls closure (unused) * @param section section with the value (NULL) * @param option option name (NULL) * @param widget the cell renderer * @param cfg configuration handle to update * @return GNUNET_OK on success, GNUNET_SYSERR if there was a problem */ static int save_string_list_store (const void *cls, const char *section, const char *option, GObject * widget, struct GNUNET_CONFIGURATION_Handle *cfg) { GtkTreeModel *tm; GtkTreeIter iter; char *value; char *n; gchar *val; tm = GTK_TREE_MODEL (widget); if (tm == NULL) return GNUNET_SYSERR; value = NULL; if (TRUE == gtk_tree_model_get_iter_first (tm, &iter)) { do { gtk_tree_model_get (tm, &iter, GNUNET_GTK_SETUP_HOSTLIST_URL_MC_URL, &val, -1); if (0 < strlen (val)) { if (value == NULL) { value = GNUNET_strdup (val); } else { GNUNET_asprintf (&n, "%s %s", value, val); GNUNET_free (value); value = n; } } g_free (val); } while (TRUE == gtk_tree_model_iter_next (tm, &iter)); } if (value == NULL) value = GNUNET_strdup (""); GNUNET_CONFIGURATION_set_value_string (cfg, section, option, value); GNUNET_free (value); return GNUNET_OK; } /** * Check if the section represents a DNS entry and then update the * GtkListStore accordingly. * * @param cls the list store to modify * @param section name of the section */ static void add_dns_entry_to_list_store (void *cls, const char *section) { GtkListStore *ls = cls; GtkTreeIter iter; char *sld; char *hostname; char *hostport; char *redirect; char *cpy; gboolean udp; if (NULL == section) { gtk_list_store_insert_with_values (ls, &iter, G_MAXINT, GNUNET_GTK_SETUP_GNS_MC_HOSTNAME, "", GNUNET_GTK_SETUP_GNS_MC_SOURCEPORT, (guint) 80, GNUNET_GTK_SETUP_GNS_MC_TARGETPORT, (guint) 8080, GNUNET_GTK_SETUP_GNS_MC_HOSTNAME, "localhost4", GNUNET_GTK_SETUP_GNS_MC_ISUDP, "tcp", -1); return; } if ((8 > strlen (section)) || (0 != strcmp (".gnunet.", section + ((strlen (section) - 8))))) return; sld = GNUNET_strdup (section); sld[strlen (section) - 8] = '\0'; udp = FALSE; do { if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, section, (TRUE == udp) ? "UDP_REDIRECTS" : "TCP_REDIRECTS", &cpy)) { for (redirect = strtok (cpy, " "); redirect != NULL; redirect = strtok (NULL, " ")) { if (NULL == (hostname = strstr (redirect, ":"))) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Option `%s' is not formatted correctly!\n"), redirect); continue; } hostname[0] = '\0'; hostname++; if (NULL == (hostport = strstr (hostname, ":"))) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Option `%s' is not formatted correctly!\n"), redirect); continue; } hostport[0] = '\0'; hostport++; int local_port = atoi (redirect); if (!((local_port > 0) && (local_port < 65536))) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("`%s' is not a valid port number!\n"), redirect); continue; } int host_port = atoi (hostport); if (!((host_port > 0) && (host_port < 65536))) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("`%s' is not a valid port number!\n"), hostport); continue; } gtk_list_store_insert_with_values (ls, &iter, 0, GNUNET_GTK_SETUP_GNS_MC_HOSTNAME, sld, GNUNET_GTK_SETUP_GNS_MC_SOURCEPORT, (guint) local_port, GNUNET_GTK_SETUP_GNS_MC_TARGETPORT, (guint) host_port, GNUNET_GTK_SETUP_GNS_MC_TARGETHOSTNAME, hostname, GNUNET_GTK_SETUP_GNS_MC_ISUDP, (TRUE == udp) ? "udp" : "tcp", -1); } GNUNET_free (cpy); } udp = !udp; } while (udp != FALSE); GNUNET_free (sld); } /** * Initialize the GtkListModel with the VPN's DNS service specification. * * @param cls NULL * @param section section with the value (NULL) * @param option option name (NULL) * @param value value as a string (NULL) * @param widget widget to initialize (the GtkTreeView) * @param cfg configuration handle * @return GNUNET_OK on success, GNUNET_SYSERR if there was a problem */ static int load_vpn_dns_configuration (const void *cls, const char *section, const char *option, const char *value, GObject * widget, const struct GNUNET_CONFIGURATION_Handle *cfg) { GtkTreeView *tv; GtkListStore *ls; tv = GTK_TREE_VIEW (widget); if (tv == NULL) { GNUNET_break (0); return GNUNET_SYSERR; } ls = GTK_LIST_STORE (gtk_tree_view_get_model (tv)); GNUNET_CONFIGURATION_iterate_sections (cfg, &add_dns_entry_to_list_store, ls); /* finally, add empty entry */ add_dns_entry_to_list_store (ls, NULL); return GNUNET_OK; } /** * Records we use to build DNS information lists. */ struct DnsInfo { struct DnsInfo *next; char *section; char *altnames; char *tcpred; char *udpred; unsigned long long ttl; }; /** * Function called for each section in the configuration. * Gather existing ttl, section names and altnames. * * @param cls 'struct DnsInfo**' to create * @param section name of a section in the configuration */ static void collect_dns_sections (void *cls, const char *section) { struct DnsInfo **base = cls; struct DnsInfo *pos; if ((8 > strlen (section)) || (0 != strcmp (".gnunet.", section + ((strlen (section) - 8))))) return; pos = GNUNET_malloc (sizeof (struct DnsInfo)); pos->section = GNUNET_strdup (section); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, section, "TTL", &pos->ttl)) pos->ttl = 3600000; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, section, "ALTERNATIVE_NAMES", &pos->altnames)) pos->altnames = NULL; pos->tcpred = GNUNET_strdup (""); pos->udpred = GNUNET_strdup (""); pos->next = *base; *base = pos; } /** * Function called for each section in the configuration. * Removes those ending in '.gnunet.'. * * @param cls unused * @param section name of a section in the configuration */ static void remove_dns_sections (void *cls, const char *section) { if ((8 > strlen (section)) || (0 != strcmp (".gnunet.", section + ((strlen (section) - 8))))) return; GNUNET_CONFIGURATION_remove_section (cfg, section); } /** * Given the list store and the data in it, update the * configuration file accordingly. * * @param tm model to use */ static void update_vpn_dns_configuration (GtkTreeModel * tm) { GtkTreeIter iter; gchar *hostname; guint srcport; guint targetport; gchar *targethost; gchar *tcpudp; char *tmp; struct DnsInfo *head; struct DnsInfo *pos; head = NULL; GNUNET_CONFIGURATION_iterate_sections (cfg, &collect_dns_sections, &head); if (TRUE == gtk_tree_model_get_iter_first (tm, &iter)) do { gtk_tree_model_get (tm, &iter, GNUNET_GTK_SETUP_GNS_MC_HOSTNAME, &hostname, GNUNET_GTK_SETUP_GNS_MC_SOURCEPORT, &srcport, GNUNET_GTK_SETUP_GNS_MC_TARGETPORT, &targetport, GNUNET_GTK_SETUP_GNS_MC_TARGETHOSTNAME, &targethost, GNUNET_GTK_SETUP_GNS_MC_ISUDP, &tcpudp, -1); if (0 != strlen (hostname)) { pos = head; GNUNET_asprintf (&tmp, "%s.gnunet.", hostname); while ((NULL != pos) && (0 != strcasecmp (tmp, pos->section))) pos = pos->next; if (pos == NULL) { pos = GNUNET_malloc (sizeof (struct DnsInfo)); pos->section = tmp; pos->ttl = 3600000; pos->altnames = NULL; pos->tcpred = GNUNET_strdup (""); pos->udpred = GNUNET_strdup (""); pos->next = head; head = pos; } else { GNUNET_free (tmp); } GNUNET_asprintf (&tmp, "%u:%s:%u %s", srcport, targethost, targetport, (0 == strcasecmp ("tcp", tcpudp)) ? pos->tcpred : pos->udpred); if (0 == strcasecmp ("tcp", tcpudp)) { GNUNET_free (pos->tcpred); pos->tcpred = tmp; } else { GNUNET_free (pos->udpred); pos->udpred = tmp; } } g_free (tcpudp); g_free (hostname); g_free (targethost); } while (TRUE == gtk_tree_model_iter_next (tm, &iter)); GNUNET_CONFIGURATION_iterate_sections (cfg, &remove_dns_sections, NULL); while (NULL != head) { pos = head; head = pos->next; if (pos->altnames != NULL) GNUNET_CONFIGURATION_set_value_string (cfg, pos->section, "ALTERNATIVE_NAMES", pos->altnames); if (strlen (pos->udpred) > 0) GNUNET_CONFIGURATION_set_value_string (cfg, pos->section, "UDP_REDIRECTS", pos->udpred); if (strlen (pos->tcpred) > 0) GNUNET_CONFIGURATION_set_value_string (cfg, pos->section, "TCP_REDIRECTS", pos->tcpred); if ((strlen (pos->udpred) > 0) || (strlen (pos->tcpred) > 0)) GNUNET_CONFIGURATION_set_value_number (cfg, pos->section, "TTL", pos->ttl); GNUNET_free_non_null (pos->altnames); GNUNET_free (pos->tcpred); GNUNET_free (pos->udpred); GNUNET_free (pos->section); GNUNET_free (pos); } } /** * The user has edited the DNS name of a service we're offering. * Update the GtkTreeModel (at the given path) and update the * respective service entry in the configuration file. Finally, * if the edited path is for a "fresh" entry, create another empty * one at the bottom. If the hostname was set to empty, remove * the entire entry from the configuration and the model. * * @param renderer GtkCellRendererText that changed * @param path GtkTreePath identifying where in the Model the change is * @param new_text the new text that was stored in the line * @param user_data NULL */ static void save_vpn_dns_service_dnsname (GtkCellRendererText * renderer, gchar * path, gchar * new_text, gpointer user_data) { GtkTreeModel *tm; GtkListStore *ls; GtkTreeIter iter; gchar *old; tm = GTK_TREE_MODEL (GNUNET_SETUP_get_object ("GNUNET_setup_gns_liststore")); if (NULL == tm) { GNUNET_break (0); return; } ls = GTK_LIST_STORE (tm); if (NULL == ls) { GNUNET_break (0); return; } if (TRUE != gtk_tree_model_get_iter_from_string (tm, &iter, path)) { GNUNET_break (0); return; } gtk_tree_model_get (tm, &iter, GNUNET_GTK_SETUP_GNS_MC_HOSTNAME, &old, -1); if ((0 != strlen (old)) && (0 == strlen (new_text))) { /* deletion */ gtk_list_store_remove (ls, &iter); g_free (old); /* update configuration */ update_vpn_dns_configuration (tm); return; } /* update model */ gtk_list_store_set (ls, &iter, GNUNET_GTK_SETUP_GNS_MC_HOSTNAME, new_text, -1); /* update configuration */ update_vpn_dns_configuration (tm); if ((0 == strlen (old)) && (0 != strlen (new_text))) { /* need another empty entry at the end for future expansion */ add_dns_entry_to_list_store (GTK_LIST_STORE (tm), NULL); } g_free (old); } /** * Initialize the GtkListModel with the VPN's DNS service specification. * * @param cls NULL * @param section section with the value (NULL) * @param option option name (NULL) * @param widget widget to initialize (the GtkTreeView) * @param cfg configuration handle * @return GNUNET_OK on success, GNUNET_SYSERR if there was a problem */ static int gns_name_install_edited_handler (const void *cls, const char *section, const char *option, GObject * widget, struct GNUNET_CONFIGURATION_Handle *cfg) { static int once; GtkCellRendererText *rt; rt = GTK_CELL_RENDERER_TEXT (widget); if (NULL == rt) return GNUNET_SYSERR; if (0 != once++) return GNUNET_OK; g_signal_connect (rt, "edited", G_CALLBACK (&save_vpn_dns_service_dnsname), NULL); return GNUNET_OK; } /** * The user has edited the DNS name of a service we're offering. * Update the GtkTreeModel (at the given path) and update the * respective service entry in the configuration file. Finally, * if the edited path is for a "fresh" entry, create another empty * one at the bottom. If the hostname was set to empty, remove * the entire entry from the configuration and the model. * * @param renderer GtkCellRendererText that changed * @param path GtkTreePath identifying where in the Model the change is * @param new_text the new text that was stored in the line * @param user_data NULL */ static void save_vpn_dns_service_tcpudp (GtkCellRendererText * renderer, gchar * path, gchar * new_text, gpointer user_data) { GtkTreeModel *tm; GtkListStore *ls; GtkTreeIter iter; if ((0 != strcasecmp ("tcp", new_text)) && (0 != strcasecmp ("udp", new_text))) { /* FIXME: warn... */ return; } tm = GTK_TREE_MODEL (GNUNET_SETUP_get_object ("GNUNET_setup_gns_liststore")); if (NULL == tm) { GNUNET_break (0); return; } ls = GTK_LIST_STORE (tm); if (NULL == ls) { GNUNET_break (0); return; } if (TRUE != gtk_tree_model_get_iter_from_string (tm, &iter, path)) { GNUNET_break (0); return; } /* update model */ gtk_list_store_set (ls, &iter, GNUNET_GTK_SETUP_GNS_MC_ISUDP, new_text, -1); /* update configuration */ update_vpn_dns_configuration (tm); } /** * Initialize the GtkListModel with the VPN's DNS service specification. * * @param cls NULL * @param section section with the value (NULL) * @param option option name (NULL) * @param widget widget to initialize (the GtkTreeView) * @param cfg configuration handle * @return GNUNET_OK on success, GNUNET_SYSERR if there was a problem */ static int gns_type_install_edited_handler (const void *cls, const char *section, const char *option, GObject * widget, struct GNUNET_CONFIGURATION_Handle *cfg) { static int once; GtkCellRendererText *rt; rt = GTK_CELL_RENDERER_TEXT (widget); if (NULL == rt) return GNUNET_SYSERR; if (0 != once++) return GNUNET_OK; g_signal_connect (rt, "edited", G_CALLBACK (&save_vpn_dns_service_tcpudp), NULL); return GNUNET_OK; } /** * The user has edited the DNS name of a service we're offering. * Update the GtkTreeModel (at the given path) and update the * respective service entry in the configuration file. Finally, * if the edited path is for a "fresh" entry, create another empty * one at the bottom. If the hostname was set to empty, remove * the entire entry from the configuration and the model. * * @param renderer GtkCellRendererText that changed * @param path GtkTreePath identifying where in the Model the change is * @param new_text the new text that was stored in the line * @param user_data NULL */ static void save_vpn_dns_service_sourceport (GtkCellRendererText * renderer, gchar * path, gchar * new_text, gpointer user_data) { GtkTreeModel *tm; GtkListStore *ls; GtkTreeIter iter; int port; port = atoi (new_text); if ((port < 1) || (port > UINT16_MAX)) { /* invalid port, FIXME: warn */ return; } tm = GTK_TREE_MODEL (GNUNET_SETUP_get_object ("GNUNET_setup_gns_liststore")); if (NULL == tm) { GNUNET_break (0); return; } ls = GTK_LIST_STORE (tm); if (NULL == ls) { GNUNET_break (0); return; } if (TRUE != gtk_tree_model_get_iter_from_string (tm, &iter, path)) { GNUNET_break (0); return; } /* update model */ gtk_list_store_set (ls, &iter, GNUNET_GTK_SETUP_GNS_MC_SOURCEPORT, (guint) port, -1); /* update configuration */ update_vpn_dns_configuration (tm); } /** * Initialize the GtkListModel with the VPN's DNS service specification. * * @param cls NULL * @param section section with the value (NULL) * @param option option name (NULL) * @param widget widget to initialize (the GtkTreeView) * @param cfg configuration handle * @return GNUNET_OK on success, GNUNET_SYSERR if there was a problem */ static int gns_ttl_install_edited_handler (const void *cls, const char *section, const char *option, GObject * widget, struct GNUNET_CONFIGURATION_Handle *cfg) { static int once; GtkCellRendererText *rt; rt = GTK_CELL_RENDERER_TEXT (widget); if (NULL == rt) return GNUNET_SYSERR; if (0 != once++) return GNUNET_OK; g_signal_connect (rt, "edited", G_CALLBACK (&save_vpn_dns_service_sourceport), NULL); return GNUNET_OK; } /** * The user has edited the DNS name of a service we're offering. * Update the GtkTreeModel (at the given path) and update the * respective service entry in the configuration file. Finally, * if the edited path is for a "fresh" entry, create another empty * one at the bottom. If the hostname was set to empty, remove * the entire entry from the configuration and the model. * * @param renderer GtkCellRendererText that changed * @param path GtkTreePath identifying where in the Model the change is * @param new_text the new text that was stored in the line * @param user_data NULL */ static void save_vpn_dns_service_targethostname (GtkCellRendererText * renderer, gchar * path, gchar * new_text, gpointer user_data) { GtkTreeModel *tm; GtkListStore *ls; GtkTreeIter iter; tm = GTK_TREE_MODEL (GNUNET_SETUP_get_object ("GNUNET_setup_gns_liststore")); if (NULL == tm) { GNUNET_break (0); return; } ls = GTK_LIST_STORE (tm); if (NULL == ls) { GNUNET_break (0); return; } if (TRUE != gtk_tree_model_get_iter_from_string (tm, &iter, path)) { GNUNET_break (0); return; } /* update model */ gtk_list_store_set (ls, &iter, GNUNET_GTK_SETUP_GNS_MC_TARGETHOSTNAME, new_text, -1); /* update configuration */ update_vpn_dns_configuration (tm); } /** * Initialize the GtkListModel with the VPN's DNS service specification. * * @param cls NULL * @param section section with the value (NULL) * @param option option name (NULL) * @param widget widget to initialize (the GtkTreeView) * @param cfg configuration handle * @return GNUNET_OK on success, GNUNET_SYSERR if there was a problem */ static int gns_value_install_edited_handler (const void *cls, const char *section, const char *option, GObject * widget, struct GNUNET_CONFIGURATION_Handle *cfg) { static int once; GtkCellRendererText *rt; rt = GTK_CELL_RENDERER_TEXT (widget); if (NULL == rt) return GNUNET_SYSERR; if (0 != once++) return GNUNET_OK; g_signal_connect (rt, "edited", G_CALLBACK (&save_vpn_dns_service_targethostname), NULL); return GNUNET_OK; } /** * Hide "min connected friends" option if in F2F-only mode. */ static struct GNUNET_SETUP_VisibilitySpecification hide_min_connected_friends[] = { {"GNUNET_setup_minimum_friends_label", NULL, REX_YES}, {"GNUNET_setup_minimum_friends_spinbutton", NULL, REX_YES}, {NULL, NULL, NULL} }; /** * Hide "hostlist" options if hostlist is not in use. */ static struct GNUNET_SETUP_VisibilitySpecification hide_hostlist_options[] = { {"GNUNET_setup_hostlist_client_enable_checkbutton", "(^| )hostlist($| )", NULL}, {"GNUNET_setup_hostlist_client_learn_checkbutton", "(^| )hostlist($| )", NULL}, {"GNUNET_setup_hostlist_options_hbox", "(^| )hostlist($| )", NULL}, {"GNUNET_setup_hostlist_frame", "(^| )hostlist($| )", NULL}, {NULL, NULL, NULL} }; /** * Hide "exit" options if VPN exit is not in use. */ static struct GNUNET_SETUP_VisibilitySpecification hide_exit_options[] = { {"GNUNET_setup_exit_label", "(^| )exit($| )", NULL}, {"GNUNET_setup_exit_vbox", "(^| )exit($| )", NULL}, {NULL, NULL, NULL} }; /** * Hide "hostlist" server options if hostlist server is not in use. */ static struct GNUNET_SETUP_VisibilitySpecification hide_hostlist_server_options[] = { {"GNUNET_setup_hostlist_advertise_checkbutton", "(^| )-p($| )", NULL}, {"GNUNET_setup_hostlist_port_label", "(^| )-p($| )", NULL}, {"GNUNET_setup_hostlist_server_port_spin_button", "(^| )-p($| )", NULL}, {NULL, NULL, NULL} }; /** * Hide "fs tab" if FS not active. */ static struct GNUNET_SETUP_VisibilitySpecification hide_fs_tab[] = { {"GNUNET_setup_fs_main_vbox", "(^| )fs($| )", NULL}, {NULL, NULL, NULL} }; /** * Hide "vpn tab" if VPN not active. */ static struct GNUNET_SETUP_VisibilitySpecification hide_vpn_tab[] = { {"GNUNET_setup_vpn_vbox", "(^| )pt($| )", NULL}, {NULL, NULL, NULL} }; /** * Hide "gns tab" if GNS not active. */ static struct GNUNET_SETUP_VisibilitySpecification hide_gns_tab[] = { {"GNUNET_setup_gns_vbox", "(^| )gns($| )", NULL}, {NULL, NULL, NULL} }; /** * Hide "tcp tab" if TCP not active. */ static struct GNUNET_SETUP_VisibilitySpecification hide_tcp_tab[] = { {"GNUNET_setup_transport_tcp_vbox", "(^| )tcp($| )", NULL}, {NULL, NULL, NULL} }; /** * Hide "udp tab" if UDP not active. */ static struct GNUNET_SETUP_VisibilitySpecification hide_udp_tab[] = { {"GNUNET_setup_transport_udp_vbox", "(^| )udp($| )", NULL}, {NULL, NULL, NULL} }; /** * Hide "http tab" if HTTP not active. */ static struct GNUNET_SETUP_VisibilitySpecification hide_http_tab[] = { {"GNUNET_setup_transport_http_vbox", "(^| )http($| )", NULL}, {NULL, NULL, NULL} }; /** * Hide "https tab" if HTTPS not active. */ static struct GNUNET_SETUP_VisibilitySpecification hide_https_tab[] = { {"GNUNET_setup_transport_https_vbox", "(^| )https($| )", NULL}, {NULL, NULL, NULL} }; /** * Hide "dv tab" if DV not active. */ static struct GNUNET_SETUP_VisibilitySpecification hide_dv_tab[] = { {"GNUNET_setup_transport_dv_vbox", "(^| )dv($| )", NULL}, {NULL, NULL, NULL} }; /** * Hide "wlan tab" if WLAN not active. */ static struct GNUNET_SETUP_VisibilitySpecification hide_wlan_tab[] = { {"GNUNET_setup_transport_wlan_vbox", "(^| )wlan($| )", NULL}, {NULL, NULL, NULL} }; /** * Hide "sqlite datastore" tab if sqlite not active. */ static struct GNUNET_SETUP_VisibilitySpecification hide_sqlite_datastore_tab[] = { {"GNUNET_setup_fs_datastore_sqlite_label", "^sqlite$", NULL}, {NULL, NULL, NULL} }; /** * Hide "mysql datastore" tab if mysql not active. */ static struct GNUNET_SETUP_VisibilitySpecification hide_mysql_datastore_tab[] = { {"GNUNET_setup_datastore_mysql_vbox", "^mysql$", NULL}, {NULL, NULL, NULL} }; /** * Hide "postgres datastore" tab if postgres not active. */ static struct GNUNET_SETUP_VisibilitySpecification hide_postgres_datastore_tab[] = { {"GNUNET_setup_datastore_postgres_hbox", "^postgres$", NULL}, {NULL, NULL, NULL} }; /** * Hide "sqlite datacache" tab if sqlite not active. */ static struct GNUNET_SETUP_VisibilitySpecification hide_sqlite_datacache_tab[] = { {"GNUNET_setup_fs_datacache_sqlite_body_label", "^sqlite$", NULL}, {NULL, NULL, NULL} }; /** * Hide "mysql datacache" tab if mysql not active. */ static struct GNUNET_SETUP_VisibilitySpecification hide_mysql_datacache_tab[] = { {"GNUNET_setup_datacache_mysql_vbox", "^mysql$", NULL}, {NULL, NULL, NULL} }; /** * Hide "postgres datacache" tab if postgres not active. */ static struct GNUNET_SETUP_VisibilitySpecification hide_postgres_datacache_tab[] = { {"GNUNET_setup_datacache_postgres_hbox", "^postgres$", NULL}, {NULL, NULL, NULL} }; /** * Hide advertised TCP port if port is zero. */ static struct GNUNET_SETUP_VisibilitySpecification hide_all_tcp_options[] = { {"GNUNET_setup_transport_tcp_adv_port_hbox", NULL, "^0$"}, {NULL, NULL, NULL} }; /** * Hide NATed peer options. */ static struct GNUNET_SETUP_VisibilitySpecification toggle_nat_options[] = { {"GNUNET_setup_transport_hole_punched_checkbutton", "^YES$", NULL}, {"GNUNET_setup_transport_upnp_enable_checkbutton", "^YES$", NULL}, {"GNUNET_setup_transport_icmp_server_enable_checkbutton", "^YES$", NULL}, {"GNUNET_setup_transport_external_ip_hbox", "^YES$", NULL}, {NULL, NULL, NULL} }; /** * Hide hole-punched NATed peer options. */ static struct GNUNET_SETUP_VisibilitySpecification toggle_nat_punched_options[] = { {"GNUNET_setup_transport_upnp_enable_checkbutton", "^NO$", NULL}, {"GNUNET_setup_transport_icmp_server_enable_checkbutton", "^NO$", NULL}, {NULL, NULL, NULL} }; /** * Hide internal IP options. */ static struct GNUNET_SETUP_VisibilitySpecification toggle_internal_ip[] = { {"GNUNET_setup_transport_internal_ip_hbox", "^YES$", NULL}, {NULL, NULL, NULL} }; /** * Option specification data. */ const struct GNUNET_SETUP_OptionSpecification option_specifications[] = { /* GENERAL TAB */ { "GNUNET_setup_friends_only_checkbutton", "toggled", "topology", "FRIENDS-ONLY", gettext_noop ("Should GNUnet exclusively connect to friends?"), "https://gnunet.org/configuration-f2f", &load_yes_no, &save_yes_no, NULL, NULL, NULL, hide_min_connected_friends}, { "GNUNET_setup_friends_filechooserbutton", "selection-changed", "topology", "FRIENDS", gettext_noop ("Friends file containing the list of friendly peers"), "https://gnunet.org/configuration-f2f", &load_filename, &save_filename, NULL, NULL, NULL, NULL}, { "GNUNET_setup_minimum_friends_spinbutton", "value-changed", "topology", "MINIMUM-FRIENDS", gettext_noop ("Minimum number of friendly connections"), "https://gnunet.org/configuration-f2f", &load_number, &save_number, NULL, NULL, NULL, NULL}, { "GNUNET_setup_general_services_topology_checkbutton", "toggled", "arm", "DEFAULTSERVICES", gettext_noop ("Topology should always be loaded"), "https://gnunet.org/configuration-topology", &load_option_list, &save_option_list, "topology", NULL, NULL, NULL}, { "GNUNET_setup_general_services_hostlist_checkbutton", "toggled", "arm", "DEFAULTSERVICES", gettext_noop ("Should hostlist support be started automatically on startup?"), "https://gnunet.org/configuration-hostlist", &load_option_list, &save_option_list, "hostlist", NULL, NULL, hide_hostlist_options}, { "GNUNET_setup_general_services_fs_checkbutton", "toggled", "arm", "DEFAULTSERVICES", gettext_noop ("Should file-sharing be started automatically on startup?"), "https://gnunet.org/configuration-fs", &load_option_list, &save_option_list, "fs", NULL, NULL, hide_fs_tab}, { "GNUNET_setup_hostlist_client_enable_checkbutton", "toggled", "hostlist", "OPTIONS", gettext_noop ("Should GNUnet learn about other peers using hostlists"), "https://gnunet.org/configuration-hostlist", &load_option_list, &save_option_list, "-b", NULL, NULL, NULL}, { "GNUNET_setup_hostlist_client_learn_checkbutton", "toggled", "hostlist", "OPTIONS", gettext_noop ("Should GNUnet learn hostlists from other peers"), "https://gnunet.org/configuration-hostlist", &load_option_list, &save_option_list, "-e", NULL, NULL, NULL}, { "GNUNET_setup_hostlist_offer_hostlist_checkbutton", "toggled", "hostlist", "OPTIONS", gettext_noop ("Should this peer offer a hostlist to other peers"), "https://gnunet.org/configuration-hostlist-server", &load_option_list, &save_option_list, "-p", &highlight_port_collisions, NULL, hide_hostlist_server_options}, { "GNUNET_setup_hostlist_advertise_checkbutton", "toggled", "hostlist", "OPTIONS", gettext_noop ("Should this peer advertise its hostlist to other peers"), "https://gnunet.org/configuration-hostlist-server", &load_option_list, &save_option_list, "-a", NULL, NULL, NULL}, { "GNUNET_setup_hostlist_server_port_spin_button", "value-changed", "hostlist", "HTTPPORT", gettext_noop ("Port this peers hostlist should be offered on"), "https://gnunet.org/configuration-hostlist-server", &load_number, &save_number, NULL, &highlight_port_collisions, NULL, NULL}, { "GNUNET_setup_hostlist_url_liststore", "row-changed", "hostlist", "SERVERS", NULL, NULL, &load_string_list_store, &save_string_list_store, NULL, NULL, NULL, NULL}, { "GNUNET_setup_hostlist_url_liststore", "row-deleted", "hostlist", "SERVERS", NULL, NULL, NULL, &save_string_list_store, NULL, NULL, NULL, NULL}, { "GNUNET_setup_hostlist_url_treeview", NULL, NULL, NULL, /* FIXME */ gettext_noop ("Known hostlist URLs"), "https://gnunet.org/configuration-hostlist", NULL, NULL, NULL, /* FIXME */ NULL, NULL, NULL}, { "GNUNET_setup_bandwidth_out_spinbutton", "value-changed", "ats", "WAN_QUOTA_OUT", gettext_noop ("How many bytes per second are we allowed to transmit?"), "https://gnunet.org/configuration-bandwidth", &load_number, &save_number, NULL, NULL, NULL, NULL}, { "GNUNET_setup_bandwidth_in_spinbutton", "value-changed", "ats", "WAN_QUOTA_IN", gettext_noop ("How many bytes per second are we allowed to receive?"), "https://gnunet.org/configuration-bandwidth", &load_number, &save_number, NULL, NULL, NULL, NULL}, /* Transport TAB */ { "GNUNET_setup_transport_tcp_checkbutton", "toggled", "transport", "PLUGINS", gettext_noop ("Enable communication via TCP"), "https://gnunet.org/configuration-tcp", &load_option_list, &save_option_list, "tcp", &highlight_port_collisions, NULL, hide_tcp_tab}, { "GNUNET_setup_transport_udp_checkbutton", "toggled", "transport", "PLUGINS", gettext_noop ("Enable communication via UDP"), "https://gnunet.org/configuration-udp", &load_option_list, &save_option_list, "udp", NULL, NULL, hide_udp_tab}, { "GNUNET_setup_transport_http_checkbutton", "toggled", "transport", "PLUGINS", gettext_noop ("Enable communication via HTTP"), "https://gnunet.org/configuration-http", &load_option_list, &save_option_list, "http", &highlight_port_collisions, NULL, hide_http_tab}, { "GNUNET_setup_transport_https_checkbutton", "toggled", "transport", "PLUGINS", gettext_noop ("Enable communication via HTTPS"), "https://gnunet.org/configuration-https", &load_option_list, &save_option_list, "https", &highlight_port_collisions, NULL, hide_https_tab}, { "GNUNET_setup_transport_dv_checkbutton", "toggled", "transport", "PLUGINS", gettext_noop ("Enable communication via DV"), "https://gnunet.org/configuration-dv", &load_option_list, &save_option_list, "dv", NULL, NULL, hide_dv_tab}, { "GNUNET_setup_transport_wlan_checkbutton", "toggled", "transport", "PLUGINS", gettext_noop ("Enable communication via WLAN"), "https://gnunet.org/configuration-wlan", &load_option_list, &save_option_list, "wlan", NULL, NULL, hide_wlan_tab}, { "GNUNET_setup_transport_tcp_port_spinbutton", "value-changed", "transport-tcp", "PORT", gettext_noop ("Port we bind to for TCP"), "https://gnunet.org/configuration-tcp", &load_number, &save_number, NULL, &highlight_port_collisions, NULL, hide_all_tcp_options}, { "GNUNET_setup_transport_tcp_adv_port_spinbutton", "value-changed", "transport-tcp", "ADVERTISED_PORT", gettext_noop ("Port visible to other peers"), "https://gnunet.org/configuration-tcp", &load_number, &save_number, NULL, NULL, NULL, NULL}, { "GNUNET_setup_transport_nat_checkbutton", "toggled", "nat", "BEHIND_NAT", gettext_noop ("Check if this peer is behind a NAT"), "https://gnunet.org/configuration-nat", &load_yes_no, &save_yes_no, NULL, NULL, NULL, toggle_nat_options}, { "GNUNET_setup_transport_hole_punched_checkbutton", "toggled", "nat", "PUNCHED_NAT", gettext_noop ("Check if the NAT has been configured manually to forward ports"), "https://gnunet.org/configuration-nat", &load_yes_no, &save_yes_no, NULL, NULL, NULL, toggle_nat_punched_options}, { "GNUNET_setup_transport_upnp_enable_checkbutton", "toggled", "nat", "ENABLE_UPNP", gettext_noop ("Enable NAT traversal with UPnP/PMP"), "https://gnunet.org/configuration-nat", &load_yes_no, &save_yes_no, NULL, NULL, NULL, NULL, }, { "GNUNET_setup_transport_icmp_server_enable_checkbutton", "toggled", "nat", "ENABLE_ICMP_SERVER", gettext_noop ("Enable NAT traversal with ICMP as server"), "https://gnunet.org/configuration-nat", &load_yes_no, &save_yes_no, NULL, NULL, NULL, NULL, }, { "GNUNET_setup_transport_external_ip_address_entry", "changed", "nat", "EXTERNAL_ADDRESS", gettext_noop ("External (public) IP address of the NAT"), "https://gnunet.org/configuration-nat", &load_text, &save_text, NULL, NULL, NULL, NULL}, { "GNUNET_setup_transport_icmp_client_enable_checkbutton", "toggled", "nat", "ENABLE_ICMP_CLIENT", gettext_noop ("Enable NAT traversal with ICMP as client"), "https://gnunet.org/configuration-nat", &load_yes_no, &save_yes_no, NULL, NULL, NULL, toggle_internal_ip}, { "GNUNET_setup_transport_internal_ip_entry", "changed", "nat", "INTERNAL_ADDRESS", gettext_noop ("Internal (private) IP address of the NAT"), "https://gnunet.org/configuration-nat", &load_text, &save_text, NULL, NULL, NULL, NULL}, { "GNUNET_setup_transport_disable_ipv6_checkbutton", "toggled", "nat", "DISABLEV6", gettext_noop ("Disable IPv6 support"), "https://gnunet.org/configuration-ipv6", &load_yes_no, &save_yes_no, NULL, NULL, NULL, NULL, }, { "GNUNET_setup_transport_udp_port_spinbutton", "value-changed", "transport-udp", "PORT", gettext_noop ("Port for inbound UDP packets, use 0 if behind NAT"), "https://gnunet.org/configuration-udp", &load_number, &save_number, NULL, NULL, NULL, NULL}, { "GNUNET_setup_transport_http_port_spinbutton", "value-changed", "transport-http", "PORT", gettext_noop ("Port for inbound HTTP connections, use 0 if behind NAT"), "https://gnunet.org/configuration-http", &load_number, &save_number, NULL, &highlight_port_collisions, NULL, NULL}, { "GNUNET_setup_transport_https_port_spinbutton", "value-changed", "transport-https", "PORT", gettext_noop ("Port for inbound HTTPS connections, use 0 if behind NAT"), "https://gnunet.org/configuration-https", &load_number, &save_number, NULL, &highlight_port_collisions, NULL, NULL}, /* FS TAB */ { "GNUNET_setup_fs_datastore_sqlite_radiobutton", "toggled", "datastore", "DATABASE", gettext_noop ("Use sqLite to store file-sharing content"), "https://gnunet.org/configuration-datastore", &load_option_list /* abuse! */ , &save_option_list /* abuse! */ , "sqlite", NULL, NULL, hide_sqlite_datastore_tab}, { "GNUNET_setup_fs_datastore_mysql_radiobutton", "toggled", "datastore", "DATABASE", gettext_noop ("Use MySQL to store file-sharing content"), "https://gnunet.org/configuration-datastore", &load_option_list /* abuse! */ , &save_option_list /* abuse! */ , "mysql", NULL, NULL, hide_mysql_datastore_tab}, { "GNUNET_setup_fs_datastore_postgres_radiobutton", "toggled", "datastore", "DATABASE", gettext_noop ("Use Postgres to store file-sharing content"), "https://gnunet.org/configuration-datastore", &load_option_list /* abuse! */ , &save_option_list /* abuse! */ , "postgres", NULL, NULL, hide_postgres_datastore_tab}, { "GNUNET_setup_datastore_mysql_database_name_entry", "changed", "datastore-mysql", "DATABASE", gettext_noop ("Name for the MySQL database"), "https://gnunet.org/configuration-datastore", &load_text, &save_text, NULL, NULL, NULL, NULL}, { "GNUNET_setup_datastore_mysql_config_file_filechooserbutton", "selection-changed", "datastore-mysql", "CONFIG", gettext_noop ("Configuration file for MySQL access"), "http://dev.mysql.com/doc/refman/5.5/en/option-files.html", &load_filename, &save_filename, NULL, NULL, NULL, NULL}, { "GNUNET_setup_datastore_mysql_username_entry", "changed", "datastore-mysql", "USER", gettext_noop ("Username for MySQL access"), "https://gnunet.org/configuration-datastore", &load_text, &save_text, NULL, NULL, NULL, NULL}, { "GNUNET_setup_datastore_mysql_password_entry", "changed", "datastore-mysql", "PASSWORD", gettext_noop ("Password for MySQL access"), "https://gnunet.org/configuration-datastore", &load_text, &save_text, NULL, NULL, NULL, NULL}, { "GNUNET_setup_datastore_mysql_hostname_entry", "changed", "datastore-mysql", "HOST", gettext_noop ("Name of host running MySQL database"), "https://gnunet.org/configuration-datastore", &load_text, &save_text, NULL, NULL, NULL, NULL}, { "GNUNET_setup_datastore_mysql_port_spinbutton", "value-changed", "datastore-mysql", "PORT", gettext_noop ("Port of MySQL database"), "https://gnunet.org/configuration-datastore", &load_number, &save_number, NULL, NULL, NULL, NULL}, { "GNUNET_setup_datastore_postgres_config_entry", "changed", "datastore-postgres", "CONFIG", gettext_noop ("Configuration for Postgres (passed to PQconnectdb)"), "http://www.postgresql.org/docs/8.1/static/libpq.html#LIBPQ-CONNECT", &load_text, &save_text, NULL, NULL, NULL, NULL}, { "GNUNET_setup_fs_migration_from_checkbutton", "toggled", "fs", "CONTENT_PUSHING", gettext_noop ("Should we try to push our content to other peers?"), "https://gnunet.org/configuration-fs", &load_yes_no, &save_yes_no, NULL, NULL, NULL, NULL}, { "GNUNET_setup_fs_migration_to_checkbutton", "toggled", "fs", "CONTENT_CACHING", gettext_noop ("Are we allowed to cache content received from other peers?"), "https://gnunet.org/configuration-fs", &load_yes_no, &save_yes_no, NULL, NULL, NULL, NULL}, { "GNUNET_setup_fs_datacache_sqlite_radiobutton", "toggled", "dhtcache", "DATABASE", gettext_noop ("Use sqLite to cache DHT data"), "https://gnunet.org/configuration-datacache", &load_option_list /* abuse! */ , &save_option_list /* abuse! */ , "sqlite", NULL, NULL, hide_sqlite_datacache_tab}, { "GNUNET_setup_fs_datacache_mysql_radiobutton", "toggled", "dhtcache", "DATABASE", gettext_noop ("Use MySQL to cache DHT data"), "https://gnunet.org/configuration-datacache", &load_option_list /* abuse! */ , &save_option_list /* abuse! */ , "mysql", NULL, NULL, hide_mysql_datacache_tab}, { "GNUNET_setup_fs_datacache_postgres_radiobutton", "toggled", "dhtcache", "DATABASE", gettext_noop ("Use Postgres to cache DHT data"), "https://gnunet.org/configuration-datacache", &load_option_list /* abuse! */ , &save_option_list /* abuse! */ , "postgres", NULL, NULL, hide_postgres_datacache_tab}, { "GNUNET_setup_datacache_mysql_database_name_entry", "changed", "datacache-mysql", "DATABASE", gettext_noop ("Name for the MySQL database"), "https://gnunet.org/configuration-datacache", &load_text, &save_text, NULL, NULL, NULL, NULL}, { "GNUNET_setup_datacache_mysql_config_file_filechooserbutton", "selection-changed", "datacache-mysql", "CONFIG", gettext_noop ("Configuration file for MySQL access"), "http://dev.mysql.com/doc/refman/5.5/en/option-files.html", &load_filename, &save_filename, NULL, NULL, NULL, NULL}, { "GNUNET_setup_datacache_mysql_username_entry", "changed", "datacache-mysql", "USER", gettext_noop ("Username for MySQL access"), "https://gnunet.org/configuration-datacache", &load_text, &save_text, NULL, NULL, NULL, NULL}, { "GNUNET_setup_datacache_mysql_password_entry", "changed", "datacache-mysql", "PASSWORD", gettext_noop ("Password for MySQL access"), "https://gnunet.org/configuration-datacache", &load_text, &save_text, NULL, NULL, NULL, NULL}, { "GNUNET_setup_datacache_mysql_hostname_entry", "changed", "datacache-mysql", "HOST", gettext_noop ("Name of host running MySQL database"), "https://gnunet.org/configuration-datacache", &load_text, &save_text, NULL, NULL, NULL, NULL}, { "GNUNET_setup_transport_wlan_interface_entry", "changed", "transport-wlan", "INTERFACE", gettext_noop ("Name of monitoring interface to use (monX)"), "https://gnunet.org/configuration-wlan", &load_text, &save_text, NULL, NULL, NULL, NULL}, { "GNUNET_setup_datacache_mysql_port_spinbutton", "value-changed", "datacache-mysql", "PORT", gettext_noop ("Port of MySQL database"), "https://gnunet.org/configuration-datacache", &load_number, &save_number, NULL, NULL, NULL, NULL}, { "GNUNET_setup_datacache_postgres_config_entry", "changed", "datacache-postgres", "CONFIG", gettext_noop ("Configuration for Postgres (passed to PQconnectdb)"), "http://www.postgresql.org/docs/8.1/static/libpq.html#LIBPQ-CONNECT", &load_text, &save_text, NULL, NULL, NULL, NULL}, /* VPN/PT service */ { "GNUNET_setup_general_services_pt_checkbutton", "toggled", "arm", "DEFAULTSERVICES", gettext_noop ("Should the VPN/PT be started automatically on startup?"), "https://gnunet.org/configuration-vpn", &load_option_list, &save_option_list, "pt", NULL, NULL, hide_vpn_tab}, { "GNUNET_setup_pt_ipv4_checkbutton", "toggled", "pt", "TUNNEL_IPV4", gettext_noop ("Tunnel IPv4 traffic over GNUnet"), "https://gnunet.org/configuration-vpn", &load_yes_no, &save_yes_no, NULL, NULL, NULL, NULL }, { "GNUNET_setup_pt_ipv6_checkbutton", "toggled", "pt", "TUNNEL_IPV6", gettext_noop ("Tunnel IPv6 traffic over GNUnet"), "https://gnunet.org/configuration-vpn", &load_yes_no, &save_yes_no, NULL, NULL, NULL, NULL }, { "GNUNET_setup_pt_dns_checkbutton", "toggled", "pt", "TUNNEL_DNS", gettext_noop ("Tunnel DNS traffic over GNUnet"), "https://gnunet.org/configuration-vpn", &load_yes_no, &save_yes_no, NULL, NULL, NULL, NULL }, { "GNUNET_setup_vpn_interface_entry", "changed", "vpn", "IFNAME", gettext_noop ("Name of the virtual interface the GNUnet VPN should create"), "https://gnunet.org/configuration-vpn", &load_text, &save_text, NULL, NULL, NULL, NULL}, { "GNUNET_setup_vpn_interface_v4_ip_entry", "changed", "vpn", "IPV4ADDR", gettext_noop ("IPv4 address to use for the VPN interface"), "https://gnunet.org/configuration-vpn", &load_text, &save_text, NULL, NULL, NULL, NULL}, { "GNUNET_setup_vpn_interface_v4_mask_entry", "changed", "vpn", "IPV4MASK", gettext_noop ("IPv4 network mask to use for the VPN interface"), "https://gnunet.org/configuration-vpn", &load_text, &save_text, NULL, NULL, NULL, NULL}, { "GNUNET_setup_vpn_interface_v6_ip_entry", "changed", "vpn", "IPV6ADDR", gettext_noop ("IPv6 address to use for the VPN interface"), "https://gnunet.org/configuration-vpn", &load_text, &save_text, NULL, NULL, NULL, NULL}, { "GNUNET_setup_vpn_interface_v6_mask_spinbutton", "value-changed", "vpn", "IPV6MASK", gettext_noop ("IPv6 network prefix length to use for the VPN interface"), "https://gnunet.org/configuration-vpn", &load_number, &save_number, NULL, NULL, NULL, NULL}, /* exit daemon */ { "GNUNET_setup_general_services_exit_checkbutton", "toggled", "arm", "DEFAULTSERVICES", gettext_noop ("Activate the VPN exit to provide services and/or to enable others to use your Internet connection"), "https://gnunet.org/configuration-exit", &load_option_list, &save_option_list, "exit", NULL, NULL, hide_exit_options}, { "GNUNET_setup_dns_resolver_ip_entry", "changed", "dns", "DNS_EXIT", gettext_noop ("IP address of the external DNS resolver to use (values from your resolve.conf are usually appropriate))"), "https://gnunet.org/configuration-exit", &load_text, &save_text, NULL, NULL, NULL, NULL}, { "GNUNET_setup_dns_enable_exit_checkbutton", "toggled", "dns", "PROVIDE_EXIT", gettext_noop ("Allow other peers to perform DNS resolutions using your Internet connection"), "https://gnunet.org/configuration-dns", &load_yes_no, &save_yes_no, NULL, NULL, NULL, NULL}, { "GNUNET_setup_exit_interface_name_entry", "changed", "exit", "IFNAME", gettext_noop ("Name of the virtual interface the GNUnet exit service should create for traffic exiting the VPN to the Internet"), "https://gnunet.org/configuration-exit", &load_text, &save_text, NULL, NULL, NULL, NULL}, { "GNUNET_setup_exit_interface_v4_ip_entry", "changed", "exit", "IPV4ADDR", gettext_noop ("IPv4 address to use for the Exit interface"), "https://gnunet.org/configuration-exit", &load_text, &save_text, NULL, NULL, NULL, NULL}, { "GNUNET_setup_exit_interface_v4_mask_entry", "changed", "exit", "IPV4MASK", gettext_noop ("IPv4 network mask to use for the Exit interface"), "https://gnunet.org/configuration-exit", &load_text, &save_text, NULL, NULL, NULL, NULL}, { "GNUNET_setup_exit_interface_v6_ip_entry", "changed", "exit", "IPV6ADDR", gettext_noop ("IPv6 address to use for the Exit interface"), "https://gnunet.org/configuration-exit", &load_text, &save_text, NULL, NULL, NULL, NULL}, { "GNUNET_setup_exit_interface_v6_mask_spinbutton", "value-changed", "exit", "IPV6MASK", gettext_noop ("IPv6 network prefix length to use for the Exit interface"), "https://gnunet.org/configuration-exit", &load_number, &save_number, NULL, NULL, NULL, NULL}, { "GNUNET_setup_exit_enable_ipv4_exit_checkbutton", "toggled", "exit", "EXIT_IPV4", gettext_noop ("Allow other users to use your Internet connection for UDP traffic (via the Exit interface)"), "https://gnunet.org/configuration-exit", &load_yes_no, &save_yes_no, NULL, NULL, NULL, NULL}, { "GNUNET_setup_exit_enable_ipv6_exit_checkbutton", "toggled", "exit", "EXIT_IPV6", gettext_noop ("Allow other users to use your Internet connection for TCP traffic (via the Exit interface)"), "https://gnunet.org/configuration-exit", &load_yes_no, &save_yes_no, NULL, NULL, NULL, NULL}, /* GNS treeview */ { "GNUNET_setup_general_services_gns_checkbutton", "toggled", "arm", "DEFAULTSERVICES", gettext_noop ("Should the GNS be started automatically on startup?"), "https://gnunet.org/configuration-gns", &load_option_list, &save_option_list, "gns", NULL, NULL, hide_gns_tab}, { "GNUNET_setup_gns_treeview", NULL, NULL, NULL, gettext_noop ("Specification of .gnunet TLD"), "https://gnunet.org/configuration-dns", &load_vpn_dns_configuration, NULL, NULL, NULL, NULL, NULL}, { "GNUNET_setup_gns_name_cellrenderertext", "editing-started", NULL, NULL, NULL, "https://gnunet.org/configuration-dns", NULL, &gns_name_install_edited_handler, NULL, NULL, NULL, NULL}, { "GNUNET_setup_gns_type_cellrenderertext", "editing-started", NULL, NULL, NULL, "https://gnunet.org/configuration-dns", NULL, &gns_type_install_edited_handler, NULL, NULL, NULL, NULL}, { "GNUNET_setup_gns_ttl_cellrenderertext", "editing-started", NULL, NULL, NULL, "https://gnunet.org/configuration-dns", NULL, &gns_ttl_install_edited_handler, NULL, NULL, NULL, NULL}, { "GNUNET_setup_gns_value_cellrenderertext", "editing-started", NULL, NULL, NULL, "https://gnunet.org/configuration-dns", NULL, &gns_value_install_edited_handler, NULL, NULL, NULL, NULL}, /* END of list */ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL} }; /* end of gnunet-setup-options.c */