"Fossies" - the Fresh Open Source Software Archive

Member "etherape-0.9.18/src/preferences.c" (3 Jun 2018, 11744 Bytes) of package /linux/privat/etherape-0.9.18.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "preferences.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 0.9.17_vs_0.9.18.

    1 /* EtherApe
    2  * Copyright (C) 2001 Juan Toledo, Riccardo Ghetta
    3  * 
    4  * This program is free software; you can redistribute it and/or modify
    5  * it under the terms of the GNU General Public License as published by
    6  * the Free Software Foundation; either version 2 of the License, or
    7  * (at your option) any later version.
    8  *
    9  * This program is distributed in the hope that it will be useful,
   10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12  * GNU General Public License for more details.
   13  *
   14  * You should have received a copy of the GNU General Public License
   15  * along with this program; if not, see <http://www.gnu.org/licenses/>.
   16  */
   17 
   18 #ifdef HAVE_CONFIG_H
   19 #include <config.h>
   20 #endif
   21 #include <gtk/gtk.h>
   22 #include "preferences.h"
   23 #include "math.h"
   24 #include "datastructs.h"
   25 #include "stats/node.h"
   26 
   27 struct pref_struct pref;
   28 GList *centered_node_speclist = NULL;
   29 static const gchar *pref_group = "Diagram";
   30 
   31 /* Separator character used in encoding string-vectors */
   32 #define STRVEC_SEP " "
   33 
   34 /***************************************************************
   35  *
   36  * internal helpers
   37  *
   38  ***************************************************************/
   39 
   40 static void read_string_config(gchar **item, GKeyFile *gkey, const char *key)
   41 {
   42   gchar *tmp;
   43   tmp = g_key_file_get_string(gkey, pref_group, key, NULL);
   44   if (!tmp)
   45     return;
   46 
   47   /* frees previous value and sets to new pointer */
   48   g_free(*item);
   49   *item = tmp;
   50 }
   51 
   52 static void read_strvec_config(gchar ***item, GKeyFile *gkey, const char *key)
   53 {
   54   gchar *tmp = NULL;
   55   read_string_config(&tmp, gkey, key);
   56   if (tmp)
   57     {
   58       g_strfreev(*item);
   59       *item = g_strsplit(tmp, STRVEC_SEP, 0);
   60       g_free(tmp);
   61     }
   62 }
   63 
   64 static void read_boolean_config(gboolean *item, GKeyFile *gkey, const char *key)
   65 {
   66   gboolean tmp;
   67   GError *err = NULL;
   68   tmp = g_key_file_get_boolean(gkey, pref_group, key, &err);
   69   if (err)
   70     return; /* key not found, exit */
   71   *item = tmp;
   72 }
   73 
   74 static void read_int_config(gint *item, GKeyFile *gkey, const char *key)
   75 {
   76   gint tmp;
   77   GError *err = NULL;
   78   tmp = g_key_file_get_integer(gkey, pref_group, key, &err);
   79   if (err)
   80     return; /* key not found, exit */
   81   *item = tmp;
   82 }
   83 
   84 static void read_double_config(gdouble *item, GKeyFile *gkey, const char *key)
   85 {
   86   gdouble tmp;
   87   GError *err = NULL;
   88   tmp = g_key_file_get_double(gkey, pref_group, key, &err);
   89   if (err)
   90     return; /* key not found, exit */
   91   *item = tmp;
   92 }
   93 
   94 static gchar *config_file_name(void)
   95 {
   96   return g_strdup_printf("%s/%s", g_get_user_config_dir(), "etherape");
   97 }
   98 static gchar *old_config_file_name(void)
   99 {
  100   return g_strdup_printf("%s/.gnome2/Etherape", g_get_home_dir());
  101 }
  102 
  103 typedef enum
  104 {
  105   PT_bool,
  106   PT_int,
  107   PT_double,
  108   PT_string,
  109   PT_strvec,
  110 } preftype_t;
  111 
  112 /* Describes a setting in the config file */
  113 struct preference
  114 {
  115   /* Label used in the config file */
  116   const char *name;
  117 
  118   /* where it sits within pref_struct */
  119   ptrdiff_t offset;
  120 
  121   /* What type of setting it is */
  122   preftype_t type;
  123 
  124   /* Default value for the setting */
  125   union
  126   {
  127     gboolean pv_bool;
  128     gint pv_int;
  129     gdouble pv_double;
  130     gchar *pv_string;
  131     gchar **pv_strvec;
  132   } defval;
  133 };
  134 
  135 #define MKPREF(n, t, d) { \
  136     .name = #n, \
  137     .offset = offsetof(struct pref_struct, n), \
  138     .type = PT_##t, \
  139     .defval.pv_##t = d, \
  140   }
  141 
  142 static const struct preference preferences[] = {
  143   MKPREF(name_res, bool, TRUE),
  144   MKPREF(diagram_only, bool, FALSE),
  145   MKPREF(group_unk, bool, TRUE),
  146   MKPREF(centered_nodes, string, ""),
  147 
  148   MKPREF(text_color, string, "#ffff00"),
  149   MKPREF(fontname, string, "Sans 8"),
  150   MKPREF(colors, strvec, ((char*[]){ "#ff0000;WWW,HTTP,HTTPS", "#0000ff;DOMAIN",
  151                                      "#00ff00", "#ffff00", "#ff00ff", 
  152                                      "#00ffff;ICMP,ICMPV6",
  153                                      "#ffffff", "#ff7700", "#ff0077", "#ffaa77",
  154                                      "#7777ff", "#aaaa33", NULL, })),
  155 
  156   MKPREF(bck_image_enabled, bool, TRUE),
  157   MKPREF(bck_image_path, string, ""),
  158 
  159   MKPREF(show_statusbar, bool, TRUE),
  160   MKPREF(show_toolbar, bool, TRUE),
  161   MKPREF(show_legend, bool, TRUE),
  162 
  163   MKPREF(inner_ring_scale, double, 0.5),
  164   MKPREF(node_radius_multiplier, double, 0.0005),
  165   MKPREF(link_node_ratio, double, 1.0),
  166   MKPREF(node_size_variable, int, INST_OUTBOUND),
  167   MKPREF(size_mode, int, LINEAR),
  168 
  169   MKPREF(node_timeout_time, double, 120000.0),
  170   MKPREF(gui_node_timeout_time, double, 60000.0),
  171   MKPREF(proto_node_timeout_time, double, 0),
  172 
  173   MKPREF(link_timeout_time, double, 20000.0),
  174   MKPREF(gui_link_timeout_time, double, 20000.0),
  175   MKPREF(proto_link_timeout_time, double, 600000.0),
  176 
  177   MKPREF(proto_timeout_time, double, 60000.0),
  178   MKPREF(refresh_period, int, 100),
  179   MKPREF(averaging_time, double, 2000.0),
  180 
  181   MKPREF(filter, string, "ip or ip6"),
  182   MKPREF(pcap_stats_pos, int, STATSPOS_NONE),
  183   MKPREF(stack_level, int, 0),
  184 };
  185 
  186 #define NUM_PREFS (sizeof(preferences) / sizeof(preferences[0]))
  187 
  188 /***************************************************************
  189  *
  190  * pref handling
  191  *
  192  ***************************************************************/
  193 static void default_config(struct pref_struct *p)
  194 {
  195   int i;
  196   void *addr;
  197   gchar *tmp;
  198 
  199   for (i = 0; i < NUM_PREFS; i++)
  200     {
  201       addr = (char *)p + preferences[i].offset;
  202       switch (preferences[i].type)
  203         {
  204         case PT_bool:
  205           *(gboolean *)addr = preferences[i].defval.pv_bool;
  206           break;
  207 
  208         case PT_int:
  209           *(gint *)addr = preferences[i].defval.pv_int;
  210           break;
  211 
  212         case PT_double:
  213           *(gdouble *)addr = preferences[i].defval.pv_double;
  214           break;
  215 
  216         case PT_string:
  217           *(gchar **)addr = g_strdup(preferences[i].defval.pv_string);
  218           break;
  219 
  220         case PT_strvec:
  221           /*
  222            * Slightly clunky join-and-re-split dance so that the initialized
  223            * result is a g_strfreev()-able string vector.
  224            */
  225           tmp = g_strjoinv(STRVEC_SEP, preferences[i].defval.pv_strvec);
  226           *(gchar ***)addr = g_strsplit(tmp, STRVEC_SEP, 0);
  227           g_free(tmp);
  228           break;
  229         }
  230     }
  231 }
  232 
  233 /* loads configuration from .gnome/Etherape */
  234 void load_config(struct pref_struct *p)
  235 {
  236   gchar *pref_file;
  237   GKeyFile *gkey;
  238   int i;
  239   void *addr;
  240 
  241   /* first set up defaults */
  242   default_config(p);
  243 
  244   gkey = g_key_file_new();
  245 
  246   /* tries to read config from file (~/.config/etherape) */
  247   pref_file = config_file_name();
  248   if (!g_key_file_load_from_file(gkey, pref_file, G_KEY_FILE_NONE, NULL))
  249     {
  250       /* file not found, try old location (~/.gnome2/Etherape) */
  251       g_free(pref_file);
  252       pref_file = old_config_file_name();
  253       if (!g_key_file_load_from_file(gkey, pref_file, G_KEY_FILE_NONE, NULL))
  254         {
  255           g_free(pref_file);
  256           return;
  257         }
  258     }
  259   g_free(pref_file);
  260 
  261   for (i = 0; i < NUM_PREFS; i++)
  262     {
  263       addr = (char *)p + preferences[i].offset;
  264       switch (preferences[i].type)
  265         {
  266         case PT_bool:
  267           read_boolean_config(addr, gkey, preferences[i].name);
  268           break;
  269 
  270         case PT_int:
  271           read_int_config(addr, gkey, preferences[i].name);
  272           break;
  273 
  274         case PT_double:
  275           read_double_config(addr, gkey, preferences[i].name);
  276           break;
  277 
  278         case PT_string:
  279           read_string_config(addr, gkey, preferences[i].name);
  280           break;
  281 
  282         case PT_strvec:
  283           read_strvec_config(addr, gkey, preferences[i].name);
  284           break;
  285         }
  286     }
  287 
  288   p->colors = protohash_compact(p->colors);
  289 
  290   g_key_file_free(gkey);
  291 }
  292 
  293 /* saves configuration to .gnome/Etherape */
  294 /* It's not static since it will be called from the GUI */
  295 void save_config(const struct pref_struct *p)
  296 {
  297   int i;
  298   gchar *pref_file;
  299   gchar *cfgdata;
  300   gchar *tmp;
  301   const gchar *name;
  302   gboolean res;
  303   GError *error = NULL;
  304   GKeyFile *gkey;
  305   void *addr;
  306 
  307   gkey = g_key_file_new();
  308 
  309   for (i = 0; i < NUM_PREFS; i++)
  310     {
  311       addr = (char *)p + preferences[i].offset;
  312       name = preferences[i].name;
  313       switch (preferences[i].type)
  314         {
  315         case PT_bool:
  316           g_key_file_set_boolean(gkey, pref_group, name, *(gboolean *)addr);
  317           break;
  318 
  319         case PT_int:
  320           g_key_file_set_integer(gkey, pref_group, name, *(gint *)addr);
  321           break;
  322 
  323         case PT_double:
  324           g_key_file_set_double(gkey, pref_group, name, *(gdouble *)addr);
  325           break;
  326 
  327         case PT_string:
  328           g_key_file_set_string(gkey, pref_group, name, *(gchar **)addr);
  329           break;
  330 
  331         case PT_strvec:
  332           tmp = g_strjoinv(STRVEC_SEP, *(gchar ***)addr);
  333           g_key_file_set_string(gkey, pref_group, preferences[i].name, tmp);
  334           g_free(tmp);
  335           break;
  336         }
  337     }
  338 
  339   g_key_file_set_string(gkey, "General", "version", VERSION);
  340 
  341   /* write config to file */
  342   cfgdata = g_key_file_to_data(gkey, NULL, NULL);
  343   pref_file = config_file_name();
  344   res = g_file_set_contents(pref_file, cfgdata, -1, &error);
  345   g_free(cfgdata);
  346 
  347   if (res)
  348     g_my_info(_("Preferences saved to %s"), pref_file);
  349   else
  350     {
  351       GtkWidget *dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_DESTROY_WITH_PARENT,
  352                                                  GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
  353                                                  _("Error saving preferences to '%s': %s"),
  354                                                  pref_file, error->message);
  355       gtk_dialog_run(GTK_DIALOG(dialog));
  356       gtk_widget_destroy(dialog);
  357     }
  358   g_free(pref_file);
  359   g_key_file_free(gkey);
  360 }
  361 
  362 /* releases all memory allocated for internal fields */
  363 void free_config(struct pref_struct *p)
  364 {
  365   int i;
  366   void *addr;
  367 
  368   for (i = 0; i < NUM_PREFS; i++)
  369     {
  370       addr = (char *)p + preferences[i].offset;
  371       switch (preferences[i].type)
  372         {
  373         case PT_string:
  374           g_free(*(gchar **)addr);
  375           *(gchar **)addr = NULL;
  376           break;
  377 
  378         case PT_strvec:
  379           g_strfreev(*(gchar ***)addr);
  380           *(gchar ***)addr = NULL;
  381           break;
  382 
  383         default:
  384           break;
  385         }
  386     }
  387 }
  388 
  389 /* copies a configuration from src to tgt */
  390 void copy_config(struct pref_struct *tgt, const struct pref_struct *src)
  391 {
  392   int i;
  393   void *src_addr;
  394   void *tgt_addr;
  395 
  396   for (i = 0; i < NUM_PREFS; i++)
  397     {
  398       src_addr = (char *)src + preferences[i].offset;
  399       tgt_addr = (char *)tgt + preferences[i].offset;
  400       switch (preferences[i].type)
  401         {
  402         case PT_bool:
  403           *(gboolean *)tgt_addr = *(gboolean *)src_addr;
  404           break;
  405 
  406         case PT_int:
  407           *(gint *)tgt_addr = *(gint *)src_addr;
  408           break;
  409 
  410         case PT_double:
  411           *(gdouble *)tgt_addr = *(gdouble *)src_addr;
  412           break;
  413 
  414         case PT_string:
  415           *(gchar **)tgt_addr = g_strdup(*(gchar **)src_addr);
  416           break;
  417 
  418         case PT_strvec:
  419           *(gchar ***)tgt_addr = g_strdupv(*(gchar ***)src_addr);
  420           break;
  421         }
  422     }
  423 }
  424 
  425 /*
  426  * Sometimes (when showing/hiding statusbar, toolbar, or legend, specifically)
  427  * we want to update the saved form of a single preference setting in-place
  428  * without updating any others (to avoid implicitly doing an unwanted 'save'
  429  * operation on unsaved preference changes).  This function thus loads the
  430  * saved preferences into a temporary pref_struct, performs a given
  431  * modification on it via the supplied 'edit' function (to which the arbitrary
  432  * pointer 'data' is also passed), and then saves it.
  433  */
  434 void mutate_saved_config(config_edit_fn edit, void *data)
  435 {
  436   struct pref_struct tmp_prefs;
  437 
  438   load_config(&tmp_prefs);
  439 
  440   edit(&tmp_prefs, data);
  441 
  442   save_config(&tmp_prefs);
  443 
  444   free_config(&tmp_prefs);
  445 }