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>
This commit is contained in:
Roland Knall 2015-12-29 07:57:36 +01:00 committed by Michael Mann
parent 191f9bdbc5
commit 485bc456c5
16 changed files with 329 additions and 90 deletions

View File

@ -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);

145
extcap.c
View File

@ -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));
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));
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 **)&(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,

View File

@ -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
}

View File

@ -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);

View File

@ -118,6 +118,7 @@ typedef struct _extcap_arg {
extcap_complex *default_complex;
gchar * storeval;
gchar * device_name;
GList * values;
} extcap_arg;

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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()

View File

@ -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
{

View File

@ -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 )

View File

@ -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);
}
}
}

View File

@ -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 */

View File

@ -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>

View File

@ -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);