aboutsummaryrefslogtreecommitdiffstats
path: root/extcap.c
diff options
context:
space:
mode:
authorRoland Knall <roland.knall@br-automation.com>2015-12-29 07:57:36 +0100
committerRoland Knall <rknall@gmail.com>2016-02-01 12:12:41 +0000
commit927ffaa794d5fb24e0b4f3fba08c4c31f4dd7d63 (patch)
tree70676d0b7e00e0b10678d0f7f3ff7dd707eabcd2 /extcap.c
parent5e89f9332228015c3e5c813939bf35dbcc5a105d (diff)
extcap: Add Save functionality to options dialog
This patch creates the functionality of saving all parameters for extcap devices in the general preference section. For now, multiselect and fileselect do not save their values but patches for this will be provided in the future Also, all preferences are stored as strings to make handling easier. This might change in the future, but for the first version it will stick. Restore to Defaults is not implemented as of yet, and will be in a future version, once the preference storing is finalized Bug: 11666 Change-Id: I178346405146d2e43f4f3481c05c92c0b3595af5 Reviewed-on: https://code.wireshark.org/review/13451 Petri-Dish: Roland Knall <rknall@gmail.com> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Roland Knall <rknall@gmail.com>
Diffstat (limited to 'extcap.c')
-rw-r--r--extcap.c146
1 files changed, 121 insertions, 25 deletions
diff --git a/extcap.c b/extcap.c
index df40bd1017..c2f01d102a 100644
--- a/extcap.c
+++ b/extcap.c
@@ -40,6 +40,9 @@
#include <glib.h>
#include <log.h>
+#include <epan/prefs.h>
+#include <epan/prefs-int.h>
+
#include <wsutil/file_util.h>
#include <wsutil/filesystem.h>
#include <wsutil/tempfile.h>
@@ -69,7 +72,7 @@ static GHashTable *ifaces = NULL;
static GHashTable *tools = NULL;
/* Callback definition for extcap_foreach */
-typedef gboolean (*extcap_cb_t)(const gchar *extcap, gchar *output, void *data,
+typedef gboolean (*extcap_cb_t)(const gchar *extcap, const gchar *ifname, gchar *output, void *data,
gchar **err_str);
/* #define ARG_DEBUG */
@@ -201,7 +204,7 @@ static void extcap_foreach(gint argc, gchar **args, extcap_cb_t cb,
&command_output, NULL, &exit_status, &error);
if (status && exit_status == 0)
- keep_going = cb(extcap_path->str, command_output, cb_data, err_str);
+ keep_going = cb(extcap_path->str, ifname, command_output, cb_data, err_str);
g_free(argv[0]);
g_free(command_output);
@@ -217,7 +220,7 @@ static void extcap_foreach(gint argc, gchar **args, extcap_cb_t cb,
g_free(argv);
}
-static gboolean dlt_cb(const gchar *extcap _U_, gchar *output, void *data,
+static gboolean dlt_cb(const gchar *extcap _U_, const gchar *ifname _U_, gchar *output, void *data,
char **err_str) {
extcap_token_sentence *tokens;
extcap_dlt *dlts, *dlt_iter, *next;
@@ -300,7 +303,7 @@ extcap_get_if_dlts(const gchar *ifname, char **err_str) {
return caps;
}
-static gboolean interfaces_cb(const gchar *extcap, gchar *output, void *data,
+static gboolean interfaces_cb(const gchar *extcap, const gchar *ifname _U_, gchar *output, void *data,
char **err_str _U_) {
GList **il = (GList **) data;
extcap_token_sentence *tokens;
@@ -422,6 +425,27 @@ static void extcap_free_arg_elem(gpointer data, gpointer user_data _U_) {
g_free(data);
}
+void extcap_register_preferences(void)
+{
+ GList * interfaces = NULL;
+
+ module_t * dev_module = prefs_find_module("extcap");
+
+ if ( !dev_module )
+ return;
+
+ if ( ! ifaces || g_hash_table_size(ifaces) == 0 )
+ extcap_interface_list(NULL);
+
+ interfaces = g_hash_table_get_keys(ifaces);
+
+ while ( interfaces ) {
+ extcap_get_if_configuration((gchar *)interfaces->data);
+
+ interfaces = g_list_next(interfaces);
+ }
+}
+
static void extcap_free_if_configuration(GList *list)
{
GList *elem, *sl;
@@ -438,11 +462,12 @@ static void extcap_free_if_configuration(GList *list)
g_list_free(list);
}
-static gboolean search_cb(const gchar *extcap _U_, gchar *output, void *data,
+static gboolean search_cb(const gchar *extcap _U_, const gchar *ifname _U_, gchar *output, void *data,
char **err_str _U_) {
extcap_token_sentence *tokens = NULL;
GList *arguments = NULL;
GList **il = (GList **) data;
+ module_t * dev_module = NULL;
tokens = extcap_tokenize_sentences(output);
arguments = extcap_parse_args(tokens);
@@ -453,6 +478,45 @@ static gboolean search_cb(const gchar *extcap _U_, gchar *output, void *data,
extcap_debug_arguments ( arguments );
#endif
+ dev_module = prefs_find_module("extcap");
+
+ if ( dev_module ) {
+ GList * walker = arguments;
+
+ GRegex * regex = g_regex_new ("[-]+", (GRegexCompileFlags) 0, (GRegexMatchFlags) 0, NULL );
+ if (regex) {
+ while ( walker != NULL ) {
+ extcap_arg * arg = (extcap_arg *)walker->data;
+
+ if ( arg->save ) {
+ struct preference * pref = NULL;
+
+ gchar * pref_name = g_regex_replace(regex, arg->call, strlen(arg->call), 0, "", (GRegexMatchFlags) 0, NULL );
+ gchar * pref_ifname = g_strdup(g_strconcat(ifname, ".", pref_name, NULL));
+
+ if ( ( pref = prefs_find_preference(dev_module, pref_ifname) ) == NULL ) {
+ /* Set an initial value */
+ if ( ! arg->storeval && arg->default_complex )
+ arg->storeval = g_strdup(arg->default_complex->_val);
+
+ prefs_register_string_preference(dev_module, g_strdup(pref_ifname),
+ arg->display, arg->display, (const gchar **)&(arg->storeval));
+ } else {
+ /* Been here before, restore stored value */
+ if (! arg->storeval && pref->varp.string)
+ arg->storeval = g_strdup(*(pref->varp.string));
+ }
+
+ g_free(pref_name);
+ g_free(pref_ifname);
+ }
+
+ walker = g_list_next(walker);
+ }
+ g_regex_unref(regex);
+ }
+ }
+
*il = g_list_append(*il, arguments);
/* By returning false, extcap_foreach will break on first found */
@@ -494,16 +558,33 @@ extcap_has_configuration(const char * ifname, gboolean is_required) {
arguments = extcap_get_if_configuration((const char *)( ifname ) );
walker = g_list_first(arguments);
- while ( walker != NULL && ! found )
- {
+ while ( walker != NULL && ! found ) {
item = g_list_first((GList *)(walker->data));
- while ( item != NULL && ! found )
- {
- if ( (extcap_arg *)(item->data) != NULL )
- {
+ while ( item != NULL && ! found ) {
+ if ( (extcap_arg *)(item->data) != NULL ) {
+ extcap_arg * arg = (extcap_arg *)(item->data);
/* Should required options be present, or any kind of options */
- if ( ! is_required || ((extcap_arg *)(item->data))->is_required )
+ if ( ! is_required )
found = TRUE;
+ else if ( arg->is_required ) {
+ gchar * stored = NULL;
+ gchar * defval = NULL;
+
+ if ( arg->storeval != NULL )
+ stored = arg->storeval;
+
+ if ( arg->default_complex != NULL && arg->default_complex->_val != NULL )
+ defval = arg->default_complex->_val;
+
+ if ( arg->is_required ) {
+ /* If stored and defval is identical and the argument is required,
+ * configuration is needed */
+ if ( defval && stored && g_strcmp0(stored, defval) == 0 )
+ found = TRUE;
+ else if ( ! defval && (!stored || strlen(g_strchomp(stored)) <= (size_t)0) )
+ found = TRUE;
+ }
+ }
}
item = item->next;
@@ -574,8 +655,8 @@ void extcap_cleanup(capture_options * capture_opts) {
}
}
-static void
-extcap_arg_cb(gpointer key, gpointer value, gpointer data) {
+static gboolean
+extcap_add_arg_and_remove_cb(gpointer key, gpointer value, gpointer data) {
GPtrArray *args = (GPtrArray *)data;
if ( key != NULL )
@@ -584,7 +665,11 @@ extcap_arg_cb(gpointer key, gpointer value, gpointer data) {
if ( value != NULL )
g_ptr_array_add(args, g_strdup((const gchar*)value));
+
+ return TRUE;
}
+
+ return FALSE;
}
static void extcap_child_watch_cb(GPid pid, gint status _U_, gpointer user_data)
@@ -650,7 +735,7 @@ extcap_init_interfaces(capture_options *capture_opts)
}
add_arg(EXTCAP_ARGUMENT_RUN_PIPE);
add_arg(interface_opts.extcap_fifo);
- if (interface_opts.extcap_args == NULL)
+ if (interface_opts.extcap_args == NULL || g_hash_table_size(interface_opts.extcap_args) == 0)
{
/* User did not perform interface configuration.
*
@@ -672,18 +757,29 @@ extcap_init_interfaces(capture_options *capture_opts)
}
arg_list = g_list_first((GList *)elem->data);
- while (arg_list != NULL)
- {
+ while (arg_list != NULL) {
+ gchar * stored = NULL, * defval = NULL;
/* In case of boolflags only first element in arg_list is relevant. */
arg_iter = (extcap_arg*) (arg_list->data);
-
- if (arg_iter->arg_type == EXTCAP_ARG_BOOLFLAG)
- {
- if (arg_iter->default_complex != NULL
- && extcap_complex_get_bool(arg_iter->default_complex))
- {
- add_arg(arg_iter->call);
+ if ( arg_iter->storeval != NULL )
+ stored = arg_iter->storeval;
+
+ if ( arg_iter->default_complex != NULL && arg_iter->default_complex->_val != NULL )
+ defval = arg_iter->default_complex->_val;
+
+ /* Different data in storage then set for default */
+ if ( g_strcmp0(stored, defval) != 0 ) {
+ if ( arg_iter->arg_type == EXTCAP_ARG_BOOLFLAG ) {
+ if ( g_strcmp0(stored, "true") == 0 )
+ add_arg(arg_iter->call);
+ } else {
+ gchar * call = g_strconcat(arg_iter->call, " ", stored, NULL);
+ add_arg(call);
+ g_free(call);
}
+ } else if (arg_iter->arg_type == EXTCAP_ARG_BOOLFLAG) {
+ if (extcap_complex_get_bool(arg_iter->default_complex))
+ add_arg(arg_iter->call);
}
arg_list = arg_list->next;
@@ -694,7 +790,7 @@ extcap_init_interfaces(capture_options *capture_opts)
}
else
{
- g_hash_table_foreach(interface_opts.extcap_args, extcap_arg_cb, args);
+ g_hash_table_foreach_remove(interface_opts.extcap_args, extcap_add_arg_and_remove_cb, args);
}
add_arg(NULL);
#undef add_arg