diff --git a/docbook/release-notes.adoc b/docbook/release-notes.adoc index cd8ac43164..b244bbfbd4 100644 --- a/docbook/release-notes.adoc +++ b/docbook/release-notes.adoc @@ -40,6 +40,7 @@ since version 3.1.0: * IOGraph automatically adds a graph for the selected display filter if no previous graph exists * Action buttons for the display filter bar may be aligned left via the context menu +* Allow extcaps to be loaded from the personal configuration directory The following features are new (or have been significantly updated) since version 3.0.0: diff --git a/extcap.c b/extcap.c index fcf3ab8f78..8921915c7a 100644 --- a/extcap.c +++ b/extcap.c @@ -219,17 +219,13 @@ extcap_dump_all(void) extcap_get_descriptions(print_extcap_description, NULL); } -/** - * Obtains a list of extcap program paths. Use g_slist_free_full(paths, g_free) - * to destroy the list. - */ static GSList * -extcap_get_extcap_paths(void) +extcap_get_extcap_paths_from_dir(GSList * list, const char * dirname) { - GDir *dir; - const char *dirname = get_extcap_dir(); - const gchar *file; - GSList *paths = NULL; + GDir * dir; + const char * file; + + GSList * paths = list; if ((dir = g_dir_open(dirname, 0, NULL)) != NULL) { while ((file = g_dir_read_name(dir)) != NULL) { @@ -250,6 +246,21 @@ extcap_get_extcap_paths(void) return paths; } +/** + * Obtains a list of extcap program paths. Use g_slist_free_full(paths, g_free) + * to destroy the list. + */ +static GSList * +extcap_get_extcap_paths(void) +{ + GSList *paths = NULL; + + paths = extcap_get_extcap_paths_from_dir(paths, get_persconffile_path("extcap", FALSE)); + paths = extcap_get_extcap_paths_from_dir(paths, get_extcap_dir()); + + return paths; +} + static extcap_interface * extcap_find_interface_for_ifname(const gchar *ifname) { @@ -1688,6 +1699,9 @@ extcap_ensure_interface(const gchar * toolname, gboolean create_if_nonexist) _loaded_interfaces = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, extcap_free_interface); element = (extcap_info *) g_hash_table_lookup(_loaded_interfaces, toolname ); + if ( element ) + return NULL; + if ( ! element && create_if_nonexist ) { g_hash_table_insert(_loaded_interfaces, g_strdup(toolname), g_new0(extcap_info, 1)); @@ -1753,7 +1767,8 @@ process_new_extcap(const char *extcap, char *output) element = extcap_ensure_interface(toolname, TRUE); if ( element == NULL ) { - g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_ERROR, "Cannot store interface %s, maybe duplicate?", extcap ); + g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_WARNING, + "Cannot store interface %s, already loaded as personal plugin", extcap ); g_list_foreach(interfaces, remove_extcap_entry, NULL); g_list_free(interfaces); g_list_free(interface_keys); diff --git a/ui/qt/about_dialog.cpp b/ui/qt/about_dialog.cpp index 7cb00132e1..50c4482370 100644 --- a/ui/qt/about_dialog.cpp +++ b/ui/qt/about_dialog.cpp @@ -233,10 +233,8 @@ FolderListModel::FolderListModel(QObject * parent): #endif /* Extcap */ - QStringList extPaths = QString(get_extcap_dir()).split(G_SEARCHPATH_SEPARATOR_S); - - foreach(QString path, extPaths) - appendRow( QStringList() << tr("Extcap path") << path.trimmed() << tr("Extcap Plugins search path")); + appendRow( QStringList() << tr("Personal Extcap path") << QString(get_persconffile_path("extcap", FALSE)).trimmed() << tr("Extcap Plugins search path")); + appendRow( QStringList() << tr("Global Extcap path") << QString(get_extcap_dir()).trimmed() << tr("Extcap Plugins search path")); #ifdef HAVE_MAXMINDDB /* MaxMind DB */