2 * Routines for handling preferences
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
39 #include <epan/filesystem.h>
40 #include <epan/address.h>
41 #include <epan/addr_resolv.h>
42 #include <epan/oids.h>
44 #include <epan/geoip_db.h>
46 #include <epan/packet.h>
47 #include <epan/prefs.h>
48 #include <epan/proto.h>
49 #include <epan/strutil.h>
50 #include <epan/column.h>
52 #include <wsutil/file_util.h>
54 #include <epan/prefs-int.h>
55 #include <epan/uat-int.h>
57 #include "epan/filter_expressions.h"
59 #include "epan/wmem/wmem.h"
61 /* Internal functions */
62 static module_t
*find_subtree(module_t
*parent
, const char *tilte
);
63 static module_t
*prefs_register_module_or_subtree(module_t
*parent
,
64 const char *name
, const char *title
, const char *description
, gboolean is_subtree
,
65 void (*apply_cb
)(void), gboolean use_gui
);
66 static prefs_set_pref_e
set_pref(gchar
*, const gchar
*, void *, gboolean
);
67 static char * join_string_list(GList
*);
68 static void free_col_info(GList
*);
69 static void pre_init_prefs(void);
70 static gboolean
prefs_is_column_visible(const gchar
*cols_hidden
, fmt_data
*cfmt
);
71 static gboolean
parse_column_format(fmt_data
*cfmt
, const char *fmt
);
72 static void try_convert_to_custom_column(gpointer
*el_data
);
75 #define PF_NAME "preferences"
76 #define OLD_GPF_NAME "wireshark.conf" /* old name for global preferences file */
78 static gboolean prefs_initialized
= FALSE
;
79 static gboolean prefs_pre_initialized
= FALSE
;
80 static gchar
*gpf_path
= NULL
;
81 static gchar
*cols_hidden_list
= NULL
;
84 * XXX - variables to allow us to attempt to interpret the first
85 * "mgcp.{tcp,udp}.port" in a preferences file as
86 * "mgcp.{tcp,udp}.gateway_port" and the second as
87 * "mgcp.{tcp,udp}.callagent_port".
89 static int mgcp_tcp_port_count
;
90 static int mgcp_udp_port_count
;
94 static const enum_val_t gui_ptree_line_style
[] = {
96 {"SOLID", "SOLID", 1},
97 {"DOTTED", "DOTTED", 2},
98 {"TABBED", "TABBED", 3},
102 static const enum_val_t gui_ptree_expander_style
[] = {
104 {"SQUARE", "SQUARE", 1},
105 {"TRIANGLE", "TRIANGLE", 2},
106 {"CIRCULAR", "CIRCULAR", 3},
110 static const enum_val_t gui_hex_dump_highlight_style
[] = {
112 {"INVERSE", "INVERSE", 1},
116 static const enum_val_t gui_console_open_type
[] = {
117 {"NEVER", "NEVER", console_open_never
},
118 {"AUTOMATIC", "AUTOMATIC", console_open_auto
},
119 {"ALWAYS", "ALWAYS", console_open_always
},
123 static const enum_val_t gui_version_placement_type
[] = {
124 {"WELCOME", "WELCOME", version_welcome_only
},
125 {"TITLE", "TITLE", version_title_only
},
126 {"BOTH", "BOTH", version_both
},
127 {"NEITHER", "NEITHER", version_neither
},
131 static const enum_val_t gui_fileopen_style
[] = {
132 {"LAST_OPENED", "LAST_OPENED", 0},
133 {"SPECIFIED", "SPECIFIED", 1},
137 /* GTK knows of two ways representing "both", vertical and horizontal aligned.
138 * as this may not work on other guis, we use only "both" in general here */
139 static const enum_val_t gui_toolbar_style
[] = {
140 {"ICONS", "ICONS", 0},
146 static const enum_val_t gui_layout_content
[] = {
148 {"PLIST", "PLIST", 1},
149 {"PDETAILS", "PDETAILS", 2},
150 {"PBYTES", "PBYTES", 3},
154 static const enum_val_t gui_update_channel
[] = {
155 {"DEVELOPMENT", "DEVELOPMENT", UPDATE_CHANNEL_DEVELOPMENT
},
156 {"STABLE", "STABLE", UPDATE_CHANNEL_STABLE
},
160 #if defined(HAVE_PCAP_CREATE)
161 /* Can set monitor mode and buffer size. */
162 static gint num_capture_cols
= 7;
163 static const gchar
*capture_cols
[7] = {
172 #define CAPTURE_COL_TYPE_DESCRIPTION \
173 "Possible values: INTERFACE, LINK, PMODE, SNAPLEN, MONITOR, BUFFER, FILTER\n"
174 #elif defined(_WIN32) && !defined (HAVE_PCAP_CREATE)
175 /* Can set buffer size but not monitor mode. */
176 static gint num_capture_cols
= 6;
177 static const gchar
*capture_cols
[6] = {
185 #define CAPTURE_COL_TYPE_DESCRIPTION \
186 "Possible values: INTERFACE, LINK, PMODE, SNAPLEN, BUFFER, FILTER\n"
188 /* Can neither set buffer size nor monitor mode. */
189 static gint num_capture_cols
= 5;
190 static const gchar
*capture_cols
[5] = {
197 #define CAPTURE_COL_TYPE_DESCRIPTION \
198 "Possible values: INTERFACE, LINK, PMODE, SNAPLEN, FILTER\n"
202 * List of all modules with preference settings.
204 static wmem_tree_t
*prefs_modules
= NULL
;
207 * List of all modules that should show up at the top level of the
208 * tree in the preference dialog box.
210 static wmem_tree_t
*prefs_top_level_modules
= NULL
;
212 /** Sets up memory used by proto routines. Called at program startup */
216 prefs_modules
= wmem_tree_new(wmem_epan_scope());
217 prefs_top_level_modules
= wmem_tree_new(wmem_epan_scope());
221 free_pref(gpointer data
, gpointer user_data _U_
)
223 pref_t
*pref
= (pref_t
*)data
;
225 switch (pref
->type
) {
230 case PREF_STATIC_TEXT
:
237 g_free((char *)*pref
->varp
.string
);
238 *pref
->varp
.string
= NULL
;
239 g_free(pref
->default_val
.string
);
240 pref
->default_val
.string
= NULL
;
243 g_free(*pref
->varp
.range
);
244 *pref
->varp
.range
= NULL
;
245 g_free(pref
->default_val
.range
);
246 pref
->default_val
.range
= NULL
;
249 if (strcmp(pref
->name
, "columns") == 0)
250 pref
->stashed_val
.boolval
= TRUE
;
251 pref
->custom_cbs
.free_cb(pref
);
259 free_module_prefs(module_t
*module
, gpointer data _U_
)
262 g_list_foreach(module
->prefs
, free_pref
, NULL
);
263 g_list_free(module
->prefs
);
265 module
->prefs
= NULL
;
266 module
->numprefs
= 0;
267 if (module
->submodules
) {
268 prefs_modules_foreach_submodules(module
, free_module_prefs
, NULL
);
270 /* We don't free the actual module: its submodules pointer points to
271 a wmem_tree and the module itself is stored in a wmem_tree
277 /** Frees memory used by proto routines. Called at program shutdown */
281 /* This isn't strictly necessary since we're exiting anyway, but let's
282 * do what clean up we can.
284 prefs_modules_foreach(free_module_prefs
, NULL
);
288 * Register a module that will have preferences.
289 * Specify the module under which to register it or NULL to register it
290 * at the top level, the name used for the module in the preferences file,
291 * the title used in the tab for it in a preferences dialog box, and a
292 * routine to call back when we apply the preferences.
295 prefs_register_module(module_t
*parent
, const char *name
, const char *title
,
296 const char *description
, void (*apply_cb
)(void),
297 const gboolean use_gui
)
299 return prefs_register_module_or_subtree(parent
, name
, title
, description
,
300 FALSE
, apply_cb
, use_gui
);
304 * Register a subtree that will have modules under it.
305 * Specify the module under which to register it or NULL to register it
306 * at the top level and the title used in the tab for it in a preferences
310 prefs_register_subtree(module_t
*parent
, const char *title
, const char *description
,
311 void (*apply_cb
)(void))
313 return prefs_register_module_or_subtree(parent
, NULL
, title
, description
,
315 parent
? parent
->use_gui
: FALSE
);
319 prefs_register_module_or_subtree(module_t
*parent
, const char *name
,
320 const char *title
, const char *description
,
321 gboolean is_subtree
, void (*apply_cb
)(void),
328 /* this module may have been created as a subtree item previously */
329 if ((module
= find_subtree(parent
, title
))) {
330 /* the module is currently a subtree */
332 module
->apply_cb
= apply_cb
;
333 module
->description
= description
;
335 if (prefs_find_module(name
) == NULL
) {
336 wmem_tree_insert_string(prefs_modules
, name
, module
,
337 WMEM_TREE_STRING_NOCASE
);
343 module
= wmem_new(wmem_epan_scope(), module_t
);
345 module
->title
= title
;
346 module
->description
= description
;
347 module
->apply_cb
= apply_cb
;
348 module
->prefs
= NULL
; /* no preferences, to start */
349 module
->parent
= parent
;
350 module
->submodules
= NULL
; /* no submodules, to start */
351 module
->numprefs
= 0;
352 module
->prefs_changed
= FALSE
;
353 module
->obsolete
= FALSE
;
354 module
->use_gui
= use_gui
;
357 * Do we have a module name?
362 * Make sure that only lower-case ASCII letters, numbers,
363 * underscores, hyphens, and dots appear in the name.
365 * Crash if there is, as that's an error in the code;
366 * you can make the title a nice string with capitalization,
367 * white space, punctuation, etc., but the name can be used
368 * on the command line, and shouldn't require quoting,
371 for (p
= name
; (c
= *p
) != '\0'; p
++)
372 g_assert(isascii(c
) &&
373 (islower(c
) || isdigit(c
) || c
== '_' ||
374 c
== '-' || c
== '.'));
377 * Make sure there's not already a module with that
378 * name. Crash if there is, as that's an error in the
379 * code, and the code has to be fixed not to register
380 * more than one module with the same name.
382 * We search the list of all modules; the subtree stuff
383 * doesn't require preferences in subtrees to have names
384 * that reflect the subtree they're in (that would require
385 * protocol preferences to have a bogus "protocol.", or
386 * something such as that, to be added to all their names).
388 g_assert(prefs_find_module(name
) == NULL
);
391 * Insert this module in the list of all modules.
393 wmem_tree_insert_string(prefs_modules
, name
, module
, WMEM_TREE_STRING_NOCASE
);
396 * This has no name, just a title; check to make sure it's a
397 * subtree, and crash if it's not.
399 g_assert(is_subtree
);
403 * Insert this module into the appropriate place in the display
406 if (parent
== NULL
) {
408 * It goes at the top.
410 wmem_tree_insert_string(prefs_top_level_modules
, title
, module
, WMEM_TREE_STRING_NOCASE
);
413 * It goes into the list for this module.
416 if (parent
->submodules
== NULL
)
417 parent
->submodules
= wmem_tree_new(wmem_epan_scope());
419 wmem_tree_insert_string(parent
->submodules
, title
, module
, WMEM_TREE_STRING_NOCASE
);
426 * Register that a protocol has preferences.
428 module_t
*protocols_module
= NULL
;
431 prefs_register_protocol(int id
, void (*apply_cb
)(void))
433 protocol_t
*protocol
;
436 * Have we yet created the "Protocols" subtree?
438 if (protocols_module
== NULL
) {
440 * No. Register Protocols subtree as well as any preferences
441 * for non-dissector modules.
443 prefs_register_modules();
445 protocol
= find_protocol_by_id(id
);
446 return prefs_register_module(protocols_module
,
447 proto_get_protocol_filter_name(id
),
448 proto_get_protocol_short_name(protocol
),
449 proto_get_protocol_name(id
), apply_cb
, TRUE
);
453 prefs_register_protocol_subtree(const char *subtree
, int id
, void (*apply_cb
)(void))
455 protocol_t
*protocol
;
456 module_t
*subtree_module
;
457 module_t
*new_module
;
458 char *sep
= NULL
, *ptr
= NULL
, *orig
= NULL
;
461 * Have we yet created the "Protocols" subtree?
462 * XXX - can we just do this by registering Protocols/{subtree}?
465 if (protocols_module
== NULL
) {
467 * No. Register Protocols subtree as well as any preferences
468 * for non-dissector modules.
470 prefs_register_modules();
473 subtree_module
= protocols_module
;
476 /* take a copy of the buffer, orig keeps a base pointer while ptr
477 * walks through the string */
478 orig
= ptr
= g_strdup(subtree
);
480 while (ptr
&& *ptr
) {
482 if ((sep
= strchr(ptr
, '/')))
485 if (!(new_module
= find_subtree(subtree_module
, ptr
))) {
487 * There's no such module; create it, with the description
488 * being the name (if it's later registered explicitly
489 * with a description, that will override it).
491 ptr
= wmem_strdup(wmem_epan_scope(), ptr
),
492 new_module
= prefs_register_subtree(subtree_module
, ptr
, ptr
, NULL
);
495 subtree_module
= new_module
;
503 protocol
= find_protocol_by_id(id
);
504 return prefs_register_module(subtree_module
,
505 proto_get_protocol_filter_name(id
),
506 proto_get_protocol_short_name(protocol
),
507 proto_get_protocol_name(id
), apply_cb
, TRUE
);
512 * Register that a protocol used to have preferences but no longer does,
513 * by creating an "obsolete" module for it.
516 prefs_register_protocol_obsolete(int id
)
519 protocol_t
*protocol
;
522 * Have we yet created the "Protocols" subtree?
524 if (protocols_module
== NULL
) {
526 * No. Register Protocols subtree as well as any preferences
527 * for non-dissector modules.
529 prefs_register_modules();
531 protocol
= find_protocol_by_id(id
);
532 module
= prefs_register_module(protocols_module
,
533 proto_get_protocol_filter_name(id
),
534 proto_get_protocol_short_name(protocol
),
535 proto_get_protocol_name(id
), NULL
, TRUE
);
536 module
->obsolete
= TRUE
;
541 * Register that a statistical tap has preferences.
543 * "name" is a name for the tap to use on the command line with "-o"
544 * and in preference files.
546 * "title" is a short human-readable name for the tap.
548 * "description" is a longer human-readable description of the tap.
550 module_t
*stats_module
= NULL
;
553 prefs_register_stat(const char *name
, const char *title
,
554 const char *description
, void (*apply_cb
)(void))
557 * Have we yet created the "Statistics" subtree?
559 if (stats_module
== NULL
) {
561 * No. Register Statistics subtree as well as any preferences
562 * for non-dissector modules.
564 prefs_register_modules();
567 return prefs_register_module(stats_module
, name
, title
, description
,
572 prefs_find_module(const char *name
)
574 return (module_t
*)wmem_tree_lookup_string(prefs_modules
, name
, WMEM_TREE_STRING_NOCASE
);
578 find_subtree(module_t
*parent
, const char *name
)
580 return (module_t
*)wmem_tree_lookup_string(parent
? parent
->submodules
: prefs_top_level_modules
, name
, WMEM_TREE_STRING_NOCASE
);
584 * Call a callback function, with a specified argument, for each module
585 * in a list of modules. If the list is NULL, searches the top-level
586 * list in the display tree of modules. If any callback returns a
587 * non-zero value, we stop and return that value, otherwise we
590 * Ignores "obsolete" modules; their sole purpose is to allow old
591 * preferences for dissectors that no longer have preferences to be
592 * silently ignored in preference files. Does not ignore subtrees,
593 * as this can be used when walking the display tree of modules.
603 call_foreach_cb(void *value
, void *data
)
605 module_t
*module
= (module_t
*)value
;
606 call_foreach_t
*call_data
= (call_foreach_t
*)data
;
608 if (!module
->obsolete
)
609 call_data
->ret
= (*call_data
->callback
)(module
, call_data
->user_data
);
611 return (call_data
->ret
!= 0);
615 prefs_module_list_foreach(wmem_tree_t
*module_list
, module_cb callback
,
618 call_foreach_t call_data
;
620 if (module_list
== NULL
)
621 module_list
= prefs_top_level_modules
;
623 call_data
.callback
= callback
;
624 call_data
.user_data
= user_data
;
626 wmem_tree_foreach(module_list
, call_foreach_cb
, &call_data
);
627 return call_data
.ret
;
631 * Returns TRUE if module has any submodules
634 prefs_module_has_submodules(module_t
*module
)
636 if (module
->submodules
== NULL
) {
640 if (wmem_tree_is_empty(module
->submodules
)) {
648 * Call a callback function, with a specified argument, for each module
649 * in the list of all modules. (This list does not include subtrees.)
651 * Ignores "obsolete" modules; their sole purpose is to allow old
652 * preferences for dissectors that no longer have preferences to be
653 * silently ignored in preference files.
656 prefs_modules_foreach(module_cb callback
, gpointer user_data
)
658 return prefs_module_list_foreach(prefs_modules
, callback
, user_data
);
662 * Call a callback function, with a specified argument, for each submodule
663 * of specified modules. If the module is NULL, goes through the top-level
664 * list in the display tree of modules.
666 * Ignores "obsolete" modules; their sole purpose is to allow old
667 * preferences for dissectors that no longer have preferences to be
668 * silently ignored in preference files. Does not ignore subtrees,
669 * as this can be used when walking the display tree of modules.
672 prefs_modules_foreach_submodules(module_t
*module
, module_cb callback
,
675 return prefs_module_list_foreach((module
)?module
->submodules
:prefs_top_level_modules
, callback
, user_data
);
679 call_apply_cb(void *value
, void *data _U_
)
681 module_t
*module
= (module_t
*)value
;
683 if (module
->obsolete
)
685 if (module
->prefs_changed
) {
686 if (module
->apply_cb
!= NULL
)
687 (*module
->apply_cb
)();
688 module
->prefs_changed
= FALSE
;
694 * Call the "apply" callback function for each module if any of its
695 * preferences have changed, and then clear the flag saying its
696 * preferences have changed, as the module has been notified of that
700 prefs_apply_all(void)
702 wmem_tree_foreach(prefs_modules
, call_apply_cb
, NULL
);
706 * Call the "apply" callback function for a specific module if any of
707 * its preferences have changed, and then clear the flag saying its
708 * preferences have changed, as the module has been notified of that
712 prefs_apply(module_t
*module
)
714 if (module
&& module
->prefs_changed
)
715 call_apply_cb(module
, NULL
);
719 * Register a preference in a module's list of preferences.
720 * If it has a title, give it an ordinal number; otherwise, it's a
721 * preference that won't show up in the UI, so it shouldn't get an
722 * ordinal number (the ordinal should be the ordinal in the set of
723 * *visible* preferences).
726 register_preference(module_t
*module
, const char *name
, const char *title
,
727 const char *description
, pref_type_t type
)
732 preference
= g_new(pref_t
,1);
733 preference
->name
= name
;
734 preference
->title
= title
;
735 preference
->description
= description
;
736 preference
->type
= type
;
738 preference
->ordinal
= module
->numprefs
;
740 preference
->ordinal
= -1; /* no ordinal for you */
743 * Make sure that only lower-case ASCII letters, numbers,
744 * underscores, and dots appear in the preference name.
746 * Crash if there is, as that's an error in the code;
747 * you can make the title and description nice strings
748 * with capitalization, white space, punctuation, etc.,
749 * but the name can be used on the command line,
750 * and shouldn't require quoting, shifting, etc.
752 for (p
= name
; *p
!= '\0'; p
++)
753 if (!(isascii((guchar
)*p
) &&
754 (islower((guchar
)*p
) || isdigit((guchar
)*p
) || *p
== '_' || *p
== '.')))
755 g_error("Preference %s.%s contains invalid characters", module
->name
, name
);
758 * Make sure there's not already a preference with that
759 * name. Crash if there is, as that's an error in the
760 * code, and the code has to be fixed not to register
761 * more than one preference with the same name.
763 if (prefs_find_preference(module
, name
) != NULL
)
764 g_error("Preference %s has already been registered", name
);
766 if ((type
!= PREF_OBSOLETE
) &&
767 /* Don't compare if it's a subtree */
768 (module
->name
!= NULL
)) {
770 * Make sure the preference name doesn't begin with the
771 * module name, as that's redundant and Just Silly.
773 if (!((strncmp(name
, module
->name
, strlen(module
->name
)) != 0) ||
774 (((name
[strlen(module
->name
)]) != '.') && ((name
[strlen(module
->name
)]) != '_'))))
775 g_error("Preference %s begins with the module name", name
);
779 * There isn't already one with that name, so add the
782 module
->prefs
= g_list_append(module
->prefs
, preference
);
790 * Find a preference in a module's list of preferences, given the module
791 * and the preference's name.
799 preference_match(gconstpointer a
, gconstpointer b
)
801 const pref_t
*pref
= (const pref_t
*)a
;
802 const char *name
= (const char *)b
;
804 return strcmp(name
, pref
->name
);
808 module_find_pref_cb(void *value
, void *data
)
810 find_pref_arg_t
* arg
= (find_pref_arg_t
*)data
;
812 module_t
*module
= (module_t
*)value
;
817 list_entry
= g_list_find_custom(module
->prefs
, arg
->name
,
820 if (list_entry
== NULL
)
823 arg
->list_entry
= list_entry
;
828 prefs_find_preference(module_t
*module
, const char *name
)
834 return NULL
; /* invalid parameters */
836 list_entry
= g_list_find_custom(module
->prefs
, name
,
839 if (list_entry
== NULL
)
841 arg
.list_entry
= NULL
;
842 if (module
->submodules
!= NULL
)
845 wmem_tree_foreach(module
->submodules
, module_find_pref_cb
, &arg
);
848 list_entry
= arg
.list_entry
;
851 if (list_entry
== NULL
)
852 return NULL
; /* no such preference */
854 return (struct preference
*) list_entry
->data
;
858 * Returns TRUE if the given protocol has registered preferences
861 prefs_is_registered_protocol(const char *name
)
863 module_t
*m
= prefs_find_module(name
);
865 return (m
!= NULL
&& !m
->obsolete
);
869 * Returns the module title of a registered protocol
872 prefs_get_title_by_name(const char *name
)
874 module_t
*m
= prefs_find_module(name
);
876 return (m
!= NULL
&& !m
->obsolete
) ? m
->title
: NULL
;
880 * Register a preference with an unsigned integral value.
883 prefs_register_uint_preference(module_t
*module
, const char *name
,
884 const char *title
, const char *description
,
885 guint base
, guint
*var
)
889 preference
= register_preference(module
, name
, title
, description
,
891 preference
->varp
.uint
= var
;
892 preference
->default_val
.uint
= *var
;
893 g_assert(base
> 0 && base
!= 1 && base
< 37);
894 preference
->info
.base
= base
;
898 * XXX Add a prefs_register_{uint16|port}_preference which sets max_value?
903 * Register a "custom" preference with a unsigned integral value.
904 * XXX - This should be temporary until we can find a better way
905 * to do "custom" preferences
908 prefs_register_uint_custom_preference(module_t
*module
, const char *name
,
909 const char *title
, const char *description
,
910 struct pref_custom_cbs
* custom_cbs
, guint
*var
)
914 preference
= register_preference(module
, name
, title
, description
,
917 preference
->custom_cbs
= *custom_cbs
;
918 preference
->varp
.uint
= var
;
919 preference
->default_val
.uint
= *var
;
923 * Register a preference with an Boolean value.
926 prefs_register_bool_preference(module_t
*module
, const char *name
,
927 const char *title
, const char *description
,
932 preference
= register_preference(module
, name
, title
, description
,
934 preference
->varp
.boolp
= var
;
935 preference
->default_val
.boolval
= *var
;
939 * Register a preference with an enumerated value.
942 prefs_register_enum_preference(module_t
*module
, const char *name
,
943 const char *title
, const char *description
,
944 gint
*var
, const enum_val_t
*enumvals
,
945 gboolean radio_buttons
)
949 preference
= register_preference(module
, name
, title
, description
,
951 preference
->varp
.enump
= var
;
952 preference
->default_val
.enumval
= *var
;
953 preference
->info
.enum_info
.enumvals
= enumvals
;
954 preference
->info
.enum_info
.radio_buttons
= radio_buttons
;
958 register_string_like_preference(module_t
*module
, const char *name
,
959 const char *title
, const char *description
,
960 const char **var
, pref_type_t type
)
965 preference
= register_preference(module
, name
, title
, description
,
969 * String preference values should be non-null (as you can't
970 * keep them null after using the preferences GUI, you can at best
971 * have them be null strings) and freeable (as we free them
972 * if we change them).
974 * If the value is a null pointer, make it a copy of a null
975 * string, otherwise make it a copy of the value.
979 varcopy
= g_strdup("");
981 *var
= g_strdup(*var
);
982 varcopy
= g_strdup(*var
);
984 preference
->varp
.string
= var
;
985 preference
->default_val
.string
= varcopy
;
986 preference
->stashed_val
.string
= NULL
;
992 * Register a preference with a character-string value.
995 prefs_register_string_preference(module_t
*module
, const char *name
,
996 const char *title
, const char *description
,
999 register_string_like_preference(module
, name
, title
, description
, var
,
1004 * Register a "custom" preference with a character-string value.
1005 * XXX - This should be temporary until we can find a better way
1006 * to do "custom" preferences
1009 prefs_register_string_custom_preference(module_t
*module
, const char *name
,
1010 const char *title
, const char *description
,
1011 struct pref_custom_cbs
* custom_cbs
, const char **var
)
1015 preference
= register_string_like_preference(module
, name
, title
, description
, var
,
1018 preference
->custom_cbs
= *custom_cbs
;
1023 * Register a preference with a file name (string) value.
1026 prefs_register_filename_preference(module_t
*module
, const char *name
,
1027 const char *title
, const char *description
,
1030 register_string_like_preference(module
, name
, title
, description
, var
,
1035 * Register a preference with a directory name (string) value.
1038 prefs_register_directory_preference(module_t
*module
, const char *name
,
1039 const char *title
, const char *description
,
1042 register_string_like_preference(module
, name
, title
, description
, var
,
1047 * Register a preference with a ranged value.
1050 prefs_register_range_preference(module_t
*module
, const char *name
,
1051 const char *title
, const char *description
,
1052 range_t
**var
, guint32 max_value
)
1056 preference
= register_preference(module
, name
, title
, description
,
1058 preference
->info
.max_value
= max_value
;
1062 * Range preference values should be non-null (as you can't
1063 * keep them null after using the preferences GUI, you can at best
1064 * have them be empty ranges) and freeable (as we free them
1065 * if we change them).
1067 * If the value is a null pointer, make it an empty range.
1070 *var
= range_empty();
1071 preference
->varp
.range
= var
;
1072 preference
->default_val
.range
= range_copy(*var
);
1073 preference
->stashed_val
.range
= NULL
;
1077 * Register a static text 'preference'. It can be used to add explanatory
1078 * text inline with other preferences in the GUI.
1079 * Note: Static preferences are not saved to the preferences file.
1082 prefs_register_static_text_preference(module_t
*module
, const char *name
,
1084 const char *description
)
1086 register_preference(module
, name
, title
, description
, PREF_STATIC_TEXT
);
1090 * Register a uat 'preference'. It adds a button that opens the uat's window in the
1091 * preferences tab of the module.
1094 prefs_register_uat_preference(module_t
*module
, const char *name
,
1095 const char *title
, const char *description
,
1099 pref_t
* preference
= register_preference(module
, name
, title
, description
, PREF_UAT
);
1101 preference
->varp
.uat
= uat
;
1105 * Register a color preference.
1108 prefs_register_color_preference(module_t
*module
, const char *name
,
1109 const char *title
, const char *description
,
1112 pref_t
* preference
= register_preference(module
, name
, title
, description
, PREF_COLOR
);
1114 preference
->varp
.colorp
= color
;
1115 preference
->default_val
.color
= *color
;
1119 * Register a "custom" preference with a list.
1120 * XXX - This should be temporary until we can find a better way
1121 * to do "custom" preferences
1123 typedef void (*pref_custom_list_init_cb
) (pref_t
* pref
, GList
** value
);
1126 prefs_register_list_custom_preference(module_t
*module
, const char *name
,
1127 const char *title
, const char *description
,
1128 struct pref_custom_cbs
* custom_cbs
,
1129 pref_custom_list_init_cb init_cb
,
1132 pref_t
* preference
= register_preference(module
, name
, title
, description
, PREF_CUSTOM
);
1134 preference
->custom_cbs
= *custom_cbs
;
1135 init_cb(preference
, list
);
1139 * Register a custom preference.
1142 prefs_register_custom_preference(module_t
*module
, const char *name
,
1143 const char *title
, const char *description
,
1144 struct pref_custom_cbs
* custom_cbs
,
1145 void **custom_data _U_
)
1147 pref_t
* preference
= register_preference(module
, name
, title
, description
, PREF_CUSTOM
);
1149 preference
->custom_cbs
= *custom_cbs
;
1150 /* XXX - wait until we can handle void** pointers
1151 preference->custom_cbs.init_cb(preference, custom_data);
1156 * Register a preference that used to be supported but no longer is.
1159 prefs_register_obsolete_preference(module_t
*module
, const char *name
)
1161 register_preference(module
, name
, NULL
, NULL
, PREF_OBSOLETE
);
1165 * Check to see if a preference is obsolete.
1168 prefs_get_preference_obsolete(pref_t
*pref
)
1171 return pref
->type
== PREF_OBSOLETE
? TRUE
: FALSE
;
1177 * Make a preference obsolete.
1179 extern prefs_set_pref_e
1180 prefs_set_preference_obsolete(pref_t
*pref
)
1183 pref
->type
= PREF_OBSOLETE
;
1184 return PREFS_SET_OK
;
1186 return PREFS_SET_NO_SUCH_PREF
;
1189 /* Return the value assigned to the given uint preference. */
1191 prefs_get_uint_preference(pref_t
*pref
)
1193 if (pref
&& pref
->type
== PREF_UINT
)
1194 return *pref
->varp
.uint
;
1199 * Call a callback function, with a specified argument, for each preference
1200 * in a given module.
1202 * If any of the callbacks return a non-zero value, stop and return that
1203 * value, otherwise return 0.
1206 prefs_pref_foreach(module_t
*module
, pref_cb callback
, gpointer user_data
)
1212 for (elem
= g_list_first(module
->prefs
); elem
!= NULL
; elem
= g_list_next(elem
)) {
1213 pref
= (pref_t
*)elem
->data
;
1214 if (pref
->type
== PREF_OBSOLETE
) {
1216 * This preference is no longer supported; it's
1217 * not a real preference, so we don't call the
1218 * callback for it (i.e., we treat it as if it
1219 * weren't found in the list of preferences,
1220 * and we weren't called in the first place).
1225 ret
= (*callback
)(pref
, user_data
);
1232 static const enum_val_t print_format_vals
[] = {
1233 { "text", "Plain Text", PR_FMT_TEXT
},
1234 { "postscript", "Postscript", PR_FMT_PS
},
1238 static const enum_val_t print_dest_vals
[] = {
1240 /* "PR_DEST_CMD" means "to printer" on Windows */
1241 { "command", "Printer", PR_DEST_CMD
},
1243 { "command", "Command", PR_DEST_CMD
},
1245 { "file", "File", PR_DEST_FILE
},
1249 static const enum_val_t gui_qt_language
[] = {
1250 {"Auto-Detect", "auto", 0},
1251 {"English", "en", 1},
1252 {"French", "fr", 2},
1253 {"German", "de", 3},
1254 {"Chinese", "zh_CN", 4},
1259 stats_callback(void)
1261 /* Test for a sane tap update interval */
1262 if (prefs
.tap_update_interval
< 100 || prefs
.tap_update_interval
> 10000)
1263 prefs
.tap_update_interval
= TAP_UPDATE_DEFAULT_INTERVAL
;
1265 #ifdef HAVE_LIBPORTAUDIO
1266 /* Test for a sane max channels entry */
1267 if (prefs
.rtp_player_max_visible
< 1 || prefs
.rtp_player_max_visible
> 10)
1268 prefs
.rtp_player_max_visible
= RTP_PLAYER_DEFAULT_VISIBLE
;
1276 /* Ensure there is at least one file count */
1277 if (prefs
.gui_recent_files_count_max
== 0)
1278 prefs
.gui_recent_files_count_max
= 10;
1280 /* Ensure there is at least one display filter entry */
1281 if (prefs
.gui_recent_df_entries_max
== 0)
1282 prefs
.gui_recent_df_entries_max
= 10;
1286 gui_layout_callback(void)
1288 if (prefs
.gui_layout_type
== layout_unused
||
1289 prefs
.gui_layout_type
>= layout_type_max
) {
1290 /* XXX - report an error? It's not a syntax error - we'd need to
1291 add a way of reporting a *semantic* error. */
1292 prefs
.gui_layout_type
= layout_type_5
;
1296 /******************************************************
1297 * All custom preference function callbacks
1298 ******************************************************/
1299 static void custom_pref_no_cb(pref_t
* pref _U_
) {}
1303 * Console log level custom preference functions
1306 console_log_level_reset_cb(pref_t
* pref
)
1308 *pref
->varp
.uint
= pref
->default_val
.uint
;
1311 static prefs_set_pref_e
1312 console_log_level_set_cb(pref_t
* pref
, const gchar
* value
, gboolean
* changed
)
1316 uval
= (guint
)strtoul(value
, NULL
, 10);
1318 if (*pref
->varp
.uint
!= uval
) {
1320 *pref
->varp
.uint
= uval
;
1323 if (*pref
->varp
.uint
& (G_LOG_LEVEL_INFO
|G_LOG_LEVEL_DEBUG
)) {
1325 * GLib >= 2.32 drops INFO and DEBUG messages by default. Tell
1326 * it not to do that.
1328 g_setenv("G_MESSAGES_DEBUG", "all", TRUE
);
1331 return PREFS_SET_OK
;
1334 static const char * console_log_level_type_name_cb(void) {
1338 static char * console_log_level_type_description_cb(void) {
1339 return g_strdup_printf(
1340 "Console log level (for debugging)\n"
1341 "A bitmask of log levels:\n"
1350 static gboolean
console_log_level_is_default_cb(pref_t
* pref
) {
1351 return *pref
->varp
.uint
== pref
->default_val
.uint
;
1354 static char * console_log_level_to_str_cb(pref_t
* pref
, gboolean default_val
) {
1355 return g_strdup_printf("%u", default_val
? pref
->default_val
.uint
: *pref
->varp
.uint
);
1359 * Column preference functions
1361 #define PRS_COL_HIDDEN "column.hidden"
1362 #define PRS_COL_FMT "column.format"
1363 #define PRS_COL_NUM "column.number"
1364 static module_t
*gui_column_module
= NULL
;
1367 column_hidden_free_cb(pref_t
* pref
)
1369 g_free((char *)*pref
->varp
.string
);
1370 *pref
->varp
.string
= NULL
;
1371 g_free(pref
->default_val
.string
);
1372 pref
->default_val
.string
= NULL
;
1376 column_hidden_reset_cb(pref_t
* pref
)
1378 g_free((void *)*pref
->varp
.string
);
1379 *pref
->varp
.string
= g_strdup(pref
->default_val
.string
);
1382 static prefs_set_pref_e
1383 column_hidden_set_cb(pref_t
* pref
, const gchar
* value
, gboolean
* changed
)
1387 pref_t
*format_pref
;
1389 if (*pref
->varp
.string
) {
1390 if (strcmp(*pref
->varp
.string
, value
) != 0) {
1392 g_free((void *)*pref
->varp
.string
);
1393 *pref
->varp
.string
= g_strdup(value
);
1396 *pref
->varp
.string
= g_strdup(value
);
1400 * Set the "visible" flag for the existing columns; we need to
1401 * do this if we set PRS_COL_HIDDEN but don't set PRS_COL_FMT
1402 * after setting it (which might be the case if, for example, we
1403 * set PRS_COL_HIDDEN on the command line).
1405 format_pref
= prefs_find_preference(gui_column_module
, PRS_COL_FMT
);
1406 for (clp
= *format_pref
->varp
.list
; clp
!= NULL
; clp
= clp
->next
) {
1407 cfmt
= (fmt_data
*)clp
->data
;
1408 cfmt
->visible
= prefs_is_column_visible(*pref
->varp
.string
, cfmt
);
1411 return PREFS_SET_OK
;
1415 column_hidden_type_name_cb(void)
1417 return "Packet list hidden columns";
1421 column_hidden_type_description_cb(void)
1423 return g_strdup("List all columns to hide in the packet list.");
1427 column_hidden_to_str_cb(pref_t
* pref
, gboolean default_val
)
1429 GString
*cols_hidden
= g_string_new ("");
1432 pref_t
*format_pref
;
1435 return g_strdup(pref
->default_val
.string
);
1437 format_pref
= prefs_find_preference(gui_column_module
, PRS_COL_FMT
);
1438 clp
= (format_pref
) ? *format_pref
->varp
.list
: NULL
;
1441 cfmt
= (fmt_data
*) clp
->data
;
1442 if ((cfmt
->fmt
== COL_CUSTOM
) && (cfmt
->custom_field
)) {
1443 prefs_fmt
= g_strdup_printf("%s:%s:%d:%c",
1444 col_format_to_string(cfmt
->fmt
),
1446 cfmt
->custom_occurrence
,
1447 cfmt
->resolved
? 'R' : 'U');
1449 prefs_fmt
= g_strdup(col_format_to_string(cfmt
->fmt
));
1451 if (!cfmt
->visible
) {
1452 if (cols_hidden
->len
)
1453 g_string_append (cols_hidden
, ",");
1454 g_string_append (cols_hidden
, prefs_fmt
);
1459 return g_string_free (cols_hidden
, FALSE
);
1463 column_hidden_is_default_cb(pref_t
* pref
)
1465 char *cur_hidden_str
= column_hidden_to_str_cb(pref
, FALSE
);
1466 gboolean is_default
= g_strcmp0(cur_hidden_str
, pref
->default_val
.string
) == 0;
1468 g_free(cur_hidden_str
);
1473 /* Number of columns "preference". This is only used internally and is not written to the
1477 column_num_reset_cb(pref_t
* pref
)
1479 *pref
->varp
.uint
= pref
->default_val
.uint
;
1482 static prefs_set_pref_e
1483 column_num_set_cb(pref_t
* pref _U_
, const gchar
* value _U_
, gboolean
* changed _U_
)
1485 /* Don't write this to the preferences file */
1486 return PREFS_SET_OK
;
1490 column_num_type_name_cb(void)
1496 column_num_type_description_cb(void)
1498 return g_strdup("");
1502 column_num_is_default_cb(pref_t
* pref _U_
)
1508 column_num_to_str_cb(pref_t
* pref _U_
, gboolean default_val _U_
)
1510 return g_strdup("");
1514 * Column format custom preference functions
1517 column_format_init_cb(pref_t
* pref
, GList
** value
)
1519 fmt_data
*src_cfmt
, *dest_cfmt
;
1522 pref
->varp
.list
= value
;
1524 pref
->default_val
.list
= NULL
;
1525 for (entry
= *pref
->varp
.list
; entry
!= NULL
; entry
= g_list_next(entry
)) {
1526 src_cfmt
= (fmt_data
*)entry
->data
;
1527 dest_cfmt
= g_new(fmt_data
,1);
1528 dest_cfmt
->title
= g_strdup(src_cfmt
->title
);
1529 dest_cfmt
->fmt
= src_cfmt
->fmt
;
1530 if (src_cfmt
->custom_field
) {
1531 dest_cfmt
->custom_field
= g_strdup(src_cfmt
->custom_field
);
1532 dest_cfmt
->custom_occurrence
= src_cfmt
->custom_occurrence
;
1534 dest_cfmt
->custom_field
= NULL
;
1535 dest_cfmt
->custom_occurrence
= 0;
1537 dest_cfmt
->visible
= src_cfmt
->visible
;
1538 dest_cfmt
->resolved
= src_cfmt
->resolved
;
1539 pref
->default_val
.list
= g_list_append(pref
->default_val
.list
, dest_cfmt
);
1544 column_format_free_cb(pref_t
* pref
)
1546 free_col_info(*pref
->varp
.list
);
1547 free_col_info(pref
->default_val
.list
);
1551 column_format_reset_cb(pref_t
* pref
)
1553 fmt_data
*src_cfmt
, *dest_cfmt
;
1555 pref_t
*col_num_pref
;
1557 free_col_info(*pref
->varp
.list
);
1558 *pref
->varp
.list
= NULL
;
1560 for (entry
= pref
->default_val
.list
; entry
!= NULL
; entry
= g_list_next(entry
)) {
1561 src_cfmt
= (fmt_data
*)entry
->data
;
1562 dest_cfmt
= g_new(fmt_data
,1);
1563 dest_cfmt
->title
= g_strdup(src_cfmt
->title
);
1564 dest_cfmt
->fmt
= src_cfmt
->fmt
;
1565 if (src_cfmt
->custom_field
) {
1566 dest_cfmt
->custom_field
= g_strdup(src_cfmt
->custom_field
);
1567 dest_cfmt
->custom_occurrence
= src_cfmt
->custom_occurrence
;
1569 dest_cfmt
->custom_field
= NULL
;
1570 dest_cfmt
->custom_occurrence
= 0;
1572 dest_cfmt
->visible
= src_cfmt
->visible
;
1573 dest_cfmt
->resolved
= src_cfmt
->resolved
;
1574 *pref
->varp
.list
= g_list_append(*pref
->varp
.list
, dest_cfmt
);
1577 col_num_pref
= prefs_find_preference(gui_column_module
, PRS_COL_NUM
);
1578 g_assert(col_num_pref
!= NULL
); /* Should never happen */
1579 column_num_reset_cb(col_num_pref
);
1582 static prefs_set_pref_e
1583 column_format_set_cb(pref_t
* pref
, const gchar
* value
, gboolean
* changed _U_
)
1585 GList
*col_l
, *col_l_elt
;
1588 pref_t
*hidden_pref
, *col_num_pref
;
1590 col_l
= prefs_get_string_list(value
);
1592 return PREFS_SET_SYNTAX_ERR
;
1593 if ((g_list_length(col_l
) % 2) != 0) {
1594 /* A title didn't have a matching format. */
1595 prefs_clear_string_list(col_l
);
1596 return PREFS_SET_SYNTAX_ERR
;
1598 /* Check to make sure all column formats are valid. */
1599 col_l_elt
= g_list_first(col_l
);
1601 fmt_data cfmt_check
;
1603 /* Go past the title. */
1604 col_l_elt
= col_l_elt
->next
;
1606 /* Parse the format to see if it's valid. */
1607 if (!parse_column_format(&cfmt_check
, (char *)col_l_elt
->data
)) {
1608 /* It's not a valid column format. */
1609 prefs_clear_string_list(col_l
);
1610 return PREFS_SET_SYNTAX_ERR
;
1612 if (cfmt_check
.fmt
!= COL_CUSTOM
) {
1613 /* Some predefined columns have been migrated to use custom columns.
1614 * We'll convert these silently here */
1615 try_convert_to_custom_column(&col_l_elt
->data
);
1617 /* We don't need the custom column field on this pass. */
1618 g_free(cfmt_check
.custom_field
);
1621 /* Go past the format. */
1622 col_l_elt
= col_l_elt
->next
;
1625 /* They're all valid; process them. */
1626 free_col_info(*pref
->varp
.list
);
1627 *pref
->varp
.list
= NULL
;
1628 hidden_pref
= prefs_find_preference(gui_column_module
, PRS_COL_HIDDEN
);
1629 g_assert(hidden_pref
!= NULL
); /* Should never happen */
1630 col_num_pref
= prefs_find_preference(gui_column_module
, PRS_COL_NUM
);
1631 g_assert(col_num_pref
!= NULL
); /* Should never happen */
1632 llen
= g_list_length(col_l
);
1633 *col_num_pref
->varp
.uint
= llen
/ 2;
1634 col_l_elt
= g_list_first(col_l
);
1636 cfmt
= g_new(fmt_data
,1);
1637 cfmt
->title
= g_strdup((gchar
*)col_l_elt
->data
);
1638 col_l_elt
= col_l_elt
->next
;
1639 parse_column_format(cfmt
, (char *)col_l_elt
->data
);
1640 cfmt
->visible
= prefs_is_column_visible((gchar
*)(*hidden_pref
->varp
.string
), cfmt
);
1641 col_l_elt
= col_l_elt
->next
;
1642 *pref
->varp
.list
= g_list_append(*pref
->varp
.list
, cfmt
);
1645 prefs_clear_string_list(col_l
);
1646 column_hidden_free_cb(hidden_pref
);
1647 return PREFS_SET_OK
;
1652 column_format_type_name_cb(void)
1654 return "Packet list column format";
1658 column_format_type_description_cb(void)
1660 return g_strdup("Each pair of strings consists of a column title and its format");
1664 column_format_is_default_cb(pref_t
* pref
)
1666 GList
*clp
= *pref
->varp
.list
,
1667 *pref_col
= g_list_first(clp
),
1668 *def_col
= g_list_first(pref
->default_val
.list
);
1669 fmt_data
*cfmt
, *def_cfmt
;
1670 gboolean is_default
= TRUE
;
1671 pref_t
*col_num_pref
;
1673 /* See if the column data has changed from the default */
1674 col_num_pref
= prefs_find_preference(gui_column_module
, PRS_COL_NUM
);
1675 if (col_num_pref
&& *col_num_pref
->varp
.uint
!= col_num_pref
->default_val
.uint
) {
1678 while (pref_col
&& def_col
) {
1679 cfmt
= (fmt_data
*) pref_col
->data
;
1680 def_cfmt
= (fmt_data
*) def_col
->data
;
1681 if ((g_strcmp0(cfmt
->title
, def_cfmt
->title
) != 0) ||
1682 (cfmt
->fmt
!= def_cfmt
->fmt
) ||
1683 (((cfmt
->fmt
== COL_CUSTOM
) && (cfmt
->custom_field
)) &&
1684 ((g_strcmp0(cfmt
->custom_field
, def_cfmt
->custom_field
) != 0) ||
1685 (cfmt
->resolved
!= def_cfmt
->resolved
)))) {
1690 pref_col
= pref_col
->next
;
1691 def_col
= def_col
->next
;
1699 column_format_to_str_cb(pref_t
* pref
, gboolean default_val
)
1701 GList
*pref_l
= default_val
? pref
->default_val
.list
: *pref
->varp
.list
;
1702 GList
*clp
= g_list_first(pref_l
);
1706 char *column_format_str
;
1710 cfmt
= (fmt_data
*) clp
->data
;
1711 col_l
= g_list_append(col_l
, g_strdup(cfmt
->title
));
1712 if ((cfmt
->fmt
== COL_CUSTOM
) && (cfmt
->custom_field
)) {
1713 prefs_fmt
= g_strdup_printf("%s:%s:%d:%c",
1714 col_format_to_string(cfmt
->fmt
),
1716 cfmt
->custom_occurrence
,
1717 cfmt
->resolved
? 'R' : 'U');
1719 prefs_fmt
= g_strdup(col_format_to_string(cfmt
->fmt
));
1721 col_l
= g_list_append(col_l
, prefs_fmt
);
1725 column_format_str
= join_string_list(col_l
);
1727 /* This frees the list of strings, but not the strings to which it
1728 refers; they are free'ed in join_string_list(). */
1730 return column_format_str
;
1734 /****** Capture column custom preference functions ******/
1736 /* This routine is only called when Wireshark is started, NOT when another profile is selected.
1737 Copy the pref->capture_columns list (just loaded with the capture_cols[] struct values)
1738 to prefs->default_val.list.
1741 capture_column_init_cb(pref_t
* pref
, GList
** capture_cols_values
)
1743 GList
*ccv_list
= *capture_cols_values
,
1748 dlist
= g_list_append(dlist
, g_strdup((gchar
*)ccv_list
->data
));
1749 ccv_list
= ccv_list
->next
;
1752 pref
->default_val
.list
= dlist
;
1753 pref
->varp
.list
= &prefs
.capture_columns
;
1754 pref
->stashed_val
.boolval
= FALSE
;
1757 /* Free the prefs->capture_columns list strings and remove the list entries.
1758 Note that since pref->varp.list points to &prefs.capture_columns, it is
1762 capture_column_free_cb(pref_t
* pref
)
1764 GList
*clist
= prefs
.capture_columns
;
1768 col_name
= (gchar
*)clist
->data
;
1770 clist
= g_list_remove_link(clist
, clist
);
1773 prefs
.capture_columns
= NULL
;
1775 if (pref
->stashed_val
.boolval
== TRUE
) {
1779 dlist
= pref
->default_val
.list
;
1780 while (dlist
!= NULL
) {
1781 col
= (gchar
*)dlist
->data
;
1783 dlist
= g_list_remove_link(dlist
, dlist
);
1790 /* Copy pref->default_val.list to *pref->varp.list.
1793 capture_column_reset_cb(pref_t
* pref
)
1795 GList
*vlist
, *dlist
;
1798 /* Free the column name strings and remove the links from *pref->varp.list */
1799 vlist
= *pref
->varp
.list
;
1800 while (vlist
!= NULL
) {
1801 vcol
= (gchar
*)vlist
->data
;
1803 vlist
= g_list_remove_link(vlist
, vlist
);
1808 for (dlist
= pref
->default_val
.list
; dlist
!= NULL
; dlist
= g_list_next(dlist
)) {
1809 vlist
= g_list_append(vlist
, g_strdup((gchar
*)dlist
->data
));
1811 *pref
->varp
.list
= vlist
;
1814 static prefs_set_pref_e
1815 capture_column_set_cb(pref_t
* pref
, const gchar
* value
, gboolean
* changed _U_
)
1817 GList
*col_l
= prefs_get_string_list(value
);
1823 return PREFS_SET_SYNTAX_ERR
;
1825 capture_column_free_cb(pref
);
1827 /* If value (the list of capture.columns read from preferences) is empty, set capture.columns
1828 to the full list of valid capture column names. */
1829 col_l_elt
= g_list_first(col_l
);
1830 if (!(*(gchar
*)col_l_elt
->data
)) {
1831 for (i
= 0; i
< num_capture_cols
; i
++) {
1832 col_name
= g_strdup(capture_cols
[i
]);
1833 prefs
.capture_columns
= g_list_append(prefs
.capture_columns
, col_name
);
1837 /* Verify that all the column names are valid. If not, use the entire list of valid columns.
1840 gboolean found_match
= FALSE
;
1841 col_name
= (gchar
*)col_l_elt
->data
;
1843 for (i
= 0; i
< num_capture_cols
; i
++) {
1844 if (strcmp(col_name
, capture_cols
[i
])==0) {
1850 /* One or more cols are invalid so use the entire list of valid cols. */
1851 for (i
= 0; i
< num_capture_cols
; i
++) {
1852 col_name
= g_strdup(capture_cols
[i
]);
1853 prefs
.capture_columns
= g_list_append(prefs
.capture_columns
, col_name
);
1855 pref
->varp
.list
= &prefs
.capture_columns
;
1856 return PREFS_SET_SYNTAX_ERR
;
1858 col_l_elt
= col_l_elt
->next
;
1861 col_l_elt
= g_list_first(col_l
);
1863 col_name
= (gchar
*)col_l_elt
->data
;
1864 prefs
.capture_columns
= g_list_append(prefs
.capture_columns
, col_name
);
1865 col_l_elt
= col_l_elt
->next
;
1867 pref
->varp
.list
= &prefs
.capture_columns
;
1868 return PREFS_SET_OK
;
1873 capture_column_type_name_cb(void)
1875 return "Column list";
1879 capture_column_type_description_cb(void)
1882 "List of columns to be displayed in the capture options dialog.\n"
1883 CAPTURE_COL_TYPE_DESCRIPTION
);
1887 capture_column_is_default_cb(pref_t
* pref
)
1889 GList
*pref_col
= g_list_first(prefs
.capture_columns
),
1890 *def_col
= g_list_first(pref
->default_val
.list
);
1891 gboolean is_default
= TRUE
;
1893 /* See if the column data has changed from the default */
1894 while (pref_col
&& def_col
) {
1895 if (strcmp((gchar
*)pref_col
->data
, (gchar
*)def_col
->data
) != 0) {
1899 pref_col
= pref_col
->next
;
1900 def_col
= def_col
->next
;
1903 /* Ensure the same column count */
1904 if (((pref_col
== NULL
) && (def_col
!= NULL
)) ||
1905 ((pref_col
!= NULL
) && (def_col
== NULL
)))
1912 capture_column_to_str_cb(pref_t
* pref
, gboolean default_val
)
1915 GList
*pref_l
= default_val
? pref
->default_val
.list
: prefs
.capture_columns
;
1916 GList
*clp
= g_list_first(pref_l
);
1917 GList
*col_l
= NULL
;
1918 gchar
*col
, *capture_column_str
;
1921 col
= (gchar
*) clp
->data
;
1922 col_l
= g_list_append(col_l
, g_strdup(col
));
1926 capture_column_str
= join_string_list(col_l
);
1927 /* This frees the list of strings, but not the strings to which it
1928 refers; they are free'ed in write_string_list(). */
1930 return capture_column_str
;
1935 colorized_frame_free_cb(pref_t
* pref
)
1937 g_free((char *)*pref
->varp
.string
);
1938 *pref
->varp
.string
= NULL
;
1939 g_free(pref
->default_val
.string
);
1940 pref
->default_val
.string
= NULL
;
1945 colorized_frame_reset_cb(pref_t
* pref
)
1947 g_free((void *)*pref
->varp
.string
);
1948 *pref
->varp
.string
= g_strdup(pref
->default_val
.string
);
1951 static prefs_set_pref_e
1952 colorized_frame_set_cb(pref_t
* pref
, const gchar
* value
, gboolean
* changed
)
1954 if (strcmp(*pref
->varp
.string
, value
) != 0) {
1956 g_free((void *)*pref
->varp
.string
);
1957 *pref
->varp
.string
= g_strdup(value
);
1960 return PREFS_SET_OK
;
1964 colorized_frame_type_name_cb(void)
1966 /* Don't write the colors of the 10 easy-access-colorfilters to the preferences
1967 * file until the colors can be changed in the GUI. Currently this is not really
1968 * possible since the STOCK-icons for these colors are hardcoded.
1970 * XXX Find a way to change the colors of the STOCK-icons on the fly and then
1971 * add these 10 colors to the list of colors that can be changed through
1979 colorized_frame_type_description_cb(void)
1981 return g_strdup("");
1985 colorized_frame_is_default_cb(pref_t
* pref _U_
)
1991 colorized_frame_to_str_cb(pref_t
* pref _U_
, gboolean default_val _U_
)
1993 return g_strdup("");
1997 * Register all non-dissector modules' preferences.
1999 static module_t
*gui_module
= NULL
;
2000 static module_t
*gui_color_module
= NULL
;
2001 static module_t
*nameres_module
= NULL
;
2004 prefs_register_modules(void)
2006 module_t
*printing
, *capture_module
, *console_module
,
2007 *gui_layout_module
, *gui_font_module
;
2008 struct pref_custom_cbs custom_cbs
;
2010 if (protocols_module
!= NULL
) {
2011 /* Already setup preferences */
2015 /* Ensure the "global" preferences have been initialized so the
2016 * preference API has the proper default values to work from
2021 * These are "simple" GUI preferences that can be read/written using the
2022 * preference module API. These preferences still use their own
2023 * configuration screens for access, but this cuts down on the
2024 * preference "string compare list" in set_pref()
2026 gui_module
= prefs_register_module(NULL
, "gui", "User Interface",
2027 "User Interface", &gui_callback
, FALSE
);
2029 /* gui.console_open is placed first in the list so that any problems encountered
2030 * in the following prefs can be displayed in the console window.
2032 prefs_register_enum_preference(gui_module
, "console_open",
2033 "Open a console window",
2034 "Open a console window (WIN32 only)",
2035 (gint
*)(void*)(&prefs
.gui_console_open
), gui_console_open_type
, FALSE
);
2037 prefs_register_obsolete_preference(gui_module
, "scrollbar_on_right");
2038 prefs_register_obsolete_preference(gui_module
, "packet_list_sel_browse");
2039 prefs_register_obsolete_preference(gui_module
, "protocol_tree_sel_browse");
2041 prefs_register_bool_preference(gui_module
, "tree_view_altern_colors",
2042 "Alternating colors in TreeViews",
2043 "Alternating colors in TreeViews?",
2044 &prefs
.gui_altern_colors
);
2046 prefs_register_bool_preference(gui_module
, "expert_composite_eyecandy",
2047 "Display Icons on Expert Composite Dialog Tabs",
2048 "Display Icons on Expert Composite Dialog Tabs?",
2049 &prefs
.gui_expert_composite_eyecandy
);
2051 prefs_register_bool_preference(gui_module
, "filter_toolbar_show_in_statusbar",
2052 "Place filter toolbar inside the statusbar",
2053 "Place filter toolbar inside the statusbar?",
2054 &prefs
.filter_toolbar_show_in_statusbar
);
2056 prefs_register_enum_preference(gui_module
, "protocol_tree_line_style",
2057 "Protocol-tree line style",
2058 "Protocol-tree line style",
2059 &prefs
.gui_ptree_line_style
, gui_ptree_line_style
, FALSE
);
2061 prefs_register_enum_preference(gui_module
, "protocol_tree_expander_style",
2062 "Protocol-tree expander style",
2063 "Protocol-tree expander style",
2064 &prefs
.gui_ptree_expander_style
, gui_ptree_expander_style
, FALSE
);
2066 prefs_register_enum_preference(gui_module
, "hex_dump_highlight_style",
2067 "Hex dump highlight style",
2068 "Hex dump highlight style",
2069 &prefs
.gui_hex_dump_highlight_style
, gui_hex_dump_highlight_style
, FALSE
);
2071 gui_column_module
= prefs_register_subtree(gui_module
, "Columns", "Columns", NULL
);
2073 custom_cbs
.free_cb
= column_hidden_free_cb
;
2074 custom_cbs
.reset_cb
= column_hidden_reset_cb
;
2075 custom_cbs
.set_cb
= column_hidden_set_cb
;
2076 custom_cbs
.type_name_cb
= column_hidden_type_name_cb
;
2077 custom_cbs
.type_description_cb
= column_hidden_type_description_cb
;
2078 custom_cbs
.is_default_cb
= column_hidden_is_default_cb
;
2079 custom_cbs
.to_str_cb
= column_hidden_to_str_cb
;
2080 prefs_register_string_custom_preference(gui_column_module
, PRS_COL_HIDDEN
, "Packet list hidden columns",
2081 "List all columns to hide in the packet list", &custom_cbs
, (const char **)&cols_hidden_list
);
2083 custom_cbs
.free_cb
= column_format_free_cb
;
2084 custom_cbs
.reset_cb
= column_format_reset_cb
;
2085 custom_cbs
.set_cb
= column_format_set_cb
;
2086 custom_cbs
.type_name_cb
= column_format_type_name_cb
;
2087 custom_cbs
.type_description_cb
= column_format_type_description_cb
;
2088 custom_cbs
.is_default_cb
= column_format_is_default_cb
;
2089 custom_cbs
.to_str_cb
= column_format_to_str_cb
;
2091 prefs_register_list_custom_preference(gui_column_module
, PRS_COL_FMT
, "Packet list column format",
2092 "Each pair of strings consists of a column title and its format", &custom_cbs
,
2093 column_format_init_cb
, &prefs
.col_list
);
2095 /* Number of columns. This is only used internally and is not written to the
2098 custom_cbs
.free_cb
= custom_pref_no_cb
;
2099 custom_cbs
.reset_cb
= column_num_reset_cb
;
2100 custom_cbs
.set_cb
= column_num_set_cb
;
2101 custom_cbs
.type_name_cb
= column_num_type_name_cb
;
2102 custom_cbs
.type_description_cb
= column_num_type_description_cb
;
2103 custom_cbs
.is_default_cb
= column_num_is_default_cb
;
2104 custom_cbs
.to_str_cb
= column_num_to_str_cb
;
2105 prefs_register_uint_custom_preference(gui_column_module
, PRS_COL_NUM
, "Number of columns",
2106 "Number of columns in col_list", &custom_cbs
, &prefs
.num_cols
);
2108 /* User Interface : Font */
2109 gui_font_module
= prefs_register_subtree(gui_module
, "Font", "Font", NULL
);
2111 prefs_register_obsolete_preference(gui_font_module
, "font_name");
2113 prefs_register_string_preference(gui_font_module
, "gtk2.font_name", "Font name",
2114 "Font name for packet list, protocol tree, and hex dump panes. (GTK+)", (const char **)&prefs
.gui_gtk2_font_name
);
2116 prefs_register_string_preference(gui_font_module
, "qt.font_name", "Font name",
2117 "Font name for packet list, protocol tree, and hex dump panes. (Qt)", (const char **)&prefs
.gui_qt_font_name
);
2119 /* User Interface : Colors */
2120 gui_color_module
= prefs_register_subtree(gui_module
, "Colors", "Colors", NULL
);
2122 prefs_register_color_preference(gui_color_module
, "marked_frame.fg", "Color preferences for a marked frame",
2123 "Color preferences for a marked frame", &prefs
.gui_marked_fg
);
2125 prefs_register_color_preference(gui_color_module
, "marked_frame.bg", "Color preferences for a marked frame",
2126 "Color preferences for a marked frame", &prefs
.gui_marked_bg
);
2128 prefs_register_color_preference(gui_color_module
, "ignored_frame.fg", "Color preferences for a ignored frame",
2129 "Color preferences for a ignored frame", &prefs
.gui_ignored_fg
);
2131 prefs_register_color_preference(gui_color_module
, "ignored_frame.bg", "Color preferences for a ignored frame",
2132 "Color preferences for a ignored frame", &prefs
.gui_ignored_bg
);
2134 prefs_register_color_preference(gui_color_module
, "stream.client.fg", "TCP stream window color preference",
2135 "TCP stream window color preference", &prefs
.st_client_fg
);
2137 prefs_register_color_preference(gui_color_module
, "stream.client.bg", "TCP stream window color preference",
2138 "TCP stream window color preference", &prefs
.st_client_bg
);
2140 prefs_register_color_preference(gui_color_module
, "stream.server.fg", "TCP stream window color preference",
2141 "TCP stream window color preference", &prefs
.st_server_fg
);
2143 prefs_register_color_preference(gui_color_module
, "stream.server.bg", "TCP stream window color preference",
2144 "TCP stream window color preference", &prefs
.st_server_bg
);
2146 custom_cbs
.free_cb
= colorized_frame_free_cb
;
2147 custom_cbs
.reset_cb
= colorized_frame_reset_cb
;
2148 custom_cbs
.set_cb
= colorized_frame_set_cb
;
2149 custom_cbs
.type_name_cb
= colorized_frame_type_name_cb
;
2150 custom_cbs
.type_description_cb
= colorized_frame_type_description_cb
;
2151 custom_cbs
.is_default_cb
= colorized_frame_is_default_cb
;
2152 custom_cbs
.to_str_cb
= colorized_frame_to_str_cb
;
2153 prefs_register_string_custom_preference(gui_column_module
, "colorized_frame.fg", "Colorized Foreground",
2154 "Filter Colorized Foreground", &custom_cbs
, (const char **)&prefs
.gui_colorized_fg
);
2156 custom_cbs
.free_cb
= colorized_frame_free_cb
;
2157 custom_cbs
.reset_cb
= colorized_frame_reset_cb
;
2158 custom_cbs
.set_cb
= colorized_frame_set_cb
;
2159 custom_cbs
.type_name_cb
= colorized_frame_type_name_cb
;
2160 custom_cbs
.type_description_cb
= colorized_frame_type_description_cb
;
2161 custom_cbs
.is_default_cb
= colorized_frame_is_default_cb
;
2162 custom_cbs
.to_str_cb
= colorized_frame_to_str_cb
;
2163 prefs_register_string_custom_preference(gui_column_module
, "colorized_frame.bg", "Colorized Background",
2164 "Filter Colorized Background", &custom_cbs
, (const char **)&prefs
.gui_colorized_bg
);
2166 prefs_register_color_preference(gui_color_module
, "color_filter_bg.valid", "Valid color filter background",
2167 "Valid color filter background", &prefs
.gui_text_valid
);
2169 prefs_register_color_preference(gui_color_module
, "color_filter_bg.invalid", "Invalid color filter background",
2170 "Invalid color filter background", &prefs
.gui_text_invalid
);
2172 prefs_register_color_preference(gui_color_module
, "color_filter_bg.deprecated", "Deprecated color filter background",
2173 "Deprecated color filter background", &prefs
.gui_text_deprecated
);
2175 prefs_register_enum_preference(gui_module
, "fileopen.style",
2176 "Where to start the File Open dialog box",
2177 "Where to start the File Open dialog box",
2178 &prefs
.gui_fileopen_style
, gui_fileopen_style
, FALSE
);
2180 prefs_register_uint_preference(gui_module
, "recent_files_count.max",
2181 "The max. number of items in the open recent files list",
2182 "The max. number of items in the open recent files list",
2184 &prefs
.gui_recent_files_count_max
);
2186 prefs_register_uint_preference(gui_module
, "recent_display_filter_entries.max",
2187 "The max. number of entries in the display filter list",
2188 "The max. number of entries in the display filter list",
2190 &prefs
.gui_recent_df_entries_max
);
2192 prefs_register_directory_preference(gui_module
, "fileopen.dir", "Start Directory",
2193 "Directory to start in when opening File Open dialog.", (const char **)&prefs
.gui_fileopen_dir
);
2195 prefs_register_obsolete_preference(gui_module
, "fileopen.remembered_dir");
2197 prefs_register_uint_preference(gui_module
, "fileopen.preview",
2198 "The preview timeout in the File Open dialog",
2199 "The preview timeout in the File Open dialog",
2201 &prefs
.gui_fileopen_preview
);
2203 prefs_register_bool_preference(gui_module
, "ask_unsaved",
2204 "Ask to save unsaved capture files",
2205 "Ask to save unsaved capture files?",
2206 &prefs
.gui_ask_unsaved
);
2208 prefs_register_bool_preference(gui_module
, "find_wrap",
2209 "Wrap to beginning/end of file during search",
2210 "Wrap to beginning/end of file during search?",
2211 &prefs
.gui_find_wrap
);
2213 prefs_register_bool_preference(gui_module
, "use_pref_save",
2214 "Settings dialogs use a save button",
2215 "Settings dialogs use a save button?",
2216 &prefs
.gui_use_pref_save
);
2218 prefs_register_bool_preference(gui_module
, "geometry.save.position",
2219 "Save window position at exit",
2220 "Save window position at exit?",
2221 &prefs
.gui_geometry_save_position
);
2223 prefs_register_bool_preference(gui_module
, "geometry.save.size",
2224 "Save window size at exit",
2225 "Save window size at exit?",
2226 &prefs
.gui_geometry_save_size
);
2228 prefs_register_bool_preference(gui_module
, "geometry.save.maximized",
2229 "Save window maximized state at exit",
2230 "Save window maximized state at exit?",
2231 &prefs
.gui_geometry_save_maximized
);
2233 prefs_register_bool_preference(gui_module
, "macosx_style",
2234 "Use Mac OS X style",
2235 "Use Mac OS X style (Mac OS X with native GTK only)?",
2236 &prefs
.gui_macosx_style
);
2238 prefs_register_obsolete_preference(gui_module
, "geometry.main.x");
2239 prefs_register_obsolete_preference(gui_module
, "geometry.main.y");
2240 prefs_register_obsolete_preference(gui_module
, "geometry.main.width");
2241 prefs_register_obsolete_preference(gui_module
, "geometry.main.height");
2242 prefs_register_obsolete_preference(gui_module
, "toolbar_main_show");
2244 prefs_register_enum_preference(gui_module
, "toolbar_main_style",
2245 "Main Toolbar style",
2246 "Main Toolbar style",
2247 &prefs
.gui_toolbar_main_style
, gui_toolbar_style
, FALSE
);
2249 prefs_register_enum_preference(gui_module
, "toolbar_filter_style",
2250 "Filter Toolbar style",
2251 "Filter Toolbar style",
2252 &prefs
.gui_toolbar_filter_style
, gui_toolbar_style
, FALSE
);
2254 prefs_register_string_preference(gui_module
, "webbrowser", "The path to the webbrowser",
2255 "The path to the webbrowser (Ex: mozilla)", (const char **)&prefs
.gui_webbrowser
);
2257 prefs_register_bool_preference(gui_module
, "update.enabled",
2258 "Check for updates",
2259 "Check for updates (Windows only)",
2260 &prefs
.gui_update_enabled
);
2262 prefs_register_enum_preference(gui_module
, "update.channel",
2264 "The type of update to fetch. You should probably leave this set to UPDATE_CHANNEL_STABLE.",
2265 (gint
*)(void*)(&prefs
.gui_update_channel
), gui_update_channel
, FALSE
);
2267 prefs_register_uint_preference(gui_module
, "update.interval",
2268 "How often to check for software updates",
2269 "How often to check for software updates in seconds",
2271 &prefs
.gui_update_interval
);
2273 prefs_register_string_preference(gui_module
, "window_title", "Custom window title",
2274 "Custom window title. (Appended to existing titles.)", (const char **)&prefs
.gui_window_title
);
2276 prefs_register_string_preference(gui_module
, "start_title", "Custom start page title",
2277 "Custom start page title", (const char**)(&prefs
.gui_start_title
));
2279 prefs_register_enum_preference(gui_module
, "version_placement",
2280 "Show version in the start page and/or main screen's title bar",
2281 "Show version in the start page and/or main screen's title bar",
2282 (gint
*)(void*)(&prefs
.gui_version_placement
), gui_version_placement_type
, FALSE
);
2284 prefs_register_bool_preference(gui_module
, "auto_scroll_on_expand",
2285 "Automatically scroll the recently expanded item",
2286 "Automatically scroll the recently expanded item",
2287 &prefs
.gui_auto_scroll_on_expand
);
2289 prefs_register_uint_preference(gui_module
, "auto_scroll_percentage",
2290 "The percentage down the view the recently expanded item should be scrolled",
2291 "The percentage down the view the recently expanded item should be scrolled",
2293 &prefs
.gui_auto_scroll_percentage
);
2295 prefs_register_enum_preference(gui_module
, "qt_language",
2298 &prefs
.gui_qt_language
, gui_qt_language
, FALSE
);
2300 /* User Interface : Layout */
2301 gui_layout_module
= prefs_register_subtree(gui_module
, "Layout", "Layout", gui_layout_callback
);
2303 prefs_register_uint_preference(gui_layout_module
, "layout_type",
2305 "Layout type (1-6)",
2307 (guint
*)(void*)(&prefs
.gui_layout_type
));
2309 prefs_register_enum_preference(gui_layout_module
, "layout_content_1",
2310 "Layout content of the pane 1",
2311 "Layout content of the pane 1",
2312 (gint
*)(void*)(&prefs
.gui_layout_content_1
), gui_layout_content
, FALSE
);
2314 prefs_register_enum_preference(gui_layout_module
, "layout_content_2",
2315 "Layout content of the pane 2",
2316 "Layout content of the pane 2",
2317 (gint
*)(void*)(&prefs
.gui_layout_content_2
), gui_layout_content
, FALSE
);
2319 prefs_register_enum_preference(gui_layout_module
, "layout_content_3",
2320 "Layout content of the pane 3",
2321 "Layout content of the pane 3",
2322 (gint
*)(void*)(&prefs
.gui_layout_content_3
), gui_layout_content
, FALSE
);
2324 prefs_register_bool_preference(gui_module
, "packet_editor.enabled",
2325 "Enable Packet Editor",
2326 "Enable Packet Editor (Experimental)",
2327 &prefs
.gui_packet_editor
);
2329 * These are preferences that can be read/written using the
2330 * preference module API. These preferences still use their own
2331 * configuration screens for access, but this cuts down on the
2332 * preference "string compare list" in set_pref()
2334 console_module
= prefs_register_module(NULL
, "console", "Console",
2335 "CONSOLE", NULL
, FALSE
);
2337 custom_cbs
.free_cb
= custom_pref_no_cb
;
2338 custom_cbs
.reset_cb
= console_log_level_reset_cb
;
2339 custom_cbs
.set_cb
= console_log_level_set_cb
;
2340 custom_cbs
.type_name_cb
= console_log_level_type_name_cb
;
2341 custom_cbs
.type_description_cb
= console_log_level_type_description_cb
;
2342 custom_cbs
.is_default_cb
= console_log_level_is_default_cb
;
2343 custom_cbs
.to_str_cb
= console_log_level_to_str_cb
;
2344 prefs_register_uint_custom_preference(console_module
, "log.level", "logging level",
2345 "A bitmask of glib log levels", &custom_cbs
, &prefs
.console_log_level
);
2348 * These are preferences that can be read/written using the
2349 * preference module API. These preferences still use their own
2350 * configuration screens for access, but this cuts down on the
2351 * preference "string compare list" in set_pref()
2353 capture_module
= prefs_register_module(NULL
, "capture", "Capture",
2354 "CAPTURE", NULL
, FALSE
);
2356 prefs_register_string_preference(capture_module
, "device", "Default capture device",
2357 "Default capture device", (const char **)&prefs
.capture_device
);
2359 prefs_register_string_preference(capture_module
, "devices_linktypes", "Interface link-layer header type",
2360 "Interface link-layer header types (Ex: en0(1),en1(143),...)",
2361 (const char **)&prefs
.capture_devices_linktypes
);
2363 prefs_register_string_preference(capture_module
, "devices_descr", "Interface descriptions",
2364 "Interface descriptions (Ex: eth0(eth0 descr),eth1(eth1 descr),...)",
2365 (const char **)&prefs
.capture_devices_descr
);
2367 prefs_register_string_preference(capture_module
, "devices_hide", "Hide interface",
2368 "Hide interface? (Ex: eth0,eth3,...)", (const char **)&prefs
.capture_devices_hide
);
2370 prefs_register_string_preference(capture_module
, "devices_monitor_mode", "Capture in monitor mode",
2371 "By default, capture in monitor mode on interface? (Ex: eth0,eth3,...)",
2372 (const char **)&prefs
.capture_devices_monitor_mode
);
2374 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2375 prefs_register_string_preference(capture_module
, "devices_buffersize", "Interface buffer size",
2376 "Interface buffer size (Ex: en0(1),en1(143),...)",
2377 ((const char **)&prefs
.capture_devices_buffersize
));
2380 prefs_register_string_preference(capture_module
, "devices_snaplen", "Interface snap length",
2381 "Interface snap length (Ex: en0(65535),en1(1430),...)",
2382 (const char **)&prefs
.capture_devices_snaplen
);
2384 prefs_register_string_preference(capture_module
, "devices_pmode", "Interface promiscuous mode",
2385 "Interface promiscuous mode (Ex: en0(0),en1(1),...)",
2386 (const char **)&prefs
.capture_devices_pmode
);
2388 prefs_register_bool_preference(capture_module
, "prom_mode", "Capture in promiscuous mode",
2389 "Capture in promiscuous mode?", &prefs
.capture_prom_mode
);
2391 prefs_register_bool_preference(capture_module
, "pcap_ng", "Capture in Pcap-NG format",
2392 "Capture in Pcap-NG format?", &prefs
.capture_pcap_ng
);
2394 prefs_register_bool_preference(capture_module
, "real_time_update", "Update packet list in real time during capture",
2395 "Update packet list in real time during capture?", &prefs
.capture_real_time
);
2397 prefs_register_bool_preference(capture_module
, "auto_scroll", "Scroll packet list during capture",
2398 "Scroll packet list during capture?", &prefs
.capture_auto_scroll
);
2400 prefs_register_bool_preference(capture_module
, "show_info", "Show capture info dialog while capturing",
2401 "Show capture info dialog while capturing?", &prefs
.capture_show_info
);
2403 prefs_register_obsolete_preference(capture_module
, "syntax_check_filter");
2405 custom_cbs
.free_cb
= capture_column_free_cb
;
2406 custom_cbs
.reset_cb
= capture_column_reset_cb
;
2407 custom_cbs
.set_cb
= capture_column_set_cb
;
2408 custom_cbs
.type_name_cb
= capture_column_type_name_cb
;
2409 custom_cbs
.type_description_cb
= capture_column_type_description_cb
;
2410 custom_cbs
.is_default_cb
= capture_column_is_default_cb
;
2411 custom_cbs
.to_str_cb
= capture_column_to_str_cb
;
2412 prefs_register_list_custom_preference(capture_module
, "columns", "Capture options dialog column list",
2413 "List of columns to be displayed", &custom_cbs
, capture_column_init_cb
, &prefs
.capture_columns
);
2415 /* Name Resolution */
2416 nameres_module
= prefs_register_module(NULL
, "nameres", "Name Resolution",
2417 "Name Resolution", NULL
, TRUE
);
2418 addr_resolve_pref_init(nameres_module
);
2419 oid_pref_init(nameres_module
);
2421 geoip_db_pref_init(nameres_module
);
2425 printing
= prefs_register_module(NULL
, "print", "Printing",
2426 "Printing", NULL
, TRUE
);
2428 prefs_register_enum_preference(printing
, "format",
2429 "Format", "Can be one of \"text\" or \"postscript\"",
2430 &prefs
.pr_format
, print_format_vals
, TRUE
);
2432 prefs_register_enum_preference(printing
, "destination",
2433 "Print to", "Can be one of \"command\" or \"file\"",
2434 &prefs
.pr_dest
, print_dest_vals
, TRUE
);
2437 prefs_register_string_preference(printing
, "command", "Command",
2438 "Output gets piped to this command when the destination is set to \"command\"", (const char**)(&prefs
.pr_cmd
));
2441 prefs_register_filename_preference(printing
, "file", "File",
2442 "This is the file that gets written to when the destination is set to \"file\"", (const char**)(&prefs
.pr_file
));
2446 stats_module
= prefs_register_module(NULL
, "statistics", "Statistics",
2447 "Statistics", &stats_callback
, TRUE
);
2449 prefs_register_uint_preference(stats_module
, "update_interval",
2450 "Tap update interval in ms",
2451 "Determines time between tap updates",
2453 &prefs
.tap_update_interval
);
2455 #ifdef HAVE_LIBPORTAUDIO
2456 prefs_register_uint_preference(stats_module
, "rtp_player_max_visible",
2457 "Max visible channels in RTP Player",
2458 "Determines maximum height of RTP Player window",
2460 &prefs
.rtp_player_max_visible
);
2465 protocols_module
= prefs_register_module(NULL
, "protocols", "Protocols",
2466 "Protocols", NULL
, TRUE
);
2468 prefs_register_bool_preference(protocols_module
, "display_hidden_proto_items",
2469 "Display hidden protocol items",
2470 "Display all hidden protocol items in the packet list.",
2471 &prefs
.display_hidden_proto_items
);
2473 /* Obsolete preferences
2474 * These "modules" were reorganized/renamed to correspond to their GUI
2475 * configuration screen within the preferences dialog
2478 /* taps is now part of the stats module */
2479 prefs_register_module(NULL
, "taps", "TAPS", "TAPS", NULL
, FALSE
);
2480 /* packet_list is now part of the protocol (parent) module */
2481 prefs_register_module(NULL
, "packet_list", "PACKET_LIST", "PACKET_LIST", NULL
, FALSE
);
2482 /* stream is now part of the gui module */
2483 prefs_register_module(NULL
, "stream", "STREAM", "STREAM", NULL
, FALSE
);
2487 /* Parse through a list of comma-separated, possibly quoted strings.
2488 Return a list of the string data. */
2490 prefs_get_string_list(const gchar
*str
)
2492 enum { PRE_STRING
, IN_QUOT
, NOT_IN_QUOT
};
2494 gint state
= PRE_STRING
, i
= 0, j
= 0;
2495 gboolean backslash
= FALSE
;
2497 gchar
*slstr
= NULL
;
2500 /* Allocate a buffer for the first string. */
2501 slstr
= (gchar
*) g_malloc(sizeof(gchar
) * COL_MAX_LEN
);
2506 if (cur_c
== '\0') {
2507 /* It's the end of the input, so it's the end of the string we
2508 were working on, and there's no more input. */
2509 if (state
== IN_QUOT
|| backslash
) {
2510 /* We were in the middle of a quoted string or backslash escape,
2511 and ran out of characters; that's an error. */
2513 prefs_clear_string_list(sl
);
2517 sl
= g_list_append(sl
, slstr
);
2520 if (cur_c
== '"' && ! backslash
) {
2523 /* We hadn't yet started processing a string; this starts the
2524 string, and we're now quoting. */
2528 /* We're in the middle of a quoted string, and we saw a quotation
2529 mark; we're no longer quoting. */
2530 state
= NOT_IN_QUOT
;
2533 /* We're working on a string, but haven't seen a quote; we're
2540 } else if (cur_c
== '\\' && ! backslash
) {
2541 /* We saw a backslash, and the previous character wasn't a
2542 backslash; escape the next character.
2544 This also means we've started a new string. */
2546 if (state
== PRE_STRING
)
2547 state
= NOT_IN_QUOT
;
2548 } else if (cur_c
== ',' && state
!= IN_QUOT
&& ! backslash
) {
2549 /* We saw a comma, and we're not in the middle of a quoted string
2550 and it wasn't preceded by a backslash; it's the end of
2551 the string we were working on... */
2553 sl
= g_list_append(sl
, slstr
);
2555 /* ...and the beginning of a new string. */
2557 slstr
= (gchar
*) g_malloc(sizeof(gchar
) * COL_MAX_LEN
);
2559 } else if (!isspace(cur_c
) || state
!= PRE_STRING
) {
2560 /* Either this isn't a white-space character, or we've started a
2561 string (i.e., already seen a non-white-space character for that
2562 string and put it into the string).
2564 The character is to be put into the string; do so if there's
2566 if (j
< COL_MAX_LEN
) {
2571 /* If it was backslash-escaped, we're done with the backslash escape. */
2580 join_string_list(GList
*sl
)
2582 GString
*joined_str
= g_string_new("");
2586 guint item_count
= 0;
2588 cur
= first
= g_list_first(sl
);
2591 str
= (gchar
*)cur
->data
;
2594 g_string_append_c(joined_str
, ',');
2596 if (item_count
% 2) {
2597 /* Wrap the line. */
2598 g_string_append(joined_str
, "\n\t");
2600 g_string_append_c(joined_str
, ' ');
2602 quoted_str
= g_strescape(str
, "");
2603 g_string_append_printf(joined_str
, "\"%s\"", quoted_str
);
2608 return g_string_free(joined_str
, FALSE
);
2612 prefs_clear_string_list(GList
*sl
)
2618 l
= g_list_remove_link(l
, l
);
2623 * Takes a string, a pointer to an array of "enum_val_t"s, and a default gint
2625 * The array must be terminated by an entry with a null "name" string.
2627 * If the string matches a "name" string in an entry, the value from that
2628 * entry is returned.
2630 * Otherwise, if a string matches a "desctiption" string in an entry, the
2631 * value from that entry is returned; we do that for backwards compatibility,
2632 * as we used to have only a "name" string that was used both for command-line
2633 * and configuration-file values and in the GUI (which meant either that
2634 * the GUI had what might be somewhat cryptic values to select from or that
2635 * the "-o" flag took long strings, often with spaces in them).
2637 * Otherwise, the default value that was passed as the third argument is
2641 find_val_for_string(const char *needle
, const enum_val_t
*haystack
,
2646 for (i
= 0; haystack
[i
].name
!= NULL
; i
++) {
2647 if (g_ascii_strcasecmp(needle
, haystack
[i
].name
) == 0) {
2648 return haystack
[i
].value
;
2651 for (i
= 0; haystack
[i
].name
!= NULL
; i
++) {
2652 if (g_ascii_strcasecmp(needle
, haystack
[i
].description
) == 0) {
2653 return haystack
[i
].value
;
2656 return default_value
;
2659 /* Preferences file format:
2660 * - Configuration directives start at the beginning of the line, and
2661 * are terminated with a colon.
2662 * - Directives can be continued on the next line by preceding them with
2667 # This is a comment line
2669 print.file: /a/very/long/path/
2674 #define DEF_NUM_COLS 7
2677 * Parse a column format, filling in the relevant fields of a fmt_data.
2680 parse_column_format(fmt_data
*cfmt
, const char *fmt
)
2682 const gchar
*cust_format
= col_format_to_string(COL_CUSTOM
);
2683 size_t cust_format_len
= strlen(cust_format
);
2684 gchar
**cust_format_info
;
2687 gchar
*col_custom_field
;
2688 long col_custom_occurrence
;
2689 gboolean col_resolved
;
2692 * Is this a custom column?
2694 if ((strlen(fmt
) > cust_format_len
) && (fmt
[cust_format_len
] == ':') &&
2695 strncmp(fmt
, cust_format
, cust_format_len
) == 0) {
2697 col_fmt
= COL_CUSTOM
;
2698 cust_format_info
= g_strsplit(&fmt
[cust_format_len
+1],":",3); /* add 1 for ':' */
2699 col_custom_field
= g_strdup(cust_format_info
[0]);
2700 if (col_custom_field
&& cust_format_info
[1]) {
2701 col_custom_occurrence
= strtol(cust_format_info
[1], &p
, 10);
2702 if (p
== cust_format_info
[1] || *p
!= '\0') {
2703 /* Not a valid number. */
2704 g_free(col_custom_field
);
2705 g_strfreev(cust_format_info
);
2709 col_custom_occurrence
= 0;
2711 if (col_custom_field
&& cust_format_info
[1] && cust_format_info
[2]) {
2712 col_resolved
= (cust_format_info
[2][0] == 'U') ? FALSE
: TRUE
;
2714 col_resolved
= TRUE
;
2716 g_strfreev(cust_format_info
);
2718 col_fmt
= get_column_format_from_str(fmt
);
2721 col_custom_field
= NULL
;
2722 col_custom_occurrence
= 0;
2723 col_resolved
= TRUE
;
2726 cfmt
->fmt
= col_fmt
;
2727 cfmt
->custom_field
= col_custom_field
;
2728 cfmt
->custom_occurrence
= (int)col_custom_occurrence
;
2729 cfmt
->resolved
= col_resolved
;
2733 /* Initialize non-dissector preferences to wired-in default values.
2734 * (The dissector preferences are assumed to be set to those values
2735 * by the dissectors.)
2736 * They may be overridden by the global preferences file or the
2737 * user's preferences file.
2742 if (prefs_initialized
)
2747 prefs_register_modules();
2749 filter_expression_init(TRUE
);
2751 prefs_initialized
= TRUE
;
2754 /* Initialize non-dissector preferences used by the "register preference" API
2755 * to default values so the default values can be used when registered
2758 pre_init_prefs(void)
2763 static const gchar
*col_fmt
[DEF_NUM_COLS
*2] = {
2764 "No.", "%m", "Time", "%t",
2765 "Source", "%s", "Destination", "%d",
2766 "Protocol", "%p", "Length", "%L",
2769 if (prefs_pre_initialized
)
2772 prefs
.pr_format
= PR_FMT_TEXT
;
2773 prefs
.pr_dest
= PR_DEST_CMD
;
2774 prefs
.pr_file
= "wireshark.out";
2775 prefs
.pr_cmd
= "lpr";
2777 prefs
.gui_altern_colors
= FALSE
;
2778 prefs
.gui_expert_composite_eyecandy
= FALSE
;
2779 prefs
.gui_ptree_line_style
= 0;
2780 prefs
.gui_ptree_expander_style
= 1;
2781 prefs
.gui_hex_dump_highlight_style
= 1;
2782 prefs
.filter_toolbar_show_in_statusbar
= FALSE
;
2783 prefs
.gui_toolbar_main_style
= TB_STYLE_ICONS
;
2784 prefs
.gui_toolbar_filter_style
= TB_STYLE_TEXT
;
2785 /* These string prefs will be strduped shortly, so we can safely cast away
2786 * their constness in these assignments */
2788 prefs
.gui_gtk2_font_name
= (char *) "Lucida Console 10";
2790 prefs
.gui_gtk2_font_name
= (char *) "Monospace 10";
2792 /* We try to find the best font in the Qt code */
2793 prefs
.gui_qt_font_name
= (char *) "";
2794 prefs
.gui_marked_fg
.pixel
= 65535;
2795 prefs
.gui_marked_fg
.red
= 65535;
2796 prefs
.gui_marked_fg
.green
= 65535;
2797 prefs
.gui_marked_fg
.blue
= 65535;
2798 prefs
.gui_marked_bg
.pixel
= 0;
2799 prefs
.gui_marked_bg
.red
= 0;
2800 prefs
.gui_marked_bg
.green
= 8224;
2801 prefs
.gui_marked_bg
.blue
= 10794;
2802 prefs
.gui_ignored_fg
.pixel
= 32767;
2803 prefs
.gui_ignored_fg
.red
= 32767;
2804 prefs
.gui_ignored_fg
.green
= 32767;
2805 prefs
.gui_ignored_fg
.blue
= 32767;
2806 prefs
.gui_ignored_bg
.pixel
= 65535;
2807 prefs
.gui_ignored_bg
.red
= 65535;
2808 prefs
.gui_ignored_bg
.green
= 65535;
2809 prefs
.gui_ignored_bg
.blue
= 65535;
2810 prefs
.gui_colorized_fg
= "000000,000000,000000,000000,000000,000000,000000,000000,000000,000000";
2811 prefs
.gui_colorized_bg
= "ffc0c0,ffc0ff,e0c0e0,c0c0ff,c0e0e0,c0ffff,c0ffc0,ffffc0,e0e0c0,e0e0e0";
2812 prefs
.st_client_fg
.pixel
= 0;
2813 prefs
.st_client_fg
.red
= 32767;
2814 prefs
.st_client_fg
.green
= 0;
2815 prefs
.st_client_fg
.blue
= 0;
2816 prefs
.st_client_bg
.pixel
= 0;
2817 prefs
.st_client_bg
.red
= 64507;
2818 prefs
.st_client_bg
.green
= 60909;
2819 prefs
.st_client_bg
.blue
= 60909;
2820 prefs
.st_server_fg
.pixel
= 0;
2821 prefs
.st_server_fg
.red
= 0;
2822 prefs
.st_server_fg
.green
= 0;
2823 prefs
.st_server_fg
.blue
= 32767;
2824 prefs
.st_server_bg
.pixel
= 0;
2825 prefs
.st_server_bg
.red
= 60909;
2826 prefs
.st_server_bg
.green
= 60909;
2827 prefs
.st_server_bg
.blue
= 64507;
2828 prefs
.gui_text_valid
.pixel
= 0; /* light green */
2829 prefs
.gui_text_valid
.red
= 0xAFFF;
2830 prefs
.gui_text_valid
.green
= 0xFFFF;
2831 prefs
.gui_text_valid
.blue
= 0xAFFF;
2832 prefs
.gui_text_invalid
.pixel
= 0; /* light red */
2833 prefs
.gui_text_invalid
.red
= 0xFFFF;
2834 prefs
.gui_text_invalid
.green
= 0xAFFF;
2835 prefs
.gui_text_invalid
.blue
= 0xAFFF;
2836 prefs
.gui_text_deprecated
.pixel
= 0; /* light yellow */
2837 prefs
.gui_text_deprecated
.red
= 0xFFFF;
2838 prefs
.gui_text_deprecated
.green
= 0xFFFF;
2839 prefs
.gui_text_deprecated
.blue
= 0xAFFF;
2840 prefs
.gui_geometry_save_position
= TRUE
;
2841 prefs
.gui_geometry_save_size
= TRUE
;
2842 prefs
.gui_geometry_save_maximized
= TRUE
;
2843 prefs
.gui_macosx_style
= TRUE
;
2844 prefs
.gui_console_open
= console_open_never
;
2845 prefs
.gui_fileopen_style
= FO_STYLE_LAST_OPENED
;
2846 prefs
.gui_recent_df_entries_max
= 10;
2847 prefs
.gui_recent_files_count_max
= 10;
2848 prefs
.gui_fileopen_dir
= (char *) get_persdatafile_dir();
2849 prefs
.gui_fileopen_preview
= 3;
2850 prefs
.gui_ask_unsaved
= TRUE
;
2851 prefs
.gui_find_wrap
= TRUE
;
2852 prefs
.gui_use_pref_save
= FALSE
;
2853 prefs
.gui_update_enabled
= TRUE
;
2854 prefs
.gui_update_channel
= UPDATE_CHANNEL_STABLE
;
2855 prefs
.gui_update_interval
= 60*60*24; /* Seconds */
2856 prefs
.gui_webbrowser
= (char *) HTML_VIEWER
" %s";
2857 prefs
.gui_window_title
= (char *) "";
2858 prefs
.gui_start_title
= "The World's Most Popular Network Protocol Analyzer";
2859 prefs
.gui_version_placement
= version_both
;
2860 prefs
.gui_auto_scroll_on_expand
= FALSE
;
2861 prefs
.gui_auto_scroll_percentage
= 0;
2862 prefs
.gui_layout_type
= layout_type_5
;
2863 prefs
.gui_layout_content_1
= layout_pane_content_plist
;
2864 prefs
.gui_layout_content_2
= layout_pane_content_pdetails
;
2865 prefs
.gui_layout_content_3
= layout_pane_content_pbytes
;
2866 prefs
.gui_qt_language
= 0; /* (Auto-Detect) */
2867 prefs
.gui_packet_editor
= FALSE
;
2869 prefs
.col_list
= NULL
;
2870 for (i
= 0; i
< DEF_NUM_COLS
; i
++) {
2871 cfmt
= g_new(fmt_data
,1);
2872 cfmt
->title
= g_strdup(col_fmt
[i
* 2]);
2873 parse_column_format(cfmt
, col_fmt
[(i
* 2) + 1]);
2874 cfmt
->visible
= TRUE
;
2875 cfmt
->resolved
= TRUE
;
2876 cfmt
->custom_field
= NULL
;
2877 cfmt
->custom_occurrence
= 0;
2878 prefs
.col_list
= g_list_append(prefs
.col_list
, cfmt
);
2880 prefs
.num_cols
= DEF_NUM_COLS
;
2882 /* set the default values for the capture dialog box */
2883 prefs
.capture_prom_mode
= TRUE
;
2884 #ifdef PCAP_NG_DEFAULT
2885 prefs
.capture_pcap_ng
= TRUE
;
2887 prefs
.capture_pcap_ng
= FALSE
;
2889 prefs
.capture_real_time
= TRUE
;
2890 prefs
.capture_auto_scroll
= TRUE
;
2891 prefs
.capture_show_info
= FALSE
;
2893 prefs
.capture_columns
= NULL
;
2894 for (i
= 0; i
< num_capture_cols
; i
++) {
2895 col_name
= g_strdup(capture_cols
[i
]);
2896 prefs
.capture_columns
= g_list_append(prefs
.capture_columns
, col_name
);
2899 prefs
.console_log_level
=
2900 G_LOG_LEVEL_WARNING
| G_LOG_LEVEL_CRITICAL
| G_LOG_LEVEL_ERROR
;
2902 /* set the default values for the tap/statistics dialog box */
2903 prefs
.tap_update_interval
= TAP_UPDATE_DEFAULT_INTERVAL
;
2904 prefs
.rtp_player_max_visible
= RTP_PLAYER_DEFAULT_VISIBLE
;
2906 prefs
.display_hidden_proto_items
= FALSE
;
2908 prefs_pre_initialized
= TRUE
;
2912 * Reset a single dissector preference.
2915 reset_pref(pref_t
*pref
)
2919 switch (pref
->type
) {
2922 *pref
->varp
.uint
= pref
->default_val
.uint
;
2926 *pref
->varp
.boolp
= pref
->default_val
.boolval
;
2931 * For now, we save the "description" value, so that if we
2932 * save the preferences older versions of Wireshark can at
2933 * least read preferences that they supported; we support
2934 * either the short name or the description when reading
2935 * the preferences file or a "-o" option.
2937 *pref
->varp
.enump
= pref
->default_val
.enumval
;
2943 g_free((void *)*pref
->varp
.string
);
2944 *pref
->varp
.string
= g_strdup(pref
->default_val
.string
);
2948 g_free(*pref
->varp
.range
);
2949 *pref
->varp
.range
= range_copy(pref
->default_val
.range
);
2952 case PREF_STATIC_TEXT
:
2958 *pref
->varp
.colorp
= pref
->default_val
.color
;
2962 pref
->custom_cbs
.reset_cb(pref
);
2967 * This preference is no longer supported; it's not a
2968 * real preference, so we don't reset it (i.e., we
2969 * treat it as if it weren't found in the list of
2970 * preferences, and we weren't called in the first place).
2977 reset_pref_cb(gpointer data
, gpointer user_data _U_
)
2979 pref_t
*pref
= (pref_t
*) data
;
2988 * Reset all preferences for a module.
2991 reset_module_prefs(void *value
, void *data _U_
)
2993 reset_pref_arg_t arg
;
2995 arg
.module
= (module_t
*)value
;
2996 g_list_foreach(arg
.module
->prefs
, reset_pref_cb
, &arg
);
3000 /* Reset preferences */
3004 prefs_initialized
= FALSE
;
3005 g_free(prefs
.saved_at_version
);
3007 * Unload all UAT preferences.
3012 * Unload any loaded MIBs.
3017 * Reset the non-dissector preferences.
3022 * Reset the non-UAT dissector preferences.
3024 wmem_tree_foreach(prefs_modules
, reset_module_prefs
, NULL
);
3027 /* Read the preferences file, fill in "prefs", and return a pointer to it.
3029 If we got an error (other than "it doesn't exist") trying to read
3030 the global preferences file, stuff the errno into "*gpf_errno_return"
3031 and a pointer to the path of the file into "*gpf_path_return", and
3034 If we got an error (other than "it doesn't exist") trying to read
3035 the user's preferences file, stuff the errno into "*pf_errno_return"
3036 and a pointer to the path of the file into "*pf_path_return", and
3039 read_prefs(int *gpf_errno_return
, int *gpf_read_errno_return
,
3040 char **gpf_path_return
, int *pf_errno_return
,
3041 int *pf_read_errno_return
, char **pf_path_return
)
3047 /* clean up libsmi structures before reading prefs */
3053 * If we don't already have the pathname of the global preferences
3054 * file, construct it. Then, in either case, try to open the file.
3056 if (gpf_path
== NULL
) {
3058 * We don't have the path; try the new path first, and, if that
3059 * file doesn't exist, try the old path.
3061 gpf_path
= get_datafile_path(PF_NAME
);
3062 if ((pf
= ws_fopen(gpf_path
, "r")) == NULL
&& errno
== ENOENT
) {
3064 * It doesn't exist by the new name; try the old name.
3067 gpf_path
= get_datafile_path(OLD_GPF_NAME
);
3068 pf
= ws_fopen(gpf_path
, "r");
3072 * We have the path; try it.
3074 pf
= ws_fopen(gpf_path
, "r");
3078 * If we were able to open the file, read it.
3079 * XXX - if it failed for a reason other than "it doesn't exist",
3082 *gpf_path_return
= NULL
;
3085 * Start out the counters of "mgcp.{tcp,udp}.port" entries we've
3088 mgcp_tcp_port_count
= 0;
3089 mgcp_udp_port_count
= 0;
3091 /* We succeeded in opening it; read it. */
3092 err
= read_prefs_file(gpf_path
, pf
, set_pref
, NULL
);
3094 /* We had an error reading the file; return the errno and the
3095 pathname, so our caller can report the error. */
3096 *gpf_errno_return
= 0;
3097 *gpf_read_errno_return
= err
;
3098 *gpf_path_return
= gpf_path
;
3102 /* We failed to open it. If we failed for some reason other than
3103 "it doesn't exist", return the errno and the pathname, so our
3104 caller can report the error. */
3105 if (errno
!= ENOENT
) {
3106 *gpf_errno_return
= errno
;
3107 *gpf_read_errno_return
= 0;
3108 *gpf_path_return
= gpf_path
;
3112 /* Construct the pathname of the user's preferences file. */
3113 pf_path
= get_persconffile_path(PF_NAME
, TRUE
);
3115 /* Read the user's preferences file, if it exists. */
3116 *pf_path_return
= NULL
;
3117 if ((pf
= ws_fopen(pf_path
, "r")) != NULL
) {
3119 * Start out the counters of "mgcp.{tcp,udp}.port" entries we've
3122 mgcp_tcp_port_count
= 0;
3123 mgcp_udp_port_count
= 0;
3125 /* We succeeded in opening it; read it. */
3126 err
= read_prefs_file(pf_path
, pf
, set_pref
, NULL
);
3128 /* We had an error reading the file; return the errno and the
3129 pathname, so our caller can report the error. */
3130 *pf_errno_return
= 0;
3131 *pf_read_errno_return
= err
;
3132 *pf_path_return
= pf_path
;
3137 /* We failed to open it. If we failed for some reason other than
3138 "it doesn't exist", return the errno and the pathname, so our
3139 caller can report the error. */
3140 if (errno
!= ENOENT
) {
3141 *pf_errno_return
= errno
;
3142 *pf_read_errno_return
= 0;
3143 *pf_path_return
= pf_path
;
3148 /* load SMI modules if needed */
3154 /* read the preferences file (or similiar) and call the callback
3155 * function to set each key/value pair found */
3157 read_prefs_file(const char *pf_path
, FILE *pf
,
3158 pref_set_pair_cb pref_set_pair_fct
, void *private_data
)
3160 enum { START
, IN_VAR
, PRE_VAL
, IN_VAL
, IN_SKIP
};
3161 int got_c
, state
= START
;
3164 gboolean got_val
= FALSE
;
3165 gint fline
= 1, pline
= 1;
3166 gchar hint
[] = "(save preferences to remove this warning)";
3168 cur_val
= g_string_new("");
3169 cur_var
= g_string_new("");
3171 /* Try to read in the profile name in the first line of the preferences file. */
3176 if (fgets(firstl
, 100, pf
) != NULL
) {
3177 if (strncmp((const char *)firstl
, " Configuration file for ", 24) == 0) {
3178 const gchar
*ver
= (gchar
*)&firstl
[24];
3179 /* Eliminate the period and LF the end of the string */
3180 prefs
.saved_at_version
= g_strndup(ver
, strlen(ver
) - 2);
3186 while ((got_c
= getc(pf
)) != EOF
) {
3187 if (got_c
== '\n') {
3195 if (isalnum(got_c
)) {
3196 if (cur_var
->len
> 0) {
3198 if (cur_val
->len
> 0) {
3199 if (cur_val
->str
[cur_val
->len
-1] == ',') {
3201 * If the pref has a trailing comma, eliminate it.
3203 cur_val
->str
[cur_val
->len
-1] = '\0';
3204 g_warning ("%s line %d: trailing comma in \"%s\" %s", pf_path
, pline
, cur_var
->str
, hint
);
3207 /* Call the routine to set the preference; it will parse
3208 the value as appropriate. */
3209 switch (pref_set_pair_fct(cur_var
->str
, cur_val
->str
, private_data
, FALSE
)) {
3214 case PREFS_SET_SYNTAX_ERR
:
3215 g_warning ("Syntax error in preference \"%s\" at line %d of\n%s %s",
3216 cur_var
->str
, pline
, pf_path
, hint
);
3219 case PREFS_SET_NO_SUCH_PREF
:
3221 * If "print.command" silently ignore it because it's valid
3222 * on non-Win32 platforms.
3224 if (strcmp(cur_var
->str
, "print.command") != 0)
3225 g_warning ("No such preference \"%s\" at line %d of\n%s %s",
3226 cur_var
->str
, pline
, pf_path
, hint
);
3227 prefs
.unknown_prefs
= TRUE
;
3230 case PREFS_SET_OBSOLETE
:
3231 if (strcmp(cur_var
->str
, "print.command") != 0)
3232 /* If an attempt is made to save the preferences, a popup warning will be
3233 displayed stating that obsolete prefs have been detected and the user will
3234 be given the opportunity to save these prefs under a different profile name.
3235 The prefs in question need to be listed in the console window so that the
3236 user can make an informed choice.
3238 g_warning ("Obsolete preference \"%s\" at line %d of\n%s %s",
3239 cur_var
->str
, pline
, pf_path
, hint
);
3240 prefs
.unknown_prefs
= TRUE
;
3244 g_warning ("Incomplete preference at line %d: of\n%s %s", pline
, pf_path
, hint
);
3249 g_string_truncate(cur_var
, 0);
3250 g_string_append_c(cur_var
, (gchar
) got_c
);
3252 } else if (isspace(got_c
) && cur_var
->len
> 0 && got_val
) {
3254 } else if (got_c
== '#') {
3257 g_warning ("Malformed preference at line %d of\n%s %s", fline
, pf_path
, hint
);
3262 g_string_append_c(cur_var
, (gchar
) got_c
);
3264 /* This is a colon (':') */
3266 g_string_truncate(cur_val
, 0);
3268 * Set got_val to TRUE to accommodate prefs such as
3269 * "gui.fileopen.dir" that do not require a value.
3275 if (!isspace(got_c
)) {
3277 g_string_append_c(cur_val
, (gchar
) got_c
);
3281 g_string_append_c(cur_val
, (gchar
) got_c
);
3285 if (cur_var
->len
> 0) {
3287 /* Convert the string to a range. Since we're reading the
3288 * preferences file, silently lower values in excess of the
3291 switch (pref_set_pair_fct(cur_var
->str
, cur_val
->str
, private_data
, FALSE
)) {
3296 case PREFS_SET_SYNTAX_ERR
:
3297 g_warning ("Syntax error in preference %s at line %d of\n%s %s",
3298 cur_var
->str
, pline
, pf_path
, hint
);
3301 case PREFS_SET_NO_SUCH_PREF
:
3302 g_warning ("No such preference \"%s\" at line %d of\n%s %s",
3303 cur_var
->str
, pline
, pf_path
, hint
);
3304 prefs
.unknown_prefs
= TRUE
;
3307 case PREFS_SET_OBSOLETE
:
3308 prefs
.unknown_prefs
= TRUE
;
3312 g_warning ("Incomplete preference at line %d of\n%s %s",
3313 pline
, pf_path
, hint
);
3317 g_string_free(cur_val
, TRUE
);
3318 g_string_free(cur_var
, TRUE
);
3327 * If we were handed a preference starting with "uat:", try to turn it into
3328 * a valid uat entry.
3331 prefs_set_uat_pref(char *uat_entry
) {
3336 colonp
= strchr(uat_entry
, ':');
3344 * Skip over any white space (there probably won't be any, but
3345 * as we allow it in the preferences file, we might as well
3348 while (isspace((guchar
)*p
))
3352 * Put the colon back, so if our caller uses, in an
3353 * error message, the string they passed us, the message
3360 uat
= uat_find(uat_entry
);
3366 if (uat_load_str(uat
, p
, &err
)) {
3373 * Given a string of the form "<pref name>:<pref value>", as might appear
3374 * as an argument to a "-o" option, parse it and set the preference in
3375 * question. Return an indication of whether it succeeded or failed
3379 prefs_set_pref(char *prefarg
)
3382 prefs_set_pref_e ret
;
3385 * Set the counters of "mgcp.{tcp,udp}.port" entries we've
3386 * seen to values that keep us from trying to interpret tham
3387 * as "mgcp.{tcp,udp}.gateway_port" or "mgcp.{tcp,udp}.callagent_port",
3388 * as, from the command line, we have no way of guessing which
3389 * the user had in mind.
3391 mgcp_tcp_port_count
= -1;
3392 mgcp_udp_port_count
= -1;
3394 colonp
= strchr(prefarg
, ':');
3396 return PREFS_SET_SYNTAX_ERR
;
3402 * Skip over any white space (there probably won't be any, but
3403 * as we allow it in the preferences file, we might as well
3406 while (isspace((guchar
)*p
))
3410 * Put the colon back, so if our caller uses, in an
3411 * error message, the string they passed us, the message
3415 return PREFS_SET_SYNTAX_ERR
;
3417 if (strcmp(prefarg
, "uat")) {
3418 ret
= set_pref(prefarg
, p
, NULL
, TRUE
);
3420 ret
= prefs_set_uat_pref(p
) ? PREFS_SET_OK
: PREFS_SET_SYNTAX_ERR
;
3422 *colonp
= ':'; /* put the colon back */
3427 * Returns TRUE if the given device is hidden
3430 prefs_is_capture_device_hidden(const char *name
)
3432 gchar
*tok
, *devices
;
3435 if (prefs
.capture_devices_hide
&& name
) {
3436 devices
= g_strdup (prefs
.capture_devices_hide
);
3437 len
= strlen (name
);
3438 for (tok
= strtok (devices
, ","); tok
; tok
= strtok(NULL
, ",")) {
3439 if (strlen (tok
) == len
&& strcmp (name
, tok
) == 0) {
3451 * Returns TRUE if the given column is visible (not hidden)
3454 prefs_is_column_visible(const gchar
*cols_hidden
, fmt_data
*cfmt
)
3457 fmt_data cfmt_hidden
;
3460 * Do we have a list of hidden columns?
3464 * Yes - check the column against each of the ones in the
3467 cols
= g_strdup(cols_hidden
);
3468 for (tok
= strtok(cols
, ","); tok
; tok
= strtok(NULL
, ",")) {
3469 tok
= g_strstrip(tok
);
3472 * Parse this column format.
3474 if (!parse_column_format(&cfmt_hidden
, tok
)) {
3476 * It's not valid; ignore it.
3482 * Does it match the column?
3484 if (cfmt
->fmt
!= cfmt_hidden
.fmt
) {
3486 g_free(cfmt_hidden
.custom_field
);
3489 if (cfmt
->fmt
== COL_CUSTOM
) {
3491 * A custom column has to have the
3492 * same custom field and occurrence.
3494 if (strcmp(cfmt
->custom_field
,
3495 cfmt_hidden
.custom_field
) != 0) {
3496 /* Different fields. */
3497 g_free(cfmt_hidden
.custom_field
);
3500 if (cfmt
->custom_occurrence
!= cfmt_hidden
.custom_occurrence
) {
3501 /* Different occurrences. */
3502 g_free(cfmt_hidden
.custom_field
);
3508 * OK, they match, so it's one of the hidden fields,
3509 * hence not visible.
3511 g_free(cfmt_hidden
.custom_field
);
3519 * No - either there are no hidden columns or this isn't one
3520 * of them - so it is visible.
3526 * Returns TRUE if the given device should capture in monitor mode by default
3529 prefs_capture_device_monitor_mode(const char *name
)
3531 gchar
*tok
, *devices
;
3534 if (prefs
.capture_devices_monitor_mode
&& name
) {
3535 devices
= g_strdup (prefs
.capture_devices_monitor_mode
);
3536 len
= strlen (name
);
3537 for (tok
= strtok (devices
, ","); tok
; tok
= strtok(NULL
, ",")) {
3538 if (strlen (tok
) == len
&& strcmp (name
, tok
) == 0) {
3550 * Returns TRUE if the user has marked this column as visible
3553 prefs_capture_options_dialog_column_is_visible(const gchar
*column
)
3558 for (curr
= g_list_first(prefs
.capture_columns
); curr
; curr
= g_list_next(curr
)) {
3559 col
= (gchar
*)curr
->data
;
3560 if (col
&& (g_ascii_strcasecmp(col
, column
) == 0)) {
3567 #define PRS_GUI_FILTER_LABEL "gui.filter_expressions.label"
3568 #define PRS_GUI_FILTER_EXPR "gui.filter_expressions.expr"
3569 #define PRS_GUI_FILTER_ENABLED "gui.filter_expressions.enabled"
3571 #define RED_COMPONENT(x) (guint16) (((((x) >> 16) & 0xff) * 65535 / 255))
3572 #define GREEN_COMPONENT(x) (guint16) (((((x) >> 8) & 0xff) * 65535 / 255))
3573 #define BLUE_COMPONENT(x) (guint16) ( (((x) & 0xff) * 65535 / 255))
3576 string_to_name_resolve(const char *string
, e_addr_resolve
*name_resolve
)
3580 memset(name_resolve
, 0, sizeof(e_addr_resolve
));
3581 while ((c
= *string
++) != '\0') {
3584 name_resolve
->mac_name
= TRUE
;
3587 name_resolve
->network_name
= TRUE
;
3590 name_resolve
->use_external_net_name_resolver
= TRUE
;
3593 name_resolve
->transport_name
= TRUE
;
3596 name_resolve
->concurrent_dns
= TRUE
;
3600 * Unrecognized letter.
3610 try_convert_to_custom_column(gpointer
*el_data
)
3612 /* Array of columns that have been migrated to custom columns */
3615 const gchar
*col_expr
;
3616 } migrated_columns
[] = {
3617 { COL_COS_VALUE
, "vlan.priority" },
3618 { COL_CIRCUIT_ID
, "iax2.call" },
3619 { COL_BSSGP_TLLI
, "bssgp.tlli" },
3620 { COL_HPUX_SUBSYS
, "nettl.subsys" },
3621 { COL_HPUX_DEVID
, "nettl.devid" },
3622 { COL_FR_DLCI
, "fr.dlci" },
3623 { COL_REL_CONV_TIME
, "tcp.time_relative" },
3624 { COL_DELTA_CONV_TIME
, "tcp.time_delta" },
3625 { COL_OXID
, "fc.ox_id" },
3626 { COL_RXID
, "fc.rx_id" },
3627 { COL_SRCIDX
, "mdshdr.srcidx" },
3628 { COL_DSTIDX
, "mdshdr.dstidx" },
3629 { COL_DCE_CTX
, "dcerpc.cn_ctx_id" }
3633 const gchar
*haystack_fmt
;
3635 gchar
**fmt
= (gchar
**) el_data
;
3637 for (haystack_idx
= 0;
3638 haystack_idx
< G_N_ELEMENTS(migrated_columns
);
3641 haystack_fmt
= col_format_to_string(migrated_columns
[haystack_idx
].el
);
3642 if (strcmp(haystack_fmt
, *fmt
) == 0) {
3643 gchar
*cust_col
= g_strdup_printf("%%Cus:%s:0",
3644 migrated_columns
[haystack_idx
].col_expr
);
3652 static prefs_set_pref_e
3653 set_pref(gchar
*pref_name
, const gchar
*value
, void *private_data _U_
,
3654 gboolean return_range_errors
)
3656 unsigned long int cval
;
3661 gchar
*dotp
, *last_dotp
;
3662 static gchar
*filter_label
= NULL
;
3663 static gboolean filter_enabled
= FALSE
;
3664 gchar
*filter_expr
= NULL
;
3668 if (strcmp(pref_name
, PRS_GUI_FILTER_LABEL
) == 0) {
3669 filter_label
= g_strdup(value
);
3670 } else if (strcmp(pref_name
, PRS_GUI_FILTER_ENABLED
) == 0) {
3671 filter_enabled
= (strcmp(value
, "TRUE") == 0) ? TRUE
: FALSE
;
3672 } else if (strcmp(pref_name
, PRS_GUI_FILTER_EXPR
) == 0) {
3673 filter_expr
= g_strdup(value
);
3674 filter_expression_new(filter_label
, filter_expr
, filter_enabled
);
3675 g_free(filter_label
);
3676 g_free(filter_expr
);
3677 } else if (strcmp(pref_name
, "gui.version_in_start_page") == 0) {
3678 /* Convert deprecated value to closest current equivalent */
3679 if (g_ascii_strcasecmp(value
, "true") == 0) {
3680 prefs
.gui_version_placement
= version_both
;
3682 prefs
.gui_version_placement
= version_neither
;
3684 } else if (strcmp(pref_name
, "name_resolve") == 0 ||
3685 strcmp(pref_name
, "capture.name_resolve") == 0) {
3687 * Handle the deprecated name resolution options.
3689 * "TRUE" and "FALSE", for backwards compatibility, are synonyms for
3690 * RESOLV_ALL and RESOLV_NONE.
3692 * Otherwise, we treat it as a list of name types we want to resolve.
3694 if (g_ascii_strcasecmp(value
, "true") == 0) {
3695 gbl_resolv_flags
.mac_name
= TRUE
;
3696 gbl_resolv_flags
.network_name
= TRUE
;
3697 gbl_resolv_flags
.transport_name
= TRUE
;
3698 gbl_resolv_flags
.concurrent_dns
= TRUE
;
3700 else if (g_ascii_strcasecmp(value
, "false") == 0) {
3701 gbl_resolv_flags
.mac_name
= FALSE
;
3702 gbl_resolv_flags
.network_name
= FALSE
;
3703 gbl_resolv_flags
.transport_name
= FALSE
;
3704 gbl_resolv_flags
.concurrent_dns
= FALSE
;
3707 /* start out with none set */
3708 gbl_resolv_flags
.mac_name
= FALSE
;
3709 gbl_resolv_flags
.network_name
= FALSE
;
3710 gbl_resolv_flags
.transport_name
= FALSE
;
3711 gbl_resolv_flags
.concurrent_dns
= FALSE
;
3712 if (string_to_name_resolve(value
, &gbl_resolv_flags
) != '\0')
3713 return PREFS_SET_SYNTAX_ERR
;
3716 /* Handle deprecated "global" options that don't have a module
3717 * associated with them
3719 if ((strcmp(pref_name
, "name_resolve_concurrency") == 0) ||
3720 (strcmp(pref_name
, "name_resolve_load_smi_modules") == 0) ||
3721 (strcmp(pref_name
, "name_resolve_suppress_smi_errors") == 0)) {
3722 module
= nameres_module
;
3725 /* To which module does this preference belong? */
3727 last_dotp
= pref_name
;
3729 dotp
= strchr(last_dotp
, '.');
3731 /* Either there's no such module, or no module was specified.
3732 In either case, that means there's no such preference. */
3733 return PREFS_SET_NO_SUCH_PREF
;
3735 *dotp
= '\0'; /* separate module and preference name */
3736 module
= prefs_find_module(pref_name
);
3739 * XXX - "Diameter" rather than "diameter" was used in earlier
3740 * versions of Wireshark; if we didn't find the module, and its name
3741 * was "Diameter", look for "diameter" instead.
3743 * In addition, the BEEP protocol used to be the BXXP protocol,
3744 * so if we didn't find the module, and its name was "bxxp",
3745 * look for "beep" instead.
3747 * Also, the preferences for GTP v0 and v1 were combined under
3748 * a single "gtp" heading, and the preferences for SMPP were
3749 * moved to "smpp-gsm-sms" and then moved to "gsm-sms-ud".
3750 * However, SMPP now has its own preferences, so we just map
3751 * "smpp-gsm-sms" to "gsm-sms-ud", and then handle SMPP below.
3753 * We also renamed "dcp" to "dccp", "x.25" to "x25", "x411" to "p1"
3754 * and "nsip" to "gprs_ns".
3756 * The SynOptics Network Management Protocol (SONMP) is now known by
3757 * its modern name, the Nortel Discovery Protocol (NDP).
3759 if (module
== NULL
) {
3760 if (strcmp(pref_name
, "column") == 0)
3761 module
= gui_column_module
;
3762 else if (strcmp(pref_name
, "Diameter") == 0)
3763 module
= prefs_find_module("diameter");
3764 else if (strcmp(pref_name
, "bxxp") == 0)
3765 module
= prefs_find_module("beep");
3766 else if (strcmp(pref_name
, "gtpv0") == 0 ||
3767 strcmp(pref_name
, "gtpv1") == 0)
3768 module
= prefs_find_module("gtp");
3769 else if (strcmp(pref_name
, "smpp-gsm-sms") == 0)
3770 module
= prefs_find_module("gsm-sms-ud");
3771 else if (strcmp(pref_name
, "dcp") == 0)
3772 module
= prefs_find_module("dccp");
3773 else if (strcmp(pref_name
, "x.25") == 0)
3774 module
= prefs_find_module("x25");
3775 else if (strcmp(pref_name
, "x411") == 0)
3776 module
= prefs_find_module("p1");
3777 else if (strcmp(pref_name
, "nsip") == 0)
3778 module
= prefs_find_module("gprs-ns");
3779 else if (strcmp(pref_name
, "sonmp") == 0)
3780 module
= prefs_find_module("ndp");
3781 else if (strcmp(pref_name
, "etheric") == 0 ||
3782 strcmp(pref_name
, "isup_thin") == 0) {
3783 /* This protocol was removed 7. July 2009 */
3784 return PREFS_SET_OBSOLETE
;
3787 g_warning ("Preference \"%s.%s\" has been converted to \"%s.%s.%s\"\n"
3788 "Save your preferences to make this change permanent.",
3789 pref_name
, dotp
+1, module
->parent
->name
, pref_name
, dotp
+1);
3790 prefs
.unknown_prefs
= TRUE
;
3793 *dotp
= '.'; /* put the preference string back */
3794 dotp
++; /* skip past separator to preference name */
3799 pref
= prefs_find_preference(module
, dotp
);
3802 prefs
.unknown_prefs
= TRUE
;
3804 /* "gui" prefix was added to column preferences for better organization
3805 * within the preferences file
3807 if ((strcmp(pref_name
, PRS_COL_HIDDEN
) == 0) ||
3808 (strcmp(pref_name
, PRS_COL_FMT
) == 0)) {
3809 pref
= prefs_find_preference(module
, pref_name
);
3811 else if (strcmp(module
->name
, "mgcp") == 0) {
3813 * XXX - "mgcp.display raw text toggle" and "mgcp.display dissect tree"
3814 * rather than "mgcp.display_raw_text" and "mgcp.display_dissect_tree"
3815 * were used in earlier versions of Wireshark; if we didn't find the
3816 * preference, it was an MGCP preference, and its name was
3817 * "display raw text toggle" or "display dissect tree", look for
3818 * "display_raw_text" or "display_dissect_tree" instead.
3820 * "mgcp.tcp.port" and "mgcp.udp.port" are harder to handle, as both
3821 * the gateway and callagent ports were given those names; we interpret
3822 * the first as "mgcp.{tcp,udp}.gateway_port" and the second as
3823 * "mgcp.{tcp,udp}.callagent_port", as that's the order in which
3824 * they were registered by the MCCP dissector and thus that's the
3825 * order in which they were written to the preferences file. (If
3826 * we're not reading the preferences file, but are handling stuff
3827 * from a "-o" command-line option, we have no clue which the user
3828 * had in mind - they should have used "mgcp.{tcp,udp}.gateway_port"
3829 * or "mgcp.{tcp,udp}.callagent_port" instead.)
3831 if (strcmp(dotp
, "display raw text toggle") == 0)
3832 pref
= prefs_find_preference(module
, "display_raw_text");
3833 else if (strcmp(dotp
, "display dissect tree") == 0)
3834 pref
= prefs_find_preference(module
, "display_dissect_tree");
3835 else if (strcmp(dotp
, "tcp.port") == 0) {
3836 mgcp_tcp_port_count
++;
3837 if (mgcp_tcp_port_count
== 1) {
3838 /* It's the first one */
3839 pref
= prefs_find_preference(module
, "tcp.gateway_port");
3840 } else if (mgcp_tcp_port_count
== 2) {
3841 /* It's the second one */
3842 pref
= prefs_find_preference(module
, "tcp.callagent_port");
3844 /* Otherwise it's from the command line, and we don't bother
3846 } else if (strcmp(dotp
, "udp.port") == 0) {
3847 mgcp_udp_port_count
++;
3848 if (mgcp_udp_port_count
== 1) {
3849 /* It's the first one */
3850 pref
= prefs_find_preference(module
, "udp.gateway_port");
3851 } else if (mgcp_udp_port_count
== 2) {
3852 /* It's the second one */
3853 pref
= prefs_find_preference(module
, "udp.callagent_port");
3855 /* Otherwise it's from the command line, and we don't bother
3858 } else if (strcmp(module
->name
, "smb") == 0) {
3859 /* Handle old names for SMB preferences. */
3860 if (strcmp(dotp
, "smb.trans.reassembly") == 0)
3861 pref
= prefs_find_preference(module
, "trans_reassembly");
3862 else if (strcmp(dotp
, "smb.dcerpc.reassembly") == 0)
3863 pref
= prefs_find_preference(module
, "dcerpc_reassembly");
3864 } else if (strcmp(module
->name
, "ndmp") == 0) {
3865 /* Handle old names for NDMP preferences. */
3866 if (strcmp(dotp
, "ndmp.desegment") == 0)
3867 pref
= prefs_find_preference(module
, "desegment");
3868 } else if (strcmp(module
->name
, "diameter") == 0) {
3869 /* Handle old names for Diameter preferences. */
3870 if (strcmp(dotp
, "diameter.desegment") == 0)
3871 pref
= prefs_find_preference(module
, "desegment");
3872 } else if (strcmp(module
->name
, "pcli") == 0) {
3873 /* Handle old names for PCLI preferences. */
3874 if (strcmp(dotp
, "pcli.udp_port") == 0)
3875 pref
= prefs_find_preference(module
, "udp_port");
3876 } else if (strcmp(module
->name
, "artnet") == 0) {
3877 /* Handle old names for ARTNET preferences. */
3878 if (strcmp(dotp
, "artnet.udp_port") == 0)
3879 pref
= prefs_find_preference(module
, "udp_port");
3880 } else if (strcmp(module
->name
, "mapi") == 0) {
3881 /* Handle old names for MAPI preferences. */
3882 if (strcmp(dotp
, "mapi_decrypt") == 0)
3883 pref
= prefs_find_preference(module
, "decrypt");
3884 } else if (strcmp(module
->name
, "fc") == 0) {
3885 /* Handle old names for Fibre Channel preferences. */
3886 if (strcmp(dotp
, "reassemble_fc") == 0)
3887 pref
= prefs_find_preference(module
, "reassemble");
3888 else if (strcmp(dotp
, "fc_max_frame_size") == 0)
3889 pref
= prefs_find_preference(module
, "max_frame_size");
3890 } else if (strcmp(module
->name
, "fcip") == 0) {
3891 /* Handle old names for Fibre Channel-over-IP preferences. */
3892 if (strcmp(dotp
, "desegment_fcip_messages") == 0)
3893 pref
= prefs_find_preference(module
, "desegment");
3894 else if (strcmp(dotp
, "fcip_port") == 0)
3895 pref
= prefs_find_preference(module
, "target_port");
3896 } else if (strcmp(module
->name
, "gtp") == 0) {
3897 /* Handle old names for GTP preferences. */
3898 if (strcmp(dotp
, "gtpv0_port") == 0)
3899 pref
= prefs_find_preference(module
, "v0_port");
3900 else if (strcmp(dotp
, "gtpv1c_port") == 0)
3901 pref
= prefs_find_preference(module
, "v1c_port");
3902 else if (strcmp(dotp
, "gtpv1u_port") == 0)
3903 pref
= prefs_find_preference(module
, "v1u_port");
3904 else if (strcmp(dotp
, "gtp_dissect_tpdu") == 0)
3905 pref
= prefs_find_preference(module
, "dissect_tpdu");
3906 else if (strcmp(dotp
, "gtpv0_dissect_cdr_as") == 0)
3907 pref
= prefs_find_preference(module
, "v0_dissect_cdr_as");
3908 else if (strcmp(dotp
, "gtpv0_check_etsi") == 0)
3909 pref
= prefs_find_preference(module
, "v0_check_etsi");
3910 else if (strcmp(dotp
, "gtpv1_check_etsi") == 0)
3911 pref
= prefs_find_preference(module
, "v1_check_etsi");
3912 } else if (strcmp(module
->name
, "ip") == 0) {
3913 /* Handle old names for IP preferences. */
3914 if (strcmp(dotp
, "ip_summary_in_tree") == 0)
3915 pref
= prefs_find_preference(module
, "summary_in_tree");
3916 } else if (strcmp(module
->name
, "iscsi") == 0) {
3917 /* Handle old names for iSCSI preferences. */
3918 if (strcmp(dotp
, "iscsi_port") == 0)
3919 pref
= prefs_find_preference(module
, "target_port");
3920 } else if (strcmp(module
->name
, "lmp") == 0) {
3921 /* Handle old names for LMP preferences. */
3922 if (strcmp(dotp
, "lmp_version") == 0)
3923 pref
= prefs_find_preference(module
, "version");
3924 } else if (strcmp(module
->name
, "mtp3") == 0) {
3925 /* Handle old names for MTP3 preferences. */
3926 if (strcmp(dotp
, "mtp3_standard") == 0)
3927 pref
= prefs_find_preference(module
, "standard");
3928 else if (strcmp(dotp
, "net_addr_format") == 0)
3929 pref
= prefs_find_preference(module
, "addr_format");
3930 } else if (strcmp(module
->name
, "nlm") == 0) {
3931 /* Handle old names for NLM preferences. */
3932 if (strcmp(dotp
, "nlm_msg_res_matching") == 0)
3933 pref
= prefs_find_preference(module
, "msg_res_matching");
3934 } else if (strcmp(module
->name
, "ppp") == 0) {
3935 /* Handle old names for PPP preferences. */
3936 if (strcmp(dotp
, "ppp_fcs") == 0)
3937 pref
= prefs_find_preference(module
, "fcs_type");
3938 else if (strcmp(dotp
, "ppp_vj") == 0)
3939 pref
= prefs_find_preference(module
, "decompress_vj");
3940 } else if (strcmp(module
->name
, "rsvp") == 0) {
3941 /* Handle old names for RSVP preferences. */
3942 if (strcmp(dotp
, "rsvp_process_bundle") == 0)
3943 pref
= prefs_find_preference(module
, "process_bundle");
3944 } else if (strcmp(module
->name
, "tcp") == 0) {
3945 /* Handle old names for TCP preferences. */
3946 if (strcmp(dotp
, "tcp_summary_in_tree") == 0)
3947 pref
= prefs_find_preference(module
, "summary_in_tree");
3948 else if (strcmp(dotp
, "tcp_analyze_sequence_numbers") == 0)
3949 pref
= prefs_find_preference(module
, "analyze_sequence_numbers");
3950 else if (strcmp(dotp
, "tcp_relative_sequence_numbers") == 0)
3951 pref
= prefs_find_preference(module
, "relative_sequence_numbers");
3952 } else if (strcmp(module
->name
, "udp") == 0) {
3953 /* Handle old names for UDP preferences. */
3954 if (strcmp(dotp
, "udp_summary_in_tree") == 0)
3955 pref
= prefs_find_preference(module
, "summary_in_tree");
3956 } else if (strcmp(module
->name
, "ndps") == 0) {
3957 /* Handle old names for NDPS preferences. */
3958 if (strcmp(dotp
, "desegment_ndps") == 0)
3959 pref
= prefs_find_preference(module
, "desegment_tcp");
3960 } else if (strcmp(module
->name
, "http") == 0) {
3961 /* Handle old names for HTTP preferences. */
3962 if (strcmp(dotp
, "desegment_http_headers") == 0)
3963 pref
= prefs_find_preference(module
, "desegment_headers");
3964 else if (strcmp(dotp
, "desegment_http_body") == 0)
3965 pref
= prefs_find_preference(module
, "desegment_body");
3966 } else if (strcmp(module
->name
, "smpp") == 0) {
3967 /* Handle preferences that moved from SMPP. */
3968 module_t
*new_module
= prefs_find_module("gsm-sms-ud");
3970 if (strcmp(dotp
, "port_number_udh_means_wsp") == 0)
3971 pref
= prefs_find_preference(new_module
, "port_number_udh_means_wsp");
3972 else if (strcmp(dotp
, "try_dissect_1st_fragment") == 0)
3973 pref
= prefs_find_preference(new_module
, "try_dissect_1st_fragment");
3975 } else if (strcmp(module
->name
, "asn1") == 0) {
3976 /* Handle old generic ASN.1 preferences (it's not really a
3977 rename, as the new preferences support multiple ports,
3978 but we might as well copy them over). */
3979 if (strcmp(dotp
, "tcp_port") == 0)
3980 pref
= prefs_find_preference(module
, "tcp_ports");
3981 else if (strcmp(dotp
, "udp_port") == 0)
3982 pref
= prefs_find_preference(module
, "udp_ports");
3983 else if (strcmp(dotp
, "sctp_port") == 0)
3984 pref
= prefs_find_preference(module
, "sctp_ports");
3985 } else if (strcmp(module
->name
, "llcgprs") == 0) {
3986 if (strcmp(dotp
, "ignore_cipher_bit") == 0)
3987 pref
= prefs_find_preference(module
, "autodetect_cipher_bit");
3988 } else if (strcmp(module
->name
, "erf") == 0) {
3989 if (strcmp(dotp
, "erfeth") == 0) {
3990 /* Handle the old "erfeth" preference; map it to the new
3991 "ethfcs" preference, and map the values to those for
3992 the new preference. */
3993 pref
= prefs_find_preference(module
, "ethfcs");
3994 if (strcmp(value
, "ethfcs") == 0 || strcmp(value
, "Ethernet with FCS") == 0)
3996 else if (strcmp(value
, "eth") == 0 || strcmp(value
, "Ethernet") == 0)
3998 else if (strcmp(value
, "raw") == 0 || strcmp(value
, "Raw data") == 0)
4000 } else if (strcmp(dotp
, "erfatm") == 0) {
4001 /* Handle the old "erfatm" preference; map it to the new
4002 "aal5_type" preference, and map the values to those for
4003 the new preference. */
4004 pref
= prefs_find_preference(module
, "aal5_type");
4005 if (strcmp(value
, "atm") == 0 || strcmp(value
, "ATM") == 0)
4007 else if (strcmp(value
, "llc") == 0 || strcmp(value
, "LLC") == 0)
4009 else if (strcmp(value
, "raw") == 0 || strcmp(value
, "Raw data") == 0)
4011 } else if (strcmp(dotp
, "erfhdlc") == 0) {
4012 /* Handle the old "erfhdlc" preference; map it to the new
4013 "hdlc_type" preference, and map the values to those for
4014 the new preference. */
4015 pref
= prefs_find_preference(module
, "hdlc_type");
4016 if (strcmp(value
, "chdlc") == 0 || strcmp(value
, "Cisco HDLC") == 0)
4018 else if (strcmp(value
, "ppp") == 0 || strcmp(value
, "PPP serial") == 0)
4020 else if (strcmp(value
, "fr") == 0 || strcmp(value
, "Frame Relay") == 0)
4022 else if (strcmp(value
, "mtp2") == 0 || strcmp(value
, "SS7 MTP2") == 0)
4024 else if (strcmp(value
, "raw") == 0 || strcmp(value
, "Raw data") == 0)
4027 } else if (strcmp(module
->name
, "eth") == 0) {
4028 /* "eth.qinq_ethertype" has been changed(restored) to "vlan.qinq.ethertype" */
4029 if (strcmp(dotp
, "qinq_ethertype") == 0) {
4030 module_t
*new_module
= prefs_find_module("vlan");
4032 pref
= prefs_find_preference(new_module
, "qinq_ethertype");
4033 module
= new_module
;
4036 } else if (strcmp(module
->name
, "taps") == 0) {
4037 /* taps preferences moved to "statistics" module */
4038 if (strcmp(dotp
, "update_interval") == 0 ||
4039 strcmp(dotp
, "rtp_player_max_visible") == 0)
4040 pref
= prefs_find_preference(stats_module
, dotp
);
4041 } else if (strcmp(module
->name
, "packet_list") == 0) {
4042 /* packet_list preferences moved to protocol module */
4043 if (strcmp(dotp
, "display_hidden_proto_items") == 0)
4044 pref
= prefs_find_preference(protocols_module
, dotp
);
4045 } else if (strcmp(module
->name
, "stream") == 0) {
4046 /* stream preferences moved to gui color module */
4047 if ((strcmp(dotp
, "client.fg") == 0) ||
4048 (strcmp(dotp
, "client.bg") == 0) ||
4049 (strcmp(dotp
, "server.fg") == 0) ||
4050 (strcmp(dotp
, "server.bg") == 0))
4051 pref
= prefs_find_preference(gui_color_module
, pref_name
);
4052 } else if (strcmp(module
->name
, "nameres") == 0) {
4053 if (strcmp(pref_name
, "name_resolve_concurrency") == 0) {
4054 pref
= prefs_find_preference(nameres_module
, pref_name
);
4055 } else if (strcmp(pref_name
, "name_resolve_load_smi_modules") == 0) {
4056 pref
= prefs_find_preference(nameres_module
, "load_smi_modules");
4057 } else if (strcmp(pref_name
, "name_resolve_suppress_smi_errors") == 0) {
4058 pref
= prefs_find_preference(nameres_module
, "suppress_smi_errors");
4063 return PREFS_SET_NO_SUCH_PREF
; /* no such preference */
4065 switch (pref
->type
) {
4068 /* XXX - give an error if it doesn't fit in a guint? */
4069 uval
= (guint
)strtoul(value
, &p
, pref
->info
.base
);
4070 if (p
== value
|| *p
!= '\0')
4071 return PREFS_SET_SYNTAX_ERR
; /* number was bad */
4072 if (*pref
->varp
.uint
!= uval
) {
4073 module
->prefs_changed
= TRUE
;
4074 *pref
->varp
.uint
= uval
;
4079 /* XXX - give an error if it's neither "true" nor "false"? */
4080 if (g_ascii_strcasecmp(value
, "true") == 0)
4084 if (*pref
->varp
.boolp
!= bval
) {
4085 module
->prefs_changed
= TRUE
;
4086 *pref
->varp
.boolp
= bval
;
4091 /* XXX - give an error if it doesn't match? */
4092 enum_val
= find_val_for_string(value
, pref
->info
.enum_info
.enumvals
,
4094 if (*pref
->varp
.enump
!= enum_val
) {
4095 module
->prefs_changed
= TRUE
;
4096 *pref
->varp
.enump
= enum_val
;
4103 if (strcmp(*pref
->varp
.string
, value
) != 0) {
4104 module
->prefs_changed
= TRUE
;
4105 g_free((void *)*pref
->varp
.string
);
4106 *pref
->varp
.string
= g_strdup(value
);
4114 if (range_convert_str_work(&newrange
, value
, pref
->info
.max_value
,
4115 return_range_errors
) != CVT_NO_ERROR
) {
4116 return PREFS_SET_SYNTAX_ERR
; /* number was bad */
4119 if (!ranges_are_equal(*pref
->varp
.range
, newrange
)) {
4120 module
->prefs_changed
= TRUE
;
4121 g_free(*pref
->varp
.range
);
4122 *pref
->varp
.range
= newrange
;
4131 cval
= strtoul(value
, NULL
, 16);
4132 pref
->varp
.colorp
->pixel
= 0;
4133 if ((pref
->varp
.colorp
->red
!= RED_COMPONENT(cval
)) ||
4134 (pref
->varp
.colorp
->green
!= GREEN_COMPONENT(cval
)) ||
4135 (pref
->varp
.colorp
->blue
!= BLUE_COMPONENT(cval
))) {
4136 module
->prefs_changed
= TRUE
;
4137 pref
->varp
.colorp
->red
= RED_COMPONENT(cval
);
4138 pref
->varp
.colorp
->green
= GREEN_COMPONENT(cval
);
4139 pref
->varp
.colorp
->blue
= BLUE_COMPONENT(cval
);
4145 return pref
->custom_cbs
.set_cb(pref
, value
, &module
->prefs_changed
);
4147 case PREF_STATIC_TEXT
:
4154 return PREFS_SET_OBSOLETE
; /* no such preference any more */
4158 return PREFS_SET_OK
;
4163 gboolean is_gui_module
;
4164 } write_gui_pref_arg_t
;
4167 prefs_pref_type_name(pref_t
*pref
)
4169 const char *type_name
= "[Unknown]";
4172 return type_name
; /* ...or maybe assert? */
4175 switch (pref
->type
) {
4178 switch (pref
->info
.base
) {
4181 type_name
= "Decimal";
4185 type_name
= "Octal";
4189 type_name
= "Hexadecimal";
4195 type_name
= "Boolean";
4199 type_name
= "Choice";
4203 type_name
= "String";
4207 type_name
= "Filename";
4211 type_name
= "Directory";
4215 type_name
= "Range";
4219 type_name
= "Color";
4223 if (pref
->custom_cbs
.type_name_cb
)
4224 return pref
->custom_cbs
.type_name_cb();
4225 type_name
= "Custom";
4229 type_name
= "Obsolete";
4232 case PREF_STATIC_TEXT
:
4233 type_name
= "Static text";
4244 prefs_pref_type_description(pref_t
*pref
)
4246 const char *type_desc
= "An unkown preference type";
4249 return g_strdup_printf("%s.", type_desc
); /* ...or maybe assert? */
4252 switch (pref
->type
) {
4255 switch (pref
->info
.base
) {
4258 type_desc
= "A decimal number";
4262 type_desc
= "An octal number";
4266 type_desc
= "A hexadecimal number";
4272 type_desc
= "TRUE or FALSE (case-insensitive)";
4277 const enum_val_t
*enum_valp
= pref
->info
.enum_info
.enumvals
;
4278 GString
*enum_str
= g_string_new("One of: ");
4279 while (enum_valp
->name
!= NULL
) {
4280 g_string_append(enum_str
, enum_valp
->description
);
4282 if (enum_valp
->name
!= NULL
)
4283 g_string_append(enum_str
, ", ");
4285 g_string_append(enum_str
, "\n(case-insensitive).");
4286 return g_string_free(enum_str
, FALSE
);
4291 type_desc
= "A string";
4295 type_desc
= "A path to a file";
4299 type_desc
= "A path to a directory";
4304 type_desc
= "A string denoting an positive integer range (e.g., \"1-20,30-40\")";
4310 type_desc
= "A six-digit hexadecimal RGB color triplet (e.g. fce94f)";
4315 if (pref
->custom_cbs
.type_description_cb
)
4316 return pref
->custom_cbs
.type_description_cb();
4317 type_desc
= "A custom value";
4321 type_desc
= "An obsolete preference";
4324 case PREF_STATIC_TEXT
:
4325 type_desc
= "[Static text]";
4329 type_desc
= "Configuration data stored in its own file";
4335 return g_strdup(type_desc
);
4339 prefs_pref_is_default(pref_t
*pref
) {
4340 if (!pref
) return FALSE
;
4342 switch (pref
->type
) {
4345 if (pref
->default_val
.uint
== *pref
->varp
.uint
)
4350 if (pref
->default_val
.boolval
== *pref
->varp
.boolp
)
4355 if (pref
->default_val
.enumval
== *pref
->varp
.enump
)
4362 if (!(g_strcmp0(pref
->default_val
.string
, *pref
->varp
.string
)))
4368 if ((ranges_are_equal(pref
->default_val
.range
, *pref
->varp
.range
)))
4375 if ((pref
->default_val
.color
.red
== pref
->varp
.colorp
->red
) &&
4376 (pref
->default_val
.color
.green
== pref
->varp
.colorp
->green
) &&
4377 (pref
->default_val
.color
.blue
== pref
->varp
.colorp
->blue
))
4383 return pref
->custom_cbs
.is_default_cb(pref
);
4386 case PREF_STATIC_TEXT
:
4389 /* g_assert_not_reached(); */
4396 prefs_pref_to_str(pref_t
*pref
, pref_source_t source
) {
4397 const char *pref_text
= "[Unknown]";
4399 gboolean pref_boolval
;
4401 const char *pref_string
;
4402 range_t
*pref_range
;
4403 color_t
*pref_color
;
4406 return g_strdup(pref_text
);
4411 pref_uint
= pref
->default_val
.uint
;
4412 pref_boolval
= pref
->default_val
.boolval
;
4413 pref_enumval
= pref
->default_val
.enumval
;
4414 pref_string
= pref
->default_val
.string
;
4415 pref_range
= pref
->default_val
.range
;
4416 pref_color
= &pref
->default_val
.color
;
4419 pref_uint
= pref
->stashed_val
.uint
;
4420 pref_boolval
= pref
->stashed_val
.boolval
;
4421 pref_enumval
= pref
->stashed_val
.enumval
;
4422 pref_string
= pref
->stashed_val
.string
;
4423 pref_range
= pref
->stashed_val
.range
;
4424 pref_color
= &pref
->stashed_val
.color
;
4427 pref_uint
= *pref
->varp
.uint
;
4428 pref_boolval
= *pref
->varp
.boolp
;
4429 pref_enumval
= *pref
->varp
.enump
;
4430 pref_string
= *pref
->varp
.string
;
4431 pref_range
= *pref
->varp
.range
;
4432 pref_color
= pref
->varp
.colorp
;
4435 return g_strdup(pref_text
);
4438 switch (pref
->type
) {
4441 switch (pref
->info
.base
) {
4444 return g_strdup_printf("%u", pref_uint
);
4448 return g_strdup_printf("%#o", pref_uint
);
4452 return g_strdup_printf("%#x", pref_uint
);
4458 return g_strdup_printf("%s", pref_boolval
? "TRUE" : "FALSE");
4464 * For now, we return the "description" value, so that if we
4465 * save the preferences older versions of Wireshark can at
4466 * least read preferences that they supported; we support
4467 * either the short name or the description when reading
4468 * the preferences file or a "-o" option.
4470 const enum_val_t
*enum_valp
= pref
->info
.enum_info
.enumvals
;
4471 while (enum_valp
->name
!= NULL
) {
4472 if (enum_valp
->value
== pref_enumval
)
4473 return g_strdup(enum_valp
->description
);
4482 return g_strdup(pref_string
);
4486 pref_text
= range_convert_range(pref_range
);
4490 return g_strdup_printf("%02x%02x%02x",
4491 (pref_color
->red
* 255 / 65535),
4492 (pref_color
->green
* 255 / 65535),
4493 (pref_color
->blue
* 255 / 65535));
4497 if (pref
->custom_cbs
.to_str_cb
)
4498 return pref
->custom_cbs
.to_str_cb(pref
, source
== pref_default
? TRUE
: FALSE
);
4499 pref_text
= "[Custom]";
4503 pref_text
= "[Obsolete]";
4506 case PREF_STATIC_TEXT
:
4507 pref_text
= "[Static text]";
4512 uat_t
*uat
= pref
->varp
.uat
;
4513 if (uat
&& uat
->filename
)
4514 return g_strdup_printf("[Managed in the file \"%s\"]", uat
->filename
);
4516 pref_text
= "[Managed in an unknown file]";
4523 return g_strdup(pref_text
);
4527 * Write out a single dissector preference.
4530 write_pref(gpointer data
, gpointer user_data
)
4532 pref_t
*pref
= (pref_t
*)data
;
4533 write_pref_arg_t
*arg
= (write_pref_arg_t
*)user_data
;
4537 switch (pref
->type
) {
4540 * This preference is no longer supported; it's not a
4541 * real preference, so we don't write it out (i.e., we
4542 * treat it as if it weren't found in the list of
4543 * preferences, and we weren't called in the first place).
4547 case PREF_STATIC_TEXT
:
4549 /* Nothing to do; don't bother printing the description */
4555 if (pref
->type
!= PREF_CUSTOM
|| pref
->custom_cbs
.type_name_cb() != NULL
) {
4557 * The prefix will either be the module name or the parent
4558 * name if it's a subtree
4560 const char *name_prefix
= (arg
->module
->name
!= NULL
) ? arg
->module
->name
: arg
->module
->parent
->name
;
4561 char *type_desc
, *pref_text
;
4562 const char * def_prefix
= prefs_pref_is_default(pref
) ? "#" : "";
4564 if (pref
->type
== PREF_CUSTOM
) fprintf(arg
->pf
, "\n# %s", pref
->custom_cbs
.type_name_cb());
4565 fprintf(arg
->pf
, "\n");
4566 if (pref
->description
&&
4567 (g_ascii_strncasecmp(pref
->description
,"", 2) != 0)) {
4568 if (pref
->type
!= PREF_CUSTOM
) {
4569 /* We get duplicate lines otherwise. */
4571 desc_lines
= g_strsplit(pref
->description
,"\n",0);
4572 for (i
= 0; desc_lines
[i
] != NULL
; ++i
) {
4573 fprintf(arg
->pf
, "# %s\n", desc_lines
[i
]);
4575 g_strfreev(desc_lines
);
4578 fprintf(arg
->pf
, "# No description\n");
4581 type_desc
= prefs_pref_type_description(pref
);
4582 desc_lines
= g_strsplit(type_desc
,"\n",0);
4583 for (i
= 0; desc_lines
[i
] != NULL
; ++i
) {
4584 fprintf(arg
->pf
, "# %s\n", desc_lines
[i
]);
4586 g_strfreev(desc_lines
);
4589 pref_text
= prefs_pref_to_str(pref
, pref_current
);
4590 fprintf(arg
->pf
, "%s%s.%s: ", def_prefix
, name_prefix
, pref
->name
);
4591 desc_lines
= g_strsplit(pref_text
,"\n",0);
4592 for (i
= 0; desc_lines
[i
] != NULL
; ++i
) {
4593 fprintf(arg
->pf
, "%s%s\n", i
== 0 ? "" : def_prefix
, desc_lines
[i
]);
4595 if (i
== 0) fprintf(arg
->pf
, "\n");
4596 g_strfreev(desc_lines
);
4603 * Write out all preferences for a module.
4606 write_module_prefs(module_t
*module
, gpointer user_data
)
4608 write_gui_pref_arg_t
*gui_pref_arg
= (write_gui_pref_arg_t
*)user_data
;
4609 write_pref_arg_t arg
;
4611 /* The GUI module needs to be explicitly called out so it
4612 can be written out of order */
4613 if ((module
== gui_module
) && (gui_pref_arg
->is_gui_module
!= TRUE
))
4616 /* Write a header for the main modules and GUI sub-modules */
4617 if (((module
->parent
== NULL
) || (module
->parent
== gui_module
)) &&
4618 ((prefs_module_has_submodules(module
)) ||
4619 (module
->numprefs
> 0) ||
4620 (module
->name
== NULL
))) {
4621 if ((module
->name
== NULL
) && (module
->parent
!= NULL
)) {
4622 fprintf(gui_pref_arg
->pf
, "\n####### %s: %s ########\n", module
->parent
->title
, module
->title
);
4624 fprintf(gui_pref_arg
->pf
, "\n####### %s ########\n", module
->title
);
4628 arg
.module
= module
;
4629 arg
.pf
= gui_pref_arg
->pf
;
4630 g_list_foreach(arg
.module
->prefs
, write_pref
, &arg
);
4632 if (prefs_module_has_submodules(module
))
4633 return prefs_modules_foreach_submodules(module
, write_module_prefs
, user_data
);
4638 /* Write out "prefs" to the user's preferences file, and return 0.
4640 If the preferences file path is NULL, write to stdout.
4642 If we got an error, stuff a pointer to the path of the preferences file
4643 into "*pf_path_return", and return the errno. */
4645 write_prefs(char **pf_path_return
)
4649 write_gui_pref_arg_t write_gui_pref_info
;
4651 /* Needed for "-G defaultprefs" */
4655 * - Split output lines longer than MAX_VAL_LEN
4656 * - Create a function for the preference directory check/creation
4657 * so that duplication can be avoided with filter.c
4660 if (pf_path_return
!= NULL
) {
4661 pf_path
= get_persconffile_path(PF_NAME
, TRUE
);
4662 if ((pf
= ws_fopen(pf_path
, "w")) == NULL
) {
4663 *pf_path_return
= pf_path
;
4670 fputs("# Configuration file for Wireshark " VERSION
".\n"
4672 "# This file is regenerated each time preferences are saved within\n"
4673 "# Wireshark. Making manual changes should be safe, however.\n"
4674 "# Preferences that have been commented out have not been\n"
4675 "# changed from their default value.\n", pf
);
4678 * For "backwards compatibility" the GUI module is written first as it's
4679 * at the top of the file. This is followed by all modules that can't
4680 * fit into the preferences read/write API. Finally the remaining modules
4681 * are written in alphabetical order (including of course the protocol preferences)
4683 write_gui_pref_info
.pf
= pf
;
4684 write_gui_pref_info
.is_gui_module
= TRUE
;
4686 write_module_prefs(gui_module
, &write_gui_pref_info
);
4689 struct filter_expression
*fe
= *(struct filter_expression
**)prefs
.filter_expressions
;
4692 fprintf(pf
, "\n####### Filter Expressions ########\n");
4694 while (fe
!= NULL
) {
4695 if (fe
->deleted
== FALSE
) {
4696 fprintf(pf
, "%s: %s\n", PRS_GUI_FILTER_LABEL
, fe
->label
);
4697 fprintf(pf
, "%s: %s\n", PRS_GUI_FILTER_ENABLED
,
4698 fe
->enabled
== TRUE
? "TRUE" : "FALSE");
4699 fprintf(pf
, "%s: %s\n", PRS_GUI_FILTER_EXPR
, fe
->expression
);
4705 write_gui_pref_info
.is_gui_module
= FALSE
;
4706 prefs_modules_foreach_submodules(NULL
, write_module_prefs
, &write_gui_pref_info
);
4710 /* XXX - catch I/O errors (e.g. "ran out of disk space") and return
4711 an error indication, or maybe write to a new preferences file and
4712 rename that file on top of the old one only if there are not I/O
4717 /** The col_list is only partly managed by the custom preference API
4718 * because its data is shared between multiple preferences, so
4722 free_col_info(GList
* list
)
4726 while (list
!= NULL
) {
4727 cfmt
= (fmt_data
*)list
->data
;
4729 g_free(cfmt
->title
);
4730 g_free(cfmt
->custom_field
);
4732 list
= g_list_remove_link(list
, list
);
4744 * indent-tabs-mode: nil
4747 * ex: set shiftwidth=4 tabstop=8 expandtab:
4748 * :indentSize=4:tabSize=8:noTabs=true: