2 * Recent "preference" handling routines
3 * Copyright 2004, Ulf Lamping <ulf.lamping@web.de>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
35 #include <epan/epan.h>
36 #include <epan/filesystem.h>
37 #include <epan/emem.h>
38 #include <epan/prefs.h>
39 #include <epan/prefs-int.h>
40 #include <epan/column.h>
42 #include "../simple_dialog.h"
44 #include <wsutil/file_util.h>
46 #include "gtk/recent.h"
48 #include "gtk/menus.h"
49 #include "gtk/gui_utils.h"
50 #ifdef NEW_PACKET_LIST
51 #include "gtk/new_packet_list.h"
53 #include "gtk/main_packet_list.h"
54 #endif /*NEW_PACKET_LIST */
55 #include "gtk/file_dlg.h"
56 #include "gtk/cfilter_combo_utils.h"
58 #ifdef HAVE_PCAP_REMOTE
59 #include "gtk/capture_dlg.h"
62 #define RECENT_KEY_MAIN_TOOLBAR_SHOW "gui.toolbar_main_show"
63 #define RECENT_KEY_FILTER_TOOLBAR_SHOW "gui.filter_toolbar_show"
64 #define RECENT_KEY_AIRPCAP_TOOLBAR_SHOW "gui.airpcap_toolbar_show"
65 #define RECENT_KEY_DRIVER_CHECK_SHOW "gui.airpcap_driver_check_show"
66 #define RECENT_KEY_PACKET_LIST_SHOW "gui.packet_list_show"
67 #define RECENT_KEY_TREE_VIEW_SHOW "gui.tree_view_show"
68 #define RECENT_KEY_BYTE_VIEW_SHOW "gui.byte_view_show"
69 #define RECENT_KEY_STATUSBAR_SHOW "gui.statusbar_show"
70 #define RECENT_KEY_PACKET_LIST_COLORIZE "gui.packet_list_colorize"
71 #define RECENT_GUI_TIME_FORMAT "gui.time_format"
72 #define RECENT_GUI_TIME_PRECISION "gui.time_precision"
73 #define RECENT_GUI_SECONDS_FORMAT "gui.seconds_format"
74 #define RECENT_GUI_ZOOM_LEVEL "gui.zoom_level"
75 #define RECENT_GUI_BYTES_VIEW "gui.bytes_view"
76 #define RECENT_GUI_GEOMETRY_MAIN_X "gui.geometry_main_x"
77 #define RECENT_GUI_GEOMETRY_MAIN_Y "gui.geometry_main_y"
78 #define RECENT_GUI_GEOMETRY_MAIN_WIDTH "gui.geometry_main_width"
79 #define RECENT_GUI_GEOMETRY_MAIN_HEIGHT "gui.geometry_main_height"
80 #define RECENT_GUI_GEOMETRY_MAIN_MAXIMIZED "gui.geometry_main_maximized"
81 #define RECENT_GUI_GEOMETRY_MAIN_UPPER_PANE "gui.geometry_main_upper_pane"
82 #define RECENT_GUI_GEOMETRY_MAIN_LOWER_PANE "gui.geometry_main_lower_pane"
83 #define RECENT_GUI_GEOMETRY_STATUS_PANE_LEFT "gui.geometry_status_pane"
84 #define RECENT_GUI_GEOMETRY_STATUS_PANE_RIGHT "gui.geometry_status_pane_right"
85 #define RECENT_GUI_GEOMETRY_WLAN_STATS_PANE "gui.geometry_status_wlan_stats_pane"
86 #define RECENT_LAST_USED_PROFILE "gui.last_used_profile"
87 #define RECENT_GUI_FILEOPEN_REMEMBERED_DIR "gui.fileopen_remembered_dir"
88 #define RECENT_GUI_GEOMETRY "gui.geom."
89 #define RECENT_KEY_PRIVS_WARN_IF_ELEVATED "privs.warn_if_elevated"
90 #define RECENT_KEY_PRIVS_WARN_IF_NO_NPF "privs.warn_if_no_npf"
92 #define RECENT_FILE_NAME "recent"
93 #define RECENT_COMMON_FILE_NAME "recent_common"
95 recent_settings_t recent;
97 static const char *ts_type_text[] =
98 { "RELATIVE", "ABSOLUTE", "ABSOLUTE_WITH_DATE", "DELTA", "DELTA_DIS", "EPOCH", NULL };
100 static const char *ts_precision_text[] =
101 { "AUTO", "SEC", "DSEC", "CSEC", "MSEC", "USEC", "NSEC", NULL };
103 static const char *ts_seconds_text[] =
104 { "SECONDS", "HOUR_MIN_SEC", NULL };
106 /* Takes an string and a pointer to an array of strings, and a default int value.
107 * The array must be terminated by a NULL string. If the string is found in the array
108 * of strings, the index of that string in the array is returned. Otherwise, the
109 * default value that was passed as the third argument is returned.
112 find_index_from_string_array(const char *needle, const char **haystack, int default_value)
116 while (haystack[i] != NULL) {
117 if (strcmp(needle, haystack[i]) == 0) {
122 return default_value;
126 free_col_width_info(recent_settings_t *rs)
128 col_width_data *cfmt;
130 while (rs->col_width_list != NULL) {
131 cfmt = rs->col_width_list->data;
132 g_free(cfmt->cfield);
134 rs->col_width_list = g_list_remove_link(rs->col_width_list, rs->col_width_list);
136 g_list_free(rs->col_width_list);
137 rs->col_width_list = NULL;
140 /* Attempt to Write out "recent common" to the user's recent common file.
141 If we got an error report it with a dialog box and return FALSE,
142 otherwise return TRUE. */
151 * - Split output lines longer than MAX_VAL_LEN
152 * - Create a function for the preference directory check/creation
153 * so that duplication can be avoided with filter.c
156 /* Create the directory that holds personal configuration files, if
158 if (create_persconffile_dir(&pf_dir_path) == -1) {
159 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
160 "Can't create directory\n\"%s\"\nfor recent file: %s.", pf_dir_path,
166 rf_path = get_persconffile_path(RECENT_COMMON_FILE_NAME, FALSE, TRUE);
167 if ((rf = ws_fopen(rf_path, "w")) == NULL) {
168 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
169 "Can't open recent file\n\"%s\": %s.", rf_path,
176 fputs("# Recent settings file for Wireshark " VERSION ".\n"
178 "# This file is regenerated each time Wireshark is quit.\n"
179 "# So be careful, if you want to make manual changes here.\n"
181 "######## Recent capture files (latest last), cannot be altered through command line ########\n"
184 menu_recent_file_write_all(rf);
187 "######## Recent capture filters (latest last), cannot be altered through command line ########\n"
190 cfilter_combo_recent_write_all(rf);
193 "######## Recent display filters (latest last), cannot be altered through command line ########\n"
196 dfilter_recent_combo_write_all(rf);
198 #ifdef HAVE_PCAP_REMOTE
200 "######## Recent remote hosts, cannot be altered through command line ########\n"
203 capture_remote_combo_recent_write_all(rf);
206 fprintf(rf, "\n# Main window geometry.\n");
207 fprintf(rf, "# Decimal numbers.\n");
208 fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_X ": %d\n", recent.gui_geometry_main_x);
209 fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_Y ": %d\n", recent.gui_geometry_main_y);
210 fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_WIDTH ": %d\n",
211 recent.gui_geometry_main_width);
212 fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_HEIGHT ": %d\n",
213 recent.gui_geometry_main_height);
215 fprintf(rf, "\n# Main window maximized.\n");
216 fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
217 fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_MAXIMIZED ": %s\n",
218 recent.gui_geometry_main_maximized == TRUE ? "TRUE" : "FALSE");
220 fprintf(rf, "\n# Statusbar left pane size.\n");
221 fprintf(rf, "# Decimal number.\n");
222 if (recent.gui_geometry_status_pane_left != 0) {
223 fprintf(rf, RECENT_GUI_GEOMETRY_STATUS_PANE_LEFT ": %d\n",
224 recent.gui_geometry_status_pane_left);
226 fprintf(rf, "\n# Statusbar middle pane size.\n");
227 fprintf(rf, "# Decimal number.\n");
228 if (recent.gui_geometry_status_pane_right != 0) {
229 fprintf(rf, RECENT_GUI_GEOMETRY_STATUS_PANE_RIGHT ": %d\n",
230 recent.gui_geometry_status_pane_right);
233 fprintf(rf, "\n# Last used Configuration Profile.\n");
234 fprintf(rf, RECENT_LAST_USED_PROFILE ": %s\n", get_profile_name());
236 fprintf(rf, "\n# WLAN statistics upper pane size.\n");
237 fprintf(rf, "# Decimal number.\n");
238 fprintf(rf, RECENT_GUI_GEOMETRY_WLAN_STATS_PANE ": %d\n",
239 recent.gui_geometry_wlan_stats_pane);
241 fprintf(rf, "\n# Warn if running with elevated permissions (e.g. as root).\n");
242 fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
243 fprintf(rf, RECENT_KEY_PRIVS_WARN_IF_ELEVATED ": %s\n",
244 recent.privs_warn_if_elevated == TRUE ? "TRUE" : "FALSE");
246 fprintf(rf, "\n# Warn if npf.sys isn't loaded on Windows >= 6.0.\n");
247 fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
248 fprintf(rf, RECENT_KEY_PRIVS_WARN_IF_NO_NPF ": %s\n",
249 recent.privs_warn_if_no_npf == TRUE ? "TRUE" : "FALSE");
251 window_geom_recent_write_all(rf);
255 /* XXX - catch I/O errors (e.g. "ran out of disk space") and return
256 an error indication, or maybe write to a new recent file and
257 rename that file on top of the old one only if there are not I/O
263 /* Attempt to Write out profile "recent" to the user's profile recent file.
264 If we got an error report it with a dialog box and return FALSE,
265 otherwise return TRUE. */
267 write_profile_recent(void)
274 * - Split output lines longer than MAX_VAL_LEN
275 * - Create a function for the preference directory check/creation
276 * so that duplication can be avoided with filter.c
279 /* Create the directory that holds personal configuration files, if
281 if (create_persconffile_dir(&pf_dir_path) == -1) {
282 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
283 "Can't create directory\n\"%s\"\nfor recent file: %s.", pf_dir_path,
289 rf_path = get_persconffile_path(RECENT_FILE_NAME, TRUE, TRUE);
290 if ((rf = ws_fopen(rf_path, "w")) == NULL) {
291 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
292 "Can't open recent file\n\"%s\": %s.", rf_path,
299 fputs("# Recent settings file for Wireshark " VERSION ".\n"
301 "# This file is regenerated each time Wireshark is quit\n"
302 "# and when changing configuration profile.\n"
303 "# So be careful, if you want to make manual changes here.\n"
306 fprintf(rf, "\n# Main Toolbar show (hide).\n");
307 fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
308 fprintf(rf, RECENT_KEY_MAIN_TOOLBAR_SHOW ": %s\n",
309 recent.main_toolbar_show == TRUE ? "TRUE" : "FALSE");
311 fprintf(rf, "\n# Filter Toolbar show (hide).\n");
312 fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
313 fprintf(rf, RECENT_KEY_FILTER_TOOLBAR_SHOW ": %s\n",
314 recent.filter_toolbar_show == TRUE ? "TRUE" : "FALSE");
317 fprintf(rf, "\n# Wireless Settings Toolbar show (hide).\n");
318 fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
319 fprintf(rf, RECENT_KEY_AIRPCAP_TOOLBAR_SHOW ": %s\n",
320 recent.airpcap_toolbar_show == TRUE ? "TRUE" : "FALSE");
324 fprintf(rf, "\n# Show (hide) old AirPcap driver warning dialog box.\n");
325 fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
326 fprintf(rf, RECENT_KEY_DRIVER_CHECK_SHOW ": %s\n",
327 recent.airpcap_driver_check_show == TRUE ? "TRUE" : "FALSE");
330 fprintf(rf, "\n# Packet list show (hide).\n");
331 fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
332 fprintf(rf, RECENT_KEY_PACKET_LIST_SHOW ": %s\n",
333 recent.packet_list_show == TRUE ? "TRUE" : "FALSE");
335 fprintf(rf, "\n# Tree view show (hide).\n");
336 fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
337 fprintf(rf, RECENT_KEY_TREE_VIEW_SHOW ": %s\n",
338 recent.tree_view_show == TRUE ? "TRUE" : "FALSE");
340 fprintf(rf, "\n# Byte view show (hide).\n");
341 fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
342 fprintf(rf, RECENT_KEY_BYTE_VIEW_SHOW ": %s\n",
343 recent.byte_view_show == TRUE ? "TRUE" : "FALSE");
345 fprintf(rf, "\n# Statusbar show (hide).\n");
346 fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
347 fprintf(rf, RECENT_KEY_STATUSBAR_SHOW ": %s\n",
348 recent.statusbar_show == TRUE ? "TRUE" : "FALSE");
350 fprintf(rf, "\n# Packet list colorize (hide).\n");
351 fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
352 fprintf(rf, RECENT_KEY_PACKET_LIST_COLORIZE ": %s\n",
353 recent.packet_list_colorize == TRUE ? "TRUE" : "FALSE");
355 fprintf(rf, "\n# Timestamp display format.\n");
356 fprintf(rf, "# One of: RELATIVE, ABSOLUTE, ABSOLUTE_WITH_DATE, DELTA, DELTA_DIS, EPOCH\n");
357 fprintf(rf, RECENT_GUI_TIME_FORMAT ": %s\n",
358 ts_type_text[recent.gui_time_format]);
360 fprintf(rf, "\n# Timestamp display precision.\n");
361 fprintf(rf, "# One of: AUTO, SEC, DSEC, CSEC, MSEC, USEC, NSEC\n");
362 fprintf(rf, RECENT_GUI_TIME_PRECISION ": %s\n",
363 ts_precision_text[recent.gui_time_precision]);
365 fprintf(rf, "\n# Seconds display format.\n");
366 fprintf(rf, "# One of: SECONDS, HOUR_MIN_SEC\n");
367 fprintf(rf, RECENT_GUI_SECONDS_FORMAT ": %s\n",
368 ts_seconds_text[recent.gui_seconds_format]);
370 fprintf(rf, "\n# Zoom level.\n");
371 fprintf(rf, "# A decimal number.\n");
372 fprintf(rf, RECENT_GUI_ZOOM_LEVEL ": %d\n",
373 recent.gui_zoom_level);
375 fprintf(rf, "\n# Bytes view.\n");
376 fprintf(rf, "# A decimal number.\n");
377 fprintf(rf, RECENT_GUI_BYTES_VIEW ": %d\n",
378 recent.gui_bytes_view);
380 fprintf(rf, "\n# Main window upper (or leftmost) pane size.\n");
381 fprintf(rf, "# Decimal number.\n");
382 if (recent.gui_geometry_main_upper_pane != 0) {
383 fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_UPPER_PANE ": %d\n",
384 recent.gui_geometry_main_upper_pane);
386 fprintf(rf, "\n# Main window middle pane size.\n");
387 fprintf(rf, "# Decimal number.\n");
388 if (recent.gui_geometry_main_lower_pane != 0) {
389 fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_LOWER_PANE ": %d\n",
390 recent.gui_geometry_main_lower_pane);
393 fprintf(rf, "\n# Packet list column pixel widths.\n");
394 fprintf(rf, "# Each pair of strings consists of a column format and its pixel width.\n");
395 #ifdef NEW_PACKET_LIST
396 new_packet_list_recent_write_all(rf);
398 packet_list_recent_write_all(rf);
401 if (get_last_open_dir() != NULL) {
402 fprintf(rf, "\n# Last directory navigated to in File Open dialog.\n");
405 fprintf(rf, RECENT_GUI_FILEOPEN_REMEMBERED_DIR ": %s\n", u3_contract_device_path(get_last_open_dir()));
407 fprintf(rf, RECENT_GUI_FILEOPEN_REMEMBERED_DIR ": %s\n", get_last_open_dir());
412 /* XXX - catch I/O errors (e.g. "ran out of disk space") and return
413 an error indication, or maybe write to a new recent file and
414 rename that file on top of the old one only if there are not I/O
420 /* write the geometry values of a window to recent file */
422 write_recent_geom(gpointer key _U_, gpointer value, gpointer rf)
424 window_geometry_t *geom = value;
426 fprintf(rf, "\n# Geometry and maximized state of %s window.\n", geom->key);
427 fprintf(rf, "# Decimal integers.\n");
428 fprintf(rf, RECENT_GUI_GEOMETRY "%s.x: %d\n", geom->key, geom->x);
429 fprintf(rf, RECENT_GUI_GEOMETRY "%s.y: %d\n", geom->key, geom->y);
430 fprintf(rf, RECENT_GUI_GEOMETRY "%s.width: %d\n", geom->key,
432 fprintf(rf, RECENT_GUI_GEOMETRY "%s.height: %d\n", geom->key,
435 fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
436 fprintf(rf, RECENT_GUI_GEOMETRY "%s.maximized: %s\n", geom->key,
437 geom->maximized == TRUE ? "TRUE" : "FALSE");
441 /* set one user's recent common file key/value pair */
442 static prefs_set_pref_e
443 read_set_recent_common_pair_static(gchar *key, gchar *value,
444 void *private_data _U_,
445 gboolean return_range_errors _U_)
450 if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_MAXIMIZED) == 0) {
451 if (g_ascii_strcasecmp(value, "true") == 0) {
452 recent.gui_geometry_main_maximized = TRUE;
455 recent.gui_geometry_main_maximized = FALSE;
458 } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_X) == 0) {
459 num = strtol(value, &p, 0);
460 if (p == value || *p != '\0')
461 return PREFS_SET_SYNTAX_ERR; /* number was bad */
462 recent.gui_geometry_main_x = num;
463 } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_Y) == 0) {
464 num = strtol(value, &p, 0);
465 if (p == value || *p != '\0')
466 return PREFS_SET_SYNTAX_ERR; /* number was bad */
467 recent.gui_geometry_main_y = num;
468 } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_WIDTH) == 0) {
469 num = strtol(value, &p, 0);
470 if (p == value || *p != '\0')
471 return PREFS_SET_SYNTAX_ERR; /* number was bad */
473 return PREFS_SET_SYNTAX_ERR; /* number must be positive */
474 recent.gui_geometry_main_width = num;
475 } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_HEIGHT) == 0) {
476 num = strtol(value, &p, 0);
477 if (p == value || *p != '\0')
478 return PREFS_SET_SYNTAX_ERR; /* number was bad */
480 return PREFS_SET_SYNTAX_ERR; /* number must be positive */
481 recent.gui_geometry_main_height = num;
482 } else if (strcmp(key, RECENT_GUI_GEOMETRY_STATUS_PANE_RIGHT) == 0) {
483 num = strtol(value, &p, 0);
484 if (p == value || *p != '\0')
485 return PREFS_SET_SYNTAX_ERR; /* number was bad */
487 return PREFS_SET_SYNTAX_ERR; /* number must be positive */
488 recent.gui_geometry_status_pane_right = num;
489 recent.has_gui_geometry_status_pane = TRUE;
490 } else if (strcmp(key, RECENT_GUI_GEOMETRY_STATUS_PANE_LEFT) == 0) {
491 num = strtol(value, &p, 0);
492 if (p == value || *p != '\0')
493 return PREFS_SET_SYNTAX_ERR; /* number was bad */
495 return PREFS_SET_SYNTAX_ERR; /* number must be positive */
496 recent.gui_geometry_status_pane_left = num;
497 recent.has_gui_geometry_status_pane = TRUE;
498 } else if (strcmp(key, RECENT_LAST_USED_PROFILE) == 0) {
499 if ((strcmp(value, DEFAULT_PROFILE) != 0) && profile_exists (value, FALSE)) {
500 set_profile_name (value);
502 } else if (strcmp(key, RECENT_GUI_GEOMETRY_WLAN_STATS_PANE) == 0) {
503 num = strtol(value, &p, 0);
504 if (p == value || *p != '\0')
505 return PREFS_SET_SYNTAX_ERR; /* number was bad */
507 return PREFS_SET_SYNTAX_ERR; /* number must be positive */
508 recent.gui_geometry_wlan_stats_pane = num;
509 } else if (strncmp(key, RECENT_GUI_GEOMETRY, sizeof(RECENT_GUI_GEOMETRY)-1) == 0) {
510 /* now have something like "gui.geom.main.x", split it into win and sub_key */
511 char *win = &key[sizeof(RECENT_GUI_GEOMETRY)-1];
512 char *sub_key = strchr(win, '.');
516 window_geom_recent_read_pair(win, sub_key, value);
518 } else if (strcmp(key, RECENT_KEY_PRIVS_WARN_IF_ELEVATED) == 0) {
519 if (g_ascii_strcasecmp(value, "true") == 0) {
520 recent.privs_warn_if_elevated = TRUE;
523 recent.privs_warn_if_elevated = FALSE;
525 } else if (strcmp(key, RECENT_KEY_PRIVS_WARN_IF_NO_NPF) == 0) {
526 if (g_ascii_strcasecmp(value, "true") == 0) {
527 recent.privs_warn_if_no_npf = TRUE;
530 recent.privs_warn_if_no_npf = FALSE;
537 /* set one user's recent file key/value pair */
538 static prefs_set_pref_e
539 read_set_recent_pair_static(gchar *key, gchar *value, void *private_data _U_,
540 gboolean return_range_errors _U_)
544 GList *col_l, *col_l_elt;
545 col_width_data *cfmt;
546 const gchar *cust_format = col_format_to_string(COL_CUSTOM);
547 int cust_format_len = (int) strlen(cust_format);
549 if (strcmp(key, RECENT_KEY_MAIN_TOOLBAR_SHOW) == 0) {
550 if (g_ascii_strcasecmp(value, "true") == 0) {
551 recent.main_toolbar_show = TRUE;
554 recent.main_toolbar_show = FALSE;
556 } else if (strcmp(key, RECENT_KEY_FILTER_TOOLBAR_SHOW) == 0) {
557 if (g_ascii_strcasecmp(value, "true") == 0) {
558 recent.filter_toolbar_show = TRUE;
561 recent.filter_toolbar_show = FALSE;
563 } else if (strcmp(key, RECENT_KEY_AIRPCAP_TOOLBAR_SHOW) == 0) {
564 if (g_ascii_strcasecmp(value, "true") == 0) {
565 recent.airpcap_toolbar_show = TRUE;
568 recent.airpcap_toolbar_show = FALSE;
570 } else if (strcmp(key, RECENT_KEY_DRIVER_CHECK_SHOW) == 0) {
571 if (g_ascii_strcasecmp(value, "true") == 0) {
572 recent.airpcap_driver_check_show = TRUE;
575 recent.airpcap_driver_check_show = FALSE;
577 } else if (strcmp(key, RECENT_KEY_PACKET_LIST_SHOW) == 0) {
578 if (g_ascii_strcasecmp(value, "true") == 0) {
579 recent.packet_list_show = TRUE;
582 recent.packet_list_show = FALSE;
584 } else if (strcmp(key, RECENT_KEY_TREE_VIEW_SHOW) == 0) {
585 if (g_ascii_strcasecmp(value, "true") == 0) {
586 recent.tree_view_show = TRUE;
589 recent.tree_view_show = FALSE;
591 } else if (strcmp(key, RECENT_KEY_BYTE_VIEW_SHOW) == 0) {
592 if (g_ascii_strcasecmp(value, "true") == 0) {
593 recent.byte_view_show = TRUE;
596 recent.byte_view_show = FALSE;
598 } else if (strcmp(key, RECENT_KEY_STATUSBAR_SHOW) == 0) {
599 if (g_ascii_strcasecmp(value, "true") == 0) {
600 recent.statusbar_show = TRUE;
603 recent.statusbar_show = FALSE;
605 } else if (strcmp(key, RECENT_KEY_PACKET_LIST_COLORIZE) == 0) {
606 if (g_ascii_strcasecmp(value, "true") == 0) {
607 recent.packet_list_colorize = TRUE;
610 recent.packet_list_colorize = FALSE;
612 } else if (strcmp(key, RECENT_GUI_TIME_FORMAT) == 0) {
613 recent.gui_time_format =
614 find_index_from_string_array(value, ts_type_text, TS_RELATIVE);
615 } else if (strcmp(key, RECENT_GUI_TIME_PRECISION) == 0) {
616 recent.gui_time_precision =
617 find_index_from_string_array(value, ts_precision_text, TS_PREC_AUTO);
618 } else if (strcmp(key, RECENT_GUI_SECONDS_FORMAT) == 0) {
619 recent.gui_seconds_format =
620 find_index_from_string_array(value, ts_seconds_text, TS_SECONDS_DEFAULT);
621 } else if (strcmp(key, RECENT_GUI_ZOOM_LEVEL) == 0) {
622 num = strtol(value, &p, 0);
623 if (p == value || *p != '\0')
624 return PREFS_SET_SYNTAX_ERR; /* number was bad */
625 recent.gui_zoom_level = num;
626 } else if (strcmp(key, RECENT_GUI_BYTES_VIEW) == 0) {
627 num = strtol(value, &p, 0);
628 if (p == value || *p != '\0')
629 return PREFS_SET_SYNTAX_ERR; /* number was bad */
630 recent.gui_bytes_view = num;
631 } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_MAXIMIZED) == 0) {
632 if (g_ascii_strcasecmp(value, "true") == 0) {
633 recent.gui_geometry_main_maximized = TRUE;
636 recent.gui_geometry_main_maximized = FALSE;
639 } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_UPPER_PANE) == 0) {
640 num = strtol(value, &p, 0);
641 if (p == value || *p != '\0')
642 return PREFS_SET_SYNTAX_ERR; /* number was bad */
644 return PREFS_SET_SYNTAX_ERR; /* number must be positive */
645 recent.gui_geometry_main_upper_pane = num;
646 recent.has_gui_geometry_main_upper_pane = TRUE;
647 } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_LOWER_PANE) == 0) {
648 num = strtol(value, &p, 0);
649 if (p == value || *p != '\0')
650 return PREFS_SET_SYNTAX_ERR; /* number was bad */
652 return PREFS_SET_SYNTAX_ERR; /* number must be positive */
653 recent.gui_geometry_main_lower_pane = num;
654 recent.has_gui_geometry_main_lower_pane = TRUE;
656 else if (strcmp(key, RECENT_KEY_COL_WIDTH) == 0) {
657 col_l = prefs_get_string_list(value);
659 return PREFS_SET_SYNTAX_ERR;
660 if ((g_list_length(col_l) % 2) != 0) {
661 /* A title didn't have a matching width. */
662 prefs_clear_string_list(col_l);
663 return PREFS_SET_SYNTAX_ERR;
665 /* Check to make sure all column formats are valid. */
666 col_l_elt = g_list_first(col_l);
668 /* Make sure the format isn't empty. */
669 if (strcmp(col_l_elt->data, "") == 0) {
671 prefs_clear_string_list(col_l);
672 return PREFS_SET_SYNTAX_ERR;
675 /* Check the format. */
676 if (strncmp(col_l_elt->data, cust_format, cust_format_len) != 0) {
677 if (get_column_format_from_str(col_l_elt->data) == -1) {
678 /* It's not a valid column format. */
679 prefs_clear_string_list(col_l);
680 return PREFS_SET_SYNTAX_ERR;
684 /* Go past the format. */
685 col_l_elt = col_l_elt->next;
687 /* Go past the width. */
688 col_l_elt = col_l_elt->next;
690 free_col_width_info(&recent);
691 recent.col_width_list = NULL;
692 col_l_elt = g_list_first(col_l);
694 gchar *fmt = g_strdup(col_l_elt->data);
695 cfmt = (col_width_data *) g_malloc(sizeof(col_width_data));
696 if (strncmp(fmt, cust_format, cust_format_len) != 0) {
697 cfmt->cfmt = get_column_format_from_str(fmt);
700 cfmt->cfmt = COL_CUSTOM;
701 cfmt->cfield = g_strdup(&fmt[cust_format_len+1]); /* add 1 for ':' */
704 if (cfmt->cfmt == -1) {
705 g_free(cfmt->cfield);
707 return PREFS_SET_SYNTAX_ERR; /* string was bad */
710 col_l_elt = col_l_elt->next;
711 cfmt->width = strtol(col_l_elt->data, &p, 0);
712 if (p == col_l_elt->data || (*p != '\0' && *p != ':')) {
713 g_free(cfmt->cfield);
715 return PREFS_SET_SYNTAX_ERR; /* number was bad */
719 cfmt->xalign = *(++p);
721 cfmt->xalign = COLUMN_XALIGN_DEFAULT;
724 col_l_elt = col_l_elt->next;
725 recent.col_width_list = g_list_append(recent.col_width_list, cfmt);
727 prefs_clear_string_list(col_l);
728 } else if (strcmp(key, RECENT_GUI_FILEOPEN_REMEMBERED_DIR) == 0) {
729 if (recent.gui_fileopen_remembered_dir) {
730 g_free (recent.gui_fileopen_remembered_dir);
732 recent.gui_fileopen_remembered_dir = g_strdup(value);
739 /* set one user's recent file key/value pair */
740 static prefs_set_pref_e
741 read_set_recent_pair_dynamic(gchar *key, gchar *value, void *private_data _U_,
742 gboolean return_range_errors _U_)
744 if (strcmp(key, RECENT_KEY_CAPTURE_FILE) == 0) {
746 add_menu_recent_capture_file(u3_expand_device_path(value));
748 add_menu_recent_capture_file(value);
749 } else if (strcmp(key, RECENT_KEY_DISPLAY_FILTER) == 0) {
750 dfilter_combo_add_recent(value);
751 } else if (strcmp(key, RECENT_KEY_CAPTURE_FILTER) == 0) {
752 cfilter_combo_add_recent(value);
753 #ifdef HAVE_PCAP_REMOTE
754 } else if (strcmp(key, RECENT_KEY_REMOTE_HOST) == 0) {
755 capture_remote_combo_add_recent(value);
764 * Given a string of the form "<recent name>:<recent value>", as might appear
765 * as an argument to a "-o" option, parse it and set the recent value in
766 * question. Return an indication of whether it succeeded or failed
770 recent_set_arg(char *prefarg)
775 colonp = strchr(prefarg, ':');
777 return PREFS_SET_SYNTAX_ERR;
783 * Skip over any white space (there probably won't be any, but
784 * as we allow it in the preferences file, we might as well
787 while (isspace((guchar)*p))
791 * Put the colon back, so if our caller uses, in an
792 * error message, the string they passed us, the message
796 return PREFS_SET_SYNTAX_ERR;
799 ret = read_set_recent_pair_static(prefarg, p, NULL, TRUE);
800 *colonp = ':'; /* put the colon back */
805 /* opens the user's recent common file and read the first part */
807 recent_read_static(char **rf_path_return, int *rf_errno_return)
813 recent.gui_geometry_main_x = 20;
814 recent.gui_geometry_main_y = 20;
815 recent.gui_geometry_main_width = DEF_WIDTH;
816 recent.gui_geometry_main_height = DEF_HEIGHT;
817 recent.gui_geometry_main_maximized= FALSE;
819 recent.gui_geometry_status_pane_left = (DEF_WIDTH/3);
820 recent.gui_geometry_status_pane_right = (DEF_WIDTH/3);
821 recent.gui_geometry_wlan_stats_pane = 200;
823 recent.privs_warn_if_elevated = TRUE;
824 recent.privs_warn_if_no_npf = TRUE;
826 recent.col_width_list = NULL;
827 recent.gui_fileopen_remembered_dir = NULL;
829 /* Construct the pathname of the user's recent common file. */
830 rf_path = get_persconffile_path(RECENT_COMMON_FILE_NAME, FALSE, FALSE);
832 /* Read the user's recent common file, if it exists. */
833 *rf_path_return = NULL;
834 if ((rf = ws_fopen(rf_path, "r")) != NULL) {
835 /* We succeeded in opening it; read it. */
836 read_prefs_file(rf_path, rf, read_set_recent_common_pair_static, NULL);
842 /* We failed to open it. If we failed for some reason other than
843 "it doesn't exist", return the errno and the pathname, so our
844 caller can report the error. */
845 if (errno != ENOENT) {
846 *rf_errno_return = errno;
847 *rf_path_return = rf_path;
854 /* opens the user's recent file and read the first part */
856 recent_read_profile_static(char **rf_path_return, int *rf_errno_return)
858 char *rf_path, *rf_common_path;
862 recent.main_toolbar_show = TRUE;
863 recent.filter_toolbar_show = TRUE;
864 recent.airpcap_toolbar_show = FALSE;
865 recent.airpcap_driver_check_show = TRUE;
866 recent.packet_list_show = TRUE;
867 recent.tree_view_show = TRUE;
868 recent.byte_view_show = TRUE;
869 recent.statusbar_show = TRUE;
870 recent.packet_list_colorize = TRUE;
871 recent.gui_time_format = TS_RELATIVE;
872 recent.gui_time_precision = TS_PREC_AUTO;
873 recent.gui_seconds_format = TS_SECONDS_DEFAULT;
874 recent.gui_zoom_level = 0;
875 recent.gui_bytes_view = 0;
877 /* pane size of zero will autodetect */
878 recent.gui_geometry_main_upper_pane = 0;
879 recent.gui_geometry_main_lower_pane = 0;
881 recent.has_gui_geometry_main_upper_pane = TRUE;
882 recent.has_gui_geometry_main_lower_pane = TRUE;
883 recent.has_gui_geometry_status_pane = TRUE;
885 if (recent.col_width_list) {
886 free_col_width_info(&recent);
889 if (recent.gui_fileopen_remembered_dir) {
890 g_free (recent.gui_fileopen_remembered_dir);
891 recent.gui_fileopen_remembered_dir = NULL;
894 /* Construct the pathname of the user's profile recent file. */
895 rf_path = get_persconffile_path(RECENT_FILE_NAME, TRUE, FALSE);
897 /* Read the user's recent file, if it exists. */
898 *rf_path_return = NULL;
899 if ((rf = ws_fopen(rf_path, "r")) != NULL) {
900 /* We succeeded in opening it; read it. */
901 read_prefs_file(rf_path, rf, read_set_recent_pair_static, NULL);
904 /* XXX: The following code doesn't actually do anything since
905 * the "recent common file" always exists. Presumably the
906 * "if (!file_exists())" should actually be "if (file_exists())".
907 * However, I've left the code as is because this
908 * behaviour has existed for quite some time and I don't
909 * know what's supposed to happen at this point.
910 * ToDo: Determine if the "recent common file" should be read at this point
912 rf_common_path = get_persconffile_path(RECENT_COMMON_FILE_NAME, FALSE, FALSE);
913 if (!file_exists(rf_common_path)) {
914 /* Read older common settings from recent file */
915 rf = ws_fopen(rf_path, "r");
916 read_prefs_file(rf_path, rf, read_set_recent_common_pair_static, NULL);
919 g_free(rf_common_path);
923 /* We failed to open it. If we failed for some reason other than
924 "it doesn't exist", return the errno and the pathname, so our
925 caller can report the error. */
926 if (errno != ENOENT) {
927 *rf_errno_return = errno;
928 *rf_path_return = rf_path;
933 /* opens the user's recent file and read it out */
935 recent_read_dynamic(char **rf_path_return, int *rf_errno_return)
941 /* Construct the pathname of the user's recent common file. */
942 rf_path = get_persconffile_path(RECENT_COMMON_FILE_NAME, FALSE, FALSE);
943 if (!file_exists (rf_path)) {
944 /* Recent common file does not exist, read from default recent */
946 rf_path = get_persconffile_path(RECENT_FILE_NAME, FALSE, FALSE);
949 /* Read the user's recent file, if it exists. */
950 *rf_path_return = NULL;
951 if ((rf = ws_fopen(rf_path, "r")) != NULL) {
952 /* We succeeded in opening it; read it. */
953 read_prefs_file(rf_path, rf, read_set_recent_pair_dynamic, NULL);
955 /* set dfilter combobox to have an empty line */
956 dfilter_combo_add_empty();
962 /* We failed to open it. If we failed for some reason other than
963 "it doesn't exist", return the errno and the pathname, so our
964 caller can report the error. */
965 if (errno != ENOENT) {
966 *rf_errno_return = errno;
967 *rf_path_return = rf_path;
973 recent_get_column_width(gint col)
976 col_width_data *col_w;
978 const gchar *cfield = NULL;
980 cfmt = get_column_format(col);
981 if (cfmt == COL_CUSTOM) {
982 cfield = get_column_custom_field(col);
985 col_l = g_list_first(recent.col_width_list);
987 col_w = (col_width_data *) col_l->data;
988 if (col_w->cfmt == cfmt) {
989 if (cfmt != COL_CUSTOM || strcmp (cfield, col_w->cfield) == 0) {
1000 recent_set_column_width(gint col, gint width)
1003 col_width_data *col_w;
1005 const gchar *cfield = NULL;
1006 gboolean found = FALSE;
1008 cfmt = get_column_format(col);
1009 if (cfmt == COL_CUSTOM) {
1010 cfield = get_column_custom_field(col);
1013 col_l = g_list_first(recent.col_width_list);
1015 col_w = (col_width_data *) col_l->data;
1016 if (col_w->cfmt == cfmt) {
1017 if (cfmt != COL_CUSTOM || strcmp (cfield, col_w->cfield) == 0) {
1018 col_w->width = width;
1023 col_l = col_l->next;
1027 col_w = (col_width_data *) g_malloc(sizeof(col_width_data));
1030 col_w->cfield = g_strdup(cfield);
1032 col_w->cfield = NULL;
1034 col_w->width = width;
1035 col_w->xalign = COLUMN_XALIGN_DEFAULT;
1036 recent.col_width_list = g_list_append(recent.col_width_list, col_w);
1041 recent_get_column_xalign(gint col)
1044 col_width_data *col_w;
1046 const gchar *cfield = NULL;
1048 cfmt = get_column_format(col);
1049 if (cfmt == COL_CUSTOM) {
1050 cfield = get_column_custom_field(col);
1053 col_l = g_list_first(recent.col_width_list);
1055 col_w = (col_width_data *) col_l->data;
1056 if (col_w->cfmt == cfmt) {
1057 if (cfmt != COL_CUSTOM || strcmp (cfield, col_w->cfield) == 0) {
1058 return col_w->xalign;
1061 col_l = col_l->next;
1068 recent_set_column_xalign(gint col, gchar xalign)
1071 col_width_data *col_w;
1073 const gchar *cfield = NULL;
1074 gboolean found = FALSE;
1076 cfmt = get_column_format(col);
1077 if (cfmt == COL_CUSTOM) {
1078 cfield = get_column_custom_field(col);
1081 col_l = g_list_first(recent.col_width_list);
1083 col_w = (col_width_data *) col_l->data;
1084 if (col_w->cfmt == cfmt) {
1085 if (cfmt != COL_CUSTOM || strcmp (cfield, col_w->cfield) == 0) {
1086 col_w->xalign = xalign;
1091 col_l = col_l->next;
1095 col_w = (col_width_data *) g_malloc(sizeof(col_width_data));
1098 col_w->cfield = g_strdup(cfield);
1100 col_w->cfield = NULL;
1103 col_w->xalign = xalign;
1104 recent.col_width_list = g_list_append(recent.col_width_list, col_w);