/* This file is part of GNUnet. (C) 2010, 2011 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-options.h" #include #include /** * Regular expression for YES */ #define REX_YES "^YES$" /** * Regular expression for NO */ #define REX_NO "^NO$" /** * 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; } /** * 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) || (event->keyval != GDK_Delete) ) 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, 1, &editable, -1); if (TRUE == editable) return FALSE; /* likely currently editing... */ gtk_list_store_remove (ls, &iter); 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); w = strtok (t, " "); while (w != NULL) { gtk_list_store_insert_with_values (ls, &iter, G_MAXINT, 0, w, 1, FALSE, -1); w = strtok (NULL, " "); } GNUNET_free (t); gtk_list_store_insert_with_values (ls, &iter, G_MAXINT, 0, "", 1, 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, 0, &val, -1); 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, 0, "", 1, (guint) 80, 2, (guint) 8080, 3, "localhost", 4, "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, 0, sld, 1, (guint) local_port, 2, (guint) host_port, 3, hostname, 4, (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, 0, &hostname, 1, &srcport, 2, &targetport, 3, &targethost, 4, &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); 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 ("vpn_dns_config_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, 0, &old, -1); if ( (0 != strlen (old)) && (0 == strlen (new_text)) ) { /* deletion */ gtk_list_store_remove (ls, &iter); g_free (old); return; } /* update model */ gtk_list_store_set (ls, &iter, 0, 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 vpn_dns_service_dnsname_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 ("vpn_dns_config_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, 4, 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 vpn_dns_service_tcpudp_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 ("vpn_dns_config_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, 1, (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 vpn_dns_service_sourceport_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 ("vpn_dns_config_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, 3, 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 vpn_dns_service_targethostname_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; } /** * 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_targetport (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 ("vpn_dns_config_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, 2, (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 vpn_dns_service_targetport_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_targetport), 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_vpn_exit_frame", "(^| )exit($| )", NULL }, { "GNUNET_setup_vpn_service_configuration_frame", "(^| )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", "(^| )vpn($| )", 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_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, 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 }, { "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 }, { "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 }, { "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", 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", hide_fs_tab }, { "GNUNET_setup_general_services_vpn_checkbutton", "toggled", "arm", "DEFAULTSERVICES", gettext_noop ("Should the VPN be started automatically on startup?"), "https://gnunet.org/configuration-vpn", &load_option_list, &save_option_list, "vpn", hide_vpn_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 }, { "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 }, { "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", 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 }, { "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, NULL }, { "GNUNET_setup_hostlist_url_liststore", "row-changed", "hostlist", "SERVERS", NULL, NULL, &load_string_list_store, &save_string_list_store, 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 }, { "GNUNET_setup_bandwidth_out_spinbutton", "value-changed", "core", "TOTAL_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 }, { "GNUNET_setup_bandwidth_in_spinbutton", "value-changed", "core", "TOTAL_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 }, /* 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", 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", 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", 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", 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", 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", 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, 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 }, { "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, toggle_nat_options }, { "GNUNET_setup_transport_hole_punched_checkbutton", "toggled", "nat", "PUNCHED_NAT", gettext_noop ("Check if the NAT has been hole-punched manually"), "https://gnunet.org/configuration-nat", &load_yes_no, &save_yes_no, 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, }, { "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, }, { "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 }, { "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, 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 }, { "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, }, { "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 }, { "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, 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, 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", 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", 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", 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 }, { "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 }, { "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 }, { "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 }, { "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 }, { "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 }, { "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 }, { "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 }, { "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 }, { "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", 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", 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", 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 }, { "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 }, { "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 }, { "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 }, { "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 }, { "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 }, { "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 }, { "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 }, { "GNUNET_setup_vpn_master_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 }, { "GNUNET_setup_vpn_master_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 }, { "GNUNET_setup_vpn_master_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 }, { "GNUNET_setup_vpn_master_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 }, { "GNUNET_setup_vpn_master_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 }, { "GNUNET_setup_vpn_master_vdns_server_entry", "changed", "vpn", "VIRTDNS", gettext_noop ("IP address of the virtual DNS server that resolves through GNUnet (use in resolve.conf if you want to resolve through some GNUnet DNS Exit)"), "https://gnunet.org/configuration-vpn", &load_text, &save_text, NULL, NULL }, { "GNUNET_setup_vpn_enable_vpn_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", hide_exit_options }, { "GNUNET_setup_vpn_enable_dns_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 }, { "GNUNET_setup_vpn_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 }, { "GNUNET_setup_vpn_exit_interface_v4_ip_entry", "changed", "exit", "IPV4ADDR", gettext_noop ("IPv4 address to use for the VPN Exit interface"), "https://gnunet.org/configuration-exit", &load_text, &save_text, NULL, NULL }, { "GNUNET_setup_vpn_exit_interface_v4_mask_entry", "changed", "exit", "IPV4MASK", gettext_noop ("IPv4 network mask to use for the VPN Exit interface"), "https://gnunet.org/configuration-exit", &load_text, &save_text, NULL, NULL }, { "GNUNET_setup_vpn_exit_interface_v6_ip_entry", "changed", "exit", "IPV6ADDR", gettext_noop ("IPv6 address to use for the VPN Exit interface"), "https://gnunet.org/configuration-exit", &load_text, &save_text, NULL, NULL }, { "GNUNET_setup_vpn_exit_interface_v6_mask_spinbutton", "value-changed", "exit", "IPV6MASK", gettext_noop ("IPv6 network prefix length to use for the VPN Exit interface"), "https://gnunet.org/configuration-exit", &load_number, &save_number, NULL, NULL }, { "GNUNET_setup_vpn_exit_enable_udp_checkbutton", "toggled", "exit", "ENABLE_UDP", 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 }, { "GNUNET_setup_vpn_exit_enable_tcp_checkbutton", "toggled", "exit", "ENABLE_TCP", 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 }, /* DNS treeview */ { "GNUNET_setup_vpn_dns_service_treeview", NULL, NULL, NULL, gettext_noop ("Specification of .gnunet hostnames and services offered by this peer"), "https://gnunet.org/configuration-dns", &load_vpn_dns_configuration, NULL, NULL, NULL }, { "GNUNET_setup_vpn_dns_service_dnsname_cellrenderertext", "editing-started", NULL, NULL, NULL, "https://gnunet.org/configuration-dns", NULL, &vpn_dns_service_dnsname_install_edited_handler, NULL, NULL }, { "GNUNET_setup_vpn_dns_service_tcpudp_cellrenderertext", "editing-started", NULL, NULL, NULL, "https://gnunet.org/configuration-dns", NULL, &vpn_dns_service_tcpudp_install_edited_handler, NULL, NULL }, { "GNUNET_setup_vpn_dns_service_sourceport_cellrenderertext", "editing-started", NULL, NULL, NULL, "https://gnunet.org/configuration-dns", NULL, &vpn_dns_service_sourceport_install_edited_handler, NULL, NULL }, { "GNUNET_setup_vpn_dns_service_targethostname_cellrenderertext", "editing-started", NULL, NULL, NULL, "https://gnunet.org/configuration-dns", NULL, &vpn_dns_service_targethostname_install_edited_handler, NULL, NULL }, { "GNUNET_setup_vpn_dns_service_targetport_cellrenderertext", "editing-started", NULL, NULL, NULL, "https://gnunet.org/configuration-dns", NULL, &vpn_dns_service_targetport_install_edited_handler, NULL, NULL }, /* END of list */ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } }; /* end of gnunet-setup-options.c */