mirror of
https://github.com/zeek/zeek.git
synced 2025-10-05 16:18:19 +00:00
Updates of the dynamic plugin code.
Includes: - Cleanup of the plugin API, in particular generally changing const char* to std::string - Renaming environment variable BRO_PLUGINS to BRO_PLUGIN_PATH, defaulting to <prefix>/lib/bro/plugins - Reworking how dynamic plugins are searched and activated. See doc/devel/plugins.rst for details. - New @load-plugin directive to explicitly activate a plugin - Support for Darwin. (Linux untested right now) - The init-plugin updates come with support for "make test", "make sdist", and "make bdist" (see how-to). - Test updates. Notes: The new hook mechanism, which allows plugins to hook into Bro's core a well-defined points, is still essentially untested.
This commit is contained in:
parent
987452beff
commit
a80dd10215
18 changed files with 257 additions and 143 deletions
|
@ -22,10 +22,11 @@ set(BRO_SCRIPT_SOURCE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/scripts)
|
||||||
get_filename_component(BRO_SCRIPT_INSTALL_PATH ${BRO_SCRIPT_INSTALL_PATH}
|
get_filename_component(BRO_SCRIPT_INSTALL_PATH ${BRO_SCRIPT_INSTALL_PATH}
|
||||||
ABSOLUTE)
|
ABSOLUTE)
|
||||||
|
|
||||||
set(BRO_PLUGIN_INSTALL_PATH ${BRO_ROOT_DIR}/lib/bro/plugins)
|
set(BRO_PLUGIN_INSTALL_PATH ${BRO_ROOT_DIR}/lib/bro/plugins CACHE STRING "Installation path for plugins" FORCE)
|
||||||
set(BRO_MAGIC_INSTALL_PATH ${BRO_ROOT_DIR}/share/bro/magic)
|
set(BRO_MAGIC_INSTALL_PATH ${BRO_ROOT_DIR}/share/bro/magic)
|
||||||
set(BRO_MAGIC_SOURCE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/magic/database)
|
set(BRO_MAGIC_SOURCE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/magic/database)
|
||||||
|
|
||||||
|
|
||||||
configure_file(bro-path-dev.in ${CMAKE_CURRENT_BINARY_DIR}/bro-path-dev)
|
configure_file(bro-path-dev.in ${CMAKE_CURRENT_BINARY_DIR}/bro-path-dev)
|
||||||
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/bro-path-dev.sh
|
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/bro-path-dev.sh
|
||||||
"export BROPATH=`${CMAKE_CURRENT_BINARY_DIR}/bro-path-dev`\n"
|
"export BROPATH=`${CMAKE_CURRENT_BINARY_DIR}/bro-path-dev`\n"
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 715937ad72d9158d8c3142f81ee7005601d75db8
|
Subproject commit f89d870437dbbbb107fd29f1085aef070e3bf373
|
2
cmake
2
cmake
|
@ -1 +1 @@
|
||||||
Subproject commit 6eb4cbfbc75f0bd13e247150b19932905a85e10c
|
Subproject commit 763b6d2574294e62f116e167c564a6292206a655
|
|
@ -214,7 +214,7 @@
|
||||||
#define HOST_ARCHITECTURE "@HOST_ARCHITECTURE@"
|
#define HOST_ARCHITECTURE "@HOST_ARCHITECTURE@"
|
||||||
|
|
||||||
/* String with extension of dynamic libraries (e.g., ".so") */
|
/* String with extension of dynamic libraries (e.g., ".so") */
|
||||||
#define SHARED_LIBRARY_SUFFIX "@CMAKE_SHARED_LIBRARY_SUFFIX@"
|
#define DYNAMIC_PLUGIN_SUFFIX "@CMAKE_SHARED_MODULE_SUFFIX@"
|
||||||
|
|
||||||
/* True if we're building outside of the main Bro source code tree. */
|
/* True if we're building outside of the main Bro source code tree. */
|
||||||
#ifndef BRO_PLUGIN_INTERNAL_BUILD
|
#ifndef BRO_PLUGIN_INTERNAL_BUILD
|
||||||
|
|
|
@ -467,7 +467,7 @@ static void WritePluginSectionHeading(FILE* f, const plugin::Plugin* p)
|
||||||
fprintf(f, "-");
|
fprintf(f, "-");
|
||||||
fprintf(f, "\n\n");
|
fprintf(f, "\n\n");
|
||||||
|
|
||||||
fprintf(f, "%s\n\n", p->Description());
|
fprintf(f, "%s\n\n", p->Description().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WriteAnalyzerComponent(FILE* f, const analyzer::Component* c)
|
static void WriteAnalyzerComponent(FILE* f, const analyzer::Component* c)
|
||||||
|
@ -568,7 +568,7 @@ static void WritePluginBifItems(FILE* f, const plugin::Plugin* p,
|
||||||
if ( o )
|
if ( o )
|
||||||
o->WriteReST(f);
|
o->WriteReST(f);
|
||||||
else
|
else
|
||||||
reporter->Warning("No docs for ID: %s\n", it->GetID());
|
reporter->Warning("No docs for ID: %s\n", it->GetID().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -389,6 +389,9 @@ install(TARGETS bro DESTINATION bin)
|
||||||
set(BRO_EXE bro
|
set(BRO_EXE bro
|
||||||
CACHE STRING "Bro executable binary" FORCE)
|
CACHE STRING "Bro executable binary" FORCE)
|
||||||
|
|
||||||
|
set(BRO_EXE_PATH ${CMAKE_CURRENT_BINARY_DIR}/bro
|
||||||
|
CACHE STRING "Path to Bro executable binary" FORCE)
|
||||||
|
|
||||||
# Target to create all the autogenerated files.
|
# Target to create all the autogenerated files.
|
||||||
add_custom_target(generate_outputs_stage1)
|
add_custom_target(generate_outputs_stage1)
|
||||||
add_dependencies(generate_outputs_stage1 ${bro_ALL_GENERATED_OUTPUTS})
|
add_dependencies(generate_outputs_stage1 ${bro_ALL_GENERATED_OUTPUTS})
|
||||||
|
|
|
@ -117,7 +117,7 @@ void DebugLogger::Log(const plugin::Plugin& plugin, const char* fmt, ...)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fprintf(file, "%17.06f/%17.06f [plugin %s] ",
|
fprintf(file, "%17.06f/%17.06f [plugin %s] ",
|
||||||
network_time, current_time(true), plugin.Name());
|
network_time, current_time(true), plugin.Name().c_str());
|
||||||
|
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
|
|
|
@ -15,6 +15,7 @@ extern int brolex();
|
||||||
extern char last_tok[128];
|
extern char last_tok[128];
|
||||||
|
|
||||||
extern void add_input_file(const char* file);
|
extern void add_input_file(const char* file);
|
||||||
|
extern void add_input_file_at_front(const char* file);
|
||||||
|
|
||||||
// Adds the substrings (using the given delimiter) in a string to the
|
// Adds the substrings (using the given delimiter) in a string to the
|
||||||
// given namelist.
|
// given namelist.
|
||||||
|
|
10
src/main.cc
10
src/main.cc
|
@ -223,7 +223,7 @@ void usage()
|
||||||
|
|
||||||
fprintf(stderr, " $BROPATH | file search path (%s)\n", bro_path().c_str());
|
fprintf(stderr, " $BROPATH | file search path (%s)\n", bro_path().c_str());
|
||||||
fprintf(stderr, " $BROMAGIC | libmagic mime magic database search path (%s)\n", bro_magic_path());
|
fprintf(stderr, " $BROMAGIC | libmagic mime magic database search path (%s)\n", bro_magic_path());
|
||||||
fprintf(stderr, " $BRO_PLUGINS | plugin search path (%s)\n", bro_plugin_path());
|
fprintf(stderr, " $BRO_PLUGIN_PATH | plugin search path (%s)\n", bro_plugin_path());
|
||||||
fprintf(stderr, " $BRO_PREFIXES | prefix list (%s)\n", bro_prefixes().c_str());
|
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_DNS_FAKE | disable DNS lookups (%s)\n", bro_dns_fake());
|
||||||
fprintf(stderr, " $BRO_SEED_FILE | file to load seeds from (not set)\n");
|
fprintf(stderr, " $BRO_SEED_FILE | file to load seeds from (not set)\n");
|
||||||
|
@ -820,7 +820,7 @@ int main(int argc, char** argv)
|
||||||
if ( ! bare_mode )
|
if ( ! bare_mode )
|
||||||
add_input_file("base/init-default.bro");
|
add_input_file("base/init-default.bro");
|
||||||
|
|
||||||
plugin_mgr->LoadPluginsFrom(bro_plugin_path());
|
plugin_mgr->SearchDynamicPlugins(bro_plugin_path());
|
||||||
|
|
||||||
if ( optind == argc &&
|
if ( optind == argc &&
|
||||||
read_files.length() == 0 && flow_files.length() == 0 &&
|
read_files.length() == 0 && flow_files.length() == 0 &&
|
||||||
|
@ -860,6 +860,9 @@ int main(int argc, char** argv)
|
||||||
analyzer_mgr->InitPreScript();
|
analyzer_mgr->InitPreScript();
|
||||||
file_mgr->InitPreScript();
|
file_mgr->InitPreScript();
|
||||||
|
|
||||||
|
if ( ! bare_mode )
|
||||||
|
plugin_mgr->ActivateAllDynamicPlugins();
|
||||||
|
|
||||||
if ( events_file )
|
if ( events_file )
|
||||||
event_player = new EventPlayer(events_file);
|
event_player = new EventPlayer(events_file);
|
||||||
|
|
||||||
|
@ -896,13 +899,14 @@ int main(int argc, char** argv)
|
||||||
if ( reporter->Errors() > 0 )
|
if ( reporter->Errors() > 0 )
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
||||||
|
plugin_mgr->InitPostScript();
|
||||||
|
|
||||||
if ( print_plugins )
|
if ( print_plugins )
|
||||||
{
|
{
|
||||||
show_plugins(print_plugins);
|
show_plugins(print_plugins);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
plugin_mgr->InitPostScript();
|
|
||||||
analyzer_mgr->InitPostScript();
|
analyzer_mgr->InitPostScript();
|
||||||
file_mgr->InitPostScript();
|
file_mgr->InitPostScript();
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
// See the file "COPYING" in the main distribution directory for copyright.
|
// See the file "COPYING" in the main distribution directory for copyright.
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <fstream>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <glob.h>
|
#include <glob.h>
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
@ -15,6 +16,7 @@
|
||||||
|
|
||||||
using namespace plugin;
|
using namespace plugin;
|
||||||
|
|
||||||
|
Plugin* Manager::current_plugin = 0;
|
||||||
string Manager::current_dir;
|
string Manager::current_dir;
|
||||||
string Manager::current_sopath;
|
string Manager::current_sopath;
|
||||||
|
|
||||||
|
@ -37,7 +39,7 @@ Manager::~Manager()
|
||||||
delete [] hooks;
|
delete [] hooks;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::LoadPluginsFrom(const string& dir)
|
void Manager::SearchDynamicPlugins(const std::string& dir)
|
||||||
{
|
{
|
||||||
assert(! init);
|
assert(! init);
|
||||||
|
|
||||||
|
@ -51,7 +53,7 @@ void Manager::LoadPluginsFrom(const string& dir)
|
||||||
std::string d;
|
std::string d;
|
||||||
|
|
||||||
while ( std::getline(s, d, ':') )
|
while ( std::getline(s, d, ':') )
|
||||||
LoadPluginsFrom(d);
|
SearchDynamicPlugins(d);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -62,12 +64,34 @@ void Manager::LoadPluginsFrom(const string& dir)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rc = LoadPlugin(dir);
|
// Check if it's a plugin dirctory.
|
||||||
|
|
||||||
if ( rc >= 0 )
|
const std::string magic = dir + "/__bro_plugin__";
|
||||||
|
|
||||||
|
if ( is_file(magic) )
|
||||||
|
{
|
||||||
|
// It's a plugin, get it's name.
|
||||||
|
std::ifstream in(magic);
|
||||||
|
|
||||||
|
if ( in.fail() )
|
||||||
|
reporter->FatalError("cannot open plugin magic file %s", magic.c_str());
|
||||||
|
|
||||||
|
std::string name;
|
||||||
|
std::getline(in, name);
|
||||||
|
strstrip(name);
|
||||||
|
|
||||||
|
if ( name.empty() )
|
||||||
|
reporter->FatalError("empty plugin magic file %s", magic.c_str());
|
||||||
|
|
||||||
|
// Record it, so that we can later activate it.
|
||||||
|
|
||||||
|
dynamic_plugins.insert(std::make_pair(name, dir));
|
||||||
|
|
||||||
|
DBG_LOG(DBG_PLUGINS, "Found plugin %s in %s", name.c_str(), dir.c_str());
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
DBG_LOG(DBG_PLUGINS, "Searching directory %s recursively for plugins", dir.c_str());
|
// No plugin here, traverse subirectories.
|
||||||
|
|
||||||
DIR* d = opendir(dir.c_str());
|
DIR* d = opendir(dir.c_str());
|
||||||
|
|
||||||
|
@ -98,22 +122,33 @@ void Manager::LoadPluginsFrom(const string& dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( st.st_mode & S_IFDIR )
|
if ( st.st_mode & S_IFDIR )
|
||||||
LoadPluginsFrom(path);
|
SearchDynamicPlugins(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int Manager::LoadPlugin(const std::string& dir)
|
bool Manager::ActivateDynamicPluginInternal(const std::string& name)
|
||||||
{
|
{
|
||||||
assert(! init);
|
dynamic_plugin_map::iterator m = dynamic_plugins.find(name);
|
||||||
|
|
||||||
// Check if it's a plugin dirctory.
|
if ( m == dynamic_plugins.end() )
|
||||||
if ( ! is_file(dir + "/__bro_plugin__") )
|
{
|
||||||
return -1;
|
reporter->Error("plugin %s is not available", name.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
DBG_LOG(DBG_PLUGINS, "Loading plugin from %s", dir.c_str());
|
std::string dir = m->second + "/";
|
||||||
|
|
||||||
|
if ( dir.empty() )
|
||||||
|
{
|
||||||
|
// That's our marker that we have already activated this
|
||||||
|
// plugin. Silently ignore the new request.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBG_LOG(DBG_PLUGINS, "Activating plugin %s", name.c_str());
|
||||||
|
|
||||||
// Add the "scripts" and "bif" directories to BROPATH.
|
// Add the "scripts" and "bif" directories to BROPATH.
|
||||||
string scripts = dir + "/scripts";
|
std::string scripts = dir + "scripts";
|
||||||
|
|
||||||
if ( is_dir(scripts) )
|
if ( is_dir(scripts) )
|
||||||
{
|
{
|
||||||
|
@ -121,44 +156,27 @@ int Manager::LoadPlugin(const std::string& dir)
|
||||||
add_to_bro_path(scripts);
|
add_to_bro_path(scripts);
|
||||||
}
|
}
|
||||||
|
|
||||||
string bif = dir + "/bif";
|
// Load {bif,scripts}/__load__.bro automatically.
|
||||||
|
|
||||||
if ( is_dir(bif) )
|
string init = dir + "lib/bif/__load__.bro";
|
||||||
{
|
|
||||||
DBG_LOG(DBG_PLUGINS, " Adding %s to BROPATH", bif.c_str());
|
|
||||||
add_to_bro_path(bif);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load dylib/scripts/__load__.bro automatically.
|
|
||||||
string dyinit = dir + "/dylib/scripts/__load__.bro";
|
|
||||||
|
|
||||||
if ( is_file(dyinit) )
|
|
||||||
{
|
|
||||||
DBG_LOG(DBG_PLUGINS, " Adding %s for loading", dyinit.c_str());
|
|
||||||
add_input_file(dyinit.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load scripts/__load__.bro automatically.
|
|
||||||
string init = scripts + "/__load__.bro";
|
|
||||||
|
|
||||||
if ( is_file(init) )
|
if ( is_file(init) )
|
||||||
{
|
{
|
||||||
DBG_LOG(DBG_PLUGINS, " Adding %s for loading", init.c_str());
|
DBG_LOG(DBG_PLUGINS, " Loading %s", init.c_str());
|
||||||
add_input_file(init.c_str());
|
scripts_to_load.push_back(init);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load bif/__load__.bro automatically.
|
init = dir + "scripts/__load__.bro";
|
||||||
init = bif + "/__load__.bro";
|
|
||||||
|
|
||||||
if ( is_file(init) )
|
if ( is_file(init) )
|
||||||
{
|
{
|
||||||
DBG_LOG(DBG_PLUGINS, " Adding %s for loading", init.c_str());
|
DBG_LOG(DBG_PLUGINS, " Loading %s", init.c_str());
|
||||||
add_input_file(init.c_str());
|
scripts_to_load.push_back(init);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load shared libraries.
|
// Load shared libraries.
|
||||||
|
|
||||||
string dypattern = dir + "/dylib/*." + HOST_ARCHITECTURE + SHARED_LIBRARY_SUFFIX;
|
string dypattern = dir + "/lib/*." + HOST_ARCHITECTURE + DYNAMIC_PLUGIN_SUFFIX;
|
||||||
|
|
||||||
DBG_LOG(DBG_PLUGINS, " Searching for shared libraries %s", dypattern.c_str());
|
DBG_LOG(DBG_PLUGINS, " Searching for shared libraries %s", dypattern.c_str());
|
||||||
|
|
||||||
|
@ -170,11 +188,10 @@ int Manager::LoadPlugin(const std::string& dir)
|
||||||
{
|
{
|
||||||
const char* path = gl.gl_pathv[i];
|
const char* path = gl.gl_pathv[i];
|
||||||
|
|
||||||
|
current_plugin = 0;
|
||||||
current_dir = dir;
|
current_dir = dir;
|
||||||
current_sopath = path;
|
current_sopath = path;
|
||||||
void* hdl = dlopen(path, RTLD_LAZY | RTLD_GLOBAL);
|
void* hdl = dlopen(path, RTLD_LAZY | RTLD_GLOBAL);
|
||||||
current_dir.clear();
|
|
||||||
current_sopath.clear();
|
|
||||||
|
|
||||||
if ( ! hdl )
|
if ( ! hdl )
|
||||||
{
|
{
|
||||||
|
@ -182,6 +199,24 @@ int Manager::LoadPlugin(const std::string& dir)
|
||||||
reporter->FatalError("cannot load plugin library %s: %s", path, err ? err : "<unknown error>");
|
reporter->FatalError("cannot load plugin library %s: %s", path, err ? err : "<unknown error>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( ! current_plugin )
|
||||||
|
reporter->FatalError("load plugin library %s did not instantiate a plugin", path);
|
||||||
|
|
||||||
|
// We execute the pre-script initialization here; this in
|
||||||
|
// fact could be *during* script initialization if we got
|
||||||
|
// triggered via @load-plugin.
|
||||||
|
current_plugin->InitPreScript();
|
||||||
|
|
||||||
|
// Make sure the name the plugin reports is consistent with
|
||||||
|
// what we expect from its magic file.
|
||||||
|
if ( string(current_plugin->Name()) != name )
|
||||||
|
reporter->FatalError("inconsistent plugin name: %s vs %s",
|
||||||
|
current_plugin->Name().c_str(), name.c_str());
|
||||||
|
|
||||||
|
current_dir.clear();
|
||||||
|
current_sopath.clear();
|
||||||
|
current_plugin = 0;
|
||||||
|
|
||||||
DBG_LOG(DBG_PLUGINS, " Loaded %s", path);
|
DBG_LOG(DBG_PLUGINS, " Loaded %s", path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -189,10 +224,42 @@ int Manager::LoadPlugin(const std::string& dir)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DBG_LOG(DBG_PLUGINS, " No shared library found");
|
DBG_LOG(DBG_PLUGINS, " No shared library found");
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
// Mark this plugin as activated by clearing the path.
|
||||||
|
m->second.clear();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Manager::ActivateDynamicPlugin(const std::string& name)
|
||||||
|
{
|
||||||
|
if ( ! ActivateDynamicPluginInternal(name) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
UpdateInputFiles();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Manager::ActivateAllDynamicPlugins()
|
||||||
|
{
|
||||||
|
for ( dynamic_plugin_map::const_iterator i = dynamic_plugins.begin();
|
||||||
|
i != dynamic_plugins.end(); i++ )
|
||||||
|
{
|
||||||
|
if ( ! ActivateDynamicPluginInternal(i->first) )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateInputFiles();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::UpdateInputFiles()
|
||||||
|
{
|
||||||
|
for ( file_list::const_reverse_iterator i = scripts_to_load.rbegin();
|
||||||
|
i != scripts_to_load.rend(); i++ )
|
||||||
|
add_input_file_at_front((*i).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool plugin_cmp(const Plugin* a, const Plugin* b)
|
static bool plugin_cmp(const Plugin* a, const Plugin* b)
|
||||||
|
@ -205,11 +272,13 @@ bool Manager::RegisterPlugin(Plugin *plugin)
|
||||||
Manager::PluginsInternal()->push_back(plugin);
|
Manager::PluginsInternal()->push_back(plugin);
|
||||||
|
|
||||||
if ( current_dir.size() && current_sopath.size() )
|
if ( current_dir.size() && current_sopath.size() )
|
||||||
|
// A dynamic plugin, record its location.
|
||||||
plugin->SetPluginLocation(current_dir.c_str(), current_sopath.c_str());
|
plugin->SetPluginLocation(current_dir.c_str(), current_sopath.c_str());
|
||||||
|
|
||||||
// Sort plugins by name to make sure we have a deterministic order.
|
// Sort plugins by name to make sure we have a deterministic order.
|
||||||
PluginsInternal()->sort(plugin_cmp);
|
PluginsInternal()->sort(plugin_cmp);
|
||||||
|
|
||||||
|
current_plugin = plugin;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,7 +289,6 @@ void Manager::InitPreScript()
|
||||||
for ( plugin_list::iterator i = Manager::PluginsInternal()->begin(); i != Manager::PluginsInternal()->end(); i++ )
|
for ( plugin_list::iterator i = Manager::PluginsInternal()->begin(); i != Manager::PluginsInternal()->end(); i++ )
|
||||||
{
|
{
|
||||||
Plugin* plugin = *i;
|
Plugin* plugin = *i;
|
||||||
|
|
||||||
plugin->InitPreScript();
|
plugin->InitPreScript();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,7 +401,7 @@ void Manager::DisableHook(HookType hook, Plugin* plugin)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int Manager::HookLoadFile(const char* file)
|
int Manager::HookLoadFile(const string& file)
|
||||||
{
|
{
|
||||||
hook_list* l = hooks[HOOK_LOAD_FILE];
|
hook_list* l = hooks[HOOK_LOAD_FILE];
|
||||||
|
|
||||||
|
|
|
@ -40,17 +40,41 @@ public:
|
||||||
virtual ~Manager();
|
virtual ~Manager();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads all plugins dynamically from a set of directories. Multiple
|
* Searches a set of directories for plugins. If a specificed
|
||||||
* directories are split by ':'. If a directory does not contain a
|
* directory does not contain a plugin itself, the method searches
|
||||||
* plugin itself, the method searches for plugins recursively. For
|
* for plugins recursively. For plugins found, the method makes them
|
||||||
* plugins found, the method loads the plugin's shared library and
|
* available for later activation via ActivatePlugin().
|
||||||
* makes its scripts available to the interpreter.
|
|
||||||
*
|
*
|
||||||
* This must be called only before InitPluginsPreScript().
|
* This must be called only before InitPluginsPreScript().
|
||||||
*
|
*
|
||||||
* @param dir The directory to search for plugins.
|
* @param dir The directory to search for plugins. Multiple
|
||||||
|
* directories are split by ':'.
|
||||||
*/
|
*/
|
||||||
void LoadPluginsFrom(const std::string& dir);
|
void SearchDynamicPlugins(const std::string& dir);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Activates a plugin that SearchPlugins() has previously discovered.
|
||||||
|
* Activing a plugin involved loading its dynamic module, making its
|
||||||
|
* bifs available, and adding its script paths to BROPATH.
|
||||||
|
*
|
||||||
|
* @param name The name of the plugin, as determined previously by
|
||||||
|
* SearchPlugin().
|
||||||
|
*
|
||||||
|
* @return True if the plugin has been loaded successfully.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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.
|
||||||
|
*
|
||||||
|
* @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();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* First-stage initializion of the manager. This is called early on
|
* First-stage initializion of the manager. This is called early on
|
||||||
|
@ -148,7 +172,7 @@ public:
|
||||||
* successfully; 0 if a plugin took over the file but had trouble
|
* successfully; 0 if a plugin took over the file but had trouble
|
||||||
* loading it; and -1 if no plugin was interested in the file at all.
|
* loading it; and -1 if no plugin was interested in the file at all.
|
||||||
*/
|
*/
|
||||||
virtual int HookLoadFile(const char* file);
|
virtual int HookLoadFile(const string& file);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook that filters calls to a script function/event/hook.
|
* Hook that filters calls to a script function/event/hook.
|
||||||
|
@ -196,40 +220,37 @@ public:
|
||||||
*/
|
*/
|
||||||
static bool RegisterPlugin(Plugin* plugin);
|
static bool RegisterPlugin(Plugin* plugin);
|
||||||
|
|
||||||
protected:
|
|
||||||
/**
|
|
||||||
* Loads a plugin dynamically from a given directory. It loads the
|
|
||||||
* plugin's shared library, and makes its scripts available to the
|
|
||||||
* interpreter. Different from LoadPluginsFrom() this method does not
|
|
||||||
* further descend the directory tree recursively to search for
|
|
||||||
* plugins.
|
|
||||||
*
|
|
||||||
* This must be called only before InitPluginsPreScript()
|
|
||||||
*
|
|
||||||
* @param file The path to the plugin to load.
|
|
||||||
*
|
|
||||||
* @return 0 if there's a plugin in this directory, but there was a
|
|
||||||
* problem loading it; -1 if there's no plugin at all in this
|
|
||||||
* directory; 1 if there's a plugin in this directory and we loaded
|
|
||||||
* it successfully.
|
|
||||||
*/
|
|
||||||
int LoadPlugin(const std::string& dir);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool ActivateDynamicPluginInternal(const std::string& name);
|
||||||
|
void UpdateInputFiles();
|
||||||
|
|
||||||
|
// All found dynamic plugins, mapping their names to base directory.
|
||||||
|
typedef std::map<std::string, std::string> dynamic_plugin_map;
|
||||||
|
dynamic_plugin_map dynamic_plugins;
|
||||||
|
|
||||||
|
// We buffer scripts to load temporarliy to get them to load in the
|
||||||
|
// right order.
|
||||||
|
typedef std::list<std::string> file_list;
|
||||||
|
file_list scripts_to_load;
|
||||||
|
|
||||||
|
bool init;
|
||||||
|
|
||||||
// A hook list keeps pairs of plugin and priority interested in a
|
// A hook list keeps pairs of plugin and priority interested in a
|
||||||
// given hook.
|
// given hook.
|
||||||
typedef std::list<std::pair<int, Plugin*> > hook_list;
|
typedef std::list<std::pair<int, Plugin*> > hook_list;
|
||||||
|
|
||||||
static plugin_list* PluginsInternal();
|
|
||||||
|
|
||||||
bool init;
|
|
||||||
|
|
||||||
// An array indexed by HookType. An entry is null if there's no hook
|
// An array indexed by HookType. An entry is null if there's no hook
|
||||||
// of that type enabled.
|
// of that type enabled.
|
||||||
hook_list** hooks;
|
hook_list** hooks;
|
||||||
|
|
||||||
|
static Plugin* current_plugin;
|
||||||
static string current_dir;
|
static string current_dir;
|
||||||
static string current_sopath;
|
static string current_sopath;
|
||||||
|
|
||||||
|
// Returns a modifiable list of all plugins, both static and dynamic.
|
||||||
|
// This is a static method so that plugins can register themselves
|
||||||
|
// even before the manager exists.
|
||||||
|
static plugin_list* PluginsInternal();
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
|
|
|
@ -26,15 +26,15 @@ const char* hook_name(HookType h)
|
||||||
return hook_names[int(h)];
|
return hook_names[int(h)];
|
||||||
}
|
}
|
||||||
|
|
||||||
BifItem::BifItem(const char* arg_id, Type arg_type)
|
BifItem::BifItem(const std::string& arg_id, Type arg_type)
|
||||||
{
|
{
|
||||||
id = copy_string(arg_id);
|
id = arg_id;
|
||||||
type = arg_type;
|
type = arg_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
BifItem::BifItem(const BifItem& other)
|
BifItem::BifItem(const BifItem& other)
|
||||||
{
|
{
|
||||||
id = copy_string(other.id);
|
id = other.id;
|
||||||
type = other.type;
|
type = other.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ BifItem& BifItem::operator=(const BifItem& other)
|
||||||
{
|
{
|
||||||
if ( this != &other )
|
if ( this != &other )
|
||||||
{
|
{
|
||||||
id = copy_string(other.id);
|
id = other.id;
|
||||||
type = other.type;
|
type = other.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,20 +51,19 @@ BifItem& BifItem::operator=(const BifItem& other)
|
||||||
|
|
||||||
BifItem::~BifItem()
|
BifItem::~BifItem()
|
||||||
{
|
{
|
||||||
delete [] id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Plugin::Plugin()
|
Plugin::Plugin()
|
||||||
{
|
{
|
||||||
name = copy_string("<NAME-NOT-SET>");
|
name = "<NAME-NOT-SET>";
|
||||||
description = copy_string("");
|
description = "";
|
||||||
|
|
||||||
// These will be reset by the BRO_PLUGIN_* macros.
|
// These will be reset by the BRO_PLUGIN_* macros.
|
||||||
version = -9999;
|
version = -9999;
|
||||||
api_version = -9999;
|
api_version = -9999;
|
||||||
dynamic = false;
|
dynamic = false;
|
||||||
base_dir = 0;
|
base_dir = "";
|
||||||
sopath = 0;
|
sopath = "";
|
||||||
|
|
||||||
Manager::RegisterPlugin(this);
|
Manager::RegisterPlugin(this);
|
||||||
}
|
}
|
||||||
|
@ -72,33 +71,26 @@ Plugin::Plugin()
|
||||||
Plugin::~Plugin()
|
Plugin::~Plugin()
|
||||||
{
|
{
|
||||||
Done();
|
Done();
|
||||||
|
|
||||||
delete [] name;
|
|
||||||
delete [] description;
|
|
||||||
delete [] base_dir;
|
|
||||||
delete [] sopath;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* Plugin::Name() const
|
const std::string& Plugin::Name() const
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Plugin::SetName(const char* arg_name)
|
void Plugin::SetName(const std::string& arg_name)
|
||||||
{
|
{
|
||||||
delete [] name;
|
name = arg_name;
|
||||||
name = copy_string(arg_name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* Plugin::Description() const
|
const std::string& Plugin::Description() const
|
||||||
{
|
{
|
||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Plugin::SetDescription(const char* arg_description)
|
void Plugin::SetDescription(const std::string& arg_description)
|
||||||
{
|
{
|
||||||
delete [] description;
|
description = arg_description;
|
||||||
description = copy_string(arg_description);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Plugin::Version() const
|
int Plugin::Version() const
|
||||||
|
@ -121,12 +113,12 @@ bool Plugin::DynamicPlugin() const
|
||||||
return dynamic;
|
return dynamic;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* Plugin::PluginDirectory() const
|
const std::string& Plugin::PluginDirectory() const
|
||||||
{
|
{
|
||||||
return base_dir;
|
return base_dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* Plugin::PluginPath() const
|
const std::string& Plugin::PluginPath() const
|
||||||
{
|
{
|
||||||
return sopath;
|
return sopath;
|
||||||
}
|
}
|
||||||
|
@ -141,12 +133,10 @@ void Plugin::SetDynamicPlugin(bool arg_dynamic)
|
||||||
dynamic = arg_dynamic;
|
dynamic = arg_dynamic;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Plugin::SetPluginLocation(const char* arg_dir, const char* arg_sopath)
|
void Plugin::SetPluginLocation(const std::string& arg_dir, const std::string& arg_sopath)
|
||||||
{
|
{
|
||||||
delete [] base_dir;
|
base_dir = arg_dir;
|
||||||
delete [] sopath;
|
sopath = arg_sopath;
|
||||||
base_dir = copy_string(arg_dir);
|
|
||||||
sopath = copy_string(arg_sopath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Plugin::InitPreScript()
|
void Plugin::InitPreScript()
|
||||||
|
@ -197,9 +187,9 @@ static bool component_cmp(const Component* a, const Component* b)
|
||||||
return a->Name() < b->Name();
|
return a->Name() < b->Name();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Plugin::LoadBroFile(const char* file)
|
bool Plugin::LoadBroFile(const std::string& file)
|
||||||
{
|
{
|
||||||
::add_input_file(file);
|
::add_input_file(file.c_str());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,7 +198,7 @@ void Plugin::__AddBifInitFunction(bif_init_func c)
|
||||||
bif_inits.push_back(c);
|
bif_inits.push_back(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Plugin::AddBifItem(const char* name, BifItem::Type type)
|
void Plugin::AddBifItem(const std::string& name, BifItem::Type type)
|
||||||
{
|
{
|
||||||
BifItem bi(name, (BifItem::Type)type);
|
BifItem bi(name, (BifItem::Type)type);
|
||||||
bif_items.push_back(bi);
|
bif_items.push_back(bi);
|
||||||
|
@ -238,7 +228,7 @@ void Plugin::DisableHook(HookType hook)
|
||||||
plugin_mgr->DisableHook(hook, this);
|
plugin_mgr->DisableHook(hook, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Plugin::HookLoadFile(const char* file)
|
int Plugin::HookLoadFile(const std::string& file)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -266,7 +256,7 @@ void Plugin::Describe(ODesc* d) const
|
||||||
d->Add("Plugin: ");
|
d->Add("Plugin: ");
|
||||||
d->Add(name);
|
d->Add(name);
|
||||||
|
|
||||||
if ( description && *description )
|
if ( description.size() )
|
||||||
{
|
{
|
||||||
d->Add(" - ");
|
d->Add(" - ");
|
||||||
d->Add(description);
|
d->Add(description);
|
||||||
|
|
|
@ -50,7 +50,7 @@ public:
|
||||||
*
|
*
|
||||||
* @param type The type of the item.
|
* @param type The type of the item.
|
||||||
*/
|
*/
|
||||||
BifItem(const char* id, Type type);
|
BifItem(const std::string& id, Type type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy constructor.
|
* Copy constructor.
|
||||||
|
@ -70,7 +70,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* Returns the script-level ID as passed into the constructor.
|
* Returns the script-level ID as passed into the constructor.
|
||||||
*/
|
*/
|
||||||
const char* GetID() const { return id; }
|
const std::string& GetID() const { return id; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the type as passed into the constructor.
|
* Returns the type as passed into the constructor.
|
||||||
|
@ -78,7 +78,7 @@ public:
|
||||||
Type GetType() const { return type; }
|
Type GetType() const { return type; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const char* id;
|
std::string id;
|
||||||
Type type;
|
Type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ public:
|
||||||
typedef std::list<Component *> component_list;
|
typedef std::list<Component *> component_list;
|
||||||
typedef std::list<BifItem> bif_item_list;
|
typedef std::list<BifItem> bif_item_list;
|
||||||
typedef std::list<std::pair<HookType, int> > hook_list;
|
typedef std::list<std::pair<HookType, int> > hook_list;
|
||||||
typedef std::list<std::pair<const char*, int> > bif_init_func_result;
|
typedef std::list<std::pair<std::string, int> > bif_init_func_result;
|
||||||
typedef void (*bif_init_func)(Plugin *);
|
typedef void (*bif_init_func)(Plugin *);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -129,12 +129,12 @@ public:
|
||||||
/**
|
/**
|
||||||
* Returns the name of the plugin.
|
* Returns the name of the plugin.
|
||||||
*/
|
*/
|
||||||
const char* Name() const;
|
const std::string& Name() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a short textual description of the plugin, if provided.
|
* Returns a short textual description of the plugin, if provided.
|
||||||
*/
|
*/
|
||||||
const char* Description() const;
|
const std::string& Description() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the version of the plugin. Version are only meaningful for
|
* Returns the version of the plugin. Version are only meaningful for
|
||||||
|
@ -152,13 +152,13 @@ public:
|
||||||
* For dynamic plugins, returns the base directory from which it was
|
* For dynamic plugins, returns the base directory from which it was
|
||||||
* loaded. For static plugins, returns null.
|
* loaded. For static plugins, returns null.
|
||||||
**/
|
**/
|
||||||
const char* PluginDirectory() const;
|
const std::string& PluginDirectory() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For dynamic plugins, returns the full path to the shared library
|
* For dynamic plugins, returns the full path to the shared library
|
||||||
* from which it was loaded. For static plugins, returns null.
|
* from which it was loaded. For static plugins, returns null.
|
||||||
**/
|
**/
|
||||||
const char* PluginPath() const;
|
const std::string& PluginPath() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the internal API version that this plugin relies on. Only
|
* Returns the internal API version that this plugin relies on. Only
|
||||||
|
@ -225,7 +225,7 @@ public:
|
||||||
*
|
*
|
||||||
* @param type The item's type.
|
* @param type The item's type.
|
||||||
*/
|
*/
|
||||||
void AddBifItem(const char* name, BifItem::Type type);
|
void AddBifItem(const std::string& name, BifItem::Type type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a file to the list of files that Bro loads at startup. This
|
* Adds a file to the list of files that Bro loads at startup. This
|
||||||
|
@ -242,7 +242,7 @@ public:
|
||||||
* @return True if successful (which however may only mean
|
* @return True if successful (which however may only mean
|
||||||
* "successfully queued").
|
* "successfully queued").
|
||||||
*/
|
*/
|
||||||
bool LoadBroFile(const char* file);
|
bool LoadBroFile(const std::string& file);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal function adding an entry point for registering
|
* Internal function adding an entry point for registering
|
||||||
|
@ -324,7 +324,7 @@ protected:
|
||||||
* printed an error message); and -1 if the plugin wasn't interested
|
* printed an error message); and -1 if the plugin wasn't interested
|
||||||
* in the file at all.
|
* in the file at all.
|
||||||
*/
|
*/
|
||||||
virtual int HookLoadFile(const char* file);
|
virtual int HookLoadFile(const std::string& file);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook into executing a script-level function/event/hook. Whenever
|
* Hook into executing a script-level function/event/hook. Whenever
|
||||||
|
@ -396,7 +396,7 @@ protected:
|
||||||
*
|
*
|
||||||
* @param name The name. Makes a copy internally.
|
* @param name The name. Makes a copy internally.
|
||||||
*/
|
*/
|
||||||
void SetName(const char* name);
|
void SetName(const std::string& name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the plugin's textual description.
|
* Sets the plugin's textual description.
|
||||||
|
@ -406,7 +406,7 @@ protected:
|
||||||
*
|
*
|
||||||
* @param name The description. Makes a copy internally.
|
* @param name The description. Makes a copy internally.
|
||||||
*/
|
*/
|
||||||
void SetDescription(const char* descr);
|
void SetDescription(const std::string& descr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the plugin's version.
|
* Sets the plugin's version.
|
||||||
|
@ -454,7 +454,7 @@ protected:
|
||||||
* @param sopath The full path the shared library loaded. The
|
* @param sopath The full path the shared library loaded. The
|
||||||
* functions makes an internal copy of string.
|
* functions makes an internal copy of string.
|
||||||
*/
|
*/
|
||||||
void SetPluginLocation(const char* dir, const char* sopath);
|
void SetPluginLocation(const std::string& dir, const std::string& sopath);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
|
@ -465,10 +465,10 @@ private:
|
||||||
|
|
||||||
typedef std::list<bif_init_func> bif_init_func_list;
|
typedef std::list<bif_init_func> bif_init_func_list;
|
||||||
|
|
||||||
const char* name;
|
std::string name;
|
||||||
const char* description;
|
std::string description;
|
||||||
const char* base_dir;
|
std::string base_dir;
|
||||||
const char* sopath;
|
std::string sopath;
|
||||||
int version;
|
int version;
|
||||||
int api_version;
|
int api_version;
|
||||||
bool dynamic;
|
bool dynamic;
|
||||||
|
|
16
src/scan.l
16
src/scan.l
|
@ -407,6 +407,11 @@ when return TOK_WHEN;
|
||||||
new_sig_file);
|
new_sig_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@load-plugin{WS}{ID} {
|
||||||
|
const char* plugin = skip_whitespace(yytext + 12);
|
||||||
|
plugin_mgr->ActivateDynamicPlugin(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
@unload{WS}{FILE} {
|
@unload{WS}{FILE} {
|
||||||
// Skip "@unload".
|
// Skip "@unload".
|
||||||
const char* new_file = skip_whitespace(yytext + 7);
|
const char* new_file = skip_whitespace(yytext + 7);
|
||||||
|
@ -829,6 +834,17 @@ void add_input_file(const char* file)
|
||||||
input_files.append(copy_string(file));
|
input_files.append(copy_string(file));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void add_input_file_at_front(const char* file)
|
||||||
|
{
|
||||||
|
if ( ! file )
|
||||||
|
reporter->InternalError("empty filename");
|
||||||
|
|
||||||
|
if ( ! filename )
|
||||||
|
(void) load_files(file);
|
||||||
|
else
|
||||||
|
input_files.insert(copy_string(file));
|
||||||
|
}
|
||||||
|
|
||||||
void add_to_name_list(char* s, char delim, name_list& nl)
|
void add_to_name_list(char* s, char delim, name_list& nl)
|
||||||
{
|
{
|
||||||
while ( s )
|
while ( s )
|
||||||
|
|
|
@ -664,6 +664,13 @@ string strreplace(const string& s, const string& o, const string& n)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string strstrip(std::string s)
|
||||||
|
{
|
||||||
|
s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
|
||||||
|
s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
int hmac_key_set = 0;
|
int hmac_key_set = 0;
|
||||||
uint8 shared_hmac_md5_key[16];
|
uint8 shared_hmac_md5_key[16];
|
||||||
|
|
||||||
|
@ -942,7 +949,7 @@ const char* bro_magic_path()
|
||||||
|
|
||||||
const char* bro_plugin_path()
|
const char* bro_plugin_path()
|
||||||
{
|
{
|
||||||
const char* path = getenv("BRO_PLUGINS");
|
const char* path = getenv("BRO_PLUGIN_PATH");
|
||||||
|
|
||||||
if ( ! path )
|
if ( ! path )
|
||||||
path = BRO_PLUGIN_INSTALL_PATH;
|
path = BRO_PLUGIN_INSTALL_PATH;
|
||||||
|
|
|
@ -155,6 +155,9 @@ bool is_file(const std::string& path);
|
||||||
// Replaces all occurences of *o* in *s* with *n*.
|
// Replaces all occurences of *o* in *s* with *n*.
|
||||||
extern std::string strreplace(const std::string& s, const std::string& o, const std::string& n);
|
extern std::string strreplace(const std::string& s, const std::string& o, const std::string& n);
|
||||||
|
|
||||||
|
// Remove all leading and trainling white space from string.
|
||||||
|
extern std::string strstrip(std::string s);
|
||||||
|
|
||||||
extern uint8 shared_hmac_md5_key[16];
|
extern uint8 shared_hmac_md5_key[16];
|
||||||
|
|
||||||
extern int hmac_key_set;
|
extern int hmac_key_set;
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
# @TEST-EXEC: ${DIST}/aux/bro-aux/plugin-support/init-plugin Demo Foo
|
# @TEST-EXEC: ${DIST}/aux/bro-aux/plugin-support/init-plugin Demo Foo
|
||||||
# @TEST-EXEC: cp -r %DIR/analyzer-plugin/* .
|
# @TEST-EXEC: cp -r %DIR/analyzer-plugin/* .
|
||||||
# @TEST-EXEC: make BRO=${DIST}
|
# @TEST-EXEC: make BRO=${DIST}
|
||||||
# @TEST-EXEC: BROPLUGINS=`pwd` bro -NN | awk '/^Plugin:.*Demo/ {p=1; print; next} /^Plugin:/{p=0} p==1{print}' >>output
|
# @TEST-EXEC: BRO_PLUGIN_PATH=`pwd` bro -NN | awk '/^Plugin:.*Demo/ {p=1; print; next} /^Plugin:/{p=0} p==1{print}' >>output
|
||||||
# @TEST-EXEC: echo === >>output
|
# @TEST-EXEC: echo === >>output
|
||||||
# @TEST-EXEC: BROPLUGINS=`pwd` bro -r $TRACES/port4242.trace %INPUT >>output
|
# @TEST-EXEC: BRO_PLUGIN_PATH=`pwd` bro -r $TRACES/port4242.trace %INPUT >>output
|
||||||
# @TEST-EXEC: btest-diff output
|
# @TEST-EXEC: btest-diff output
|
||||||
|
|
||||||
event foo_message(c: connection, data: string)
|
event foo_message(c: connection, data: string)
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
# @TEST-EXEC: ${DIST}/aux/bro-aux/plugin-support/init-plugin Demo Foo
|
# @TEST-EXEC: ${DIST}/aux/bro-aux/plugin-support/init-plugin Demo Foo
|
||||||
# @TEST-EXEC: bash %INPUT
|
# @TEST-EXEC: bash %INPUT
|
||||||
# @TEST-EXEC: make BRO=${DIST}
|
# @TEST-EXEC: make BRO=${DIST}
|
||||||
# @TEST-EXEC: BROPLUGINS=`pwd` bro -NN | awk '/^Plugin:.*Demo/ {p=1; print; next} /^Plugin:/{p=0} p==1{print}' >>output
|
# @TEST-EXEC: BRO_PLUGIN_PATH=`pwd` bro -NN | awk '/^Plugin:.*Demo/ {p=1; print; next} /^Plugin:/{p=0} p==1{print}' >>output
|
||||||
# @TEST-EXEC: echo === >>output
|
# @TEST-EXEC: echo === >>output
|
||||||
# @TEST-EXEC: BROPLUGINS=`pwd` bro -r $TRACES/empty.trace >>output
|
# @TEST-EXEC: BRO_PLUGIN_PATH=`pwd` bro -r $TRACES/empty.trace >>output
|
||||||
# @TEST-EXEC: echo === >>output
|
# @TEST-EXEC: echo === >>output
|
||||||
# @TEST-EXEC: BROPLUGINS=`pwd` bro demo/foo -r $TRACES/empty.trace >>output
|
# @TEST-EXEC: BRO_PLUGIN_PATH=`pwd` bro demo/foo -r $TRACES/empty.trace >>output
|
||||||
# @TEST-EXEC: btest-diff output
|
# @TEST-EXEC: btest-diff output
|
||||||
|
|
||||||
cat >scripts/__load__.bro <<EOF
|
cat >scripts/__load__.bro <<EOF
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue