PageRenderTime 89ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/ui/recent.c

https://github.com/labx-technologies-llc/wireshark
C | 1357 lines | 1008 code | 158 blank | 191 comment | 382 complexity | 850c2a195fc1501c3801e9414f7f9623 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause
  1. /* recent.c
  2. * Recent "preference" handling routines
  3. * Copyright 2004, Ulf Lamping <ulf.lamping@web.de>
  4. *
  5. * $Id$
  6. *
  7. * Wireshark - Network traffic analyzer
  8. * By Gerald Combs <gerald@wireshark.org>
  9. * Copyright 1998 Gerald Combs
  10. *
  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.
  15. *
  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.
  20. *
  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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  24. */
  25. #include "config.h"
  26. #include <stdio.h>
  27. #include <string.h>
  28. #include <ctype.h>
  29. #include <errno.h>
  30. #include <epan/epan.h>
  31. #include <epan/filesystem.h>
  32. #include <epan/emem.h>
  33. #include <epan/prefs.h>
  34. #include <epan/prefs-int.h>
  35. #include <epan/column.h>
  36. #include <epan/timestamp.h>
  37. #include "ui/last_open_dir.h"
  38. #include "ui/recent.h"
  39. #include "ui/recent_utils.h"
  40. #include "ui/simple_dialog.h"
  41. #include "ui/ui_util.h"
  42. #include <wsutil/u3.h>
  43. #include <wsutil/file_util.h>
  44. #include <wsutil/str_util.h>
  45. #define RECENT_KEY_MAIN_TOOLBAR_SHOW "gui.toolbar_main_show"
  46. #define RECENT_KEY_FILTER_TOOLBAR_SHOW "gui.filter_toolbar_show"
  47. #define RECENT_KEY_WIRELESS_TOOLBAR_SHOW "gui.wireless_toolbar_show"
  48. #define RECENT_KEY_DRIVER_CHECK_SHOW "gui.airpcap_driver_check_show"
  49. #define RECENT_KEY_PACKET_LIST_SHOW "gui.packet_list_show"
  50. #define RECENT_KEY_TREE_VIEW_SHOW "gui.tree_view_show"
  51. #define RECENT_KEY_BYTE_VIEW_SHOW "gui.byte_view_show"
  52. #define RECENT_KEY_STATUSBAR_SHOW "gui.statusbar_show"
  53. #define RECENT_KEY_PACKET_LIST_COLORIZE "gui.packet_list_colorize"
  54. #define RECENT_GUI_TIME_FORMAT "gui.time_format"
  55. #define RECENT_GUI_TIME_PRECISION "gui.time_precision"
  56. #define RECENT_GUI_SECONDS_FORMAT "gui.seconds_format"
  57. #define RECENT_GUI_ZOOM_LEVEL "gui.zoom_level"
  58. #define RECENT_GUI_BYTES_VIEW "gui.bytes_view"
  59. #define RECENT_GUI_GEOMETRY_MAIN_X "gui.geometry_main_x"
  60. #define RECENT_GUI_GEOMETRY_MAIN_Y "gui.geometry_main_y"
  61. #define RECENT_GUI_GEOMETRY_MAIN_WIDTH "gui.geometry_main_width"
  62. #define RECENT_GUI_GEOMETRY_MAIN_HEIGHT "gui.geometry_main_height"
  63. #define RECENT_GUI_GEOMETRY_MAIN_MAXIMIZED "gui.geometry_main_maximized"
  64. #define RECENT_GUI_GEOMETRY_MAIN_UPPER_PANE "gui.geometry_main_upper_pane"
  65. #define RECENT_GUI_GEOMETRY_MAIN_LOWER_PANE "gui.geometry_main_lower_pane"
  66. #define RECENT_GUI_GEOMETRY_STATUS_PANE_LEFT "gui.geometry_status_pane"
  67. #define RECENT_GUI_GEOMETRY_STATUS_PANE_RIGHT "gui.geometry_status_pane_right"
  68. #define RECENT_GUI_GEOMETRY_WLAN_STATS_PANE "gui.geometry_status_wlan_stats_pane"
  69. #define RECENT_LAST_USED_PROFILE "gui.last_used_profile"
  70. #define RECENT_GUI_FILEOPEN_REMEMBERED_DIR "gui.fileopen_remembered_dir"
  71. #define RECENT_GUI_GEOMETRY "gui.geom."
  72. #define RECENT_KEY_PRIVS_WARN_IF_ELEVATED "privs.warn_if_elevated"
  73. #define RECENT_KEY_PRIVS_WARN_IF_NO_NPF "privs.warn_if_no_npf"
  74. #define RECENT_FILE_NAME "recent"
  75. #define RECENT_COMMON_FILE_NAME "recent_common"
  76. recent_settings_t recent;
  77. static const char *ts_type_text[] =
  78. { "RELATIVE", "ABSOLUTE", "ABSOLUTE_WITH_DATE", "DELTA", "DELTA_DIS", "EPOCH", "UTC", "UTC_WITH_DATE", NULL };
  79. static const char *ts_precision_text[] =
  80. { "AUTO", "SEC", "DSEC", "CSEC", "MSEC", "USEC", "NSEC", NULL };
  81. static const char *ts_seconds_text[] =
  82. { "SECONDS", "HOUR_MIN_SEC", NULL };
  83. /* Takes an string and a pointer to an array of strings, and a default int value.
  84. * The array must be terminated by a NULL string. If the string is found in the array
  85. * of strings, the index of that string in the array is returned. Otherwise, the
  86. * default value that was passed as the third argument is returned.
  87. */
  88. static int
  89. find_index_from_string_array(const char *needle, const char **haystack, int default_value)
  90. {
  91. int i = 0;
  92. while (haystack[i] != NULL) {
  93. if (strcmp(needle, haystack[i]) == 0) {
  94. return i;
  95. }
  96. i++;
  97. }
  98. return default_value;
  99. }
  100. static void
  101. free_col_width_info(recent_settings_t *rs)
  102. {
  103. col_width_data *cfmt;
  104. while (rs->col_width_list != NULL) {
  105. cfmt = (col_width_data *)rs->col_width_list->data;
  106. g_free(cfmt->cfield);
  107. g_free(cfmt);
  108. rs->col_width_list = g_list_remove_link(rs->col_width_list, rs->col_width_list);
  109. }
  110. g_list_free(rs->col_width_list);
  111. rs->col_width_list = NULL;
  112. }
  113. /** Write the geometry values of a single window to the recent file.
  114. *
  115. * @param key unused
  116. * @param value the geometry values
  117. * @param rfh recent file handle (FILE)
  118. */
  119. static void
  120. write_recent_geom(gpointer key _U_, gpointer value, gpointer rfh)
  121. {
  122. window_geometry_t *geom = (window_geometry_t *)value;
  123. FILE *rf = (FILE *)rfh;
  124. fprintf(rf, "\n# Geometry and maximized state of %s window.\n", geom->key);
  125. fprintf(rf, "# Decimal integers.\n");
  126. fprintf(rf, RECENT_GUI_GEOMETRY "%s.x: %d\n", geom->key, geom->x);
  127. fprintf(rf, RECENT_GUI_GEOMETRY "%s.y: %d\n", geom->key, geom->y);
  128. fprintf(rf, RECENT_GUI_GEOMETRY "%s.width: %d\n", geom->key,
  129. geom->width);
  130. fprintf(rf, RECENT_GUI_GEOMETRY "%s.height: %d\n", geom->key,
  131. geom->height);
  132. fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
  133. fprintf(rf, RECENT_GUI_GEOMETRY "%s.maximized: %s\n", geom->key,
  134. geom->maximized == TRUE ? "TRUE" : "FALSE");
  135. }
  136. /* the geometry hashtable for all known window classes,
  137. * the window name is the key, and the geometry struct is the value */
  138. static GHashTable *window_geom_hash = NULL;
  139. /* save the window and its current geometry into the geometry hashtable */
  140. void
  141. window_geom_save(const gchar *name, window_geometry_t *geom)
  142. {
  143. gchar *key;
  144. window_geometry_t *work;
  145. /* init hashtable, if not already done */
  146. if(!window_geom_hash) {
  147. window_geom_hash = g_hash_table_new(g_str_hash, g_str_equal);
  148. }
  149. /* if we have an old one, remove and free it first */
  150. work = (window_geometry_t *)g_hash_table_lookup(window_geom_hash, name);
  151. if(work) {
  152. g_hash_table_remove(window_geom_hash, name);
  153. g_free(work->key);
  154. g_free(work);
  155. }
  156. /* g_malloc and insert the new one */
  157. work = (window_geometry_t *)g_malloc(sizeof(window_geometry_t));
  158. *work = *geom;
  159. key = g_strdup(name);
  160. work->key = key;
  161. g_hash_table_insert(window_geom_hash, key, work);
  162. }
  163. /* load the desired geometry for this window from the geometry hashtable */
  164. gboolean
  165. window_geom_load(const gchar *name,
  166. window_geometry_t *geom)
  167. {
  168. window_geometry_t *p;
  169. /* init hashtable, if not already done */
  170. if(!window_geom_hash) {
  171. window_geom_hash = g_hash_table_new(g_str_hash, g_str_equal);
  172. }
  173. p = (window_geometry_t *)g_hash_table_lookup(window_geom_hash, name);
  174. if(p) {
  175. *geom = *p;
  176. return TRUE;
  177. } else {
  178. return FALSE;
  179. }
  180. }
  181. /** Read in a single geometry key value pair from the recent file.
  182. *
  183. * @param name the geom_name of the window
  184. * @param key the subkey of this pair (e.g. "x")
  185. * @param value the new value (e.g. "123")
  186. */
  187. static void
  188. window_geom_recent_read_pair(const char *name,
  189. const char *key,
  190. const char *value)
  191. {
  192. window_geometry_t geom;
  193. /* find window geometry maybe already in hashtable */
  194. if(!window_geom_load(name, &geom)) {
  195. /* not in table, init geom with "basic" values */
  196. geom.key = NULL; /* Will be set in window_geom_save() */
  197. geom.set_pos = FALSE;
  198. geom.x = -1;
  199. geom.y = -1;
  200. geom.set_size = FALSE;
  201. geom.width = -1;
  202. geom.height = -1;
  203. geom.set_maximized = FALSE;/* this is valid in GTK2 only */
  204. geom.maximized = FALSE; /* this is valid in GTK2 only */
  205. }
  206. if (strcmp(key, "x") == 0) {
  207. geom.x = (gint)strtol(value, NULL, 10);
  208. geom.set_pos = TRUE;
  209. } else if (strcmp(key, "y") == 0) {
  210. geom.y = (gint)strtol(value, NULL, 10);
  211. geom.set_pos = TRUE;
  212. } else if (strcmp(key, "width") == 0) {
  213. geom.width = (gint)strtol(value, NULL, 10);
  214. geom.set_size = TRUE;
  215. } else if (strcmp(key, "height") == 0) {
  216. geom.height = (gint)strtol(value, NULL, 10);
  217. geom.set_size = TRUE;
  218. } else if (strcmp(key, "maximized") == 0) {
  219. if (g_ascii_strcasecmp(value, "true") == 0) {
  220. geom.maximized = TRUE;
  221. }
  222. else {
  223. geom.maximized = FALSE;
  224. }
  225. geom.set_maximized = TRUE;
  226. } else {
  227. /*
  228. * Silently ignore the bogus key. We shouldn't abort here,
  229. * as this could be due to a corrupt recent file.
  230. *
  231. * XXX - should we print a message about this?
  232. */
  233. return;
  234. }
  235. /* save / replace geometry in hashtable */
  236. window_geom_save(name, &geom);
  237. }
  238. /** Write all geometry values of all windows to the recent file.
  239. * Will call write_recent_geom() for every existing window type.
  240. *
  241. * @param rf recent file handle from caller
  242. */
  243. static void
  244. window_geom_recent_write_all(FILE *rf)
  245. {
  246. /* init hashtable, if not already done */
  247. if(!window_geom_hash) {
  248. window_geom_hash = g_hash_table_new(g_str_hash, g_str_equal);
  249. }
  250. g_hash_table_foreach(window_geom_hash, write_recent_geom, rf);
  251. }
  252. /* Global list of recent capture filters. */
  253. static GList *recent_cfilter_list;
  254. /*
  255. * Per-interface lists of recent capture filters; stored in a hash
  256. * table indexed by interface name.
  257. */
  258. static GHashTable *per_interface_cfilter_lists_hash;
  259. /* XXX: use a preference for this setting! */
  260. static guint cfilter_combo_max_recent = 20;
  261. /**
  262. * Returns a list of recent capture filters.
  263. *
  264. * @param ifname interface name; NULL refers to the global list.
  265. */
  266. GList *
  267. recent_get_cfilter_list(const gchar *ifname)
  268. {
  269. if (ifname == NULL)
  270. return recent_cfilter_list;
  271. if (per_interface_cfilter_lists_hash == NULL) {
  272. /* No such lists exist. */
  273. return NULL;
  274. }
  275. return (GList *)g_hash_table_lookup(per_interface_cfilter_lists_hash, ifname);
  276. }
  277. /**
  278. * Add a capture filter to the global recent capture filter list or
  279. * the recent capture filter list for an interface.
  280. *
  281. * @param ifname interface name; NULL refers to the global list.
  282. * @param s text of capture filter
  283. */
  284. void
  285. recent_add_cfilter(const gchar *ifname, const gchar *s)
  286. {
  287. GList *cfilter_list;
  288. GList *li;
  289. gchar *li_filter, *newfilter = NULL;
  290. /* Don't add empty filters to the list. */
  291. if (s[0] == '\0')
  292. return;
  293. if (ifname == NULL)
  294. cfilter_list = recent_cfilter_list;
  295. else {
  296. /* If we don't yet have a hash table for per-interface recent
  297. capture filter lists, create one. Have it free the new key
  298. if we're updating an entry rather than creating it below. */
  299. if (per_interface_cfilter_lists_hash == NULL)
  300. per_interface_cfilter_lists_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
  301. cfilter_list = (GList *)g_hash_table_lookup(per_interface_cfilter_lists_hash, ifname);
  302. }
  303. li = g_list_first(cfilter_list);
  304. while (li) {
  305. /* If the filter is already in the list, remove the old one and
  306. * append the new one at the latest position (at g_list_append() below) */
  307. li_filter = (char *)li->data;
  308. if (strcmp(s, li_filter) == 0) {
  309. /* No need to copy the string, we're just moving it. */
  310. newfilter = li_filter;
  311. cfilter_list = g_list_remove(cfilter_list, li->data);
  312. break;
  313. }
  314. li = li->next;
  315. }
  316. if (newfilter == NULL) {
  317. /* The filter wasn't already in the list; make a copy to add. */
  318. newfilter = g_strdup(s);
  319. }
  320. cfilter_list = g_list_append(cfilter_list, newfilter);
  321. if (ifname == NULL)
  322. recent_cfilter_list = cfilter_list;
  323. else
  324. g_hash_table_insert(per_interface_cfilter_lists_hash, g_strdup(ifname), cfilter_list);
  325. }
  326. static void
  327. cfilter_recent_write_all_list(FILE *rf, const gchar *ifname, GList *cfilter_list)
  328. {
  329. guint max_count = 0;
  330. GList *li;
  331. /* write all non empty capture filter strings to the recent file (until max count) */
  332. li = g_list_first(cfilter_list);
  333. while (li && (max_count++ <= cfilter_combo_max_recent) ) {
  334. if (li->data && strlen((const char *)li->data)) {
  335. if (ifname == NULL)
  336. fprintf (rf, RECENT_KEY_CAPTURE_FILTER ": %s\n", (char *)li->data);
  337. else
  338. fprintf (rf, RECENT_KEY_CAPTURE_FILTER ".%s: %s\n", ifname, (char *)li->data);
  339. }
  340. li = li->next;
  341. }
  342. }
  343. static void
  344. cfilter_recent_write_all_hash_callback(gpointer key, gpointer value, gpointer user_data)
  345. {
  346. cfilter_recent_write_all_list((FILE *)user_data, (const gchar *)key, (GList *)value);
  347. }
  348. /** Write all capture filter values to the recent file.
  349. *
  350. * @param rf recent file handle from caller
  351. */
  352. static void
  353. cfilter_recent_write_all(FILE *rf)
  354. {
  355. /* Write out the global list. */
  356. cfilter_recent_write_all_list(rf, NULL, recent_cfilter_list);
  357. /* Write out all the per-interface lists. */
  358. if (per_interface_cfilter_lists_hash != NULL) {
  359. g_hash_table_foreach(per_interface_cfilter_lists_hash, cfilter_recent_write_all_hash_callback, (gpointer)rf);
  360. }
  361. }
  362. /* Attempt to Write out "recent common" to the user's recent common file.
  363. If we got an error report it with a dialog box and return FALSE,
  364. otherwise return TRUE. */
  365. gboolean
  366. write_recent(void)
  367. {
  368. char *pf_dir_path;
  369. char *rf_path;
  370. FILE *rf;
  371. /* To do:
  372. * - Split output lines longer than MAX_VAL_LEN
  373. * - Create a function for the preference directory check/creation
  374. * so that duplication can be avoided with filter.c
  375. */
  376. /* Create the directory that holds personal configuration files, if
  377. necessary. */
  378. if (create_persconffile_dir(&pf_dir_path) == -1) {
  379. simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
  380. "Can't create directory\n\"%s\"\nfor recent file: %s.", pf_dir_path,
  381. g_strerror(errno));
  382. g_free(pf_dir_path);
  383. return FALSE;
  384. }
  385. rf_path = get_persconffile_path(RECENT_COMMON_FILE_NAME, FALSE);
  386. if ((rf = ws_fopen(rf_path, "w")) == NULL) {
  387. simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
  388. "Can't open recent file\n\"%s\": %s.", rf_path,
  389. g_strerror(errno));
  390. g_free(rf_path);
  391. return FALSE;
  392. }
  393. g_free(rf_path);
  394. fputs("# Recent settings file for Wireshark " VERSION ".\n"
  395. "#\n"
  396. "# This file is regenerated each time Wireshark is quit.\n"
  397. "# So be careful, if you want to make manual changes here.\n"
  398. "\n"
  399. "######## Recent capture files (latest last), cannot be altered through command line ########\n"
  400. "\n", rf);
  401. menu_recent_file_write_all(rf);
  402. fputs("\n"
  403. "######## Recent capture filters (latest last), cannot be altered through command line ########\n"
  404. "\n", rf);
  405. cfilter_recent_write_all(rf);
  406. fputs("\n"
  407. "######## Recent display filters (latest last), cannot be altered through command line ########\n"
  408. "\n", rf);
  409. dfilter_recent_combo_write_all(rf);
  410. #ifdef HAVE_PCAP_REMOTE
  411. fputs("\n"
  412. "######## Recent remote hosts, cannot be altered through command line ########\n"
  413. "\n", rf);
  414. capture_remote_combo_recent_write_all(rf);
  415. #endif
  416. fprintf(rf, "\n# Main window geometry.\n");
  417. fprintf(rf, "# Decimal numbers.\n");
  418. fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_X ": %d\n", recent.gui_geometry_main_x);
  419. fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_Y ": %d\n", recent.gui_geometry_main_y);
  420. fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_WIDTH ": %d\n",
  421. recent.gui_geometry_main_width);
  422. fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_HEIGHT ": %d\n",
  423. recent.gui_geometry_main_height);
  424. fprintf(rf, "\n# Main window maximized.\n");
  425. fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
  426. fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_MAXIMIZED ": %s\n",
  427. recent.gui_geometry_main_maximized == TRUE ? "TRUE" : "FALSE");
  428. fprintf(rf, "\n# Statusbar left pane size.\n");
  429. fprintf(rf, "# Decimal number.\n");
  430. if (recent.gui_geometry_status_pane_left != 0) {
  431. fprintf(rf, RECENT_GUI_GEOMETRY_STATUS_PANE_LEFT ": %d\n",
  432. recent.gui_geometry_status_pane_left);
  433. }
  434. fprintf(rf, "\n# Statusbar middle pane size.\n");
  435. fprintf(rf, "# Decimal number.\n");
  436. if (recent.gui_geometry_status_pane_right != 0) {
  437. fprintf(rf, RECENT_GUI_GEOMETRY_STATUS_PANE_RIGHT ": %d\n",
  438. recent.gui_geometry_status_pane_right);
  439. }
  440. fprintf(rf, "\n# Last used Configuration Profile.\n");
  441. fprintf(rf, RECENT_LAST_USED_PROFILE ": %s\n", get_profile_name());
  442. fprintf(rf, "\n# WLAN statistics upper pane size.\n");
  443. fprintf(rf, "# Decimal number.\n");
  444. fprintf(rf, RECENT_GUI_GEOMETRY_WLAN_STATS_PANE ": %d\n",
  445. recent.gui_geometry_wlan_stats_pane);
  446. fprintf(rf, "\n# Warn if running with elevated permissions (e.g. as root).\n");
  447. fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
  448. fprintf(rf, RECENT_KEY_PRIVS_WARN_IF_ELEVATED ": %s\n",
  449. recent.privs_warn_if_elevated == TRUE ? "TRUE" : "FALSE");
  450. fprintf(rf, "\n# Warn if npf.sys isn't loaded on Windows >= 6.0.\n");
  451. fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
  452. fprintf(rf, RECENT_KEY_PRIVS_WARN_IF_NO_NPF ": %s\n",
  453. recent.privs_warn_if_no_npf == TRUE ? "TRUE" : "FALSE");
  454. window_geom_recent_write_all(rf);
  455. fclose(rf);
  456. /* XXX - catch I/O errors (e.g. "ran out of disk space") and return
  457. an error indication, or maybe write to a new recent file and
  458. rename that file on top of the old one only if there are not I/O
  459. errors. */
  460. return TRUE;
  461. }
  462. /* Attempt to Write out profile "recent" to the user's profile recent file.
  463. If we got an error report it with a dialog box and return FALSE,
  464. otherwise return TRUE. */
  465. gboolean
  466. write_profile_recent(void)
  467. {
  468. char *pf_dir_path;
  469. char *rf_path;
  470. FILE *rf;
  471. /* To do:
  472. * - Split output lines longer than MAX_VAL_LEN
  473. * - Create a function for the preference directory check/creation
  474. * so that duplication can be avoided with filter.c
  475. */
  476. /* Create the directory that holds personal configuration files, if
  477. necessary. */
  478. if (create_persconffile_dir(&pf_dir_path) == -1) {
  479. simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
  480. "Can't create directory\n\"%s\"\nfor recent file: %s.", pf_dir_path,
  481. g_strerror(errno));
  482. g_free(pf_dir_path);
  483. return FALSE;
  484. }
  485. rf_path = get_persconffile_path(RECENT_FILE_NAME, TRUE);
  486. if ((rf = ws_fopen(rf_path, "w")) == NULL) {
  487. simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
  488. "Can't open recent file\n\"%s\": %s.", rf_path,
  489. g_strerror(errno));
  490. g_free(rf_path);
  491. return FALSE;
  492. }
  493. g_free(rf_path);
  494. fputs("# Recent settings file for Wireshark " VERSION ".\n"
  495. "#\n"
  496. "# This file is regenerated each time Wireshark is quit\n"
  497. "# and when changing configuration profile.\n"
  498. "# So be careful, if you want to make manual changes here.\n"
  499. "\n", rf);
  500. fprintf(rf, "\n# Main Toolbar show (hide).\n");
  501. fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
  502. fprintf(rf, RECENT_KEY_MAIN_TOOLBAR_SHOW ": %s\n",
  503. recent.main_toolbar_show == TRUE ? "TRUE" : "FALSE");
  504. fprintf(rf, "\n# Filter Toolbar show (hide).\n");
  505. fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
  506. fprintf(rf, RECENT_KEY_FILTER_TOOLBAR_SHOW ": %s\n",
  507. recent.filter_toolbar_show == TRUE ? "TRUE" : "FALSE");
  508. fprintf(rf, "\n# Wireless Settings Toolbar show (hide).\n");
  509. fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
  510. fprintf(rf, RECENT_KEY_WIRELESS_TOOLBAR_SHOW ": %s\n",
  511. recent.wireless_toolbar_show == TRUE ? "TRUE" : "FALSE");
  512. #ifdef HAVE_AIRPCAP
  513. fprintf(rf, "\n# Show (hide) old AirPcap driver warning dialog box.\n");
  514. fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
  515. fprintf(rf, RECENT_KEY_DRIVER_CHECK_SHOW ": %s\n",
  516. recent.airpcap_driver_check_show == TRUE ? "TRUE" : "FALSE");
  517. #endif
  518. fprintf(rf, "\n# Packet list show (hide).\n");
  519. fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
  520. fprintf(rf, RECENT_KEY_PACKET_LIST_SHOW ": %s\n",
  521. recent.packet_list_show == TRUE ? "TRUE" : "FALSE");
  522. fprintf(rf, "\n# Tree view show (hide).\n");
  523. fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
  524. fprintf(rf, RECENT_KEY_TREE_VIEW_SHOW ": %s\n",
  525. recent.tree_view_show == TRUE ? "TRUE" : "FALSE");
  526. fprintf(rf, "\n# Byte view show (hide).\n");
  527. fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
  528. fprintf(rf, RECENT_KEY_BYTE_VIEW_SHOW ": %s\n",
  529. recent.byte_view_show == TRUE ? "TRUE" : "FALSE");
  530. fprintf(rf, "\n# Statusbar show (hide).\n");
  531. fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
  532. fprintf(rf, RECENT_KEY_STATUSBAR_SHOW ": %s\n",
  533. recent.statusbar_show == TRUE ? "TRUE" : "FALSE");
  534. fprintf(rf, "\n# Packet list colorize (hide).\n");
  535. fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
  536. fprintf(rf, RECENT_KEY_PACKET_LIST_COLORIZE ": %s\n",
  537. recent.packet_list_colorize == TRUE ? "TRUE" : "FALSE");
  538. fprintf(rf, "\n# Timestamp display format.\n");
  539. fprintf(rf, "# One of: RELATIVE, ABSOLUTE, ABSOLUTE_WITH_DATE, DELTA, DELTA_DIS, EPOCH, UTC, UTC_WITH_DATE\n");
  540. fprintf(rf, RECENT_GUI_TIME_FORMAT ": %s\n",
  541. ts_type_text[recent.gui_time_format]);
  542. fprintf(rf, "\n# Timestamp display precision.\n");
  543. fprintf(rf, "# One of: AUTO, SEC, DSEC, CSEC, MSEC, USEC, NSEC\n");
  544. fprintf(rf, RECENT_GUI_TIME_PRECISION ": %s\n",
  545. ts_precision_text[recent.gui_time_precision]);
  546. fprintf(rf, "\n# Seconds display format.\n");
  547. fprintf(rf, "# One of: SECONDS, HOUR_MIN_SEC\n");
  548. fprintf(rf, RECENT_GUI_SECONDS_FORMAT ": %s\n",
  549. ts_seconds_text[recent.gui_seconds_format]);
  550. fprintf(rf, "\n# Zoom level.\n");
  551. fprintf(rf, "# A decimal number.\n");
  552. fprintf(rf, RECENT_GUI_ZOOM_LEVEL ": %d\n",
  553. recent.gui_zoom_level);
  554. fprintf(rf, "\n# Bytes view.\n");
  555. fprintf(rf, "# A decimal number.\n");
  556. fprintf(rf, RECENT_GUI_BYTES_VIEW ": %d\n",
  557. recent.gui_bytes_view);
  558. fprintf(rf, "\n# Main window upper (or leftmost) pane size.\n");
  559. fprintf(rf, "# Decimal number.\n");
  560. if (recent.gui_geometry_main_upper_pane != 0) {
  561. fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_UPPER_PANE ": %d\n",
  562. recent.gui_geometry_main_upper_pane);
  563. }
  564. fprintf(rf, "\n# Main window middle pane size.\n");
  565. fprintf(rf, "# Decimal number.\n");
  566. if (recent.gui_geometry_main_lower_pane != 0) {
  567. fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_LOWER_PANE ": %d\n",
  568. recent.gui_geometry_main_lower_pane);
  569. }
  570. fprintf(rf, "\n# Packet list column pixel widths.\n");
  571. fprintf(rf, "# Each pair of strings consists of a column format and its pixel width.\n");
  572. packet_list_recent_write_all(rf);
  573. if (get_last_open_dir() != NULL) {
  574. fprintf(rf, "\n# Last directory navigated to in File Open dialog.\n");
  575. if(u3_active())
  576. fprintf(rf, RECENT_GUI_FILEOPEN_REMEMBERED_DIR ": %s\n", u3_contract_device_path(get_last_open_dir()));
  577. else
  578. fprintf(rf, RECENT_GUI_FILEOPEN_REMEMBERED_DIR ": %s\n", get_last_open_dir());
  579. }
  580. fclose(rf);
  581. /* XXX - catch I/O errors (e.g. "ran out of disk space") and return
  582. an error indication, or maybe write to a new recent file and
  583. rename that file on top of the old one only if there are not I/O
  584. errors. */
  585. return TRUE;
  586. }
  587. /* set one user's recent common file key/value pair */
  588. static prefs_set_pref_e
  589. read_set_recent_common_pair_static(gchar *key, const gchar *value,
  590. void *private_data _U_,
  591. gboolean return_range_errors _U_)
  592. {
  593. long num;
  594. char *p;
  595. if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_MAXIMIZED) == 0) {
  596. if (g_ascii_strcasecmp(value, "true") == 0) {
  597. recent.gui_geometry_main_maximized = TRUE;
  598. }
  599. else {
  600. recent.gui_geometry_main_maximized = FALSE;
  601. }
  602. } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_X) == 0) {
  603. num = strtol(value, &p, 0);
  604. if (p == value || *p != '\0')
  605. return PREFS_SET_SYNTAX_ERR; /* number was bad */
  606. recent.gui_geometry_main_x = (gint)num;
  607. } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_Y) == 0) {
  608. num = strtol(value, &p, 0);
  609. if (p == value || *p != '\0')
  610. return PREFS_SET_SYNTAX_ERR; /* number was bad */
  611. recent.gui_geometry_main_y = (gint)num;
  612. } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_WIDTH) == 0) {
  613. num = strtol(value, &p, 0);
  614. if (p == value || *p != '\0')
  615. return PREFS_SET_SYNTAX_ERR; /* number was bad */
  616. if (num <= 0)
  617. return PREFS_SET_SYNTAX_ERR; /* number must be positive */
  618. recent.gui_geometry_main_width = (gint)num;
  619. } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_HEIGHT) == 0) {
  620. num = strtol(value, &p, 0);
  621. if (p == value || *p != '\0')
  622. return PREFS_SET_SYNTAX_ERR; /* number was bad */
  623. if (num <= 0)
  624. return PREFS_SET_SYNTAX_ERR; /* number must be positive */
  625. recent.gui_geometry_main_height = (gint)num;
  626. } else if (strcmp(key, RECENT_GUI_GEOMETRY_STATUS_PANE_RIGHT) == 0) {
  627. num = strtol(value, &p, 0);
  628. if (p == value || *p != '\0')
  629. return PREFS_SET_SYNTAX_ERR; /* number was bad */
  630. if (num <= 0)
  631. return PREFS_SET_SYNTAX_ERR; /* number must be positive */
  632. recent.gui_geometry_status_pane_right = (gint)num;
  633. recent.has_gui_geometry_status_pane = TRUE;
  634. } else if (strcmp(key, RECENT_GUI_GEOMETRY_STATUS_PANE_LEFT) == 0) {
  635. num = strtol(value, &p, 0);
  636. if (p == value || *p != '\0')
  637. return PREFS_SET_SYNTAX_ERR; /* number was bad */
  638. if (num <= 0)
  639. return PREFS_SET_SYNTAX_ERR; /* number must be positive */
  640. recent.gui_geometry_status_pane_left = (gint)num;
  641. recent.has_gui_geometry_status_pane = TRUE;
  642. } else if (strcmp(key, RECENT_LAST_USED_PROFILE) == 0) {
  643. if ((strcmp(value, DEFAULT_PROFILE) != 0) && profile_exists (value, FALSE)) {
  644. set_profile_name (value);
  645. }
  646. } else if (strcmp(key, RECENT_GUI_GEOMETRY_WLAN_STATS_PANE) == 0) {
  647. num = strtol(value, &p, 0);
  648. if (p == value || *p != '\0')
  649. return PREFS_SET_SYNTAX_ERR; /* number was bad */
  650. if (num <= 0)
  651. return PREFS_SET_SYNTAX_ERR; /* number must be positive */
  652. recent.gui_geometry_wlan_stats_pane = (gint)num;
  653. } else if (strncmp(key, RECENT_GUI_GEOMETRY, sizeof(RECENT_GUI_GEOMETRY)-1) == 0) {
  654. /* now have something like "gui.geom.main.x", split it into win and sub_key */
  655. char *win = &key[sizeof(RECENT_GUI_GEOMETRY)-1];
  656. char *sub_key = strchr(win, '.');
  657. if(sub_key) {
  658. *sub_key = '\0';
  659. sub_key++;
  660. window_geom_recent_read_pair(win, sub_key, value);
  661. }
  662. } else if (strcmp(key, RECENT_KEY_PRIVS_WARN_IF_ELEVATED) == 0) {
  663. if (g_ascii_strcasecmp(value, "true") == 0) {
  664. recent.privs_warn_if_elevated = TRUE;
  665. }
  666. else {
  667. recent.privs_warn_if_elevated = FALSE;
  668. }
  669. } else if (strcmp(key, RECENT_KEY_PRIVS_WARN_IF_NO_NPF) == 0) {
  670. if (g_ascii_strcasecmp(value, "true") == 0) {
  671. recent.privs_warn_if_no_npf = TRUE;
  672. }
  673. else {
  674. recent.privs_warn_if_no_npf = FALSE;
  675. }
  676. }
  677. return PREFS_SET_OK;
  678. }
  679. /* set one user's recent file key/value pair */
  680. static prefs_set_pref_e
  681. read_set_recent_pair_static(gchar *key, const gchar *value,
  682. void *private_data _U_,
  683. gboolean return_range_errors _U_)
  684. {
  685. long num;
  686. char *p;
  687. GList *col_l, *col_l_elt;
  688. col_width_data *cfmt;
  689. const gchar *cust_format = col_format_to_string(COL_CUSTOM);
  690. int cust_format_len = (int) strlen(cust_format);
  691. if (strcmp(key, RECENT_KEY_MAIN_TOOLBAR_SHOW) == 0) {
  692. if (g_ascii_strcasecmp(value, "true") == 0) {
  693. recent.main_toolbar_show = TRUE;
  694. }
  695. else {
  696. recent.main_toolbar_show = FALSE;
  697. }
  698. } else if (strcmp(key, RECENT_KEY_FILTER_TOOLBAR_SHOW) == 0) {
  699. if (g_ascii_strcasecmp(value, "true") == 0) {
  700. recent.filter_toolbar_show = TRUE;
  701. }
  702. else {
  703. recent.filter_toolbar_show = FALSE;
  704. }
  705. /* check both the old and the new keyword */
  706. } else if (strcmp(key, RECENT_KEY_WIRELESS_TOOLBAR_SHOW) == 0 || (strcmp(key, "gui.airpcap_toolbar_show") == 0)) {
  707. if (g_ascii_strcasecmp(value, "true") == 0) {
  708. recent.wireless_toolbar_show = TRUE;
  709. }
  710. else {
  711. recent.wireless_toolbar_show = FALSE;
  712. }
  713. } else if (strcmp(key, RECENT_KEY_DRIVER_CHECK_SHOW) == 0) {
  714. if (g_ascii_strcasecmp(value, "true") == 0) {
  715. recent.airpcap_driver_check_show = TRUE;
  716. }
  717. else {
  718. recent.airpcap_driver_check_show = FALSE;
  719. }
  720. } else if (strcmp(key, RECENT_KEY_PACKET_LIST_SHOW) == 0) {
  721. if (g_ascii_strcasecmp(value, "true") == 0) {
  722. recent.packet_list_show = TRUE;
  723. }
  724. else {
  725. recent.packet_list_show = FALSE;
  726. }
  727. } else if (strcmp(key, RECENT_KEY_TREE_VIEW_SHOW) == 0) {
  728. if (g_ascii_strcasecmp(value, "true") == 0) {
  729. recent.tree_view_show = TRUE;
  730. }
  731. else {
  732. recent.tree_view_show = FALSE;
  733. }
  734. } else if (strcmp(key, RECENT_KEY_BYTE_VIEW_SHOW) == 0) {
  735. if (g_ascii_strcasecmp(value, "true") == 0) {
  736. recent.byte_view_show = TRUE;
  737. }
  738. else {
  739. recent.byte_view_show = FALSE;
  740. }
  741. } else if (strcmp(key, RECENT_KEY_STATUSBAR_SHOW) == 0) {
  742. if (g_ascii_strcasecmp(value, "true") == 0) {
  743. recent.statusbar_show = TRUE;
  744. }
  745. else {
  746. recent.statusbar_show = FALSE;
  747. }
  748. } else if (strcmp(key, RECENT_KEY_PACKET_LIST_COLORIZE) == 0) {
  749. if (g_ascii_strcasecmp(value, "true") == 0) {
  750. recent.packet_list_colorize = TRUE;
  751. }
  752. else {
  753. recent.packet_list_colorize = FALSE;
  754. }
  755. } else if (strcmp(key, RECENT_GUI_TIME_FORMAT) == 0) {
  756. recent.gui_time_format =
  757. (ts_type)find_index_from_string_array(value, ts_type_text, TS_RELATIVE);
  758. } else if (strcmp(key, RECENT_GUI_TIME_PRECISION) == 0) {
  759. recent.gui_time_precision =
  760. find_index_from_string_array(value, ts_precision_text, TS_PREC_AUTO);
  761. } else if (strcmp(key, RECENT_GUI_SECONDS_FORMAT) == 0) {
  762. recent.gui_seconds_format =
  763. (ts_seconds_type)find_index_from_string_array(value, ts_seconds_text, TS_SECONDS_DEFAULT);
  764. } else if (strcmp(key, RECENT_GUI_ZOOM_LEVEL) == 0) {
  765. num = strtol(value, &p, 0);
  766. if (p == value || *p != '\0')
  767. return PREFS_SET_SYNTAX_ERR; /* number was bad */
  768. recent.gui_zoom_level = (gint)num;
  769. } else if (strcmp(key, RECENT_GUI_BYTES_VIEW) == 0) {
  770. num = strtol(value, &p, 0);
  771. if (p == value || *p != '\0')
  772. return PREFS_SET_SYNTAX_ERR; /* number was bad */
  773. recent.gui_bytes_view = (gint)num;
  774. } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_MAXIMIZED) == 0) {
  775. if (g_ascii_strcasecmp(value, "true") == 0) {
  776. recent.gui_geometry_main_maximized = TRUE;
  777. }
  778. else {
  779. recent.gui_geometry_main_maximized = FALSE;
  780. }
  781. } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_UPPER_PANE) == 0) {
  782. num = strtol(value, &p, 0);
  783. if (p == value || *p != '\0')
  784. return PREFS_SET_SYNTAX_ERR; /* number was bad */
  785. if (num <= 0)
  786. return PREFS_SET_SYNTAX_ERR; /* number must be positive */
  787. recent.gui_geometry_main_upper_pane = (gint)num;
  788. recent.has_gui_geometry_main_upper_pane = TRUE;
  789. } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_LOWER_PANE) == 0) {
  790. num = strtol(value, &p, 0);
  791. if (p == value || *p != '\0')
  792. return PREFS_SET_SYNTAX_ERR; /* number was bad */
  793. if (num <= 0)
  794. return PREFS_SET_SYNTAX_ERR; /* number must be positive */
  795. recent.gui_geometry_main_lower_pane = (gint)num;
  796. recent.has_gui_geometry_main_lower_pane = TRUE;
  797. }
  798. else if (strcmp(key, RECENT_KEY_COL_WIDTH) == 0) {
  799. col_l = prefs_get_string_list(value);
  800. if (col_l == NULL)
  801. return PREFS_SET_SYNTAX_ERR;
  802. if ((g_list_length(col_l) % 2) != 0) {
  803. /* A title didn't have a matching width. */
  804. prefs_clear_string_list(col_l);
  805. return PREFS_SET_SYNTAX_ERR;
  806. }
  807. /* Check to make sure all column formats are valid. */
  808. col_l_elt = g_list_first(col_l);
  809. while(col_l_elt) {
  810. /* Make sure the format isn't empty. */
  811. if (strcmp((const char *)col_l_elt->data, "") == 0) {
  812. /* It is. */
  813. prefs_clear_string_list(col_l);
  814. return PREFS_SET_SYNTAX_ERR;
  815. }
  816. /* Check the format. */
  817. if (strncmp((const char *)col_l_elt->data, cust_format, cust_format_len) != 0) {
  818. if (get_column_format_from_str((const gchar *)col_l_elt->data) == -1) {
  819. /* It's not a valid column format. */
  820. prefs_clear_string_list(col_l);
  821. return PREFS_SET_SYNTAX_ERR;
  822. }
  823. }
  824. /* Go past the format. */
  825. col_l_elt = col_l_elt->next;
  826. /* Go past the width. */
  827. col_l_elt = col_l_elt->next;
  828. }
  829. free_col_width_info(&recent);
  830. recent.col_width_list = NULL;
  831. col_l_elt = g_list_first(col_l);
  832. while(col_l_elt) {
  833. gchar *fmt = g_strdup((const gchar *)col_l_elt->data);
  834. cfmt = (col_width_data *) g_malloc(sizeof(col_width_data));
  835. if (strncmp(fmt, cust_format, cust_format_len) != 0) {
  836. cfmt->cfmt = get_column_format_from_str(fmt);
  837. cfmt->cfield = NULL;
  838. } else {
  839. cfmt->cfmt = COL_CUSTOM;
  840. cfmt->cfield = g_strdup(&fmt[cust_format_len+1]); /* add 1 for ':' */
  841. }
  842. g_free (fmt);
  843. if (cfmt->cfmt == -1) {
  844. g_free(cfmt->cfield);
  845. g_free(cfmt);
  846. return PREFS_SET_SYNTAX_ERR; /* string was bad */
  847. }
  848. col_l_elt = col_l_elt->next;
  849. cfmt->width = (gint)strtol((const char *)col_l_elt->data, &p, 0);
  850. if (p == col_l_elt->data || (*p != '\0' && *p != ':')) {
  851. g_free(cfmt->cfield);
  852. g_free(cfmt);
  853. return PREFS_SET_SYNTAX_ERR; /* number was bad */
  854. }
  855. if (*p == ':') {
  856. cfmt->xalign = *(++p);
  857. } else {
  858. cfmt->xalign = COLUMN_XALIGN_DEFAULT;
  859. }
  860. col_l_elt = col_l_elt->next;
  861. recent.col_width_list = g_list_append(recent.col_width_list, cfmt);
  862. }
  863. prefs_clear_string_list(col_l);
  864. } else if (strcmp(key, RECENT_GUI_FILEOPEN_REMEMBERED_DIR) == 0) {
  865. if (recent.gui_fileopen_remembered_dir) {
  866. g_free (recent.gui_fileopen_remembered_dir);
  867. }
  868. recent.gui_fileopen_remembered_dir = g_strdup(value);
  869. }
  870. return PREFS_SET_OK;
  871. }
  872. /* set one user's recent file key/value pair */
  873. static prefs_set_pref_e
  874. read_set_recent_pair_dynamic(gchar *key, const gchar *value,
  875. void *private_data _U_,
  876. gboolean return_range_errors _U_)
  877. {
  878. if (!isprint_string(value)) {
  879. return PREFS_SET_SYNTAX_ERR;
  880. }
  881. if (strcmp(key, RECENT_KEY_CAPTURE_FILE) == 0) {
  882. if (u3_active())
  883. add_menu_recent_capture_file(u3_expand_device_path(value));
  884. else
  885. add_menu_recent_capture_file(value);
  886. } else if (strcmp(key, RECENT_KEY_DISPLAY_FILTER) == 0) {
  887. dfilter_combo_add_recent(value);
  888. } else if (strcmp(key, RECENT_KEY_CAPTURE_FILTER) == 0) {
  889. recent_add_cfilter(NULL, value);
  890. } else if (g_str_has_prefix(key, RECENT_KEY_CAPTURE_FILTER ".")) {
  891. /* strrchr() can't fail - string has a prefix that ends with a "." */
  892. recent_add_cfilter(strrchr(key, '.') + 1, value);
  893. #ifdef HAVE_PCAP_REMOTE
  894. } else if (strcmp(key, RECENT_KEY_REMOTE_HOST) == 0) {
  895. capture_remote_combo_add_recent(value);
  896. #endif
  897. }
  898. return PREFS_SET_OK;
  899. }
  900. /*
  901. * Given a string of the form "<recent name>:<recent value>", as might appear
  902. * as an argument to a "-o" option, parse it and set the recent value in
  903. * question. Return an indication of whether it succeeded or failed
  904. * in some fashion.
  905. */
  906. int
  907. recent_set_arg(char *prefarg)
  908. {
  909. gchar *p, *colonp;
  910. int ret;
  911. colonp = strchr(prefarg, ':');
  912. if (colonp == NULL)
  913. return PREFS_SET_SYNTAX_ERR;
  914. p = colonp;
  915. *p++ = '\0';
  916. /*
  917. * Skip over any white space (there probably won't be any, but
  918. * as we allow it in the preferences file, we might as well
  919. * allow it here).
  920. */
  921. while (isspace((guchar)*p))
  922. p++;
  923. if (*p == '\0') {
  924. /*
  925. * Put the colon back, so if our caller uses, in an
  926. * error message, the string they passed us, the message
  927. * looks correct.
  928. */
  929. *colonp = ':';
  930. return PREFS_SET_SYNTAX_ERR;
  931. }
  932. ret = read_set_recent_pair_static(prefarg, p, NULL, TRUE);
  933. *colonp = ':'; /* put the colon back */
  934. return ret;
  935. }
  936. /* opens the user's recent common file and read the first part */
  937. void
  938. recent_read_static(char **rf_path_return, int *rf_errno_return)
  939. {
  940. char *rf_path;
  941. FILE *rf;
  942. /* set defaults */
  943. recent.gui_geometry_main_x = 20;
  944. recent.gui_geometry_main_y = 20;
  945. recent.gui_geometry_main_width = DEF_WIDTH;
  946. recent.gui_geometry_main_height = DEF_HEIGHT;
  947. recent.gui_geometry_main_maximized= FALSE;
  948. recent.gui_geometry_status_pane_left = (DEF_WIDTH/3);
  949. recent.gui_geometry_status_pane_right = (DEF_WIDTH/3);
  950. recent.gui_geometry_wlan_stats_pane = 200;
  951. recent.privs_warn_if_elevated = TRUE;
  952. recent.privs_warn_if_no_npf = TRUE;
  953. recent.col_width_list = NULL;
  954. recent.gui_fileopen_remembered_dir = NULL;
  955. /* Construct the pathname of the user's recent common file. */
  956. rf_path = get_persconffile_path(RECENT_COMMON_FILE_NAME, FALSE);
  957. /* Read the user's recent common file, if it exists. */
  958. *rf_path_return = NULL;
  959. if ((rf = ws_fopen(rf_path, "r")) != NULL) {
  960. /* We succeeded in opening it; read it. */
  961. read_prefs_file(rf_path, rf, read_set_recent_common_pair_static, NULL);
  962. fclose(rf);
  963. g_free(rf_path);
  964. rf_path = NULL;
  965. } else {
  966. /* We failed to open it. If we failed for some reason other than
  967. "it doesn't exist", return the errno and the pathname, so our
  968. caller can report the error. */
  969. if (errno != ENOENT) {
  970. *rf_errno_return = errno;
  971. *rf_path_return = rf_path;
  972. }
  973. }
  974. }
  975. /* opens the user's recent file and read the first part */
  976. void
  977. recent_read_profile_static(char **rf_path_return, int *rf_errno_return)
  978. {
  979. char *rf_path, *rf_common_path;
  980. FILE *rf;
  981. /* set defaults */
  982. recent.main_toolbar_show = TRUE;
  983. recent.filter_toolbar_show = TRUE;
  984. recent.wireless_toolbar_show = FALSE;
  985. recent.airpcap_driver_check_show = TRUE;
  986. recent.packet_list_show = TRUE;
  987. recent.tree_view_show = TRUE;
  988. recent.byte_view_show = TRUE;
  989. recent.statusbar_show = TRUE;
  990. recent.packet_list_colorize = TRUE;
  991. recent.gui_time_format = TS_RELATIVE;
  992. recent.gui_time_precision = TS_PREC_AUTO;
  993. recent.gui_seconds_format = TS_SECONDS_DEFAULT;
  994. recent.gui_zoom_level = 0;
  995. recent.gui_bytes_view = 0;
  996. /* pane size of zero will autodetect */
  997. recent.gui_geometry_main_upper_pane = 0;
  998. recent.gui_geometry_main_lower_pane = 0;
  999. recent.has_gui_geometry_main_upper_pane = TRUE;
  1000. recent.has_gui_geometry_main_lower_pane = TRUE;
  1001. recent.has_gui_geometry_status_pane = TRUE;
  1002. if (recent.col_width_list) {
  1003. free_col_width_info(&recent);
  1004. }
  1005. if (recent.gui_fileopen_remembered_dir) {
  1006. g_free (recent.gui_fileopen_remembered_dir);
  1007. recent.gui_fileopen_remembered_dir = NULL;
  1008. }
  1009. /* Construct the pathname of the user's profile recent file. */
  1010. rf_path = get_persconffile_path(RECENT_FILE_NAME, TRUE);
  1011. /* Read the user's recent file, if it exists. */
  1012. *rf_path_return = NULL;
  1013. if ((rf = ws_fopen(rf_path, "r")) != NULL) {
  1014. /* We succeeded in opening it; read it. */
  1015. read_prefs_file(rf_path, rf, read_set_recent_pair_static, NULL);
  1016. fclose(rf);
  1017. /* XXX: The following code doesn't actually do anything since
  1018. * the "recent common file" always exists. Presumably the
  1019. * "if (!file_exists())" should actually be "if (file_exists())".
  1020. * However, I've left the code as is because this
  1021. * behaviour has existed for quite some time and I don't
  1022. * know what's supposed to happen at this point.
  1023. * ToDo: Determine if the "recent common file" should be read at this point
  1024. */
  1025. rf_common_path = get_persconffile_path(RECENT_COMMON_FILE_NAME, FALSE);
  1026. if (!file_exists(rf_common_path)) {
  1027. /* Read older common settings from recent file */
  1028. rf = ws_fopen(rf_path, "r");
  1029. read_prefs_file(rf_path, rf, read_set_recent_common_pair_static, NULL);
  1030. fclose(rf);
  1031. }
  1032. g_free(rf_common_path);
  1033. g_free(rf_path);
  1034. rf_path = NULL;
  1035. } else {
  1036. /* We failed to open it. If we failed for some reason other than
  1037. "it doesn't exist", return the errno and the pathname, so our
  1038. caller can report the error. */
  1039. if (errno != ENOENT) {
  1040. *rf_errno_return = errno;
  1041. *rf_path_return = rf_path;
  1042. }
  1043. }
  1044. }
  1045. /* opens the user's recent file and read it out */
  1046. void
  1047. recent_read_dynamic(char **rf_path_return, int *rf_errno_return)
  1048. {
  1049. char *rf_path;
  1050. FILE *rf;
  1051. /* Construct the pathname of the user's recent common file. */
  1052. rf_path = get_persconffile_path(RECENT_COMMON_FILE_NAME, FALSE);
  1053. if (!file_exists (rf_path)) {
  1054. /* Recent common file does not exist, read from default recent */
  1055. g_free (rf_path);
  1056. rf_path = get_persconffile_path(RECENT_FILE_NAME, FALSE);
  1057. }
  1058. /* Read the user's recent file, if it exists. */
  1059. *rf_path_return = NULL;
  1060. if ((rf = ws_fopen(rf_path, "r")) != NULL) {
  1061. /* We succeeded in opening it; read it. */
  1062. read_prefs_file(rf_path, rf, read_set_recent_pair_dynamic, NULL);
  1063. #if 0
  1064. /* set dfilter combobox to have an empty line */
  1065. dfilter_combo_add_empty();
  1066. #endif
  1067. fclose(rf);
  1068. g_free(rf_path);
  1069. rf_path = NULL;
  1070. } else {
  1071. /* We failed to open it. If we failed for some reason other than
  1072. "it doesn't exist", return the errno and the pathname, so our
  1073. caller can report the error. */
  1074. if (errno != ENOENT) {
  1075. *rf_errno_return = errno;
  1076. *rf_path_return = rf_path;
  1077. }
  1078. }
  1079. }
  1080. gint
  1081. recent_get_column_width(gint col)
  1082. {
  1083. GList *col_l;
  1084. col_width_data *col_w;
  1085. gint cfmt;
  1086. const gchar *cfield = NULL;
  1087. cfmt = get_column_format(col);
  1088. if (cfmt == COL_CUSTOM) {
  1089. cfield = get_column_custom_field(col);
  1090. }
  1091. col_l = g_list_first(recent.col_width_list);
  1092. while (col_l) {
  1093. col_w = (col_width_data *) col_l->data;
  1094. if (col_w->cfmt == cfmt) {
  1095. if (cfmt != COL_CUSTOM || strcmp (cfield, col_w->cfield) == 0) {
  1096. return col_w->width;
  1097. }
  1098. }
  1099. col_l = col_l->next;
  1100. }
  1101. return -1;
  1102. }
  1103. void
  1104. recent_set_column_width(gint col, gint width)
  1105. {
  1106. GList *col_l;
  1107. col_width_data *col_w;
  1108. gint cfmt;
  1109. const gchar *cfield = NULL;
  1110. gboolean found = FALSE;
  1111. cfmt = get_column_format(col);
  1112. if (cfmt == COL_CUSTOM) {
  1113. cfield = get_column_custom_field(col);
  1114. }
  1115. col_l = g_list_first(recent.col_width_list);
  1116. while (col_l) {
  1117. col_w = (col_width_data *) col_l->data;
  1118. if (col_w->cfmt == cfmt) {
  1119. if (cfmt != COL_CUSTOM || strcmp (cfield, col_w->cfield) == 0) {
  1120. col_w->width = width;
  1121. found = TRUE;
  1122. break;
  1123. }
  1124. }
  1125. col_l = col_l->next;
  1126. }
  1127. if (!found) {
  1128. col_w = (col_width_data *) g_malloc(sizeof(col_width_data));
  1129. col_w->cfmt = cfmt;
  1130. if (cfield) {
  1131. col_w->cfield = g_strdup(cfield);
  1132. } else {
  1133. col_w->cfield = NULL;
  1134. }
  1135. col_w->width = width;
  1136. col_w->xalign = COLUMN_XALIGN_DEFAULT;
  1137. recent.col_width_list = g_list_append(recent.col_width_list, col_w);
  1138. }
  1139. }
  1140. gchar
  1141. recent_get_column_xalign(gint col)
  1142. {
  1143. GList *col_l;
  1144. col_width_data *col_w;
  1145. gint cfmt;
  1146. const gchar *cfield = NULL;
  1147. cfmt = get_column_format(col);
  1148. if (cfmt == COL_CUSTOM) {
  1149. cfield = get_column_custom_field(col);
  1150. }
  1151. col_l = g_list_first(recent.col_width_list);
  1152. while (col_l) {
  1153. col_w = (col_width_data *) col_l->data;
  1154. if (col_w->cfmt == cfmt) {
  1155. if (cfmt != COL_CUSTOM || strcmp (cfield, col_w->cfield) == 0) {
  1156. return col_w->xalign;
  1157. }
  1158. }
  1159. col_l = col_l->next;
  1160. }
  1161. return 0;
  1162. }
  1163. void
  1164. recent_set_column_xalign(gint col, gchar xalign)
  1165. {
  1166. GList *col_l;
  1167. col_width_data *col_w;
  1168. gint cfmt;
  1169. const gchar *cfield = NULL;
  1170. gboolean found = FALSE;
  1171. cfmt = get_column_format(col);
  1172. if (cfmt == COL_CUSTOM) {
  1173. cfield = get_column_custom_field(col);
  1174. }
  1175. col_l = g_list_first(recent.col_width_list);
  1176. while (col_l) {
  1177. col_w = (col_width_data *) col_l->data;
  1178. if (col_w->cfmt == cfmt) {
  1179. if (cfmt != COL_CUSTOM || strcmp (cfield, col_w->cfield) == 0) {
  1180. col_w->xalign = xalign;
  1181. found = TRUE;
  1182. break;
  1183. }
  1184. }
  1185. col_l = col_l->next;
  1186. }
  1187. if (!found) {
  1188. col_w = (col_width_data *) g_malloc(sizeof(col_width_data));
  1189. col_w->cfmt = cfmt;
  1190. if (cfield) {
  1191. col_w->cfield = g_strdup(cfield);
  1192. } else {
  1193. col_w->cfield = NULL;
  1194. }
  1195. col_w->width = 40;
  1196. col_w->xalign = xalign;
  1197. recent.col_width_list = g_list_append(recent.col_width_list, col_w);
  1198. }
  1199. }