diff --git a/epan/prefs-int.h b/epan/prefs-int.h index be83d8755d..e2186bde86 100644 --- a/epan/prefs-int.h +++ b/epan/prefs-int.h @@ -264,6 +264,16 @@ WS_DLL_PUBLIC int read_prefs_file(const char *pf_path, FILE *pf, pref_set_pair_cb pref_set_pair_fct, void *private_data); +/** Given a module name, read the preferences associated with only that module. + * Checks for a file in the personal configuration directory named after the + * module first. + * + * @param name The preference module name, e.g. "extcap". + */ +WS_DLL_PUBLIC +void +prefs_read_module(const char *name); + WS_DLL_PUBLIC gboolean prefs_pref_is_default(pref_t *pref); diff --git a/epan/prefs.c b/epan/prefs.c index ce526a70cc..04e855fcfe 100644 --- a/epan/prefs.c +++ b/epan/prefs.c @@ -4520,6 +4520,52 @@ read_registry(void) } #endif +void +prefs_read_module(const char *module) +{ + int err; + char *pf_path; + FILE *pf; + + module_t *target_module = prefs_find_module(module); + if (!target_module) { + return; + } + + /* Construct the pathname of the user's preferences file for the module. */ + pf_path = get_persconffile_path(module, TRUE); + + /* Read the user's preferences file, if it exists. */ + if ((pf = ws_fopen(pf_path, "r")) == NULL && errno == ENOENT) { + g_free(pf_path); + /* Fall back to the user's generic preferences file. */ + pf_path = get_persconffile_path(PF_NAME, TRUE); + pf = ws_fopen(pf_path, "r"); + } + + if (pf != NULL) { + /* We succeeded in opening it; read it. */ + err = read_prefs_file(pf_path, pf, set_pref, target_module); + if (err != 0) { + /* We had an error reading the file; report it. */ + report_warning("Error reading your preferences file \"%s\": %s.", + pf_path, g_strerror(err)); + } else + g_free(pf_path); + fclose(pf); + } else { + /* We failed to open it. If we failed for some reason other than + "it doesn't exist", return the errno and the pathname, so our + caller can report the error. */ + if (errno != ENOENT) { + report_warning("Can't open your preferences file \"%s\": %s.", + pf_path, g_strerror(errno)); + } else + g_free(pf_path); + } + + return; +} /* Read the preferences file, fill in "prefs", and return a pointer to it. @@ -5690,7 +5736,7 @@ deprecated_port_pref(gchar *pref_name, const gchar *value) } static prefs_set_pref_e -set_pref(gchar *pref_name, const gchar *value, void *private_data _U_, +set_pref(gchar *pref_name, const gchar *value, void *private_data, gboolean return_range_errors) { guint cval; @@ -5700,11 +5746,13 @@ set_pref(gchar *pref_name, const gchar *value, void *private_data _U_, gchar *dotp, *last_dotp; static gchar *filter_label = NULL; static gboolean filter_enabled = FALSE; - module_t *module, *containing_module; + module_t *module, *containing_module, *target_module; pref_t *pref; int type; gboolean converted_pref = FALSE; + target_module = (module_t*)private_data; + //The PRS_GUI field names are here for backwards compatibility //display filters have been converted to a UAT. if (strcmp(pref_name, PRS_GUI_FILTER_LABEL) == 0) { @@ -6149,6 +6197,11 @@ set_pref(gchar *pref_name, const gchar *value, void *private_data _U_, return PREFS_SET_NO_SUCH_PREF; /* no such preference */ } + if (target_module && target_module != containing_module) { + /* Ignore */ + return PREFS_SET_OK; + } + type = pref->type; if (IS_PREF_OBSOLETE(type)) { return PREFS_SET_OBSOLETE; /* no such preference any more */ @@ -7055,6 +7108,31 @@ write_prefs(char **pf_path_return) g_free(err); } } + + module_t *extcap_module = prefs_find_module("extcap"); + if (extcap_module && !prefs.capture_no_extcap) { + char *ext_path = get_persconffile_path("extcap", TRUE); + FILE *extf; + if ((extf = ws_fopen(ext_path, "w")) == NULL) { + *pf_path_return = ext_path; + return errno; + } + g_free(ext_path); + + fputs("# Extcap configuration file for Wireshark " VERSION ".\n" + "#\n" + "# This file is regenerated each time preferences are saved within\n" + "# Wireshark. Making manual changes should be safe, however.\n" + "# Preferences that have been commented out have not been\n" + "# changed from their default value.\n", extf); + + write_gui_pref_info.pf = extf; + write_gui_pref_info.is_gui_module = FALSE; + + write_module_prefs(extcap_module, &write_gui_pref_info); + + fclose(extf); + } } fputs("# Configuration file for Wireshark " VERSION ".\n" diff --git a/extcap.c b/extcap.c index 72a09c586d..de9a859559 100644 --- a/extcap.c +++ b/extcap.c @@ -31,6 +31,7 @@ #include #include +#include #include "ui/iface_toolbar.h" @@ -740,6 +741,12 @@ append_extcap_interface_list(GList *list) void extcap_register_preferences(void) { + /* Unconditionally register the extcap configuration file, so that + * it is copied if we copy the profile even if we're not going to + * read it because extcaps are disabled. + */ + profile_register_persconffile("extcap"); + if (prefs.capture_no_extcap) return; @@ -862,6 +869,7 @@ extcap_pref_for_argument(const gchar *ifname, struct _extcap_arg *arg) static gboolean cb_preference(extcap_callback_info_t cb_info) { + gboolean new_pref = false; GList *arguments = NULL; GList **il = (GList **) cb_info.data; module_t *dev_module = NULL; @@ -894,7 +902,7 @@ static gboolean cb_preference(extcap_callback_info_t cb_info) { char *pref_name_for_prefs; char *pref_title = wmem_strdup(wmem_epan_scope(), arg->display); - + new_pref = TRUE; arg->pref_valptr = extcap_prefs_dynamic_valptr(pref_ifname, &pref_name_for_prefs); /* Set an initial value if any (the string will be copied at registration) */ if (arg->default_complex) @@ -945,7 +953,7 @@ static gboolean cb_preference(extcap_callback_info_t cb_info) extcap_free_arg_list(arguments); } - return TRUE; + return new_pref; } GList * @@ -2154,6 +2162,7 @@ extcap_list_interfaces_cb(thread_pool_t *pool, void *data, char *output) static void extcap_load_interface_list(void) { + bool prefs_registered = false; if (prefs.capture_no_extcap) return; @@ -2219,12 +2228,17 @@ extcap_load_interface_list(void) .output = iface_info->output, .data = NULL, }; - cb_preference(cb_info); + prefs_registered = cb_preference(cb_info); } } extcap_free_extcaps_info_array(infos, count); g_free(arg_version); } + + if (prefs_registered) + { + prefs_read_module("extcap"); + } } /* diff --git a/ui/logray/logray_main.cpp b/ui/logray/logray_main.cpp index b060073506..1a5369a4dd 100644 --- a/ui/logray/logray_main.cpp +++ b/ui/logray/logray_main.cpp @@ -800,11 +800,6 @@ int main(int argc, char *qt_argv[]) in_file_type = open_info_name_to_type(ex_opt_get_next("read_format")); } -#ifdef DEBUG_STARTUP_TIME - ws_log(LOG_DOMAIN_MAIN, LOG_LEVEL_INFO, "Calling extcap_register_preferences, elapsed time %" G_GUINT64_FORMAT " us \n", g_get_monotonic_time() - start_time); -#endif - splash_update(RA_EXTCAP, NULL, NULL); - extcap_register_preferences(); splash_update(RA_PREFERENCES, NULL, NULL); #ifdef DEBUG_STARTUP_TIME ws_log(LOG_DOMAIN_MAIN, LOG_LEVEL_INFO, "Calling module preferences, elapsed time %" G_GUINT64_FORMAT " us \n", g_get_monotonic_time() - start_time); @@ -819,6 +814,16 @@ int main(int argc, char *qt_argv[]) */ commandline_override_prefs(argc, argv, TRUE); + /* Register the extcap preferences. We do this after seeing if the + * capture_no_extcap preference is set in the configuration file + * or command line. This will re-read the extcap specific preferences. + */ +#ifdef DEBUG_STARTUP_TIME + ws_log(LOG_DOMAIN_MAIN, LOG_LEVEL_INFO, "Calling extcap_register_preferences, elapsed time %" G_GUINT64_FORMAT " us \n", g_get_monotonic_time() - start_time); +#endif + splash_update(RA_EXTCAP, NULL, NULL); + extcap_register_preferences(); + /* Some of the preferences affect the capture options. Apply those * before getting the other command line arguments, which can also * affect the capture options. The command line arguments should be diff --git a/ui/qt/main.cpp b/ui/qt/main.cpp index 0634e229ca..ca7e6fa453 100644 --- a/ui/qt/main.cpp +++ b/ui/qt/main.cpp @@ -851,11 +851,6 @@ int main(int argc, char *qt_argv[]) in_file_type = open_info_name_to_type(ex_opt_get_next("read_format")); } -#ifdef DEBUG_STARTUP_TIME - ws_log(LOG_DOMAIN_MAIN, LOG_LEVEL_INFO, "Calling extcap_register_preferences, elapsed time %" PRIu64 " us \n", g_get_monotonic_time() - start_time); -#endif - splash_update(RA_EXTCAP, NULL, NULL); - extcap_register_preferences(); splash_update(RA_PREFERENCES, NULL, NULL); #ifdef DEBUG_STARTUP_TIME ws_log(LOG_DOMAIN_MAIN, LOG_LEVEL_INFO, "Calling module preferences, elapsed time %" PRIu64 " us \n", g_get_monotonic_time() - start_time); @@ -870,6 +865,16 @@ int main(int argc, char *qt_argv[]) */ commandline_override_prefs(argc, argv, TRUE); + /* Register the extcap preferences. We do this after seeing if the + * capture_no_extcap preference is set in the configuration file + * or command line. This will re-read the extcap specific preferences. + */ +#ifdef DEBUG_STARTUP_TIME + ws_log(LOG_DOMAIN_MAIN, LOG_LEVEL_INFO, "Calling extcap_register_preferences, elapsed time %" PRIu64 " us \n", g_get_monotonic_time() - start_time); +#endif + splash_update(RA_EXTCAP, NULL, NULL); + extcap_register_preferences(); + /* Some of the preferences affect the capture options. Apply those * before getting the other command line arguments, which can also * affect the capture options. The command line arguments should be diff --git a/ui/qt/main_application.cpp b/ui/qt/main_application.cpp index 52ae564653..038ddf1915 100644 --- a/ui/qt/main_application.cpp +++ b/ui/qt/main_application.cpp @@ -470,6 +470,7 @@ void MainApplication::setConfigurationProfile(const gchar *profile_name, bool wr * they don't get reapplied later, e.g. when reloading Lua plugins)? */ commandline_options_free(); + extcap_register_preferences(); /* Switching profile requires reloading the macro list. */ reloadDisplayFilterMacros(); diff --git a/ui/qt/preferences_dialog.cpp b/ui/qt/preferences_dialog.cpp index 6c3daefbfe..7e41fc43ee 100644 --- a/ui/qt/preferences_dialog.cpp +++ b/ui/qt/preferences_dialog.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include @@ -253,6 +254,8 @@ void PreferencesDialog::on_buttonBox_accepted() // XXX - We're also too enthusiastic about setting must_redissect. prefs_modules_foreach_submodules(NULL, module_prefs_unstash, (gpointer)&redissect_flags); + extcap_register_preferences(); + if (redissect_flags & PREF_EFFECT_GUI_LAYOUT) { // Layout type changed, reset sizes recent.gui_geometry_main_upper_pane = 0;