From 551950c438ba5d9977504b7619e6b5abf59f90ed Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Thu, 29 May 2014 16:54:23 -0700 Subject: [PATCH] Adding environment variable BRO_PLUGIN_ACTIVATE that unconditionally activates plugins. Plugins are specified with a comma-separated list of names. --- doc/devel/plugins.rst | 10 +++++++- src/Event.cc | 5 +++- src/main.cc | 18 +++++++++++++-- src/plugin/Manager.cc | 53 +++++++++++++++++++++++++++++++++++++------ src/plugin/Manager.h | 29 ++++++++++++++++------- src/plugin/Plugin.cc | 1 - src/util.cc | 10 ++++++++ src/util.h | 1 + 8 files changed, 107 insertions(+), 20 deletions(-) diff --git a/doc/devel/plugins.rst b/doc/devel/plugins.rst index e9b8bf337c..8a78288901 100644 --- a/doc/devel/plugins.rst +++ b/doc/devel/plugins.rst @@ -250,7 +250,10 @@ in its search path ``BRO_PLUGIN_PATH``. However, in bare mode (``bro -b``), no dynamic plugins will be activated by default; instead the user can selectively enable individual plugins in scriptland using the ``@load-plugin `` directive (e.g., -``@load-plugin Demo::Rot13``). +``@load-plugin Demo::Rot13``). Alternatively, one can also set the +environment variable ``BRO_PLUGIN_ACTIVATE`` to a list of +comma(!)-separated names to unconditionally activate even in bare +mode. ``bro -N`` shows activated and found yet unactivated plugins separately. Note that plugins compiled statically into Bro are always @@ -328,6 +331,11 @@ Packet Dumpers Not yet implemented. +Debugging Plugins +================= + +TODO. + Documenting Plugins =================== diff --git a/src/Event.cc b/src/Event.cc index 6b345a9c5b..82ea80988e 100644 --- a/src/Event.cc +++ b/src/Event.cc @@ -78,7 +78,10 @@ EventMgr::~EventMgr() void EventMgr::QueueEvent(Event* event) { - PLUGIN_HOOK_VOID(HOOK_QUEUE_EVENT, HookQueueEvent(event)); + bool done = PLUGIN_HOOK_WITH_RESULT(HOOK_QUEUE_EVENT, HookQueueEvent(event), false); + + if ( done ) + return; if ( ! head ) head = tail = event; diff --git a/src/main.cc b/src/main.cc index dab66b780a..23d33f8a06 100644 --- a/src/main.cc +++ b/src/main.cc @@ -218,6 +218,7 @@ void usage() fprintf(stderr, " $BROPATH | file search path (%s)\n", bro_path().c_str()); fprintf(stderr, " $BRO_PLUGIN_PATH | plugin search path (%s)\n", bro_plugin_path()); + fprintf(stderr, " $BRO_PLUGIN_ACTIVATE | plugins to always activate (%s)\n", bro_plugin_activate()); fprintf(stderr, " $BRO_PREFIXES | prefix list (%s)\n", bro_prefixes().c_str()); fprintf(stderr, " $BRO_DNS_FAKE | disable DNS lookups (%s)\n", bro_dns_fake()); fprintf(stderr, " $BRO_SEED_FILE | file to load seeds from (not set)\n"); @@ -273,6 +274,20 @@ void show_plugins(int level) } printf("%s", d.Description()); + + plugin::Manager::inactive_plugin_list inactives = plugin_mgr->InactivePlugins(); + + if ( ! inactives.size() ) + return; + + printf("\nInactive dynamic plugins:\n"); + + for ( plugin::Manager::inactive_plugin_list::const_iterator i = inactives.begin(); i != inactives.end(); i++ ) + { + string name = (*i).first; + string path = (*i).second; + printf(" %s (%s)\n", name.c_str(), path.c_str()); + } } void done_with_network() @@ -862,8 +877,7 @@ int main(int argc, char** argv) file_mgr->InitPreScript(); broxygen_mgr->InitPreScript(); - if ( ! bare_mode ) - plugin_mgr->ActivateAllDynamicPlugins(); + plugin_mgr->ActivateDynamicPlugins(! bare_mode); if ( events_file ) event_player = new EventPlayer(events_file); diff --git a/src/plugin/Manager.cc b/src/plugin/Manager.cc index 747e80cb31..21b3f0f9d3 100644 --- a/src/plugin/Manager.cc +++ b/src/plugin/Manager.cc @@ -133,15 +133,18 @@ void Manager::SearchDynamicPlugins(const std::string& dir) closedir(d); } -bool Manager::ActivateDynamicPluginInternal(const std::string& name) +bool Manager::ActivateDynamicPluginInternal(const std::string& name, bool ok_if_not_found) { dynamic_plugin_map::iterator m = dynamic_plugins.find(name); if ( m == dynamic_plugins.end() ) { + if ( ok_if_not_found ) + return true; + reporter->Error("plugin %s is not available", name.c_str()); return false; - } + } std::string dir = m->second + "/"; @@ -251,13 +254,23 @@ bool Manager::ActivateDynamicPlugin(const std::string& name) return true; } -bool Manager::ActivateAllDynamicPlugins() +bool Manager::ActivateDynamicPlugins(bool all) { - for ( dynamic_plugin_map::const_iterator i = dynamic_plugins.begin(); - i != dynamic_plugins.end(); i++ ) + // Activate plugins that our environment tells us to. + vector p; + tokenize_string(bro_plugin_activate(), ",", &p); + + for ( size_t n = 0; n < p.size(); ++n ) + ActivateDynamicPluginInternal(p[n], true); + + if ( all ) { - if ( ! ActivateDynamicPluginInternal(i->first) ) - return false; + for ( dynamic_plugin_map::const_iterator i = dynamic_plugins.begin(); + i != dynamic_plugins.end(); i++ ) + { + if ( ! ActivateDynamicPluginInternal(i->first) ) + return false; + } } UpdateInputFiles(); @@ -361,6 +374,32 @@ Manager::plugin_list Manager::Plugins() const return *Manager::PluginsInternal(); } +Manager::inactive_plugin_list Manager::InactivePlugins() const + { + plugin_list* all = PluginsInternal(); + + inactive_plugin_list inactives; + + for ( dynamic_plugin_map::const_iterator i = dynamic_plugins.begin(); i != dynamic_plugins.end(); i++ ) + { + bool found = false; + + for ( plugin_list::const_iterator j = all->begin(); j != all->end(); j++ ) + { + if ( (*i).first == (*j)->Name() ) + { + found = true; + break; + } + } + + if ( ! found ) + inactives.push_back(*i); + } + + return inactives; + } + Manager::plugin_list* Manager::PluginsInternal() { static plugin_list* plugins = 0; diff --git a/src/plugin/Manager.h b/src/plugin/Manager.h index 881255d022..1a4db741f3 100644 --- a/src/plugin/Manager.h +++ b/src/plugin/Manager.h @@ -30,6 +30,7 @@ public: typedef void (*bif_init_func)(Plugin *); typedef std::list plugin_list; typedef Plugin::component_list component_list; + typedef std::list > inactive_plugin_list; /** * Constructor. @@ -68,15 +69,19 @@ public: bool ActivateDynamicPlugin(const std::string& name); /** - * Activates all plugins that SearchPlugins() has previously - * discovered. The effect is the same all calling \a - * ActivePlugin(name) for every plugin. + * Activates plugins that SearchPlugins() has previously discovered. The + * effect is the same all calling \a ActivePlugin(name) for the plugins. + * + * @param all If true, activates all plugins that are found. If false, + * activate only those that should always be activated unconditionally + * via the BRO_PLUGIN_ACTIVATE enviroment variable. In other words, it's + * false if running bare mode. * * @return True if all plugins have been loaded successfully. If one * fail to load, the method stops there without loading any furthers * and returns false. */ - bool ActivateAllDynamicPlugins(); + bool ActivateDynamicPlugins(bool all); /** * First-stage initializion of the manager. This is called early on @@ -105,12 +110,20 @@ public: void FinishPlugins(); /** - * Returns a list of all available plugins. This includes all that - * are compiled in statically, as well as those loaded dynamically so - * far. + * Returns a list of all available and activated plugins. This includes + * all that are compiled in statically, as well as those loaded + * dynamically so far. */ plugin_list Plugins() const; + /** + * Returns a list of all dynamic plugins that have been found, yet not + * activated. The returned list contains pairs of plugin name and base + * directory. Note that because they aren't activated, that's all + * information we have access to. + */ + inactive_plugin_list InactivePlugins() const; + /** * Returns a list of all available components, in any plugin, that * are derived from a specific class. The class is given as the @@ -255,7 +268,7 @@ public: static void RegisterBifFile(const char* plugin, bif_init_func c); private: - bool ActivateDynamicPluginInternal(const std::string& name); + bool ActivateDynamicPluginInternal(const std::string& name, bool ok_if_not_found = false); void UpdateInputFiles(); void MetaHookPre(HookType hook, const HookArgumentList& args) const; void MetaHookPost(HookType hook, const HookArgumentList& args, HookArgument result) const; diff --git a/src/plugin/Plugin.cc b/src/plugin/Plugin.cc index 43181945a6..2c26e62743 100644 --- a/src/plugin/Plugin.cc +++ b/src/plugin/Plugin.cc @@ -321,7 +321,6 @@ void Plugin::MetaHookPost(HookType hook, const HookArgumentList& args, HookArgum void Plugin::Describe(ODesc* d) const { - d->Add("Plugin: "); d->Add(config.name); if ( config.description.size() ) diff --git a/src/util.cc b/src/util.cc index 9c099382c9..1e2ab7b49e 100644 --- a/src/util.cc +++ b/src/util.cc @@ -984,6 +984,16 @@ const char* bro_plugin_path() return path; } +const char* bro_plugin_activate() + { + const char* names = getenv("BRO_PLUGIN_ACTIVATE"); + + if ( ! names ) + names = ""; + + return names; + } + string bro_prefixes() { string rval; diff --git a/src/util.h b/src/util.h index 2cd32409c8..ac3b0c7290 100644 --- a/src/util.h +++ b/src/util.h @@ -241,6 +241,7 @@ extern const char* PACKAGE_LOADER; extern const std::string& bro_path(); extern const char* bro_magic_path(); extern const char* bro_plugin_path(); +extern const char* bro_plugin_activate(); extern std::string bro_prefixes(); extern void add_to_bro_path(const std::string& dir);