2018-01-08 22:02:15 +00:00
|
|
|
/* preference_utils.c
|
2013-01-18 00:50:14 +00:00
|
|
|
* Routines for handling preferences
|
|
|
|
*
|
|
|
|
* Wireshark - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@wireshark.org>
|
|
|
|
* Copyright 1998 Gerald Combs
|
|
|
|
*
|
2018-02-07 11:26:45 +00:00
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
2013-01-18 00:50:14 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
2013-01-23 19:04:36 +00:00
|
|
|
#include <epan/column.h>
|
2013-11-17 02:55:14 +00:00
|
|
|
#include <wsutil/filesystem.h>
|
2021-06-17 14:58:56 +00:00
|
|
|
#include <wsutil/wslog.h>
|
2013-01-18 00:50:14 +00:00
|
|
|
#include <epan/prefs.h>
|
|
|
|
#include <epan/prefs-int.h>
|
2016-10-07 20:25:01 +00:00
|
|
|
#include <epan/packet.h>
|
|
|
|
#include <epan/decode_as.h>
|
2018-09-08 09:49:22 +00:00
|
|
|
#include <epan/uat-int.h>
|
2019-12-11 03:01:16 +00:00
|
|
|
#include <ui/recent.h>
|
2013-01-18 00:50:14 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_LIBPCAP
|
|
|
|
#include "capture_opts.h"
|
|
|
|
#include "ui/capture_globals.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "ui/preference_utils.h"
|
|
|
|
#include "ui/simple_dialog.h"
|
|
|
|
|
2018-04-16 00:35:42 +00:00
|
|
|
#ifdef HAVE_LIBPCAP
|
|
|
|
gboolean auto_scroll_live;
|
|
|
|
#endif
|
2013-01-18 00:50:14 +00:00
|
|
|
|
|
|
|
/* Fill in capture options with values from the preferences */
|
|
|
|
void
|
|
|
|
prefs_to_capture_opts(void)
|
|
|
|
{
|
|
|
|
#ifdef HAVE_LIBPCAP
|
2017-11-29 00:03:11 +00:00
|
|
|
/* Set promiscuous mode from the preferences setting. */
|
|
|
|
/* the same applies to other preferences settings as well. */
|
2013-01-18 00:50:14 +00:00
|
|
|
global_capture_opts.default_options.promisc_mode = prefs.capture_prom_mode;
|
|
|
|
global_capture_opts.use_pcapng = prefs.capture_pcap_ng;
|
2018-05-16 08:22:54 +00:00
|
|
|
global_capture_opts.show_info = prefs.capture_show_info;
|
2013-01-18 00:50:14 +00:00
|
|
|
global_capture_opts.real_time_mode = prefs.capture_real_time;
|
|
|
|
auto_scroll_live = prefs.capture_auto_scroll;
|
|
|
|
#endif /* HAVE_LIBPCAP */
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
prefs_main_write(void)
|
|
|
|
{
|
2017-11-29 00:03:11 +00:00
|
|
|
int err;
|
|
|
|
char *pf_dir_path;
|
|
|
|
char *pf_path;
|
|
|
|
|
|
|
|
/* Create the directory that holds personal configuration files, if
|
|
|
|
necessary. */
|
|
|
|
if (create_persconffile_dir(&pf_dir_path) == -1) {
|
|
|
|
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
|
|
|
|
"Can't create directory\n\"%s\"\nfor preferences file: %s.", pf_dir_path,
|
|
|
|
g_strerror(errno));
|
|
|
|
g_free(pf_dir_path);
|
|
|
|
} else {
|
2019-12-11 03:01:16 +00:00
|
|
|
/* Write the preferences out. */
|
2017-11-29 00:03:11 +00:00
|
|
|
err = write_prefs(&pf_path);
|
|
|
|
if (err != 0) {
|
|
|
|
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
|
2013-01-18 00:50:14 +00:00
|
|
|
"Can't open preferences file\n\"%s\": %s.", pf_path,
|
|
|
|
g_strerror(err));
|
2017-11-29 00:03:11 +00:00
|
|
|
g_free(pf_path);
|
|
|
|
}
|
2019-12-11 03:01:16 +00:00
|
|
|
/* Write recent and recent_common files out to ensure sync with prefs. */
|
|
|
|
write_profile_recent();
|
|
|
|
write_recent();
|
2013-01-18 00:50:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-06 04:39:55 +00:00
|
|
|
static unsigned int
|
2016-01-21 12:41:42 +00:00
|
|
|
prefs_store_ext_helper(const char * module_name, const char *pref_name, const char *pref_value)
|
2015-06-05 09:19:37 +00:00
|
|
|
{
|
2017-11-29 00:03:11 +00:00
|
|
|
module_t * module = NULL;
|
|
|
|
pref_t * pref = NULL;
|
2018-01-06 04:39:55 +00:00
|
|
|
unsigned int pref_changed = 0;
|
2015-06-05 09:19:37 +00:00
|
|
|
|
2021-12-30 16:03:15 +00:00
|
|
|
if ( !prefs_is_registered_protocol(module_name))
|
2018-01-06 04:39:55 +00:00
|
|
|
return 0;
|
2015-06-05 09:19:37 +00:00
|
|
|
|
2017-11-29 00:03:11 +00:00
|
|
|
module = prefs_find_module(module_name);
|
2021-12-30 16:03:15 +00:00
|
|
|
if ( !module )
|
2018-01-06 04:39:55 +00:00
|
|
|
return 0;
|
2015-06-05 09:19:37 +00:00
|
|
|
|
2017-11-29 00:03:11 +00:00
|
|
|
pref = prefs_find_preference(module, pref_name);
|
2015-06-05 09:19:37 +00:00
|
|
|
|
2017-11-29 00:03:11 +00:00
|
|
|
if (!pref)
|
2018-01-06 04:39:55 +00:00
|
|
|
return 0;
|
2015-06-05 09:19:37 +00:00
|
|
|
|
2017-11-29 00:03:11 +00:00
|
|
|
if (prefs_get_type(pref) == PREF_STRING )
|
|
|
|
{
|
2018-01-06 04:39:55 +00:00
|
|
|
pref_changed |= prefs_set_string_value(pref, pref_value, pref_stashed);
|
2021-12-30 16:03:15 +00:00
|
|
|
if ( !pref_changed || prefs_get_string_value(pref, pref_stashed) != 0 )
|
2018-01-06 04:39:55 +00:00
|
|
|
pref_changed |= prefs_set_string_value(pref, pref_value, pref_current);
|
2021-12-30 16:03:15 +00:00
|
|
|
} else if (prefs_get_type(pref) == PREF_PASSWORD )
|
|
|
|
{
|
|
|
|
pref_changed |= prefs_set_password_value(pref, pref_value, pref_stashed);
|
|
|
|
if ( !pref_changed || prefs_get_password_value(pref, pref_stashed) != 0 )
|
|
|
|
pref_changed |= prefs_set_password_value(pref, pref_value, pref_current);
|
2017-11-29 00:03:11 +00:00
|
|
|
}
|
2015-06-05 09:19:37 +00:00
|
|
|
|
2017-11-29 00:03:11 +00:00
|
|
|
return pref_changed;
|
2016-01-21 12:41:42 +00:00
|
|
|
}
|
|
|
|
|
2018-01-06 04:39:55 +00:00
|
|
|
unsigned int
|
2016-01-21 12:41:42 +00:00
|
|
|
prefs_store_ext(const char * module_name, const char *pref_name, const char *pref_value)
|
|
|
|
{
|
2018-01-06 04:39:55 +00:00
|
|
|
unsigned int changed_flags = prefs_store_ext_helper(module_name, pref_name, pref_value);
|
|
|
|
if ( changed_flags )
|
2017-11-29 00:03:11 +00:00
|
|
|
{
|
|
|
|
prefs_main_write();
|
|
|
|
prefs_apply_all();
|
|
|
|
prefs_to_capture_opts();
|
2018-01-06 04:39:55 +00:00
|
|
|
return changed_flags;
|
2017-11-29 00:03:11 +00:00
|
|
|
}
|
2016-01-21 12:41:42 +00:00
|
|
|
|
2018-01-06 04:39:55 +00:00
|
|
|
return 0;
|
2016-01-21 12:41:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
prefs_store_ext_multiple(const char * module, GHashTable * pref_values)
|
|
|
|
{
|
2017-11-29 00:03:11 +00:00
|
|
|
gboolean pref_changed = FALSE;
|
|
|
|
GList * keys = NULL;
|
2016-01-21 12:41:42 +00:00
|
|
|
|
2021-12-30 16:03:15 +00:00
|
|
|
if ( !prefs_is_registered_protocol(module))
|
2017-11-29 00:03:11 +00:00
|
|
|
return pref_changed;
|
2016-01-21 12:41:42 +00:00
|
|
|
|
2017-11-29 00:03:11 +00:00
|
|
|
keys = g_hash_table_get_keys(pref_values);
|
2021-12-30 16:03:15 +00:00
|
|
|
if ( !keys )
|
2017-11-29 00:03:11 +00:00
|
|
|
return pref_changed;
|
2016-01-21 12:41:42 +00:00
|
|
|
|
2019-05-20 17:33:12 +00:00
|
|
|
for ( GList * key = keys; key != NULL; key = g_list_next(key) )
|
2016-01-21 12:41:42 +00:00
|
|
|
{
|
2019-05-20 17:33:12 +00:00
|
|
|
gchar * pref_name = (gchar *)key->data;
|
|
|
|
gchar * pref_value = (gchar *) g_hash_table_lookup(pref_values, key->data);
|
2017-11-29 00:03:11 +00:00
|
|
|
|
|
|
|
if ( pref_name && pref_value )
|
|
|
|
{
|
|
|
|
if ( prefs_store_ext_helper(module, pref_name, pref_value) )
|
|
|
|
pref_changed = TRUE;
|
|
|
|
}
|
2016-01-21 12:41:42 +00:00
|
|
|
}
|
2019-05-20 17:33:12 +00:00
|
|
|
g_list_free(keys);
|
2016-01-21 12:41:42 +00:00
|
|
|
|
2017-11-29 00:03:11 +00:00
|
|
|
if ( pref_changed )
|
|
|
|
{
|
|
|
|
prefs_main_write();
|
|
|
|
prefs_apply_all();
|
|
|
|
prefs_to_capture_opts();
|
|
|
|
}
|
2015-06-05 09:19:37 +00:00
|
|
|
|
2017-11-29 00:03:11 +00:00
|
|
|
return TRUE;
|
2015-06-05 09:19:37 +00:00
|
|
|
}
|
|
|
|
|
2015-03-09 07:11:13 +00:00
|
|
|
gint
|
2019-06-27 20:00:11 +00:00
|
|
|
column_prefs_add_custom(gint fmt, const gchar *title, const gchar *custom_fields, gint position)
|
2013-01-23 19:04:36 +00:00
|
|
|
{
|
|
|
|
GList *clp;
|
|
|
|
fmt_data *cfmt, *last_cfmt;
|
2015-03-09 07:11:13 +00:00
|
|
|
gint colnr;
|
2013-01-23 19:04:36 +00:00
|
|
|
|
2020-12-21 02:30:28 +00:00
|
|
|
cfmt = g_new(fmt_data, 1);
|
2013-01-23 19:04:36 +00:00
|
|
|
/*
|
|
|
|
* Because a single underscore is interpreted as a signal that the next character
|
|
|
|
* is going to be marked as accelerator for this header (i.e. is going to be
|
|
|
|
* shown underlined), escape it be inserting a second consecutive underscore.
|
|
|
|
*/
|
|
|
|
cfmt->title = g_strdup(title);
|
|
|
|
cfmt->fmt = fmt;
|
2015-12-11 08:34:08 +00:00
|
|
|
cfmt->custom_fields = g_strdup(custom_fields);
|
2019-06-27 20:00:11 +00:00
|
|
|
cfmt->custom_occurrence = 0;
|
2013-01-23 19:04:36 +00:00
|
|
|
cfmt->resolved = TRUE;
|
|
|
|
|
2015-03-09 07:11:13 +00:00
|
|
|
colnr = g_list_length(prefs.col_list);
|
|
|
|
|
2015-12-11 08:34:08 +00:00
|
|
|
if (custom_fields) {
|
2013-01-23 19:04:36 +00:00
|
|
|
cfmt->visible = TRUE;
|
|
|
|
clp = g_list_last(prefs.col_list);
|
|
|
|
last_cfmt = (fmt_data *) clp->data;
|
2019-06-27 19:51:49 +00:00
|
|
|
if (position > 0 && position <= colnr) {
|
2019-06-12 23:35:29 +00:00
|
|
|
/* Custom fields may be added at any position, depending on the given argument */
|
|
|
|
prefs.col_list = g_list_insert(prefs.col_list, cfmt, position);
|
|
|
|
} else if (last_cfmt->fmt == COL_INFO) {
|
2013-01-23 19:04:36 +00:00
|
|
|
/* Last column is COL_INFO, add custom column before this */
|
2015-03-09 07:11:13 +00:00
|
|
|
colnr -= 1;
|
|
|
|
prefs.col_list = g_list_insert(prefs.col_list, cfmt, colnr);
|
2013-01-23 19:04:36 +00:00
|
|
|
} else {
|
|
|
|
prefs.col_list = g_list_append(prefs.col_list, cfmt);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
cfmt->visible = FALSE; /* Will be set to TRUE in visible_toggled() when added to list */
|
|
|
|
prefs.col_list = g_list_append(prefs.col_list, cfmt);
|
|
|
|
}
|
2015-03-09 07:11:13 +00:00
|
|
|
|
|
|
|
return colnr;
|
2013-01-23 19:04:36 +00:00
|
|
|
}
|
|
|
|
|
2020-07-14 17:04:00 +00:00
|
|
|
gint
|
|
|
|
column_prefs_has_custom(const gchar *custom_field)
|
|
|
|
{
|
|
|
|
GList *clp;
|
|
|
|
fmt_data *cfmt;
|
|
|
|
gint colnr = -1;
|
|
|
|
|
|
|
|
for (gint i = 0; i < prefs.num_cols; i++) {
|
|
|
|
clp = g_list_nth(prefs.col_list, i);
|
|
|
|
if (clp == NULL) /* Sanity check, invalid column requested */
|
|
|
|
continue;
|
|
|
|
|
|
|
|
cfmt = (fmt_data *) clp->data;
|
|
|
|
if (cfmt->fmt == COL_CUSTOM && strcmp(custom_field, cfmt->custom_fields) == 0) {
|
|
|
|
colnr = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return colnr;
|
|
|
|
}
|
|
|
|
|
2022-06-28 04:36:39 +00:00
|
|
|
gboolean
|
|
|
|
column_prefs_custom_resolve(const gchar* custom_field)
|
|
|
|
{
|
|
|
|
gchar **fields;
|
|
|
|
header_field_info *hfi;
|
|
|
|
bool resolve = false;
|
|
|
|
|
|
|
|
fields = g_regex_split_simple(COL_CUSTOM_PRIME_REGEX, custom_field,
|
|
|
|
(GRegexCompileFlags) (G_REGEX_ANCHORED | G_REGEX_RAW),
|
|
|
|
G_REGEX_MATCH_ANCHORED);
|
|
|
|
|
|
|
|
for (guint i = 0; i < g_strv_length(fields); i++) {
|
|
|
|
if (fields[i] && *fields[i]) {
|
|
|
|
hfi = proto_registrar_get_byname(fields[i]);
|
|
|
|
if (hfi && ((hfi->type == FT_OID) || (hfi->type == FT_REL_OID) || (hfi->type == FT_BOOLEAN) ||
|
|
|
|
((hfi->strings != NULL) &&
|
|
|
|
(IS_FT_INT(hfi->type) || IS_FT_UINT(hfi->type)))))
|
|
|
|
{
|
|
|
|
resolve = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
g_strfreev(fields);
|
|
|
|
|
|
|
|
return resolve;
|
|
|
|
}
|
|
|
|
|
2013-01-23 19:04:36 +00:00
|
|
|
void
|
|
|
|
column_prefs_remove_link(GList *col_link)
|
|
|
|
{
|
|
|
|
fmt_data *cfmt;
|
|
|
|
|
|
|
|
if (!col_link || !col_link->data) return;
|
2014-02-25 20:42:35 +00:00
|
|
|
|
2013-01-23 19:04:36 +00:00
|
|
|
cfmt = (fmt_data *) col_link->data;
|
|
|
|
|
|
|
|
g_free(cfmt->title);
|
2015-12-11 08:34:08 +00:00
|
|
|
g_free(cfmt->custom_fields);
|
2013-01-23 19:04:36 +00:00
|
|
|
g_free(cfmt);
|
|
|
|
prefs.col_list = g_list_remove_link(prefs.col_list, col_link);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
column_prefs_remove_nth(gint col)
|
|
|
|
{
|
|
|
|
column_prefs_remove_link(g_list_nth(prefs.col_list, col));
|
|
|
|
}
|
|
|
|
|
2018-09-08 09:49:22 +00:00
|
|
|
void save_migrated_uat(const char *uat_name, gboolean *old_pref)
|
|
|
|
{
|
|
|
|
char *err = NULL;
|
|
|
|
|
|
|
|
if (!uat_save(uat_get_table_by_name(uat_name), &err)) {
|
2021-06-14 23:06:02 +00:00
|
|
|
ws_warning("Unable to save %s: %s", uat_name, err);
|
2018-09-08 09:49:22 +00:00
|
|
|
g_free(err);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure that any old preferences are removed after successful migration.
|
|
|
|
if (*old_pref) {
|
|
|
|
*old_pref = FALSE;
|
|
|
|
prefs_main_write();
|
|
|
|
}
|
|
|
|
}
|