ISO14443: Fix Dead Store (Dead assignement/Dead increment) Warning found by Clang
[metze/wireshark/wip.git] / epan / prefs.c
index 028fee457abf9bf12960204aad9f287e0fb82aad..a1b4072b0e0a882351b0c1fa50dc3a81f6c39e1f 100644 (file)
 #include <string.h>
 #include <errno.h>
 
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
 #include <glib.h>
 
 #include <stdio.h>
@@ -73,7 +69,6 @@ static void try_convert_to_custom_column(gpointer *el_data);
 #define OLD_GPF_NAME    "wireshark.conf" /* old name for global preferences file */
 
 static gboolean prefs_initialized = FALSE;
-static gboolean prefs_pre_initialized = FALSE;
 static gchar *gpf_path = NULL;
 static gchar *cols_hidden_list = NULL;
 
@@ -168,7 +163,7 @@ static const gchar *capture_cols[7] = {
 };
 #define CAPTURE_COL_TYPE_DESCRIPTION \
     "Possible values: INTERFACE, LINK, PMODE, SNAPLEN, MONITOR, BUFFER, FILTER\n"
-#elif defined(_WIN32) && !defined (HAVE_PCAP_CREATE)
+#elif defined(CAN_SET_CAPTURE_BUFFER_SIZE)
 /* Can set buffer size but not monitor mode. */
 static gint num_capture_cols = 6;
 static const gchar *capture_cols[6] = {
@@ -195,6 +190,14 @@ static const gchar *capture_cols[5] = {
     "Possible values: INTERFACE, LINK, PMODE, SNAPLEN, FILTER\n"
 #endif
 
+static const enum_val_t gui_packet_list_elide_mode[] = {
+    {"LEFT", "LEFT", ELIDE_LEFT},
+    {"RIGHT", "RIGHT", ELIDE_RIGHT},
+    {"MIDDLE", "MIDDLE", ELIDE_MIDDLE},
+    {"NONE", "NONE", ELIDE_NONE},
+    {NULL, NULL, -1}
+};
+
 /*
  * List of all modules with preference settings.
  */
@@ -210,6 +213,7 @@ static wmem_tree_t *prefs_top_level_modules = NULL;
 void
 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());
 }
@@ -297,6 +301,27 @@ prefs_register_module(module_t *parent, const char *name, const char *title,
                                             FALSE, apply_cb, use_gui);
 }
 
+static void
+prefs_deregister_module(module_t *parent, const char *name, const char *title)
+{
+    /* Remove this module from the list of all modules */
+    module_t *module = (module_t *)wmem_tree_remove_string(prefs_modules, name, WMEM_TREE_STRING_NOCASE);
+
+    if (!module)
+        return;
+
+    if (parent == NULL) {
+        /* Remove from top */
+        wmem_tree_remove_string(prefs_top_level_modules, title, WMEM_TREE_STRING_NOCASE);
+    } else if (parent->submodules) {
+        /* Remove from parent */
+        wmem_tree_remove_string(parent->submodules, title, WMEM_TREE_STRING_NOCASE);
+    }
+
+    free_module_prefs(module, NULL);
+    wmem_free(wmem_epan_scope(), module);
+}
+
 /*
  * Register a subtree that will have modules under it.
  * Specify the module under which to register it or NULL to register it
@@ -436,6 +461,7 @@ prefs_register_protocol(int id, void (*apply_cb)(void))
          * No.  Register Protocols subtree as well as any preferences
          * for non-dissector modules.
          */
+        pre_init_prefs();
         prefs_register_modules();
     }
     protocol = find_protocol_by_id(id);
@@ -445,6 +471,15 @@ prefs_register_protocol(int id, void (*apply_cb)(void))
                                  proto_get_protocol_name(id), apply_cb, TRUE);
 }
 
+void
+prefs_deregister_protocol (int id)
+{
+    protocol_t *protocol = find_protocol_by_id(id);
+    prefs_deregister_module (protocols_module,
+                             proto_get_protocol_filter_name(id),
+                             proto_get_protocol_short_name(protocol));
+}
+
 module_t *
 prefs_register_protocol_subtree(const char *subtree, int id, void (*apply_cb)(void))
 {
@@ -463,6 +498,7 @@ prefs_register_protocol_subtree(const char *subtree, int id, void (*apply_cb)(vo
          * No.  Register Protocols subtree as well as any preferences
          * for non-dissector modules.
          */
+        pre_init_prefs();
         prefs_register_modules();
     }
 
@@ -522,6 +558,7 @@ prefs_register_protocol_obsolete(int id)
          * No.  Register Protocols subtree as well as any preferences
          * for non-dissector modules.
          */
+        pre_init_prefs();
         prefs_register_modules();
     }
     protocol = find_protocol_by_id(id);
@@ -557,7 +594,8 @@ prefs_register_stat(const char *name, const char *title,
          * No.  Register Statistics subtree as well as any preferences
          * for non-dissector modules.
          */
-         prefs_register_modules();
+        pre_init_prefs();
+        prefs_register_modules();
     }
 
     return prefs_register_module(stats_module, name, title, description,
@@ -596,7 +634,7 @@ typedef struct {
 } call_foreach_t;
 
 static gboolean
-call_foreach_cb(void *value, void *data)
+call_foreach_cb(const void *key _U_, void *value, void *data)
 {
     module_t *module = (module_t*)value;
     call_foreach_t *call_data = (call_foreach_t*)data;
@@ -672,7 +710,7 @@ prefs_modules_foreach_submodules(module_t *module, module_cb callback,
 }
 
 static gboolean
-call_apply_cb(void *value, void *data _U_)
+call_apply_cb(const void *key _U_, void *value, void *data _U_)
 {
     module_t *module = (module_t *)value;
 
@@ -708,7 +746,7 @@ void
 prefs_apply(module_t *module)
 {
     if (module && module->prefs_changed)
-        call_apply_cb(module, NULL);
+        call_apply_cb(NULL, module, NULL);
 }
 
 /*
@@ -801,7 +839,7 @@ preference_match(gconstpointer a, gconstpointer b)
 }
 
 static gboolean
-module_find_pref_cb(void *value, void *data)
+module_find_pref_cb(const void *key _U_, void *value, void *data)
 {
     find_pref_arg_t* arg = (find_pref_arg_t*)data;
     GList *list_entry;
@@ -1485,6 +1523,7 @@ column_hidden_to_str_cb(pref_t* pref, gboolean default_val)
                 g_string_append (cols_hidden, ",");
             g_string_append (cols_hidden, prefs_fmt);
         }
+        g_free(prefs_fmt);
         clp = clp->next;
     }
 
@@ -1790,29 +1829,12 @@ capture_column_init_cb(pref_t* pref, GList** capture_cols_values)
 static void
 capture_column_free_cb(pref_t* pref)
 {
-    GList    *clist = prefs.capture_columns;
-    gchar    *col_name;
-
-    while (clist) {
-        col_name = (gchar *)clist->data;
-        g_free(col_name);
-        clist = g_list_remove_link(clist, clist);
-    }
-    g_list_free(clist);
+    prefs_clear_string_list(prefs.capture_columns);
     prefs.capture_columns = NULL;
 
     if (pref->stashed_val.boolval == TRUE) {
-      GList *dlist;
-      gchar *col;
-
-      dlist = pref->default_val.list;
-      while (dlist != NULL) {
-        col = (gchar *)dlist->data;
-        g_free(col);
-        dlist = g_list_remove_link(dlist, dlist);
-      }
-      g_list_free(dlist);
-      dlist = NULL;
+      prefs_clear_string_list(pref->default_val.list);
+      pref->default_val.list = NULL;
     }
 }
 
@@ -1821,18 +1843,10 @@ capture_column_free_cb(pref_t* pref)
 static void
 capture_column_reset_cb(pref_t* pref)
 {
-    GList *vlist, *dlist;
-    gchar *vcol;
+    GList *vlist = NULL, *dlist;
 
     /* Free the column name strings and remove the links from *pref->varp.list */
-    vlist = *pref->varp.list;
-    while (vlist != NULL) {
-      vcol = (gchar *)vlist->data;
-      g_free(vcol);
-      vlist = g_list_remove_link(vlist, vlist);
-    }
-    g_list_free(vlist);
-    vlist = NULL;
+    prefs_clear_string_list(*pref->varp.list);
 
     for (dlist = pref->default_val.list; dlist != NULL; dlist = g_list_next(dlist)) {
       vlist = g_list_append(vlist, g_strdup((gchar *)dlist->data));
@@ -1843,9 +1857,9 @@ capture_column_reset_cb(pref_t* pref)
 static prefs_set_pref_e
 capture_column_set_cb(pref_t* pref, const gchar* value, gboolean* changed _U_)
 {
-    GList   *col_l  = prefs_get_string_list(value);
-    GList    *col_l_elt;
-    gchar   *col_name;
+    GList *col_l  = prefs_get_string_list(value);
+    GList *col_l_elt;
+    gchar *col_name;
     int i;
 
     if (col_l == NULL)
@@ -1882,6 +1896,7 @@ capture_column_set_cb(pref_t* pref, const gchar* value, gboolean* changed _U_)
           prefs.capture_columns = g_list_append(prefs.capture_columns, col_name);
         }
         pref->varp.list = &prefs.capture_columns;
+        prefs_clear_string_list(col_l);
         return PREFS_SET_SYNTAX_ERR;
       }
       col_l_elt = col_l_elt->next;
@@ -1894,6 +1909,7 @@ capture_column_set_cb(pref_t* pref, const gchar* value, gboolean* changed _U_)
       col_l_elt = col_l_elt->next;
     }
     pref->varp.list = &prefs.capture_columns;
+    g_list_free(col_l);
     return PREFS_SET_OK;
 }
 
@@ -2034,17 +2050,13 @@ prefs_register_modules(void)
     module_t *printing, *capture_module, *console_module,
         *gui_layout_module, *gui_font_module;
     struct pref_custom_cbs custom_cbs;
+    gchar *tmp;
 
     if (protocols_module != NULL) {
         /* Already setup preferences */
         return;
     }
 
-    /* Ensure the "global" preferences have been initialized so the
-     * preference API has the proper default values to work from
-     */
-    pre_init_prefs();
-
     /* GUI
      * These are "simple" GUI preferences that can be read/written using the
      * preference module API.  These preferences still use their own
@@ -2059,7 +2071,7 @@ prefs_register_modules(void)
      */
     prefs_register_enum_preference(gui_module, "console_open",
                        "Open a console window",
-                       "Open a console window (WIN32 only)",
+                       "Open a console window (Windows only)",
                        (gint*)(void*)(&prefs.gui_console_open), gui_console_open_type, FALSE);
 
     prefs_register_obsolete_preference(gui_module, "scrollbar_on_right");
@@ -2138,11 +2150,15 @@ prefs_register_modules(void)
 
     prefs_register_obsolete_preference(gui_font_module, "font_name");
 
+    tmp = prefs.gui_gtk2_font_name;
     prefs_register_string_preference(gui_font_module, "gtk2.font_name", "Font name",
         "Font name for packet list, protocol tree, and hex dump panes. (GTK+)", (const char **)&prefs.gui_gtk2_font_name);
+    g_free(tmp);
 
+    tmp = prefs.gui_qt_font_name;
     prefs_register_string_preference(gui_font_module, "qt.font_name", "Font name",
         "Font name for packet list, protocol tree, and hex dump panes. (Qt)", (const char **)&prefs.gui_qt_font_name);
+    g_free(tmp);
 
     /* User Interface : Colors */
     gui_color_module = prefs_register_subtree(gui_module, "Colors", "Colors", NULL);
@@ -2178,8 +2194,10 @@ prefs_register_modules(void)
     custom_cbs.type_description_cb = colorized_frame_type_description_cb;
     custom_cbs.is_default_cb = colorized_frame_is_default_cb;
     custom_cbs.to_str_cb = colorized_frame_to_str_cb;
+    tmp = prefs.gui_colorized_fg;
     prefs_register_string_custom_preference(gui_column_module, "colorized_frame.fg", "Colorized Foreground",
         "Filter Colorized Foreground", &custom_cbs, (const char **)&prefs.gui_colorized_fg);
+    g_free(tmp);
 
     custom_cbs.free_cb = colorized_frame_free_cb;
     custom_cbs.reset_cb = colorized_frame_reset_cb;
@@ -2188,8 +2206,10 @@ prefs_register_modules(void)
     custom_cbs.type_description_cb = colorized_frame_type_description_cb;
     custom_cbs.is_default_cb = colorized_frame_is_default_cb;
     custom_cbs.to_str_cb = colorized_frame_to_str_cb;
+    tmp = prefs.gui_colorized_bg;
     prefs_register_string_custom_preference(gui_column_module, "colorized_frame.bg", "Colorized Background",
         "Filter Colorized Background", &custom_cbs, (const char **)&prefs.gui_colorized_bg);
+    g_free(tmp);
 
     prefs_register_color_preference(gui_color_module, "color_filter_bg.valid", "Valid color filter background",
         "Valid color filter background", &prefs.gui_text_valid);
@@ -2217,8 +2237,10 @@ prefs_register_modules(void)
                                    10,
                                    &prefs.gui_recent_df_entries_max);
 
+    tmp = prefs.gui_fileopen_dir;
     prefs_register_directory_preference(gui_module, "fileopen.dir", "Start Directory",
         "Directory to start in when opening File Open dialog.", (const char **)&prefs.gui_fileopen_dir);
+    g_free(tmp);
 
     prefs_register_obsolete_preference(gui_module, "fileopen.remembered_dir");
 
@@ -2259,8 +2281,8 @@ prefs_register_modules(void)
                                    &prefs.gui_geometry_save_maximized);
 
     prefs_register_bool_preference(gui_module, "macosx_style",
-                                   "Use Mac OS X style",
-                                   "Use Mac OS X style (Mac OS X with native GTK only)?",
+                                   "Use OS X style",
+                                   "Use OS X style (OS X with native GTK only)?",
                                    &prefs.gui_macosx_style);
 
     prefs_register_obsolete_preference(gui_module, "geometry.main.x");
@@ -2279,8 +2301,10 @@ prefs_register_modules(void)
                        "Filter Toolbar style",
                        &prefs.gui_toolbar_filter_style, gui_toolbar_style, FALSE);
 
+    tmp = prefs.gui_webbrowser;
     prefs_register_string_preference(gui_module, "webbrowser", "The path to the webbrowser",
         "The path to the webbrowser (Ex: mozilla)", (const char **)&prefs.gui_webbrowser);
+    g_free(tmp);
 
     prefs_register_bool_preference(gui_module, "update.enabled",
                                    "Check for updates",
@@ -2298,11 +2322,15 @@ prefs_register_modules(void)
                                    10,
                                    &prefs.gui_update_interval);
 
+    tmp = prefs.gui_window_title;
     prefs_register_string_preference(gui_module, "window_title", "Custom window title",
         "Custom window title. (Appended to existing titles.)", (const char **)&prefs.gui_window_title);
+    g_free(tmp);
 
+    tmp = prefs.gui_start_title;
     prefs_register_string_preference(gui_module, "start_title", "Custom start page title",
         "Custom start page title", (const char**)(&prefs.gui_start_title));
+    g_free(tmp);
 
     prefs_register_enum_preference(gui_module, "version_placement",
                        "Show version in the start page and/or main screen's title bar",
@@ -2344,10 +2372,31 @@ prefs_register_modules(void)
                        "Layout content of the pane 3",
                        (gint*)(void*)(&prefs.gui_layout_content_3), gui_layout_content, FALSE);
 
+    prefs_register_bool_preference(gui_layout_module, "packet_list_separator.enabled",
+                                   "Enable Packet List Separator",
+                                   "Enable Packet List Separator",
+                                   &prefs.gui_qt_packet_list_separator);
+
     prefs_register_bool_preference(gui_module, "packet_editor.enabled",
                                    "Enable Packet Editor",
                                    "Enable Packet Editor (Experimental)",
                                    &prefs.gui_packet_editor);
+
+    prefs_register_enum_preference(gui_module, "packet_list_elide_mode",
+                       "Elide mode",
+                       "The position of \"...\" in packet list text.",
+                       (gint*)(void*)(&prefs.gui_packet_list_elide_mode), gui_packet_list_elide_mode, FALSE);
+
+    prefs_register_bool_preference(gui_layout_module, "packet_list_show_related",
+                                   "Show Related Packets",
+                                   "Show related packet indicators in the first column",
+                                   &prefs.gui_packet_list_show_related);
+
+    prefs_register_bool_preference(gui_layout_module, "packet_list_show_minimap",
+                                   "Enable Intelligent Scroll Bar",
+                                   "Show the intelligent scroll bar (a minimap of packet list colors in the scrollbar)",
+                                   &prefs.gui_packet_list_show_minimap);
+
     /* Console
      * These are preferences that can be read/written using the
      * preference module API.  These preferences still use their own
@@ -2394,7 +2443,7 @@ prefs_register_modules(void)
         "By default, capture in monitor mode on interface? (Ex: eth0,eth3,...)",
         (const char **)&prefs.capture_devices_monitor_mode);
 
-#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
+#ifdef CAN_SET_CAPTURE_BUFFER_SIZE
     prefs_register_string_preference(capture_module, "devices_buffersize", "Interface buffer size",
         "Interface buffer size (Ex: en0(1),en1(143),...)",
         ((const char **)&prefs.capture_devices_buffersize));
@@ -2421,6 +2470,7 @@ 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);
 
+    /* We might want to make this a "recent" setting. */
     prefs_register_bool_preference(capture_module, "auto_scroll", "Scroll packet list during capture",
         "Scroll packet list during capture?", &prefs.capture_auto_scroll);
 
@@ -2461,13 +2511,16 @@ prefs_register_modules(void)
                                    &prefs.pr_dest, print_dest_vals, TRUE);
 
 #ifndef _WIN32
+    tmp = prefs.pr_cmd;
     prefs_register_string_preference(printing, "command", "Command",
         "Output gets piped to this command when the destination is set to \"command\"", (const char**)(&prefs.pr_cmd));
+    g_free(tmp);
 #endif
 
+    tmp = prefs.pr_file;
     prefs_register_filename_preference(printing, "file", "File",
         "This is the file that gets written to when the destination is set to \"file\"", (const char**)(&prefs.pr_file));
-
+    g_free(tmp);
 
     /* Statistics */
     stats_module = prefs_register_module(NULL, "statistics", "Statistics",
@@ -2714,12 +2767,9 @@ char *join_string_list(GList *sl)
 void
 prefs_clear_string_list(GList *sl)
 {
-    GList *l = sl;
-
-    while (l) {
-        g_free(l->data);
-        l = g_list_remove_link(l, l);
-    }
+    /* g_list_free_full() only exists since 2.28. */
+    g_list_foreach(sl, (GFunc)g_free, NULL);
+    g_list_free(sl);
 }
 
 /*
@@ -2826,11 +2876,11 @@ parse_column_format(fmt_data *cfmt, const char *fmt)
     return TRUE;
 }
 
-/* Initialize non-dissector preferences to wired-in default values.
- * (The dissector preferences are assumed to be set to those values
- * by the dissectors.)
- * They may be overridden by the global preferences file or the
- *  user's preferences file.
+/* Initialize non-dissector preferences to wired-in default values Called
+ * at program startup and any time the profile changes. (The dissector
+ * preferences are assumed to be set to those values by the dissectors.)
+ * They may be overridden by the global preferences file or the user's
+ * preferences file.
  */
 static void
 init_prefs(void)
@@ -2840,6 +2890,12 @@ init_prefs(void)
 
     uat_load_all();
 
+    /*
+     * Ensure the "global" preferences have been initialized so the
+     * preference API has the proper default values to work from
+     */
+    pre_init_prefs();
+
     prefs_register_modules();
 
     filter_expression_init(TRUE);
@@ -2847,8 +2903,12 @@ init_prefs(void)
     prefs_initialized = TRUE;
 }
 
-/* Initialize non-dissector preferences used by the "register preference" API
- * to default values so the default values can be used when registered
+/*
+ * Initialize non-dissector preferences used by the "register preference" API
+ * to default values so the default values can be used when registered.
+ *
+ * String, filename, and directory preferences will be g_freed so they must
+ * be g_mallocated.
  */
 static void
 pre_init_prefs(void)
@@ -2862,13 +2922,12 @@ pre_init_prefs(void)
         "Protocol", "%p", "Length",      "%L",
         "Info",     "%i"};
 
-    if (prefs_pre_initialized)
-        return;
-
     prefs.pr_format  = PR_FMT_TEXT;
     prefs.pr_dest    = PR_DEST_CMD;
-    prefs.pr_file    = "wireshark.out";
-    prefs.pr_cmd     = "lpr";
+    if (prefs.pr_file) g_free(prefs.pr_file);
+    prefs.pr_file    = g_strdup("wireshark.out");
+    if (prefs.pr_cmd) g_free(prefs.pr_cmd);
+    prefs.pr_cmd     = g_strdup("lpr");
 
     prefs.gui_altern_colors = FALSE;
     prefs.gui_expert_composite_eyecandy = FALSE;
@@ -2878,15 +2937,16 @@ pre_init_prefs(void)
     prefs.filter_toolbar_show_in_statusbar = FALSE;
     prefs.gui_toolbar_main_style = TB_STYLE_ICONS;
     prefs.gui_toolbar_filter_style = TB_STYLE_TEXT;
-    /* These string prefs will be strduped shortly, so we can safely cast away
-     * their constness in these assignments */
+    /* These will be g_freed, so they must be g_mallocated. */
+    if (prefs.gui_gtk2_font_name) g_free(prefs.gui_gtk2_font_name);
 #ifdef _WIN32
-    prefs.gui_gtk2_font_name         = (char *) "Lucida Console 10";
+    prefs.gui_gtk2_font_name         = g_strdup("Lucida Console 10");
 #else
-    prefs.gui_gtk2_font_name         = (char *) "Monospace 10";
+    prefs.gui_gtk2_font_name         = g_strdup("Monospace 10");
 #endif
     /* We try to find the best font in the Qt code */
-    prefs.gui_qt_font_name           = (char *) "";
+    if (prefs.gui_qt_font_name) g_free(prefs.gui_qt_font_name);
+    prefs.gui_qt_font_name           = g_strdup("");
     prefs.gui_marked_fg.pixel        =     65535;
     prefs.gui_marked_fg.red          =     65535;
     prefs.gui_marked_fg.green        =     65535;
@@ -2903,8 +2963,10 @@ pre_init_prefs(void)
     prefs.gui_ignored_bg.red         =     65535;
     prefs.gui_ignored_bg.green       =     65535;
     prefs.gui_ignored_bg.blue        =     65535;
-    prefs.gui_colorized_fg           = "000000,000000,000000,000000,000000,000000,000000,000000,000000,000000";
-    prefs.gui_colorized_bg           = "ffc0c0,ffc0ff,e0c0e0,c0c0ff,c0e0e0,c0ffff,c0ffc0,ffffc0,e0e0c0,e0e0e0";
+    if (prefs.gui_colorized_fg) g_free(prefs.gui_colorized_fg);
+    prefs.gui_colorized_fg           = g_strdup("000000,000000,000000,000000,000000,000000,000000,000000,000000,000000");
+    if (prefs.gui_colorized_bg) g_free(prefs.gui_colorized_bg);
+    prefs.gui_colorized_bg           = g_strdup("ffc0c0,ffc0ff,e0c0e0,c0c0ff,c0e0e0,c0ffff,c0ffc0,ffffc0,e0e0c0,e0e0e0");
     prefs.st_client_fg.pixel         =     0;
     prefs.st_client_fg.red           = 32767;
     prefs.st_client_fg.green         =     0;
@@ -2941,7 +3003,8 @@ pre_init_prefs(void)
     prefs.gui_fileopen_style         = FO_STYLE_LAST_OPENED;
     prefs.gui_recent_df_entries_max  = 10;
     prefs.gui_recent_files_count_max = 10;
-    prefs.gui_fileopen_dir           = (char *) get_persdatafile_dir();
+    if (prefs.gui_fileopen_dir) g_free(prefs.gui_fileopen_dir);
+    prefs.gui_fileopen_dir           = g_strdup(get_persdatafile_dir());
     prefs.gui_fileopen_preview       = 3;
     prefs.gui_ask_unsaved            = TRUE;
     prefs.gui_find_wrap              = TRUE;
@@ -2949,13 +3012,16 @@ pre_init_prefs(void)
     prefs.gui_update_enabled         = TRUE;
     prefs.gui_update_channel         = UPDATE_CHANNEL_STABLE;
     prefs.gui_update_interval        = 60*60*24; /* Seconds */
+    if (prefs.gui_webbrowser) g_free(prefs.gui_webbrowser);
 #ifdef HTML_VIEWER
-    prefs.gui_webbrowser             = (char *) HTML_VIEWER " %s";
+    prefs.gui_webbrowser             = g_strdup(HTML_VIEWER " %s");
 #else
-    prefs.gui_webbrowser             = (char *) "";
+    prefs.gui_webbrowser             = g_strdup("");
 #endif
-    prefs.gui_window_title           = (char *) "";
-    prefs.gui_start_title            = "The World's Most Popular Network Protocol Analyzer";
+    if (prefs.gui_window_title) g_free(prefs.gui_window_title);
+    prefs.gui_window_title           = g_strdup("");
+    if (prefs.gui_start_title) g_free(prefs.gui_start_title);
+    prefs.gui_start_title            = g_strdup("The World's Most Popular Network Protocol Analyzer");
     prefs.gui_version_placement      = version_both;
     prefs.gui_auto_scroll_on_expand  = FALSE;
     prefs.gui_auto_scroll_percentage = 0;
@@ -2964,8 +3030,16 @@ pre_init_prefs(void)
     prefs.gui_layout_content_2       = layout_pane_content_pdetails;
     prefs.gui_layout_content_3       = layout_pane_content_pbytes;
     prefs.gui_packet_editor          = FALSE;
+    prefs.gui_packet_list_elide_mode = ELIDE_RIGHT;
+    prefs.gui_packet_list_show_related = TRUE;
+    prefs.gui_packet_list_show_minimap = TRUE;
 
-    prefs.col_list = NULL;
+    prefs.gui_qt_packet_list_separator = FALSE;
+
+    if (prefs.col_list) {
+        free_col_info(prefs.col_list);
+        prefs.col_list = NULL;
+    }
     for (i = 0; i < DEF_NUM_COLS; i++) {
         cfmt = g_new(fmt_data,1);
         cfmt->title = g_strdup(col_fmt[i * 2]);
@@ -2989,10 +3063,12 @@ pre_init_prefs(void)
     prefs.capture_auto_scroll           = TRUE;
     prefs.capture_show_info             = FALSE;
 
-    prefs.capture_columns               = NULL;
-    for (i = 0; i < num_capture_cols; i++) {
-        col_name = g_strdup(capture_cols[i]);
-        prefs.capture_columns = g_list_append(prefs.capture_columns, col_name);
+    if (!prefs.capture_columns) {
+        /* First time through */
+        for (i = 0; i < num_capture_cols; i++) {
+            col_name = g_strdup(capture_cols[i]);
+            prefs.capture_columns = g_list_append(prefs.capture_columns, col_name);
+        }
     }
 
     prefs.console_log_level          =
@@ -3013,8 +3089,6 @@ pre_init_prefs(void)
     prefs.st_sort_showfullname = FALSE;
     prefs.display_hidden_proto_items = FALSE;
     prefs.display_byte_fields_with_spaces = FALSE;
-
-    prefs_pre_initialized = TRUE;
 }
 
 /*
@@ -3097,7 +3171,7 @@ typedef struct {
  * Reset all preferences for a module.
  */
 static gboolean
-reset_module_prefs(void *value, void *data _U_)
+reset_module_prefs(const void *key _U_, void *value, void *data _U_)
 {
     reset_pref_arg_t arg;
 
@@ -3270,7 +3344,7 @@ read_prefs(int *gpf_errno_return, int *gpf_read_errno_return,
     return &prefs;
 }
 
-/* read the preferences file (or similiar) and call the callback
+/* read the preferences file (or similar) and call the callback
  * function to set each key/value pair found */
 int
 read_prefs_file(const char *pf_path, FILE *pf,
@@ -3297,6 +3371,7 @@ read_prefs_file(const char *pf_path, FILE *pf,
     /* Try to read in the profile name in the first line of the preferences file. */
     if (fscanf(pf, "# Configuration file for %127[^\r\n]", ver) == 1) {
         /* Assume trailing period and remove it */
+        g_free(prefs.saved_at_version);
         prefs.saved_at_version = g_strndup(ver, strlen(ver) - 1);
     }
     rewind(pf);
@@ -3741,6 +3816,9 @@ string_to_name_resolve(const char *string, e_addr_resolve *name_resolve)
         case 'C':
             name_resolve->concurrent_dns = TRUE;
             break;
+        case 'd':
+            name_resolve->dns_pkt_addr_resolution = TRUE;
+            break;
         default:
             /*
              * Unrecognized letter.
@@ -3795,6 +3873,78 @@ try_convert_to_custom_column(gpointer *el_data)
     }
 }
 
+static gboolean
+deprecated_heur_dissector_pref(gchar *pref_name, const gchar *value)
+{
+    struct heur_pref_name
+    {
+        const char* pref_name;
+        const char* short_name;
+        gboolean  more_dissectors; /* For multiple dissectors controlled by the same preference */
+    };
+
+    struct heur_pref_name heur_prefs[] = {
+        {"acn.heuristic_acn", "acn_udp", 0},
+        {"bfcp.enable", "bfcp_tcp", 1},
+        {"bfcp.enable", "bfcp_udp", 0},
+        {"bt-dht.enable", "bittorrent_dht_udp", 0},
+        {"bt-utp.enable", "bt_utp_udp", 0},
+        {"cattp.enable", "cattp_udp", 0},
+        {"cfp.enable", "fp_eth", 0},
+        {"dicom.heuristic", "dicom_tcp", 0},
+        {"dnp3.heuristics", "dnp3_tcp", 1},
+        {"dnp3.heuristics", "dnp3_udp", 0},
+        {"dvb-s2_modeadapt.enable", "dvb_s2_udp", 0},
+        {"esl.enable", "esl_eth", 0},
+        {"fp.udp_heur", "fp_udp", 0},
+        {"gvsp.enable_heuristic", "gvsp_udp", 0},
+        {"hdcp2.enable", "hdcp2_tcp", 0},
+        {"hislip.enable_heuristic", "hislip_tcp", 0},
+        {"jxta.udp.heuristic", "jxta_udp", 0},
+        {"jxta.tcp.heuristic", "jxta_tcp", 0},
+        {"jxta.sctp.heuristic", "jxta_sctp", 0},
+        {"mac-lte.heuristic_mac_lte_over_udp", "mac_lte_udp", 0},
+        {"mbim.bulk_heuristic", "mbim_usb_bulk", 0},
+        {"norm.heuristic_norm", "rmt_norm_udp", 0},
+        {"openflow.heuristic", "openflow_tcp", 0},
+        {"pdcp-lte.heuristic_pdcp_lte_over_udp", "pdcp_lte_udp", 0},
+        {"rlc.heuristic_rlc_over_udp", "rlc_udp", 0},
+        {"rlc-lte.heuristic_rlc_lte_over_udp", "rlc_lte_udp", 0},
+        {"rtcp.heuristic_rtcp", "rtcp_udp", 1},
+        {"rtcp.heuristic_rtcp", "rtcp_stun", 0},
+        {"rtp.heuristic_rtp", "rtp_udp", 1},
+        {"rtp.heuristic_rtp", "rtp_stun", 0},
+        {"teredo.heuristic_teredo", "teredo_udp", 0},
+        {"vssmonitoring.use_heuristics", "vssmonitoring_eth", 0},
+        {"xml.heuristic", "xml_http", 1},
+        {"xml.heuristic", "xml_sip", 1},
+        {"xml.heuristic", "xml_media", 0},
+        {"xml.heuristic_tcp", "xml_tcp", 0},
+        {"xml.heuristic_udp", "xml_udp", 0},
+    };
+
+    unsigned int i;
+    heur_dtbl_entry_t* heuristic;
+
+
+    for (i = 0; i < sizeof(heur_prefs)/sizeof(struct heur_pref_name); i++)
+    {
+        if (strcmp(pref_name, heur_prefs[i].pref_name) == 0)
+        {
+            heuristic = find_heur_dissector_by_unique_short_name(heur_prefs[i].short_name);
+            if (heuristic != NULL) {
+                heuristic->enabled = ((g_ascii_strcasecmp(value, "true") == 0) ? TRUE : FALSE);
+            }
+
+            if (!heur_prefs[i].more_dissectors)
+                return TRUE;
+        }
+    }
+
+
+    return FALSE;
+}
+
 static prefs_set_pref_e
 set_pref(gchar *pref_name, const gchar *value, void *private_data _U_,
          gboolean return_range_errors)
@@ -3844,20 +3994,16 @@ set_pref(gchar *pref_name, const gchar *value, void *private_data _U_,
             gbl_resolv_flags.concurrent_dns = TRUE;
         }
         else if (g_ascii_strcasecmp(value, "false") == 0) {
-            gbl_resolv_flags.mac_name = FALSE;
-            gbl_resolv_flags.network_name = FALSE;
-            gbl_resolv_flags.transport_name = FALSE;
-            gbl_resolv_flags.concurrent_dns = FALSE;
+            disable_name_resolution();
         }
         else {
             /* start out with none set */
-            gbl_resolv_flags.mac_name = FALSE;
-            gbl_resolv_flags.network_name = FALSE;
-            gbl_resolv_flags.transport_name = FALSE;
-            gbl_resolv_flags.concurrent_dns = FALSE;
+            disable_name_resolution();
             if (string_to_name_resolve(value, &gbl_resolv_flags) != '\0')
                 return PREFS_SET_SYNTAX_ERR;
         }
+    } else if (deprecated_heur_dissector_pref(pref_name, value)) {
+         /* Handled within deprecated_heur_dissector_pref() if found */
     } else {
         /* Handle deprecated "global" options that don't have a module
          * associated with them
@@ -4854,9 +5000,10 @@ write_prefs(char **pf_path_return)
  * it's freed here
  */
 static void
-free_col_info(GList * list)
+free_col_info(GList *list)
 {
     fmt_data *cfmt;
+    GList *list_head = list;
 
     while (list != NULL) {
         cfmt = (fmt_data *)list->data;
@@ -4864,10 +5011,9 @@ free_col_info(GList * list)
         g_free(cfmt->title);
         g_free(cfmt->custom_field);
         g_free(cfmt);
-        list = g_list_remove_link(list, list);
+        list = g_list_next(list);
     }
-    g_list_free(list);
-    list = NULL;
+    g_list_free(list_head);
 }
 
 /*