Bug Summary

File:builds/wireshark/wireshark/ui/recent.c
Warning:line 1812, column 13
Null pointer passed to 1st parameter expecting 'nonnull'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name recent.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-21/lib/clang/21 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_DEBUG -D WS_DEBUG_UTF_8 -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -I /builds/wireshark/wireshark/ui -I /builds/wireshark/wireshark/build/ui -I /builds/wireshark/wireshark/wiretap -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=gnu11 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2026-03-14-100340-3641-1 -x c /builds/wireshark/wireshark/ui/recent.c
1/* recent.c
2 * Recent "preference" handling routines
3 * Copyright 2004, Ulf Lamping <[email protected]>
4 *
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <[email protected]>
7 * Copyright 1998 Gerald Combs
8 *
9 * SPDX-License-Identifier: GPL-2.0-or-later
10 */
11
12#include "config.h"
13
14#include <wireshark.h>
15
16#include <stdlib.h>
17#include <errno(*__errno_location ()).h>
18
19#include <app/application_flavor.h>
20#include <wsutil/filesystem.h>
21#include <epan/prefs.h>
22#include <epan/prefs-int.h>
23#include <epan/column.h>
24#include <wsutil/value_string.h>
25
26#ifdef HAVE_PCAP_REMOTE
27#include "ui/capture_opts.h"
28#endif
29#include "ui/util.h"
30#include "ui/recent.h"
31#include "ui/recent_utils.h"
32#include "ui/packet_list_utils.h"
33#include "ui/simple_dialog.h"
34
35#include <wsutil/file_util.h>
36#include <wsutil/strtoi.h>
37
38#define RECENT_KEY_MAIN_TOOLBAR_SHOW"gui.toolbar_main_show" "gui.toolbar_main_show"
39#define RECENT_KEY_FILTER_TOOLBAR_SHOW"gui.filter_toolbar_show" "gui.filter_toolbar_show"
40#define RECENT_KEY_WIRELESS_TOOLBAR_SHOW"gui.wireless_toolbar_show" "gui.wireless_toolbar_show"
41#define RECENT_KEY_PACKET_LIST_SHOW"gui.packet_list_show" "gui.packet_list_show"
42#define RECENT_KEY_TREE_VIEW_SHOW"gui.tree_view_show" "gui.tree_view_show"
43#define RECENT_KEY_BYTE_VIEW_SHOW"gui.byte_view_show" "gui.byte_view_show"
44#define RECENT_KEY_PACKET_DIAGRAM_SHOW"gui.packet_diagram_show" "gui.packet_diagram_show"
45#define RECENT_KEY_STATUSBAR_SHOW"gui.statusbar_show" "gui.statusbar_show"
46#define RECENT_KEY_PACKET_LIST_COLORIZE"gui.packet_list_colorize" "gui.packet_list_colorize"
47#define RECENT_KEY_CAPTURE_AUTO_SCROLL"capture.auto_scroll" "capture.auto_scroll"
48#define RECENT_KEY_AGGREGATION_VIEW"capture.aggregation_view" "capture.aggregation_view"
49#define RECENT_GUI_TIME_FORMAT"gui.time_format" "gui.time_format"
50#define RECENT_GUI_TIME_PRECISION"gui.time_precision" "gui.time_precision"
51#define RECENT_GUI_SECONDS_FORMAT"gui.seconds_format" "gui.seconds_format"
52#define RECENT_GUI_ZOOM_LEVEL"gui.zoom_level" "gui.zoom_level"
53#define RECENT_GUI_BYTES_VIEW"gui.bytes_view" "gui.bytes_view"
54#define RECENT_GUI_BYTES_ENCODING"gui.bytes_encoding" "gui.bytes_encoding"
55#define RECENT_GUI_ALLOW_HOVER_SELECTION"gui.allow_hover_selection" "gui.allow_hover_selection"
56#define RECENT_GUI_PACKET_DIAGRAM_FIELD_VALUES"gui.packet_diagram_field_values" "gui.packet_diagram_field_values"
57#define RECENT_GUI_GEOMETRY_MAIN_X"gui.geometry_main_x" "gui.geometry_main_x"
58#define RECENT_GUI_GEOMETRY_MAIN_Y"gui.geometry_main_y" "gui.geometry_main_y"
59#define RECENT_GUI_GEOMETRY_MAIN_WIDTH"gui.geometry_main_width" "gui.geometry_main_width"
60#define RECENT_GUI_GEOMETRY_MAIN_HEIGHT"gui.geometry_main_height" "gui.geometry_main_height"
61#define RECENT_GUI_GEOMETRY_MAIN_MAXIMIZED"gui.geometry_main_maximized" "gui.geometry_main_maximized"
62#define RECENT_GUI_GEOMETRY_MAIN"gui.geometry_main" "gui.geometry_main"
63#define RECENT_GUI_GEOMETRY_LEFTALIGN_ACTIONS"gui.geometry_leftalign_actions" "gui.geometry_leftalign_actions"
64#define RECENT_GUI_GEOMETRY_MAIN_UPPER_PANE"gui.geometry_main_upper_pane" "gui.geometry_main_upper_pane"
65#define RECENT_GUI_GEOMETRY_MAIN_LOWER_PANE"gui.geometry_main_lower_pane" "gui.geometry_main_lower_pane"
66#define RECENT_GUI_GEOMETRY_MAIN_MASTER_SPLIT"gui.geometry_main_master_split" "gui.geometry_main_master_split"
67#define RECENT_GUI_GEOMETRY_MAIN_EXTRA_SPLIT"gui.geometry_main_extra_split" "gui.geometry_main_extra_split"
68#define RECENT_LAST_USED_PROFILE"gui.last_used_profile" "gui.last_used_profile"
69#define RECENT_PROFILE_SWITCH_CHECK_COUNT"gui.profile_switch_check_count" "gui.profile_switch_check_count"
70#define RECENT_GUI_FILEOPEN_REMEMBERED_DIR"gui.fileopen_remembered_dir" "gui.fileopen_remembered_dir"
71#define RECENT_GUI_CONVERSATION_TABS"gui.conversation_tabs" "gui.conversation_tabs"
72#define RECENT_GUI_CONVERSATION_TABS_COLUMNS"gui.conversation_tabs_columns" "gui.conversation_tabs_columns"
73#define RECENT_GUI_ENDPOINT_TABS"gui.endpoint_tabs" "gui.endpoint_tabs"
74#define RECENT_GUI_ENDPOINT_TABS_COLUMNS"gui.endpoint_tabs_columns" "gui.endpoint_tabs_columns"
75#define RECENT_GUI_RLC_PDUS_FROM_MAC_FRAMES"gui.rlc_pdus_from_mac_frames" "gui.rlc_pdus_from_mac_frames"
76#define RECENT_GUI_CUSTOM_COLORS"gui.custom_colors" "gui.custom_colors"
77#define RECENT_GUI_TOOLBAR_SHOW"gui.additional_toolbar_show" "gui.additional_toolbar_show"
78#define RECENT_GUI_INTERFACE_TOOLBAR_SHOW"gui.interface_toolbar_show" "gui.interface_toolbar_show"
79#define RECENT_GUI_SEARCH_IN"gui.search_in" "gui.search_in"
80#define RECENT_GUI_SEARCH_CHAR_SET"gui.search_char_set" "gui.search_char_set"
81#define RECENT_GUI_SEARCH_CASE_SENSITIVE"gui.search_case_sensitive" "gui.search_case_sensitive"
82#define RECENT_GUI_SEARCH_REVERSE_DIR"gui.search_reverse_dir" "gui.search_reverse_dir"
83#define RECENT_GUI_SEARCH_MULTIPLE_OCCURS"gui.search_multiple_occurs" "gui.search_multiple_occurs"
84#define RECENT_GUI_SEARCH_TYPE"gui.search_type" "gui.search_type"
85#define RECENT_GUI_FOLLOW_SHOW"gui.follow_show" "gui.follow_show"
86#define RECENT_GUI_FOLLOW_DELTA"gui.follow_delta" "gui.follow_delta"
87#define RECENT_GUI_SHOW_BYTES_DECODE"gui.show_bytes_decode" "gui.show_bytes_decode"
88#define RECENT_GUI_SHOW_BYTES_SHOW"gui.show_bytes_show" "gui.show_bytes_show"
89#define RECENT_GUI_TSD_MA_WINDOW_SIZE"gui.tsd_ma_window_size" "gui.tsd_ma_window_size"
90#define RECENT_GUI_TSD_THROUGHPUT_SHOW"gui.tsd_throughput_show" "gui.tsd_throughput_show"
91#define RECENT_GUI_TSD_GOODPUT_SHOW"gui.tsd_goodput_show" "gui.tsd_goodput_show"
92#define RECENT_KEY_SIDEBAR_LEARN_VISIBLE"gui.welcome_page.sidebar.learn_visible" "gui.welcome_page.sidebar.learn_visible"
93#define RECENT_KEY_SIDEBAR_TIPS_VISIBLE"gui.welcome_page.sidebar.tips_visible" "gui.welcome_page.sidebar.tips_visible"
94#define RECENT_KEY_SIDEBAR_TIPS_EVENTS"gui.welcome_page.sidebar.tips_events" "gui.welcome_page.sidebar.tips_events"
95#define RECENT_KEY_SIDEBAR_TIPS_SPONSORSHIP"gui.welcome_page.sidebar.tips_sponsorship" "gui.welcome_page.sidebar.tips_sponsorship"
96#define RECENT_KEY_SIDEBAR_TIPS_TIPS"gui.welcome_page.sidebar.tips_tips" "gui.welcome_page.sidebar.tips_tips"
97#define RECENT_KEY_SIDEBAR_TIPS_INTERVAL"gui.welcome_page.sidebar.tips_interval" "gui.welcome_page.sidebar.tips_interval"
98
99#define RECENT_GUI_GEOMETRY"gui.geom." "gui.geom."
100
101#define RECENT_KEY_PRIVS_WARN_IF_ELEVATED"privs.warn_if_elevated" "privs.warn_if_elevated"
102#define RECENT_KEY_SYS_WARN_IF_NO_CAPTURE"sys.warn_if_no_capture" "sys.warn_if_no_capture"
103
104#define RECENT_FILE_NAME"recent" "recent"
105#define RECENT_COMMON_FILE_NAME"recent_common" "recent_common"
106
107recent_settings_t recent;
108
109static const value_string ts_type_values[] = {
110 { TS_RELATIVE, "RELATIVE" },
111 { TS_RELATIVE_CAP, "RELATIVE_CAP" },
112 { TS_ABSOLUTE, "ABSOLUTE" },
113 { TS_ABSOLUTE_WITH_YMD, "ABSOLUTE_WITH_YMD" },
114 { TS_ABSOLUTE_WITH_YDOY, "ABSOLUTE_WITH_YDOY" },
115 { TS_ABSOLUTE_WITH_YMD, "ABSOLUTE_WITH_DATE" }, /* Backward compatibility */
116 { TS_DELTA, "DELTA" },
117 { TS_DELTA_DIS, "DELTA_DIS" },
118 { TS_EPOCH, "EPOCH" },
119 { TS_UTC, "UTC" },
120 { TS_UTC_WITH_YMD, "UTC_WITH_YMD" },
121 { TS_UTC_WITH_YDOY, "UTC_WITH_YDOY" },
122 { TS_UTC_WITH_YMD, "UTC_WITH_DATE" }, /* Backward compatibility */
123 { 0, NULL((void*)0) }
124};
125
126/*
127 * NOTE: all values other than TS_PREC_AUTO are the number of digits
128 * of precision.
129 *
130 * We continue to use the old names for values where they may have
131 * been written to the recent file by previous releases. For other
132 * values, we just write it out numerically.
133 */
134static const value_string ts_precision_values[] = {
135 { TS_PREC_AUTO, "AUTO" },
136 { TS_PREC_FIXED_SEC, "SEC" },
137 { TS_PREC_FIXED_100_MSEC, "DSEC" },
138 { TS_PREC_FIXED_10_MSEC, "CSEC" },
139 { TS_PREC_FIXED_MSEC, "MSEC" },
140 { TS_PREC_FIXED_USEC, "USEC" },
141 { TS_PREC_FIXED_NSEC, "NSEC" },
142 { 0, NULL((void*)0) }
143};
144
145static const value_string ts_seconds_values[] = {
146 { TS_SECONDS_DEFAULT, "SECONDS" },
147 { TS_SECONDS_HOUR_MIN_SEC, "HOUR_MIN_SEC" },
148 { 0, NULL((void*)0) }
149};
150
151static const value_string bytes_view_type_values[] = {
152 { BYTES_HEX, "HEX" },
153 { BYTES_BITS, "BITS" },
154 { BYTES_DEC, "DEC" },
155 { BYTES_OCT, "OCT" },
156 { 0, NULL((void*)0) }
157};
158
159static const value_string bytes_encoding_type_values[] = {
160 { BYTES_ENC_FROM_PACKET, "FROM_PACKET" },
161 { BYTES_ENC_ASCII, "ASCII" },
162 { BYTES_ENC_EBCDIC, "EBCDIC" },
163 { 0, NULL((void*)0) }
164};
165
166static const value_string search_in_values[] = {
167 { SEARCH_IN_PACKET_LIST, "PACKET_LIST" },
168 { SEARCH_IN_PACKET_DETAILS, "PACKET_DETAILS" },
169 { SEARCH_IN_PACKET_BYTES, "PACKET_BYTES" },
170 { 0, NULL((void*)0) }
171};
172
173static const value_string search_char_set_values[] = {
174 { SEARCH_CHAR_SET_NARROW_AND_WIDE, "NARROW_AND_WIDE" },
175 { SEARCH_CHAR_SET_NARROW, "NARROW" },
176 { SEARCH_CHAR_SET_WIDE, "WIDE" },
177 { 0, NULL((void*)0) }
178};
179
180static const value_string search_type_values[] = {
181 { SEARCH_TYPE_DISPLAY_FILTER, "DISPLAY_FILTER" },
182 { SEARCH_TYPE_HEX_VALUE, "HEX_VALUE" },
183 { SEARCH_TYPE_STRING, "STRING" },
184 { SEARCH_TYPE_REGEX, "REGEX" },
185 { 0, NULL((void*)0) }
186};
187
188static const value_string bytes_show_values[] = {
189 { SHOW_ASCII, "ASCII" },
190 { SHOW_ASCII_CONTROL, "ASCII_CONTROL" },
191 { SHOW_CARRAY, "C_ARRAYS" },
192 { SHOW_EBCDIC, "EBCDIC" },
193 { SHOW_HEXDUMP, "HEX_DUMP" },
194 { SHOW_HTML, "HTML" },
195 { SHOW_IMAGE, "IMAGE" },
196 { SHOW_JSON, "JSON" },
197 { SHOW_RAW, "RAW" },
198 { SHOW_RUSTARRAY, "RUST_ARRAY" },
199 { SHOW_CODEC, "UTF-8" },
200 // Other codecs are generated at runtime
201 { SHOW_YAML, "YAML"},
202 { 0, NULL((void*)0) }
203};
204
205static const value_string follow_delta_values[] = {
206 { FOLLOW_DELTA_NONE, "NONE" },
207 { FOLLOW_DELTA_TURN, "TURN" },
208 { FOLLOW_DELTA_ALL, "ALL" },
209 { 0, NULL((void*)0) }
210};
211
212static const value_string show_bytes_decode_values[] = {
213 { DecodeAsNone, "NONE" },
214 { DecodeAsBASE64, "BASE64" },
215 { DecodeAsCompressed, "COMPRESSED" },
216 { DecodeAsHexDigits, "HEX_DIGITS" },
217 { DecodeAsPercentEncoding, "PERCENT_ENCODING" },
218 { DecodeAsQuotedPrintable, "QUOTED_PRINTABLE" },
219 { DecodeAsROT13, "ROT13"},
220 { 0, NULL((void*)0) }
221};
222
223static void
224free_col_width_data(void *data)
225{
226 col_width_data *cfmt = (col_width_data *)data;
227 g_free(cfmt);
228}
229
230void
231recent_free_column_width_info(recent_settings_t *rs)
232{
233 g_list_free_full(rs->col_width_list, free_col_width_data);
234 rs->col_width_list = NULL((void*)0);
235}
236
237/** Write the geometry values of a single window to the recent file.
238 *
239 * @param key unused
240 * @param value the geometry values
241 * @param rfh recent file handle (FILE)
242 */
243static void
244write_recent_geom(void *key _U___attribute__((unused)), void *value, void *rfh)
245{
246 window_geometry_t *geom = (window_geometry_t *)value;
247 FILE *rf = (FILE *)rfh;
248
249 fprintf(rf, "\n# Geometry and maximized state of %s window.\n", geom->key);
250 fprintf(rf, "# Decimal integers.\n");
251 fprintf(rf, RECENT_GUI_GEOMETRY"gui.geom." "%s.x: %d\n", geom->key, geom->x);
252 fprintf(rf, RECENT_GUI_GEOMETRY"gui.geom." "%s.y: %d\n", geom->key, geom->y);
253 fprintf(rf, RECENT_GUI_GEOMETRY"gui.geom." "%s.width: %d\n", geom->key,
254 geom->width);
255 fprintf(rf, RECENT_GUI_GEOMETRY"gui.geom." "%s.height: %d\n", geom->key,
256 geom->height);
257
258 fprintf(rf, "# true or false (case-insensitive).\n");
259 fprintf(rf, RECENT_GUI_GEOMETRY"gui.geom." "%s.maximized: %s\n", geom->key,
260 geom->maximized == true1 ? "true" : "false");
261
262 fprintf(rf, "# Qt Geometry State (hex byte string).\n");
263 fprintf(rf, RECENT_GUI_GEOMETRY"gui.geom." "%s.qt_geometry: %s\n", geom->key,
264 geom->qt_geom);
265}
266
267/* the geometry hashtable for all known window classes,
268 * the window name is the key, and the geometry struct is the value */
269static GHashTable *window_geom_hash;
270
271static GHashTable *window_splitter_hash;
272
273void
274window_geom_free(void *data)
275{
276 window_geometry_t *geom = (window_geometry_t*)data;
277 g_free(geom->key);
278 g_free(geom->qt_geom);
279 g_free(geom);
280}
281
282/* save the window and its current geometry into the geometry hashtable */
283void
284window_geom_save(const char *name, window_geometry_t *geom)
285{
286 char *key;
287 window_geometry_t *work;
288
289 /* init hashtable, if not already done */
290 if (!window_geom_hash) {
291 window_geom_hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL((void*)0), window_geom_free);
292 }
293
294 /* g_malloc and insert the new one */
295 work = g_new(window_geometry_t, 1)((window_geometry_t *) g_malloc_n ((1), sizeof (window_geometry_t
)))
;
296 *work = *geom;
297 key = g_strdup(name)g_strdup_inline (name);
298 work->key = key;
299 g_hash_table_replace(window_geom_hash, key, work);
300}
301
302/* load the desired geometry for this window from the geometry hashtable */
303bool_Bool
304window_geom_load(const char *name,
305 window_geometry_t *geom)
306{
307 window_geometry_t *p;
308
309 /* init hashtable, if not already done */
310 if (!window_geom_hash) {
311 window_geom_hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL((void*)0), window_geom_free);
312 }
313
314 p = (window_geometry_t *)g_hash_table_lookup(window_geom_hash, name);
315 if (p) {
316 *geom = *p;
317 return true1;
318 } else {
319 return false0;
320 }
321}
322
323/* save the window and its splitter state into the splitter hashtable */
324void
325window_splitter_save(const char *name, const char *splitter_state)
326{
327 /* init hashtable, if not already done */
328 if (!window_splitter_hash) {
329 window_splitter_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
330 }
331
332 g_hash_table_replace(window_splitter_hash, g_strdup(name)g_strdup_inline (name), g_strdup(splitter_state)g_strdup_inline (splitter_state));
333}
334
335/* save the window and its splitter state into the geometry hashtable */
336const char*
337window_splitter_load(const char *name)
338{
339 /* init hashtable, if not already done */
340 if (!window_splitter_hash) {
341 return NULL((void*)0);
342 }
343
344 return g_hash_table_lookup(window_splitter_hash, name);
345}
346
347
348/* parse values of particular types */
349static void
350parse_recent_boolean(const char *val_str, bool_Bool *valuep)
351{
352 if (g_ascii_strcasecmp(val_str, "true") == 0) {
353 *valuep = true1;
354 }
355 else {
356 *valuep = false0;
357 }
358}
359
360/** Read in a single geometry key value pair from the recent file.
361 *
362 * @param name the geom_name of the window
363 * @param key the subkey of this pair (e.g. "x")
364 * @param value the new value (e.g. "123")
365 */
366static void
367window_geom_recent_read_pair(const char *name,
368 const char *key,
369 const char *value)
370{
371 window_geometry_t geom;
372
373 if (strcmp(key, "splitter") == 0) {
374 window_splitter_save(name, value);
375 return;
376 }
377
378 /* find window geometry maybe already in hashtable */
379 if (!window_geom_load(name, &geom)) {
380 /* not in table, init geom with "basic" values */
381 geom.key = NULL((void*)0); /* Will be set in window_geom_save() */
382 geom.set_pos = false0;
383 geom.x = -1;
384 geom.y = -1;
385 geom.set_size = false0;
386 geom.width = -1;
387 geom.height = -1;
388 geom.qt_geom = NULL((void*)0);
389 }
390
391 if (strcmp(key, "x") == 0) {
392 geom.x = (int)strtol(value, NULL((void*)0), 10);
393 geom.set_pos = true1;
394 } else if (strcmp(key, "y") == 0) {
395 geom.y = (int)strtol(value, NULL((void*)0), 10);
396 geom.set_pos = true1;
397 } else if (strcmp(key, "width") == 0) {
398 geom.width = (int)strtol(value, NULL((void*)0), 10);
399 geom.set_size = true1;
400 } else if (strcmp(key, "height") == 0) {
401 geom.height = (int)strtol(value, NULL((void*)0), 10);
402 geom.set_size = true1;
403 } else if (strcmp(key, "maximized") == 0) {
404 parse_recent_boolean(value, &geom.maximized);
405 geom.set_maximized = true1;
406 } else if (strcmp(key, "qt_geometry") == 0) {
407 geom.qt_geom = g_strdup(value)g_strdup_inline (value);
408 } else {
409 /*
410 * Silently ignore the bogus key. We shouldn't abort here,
411 * as this could be due to a corrupt recent file.
412 *
413 * XXX - should we print a message about this?
414 */
415 return;
416 }
417
418 /* save / replace geometry in hashtable */
419 window_geom_save(name, &geom);
420}
421
422/** Write all geometry values of all windows to the recent file.
423 * Will call write_recent_geom() for every existing window type.
424 *
425 * @param rf recent file handle from caller
426 */
427static void
428window_geom_recent_write_all(FILE *rf)
429{
430 /* init hashtable, if not already done */
431 if (!window_geom_hash) {
432 window_geom_hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL((void*)0), window_geom_free);
433 }
434
435 g_hash_table_foreach(window_geom_hash, write_recent_geom, rf);
436}
437
438/** Write all known window splitter states to the recent file.
439 *
440 * @param rf recent file handle from caller
441 */
442static void
443window_splitter_recent_write_all(FILE *rf)
444{
445 /* init hashtable, if not already done */
446 if (!window_splitter_hash) {
447 return;
448 }
449
450 GHashTableIter iter;
451 void *key, *value;
452 g_hash_table_iter_init(&iter, window_splitter_hash);
453 while (g_hash_table_iter_next(&iter, &key, &value)) {
454 fprintf(rf, "\n# Splitter state of %s window.\n", (char*)key);
455 fprintf(rf, "# Qt Splitter state (hex byte string).\n");
456 fprintf(rf, RECENT_GUI_GEOMETRY"gui.geom." "%s.splitter: %s\n", (char*)key,
457 (char*)value);
458 }
459}
460
461/* Global list of recent capture filters. */
462static GList *recent_cfilter_list;
463
464/*
465 * Per-interface lists of recent capture filters; stored in a hash
466 * table indexed by interface name.
467 */
468static GHashTable *per_interface_cfilter_lists_hash;
469
470/* XXX: use a preference for this setting! */
471/* N.B.: If we use a pref, we will read the recent_common file
472 * before the pref, so don't truncate the list when reading
473 * (see the similar #16782 for the recent files.)
474 */
475static unsigned cfilter_combo_max_recent = 20;
476
477/**
478 * Returns a list of recent capture filters.
479 *
480 * @param ifname interface name; NULL refers to the global list.
481 */
482GList *
483recent_get_cfilter_list(const char *ifname)
484{
485 if (ifname == NULL((void*)0))
486 return recent_cfilter_list;
487 if (per_interface_cfilter_lists_hash == NULL((void*)0)) {
488 /* No such lists exist. */
489 return NULL((void*)0);
490 }
491 return (GList *)g_hash_table_lookup(per_interface_cfilter_lists_hash, ifname);
492}
493
494/**
495 * Add a capture filter to the global recent capture filter list or
496 * the recent capture filter list for an interface.
497 *
498 * @param ifname interface name; NULL refers to the global list.
499 * @param s text of capture filter
500 */
501void
502recent_add_cfilter(const char *ifname, const char *s)
503{
504 GList *cfilter_list;
505 GList *li;
506 char *li_filter, *newfilter = NULL((void*)0);
507
508 /* Don't add empty filters to the list. */
509 if (s[0] == '\0')
510 return;
511
512 if (ifname == NULL((void*)0))
513 cfilter_list = recent_cfilter_list;
514 else {
515 /* If we don't yet have a hash table for per-interface recent
516 capture filter lists, create one. Have it free the new key
517 if we're updating an entry rather than creating it below. */
518 if (per_interface_cfilter_lists_hash == NULL((void*)0))
519 per_interface_cfilter_lists_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL((void*)0));
520 cfilter_list = (GList *)g_hash_table_lookup(per_interface_cfilter_lists_hash, ifname);
521 }
522
523 li = g_list_first(cfilter_list);
524 while (li) {
525 /* If the filter is already in the list, remove the old one and
526 * append the new one at the latest position (at g_list_append() below) */
527 li_filter = (char *)li->data;
528 if (strcmp(s, li_filter) == 0) {
529 /* No need to copy the string, we're just moving it. */
530 newfilter = li_filter;
531 cfilter_list = g_list_remove(cfilter_list, li->data);
532 break;
533 }
534 li = li->next;
535 }
536 if (newfilter == NULL((void*)0)) {
537 /* The filter wasn't already in the list; make a copy to add. */
538 newfilter = g_strdup(s)g_strdup_inline (s);
539 }
540 cfilter_list = g_list_prepend(cfilter_list, newfilter);
541
542 if (ifname == NULL((void*)0))
543 recent_cfilter_list = cfilter_list;
544 else
545 g_hash_table_insert(per_interface_cfilter_lists_hash, g_strdup(ifname)g_strdup_inline (ifname), cfilter_list);
546}
547
548#ifdef HAVE_PCAP_REMOTE
549/* XXX: use a preference for this setting! */
550/* N.B.: If we use a pref, we will read the recent_common file
551 * before the pref, so don't truncate the list when reading
552 * (see the similar #16782 for the recent files.)
553 */
554static unsigned remote_host_max_recent = 20;
555static GList *remote_host_list;
556
557int recent_get_remote_host_list_size(void)
558{
559 if (remote_host_list == NULL((void*)0)) {
560 /* No entries exist. */
561 return 0;
562 }
563 return g_list_length(remote_host_list);
564}
565
566static void
567free_remote_host(void *value)
568{
569 struct remote_host* rh = (struct remote_host*)value;
570
571 g_free(rh->r_host);
572 g_free(rh->remote_port);
573 g_free(rh->auth_username);
574 g_free(rh->auth_password);
575
576}
577
578static int
579remote_host_compare(const void *a, const void *b)
580{
581 const struct remote_host* rh_a = (const struct remote_host*)a;
582 const struct remote_host* rh_b = (const struct remote_host*)b;
583
584 /* We assume only one entry per host (the GUI assumes that too.) */
585 return g_strcmp0(rh_a->r_host, rh_b->r_host);
586}
587
588static void
589remote_host_reverse(void)
590{
591 if (remote_host_list) {
592 remote_host_list = g_list_reverse(remote_host_list);
593 }
594}
595
596void recent_add_remote_host(char *host _U___attribute__((unused)), struct remote_host *rh)
597{
598 GList* li = NULL((void*)0);
599 if (remote_host_list) {
600 li = g_list_find_custom(remote_host_list, rh, remote_host_compare);
601 if (li != NULL((void*)0)) {
602 free_remote_host(li->data);
603 remote_host_list = g_list_delete_link(remote_host_list, li);
604 }
605 }
606 remote_host_list = g_list_prepend(remote_host_list, rh);
607}
608
609void
610recent_remote_host_list_foreach(GFunc func, void *user_data)
611{
612 if (remote_host_list != NULL((void*)0)) {
613 g_list_foreach(remote_host_list, func, user_data);
614 }
615}
616
617static void
618recent_print_remote_host(void *value, void *user)
619{
620 FILE *rf = (FILE *)user;
621 struct remote_host_info *ri = (struct remote_host_info *)value;
622
623 fprintf (rf, RECENT_KEY_REMOTE_HOST"recent.remote_host" ": %s,%s,%d\n", ri->remote_host, ri->remote_port, ri->auth_type);
624}
625
626/**
627 * Write the contents of the remote_host_list to the 'recent' file.
628 *
629 * @param rf File to write to.
630 */
631static void
632capture_remote_combo_recent_write_all(FILE *rf)
633{
634 unsigned max_count = 0;
635 GList *li = g_list_first(remote_host_list);
636
637 /* write all non empty remote capture hosts to the recent file (until max count) */
638 while (li && (max_count++ <= remote_host_max_recent)) {
639 recent_print_remote_host(li->data, rf);
640 li = li->next;
641 }
642}
643
644
645void recent_free_remote_host_list(void)
646{
647 g_list_free_full(remote_host_list, free_remote_host);
648 remote_host_list = NULL((void*)0);
649}
650
651struct remote_host *
652recent_get_remote_host(const char *host)
653{
654 if (host == NULL((void*)0))
655 return NULL((void*)0);
656 for (GList* li = g_list_first(remote_host_list); li != NULL((void*)0); li = li->next) {
657 struct remote_host *rh = (struct remote_host*)li->data;
658 if (g_strcmp0(host, rh->r_host) == 0) {
659 return rh;
660 }
661 }
662 return NULL((void*)0);
663}
664
665/**
666 * Fill the remote_host_list with the entries stored in the 'recent' file.
667 *
668 * @param s String to be filled from the 'recent' file.
669 * @return True, if the list was written successfully, False otherwise.
670 */
671static bool_Bool
672capture_remote_combo_add_recent(const char *s)
673{
674 GList *vals = prefs_get_string_list (s);
675 GList *valp = vals;
676 capture_auth auth_type;
677 char *p;
678 struct remote_host *rh;
679
680 if (valp == NULL((void*)0))
681 return false0;
682
683 /* First value is the host */
684 if (recent_get_remote_host(valp->data)) {
685 /* Don't add it, it's already in the list (shouldn't happen). */
686 return false0; // Should this be true or false?
687 }
688 rh = (struct remote_host *) g_malloc (sizeof (*rh));
689
690 /* First value is the host */
691 rh->r_host = (char *)g_strdup ((const char *)valp->data)g_strdup_inline ((const char *)valp->data);
692 if (strlen(rh->r_host) == 0) {
693 /* Empty remote host */
694 g_free(rh->r_host);
695 g_free(rh);
696 return false0;
697 }
698 rh->auth_type = CAPTURE_AUTH_NULL;
699 valp = valp->next;
700
701 if (valp) {
702 /* Found value 2, this is the port number */
703 if (!strcmp((const char*)valp->data, "0")) {
704 /* Port 0 isn't valid, so leave port blank */
705 rh->remote_port = (char *)g_strdup ("")g_strdup_inline ("");
706 } else {
707 rh->remote_port = (char *)g_strdup ((const char *)valp->data)g_strdup_inline ((const char *)valp->data);
708 }
709 valp = valp->next;
710 } else {
711 /* Did not find a port number */
712 rh->remote_port = g_strdup ("")g_strdup_inline ("");
713 }
714
715 if (valp) {
716 /* Found value 3, this is the authentication type */
717 auth_type = (capture_auth)strtol((const char *)valp->data, &p, 0);
718 if (p != valp->data && *p == '\0') {
719 rh->auth_type = auth_type;
720 }
721 }
722
723 /* Do not store username and password */
724 rh->auth_username = g_strdup ("")g_strdup_inline ("");
725 rh->auth_password = g_strdup ("")g_strdup_inline ("");
726
727 prefs_clear_string_list(vals);
728
729 remote_host_list = g_list_prepend(remote_host_list, rh);
730 return true1;
731}
732#endif
733
734static void
735cfilter_recent_write_all_list(FILE *rf, const char *ifname, GList *cfilter_list)
736{
737 unsigned max_count = 0;
738 GList *li;
739 char *sanitized;
740
741 /* write all non empty capture filter strings to the recent file (until max count) */
742 li = g_list_first(cfilter_list);
743 while (li && (max_count++ <= cfilter_combo_max_recent) ) {
744 if (li->data && strlen((const char *)li->data)) {
745 sanitized = prefs_sanitize_string((char *)li->data);
746 if (ifname == NULL((void*)0))
747 fprintf (rf, RECENT_KEY_CAPTURE_FILTER"recent.capture_filter" ": %s\n", sanitized);
748 else
749 fprintf (rf, RECENT_KEY_CAPTURE_FILTER"recent.capture_filter" ".%s: %s\n", ifname, sanitized);
750 g_free(sanitized);
751 }
752 li = li->next;
753 }
754}
755
756static void
757cfilter_recent_write_all_hash_callback(void *key, void *value, void *user_data)
758{
759 cfilter_recent_write_all_list((FILE *)user_data, (const char *)key, (GList *)value);
760}
761
762/** Write all capture filter values to the recent file.
763 *
764 * @param rf recent file handle from caller
765 */
766static void
767cfilter_recent_write_all(FILE *rf)
768{
769 /* Write out the global list. */
770 cfilter_recent_write_all_list(rf, NULL((void*)0), recent_cfilter_list);
771
772 /* Write out all the per-interface lists. */
773 if (per_interface_cfilter_lists_hash != NULL((void*)0)) {
774 g_hash_table_foreach(per_interface_cfilter_lists_hash, cfilter_recent_write_all_hash_callback, (void *)rf);
775 }
776}
777
778/** Reverse the order of all the capture filter lists after
779 * reading recent_common (we want the latest first).
780 * Note this is O(N), whereas appendng N items to a GList is O(N^2),
781 * since it doesn't have a pointer to the end like a GQueue.
782 */
783static void
784cfilter_recent_reverse_all(void)
785{
786 recent_cfilter_list = g_list_reverse(recent_cfilter_list);
787
788 /* Reverse all the per-interface lists. */
789 if (per_interface_cfilter_lists_hash != NULL((void*)0)) {
790 GHashTableIter iter;
791 void *key, *value;
792 g_hash_table_iter_init(&iter, per_interface_cfilter_lists_hash);
793 GList *li;
794 while (g_hash_table_iter_next(&iter, &key, &value)) {
795 li = (GList *)value;
796 li = g_list_reverse(li);
797 /* per_interface_cfilter_lists_hash was created without a
798 * value_destroy_func, so this is fine.
799 */
800 g_hash_table_iter_replace(&iter, li);
801 }
802 }
803}
804
805/* Write out recent settings of particular types. */
806static void
807write_recent_boolean(FILE *rf, const char *description, const char *name,
808 bool_Bool value)
809{
810 fprintf(rf, "\n# %s.\n", description);
811 fprintf(rf, "# true or false (case-insensitive).\n");
812 fprintf(rf, "%s: %s\n", name, value == true1 ? "true" : "false");
813}
814
815static void
816write_recent_double(FILE *rf, const char *description, const char *name,
817 double value)
818{
819 fprintf(rf, "\n# %s.\n", description);
820 char buf[G_ASCII_DTOSTR_BUF_SIZE(29 + 10)];
821 fprintf(rf, "%s: %s\n", name, g_ascii_dtostr(buf, sizeof(buf), value));
822}
823
824static void
825write_recent_enum(FILE *rf, const char *description, const char *name,
826 const value_string *values, unsigned value)
827{
828 const char *if_invalid = NULL((void*)0);
829 const value_string *valp;
830 const char *str_value;
831
832 fprintf(rf, "\n# %s.\n", description);
833 fprintf(rf, "# One of: ");
834 valp = values;
835 while (valp->strptr != NULL((void*)0)) {
836 if (if_invalid == NULL((void*)0))
837 if_invalid = valp->strptr;
838 fprintf(rf, "%s", valp->strptr);
839 valp++;
840 if (valp->strptr != NULL((void*)0))
841 fprintf(rf, ", ");
842 }
843 fprintf(rf, "\n");
844 str_value = try_val_to_str(value, values);
845 if (str_value != NULL((void*)0))
846 fprintf(rf, "%s: %s\n", name, str_value);
847 else
848 fprintf(rf, "%s: %s\n", name, if_invalid != NULL((void*)0) ? if_invalid : "Unknown");
849}
850
851/* Attempt to write out "recent common" to the user's recent_common file.
852 If we got an error report it with a dialog box and return false,
853 otherwise return true. */
854bool_Bool
855write_recent(void)
856{
857 char *pf_dir_path;
858 char *rf_path;
859 FILE *rf;
860 char *string_list;
861
862 /* To do:
863 * - Split output lines longer than MAX_VAL_LEN
864 * - Create a function for the preference directory check/creation
865 * so that duplication can be avoided with filter.c
866 */
867
868 /* Create the directory that holds personal configuration files, if
869 necessary. */
870 if (create_persconffile_dir(application_configuration_environment_prefix(), &pf_dir_path) == -1) {
871 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK0x01,
872 "Can't create directory\n\"%s\"\nfor recent file: %s.", pf_dir_path,
873 g_strerror(errno(*__errno_location ())));
874 g_free(pf_dir_path);
875 return false0;
876 }
877
878 rf_path = get_persconffile_path(RECENT_COMMON_FILE_NAME"recent_common", false0, application_configuration_environment_prefix());
879 if ((rf = ws_fopenfopen(rf_path, "w")) == NULL((void*)0)) {
880 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK0x01,
881 "Can't open recent file\n\"%s\": %s.", rf_path,
882 g_strerror(errno(*__errno_location ())));
883 g_free(rf_path);
884 return false0;
885 }
886 g_free(rf_path);
887
888 fprintf(rf, "# Common recent settings file for %s " VERSION"4.7.0" ".\n"
889 "#\n"
890 "# This file is regenerated each time %s is quit\n"
891 "# and when changing configuration profile.\n"
892 "# So be careful, if you want to make manual changes here.\n"
893 "\n"
894 "######## Recent capture files (latest last), cannot be altered through command line ########\n"
895 "\n",
896 application_flavor_name_proper(), application_flavor_name_proper());
897
898
899 menu_recent_file_write_all(rf);
900
901 fputs("\n"
902 "######## Recent capture filters (latest first), cannot be altered through command line ########\n"
903 "\n", rf);
904
905 cfilter_recent_write_all(rf);
906
907 fputs("\n"
908 "######## Recent display filters (latest last), cannot be altered through command line ########\n"
909 "\n", rf);
910
911 dfilter_recent_combo_write_all(rf);
912
913#ifdef HAVE_PCAP_REMOTE
914 fputs("\n"
915 "######## Recent remote hosts (latest first), cannot be altered through command line ########\n"
916 "\n", rf);
917
918 capture_remote_combo_recent_write_all(rf);
919#endif
920
921 fprintf(rf, "\n# Main window geometry.\n");
922 fprintf(rf, "# Decimal numbers.\n");
923 fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_X"gui.geometry_main_x" ": %d\n", recent.gui_geometry_main_x);
924 fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_Y"gui.geometry_main_y" ": %d\n", recent.gui_geometry_main_y);
925 fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_WIDTH"gui.geometry_main_width" ": %d\n",
926 recent.gui_geometry_main_width);
927 fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_HEIGHT"gui.geometry_main_height" ": %d\n",
928 recent.gui_geometry_main_height);
929
930 write_recent_boolean(rf, "Main window maximized",
931 RECENT_GUI_GEOMETRY_MAIN_MAXIMIZED"gui.geometry_main_maximized",
932 recent.gui_geometry_main_maximized);
933
934 if (recent.gui_geometry_main != NULL((void*)0)) {
935 fprintf(rf, "\n# Main window geometry state.\n");
936 fprintf(rf, "# Hex byte string.\n");
937 fprintf(rf, RECENT_GUI_GEOMETRY_MAIN"gui.geometry_main" ": %s\n",
938 recent.gui_geometry_main);
939 }
940
941 write_recent_boolean(rf, "Leftalign Action Buttons",
942 RECENT_GUI_GEOMETRY_LEFTALIGN_ACTIONS"gui.geometry_leftalign_actions",
943 recent.gui_geometry_leftalign_actions);
944
945 fprintf(rf, "\n# Last used Configuration Profile.\n");
946 fprintf(rf, RECENT_LAST_USED_PROFILE"gui.last_used_profile" ": %s\n", get_profile_name());
947
948 fprintf(rf, "\n# Number of packets or events to check for automatic profile switching.\n");
949 fprintf(rf, "# Decimal number. Zero disables switching.\n");
950 const char * def_prefix = recent.gui_profile_switch_check_count == 1000 ? "#" : "";
951 fprintf(rf, "%s" RECENT_PROFILE_SWITCH_CHECK_COUNT"gui.profile_switch_check_count" ": %d\n", def_prefix,
952 recent.gui_profile_switch_check_count);
953
954 write_recent_boolean(rf, "Warn if running with elevated permissions (e.g. as root)",
955 RECENT_KEY_PRIVS_WARN_IF_ELEVATED"privs.warn_if_elevated",
956 recent.privs_warn_if_elevated);
957
958 write_recent_boolean(rf, "Warn if Wireshark is unable to capture",
959 RECENT_KEY_SYS_WARN_IF_NO_CAPTURE"sys.warn_if_no_capture",
960 recent.sys_warn_if_no_capture);
961
962 write_recent_enum(rf, "Find packet search in", RECENT_GUI_SEARCH_IN"gui.search_in", search_in_values,
963 recent.gui_search_in);
964 write_recent_enum(rf, "Find packet character set", RECENT_GUI_SEARCH_CHAR_SET"gui.search_char_set", search_char_set_values,
965 recent.gui_search_char_set);
966 write_recent_boolean(rf, "Find packet case sensitive search",
967 RECENT_GUI_SEARCH_CASE_SENSITIVE"gui.search_case_sensitive",
968 recent.gui_search_case_sensitive);
969 write_recent_boolean(rf, "Find packet search reverse direction",
970 RECENT_GUI_SEARCH_REVERSE_DIR"gui.search_reverse_dir",
971 recent.gui_search_reverse_dir);
972 write_recent_boolean(rf, "Find packet search multiple occurrences",
973 RECENT_GUI_SEARCH_MULTIPLE_OCCURS"gui.search_multiple_occurs",
974 recent.gui_search_multiple_occurs);
975 write_recent_enum(rf, "Find packet search type", RECENT_GUI_SEARCH_TYPE"gui.search_type", search_type_values,
976 recent.gui_search_type);
977
978 window_geom_recent_write_all(rf);
979
980 fprintf(rf, "\n# Custom colors.\n");
981 fprintf(rf, "# List of custom colors selected in Qt color picker.\n");
982 string_list = join_string_list(recent.custom_colors);
983 fprintf(rf, RECENT_GUI_CUSTOM_COLORS"gui.custom_colors" ": %s\n", string_list);
984 g_free(string_list);
985
986 fclose(rf);
987
988 /* XXX - catch I/O errors (e.g. "ran out of disk space") and return
989 an error indication, or maybe write to a new recent file and
990 rename that file on top of the old one only if there are not I/O
991 errors. */
992 return true1;
993}
994
995
996/* Attempt to Write out profile "recent" to the user's profile recent file.
997 If we got an error report it with a dialog box and return false,
998 otherwise return true. */
999bool_Bool
1000write_profile_recent(void)
1001{
1002 char *pf_dir_path;
1003 char *rf_path;
1004 char *string_list;
1005 FILE *rf;
1006
1007 /* To do:
1008 * - Split output lines longer than MAX_VAL_LEN
1009 * - Create a function for the preference directory check/creation
1010 * so that duplication can be avoided with filter.c
1011 */
1012
1013 /* Create the directory that holds personal configuration files, if
1014 necessary. */
1015 if (create_persconffile_dir(application_configuration_environment_prefix(), &pf_dir_path) == -1) {
1016 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK0x01,
1017 "Can't create directory\n\"%s\"\nfor recent file: %s.", pf_dir_path,
1018 g_strerror(errno(*__errno_location ())));
1019 g_free(pf_dir_path);
1020 return false0;
1021 }
1022
1023 rf_path = get_persconffile_path(RECENT_FILE_NAME"recent", true1, application_configuration_environment_prefix());
1024 if ((rf = ws_fopenfopen(rf_path, "w")) == NULL((void*)0)) {
1025 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK0x01,
1026 "Can't open recent file\n\"%s\": %s.", rf_path,
1027 g_strerror(errno(*__errno_location ())));
1028 g_free(rf_path);
1029 return false0;
1030 }
1031 g_free(rf_path);
1032
1033 fprintf(rf, "# Recent settings file for %s " VERSION"4.7.0" ".\n"
1034 "#\n"
1035 "# This file is regenerated each time %s is quit\n"
1036 "# and when changing configuration profile.\n"
1037 "# So be careful, if you want to make manual changes here.\n"
1038 "\n",
1039 application_flavor_name_proper(), application_flavor_name_proper());
1040
1041 write_recent_boolean(rf, "Main Toolbar show (hide)",
1042 RECENT_KEY_MAIN_TOOLBAR_SHOW"gui.toolbar_main_show",
1043 recent.main_toolbar_show);
1044
1045 write_recent_boolean(rf, "Filter Toolbar show (hide)",
1046 RECENT_KEY_FILTER_TOOLBAR_SHOW"gui.filter_toolbar_show",
1047 recent.filter_toolbar_show);
1048
1049 write_recent_boolean(rf, "Wireless Settings Toolbar show (hide)",
1050 RECENT_KEY_WIRELESS_TOOLBAR_SHOW"gui.wireless_toolbar_show",
1051 recent.wireless_toolbar_show);
1052
1053 write_recent_boolean(rf, "Packet list show (hide)",
1054 RECENT_KEY_PACKET_LIST_SHOW"gui.packet_list_show",
1055 recent.packet_list_show);
1056
1057 write_recent_boolean(rf, "Tree view show (hide)",
1058 RECENT_KEY_TREE_VIEW_SHOW"gui.tree_view_show",
1059 recent.tree_view_show);
1060
1061 write_recent_boolean(rf, "Byte view show (hide)",
1062 RECENT_KEY_BYTE_VIEW_SHOW"gui.byte_view_show",
1063 recent.byte_view_show);
1064
1065 write_recent_boolean(rf, "Packet diagram show (hide)",
1066 RECENT_KEY_PACKET_DIAGRAM_SHOW"gui.packet_diagram_show",
1067 recent.packet_diagram_show);
1068
1069 write_recent_boolean(rf, "Statusbar show (hide)",
1070 RECENT_KEY_STATUSBAR_SHOW"gui.statusbar_show",
1071 recent.statusbar_show);
1072
1073 write_recent_boolean(rf, "Packet list colorize (hide)",
1074 RECENT_KEY_PACKET_LIST_COLORIZE"gui.packet_list_colorize",
1075 recent.packet_list_colorize);
1076
1077 write_recent_boolean(rf, "Auto scroll packet list when capturing",
1078 RECENT_KEY_CAPTURE_AUTO_SCROLL"capture.auto_scroll",
1079 recent.capture_auto_scroll);
1080
1081 write_recent_boolean(rf, "use as aggragation view",
1082 RECENT_KEY_AGGREGATION_VIEW"capture.aggregation_view",
1083 recent.aggregation_view);
1084
1085 write_recent_enum(rf, "Timestamp display format",
1086 RECENT_GUI_TIME_FORMAT"gui.time_format", ts_type_values,
1087 recent.gui_time_format);
1088
1089 /*
1090 * The value of this item is either TS_PREC_AUTO, which is a
1091 * negative number meaning "pick the display precision based
1092 * on the time stamp precision of the packet", or is a numerical
1093 * value giving the number of decimal places to display, from 0
1094 * to WS_TSPREC_MAX.
1095 *
1096 * It used to be that not all values between 0 and 9 (the maximum
1097 * precision back then) were supported, and that names were
1098 * written out to the recent file.
1099 *
1100 * For backwards compatibility with those older versions of
1101 * Wireshark, write out the names for those values, and the
1102 * raw number for other values.
1103 */
1104 {
1105 const char *if_invalid = NULL((void*)0);
1106 const value_string *valp;
1107 const char *str_value;
1108
1109 fprintf(rf, "\n# %s.\n", "Timestamp display precision");
1110 fprintf(rf, "# One of: ");
1111 valp = ts_precision_values;
1112 while (valp->strptr != NULL((void*)0)) {
1113 if (if_invalid == NULL((void*)0))
1114 if_invalid = valp->strptr;
1115 fprintf(rf, "%s", valp->strptr);
1116 valp++;
1117 if (valp->strptr != NULL((void*)0))
1118 fprintf(rf, ", ");
1119 }
1120 fprintf(rf, ", or a number between 0 and %d\n", WS_TSPREC_MAX9);
1121
1122 str_value = try_val_to_str(recent.gui_time_precision, ts_precision_values);
1123 if (str_value != NULL((void*)0))
1124 fprintf(rf, "%s: %s\n", RECENT_GUI_TIME_PRECISION"gui.time_precision", str_value);
1125 else {
1126 if (recent.gui_time_precision >= 0 && recent.gui_time_precision < WS_TSPREC_MAX9)
1127 fprintf(rf, "%s: %d\n", RECENT_GUI_TIME_PRECISION"gui.time_precision", recent.gui_time_precision);
1128 else
1129 fprintf(rf, "%s: %s\n", RECENT_GUI_TIME_PRECISION"gui.time_precision", if_invalid != NULL((void*)0) ? if_invalid : "Unknown");
1130 }
1131 }
1132
1133 write_recent_enum(rf, "Seconds display format",
1134 RECENT_GUI_SECONDS_FORMAT"gui.seconds_format", ts_seconds_values,
1135 recent.gui_seconds_format);
1136
1137 fprintf(rf, "\n# Zoom level.\n");
1138 fprintf(rf, "# A decimal number.\n");
1139 fprintf(rf, RECENT_GUI_ZOOM_LEVEL"gui.zoom_level" ": %d\n",
1140 recent.gui_zoom_level);
1141
1142 write_recent_enum(rf, "Bytes view display type",
1143 RECENT_GUI_BYTES_VIEW"gui.bytes_view", bytes_view_type_values,
1144 recent.gui_bytes_view);
1145
1146 write_recent_enum(rf, "Bytes view text encoding",
1147 RECENT_GUI_BYTES_ENCODING"gui.bytes_encoding", bytes_encoding_type_values,
1148 recent.gui_bytes_encoding);
1149
1150 write_recent_boolean(rf, "Packet diagram field values show (hide)",
1151 RECENT_GUI_PACKET_DIAGRAM_FIELD_VALUES"gui.packet_diagram_field_values",
1152 recent.gui_packet_diagram_field_values);
1153
1154 write_recent_boolean(rf, "Allow hover selection in byte view",
1155 RECENT_GUI_ALLOW_HOVER_SELECTION"gui.allow_hover_selection",
1156 recent.gui_allow_hover_selection);
1157
1158 write_recent_enum(rf, "Follow stream show as",
1159 RECENT_GUI_FOLLOW_SHOW"gui.follow_show", bytes_show_values,
1160 recent.gui_follow_show);
1161
1162 write_recent_enum(rf, "Follow stream delta times",
1163 RECENT_GUI_FOLLOW_DELTA"gui.follow_delta", follow_delta_values,
1164 recent.gui_follow_delta);
1165
1166 write_recent_enum(rf, "Show packet bytes decode as",
1167 RECENT_GUI_SHOW_BYTES_DECODE"gui.show_bytes_decode", show_bytes_decode_values,
1168 recent.gui_show_bytes_decode);
1169
1170 write_recent_enum(rf, "Show packet bytes show as",
1171 RECENT_GUI_SHOW_BYTES_SHOW"gui.show_bytes_show", bytes_show_values,
1172 recent.gui_show_bytes_show);
1173
1174 fprintf(rf, "\n# Main window upper (or leftmost) pane size.\n");
1175 fprintf(rf, "# Decimal number.\n");
1176 if (recent.gui_geometry_main_upper_pane != 0) {
1177 fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_UPPER_PANE"gui.geometry_main_upper_pane" ": %d\n",
1178 recent.gui_geometry_main_upper_pane);
1179 }
1180 fprintf(rf, "\n# Main window middle pane size.\n");
1181 fprintf(rf, "# Decimal number.\n");
1182 if (recent.gui_geometry_main_lower_pane != 0) {
1183 fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_LOWER_PANE"gui.geometry_main_lower_pane" ": %d\n",
1184 recent.gui_geometry_main_lower_pane);
1185 }
1186
1187 if (recent.gui_geometry_main_master_split != NULL((void*)0)) {
1188 fprintf(rf, "\n# Main window master splitter state.\n");
1189 fprintf(rf, "# Hex byte string.\n");
1190 fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_MASTER_SPLIT"gui.geometry_main_master_split" ": %s\n",
1191 recent.gui_geometry_main_master_split);
1192 }
1193
1194 if (recent.gui_geometry_main_extra_split != NULL((void*)0)) {
1195 fprintf(rf, "\n# Main window extra splitter state.\n");
1196 fprintf(rf, "# Hex byte string.\n");
1197 fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_EXTRA_SPLIT"gui.geometry_main_extra_split" ": %s\n",
1198 recent.gui_geometry_main_extra_split);
1199 }
1200
1201 window_splitter_recent_write_all(rf);
1202
1203 fprintf(rf, "\n# Packet list column pixel widths.\n");
1204 fprintf(rf, "# Each pair of strings consists of a column format and its pixel width.\n");
1205 packet_list_recent_write_all(rf);
1206
1207 fprintf(rf, "\n# Open conversation dialog tabs.\n");
1208 fprintf(rf, "# List of conversation names, e.g. \"TCP\", \"IPv6\".\n");
1209 string_list = join_string_list(recent.conversation_tabs);
1210 fprintf(rf, RECENT_GUI_CONVERSATION_TABS"gui.conversation_tabs" ": %s\n", string_list);
1211 g_free(string_list);
1212
1213 fprintf(rf, "\n# Conversation dialog tabs columns.\n");
1214 fprintf(rf, "# List of conversation columns numbers.\n");
1215 string_list = join_string_list(recent.conversation_tabs_columns);
1216 fprintf(rf, RECENT_GUI_CONVERSATION_TABS_COLUMNS"gui.conversation_tabs_columns" ": %s\n", string_list);
1217 g_free(string_list);
1218
1219 fprintf(rf, "\n# Open endpoint dialog tabs.\n");
1220 fprintf(rf, "# List of endpoint names, e.g. \"TCP\", \"IPv6\".\n");
1221 string_list = join_string_list(recent.endpoint_tabs);
1222 fprintf(rf, RECENT_GUI_ENDPOINT_TABS"gui.endpoint_tabs" ": %s\n", string_list);
1223 g_free(string_list);
1224
1225 fprintf(rf, "\n# Endpoint dialog tabs columns.\n");
1226 fprintf(rf, "# List of endpoint columns numbers.\n");
1227 string_list = join_string_list(recent.endpoint_tabs_columns);
1228 fprintf(rf, RECENT_GUI_ENDPOINT_TABS_COLUMNS"gui.endpoint_tabs_columns" ": %s\n", string_list);
1229 g_free(string_list);
1230
1231 write_recent_boolean(rf, "For RLC stats, whether to use RLC PDUs found inside MAC frames",
1232 RECENT_GUI_RLC_PDUS_FROM_MAC_FRAMES"gui.rlc_pdus_from_mac_frames",
1233 recent.gui_rlc_use_pdus_from_mac);
1234
1235 if (get_last_open_dir() != NULL((void*)0)) {
1236 fprintf(rf, "\n# Last directory navigated to in File Open dialog.\n");
1237 fprintf(rf, RECENT_GUI_FILEOPEN_REMEMBERED_DIR"gui.fileopen_remembered_dir" ": %s\n", get_last_open_dir());
1238 }
1239
1240 fprintf(rf, "\n# Additional Toolbars shown\n");
1241 fprintf(rf, "# List of additional toolbars to show.\n");
1242 string_list = join_string_list(recent.gui_additional_toolbars);
1243 fprintf(rf, RECENT_GUI_TOOLBAR_SHOW"gui.additional_toolbar_show" ": %s\n", string_list);
1244 g_free(string_list);
1245
1246 fprintf(rf, "\n# Interface Toolbars show.\n");
1247 fprintf(rf, "# List of interface toolbars to show.\n");
1248 string_list = join_string_list(recent.interface_toolbars);
1249 fprintf(rf, RECENT_GUI_INTERFACE_TOOLBAR_SHOW"gui.interface_toolbar_show" ": %s\n", string_list);
1250 g_free(string_list);
1251
1252 write_recent_double(rf, "TCP Stream Graphs Moving Average Window Size",
1253 RECENT_GUI_TSD_MA_WINDOW_SIZE"gui.tsd_ma_window_size",
1254 recent.gui_tsgd_ma_window_size);
1255 write_recent_boolean(rf, "TCP Stream Graphs Dialog Throughput show (hide)",
1256 RECENT_GUI_TSD_THROUGHPUT_SHOW"gui.tsd_throughput_show",
1257 recent.gui_tsgd_throughput_show);
1258 write_recent_boolean(rf, "TCP Stream Graphs Dialog Goodput show (hide)",
1259 RECENT_GUI_TSD_GOODPUT_SHOW"gui.tsd_goodput_show",
1260 recent.gui_tsgd_goodput_show);
1261
1262 write_recent_boolean(rf, "Welcome page sidebar Learn section visible",
1263 RECENT_KEY_SIDEBAR_LEARN_VISIBLE"gui.welcome_page.sidebar.learn_visible",
1264 recent.gui_welcome_page_sidebar_learn_visible);
1265
1266 write_recent_boolean(rf, "Welcome page sidebar Tips section visible",
1267 RECENT_KEY_SIDEBAR_TIPS_VISIBLE"gui.welcome_page.sidebar.tips_visible",
1268 recent.gui_welcome_page_sidebar_tips_visible);
1269
1270 write_recent_boolean(rf, "Welcome page sidebar Tips event slides",
1271 RECENT_KEY_SIDEBAR_TIPS_EVENTS"gui.welcome_page.sidebar.tips_events",
1272 recent.gui_welcome_page_sidebar_tips_events);
1273
1274 write_recent_boolean(rf, "Welcome page sidebar Tips sponsorship slides",
1275 RECENT_KEY_SIDEBAR_TIPS_SPONSORSHIP"gui.welcome_page.sidebar.tips_sponsorship",
1276 recent.gui_welcome_page_sidebar_tips_sponsorship);
1277
1278 write_recent_boolean(rf, "Welcome page sidebar Tips tip-of-the-day slides",
1279 RECENT_KEY_SIDEBAR_TIPS_TIPS"gui.welcome_page.sidebar.tips_tips",
1280 recent.gui_welcome_page_sidebar_tips_tips);
1281
1282 fprintf(rf, "\n# Welcome page sidebar Tips slide auto-advance interval in seconds.\n");
1283 fprintf(rf, RECENT_KEY_SIDEBAR_TIPS_INTERVAL"gui.welcome_page.sidebar.tips_interval" ": %u\n",
1284 recent.gui_welcome_page_sidebar_tips_interval);
1285
1286 fclose(rf);
1287
1288 /* XXX - catch I/O errors (e.g. "ran out of disk space") and return
1289 an error indication, or maybe write to a new recent file and
1290 rename that file on top of the old one only if there are not I/O
1291 errors. */
1292 return true1;
1293}
1294
1295/* set one user's recent common file key/value pair */
1296static prefs_set_pref_e
1297read_set_recent_common_pair_static(char *key, const char *value,
1298 void *private_data _U___attribute__((unused)),
1299 bool_Bool return_range_errors _U___attribute__((unused)))
1300{
1301 long num;
1302 char *p;
1303
1304 if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_MAXIMIZED"gui.geometry_main_maximized") == 0) {
1305 parse_recent_boolean(value, &recent.gui_geometry_main_maximized);
1306 } else if (strcmp(key, RECENT_GUI_GEOMETRY_LEFTALIGN_ACTIONS"gui.geometry_leftalign_actions") == 0) {
1307 parse_recent_boolean(value, &recent.gui_geometry_leftalign_actions);
1308 } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_X"gui.geometry_main_x") == 0) {
1309 num = strtol(value, &p, 0);
1310 if (p == value || *p != '\0')
1311 return PREFS_SET_SYNTAX_ERR; /* number was bad */
1312 recent.gui_geometry_main_x = (int)num;
1313 } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_Y"gui.geometry_main_y") == 0) {
1314 num = strtol(value, &p, 0);
1315 if (p == value || *p != '\0')
1316 return PREFS_SET_SYNTAX_ERR; /* number was bad */
1317 recent.gui_geometry_main_y = (int)num;
1318 } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_WIDTH"gui.geometry_main_width") == 0) {
1319 num = strtol(value, &p, 0);
1320 if (p == value || *p != '\0')
1321 return PREFS_SET_SYNTAX_ERR; /* number was bad */
1322 if (num <= 0)
1323 return PREFS_SET_SYNTAX_ERR; /* number must be positive */
1324 recent.gui_geometry_main_width = (int)num;
1325 } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_HEIGHT"gui.geometry_main_height") == 0) {
1326 num = strtol(value, &p, 0);
1327 if (p == value || *p != '\0')
1328 return PREFS_SET_SYNTAX_ERR; /* number was bad */
1329 if (num <= 0)
1330 return PREFS_SET_SYNTAX_ERR; /* number must be positive */
1331 recent.gui_geometry_main_height = (int)num;
1332 } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN"gui.geometry_main") == 0) {
1333 g_free(recent.gui_geometry_main);
1334 recent.gui_geometry_main = g_strdup(value)g_strdup_inline (value);
1335 } else if (strcmp(key, RECENT_LAST_USED_PROFILE"gui.last_used_profile") == 0) {
1336 if ((strcmp(value, DEFAULT_PROFILE"Default") != 0) && profile_exists(application_configuration_environment_prefix(), value, false0)) {
1337 set_profile_name (value);
1338 }
1339 } else if (strcmp(key, RECENT_PROFILE_SWITCH_CHECK_COUNT"gui.profile_switch_check_count") == 0) {
1340 num = strtol(value, &p, 0);
1341 if (p == value || *p != '\0')
1342 return PREFS_SET_SYNTAX_ERR; /* number was bad */
1343 if (num <= 0)
1344 return PREFS_SET_SYNTAX_ERR; /* number must be positive */
1345 recent.gui_profile_switch_check_count = (int)num;
1346 } else if (strncmp(key, RECENT_GUI_GEOMETRY"gui.geom.", sizeof(RECENT_GUI_GEOMETRY"gui.geom.")-1) == 0) {
1347 /* now have something like "gui.geom.main.x", split it into win and sub_key */
1348 char *win = &key[sizeof(RECENT_GUI_GEOMETRY"gui.geom.")-1];
1349 char *sub_key = strchr(win, '.');
1350 if (sub_key) {
1351 *sub_key = '\0';
1352 sub_key++;
1353 window_geom_recent_read_pair(win, sub_key, value);
1354 }
1355 } else if (strcmp(key, RECENT_KEY_PRIVS_WARN_IF_ELEVATED"privs.warn_if_elevated") == 0) {
1356 parse_recent_boolean(value, &recent.privs_warn_if_elevated);
1357 } else if (strcmp(key, RECENT_KEY_SYS_WARN_IF_NO_CAPTURE"sys.warn_if_no_capture") == 0) {
1358 parse_recent_boolean(value, &recent.sys_warn_if_no_capture);
1359 } else if (strcmp(key, RECENT_GUI_SEARCH_IN"gui.search_in") == 0) {
1360 recent.gui_search_in = (search_in_type)str_to_val(value, search_in_values, SEARCH_IN_PACKET_LIST);
1361 } else if (strcmp(key, RECENT_GUI_SEARCH_CHAR_SET"gui.search_char_set") == 0) {
1362 recent.gui_search_char_set = (search_char_set_type)str_to_val(value, search_char_set_values, SEARCH_CHAR_SET_NARROW_AND_WIDE);
1363 } else if (strcmp(key, RECENT_GUI_SEARCH_CASE_SENSITIVE"gui.search_case_sensitive") == 0) {
1364 parse_recent_boolean(value, &recent.gui_search_case_sensitive);
1365 } else if (strcmp(key, RECENT_GUI_SEARCH_REVERSE_DIR"gui.search_reverse_dir") == 0) {
1366 parse_recent_boolean(value, &recent.gui_search_reverse_dir);
1367 } else if (strcmp(key, RECENT_GUI_SEARCH_MULTIPLE_OCCURS"gui.search_multiple_occurs") == 0) {
1368 parse_recent_boolean(value, &recent.gui_search_multiple_occurs);
1369 } else if (strcmp(key, RECENT_GUI_SEARCH_TYPE"gui.search_type") == 0) {
1370 recent.gui_search_type = (search_type_type)str_to_val(value, search_type_values, SEARCH_TYPE_DISPLAY_FILTER);
1371 } else if (strcmp(key, RECENT_GUI_CUSTOM_COLORS"gui.custom_colors") == 0) {
1372 recent.custom_colors = prefs_get_string_list(value);
1373 }
1374
1375 return PREFS_SET_OK;
1376}
1377
1378/* set one user's recent file key/value pair */
1379static prefs_set_pref_e
1380read_set_recent_pair_static(char *key, const char *value,
1381 void *private_data _U___attribute__((unused)),
1382 bool_Bool return_range_errors _U___attribute__((unused)))
1383{
1384 long num;
1385 int32_t num_int32;
1386 double val_as_dbl;
1387 char *p;
1388 GList *col_l, *col_l_elt;
1389 col_width_data *cfmt;
1390
1391 if (strcmp(key, RECENT_KEY_MAIN_TOOLBAR_SHOW"gui.toolbar_main_show") == 0) {
1392 parse_recent_boolean(value, &recent.main_toolbar_show);
1393 } else if (strcmp(key, RECENT_KEY_FILTER_TOOLBAR_SHOW"gui.filter_toolbar_show") == 0) {
1394 parse_recent_boolean(value, &recent.filter_toolbar_show);
1395 /* check both the old and the new keyword */
1396 } else if (strcmp(key, RECENT_KEY_WIRELESS_TOOLBAR_SHOW"gui.wireless_toolbar_show") == 0 || (strcmp(key, "gui.airpcap_toolbar_show") == 0)) {
1397 parse_recent_boolean(value, &recent.wireless_toolbar_show);
1398 } else if (strcmp(key, RECENT_KEY_PACKET_LIST_SHOW"gui.packet_list_show") == 0) {
1399 parse_recent_boolean(value, &recent.packet_list_show);
1400 } else if (strcmp(key, RECENT_KEY_TREE_VIEW_SHOW"gui.tree_view_show") == 0) {
1401 parse_recent_boolean(value, &recent.tree_view_show);
1402 } else if (strcmp(key, RECENT_KEY_BYTE_VIEW_SHOW"gui.byte_view_show") == 0) {
1403 parse_recent_boolean(value, &recent.byte_view_show);
1404 } else if (strcmp(key, RECENT_KEY_PACKET_DIAGRAM_SHOW"gui.packet_diagram_show") == 0) {
1405 parse_recent_boolean(value, &recent.packet_diagram_show);
1406 } else if (strcmp(key, RECENT_KEY_STATUSBAR_SHOW"gui.statusbar_show") == 0) {
1407 parse_recent_boolean(value, &recent.statusbar_show);
1408 } else if (strcmp(key, RECENT_KEY_PACKET_LIST_COLORIZE"gui.packet_list_colorize") == 0) {
1409 parse_recent_boolean(value, &recent.packet_list_colorize);
1410 } else if (strcmp(key, RECENT_KEY_CAPTURE_AUTO_SCROLL"capture.auto_scroll") == 0) {
1411 parse_recent_boolean(value, &recent.capture_auto_scroll);
1412 } else if (strcmp(key, RECENT_KEY_AGGREGATION_VIEW"capture.aggregation_view") == 0) {
1413 parse_recent_boolean(value, &recent.aggregation_view);
1414 } else if (strcmp(key, RECENT_GUI_TIME_FORMAT"gui.time_format") == 0) {
1415 recent.gui_time_format = (ts_type)str_to_val(value, ts_type_values,
1416 application_flavor_is_wireshark() ? TS_RELATIVE : TS_ABSOLUTE);
1417 } else if (strcmp(key, RECENT_GUI_TIME_PRECISION"gui.time_precision") == 0) {
1418 /*
1419 * The value of this item is either TS_PREC_AUTO, which is a
1420 * negative number meaning "pick the display precision based
1421 * on the time stamp precision of the packet", or is a numerical
1422 * value giving the number of decimal places to display, from 0
1423 * to WS_TSPREC_MAX.
1424 *
1425 * It used to be that not all values between 0 and 9 (the maximum
1426 * precision back then) were supported, and that names were
1427 * written out to the recent file.
1428 *
1429 * If the string value is a valid number in that range, use
1430 * that number, otherwise look it up in the table of names,
1431 * and, if that fails, set it to TS_PREC_AUTO.
1432 */
1433 if (ws_strtoi32(value, NULL((void*)0), &num_int32) && num_int32 >= 0 &&
1434 num_int32 <= WS_TSPREC_MAX9) {
1435 recent.gui_time_precision = num_int32;
1436 } else {
1437 recent.gui_time_precision =
1438 (ts_precision)str_to_val(value, ts_precision_values, TS_PREC_AUTO);
1439 }
1440 } else if (strcmp(key, RECENT_GUI_SECONDS_FORMAT"gui.seconds_format") == 0) {
1441 recent.gui_seconds_format =
1442 (ts_seconds_type)str_to_val(value, ts_seconds_values, TS_SECONDS_DEFAULT);
1443 } else if (strcmp(key, RECENT_GUI_ZOOM_LEVEL"gui.zoom_level") == 0) {
1444 num = strtol(value, &p, 0);
1445 if (p == value || *p != '\0')
1446 return PREFS_SET_SYNTAX_ERR; /* number was bad */
1447 recent.gui_zoom_level = (int)num;
1448 } else if (strcmp(key, RECENT_GUI_BYTES_VIEW"gui.bytes_view") == 0) {
1449 recent.gui_bytes_view =
1450 (bytes_view_type)str_to_val(value, bytes_view_type_values, BYTES_HEX);
1451 } else if (strcmp(key, RECENT_GUI_BYTES_ENCODING"gui.bytes_encoding") == 0) {
1452 recent.gui_bytes_encoding =
1453 (bytes_encoding_type)str_to_val(value, bytes_encoding_type_values, BYTES_ENC_FROM_PACKET);
1454 } else if (strcmp(key, RECENT_GUI_PACKET_DIAGRAM_FIELD_VALUES"gui.packet_diagram_field_values") == 0) {
1455 parse_recent_boolean(value, &recent.gui_packet_diagram_field_values);
1456 } else if (strcmp(key, RECENT_GUI_ALLOW_HOVER_SELECTION"gui.allow_hover_selection") == 0) {
1457 parse_recent_boolean(value, &recent.gui_allow_hover_selection);
1458 } else if (strcmp(key, RECENT_GUI_FOLLOW_SHOW"gui.follow_show") == 0) {
1459 recent.gui_follow_show = (bytes_show_type)str_to_val(value, bytes_show_values, SHOW_ASCII);
1460 } else if (strcmp(key, RECENT_GUI_FOLLOW_DELTA"gui.follow_delta") == 0) {
1461 recent.gui_follow_delta = (follow_delta_type)str_to_val(value, follow_delta_values, FOLLOW_DELTA_NONE);
1462 } else if (strcmp(key, RECENT_GUI_SHOW_BYTES_DECODE"gui.show_bytes_decode") == 0) {
1463 recent.gui_show_bytes_decode = (bytes_decode_type)str_to_val(value, show_bytes_decode_values, DecodeAsNone);
1464 } else if (strcmp(key, RECENT_GUI_SHOW_BYTES_SHOW"gui.show_bytes_show") == 0) {
1465 recent.gui_show_bytes_show = (bytes_show_type)str_to_val(value, bytes_show_values, SHOW_ASCII);
1466 } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_UPPER_PANE"gui.geometry_main_upper_pane") == 0) {
1467 num = strtol(value, &p, 0);
1468 if (p == value || *p != '\0')
1469 return PREFS_SET_SYNTAX_ERR; /* number was bad */
1470 if (num <= 0)
1471 return PREFS_SET_SYNTAX_ERR; /* number must be positive */
1472 recent.gui_geometry_main_upper_pane = (int)num;
1473 } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_LOWER_PANE"gui.geometry_main_lower_pane") == 0) {
1474 num = strtol(value, &p, 0);
1475 if (p == value || *p != '\0')
1476 return PREFS_SET_SYNTAX_ERR; /* number was bad */
1477 if (num <= 0)
1478 return PREFS_SET_SYNTAX_ERR; /* number must be positive */
1479 recent.gui_geometry_main_lower_pane = (int)num;
1480 } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_MASTER_SPLIT"gui.geometry_main_master_split") == 0) {
1481 g_free(recent.gui_geometry_main_master_split);
1482 recent.gui_geometry_main_master_split = g_strdup(value)g_strdup_inline (value);
1483 } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_EXTRA_SPLIT"gui.geometry_main_extra_split") == 0) {
1484 g_free(recent.gui_geometry_main_extra_split);
1485 recent.gui_geometry_main_extra_split = g_strdup(value)g_strdup_inline (value);
1486 } else if (strncmp(key, RECENT_GUI_GEOMETRY"gui.geom.", sizeof(RECENT_GUI_GEOMETRY"gui.geom.")-1) == 0) {
1487 /* now have something like "gui.geom.win.sub_key", split it into win and sub_key */
1488 char *win = &key[sizeof(RECENT_GUI_GEOMETRY"gui.geom.")-1];
1489 char *sub_key = strchr(win, '.');
1490 if (sub_key) {
1491 *sub_key = '\0';
1492 sub_key++;
1493 window_geom_recent_read_pair(win, sub_key, value);
1494 }
1495 } else if (strcmp(key, RECENT_GUI_CONVERSATION_TABS"gui.conversation_tabs") == 0) {
1496 g_list_free_full(recent.conversation_tabs, g_free);
1497 recent.conversation_tabs = prefs_get_string_list(value);
1498 } else if (strcmp(key, RECENT_GUI_CONVERSATION_TABS_COLUMNS"gui.conversation_tabs_columns") == 0) {
1499 g_list_free_full(recent.conversation_tabs_columns, g_free);
1500 recent.conversation_tabs_columns = prefs_get_string_list(value);
1501 } else if (strcmp(key, RECENT_GUI_ENDPOINT_TABS"gui.endpoint_tabs") == 0) {
1502 g_list_free_full(recent.endpoint_tabs, g_free);
1503 recent.endpoint_tabs = prefs_get_string_list(value);
1504 } else if (strcmp(key, RECENT_GUI_ENDPOINT_TABS_COLUMNS"gui.endpoint_tabs_columns") == 0) {
1505 g_list_free_full(recent.endpoint_tabs_columns, g_free);
1506 recent.endpoint_tabs_columns = prefs_get_string_list(value);
1507 } else if (strcmp(key, RECENT_GUI_RLC_PDUS_FROM_MAC_FRAMES"gui.rlc_pdus_from_mac_frames") == 0) {
1508 parse_recent_boolean(value, &recent.gui_rlc_use_pdus_from_mac);
1509 } else if (strcmp(key, RECENT_KEY_COL_WIDTH"column.width") == 0) {
1510 col_l = prefs_get_string_list(value);
1511 if (col_l == NULL((void*)0))
1512 return PREFS_SET_SYNTAX_ERR;
1513 if ((g_list_length(col_l) % 2) != 0) {
1514 /* A title didn't have a matching width. */
1515 prefs_clear_string_list(col_l);
1516 return PREFS_SET_SYNTAX_ERR;
1517 }
1518 recent_free_column_width_info(&recent);
1519 recent.col_width_list = NULL((void*)0);
1520 col_l_elt = g_list_first(col_l);
1521 while (col_l_elt) {
1522 cfmt = g_new(col_width_data, 1)((col_width_data *) g_malloc_n ((1), sizeof (col_width_data))
)
;
1523 /* Skip the column format, we don't use it anymore because the
1524 * column indices are in sync and the key since 4.4. Format is
1525 * still written for backwards compatibility.
1526 */
1527 col_l_elt = col_l_elt->next;
1528 cfmt->width = (int)strtol((const char *)col_l_elt->data, &p, 0);
1529 if (p == col_l_elt->data || (*p != '\0' && *p != ':')) {
1530 g_free(cfmt);
1531 return PREFS_SET_SYNTAX_ERR; /* number was bad */
1532 }
1533
1534 if (*p == ':') {
1535 cfmt->xalign = *(++p);
1536 } else {
1537 cfmt->xalign = COLUMN_XALIGN_DEFAULT0;
1538 }
1539
1540 col_l_elt = col_l_elt->next;
1541 recent.col_width_list = g_list_append(recent.col_width_list, cfmt);
1542 }
1543 prefs_clear_string_list(col_l);
1544 } else if (strcmp(key, RECENT_GUI_FILEOPEN_REMEMBERED_DIR"gui.fileopen_remembered_dir") == 0) {
1545 g_free(recent.gui_fileopen_remembered_dir);
1546 recent.gui_fileopen_remembered_dir = g_strdup(value)g_strdup_inline (value);
1547 } else if (strcmp(key, RECENT_GUI_TOOLBAR_SHOW"gui.additional_toolbar_show") == 0) {
1548 recent.gui_additional_toolbars = prefs_get_string_list(value);
1549 } else if (strcmp(key, RECENT_GUI_INTERFACE_TOOLBAR_SHOW"gui.interface_toolbar_show") == 0) {
1550 recent.interface_toolbars = prefs_get_string_list(value);
1551 } else if (strcmp(key, RECENT_GUI_TSD_THROUGHPUT_SHOW"gui.tsd_throughput_show") == 0) {
1552 parse_recent_boolean(value, &recent.gui_tsgd_throughput_show);
1553 } else if (strcmp(key, RECENT_GUI_TSD_GOODPUT_SHOW"gui.tsd_goodput_show") == 0) {
1554 parse_recent_boolean(value, &recent.gui_tsgd_goodput_show);
1555 } else if (strcmp(key, RECENT_GUI_TSD_MA_WINDOW_SIZE"gui.tsd_ma_window_size") == 0) {
1556 val_as_dbl = g_ascii_strtod(value, &p);
1557 if (p == value || *p != '\0') {
1558 return PREFS_SET_SYNTAX_ERR; /* number was bad */
1559 }
1560 if (val_as_dbl <= 0) {
1561 return PREFS_SET_SYNTAX_ERR; /* number must be positive */
1562 }
1563 recent.gui_tsgd_ma_window_size = val_as_dbl;
1564 } else if (strcmp(key, RECENT_KEY_SIDEBAR_LEARN_VISIBLE"gui.welcome_page.sidebar.learn_visible") == 0) {
1565 parse_recent_boolean(value, &recent.gui_welcome_page_sidebar_learn_visible);
1566 } else if (strcmp(key, RECENT_KEY_SIDEBAR_TIPS_VISIBLE"gui.welcome_page.sidebar.tips_visible") == 0) {
1567 parse_recent_boolean(value, &recent.gui_welcome_page_sidebar_tips_visible);
1568 } else if (strcmp(key, RECENT_KEY_SIDEBAR_TIPS_EVENTS"gui.welcome_page.sidebar.tips_events") == 0) {
1569 parse_recent_boolean(value, &recent.gui_welcome_page_sidebar_tips_events);
1570 } else if (strcmp(key, RECENT_KEY_SIDEBAR_TIPS_SPONSORSHIP"gui.welcome_page.sidebar.tips_sponsorship") == 0) {
1571 parse_recent_boolean(value, &recent.gui_welcome_page_sidebar_tips_sponsorship);
1572 } else if (strcmp(key, RECENT_KEY_SIDEBAR_TIPS_TIPS"gui.welcome_page.sidebar.tips_tips") == 0) {
1573 parse_recent_boolean(value, &recent.gui_welcome_page_sidebar_tips_tips);
1574 } else if (strcmp(key, RECENT_KEY_SIDEBAR_TIPS_INTERVAL"gui.welcome_page.sidebar.tips_interval") == 0) {
1575 num = strtol(value, &p, 0);
1576 if (p == value || *p != '\0')
1577 return PREFS_SET_SYNTAX_ERR;
1578 if (num < 1)
1579 num = 1;
1580 recent.gui_welcome_page_sidebar_tips_interval = (unsigned)num;
1581 } else {
1582 return PREFS_SET_NO_SUCH_PREF;
1583 }
1584
1585 return PREFS_SET_OK;
1586}
1587
1588
1589/* set one user's recent file key/value pair */
1590static prefs_set_pref_e
1591read_set_recent_pair_dynamic(char *key, const char *value,
1592 void *private_data _U___attribute__((unused)),
1593 bool_Bool return_range_errors _U___attribute__((unused)))
1594{
1595 if (!g_utf8_validate(value, -1, NULL((void*)0))) {
1596 return PREFS_SET_SYNTAX_ERR;
1597 }
1598 if (strcmp(key, RECENT_KEY_DISPLAY_FILTER"recent.display_filter") == 0) {
1599 dfilter_combo_add_recent(value);
1600 } else if (strcmp(key, RECENT_KEY_CAPTURE_FILTER"recent.capture_filter") == 0) {
1601 recent_add_cfilter(NULL((void*)0), value);
1602 } else if (g_str_has_prefix(key, RECENT_KEY_CAPTURE_FILTER ".")(__builtin_constant_p ("recent.capture_filter" ".")? __extension__
({ const char * const __str = (key); const char * const __prefix
= ("recent.capture_filter" "."); gboolean __result = (0); if
(__str == ((void*)0) || __prefix == ((void*)0)) __result = (
g_str_has_prefix) (__str, __prefix); else { const size_t __str_len
= strlen (((__str) + !(__str))); const size_t __prefix_len =
strlen (((__prefix) + !(__prefix))); if (__str_len >= __prefix_len
) __result = memcmp (((__str) + !(__str)), ((__prefix) + !(__prefix
)), __prefix_len) == 0; } __result; }) : (g_str_has_prefix) (
key, "recent.capture_filter" ".") )
) {
1603 /* strrchr() can't fail - string has a prefix that ends with a "." */
1604 recent_add_cfilter(strrchr(key, '.') + 1, value);
1605#ifdef HAVE_PCAP_REMOTE
1606 } else if (strcmp(key, RECENT_KEY_REMOTE_HOST"recent.remote_host") == 0) {
1607 capture_remote_combo_add_recent(value);
1608#endif
1609 }
1610
1611 return PREFS_SET_OK;
1612}
1613
1614
1615/*
1616 * Given a string of the form "<recent name>:<recent value>", as might appear
1617 * as an argument to a "-o" option, parse it and set the recent value in
1618 * question. Return an indication of whether it succeeded or failed
1619 * in some fashion.
1620 */
1621int
1622recent_set_arg(char *prefarg)
1623{
1624 char *p, *colonp;
1625 int ret;
1626
1627 colonp = strchr(prefarg, ':');
1628 if (colonp == NULL((void*)0))
1629 return PREFS_SET_SYNTAX_ERR;
1630
1631 p = colonp;
1632 *p++ = '\0';
1633
1634 /*
1635 * Skip over any white space (there probably won't be any, but
1636 * as we allow it in the preferences file, we might as well
1637 * allow it here).
1638 */
1639 while (g_ascii_isspace(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_SPACE) != 0))
1640 p++;
1641 if (*p == '\0') {
1642 /*
1643 * Put the colon back, so if our caller uses, in an
1644 * error message, the string they passed us, the message
1645 * looks correct.
1646 */
1647 *colonp = ':';
1648 return PREFS_SET_SYNTAX_ERR;
1649 }
1650
1651 ret = read_set_recent_pair_static(prefarg, p, NULL((void*)0), true1);
1652 *colonp = ':'; /* put the colon back */
1653 return ret;
1654}
1655
1656
1657/* opens the user's recent common file and read the first part */
1658bool_Bool
1659recent_read_static(char **rf_path_return, int *rf_errno_return)
1660{
1661 char *rf_path;
1662 FILE *rf;
1663
1664 /* set defaults */
1665 recent.gui_geometry_main_x = 20;
1666 recent.gui_geometry_main_y = 20;
1667 recent.gui_geometry_main_width = DEF_WIDTH750;
1668 recent.gui_geometry_main_height = DEF_HEIGHT550;
1669 recent.gui_geometry_main_maximized= false0;
1670
1671 recent.gui_geometry_leftalign_actions = false0;
1672
1673 recent.privs_warn_if_elevated = true1;
1674 recent.sys_warn_if_no_capture = true1;
1675
1676 recent.col_width_list = NULL((void*)0);
1677 recent.gui_geometry_main = NULL((void*)0);
1678 recent.gui_geometry_main_master_split = NULL((void*)0);
1679 recent.gui_geometry_main_extra_split = NULL((void*)0);
1680 recent.gui_profile_switch_check_count = 1000;
1681 recent.gui_fileopen_remembered_dir = NULL((void*)0);
1682
1683 /* Construct the pathname of the user's recent common file. */
1684 rf_path = get_persconffile_path(RECENT_COMMON_FILE_NAME"recent_common", false0, application_configuration_environment_prefix());
1685
1686 /* Read the user's recent common file, if it exists. */
1687 *rf_path_return = NULL((void*)0);
1688 if ((rf = ws_fopenfopen(rf_path, "r")) != NULL((void*)0)) {
1689 /* We succeeded in opening it; read it. */
1690 read_prefs_file(rf_path, rf, read_set_recent_common_pair_static, NULL((void*)0));
1691
1692 fclose(rf);
1693 } else {
1694 /* We failed to open it. If we failed for some reason other than
1695 "it doesn't exist", return the errno and the pathname, so our
1696 caller can report the error. */
1697 if (errno(*__errno_location ()) != ENOENT2) {
1698 *rf_errno_return = errno(*__errno_location ());
1699 *rf_path_return = rf_path;
1700 return false0;
1701 }
1702 }
1703 g_free(rf_path);
1704 return true1;
1705}
1706
1707
1708
1709/* opens the user's recent file and read the first part */
1710bool_Bool
1711recent_read_profile_static(char **rf_path_return, int *rf_errno_return)
1712{
1713 char *rf_path, *rf_common_path;
1714 FILE *rf;
1715
1716 /* set defaults */
1717 recent.main_toolbar_show = true1;
1718 recent.filter_toolbar_show = true1;
1719 recent.wireless_toolbar_show = false0;
1720 recent.packet_list_show = true1;
1721 recent.tree_view_show = true1;
1722 recent.byte_view_show = true1;
1723 recent.packet_diagram_show = true1;
1724 recent.statusbar_show = true1;
1725 recent.packet_list_colorize = true1;
1726 recent.capture_auto_scroll = true1;
1727 recent.gui_time_format = TS_RELATIVE;
1728 recent.gui_time_precision = TS_PREC_AUTO;
1729 recent.gui_seconds_format = TS_SECONDS_DEFAULT;
1730 recent.gui_zoom_level = 0;
1731 recent.gui_bytes_view = BYTES_HEX;
1732 recent.gui_bytes_encoding = BYTES_ENC_FROM_PACKET;
1733 recent.gui_allow_hover_selection = true1;
1734 recent.gui_follow_show = SHOW_ASCII;
1735 recent.gui_follow_delta = FOLLOW_DELTA_NONE;
1736 recent.gui_show_bytes_decode = DecodeAsNone;
1737 recent.gui_show_bytes_show = SHOW_ASCII;
1738
1739 /* defaults for the TCP Stream Graph Dialog */
1740 recent.gui_tsgd_ma_window_size = 1.0;
1741 recent.gui_tsgd_throughput_show = true1;
1742 recent.gui_tsgd_goodput_show = false0;
1743
1744 /* defaults for the welcome page sidebar */
1745 recent.gui_welcome_page_sidebar_learn_visible = true1;
1746 recent.gui_welcome_page_sidebar_tips_visible = true1;
1747 recent.gui_welcome_page_sidebar_tips_events = true1;
1748 recent.gui_welcome_page_sidebar_tips_sponsorship = true1;
1749 recent.gui_welcome_page_sidebar_tips_tips = true1;
1750 recent.gui_welcome_page_sidebar_tips_interval = 8;
1751
1752 /* pane size of zero will autodetect */
1753 recent.gui_geometry_main_upper_pane = 0;
1754 recent.gui_geometry_main_lower_pane = 0;
1755
1756 if (recent.gui_geometry_main) {
1
Assuming field 'gui_geometry_main' is null
2
Taking false branch
1757 g_free(recent.gui_geometry_main);
1758 recent.gui_geometry_main = NULL((void*)0);
1759 }
1760
1761 if (recent.gui_geometry_main_master_split) {
3
Assuming field 'gui_geometry_main_master_split' is null
4
Taking false branch
1762 g_free(recent.gui_geometry_main_master_split);
1763 recent.gui_geometry_main_master_split = NULL((void*)0);
1764 }
1765 if (recent.gui_geometry_main_extra_split) {
5
Assuming field 'gui_geometry_main_extra_split' is null
6
Taking false branch
1766 g_free(recent.gui_geometry_main_extra_split);
1767 recent.gui_geometry_main_extra_split = NULL((void*)0);
1768 }
1769
1770 if (recent.col_width_list) {
7
Assuming field 'col_width_list' is null
8
Taking false branch
1771 recent_free_column_width_info(&recent);
1772 }
1773
1774 if (recent.gui_fileopen_remembered_dir) {
9
Assuming field 'gui_fileopen_remembered_dir' is null
10
Taking false branch
1775 g_free (recent.gui_fileopen_remembered_dir);
1776 recent.gui_fileopen_remembered_dir = NULL((void*)0);
1777 }
1778
1779 if (recent.gui_additional_toolbars) {
11
Assuming field 'gui_additional_toolbars' is null
12
Taking false branch
1780 g_list_free_full (recent.gui_additional_toolbars, g_free);
1781 recent.gui_additional_toolbars = NULL((void*)0);
1782 }
1783
1784 if (recent.interface_toolbars) {
13
Assuming field 'interface_toolbars' is null
14
Taking false branch
1785 g_list_free_full (recent.interface_toolbars, g_free);
1786 recent.interface_toolbars = NULL((void*)0);
1787 }
1788
1789 /* Construct the pathname of the user's profile recent file. */
1790 rf_path = get_persconffile_path(RECENT_FILE_NAME"recent", true1, application_configuration_environment_prefix());
1791
1792 /* Read the user's recent file, if it exists. */
1793 *rf_path_return = NULL((void*)0);
1794 if ((rf = ws_fopenfopen(rf_path, "r")) != NULL((void*)0)) {
15
Taking true branch
1795 /* We succeeded in opening it; read it. */
1796 read_prefs_file(rf_path, rf, read_set_recent_pair_static, NULL((void*)0));
1797 fclose(rf);
1798
1799 /* XXX: The following code doesn't actually do anything since
1800 * the "recent common file" always exists. Presumably the
1801 * "if (!file_exists())" should actually be "if (file_exists())".
1802 * However, I've left the code as is because this
1803 * behaviour has existed for quite some time and I don't
1804 * know what's supposed to happen at this point.
1805 * ToDo: Determine if the "recent common file" should be read at this point
1806 */
1807 rf_common_path = get_persconffile_path(RECENT_COMMON_FILE_NAME"recent_common", false0, application_configuration_environment_prefix());
1808 if (!file_exists(rf_common_path)) {
16
Assuming the condition is true
17
Taking true branch
1809 /* Read older common settings from recent file */
1810 rf = ws_fopenfopen(rf_path, "r");
18
Assuming pointer value is null
19
Assuming that 'fopen' fails
20
Value assigned to 'rf'
1811 read_prefs_file(rf_path, rf, read_set_recent_common_pair_static, NULL((void*)0));
1812 fclose(rf);
21
Null pointer passed to 1st parameter expecting 'nonnull'
1813 }
1814 g_free(rf_common_path);
1815 } else {
1816 /* We failed to open it. If we failed for some reason other than
1817 "it doesn't exist", return the errno and the pathname, so our
1818 caller can report the error. */
1819 if (errno(*__errno_location ()) != ENOENT2) {
1820 *rf_errno_return = errno(*__errno_location ());
1821 *rf_path_return = rf_path;
1822 return false0;
1823 }
1824 }
1825 g_free(rf_path);
1826 return true1;
1827}
1828
1829/* opens the user's recent file and read it out */
1830bool_Bool
1831recent_read_dynamic(char **rf_path_return, int *rf_errno_return)
1832{
1833 char *rf_path;
1834 FILE *rf;
1835
1836
1837 /* Construct the pathname of the user's recent common file. */
1838 rf_path = get_persconffile_path(RECENT_COMMON_FILE_NAME"recent_common", false0, application_configuration_environment_prefix());
1839 if (!file_exists (rf_path)) {
1840 /* Recent common file does not exist, read from default recent */
1841 g_free (rf_path);
1842 rf_path = get_persconffile_path(RECENT_FILE_NAME"recent", false0, application_configuration_environment_prefix());
1843 }
1844
1845 /* Read the user's recent file, if it exists. */
1846 *rf_path_return = NULL((void*)0);
1847 if ((rf = ws_fopenfopen(rf_path, "r")) != NULL((void*)0)) {
1848 /* We succeeded in opening it; read it. */
1849 read_prefs_file(rf_path, rf, read_set_recent_pair_dynamic, NULL((void*)0));
1850#if 0
1851 /* set dfilter combobox to have an empty line */
1852 dfilter_combo_add_empty();
1853#endif
1854 /* We prepend new capture filters, so reverse them after adding
1855 * all to keep the latest first.
1856 */
1857 cfilter_recent_reverse_all();
1858#ifdef HAVE_PCAP_REMOTE
1859 remote_host_reverse();
1860#endif
1861 fclose(rf);
1862 } else {
1863 /* We failed to open it. If we failed for some reason other than
1864 "it doesn't exist", return the errno and the pathname, so our
1865 caller can report the error. */
1866 if (errno(*__errno_location ()) != ENOENT2) {
1867 *rf_errno_return = errno(*__errno_location ());
1868 *rf_path_return = rf_path;
1869 return false0;
1870 }
1871 }
1872 g_free(rf_path);
1873 return true1;
1874}
1875
1876void
1877recent_insert_column(int col)
1878{
1879 col_width_data *col_w;
1880
1881 col_w = g_new(col_width_data, 1)((col_width_data *) g_malloc_n ((1), sizeof (col_width_data))
)
;
1882 col_w->width = -1;
1883 col_w->xalign = COLUMN_XALIGN_DEFAULT0;
1884 recent.col_width_list = g_list_insert(recent.col_width_list, col_w, col);
1885}
1886
1887void
1888recent_remove_column(int col)
1889{
1890 GList *col_l = g_list_nth(recent.col_width_list, col);
1891 col_width_data *col_w;
1892
1893 if (!col_l) return;
1894
1895 col_w = (col_width_data*)col_l->data;
1896
1897 if (col_w) {
1898 free_col_width_data(col_w);
1899 }
1900
1901 recent.col_width_list = g_list_delete_link(recent.col_width_list, col_l);
1902}
1903
1904int
1905recent_get_column_width(int col)
1906{
1907 col_width_data *col_w;
1908
1909 col_w = g_list_nth_data(recent.col_width_list, col);
1910 if (col_w) {
1911 return col_w->width;
1912 } else {
1913 /* Make sure the recent column list isn't out of sync with the
1914 * number of columns (e.g., for a brand new profile.)
1915 */
1916 for (unsigned colnr = g_list_length(recent.col_width_list); colnr < g_list_length(prefs.col_list); colnr++) {
1917 recent_insert_column(colnr);
1918 }
1919 }
1920
1921 return -1;
1922}
1923
1924void
1925recent_set_column_width(int col, int width)
1926{
1927 col_width_data *col_w;
1928
1929 col_w = g_list_nth_data(recent.col_width_list, col);
1930 if (col_w) {
1931 col_w->width = width;
1932 } else {
1933 /* Make sure the recent column list isn't out of sync with the
1934 * number of columns (e.g., for a brand new profile.)
1935 */
1936 for (unsigned colnr = g_list_length(recent.col_width_list); colnr < g_list_length(prefs.col_list); colnr++) {
1937 recent_insert_column(colnr);
1938 }
1939 col_w = g_list_nth_data(recent.col_width_list, col);
1940 if (col_w) {
1941 col_w->width = width;
1942 }
1943 }
1944}
1945
1946char
1947recent_get_column_xalign(int col)
1948{
1949 col_width_data *col_w;
1950
1951 col_w = g_list_nth_data(recent.col_width_list, col);
1952 if (col_w) {
1953 return col_w->xalign;
1954 } else {
1955 /* Make sure the recent column list isn't out of sync with the
1956 * number of columns (e.g., for a brand new profile.)
1957 */
1958 for (unsigned colnr = g_list_length(recent.col_width_list); colnr < g_list_length(prefs.col_list); colnr++) {
1959 recent_insert_column(colnr);
1960 }
1961 }
1962
1963 return COLUMN_XALIGN_DEFAULT0;
1964}
1965
1966void
1967recent_set_column_xalign(int col, char xalign)
1968{
1969 col_width_data *col_w;
1970
1971 col_w = g_list_nth_data(recent.col_width_list, col);
1972 if (col_w) {
1973 col_w->xalign = xalign;
1974 } else {
1975 /* Make sure the recent column list isn't out of sync with the
1976 * number of columns (e.g., for a brand new profile.)
1977 */
1978 for (unsigned colnr = g_list_length(recent.col_width_list); colnr < g_list_length(prefs.col_list); colnr++) {
1979 recent_insert_column(colnr);
1980 }
1981 col_w = g_list_nth_data(recent.col_width_list, col);
1982 if (col_w) {
1983 col_w->xalign = xalign;
1984 }
1985 }
1986}
1987
1988void
1989recent_init(void)
1990{
1991 memset(&recent, 0, sizeof(recent_settings_t));
1992}
1993
1994void
1995recent_cleanup(void)
1996{
1997 recent_free_column_width_info(&recent);
1998 g_free(recent.gui_geometry_main);
1999 g_free(recent.gui_geometry_main_master_split);
2000 g_free(recent.gui_geometry_main_extra_split);
2001 g_free(recent.gui_fileopen_remembered_dir);
2002 g_list_free_full(recent.gui_additional_toolbars, g_free);
2003 g_list_free_full(recent.interface_toolbars, g_free);
2004 prefs_clear_string_list(recent.conversation_tabs);
2005 prefs_clear_string_list(recent.conversation_tabs_columns);
2006 prefs_clear_string_list(recent.endpoint_tabs);
2007 prefs_clear_string_list(recent.endpoint_tabs_columns);
2008 prefs_clear_string_list(recent.custom_colors);
2009}