2 * Routines for handling preferences
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * SPDX-License-Identifier: GPL-2.0+
20 #include <wsutil/filesystem.h>
21 #include <epan/address.h>
22 #include <epan/addr_resolv.h>
23 #include <epan/oids.h>
25 #include <epan/geoip_db.h>
27 #include <epan/packet.h>
28 #include <epan/prefs.h>
29 #include <epan/proto.h>
30 #include <epan/strutil.h>
31 #include <epan/column.h>
32 #include <epan/decode_as.h>
34 #include <wsutil/file_util.h>
35 #include <wsutil/ws_printf.h> /* ws_g_warning */
36 #include <wsutil/report_message.h>
38 #include <epan/prefs-int.h>
39 #include <epan/uat-int.h>
41 #include "epan/filter_expressions.h"
43 #include "epan/wmem/wmem.h"
44 #include <epan/stats_tree.h>
46 /* Internal functions */
47 static module_t *find_subtree(module_t *parent, const char *tilte);
48 static module_t *prefs_register_module_or_subtree(module_t *parent,
49 const char *name, const char *title, const char *description, gboolean is_subtree,
50 void (*apply_cb)(void), gboolean use_gui);
51 static void prefs_register_modules(void);
52 static prefs_set_pref_e set_pref(gchar*, const gchar*, void *, gboolean);
53 static void free_col_info(GList *);
54 static void pre_init_prefs(void);
55 static gboolean prefs_is_column_visible(const gchar *cols_hidden, fmt_data *cfmt);
56 static gboolean parse_column_format(fmt_data *cfmt, const char *fmt);
57 static void try_convert_to_custom_column(gpointer *el_data);
58 static guint prefs_module_list_foreach(wmem_tree_t *module_list, module_cb callback,
59 gpointer user_data, gboolean skip_obsolete);
61 #define IS_PREF_OBSOLETE(p) ((p) & PREF_OBSOLETE)
62 #define SET_PREF_OBSOLETE(p) ((p) |= PREF_OBSOLETE)
63 #define RESET_PREF_OBSOLETE(p) ((p) &= ~PREF_OBSOLETE)
65 #define PF_NAME "preferences"
66 #define OLD_GPF_NAME "wireshark.conf" /* old name for global preferences file */
68 static gboolean prefs_initialized = FALSE;
69 static gchar *gpf_path = NULL;
70 static gchar *cols_hidden_list = NULL;
71 static gboolean gui_theme_is_dark = FALSE;
74 * XXX - variables to allow us to attempt to interpret the first
75 * "mgcp.{tcp,udp}.port" in a preferences file as
76 * "mgcp.{tcp,udp}.gateway_port" and the second as
77 * "mgcp.{tcp,udp}.callagent_port".
79 static int mgcp_tcp_port_count;
80 static int mgcp_udp_port_count;
84 static const enum_val_t gui_ptree_line_style[] = {
86 {"SOLID", "SOLID", 1},
87 {"DOTTED", "DOTTED", 2},
88 {"TABBED", "TABBED", 3},
92 static const enum_val_t gui_ptree_expander_style[] = {
94 {"SQUARE", "SQUARE", 1},
95 {"TRIANGLE", "TRIANGLE", 2},
96 {"CIRCULAR", "CIRCULAR", 3},
101 static const enum_val_t gui_hex_dump_highlight_style[] = {
103 {"INVERSE", "INVERSE", 1},
107 static const enum_val_t gui_console_open_type[] = {
108 {"NEVER", "NEVER", console_open_never},
109 {"AUTOMATIC", "AUTOMATIC", console_open_auto},
110 {"ALWAYS", "ALWAYS", console_open_always},
114 static const enum_val_t gui_version_placement_type[] = {
115 {"WELCOME", "WELCOME", version_welcome_only},
116 {"TITLE", "TITLE", version_title_only},
117 {"BOTH", "BOTH", version_both},
118 {"NEITHER", "NEITHER", version_neither},
122 static const enum_val_t gui_fileopen_style[] = {
123 {"LAST_OPENED", "LAST_OPENED", 0},
124 {"SPECIFIED", "SPECIFIED", 1},
128 /* GTK knows of two ways representing "both", vertical and horizontal aligned.
129 * as this may not work on other guis, we use only "both" in general here */
130 static const enum_val_t gui_toolbar_style[] = {
131 {"ICONS", "ICONS", 0},
137 static const enum_val_t gui_layout_content[] = {
139 {"PLIST", "PLIST", 1},
140 {"PDETAILS", "PDETAILS", 2},
141 {"PBYTES", "PBYTES", 3},
145 static const enum_val_t gui_update_channel[] = {
146 {"DEVELOPMENT", "DEVELOPMENT", UPDATE_CHANNEL_DEVELOPMENT},
147 {"STABLE", "STABLE", UPDATE_CHANNEL_STABLE},
151 #if defined(HAVE_PCAP_CREATE)
152 /* Can set monitor mode and buffer size. */
153 static gint num_capture_cols = 7;
154 static const gchar *capture_cols[7] = {
163 #define CAPTURE_COL_TYPE_DESCRIPTION \
164 "Possible values: INTERFACE, LINK, PMODE, SNAPLEN, MONITOR, BUFFER, FILTER\n"
165 #elif defined(CAN_SET_CAPTURE_BUFFER_SIZE)
166 /* Can set buffer size but not monitor mode. */
167 static gint num_capture_cols = 6;
168 static const gchar *capture_cols[6] = {
176 #define CAPTURE_COL_TYPE_DESCRIPTION \
177 "Possible values: INTERFACE, LINK, PMODE, SNAPLEN, BUFFER, FILTER\n"
179 /* Can neither set buffer size nor monitor mode. */
180 static gint num_capture_cols = 5;
181 static const gchar *capture_cols[5] = {
188 #define CAPTURE_COL_TYPE_DESCRIPTION \
189 "Possible values: INTERFACE, LINK, PMODE, SNAPLEN, FILTER\n"
192 static const enum_val_t gui_packet_list_elide_mode[] = {
193 {"LEFT", "LEFT", ELIDE_LEFT},
194 {"RIGHT", "RIGHT", ELIDE_RIGHT},
195 {"MIDDLE", "MIDDLE", ELIDE_MIDDLE},
196 {"NONE", "NONE", ELIDE_NONE},
200 /** Struct to hold preference data */
202 const char *name; /**< name of preference */
203 const char *title; /**< title to use in GUI */
204 const char *description; /**< human-readable description of preference */
205 int ordinal; /**< ordinal number of this preference */
206 int type; /**< type of that preference */
207 unsigned int effect_flags; /**< Flags of types effected by preference (PREF_TYPE_DISSECTION, PREF_EFFECT_CAPTURE, etc).
208 Flags must be non-zero to ensure saving to disk */
209 gui_type_t gui; /**< type of the GUI (QT, GTK or both) the preference is registered for */
210 union { /* The Qt preference code assumes that these will all be pointers (and unique) */
216 struct epan_uat* uat;
219 } varp; /**< pointer to variable storing the value */
228 } stashed_val; /**< original value, when editing from the GUI */
237 } default_val; /**< the default value of the preference */
239 guint base; /**< input/output base, for PREF_UINT */
240 guint32 max_value; /**< maximum value of a range */
242 const enum_val_t *enumvals; /**< list of name & values */
243 gboolean radio_buttons; /**< TRUE if it should be shown as
244 radio buttons rather than as an
245 option menu or combo box in
246 the preferences tab */
247 } enum_info; /**< for PREF_ENUM */
248 } info; /**< display/text file information */
249 struct pref_custom_cbs custom_cbs; /**< for PREF_CUSTOM */
250 void *control; /**< handle for GUI control for this preference. GTK+ only? */
253 const char* prefs_get_description(pref_t *pref)
255 return pref->description;
258 const char* prefs_get_title(pref_t *pref)
263 int prefs_get_type(pref_t *pref)
268 gui_type_t prefs_get_gui_type(pref_t *pref)
273 const char* prefs_get_name(pref_t *pref)
278 guint32 prefs_get_max_value(pref_t *pref)
280 return pref->info.max_value;
283 void* prefs_get_control(pref_t *pref)
285 return pref->control;
288 void prefs_set_control(pref_t *pref, void* control)
290 pref->control = control;
293 int prefs_get_ordinal(pref_t *pref)
295 return pref->ordinal;
299 * List of all modules with preference settings.
301 static wmem_tree_t *prefs_modules = NULL;
304 * List of all modules that should show up at the top level of the
305 * tree in the preference dialog box.
307 static wmem_tree_t *prefs_top_level_modules = NULL;
309 /** Sets up memory used by proto routines. Called at program startup */
313 memset(&prefs, 0, sizeof(prefs));
314 prefs_modules = wmem_tree_new(wmem_epan_scope());
315 prefs_top_level_modules = wmem_tree_new(wmem_epan_scope());
319 * Free the strings for a string-like preference.
322 free_string_like_preference(pref_t *pref)
324 g_free(*pref->varp.string);
325 *pref->varp.string = NULL;
326 g_free(pref->default_val.string);
327 pref->default_val.string = NULL;
331 free_pref(gpointer data, gpointer user_data _U_)
333 pref_t *pref = (pref_t *)data;
334 int type = pref->type;
336 /* we reset the PREF_OBSOLETE bit in order to allow the original preference to be freed */
337 RESET_PREF_OBSOLETE(type);
343 case PREF_DECODE_AS_UINT:
344 case PREF_STATIC_TEXT:
349 case PREF_SAVE_FILENAME:
350 case PREF_OPEN_FILENAME:
352 g_free(*pref->varp.string);
353 *pref->varp.string = NULL;
354 g_free(pref->default_val.string);
355 pref->default_val.string = NULL;
358 case PREF_DECODE_AS_RANGE:
359 wmem_free(wmem_epan_scope(), *pref->varp.range);
360 *pref->varp.range = NULL;
361 wmem_free(wmem_epan_scope(), pref->default_val.range);
362 pref->default_val.range = NULL;
365 if (strcmp(pref->name, "columns") == 0)
366 pref->stashed_val.boolval = TRUE;
367 pref->custom_cbs.free_cb(pref);
375 free_module_prefs(module_t *module, gpointer data _U_)
378 g_list_foreach(module->prefs, free_pref, NULL);
379 g_list_free(module->prefs);
381 module->prefs = NULL;
382 module->numprefs = 0;
383 if (module->submodules) {
384 prefs_module_list_foreach(module->submodules, free_module_prefs, NULL, FALSE);
386 /* We don't free the actual module: its submodules pointer points to
387 a wmem_tree and the module itself is stored in a wmem_tree
393 /** Frees memory used by proto routines. Called at program shutdown */
397 /* This isn't strictly necessary since we're exiting anyway, but let's
398 * do what clean up we can.
400 prefs_module_list_foreach(prefs_modules, free_module_prefs, NULL, FALSE);
405 g_free(prefs.saved_at_version);
410 void prefs_set_gui_theme_is_dark(gboolean is_dark)
412 gui_theme_is_dark = is_dark;
416 * Register a module that will have preferences.
417 * Specify the module under which to register it or NULL to register it
418 * at the top level, the name used for the module in the preferences file,
419 * the title used in the tab for it in a preferences dialog box, and a
420 * routine to call back when we apply the preferences.
423 prefs_register_module(module_t *parent, const char *name, const char *title,
424 const char *description, void (*apply_cb)(void),
425 const gboolean use_gui)
427 return prefs_register_module_or_subtree(parent, name, title, description,
428 FALSE, apply_cb, use_gui);
432 prefs_deregister_module(module_t *parent, const char *name, const char *title)
434 /* Remove this module from the list of all modules */
435 module_t *module = (module_t *)wmem_tree_remove_string(prefs_modules, name, WMEM_TREE_STRING_NOCASE);
440 if (parent == NULL) {
441 /* Remove from top */
442 wmem_tree_remove_string(prefs_top_level_modules, title, WMEM_TREE_STRING_NOCASE);
443 } else if (parent->submodules) {
444 /* Remove from parent */
445 wmem_tree_remove_string(parent->submodules, title, WMEM_TREE_STRING_NOCASE);
448 free_module_prefs(module, NULL);
449 wmem_free(wmem_epan_scope(), module);
453 * Register a subtree that will have modules under it.
454 * Specify the module under which to register it or NULL to register it
455 * at the top level and the title used in the tab for it in a preferences
459 prefs_register_subtree(module_t *parent, const char *title, const char *description,
460 void (*apply_cb)(void))
462 return prefs_register_module_or_subtree(parent, NULL, title, description,
464 parent ? parent->use_gui : FALSE);
468 prefs_register_module_or_subtree(module_t *parent, const char *name,
469 const char *title, const char *description,
470 gboolean is_subtree, void (*apply_cb)(void),
477 /* this module may have been created as a subtree item previously */
478 if ((module = find_subtree(parent, title))) {
479 /* the module is currently a subtree */
481 module->apply_cb = apply_cb;
482 module->description = description;
484 if (prefs_find_module(name) == NULL) {
485 wmem_tree_insert_string(prefs_modules, name, module,
486 WMEM_TREE_STRING_NOCASE);
492 module = wmem_new(wmem_epan_scope(), module_t);
494 module->title = title;
495 module->description = description;
496 module->apply_cb = apply_cb;
497 module->prefs = NULL; /* no preferences, to start */
498 module->parent = parent;
499 module->submodules = NULL; /* no submodules, to start */
500 module->numprefs = 0;
501 module->prefs_changed_flags = 0;
502 module->obsolete = FALSE;
503 module->use_gui = use_gui;
504 /* A module's preferences affects dissection unless otherwise told */
505 module->effect_flags = PREF_EFFECT_DISSECTION;
508 * Do we have a module name?
513 * Make sure that only lower-case ASCII letters, numbers,
514 * underscores, hyphens, and dots appear in the name.
516 * Crash if there is, as that's an error in the code;
517 * you can make the title a nice string with capitalization,
518 * white space, punctuation, etc., but the name can be used
519 * on the command line, and shouldn't require quoting,
522 for (p = name; (c = *p) != '\0'; p++) {
523 if (!(g_ascii_islower(c) || g_ascii_isdigit(c) || c == '_' ||
524 c == '-' || c == '.'))
525 g_error("Preference module \"%s\" contains invalid characters", name);
529 * Make sure there's not already a module with that
530 * name. Crash if there is, as that's an error in the
531 * code, and the code has to be fixed not to register
532 * more than one module with the same name.
534 * We search the list of all modules; the subtree stuff
535 * doesn't require preferences in subtrees to have names
536 * that reflect the subtree they're in (that would require
537 * protocol preferences to have a bogus "protocol.", or
538 * something such as that, to be added to all their names).
540 g_assert(prefs_find_module(name) == NULL);
543 * Insert this module in the list of all modules.
545 wmem_tree_insert_string(prefs_modules, name, module, WMEM_TREE_STRING_NOCASE);
548 * This has no name, just a title; check to make sure it's a
549 * subtree, and crash if it's not.
551 g_assert(is_subtree);
555 * Insert this module into the appropriate place in the display
558 if (parent == NULL) {
560 * It goes at the top.
562 wmem_tree_insert_string(prefs_top_level_modules, title, module, WMEM_TREE_STRING_NOCASE);
565 * It goes into the list for this module.
568 if (parent->submodules == NULL)
569 parent->submodules = wmem_tree_new(wmem_epan_scope());
571 wmem_tree_insert_string(parent->submodules, title, module, WMEM_TREE_STRING_NOCASE);
578 * Register that a protocol has preferences.
580 module_t *protocols_module = NULL;
583 prefs_register_protocol(int id, void (*apply_cb)(void))
585 protocol_t *protocol;
588 * Have we yet created the "Protocols" subtree?
590 if (protocols_module == NULL) {
592 * No. Register Protocols subtree as well as any preferences
593 * for non-dissector modules.
596 prefs_register_modules();
598 protocol = find_protocol_by_id(id);
599 if (protocol == NULL)
600 g_error("Protocol preferences being registered with an invalid protocol ID");
601 return prefs_register_module(protocols_module,
602 proto_get_protocol_filter_name(id),
603 proto_get_protocol_short_name(protocol),
604 proto_get_protocol_name(id), apply_cb, TRUE);
608 prefs_deregister_protocol (int id)
610 protocol_t *protocol = find_protocol_by_id(id);
611 if (protocol == NULL)
612 g_error("Protocol preferences being de-registered with an invalid protocol ID");
613 prefs_deregister_module (protocols_module,
614 proto_get_protocol_filter_name(id),
615 proto_get_protocol_short_name(protocol));
619 prefs_register_protocol_subtree(const char *subtree, int id, void (*apply_cb)(void))
621 protocol_t *protocol;
622 module_t *subtree_module;
623 module_t *new_module;
624 char *sep = NULL, *ptr = NULL, *orig = NULL;
627 * Have we yet created the "Protocols" subtree?
628 * XXX - can we just do this by registering Protocols/{subtree}?
631 if (protocols_module == NULL) {
633 * No. Register Protocols subtree as well as any preferences
634 * for non-dissector modules.
637 prefs_register_modules();
640 subtree_module = protocols_module;
643 /* take a copy of the buffer, orig keeps a base pointer while ptr
644 * walks through the string */
645 orig = ptr = g_strdup(subtree);
647 while (ptr && *ptr) {
649 if ((sep = strchr(ptr, '/')))
652 if (!(new_module = find_subtree(subtree_module, ptr))) {
654 * There's no such module; create it, with the description
655 * being the name (if it's later registered explicitly
656 * with a description, that will override it).
658 ptr = wmem_strdup(wmem_epan_scope(), ptr);
659 new_module = prefs_register_subtree(subtree_module, ptr, ptr, NULL);
662 subtree_module = new_module;
670 protocol = find_protocol_by_id(id);
671 if (protocol == NULL)
672 g_error("Protocol subtree being registered with an invalid protocol ID");
673 return prefs_register_module(subtree_module,
674 proto_get_protocol_filter_name(id),
675 proto_get_protocol_short_name(protocol),
676 proto_get_protocol_name(id), apply_cb, TRUE);
681 * Register that a protocol used to have preferences but no longer does,
682 * by creating an "obsolete" module for it.
685 prefs_register_protocol_obsolete(int id)
688 protocol_t *protocol;
691 * Have we yet created the "Protocols" subtree?
693 if (protocols_module == NULL) {
695 * No. Register Protocols subtree as well as any preferences
696 * for non-dissector modules.
699 prefs_register_modules();
701 protocol = find_protocol_by_id(id);
702 if (protocol == NULL)
703 g_error("Protocol being registered with an invalid protocol ID");
704 module = prefs_register_module(protocols_module,
705 proto_get_protocol_filter_name(id),
706 proto_get_protocol_short_name(protocol),
707 proto_get_protocol_name(id), NULL, TRUE);
708 module->obsolete = TRUE;
713 * Register that a statistical tap has preferences.
715 * "name" is a name for the tap to use on the command line with "-o"
716 * and in preference files.
718 * "title" is a short human-readable name for the tap.
720 * "description" is a longer human-readable description of the tap.
722 module_t *stats_module = NULL;
725 prefs_register_stat(const char *name, const char *title,
726 const char *description, void (*apply_cb)(void))
729 * Have we yet created the "Statistics" subtree?
731 if (stats_module == NULL) {
733 * No. Register Statistics subtree as well as any preferences
734 * for non-dissector modules.
737 prefs_register_modules();
740 return prefs_register_module(stats_module, name, title, description,
745 * Register that a codec has preferences.
747 * "name" is a name for the codec to use on the command line with "-o"
748 * and in preference files.
750 * "title" is a short human-readable name for the codec.
752 * "description" is a longer human-readable description of the codec.
754 module_t *codecs_module = NULL;
757 prefs_register_codec(const char *name, const char *title,
758 const char *description, void (*apply_cb)(void))
761 * Have we yet created the "Codecs" subtree?
763 if (codecs_module == NULL) {
765 * No. Register Codecs subtree as well as any preferences
766 * for non-dissector modules.
769 prefs_register_modules();
772 return prefs_register_module(codecs_module, name, title, description,
777 prefs_find_module(const char *name)
779 return (module_t *)wmem_tree_lookup_string(prefs_modules, name, WMEM_TREE_STRING_NOCASE);
783 find_subtree(module_t *parent, const char *name)
785 return (module_t *)wmem_tree_lookup_string(parent ? parent->submodules : prefs_top_level_modules, name, WMEM_TREE_STRING_NOCASE);
789 * Call a callback function, with a specified argument, for each module
790 * in a list of modules. If the list is NULL, searches the top-level
791 * list in the display tree of modules. If any callback returns a
792 * non-zero value, we stop and return that value, otherwise we
795 * Normally "obsolete" modules are ignored; their sole purpose is to allow old
796 * preferences for dissectors that no longer have preferences to be
797 * silently ignored in preference files. Does not ignore subtrees,
798 * as this can be used when walking the display tree of modules.
805 gboolean skip_obsolete;
809 call_foreach_cb(const void *key _U_, void *value, void *data)
811 module_t *module = (module_t*)value;
812 call_foreach_t *call_data = (call_foreach_t*)data;
814 if (!call_data->skip_obsolete || !module->obsolete)
815 call_data->ret = (*call_data->callback)(module, call_data->user_data);
817 return (call_data->ret != 0);
821 prefs_module_list_foreach(wmem_tree_t *module_list, module_cb callback,
822 gpointer user_data, gboolean skip_obsolete)
824 call_foreach_t call_data;
826 if (module_list == NULL)
827 module_list = prefs_top_level_modules;
829 call_data.callback = callback;
830 call_data.user_data = user_data;
832 call_data.skip_obsolete = skip_obsolete;
833 wmem_tree_foreach(module_list, call_foreach_cb, &call_data);
834 return call_data.ret;
838 * Returns TRUE if module has any submodules
841 prefs_module_has_submodules(module_t *module)
843 if (module->submodules == NULL) {
847 if (wmem_tree_is_empty(module->submodules)) {
855 * Call a callback function, with a specified argument, for each module
856 * in the list of all modules. (This list does not include subtrees.)
858 * Ignores "obsolete" modules; their sole purpose is to allow old
859 * preferences for dissectors that no longer have preferences to be
860 * silently ignored in preference files.
863 prefs_modules_foreach(module_cb callback, gpointer user_data)
865 return prefs_module_list_foreach(prefs_modules, callback, user_data, TRUE);
869 * Call a callback function, with a specified argument, for each submodule
870 * of specified modules. If the module is NULL, goes through the top-level
871 * list in the display tree of modules.
873 * Ignores "obsolete" modules; their sole purpose is to allow old
874 * preferences for dissectors that no longer have preferences to be
875 * silently ignored in preference files. Does not ignore subtrees,
876 * as this can be used when walking the display tree of modules.
879 prefs_modules_foreach_submodules(module_t *module, module_cb callback,
882 return prefs_module_list_foreach((module)?module->submodules:prefs_top_level_modules, callback, user_data, TRUE);
886 call_apply_cb(const void *key _U_, void *value, void *data _U_)
888 module_t *module = (module_t *)value;
890 if (module->obsolete)
892 if (module->prefs_changed_flags) {
893 if (module->apply_cb != NULL)
894 (*module->apply_cb)();
895 module->prefs_changed_flags = 0;
897 if (module->submodules)
898 wmem_tree_foreach(module->submodules, call_apply_cb, NULL);
903 * Call the "apply" callback function for each module if any of its
904 * preferences have changed, and then clear the flag saying its
905 * preferences have changed, as the module has been notified of that
909 prefs_apply_all(void)
911 wmem_tree_foreach(prefs_modules, call_apply_cb, NULL);
915 * Call the "apply" callback function for a specific module if any of
916 * its preferences have changed, and then clear the flag saying its
917 * preferences have changed, as the module has been notified of that
921 prefs_apply(module_t *module)
923 if (module && module->prefs_changed_flags)
924 call_apply_cb(NULL, module, NULL);
928 * Register a preference in a module's list of preferences.
929 * If it has a title, give it an ordinal number; otherwise, it's a
930 * preference that won't show up in the UI, so it shouldn't get an
931 * ordinal number (the ordinal should be the ordinal in the set of
932 * *visible* preferences).
935 register_preference(module_t *module, const char *name, const char *title,
936 const char *description, int type)
940 const char *name_prefix = (module->name != NULL) ? module->name : module->parent->name;
942 preference = g_new(pref_t,1);
943 preference->name = name;
944 preference->title = title;
945 preference->description = description;
946 preference->type = type;
947 /* Default to module's preference effects */
948 preference->effect_flags = module->effect_flags;
950 preference->gui = GUI_ALL; /* default */
952 preference->ordinal = module->numprefs;
954 preference->ordinal = -1; /* no ordinal for you */
957 * Make sure that only lower-case ASCII letters, numbers,
958 * underscores, and dots appear in the preference name.
960 * Crash if there is, as that's an error in the code;
961 * you can make the title and description nice strings
962 * with capitalization, white space, punctuation, etc.,
963 * but the name can be used on the command line,
964 * and shouldn't require quoting, shifting, etc.
966 for (p = name; *p != '\0'; p++)
967 if (!(g_ascii_islower(*p) || g_ascii_isdigit(*p) || *p == '_' || *p == '.'))
968 g_error("Preference \"%s.%s\" contains invalid characters", module->name, name);
971 * Make sure there's not already a preference with that
972 * name. Crash if there is, as that's an error in the
973 * code, and the code has to be fixed not to register
974 * more than one preference with the same name.
976 if (prefs_find_preference(module, name) != NULL)
977 g_error("Preference %s has already been registered", name);
979 if ((!IS_PREF_OBSOLETE(type)) &&
980 /* Don't compare if it's a subtree */
981 (module->name != NULL)) {
983 * Make sure the preference name doesn't begin with the
984 * module name, as that's redundant and Just Silly.
986 if (!((strncmp(name, module->name, strlen(module->name)) != 0) ||
987 (((name[strlen(module->name)]) != '.') && ((name[strlen(module->name)]) != '_'))))
988 g_error("Preference %s begins with the module name", name);
991 /* The title shows up in the preferences dialog. Make sure it's UI-friendly. */
992 if (preference->title) {
993 const char *cur_char;
994 if (preference->type != PREF_STATIC_TEXT && g_utf8_strlen(preference->title, -1) > 80) { // Arbitrary.
995 g_error("Title for preference %s.%s is too long: %s", name_prefix, preference->name, preference->title);
998 if (!g_utf8_validate(preference->title, -1, NULL)) {
999 g_error("Title for preference %s.%s isn't valid UTF-8.", name_prefix, preference->name);
1002 for (cur_char = preference->title; *cur_char; cur_char = g_utf8_next_char(cur_char)) {
1003 if (!g_unichar_isprint(g_utf8_get_char(cur_char))) {
1004 g_error("Title for preference %s.%s isn't printable UTF-8.", name_prefix, preference->name);
1009 if (preference->description) {
1010 if (!g_utf8_validate(preference->description, -1, NULL)) {
1011 g_error("Description for preference %s.%s isn't valid UTF-8.", name_prefix, preference->name);
1016 * We passed all of our checks. Add the preference.
1018 module->prefs = g_list_append(module->prefs, preference);
1026 * Find a preference in a module's list of preferences, given the module
1027 * and the preference's name.
1032 module_t *submodule;
1036 preference_match(gconstpointer a, gconstpointer b)
1038 const pref_t *pref = (const pref_t *)a;
1039 const char *name = (const char *)b;
1041 return strcmp(name, pref->name);
1045 module_find_pref_cb(const void *key _U_, void *value, void *data)
1047 find_pref_arg_t* arg = (find_pref_arg_t*)data;
1049 module_t *module = (module_t *)value;
1054 list_entry = g_list_find_custom(module->prefs, arg->name,
1057 if (list_entry == NULL)
1060 arg->list_entry = list_entry;
1061 arg->submodule = module;
1065 /* Tries to find a preference, setting containing_module to the (sub)module
1066 * holding this preference. */
1067 static struct preference *
1068 prefs_find_preference_with_submodule(module_t *module, const char *name,
1069 module_t **containing_module)
1071 find_pref_arg_t arg;
1075 return NULL; /* invalid parameters */
1077 list_entry = g_list_find_custom(module->prefs, name,
1079 arg.submodule = NULL;
1081 if (list_entry == NULL)
1083 arg.list_entry = NULL;
1084 if (module->submodules != NULL)
1087 wmem_tree_foreach(module->submodules, module_find_pref_cb, &arg);
1090 list_entry = arg.list_entry;
1093 if (list_entry == NULL)
1094 return NULL; /* no such preference */
1096 if (containing_module)
1097 *containing_module = arg.submodule ? arg.submodule : module;
1099 return (struct preference *) list_entry->data;
1103 prefs_find_preference(module_t *module, const char *name)
1105 return prefs_find_preference_with_submodule(module, name, NULL);
1109 * Returns TRUE if the given protocol has registered preferences
1112 prefs_is_registered_protocol(const char *name)
1114 module_t *m = prefs_find_module(name);
1116 return (m != NULL && !m->obsolete);
1120 * Returns the module title of a registered protocol
1123 prefs_get_title_by_name(const char *name)
1125 module_t *m = prefs_find_module(name);
1127 return (m != NULL && !m->obsolete) ? m->title : NULL;
1131 * Register a preference with an unsigned integral value.
1134 prefs_register_uint_preference(module_t *module, const char *name,
1135 const char *title, const char *description,
1136 guint base, guint *var)
1140 preference = register_preference(module, name, title, description,
1142 preference->varp.uint = var;
1143 preference->default_val.uint = *var;
1144 g_assert(base > 0 && base != 1 && base < 37);
1145 preference->info.base = base;
1149 * XXX Add a prefs_register_{uint16|port}_preference which sets max_value?
1154 * Register a "custom" preference with a unsigned integral value.
1155 * XXX - This should be temporary until we can find a better way
1156 * to do "custom" preferences
1159 prefs_register_uint_custom_preference(module_t *module, const char *name,
1160 const char *title, const char *description,
1161 struct pref_custom_cbs* custom_cbs, guint *var)
1165 preference = register_preference(module, name, title, description,
1168 preference->custom_cbs = *custom_cbs;
1169 preference->varp.uint = var;
1170 preference->default_val.uint = *var;
1174 * Register a preference with an Boolean value.
1177 prefs_register_bool_preference(module_t *module, const char *name,
1178 const char *title, const char *description,
1183 preference = register_preference(module, name, title, description,
1185 preference->varp.boolp = var;
1186 preference->default_val.boolval = *var;
1189 unsigned int prefs_set_bool_value(pref_t *pref, gboolean value, pref_source_t source)
1191 unsigned int changed = 0;
1196 if (pref->default_val.boolval != value) {
1197 pref->default_val.boolval = value;
1198 changed = prefs_get_effect_flags(pref);
1202 if (pref->stashed_val.boolval != value) {
1203 pref->stashed_val.boolval = value;
1204 changed = prefs_get_effect_flags(pref);
1208 if (*pref->varp.boolp != value) {
1209 *pref->varp.boolp = value;
1210 changed = prefs_get_effect_flags(pref);
1214 g_assert_not_reached();
1221 void prefs_invert_bool_value(pref_t *pref, pref_source_t source)
1226 pref->default_val.boolval = !pref->default_val.boolval;
1229 pref->stashed_val.boolval = !pref->stashed_val.boolval;
1232 *pref->varp.boolp = !(*pref->varp.boolp);
1235 g_assert_not_reached();
1240 gboolean prefs_get_bool_value(pref_t *pref, pref_source_t source)
1245 return pref->default_val.boolval;
1248 return pref->stashed_val.boolval;
1251 return *pref->varp.boolp;
1254 g_assert_not_reached();
1262 * Register a preference with an enumerated value.
1265 * XXX Should we get rid of the radio_buttons parameter and make that
1266 * behavior automatic depending on the number of items?
1269 prefs_register_enum_preference(module_t *module, const char *name,
1270 const char *title, const char *description,
1271 gint *var, const enum_val_t *enumvals,
1272 gboolean radio_buttons)
1276 preference = register_preference(module, name, title, description,
1278 preference->varp.enump = var;
1279 preference->default_val.enumval = *var;
1280 preference->info.enum_info.enumvals = enumvals;
1281 preference->info.enum_info.radio_buttons = radio_buttons;
1284 unsigned int prefs_set_enum_value(pref_t *pref, gint value, pref_source_t source)
1286 unsigned int changed = 0;
1291 if (pref->default_val.enumval != value) {
1292 pref->default_val.enumval = value;
1293 changed = prefs_get_effect_flags(pref);
1297 if (pref->stashed_val.enumval != value) {
1298 pref->stashed_val.enumval = value;
1299 changed = prefs_get_effect_flags(pref);
1303 if (*pref->varp.enump != value) {
1304 *pref->varp.enump = value;
1305 changed = prefs_get_effect_flags(pref);
1309 g_assert_not_reached();
1316 gint prefs_get_enum_value(pref_t *pref, pref_source_t source)
1321 return pref->default_val.enumval;
1324 return pref->stashed_val.enumval;
1327 return *pref->varp.enump;
1330 g_assert_not_reached();
1337 const enum_val_t* prefs_get_enumvals(pref_t *pref)
1339 return pref->info.enum_info.enumvals;
1342 gboolean prefs_get_enum_radiobuttons(pref_t *pref)
1344 return pref->info.enum_info.radio_buttons;
1348 register_string_like_preference(module_t *module, const char *name,
1349 const char *title, const char *description,
1350 char **var, int type,
1351 struct pref_custom_cbs* custom_cbs,
1357 pref = register_preference(module, name, title, description, type);
1360 * String preference values should be non-null (as you can't
1361 * keep them null after using the preferences GUI, you can at best
1362 * have them be null strings) and freeable (as we free them
1363 * if we change them).
1365 * If the value is a null pointer, make it a copy of a null
1366 * string, otherwise make it a copy of the value.
1370 *var = g_strdup("");
1372 *var = g_strdup(*var);
1377 pref->varp.string = var;
1378 pref->default_val.string = g_strdup(*var);
1379 pref->stashed_val.string = NULL;
1380 if (type == PREF_CUSTOM) {
1381 g_assert(custom_cbs);
1382 pref->custom_cbs = *custom_cbs;
1387 * For use by UI code that sets preferences.
1390 prefs_set_string_value(pref_t *pref, const char* value, pref_source_t source)
1392 unsigned int changed = 0;
1397 if (*pref->default_val.string) {
1398 if (strcmp(pref->default_val.string, value) != 0) {
1399 changed = prefs_get_effect_flags(pref);
1400 g_free(pref->default_val.string);
1401 pref->default_val.string = g_strdup(value);
1404 pref->default_val.string = g_strdup(value);
1408 if (pref->stashed_val.string) {
1409 if (strcmp(pref->stashed_val.string, value) != 0) {
1410 changed = prefs_get_effect_flags(pref);
1411 g_free(pref->stashed_val.string);
1412 pref->stashed_val.string = g_strdup(value);
1415 pref->stashed_val.string = g_strdup(value);
1419 if (*pref->varp.string) {
1420 if (strcmp(*pref->varp.string, value) != 0) {
1421 changed = prefs_get_effect_flags(pref);
1422 g_free(*pref->varp.string);
1423 *pref->varp.string = g_strdup(value);
1426 *pref->varp.string = g_strdup(value);
1430 g_assert_not_reached();
1437 char* prefs_get_string_value(pref_t *pref, pref_source_t source)
1442 return pref->default_val.string;
1444 return pref->stashed_val.string;
1446 return *pref->varp.string;
1448 g_assert_not_reached();
1456 * Reset the value of a string-like preference.
1459 reset_string_like_preference(pref_t *pref)
1461 g_free(*pref->varp.string);
1462 *pref->varp.string = g_strdup(pref->default_val.string);
1466 * Register a preference with a character-string value.
1469 prefs_register_string_preference(module_t *module, const char *name,
1470 const char *title, const char *description,
1474 register_string_like_preference(module, name, title, description,
1475 (char **)var, PREF_STRING, NULL, FALSE);
1480 * Register a preference with a file name (string) value.
1483 prefs_register_filename_preference(module_t *module, const char *name,
1484 const char *title, const char *description,
1485 const char **var, gboolean for_writing)
1488 register_string_like_preference(module, name, title, description, (char **)var,
1489 for_writing ? PREF_SAVE_FILENAME : PREF_OPEN_FILENAME, NULL, FALSE);
1494 * Register a preference with a directory name (string) value.
1497 prefs_register_directory_preference(module_t *module, const char *name,
1498 const char *title, const char *description,
1502 register_string_like_preference(module, name, title, description,
1503 (char **)var, PREF_DIRNAME, NULL, FALSE);
1507 /* Refactoring to handle both PREF_RANGE and PREF_DECODE_AS_RANGE */
1509 prefs_register_range_preference_common(module_t *module, const char *name,
1510 const char *title, const char *description,
1511 range_t **var, guint32 max_value, int type)
1515 preference = register_preference(module, name, title, description, type);
1516 preference->info.max_value = max_value;
1519 * Range preference values should be non-null (as you can't
1520 * keep them null after using the preferences GUI, you can at best
1521 * have them be empty ranges) and freeable (as we free them
1522 * if we change them).
1524 * If the value is a null pointer, make it an empty range.
1527 *var = range_empty(wmem_epan_scope());
1528 preference->varp.range = var;
1529 preference->default_val.range = range_copy(wmem_epan_scope(), *var);
1530 preference->stashed_val.range = NULL;
1534 * Register a preference with a ranged value.
1537 prefs_register_range_preference(module_t *module, const char *name,
1538 const char *title, const char *description,
1539 range_t **var, guint32 max_value)
1541 prefs_register_range_preference_common(module, name, title,
1542 description, var, max_value, PREF_RANGE);
1546 prefs_set_range_value_work(pref_t *pref, const gchar *value,
1547 gboolean return_range_errors, unsigned int *changed_flags)
1551 if (range_convert_str_work(wmem_epan_scope(), &newrange, value, pref->info.max_value,
1552 return_range_errors) != CVT_NO_ERROR) {
1553 return FALSE; /* number was bad */
1556 if (!ranges_are_equal(*pref->varp.range, newrange)) {
1557 *changed_flags |= prefs_get_effect_flags(pref);
1558 wmem_free(wmem_epan_scope(), *pref->varp.range);
1559 *pref->varp.range = newrange;
1561 wmem_free(wmem_epan_scope(), newrange);
1567 * For use by UI code that sets preferences.
1570 prefs_set_stashed_range_value(pref_t *pref, const gchar *value)
1574 if (range_convert_str_work(wmem_epan_scope(), &newrange, value, pref->info.max_value,
1575 TRUE) != CVT_NO_ERROR) {
1576 return 0; /* number was bad */
1579 if (!ranges_are_equal(pref->stashed_val.range, newrange)) {
1580 wmem_free(wmem_epan_scope(), pref->stashed_val.range);
1581 pref->stashed_val.range = newrange;
1583 wmem_free(wmem_epan_scope(), newrange);
1585 return prefs_get_effect_flags(pref);
1589 gboolean prefs_set_range_value(pref_t *pref, range_t *value, pref_source_t source)
1591 gboolean changed = FALSE;
1596 if (!ranges_are_equal(pref->default_val.range, value)) {
1597 wmem_free(wmem_epan_scope(), pref->default_val.range);
1598 pref->default_val.range = range_copy(wmem_epan_scope(), value);
1603 if (!ranges_are_equal(pref->stashed_val.range, value)) {
1604 wmem_free(wmem_epan_scope(), pref->stashed_val.range);
1605 pref->stashed_val.range = range_copy(wmem_epan_scope(), value);
1610 if (!ranges_are_equal(*pref->varp.range, value)) {
1611 wmem_free(wmem_epan_scope(), *pref->varp.range);
1612 *pref->varp.range = range_copy(wmem_epan_scope(), value);
1617 g_assert_not_reached();
1624 range_t* prefs_get_range_value_real(pref_t *pref, pref_source_t source)
1629 return pref->default_val.range;
1631 return pref->stashed_val.range;
1634 return *pref->varp.range;
1637 g_assert_not_reached();
1644 range_t* prefs_get_range_value(const char *module_name, const char* pref_name)
1646 return prefs_get_range_value_real(prefs_find_preference(prefs_find_module(module_name), pref_name), pref_current);
1650 prefs_range_add_value(pref_t *pref, guint32 val)
1652 range_add_value(wmem_epan_scope(), pref->varp.range, val);
1656 prefs_range_remove_value(pref_t *pref, guint32 val)
1658 range_remove_value(wmem_epan_scope(), pref->varp.range, val);
1662 * Register a static text 'preference'. It can be used to add explanatory
1663 * text inline with other preferences in the GUI.
1664 * Note: Static preferences are not saved to the preferences file.
1667 prefs_register_static_text_preference(module_t *module, const char *name,
1669 const char *description)
1671 register_preference(module, name, title, description, PREF_STATIC_TEXT);
1675 * Register a uat 'preference'. It adds a button that opens the uat's window in the
1676 * preferences tab of the module.
1679 prefs_register_uat_preference(module_t *module, const char *name,
1680 const char *title, const char *description,
1684 pref_t* preference = register_preference(module, name, title, description, PREF_UAT);
1686 preference->varp.uat = uat;
1690 * Register a uat 'preference' for QT only. It adds a button that opens the uat's window in the
1691 * preferences tab of the module.
1694 prefs_register_uat_preference_qt(module_t *module, const char *name,
1695 const char *title, const char *description,
1699 pref_t* preference = register_preference(module, name, title, description, PREF_UAT);
1701 preference->varp.uat = uat;
1703 preference->gui = GUI_QT;
1706 struct epan_uat* prefs_get_uat_value(pref_t *pref)
1708 return pref->varp.uat;
1712 * Register a color preference.
1715 prefs_register_color_preference(module_t *module, const char *name,
1716 const char *title, const char *description,
1719 pref_t* preference = register_preference(module, name, title, description, PREF_COLOR);
1721 preference->varp.colorp = color;
1722 preference->default_val.color = *color;
1725 gboolean prefs_set_color_value(pref_t *pref, color_t value, pref_source_t source)
1727 gboolean changed = FALSE;
1732 if ((pref->default_val.color.red != value.red) &&
1733 (pref->default_val.color.green != value.green) &&
1734 (pref->default_val.color.blue != value.blue)) {
1736 pref->default_val.color = value;
1740 if ((pref->stashed_val.color.red != value.red) &&
1741 (pref->stashed_val.color.green != value.green) &&
1742 (pref->stashed_val.color.blue != value.blue)) {
1744 pref->stashed_val.color = value;
1748 if ((pref->varp.colorp->red != value.red) &&
1749 (pref->varp.colorp->green != value.green) &&
1750 (pref->varp.colorp->blue != value.blue)) {
1752 *pref->varp.colorp = value;
1756 g_assert_not_reached();
1763 color_t* prefs_get_color_value(pref_t *pref, pref_source_t source)
1768 return &pref->default_val.color;
1770 return &pref->stashed_val.color;
1773 return pref->varp.colorp;
1776 g_assert_not_reached();
1784 * Register a "custom" preference with a list.
1785 * XXX - This should be temporary until we can find a better way
1786 * to do "custom" preferences
1788 typedef void (*pref_custom_list_init_cb) (pref_t* pref, GList** value);
1791 prefs_register_list_custom_preference(module_t *module, const char *name,
1792 const char *title, const char *description,
1793 struct pref_custom_cbs* custom_cbs,
1794 pref_custom_list_init_cb init_cb,
1797 pref_t* preference = register_preference(module, name, title, description, PREF_CUSTOM);
1799 preference->custom_cbs = *custom_cbs;
1800 init_cb(preference, list);
1804 * Register a custom preference.
1807 prefs_register_custom_preference(module_t *module, const char *name,
1808 const char *title, const char *description,
1809 struct pref_custom_cbs* custom_cbs,
1810 void **custom_data _U_)
1812 pref_t* preference = register_preference(module, name, title, description, PREF_CUSTOM);
1814 preference->custom_cbs = *custom_cbs;
1815 /* XXX - wait until we can handle void** pointers
1816 preference->custom_cbs.init_cb(preference, custom_data);
1821 * Register a (internal) "Decode As" preference with a ranged value.
1823 void prefs_register_decode_as_range_preference(module_t *module, const char *name,
1824 const char *title, const char *description, range_t **var,
1827 prefs_register_range_preference_common(module, name, title,
1828 description, var, max_value, PREF_DECODE_AS_RANGE);
1832 * Register a (internal) "Decode As" preference with an unsigned integral value
1833 * for a dissector table.
1835 void prefs_register_decode_as_preference(module_t *module, const char *name,
1836 const char *title, const char *description, guint *var)
1840 preference = register_preference(module, name, title, description,
1841 PREF_DECODE_AS_UINT);
1842 preference->varp.uint = var;
1843 preference->default_val.uint = *var;
1844 /* XXX - Presume base 10 for now */
1845 preference->info.base = 10;
1848 gboolean prefs_add_decode_as_value(pref_t *pref, guint value, gboolean replace)
1852 case PREF_DECODE_AS_UINT:
1853 /* This doesn't support multiple values for a dissector in Decode As because the
1854 preference only supports a single value. This leads to a "last port for
1855 dissector in Decode As wins" */
1856 *pref->varp.uint = value;
1858 case PREF_DECODE_AS_RANGE:
1861 /* If range has single value, replace it */
1862 if (((*pref->varp.range)->nranges == 1) &&
1863 ((*pref->varp.range)->ranges[0].low == (*pref->varp.range)->ranges[0].high)) {
1864 wmem_free(wmem_epan_scope(), *pref->varp.range);
1865 *pref->varp.range = range_empty(wmem_epan_scope());
1869 prefs_range_add_value(pref, value);
1872 /* XXX - Worth asserting over? */
1879 gboolean prefs_remove_decode_as_value(pref_t *pref, guint value, gboolean set_default)
1883 case PREF_DECODE_AS_UINT:
1885 *pref->varp.uint = pref->default_val.uint;
1887 *pref->varp.uint = 0;
1890 case PREF_DECODE_AS_RANGE:
1891 prefs_range_remove_value(pref, value);
1901 * Register a preference that used to be supported but no longer is.
1904 prefs_register_obsolete_preference(module_t *module, const char *name)
1906 register_preference(module, name, NULL, NULL, PREF_OBSOLETE);
1910 * Check to see if a preference is obsolete.
1913 prefs_get_preference_obsolete(pref_t *pref)
1916 return (IS_PREF_OBSOLETE(pref->type) ? TRUE : FALSE);
1922 * Make a preference obsolete.
1924 extern prefs_set_pref_e
1925 prefs_set_preference_obsolete(pref_t *pref)
1928 SET_PREF_OBSOLETE(pref->type);
1929 return PREFS_SET_OK;
1931 return PREFS_SET_NO_SUCH_PREF;
1935 pref_stash(pref_t *pref, gpointer unused _U_)
1937 switch (pref->type) {
1939 case PREF_DECODE_AS_UINT:
1940 pref->stashed_val.uint = *pref->varp.uint;
1944 pref->stashed_val.uint = *pref->varp.uint;
1948 pref->stashed_val.boolval = *pref->varp.boolp;
1952 pref->stashed_val.enumval = *pref->varp.enump;
1956 case PREF_SAVE_FILENAME:
1957 case PREF_OPEN_FILENAME:
1959 g_free(pref->stashed_val.string);
1960 pref->stashed_val.string = g_strdup(*pref->varp.string);
1963 case PREF_DECODE_AS_RANGE:
1965 wmem_free(wmem_epan_scope(), pref->stashed_val.range);
1966 pref->stashed_val.range = range_copy(wmem_epan_scope(), *pref->varp.range);
1970 pref->stashed_val.color = *pref->varp.colorp;
1973 case PREF_STATIC_TEXT:
1979 g_assert_not_reached();
1986 pref_unstash(pref_t *pref, gpointer unstash_data_p)
1988 pref_unstash_data_t *unstash_data = (pref_unstash_data_t *)unstash_data_p;
1989 dissector_table_t sub_dissectors = NULL;
1990 dissector_handle_t handle = NULL;
1992 /* Revert the preference to its saved value. */
1993 switch (pref->type) {
1995 case PREF_DECODE_AS_UINT:
1996 if (*pref->varp.uint != pref->stashed_val.uint) {
1997 unstash_data->module->prefs_changed_flags |= prefs_get_effect_flags(pref);
1999 if (unstash_data->handle_decode_as) {
2000 if (*pref->varp.uint != pref->default_val.uint) {
2001 dissector_reset_uint(pref->name, *pref->varp.uint);
2005 *pref->varp.uint = pref->stashed_val.uint;
2007 if (unstash_data->handle_decode_as) {
2008 sub_dissectors = find_dissector_table(pref->name);
2009 if (sub_dissectors != NULL) {
2010 handle = dissector_table_get_dissector_handle(sub_dissectors, (gchar*)unstash_data->module->title);
2011 if (handle != NULL) {
2012 dissector_change_uint(pref->name, *pref->varp.uint, handle);
2020 if (*pref->varp.uint != pref->stashed_val.uint) {
2021 unstash_data->module->prefs_changed_flags |= prefs_get_effect_flags(pref);
2022 *pref->varp.uint = pref->stashed_val.uint;
2027 if (*pref->varp.boolp != pref->stashed_val.boolval) {
2028 unstash_data->module->prefs_changed_flags |= prefs_get_effect_flags(pref);
2029 *pref->varp.boolp = pref->stashed_val.boolval;
2034 if (*pref->varp.enump != pref->stashed_val.enumval) {
2035 unstash_data->module->prefs_changed_flags |= prefs_get_effect_flags(pref);
2036 *pref->varp.enump = pref->stashed_val.enumval;
2041 case PREF_SAVE_FILENAME:
2042 case PREF_OPEN_FILENAME:
2044 if (strcmp(*pref->varp.string, pref->stashed_val.string) != 0) {
2045 unstash_data->module->prefs_changed_flags |= prefs_get_effect_flags(pref);
2046 g_free(*pref->varp.string);
2047 *pref->varp.string = g_strdup(pref->stashed_val.string);
2051 case PREF_DECODE_AS_RANGE:
2052 if (!ranges_are_equal(*pref->varp.range, pref->stashed_val.range)) {
2054 unstash_data->module->prefs_changed_flags |= prefs_get_effect_flags(pref);
2056 if (unstash_data->handle_decode_as) {
2057 sub_dissectors = find_dissector_table(pref->name);
2058 if (sub_dissectors != NULL) {
2059 handle = dissector_table_get_dissector_handle(sub_dissectors, (gchar*)unstash_data->module->title);
2060 if (handle != NULL) {
2061 /* Delete all of the old values from the dissector table */
2062 for (i = 0; i < (*pref->varp.range)->nranges; i++) {
2063 for (j = (*pref->varp.range)->ranges[i].low; j < (*pref->varp.range)->ranges[i].high; j++) {
2064 dissector_delete_uint(pref->name, j, handle);
2065 decode_build_reset_list(pref->name, dissector_table_get_type(sub_dissectors), GUINT_TO_POINTER(j), NULL, NULL);
2068 dissector_delete_uint(pref->name, (*pref->varp.range)->ranges[i].high, handle);
2069 decode_build_reset_list(pref->name, dissector_table_get_type(sub_dissectors), GUINT_TO_POINTER((*pref->varp.range)->ranges[i].high), NULL, NULL);
2075 wmem_free(wmem_epan_scope(), *pref->varp.range);
2076 *pref->varp.range = range_copy(wmem_epan_scope(), pref->stashed_val.range);
2078 if (unstash_data->handle_decode_as) {
2079 if ((sub_dissectors != NULL) && (handle != NULL)) {
2081 /* Add new values to the dissector table */
2082 for (i = 0; i < (*pref->varp.range)->nranges; i++) {
2084 for (j = (*pref->varp.range)->ranges[i].low; j < (*pref->varp.range)->ranges[i].high; j++) {
2085 dissector_change_uint(pref->name, j, handle);
2086 decode_build_reset_list(pref->name, dissector_table_get_type(sub_dissectors), GUINT_TO_POINTER(j), NULL, NULL);
2089 dissector_change_uint(pref->name, (*pref->varp.range)->ranges[i].high, handle);
2090 decode_build_reset_list(pref->name, dissector_table_get_type(sub_dissectors), GUINT_TO_POINTER((*pref->varp.range)->ranges[i].high), NULL, NULL);
2098 if (!ranges_are_equal(*pref->varp.range, pref->stashed_val.range)) {
2099 unstash_data->module->prefs_changed_flags |= prefs_get_effect_flags(pref);
2100 wmem_free(wmem_epan_scope(), *pref->varp.range);
2101 *pref->varp.range = range_copy(wmem_epan_scope(), pref->stashed_val.range);
2106 if ((pref->varp.colorp->blue != pref->stashed_val.color.blue) ||
2107 (pref->varp.colorp->red != pref->stashed_val.color.red) ||
2108 (pref->varp.colorp->green != pref->stashed_val.color.green)) {
2109 unstash_data->module->prefs_changed_flags |= prefs_get_effect_flags(pref);
2110 *pref->varp.colorp = pref->stashed_val.color;
2114 case PREF_STATIC_TEXT:
2120 g_assert_not_reached();
2127 reset_stashed_pref(pref_t *pref) {
2128 switch (pref->type) {
2130 case PREF_DECODE_AS_UINT:
2131 pref->stashed_val.uint = pref->default_val.uint;
2135 pref->stashed_val.uint = pref->default_val.uint;
2139 pref->stashed_val.boolval = pref->default_val.boolval;
2143 pref->stashed_val.enumval = pref->default_val.enumval;
2147 case PREF_SAVE_FILENAME:
2148 case PREF_OPEN_FILENAME:
2150 g_free(pref->stashed_val.string);
2151 pref->stashed_val.string = g_strdup(pref->default_val.string);
2154 case PREF_DECODE_AS_RANGE:
2156 wmem_free(wmem_epan_scope(), pref->stashed_val.range);
2157 pref->stashed_val.range = range_copy(wmem_epan_scope(), pref->default_val.range);
2161 memcpy(&pref->stashed_val.color, &pref->default_val.color, sizeof(color_t));
2164 case PREF_STATIC_TEXT:
2170 g_assert_not_reached();
2176 pref_clean_stash(pref_t *pref, gpointer unused _U_)
2178 switch (pref->type) {
2181 case PREF_DECODE_AS_UINT:
2191 case PREF_SAVE_FILENAME:
2192 case PREF_OPEN_FILENAME:
2194 if (pref->stashed_val.string != NULL) {
2195 g_free(pref->stashed_val.string);
2196 pref->stashed_val.string = NULL;
2200 case PREF_DECODE_AS_RANGE:
2202 if (pref->stashed_val.range != NULL) {
2203 wmem_free(wmem_epan_scope(), pref->stashed_val.range);
2204 pref->stashed_val.range = NULL;
2208 case PREF_STATIC_TEXT:
2215 g_assert_not_reached();
2222 /* Return the value assigned to the given uint preference. */
2224 prefs_get_uint_preference(pref_t *pref)
2226 if (pref && pref->type == PREF_UINT)
2227 return *pref->varp.uint;
2233 * Call a callback function, with a specified argument, for each preference
2234 * in a given module.
2236 * If any of the callbacks return a non-zero value, stop and return that
2237 * value, otherwise return 0.
2240 prefs_pref_foreach(module_t *module, pref_cb callback, gpointer user_data)
2246 for (elem = g_list_first(module->prefs); elem != NULL; elem = g_list_next(elem)) {
2247 pref = (pref_t *)elem->data;
2248 if (IS_PREF_OBSOLETE(pref->type)) {
2250 * This preference is no longer supported; it's
2251 * not a real preference, so we don't call the
2252 * callback for it (i.e., we treat it as if it
2253 * weren't found in the list of preferences,
2254 * and we weren't called in the first place).
2259 ret = (*callback)(pref, user_data);
2266 static const enum_val_t print_format_vals[] = {
2267 { "text", "Plain Text", PR_FMT_TEXT },
2268 { "postscript", "Postscript", PR_FMT_PS },
2272 static const enum_val_t print_dest_vals[] = {
2274 /* "PR_DEST_CMD" means "to printer" on Windows */
2275 { "command", "Printer", PR_DEST_CMD },
2277 { "command", "Command", PR_DEST_CMD },
2279 { "file", "File", PR_DEST_FILE },
2283 static const enum_val_t st_sort_col_vals[] = {
2284 { "name", "Node name (topic/item)", ST_SORT_COL_NAME },
2285 { "count", "Item count", ST_SORT_COL_COUNT },
2286 { "average", "Average value of the node", ST_SORT_COL_AVG },
2287 { "min", "Minimum value of the node", ST_SORT_COL_MIN },
2288 { "max", "Maximum value of the node", ST_SORT_COL_MAX },
2289 { "burst", "Burst rate of the node", ST_SORT_COL_BURSTRATE },
2294 stats_callback(void)
2296 /* Test for a sane tap update interval */
2297 if (prefs.tap_update_interval < 100 || prefs.tap_update_interval > 10000)
2298 prefs.tap_update_interval = TAP_UPDATE_DEFAULT_INTERVAL;
2300 #ifdef HAVE_LIBPORTAUDIO
2301 /* Test for a sane max channels entry */
2302 if (prefs.rtp_player_max_visible < 1 || prefs.rtp_player_max_visible > 10)
2303 prefs.rtp_player_max_visible = RTP_PLAYER_DEFAULT_VISIBLE;
2306 /* burst resolution can't be less than 1 (ms) */
2307 if (prefs.st_burst_resolution < 1) {
2308 prefs.st_burst_resolution = 1;
2310 else if (prefs.st_burst_resolution > ST_MAX_BURSTRES) {
2311 prefs.st_burst_resolution = ST_MAX_BURSTRES;
2313 /* make sure burst window value makes sense */
2314 if (prefs.st_burst_windowlen < prefs.st_burst_resolution) {
2315 prefs.st_burst_windowlen = prefs.st_burst_resolution;
2317 /* round burst window down to multiple of resolution */
2318 prefs.st_burst_windowlen -= prefs.st_burst_windowlen%prefs.st_burst_resolution;
2319 if ((prefs.st_burst_windowlen/prefs.st_burst_resolution) > ST_MAX_BURSTBUCKETS) {
2320 prefs.st_burst_windowlen = prefs.st_burst_resolution*ST_MAX_BURSTBUCKETS;
2327 /* Ensure there is at least one file count */
2328 if (prefs.gui_recent_files_count_max == 0)
2329 prefs.gui_recent_files_count_max = 10;
2331 /* Ensure there is at least one display filter entry */
2332 if (prefs.gui_recent_df_entries_max == 0)
2333 prefs.gui_recent_df_entries_max = 10;
2337 gui_layout_callback(void)
2339 if (prefs.gui_layout_type == layout_unused ||
2340 prefs.gui_layout_type >= layout_type_max) {
2341 /* XXX - report an error? It's not a syntax error - we'd need to
2342 add a way of reporting a *semantic* error. */
2343 prefs.gui_layout_type = layout_type_5;
2347 /******************************************************
2348 * All custom preference function callbacks
2349 ******************************************************/
2350 static void custom_pref_no_cb(pref_t* pref _U_) {}
2354 * Console log level custom preference functions
2357 console_log_level_reset_cb(pref_t* pref)
2359 *pref->varp.uint = pref->default_val.uint;
2362 static prefs_set_pref_e
2363 console_log_level_set_cb(pref_t* pref, const gchar* value, unsigned int* changed_flags)
2367 uval = (guint)strtoul(value, NULL, 10);
2369 if (*pref->varp.uint != uval) {
2370 *changed_flags = prefs_get_effect_flags(pref);
2371 *pref->varp.uint = uval;
2374 if (*pref->varp.uint & (G_LOG_LEVEL_INFO|G_LOG_LEVEL_DEBUG)) {
2376 * GLib >= 2.32 drops INFO and DEBUG messages by default. Tell
2377 * it not to do that.
2379 g_setenv("G_MESSAGES_DEBUG", "all", TRUE);
2382 return PREFS_SET_OK;
2385 static const char * console_log_level_type_name_cb(void) {
2389 static char * console_log_level_type_description_cb(void) {
2390 return g_strdup_printf(
2391 "Console log level (for debugging)\n"
2392 "A bitmask of log levels:\n"
2401 static gboolean console_log_level_is_default_cb(pref_t* pref) {
2402 return *pref->varp.uint == pref->default_val.uint;
2405 static char * console_log_level_to_str_cb(pref_t* pref, gboolean default_val) {
2406 return g_strdup_printf("%u", default_val ? pref->default_val.uint : *pref->varp.uint);
2410 * Column preference functions
2412 #define PRS_COL_HIDDEN "column.hidden"
2413 #define PRS_COL_FMT "column.format"
2414 #define PRS_COL_NUM "column.number"
2415 static module_t *gui_column_module = NULL;
2417 static prefs_set_pref_e
2418 column_hidden_set_cb(pref_t* pref, const gchar* value, unsigned int* changed_flags)
2422 pref_t *format_pref;
2424 (*changed_flags) |= prefs_set_string_value(pref, value, pref_current);
2427 * Set the "visible" flag for the existing columns; we need to
2428 * do this if we set PRS_COL_HIDDEN but don't set PRS_COL_FMT
2429 * after setting it (which might be the case if, for example, we
2430 * set PRS_COL_HIDDEN on the command line).
2432 format_pref = prefs_find_preference(gui_column_module, PRS_COL_FMT);
2433 for (clp = *format_pref->varp.list; clp != NULL; clp = clp->next) {
2434 cfmt = (fmt_data *)clp->data;
2435 cfmt->visible = prefs_is_column_visible(*pref->varp.string, cfmt);
2438 return PREFS_SET_OK;
2442 column_hidden_type_name_cb(void)
2444 return "Packet list hidden columns";
2448 column_hidden_type_description_cb(void)
2450 return g_strdup("List all columns to hide in the packet list.");
2454 column_hidden_to_str_cb(pref_t* pref, gboolean default_val)
2456 GString *cols_hidden = g_string_new ("");
2459 pref_t *format_pref;
2462 return g_strdup(pref->default_val.string);
2464 format_pref = prefs_find_preference(gui_column_module, PRS_COL_FMT);
2465 clp = (format_pref) ? *format_pref->varp.list : NULL;
2468 cfmt = (fmt_data *) clp->data;
2469 if ((cfmt->fmt == COL_CUSTOM) && (cfmt->custom_fields)) {
2470 prefs_fmt = g_strdup_printf("%s:%s:%d:%c",
2471 col_format_to_string(cfmt->fmt),
2472 cfmt->custom_fields,
2473 cfmt->custom_occurrence,
2474 cfmt->resolved ? 'R' : 'U');
2476 prefs_fmt = g_strdup(col_format_to_string(cfmt->fmt));
2478 if (!cfmt->visible) {
2479 if (cols_hidden->len)
2480 g_string_append (cols_hidden, ",");
2481 g_string_append (cols_hidden, prefs_fmt);
2487 return g_string_free (cols_hidden, FALSE);
2491 column_hidden_is_default_cb(pref_t* pref)
2493 char *cur_hidden_str = column_hidden_to_str_cb(pref, FALSE);
2494 gboolean is_default = g_strcmp0(cur_hidden_str, pref->default_val.string) == 0;
2496 g_free(cur_hidden_str);
2501 /* Number of columns "preference". This is only used internally and is not written to the
2505 column_num_reset_cb(pref_t* pref)
2507 *pref->varp.uint = pref->default_val.uint;
2510 static prefs_set_pref_e
2511 column_num_set_cb(pref_t* pref _U_, const gchar* value _U_, unsigned int* changed_flags _U_)
2513 /* Don't write this to the preferences file */
2514 return PREFS_SET_OK;
2518 column_num_type_name_cb(void)
2524 column_num_type_description_cb(void)
2526 return g_strdup("");
2530 column_num_is_default_cb(pref_t* pref _U_)
2536 column_num_to_str_cb(pref_t* pref _U_, gboolean default_val _U_)
2538 return g_strdup("");
2542 * Column format custom preference functions
2545 column_format_init_cb(pref_t* pref, GList** value)
2547 fmt_data *src_cfmt, *dest_cfmt;
2550 pref->varp.list = value;
2552 pref->default_val.list = NULL;
2553 for (entry = *pref->varp.list; entry != NULL; entry = g_list_next(entry)) {
2554 src_cfmt = (fmt_data *)entry->data;
2555 dest_cfmt = g_new(fmt_data,1);
2556 dest_cfmt->title = g_strdup(src_cfmt->title);
2557 dest_cfmt->fmt = src_cfmt->fmt;
2558 if (src_cfmt->custom_fields) {
2559 dest_cfmt->custom_fields = g_strdup(src_cfmt->custom_fields);
2560 dest_cfmt->custom_occurrence = src_cfmt->custom_occurrence;
2562 dest_cfmt->custom_fields = NULL;
2563 dest_cfmt->custom_occurrence = 0;
2565 dest_cfmt->visible = src_cfmt->visible;
2566 dest_cfmt->resolved = src_cfmt->resolved;
2567 pref->default_val.list = g_list_append(pref->default_val.list, dest_cfmt);
2572 column_format_free_cb(pref_t* pref)
2574 free_col_info(*pref->varp.list);
2575 free_col_info(pref->default_val.list);
2579 column_format_reset_cb(pref_t* pref)
2581 fmt_data *src_cfmt, *dest_cfmt;
2583 pref_t *col_num_pref;
2585 free_col_info(*pref->varp.list);
2586 *pref->varp.list = NULL;
2588 for (entry = pref->default_val.list; entry != NULL; entry = g_list_next(entry)) {
2589 src_cfmt = (fmt_data *)entry->data;
2590 dest_cfmt = g_new(fmt_data,1);
2591 dest_cfmt->title = g_strdup(src_cfmt->title);
2592 dest_cfmt->fmt = src_cfmt->fmt;
2593 if (src_cfmt->custom_fields) {
2594 dest_cfmt->custom_fields = g_strdup(src_cfmt->custom_fields);
2595 dest_cfmt->custom_occurrence = src_cfmt->custom_occurrence;
2597 dest_cfmt->custom_fields = NULL;
2598 dest_cfmt->custom_occurrence = 0;
2600 dest_cfmt->visible = src_cfmt->visible;
2601 dest_cfmt->resolved = src_cfmt->resolved;
2602 *pref->varp.list = g_list_append(*pref->varp.list, dest_cfmt);
2605 col_num_pref = prefs_find_preference(gui_column_module, PRS_COL_NUM);
2606 g_assert(col_num_pref != NULL); /* Should never happen */
2607 column_num_reset_cb(col_num_pref);
2610 static prefs_set_pref_e
2611 column_format_set_cb(pref_t* pref, const gchar* value, unsigned int* changed_flags _U_)
2613 GList *col_l, *col_l_elt;
2616 pref_t *hidden_pref, *col_num_pref;
2618 col_l = prefs_get_string_list(value);
2620 return PREFS_SET_SYNTAX_ERR;
2621 if ((g_list_length(col_l) % 2) != 0) {
2622 /* A title didn't have a matching format. */
2623 prefs_clear_string_list(col_l);
2624 return PREFS_SET_SYNTAX_ERR;
2626 /* Check to make sure all column formats are valid. */
2627 col_l_elt = g_list_first(col_l);
2629 fmt_data cfmt_check;
2631 /* Go past the title. */
2632 col_l_elt = col_l_elt->next;
2634 /* Parse the format to see if it's valid. */
2635 if (!parse_column_format(&cfmt_check, (char *)col_l_elt->data)) {
2636 /* It's not a valid column format. */
2637 prefs_clear_string_list(col_l);
2638 return PREFS_SET_SYNTAX_ERR;
2640 if (cfmt_check.fmt != COL_CUSTOM) {
2641 /* Some predefined columns have been migrated to use custom columns.
2642 * We'll convert these silently here */
2643 try_convert_to_custom_column(&col_l_elt->data);
2645 /* We don't need the custom column field on this pass. */
2646 g_free(cfmt_check.custom_fields);
2649 /* Go past the format. */
2650 col_l_elt = col_l_elt->next;
2653 /* They're all valid; process them. */
2654 free_col_info(*pref->varp.list);
2655 *pref->varp.list = NULL;
2656 hidden_pref = prefs_find_preference(gui_column_module, PRS_COL_HIDDEN);
2657 g_assert(hidden_pref != NULL); /* Should never happen */
2658 col_num_pref = prefs_find_preference(gui_column_module, PRS_COL_NUM);
2659 g_assert(col_num_pref != NULL); /* Should never happen */
2660 llen = g_list_length(col_l);
2661 *col_num_pref->varp.uint = llen / 2;
2662 col_l_elt = g_list_first(col_l);
2664 cfmt = g_new(fmt_data,1);
2665 cfmt->title = g_strdup((gchar *)col_l_elt->data);
2666 col_l_elt = col_l_elt->next;
2667 parse_column_format(cfmt, (char *)col_l_elt->data);
2668 cfmt->visible = prefs_is_column_visible(*hidden_pref->varp.string, cfmt);
2669 col_l_elt = col_l_elt->next;
2670 *pref->varp.list = g_list_append(*pref->varp.list, cfmt);
2673 prefs_clear_string_list(col_l);
2674 free_string_like_preference(hidden_pref);
2675 return PREFS_SET_OK;
2680 column_format_type_name_cb(void)
2682 return "Packet list column format";
2686 column_format_type_description_cb(void)
2688 return g_strdup("Each pair of strings consists of a column title and its format");
2692 column_format_is_default_cb(pref_t* pref)
2694 GList *clp = *pref->varp.list,
2695 *pref_col = g_list_first(clp),
2696 *def_col = g_list_first(pref->default_val.list);
2697 fmt_data *cfmt, *def_cfmt;
2698 gboolean is_default = TRUE;
2699 pref_t *col_num_pref;
2701 /* See if the column data has changed from the default */
2702 col_num_pref = prefs_find_preference(gui_column_module, PRS_COL_NUM);
2703 if (col_num_pref && *col_num_pref->varp.uint != col_num_pref->default_val.uint) {
2706 while (pref_col && def_col) {
2707 cfmt = (fmt_data *) pref_col->data;
2708 def_cfmt = (fmt_data *) def_col->data;
2709 if ((g_strcmp0(cfmt->title, def_cfmt->title) != 0) ||
2710 (cfmt->fmt != def_cfmt->fmt) ||
2711 (((cfmt->fmt == COL_CUSTOM) && (cfmt->custom_fields)) &&
2712 ((g_strcmp0(cfmt->custom_fields, def_cfmt->custom_fields) != 0) ||
2713 (cfmt->resolved != def_cfmt->resolved)))) {
2718 pref_col = pref_col->next;
2719 def_col = def_col->next;
2727 column_format_to_str_cb(pref_t* pref, gboolean default_val)
2729 GList *pref_l = default_val ? pref->default_val.list : *pref->varp.list;
2730 GList *clp = g_list_first(pref_l);
2734 char *column_format_str;
2738 cfmt = (fmt_data *) clp->data;
2739 col_l = g_list_append(col_l, g_strdup(cfmt->title));
2740 if ((cfmt->fmt == COL_CUSTOM) && (cfmt->custom_fields)) {
2741 prefs_fmt = g_strdup_printf("%s:%s:%d:%c",
2742 col_format_to_string(cfmt->fmt),
2743 cfmt->custom_fields,
2744 cfmt->custom_occurrence,
2745 cfmt->resolved ? 'R' : 'U');
2747 prefs_fmt = g_strdup(col_format_to_string(cfmt->fmt));
2749 col_l = g_list_append(col_l, prefs_fmt);
2753 column_format_str = join_string_list(col_l);
2754 prefs_clear_string_list(col_l);
2755 return column_format_str;
2759 /****** Capture column custom preference functions ******/
2761 /* This routine is only called when Wireshark is started, NOT when another profile is selected.
2762 Copy the pref->capture_columns list (just loaded with the capture_cols[] struct values)
2763 to prefs->default_val.list.
2766 capture_column_init_cb(pref_t* pref, GList** capture_cols_values)
2768 GList *ccv_list = *capture_cols_values,
2773 dlist = g_list_append(dlist, g_strdup((gchar *)ccv_list->data));
2774 ccv_list = ccv_list->next;
2777 pref->default_val.list = dlist;
2778 pref->varp.list = &prefs.capture_columns;
2779 pref->stashed_val.boolval = FALSE;
2782 /* Free the prefs->capture_columns list strings and remove the list entries.
2783 Note that since pref->varp.list points to &prefs.capture_columns, it is
2787 capture_column_free_cb(pref_t* pref)
2789 prefs_clear_string_list(prefs.capture_columns);
2790 prefs.capture_columns = NULL;
2792 if (pref->stashed_val.boolval == TRUE) {
2793 prefs_clear_string_list(pref->default_val.list);
2794 pref->default_val.list = NULL;
2798 /* Copy pref->default_val.list to *pref->varp.list.
2801 capture_column_reset_cb(pref_t* pref)
2803 GList *vlist = NULL, *dlist;
2805 /* Free the column name strings and remove the links from *pref->varp.list */
2806 prefs_clear_string_list(*pref->varp.list);
2808 for (dlist = pref->default_val.list; dlist != NULL; dlist = g_list_next(dlist)) {
2809 vlist = g_list_append(vlist, g_strdup((gchar *)dlist->data));
2811 *pref->varp.list = vlist;
2814 static prefs_set_pref_e
2815 capture_column_set_cb(pref_t* pref, const gchar* value, unsigned int* changed_flags _U_)
2817 GList *col_l = prefs_get_string_list(value);
2823 return PREFS_SET_SYNTAX_ERR;
2825 capture_column_free_cb(pref);
2827 /* If value (the list of capture.columns read from preferences) is empty, set capture.columns
2828 to the full list of valid capture column names. */
2829 col_l_elt = g_list_first(col_l);
2830 if (!(*(gchar *)col_l_elt->data)) {
2831 for (i = 0; i < num_capture_cols; i++) {
2832 col_name = g_strdup(capture_cols[i]);
2833 prefs.capture_columns = g_list_append(prefs.capture_columns, col_name);
2837 /* Verify that all the column names are valid. If not, use the entire list of valid columns.
2840 gboolean found_match = FALSE;
2841 col_name = (gchar *)col_l_elt->data;
2843 for (i = 0; i < num_capture_cols; i++) {
2844 if (strcmp(col_name, capture_cols[i])==0) {
2850 /* One or more cols are invalid so use the entire list of valid cols. */
2851 for (i = 0; i < num_capture_cols; i++) {
2852 col_name = g_strdup(capture_cols[i]);
2853 prefs.capture_columns = g_list_append(prefs.capture_columns, col_name);
2855 pref->varp.list = &prefs.capture_columns;
2856 prefs_clear_string_list(col_l);
2857 return PREFS_SET_SYNTAX_ERR;
2859 col_l_elt = col_l_elt->next;
2862 col_l_elt = g_list_first(col_l);
2864 col_name = (gchar *)col_l_elt->data;
2865 prefs.capture_columns = g_list_append(prefs.capture_columns, col_name);
2866 col_l_elt = col_l_elt->next;
2868 pref->varp.list = &prefs.capture_columns;
2870 return PREFS_SET_OK;
2875 capture_column_type_name_cb(void)
2877 return "Column list";
2881 capture_column_type_description_cb(void)
2884 "List of columns to be displayed in the capture options dialog.\n"
2885 CAPTURE_COL_TYPE_DESCRIPTION);
2889 capture_column_is_default_cb(pref_t* pref)
2891 GList *pref_col = g_list_first(prefs.capture_columns),
2892 *def_col = g_list_first(pref->default_val.list);
2893 gboolean is_default = TRUE;
2895 /* See if the column data has changed from the default */
2896 while (pref_col && def_col) {
2897 if (strcmp((gchar *)pref_col->data, (gchar *)def_col->data) != 0) {
2901 pref_col = pref_col->next;
2902 def_col = def_col->next;
2905 /* Ensure the same column count */
2906 if (((pref_col == NULL) && (def_col != NULL)) ||
2907 ((pref_col != NULL) && (def_col == NULL)))
2914 capture_column_to_str_cb(pref_t* pref, gboolean default_val)
2917 GList *pref_l = default_val ? pref->default_val.list : prefs.capture_columns;
2918 GList *clp = g_list_first(pref_l);
2919 GList *col_l = NULL;
2921 char *capture_column_str;
2924 col = (gchar *) clp->data;
2925 col_l = g_list_append(col_l, g_strdup(col));
2929 capture_column_str = join_string_list(col_l);
2930 prefs_clear_string_list(col_l);
2931 return capture_column_str;
2934 static prefs_set_pref_e
2935 colorized_frame_set_cb(pref_t* pref, const gchar* value, unsigned int* changed_flags)
2937 (*changed_flags) |= prefs_set_string_value(pref, value, pref_current);
2938 return PREFS_SET_OK;
2942 colorized_frame_type_name_cb(void)
2944 /* Don't write the colors of the 10 easy-access-colorfilters to the preferences
2945 * file until the colors can be changed in the GUI. Currently this is not really
2946 * possible since the STOCK-icons for these colors are hardcoded.
2948 * XXX Find a way to change the colors of the STOCK-icons on the fly and then
2949 * add these 10 colors to the list of colors that can be changed through
2957 colorized_frame_type_description_cb(void)
2959 return g_strdup("");
2963 colorized_frame_is_default_cb(pref_t* pref _U_)
2969 colorized_frame_to_str_cb(pref_t* pref _U_, gboolean default_val _U_)
2971 return g_strdup("");
2975 * Register all non-dissector modules' preferences.
2977 static module_t *gui_module = NULL;
2978 static module_t *gui_color_module = NULL;
2979 static module_t *nameres_module = NULL;
2982 prefs_register_modules(void)
2984 module_t *printing, *capture_module, *console_module,
2985 *gui_layout_module, *gui_font_module;
2987 module_t *extcap_module;
2990 struct pref_custom_cbs custom_cbs;
2992 if (protocols_module != NULL) {
2993 /* Already setup preferences */
2999 * These are "simple" GUI preferences that can be read/written using the
3000 * preference module API. These preferences still use their own
3001 * configuration screens for access, but this cuts down on the
3002 * preference "string compare list" in set_pref()
3004 extcap_module = prefs_register_module(NULL, "extcap", "Extcap Utilities",
3005 "Extcap Utilities", NULL, FALSE);
3007 /* Setting default value to true */
3008 prefs.extcap_save_on_start = TRUE;
3009 prefs_register_bool_preference(extcap_module, "gui_save_on_start",
3010 "Save arguments on start of capture",
3011 "Save arguments on start of capture",
3012 &prefs.extcap_save_on_start);
3016 * These are "simple" GUI preferences that can be read/written using the
3017 * preference module API. These preferences still use their own
3018 * configuration screens for access, but this cuts down on the
3019 * preference "string compare list" in set_pref()
3021 gui_module = prefs_register_module(NULL, "gui", "User Interface",
3022 "User Interface", &gui_callback, FALSE);
3024 /* gui.console_open is placed first in the list so that any problems encountered
3025 * in the following prefs can be displayed in the console window.
3027 prefs_register_enum_preference(gui_module, "console_open",
3028 "Open a console window",
3029 "Open a console window (Windows only)",
3030 (gint*)(void*)(&prefs.gui_console_open), gui_console_open_type, FALSE);
3032 prefs_register_obsolete_preference(gui_module, "scrollbar_on_right");
3033 prefs_register_obsolete_preference(gui_module, "packet_list_sel_browse");
3034 prefs_register_obsolete_preference(gui_module, "protocol_tree_sel_browse");
3036 prefs_register_bool_preference(gui_module, "tree_view_altern_colors",
3037 "Alternating colors in TreeViews",
3038 "Alternating colors in TreeViews?",
3039 &prefs.gui_altern_colors);
3041 prefs_register_bool_preference(gui_module, "expert_composite_eyecandy",
3042 "Display Icons on Expert Composite Dialog Tabs",
3043 "Display Icons on Expert Composite Dialog Tabs?",
3044 &prefs.gui_expert_composite_eyecandy);
3046 prefs_register_bool_preference(gui_module, "filter_toolbar_show_in_statusbar",
3047 "Place filter toolbar inside the statusbar",
3048 "Place filter toolbar inside the statusbar?",
3049 &prefs.filter_toolbar_show_in_statusbar);
3051 prefs_register_bool_preference(gui_module, "restore_filter_after_following_stream",
3052 "Restore current display filter after following a stream",
3053 "Restore current display filter after following a stream?",
3054 &prefs.restore_filter_after_following_stream);
3056 prefs_register_enum_preference(gui_module, "protocol_tree_line_style",
3057 "Protocol-tree line style",
3058 "Protocol-tree line style",
3059 &prefs.gui_ptree_line_style, gui_ptree_line_style, FALSE);
3061 prefs_register_enum_preference(gui_module, "protocol_tree_expander_style",
3062 "Protocol-tree expander style",
3063 "Protocol-tree expander style",
3064 &prefs.gui_ptree_expander_style, gui_ptree_expander_style, FALSE);
3066 prefs_register_enum_preference(gui_module, "hex_dump_highlight_style",
3067 "Hex dump highlight style",
3068 "Hex dump highlight style",
3069 &prefs.gui_hex_dump_highlight_style, gui_hex_dump_highlight_style, FALSE);
3071 gui_column_module = prefs_register_subtree(gui_module, "Columns", "Columns", NULL);
3073 custom_cbs.free_cb = free_string_like_preference;
3074 custom_cbs.reset_cb = reset_string_like_preference;
3075 custom_cbs.set_cb = column_hidden_set_cb;
3076 custom_cbs.type_name_cb = column_hidden_type_name_cb;
3077 custom_cbs.type_description_cb = column_hidden_type_description_cb;
3078 custom_cbs.is_default_cb = column_hidden_is_default_cb;
3079 custom_cbs.to_str_cb = column_hidden_to_str_cb;
3080 register_string_like_preference(gui_column_module, PRS_COL_HIDDEN, "Packet list hidden columns",
3081 "List all columns to hide in the packet list",
3082 &cols_hidden_list, PREF_CUSTOM, &custom_cbs, FALSE);
3084 custom_cbs.free_cb = column_format_free_cb;
3085 custom_cbs.reset_cb = column_format_reset_cb;
3086 custom_cbs.set_cb = column_format_set_cb;
3087 custom_cbs.type_name_cb = column_format_type_name_cb;
3088 custom_cbs.type_description_cb = column_format_type_description_cb;
3089 custom_cbs.is_default_cb = column_format_is_default_cb;
3090 custom_cbs.to_str_cb = column_format_to_str_cb;
3092 prefs_register_list_custom_preference(gui_column_module, PRS_COL_FMT, "Packet list column format",
3093 "Each pair of strings consists of a column title and its format", &custom_cbs,
3094 column_format_init_cb, &prefs.col_list);
3096 /* Number of columns. This is only used internally and is not written to the
3099 custom_cbs.free_cb = custom_pref_no_cb;
3100 custom_cbs.reset_cb = column_num_reset_cb;
3101 custom_cbs.set_cb = column_num_set_cb;
3102 custom_cbs.type_name_cb = column_num_type_name_cb;
3103 custom_cbs.type_description_cb = column_num_type_description_cb;
3104 custom_cbs.is_default_cb = column_num_is_default_cb;
3105 custom_cbs.to_str_cb = column_num_to_str_cb;
3106 prefs_register_uint_custom_preference(gui_column_module, PRS_COL_NUM, "Number of columns",
3107 "Number of columns in col_list", &custom_cbs, &prefs.num_cols);
3109 /* User Interface : Font */
3110 gui_font_module = prefs_register_subtree(gui_module, "Font", "Font", NULL);
3112 prefs_register_obsolete_preference(gui_font_module, "font_name");
3114 register_string_like_preference(gui_font_module, "gtk2.font_name", "Font name",
3115 "Font name for packet list, protocol tree, and hex dump panes. (GTK+)",
3116 &prefs.gui_gtk2_font_name, PREF_STRING, NULL, TRUE);
3118 register_string_like_preference(gui_font_module, "qt.font_name", "Font name",
3119 "Font name for packet list, protocol tree, and hex dump panes. (Qt)",
3120 &prefs.gui_qt_font_name, PREF_STRING, NULL, TRUE);
3122 /* User Interface : Colors */
3123 gui_color_module = prefs_register_subtree(gui_module, "Colors", "Colors", NULL);
3125 prefs_register_color_preference(gui_color_module, "marked_frame.fg", "Color preferences for a marked frame",
3126 "Color preferences for a marked frame", &prefs.gui_marked_fg);
3128 prefs_register_color_preference(gui_color_module, "marked_frame.bg", "Color preferences for a marked frame",
3129 "Color preferences for a marked frame", &prefs.gui_marked_bg);
3131 prefs_register_color_preference(gui_color_module, "ignored_frame.fg", "Color preferences for a ignored frame",
3132 "Color preferences for a ignored frame", &prefs.gui_ignored_fg);
3134 prefs_register_color_preference(gui_color_module, "ignored_frame.bg", "Color preferences for a ignored frame",
3135 "Color preferences for a ignored frame", &prefs.gui_ignored_bg);
3137 prefs_register_color_preference(gui_color_module, "stream.client.fg", "TCP stream window color preference",
3138 "TCP stream window color preference", &prefs.st_client_fg);
3140 prefs_register_color_preference(gui_color_module, "stream.client.bg", "TCP stream window color preference",
3141 "TCP stream window color preference", &prefs.st_client_bg);
3143 prefs_register_color_preference(gui_color_module, "stream.server.fg", "TCP stream window color preference",
3144 "TCP stream window color preference", &prefs.st_server_fg);
3146 prefs_register_color_preference(gui_color_module, "stream.server.bg", "TCP stream window color preference",
3147 "TCP stream window color preference", &prefs.st_server_bg);
3149 custom_cbs.free_cb = free_string_like_preference;
3150 custom_cbs.reset_cb = reset_string_like_preference;
3151 custom_cbs.set_cb = colorized_frame_set_cb;
3152 custom_cbs.type_name_cb = colorized_frame_type_name_cb;
3153 custom_cbs.type_description_cb = colorized_frame_type_description_cb;
3154 custom_cbs.is_default_cb = colorized_frame_is_default_cb;
3155 custom_cbs.to_str_cb = colorized_frame_to_str_cb;
3156 register_string_like_preference(gui_column_module, "colorized_frame.fg", "Colorized Foreground",
3157 "Filter Colorized Foreground",
3158 &prefs.gui_colorized_fg, PREF_CUSTOM, &custom_cbs, TRUE);
3160 custom_cbs.free_cb = free_string_like_preference;
3161 custom_cbs.reset_cb = reset_string_like_preference;
3162 custom_cbs.set_cb = colorized_frame_set_cb;
3163 custom_cbs.type_name_cb = colorized_frame_type_name_cb;
3164 custom_cbs.type_description_cb = colorized_frame_type_description_cb;
3165 custom_cbs.is_default_cb = colorized_frame_is_default_cb;
3166 custom_cbs.to_str_cb = colorized_frame_to_str_cb;
3167 register_string_like_preference(gui_column_module, "colorized_frame.bg", "Colorized Background",
3168 "Filter Colorized Background",
3169 &prefs.gui_colorized_bg, PREF_CUSTOM, &custom_cbs, TRUE);
3171 prefs_register_color_preference(gui_color_module, "color_filter_bg.valid", "Valid color filter background",
3172 "Valid color filter background", &prefs.gui_text_valid);
3174 prefs_register_color_preference(gui_color_module, "color_filter_bg.invalid", "Invalid color filter background",
3175 "Invalid color filter background", &prefs.gui_text_invalid);
3177 prefs_register_color_preference(gui_color_module, "color_filter_bg.deprecated", "Deprecated color filter background",
3178 "Deprecated color filter background", &prefs.gui_text_deprecated);
3180 prefs_register_enum_preference(gui_module, "fileopen.style",
3181 "Where to start the File Open dialog box",
3182 "Where to start the File Open dialog box",
3183 &prefs.gui_fileopen_style, gui_fileopen_style, FALSE);
3185 prefs_register_uint_preference(gui_module, "recent_files_count.max",
3186 "The max. number of items in the open recent files list",
3187 "The max. number of items in the open recent files list",
3189 &prefs.gui_recent_files_count_max);
3191 prefs_register_uint_preference(gui_module, "recent_display_filter_entries.max",
3192 "The max. number of entries in the display filter list",
3193 "The max. number of entries in the display filter list",
3195 &prefs.gui_recent_df_entries_max);
3197 register_string_like_preference(gui_module, "fileopen.dir", "Start Directory",
3198 "Directory to start in when opening File Open dialog.",
3199 &prefs.gui_fileopen_dir, PREF_DIRNAME, NULL, TRUE);
3201 prefs_register_obsolete_preference(gui_module, "fileopen.remembered_dir");
3203 prefs_register_uint_preference(gui_module, "fileopen.preview",
3204 "The preview timeout in the File Open dialog",
3205 "The preview timeout in the File Open dialog",
3207 &prefs.gui_fileopen_preview);
3209 prefs_register_bool_preference(gui_module, "ask_unsaved",
3210 "Ask to save unsaved capture files",
3211 "Ask to save unsaved capture files?",
3212 &prefs.gui_ask_unsaved);
3214 prefs_register_bool_preference(gui_module, "find_wrap",
3215 "Wrap to beginning/end of file during search",
3216 "Wrap to beginning/end of file during search?",
3217 &prefs.gui_find_wrap);
3219 prefs_register_bool_preference(gui_module, "use_pref_save",
3220 "Settings dialogs use a save button",
3221 "Settings dialogs use a save button?",
3222 &prefs.gui_use_pref_save);
3224 prefs_register_bool_preference(gui_module, "geometry.save.position",
3225 "Save window position at exit",
3226 "Save window position at exit?",
3227 &prefs.gui_geometry_save_position);
3229 prefs_register_bool_preference(gui_module, "geometry.save.size",
3230 "Save window size at exit",
3231 "Save window size at exit?",
3232 &prefs.gui_geometry_save_size);
3234 prefs_register_bool_preference(gui_module, "geometry.save.maximized",
3235 "Save window maximized state at exit",
3236 "Save window maximized state at exit?",
3237 &prefs.gui_geometry_save_maximized);
3240 prefs_register_bool_preference(gui_module, "macosx_style",
3242 "Use macOS style (macOS with native GTK only)?",
3243 &prefs.gui_macosx_style);
3245 prefs_register_obsolete_preference(gui_module, "geometry.main.x");
3246 prefs_register_obsolete_preference(gui_module, "geometry.main.y");
3247 prefs_register_obsolete_preference(gui_module, "geometry.main.width");
3248 prefs_register_obsolete_preference(gui_module, "geometry.main.height");
3249 prefs_register_obsolete_preference(gui_module, "toolbar_main_show");
3251 prefs_register_enum_preference(gui_module, "toolbar_main_style",
3252 "Main Toolbar style",
3253 "Main Toolbar style",
3254 &prefs.gui_toolbar_main_style, gui_toolbar_style, FALSE);
3256 prefs_register_enum_preference(gui_module, "toolbar_filter_style",
3257 "Filter Toolbar style",
3258 "Filter Toolbar style",
3259 &prefs.gui_toolbar_filter_style, gui_toolbar_style, FALSE);
3261 register_string_like_preference(gui_module, "webbrowser", "The path to the webbrowser",
3262 "The path to the webbrowser (Ex: mozilla)",
3263 &prefs.gui_webbrowser, PREF_STRING, NULL, TRUE);
3265 prefs_register_bool_preference(gui_module, "update.enabled",
3266 "Check for updates",
3267 "Check for updates (Windows only)",
3268 &prefs.gui_update_enabled);
3270 prefs_register_enum_preference(gui_module, "update.channel",
3272 "The type of update to fetch. You should probably leave this set to UPDATE_CHANNEL_STABLE.",
3273 (gint*)(void*)(&prefs.gui_update_channel), gui_update_channel, FALSE);
3275 prefs_register_uint_preference(gui_module, "update.interval",
3276 "How often to check for software updates",
3277 "How often to check for software updates in seconds",
3279 &prefs.gui_update_interval);
3281 register_string_like_preference(gui_module, "window_title", "Custom window title",
3282 "Custom window title to be appended to the existing title\n%P = profile name\n%V = version info",
3283 &prefs.gui_window_title, PREF_STRING, NULL, TRUE);
3285 register_string_like_preference(gui_module, "prepend_window_title", "Custom window title prefix",
3286 "Custom window title to be prepended to the existing title\n%P = profile name\n%V = version info",
3287 &prefs.gui_prepend_window_title, PREF_STRING, NULL, TRUE);
3289 register_string_like_preference(gui_module, "start_title", "Custom start page title",
3290 "Custom start page title",
3291 &prefs.gui_start_title, PREF_STRING, NULL, TRUE);
3293 prefs_register_enum_preference(gui_module, "version_placement",
3294 "Show version in the start page and/or main screen's title bar",
3295 "Show version in the start page and/or main screen's title bar",
3296 (gint*)(void*)(&prefs.gui_version_placement), gui_version_placement_type, FALSE);
3298 prefs_register_bool_preference(gui_module, "auto_scroll_on_expand",
3299 "Automatically scroll packet details",
3300 "When selecting a new packet, automatically scroll"
3301 "to the packet detail item that matches the most"
3302 "recently selected item",
3303 &prefs.gui_auto_scroll_on_expand);
3305 prefs_register_uint_preference(gui_module, "auto_scroll_percentage",
3306 "Packet detail scroll percentage",
3307 "The percentage down the view the recently expanded detail item should be scrolled",
3309 &prefs.gui_auto_scroll_percentage);
3311 /* User Interface : Layout */
3312 gui_layout_module = prefs_register_subtree(gui_module, "Layout", "Layout", gui_layout_callback);
3314 prefs_register_uint_preference(gui_layout_module, "layout_type",
3316 "Layout type (1-6)",
3318 (guint*)(void*)(&prefs.gui_layout_type));
3320 prefs_register_enum_preference(gui_layout_module, "layout_content_1",
3321 "Layout content of the pane 1",
3322 "Layout content of the pane 1",
3323 (gint*)(void*)(&prefs.gui_layout_content_1), gui_layout_content, FALSE);
3325 prefs_register_enum_preference(gui_layout_module, "layout_content_2",
3326 "Layout content of the pane 2",
3327 "Layout content of the pane 2",
3328 (gint*)(void*)(&prefs.gui_layout_content_2), gui_layout_content, FALSE);
3330 prefs_register_enum_preference(gui_layout_module, "layout_content_3",
3331 "Layout content of the pane 3",
3332 "Layout content of the pane 3",
3333 (gint*)(void*)(&prefs.gui_layout_content_3), gui_layout_content, FALSE);
3335 prefs_register_bool_preference(gui_layout_module, "packet_list_separator.enabled",
3336 "Enable Packet List Separator",
3337 "Enable Packet List Separator",
3338 &prefs.gui_qt_packet_list_separator);
3340 prefs_register_bool_preference(gui_layout_module, "show_selected_packet.enabled",
3341 "Show selected packet in the Status Bar",
3342 "Show selected packet in the Status Bar",
3343 &prefs.gui_qt_show_selected_packet);
3345 prefs_register_bool_preference(gui_layout_module, "show_file_load_time.enabled",
3346 "Show file load time in the Status Bar",
3347 "Show file load time in the Status Bar",
3348 &prefs.gui_qt_show_file_load_time);
3350 prefs_register_bool_preference(gui_module, "packet_editor.enabled",
3351 "Enable Packet Editor",
3352 "Enable Packet Editor (Experimental)",
3353 &prefs.gui_packet_editor);
3355 prefs_register_enum_preference(gui_module, "packet_list_elide_mode",
3357 "The position of \"...\" in packet list text.",
3358 (gint*)(void*)(&prefs.gui_packet_list_elide_mode), gui_packet_list_elide_mode, FALSE);
3360 prefs_register_bool_preference(gui_layout_module, "packet_list_show_related",
3361 "Show Related Packets",
3362 "Show related packet indicators in the first column",
3363 &prefs.gui_packet_list_show_related);
3365 prefs_register_bool_preference(gui_layout_module, "packet_list_show_minimap",
3366 "Enable Intelligent Scroll Bar",
3367 "Show the intelligent scroll bar (a minimap of packet list colors in the scrollbar)",
3368 &prefs.gui_packet_list_show_minimap);
3371 prefs_register_bool_preference(gui_module, "interfaces_show_hidden",
3372 "Show hidden interfaces",
3373 "Show all interfaces, including interfaces marked as hidden",
3374 &prefs.gui_interfaces_show_hidden);
3376 #ifdef HAVE_PCAP_REMOTE
3377 prefs_register_bool_preference(gui_module, "interfaces_remote_display",
3378 "Show Remote interfaces",
3379 "Show remote interfaces in the interface selection",
3380 &prefs.gui_interfaces_remote_display);
3383 register_string_like_preference(gui_module, "interfaces_hidden_types", "Hide interface types in list",
3384 "Hide the given interface types in the startup list",
3385 &prefs.gui_interfaces_hide_types, PREF_STRING, NULL, TRUE);
3388 * These are preferences that can be read/written using the
3389 * preference module API. These preferences still use their own
3390 * configuration screens for access, but this cuts down on the
3391 * preference "string compare list" in set_pref()
3393 console_module = prefs_register_module(NULL, "console", "Console",
3394 "Console logging and debugging output", NULL, FALSE);
3396 custom_cbs.free_cb = custom_pref_no_cb;
3397 custom_cbs.reset_cb = console_log_level_reset_cb;
3398 custom_cbs.set_cb = console_log_level_set_cb;
3399 custom_cbs.type_name_cb = console_log_level_type_name_cb;
3400 custom_cbs.type_description_cb = console_log_level_type_description_cb;
3401 custom_cbs.is_default_cb = console_log_level_is_default_cb;
3402 custom_cbs.to_str_cb = console_log_level_to_str_cb;
3403 prefs_register_uint_custom_preference(console_module, "log.level", "logging level",
3404 "A bitmask of GLib log levels", &custom_cbs, &prefs.console_log_level);
3406 prefs_register_bool_preference(console_module, "incomplete_dissectors_check_debug",
3407 "Print debug line for incomplete dissectors",
3408 "Look for dissectors that left some bytes undecoded (debug)",
3409 &prefs.incomplete_dissectors_check_debug);
3411 /* Display filter Expressions
3412 * This used to be an array of individual fields that has now been
3413 * converted to a UAT. Just make it part of the GUI category even
3414 * though the name of the preference will never be seen in preference
3417 filter_expression_register_uat(gui_module);
3420 * These are preferences that can be read/written using the
3421 * preference module API. These preferences still use their own
3422 * configuration screens for access, but this cuts down on the
3423 * preference "string compare list" in set_pref()
3425 capture_module = prefs_register_module(NULL, "capture", "Capture",
3426 "Capture preferences", NULL, FALSE);
3427 /* Capture preferences don't affect dissection */
3428 prefs_set_module_effect_flags(capture_module, PREF_EFFECT_CAPTURE);
3430 register_string_like_preference(capture_module, "device", "Default capture device",
3431 "Default capture device",
3432 &prefs.capture_device, PREF_STRING, NULL, FALSE);
3434 register_string_like_preference(capture_module, "devices_linktypes", "Interface link-layer header type",
3435 "Interface link-layer header types (Ex: en0(1),en1(143),...)",
3436 &prefs.capture_devices_linktypes, PREF_STRING, NULL, FALSE);
3438 register_string_like_preference(capture_module, "devices_descr", "Interface descriptions",
3439 "Interface descriptions (Ex: eth0(eth0 descr),eth1(eth1 descr),...)",
3440 &prefs.capture_devices_descr, PREF_STRING, NULL, FALSE);
3442 register_string_like_preference(capture_module, "devices_hide", "Hide interface",
3443 "Hide interface? (Ex: eth0,eth3,...)",
3444 &prefs.capture_devices_hide, PREF_STRING, NULL, FALSE);
3446 register_string_like_preference(capture_module, "devices_monitor_mode", "Capture in monitor mode",
3447 "By default, capture in monitor mode on interface? (Ex: eth0,eth3,...)",
3448 &prefs.capture_devices_monitor_mode, PREF_STRING, NULL, FALSE);
3450 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
3451 register_string_like_preference(capture_module, "devices_buffersize", "Interface buffer size",
3452 "Interface buffer size (Ex: en0(1),en1(143),...)",
3453 &prefs.capture_devices_buffersize, PREF_STRING, NULL, FALSE);
3456 register_string_like_preference(capture_module, "devices_snaplen", "Interface snap length",
3457 "Interface snap length (Ex: en0(65535),en1(1430),...)",
3458 &prefs.capture_devices_snaplen, PREF_STRING, NULL, FALSE);
3460 register_string_like_preference(capture_module, "devices_pmode", "Interface promiscuous mode",
3461 "Interface promiscuous mode (Ex: en0(0),en1(1),...)",
3462 &prefs.capture_devices_pmode, PREF_STRING, NULL, FALSE);
3464 prefs_register_bool_preference(capture_module, "prom_mode", "Capture in promiscuous mode",
3465 "Capture in promiscuous mode?", &prefs.capture_prom_mode);
3467 register_string_like_preference(capture_module, "devices_filter", "Interface capture filter",
3468 "Interface capture filter (Ex: en0(tcp),en1(udp),...)",
3469 &prefs.capture_devices_filter, PREF_STRING, NULL, FALSE);
3471 prefs_register_bool_preference(capture_module, "pcap_ng", "Capture in Pcap-NG format",
3472 "Capture in Pcap-NG format?", &prefs.capture_pcap_ng);
3474 prefs_register_bool_preference(capture_module, "real_time_update", "Update packet list in real time during capture",
3475 "Update packet list in real time during capture?", &prefs.capture_real_time);
3477 /* We might want to make this a "recent" setting. */
3478 prefs_register_bool_preference(capture_module, "auto_scroll", "Scroll packet list during capture",
3479 "Scroll packet list during capture?", &prefs.capture_auto_scroll);
3482 prefs_register_bool_preference(capture_module, "show_info", "Show capture info dialog while capturing",
3483 "Show capture info dialog while capturing?", &prefs.capture_show_info);
3485 prefs_register_obsolete_preference(capture_module, "syntax_check_filter");
3487 custom_cbs.free_cb = capture_column_free_cb;
3488 custom_cbs.reset_cb = capture_column_reset_cb;
3489 custom_cbs.set_cb = capture_column_set_cb;
3490 custom_cbs.type_name_cb = capture_column_type_name_cb;
3491 custom_cbs.type_description_cb = capture_column_type_description_cb;
3492 custom_cbs.is_default_cb = capture_column_is_default_cb;
3493 custom_cbs.to_str_cb = capture_column_to_str_cb;
3494 prefs_register_list_custom_preference(capture_module, "columns", "Capture options dialog column list",
3495 "List of columns to be displayed", &custom_cbs, capture_column_init_cb, &prefs.capture_columns);
3497 /* Name Resolution */
3498 nameres_module = prefs_register_module(NULL, "nameres", "Name Resolution",
3499 "Name Resolution", NULL, TRUE);
3500 addr_resolve_pref_init(nameres_module);
3501 oid_pref_init(nameres_module);
3503 geoip_db_pref_init(nameres_module);
3507 printing = prefs_register_module(NULL, "print", "Printing",
3508 "Printing", NULL, TRUE);
3510 prefs_register_enum_preference(printing, "format",
3511 "Format", "Can be one of \"text\" or \"postscript\"",
3512 &prefs.pr_format, print_format_vals, TRUE);
3514 prefs_register_enum_preference(printing, "destination",
3515 "Print to", "Can be one of \"command\" or \"file\"",
3516 &prefs.pr_dest, print_dest_vals, TRUE);
3519 register_string_like_preference(printing, "command", "Command",
3520 "Output gets piped to this command when the destination is set to \"command\"",
3521 &prefs.pr_cmd, PREF_STRING, NULL, TRUE);
3524 register_string_like_preference(printing, "file", "File",
3525 "This is the file that gets written to when the destination is set to \"file\"",
3526 &prefs.pr_file, PREF_SAVE_FILENAME, NULL, TRUE);
3529 codecs_module = prefs_register_module(NULL, "codecs", "Codecs",
3530 "Codecs", NULL, TRUE);
3533 stats_module = prefs_register_module(NULL, "statistics", "Statistics",
3534 "Statistics", &stats_callback, TRUE);
3536 prefs_register_uint_preference(stats_module, "update_interval",
3537 "Tap update interval in ms",
3538 "Determines time between tap updates",
3540 &prefs.tap_update_interval);
3542 #ifdef HAVE_LIBPORTAUDIO
3543 prefs_register_uint_preference(stats_module, "rtp_player_max_visible",
3544 "Max visible channels in RTP Player",
3545 "Determines maximum height of RTP Player window",
3547 &prefs.rtp_player_max_visible);
3550 prefs_register_bool_preference(stats_module, "st_enable_burstinfo",
3551 "Enable the calculation of burst information",
3552 "If enabled burst rates will be calcuted for statistics that use the stats_tree system. "
3553 "Burst rates are calculated over a much shorter time interval than the rate column.",
3554 &prefs.st_enable_burstinfo);
3556 prefs_register_bool_preference(stats_module, "st_burst_showcount",
3557 "Show burst count for item rather than rate",
3558 "If selected the stats_tree statistics nodes will show the count of events "
3559 "within the burst window instead of a burst rate. Burst rate is calculated "
3560 "as number of events within burst window divided by the burst windown length.",
3561 &prefs.st_burst_showcount);
3563 prefs_register_uint_preference(stats_module, "st_burst_resolution",
3564 "Burst rate resolution (ms)",
3565 "Sets the duration of the time interval into which events are grouped when calculating "
3566 "the burst rate. Higher resolution (smaller number) increases processing overhead.",
3567 10,&prefs.st_burst_resolution);
3569 prefs_register_uint_preference(stats_module, "st_burst_windowlen",
3570 "Burst rate window size (ms)",
3571 "Sets the duration of the sliding window during which the burst rate is "
3572 "measured. Longer window relative to burst rate resolution increases "
3573 "processing overhead. Will be truncated to a multiple of burst resolution.",
3574 10,&prefs.st_burst_windowlen);
3576 prefs_register_enum_preference(stats_module, "st_sort_defcolflag",
3577 "Default sort column for stats_tree stats",
3578 "Sets the default column by which stats based on the stats_tree "
3579 "system is sorted.",
3580 &prefs.st_sort_defcolflag, st_sort_col_vals, FALSE);
3582 prefs_register_bool_preference(stats_module, "st_sort_defdescending",
3583 "Default stats_tree sort order is descending",
3584 "When selected, statistics based on the stats_tree system will by default "
3585 "be sorted in descending order.",
3586 &prefs.st_sort_defdescending);
3588 prefs_register_bool_preference(stats_module, "st_sort_casesensitve",
3589 "Case sensitive sort of stats_tree item names",
3590 "When selected, the item/node names of statistics based on the stats_tree "
3591 "system will be sorted taking case into account. Else the case of the name "
3593 &prefs.st_sort_casesensitve);
3595 prefs_register_bool_preference(stats_module, "st_sort_rng_nameonly",
3596 "Always sort 'range' nodes by name",
3597 "When selected, the stats_tree nodes representing a range of values "
3598 "(0-49, 50-100, etc.) will always be sorted by name (the range of the "
3599 "node). Else range nodes are sorted by the same column as the rest of "
3601 &prefs.st_sort_rng_nameonly);
3603 prefs_register_bool_preference(stats_module, "st_sort_rng_fixorder",
3604 "Always sort 'range' nodes in ascending order",
3605 "When selected, the stats_tree nodes representing a range of values "
3606 "(0-49, 50-100, etc.) will always be sorted ascending; else it follows "
3607 "the sort direction of the tree. Only effective if \"Always sort "
3608 "'range' nodes by name\" is also selected.",
3609 &prefs.st_sort_rng_fixorder);
3611 prefs_register_bool_preference(stats_module, "st_sort_showfullname",
3612 "Display the full stats_tree plug-in name",
3613 "When selected, the full name (including menu path) of the stats_tree "
3614 "plug-in is show in windows. If cleared the plug-in name is shown "
3615 "without menu path (only the part of the name after last '/' character.)",
3616 &prefs.st_sort_showfullname);
3619 protocols_module = prefs_register_module(NULL, "protocols", "Protocols",
3620 "Protocols", NULL, TRUE);
3622 prefs_register_bool_preference(protocols_module, "display_hidden_proto_items",
3623 "Display hidden protocol items",
3624 "Display all hidden protocol items in the packet list.",
3625 &prefs.display_hidden_proto_items);
3627 prefs_register_bool_preference(protocols_module, "display_byte_fields_with_spaces",
3628 "Display byte fields with a space character between bytes",
3629 "Display all byte fields with a space character between each byte in the packet list.",
3630 &prefs.display_byte_fields_with_spaces);
3632 prefs_register_bool_preference(protocols_module, "enable_incomplete_dissectors_check",
3633 "Look for incomplete dissectors",
3634 "Look for dissectors that left some bytes undecoded.",
3635 &prefs.enable_incomplete_dissectors_check);
3637 prefs_register_bool_preference(protocols_module, "strict_conversation_tracking_heuristics",
3638 "Enable stricter conversation tracking heuristics",
3639 "Protocols may use things like VLAN ID or interface ID to narrow the potential for duplicate conversations."
3640 "Currently only ICMP and ICMPv6 use this preference to add VLAN ID to conversation tracking",
3641 &prefs.strict_conversation_tracking_heuristics);
3643 /* Obsolete preferences
3644 * These "modules" were reorganized/renamed to correspond to their GUI
3645 * configuration screen within the preferences dialog
3648 /* taps is now part of the stats module */
3649 prefs_register_module(NULL, "taps", "TAPS", "TAPS", NULL, FALSE);
3650 /* packet_list is now part of the protocol (parent) module */
3651 prefs_register_module(NULL, "packet_list", "PACKET_LIST", "PACKET_LIST", NULL, FALSE);
3652 /* stream is now part of the gui module */
3653 prefs_register_module(NULL, "stream", "STREAM", "STREAM", NULL, FALSE);
3657 /* Parse through a list of comma-separated, possibly quoted strings.
3658 Return a list of the string data. */
3660 prefs_get_string_list(const gchar *str)
3662 enum { PRE_STRING, IN_QUOT, NOT_IN_QUOT };
3664 gint state = PRE_STRING, i = 0, j = 0;
3665 gboolean backslash = FALSE;
3667 gchar *slstr = NULL;
3670 /* Allocate a buffer for the first string. */
3671 slstr = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
3676 if (cur_c == '\0') {
3677 /* It's the end of the input, so it's the end of the string we
3678 were working on, and there's no more input. */
3679 if (state == IN_QUOT || backslash) {
3680 /* We were in the middle of a quoted string or backslash escape,
3681 and ran out of characters; that's an error. */
3683 prefs_clear_string_list(sl);
3688 sl = g_list_append(sl, slstr);
3693 if (cur_c == '"' && ! backslash) {
3696 /* We hadn't yet started processing a string; this starts the
3697 string, and we're now quoting. */
3701 /* We're in the middle of a quoted string, and we saw a quotation
3702 mark; we're no longer quoting. */
3703 state = NOT_IN_QUOT;
3706 /* We're working on a string, but haven't seen a quote; we're
3713 } else if (cur_c == '\\' && ! backslash) {
3714 /* We saw a backslash, and the previous character wasn't a
3715 backslash; escape the next character.
3717 This also means we've started a new string. */
3719 if (state == PRE_STRING)
3720 state = NOT_IN_QUOT;
3721 } else if (cur_c == ',' && state != IN_QUOT && ! backslash) {
3722 /* We saw a comma, and we're not in the middle of a quoted string
3723 and it wasn't preceded by a backslash; it's the end of
3724 the string we were working on... */
3727 sl = g_list_append(sl, slstr);
3728 slstr = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
3731 /* ...and the beginning of a new string. */
3734 } else if (!g_ascii_isspace(cur_c) || state != PRE_STRING) {
3735 /* Either this isn't a white-space character, or we've started a
3736 string (i.e., already seen a non-white-space character for that
3737 string and put it into the string).
3739 The character is to be put into the string; do so if there's
3741 if (j < COL_MAX_LEN) {
3746 /* If it was backslash-escaped, we're done with the backslash escape. */
3754 char *join_string_list(GList *sl)
3756 GString *joined_str = g_string_new("");
3759 guint item_count = 0;
3761 cur = first = g_list_first(sl);
3764 str = (gchar *)cur->data;
3767 g_string_append_c(joined_str, ',');
3769 if (item_count % 2) {
3770 /* Wrap the line. */
3771 g_string_append(joined_str, "\n\t");
3773 g_string_append_c(joined_str, ' ');
3775 g_string_append_c(joined_str, '"');
3777 gunichar uc = g_utf8_get_char (str);
3779 if (uc == '"' || uc == '\\')
3780 g_string_append_c(joined_str, '\\');
3782 if (g_unichar_isprint(uc))
3783 g_string_append_unichar (joined_str, uc);
3785 str = g_utf8_next_char (str);
3788 g_string_append_c(joined_str, '"');
3792 return g_string_free(joined_str, FALSE);
3796 prefs_clear_string_list(GList *sl)
3798 /* g_list_free_full() only exists since 2.28. */
3799 g_list_foreach(sl, (GFunc)g_free, NULL);
3804 * Takes a string, a pointer to an array of "enum_val_t"s, and a default gint
3806 * The array must be terminated by an entry with a null "name" string.
3808 * If the string matches a "name" string in an entry, the value from that
3809 * entry is returned.
3811 * Otherwise, if a string matches a "description" string in an entry, the
3812 * value from that entry is returned; we do that for backwards compatibility,
3813 * as we used to have only a "name" string that was used both for command-line
3814 * and configuration-file values and in the GUI (which meant either that
3815 * the GUI had what might be somewhat cryptic values to select from or that
3816 * the "-o" flag took long strings, often with spaces in them).
3818 * Otherwise, the default value that was passed as the third argument is
3822 find_val_for_string(const char *needle, const enum_val_t *haystack,
3827 for (i = 0; haystack[i].name != NULL; i++) {
3828 if (g_ascii_strcasecmp(needle, haystack[i].name) == 0) {
3829 return haystack[i].value;
3832 for (i = 0; haystack[i].name != NULL; i++) {
3833 if (g_ascii_strcasecmp(needle, haystack[i].description) == 0) {
3834 return haystack[i].value;
3837 return default_value;
3841 /* Array of columns that have been migrated to custom columns */
3842 struct deprecated_columns {
3843 const gchar *col_fmt;
3844 const gchar *col_expr;
3846 static struct deprecated_columns migrated_columns[] = {
3847 { /* COL_COS_VALUE */ "%U", "vlan.priority" },
3848 { /* COL_CIRCUIT_ID */ "%c", "iax2.call" },
3849 { /* COL_BSSGP_TLLI */ "%l", "bssgp.tlli" },
3850 { /* COL_HPUX_SUBSYS */ "%H", "nettl.subsys" },
3851 { /* COL_HPUX_DEVID */ "%P", "nettl.devid" },
3852 { /* COL_FR_DLCI */ "%C", "fr.dlci" },
3853 { /* COL_REL_CONV_TIME */ "%rct", "tcp.time_relative" },
3854 { /* COL_DELTA_CONV_TIME */ "%dct", "tcp.time_delta" },
3855 { /* COL_OXID */ "%XO", "fc.ox_id" },
3856 { /* COL_RXID */ "%XR", "fc.rx_id" },
3857 { /* COL_SRCIDX */ "%Xd", "mdshdr.srcidx" },
3858 { /* COL_DSTIDX */ "%Xs", "mdshdr.dstidx" },
3859 { /* COL_DCE_CTX */ "%z", "dcerpc.cn_ctx_id" }
3863 is_deprecated_column_format(const gchar* fmt)
3867 for (haystack_idx = 0;
3868 haystack_idx < G_N_ELEMENTS(migrated_columns);
3871 if (strcmp(migrated_columns[haystack_idx].col_fmt, fmt) == 0) {
3879 /* Preferences file format:
3880 * - Configuration directives start at the beginning of the line, and
3881 * are terminated with a colon.
3882 * - Directives can be continued on the next line by preceding them with
3887 # This is a comment line
3889 print.file: /a/very/long/path/
3894 #define DEF_NUM_COLS 7
3897 * Parse a column format, filling in the relevant fields of a fmt_data.
3900 parse_column_format(fmt_data *cfmt, const char *fmt)
3902 const gchar *cust_format = col_format_to_string(COL_CUSTOM);
3903 size_t cust_format_len = strlen(cust_format);
3904 gchar **cust_format_info;
3907 gchar *col_custom_fields = NULL;
3908 long col_custom_occurrence = 0;
3909 gboolean col_resolved = TRUE;
3912 * Is this a custom column?
3914 if ((strlen(fmt) > cust_format_len) && (fmt[cust_format_len] == ':') &&
3915 strncmp(fmt, cust_format, cust_format_len) == 0) {
3917 col_fmt = COL_CUSTOM;
3918 cust_format_info = g_strsplit(&fmt[cust_format_len+1],":",3); /* add 1 for ':' */
3919 col_custom_fields = g_strdup(cust_format_info[0]);
3920 if (col_custom_fields && cust_format_info[1]) {
3921 col_custom_occurrence = strtol(cust_format_info[1], &p, 10);
3922 if (p == cust_format_info[1] || *p != '\0') {
3923 /* Not a valid number. */
3924 g_free(col_custom_fields);
3925 g_strfreev(cust_format_info);
3929 if (col_custom_fields && cust_format_info[1] && cust_format_info[2]) {
3930 col_resolved = (cust_format_info[2][0] == 'U') ? FALSE : TRUE;
3932 g_strfreev(cust_format_info);
3934 col_fmt = get_column_format_from_str(fmt);
3935 if ((col_fmt == -1) && (!is_deprecated_column_format(fmt)))
3939 cfmt->fmt = col_fmt;
3940 cfmt->custom_fields = col_custom_fields;
3941 cfmt->custom_occurrence = (int)col_custom_occurrence;
3942 cfmt->resolved = col_resolved;
3946 /* Initialize non-dissector preferences to wired-in default values Called
3947 * at program startup and any time the profile changes. (The dissector
3948 * preferences are assumed to be set to those values by the dissectors.)
3949 * They may be overridden by the global preferences file or the user's
3955 if (prefs_initialized)
3961 * Ensure the "global" preferences have been initialized so the
3962 * preference API has the proper default values to work from
3966 prefs_register_modules();
3968 prefs_initialized = TRUE;
3972 * Initialize non-dissector preferences used by the "register preference" API
3973 * to default values so the default values can be used when registered.
3975 * String, filename, and directory preferences will be g_freed so they must
3979 pre_init_prefs(void)
3984 static const gchar *col_fmt[DEF_NUM_COLS*2] = {
3985 "No.", "%m", "Time", "%t",
3986 "Source", "%s", "Destination", "%d",
3987 "Protocol", "%p", "Length", "%L",
3990 prefs.pr_format = PR_FMT_TEXT;
3991 prefs.pr_dest = PR_DEST_CMD;
3992 g_free(prefs.pr_file);
3993 prefs.pr_file = g_strdup("wireshark.out");
3994 g_free(prefs.pr_cmd);
3995 prefs.pr_cmd = g_strdup("lpr");
3997 prefs.gui_altern_colors = FALSE;
3998 prefs.gui_expert_composite_eyecandy = FALSE;
3999 prefs.gui_ptree_line_style = 0;
4000 prefs.gui_ptree_expander_style = 1;
4001 prefs.gui_hex_dump_highlight_style = 1; /* GTK+ only */
4002 prefs.filter_toolbar_show_in_statusbar = FALSE;
4003 prefs.restore_filter_after_following_stream = FALSE;
4004 prefs.gui_toolbar_main_style = TB_STYLE_ICONS;
4005 prefs.gui_toolbar_filter_style = TB_STYLE_TEXT;
4006 /* These will be g_freed, so they must be g_mallocated. */
4007 g_free(prefs.gui_gtk2_font_name);
4009 prefs.gui_gtk2_font_name = g_strdup("Lucida Console 10");
4011 prefs.gui_gtk2_font_name = g_strdup("Monospace 10");
4013 /* We try to find the best font in the Qt code */
4014 g_free(prefs.gui_qt_font_name);
4015 prefs.gui_qt_font_name = g_strdup("");
4016 prefs.gui_marked_fg.red = 65535;
4017 prefs.gui_marked_fg.green = 65535;
4018 prefs.gui_marked_fg.blue = 65535;
4019 prefs.gui_marked_bg.red = 0;
4020 prefs.gui_marked_bg.green = 8224;
4021 prefs.gui_marked_bg.blue = 10794;
4022 prefs.gui_ignored_fg.red = 32767;
4023 prefs.gui_ignored_fg.green = 32767;
4024 prefs.gui_ignored_fg.blue = 32767;
4025 prefs.gui_ignored_bg.red = 65535;
4026 prefs.gui_ignored_bg.green = 65535;
4027 prefs.gui_ignored_bg.blue = 65535;
4028 g_free(prefs.gui_colorized_fg);
4029 prefs.gui_colorized_fg = g_strdup("000000,000000,000000,000000,000000,000000,000000,000000,000000,000000");
4030 g_free(prefs.gui_colorized_bg);
4031 prefs.gui_colorized_bg = g_strdup("ffc0c0,ffc0ff,e0c0e0,c0c0ff,c0e0e0,c0ffff,c0ffc0,ffffc0,e0e0c0,e0e0e0");
4032 prefs.st_client_fg.red = 32767;
4033 prefs.st_client_fg.green = 0;
4034 prefs.st_client_fg.blue = 0;
4035 prefs.st_client_bg.red = 64507;
4036 prefs.st_client_bg.green = 60909;
4037 prefs.st_client_bg.blue = 60909;
4038 prefs.st_server_fg.red = 0;
4039 prefs.st_server_fg.green = 0;
4040 prefs.st_server_fg.blue = 32767;
4041 prefs.st_server_bg.red = 60909;
4042 prefs.st_server_bg.green = 60909;
4043 prefs.st_server_bg.blue = 64507;
4045 if (gui_theme_is_dark) {
4046 // Green, red and yellow with HSV V = 84
4047 prefs.gui_text_valid.red = 0x0000; /* dark green */
4048 prefs.gui_text_valid.green = 0x66ff;
4049 prefs.gui_text_valid.blue = 0x0000;
4050 prefs.gui_text_invalid.red = 0x66FF; /* dark red */
4051 prefs.gui_text_invalid.green = 0x0000;
4052 prefs.gui_text_invalid.blue = 0x0000;
4053 prefs.gui_text_deprecated.red = 0x66FF; /* dark yellow / olive */
4054 prefs.gui_text_deprecated.green = 0x66FF;
4055 prefs.gui_text_deprecated.blue = 0x0000;
4057 // Green, red and yellow with HSV V = 20
4058 prefs.gui_text_valid.red = 0xAFFF; /* light green */
4059 prefs.gui_text_valid.green = 0xFFFF;
4060 prefs.gui_text_valid.blue = 0xAFFF;
4061 prefs.gui_text_invalid.red = 0xFFFF; /* light red */
4062 prefs.gui_text_invalid.green = 0xAFFF;
4063 prefs.gui_text_invalid.blue = 0xAFFF;
4064 prefs.gui_text_deprecated.red = 0xFFFF; /* light yellow */
4065 prefs.gui_text_deprecated.green = 0xFFFF;
4066 prefs.gui_text_deprecated.blue = 0xAFFF;
4069 prefs.gui_geometry_save_position = TRUE;
4070 prefs.gui_geometry_save_size = TRUE;
4071 prefs.gui_geometry_save_maximized= TRUE;
4072 prefs.gui_macosx_style = TRUE;
4073 prefs.gui_console_open = console_open_never;
4074 prefs.gui_fileopen_style = FO_STYLE_LAST_OPENED;
4075 prefs.gui_recent_df_entries_max = 10;
4076 prefs.gui_recent_files_count_max = 10;
4077 g_free(prefs.gui_fileopen_dir);
4078 prefs.gui_fileopen_dir = g_strdup(get_persdatafile_dir());
4079 prefs.gui_fileopen_preview = 3;
4080 prefs.gui_ask_unsaved = TRUE;
4081 prefs.gui_find_wrap = TRUE;
4082 prefs.gui_use_pref_save = FALSE;
4083 prefs.gui_update_enabled = TRUE;
4084 prefs.gui_update_channel = UPDATE_CHANNEL_STABLE;
4085 prefs.gui_update_interval = 60*60*24; /* Seconds */
4086 g_free(prefs.gui_webbrowser);
4087 prefs.gui_webbrowser = g_strdup("");
4088 g_free(prefs.gui_window_title);
4089 prefs.gui_window_title = g_strdup("");
4090 g_free(prefs.gui_prepend_window_title);
4091 prefs.gui_prepend_window_title = g_strdup("");
4092 g_free(prefs.gui_start_title);
4093 prefs.gui_start_title = g_strdup("The World's Most Popular Network Protocol Analyzer");
4094 prefs.gui_version_placement = version_both;
4095 prefs.gui_auto_scroll_on_expand = FALSE;
4096 prefs.gui_auto_scroll_percentage = 0;
4097 prefs.gui_layout_type = layout_type_5;
4098 prefs.gui_layout_content_1 = layout_pane_content_plist;
4099 prefs.gui_layout_content_2 = layout_pane_content_pdetails;
4100 prefs.gui_layout_content_3 = layout_pane_content_pbytes;
4101 prefs.gui_packet_editor = FALSE;
4102 prefs.gui_packet_list_elide_mode = ELIDE_RIGHT;
4103 prefs.gui_packet_list_show_related = TRUE;
4104 prefs.gui_packet_list_show_minimap = TRUE;
4105 g_free (prefs.gui_interfaces_hide_types);
4106 prefs.gui_interfaces_hide_types = g_strdup("");
4107 prefs.gui_interfaces_show_hidden = FALSE;
4108 #ifdef HAVE_PCAP_REMOTE
4109 prefs.gui_interfaces_remote_display = TRUE;
4112 prefs.gui_qt_packet_list_separator = FALSE;
4113 prefs.gui_qt_show_selected_packet = FALSE;
4114 prefs.gui_qt_show_file_load_time = FALSE;
4116 if (prefs.col_list) {
4117 free_col_info(prefs.col_list);
4118 prefs.col_list = NULL;
4120 for (i = 0; i < DEF_NUM_COLS; i++) {
4121 cfmt = g_new(fmt_data,1);
4122 cfmt->title = g_strdup(col_fmt[i * 2]);
4123 parse_column_format(cfmt, col_fmt[(i * 2) + 1]);
4124 cfmt->visible = TRUE;
4125 cfmt->resolved = TRUE;
4126 cfmt->custom_fields = NULL;
4127 cfmt->custom_occurrence = 0;
4128 prefs.col_list = g_list_append(prefs.col_list, cfmt);
4130 prefs.num_cols = DEF_NUM_COLS;
4132 /* set the default values for the capture dialog box */
4133 prefs.capture_prom_mode = TRUE;
4134 #ifdef PCAP_NG_DEFAULT
4135 prefs.capture_pcap_ng = TRUE;
4137 prefs.capture_pcap_ng = FALSE;
4139 prefs.capture_real_time = TRUE;
4140 prefs.capture_auto_scroll = TRUE;
4141 prefs.capture_show_info = FALSE;
4143 if (!prefs.capture_columns) {
4144 /* First time through */
4145 for (i = 0; i < num_capture_cols; i++) {
4146 col_name = g_strdup(capture_cols[i]);
4147 prefs.capture_columns = g_list_append(prefs.capture_columns, col_name);
4151 prefs.console_log_level =
4152 G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_ERROR;
4154 /* set the default values for the tap/statistics dialog box */
4155 prefs.tap_update_interval = TAP_UPDATE_DEFAULT_INTERVAL;
4156 prefs.rtp_player_max_visible = RTP_PLAYER_DEFAULT_VISIBLE;
4157 prefs.st_enable_burstinfo = TRUE;
4158 prefs.st_burst_showcount = FALSE;
4159 prefs.st_burst_resolution = ST_DEF_BURSTRES;
4160 prefs.st_burst_windowlen = ST_DEF_BURSTLEN;
4161 prefs.st_sort_casesensitve = TRUE;
4162 prefs.st_sort_rng_fixorder = TRUE;
4163 prefs.st_sort_rng_nameonly = TRUE;
4164 prefs.st_sort_defcolflag = ST_SORT_COL_COUNT;
4165 prefs.st_sort_defdescending = TRUE;
4166 prefs.st_sort_showfullname = FALSE;
4167 prefs.display_hidden_proto_items = FALSE;
4168 prefs.display_byte_fields_with_spaces = FALSE;
4172 * Reset a single dissector preference.
4175 reset_pref(pref_t *pref)
4183 * This preference is no longer supported; it's not a
4184 * real preference, so we don't reset it (i.e., we
4185 * treat it as if it weren't found in the list of
4186 * preferences, and we weren't called in the first place).
4188 if (IS_PREF_OBSOLETE(type))
4191 RESET_PREF_OBSOLETE(type);
4196 case PREF_DECODE_AS_UINT:
4197 *pref->varp.uint = pref->default_val.uint;
4201 *pref->varp.boolp = pref->default_val.boolval;
4206 * For now, we save the "description" value, so that if we
4207 * save the preferences older versions of Wireshark can at
4208 * least read preferences that they supported; we support
4209 * either the short name or the description when reading
4210 * the preferences file or a "-o" option.
4212 *pref->varp.enump = pref->default_val.enumval;
4216 case PREF_SAVE_FILENAME:
4217 case PREF_OPEN_FILENAME:
4219 reset_string_like_preference(pref);
4223 case PREF_DECODE_AS_RANGE:
4224 wmem_free(wmem_epan_scope(), *pref->varp.range);
4225 *pref->varp.range = range_copy(wmem_epan_scope(), pref->default_val.range);
4228 case PREF_STATIC_TEXT:
4234 *pref->varp.colorp = pref->default_val.color;
4238 pref->custom_cbs.reset_cb(pref);