aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoland Knall <roland.knall@br-automation.com>2015-12-29 07:57:36 +0100
committerMichael Mann <mmann78@netscape.net>2016-07-29 03:15:54 +0000
commit485bc456c57a16dbe50b76c476e48223038bb0e8 (patch)
tree5fabaa4504ccce8a08ddd23d8bbb8f9aaf60935a
parent191f9bdbc50bd3993259d31dfeeaa95187984fed (diff)
extcap: Restore functionality for options
Allow stored options to be restored to their default values. This adds a global cleanup method for extcap and globally defined preference values, which fixes the parameter problem with windows Change-Id: I48e0cf846ef81f4732d652c6a2ad0020db5df08e Reviewed-on: https://code.wireshark.org/review/13741 Petri-Dish: Roland Knall <rknall@gmail.com> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Roland Knall <rknall@gmail.com>
-rw-r--r--capchild/capture_sync.c2
-rw-r--r--extcap.c145
-rw-r--r--extcap.h19
-rw-r--r--extcap_parser.c2
-rw-r--r--extcap_parser.h1
-rw-r--r--rawshark.c16
-rw-r--r--tfshark.c19
-rw-r--r--tshark.c19
-rw-r--r--ui/gtk/main.c4
-rw-r--r--ui/qt/extcap_argument.cpp52
-rw-r--r--ui/qt/extcap_argument.h11
-rw-r--r--ui/qt/extcap_argument_file.cpp5
-rw-r--r--ui/qt/extcap_options_dialog.cpp114
-rw-r--r--ui/qt/extcap_options_dialog.h4
-rw-r--r--ui/qt/extcap_options_dialog.ui2
-rw-r--r--wireshark-qt.cpp4
16 files changed, 329 insertions, 90 deletions
diff --git a/capchild/capture_sync.c b/capchild/capture_sync.c
index 9acb64e..28c34a5 100644
--- a/capchild/capture_sync.c
+++ b/capchild/capture_sync.c
@@ -1733,7 +1733,7 @@ sync_pipe_input_cb(gint source, gpointer user_data)
#endif
#ifdef HAVE_EXTCAP
g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: cleaning extcap pipe");
- extcap_cleanup(cap_session->capture_opts);
+ extcap_if_cleanup(cap_session->capture_opts);
#endif
capture_input_closed(cap_session, primary_msg);
g_free(primary_msg);
diff --git a/extcap.c b/extcap.c
index cff8434..4fbf5d7 100644
--- a/extcap.c
+++ b/extcap.c
@@ -57,6 +57,8 @@
static HANDLE pipe_h = NULL;
#endif
+#define EXTCAP_PREF_SIZE 256
+
/* internal container, for all the extcap interfaces that have been found.
* will be resetted by every call to extcap_interface_list() and is being
* used in extcap_get_if_* as well as extcap_init_interfaces to ensure,
@@ -70,6 +72,12 @@ static GHashTable *ifaces = NULL;
*/
static GHashTable *tools = NULL;
+/* internal container, to map preferences for extcap utilities to dynamic
+ * memory content, which survives extcap if garbage collection, and does
+ * not lead to dangling pointers
+ */
+static GHashTable *extcap_prefs_dynamic_vals = NULL;
+
/* Callback definition for extcap_foreach */
typedef gboolean (*extcap_cb_t)(const gchar *extcap, const gchar *ifname, gchar *output, void *data,
gchar **err_str);
@@ -417,6 +425,41 @@ void extcap_register_preferences(void)
}
}
+void extcap_cleanup(void)
+{
+ if (extcap_prefs_dynamic_vals) {
+ g_hash_table_destroy(extcap_prefs_dynamic_vals);
+ }
+}
+
+void extcap_pref_store(extcap_arg * arg, const char * newval)
+{
+ if (arg && arg->storeval != NULL)
+ {
+ memset(arg->storeval, 0, EXTCAP_PREF_SIZE * sizeof(char));
+ if ( newval )
+ g_snprintf(arg->storeval, EXTCAP_PREF_SIZE, "%s", newval);
+ }
+
+}
+
+static gchar * extcap_prefs_dynamic_valptr(const char *name)
+{
+ gchar *valp;
+ if (!extcap_prefs_dynamic_vals) {
+ /* Initialize table only as needed, most preferences are not dynamic */
+ extcap_prefs_dynamic_vals = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, g_free);
+ }
+ valp = (gchar *)g_hash_table_lookup(extcap_prefs_dynamic_vals, name);
+ if (!valp) {
+ /* New dynamic pref, allocate, initialize and store. */
+ valp = g_new0(gchar, EXTCAP_PREF_SIZE);
+ g_hash_table_insert(extcap_prefs_dynamic_vals, g_strdup(name), valp);
+ }
+ return valp;
+}
+
static void extcap_free_if_configuration(GList *list)
{
GList *elem, *sl;
@@ -433,32 +476,25 @@ static void extcap_free_if_configuration(GList *list)
g_list_free(list);
}
-gchar * extcap_settings_key(const gchar * ifname, const gchar * setting)
-{
- gchar * setting_nohyphen;
- gchar * ifname_underscore;
- gchar * ifname_lower;
- gchar * key;
- GRegex * regex = g_regex_new ("(?![a-zA-Z1-9_]).", (GRegexCompileFlags) 0, (GRegexMatchFlags) 0, NULL );
+struct preference *
+extcap_pref_for_argument(const gchar *ifname, struct _extcap_arg * arg) {
+ struct preference * pref = NULL;
- if (!regex)
- return NULL;
+ GRegex * regex = g_regex_new ("[-]+", (GRegexCompileFlags) 0, (GRegexMatchFlags) 0, NULL );
+ if (regex) {
+ if ( prefs_find_module("extcap") ) {
+ 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));
- setting_nohyphen =
- g_regex_replace_literal(regex, setting, strlen(setting), 0,
- "", (GRegexMatchFlags) 0, NULL );
- ifname_underscore =
- g_regex_replace_literal(regex, ifname, strlen(ifname), 0,
- "_", (GRegexMatchFlags) 0, NULL );
- ifname_lower = g_utf8_strdown(ifname_underscore, -1);
- key = g_strconcat(ifname_lower, ".", setting_nohyphen, NULL);
+ pref = prefs_find_preference(prefs_find_module("extcap"), pref_ifname);
- g_free(setting_nohyphen);
- g_free(ifname_underscore);
- g_free(ifname_lower);
- g_regex_unref(regex);
+ g_free(pref_name);
+ g_free(pref_ifname);
+ }
+ g_regex_unref(regex);
+ }
- return key;
+ return pref;
}
static gboolean search_cb(const gchar *extcap _U_, const gchar *ifname _U_, gchar *output, void *data,
@@ -482,29 +518,44 @@ static gboolean search_cb(const gchar *extcap _U_, const gchar *ifname _U_, gcha
if ( dev_module ) {
GList * walker = arguments;
- while ( walker != NULL ) {
- extcap_arg * arg = (extcap_arg *)walker->data;
+ GRegex * regex = g_regex_new ("[-]+", (GRegexCompileFlags) 0, (GRegexMatchFlags) 0, NULL );
+ if (regex) {
+ while ( walker != NULL ) {
+ extcap_arg * arg = (extcap_arg *)walker->data;
+ arg->device_name = g_strdup(ifname);
- if ( arg->save ) {
- struct preference * pref = NULL;
- gchar * pref_ifname = extcap_settings_key(ifname, arg->call);
+ if ( arg->save ) {
+ struct preference * pref = 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);
+ 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 = extcap_prefs_dynamic_valptr(pref_ifname);
+ g_snprintf(arg->storeval, EXTCAP_PREF_SIZE, "%s", arg->default_complex->_val);
+ }
- prefs_register_string_preference(dev_module, g_strdup(pref_ifname),
- arg->display, arg->display, (const gchar **)(void*)(&arg->storeval));
- } else {
- /* Been here before, restore stored value */
- if (! arg->storeval && pref->varp.string)
- arg->storeval = g_strdup(*(pref->varp.string));
+ 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 = extcap_prefs_dynamic_valptr(pref_ifname);
+ g_snprintf(arg->storeval, EXTCAP_PREF_SIZE, "%s", *(pref->varp.string));
+ }
}
- g_free(pref_ifname);
- }
- walker = g_list_next(walker);
+ g_free(pref_name);
+ g_free(pref_ifname);
+ }
+
+ walker = g_list_next(walker);
+ }
+ g_regex_unref(regex);
}
}
@@ -592,7 +643,7 @@ extcap_has_configuration(const char * ifname, gboolean is_required) {
return found;
}
-void extcap_cleanup(capture_options * capture_opts) {
+void extcap_if_cleanup(capture_options * capture_opts) {
interface_options interface_opts;
guint icnt = 0;
@@ -691,15 +742,15 @@ static void extcap_child_watch_cb(GPid pid, gint status _U_, gpointer user_data)
static
GPtrArray * extcap_prepare_arguments(interface_options interface_opts)
{
- GPtrArray *result = NULL;
+ GPtrArray *result = NULL;
#if ARG_DEBUG
gchar **tmp;
int tmp_i;
#endif
- if (interface_opts.if_type == IF_EXTCAP )
- {
- result = g_ptr_array_new();
+ if (interface_opts.if_type == IF_EXTCAP )
+ {
+ result = g_ptr_array_new();
#define add_arg(X) g_ptr_array_add(result, g_strdup(X))
@@ -781,9 +832,9 @@ GPtrArray * extcap_prepare_arguments(interface_options interface_opts)
}
#endif
- }
+ }
- return result;
+ return result;
}
/* call mkfifo for each extcap,
diff --git a/extcap.h b/extcap.h
index 509e007..d8e94b9 100644
--- a/extcap.h
+++ b/extcap.h
@@ -28,6 +28,8 @@
#include <glib.h>
+#include "ws_symbol_export.h"
+
#ifdef _WIN32
#include <windows.h>
#include <wsutil/unicode-utils.h>
@@ -57,6 +59,8 @@ typedef struct _extcap_info {
gchar * version;
} extcap_info;
+struct _extcap_arg;
+
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
@@ -85,9 +89,6 @@ extcap_get_if_configuration(const char * ifname);
gboolean
extcap_has_configuration(const char * ifname, gboolean is_required);
-/* converts an extcap setting to its equivalent preference key */
-gchar * extcap_settings_key(const gchar * ifname, const gchar * setting);
-
#ifdef WIN32
HANDLE
extcap_get_win32_handle();
@@ -99,8 +100,18 @@ extcap_init_interfaces(capture_options * capture_opts);
gboolean
extcap_create_pipe(char ** fifo);
+/* Clean up all if related stuff */
void
-extcap_cleanup(capture_options * capture_opts _U_);
+extcap_if_cleanup(capture_options * capture_opts _U_);
+
+struct preference *
+extcap_pref_for_argument(const gchar *ifname, struct _extcap_arg * arg);
+
+void
+extcap_pref_store(struct _extcap_arg * arg, const char * newval);
+
+/* Clean up global extcap stuff on program exit */
+void extcap_cleanup(void);
#ifdef __cplusplus
}
diff --git a/extcap_parser.c b/extcap_parser.c
index 1e6b117..3fe0817 100644
--- a/extcap_parser.c
+++ b/extcap_parser.c
@@ -350,7 +350,7 @@ void extcap_free_arg(extcap_arg *a) {
g_free(a->tooltip);
g_free(a->fileextension);
g_free(a->regexp);
- g_free(a->storeval);
+ g_free(a->device_name);
if (a->range_start != NULL)
extcap_free_complex(a->range_start);
diff --git a/extcap_parser.h b/extcap_parser.h
index e43e1ac..b6cc762 100644
--- a/extcap_parser.h
+++ b/extcap_parser.h
@@ -118,6 +118,7 @@ typedef struct _extcap_arg {
extcap_complex *default_complex;
gchar * storeval;
+ gchar * device_name;
GList * values;
} extcap_arg;
diff --git a/rawshark.c b/rawshark.c
index ebfbea4..fe68b76 100644
--- a/rawshark.c
+++ b/rawshark.c
@@ -96,6 +96,10 @@
#include "caputils/capture-pcap-util.h"
+#ifdef HAVE_EXTCAP
+#include "extcap.h"
+#endif
+
#ifdef HAVE_LIBPCAP
#include <setjmp.h>
#ifdef _WIN32
@@ -798,6 +802,9 @@ main(int argc, char *argv[])
cmdarg_err("%s", err_msg);
g_free(err_msg);
epan_free(cfile.epan);
+#ifdef HAVE_EXTCAP
+ extcap_cleanup();
+#endif
epan_cleanup();
exit(2);
}
@@ -819,6 +826,9 @@ main(int argc, char *argv[])
if (raw_cf_open(&cfile, pipe_name) != CF_OK) {
epan_free(cfile.epan);
+#ifdef HAVE_EXTCAP
+ extcap_cleanup();
+#endif
epan_cleanup();
exit(2);
}
@@ -840,6 +850,9 @@ main(int argc, char *argv[])
/* Process the packets in the file */
if (!load_cap_file(&cfile)) {
epan_free(cfile.epan);
+#ifdef HAVE_EXTCAP
+ extcap_cleanup();
+#endif
epan_cleanup();
exit(2);
}
@@ -850,6 +863,9 @@ main(int argc, char *argv[])
}
epan_free(cfile.epan);
+#ifdef HAVE_EXTCAP
+ extcap_cleanup();
+#endif
epan_cleanup();
return 0;
diff --git a/tfshark.c b/tfshark.c
index fe97057..4bea91c 100644
--- a/tfshark.c
+++ b/tfshark.c
@@ -80,6 +80,10 @@
#include <epan/dissectors/packet-kerberos.h>
#endif
+#ifdef HAVE_EXTCAP
+#include "extcap.h"
+#endif
+
#include <wiretap/wtap-int.h>
#include <wiretap/file_wrappers.h>
@@ -859,6 +863,9 @@ main(int argc, char *argv[])
* cruft getting in the way. Makes the results of running
* $ ./tools/valgrind-wireshark -n
* much more useful. */
+#ifdef HAVE_EXTCAP
+ extcap_cleanup();
+#endif
epan_cleanup();
return 0;
}
@@ -987,6 +994,9 @@ main(int argc, char *argv[])
if (!dfilter_compile(rfilter, &rfcode, &err_msg)) {
cmdarg_err("%s", err_msg);
g_free(err_msg);
+#ifdef HAVE_EXTCAP
+ extcap_cleanup();
+#endif
epan_cleanup();
return 2;
}
@@ -997,6 +1007,9 @@ main(int argc, char *argv[])
if (!dfilter_compile(dfilter, &dfcode, &err_msg)) {
cmdarg_err("%s", err_msg);
g_free(err_msg);
+#ifdef HAVE_EXTCAP
+ extcap_cleanup();
+#endif
epan_cleanup();
return 2;
}
@@ -1042,6 +1055,9 @@ main(int argc, char *argv[])
/* TODO: if tfshark is ever changed to give the user a choice of which
open_routine reader to use, then the following needs to change. */
if (cf_open(&cfile, cf_name, WTAP_TYPE_AUTO, FALSE, &err) != CF_OK) {
+#ifdef HAVE_EXTCAP
+ extcap_cleanup();
+#endif
epan_cleanup();
return 2;
}
@@ -1080,6 +1096,9 @@ main(int argc, char *argv[])
draw_tap_listeners(TRUE);
funnel_dump_all_text_windows();
epan_free(cfile.epan);
+#ifdef HAVE_EXTCAP
+ extcap_cleanup();
+#endif
epan_cleanup();
output_fields_free(output_fields);
diff --git a/tshark.c b/tshark.c
index 452e420..7a8c2d4 100644
--- a/tshark.c
+++ b/tshark.c
@@ -122,6 +122,10 @@
#include <wsutil/str_util.h>
#include <wsutil/utf8_entities.h>
+#ifdef HAVE_EXTCAP
+#include "extcap.h"
+#endif
+
#ifdef HAVE_PLUGINS
#include <wsutil/plugins.h>
#endif
@@ -1306,6 +1310,9 @@ main(int argc, char *argv[])
* cruft getting in the way. Makes the results of running
* $ ./tools/valgrind-wireshark -n
* much more useful. */
+#ifdef HAVE_EXTCAP
+ extcap_cleanup();
+#endif
epan_cleanup();
return 0;
case 'O': /* Only output these protocols */
@@ -1725,6 +1732,9 @@ main(int argc, char *argv[])
if (!dfilter_compile(rfilter, &rfcode, &err_msg)) {
cmdarg_err("%s", err_msg);
g_free(err_msg);
+#ifdef HAVE_EXTCAP
+ extcap_cleanup();
+#endif
epan_cleanup();
#ifdef HAVE_PCAP_OPEN_DEAD
{
@@ -1751,6 +1761,9 @@ main(int argc, char *argv[])
if (!dfilter_compile(dfilter, &dfcode, &err_msg)) {
cmdarg_err("%s", err_msg);
g_free(err_msg);
+#ifdef HAVE_EXTCAP
+ extcap_cleanup();
+#endif
epan_cleanup();
#ifdef HAVE_PCAP_OPEN_DEAD
{
@@ -1862,6 +1875,9 @@ main(int argc, char *argv[])
* We're reading a capture file.
*/
if (cf_open(&cfile, cf_name, in_file_type, FALSE, &err) != CF_OK) {
+#ifdef HAVE_EXTCAP
+ extcap_cleanup();
+#endif
epan_cleanup();
return 2;
}
@@ -2023,6 +2039,9 @@ main(int argc, char *argv[])
draw_tap_listeners(TRUE);
funnel_dump_all_text_windows();
epan_free(cfile.epan);
+#ifdef HAVE_EXTCAP
+ extcap_cleanup();
+#endif
epan_cleanup();
output_fields_free(output_fields);
diff --git a/ui/gtk/main.c b/ui/gtk/main.c
index b827509..4ff33fe 100644
--- a/ui/gtk/main.c
+++ b/ui/gtk/main.c
@@ -2758,6 +2758,10 @@ main(int argc, char *argv[])
gtk_iface_mon_stop();
#endif
+#ifdef HAVE_EXTCAP
+ extcap_cleanup();
+#endif
+
epan_cleanup();
AirPDcapDestroyContext(&airpdcap_ctx);
diff --git a/ui/qt/extcap_argument.cpp b/ui/qt/extcap_argument.cpp
index 9f5ecba..5c2eff1 100644
--- a/ui/qt/extcap_argument.cpp
+++ b/ui/qt/extcap_argument.cpp
@@ -47,6 +47,7 @@
#include <extcap.h>
#include <epan/prefs.h>
+#include <epan/prefs-int.h>
#include <color_utils.h>
#include <extcap_parser.h>
@@ -280,11 +281,8 @@ bool ExtArgBool::defaultBool()
if ( _argument )
{
- if ( _argument->default_complex )
- {
- if ( extcap_complex_get_bool(_argument->default_complex) == (gboolean)TRUE )
- result = true;
- }
+ if ( extcap_complex_get_bool(_argument->default_complex) == (gboolean)TRUE )
+ result = true;
}
return result;
@@ -485,6 +483,12 @@ void ExtcapValue::setChildren(ExtcapValueList children)
_children.append(children);
}
+ExtcapArgument::ExtcapArgument(QObject *parent) :
+ QObject(parent), _argument(0), _label(0),
+ label_style(QString("QLabel { color: %1; }"))
+{
+}
+
ExtcapArgument::ExtcapArgument(extcap_arg * argument, QObject *parent) :
QObject(parent), _argument(argument), _label(0),
label_style(QString("QLabel { color: %1; }"))
@@ -497,9 +501,21 @@ ExtcapArgument::ExtcapArgument(extcap_arg * argument, QObject *parent) :
}
}
+ExtcapArgument::ExtcapArgument(const ExtcapArgument &obj) :
+ QObject(obj.parent()), _argument(obj._argument), _label(0),
+ label_style(QString("QLabel { color: %1; }"))
+{
+ if ( _argument->values != 0 )
+ {
+ ExtcapValueList elements = loadValues(QString(""));
+ if ( elements.length() > 0 )
+ values.append(elements);
+ }
+}
+
ExtcapValueList ExtcapArgument::loadValues(QString parent)
{
- if (_argument->values == 0 )
+ if (_argument == 0 || _argument->values == 0 )
return ExtcapValueList();
GList * walker = 0;
@@ -532,7 +548,6 @@ ExtcapValueList ExtcapArgument::loadValues(QString parent)
}
ExtcapArgument::~ExtcapArgument() {
- // TODO Auto-generated destructor stub
}
QWidget * ExtcapArgument::createLabel(QWidget * parent)
@@ -544,7 +559,10 @@ QWidget * ExtcapArgument::createLabel(QWidget * parent)
QString text = QString().fromUtf8(_argument->display);
- _label = new QLabel(text, parent);
+ if ( _label == 0 )
+ _label = new QLabel(text, parent);
+ else
+ _label->setText(text);
_label->setProperty("isRequired", QString(isRequired() ? "true" : "false"));
@@ -553,7 +571,7 @@ QWidget * ExtcapArgument::createLabel(QWidget * parent)
if ( _argument->tooltip != 0 )
_label->setToolTip(QString().fromUtf8(_argument->tooltip));
- return _label;
+ return (QWidget *)_label;
}
QWidget * ExtcapArgument::createEditor(QWidget *)
@@ -576,6 +594,12 @@ QString ExtcapArgument::prefValue()
return value();
}
+void ExtcapArgument::resetValue()
+{
+ if (_argument && _argument->storeval)
+ memset(_argument->storeval, 0, 128 * sizeof(char));
+}
+
bool ExtcapArgument::isValid()
{
/* Unrequired arguments are always valid, except if validity checks fail,
@@ -599,10 +623,16 @@ QString ExtcapArgument::defaultValue()
QString ExtcapArgument::prefKey(const QString & device_name)
{
- if ( ! _argument->save )
+ struct preference * pref = NULL;
+
+ if ( _argument == 0 || ! _argument->save )
return QString();
- return QString(extcap_settings_key(device_name.toStdString().c_str(), _argument->call));
+ pref = extcap_pref_for_argument(device_name.toStdString().c_str(), _argument);
+ if ( pref != NULL )
+ return QString(pref->name);
+
+ return QString();
}
bool ExtcapArgument::isRequired()
diff --git a/ui/qt/extcap_argument.h b/ui/qt/extcap_argument.h
index 084b333..d4cfd87 100644
--- a/ui/qt/extcap_argument.h
+++ b/ui/qt/extcap_argument.h
@@ -82,8 +82,9 @@ class ExtcapArgument: public QObject
Q_OBJECT
public:
+ ExtcapArgument(QObject *parent=0);
ExtcapArgument(extcap_arg * argument, QObject *parent=0);
-
+ ExtcapArgument(const ExtcapArgument &obj);
virtual ~ExtcapArgument();
virtual QWidget * createLabel(QWidget * parent = 0);
@@ -95,12 +96,14 @@ public:
virtual QString defaultValue();
bool isDefault();
- bool isValid();
+ virtual bool isValid();
bool isRequired();
QString prefKey(const QString & device_name);
virtual QString prefValue();
+ void resetValue();
+
static ExtcapArgument * create(extcap_arg * argument = 0);
Q_SIGNALS:
@@ -115,7 +118,7 @@ protected:
ExtcapValueList values;
extcap_arg * _argument;
- QWidget * _label;
+ QLabel * _label;
const QString label_style;
@@ -127,6 +130,8 @@ private Q_SLOTS:
};
+Q_DECLARE_METATYPE(ExtcapArgument)
+
class ExtArgText : public ExtcapArgument
{
diff --git a/ui/qt/extcap_argument_file.cpp b/ui/qt/extcap_argument_file.cpp
index 5e53803..df8da8c 100644
--- a/ui/qt/extcap_argument_file.cpp
+++ b/ui/qt/extcap_argument_file.cpp
@@ -57,15 +57,16 @@ QWidget * ExtcapArgumentFileSelection::createEditor(QWidget * parent)
{
QString storeval;
QString text = defaultValue();
+ QString buttonText(UTF8_HORIZONTAL_ELLIPSIS);
QWidget * fileWidget = new QWidget(parent);
QHBoxLayout * editLayout = new QHBoxLayout();
QMargins margins = editLayout->contentsMargins();
editLayout->setContentsMargins(0, 0, 0, margins.bottom());
fileWidget->setContentsMargins(margins.left(), margins.right(), 0, margins.bottom());
- QPushButton * button = new QPushButton(UTF8_HORIZONTAL_ELLIPSIS, fileWidget);
+ QPushButton * button = new QPushButton(buttonText, fileWidget);
- textBox = new QLineEdit(defaultValue(), parent);
+ textBox = new QLineEdit(text, parent);
textBox->setReadOnly(true);
if ( _argument->storeval )
diff --git a/ui/qt/extcap_options_dialog.cpp b/ui/qt/extcap_options_dialog.cpp
index 07c0523..cd728d8 100644
--- a/ui/qt/extcap_options_dialog.cpp
+++ b/ui/qt/extcap_options_dialog.cpp
@@ -190,29 +190,24 @@ void ExtcapOptionsDialog::anyValueChanged()
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(allowStart);
}
-void ExtcapOptionsDialog::updateWidgets()
+void ExtcapOptionsDialog::loadArguments()
{
- GList * arguments = NULL, * walker = NULL, * item = NULL;
- QWidget * lblWidget = NULL, *editWidget = NULL;
+ GList * arguments = NULL, * item = NULL;
ExtcapArgument * argument = NULL;
- bool allowStart = true;
-
- unsigned int counter = 0;
if ( device_name.length() == 0 )
return;
- arguments = extcap_get_if_configuration((const char *)( device_name.toStdString().c_str() ) );
- walker = g_list_first(arguments);
+ extcapArguments.clear();
- QGridLayout * layout = new QGridLayout();
+ arguments = g_list_first(extcap_get_if_configuration((const char *)( device_name.toStdString().c_str() ) ));
ExtcapArgumentList required;
ExtcapArgumentList optional;
- while ( walker != NULL )
+ while ( arguments != NULL )
{
- item = g_list_first((GList *)(walker->data));
+ item = g_list_first((GList *)(arguments->data));
while ( item != NULL )
{
argument = ExtcapArgument::create((extcap_arg *)(item->data));
@@ -226,7 +221,7 @@ void ExtcapOptionsDialog::updateWidgets()
}
item = item->next;
}
- walker = walker->next;
+ arguments = g_list_next(arguments);
}
if ( required.length() > 0 )
@@ -234,24 +229,52 @@ void ExtcapOptionsDialog::updateWidgets()
if ( optional.length() > 0 )
extcapArguments << optional;
+}
+
+void ExtcapOptionsDialog::updateWidgets()
+{
+ QWidget * lblWidget = NULL, *editWidget = NULL;
+ ExtcapArgument * argument = NULL;
+ bool allowStart = true;
+
+ unsigned int counter = 0;
+
+ if ( device_name.length() == 0 )
+ return;
+
+ /* find existing layout */
+ if (ui->verticalLayout->children().count() > 0)
+ {
+ QGridLayout * layout = (QGridLayout *)ui->verticalLayout->itemAt(0);
+ ui->verticalLayout->removeItem(layout);
+ ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
+ }
+
+ QGridLayout * layout = new QGridLayout();
+
+ /* Load all extcap arguments */
+ loadArguments();
+
ExtcapArgumentList::iterator iter = extcapArguments.begin();
while ( iter != extcapArguments.end() )
{
- lblWidget = (*iter)->createLabel((QWidget *)this);
+ argument = (ExtcapArgument *)(*iter);
+ lblWidget = argument->createLabel((QWidget *)this);
if ( lblWidget != NULL )
{
layout->addWidget(lblWidget, counter, 0, Qt::AlignVCenter);
- editWidget = (*iter)->createEditor((QWidget *) this);
+ editWidget = argument->createEditor((QWidget *) this);
if ( editWidget != NULL )
{
+ editWidget->setProperty(QString("extcap").toLocal8Bit(), QVariant::fromValue(argument));
layout->addWidget(editWidget, counter, 1, Qt::AlignVCenter);
}
- if ( (*iter)->isRequired() && ! (*iter)->isValid() )
+ if ( argument->isRequired() && ! argument->isValid() )
allowStart = false;
- connect((*iter), SIGNAL(valueChanged()), this, SLOT(anyValueChanged()));
+ connect(argument, SIGNAL(valueChanged()), this, SLOT(anyValueChanged()));
counter++;
}
@@ -326,6 +349,59 @@ bool ExtcapOptionsDialog::saveOptionToCaptureInfo()
return true;
}
+void ExtcapOptionsDialog::on_buttonBox_clicked(QAbstractButton *button)
+{
+ /* Only the save button has the ActionRole */
+ if ( ui->buttonBox->buttonRole(button) == QDialogButtonBox::ResetRole )
+ resetValues();
+}
+
+void ExtcapOptionsDialog::resetValues()
+{
+ ExtcapArgumentList::const_iterator iter;
+ QString value;
+
+ if (ui->verticalLayout->children().count() > 0)
+ {
+ QGridLayout * layout = (QGridLayout *)ui->verticalLayout->findChild<QGridLayout *>();
+
+ for ( int row = 0; row < layout->rowCount(); row++ )
+ {
+ QWidget * child = layout->itemAtPosition(row, 1)->widget();
+
+ if ( child )
+ {
+ /* Don't need labels, the edit widget contains the extcapargument property value */
+ ExtcapArgument * arg = 0;
+ QVariant prop = child->property(QString("extcap").toLocal8Bit());
+
+ if ( prop.isValid() && prop.canConvert<ExtcapArgument *>())
+ {
+ arg = prop.value<ExtcapArgument *>();
+
+ /* value<> can fail */
+ if (arg)
+ {
+ arg->resetValue();
+
+ /* replacing the edit widget after resetting will lead to default value */
+ layout->removeItem(layout->itemAtPosition(row, 1));
+ QWidget * editWidget = arg->createEditor((QWidget *) this);
+ if ( editWidget != NULL )
+ {
+ editWidget->setProperty(QString("extcap").toLocal8Bit(), QVariant::fromValue(arg));
+ layout->addWidget(editWidget, row, 1, Qt::AlignVCenter);
+ }
+ }
+ }
+ }
+ }
+
+ /* this stores all values to the preferences */
+ storeValues();
+ }
+}
+
void ExtcapOptionsDialog::storeValues()
{
GHashTable * entries = g_hash_table_new(g_str_hash, g_str_equal);
@@ -379,7 +455,7 @@ void ExtcapOptionsDialog::storeValues()
gchar * val = g_strdup(value.length() == 0 ? " " : value.toStdString().c_str());
/* Setting the internally stored value for the preference to the new value */
- (*iter)->argument()->storeval = g_strdup(val);
+ extcap_pref_store((*iter)->argument(), val);
g_hash_table_insert(entries, g_strdup(key.toStdString().c_str()), val);
}
@@ -388,10 +464,8 @@ void ExtcapOptionsDialog::storeValues()
if ( g_hash_table_size(entries) > 0 )
{
if ( prefs_store_ext_multiple("extcap", entries) )
- {
- wsApp->emitAppSignal(WiresharkApplication::PacketDissectionChanged);
wsApp->emitAppSignal(WiresharkApplication::PreferencesChanged);
- }
+
}
}
diff --git a/ui/qt/extcap_options_dialog.h b/ui/qt/extcap_options_dialog.h
index 3ca859e..14850a3 100644
--- a/ui/qt/extcap_options_dialog.h
+++ b/ui/qt/extcap_options_dialog.h
@@ -56,6 +56,7 @@ public:
private Q_SLOTS:
void on_buttonBox_accepted();
void on_buttonBox_rejected();
+ void on_buttonBox_clicked(QAbstractButton *button);
void on_buttonBox_helpRequested();
void updateWidgets();
void anyValueChanged();
@@ -69,8 +70,11 @@ private:
ExtcapArgumentList extcapArguments;
+ void loadArguments();
+
bool saveOptionToCaptureInfo();
void storeValues();
+ void resetValues();
};
#endif /* HAVE_EXTCAP */
diff --git a/ui/qt/extcap_options_dialog.ui b/ui/qt/extcap_options_dialog.ui
index edd6c96..aba6730 100644
--- a/ui/qt/extcap_options_dialog.ui
+++ b/ui/qt/extcap_options_dialog.ui
@@ -40,7 +40,7 @@
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
- <set>QDialogButtonBox::Close|QDialogButtonBox::Help|QDialogButtonBox::Ok</set>
+ <set>QDialogButtonBox::Close|QDialogButtonBox::Help|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults</set>
</property>
</widget>
</item>
diff --git a/wireshark-qt.cpp b/wireshark-qt.cpp
index 7bdf946..d32dfeb 100644
--- a/wireshark-qt.cpp
+++ b/wireshark-qt.cpp
@@ -852,6 +852,10 @@ int main(int argc, char *argv[])
ret_val = wsApp->exec();
+#ifdef HAVE_EXTCAP
+ extcap_cleanup();
+#endif
+
epan_cleanup();
AirPDcapDestroyContext(&airpdcap_ctx);