summaryrefslogtreecommitdiffstats
path: root/ui/preference_utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'ui/preference_utils.c')
-rw-r--r--ui/preference_utils.c293
1 files changed, 293 insertions, 0 deletions
diff --git a/ui/preference_utils.c b/ui/preference_utils.c
new file mode 100644
index 00000000..751b47b8
--- /dev/null
+++ b/ui/preference_utils.c
@@ -0,0 +1,293 @@
+/* preference_utils.c
+ * Routines for handling preferences
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "config.h"
+
+#include <errno.h>
+
+#include <epan/column.h>
+#include <wsutil/filesystem.h>
+#include <wsutil/wslog.h>
+#include <epan/prefs.h>
+#include <epan/prefs-int.h>
+#include <epan/packet.h>
+#include <epan/decode_as.h>
+#include <epan/uat-int.h>
+#include <ui/recent.h>
+
+#ifdef HAVE_LIBPCAP
+#include "capture_opts.h"
+#include "ui/capture_globals.h"
+#endif
+
+#include "ui/preference_utils.h"
+#include "ui/simple_dialog.h"
+
+/* Fill in capture options with values from the preferences */
+void
+prefs_to_capture_opts(void)
+{
+#ifdef HAVE_LIBPCAP
+ /* Set promiscuous mode from the preferences setting. */
+ /* the same applies to other preferences settings as well. */
+ global_capture_opts.default_options.promisc_mode = prefs.capture_prom_mode;
+ global_capture_opts.use_pcapng = prefs.capture_pcap_ng;
+ global_capture_opts.show_info = prefs.capture_show_info;
+ global_capture_opts.real_time_mode = prefs.capture_real_time;
+ global_capture_opts.update_interval = prefs.capture_update_interval;
+#endif /* HAVE_LIBPCAP */
+}
+
+void
+prefs_main_write(void)
+{
+ 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 {
+ /* Write the preferences out. */
+ err = write_prefs(&pf_path);
+ if (err != 0) {
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+ "Can't open preferences file\n\"%s\": %s.", pf_path,
+ g_strerror(err));
+ g_free(pf_path);
+ }
+ /* Write recent and recent_common files out to ensure sync with prefs. */
+ write_profile_recent();
+ write_recent();
+ }
+}
+
+static unsigned int
+prefs_store_ext_helper(const char * module_name, const char *pref_name, const char *pref_value)
+{
+ module_t * module = NULL;
+ pref_t * pref = NULL;
+ unsigned int pref_changed = 0;
+
+ if ( !prefs_is_registered_protocol(module_name))
+ return 0;
+
+ module = prefs_find_module(module_name);
+ if ( !module )
+ return 0;
+
+ pref = prefs_find_preference(module, pref_name);
+
+ if (!pref)
+ return 0;
+
+ if (prefs_get_type(pref) == PREF_STRING )
+ {
+ pref_changed |= prefs_set_string_value(pref, pref_value, pref_stashed);
+ if ( !pref_changed || prefs_get_string_value(pref, pref_stashed) != 0 )
+ pref_changed |= prefs_set_string_value(pref, pref_value, pref_current);
+ } 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);
+ }
+
+ return pref_changed;
+}
+
+unsigned int
+prefs_store_ext(const char * module_name, const char *pref_name, const char *pref_value)
+{
+ unsigned int changed_flags = prefs_store_ext_helper(module_name, pref_name, pref_value);
+ if ( changed_flags )
+ {
+ prefs_main_write();
+ prefs_apply_all();
+ prefs_to_capture_opts();
+ return changed_flags;
+ }
+
+ return 0;
+}
+
+gboolean
+prefs_store_ext_multiple(const char * module, GHashTable * pref_values)
+{
+ gboolean pref_changed = FALSE;
+ GList * keys = NULL;
+
+ if ( !prefs_is_registered_protocol(module))
+ return pref_changed;
+
+ keys = g_hash_table_get_keys(pref_values);
+ if ( !keys )
+ return pref_changed;
+
+ for ( GList * key = keys; key != NULL; key = g_list_next(key) )
+ {
+ gchar * pref_name = (gchar *)key->data;
+ gchar * pref_value = (gchar *) g_hash_table_lookup(pref_values, key->data);
+
+ if ( pref_name && pref_value )
+ {
+ if ( prefs_store_ext_helper(module, pref_name, pref_value) )
+ pref_changed = TRUE;
+ }
+ }
+ g_list_free(keys);
+
+ if ( pref_changed )
+ {
+ prefs_main_write();
+ prefs_apply_all();
+ prefs_to_capture_opts();
+ }
+
+ return TRUE;
+}
+
+gint
+column_prefs_add_custom(gint fmt, const gchar *title, const gchar *custom_fields, gint position)
+{
+ GList *clp;
+ fmt_data *cfmt, *last_cfmt;
+ gint colnr;
+
+ cfmt = g_new(fmt_data, 1);
+ /*
+ * 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;
+ cfmt->custom_fields = g_strdup(custom_fields);
+ cfmt->custom_occurrence = 0;
+ cfmt->resolved = TRUE;
+
+ colnr = g_list_length(prefs.col_list);
+
+ if (custom_fields) {
+ cfmt->visible = TRUE;
+ clp = g_list_last(prefs.col_list);
+ last_cfmt = (fmt_data *) clp->data;
+ if (position > 0 && position <= colnr) {
+ /* 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) {
+ /* Last column is COL_INFO, add custom column before this */
+ colnr -= 1;
+ prefs.col_list = g_list_insert(prefs.col_list, cfmt, colnr);
+ } 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);
+ }
+
+ return colnr;
+}
+
+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 && cfmt->custom_occurrence == 0 && strcmp(custom_field, cfmt->custom_fields) == 0) {
+ colnr = i;
+ break;
+ }
+ }
+
+ return colnr;
+}
+
+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_ETHER) || (hfi->type == FT_IPv4) || (hfi->type == FT_IPv6) || (hfi->type == FT_FCWWN) || (hfi->type == FT_BOOLEAN) ||
+ ((hfi->strings != NULL) &&
+ (FT_IS_INT(hfi->type) || FT_IS_UINT(hfi->type)))))
+ {
+ resolve = TRUE;
+ break;
+ }
+ }
+ }
+
+ g_strfreev(fields);
+
+ return resolve;
+}
+
+void
+column_prefs_remove_link(GList *col_link)
+{
+ fmt_data *cfmt;
+
+ if (!col_link || !col_link->data) return;
+
+ cfmt = (fmt_data *) col_link->data;
+
+ g_free(cfmt->title);
+ g_free(cfmt->custom_fields);
+ g_free(cfmt);
+ prefs.col_list = g_list_remove_link(prefs.col_list, col_link);
+ g_list_free_1(col_link);
+}
+
+void
+column_prefs_remove_nth(gint col)
+{
+ column_prefs_remove_link(g_list_nth(prefs.col_list, col));
+}
+
+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)) {
+ ws_warning("Unable to save %s: %s", uat_name, err);
+ g_free(err);
+ return;
+ }
+
+ // Ensure that any old preferences are removed after successful migration.
+ if (*old_pref) {
+ *old_pref = FALSE;
+ prefs_main_write();
+ }
+}