steam-ihs: fix memleak on exception
[metze/wireshark/wip.git] / epan / prefs.c
index 1ecf050fe8a853aec49d007850f14aba2eb6d4b6..d732eb2046a1e84d30da60d08318ed8f57a012c1 100644 (file)
 #include "epan/wmem/wmem.h"
 #include <epan/stats_tree.h>
 
+/*
+ * Module alias.
+ */
+typedef struct pref_module_alias {
+    const char *name;           /**< name of module alias */
+    module_t *module;           /**< module for which it's an alias */
+} module_alias_t;
+
 /* Internal functions */
 static module_t *find_subtree(module_t *parent, const char *tilte);
 static module_t *prefs_register_module_or_subtree(module_t *parent,
     const char *name, const char *title, const char *description, gboolean is_subtree,
     void (*apply_cb)(void), gboolean use_gui);
 static void prefs_register_modules(void);
+static module_t *prefs_find_module_alias(const char *name);
 static prefs_set_pref_e set_pref(gchar*, const gchar*, void *, gboolean);
 static void free_col_info(GList *);
 static void pre_init_prefs(void);
@@ -80,22 +89,6 @@ static int mgcp_udp_port_count;
 
 e_prefs prefs;
 
-static const enum_val_t gui_ptree_line_style[] = {
-    {"NONE", "NONE", 0},
-    {"SOLID", "SOLID", 1},
-    {"DOTTED", "DOTTED", 2},
-    {"TABBED", "TABBED", 3},
-    {NULL, NULL, -1}
-};
-
-static const enum_val_t gui_ptree_expander_style[] = {
-    {"NONE", "NONE", 0},
-    {"SQUARE", "SQUARE", 1},
-    {"TRIANGLE", "TRIANGLE", 2},
-    {"CIRCULAR", "CIRCULAR", 3},
-    {NULL, NULL, -1}
-};
-
 static const enum_val_t gui_console_open_type[] = {
     {"NEVER", "NEVER", console_open_never},
     {"AUTOMATIC", "AUTOMATIC", console_open_auto},
@@ -287,6 +280,11 @@ static wmem_tree_t *prefs_modules = NULL;
  */
 static wmem_tree_t *prefs_top_level_modules = NULL;
 
+/*
+ * List of aliases for modules.
+ */
+static wmem_tree_t *prefs_module_aliases = NULL;
+
 /** Sets up memory used by proto routines. Called at program startup */
 void
 prefs_init(void)
@@ -294,6 +292,7 @@ prefs_init(void)
     memset(&prefs, 0, sizeof(prefs));
     prefs_modules = wmem_tree_new(wmem_epan_scope());
     prefs_top_level_modules = wmem_tree_new(wmem_epan_scope());
+    prefs_module_aliases = wmem_tree_new(wmem_epan_scope());
 }
 
 /*
@@ -557,6 +556,50 @@ prefs_register_module_or_subtree(module_t *parent, const char *name,
     return module;
 }
 
+void
+prefs_register_module_alias(const char *name, module_t *module)
+{
+    module_alias_t *alias;
+    const char *p;
+    guchar c;
+
+    /*
+     * Yes.
+     * Make sure that only ASCII letters, numbers, underscores, hyphens,
+     * and dots appear in the name.  We allow upper-case letters, to
+     * handle the Diameter dissector having used "Diameter" rather
+     * than "diameter" as its preference module name in the past.
+     *
+     * Crash if there is, as that's an error in the code, but the name
+     * can be used on the command line, and shouldn't require quoting,
+     * etc.
+     */
+    for (p = name; (c = *p) != '\0'; p++) {
+        if (!(g_ascii_isalpha(c) || g_ascii_isdigit(c) || c == '_' ||
+              c == '-' || c == '.'))
+            g_error("Preference module alias \"%s\" contains invalid characters", name);
+    }
+
+    /*
+     * Make sure there's not already an alias with that
+     * name.  Crash if there is, as that's an error in the
+     * code, and the code has to be fixed not to register
+     * more than one alias with the same name.
+     *
+     * We search the list of all aliases.
+     */
+    g_assert(prefs_find_module_alias(name) == NULL);
+
+    alias = wmem_new(wmem_epan_scope(), module_alias_t);
+    alias->name = name;
+    alias->module = module;
+
+    /*
+     * Insert this module in the list of all modules.
+     */
+    wmem_tree_insert_string(prefs_module_aliases, name, alias, WMEM_TREE_STRING_NOCASE);
+}
+
 /*
  * Register that a protocol has preferences.
  */
@@ -907,6 +950,17 @@ prefs_apply(module_t *module)
         call_apply_cb(NULL, module, NULL);
 }
 
+static module_t *
+prefs_find_module_alias(const char *name)
+{
+    module_alias_t *alias;
+
+    alias = (module_alias_t *)wmem_tree_lookup_string(prefs_module_aliases, name, WMEM_TREE_STRING_NOCASE);
+    if (alias == NULL)
+        return NULL;
+    return alias->module;
+}
+
 /*
  * Register a preference in a module's list of preferences.
  * If it has a title, give it an ordinal number; otherwise, it's a
@@ -2257,23 +2311,6 @@ prefs_pref_foreach(module_t *module, pref_cb callback, gpointer user_data)
     return 0;
 }
 
-static const enum_val_t print_format_vals[] = {
-    { "text",       "Plain Text", PR_FMT_TEXT },
-    { "postscript", "Postscript", PR_FMT_PS },
-    { NULL,         NULL,         0 }
-};
-
-static const enum_val_t print_dest_vals[] = {
-#ifdef _WIN32
-    /* "PR_DEST_CMD" means "to printer" on Windows */
-    { "command", "Printer", PR_DEST_CMD },
-#else
-    { "command", "Command", PR_DEST_CMD },
-#endif
-    { "file",    "File",    PR_DEST_FILE },
-    { NULL,      NULL,      0 }
-};
-
 static const enum_val_t st_sort_col_vals[] = {
     { "name",    "Node name (topic/item)", ST_SORT_COL_NAME },
     { "count",   "Item count", ST_SORT_COL_COUNT },
@@ -3017,35 +3054,23 @@ prefs_register_modules(void)
     prefs_register_obsolete_preference(gui_module, "packet_list_sel_browse");
     prefs_register_obsolete_preference(gui_module, "protocol_tree_sel_browse");
     prefs_register_obsolete_preference(gui_module, "tree_view_altern_colors");
-
-    prefs_register_bool_preference(gui_module, "expert_composite_eyecandy",
-                                   "Display Icons on Expert Composite Dialog Tabs",
-                                   "Display Icons on Expert Composite Dialog Tabs?",
-                                   &prefs.gui_expert_composite_eyecandy);
-
-    prefs_register_bool_preference(gui_module, "filter_toolbar_show_in_statusbar",
-                                   "Place filter toolbar inside the statusbar",
-                                   "Place filter toolbar inside the statusbar?",
-                                   &prefs.filter_toolbar_show_in_statusbar);
+    prefs_register_obsolete_preference(gui_module, "expert_composite_eyecandy");
+    prefs_register_obsolete_preference(gui_module, "filter_toolbar_show_in_statusbar");
 
     prefs_register_bool_preference(gui_module, "restore_filter_after_following_stream",
                                    "Restore current display filter after following a stream",
                                    "Restore current display filter after following a stream?",
                                    &prefs.restore_filter_after_following_stream);
 
-    prefs_register_enum_preference(gui_module, "protocol_tree_line_style",
-                       "Protocol-tree line style",
-                       "Protocol-tree line style",
-                       &prefs.gui_ptree_line_style, gui_ptree_line_style, FALSE);
+    prefs_register_obsolete_preference(gui_module, "protocol_tree_line_style");
 
-    prefs_register_enum_preference(gui_module, "protocol_tree_expander_style",
-                       "Protocol-tree expander style",
-                       "Protocol-tree expander style",
-                       &prefs.gui_ptree_expander_style, gui_ptree_expander_style, FALSE);
+    prefs_register_obsolete_preference(gui_module, "protocol_tree_expander_style");
 
     prefs_register_obsolete_preference(gui_module, "hex_dump_highlight_style");
 
     gui_column_module = prefs_register_subtree(gui_module, "Columns", "Columns", NULL);
+    /* For reading older preference files with "column." preferences */
+    prefs_register_module_alias("column", gui_column_module);
 
     custom_cbs.free_cb = free_string_like_preference;
     custom_cbs.reset_cb = reset_string_like_preference;
@@ -3239,14 +3264,8 @@ prefs_register_modules(void)
                        "Main Toolbar style",
                        &prefs.gui_toolbar_main_style, gui_toolbar_style, FALSE);
 
-    prefs_register_enum_preference(gui_module, "toolbar_filter_style",
-                       "Filter Toolbar style",
-                       "Filter Toolbar style",
-                       &prefs.gui_toolbar_filter_style, gui_toolbar_style, FALSE);
-
-    register_string_like_preference(gui_module, "webbrowser", "The path to the webbrowser",
-        "The path to the webbrowser (Ex: mozilla)",
-        &prefs.gui_webbrowser, PREF_STRING, NULL, TRUE);
+    prefs_register_obsolete_preference(gui_module, "toolbar_filter_style");
+    prefs_register_obsolete_preference(gui_module, "webbrowser");
 
     prefs_register_bool_preference(gui_module, "update.enabled",
                                    "Check for updates",
@@ -3462,6 +3481,9 @@ prefs_register_modules(void)
     prefs_register_bool_preference(capture_module, "real_time_update", "Update packet list in real time during capture",
         "Update packet list in real time during capture?", &prefs.capture_real_time);
 
+    prefs_register_bool_preference(capture_module, "no_interface_load", "Don't load interfaces on startup",
+        "Don't automatically load capture interfaces on startup", &prefs.capture_no_interface_load);
+
     prefs_register_bool_preference(capture_module, "no_extcap", "Disable external capture interfaces",
         "Disable external capture modules (extcap)", &prefs.capture_no_extcap);
 
@@ -3491,27 +3513,15 @@ prefs_register_modules(void)
     oid_pref_init(nameres_module);
     maxmind_db_pref_init(nameres_module);
 
-    /* Printing */
+    /* Printing
+     * None of these have any effect; we keep them as obsolete preferences
+     * in order to avoid errors when reading older preference files.
+     */
     printing = prefs_register_module(NULL, "print", "Printing",
-        "Printing", NULL, TRUE);
-
-    prefs_register_enum_preference(printing, "format",
-                                   "Format", "Can be one of \"text\" or \"postscript\"",
-                                   &prefs.pr_format, print_format_vals, TRUE);
-
-    prefs_register_enum_preference(printing, "destination",
-                                   "Print to", "Can be one of \"command\" or \"file\"",
-                                   &prefs.pr_dest, print_dest_vals, TRUE);
-
-#ifndef _WIN32
-    register_string_like_preference(printing, "command", "Command",
-        "Output gets piped to this command when the destination is set to \"command\"",
-        &prefs.pr_cmd, PREF_STRING, NULL, TRUE);
-#endif
-
-    register_string_like_preference(printing, "file", "File",
-        "This is the file that gets written to when the destination is set to \"file\"",
-        &prefs.pr_file, PREF_SAVE_FILENAME, NULL, TRUE);
+        "Printing", NULL, FALSE);
+    prefs_register_obsolete_preference(printing, "format");
+    prefs_register_obsolete_preference(printing, "command");
+    prefs_register_obsolete_preference(printing, "file");
 
     /* Codecs */
     codecs_module = prefs_register_module(NULL, "codecs", "Codecs",
@@ -3967,20 +3977,8 @@ pre_init_prefs(void)
         "Protocol", "%p", "Length",      "%L",
         "Info",     "%i"};
 
-    prefs.pr_format  = PR_FMT_TEXT;
-    prefs.pr_dest    = PR_DEST_CMD;
-    g_free(prefs.pr_file);
-    prefs.pr_file    = g_strdup("wireshark.out");
-    g_free(prefs.pr_cmd);
-    prefs.pr_cmd     = g_strdup("lpr");
-
-    prefs.gui_expert_composite_eyecandy = FALSE;
-    prefs.gui_ptree_line_style = 0;
-    prefs.gui_ptree_expander_style = 1;
-    prefs.filter_toolbar_show_in_statusbar = FALSE;
     prefs.restore_filter_after_following_stream = FALSE;
     prefs.gui_toolbar_main_style = TB_STYLE_ICONS;
-    prefs.gui_toolbar_filter_style = TB_STYLE_TEXT;
     /* We try to find the best font in the Qt code */
     g_free(prefs.gui_qt_font_name);
     prefs.gui_qt_font_name           = g_strdup("");
@@ -4066,8 +4064,6 @@ pre_init_prefs(void)
     prefs.gui_update_enabled         = TRUE;
     prefs.gui_update_channel         = UPDATE_CHANNEL_STABLE;
     prefs.gui_update_interval        = 60*60*24; /* Seconds */
-    g_free(prefs.gui_webbrowser);
-    prefs.gui_webbrowser             = g_strdup("");
     g_free(prefs.gui_window_title);
     prefs.gui_window_title           = g_strdup("");
     g_free(prefs.gui_prepend_window_title);
@@ -4476,26 +4472,25 @@ read_prefs_file(const char *pf_path, FILE *pf,
                             break;
 
                         case PREFS_SET_NO_SUCH_PREF:
-                            /*
-                             * If "print.command" silently ignore it because it's valid
-                             * on non-Win32 platforms.
-                             */
-                            if (strcmp(cur_var->str, "print.command") != 0)
-                                g_warning ("No such preference \"%s\" at line %d of\n%s %s",
-                                           cur_var->str, pline, pf_path, hint);
+                            g_warning ("No such preference \"%s\" at line %d of\n%s %s",
+                                       cur_var->str, pline, pf_path, hint);
                             prefs.unknown_prefs = TRUE;
                             break;
 
                         case PREFS_SET_OBSOLETE:
-                            if (strcmp(cur_var->str, "print.command") != 0)
-                                /* If an attempt is made to save the preferences, a popup warning will be
-                                   displayed stating that obsolete prefs have been detected and the user will
-                                   be given the opportunity to save these prefs under a different profile name.
-                                   The prefs in question need to be listed in the console window so that the
-                                   user can make an informed choice.
-                                */
-                                g_warning ("Obsolete preference \"%s\" at line %d of\n%s %s",
-                                           cur_var->str, pline, pf_path, hint);
+                            /*
+                             * If an attempt is made to save the
+                             * preferences, a popup warning will be
+                             * displayed stating that obsolete prefs
+                             * have been detected and the user will
+                             * be given the opportunity to save these
+                             * prefs under a different profile name.
+                             * The prefs in question need to be listed
+                             * in the console window so that the
+                             * user can make an informed choice.
+                             */
+                            g_warning ("Obsolete preference \"%s\" at line %d of\n%s %s",
+                                       cur_var->str, pline, pf_path, hint);
                             prefs.unknown_prefs = TRUE;
                             break;
                         }
@@ -4937,10 +4932,6 @@ string_to_name_resolve(const char *string, e_addr_resolve *name_resolve)
         case 't':
             name_resolve->transport_name = TRUE;
             break;
-        case 'C':
-            /* DEPRECATED */
-            /* name_resolve->concurrent_dns */
-            break;
         case 'd':
             name_resolve->dns_pkt_addr_resolution = TRUE;
             break;
@@ -5479,38 +5470,36 @@ set_pref(gchar *pref_name, const gchar *value, void *private_data _U_,
                  * its modern name, the Nortel Discovery Protocol (NDP).
                  */
                 if (module == NULL) {
-                    if (strcmp(pref_name, "column") == 0)
-                        module = gui_column_module;
-                    else if (strcmp(pref_name, "Diameter") == 0)
-                        module = prefs_find_module("diameter");
-                    else if (strcmp(pref_name, "bxxp") == 0)
-                        module = prefs_find_module("beep");
-                    else if (strcmp(pref_name, "gtpv0") == 0 ||
-                             strcmp(pref_name, "gtpv1") == 0)
-                        module = prefs_find_module("gtp");
-                    else if (strcmp(pref_name, "smpp-gsm-sms") == 0)
-                        module = prefs_find_module("gsm-sms-ud");
-                    else if (strcmp(pref_name, "dcp") == 0)
-                        module = prefs_find_module("dccp");
-                    else if (strcmp(pref_name, "x.25") == 0)
-                        module = prefs_find_module("x25");
-                    else if (strcmp(pref_name, "x411") == 0)
-                        module = prefs_find_module("p1");
-                    else if (strcmp(pref_name, "nsip") == 0)
-                        module = prefs_find_module("gprs-ns");
-                    else if (strcmp(pref_name, "sonmp") == 0)
-                        module = prefs_find_module("ndp");
-                    else if (strcmp(pref_name, "etheric") == 0 ||
-                             strcmp(pref_name, "isup_thin") == 0) {
-                        /* This protocol was removed 7. July 2009 */
-                        return PREFS_SET_OBSOLETE;
-                    } else {
-                        /* See if the module name matches any protocol aliases. */
+                    /*
+                     * See if there's a backwards-compatibility name
+                     * that maps to this module.
+                     */
+                    module = prefs_find_module_alias(pref_name);
+                    if (module == NULL) {
+                        /*
+                         * There's no alias for the module; see if the
+                         * module name matches any protocol aliases.
+                         */
                         header_field_info *hfinfo = proto_registrar_get_byalias(pref_name);
                         if (hfinfo) {
                             module = (module_t *) wmem_tree_lookup_string(prefs_modules, hfinfo->abbrev, WMEM_TREE_STRING_NOCASE);
                         }
                     }
+                    if (module == NULL) {
+                        /*
+                         * There aren't any aliases.  Was the module
+                         * removed rather than renamed?
+                         */
+                        if (strcmp(pref_name, "etheric") == 0 ||
+                            strcmp(pref_name, "isup_thin") == 0) {
+                            /*
+                             * The dissectors for these protocols were
+                             * removed as obsolete on 2009-07-70 in change
+                             * 739bfc6ff035583abb9434e0e988048de38a8d9a.
+                             */
+                            return PREFS_SET_OBSOLETE;
+                        }
+                    }
                     if (module) {
                         g_warning ("Preference \"%s.%s\" has been converted to \"%s.%s\"\n"
                                    "Save your preferences to make this change permanent.",
@@ -5915,26 +5904,26 @@ set_pref(gchar *pref_name, const gchar *value, void *private_data _U_,
                     handle = dissector_table_get_dissector_handle(sub_dissectors, module->title);
                     if (handle != NULL) {
                         /* Delete all of the old values from the dissector table */
-                               for (i = 0; i < (*pref->varp.range)->nranges; i++) {
-                                       for (j = (*pref->varp.range)->ranges[i].low; j < (*pref->varp.range)->ranges[i].high; j++) {
+                        for (i = 0; i < (*pref->varp.range)->nranges; i++) {
+                            for (j = (*pref->varp.range)->ranges[i].low; j < (*pref->varp.range)->ranges[i].high; j++) {
                                 dissector_delete_uint(pref->name, j, handle);
                                 decode_build_reset_list(pref->name, dissector_table_get_type(sub_dissectors), GUINT_TO_POINTER(j), NULL, NULL);
                             }
 
                             dissector_delete_uint(pref->name, (*pref->varp.range)->ranges[i].high, handle);
                             decode_build_reset_list(pref->name, dissector_table_get_type(sub_dissectors), GUINT_TO_POINTER((*pref->varp.range)->ranges[i].high), NULL, NULL);
-                               }
+                        }
 
                         /* Add new values to the dissector table */
-                               for (i = 0; i < newrange->nranges; i++) {
-                                       for (j = newrange->ranges[i].low; j < newrange->ranges[i].high; j++) {
+                        for (i = 0; i < newrange->nranges; i++) {
+                            for (j = newrange->ranges[i].low; j < newrange->ranges[i].high; j++) {
                                 dissector_change_uint(pref->name, j, handle);
                                 decode_build_reset_list(pref->name, dissector_table_get_type(sub_dissectors), GUINT_TO_POINTER(j), NULL, NULL);
                             }
 
                             dissector_change_uint(pref->name, newrange->ranges[i].high, handle);
                             decode_build_reset_list(pref->name, dissector_table_get_type(sub_dissectors), GUINT_TO_POINTER(newrange->ranges[i].high), NULL, NULL);
-                               }
+                        }
 
                         /* XXX - Do we save the decode_as_entries file here? */
                     }