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"
43 #include <wsutil/file_util.h>
45 #include "gtk/recent.h"
47 #include "gtk/menus.h"
48 #include "gtk/gui_utils.h"
49 #ifdef NEW_PACKET_LIST
50 #include "gtk/new_packet_list.h"
52 #include "gtk/main_packet_list.h"
53 #endif /*NEW_PACKET_LIST */
54 #include "gtk/file_dlg.h"
55 #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_ZOOM_LEVEL "gui.zoom_level"
74 #define RECENT_GUI_BYTES_VIEW "gui.bytes_view"
75 #define RECENT_GUI_GEOMETRY_MAIN_X "gui.geometry_main_x"
76 #define RECENT_GUI_GEOMETRY_MAIN_Y "gui.geometry_main_y"
77 #define RECENT_GUI_GEOMETRY_MAIN_WIDTH "gui.geometry_main_width"
78 #define RECENT_GUI_GEOMETRY_MAIN_HEIGHT "gui.geometry_main_height"
79 #define RECENT_GUI_GEOMETRY_MAIN_MAXIMIZED "gui.geometry_main_maximized"
80 #define RECENT_GUI_GEOMETRY_MAIN_UPPER_PANE "gui.geometry_main_upper_pane"
81 #define RECENT_GUI_GEOMETRY_MAIN_LOWER_PANE "gui.geometry_main_lower_pane"
82 #define RECENT_GUI_GEOMETRY_STATUS_PANE_LEFT "gui.geometry_status_pane"
83 #define RECENT_GUI_GEOMETRY_STATUS_PANE_RIGHT "gui.geometry_status_pane_right"
84 #define RECENT_GUI_GEOMETRY_WLAN_STATS_PANE "gui.geometry_status_wlan_stats_pane"
85 #define RECENT_LAST_USED_PROFILE "gui.last_used_profile"
86 #define RECENT_GUI_FILEOPEN_REMEMBERED_DIR "gui.fileopen_remembered_dir"
87 #define RECENT_GUI_GEOMETRY "gui.geom."
88 #define RECENT_KEY_PRIVS_WARN_IF_ELEVATED "privs.warn_if_elevated"
89 #define RECENT_KEY_PRIVS_WARN_IF_NO_NPF "privs.warn_if_no_npf"
91 #define RECENT_FILE_NAME "recent"
92 #define RECENT_COMMON_FILE_NAME "recent_common"
94 recent_settings_t recent;
96 static const char *ts_type_text[] =
97 { "RELATIVE", "ABSOLUTE", "ABSOLUTE_WITH_DATE", "DELTA", "DELTA_DIS", "EPOCH", NULL };
99 static const char *ts_precision_text[] =
100 { "AUTO", "SEC", "DSEC", "CSEC", "MSEC", "USEC", "NSEC", NULL };
102 /* Takes an string and a pointer to an array of strings, and a default int value.
103 * The array must be terminated by a NULL string. If the string is found in the array
104 * of strings, the index of that string in the array is returned. Otherwise, the
105 * default value that was passed as the third argument is returned.
108 find_index_from_string_array(const char *needle, const char **haystack, int default_value)
112 while (haystack[i] != NULL) {
113 if (strcmp(needle, haystack[i]) == 0) {
118 return default_value;
122 free_col_width_info(recent_settings_t *rs)
124 col_width_data *cfmt;
126 while (rs->col_width_list != NULL) {
127 cfmt = rs->col_width_list->data;
128 g_free(cfmt->cfield);
130 rs->col_width_list = g_list_remove_link(rs->col_width_list, rs->col_width_list);
132 g_list_free(rs->col_width_list);
133 rs->col_width_list = NULL;
136 /* Attempt to Write out "recent common" to the user's recent common file.
137 If we got an error report it with a dialog box and return FALSE,
138 otherwise return TRUE. */
147 * - Split output lines longer than MAX_VAL_LEN
148 * - Create a function for the preference directory check/creation
149 * so that duplication can be avoided with filter.c
152 /* Create the directory that holds personal configuration files, if
154 if (create_persconffile_dir(&pf_dir_path) == -1) {
155 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
156 "Can't create directory\n\"%s\"\nfor recent file: %s.", pf_dir_path,
162 rf_path = get_persconffile_path(RECENT_COMMON_FILE_NAME, FALSE, TRUE);
163 if ((rf = ws_fopen(rf_path, "w")) == NULL) {
164 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
165 "Can't open recent file\n\"%s\": %s.", rf_path,
172 fputs("# Recent settings file for Wireshark " VERSION ".\n"
174 "# This file is regenerated each time Wireshark is quit.\n"
175 "# So be careful, if you want to make manual changes here.\n"
177 "######## Recent capture files (latest last), cannot be altered through command line ########\n"
180 menu_recent_file_write_all(rf);
183 "######## Recent capture filters (latest last), cannot be altered through command line ########\n"
186 cfilter_combo_recent_write_all(rf);
189 "######## Recent display filters (latest last), cannot be altered through command line ########\n"
192 dfilter_recent_combo_write_all(rf);
194 #ifdef HAVE_PCAP_REMOTE
196 "######## Recent remote hosts, cannot be altered through command line ########\n"
199 capture_remote_combo_recent_write_all(rf);
202 fprintf(rf, "\n# Main window geometry.\n");
203 fprintf(rf, "# Decimal numbers.\n");
204 fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_X ": %d\n", recent.gui_geometry_main_x);
205 fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_Y ": %d\n", recent.gui_geometry_main_y);
206 fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_WIDTH ": %d\n",
207 recent.gui_geometry_main_width);
208 fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_HEIGHT ": %d\n",
209 recent.gui_geometry_main_height);
211 fprintf(rf, "\n# Main window maximized.\n");
212 fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
213 fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_MAXIMIZED ": %s\n",
214 recent.gui_geometry_main_maximized == TRUE ? "TRUE" : "FALSE");
216 fprintf(rf, "\n# Statusbar left pane size.\n");
217 fprintf(rf, "# Decimal number.\n");
218 if (recent.gui_geometry_status_pane_left != 0) {
219 fprintf(rf, RECENT_GUI_GEOMETRY_STATUS_PANE_LEFT ": %d\n",
220 recent.gui_geometry_status_pane_left);
222 fprintf(rf, "\n# Statusbar middle pane size.\n");
223 fprintf(rf, "# Decimal number.\n");
224 if (recent.gui_geometry_status_pane_right != 0) {
225 fprintf(rf, RECENT_GUI_GEOMETRY_STATUS_PANE_RIGHT ": %d\n",
226 recent.gui_geometry_status_pane_right);
229 fprintf(rf, "\n# Last used Configuration Profile.\n");
230 fprintf(rf, RECENT_LAST_USED_PROFILE ": %s\n", get_profile_name());
232 fprintf(rf, "\n# WLAN statistics upper pane size.\n");
233 fprintf(rf, "# Decimal number.\n");
234 fprintf(rf, RECENT_GUI_GEOMETRY_WLAN_STATS_PANE ": %d\n",
235 recent.gui_geometry_wlan_stats_pane);
237 fprintf(rf, "\n# Warn if running with elevated permissions (e.g. as root).\n");
238 fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
239 fprintf(rf, RECENT_KEY_PRIVS_WARN_IF_ELEVATED ": %s\n",
240 recent.privs_warn_if_elevated == TRUE ? "TRUE" : "FALSE");
242 fprintf(rf, "\n# Warn if npf.sys isn't loaded on Windows >= 6.0.\n");
243 fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
244 fprintf(rf, RECENT_KEY_PRIVS_WARN_IF_NO_NPF ": %s\n",
245 recent.privs_warn_if_no_npf == TRUE ? "TRUE" : "FALSE");
247 window_geom_recent_write_all(rf);
251 /* XXX - catch I/O errors (e.g. "ran out of disk space") and return
252 an error indication, or maybe write to a new recent file and
253 rename that file on top of the old one only if there are not I/O
259 /* Attempt to Write out profile "recent" to the user's profile recent file.
260 If we got an error report it with a dialog box and return FALSE,
261 otherwise return TRUE. */
263 write_profile_recent(void)
270 * - Split output lines longer than MAX_VAL_LEN
271 * - Create a function for the preference directory check/creation
272 * so that duplication can be avoided with filter.c
275 /* Create the directory that holds personal configuration files, if
277 if (create_persconffile_dir(&pf_dir_path) == -1) {
278 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
279 "Can't create directory\n\"%s\"\nfor recent file: %s.", pf_dir_path,
285 rf_path = get_persconffile_path(RECENT_FILE_NAME, TRUE, TRUE);
286 if ((rf = ws_fopen(rf_path, "w")) == NULL) {
287 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
288 "Can't open recent file\n\"%s\": %s.", rf_path,
295 fputs("# Recent settings file for Wireshark " VERSION ".\n"
297 "# This file is regenerated each time Wireshark is quit\n"
298 "# and when changing configuration profile.\n"
299 "# So be careful, if you want to make manual changes here.\n"
302 fprintf(rf, "\n# Main Toolbar show (hide).\n");
303 fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
304 fprintf(rf, RECENT_KEY_MAIN_TOOLBAR_SHOW ": %s\n",
305 recent.main_toolbar_show == TRUE ? "TRUE" : "FALSE");
307 fprintf(rf, "\n# Filter Toolbar show (hide).\n");
308 fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
309 fprintf(rf, RECENT_KEY_FILTER_TOOLBAR_SHOW ": %s\n",
310 recent.filter_toolbar_show == TRUE ? "TRUE" : "FALSE");
313 fprintf(rf, "\n# Wireless Settings Toolbar show (hide).\n");
314 fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
315 fprintf(rf, RECENT_KEY_AIRPCAP_TOOLBAR_SHOW ": %s\n",
316 recent.airpcap_toolbar_show == TRUE ? "TRUE" : "FALSE");
320 fprintf(rf, "\n# Show (hide) old AirPcap driver warning dialog box.\n");
321 fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
322 fprintf(rf, RECENT_KEY_DRIVER_CHECK_SHOW ": %s\n",
323 recent.airpcap_driver_check_show == TRUE ? "TRUE" : "FALSE");
326 fprintf(rf, "\n# Packet list show (hide).\n");
327 fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
328 fprintf(rf, RECENT_KEY_PACKET_LIST_SHOW ": %s\n",
329 recent.packet_list_show == TRUE ? "TRUE" : "FALSE");
331 fprintf(rf, "\n# Tree view show (hide).\n");
332 fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
333 fprintf(rf, RECENT_KEY_TREE_VIEW_SHOW ": %s\n",
334 recent.tree_view_show == TRUE ? "TRUE" : "FALSE");
336 fprintf(rf, "\n# Byte view show (hide).\n");
337 fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
338 fprintf(rf, RECENT_KEY_BYTE_VIEW_SHOW ": %s\n",
339 recent.byte_view_show == TRUE ? "TRUE" : "FALSE");
341 fprintf(rf, "\n# Statusbar show (hide).\n");
342 fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
343 fprintf(rf, RECENT_KEY_STATUSBAR_SHOW ": %s\n",
344 recent.statusbar_show == TRUE ? "TRUE" : "FALSE");
346 fprintf(rf, "\n# Packet list colorize (hide).\n");
347 fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
348 fprintf(rf, RECENT_KEY_PACKET_LIST_COLORIZE ": %s\n",
349 recent.packet_list_colorize == TRUE ? "TRUE" : "FALSE");
351 fprintf(rf, "\n# Timestamp display format.\n");
352 fprintf(rf, "# One of: RELATIVE, ABSOLUTE, ABSOLUTE_WITH_DATE, DELTA, DELTA_DIS, EPOCH\n");
353 fprintf(rf, RECENT_GUI_TIME_FORMAT ": %s\n",
354 ts_type_text[recent.gui_time_format]);
356 fprintf(rf, "\n# Timestamp display precision.\n");
357 fprintf(rf, "# One of: AUTO, SEC, DSEC, CSEC, MSEC, USEC, NSEC\n");
358 fprintf(rf, RECENT_GUI_TIME_PRECISION ": %s\n",
359 ts_precision_text[recent.gui_time_precision]);
361 fprintf(rf, "\n# Zoom level.\n");
362 fprintf(rf, "# A decimal number.\n");
363 fprintf(rf, RECENT_GUI_ZOOM_LEVEL ": %d\n",
364 recent.gui_zoom_level);
366 fprintf(rf, "\n# Bytes view.\n");
367 fprintf(rf, "# A decimal number.\n");
368 fprintf(rf, RECENT_GUI_BYTES_VIEW ": %d\n",
369 recent.gui_bytes_view);
371 fprintf(rf, "\n# Main window upper (or leftmost) pane size.\n");
372 fprintf(rf, "# Decimal number.\n");
373 if (recent.gui_geometry_main_upper_pane != 0) {
374 fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_UPPER_PANE ": %d\n",
375 recent.gui_geometry_main_upper_pane);
377 fprintf(rf, "\n# Main window middle pane size.\n");
378 fprintf(rf, "# Decimal number.\n");
379 if (recent.gui_geometry_main_lower_pane != 0) {
380 fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_LOWER_PANE ": %d\n",
381 recent.gui_geometry_main_lower_pane);
384 fprintf(rf, "\n# Packet list column pixel widths.\n");
385 fprintf(rf, "# Each pair of strings consists of a column format and its pixel width.\n");
386 #ifdef NEW_PACKET_LIST
387 new_packet_list_recent_write_all(rf);
389 packet_list_recent_write_all(rf);
392 if (get_last_open_dir() != NULL) {
393 fprintf(rf, "\n# Last directory navigated to in File Open dialog.\n");
396 fprintf(rf, RECENT_GUI_FILEOPEN_REMEMBERED_DIR ": %s\n", u3_contract_device_path(get_last_open_dir()));
398 fprintf(rf, RECENT_GUI_FILEOPEN_REMEMBERED_DIR ": %s\n", get_last_open_dir());
403 /* XXX - catch I/O errors (e.g. "ran out of disk space") and return
404 an error indication, or maybe write to a new recent file and
405 rename that file on top of the old one only if there are not I/O
411 /* write the geometry values of a window to recent file */
413 write_recent_geom(gpointer key _U_, gpointer value, gpointer rf)
415 window_geometry_t *geom = value;
417 fprintf(rf, "\n# Geometry and maximized state of %s window.\n", geom->key);
418 fprintf(rf, "# Decimal integers.\n");
419 fprintf(rf, RECENT_GUI_GEOMETRY "%s.x: %d\n", geom->key, geom->x);
420 fprintf(rf, RECENT_GUI_GEOMETRY "%s.y: %d\n", geom->key, geom->y);
421 fprintf(rf, RECENT_GUI_GEOMETRY "%s.width: %d\n", geom->key,
423 fprintf(rf, RECENT_GUI_GEOMETRY "%s.height: %d\n", geom->key,
426 fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
427 fprintf(rf, RECENT_GUI_GEOMETRY "%s.maximized: %s\n", geom->key,
428 geom->maximized == TRUE ? "TRUE" : "FALSE");
432 /* set one user's recent common file key/value pair */
433 static prefs_set_pref_e
434 read_set_recent_common_pair_static(gchar *key, gchar *value, void *private_data _U_)
439 if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_MAXIMIZED) == 0) {
440 if (g_ascii_strcasecmp(value, "true") == 0) {
441 recent.gui_geometry_main_maximized = TRUE;
444 recent.gui_geometry_main_maximized = FALSE;
447 } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_X) == 0) {
448 num = strtol(value, &p, 0);
449 if (p == value || *p != '\0')
450 return PREFS_SET_SYNTAX_ERR; /* number was bad */
451 recent.gui_geometry_main_x = num;
452 } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_Y) == 0) {
453 num = strtol(value, &p, 0);
454 if (p == value || *p != '\0')
455 return PREFS_SET_SYNTAX_ERR; /* number was bad */
456 recent.gui_geometry_main_y = num;
457 } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_WIDTH) == 0) {
458 num = strtol(value, &p, 0);
459 if (p == value || *p != '\0')
460 return PREFS_SET_SYNTAX_ERR; /* number was bad */
462 return PREFS_SET_SYNTAX_ERR; /* number must be positive */
463 recent.gui_geometry_main_width = num;
464 } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_HEIGHT) == 0) {
465 num = strtol(value, &p, 0);
466 if (p == value || *p != '\0')
467 return PREFS_SET_SYNTAX_ERR; /* number was bad */
469 return PREFS_SET_SYNTAX_ERR; /* number must be positive */
470 recent.gui_geometry_main_height = num;
471 } else if (strcmp(key, RECENT_GUI_GEOMETRY_STATUS_PANE_RIGHT) == 0) {
472 num = strtol(value, &p, 0);
473 if (p == value || *p != '\0')
474 return PREFS_SET_SYNTAX_ERR; /* number was bad */
476 return PREFS_SET_SYNTAX_ERR; /* number must be positive */
477 recent.gui_geometry_status_pane_right = num;
478 recent.has_gui_geometry_status_pane = TRUE;
479 } else if (strcmp(key, RECENT_GUI_GEOMETRY_STATUS_PANE_LEFT) == 0) {
480 num = strtol(value, &p, 0);
481 if (p == value || *p != '\0')
482 return PREFS_SET_SYNTAX_ERR; /* number was bad */
484 return PREFS_SET_SYNTAX_ERR; /* number must be positive */
485 recent.gui_geometry_status_pane_left = num;
486 recent.has_gui_geometry_status_pane = TRUE;
487 } else if (strcmp(key, RECENT_LAST_USED_PROFILE) == 0) {
488 if ((strcmp(value, DEFAULT_PROFILE) != 0) && profile_exists (value)) {
489 set_profile_name (value);
491 } else if (strcmp(key, RECENT_GUI_GEOMETRY_WLAN_STATS_PANE) == 0) {
492 num = strtol(value, &p, 0);
493 if (p == value || *p != '\0')
494 return PREFS_SET_SYNTAX_ERR; /* number was bad */
496 return PREFS_SET_SYNTAX_ERR; /* number must be positive */
497 recent.gui_geometry_wlan_stats_pane = num;
498 } else if (strncmp(key, RECENT_GUI_GEOMETRY, sizeof(RECENT_GUI_GEOMETRY)-1) == 0) {
499 /* now have something like "gui.geom.main.x", split it into win and sub_key */
500 char *win = &key[sizeof(RECENT_GUI_GEOMETRY)-1];
501 char *sub_key = strchr(win, '.');
505 window_geom_recent_read_pair(win, sub_key, value);
507 } else if (strcmp(key, RECENT_KEY_PRIVS_WARN_IF_ELEVATED) == 0) {
508 if (g_ascii_strcasecmp(value, "true") == 0) {
509 recent.privs_warn_if_elevated = TRUE;
512 recent.privs_warn_if_elevated = FALSE;
514 } else if (strcmp(key, RECENT_KEY_PRIVS_WARN_IF_NO_NPF) == 0) {
515 if (g_ascii_strcasecmp(value, "true") == 0) {
516 recent.privs_warn_if_no_npf = TRUE;
519 recent.privs_warn_if_no_npf = FALSE;
526 /* set one user's recent file key/value pair */
527 static prefs_set_pref_e
528 read_set_recent_pair_static(gchar *key, gchar *value, void *private_data _U_)
532 GList *col_l, *col_l_elt;
533 col_width_data *cfmt;
534 const gchar *cust_format = col_format_to_string(COL_CUSTOM);
535 int cust_format_len = (int) strlen(cust_format);
537 if (strcmp(key, RECENT_KEY_MAIN_TOOLBAR_SHOW) == 0) {
538 if (g_ascii_strcasecmp(value, "true") == 0) {
539 recent.main_toolbar_show = TRUE;
542 recent.main_toolbar_show = FALSE;
544 } else if (strcmp(key, RECENT_KEY_FILTER_TOOLBAR_SHOW) == 0) {
545 if (g_ascii_strcasecmp(value, "true") == 0) {
546 recent.filter_toolbar_show = TRUE;
549 recent.filter_toolbar_show = FALSE;
551 } else if (strcmp(key, RECENT_KEY_AIRPCAP_TOOLBAR_SHOW) == 0) {
552 if (g_ascii_strcasecmp(value, "true") == 0) {
553 recent.airpcap_toolbar_show = TRUE;
556 recent.airpcap_toolbar_show = FALSE;
558 } else if (strcmp(key, RECENT_KEY_DRIVER_CHECK_SHOW) == 0) {
559 if (g_ascii_strcasecmp(value, "true") == 0) {
560 recent.airpcap_driver_check_show = TRUE;
563 recent.airpcap_driver_check_show = FALSE;
565 } else if (strcmp(key, RECENT_KEY_PACKET_LIST_SHOW) == 0) {
566 if (g_ascii_strcasecmp(value, "true") == 0) {
567 recent.packet_list_show = TRUE;
570 recent.packet_list_show = FALSE;
572 } else if (strcmp(key, RECENT_KEY_TREE_VIEW_SHOW) == 0) {
573 if (g_ascii_strcasecmp(value, "true") == 0) {
574 recent.tree_view_show = TRUE;
577 recent.tree_view_show = FALSE;
579 } else if (strcmp(key, RECENT_KEY_BYTE_VIEW_SHOW) == 0) {
580 if (g_ascii_strcasecmp(value, "true") == 0) {
581 recent.byte_view_show = TRUE;
584 recent.byte_view_show = FALSE;
586 } else if (strcmp(key, RECENT_KEY_STATUSBAR_SHOW) == 0) {
587 if (g_ascii_strcasecmp(value, "true") == 0) {
588 recent.statusbar_show = TRUE;
591 recent.statusbar_show = FALSE;
593 } else if (strcmp(key, RECENT_KEY_PACKET_LIST_COLORIZE) == 0) {
594 if (g_ascii_strcasecmp(value, "true") == 0) {
595 recent.packet_list_colorize = TRUE;
598 recent.packet_list_colorize = FALSE;
600 } else if (strcmp(key, RECENT_GUI_TIME_FORMAT) == 0) {
601 recent.gui_time_format =
602 find_index_from_string_array(value, ts_type_text, TS_RELATIVE);
603 } else if (strcmp(key, RECENT_GUI_TIME_PRECISION) == 0) {
604 recent.gui_time_precision =
605 find_index_from_string_array(value, ts_precision_text, TS_PREC_AUTO);
606 } else if (strcmp(key, RECENT_GUI_ZOOM_LEVEL) == 0) {
607 num = strtol(value, &p, 0);
608 if (p == value || *p != '\0')
609 return PREFS_SET_SYNTAX_ERR; /* number was bad */
610 recent.gui_zoom_level = num;
611 } else if (strcmp(key, RECENT_GUI_BYTES_VIEW) == 0) {
612 num = strtol(value, &p, 0);
613 if (p == value || *p != '\0')
614 return PREFS_SET_SYNTAX_ERR; /* number was bad */
615 recent.gui_bytes_view = num;
616 } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_MAXIMIZED) == 0) {
617 if (g_ascii_strcasecmp(value, "true") == 0) {
618 recent.gui_geometry_main_maximized = TRUE;
621 recent.gui_geometry_main_maximized = FALSE;
624 } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_UPPER_PANE) == 0) {
625 num = strtol(value, &p, 0);
626 if (p == value || *p != '\0')
627 return PREFS_SET_SYNTAX_ERR; /* number was bad */
629 return PREFS_SET_SYNTAX_ERR; /* number must be positive */
630 recent.gui_geometry_main_upper_pane = num;
631 recent.has_gui_geometry_main_upper_pane = TRUE;
632 } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_LOWER_PANE) == 0) {
633 num = strtol(value, &p, 0);
634 if (p == value || *p != '\0')
635 return PREFS_SET_SYNTAX_ERR; /* number was bad */
637 return PREFS_SET_SYNTAX_ERR; /* number must be positive */
638 recent.gui_geometry_main_lower_pane = num;
639 recent.has_gui_geometry_main_lower_pane = TRUE;
641 else if (strcmp(key, RECENT_KEY_COL_WIDTH) == 0) {
642 col_l = prefs_get_string_list(value);
644 return PREFS_SET_SYNTAX_ERR;
645 if ((g_list_length(col_l) % 2) != 0) {
646 /* A title didn't have a matching width. */
647 prefs_clear_string_list(col_l);
648 return PREFS_SET_SYNTAX_ERR;
650 /* Check to make sure all column formats are valid. */
651 col_l_elt = g_list_first(col_l);
653 /* Make sure the format isn't empty. */
654 if (strcmp(col_l_elt->data, "") == 0) {
656 prefs_clear_string_list(col_l);
657 return PREFS_SET_SYNTAX_ERR;
660 /* Check the format. */
661 if (strncmp(col_l_elt->data, cust_format, cust_format_len) != 0) {
662 if (get_column_format_from_str(col_l_elt->data) == -1) {
663 /* It's not a valid column format. */
664 prefs_clear_string_list(col_l);
665 return PREFS_SET_SYNTAX_ERR;
669 /* Go past the format. */
670 col_l_elt = col_l_elt->next;
672 /* Go past the width. */
673 col_l_elt = col_l_elt->next;
675 free_col_width_info(&recent);
676 recent.col_width_list = NULL;
677 col_l_elt = g_list_first(col_l);
679 gchar *fmt = g_strdup(col_l_elt->data);
680 cfmt = (col_width_data *) g_malloc(sizeof(col_width_data));
681 if (strncmp(fmt, cust_format, cust_format_len) != 0) {
682 cfmt->cfmt = get_column_format_from_str(fmt);
685 cfmt->cfmt = COL_CUSTOM;
686 cfmt->cfield = g_strdup(&fmt[cust_format_len+1]); /* add 1 for ':' */
689 if (cfmt->cfmt == -1) {
690 g_free(cfmt->cfield);
692 return PREFS_SET_SYNTAX_ERR; /* string was bad */
695 col_l_elt = col_l_elt->next;
696 cfmt->width = strtol(col_l_elt->data, &p, 0);
697 if (p == col_l_elt->data || (*p != '\0' && *p != ':')) {
698 g_free(cfmt->cfield);
700 return PREFS_SET_SYNTAX_ERR; /* number was bad */
704 cfmt->xalign = *(++p);
709 col_l_elt = col_l_elt->next;
710 recent.col_width_list = g_list_append(recent.col_width_list, cfmt);
712 prefs_clear_string_list(col_l);
719 /* set one user's recent file key/value pair */
720 static prefs_set_pref_e
721 read_set_recent_pair_dynamic(gchar *key, gchar *value, void *private_data _U_)
723 if (strcmp(key, RECENT_KEY_CAPTURE_FILE) == 0) {
725 add_menu_recent_capture_file(u3_expand_device_path(value));
727 add_menu_recent_capture_file(value);
728 } else if (strcmp(key, RECENT_KEY_DISPLAY_FILTER) == 0) {
729 dfilter_combo_add_recent(value);
730 } else if (strcmp(key, RECENT_KEY_CAPTURE_FILTER) == 0) {
731 cfilter_combo_add_recent(value);
732 #ifdef HAVE_PCAP_REMOTE
733 } else if (strcmp(key, RECENT_KEY_REMOTE_HOST) == 0) {
734 capture_remote_combo_add_recent(value);
743 * Given a string of the form "<recent name>:<recent value>", as might appear
744 * as an argument to a "-o" option, parse it and set the recent value in
745 * question. Return an indication of whether it succeeded or failed
749 recent_set_arg(char *prefarg)
754 colonp = strchr(prefarg, ':');
756 return PREFS_SET_SYNTAX_ERR;
762 * Skip over any white space (there probably won't be any, but
763 * as we allow it in the preferences file, we might as well
766 while (isspace((guchar)*p))
770 * Put the colon back, so if our caller uses, in an
771 * error message, the string they passed us, the message
775 return PREFS_SET_SYNTAX_ERR;
778 ret = read_set_recent_pair_static(prefarg, p, NULL);
779 *colonp = ':'; /* put the colon back */
784 /* opens the user's recent common file and read the first part */
786 recent_read_static(char **rf_path_return, int *rf_errno_return)
792 recent.gui_geometry_main_x = 20;
793 recent.gui_geometry_main_y = 20;
794 recent.gui_geometry_main_width = DEF_WIDTH;
795 recent.gui_geometry_main_height = DEF_HEIGHT;
796 recent.gui_geometry_main_maximized= FALSE;
798 recent.gui_geometry_status_pane_left = (DEF_WIDTH/3);
799 recent.gui_geometry_status_pane_right = (DEF_WIDTH/3);
800 recent.gui_geometry_wlan_stats_pane = 200;
802 recent.privs_warn_if_elevated = TRUE;
803 recent.privs_warn_if_no_npf = TRUE;
805 recent.col_width_list = NULL;
807 /* Construct the pathname of the user's recent common file. */
808 rf_path = get_persconffile_path(RECENT_COMMON_FILE_NAME, FALSE, FALSE);
810 /* Read the user's recent common file, if it exists. */
811 *rf_path_return = NULL;
812 if ((rf = ws_fopen(rf_path, "r")) != NULL) {
813 /* We succeeded in opening it; read it. */
814 read_prefs_file(rf_path, rf, read_set_recent_common_pair_static, NULL);
820 /* We failed to open it. If we failed for some reason other than
821 "it doesn't exist", return the errno and the pathname, so our
822 caller can report the error. */
823 if (errno != ENOENT) {
824 *rf_errno_return = errno;
825 *rf_path_return = rf_path;
832 /* opens the user's recent file and read the first part */
834 recent_read_profile_static(char **rf_path_return, int *rf_errno_return)
836 char *rf_path, *rf_common_path;
840 recent.main_toolbar_show = TRUE;
841 recent.filter_toolbar_show = TRUE;
842 recent.airpcap_toolbar_show = FALSE;
843 recent.airpcap_driver_check_show = TRUE;
844 recent.packet_list_show = TRUE;
845 recent.tree_view_show = TRUE;
846 recent.byte_view_show = TRUE;
847 recent.statusbar_show = TRUE;
848 recent.packet_list_colorize = TRUE;
849 recent.gui_time_format = TS_RELATIVE;
850 recent.gui_time_precision = TS_PREC_AUTO;
851 recent.gui_zoom_level = 0;
852 recent.gui_bytes_view = 0;
854 /* pane size of zero will autodetect */
855 recent.gui_geometry_main_upper_pane = 0;
856 recent.gui_geometry_main_lower_pane = 0;
858 recent.has_gui_geometry_main_upper_pane = TRUE;
859 recent.has_gui_geometry_main_lower_pane = TRUE;
860 recent.has_gui_geometry_status_pane = TRUE;
862 if (recent.col_width_list) {
863 free_col_width_info(&recent);
866 /* Construct the pathname of the user's profile recent file. */
867 rf_path = get_persconffile_path(RECENT_FILE_NAME, TRUE, FALSE);
869 /* Read the user's recent file, if it exists. */
870 *rf_path_return = NULL;
871 if ((rf = ws_fopen(rf_path, "r")) != NULL) {
872 /* We succeeded in opening it; read it. */
873 read_prefs_file(rf_path, rf, read_set_recent_pair_static, NULL);
876 /* XXX: The following code doesn't actually do anything since
877 * the "recent common file" always exists. Presumably the
878 * "if (!file_exists())" should actually be "if (file_exists())".
879 * However, I've left the code as is because this
880 * behaviour has existed for quite some time and I don't
881 * know what's supposed to happen at this point.
882 * ToDo: Determine if the "recent common file" should be read at this point
884 rf_common_path = get_persconffile_path(RECENT_COMMON_FILE_NAME, FALSE, FALSE);
885 if (!file_exists(rf_common_path)) {
886 /* Read older common settings from recent file */
887 rf = ws_fopen(rf_path, "r");
888 read_prefs_file(rf_path, rf, read_set_recent_common_pair_static, NULL);
891 g_free(rf_common_path);
895 /* We failed to open it. If we failed for some reason other than
896 "it doesn't exist", return the errno and the pathname, so our
897 caller can report the error. */
898 if (errno != ENOENT) {
899 *rf_errno_return = errno;
900 *rf_path_return = rf_path;
905 /* opens the user's recent file and read it out */
907 recent_read_dynamic(char **rf_path_return, int *rf_errno_return)
913 /* Construct the pathname of the user's recent common file. */
914 rf_path = get_persconffile_path(RECENT_COMMON_FILE_NAME, FALSE, FALSE);
915 if (!file_exists (rf_path)) {
916 /* Recent common file does not exist, read from default recent */
918 rf_path = get_persconffile_path(RECENT_FILE_NAME, FALSE, FALSE);
921 /* Read the user's recent file, if it exists. */
922 *rf_path_return = NULL;
923 if ((rf = ws_fopen(rf_path, "r")) != NULL) {
924 /* We succeeded in opening it; read it. */
925 read_prefs_file(rf_path, rf, read_set_recent_pair_dynamic, NULL);
926 /* set dfilter combobox to have an empty line */
927 dfilter_combo_add_empty();
932 /* We failed to open it. If we failed for some reason other than
933 "it doesn't exist", return the errno and the pathname, so our
934 caller can report the error. */
935 if (errno != ENOENT) {
936 *rf_errno_return = errno;
937 *rf_path_return = rf_path;
943 recent_get_column_width(gint col)
946 col_width_data *col_w;
948 const gchar *cfield = NULL;
950 cfmt = get_column_format(col);
951 if (cfmt == COL_CUSTOM) {
952 cfield = get_column_custom_field(col);
955 col_l = g_list_first(recent.col_width_list);
957 col_w = (col_width_data *) col_l->data;
958 if (col_w->cfmt == cfmt) {
959 if (cfmt != COL_CUSTOM || strcmp (cfield, col_w->cfield) == 0) {
970 recent_set_column_width(gint col, gint width)
973 col_width_data *col_w;
975 const gchar *cfield = NULL;
976 gboolean found = FALSE;
978 cfmt = get_column_format(col);
979 if (cfmt == COL_CUSTOM) {
980 cfield = get_column_custom_field(col);
983 col_l = g_list_first(recent.col_width_list);
985 col_w = (col_width_data *) col_l->data;
986 if (col_w->cfmt == cfmt) {
987 if (cfmt != COL_CUSTOM || strcmp (cfield, col_w->cfield) == 0) {
988 col_w->width = width;
997 col_w = (col_width_data *) g_malloc(sizeof(col_width_data));
1000 col_w->cfield = g_strdup(cfield);
1002 col_w->cfield = NULL;
1004 col_w->width = width;
1006 recent.col_width_list = g_list_append(recent.col_width_list, col_w);
1011 recent_get_column_xalign(gint col)
1014 col_width_data *col_w;
1016 const gchar *cfield = NULL;
1018 cfmt = get_column_format(col);
1019 if (cfmt == COL_CUSTOM) {
1020 cfield = get_column_custom_field(col);
1023 col_l = g_list_first(recent.col_width_list);
1025 col_w = (col_width_data *) col_l->data;
1026 if (col_w->cfmt == cfmt) {
1027 if (cfmt != COL_CUSTOM || strcmp (cfield, col_w->cfield) == 0) {
1028 return col_w->xalign;
1031 col_l = col_l->next;
1038 recent_set_column_xalign(gint col, gchar xalign)
1041 col_width_data *col_w;
1043 const gchar *cfield = NULL;
1044 gboolean found = FALSE;
1046 cfmt = get_column_format(col);
1047 if (cfmt == COL_CUSTOM) {
1048 cfield = get_column_custom_field(col);
1051 col_l = g_list_first(recent.col_width_list);
1053 col_w = (col_width_data *) col_l->data;
1054 if (col_w->cfmt == cfmt) {
1055 if (cfmt != COL_CUSTOM || strcmp (cfield, col_w->cfield) == 0) {
1056 col_w->xalign = xalign;
1061 col_l = col_l->next;
1065 col_w = (col_width_data *) g_malloc(sizeof(col_width_data));
1068 col_w->cfield = g_strdup(cfield);
1070 col_w->cfield = NULL;
1073 col_w->xalign = xalign;
1074 recent.col_width_list = g_list_append(recent.col_width_list, col_w);