summaryrefslogtreecommitdiff
path: root/ui/recent.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2013-02-02 04:49:58 +0000
committerGuy Harris <guy@alum.mit.edu>2013-02-02 04:49:58 +0000
commit4d85cfeea676b8d84be41422f32a660b2a1b3b81 (patch)
treee287c7a1a1aa6669d8d37a7a25be3f28b54c3744 /ui/recent.c
parent58b5fc9ebf648a105cb3a9d57456ca4ec2e8ba6f (diff)
downloadwireshark-4d85cfeea676b8d84be41422f32a660b2a1b3b81.tar.gz
Move recent.c to the ui directory, as we did with its header file.
svn path=/trunk/; revision=47438
Diffstat (limited to 'ui/recent.c')
-rw-r--r--ui/recent.c1096
1 files changed, 1096 insertions, 0 deletions
diff --git a/ui/recent.c b/ui/recent.c
new file mode 100644
index 0000000000..d66759672f
--- /dev/null
+++ b/ui/recent.c
@@ -0,0 +1,1096 @@
+/* recent.c
+ * Recent "preference" handling routines
+ * Copyright 2004, Ulf Lamping <ulf.lamping@web.de>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program 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
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include <epan/epan.h>
+#include <epan/filesystem.h>
+#include <epan/emem.h>
+#include <epan/prefs.h>
+#include <epan/prefs-int.h>
+#include <epan/column.h>
+#include <epan/timestamp.h>
+
+#include "ui/last_open_dir.h"
+#include "ui/recent.h"
+#include "ui/recent_utils.h"
+#include "ui/simple_dialog.h"
+#include "ui/ui_util.h"
+
+#include "u3.h"
+
+#include <wsutil/file_util.h>
+#include <wsutil/str_util.h>
+
+#define RECENT_KEY_MAIN_TOOLBAR_SHOW "gui.toolbar_main_show"
+#define RECENT_KEY_FILTER_TOOLBAR_SHOW "gui.filter_toolbar_show"
+#define RECENT_KEY_WIRELESS_TOOLBAR_SHOW "gui.wireless_toolbar_show"
+#define RECENT_KEY_DRIVER_CHECK_SHOW "gui.airpcap_driver_check_show"
+#define RECENT_KEY_PACKET_LIST_SHOW "gui.packet_list_show"
+#define RECENT_KEY_TREE_VIEW_SHOW "gui.tree_view_show"
+#define RECENT_KEY_BYTE_VIEW_SHOW "gui.byte_view_show"
+#define RECENT_KEY_STATUSBAR_SHOW "gui.statusbar_show"
+#define RECENT_KEY_PACKET_LIST_COLORIZE "gui.packet_list_colorize"
+#define RECENT_GUI_TIME_FORMAT "gui.time_format"
+#define RECENT_GUI_TIME_PRECISION "gui.time_precision"
+#define RECENT_GUI_SECONDS_FORMAT "gui.seconds_format"
+#define RECENT_GUI_ZOOM_LEVEL "gui.zoom_level"
+#define RECENT_GUI_BYTES_VIEW "gui.bytes_view"
+#define RECENT_GUI_GEOMETRY_MAIN_X "gui.geometry_main_x"
+#define RECENT_GUI_GEOMETRY_MAIN_Y "gui.geometry_main_y"
+#define RECENT_GUI_GEOMETRY_MAIN_WIDTH "gui.geometry_main_width"
+#define RECENT_GUI_GEOMETRY_MAIN_HEIGHT "gui.geometry_main_height"
+#define RECENT_GUI_GEOMETRY_MAIN_MAXIMIZED "gui.geometry_main_maximized"
+#define RECENT_GUI_GEOMETRY_MAIN_UPPER_PANE "gui.geometry_main_upper_pane"
+#define RECENT_GUI_GEOMETRY_MAIN_LOWER_PANE "gui.geometry_main_lower_pane"
+#define RECENT_GUI_GEOMETRY_STATUS_PANE_LEFT "gui.geometry_status_pane"
+#define RECENT_GUI_GEOMETRY_STATUS_PANE_RIGHT "gui.geometry_status_pane_right"
+#define RECENT_GUI_GEOMETRY_WLAN_STATS_PANE "gui.geometry_status_wlan_stats_pane"
+#define RECENT_LAST_USED_PROFILE "gui.last_used_profile"
+#define RECENT_GUI_FILEOPEN_REMEMBERED_DIR "gui.fileopen_remembered_dir"
+#define RECENT_GUI_GEOMETRY "gui.geom."
+#define RECENT_KEY_PRIVS_WARN_IF_ELEVATED "privs.warn_if_elevated"
+#define RECENT_KEY_PRIVS_WARN_IF_NO_NPF "privs.warn_if_no_npf"
+
+#define RECENT_FILE_NAME "recent"
+#define RECENT_COMMON_FILE_NAME "recent_common"
+
+recent_settings_t recent;
+
+static const char *ts_type_text[] =
+ { "RELATIVE", "ABSOLUTE", "ABSOLUTE_WITH_DATE", "DELTA", "DELTA_DIS", "EPOCH", "UTC", "UTC_WITH_DATE", NULL };
+
+static const char *ts_precision_text[] =
+ { "AUTO", "SEC", "DSEC", "CSEC", "MSEC", "USEC", "NSEC", NULL };
+
+static const char *ts_seconds_text[] =
+ { "SECONDS", "HOUR_MIN_SEC", NULL };
+
+/* Takes an string and a pointer to an array of strings, and a default int value.
+ * The array must be terminated by a NULL string. If the string is found in the array
+ * of strings, the index of that string in the array is returned. Otherwise, the
+ * default value that was passed as the third argument is returned.
+ */
+static int
+find_index_from_string_array(const char *needle, const char **haystack, int default_value)
+{
+ int i = 0;
+
+ while (haystack[i] != NULL) {
+ if (strcmp(needle, haystack[i]) == 0) {
+ return i;
+ }
+ i++;
+ }
+ return default_value;
+}
+
+static void
+free_col_width_info(recent_settings_t *rs)
+{
+ col_width_data *cfmt;
+
+ while (rs->col_width_list != NULL) {
+ cfmt = rs->col_width_list->data;
+ g_free(cfmt->cfield);
+ g_free(cfmt);
+ rs->col_width_list = g_list_remove_link(rs->col_width_list, rs->col_width_list);
+ }
+ g_list_free(rs->col_width_list);
+ rs->col_width_list = NULL;
+}
+
+/* Attempt to Write out "recent common" to the user's recent common file.
+ If we got an error report it with a dialog box and return FALSE,
+ otherwise return TRUE. */
+gboolean
+write_recent(void)
+{
+ char *pf_dir_path;
+ char *rf_path;
+ FILE *rf;
+
+ /* To do:
+ * - Split output lines longer than MAX_VAL_LEN
+ * - Create a function for the preference directory check/creation
+ * so that duplication can be avoided with filter.c
+ */
+
+ /* Create the directory that holds personal configuration files, if
+ necessary. */
+ if (create_persconffile_dir(&pf_dir_path) == -1) {
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+ "Can't create directory\n\"%s\"\nfor recent file: %s.", pf_dir_path,
+ g_strerror(errno));
+ g_free(pf_dir_path);
+ return FALSE;
+ }
+
+ rf_path = get_persconffile_path(RECENT_COMMON_FILE_NAME, FALSE, TRUE);
+ if ((rf = ws_fopen(rf_path, "w")) == NULL) {
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+ "Can't open recent file\n\"%s\": %s.", rf_path,
+ g_strerror(errno));
+ g_free(rf_path);
+ return FALSE;
+ }
+ g_free(rf_path);
+
+ fputs("# Recent settings file for Wireshark " VERSION ".\n"
+ "#\n"
+ "# This file is regenerated each time Wireshark is quit.\n"
+ "# So be careful, if you want to make manual changes here.\n"
+ "\n"
+ "######## Recent capture files (latest last), cannot be altered through command line ########\n"
+ "\n", rf);
+
+ menu_recent_file_write_all(rf);
+
+ fputs("\n"
+ "######## Recent capture filters (latest last), cannot be altered through command line ########\n"
+ "\n", rf);
+
+ cfilter_combo_recent_write_all(rf);
+
+ fputs("\n"
+ "######## Recent display filters (latest last), cannot be altered through command line ########\n"
+ "\n", rf);
+
+ dfilter_recent_combo_write_all(rf);
+
+#ifdef HAVE_PCAP_REMOTE
+ fputs("\n"
+ "######## Recent remote hosts, cannot be altered through command line ########\n"
+ "\n", rf);
+
+ capture_remote_combo_recent_write_all(rf);
+#endif
+
+ fprintf(rf, "\n# Main window geometry.\n");
+ fprintf(rf, "# Decimal numbers.\n");
+ fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_X ": %d\n", recent.gui_geometry_main_x);
+ fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_Y ": %d\n", recent.gui_geometry_main_y);
+ fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_WIDTH ": %d\n",
+ recent.gui_geometry_main_width);
+ fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_HEIGHT ": %d\n",
+ recent.gui_geometry_main_height);
+
+ fprintf(rf, "\n# Main window maximized.\n");
+ fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
+ fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_MAXIMIZED ": %s\n",
+ recent.gui_geometry_main_maximized == TRUE ? "TRUE" : "FALSE");
+
+ fprintf(rf, "\n# Statusbar left pane size.\n");
+ fprintf(rf, "# Decimal number.\n");
+ if (recent.gui_geometry_status_pane_left != 0) {
+ fprintf(rf, RECENT_GUI_GEOMETRY_STATUS_PANE_LEFT ": %d\n",
+ recent.gui_geometry_status_pane_left);
+ }
+ fprintf(rf, "\n# Statusbar middle pane size.\n");
+ fprintf(rf, "# Decimal number.\n");
+ if (recent.gui_geometry_status_pane_right != 0) {
+ fprintf(rf, RECENT_GUI_GEOMETRY_STATUS_PANE_RIGHT ": %d\n",
+ recent.gui_geometry_status_pane_right);
+ }
+
+ fprintf(rf, "\n# Last used Configuration Profile.\n");
+ fprintf(rf, RECENT_LAST_USED_PROFILE ": %s\n", get_profile_name());
+
+ fprintf(rf, "\n# WLAN statistics upper pane size.\n");
+ fprintf(rf, "# Decimal number.\n");
+ fprintf(rf, RECENT_GUI_GEOMETRY_WLAN_STATS_PANE ": %d\n",
+ recent.gui_geometry_wlan_stats_pane);
+
+ fprintf(rf, "\n# Warn if running with elevated permissions (e.g. as root).\n");
+ fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
+ fprintf(rf, RECENT_KEY_PRIVS_WARN_IF_ELEVATED ": %s\n",
+ recent.privs_warn_if_elevated == TRUE ? "TRUE" : "FALSE");
+
+ fprintf(rf, "\n# Warn if npf.sys isn't loaded on Windows >= 6.0.\n");
+ fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
+ fprintf(rf, RECENT_KEY_PRIVS_WARN_IF_NO_NPF ": %s\n",
+ recent.privs_warn_if_no_npf == TRUE ? "TRUE" : "FALSE");
+
+ window_geom_recent_write_all(rf);
+
+ fclose(rf);
+
+ /* XXX - catch I/O errors (e.g. "ran out of disk space") and return
+ an error indication, or maybe write to a new recent file and
+ rename that file on top of the old one only if there are not I/O
+ errors. */
+ return TRUE;
+}
+
+
+/* Attempt to Write out profile "recent" to the user's profile recent file.
+ If we got an error report it with a dialog box and return FALSE,
+ otherwise return TRUE. */
+gboolean
+write_profile_recent(void)
+{
+ char *pf_dir_path;
+ char *rf_path;
+ FILE *rf;
+
+ /* To do:
+ * - Split output lines longer than MAX_VAL_LEN
+ * - Create a function for the preference directory check/creation
+ * so that duplication can be avoided with filter.c
+ */
+
+ /* Create the directory that holds personal configuration files, if
+ necessary. */
+ if (create_persconffile_dir(&pf_dir_path) == -1) {
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+ "Can't create directory\n\"%s\"\nfor recent file: %s.", pf_dir_path,
+ g_strerror(errno));
+ g_free(pf_dir_path);
+ return FALSE;
+ }
+
+ rf_path = get_persconffile_path(RECENT_FILE_NAME, TRUE, TRUE);
+ if ((rf = ws_fopen(rf_path, "w")) == NULL) {
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+ "Can't open recent file\n\"%s\": %s.", rf_path,
+ g_strerror(errno));
+ g_free(rf_path);
+ return FALSE;
+ }
+ g_free(rf_path);
+
+ fputs("# Recent settings file for Wireshark " VERSION ".\n"
+ "#\n"
+ "# This file is regenerated each time Wireshark is quit\n"
+ "# and when changing configuration profile.\n"
+ "# So be careful, if you want to make manual changes here.\n"
+ "\n", rf);
+
+ fprintf(rf, "\n# Main Toolbar show (hide).\n");
+ fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
+ fprintf(rf, RECENT_KEY_MAIN_TOOLBAR_SHOW ": %s\n",
+ recent.main_toolbar_show == TRUE ? "TRUE" : "FALSE");
+
+ fprintf(rf, "\n# Filter Toolbar show (hide).\n");
+ fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
+ fprintf(rf, RECENT_KEY_FILTER_TOOLBAR_SHOW ": %s\n",
+ recent.filter_toolbar_show == TRUE ? "TRUE" : "FALSE");
+
+ fprintf(rf, "\n# Wireless Settings Toolbar show (hide).\n");
+ fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
+ fprintf(rf, RECENT_KEY_WIRELESS_TOOLBAR_SHOW ": %s\n",
+ recent.wireless_toolbar_show == TRUE ? "TRUE" : "FALSE");
+
+#ifdef HAVE_AIRPCAP
+ fprintf(rf, "\n# Show (hide) old AirPcap driver warning dialog box.\n");
+ fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
+ fprintf(rf, RECENT_KEY_DRIVER_CHECK_SHOW ": %s\n",
+ recent.airpcap_driver_check_show == TRUE ? "TRUE" : "FALSE");
+#endif
+
+ fprintf(rf, "\n# Packet list show (hide).\n");
+ fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
+ fprintf(rf, RECENT_KEY_PACKET_LIST_SHOW ": %s\n",
+ recent.packet_list_show == TRUE ? "TRUE" : "FALSE");
+
+ fprintf(rf, "\n# Tree view show (hide).\n");
+ fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
+ fprintf(rf, RECENT_KEY_TREE_VIEW_SHOW ": %s\n",
+ recent.tree_view_show == TRUE ? "TRUE" : "FALSE");
+
+ fprintf(rf, "\n# Byte view show (hide).\n");
+ fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
+ fprintf(rf, RECENT_KEY_BYTE_VIEW_SHOW ": %s\n",
+ recent.byte_view_show == TRUE ? "TRUE" : "FALSE");
+
+ fprintf(rf, "\n# Statusbar show (hide).\n");
+ fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
+ fprintf(rf, RECENT_KEY_STATUSBAR_SHOW ": %s\n",
+ recent.statusbar_show == TRUE ? "TRUE" : "FALSE");
+
+ fprintf(rf, "\n# Packet list colorize (hide).\n");
+ fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
+ fprintf(rf, RECENT_KEY_PACKET_LIST_COLORIZE ": %s\n",
+ recent.packet_list_colorize == TRUE ? "TRUE" : "FALSE");
+
+ fprintf(rf, "\n# Timestamp display format.\n");
+ fprintf(rf, "# One of: RELATIVE, ABSOLUTE, ABSOLUTE_WITH_DATE, DELTA, DELTA_DIS, EPOCH, UTC, UTC_WITH_DATE\n");
+ fprintf(rf, RECENT_GUI_TIME_FORMAT ": %s\n",
+ ts_type_text[recent.gui_time_format]);
+
+ fprintf(rf, "\n# Timestamp display precision.\n");
+ fprintf(rf, "# One of: AUTO, SEC, DSEC, CSEC, MSEC, USEC, NSEC\n");
+ fprintf(rf, RECENT_GUI_TIME_PRECISION ": %s\n",
+ ts_precision_text[recent.gui_time_precision]);
+
+ fprintf(rf, "\n# Seconds display format.\n");
+ fprintf(rf, "# One of: SECONDS, HOUR_MIN_SEC\n");
+ fprintf(rf, RECENT_GUI_SECONDS_FORMAT ": %s\n",
+ ts_seconds_text[recent.gui_seconds_format]);
+
+ fprintf(rf, "\n# Zoom level.\n");
+ fprintf(rf, "# A decimal number.\n");
+ fprintf(rf, RECENT_GUI_ZOOM_LEVEL ": %d\n",
+ recent.gui_zoom_level);
+
+ fprintf(rf, "\n# Bytes view.\n");
+ fprintf(rf, "# A decimal number.\n");
+ fprintf(rf, RECENT_GUI_BYTES_VIEW ": %d\n",
+ recent.gui_bytes_view);
+
+ fprintf(rf, "\n# Main window upper (or leftmost) pane size.\n");
+ fprintf(rf, "# Decimal number.\n");
+ if (recent.gui_geometry_main_upper_pane != 0) {
+ fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_UPPER_PANE ": %d\n",
+ recent.gui_geometry_main_upper_pane);
+ }
+ fprintf(rf, "\n# Main window middle pane size.\n");
+ fprintf(rf, "# Decimal number.\n");
+ if (recent.gui_geometry_main_lower_pane != 0) {
+ fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_LOWER_PANE ": %d\n",
+ recent.gui_geometry_main_lower_pane);
+ }
+
+ fprintf(rf, "\n# Packet list column pixel widths.\n");
+ fprintf(rf, "# Each pair of strings consists of a column format and its pixel width.\n");
+ packet_list_recent_write_all(rf);
+
+ if (get_last_open_dir() != NULL) {
+ fprintf(rf, "\n# Last directory navigated to in File Open dialog.\n");
+
+ if(u3_active())
+ fprintf(rf, RECENT_GUI_FILEOPEN_REMEMBERED_DIR ": %s\n", u3_contract_device_path(get_last_open_dir()));
+ else
+ fprintf(rf, RECENT_GUI_FILEOPEN_REMEMBERED_DIR ": %s\n", get_last_open_dir());
+ }
+
+ fclose(rf);
+
+ /* XXX - catch I/O errors (e.g. "ran out of disk space") and return
+ an error indication, or maybe write to a new recent file and
+ rename that file on top of the old one only if there are not I/O
+ errors. */
+ return TRUE;
+}
+
+
+/* write the geometry values of a window to recent file */
+void
+write_recent_geom(gpointer key _U_, gpointer value, gpointer rf)
+{
+ window_geometry_t *geom = value;
+
+ fprintf(rf, "\n# Geometry and maximized state of %s window.\n", geom->key);
+ fprintf(rf, "# Decimal integers.\n");
+ fprintf(rf, RECENT_GUI_GEOMETRY "%s.x: %d\n", geom->key, geom->x);
+ fprintf(rf, RECENT_GUI_GEOMETRY "%s.y: %d\n", geom->key, geom->y);
+ fprintf(rf, RECENT_GUI_GEOMETRY "%s.width: %d\n", geom->key,
+ geom->width);
+ fprintf(rf, RECENT_GUI_GEOMETRY "%s.height: %d\n", geom->key,
+ geom->height);
+
+ fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
+ fprintf(rf, RECENT_GUI_GEOMETRY "%s.maximized: %s\n", geom->key,
+ geom->maximized == TRUE ? "TRUE" : "FALSE");
+
+}
+
+/* set one user's recent common file key/value pair */
+static prefs_set_pref_e
+read_set_recent_common_pair_static(gchar *key, const gchar *value,
+ void *private_data _U_,
+ gboolean return_range_errors _U_)
+{
+ long num;
+ char *p;
+
+ if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_MAXIMIZED) == 0) {
+ if (g_ascii_strcasecmp(value, "true") == 0) {
+ recent.gui_geometry_main_maximized = TRUE;
+ }
+ else {
+ recent.gui_geometry_main_maximized = FALSE;
+ }
+
+ } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_X) == 0) {
+ num = strtol(value, &p, 0);
+ if (p == value || *p != '\0')
+ return PREFS_SET_SYNTAX_ERR; /* number was bad */
+ recent.gui_geometry_main_x = (gint)num;
+ } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_Y) == 0) {
+ num = strtol(value, &p, 0);
+ if (p == value || *p != '\0')
+ return PREFS_SET_SYNTAX_ERR; /* number was bad */
+ recent.gui_geometry_main_y = (gint)num;
+ } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_WIDTH) == 0) {
+ num = strtol(value, &p, 0);
+ if (p == value || *p != '\0')
+ return PREFS_SET_SYNTAX_ERR; /* number was bad */
+ if (num <= 0)
+ return PREFS_SET_SYNTAX_ERR; /* number must be positive */
+ recent.gui_geometry_main_width = (gint)num;
+ } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_HEIGHT) == 0) {
+ num = strtol(value, &p, 0);
+ if (p == value || *p != '\0')
+ return PREFS_SET_SYNTAX_ERR; /* number was bad */
+ if (num <= 0)
+ return PREFS_SET_SYNTAX_ERR; /* number must be positive */
+ recent.gui_geometry_main_height = (gint)num;
+ } else if (strcmp(key, RECENT_GUI_GEOMETRY_STATUS_PANE_RIGHT) == 0) {
+ num = strtol(value, &p, 0);
+ if (p == value || *p != '\0')
+ return PREFS_SET_SYNTAX_ERR; /* number was bad */
+ if (num <= 0)
+ return PREFS_SET_SYNTAX_ERR; /* number must be positive */
+ recent.gui_geometry_status_pane_right = (gint)num;
+ recent.has_gui_geometry_status_pane = TRUE;
+ } else if (strcmp(key, RECENT_GUI_GEOMETRY_STATUS_PANE_LEFT) == 0) {
+ num = strtol(value, &p, 0);
+ if (p == value || *p != '\0')
+ return PREFS_SET_SYNTAX_ERR; /* number was bad */
+ if (num <= 0)
+ return PREFS_SET_SYNTAX_ERR; /* number must be positive */
+ recent.gui_geometry_status_pane_left = (gint)num;
+ recent.has_gui_geometry_status_pane = TRUE;
+ } else if (strcmp(key, RECENT_LAST_USED_PROFILE) == 0) {
+ if ((strcmp(value, DEFAULT_PROFILE) != 0) && profile_exists (value, FALSE)) {
+ set_profile_name (value);
+ }
+ } else if (strcmp(key, RECENT_GUI_GEOMETRY_WLAN_STATS_PANE) == 0) {
+ num = strtol(value, &p, 0);
+ if (p == value || *p != '\0')
+ return PREFS_SET_SYNTAX_ERR; /* number was bad */
+ if (num <= 0)
+ return PREFS_SET_SYNTAX_ERR; /* number must be positive */
+ recent.gui_geometry_wlan_stats_pane = (gint)num;
+ } else if (strncmp(key, RECENT_GUI_GEOMETRY, sizeof(RECENT_GUI_GEOMETRY)-1) == 0) {
+ /* now have something like "gui.geom.main.x", split it into win and sub_key */
+ char *win = &key[sizeof(RECENT_GUI_GEOMETRY)-1];
+ char *sub_key = strchr(win, '.');
+ if(sub_key) {
+ *sub_key = '\0';
+ sub_key++;
+ window_geom_recent_read_pair(win, sub_key, value);
+ }
+ } else if (strcmp(key, RECENT_KEY_PRIVS_WARN_IF_ELEVATED) == 0) {
+ if (g_ascii_strcasecmp(value, "true") == 0) {
+ recent.privs_warn_if_elevated = TRUE;
+ }
+ else {
+ recent.privs_warn_if_elevated = FALSE;
+ }
+ } else if (strcmp(key, RECENT_KEY_PRIVS_WARN_IF_NO_NPF) == 0) {
+ if (g_ascii_strcasecmp(value, "true") == 0) {
+ recent.privs_warn_if_no_npf = TRUE;
+ }
+ else {
+ recent.privs_warn_if_no_npf = FALSE;
+ }
+ }
+
+ return PREFS_SET_OK;
+}
+
+/* set one user's recent file key/value pair */
+static prefs_set_pref_e
+read_set_recent_pair_static(gchar *key, const gchar *value,
+ void *private_data _U_,
+ gboolean return_range_errors _U_)
+{
+ long num;
+ char *p;
+ GList *col_l, *col_l_elt;
+ col_width_data *cfmt;
+ const gchar *cust_format = col_format_to_string(COL_CUSTOM);
+ int cust_format_len = (int) strlen(cust_format);
+
+ if (strcmp(key, RECENT_KEY_MAIN_TOOLBAR_SHOW) == 0) {
+ if (g_ascii_strcasecmp(value, "true") == 0) {
+ recent.main_toolbar_show = TRUE;
+ }
+ else {
+ recent.main_toolbar_show = FALSE;
+ }
+ } else if (strcmp(key, RECENT_KEY_FILTER_TOOLBAR_SHOW) == 0) {
+ if (g_ascii_strcasecmp(value, "true") == 0) {
+ recent.filter_toolbar_show = TRUE;
+ }
+ else {
+ recent.filter_toolbar_show = FALSE;
+ }
+ /* check both the old and the new keyword */
+ } else if (strcmp(key, RECENT_KEY_WIRELESS_TOOLBAR_SHOW) == 0 || (strcmp(key, "gui.airpcap_toolbar_show") == 0)) {
+ if (g_ascii_strcasecmp(value, "true") == 0) {
+ recent.wireless_toolbar_show = TRUE;
+ }
+ else {
+ recent.wireless_toolbar_show = FALSE;
+ }
+ } else if (strcmp(key, RECENT_KEY_DRIVER_CHECK_SHOW) == 0) {
+ if (g_ascii_strcasecmp(value, "true") == 0) {
+ recent.airpcap_driver_check_show = TRUE;
+ }
+ else {
+ recent.airpcap_driver_check_show = FALSE;
+ }
+ } else if (strcmp(key, RECENT_KEY_PACKET_LIST_SHOW) == 0) {
+ if (g_ascii_strcasecmp(value, "true") == 0) {
+ recent.packet_list_show = TRUE;
+ }
+ else {
+ recent.packet_list_show = FALSE;
+ }
+ } else if (strcmp(key, RECENT_KEY_TREE_VIEW_SHOW) == 0) {
+ if (g_ascii_strcasecmp(value, "true") == 0) {
+ recent.tree_view_show = TRUE;
+ }
+ else {
+ recent.tree_view_show = FALSE;
+ }
+ } else if (strcmp(key, RECENT_KEY_BYTE_VIEW_SHOW) == 0) {
+ if (g_ascii_strcasecmp(value, "true") == 0) {
+ recent.byte_view_show = TRUE;
+ }
+ else {
+ recent.byte_view_show = FALSE;
+ }
+ } else if (strcmp(key, RECENT_KEY_STATUSBAR_SHOW) == 0) {
+ if (g_ascii_strcasecmp(value, "true") == 0) {
+ recent.statusbar_show = TRUE;
+ }
+ else {
+ recent.statusbar_show = FALSE;
+ }
+ } else if (strcmp(key, RECENT_KEY_PACKET_LIST_COLORIZE) == 0) {
+ if (g_ascii_strcasecmp(value, "true") == 0) {
+ recent.packet_list_colorize = TRUE;
+ }
+ else {
+ recent.packet_list_colorize = FALSE;
+ }
+ } else if (strcmp(key, RECENT_GUI_TIME_FORMAT) == 0) {
+ recent.gui_time_format =
+ find_index_from_string_array(value, ts_type_text, TS_RELATIVE);
+ } else if (strcmp(key, RECENT_GUI_TIME_PRECISION) == 0) {
+ recent.gui_time_precision =
+ find_index_from_string_array(value, ts_precision_text, TS_PREC_AUTO);
+ } else if (strcmp(key, RECENT_GUI_SECONDS_FORMAT) == 0) {
+ recent.gui_seconds_format =
+ find_index_from_string_array(value, ts_seconds_text, TS_SECONDS_DEFAULT);
+ } else if (strcmp(key, RECENT_GUI_ZOOM_LEVEL) == 0) {
+ num = strtol(value, &p, 0);
+ if (p == value || *p != '\0')
+ return PREFS_SET_SYNTAX_ERR; /* number was bad */
+ recent.gui_zoom_level = (gint)num;
+ } else if (strcmp(key, RECENT_GUI_BYTES_VIEW) == 0) {
+ num = strtol(value, &p, 0);
+ if (p == value || *p != '\0')
+ return PREFS_SET_SYNTAX_ERR; /* number was bad */
+ recent.gui_bytes_view = (gint)num;
+ } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_MAXIMIZED) == 0) {
+ if (g_ascii_strcasecmp(value, "true") == 0) {
+ recent.gui_geometry_main_maximized = TRUE;
+ }
+ else {
+ recent.gui_geometry_main_maximized = FALSE;
+ }
+
+ } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_UPPER_PANE) == 0) {
+ num = strtol(value, &p, 0);
+ if (p == value || *p != '\0')
+ return PREFS_SET_SYNTAX_ERR; /* number was bad */
+ if (num <= 0)
+ return PREFS_SET_SYNTAX_ERR; /* number must be positive */
+ recent.gui_geometry_main_upper_pane = (gint)num;
+ recent.has_gui_geometry_main_upper_pane = TRUE;
+ } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_LOWER_PANE) == 0) {
+ num = strtol(value, &p, 0);
+ if (p == value || *p != '\0')
+ return PREFS_SET_SYNTAX_ERR; /* number was bad */
+ if (num <= 0)
+ return PREFS_SET_SYNTAX_ERR; /* number must be positive */
+ recent.gui_geometry_main_lower_pane = (gint)num;
+ recent.has_gui_geometry_main_lower_pane = TRUE;
+ }
+ else if (strcmp(key, RECENT_KEY_COL_WIDTH) == 0) {
+ col_l = prefs_get_string_list(value);
+ if (col_l == NULL)
+ return PREFS_SET_SYNTAX_ERR;
+ if ((g_list_length(col_l) % 2) != 0) {
+ /* A title didn't have a matching width. */
+ prefs_clear_string_list(col_l);
+ return PREFS_SET_SYNTAX_ERR;
+ }
+ /* Check to make sure all column formats are valid. */
+ col_l_elt = g_list_first(col_l);
+ while(col_l_elt) {
+ /* Make sure the format isn't empty. */
+ if (strcmp(col_l_elt->data, "") == 0) {
+ /* It is. */
+ prefs_clear_string_list(col_l);
+ return PREFS_SET_SYNTAX_ERR;
+ }
+
+ /* Check the format. */
+ if (strncmp(col_l_elt->data, cust_format, cust_format_len) != 0) {
+ if (get_column_format_from_str(col_l_elt->data) == -1) {
+ /* It's not a valid column format. */
+ prefs_clear_string_list(col_l);
+ return PREFS_SET_SYNTAX_ERR;
+ }
+ }
+
+ /* Go past the format. */
+ col_l_elt = col_l_elt->next;
+
+ /* Go past the width. */
+ col_l_elt = col_l_elt->next;
+ }
+ free_col_width_info(&recent);
+ recent.col_width_list = NULL;
+ col_l_elt = g_list_first(col_l);
+ while(col_l_elt) {
+ gchar *fmt = g_strdup(col_l_elt->data);
+ cfmt = (col_width_data *) g_malloc(sizeof(col_width_data));
+ if (strncmp(fmt, cust_format, cust_format_len) != 0) {
+ cfmt->cfmt = get_column_format_from_str(fmt);
+ cfmt->cfield = NULL;
+ } else {
+ cfmt->cfmt = COL_CUSTOM;
+ cfmt->cfield = g_strdup(&fmt[cust_format_len+1]); /* add 1 for ':' */
+ }
+ g_free (fmt);
+ if (cfmt->cfmt == -1) {
+ g_free(cfmt->cfield);
+ g_free(cfmt);
+ return PREFS_SET_SYNTAX_ERR; /* string was bad */
+ }
+
+ col_l_elt = col_l_elt->next;
+ cfmt->width = (gint)strtol(col_l_elt->data, &p, 0);
+ if (p == col_l_elt->data || (*p != '\0' && *p != ':')) {
+ g_free(cfmt->cfield);
+ g_free(cfmt);
+ return PREFS_SET_SYNTAX_ERR; /* number was bad */
+ }
+
+ if (*p == ':') {
+ cfmt->xalign = *(++p);
+ } else {
+ cfmt->xalign = COLUMN_XALIGN_DEFAULT;
+ }
+
+ col_l_elt = col_l_elt->next;
+ recent.col_width_list = g_list_append(recent.col_width_list, cfmt);
+ }
+ prefs_clear_string_list(col_l);
+ } else if (strcmp(key, RECENT_GUI_FILEOPEN_REMEMBERED_DIR) == 0) {
+ if (recent.gui_fileopen_remembered_dir) {
+ g_free (recent.gui_fileopen_remembered_dir);
+ }
+ recent.gui_fileopen_remembered_dir = g_strdup(value);
+ }
+
+ return PREFS_SET_OK;
+}
+
+
+/* set one user's recent file key/value pair */
+static prefs_set_pref_e
+read_set_recent_pair_dynamic(gchar *key, const gchar *value,
+ void *private_data _U_,
+ gboolean return_range_errors _U_)
+{
+ if (!isprint_string(value)) {
+ return PREFS_SET_SYNTAX_ERR;
+ }
+ if (strcmp(key, RECENT_KEY_CAPTURE_FILE) == 0) {
+ if(u3_active())
+ add_menu_recent_capture_file(u3_expand_device_path(value));
+ else
+ add_menu_recent_capture_file(value);
+ } else if (strcmp(key, RECENT_KEY_DISPLAY_FILTER) == 0) {
+ dfilter_combo_add_recent(value);
+ } else if (strcmp(key, RECENT_KEY_CAPTURE_FILTER) == 0) {
+ cfilter_combo_add_recent(value);
+#ifdef HAVE_PCAP_REMOTE
+ } else if (strcmp(key, RECENT_KEY_REMOTE_HOST) == 0) {
+ capture_remote_combo_add_recent(value);
+#endif
+ }
+
+ return PREFS_SET_OK;
+}
+
+
+/*
+ * Given a string of the form "<recent name>:<recent value>", as might appear
+ * as an argument to a "-o" option, parse it and set the recent value in
+ * question. Return an indication of whether it succeeded or failed
+ * in some fashion.
+ */
+int
+recent_set_arg(char *prefarg)
+{
+ gchar *p, *colonp;
+ int ret;
+
+ colonp = strchr(prefarg, ':');
+ if (colonp == NULL)
+ return PREFS_SET_SYNTAX_ERR;
+
+ p = colonp;
+ *p++ = '\0';
+
+ /*
+ * Skip over any white space (there probably won't be any, but
+ * as we allow it in the preferences file, we might as well
+ * allow it here).
+ */
+ while (isspace((guchar)*p))
+ p++;
+ if (*p == '\0') {
+ /*
+ * Put the colon back, so if our caller uses, in an
+ * error message, the string they passed us, the message
+ * looks correct.
+ */
+ *colonp = ':';
+ return PREFS_SET_SYNTAX_ERR;
+ }
+
+ ret = read_set_recent_pair_static(prefarg, p, NULL, TRUE);
+ *colonp = ':'; /* put the colon back */
+ return ret;
+}
+
+
+/* opens the user's recent common file and read the first part */
+void
+recent_read_static(char **rf_path_return, int *rf_errno_return)
+{
+ char *rf_path;
+ FILE *rf;
+
+ /* set defaults */
+ recent.gui_geometry_main_x = 20;
+ recent.gui_geometry_main_y = 20;
+ recent.gui_geometry_main_width = DEF_WIDTH;
+ recent.gui_geometry_main_height = DEF_HEIGHT;
+ recent.gui_geometry_main_maximized= FALSE;
+
+ recent.gui_geometry_status_pane_left = (DEF_WIDTH/3);
+ recent.gui_geometry_status_pane_right = (DEF_WIDTH/3);
+ recent.gui_geometry_wlan_stats_pane = 200;
+
+ recent.privs_warn_if_elevated = TRUE;
+ recent.privs_warn_if_no_npf = TRUE;
+
+ recent.col_width_list = NULL;
+ recent.gui_fileopen_remembered_dir = NULL;
+
+ /* Construct the pathname of the user's recent common file. */
+ rf_path = get_persconffile_path(RECENT_COMMON_FILE_NAME, FALSE, FALSE);
+
+ /* Read the user's recent common file, if it exists. */
+ *rf_path_return = NULL;
+ if ((rf = ws_fopen(rf_path, "r")) != NULL) {
+ /* We succeeded in opening it; read it. */
+ read_prefs_file(rf_path, rf, read_set_recent_common_pair_static, NULL);
+
+ fclose(rf);
+ g_free(rf_path);
+ rf_path = NULL;
+ } else {
+ /* We failed to open it. If we failed for some reason other than
+ "it doesn't exist", return the errno and the pathname, so our
+ caller can report the error. */
+ if (errno != ENOENT) {
+ *rf_errno_return = errno;
+ *rf_path_return = rf_path;
+ }
+ }
+}
+
+
+
+/* opens the user's recent file and read the first part */
+void
+recent_read_profile_static(char **rf_path_return, int *rf_errno_return)
+{
+ char *rf_path, *rf_common_path;
+ FILE *rf;
+
+ /* set defaults */
+ recent.main_toolbar_show = TRUE;
+ recent.filter_toolbar_show = TRUE;
+ recent.wireless_toolbar_show = FALSE;
+ recent.airpcap_driver_check_show = TRUE;
+ recent.packet_list_show = TRUE;
+ recent.tree_view_show = TRUE;
+ recent.byte_view_show = TRUE;
+ recent.statusbar_show = TRUE;
+ recent.packet_list_colorize = TRUE;
+ recent.gui_time_format = TS_RELATIVE;
+ recent.gui_time_precision = TS_PREC_AUTO;
+ recent.gui_seconds_format = TS_SECONDS_DEFAULT;
+ recent.gui_zoom_level = 0;
+ recent.gui_bytes_view = 0;
+
+ /* pane size of zero will autodetect */
+ recent.gui_geometry_main_upper_pane = 0;
+ recent.gui_geometry_main_lower_pane = 0;
+
+ recent.has_gui_geometry_main_upper_pane = TRUE;
+ recent.has_gui_geometry_main_lower_pane = TRUE;
+ recent.has_gui_geometry_status_pane = TRUE;
+
+ if (recent.col_width_list) {
+ free_col_width_info(&recent);
+ }
+
+ if (recent.gui_fileopen_remembered_dir) {
+ g_free (recent.gui_fileopen_remembered_dir);
+ recent.gui_fileopen_remembered_dir = NULL;
+ }
+
+ /* Construct the pathname of the user's profile recent file. */
+ rf_path = get_persconffile_path(RECENT_FILE_NAME, TRUE, FALSE);
+
+ /* Read the user's recent file, if it exists. */
+ *rf_path_return = NULL;
+ if ((rf = ws_fopen(rf_path, "r")) != NULL) {
+ /* We succeeded in opening it; read it. */
+ read_prefs_file(rf_path, rf, read_set_recent_pair_static, NULL);
+ fclose(rf);
+
+ /* XXX: The following code doesn't actually do anything since
+ * the "recent common file" always exists. Presumably the
+ * "if (!file_exists())" should actually be "if (file_exists())".
+ * However, I've left the code as is because this
+ * behaviour has existed for quite some time and I don't
+ * know what's supposed to happen at this point.
+ * ToDo: Determine if the "recent common file" should be read at this point
+ */
+ rf_common_path = get_persconffile_path(RECENT_COMMON_FILE_NAME, FALSE, FALSE);
+ if (!file_exists(rf_common_path)) {
+ /* Read older common settings from recent file */
+ rf = ws_fopen(rf_path, "r");
+ read_prefs_file(rf_path, rf, read_set_recent_common_pair_static, NULL);
+ fclose(rf);
+ }
+ g_free(rf_common_path);
+ g_free(rf_path);
+ rf_path = NULL;
+ } else {
+ /* We failed to open it. If we failed for some reason other than
+ "it doesn't exist", return the errno and the pathname, so our
+ caller can report the error. */
+ if (errno != ENOENT) {
+ *rf_errno_return = errno;
+ *rf_path_return = rf_path;
+ }
+ }
+}
+
+/* opens the user's recent file and read it out */
+void
+recent_read_dynamic(char **rf_path_return, int *rf_errno_return)
+{
+ char *rf_path;
+ FILE *rf;
+
+
+ /* Construct the pathname of the user's recent common file. */
+ rf_path = get_persconffile_path(RECENT_COMMON_FILE_NAME, FALSE, FALSE);
+ if (!file_exists (rf_path)) {
+ /* Recent common file does not exist, read from default recent */
+ g_free (rf_path);
+ rf_path = get_persconffile_path(RECENT_FILE_NAME, FALSE, FALSE);
+ }
+
+ /* Read the user's recent file, if it exists. */
+ *rf_path_return = NULL;
+ if ((rf = ws_fopen(rf_path, "r")) != NULL) {
+ /* We succeeded in opening it; read it. */
+ read_prefs_file(rf_path, rf, read_set_recent_pair_dynamic, NULL);
+#if 0
+ /* set dfilter combobox to have an empty line */
+ dfilter_combo_add_empty();
+#endif
+ fclose(rf);
+ g_free(rf_path);
+ rf_path = NULL;
+ } else {
+ /* We failed to open it. If we failed for some reason other than
+ "it doesn't exist", return the errno and the pathname, so our
+ caller can report the error. */
+ if (errno != ENOENT) {
+ *rf_errno_return = errno;
+ *rf_path_return = rf_path;
+ }
+ }
+}
+
+gint
+recent_get_column_width(gint col)
+{
+ GList *col_l;
+ col_width_data *col_w;
+ gint cfmt;
+ const gchar *cfield = NULL;
+
+ cfmt = get_column_format(col);
+ if (cfmt == COL_CUSTOM) {
+ cfield = get_column_custom_field(col);
+ }
+
+ col_l = g_list_first(recent.col_width_list);
+ while (col_l) {
+ col_w = (col_width_data *) col_l->data;
+ if (col_w->cfmt == cfmt) {
+ if (cfmt != COL_CUSTOM || strcmp (cfield, col_w->cfield) == 0) {
+ return col_w->width;
+ }
+ }
+ col_l = col_l->next;
+ }
+
+ return -1;
+}
+
+void
+recent_set_column_width(gint col, gint width)
+{
+ GList *col_l;
+ col_width_data *col_w;
+ gint cfmt;
+ const gchar *cfield = NULL;
+ gboolean found = FALSE;
+
+ cfmt = get_column_format(col);
+ if (cfmt == COL_CUSTOM) {
+ cfield = get_column_custom_field(col);
+ }
+
+ col_l = g_list_first(recent.col_width_list);
+ while (col_l) {
+ col_w = (col_width_data *) col_l->data;
+ if (col_w->cfmt == cfmt) {
+ if (cfmt != COL_CUSTOM || strcmp (cfield, col_w->cfield) == 0) {
+ col_w->width = width;
+ found = TRUE;
+ break;
+ }
+ }
+ col_l = col_l->next;
+ }
+
+ if (!found) {
+ col_w = (col_width_data *) g_malloc(sizeof(col_width_data));
+ col_w->cfmt = cfmt;
+ if (cfield) {
+ col_w->cfield = g_strdup(cfield);
+ } else {
+ col_w->cfield = NULL;
+ }
+ col_w->width = width;
+ col_w->xalign = COLUMN_XALIGN_DEFAULT;
+ recent.col_width_list = g_list_append(recent.col_width_list, col_w);
+ }
+}
+
+gchar
+recent_get_column_xalign(gint col)
+{
+ GList *col_l;
+ col_width_data *col_w;
+ gint cfmt;
+ const gchar *cfield = NULL;
+
+ cfmt = get_column_format(col);
+ if (cfmt == COL_CUSTOM) {
+ cfield = get_column_custom_field(col);
+ }
+
+ col_l = g_list_first(recent.col_width_list);
+ while (col_l) {
+ col_w = (col_width_data *) col_l->data;
+ if (col_w->cfmt == cfmt) {
+ if (cfmt != COL_CUSTOM || strcmp (cfield, col_w->cfield) == 0) {
+ return col_w->xalign;
+ }
+ }
+ col_l = col_l->next;
+ }
+
+ return 0;
+}
+
+void
+recent_set_column_xalign(gint col, gchar xalign)
+{
+ GList *col_l;
+ col_width_data *col_w;
+ gint cfmt;
+ const gchar *cfield = NULL;
+ gboolean found = FALSE;
+
+ cfmt = get_column_format(col);
+ if (cfmt == COL_CUSTOM) {
+ cfield = get_column_custom_field(col);
+ }
+
+ col_l = g_list_first(recent.col_width_list);
+ while (col_l) {
+ col_w = (col_width_data *) col_l->data;
+ if (col_w->cfmt == cfmt) {
+ if (cfmt != COL_CUSTOM || strcmp (cfield, col_w->cfield) == 0) {
+ col_w->xalign = xalign;
+ found = TRUE;
+ break;
+ }
+ }
+ col_l = col_l->next;
+ }
+
+ if (!found) {
+ col_w = (col_width_data *) g_malloc(sizeof(col_width_data));
+ col_w->cfmt = cfmt;
+ if (cfield) {
+ col_w->cfield = g_strdup(cfield);
+ } else {
+ col_w->cfield = NULL;
+ }
+ col_w->width = 40;
+ col_w->xalign = xalign;
+ recent.col_width_list = g_list_append(recent.col_width_list, col_w);
+ }
+}