update epan/dissectors/pidl/drsuapi/drsuapi.idl from samba
[wireshark-sm.git] / ui / preference_utils.c
blob74f446e5bca9c9f050f79bc5cf92fcf7f5bb0c9a
1 /* preference_utils.c
2 * Routines for handling preferences
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
11 #include "config.h"
13 #include <errno.h>
15 #include <epan/column.h>
16 #include <wsutil/filesystem.h>
17 #include <wsutil/wslog.h>
18 #include <epan/prefs.h>
19 #include <epan/prefs-int.h>
20 #include <epan/packet.h>
21 #include <epan/decode_as.h>
22 #include <epan/uat-int.h>
23 #include <ui/recent.h>
25 #ifdef HAVE_LIBPCAP
26 #include "capture_opts.h"
27 #include "ui/capture_globals.h"
28 #endif
30 #include "ui/preference_utils.h"
31 #include "ui/simple_dialog.h"
33 /* Fill in capture options with values from the preferences */
34 void
35 prefs_to_capture_opts(void)
37 #ifdef HAVE_LIBPCAP
38 /* Set promiscuous mode from the preferences setting. */
39 /* the same applies to other preferences settings as well. */
40 global_capture_opts.default_options.promisc_mode = prefs.capture_prom_mode;
41 global_capture_opts.default_options.monitor_mode = prefs.capture_monitor_mode;
42 global_capture_opts.use_pcapng = prefs.capture_pcap_ng;
43 global_capture_opts.show_info = prefs.capture_show_info;
44 global_capture_opts.real_time_mode = prefs.capture_real_time;
45 global_capture_opts.update_interval = prefs.capture_update_interval;
46 #endif /* HAVE_LIBPCAP */
49 void
50 prefs_main_write(void)
52 int err;
53 char *pf_dir_path;
54 char *pf_path;
56 /* Create the directory that holds personal configuration files, if
57 necessary. */
58 if (create_persconffile_dir(&pf_dir_path) == -1) {
59 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
60 "Can't create directory\n\"%s\"\nfor preferences file: %s.", pf_dir_path,
61 g_strerror(errno));
62 g_free(pf_dir_path);
63 } else {
64 /* Write the preferences out. */
65 err = write_prefs(&pf_path);
66 if (err != 0) {
67 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
68 "Can't open preferences file\n\"%s\": %s.", pf_path,
69 g_strerror(err));
70 g_free(pf_path);
72 /* Write recent and recent_common files out to ensure sync with prefs. */
73 write_profile_recent();
74 write_recent();
78 static unsigned int
79 prefs_store_ext_helper(const char * module_name, const char *pref_name, const char *pref_value)
81 module_t * module = NULL;
82 pref_t * pref = NULL;
83 unsigned int pref_changed = 0;
85 if ( !prefs_is_registered_protocol(module_name))
86 return 0;
88 module = prefs_find_module(module_name);
89 if ( !module )
90 return 0;
92 pref = prefs_find_preference(module, pref_name);
94 if (!pref)
95 return 0;
97 if (prefs_get_type(pref) == PREF_STRING || prefs_get_type(pref) == PREF_DISSECTOR)
99 pref_changed |= prefs_set_string_value(pref, pref_value, pref_stashed);
100 if ( !pref_changed || prefs_get_string_value(pref, pref_stashed) != 0 )
101 pref_changed |= prefs_set_string_value(pref, pref_value, pref_current);
102 } else if (prefs_get_type(pref) == PREF_PASSWORD )
104 pref_changed |= prefs_set_password_value(pref, pref_value, pref_stashed);
105 if ( !pref_changed || prefs_get_password_value(pref, pref_stashed) != 0 )
106 pref_changed |= prefs_set_password_value(pref, pref_value, pref_current);
109 return pref_changed;
112 unsigned int
113 prefs_store_ext(const char * module_name, const char *pref_name, const char *pref_value)
115 unsigned int changed_flags = prefs_store_ext_helper(module_name, pref_name, pref_value);
116 if ( changed_flags )
118 prefs_main_write();
119 prefs_apply_all();
120 prefs_to_capture_opts();
121 return changed_flags;
124 return 0;
127 bool
128 prefs_store_ext_multiple(const char * module, GHashTable * pref_values)
130 bool pref_changed = false;
131 GList * keys = NULL;
133 if ( !prefs_is_registered_protocol(module))
134 return pref_changed;
136 keys = g_hash_table_get_keys(pref_values);
137 if ( !keys )
138 return pref_changed;
140 for ( GList * key = keys; key != NULL; key = g_list_next(key) )
142 char * pref_name = (char *)key->data;
143 char * pref_value = (char *) g_hash_table_lookup(pref_values, key->data);
145 if ( pref_name && pref_value )
147 if ( prefs_store_ext_helper(module, pref_name, pref_value) )
148 pref_changed = true;
151 g_list_free(keys);
153 if ( pref_changed )
155 prefs_main_write();
156 prefs_apply_all();
157 prefs_to_capture_opts();
160 return true;
164 column_prefs_add_custom(int fmt, const char *title, const char *custom_fields, int position)
166 GList *clp;
167 fmt_data *cfmt, *last_cfmt;
168 int colnr;
170 cfmt = g_new(fmt_data, 1);
172 * Because a single underscore is interpreted as a signal that the next character
173 * is going to be marked as accelerator for this header (i.e. is going to be
174 * shown underlined), escape it be inserting a second consecutive underscore.
176 cfmt->title = g_strdup(title);
177 cfmt->fmt = fmt;
178 cfmt->custom_fields = g_strdup(custom_fields);
179 cfmt->custom_occurrence = 0;
180 if (column_prefs_custom_display_strings(custom_fields)) {
181 cfmt->display = COLUMN_DISPLAY_STRINGS;
182 } else {
183 cfmt->display = COLUMN_DISPLAY_VALUES;
186 colnr = g_list_length(prefs.col_list);
188 if (custom_fields) {
189 cfmt->visible = true;
190 clp = g_list_last(prefs.col_list);
191 last_cfmt = (fmt_data *) clp->data;
192 if (position > 0 && position <= colnr) {
193 /* Custom fields may be added at any position, depending on the given argument */
194 colnr = position;
195 prefs.col_list = g_list_insert(prefs.col_list, cfmt, colnr);
196 } else if (last_cfmt->fmt == COL_INFO) {
197 /* Last column is COL_INFO, add custom column before this */
198 colnr -= 1;
199 prefs.col_list = g_list_insert(prefs.col_list, cfmt, colnr);
200 } else {
201 prefs.col_list = g_list_append(prefs.col_list, cfmt);
203 } else {
204 cfmt->visible = false; /* Will be set to true in visible_toggled() when added to list */
205 prefs.col_list = g_list_append(prefs.col_list, cfmt);
207 recent_insert_column(colnr);
209 return colnr;
213 column_prefs_has_custom(const char *custom_field)
215 GList *clp;
216 fmt_data *cfmt;
217 int colnr = -1;
219 for (int i = 0; i < prefs.num_cols; i++) {
220 clp = g_list_nth(prefs.col_list, i);
221 if (clp == NULL) /* Sanity check, invalid column requested */
222 continue;
224 cfmt = (fmt_data *) clp->data;
225 if (cfmt->fmt == COL_CUSTOM && cfmt->custom_occurrence == 0 && strcmp(custom_field, cfmt->custom_fields) == 0) {
226 colnr = i;
227 break;
231 return colnr;
234 bool
235 column_prefs_custom_display_strings(const char* custom_field)
237 char **fields;
238 header_field_info *hfi;
239 bool resolve = false;
241 fields = g_regex_split_simple(COL_CUSTOM_PRIME_REGEX, custom_field,
242 (GRegexCompileFlags) (G_REGEX_RAW),
245 for (unsigned i = 0; i < g_strv_length(fields); i++) {
246 if (fields[i] && *fields[i]) {
247 hfi = proto_registrar_get_byname(fields[i]);
248 if (hfi && ((hfi->type == FT_OID) || (hfi->type == FT_REL_OID) || (hfi->type == FT_ETHER) || (hfi->type == FT_BYTES) || (hfi->type == FT_IPv4) || (hfi->type == FT_IPv6) || (hfi->type == FT_FCWWN) || (hfi->type == FT_BOOLEAN) ||
249 ((hfi->strings != NULL) &&
250 (FT_IS_INT(hfi->type) || FT_IS_UINT(hfi->type)))))
252 resolve = true;
253 break;
258 g_strfreev(fields);
260 return resolve;
263 bool
264 column_prefs_custom_display_details(const char* custom_field)
266 char **fields;
267 header_field_info *hfi;
268 bool resolve = false;
270 fields = g_regex_split_simple(COL_CUSTOM_PRIME_REGEX, custom_field,
271 (GRegexCompileFlags) (G_REGEX_RAW),
274 for (unsigned i = 0; i < g_strv_length(fields); i++) {
275 if (fields[i] && *fields[i]) {
276 hfi = proto_registrar_get_byname(fields[i]);
277 if (hfi && !(hfi->display & BASE_NO_DISPLAY_VALUE)) {
278 resolve = true;
279 break;
284 g_strfreev(fields);
286 return resolve;
289 void
290 column_prefs_remove_link(GList *col_link)
292 fmt_data *cfmt;
294 if (!col_link || !col_link->data) return;
296 cfmt = (fmt_data *) col_link->data;
298 g_free(cfmt->title);
299 g_free(cfmt->custom_fields);
300 g_free(cfmt);
301 prefs.col_list = g_list_remove_link(prefs.col_list, col_link);
302 g_list_free_1(col_link);
305 void
306 column_prefs_remove_nth(int col)
308 column_prefs_remove_link(g_list_nth(prefs.col_list, col));
309 recent_remove_column(col);
312 void save_migrated_uat(const char *uat_name, bool *old_pref)
314 char *err = NULL;
316 if (!uat_save(uat_get_table_by_name(uat_name), &err)) {
317 ws_warning("Unable to save %s: %s", uat_name, err);
318 g_free(err);
319 return;
322 // Ensure that any old preferences are removed after successful migration.
323 if (*old_pref) {
324 *old_pref = false;
325 prefs_main_write();