Move most of the plugin code from epan to wsutil and remove all
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Mon, 2 Dec 2013 08:30:29 +0000 (08:30 +0000)
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Mon, 2 Dec 2013 08:30:29 +0000 (08:30 +0000)
knowledge of particular types of plugins.  Instead, let particular types
of plugins register with the common plugin code, giving a name and a
routine to recognize that type of plugin.

In particular applications, only process the relevant plugin types.

Add a Makefile.common to the codecs directory.

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@53710 f5534014-38df-0310-8fa8-9805f1628bb7

39 files changed:
CMakeLists.txt
Makefile.am
Makefile.common
Makefile.nmake
capinfos.c
codecs/Makefile.am
codecs/Makefile.common [new file with mode: 0644]
codecs/Makefile.nmake
codecs/codecs.c
codecs/codecs.h
dftest.c
editcap.c
epan/CMakeLists.txt
epan/Makefile.common
epan/epan.c
epan/epan.h
epan/packet.c
epan/plugins.c [deleted file]
epan/proto.c
epan/proto.h
epan/tap.c
epan/tap.h
epan/wslua/init_wslua.c
epan/wslua/init_wslua.h
rawshark.c
tshark.c
ui/gtk/about_dlg.c
ui/gtk/main.c
ui/gtk/main_menubar.c
ui/gtk/packet_win.c
ui/gtk/plugins_dlg.c
ui/gtk/rtp_player.c
ui/qt/main.cpp
wiretap/wtap.c
wiretap/wtap.h
wsutil/CMakeLists.txt
wsutil/Makefile.common
wsutil/plugins.c [new file with mode: 0644]
wsutil/plugins.h [moved from epan/plugins.h with 52% similarity]

index 75db872ef8680e5f77ef4d547a40b8c206802be6..d578351c2431bd9cd6036dc281e003ae8f3a04a0 100644 (file)
@@ -761,10 +761,6 @@ if(WIN32)
        )
 endif()
 
-set(WTAP_PLUGIN_SOURCES
-       epan/plugins.c
-)
-
 set(SHARK_COMMON_CAPTURE_SRC
        capture_ifinfo.c
        capture_ui_utils.c
@@ -1071,7 +1067,6 @@ if(BUILD_mergecap)
        set(mergecap_FILES
                mergecap.c
                svnversion.h
-               ${WTAP_PLUGIN_SOURCES}
        )
        add_executable(mergecap ${mergecap_FILES})
        add_dependencies(mergecap svnversion)
@@ -1090,7 +1085,6 @@ if(BUILD_reordercap)
        set(reordercap_FILES
                reordercap.c
                svnversion.h
-               ${WTAP_PLUGIN_SOURCES}
        )
        add_executable(reordercap ${reordercap_FILES})
        add_dependencies(reordercap svnversion)
@@ -1110,7 +1104,6 @@ if(BUILD_capinfos)
        )
        set(capinfos_FILES
                capinfos.c
-               ${WTAP_PLUGIN_SOURCES}
        )
        add_executable(capinfos ${capinfos_FILES})
        add_dependencies(capinfos svnversion)
@@ -1128,7 +1121,6 @@ if(BUILD_editcap)
        )
        set(editcap_FILES
                editcap.c
-               ${WTAP_PLUGIN_SOURCES}
        )
        add_executable(editcap ${editcap_FILES})
        add_dependencies(editcap svnversion)
index 3ea7abaab6e980229610d1926beed2e6522f4019..6a46f4c9ac8ccf3f92adeb5d85bd3a9b8e21e9ac 100644 (file)
@@ -311,13 +311,9 @@ plugin_ldadd = $(_CUSTOM_plugin_ldadd_) \
        -dlopen plugins/wimax/wimax.la \
        -dlopen plugins/wimaxmacphy/wimaxmacphy.la
 
-WTAP_PLUGIN_SOURCES = \
-       epan/plugins.c
-
 else           # HAVE_PLUGINS
 
 plugin_ldadd =
-WTAP_PLUGIN_SOURCES =
 
 endif          # HAVE_PLUGINS
 
@@ -389,7 +385,11 @@ if HAVE_Qt
 wireshark_qt_SOURCES = $(WIRESHARK_COMMON_SRC)
 wireshark_qt_INCLUDES = $(WIRESHARK_COMMON_INCLUDES)
 wireshark_qt_CFLAGS = $(AM_CLEAN_CFLAGS) $(py_dissectors_dir)
-wireshark_qt_LDADD =  ui/qt/libqtui.a $(wireshark_ldadd) @Qt_LIBS@
+wireshark_qt_LDADD = \
+       ui/qt/libqtui.a \
+       $(wireshark_ldadd) \
+       @Qt_LIBS@
+
 #
 # XXX - this makes wireshark_qt_LDFLAGS not work; we should figure out
 # another way to get wireshark-qt linked as a C++ program, perhaps by
@@ -403,7 +403,10 @@ if HAVE_GTK
 wireshark_SOURCES = $(WIRESHARK_COMMON_SRC)
 wireshark_INCLUDES = $(WIRESHARK_COMMON_INCLUDES)
 wireshark_CFLAGS = $(AM_CLEAN_CFLAGS) $(py_dissectors_dir)
-wireshark_LDADD = ui/gtk/libgtkui.a $(wireshark_ldadd) @GTK_LIBS@
+wireshark_LDADD = \
+       ui/gtk/libgtkui.a \
+       $(wireshark_ldadd) \
+       @GTK_LIBS@
 endif
 
 # Ideally we could trigger automatic c++ linking here with
index 5e2f255071ab97b2fac03cf6d548a7bc195871cb..14622864797e5e0a62a543b5aba4b291a4d4bf57 100644 (file)
@@ -147,8 +147,7 @@ mergecap_SOURCES = \
 
 # editcap specifics
 editcap_SOURCES = \
-       editcap.c       \
-       $(WTAP_PLUGIN_SOURCES)
+       editcap.c
 
 # reordercap specifics
 reordercap_SOURCES = \
@@ -157,8 +156,7 @@ reordercap_SOURCES = \
 
 # capinfos specifics
 capinfos_SOURCES = \
-       capinfos.c \
-       $(WTAP_PLUGIN_SOURCES)
+       capinfos.c
 
 # dftest specifics
 dftest_SOURCES =       \
index 64119998ffb2aba2f24499b256fd04130805a4b1..03d575f869a64f18ad171317d46bc06cf4fb7574 100644 (file)
@@ -53,9 +53,6 @@ CFLAGS=$(WARNINGS_ARE_ERRORS) $(GENERATED_CFLAGS)
 
 PLATFORM_SRC = capture-wpcap.c capture_wpcap_packet.c capture_win_ifnames.c
 
-WTAP_PLUGIN_SOURCES = \
-       epan/plugins.c
-
 include Makefile.common
 
 wireshark_OBJECTS = $(WIRESHARK_COMMON_SRC:.c=.obj)
index 893901579c864b2d68241b735f0e5ea6bb07f433..29a3fe03dc63e2965dd74b35f6588fc56fc589bb 100644 (file)
 #include <wsutil/privileges.h>
 #include <wsutil/filesystem.h>
 
-/*
- * The symbols declared in the below are exported from libwireshark,
- * but we don't want to link whole libwireshark to capinfos.
- * We link the object directly instead and this needs a little trick
- * with the WS_BUILD_DLL #define.
- */
-#define WS_BUILD_DLL
-#define RESET_SYMBOL_EXPORT
-#include <epan/plugins.h>
-#undef WS_BUILD_DLL
-#define RESET_SYMBOL_EXPORT
+#ifdef HAVE_PLUGINS
+#include <wsutil/plugins.h>
+#endif
 
 #include "wtap.h"
 #include <wsutil/report_err.h>
@@ -1144,14 +1136,21 @@ main(int argc, char *argv[])
   init_process_policies();
 
 #ifdef HAVE_PLUGINS
-  /* Register wiretap plugins */
-
   if ((init_progfile_dir_error = init_progfile_dir(argv[0], main))) {
     g_warning("capinfos: init_progfile_dir(): %s", init_progfile_dir_error);
     g_free(init_progfile_dir_error);
   } else {
+    /* Register all the plugin types we have. */
+    wtap_register_plugin_types(); /* Types known to libwiretap */
+
     init_report_err(failure_message,NULL,NULL,NULL);
-    init_plugins();
+
+    /* Scan for plugins.  This does *not* call their registration routines;
+       that's done later. */
+    scan_plugins();
+
+    /* Register all libwiretap plugin modules. */
+    register_all_wiretap_modules();
   }
 #endif
 
index 73f9612864f10731f40f8f2bac210183946f8dd1..1ce407f1292566f4fe5011c0ef5fae6bd4d0fe3f 100644 (file)
@@ -1,10 +1,10 @@
 # Makefile.am
-# Automake file for the codecs for Wireshark
+# Automake file for the libcodec library for Wireshark
 #
 # $Id$
 #
 # Wireshark - Network traffic analyzer
-# By Gerald Combs <gerald@xxxxxxxxxxxxx>
+# By Gerald Combs <gerald@wireshark.org>
 # Copyright 1998 Gerald Combs
 #
 # This program is free software; you can redistribute it and/or
@@ -21,6 +21,9 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
+include Makefile.common
+include ../Makefile.am.inc
+
 if HAVE_WARNINGS_AS_ERRORS
 AM_CFLAGS = -Werror
 endif
@@ -28,31 +31,27 @@ endif
 noinst_LIBRARIES = libcodec.a
 
 CLEANFILES = \
-       libcodec.a      \
-       *~
+       libcodec.a      \
+       *~
 
 MAINTAINERCLEANFILES = \
-       Makefile.in
+       Makefile.in
 
+# All sources that should be put in the source distribution tarball
 libcodec_a_SOURCES = \
-       codecs.c codecs.h       \
-       G711a/G711adecode.c G711a/G711adecode.h G711a/G711atable.h      \
-       G711u/G711udecode.c G711u/G711udecode.h G711u/G711utable.h      \
-       G722/G722decode.c G722/G722decode.h                                                     \
-       G726/G726decode.c G726/G726decode.h                                                     \
-       sbc/sbc.c sbc/sbc.h
+       $(LIBCODEC_SRC) \
+       $(noinst_HEADERS)
 
 libcodec_a_DEPENDENCIES = 
 
-EXTRA_DIST = \
-       Makefile.nmake  \
-       CMakeLists.txt
+# Common headers
+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/wiretap
 
-checkapi: 
+checkapi:
        $(PERL) ../tools/checkAPIs.pl -g abort -g termoutput -build \
-       codecs.c \
-       G711a/G711adecode.c \
-       G711u/G711udecode.c \
-       G722/G722decode.c \
-       G726/G726decode.c \
-       sbc/sbc.c
+       $(LIBCODEC_SRC)
+
+EXTRA_DIST = \
+       CMakeLists.txt                  \
+       Makefile.common                 \
+       Makefile.nmake
diff --git a/codecs/Makefile.common b/codecs/Makefile.common
new file mode 100644 (file)
index 0000000..4200947
--- /dev/null
@@ -0,0 +1,41 @@
+# Makefile.common
+#     Contains the stuff from Makefile.am and Makefile.nmake that is
+#     a) common to both files and
+#     b) portable between both files
+#
+# $Id$
+#
+# Wireshark - Network traffic analyzer
+# By Gerald Combs <gerald@wireshark.org>
+# Copyright 1998 Gerald Combs
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+
+LIBCODEC_SRC = \
+       codecs.c \
+       G711a/G711adecode.c \
+       G711u/G711udecode.c \
+       G722/G722decode.c \
+       G726/G726decode.c \
+       sbc/sbc.c
+
+noinst_HEADERS = \
+       codecs.h \
+       G711a/G711adecode.h G711a/G711atable.h  \
+       G711u/G711udecode.h G711u/G711utable.h  \
+       G722/G722decode.h \
+       G726/G726decode.h \
+       sbc/sbc.h
+
index 821cd5c00ad048a6046c0c5a23a38023d7e98190..d2cbc4e35e5f9b840f17085295eb86c4cb863693 100644 (file)
@@ -4,6 +4,7 @@
 # $Id$
 
 include ..\config.nmake
+include ..\Makefile.nmake.inc
 
 ############### no need to modify below this line #########
 
@@ -11,9 +12,16 @@ CFLAGS=/I.. $(WARNINGS_ARE_ERRORS) $(STANDARD_CFLAGS) \
        $(GLIB_CFLAGS)
 
 .c.obj::
-       $(CC) $(CFLAGS)  -Fd.\ -c $<
+       $(CC) $(CFLAGS) -Fd.\ -c $<
 
-CODEC_OBJECTS= \
+include Makefile.common
+
+# if you add files here, be sure to include them also in Makefile.am EXTRA_DIST
+# XXX - if the codec files weren't in subdirectories, we could just do
+# LIBCODEC_OBJECTS = $(LIBCODEC_SRC:.c=.obj), and wouldn't need rules
+# for each of the codecs below
+#
+LIBCODEC_OBJECTS= \
     codecs.obj \
        G711udecode.obj \
        G711adecode.obj \
@@ -21,10 +29,8 @@ CODEC_OBJECTS= \
        G726decode.obj \
        sbc.obj
 
-
-codecs.lib     :  $(CODEC_OBJECTS)
-       link /lib /out:codecs.lib $(CODEC_OBJECTS)
-
+codecs.lib     :  $(LIBCODEC_OBJECTS)
+       link /lib /out:codecs.lib $(LIBCODEC_OBJECTS)
 
 codecs.obj: codecs.c codecs.h
        $(CC) $(CFLAGS) -Fd.\ -c codecs.c /Fo%|fF.obj
@@ -45,7 +51,7 @@ sbc.obj: sbc\sbc.c sbc\sbc.h
        $(CC) $(CFLAGS) -Fd.\ -c sbc\sbc.c /Fo%|fF.obj
 
 clean:
-       rm -f $(CODEC_OBJECTS) codecs.lib *.pdb *.sbr
+       rm -f $(LIBCODEC_OBJECTS) codecs.lib *.pdb *.sbr
 
 distclean: clean
 
@@ -53,9 +59,4 @@ maintainer-clean: distclean
 
 checkapi:
        $(PERL) ../tools/checkAPIs.pl -g abort -g termoutput -build \
-       codecs.c \
-       G711a/G711adecode.c \
-       G711u/G711udecode.c \
-       G722/G722decode.c \
-       G726/G726decode.c \
-       sbc/sbc.c
+       $(LIBCODEC_SRC)
index 0cb397f99bf763b33831d998ca3d6831e5c042dc..abe3eaa71435b6e4d5cb4df2502d3f79d0891216 100644 (file)
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
+#include "config.h"
+
 #include <glib.h>
 #include "codecs.h"
 
+#ifdef HAVE_PLUGINS
+
+#include <gmodule.h>
+
+#include <wsutil/plugins.h>
+
+/*
+ * List of codec plugins.
+ */
+typedef struct {
+       void (*register_codec_module)(void);  /* routine to call to register a codec */
+} codec_plugin;
+
+static GSList *codec_plugins = NULL;
+
+/*
+ * Callback for each plugin found.
+ */
+static gboolean
+check_for_codec_plugin(GModule *handle)
+{
+       gpointer gp;
+       void (*register_codec_module)(void);
+       codec_plugin *plugin;
+
+       /*
+        * Do we have a register_codec_module routine?
+        */
+       if (!g_module_symbol(handle, "register_codec_module", &gp)) {
+               /* No, so this isn't a codec plugin. */
+               return FALSE;
+       }
+
+       /*
+        * Yes - this plugin includes one or more codecs.
+        */
+       register_codec_module = (void (*)(void))gp;
+
+       /*
+        * Add this one to the list of codec plugins.
+        */
+       plugin = (codec_plugin *)g_malloc(sizeof (codec_plugin));
+       plugin->register_codec_module = register_codec_module;
+       codec_plugins = g_slist_append(codec_plugins, plugin);
+       return TRUE;
+}
+
+void
+codec_register_plugin_types(void)
+{
+       add_plugin_type("codec", check_for_codec_plugin);
+}
+
+static void
+register_codec_plugin(gpointer data, gpointer user_data _U_)
+{
+       codec_plugin *plugin = (codec_plugin *)data;
+
+       (plugin->register_codec_module)();
+}
+
+/*
+ * For all codec plugins, call their register routines.
+ */
+void
+register_all_codecs(void)
+{
+       g_slist_foreach(codec_plugins, register_codec_plugin, NULL);
+}
+#endif /* HAVE_PLUGINS */
+
 struct codec_handle {
        const char *name;
        codec_init_fn init_fn;
index 9231fe8455b54860040d600a96f264a3c53a764f..f293e26f2d177d6efae8238830a5c65576673e99 100644 (file)
 #ifndef _CODECS_H_
 #define _CODECS_H_
 
+#include "config.h"
+
+#include <epan/epan.h>
+#include "ws_symbol_export.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#ifdef HAVE_PLUGINS
+extern void codec_register_plugin_types(void);
+extern void register_all_codecs(void);
+#endif
+
 struct codec_handle;
 typedef struct codec_handle *codec_handle_t;
 
@@ -38,4 +52,8 @@ extern void *codec_init(codec_handle_t codec);
 extern void codec_release(codec_handle_t codec, void *context);
 extern int codec_decode(codec_handle_t codec, void *context, const void *input, int inputSizeBytes, void *output, int *outputSizeBytes);
 
-#endif
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _CODECS_H_ */
index 3192d3e9f84bbeb88ca43625efe74504bdf3ae1e..d4f4cdf2518795409e2908e9b433491971fdc842 100644 (file)
--- a/dftest.c
+++ b/dftest.c
 #include <errno.h>
 
 #include <glib.h>
-#include <epan/epan.h>
 
+#include <epan/epan.h>
 #include <epan/timestamp.h>
-#include <epan/plugins.h>
+#include <epan/prefs.h>
+#include <epan/dfilter/dfilter.h>
+
+#include <wsutil/plugins.h>
 #include <wsutil/filesystem.h>
 #include <wsutil/privileges.h>
-#include <epan/prefs.h>
+
 #include "ui/util.h"
-#include "epan/dfilter/dfilter.h"
 #include "register.h"
 
 static void failure_message(const char *msg_format, va_list ap);
index e28f8b2676a51e67951f5307988ea0ea731c3fff..7f9bdba555b3b2be3b4eeed75ee619d537ee1093 100644 (file)
--- a/editcap.c
+++ b/editcap.c
 #include <wsutil/report_err.h>
 #include <wsutil/strnatcmp.h>
 #include <wsutil/md5.h>
-
-/*
- * The symbols declared in the below are exported from libwireshark,
- * but we don't want to link whole libwireshark to editcap.
- * We link the object directly instead and this needs a little trick
- * with the WS_BUILD_DLL #define.
- */
-#define WS_BUILD_DLL
-#define RESET_SYMBOL_EXPORT /* wsutil/wsgetopt.h set export behavior above. */
-#include "epan/plugins.h"
-#undef WS_BUILD_DLL
-#define RESET_SYMBOL_EXPORT
+#include <wsutil/plugins.h>
 
 #include "svnversion.h"
 
@@ -910,8 +899,17 @@ main(int argc, char *argv[])
         g_warning("editcap: init_progfile_dir(): %s", init_progfile_dir_error);
         g_free(init_progfile_dir_error);
     } else {
+        /* Register all the plugin types we have. */
+        wtap_register_plugin_types(); /* Types known to libwiretap */
+
         init_report_err(failure_message,NULL,NULL,NULL);
-        init_plugins();
+
+        /* Scan for plugins.  This does *not* call their registration routines;
+           that's done later. */
+        scan_plugins();
+
+        /* Register all libwiretap plugin modules. */
+        register_all_wiretap_modules();
     }
 #endif
 
index dea24df3a28a743d31ca9142c423c16f5adceab3..21dd8d26059ae8fca32b926d04fd1a076392c7a7 100644 (file)
@@ -1503,7 +1503,6 @@ set(LIBWIRESHARK_FILES
        osi-utils.c
        packet-range.c
        packet.c
-       plugins.c
        print.c
        prefs.c
        proto.c
index b3462760eebf1dbc6139d845265e010f1a728db8..0cb1052e199d350a4a332af1dd6db1f85fff7dcc 100644 (file)
@@ -70,7 +70,6 @@ LIBWIRESHARK_SRC =            \
        osi-utils.c             \
        packet-range.c          \
        packet.c                \
-       plugins.c               \
        prefs.c                 \
        print.c                 \
        proto.c                 \
@@ -218,7 +217,6 @@ LIBWIRESHARK_INCLUDES =             \
        packet.h                \
        packet_info.h           \
        params.h                \
-       plugins.h               \
        ppptypes.h              \
        print.h                 \
        prefs.h                 \
index 6cb06f4c7bab1bf0351be1692abbf6c5afe149f3..80a4648e736c7e4085c4d10d9519b15b0d304c13 100644 (file)
@@ -74,6 +74,20 @@ epan_get_version(void) {
        return VERSION;
 }
 
+/*
+ * Register all the plugin types that are part of libwireshark, namely
+ * dissector and tap plugins.
+ *
+ * Must be called before init_plugins(), which must be called before
+ * any registration routines are called.
+ */
+void
+epan_register_plugin_types(void)
+{
+       register_dissector_plugin_type();
+       register_tap_plugin_type();
+}
+
 void
 epan_init(void (*register_all_protocols_func)(register_cb cb, gpointer client_data),
          void (*register_all_handoffs_func)(register_cb cb, gpointer client_data),
index 44f2d4c51b1f01a89fc755cb9043b3d5c26f8eb5..9347fb69f7cb32116543e7ef6c60468ef610f5c5 100644 (file)
@@ -81,6 +81,16 @@ Ref2 for further edits - delete when done
        - \ref airpcapdefs
        - \ref radiotap
 */
+/*
+ * Register all the plugin types that are part of libwireshark.
+ *
+ * Must be called before init_plugins(), which must be called before
+ * any registration routines are called, i.e. before epan_init().
+ *
+ * Must be called only once in a program.
+ */
+WS_DLL_PUBLIC void epan_register_plugin_types(void);
+
 /** init the whole epan module, this is used to be called only once in a program */
 WS_DLL_PUBLIC
 void epan_init(void (*register_all_protocols_func)(register_cb cb, gpointer client_data),
index 0ad68a5547efb3588d9596441f4180bf2e014e73..9befce39d1790f7e7e1f2705fa6a9618d98e3cdd 100644 (file)
@@ -47,7 +47,6 @@
 
 #include "addr_resolv.h"
 #include "tvbuff.h"
-#include "plugins.h"
 #include "epan_dissect.h"
 
 #include "emem.h"
diff --git a/epan/plugins.c b/epan/plugins.c
deleted file mode 100644 (file)
index 1104267..0000000
+++ /dev/null
@@ -1,575 +0,0 @@
-/* plugins.c
- * plugin routines
- *
- * $Id$
- *
- * Wireshark - Network traffic analyzer
- * By Gerald Combs <gerald@wireshark.org>
- * Copyright 1998 Gerald Combs
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include "config.h"
-
-#include "plugins.h"
-#include <stdio.h>
-
-/* linked list of Lua plugins */
-wslua_plugin *wslua_plugin_list = NULL;
-
-#ifdef HAVE_PLUGINS
-
-#include <time.h>
-
-#ifdef HAVE_DIRENT_H
-#include <dirent.h>
-#endif
-
-#ifdef HAVE_DIRECT_H
-#include <direct.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include "wsutil/filesystem.h"
-#include <wsutil/privileges.h>
-#include <wsutil/file_util.h>
-#include <wsutil/report_err.h>
-
-/* linked list of all plugins */
-plugin *plugin_list = NULL;
-
-static void register_all_wiretap_modules(void);
-static void register_all_codecs(void);
-
-/*
- * add a new plugin to the list
- * returns :
- * - 0 : OK
- * - ENOMEM : memory allocation problem
- * - EEXIST : the same plugin (i.e. name/version) was already registered.
- */
-static int
-add_plugin(void *handle, gchar *name, gchar *version,
-           void (*register_protoinfo)(void),
-           void (*reg_handoff)(void),
-           void (*register_tap_listener)(void),
-           void (*register_wtap_module)(void),
-           void (*register_codec_module)(void))
-{
-    plugin *new_plug, *pt_plug;
-
-    pt_plug = plugin_list;
-    if (!pt_plug) /* the list is empty */
-    {
-        new_plug = (plugin *)g_malloc(sizeof(plugin));
-        if (new_plug == NULL)
-            return ENOMEM;
-        plugin_list = new_plug;
-    }
-    else
-    {
-        while (1)
-        {
-            /* check if the same name/version is already registered */
-            if (!strcmp(pt_plug->name, name) &&
-                !strcmp(pt_plug->version, version))
-            {
-                return EEXIST;
-            }
-
-            /* we found the last plugin in the list */
-            if (pt_plug->next == NULL)
-                break;
-
-            pt_plug = pt_plug->next;
-        }
-        new_plug = (plugin *)g_malloc(sizeof(plugin));
-        if (new_plug == NULL)
-            return ENOMEM;
-        pt_plug->next = new_plug;
-    }
-
-    new_plug->handle = (GModule *)handle;
-    new_plug->name = name;
-    new_plug->version = version;
-    new_plug->register_protoinfo = register_protoinfo;
-    new_plug->reg_handoff = reg_handoff;
-    new_plug->register_tap_listener = register_tap_listener;
-    new_plug->register_wtap_module = register_wtap_module;
-    new_plug->register_codec_module = register_codec_module;
-    new_plug->next = NULL;
-
-    return 0;
-}
-
-/*
- * XXX - when we remove support for old-style plugins (which we should
- * probably do eventually, as all plugins should be written as new-style
- * ones), we may want to have "init_plugins()" merely save a pointer
- * to the plugin's "init" routine, just as we save a pointer to its
- * "reg_handoff" routine, and have a "register_all_plugins()" routine
- * to go through the list of plugins and call all of them.
- *
- * Then we'd have "epan_init()", or perhaps even something higher up
- * in the call tree, call "init_plugins()", and have "proto_init()"
- * call "register_all_plugins()" right after calling "register_all_protocols()";
- * this might be a bit cleaner.
- */
-static void
-plugins_scan_dir(const char *dirname)
-{
-#define FILENAME_LEN        1024
-    WS_DIR        *dir;             /* scanned directory */
-    WS_DIRENT     *file;            /* current file */
-    const char    *name;
-    gchar          filename[FILENAME_LEN];   /* current file name */
-    GModule       *handle;          /* handle returned by g_module_open */
-    gchar         *version;
-    gpointer       gp;
-    void         (*register_protoinfo)(void);
-    void         (*reg_handoff)(void);
-    void         (*register_tap_listener)(void);
-    void         (*register_wtap_module)(void);
-    void         (*register_codec_module)(void);
-
-    gchar         *dot;
-    int            cr;
-
-    if ((dir = ws_dir_open(dirname, 0, NULL)) != NULL)
-    {
-        while ((file = ws_dir_read_name(dir)) != NULL)
-        {
-            name = ws_dir_get_name(file);
-
-            /*
-             * GLib 2.x defines G_MODULE_SUFFIX as the extension used on
-             * this platform for loadable modules.
-             */
-            /* skip anything but files with G_MODULE_SUFFIX */
-            dot = strrchr(name, '.');
-            if (dot == NULL || strcmp(dot+1, G_MODULE_SUFFIX) != 0)
-                continue;
-
-            g_snprintf(filename, FILENAME_LEN, "%s" G_DIR_SEPARATOR_S "%s",
-                       dirname, name);
-            if ((handle = g_module_open(filename, (GModuleFlags)0)) == NULL)
-            {
-                report_failure("Couldn't load module %s: %s", filename,
-                               g_module_error());
-                continue;
-            }
-
-            if (!g_module_symbol(handle, "version", &gp))
-            {
-                report_failure("The plugin %s has no version symbol", name);
-                g_module_close(handle);
-                continue;
-            }
-            version = (char *)gp;
-
-            /*
-             * Do we have a register routine?
-             */
-            if (g_module_symbol(handle, "plugin_register", &gp))
-            {
-                /*
-                 * Yes - this plugin includes one or more dissectors.
-                 */
-                register_protoinfo = (void (*)(void))gp;
-            }
-            else
-            {
-                /*
-                 * No - no dissectors.
-                 */
-                register_protoinfo = NULL;
-            }
-
-            /*
-             * Do we have a reg_handoff routine?
-             */
-            if (g_module_symbol(handle, "plugin_reg_handoff", &gp))
-            {
-                /*
-                 * Yes.
-                 */
-                reg_handoff = (void (*)(void))gp;
-            }
-            else
-            {
-                /*
-                 * No - that's OK even if we have dissectors, as long
-                 * as the plugin registers by name *and* there's
-                 * a caller looking for that name.
-                 */
-                reg_handoff = NULL;
-            }
-
-            /*
-             * Do we have a register_tap_listener routine?
-             */
-            if (g_module_symbol(handle, "plugin_register_tap_listener", &gp))
-            {
-                /*
-                 * Yes - this plugin includes one or more taps.
-                 */
-                register_tap_listener = (void (*)(void))gp;
-            }
-            else
-            {
-                /*
-                 * No - no taps here.
-                 */
-                register_tap_listener = NULL;
-            }
-
-            /*
-             * Do we have an old-style init routine?
-             */
-            if (g_module_symbol(handle, "plugin_init", &gp))
-            {
-                /*
-                 * Yes - do we also have a register routine or a
-                 * register_tap_listener routine?  If so, this is a bogus
-                 * hybrid of an old-style and new-style plugin.
-                 */
-                if (register_protoinfo != NULL || register_tap_listener != NULL)
-                {
-                    report_failure("The plugin '%s' has an old plugin init routine\nand a new register or register_tap_listener routine.",
-                                   name);
-                    g_module_close(handle);
-                    continue;
-                }
-
-                /*
-                 * It's just an unsupported old-style plugin;
-                 */
-                report_failure("The plugin '%s' has an old plugin init routine. Support has been dropped.\n Information on how to update your plugin is available at \nhttp://anonsvn.wireshark.org/wireshark/trunk/doc/README.plugins",
-                               name);
-                g_module_close(handle);
-                continue;
-            }
-
-            /*
-             * Do we have a register_wtap_module routine?
-             */
-            if (g_module_symbol(handle, "register_wtap_module", &gp))
-            {
-                register_wtap_module = (void (*)(void))gp;
-            }
-            else
-            {
-                register_wtap_module = NULL;
-            }
-
-            /*
-             * Do we have a register_codec_module routine?
-             */
-            if (g_module_symbol(handle, "register_codec_module", &gp))
-            {
-                register_codec_module = (void (*)(void))gp;
-            }
-            else
-            {
-                register_codec_module = NULL;
-            }
-
-            /*
-             * Does this dissector do anything useful?
-             */
-            if (register_protoinfo == NULL &&
-                register_tap_listener == NULL &&
-                register_wtap_module == NULL &&
-                register_codec_module == NULL )
-            {
-                /*
-                 * No.
-                 */
-                report_failure("The plugin '%s' has neither a register routine, "
-                               "a register_tap_listener or a register_wtap_module or a register_codec_module routine",
-                               name);
-                g_module_close(handle);
-                continue;
-            }
-
-            /*
-             * OK, attempt to add it to the list of plugins.
-             */
-            if ((cr = add_plugin(handle, g_strdup(name), version,
-                                 register_protoinfo, reg_handoff,
-                                 register_tap_listener,register_wtap_module,register_codec_module)))
-            {
-                if (cr == EEXIST)
-                    fprintf(stderr, "The plugin %s, version %s\n"
-                            "was found in multiple directories\n", name, version);
-                else
-                    fprintf(stderr, "Memory allocation problem\n"
-                            "when processing plugin %s, version %s\n",
-                            name, version);
-                g_module_close(handle);
-                continue;
-            }
-
-        }
-        ws_dir_close(dir);
-    }
-}
-
-
-/*
- * init plugins
- */
-void
-init_plugins(void)
-{
-    const char *plugin_dir;
-    const char *name;
-    char *plugin_dir_path;
-    char *plugins_pers_dir;
-    WS_DIR *dir;                /* scanned directory */
-    WS_DIRENT *file;                /* current file */
-
-    if (plugin_list == NULL)      /* ensure init_plugins is only run once */
-    {
-        /*
-         * Scan the global plugin directory.
-         * If we're running from a build directory, scan the subdirectories
-         * of that directory, as the global plugin directory is the
-         * "plugins" directory of the source tree, and the subdirectories
-         * are the source directories for the plugins, with the plugins
-         * built in those subdirectories.
-         */
-        plugin_dir = get_plugin_dir();
-        if (running_in_build_directory())
-        {
-            if ((dir = ws_dir_open(plugin_dir, 0, NULL)) != NULL)
-            {
-                while ((file = ws_dir_read_name(dir)) != NULL)
-                {
-                    name = ws_dir_get_name(file);
-                    if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
-                        continue;        /* skip "." and ".." */
-                    /*
-                     * Get the full path of a ".libs" subdirectory of that
-                     * directory.
-                     */
-                    plugin_dir_path = g_strdup_printf(
-                        "%s" G_DIR_SEPARATOR_S "%s" G_DIR_SEPARATOR_S ".libs",
-                        plugin_dir, name);
-                    if (test_for_directory(plugin_dir_path) != EISDIR) {
-                        /*
-                         * Either it doesn't refer to a directory or it
-                         * refers to something that doesn't exist.
-                         *
-                         * Assume that means that the plugins are in
-                         * the subdirectory of the plugin directory, not
-                         * a ".libs" subdirectory of that subdirectory.
-                         */
-                        g_free(plugin_dir_path);
-                        plugin_dir_path = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
-                            plugin_dir, name);
-                    }
-                    plugins_scan_dir(plugin_dir_path);
-                    g_free(plugin_dir_path);
-                }
-                ws_dir_close(dir);
-            }
-        }
-        else
-            plugins_scan_dir(plugin_dir);
-
-        /*
-         * If the program wasn't started with special privileges,
-         * scan the users plugin directory.  (Even if we relinquish
-         * them, plugins aren't safe unless we've *permanently*
-         * relinquished them, and we can't do that in Wireshark as,
-         * if we need privileges to start capturing, we'd need to
-         * reclaim them before each time we start capturing.)
-         */
-        if (!started_with_special_privs())
-        {
-            plugins_pers_dir = get_plugins_pers_dir();
-            plugins_scan_dir(plugins_pers_dir);
-            g_free(plugins_pers_dir);
-        }
-    }
-
-    register_all_wiretap_modules();
-    register_all_codecs();
-}
-
-void
-register_all_plugin_registrations(void)
-{
-    plugin *pt_plug;
-
-    /*
-     * For all plugins with register-handoff routines, call the routines.
-     * This is called from "proto_init()"; it must be called after
-     * "register_all_protocols()" and "init_plugins()" are called,
-     * in case one plugin registers itself either with a built-in
-     * dissector or with another plugin; we must first register all
-     * dissectors, whether built-in or plugin, so their dissector tables
-     * are initialized, and only then register all handoffs.
-     */
-    for (pt_plug = plugin_list; pt_plug != NULL; pt_plug = pt_plug->next)
-    {
-        if (pt_plug->register_protoinfo)
-            (pt_plug->register_protoinfo)();
-    }
-}
-
-void
-register_all_plugin_handoffs(void)
-{
-    plugin *pt_plug;
-
-    /*
-     * For all plugins with register-handoff routines, call the routines.
-     * This is called from "proto_init()"; it must be called after
-     * "register_all_protocols()" and "init_plugins()" are called,
-     * in case one plugin registers itself either with a built-in
-     * dissector or with another plugin; we must first register all
-     * dissectors, whether built-in or plugin, so their dissector tables
-     * are initialized, and only then register all handoffs.
-     */
-    for (pt_plug = plugin_list; pt_plug != NULL; pt_plug = pt_plug->next)
-    {
-        if (pt_plug->reg_handoff)
-            (pt_plug->reg_handoff)();
-    }
-}
-
-void
-register_all_plugin_tap_listeners(void)
-{
-    plugin *pt_plug;
-
-    /*
-     * For all plugins with register-tap-listener routines, call the
-     * routines.
-     */
-    for (pt_plug = plugin_list; pt_plug != NULL; pt_plug = pt_plug->next)
-    {
-        if (pt_plug->register_tap_listener)
-            (pt_plug->register_tap_listener)();
-    }
-}
-
-static void
-register_all_wiretap_modules(void)
-{
-    plugin *pt_plug;
-
-    /*
-     * For all plugins with register_wtap_module routines, call the
-     * routines.
-     */
-    for (pt_plug = plugin_list; pt_plug != NULL; pt_plug = pt_plug->next)
-    {
-        if (pt_plug->register_wtap_module)
-            (pt_plug->register_wtap_module)();
-    }
-}
-
-static void
-register_all_codecs(void)
-{
-    plugin *pt_plug;
-
-    /*
-     * For all plugins with register_wtap_module routines, call the
-     * routines.
-     */
-    for (pt_plug = plugin_list; pt_plug != NULL; pt_plug = pt_plug->next)
-    {
-        if (pt_plug->register_codec_module)
-              (pt_plug->register_codec_module)();
-    }
-}
-
-#endif /* big HAVE_PLUGINS */
-
-/*
- * Dump plugin info to stdout. Copied from ui/gtk/plugins_dlg.c:plugins_scan.
- */
-void
-plugins_dump_all(void)
-{
-#ifdef HAVE_PLUGINS
-    plugin     *pt_plug;
-    const char *sep;
-#endif
-#ifdef HAVE_LUA
-    wslua_plugin  *lua_plug;
-#endif
-
-#ifdef HAVE_PLUGINS
-    for (pt_plug = plugin_list; pt_plug != NULL; pt_plug = pt_plug->next)
-    {
-        sep = "";
-
-        printf("%s\t%s\t", pt_plug->name, pt_plug->version);
-        if (pt_plug->register_protoinfo)
-        {
-            printf("dissector");
-            sep = ", ";
-        }
-        if (pt_plug->register_tap_listener)
-        {
-            printf("%stap", sep);
-            sep = ", ";
-        }
-        if (pt_plug->register_wtap_module)
-        {
-            printf("%sfile format", sep);
-            sep = ", ";
-        }
-        if (pt_plug->register_codec_module)
-        {
-            printf("%scodec", sep);
-        }
-        printf("\t%s\n", g_module_name(pt_plug->handle));
-    }
-#endif
-
-#ifdef HAVE_LUA
-    for (lua_plug = wslua_plugin_list; lua_plug != NULL; lua_plug = lua_plug->next)
-    {
-        printf("%s\t%s\tlua script\t%s\n", lua_plug->name, lua_plug->version, lua_plug->filename);
-    }
-#endif
-}
-
-/*
- * Editor modelines
- *
- * Local Variables:
- * c-basic-offset: 4
- * tab-width: 8
- * indent-tabs-mode: nil
- * End:
- *
- * ex: set shiftwidth=4 tabstop=8 expandtab:
- * :indentSize=4:tabSize=8:noTabs=true:
- */
index f5c1f4205e12310a968d2a00b57fd24f6dea3b4c..f3df3254a622ec9fb7b3b6ff838097ea3fa0c572 100644 (file)
@@ -41,7 +41,6 @@
 #include "strutil.h"
 #include "addr_resolv.h"
 #include "oids.h"
-#include "plugins.h"
 #include "proto.h"
 #include "epan_dissect.h"
 #include "tvbuff.h"
@@ -57,6 +56,8 @@
 
 #include "wspython/wspy_register.h"
 
+#include <wsutil/plugins.h>
+
 #define SUBTREE_ONCE_ALLOCATION_NUMBER 8
 #define SUBTREE_MAX_LEVELS 256
 /* Throw an exception if we exceed this many tree items. */
@@ -324,6 +325,87 @@ proto_compare_name(gconstpointer p1_arg, gconstpointer p2_arg)
        return g_ascii_strcasecmp(p1->short_name, p2->short_name);
 }
 
+#ifdef HAVE_PLUGINS
+/*
+ * List of dissector plugins.
+ */
+typedef struct {
+       void (*register_protoinfo)(void);       /* routine to call to register protocol information */
+       void (*reg_handoff)(void);              /* routine to call to register dissector handoff */
+} dissector_plugin;
+
+static GSList *dissector_plugins = NULL;
+
+/*
+ * Callback for each plugin found.
+ */
+static gboolean
+check_for_dissector_plugin(GModule *handle)
+{
+       gpointer gp;
+       void (*register_protoinfo)(void);
+       void (*reg_handoff)(void);
+       dissector_plugin *plugin;
+
+       /*
+        * Do we have a register routine?
+        */
+       if (g_module_symbol(handle, "plugin_register", &gp))
+               register_protoinfo = (void (*)(void))gp;
+       else
+                register_protoinfo = NULL;
+
+       /*
+        * Do we have a reg_handoff routine?
+        */
+       if (g_module_symbol(handle, "plugin_reg_handoff", &gp))
+               reg_handoff = (void (*)(void))gp;
+       else
+               reg_handoff = NULL;
+
+       /*
+        * If we have neither, we're not a dissector plugin.
+        */
+       if (register_protoinfo == NULL && reg_handoff == NULL)
+               return FALSE;
+
+       /*
+        * Add this one to the list of dissector plugins.
+        */
+       plugin = (dissector_plugin *)g_malloc(sizeof (dissector_plugin));
+       plugin->register_protoinfo = register_protoinfo;
+       plugin->reg_handoff = reg_handoff;
+       dissector_plugins = g_slist_append(dissector_plugins, plugin);
+       return TRUE;
+}
+
+static void
+register_dissector_plugin(gpointer data, gpointer user_data _U_)
+{
+       dissector_plugin *plugin = (dissector_plugin *)data;
+
+       if (plugin->register_protoinfo)
+               (plugin->register_protoinfo)();
+}
+
+static void
+reg_handoff_dissector_plugin(gpointer data, gpointer user_data _U_)
+{
+       dissector_plugin *plugin = (dissector_plugin *)data;
+
+       if (plugin->reg_handoff)
+               (plugin->reg_handoff)();
+}
+
+/*
+ * Register dissector plugin type.
+ */
+void
+register_dissector_plugin_type(void)
+{
+       add_plugin_type("dissector", check_for_dissector_plugin);
+}
+#endif /* HAVE_PLUGINS */
 
 /* initialize data structures and register protocols and fields */
 void
@@ -368,12 +450,11 @@ proto_init(void (register_all_protocols_func)(register_cb cb, gpointer client_da
 #endif
 
 #ifdef HAVE_PLUGINS
-       /* Now scan for plugins and load all the ones we find, calling
-          their register routines to do the stuff described above. */
+       /* Now call the registration routines for all disssector
+          plugins. */
        if (cb)
                (*cb)(RA_PLUGIN_REGISTER, NULL, client_data);
-       init_plugins();
-       register_all_plugin_registrations();
+       g_slist_foreach(dissector_plugins, register_dissector_plugin, NULL);
 #endif
 
        /* Now call the "handoff registration" routines of all built-in
@@ -393,7 +474,7 @@ proto_init(void (register_all_protocols_func)(register_cb cb, gpointer client_da
        /* Now do the same with plugins. */
        if (cb)
                (*cb)(RA_PLUGIN_HANDOFF, NULL, client_data);
-       register_all_plugin_handoffs();
+       g_slist_foreach(dissector_plugins, reg_handoff_dissector_plugin, NULL);
 #endif
 
        /* sort the protocols by protocol name */
index ad12588f6f04efba9da2f64382fd785f0ee2d440..0578325d173de1c40216d799dfb3e02c92e2cd15 100644 (file)
@@ -603,6 +603,10 @@ WS_DLL_PUBLIC void proto_tree_children_foreach(proto_tree *tree,
 /** Retrieve the wmem_allocator_t from a proto_node */
 #define PNODE_POOL(proto_node)   ((proto_node)->tree_data->pinfo->pool)
 
+/** Register dissector plugin type with the plugin system.
+    Called by epan_register_plugin_types(); do not call it yourself. */
+extern void register_dissector_plugin_type(void);
+
 /** Sets up memory used by proto routines. Called at program startup */
 void proto_init(void (register_all_protocols_func)(register_cb cb, gpointer client_data),
                       void (register_all_handoffs_func)(register_cb cb, gpointer client_data),
index 7ac5e54bc620f1618e5601eaa687055014d8545a..f4036afdb68f47adf11cf957ca9a8614dbad889b 100644 (file)
@@ -77,6 +77,77 @@ typedef struct _tap_listener_t {
 } tap_listener_t;
 static volatile tap_listener_t *tap_listener_queue=NULL;
 
+#ifdef HAVE_PLUGINS
+
+#include <gmodule.h>
+
+#include <wsutil/plugins.h>
+
+/*
+ * List of tap plugins.
+ */
+typedef struct {
+       void (*register_tap_listener_fn)(void);   /* routine to call to register tap listener */
+} tap_plugin;
+
+static GSList *tap_plugins = NULL;
+
+/*
+ * Callback for each plugin found.
+ */
+static gboolean
+check_for_tap_plugin(GModule *handle)
+{
+       gpointer gp;
+       void (*register_tap_listener_fn)(void);
+       tap_plugin *plugin;
+
+       /*
+        * Do we have a register_tap_listener routine?
+        */
+       if (!g_module_symbol(handle, "plugin_register_tap_listener", &gp)) {
+               /* No, so this isn't a tap plugin. */
+               return FALSE;
+       }
+
+       /*
+        * Yes - this plugin includes one or more taps.
+        */
+       register_tap_listener_fn = (void (*)(void))gp;
+
+       /*
+        * Add this one to the list of tap plugins.
+        */
+       plugin = (tap_plugin *)g_malloc(sizeof (tap_plugin));
+       plugin->register_tap_listener_fn = register_tap_listener_fn;
+       tap_plugins = g_slist_append(tap_plugins, plugin);
+       return TRUE;
+}
+
+void
+register_tap_plugin_type(void)
+{
+       add_plugin_type("tap", check_for_tap_plugin);
+}
+
+static void
+register_tap_plugin_listener(gpointer data, gpointer user_data _U_)
+{
+       tap_plugin *plugin = (tap_plugin *)data;
+
+       (plugin->register_tap_listener_fn)();
+}
+
+/*
+ * For all tap plugins, call their register routines.
+ */
+void
+register_all_plugin_tap_listeners(void)
+{
+       g_slist_foreach(tap_plugins, register_tap_plugin_listener, NULL);
+}
+#endif /* HAVE_PLUGINS */
+
 /* **********************************************************************
  * Init routine only called from epan at application startup
  * ********************************************************************** */
@@ -87,8 +158,6 @@ void
 tap_init(void)
 {
        tap_packet_index=0;
-
-       return;
 }
 
 /* **********************************************************************
index b95b98df9470035d43cf7dff5f842c1698f41ff8..692cd39c22249eb982533e5fcafd767e2080dae3 100644 (file)
@@ -46,6 +46,20 @@ typedef void (*tap_draw_cb)(void *tapdata);
 #define TL_IS_DISSECTOR_HELPER 0x00000004      /**< tap helps a dissector do work
                                                 ** but does not, itself, require dissection */
 
+/** Register tap plugin type with the plugin system.
+    Called by epan_register_plugin_types(); do not call it yourself. */
+extern void register_tap_plugin_type(void);
+
+/*
+ * For all tap plugins, call their register routines.
+ * Must be called after init_plugins(), and must be called only once in
+ * a program.
+ *
+ * XXX - should probably be handled by epan_init(), as the tap mechanism
+ * is part of libwireshark.
+ */
+WS_DLL_PUBLIC void register_all_plugin_tap_listeners(void);
+
 extern void tap_init(void);
 
 /** This function registers that a dissector has the packet tap ability
index afee46d91cccd4dd871224c659cb55eb70e64deb..0f353e48e2fccb58a72cf1c9cd6789814fbd1c7c 100644 (file)
 #include <math.h>
 #include <epan/expert.h>
 #include <epan/ex-opt.h>
-#include <epan/plugins.h>
 #include <wsutil/privileges.h>
 #include <wsutil/file_util.h>
 
+/* linked list of Lua plugins */
+typedef struct _wslua_plugin {
+    gchar       *name;            /**< plugin name */
+    gchar       *version;         /**< plugin version */
+    gchar       *filename;        /**< plugin filename */
+    struct _wslua_plugin *next;
+} wslua_plugin;
+
+static wslua_plugin *wslua_plugin_list = NULL;
+
 static lua_State* L = NULL;
 
 packet_info* lua_pinfo;
@@ -360,6 +369,30 @@ int wslua_count_plugins(void) {
     return plugins_counter;
 }
 
+void wslua_plugins_get_descriptions(wslua_plugin_description_callback callback, void *user_data) {
+    wslua_plugin  *lua_plug;
+
+    for (lua_plug = wslua_plugin_list; lua_plug != NULL; lua_plug = lua_plug->next)
+    {
+        callback(lua_plug->name, lua_plug->version, "lua script",
+                 lua_plug->filename, user_data);
+    }
+}
+
+static void
+print_wslua_plugin_description(const char *name, const char *version,
+                               const char *description, const char *filename,
+                               void *user_data _U_)
+{
+    printf("%s\t%s\t%s\t%s\n", name, version, description, filename);
+}
+
+void
+wslua_plugins_dump_all(void)
+{
+    wslua_plugins_get_descriptions(print_wslua_plugin_description, NULL);
+}
+
 int wslua_init(register_cb cb, gpointer client_data) {
     gchar* filename;
     const funnel_ops_t* ops = funnel_get_funnel_ops();
index 9072e6b9b16bb89d92ee6aa041f5df5aed52deda..72d083eb96c30a185f5c7d8aea50c96303818f65 100644 (file)
 #ifndef __INIT_WSLUA_H__
 #define __INIT_WSLUA_H__
 
+#include "ws_symbol_export.h"
+
 WS_DLL_PUBLIC int wslua_count_plugins(void);
 
+typedef void (*wslua_plugin_description_callback)(const char *, const char *,
+                                                  const char *, const char *,
+                                                  void *);
+WS_DLL_PUBLIC void wslua_plugins_get_descriptions(wslua_plugin_description_callback callback, void *user_data);
+WS_DLL_PUBLIC void wslua_plugins_dump_all(void);
+
 #endif /* __INIT_WSLUA_H__ */
index b86de656b3c9b1f6a49471f7437fc488b863240d..7dd8b793d3ca013cd343e410c6997e802e0a553f 100644 (file)
@@ -70,6 +70,7 @@
 #include <wsutil/privileges.h>
 #include <wsutil/file_util.h>
 #include <wsutil/filesystem.h>
+#include <wsutil/plugins.h>
 
 #include "globals.h"
 #include <epan/packet.h>
@@ -85,7 +86,6 @@
 #include "clopts_common.h"
 #include "cmdarg_err.h"
 #include "version_info.h"
-#include <epan/plugins.h>
 #include "register.h"
 #include "conditions.h"
 #include "capture_stop_conditions.h"
index c8d9c5bd9e0b792d42482e7d6f7440ad1c5ff911..73d0ed83097be791e4c178f3218aa8cb94cbfcdf 100644 (file)
--- a/tshark.c
+++ b/tshark.c
@@ -70,6 +70,7 @@
 #include "globals.h"
 #include <epan/timestamp.h>
 #include <epan/packet.h>
+#include <epan/wslua/init_wslua.h>
 #include "file.h"
 #include "frame_tvbuff.h"
 #include <epan/disabled_protos.h>
@@ -81,7 +82,6 @@
 #include "clopts_common.h"
 #include "cmdarg_err.h"
 #include "version_info.h"
-#include <epan/plugins.h>
 #include "register.h"
 #include <epan/epan_dissect.h>
 #include <epan/tap.h>
 #include "log.h"
 #include <epan/funnel.h>
 
+#ifdef HAVE_PLUGINS
+#include <wsutil/plugins.h>
+#endif
+
 /*
  * This is the template for the decode as option; it is shared between the
  * various functions that output the usage for this parameter.
@@ -1097,6 +1101,19 @@ main(int argc, char *argv[])
   timestamp_set_precision(TS_PREC_AUTO);
   timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
 
+#ifdef HAVE_PLUGINS
+  /* Register all the plugin types we have. */
+  epan_register_plugin_types(); /* Types known to libwireshark */
+  wtap_register_plugin_types(); /* Types known to libwiretap */
+
+  /* Scan for plugins.  This does *not* call their registration routines;
+     that's done later. */
+  scan_plugins();
+
+  /* Register all libwiretap plugin modules. */
+  register_all_wiretap_modules();
+#endif
+
   /* Register all dissectors; we must do this before checking for the
      "-G" flag, as the "-G" flag dumps information registered by the
      dissectors, and we must do it before we read the preferences, in
@@ -1147,8 +1164,12 @@ main(int argc, char *argv[])
         proto_registrar_dump_ftypes();
       else if (strcmp(argv[2], "heuristic-decodes") == 0)
         dissector_dump_heur_decodes();
-      else if (strcmp(argv[2], "plugins") == 0)
+#ifdef HAVE_PLUGINS
+      else if (strcmp(argv[2], "plugins") == 0) {
         plugins_dump_all();
+        wslua_plugins_dump_all();
+      }
+#endif
       else if (strcmp(argv[2], "protocols") == 0)
         proto_registrar_dump_protocols();
       else if (strcmp(argv[2], "values") == 0)
index 8d22e556652b145a0e5f41eaef2d59b261b4f5fd..c4e38346f63402bf37f71b6f51de6b7becd426a7 100644 (file)
 
 #include "config.h"
 
-#include <gtk/gtk.h>
-
 #include <string.h>
 
+#include <gtk/gtk.h>
+
 #include <wsutil/filesystem.h>
-#include <epan/plugins.h>
+#include <wsutil/plugins.h>
 #ifdef HAVE_LIBSMI
 #include <epan/oids.h>
 #endif
@@ -43,6 +43,7 @@
 
 #include "../log.h"
 #include "../version_info.h"
+#include "../register.h"
 
 #include "ui/last_open_dir.h"
 
index 72739e55b306d46d8e2feb202c6a5f888b257fd6..6affd20ea102785cb1dd25f45db4c2e057177346 100644 (file)
@@ -76,7 +76,6 @@
 #include <epan/disabled_protos.h>
 #include <epan/epan.h>
 #include <epan/epan_dissect.h>
-#include <epan/plugins.h>
 #include <epan/dfilter/dfilter.h>
 #include <epan/strutil.h>
 #include <epan/emem.h>
@@ -92,6 +91,8 @@
 #include <epan/print.h>
 #include <epan/timestamp.h>
 
+#include <wsutil/plugins.h>
+
 /* general (not GTK specific) */
 #include "../file.h"
 #include "../frame_tvbuff.h"
 #include "ui/iface_lists.h"
 #endif
 
+#include "codecs/codecs.h"
+
 #ifdef HAVE_LIBPCAP
 #include "capture_ui_utils.h"
 #include "capture-pcap-util.h"
@@ -2518,6 +2521,23 @@ main(int argc, char *argv[])
     g_free(init_progfile_dir_error);
   }
 
+#ifdef HAVE_PLUGINS
+  /* Register all the plugin types we have. */
+  epan_register_plugin_types(); /* Types known to libwireshark */
+  wtap_register_plugin_types(); /* Types known to libwiretap */
+  codec_register_plugin_types(); /* Types known to libcodec */
+
+  /* Scan for plugins.  This does *not* call their registration routines;
+     that's done later. */
+  scan_plugins();
+
+  /* Register all libwiretap plugin modules. */
+  register_all_wiretap_modules();
+
+  /* Register all audio codec plugins. */
+  register_all_codecs();
+#endif
+
   splash_update(RA_DISSECTORS, NULL, (gpointer)splash_win);
 
   /* Register all dissectors; we must do this before checking for the
index 03e617623b46098c07c6b39db175f14abc3c8ba7..ed677ba858fa5525088089bca521216bb58b2b84 100644 (file)
@@ -39,7 +39,6 @@
 #include <epan/etypes.h>
 #include <epan/dissector_filters.h>
 #include <epan/strutil.h>
-#include <epan/plugins.h>
 #include <epan/epan_dissect.h>
 #include <epan/column.h>
 #include <epan/stats_tree_priv.h>
index adc2c6c0a2812910e0bd0403f97aa4d0477fb9cd..8b7de8906edf43794f25c9d136e8c1fffc7aee41 100644 (file)
@@ -47,7 +47,6 @@
 #include <epan/prefs.h>
 #include <epan/column.h>
 #include <epan/addr_resolv.h>
-#include <epan/plugins.h>
 #include <epan/epan_dissect.h>
 #include <epan/strutil.h>
 #include <epan/tvbuff-int.h>
index 36589691632b11427037b0dc85c44d44ff41c94a..7cea52b5a73b81b91cb4afb6d27631e036c95d99 100644 (file)
@@ -26,7 +26,9 @@
 
 #include <gtk/gtk.h>
 
-#include "epan/plugins.h"
+#include <epan/wslua/init_wslua.h>
+
+#include <wsutil/plugins.h>
 
 #include "ui/gtk/dlg_utils.h"
 #include "ui/gtk/gui_utils.h"
@@ -72,59 +74,24 @@ about_plugins_callback(GtkWidget *widget, GdkEventButton *event, gint id _U_)
  * XXX - We might want to combine this with plugins_dump_all().
  */
 static void
-plugins_scan(GtkWidget *list)
+plugins_add_description(const char *name, const char *version,
+                        const char *types, const char *filename,
+                        void *user_data)
 {
-#ifdef HAVE_PLUGINS
-    plugin     *pt_plug;
-    const char *sep;
-#endif
-#ifdef HAVE_LUA
-    wslua_plugin  *lua_plug;
-#endif
-    GString    *type;
+    GtkWidget *list = (GtkWidget *)user_data;
 
+    simple_list_append(list, 0, name, 1, version,
+                       2, types, 3, filename, -1);
+}
+static void
+plugins_scan(GtkWidget *list)
+{
 #ifdef HAVE_PLUGINS
-    for (pt_plug = plugin_list; pt_plug != NULL; pt_plug = pt_plug->next)
-    {
-        type = g_string_new("");
-        sep = "";
-        if (pt_plug->register_protoinfo)
-        {
-            type = g_string_append(type, "dissector");
-            sep = ", ";
-        }
-        if (pt_plug->register_tap_listener)
-        {
-            type = g_string_append(type, sep);
-            type = g_string_append(type, "tap");
-            sep = ", ";
-        }
-        if (pt_plug->register_wtap_module)
-        {
-            type = g_string_append(type, sep);
-            type = g_string_append(type, "file format");
-            sep = ", ";
-        }
-        if (pt_plug->register_codec_module)
-        {
-            type = g_string_append(type, sep);
-            type = g_string_append(type, "codec");
-        }
-        simple_list_append(list, 0, pt_plug->name, 1, pt_plug->version,
-                           2, type->str, 3, g_module_name(pt_plug->handle), -1);
-        g_string_free(type, TRUE);
-    }
+    plugins_get_descriptions(plugins_add_description, list);
 #endif
 
 #ifdef HAVE_LUA
-    for (lua_plug = wslua_plugin_list; lua_plug != NULL; lua_plug = lua_plug->next)
-    {
-        type = g_string_new("");
-        type = g_string_append(type, "lua script");
-
-        simple_list_append(list, 0, lua_plug->name, 1, lua_plug->version, 2, type->str, 3, lua_plug->filename, -1);
-        g_string_free(type, TRUE);
-    }
+    wslua_plugins_get_descriptions(plugins_add_description, list);
 #endif
 }
 
index 98a20f8795f690ae86e0f882b7f4ad30d84bcaa8..acee55f804a785592307eebc441f57eba10275f1 100644 (file)
 #include <epan/addr_resolv.h>
 #include <epan/dissectors/packet-rtp.h>
 #include <epan/rtp_pt.h>
-#include <../codecs/codecs.h>
 #include <epan/prefs.h>
 
+#include <codecs/codecs.h>
+
 #include "../globals.h"
 #include "../codecs/G711a/G711adecode.h"
 #include "../codecs/G711u/G711udecode.h"
index 85b8dbb004911b196f90c048a6172ef890008243..b63692dac96b291a412a885fc28f68b465dbeeea 100644 (file)
@@ -40,6 +40,9 @@
 #include <wsutil/filesystem.h>
 #include <wsutil/file_util.h>
 #include <wsutil/privileges.h>
+#ifdef HAVE_PLUGINS
+#include <wsutil/plugins.h>
+#endif
 #include <wsutil/u3.h>
 
 #include <wiretap/merge.h>
@@ -48,7 +51,6 @@
 #include <epan/epan_dissect.h>
 #include <epan/timestamp.h>
 #include <epan/packet.h>
-#include <epan/plugins.h>
 #include <epan/dfilter/dfilter.h>
 #include <epan/strutil.h>
 #include <epan/addr_resolv.h>
 #include <epan/disabled_protos.h>
 #include <epan/print.h>
 
+#ifdef HAVE_PLUGINS
+#include <codecs/codecs.h>
+#endif
+
 /* general (not Qt specific) */
 #include "file.h"
 #include "summary.h"
@@ -821,6 +827,23 @@ int main(int argc, char *argv[])
     capture_session_init(&global_capture_session, (void *)&cfile);
 #endif
 
+#ifdef HAVE_PLUGINS
+    /* Register all the plugin types we have. */
+    epan_register_plugin_types(); /* Types known to libwireshark */
+    wtap_register_plugin_types(); /* Types known to libwiretap */
+    codec_register_plugin_types(); /* Types known to libcodec */
+
+    /* Scan for plugins.  This does *not* call their registration routines;
+       that's done later. */
+    scan_plugins();
+
+    /* Register all libwiretap plugin modules. */
+    register_all_wiretap_modules();
+
+    /* Register all audio codec plugins. */
+    register_all_codecs();
+#endif
+
     /* Register all dissectors; we must do this before checking for the
        "-G" flag, as the "-G" flag dumps information registered by the
        dissectors, and we must do it before we read the preferences, in
index c932d24c8625fc1535cedb1e16a52cd50fe4b067..712a11b7da663325be945454d841f0fbc1b232ec 100644 (file)
 #include <wsutil/file_util.h>
 #include "buffer.h"
 
+#ifdef HAVE_PLUGINS
+
+#include <wsutil/plugins.h>
+
+/*
+ * List of wiretap plugins.
+ */
+typedef struct {
+       void (*register_wtap_module)(void);  /* routine to call to register a wiretap module */
+} wtap_plugin;
+
+static GSList *wtap_plugins = NULL;
+
+/*
+ * Callback for each plugin found.
+ */
+static gboolean
+check_for_wtap_plugin(GModule *handle)
+{
+       gpointer gp;
+       void (*register_wtap_module)(void);
+       wtap_plugin *plugin;
+
+       /*
+        * Do we have a register_wtap_module routine?
+        */
+       if (!g_module_symbol(handle, "register_wtap_module", &gp)) {
+               /* No, so this isn't a wiretap module plugin. */
+               return FALSE;
+       }
+
+       /*
+        * Yes - this plugin includes one or more wiretap modules.
+        */
+       register_wtap_module = (void (*)(void))gp;
+
+       /*
+        * Add this one to the list of wiretap module plugins.
+        */
+       plugin = (wtap_plugin *)g_malloc(sizeof (wtap_plugin));
+       plugin->register_wtap_module = register_wtap_module;
+       wtap_plugins = g_slist_append(wtap_plugins, plugin);
+       return TRUE;
+}
+
+void
+wtap_register_plugin_types(void)
+{
+       add_plugin_type("file format", check_for_wtap_plugin);
+}
+
+static void
+register_wtap_module_plugin(gpointer data, gpointer user_data _U_)
+{
+       wtap_plugin *plugin = (wtap_plugin *)data;
+
+       (plugin->register_wtap_module)();
+}
+
+/*
+ * For all wiretap module plugins, call their register routines.
+ */
+void
+register_all_wiretap_modules(void)
+{
+       g_slist_foreach(wtap_plugins, register_wtap_module_plugin, NULL);
+}
+#endif /* HAVE_PLUGINS */
+
 /*
  * Return the size of the file, as reported by the OS.
  * (gint64, in case that's 64 bits.)
index eacdec32c03c8f7814d2c5f52bc3683813cc5bdf..1a89bfd7f51c55f87b937393dec3ca6ea506fcf4 100644 (file)
@@ -1394,6 +1394,10 @@ GSList *wtap_get_file_extension_type_extensions(guint extension_type);
 
 /*** dynamically register new file types and encapsulations ***/
 WS_DLL_PUBLIC
+void wtap_register_plugin_types(void);
+WS_DLL_PUBLIC
+void register_all_wiretap_modules(void);
+WS_DLL_PUBLIC
 void wtap_register_file_type_extension(const struct file_extension_info *ei);
 WS_DLL_PUBLIC
 void wtap_register_open_routine(wtap_open_routine_t, gboolean has_magic);
index 283bd567a10146714bcf5d38915ec30560845393..9ad86e824755aca552fbaccb15db9684f816847b 100644 (file)
@@ -58,6 +58,7 @@ set(WSUTIL_FILES
   md5.c
   mpeg-audio.c
   nstime.c
+  plugins.c
   privileges.c
   sha1.c
   strnatcmp.c
index 063c2a95b3be7bc252f8a62ac1c7ce8f24a68e47..9a802b83e01a75fe48f20c582478e90961d3567b 100644 (file)
@@ -51,6 +51,7 @@ LIBWSUTIL_SRC =       \
        md5.c           \
        mpeg-audio.c    \
        nstime.c        \
+       plugins.c       \
        privileges.c    \
        sha1.c          \
        strnatcmp.c     \
@@ -86,6 +87,7 @@ LIBWSUTIL_INCLUDES =  \
        md5.h           \
        mpeg-audio.h    \
        nstime.h        \
+       plugins.h       \
        privileges.h    \
        sha1.h          \
        strnatcmp.h     \
diff --git a/wsutil/plugins.c b/wsutil/plugins.c
new file mode 100644 (file)
index 0000000..ebd337c
--- /dev/null
@@ -0,0 +1,415 @@
+/* plugins.c
+ * plugin routines
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#ifdef HAVE_PLUGINS
+
+#include <time.h>
+
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+
+#ifdef HAVE_DIRECT_H
+#include <direct.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <glib.h>
+#include <gmodule.h>
+
+#include <wsutil/filesystem.h>
+#include <wsutil/privileges.h>
+#include <wsutil/file_util.h>
+#include <wsutil/report_err.h>
+
+#include <wsutil/plugins.h>
+
+/* linked list of all plugins */
+typedef struct _plugin {
+    GModule        *handle;       /* handle returned by g_module_open */
+    gchar          *name;         /* plugin name */
+    gchar          *version;      /* plugin version */
+    guint32         types;        /* bitmask of plugin types this plugin supports */
+    struct _plugin *next;         /* forward link */
+} plugin;
+
+static plugin *plugin_list = NULL;
+
+/*
+ * Add a new plugin type.
+ * Takes a callback routine as an argument; it is called for each plugin
+ * we find, and handed a handle for the plugin, the name of the plugin,
+ * and the version string for the plugin.  The plugin returns TRUE if
+ * it's a plugin for that type and FALSE if not.
+ */
+typedef struct {
+    const char *type;
+    plugin_callback callback;
+    guint type_val;
+} plugin_type;
+
+static GSList *plugin_types = NULL;
+
+void
+add_plugin_type(const char *type, plugin_callback callback)
+{
+    plugin_type *new_type;
+    static guint type_val;
+
+    if (type_val >= 32) {
+        /*
+         * There's a bitmask of types that a plugin provides, and it's
+         * 32 bits, so we don't support types > 31.
+         */
+        report_failure("At most 32 plugin types can be supported, so the plugin type '%s' won't be supported.",
+                       type);
+        return;
+    }        
+    new_type = (plugin_type *)g_malloc(sizeof (plugin_type));
+    new_type->type = type;
+    new_type->callback = callback;
+    new_type->type_val = type_val;
+    plugin_types = g_slist_append(plugin_types, new_type);
+    type_val++;
+}
+
+/*
+ * add a new plugin to the list
+ * returns :
+ * - 0 : OK
+ * - ENOMEM : memory allocation problem
+ * - EEXIST : the same plugin (i.e. name/version) was already registered.
+ */
+static int
+add_plugin(plugin *new_plug)
+{
+    plugin *pt_plug;
+
+    pt_plug = plugin_list;
+    if (!pt_plug) /* the list is empty */
+    {
+        plugin_list = new_plug;
+    }
+    else
+    {
+        while (1)
+        {
+            /* check if the same name/version is already registered */
+            if (strcmp(pt_plug->name, new_plug->name) == 0 &&
+                strcmp(pt_plug->version, new_plug->version) == 0)
+            {
+                return EEXIST;
+            }
+
+            /* we found the last plugin in the list */
+            if (pt_plug->next == NULL)
+                break;
+
+            pt_plug = pt_plug->next;
+        }
+        pt_plug->next = new_plug;
+    }
+
+    return 0;
+}
+
+static void
+call_plugin_callback(gpointer data, gpointer user_data)
+{
+    plugin_type *type = (plugin_type *)data;
+    plugin *new_plug = (plugin *)user_data;
+
+    if ((*type->callback)(new_plug->handle)) {
+        /* The plugin supports this type */
+        new_plug->types |= 1 << type->type_val;
+    }
+}
+
+static void
+plugins_scan_dir(const char *dirname)
+{
+#define FILENAME_LEN        1024
+    WS_DIR        *dir;             /* scanned directory */
+    WS_DIRENT     *file;            /* current file */
+    const char    *name;
+    gchar          filename[FILENAME_LEN];   /* current file name */
+    GModule       *handle;          /* handle returned by g_module_open */
+    gpointer       gp;
+    plugin        *new_plug;
+    gchar         *dot;
+    int            cr;
+
+    if ((dir = ws_dir_open(dirname, 0, NULL)) != NULL)
+    {
+        while ((file = ws_dir_read_name(dir)) != NULL)
+        {
+            name = ws_dir_get_name(file);
+
+            /*
+             * GLib 2.x defines G_MODULE_SUFFIX as the extension used on
+             * this platform for loadable modules.
+             */
+            /* skip anything but files with G_MODULE_SUFFIX */
+            dot = strrchr(name, '.');
+            if (dot == NULL || strcmp(dot+1, G_MODULE_SUFFIX) != 0)
+                continue;
+
+            g_snprintf(filename, FILENAME_LEN, "%s" G_DIR_SEPARATOR_S "%s",
+                       dirname, name);
+            if ((handle = g_module_open(filename, (GModuleFlags)0)) == NULL)
+            {
+                report_failure("Couldn't load module %s: %s", filename,
+                               g_module_error());
+                continue;
+            }
+
+            if (!g_module_symbol(handle, "version", &gp))
+            {
+                report_failure("The plugin %s has no version symbol", name);
+                g_module_close(handle);
+                continue;
+            }
+
+            new_plug = (plugin *)g_malloc(sizeof(plugin));
+            new_plug->handle = handle;
+            new_plug->name = g_strdup(name);
+            new_plug->version = (char *)gp;
+            new_plug->types = 0;
+            new_plug->next = NULL;
+
+            /*
+             * Hand the plugin to each of the plugin type callbacks.
+             */
+            g_slist_foreach(plugin_types, call_plugin_callback, new_plug);
+
+            /*
+             * Does this dissector do anything useful?
+             */
+            if (new_plug->types == 0)
+            {
+                /*
+                 * No.
+                 */
+                report_failure("The plugin '%s' has no registration routines",
+                               name);
+                g_module_close(handle);
+                g_free(new_plug->name);
+                g_free(new_plug);
+                continue;
+            }
+
+            /*
+             * OK, attempt to add it to the list of plugins.
+             */
+            if ((cr = add_plugin(new_plug)))
+            {
+                if (cr == EEXIST)
+                    fprintf(stderr, "The plugin %s, version %s\n"
+                            "was found in multiple directories\n",
+                            new_plug->name, new_plug->version);
+                else
+                    fprintf(stderr, "Memory allocation problem\n"
+                            "when processing plugin %s, version %s\n",
+                            new_plug->name, new_plug->version);
+                g_module_close(handle);
+                g_free(new_plug->name);
+                g_free(new_plug);
+                continue;
+            }
+
+        }
+        ws_dir_close(dir);
+    }
+}
+
+
+/*
+ * Scan for plugins.
+ */
+void
+scan_plugins(void)
+{
+    const char *plugin_dir;
+    const char *name;
+    char *plugin_dir_path;
+    char *plugins_pers_dir;
+    WS_DIR *dir;                /* scanned directory */
+    WS_DIRENT *file;                /* current file */
+
+    if (plugin_list == NULL)      /* ensure scan_plugins is only run once */
+    {
+        /*
+         * Scan the global plugin directory.
+         * If we're running from a build directory, scan the subdirectories
+         * of that directory, as the global plugin directory is the
+         * "plugins" directory of the source tree, and the subdirectories
+         * are the source directories for the plugins, with the plugins
+         * built in those subdirectories.
+         */
+        plugin_dir = get_plugin_dir();
+        if (running_in_build_directory())
+        {
+            if ((dir = ws_dir_open(plugin_dir, 0, NULL)) != NULL)
+            {
+                while ((file = ws_dir_read_name(dir)) != NULL)
+                {
+                    name = ws_dir_get_name(file);
+                    if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
+                        continue;        /* skip "." and ".." */
+                    /*
+                     * Get the full path of a ".libs" subdirectory of that
+                     * directory.
+                     */
+                    plugin_dir_path = g_strdup_printf(
+                        "%s" G_DIR_SEPARATOR_S "%s" G_DIR_SEPARATOR_S ".libs",
+                        plugin_dir, name);
+                    if (test_for_directory(plugin_dir_path) != EISDIR) {
+                        /*
+                         * Either it doesn't refer to a directory or it
+                         * refers to something that doesn't exist.
+                         *
+                         * Assume that means that the plugins are in
+                         * the subdirectory of the plugin directory, not
+                         * a ".libs" subdirectory of that subdirectory.
+                         */
+                        g_free(plugin_dir_path);
+                        plugin_dir_path = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
+                            plugin_dir, name);
+                    }
+                    plugins_scan_dir(plugin_dir_path);
+                    g_free(plugin_dir_path);
+                }
+                ws_dir_close(dir);
+            }
+        }
+        else
+            plugins_scan_dir(plugin_dir);
+
+        /*
+         * If the program wasn't started with special privileges,
+         * scan the users plugin directory.  (Even if we relinquish
+         * them, plugins aren't safe unless we've *permanently*
+         * relinquished them, and we can't do that in Wireshark as,
+         * if we need privileges to start capturing, we'd need to
+         * reclaim them before each time we start capturing.)
+         */
+        if (!started_with_special_privs())
+        {
+            plugins_pers_dir = get_plugins_pers_dir();
+            plugins_scan_dir(plugins_pers_dir);
+            g_free(plugins_pers_dir);
+        }
+    }
+}
+
+/*
+ * Iterate over all plugins, calling a callback with information about
+ * the plugin.
+ */
+typedef struct {
+    plugin  *pt_plug;
+    GString *types;
+    const char *sep;
+} type_callback_info;
+
+static void
+add_plugin_type_description(gpointer data, gpointer user_data)
+{
+    plugin_type *type = (plugin_type *)data;
+    type_callback_info *info = (type_callback_info *)user_data;
+
+    /*
+     * If the plugin handles this type, add the type to the list of types.
+     */
+    if (info->pt_plug->types & (1 << type->type_val)) {
+        g_string_append_printf(info->types, "%s%s", info->sep, type->type);
+        info->sep = ", ";
+    }
+}
+
+WS_DLL_PUBLIC void
+plugins_get_descriptions(plugin_description_callback callback, void *user_data)
+{
+    type_callback_info info;
+
+    info.types = NULL; /* FUCK LLVM UP THE ASS WITH A RED HOT POKER */
+    for (info.pt_plug = plugin_list; info.pt_plug != NULL;
+         info.pt_plug = info.pt_plug->next)
+    {
+        info.sep = "";
+        info.types = g_string_new(""); 
+
+        /*
+         * Build a list of all the plugin types.
+         */
+        g_slist_foreach(plugin_types, add_plugin_type_description, &info);
+
+        /*
+         * And hand the information to the callback.
+         */
+        callback(info.pt_plug->name, info.pt_plug->version, info.types->str,
+                 g_module_name(info.pt_plug->handle), user_data);
+
+        g_string_free(info.types, TRUE);
+    }
+}
+
+static void
+print_plugin_description(const char *name, const char *version,
+                         const char *description, const char *filename,
+                         void *user_data _U_)
+{
+    printf("%s\t%s\t%s\t%s\n", name, version, description, filename);
+}
+
+void
+plugins_dump_all(void)
+{
+    plugins_get_descriptions(print_plugin_description, NULL);
+}
+
+#endif /* HAVE_PLUGINS */
+
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
similarity index 52%
rename from epan/plugins.h
rename to wsutil/plugins.h
index 10a4f5bfff83a068a1571316f33cc4e5c1801e4f..49d24970fa48213e259bb74fbcf1bcdc7e5cbf85 100644 (file)
@@ -32,38 +32,18 @@ extern "C" {
 #include <glib.h>
 #include <gmodule.h>
 
-#include "packet.h"
 #include "ws_symbol_export.h"
 
-typedef struct _plugin {
-    GModule    *handle;          /* handle returned by g_module_open */
-    gchar       *name;            /* plugin name */
-    gchar       *version;         /* plugin version */
-    void (*register_protoinfo)(void); /* routine to call to register protocol information */
-    void (*reg_handoff)(void);    /* routine to call to register dissector handoff */
-    void (*register_tap_listener)(void);   /* routine to call to register tap listener */
-    void (*register_wtap_module)(void);  /* routine to call to register a wiretap module */
-    void (*register_codec_module)(void);  /* routine to call to register a codec */
-    struct _plugin *next;         /* forward link */
-} plugin;
+typedef gboolean (*plugin_callback)(GModule *handle);
 
-WS_DLL_PUBLIC plugin *plugin_list;
-
-extern void init_plugins(void);
-extern void register_all_plugin_registrations(void);
-extern void register_all_plugin_handoffs(void);
-WS_DLL_PUBLIC void register_all_plugin_tap_listeners(void);
+WS_DLL_PUBLIC void scan_plugins(void);
+WS_DLL_PUBLIC void add_plugin_type(const char *type, plugin_callback callback);
+typedef void (*plugin_description_callback)(const char *, const char *,
+                                            const char *, const char *,
+                                            void *);
+WS_DLL_PUBLIC void plugins_get_descriptions(plugin_description_callback callback, void *user_data);
 WS_DLL_PUBLIC void plugins_dump_all(void);
 
-typedef struct _wslua_plugin {
-    gchar       *name;            /**< plugin name */
-    gchar       *version;         /**< plugin version */
-    gchar       *filename;        /**< plugin filename */
-    struct _wslua_plugin *next;
-} wslua_plugin;
-
-WS_DLL_PUBLIC wslua_plugin *wslua_plugin_list;
-
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */