Bug Summary

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