Update script search logic for new file extension

When searching for script files, look for both the new and old file
extensions.  If a file with ".zeek" can't be found, then search for
a file with ".bro" as a fallback.
This commit is contained in:
Daniel Thayer 2019-04-09 01:26:16 -05:00
parent bff8392ad4
commit 7366155bad
9 changed files with 129 additions and 43 deletions

View file

@ -348,7 +348,7 @@ vector<ParseLocationRec> parse_location_string(const string& s)
if ( ! sscanf(line_string.c_str(), "%d", &plr.line) ) if ( ! sscanf(line_string.c_str(), "%d", &plr.line) )
plr.type = plrUnknown; plr.type = plrUnknown;
string path(find_file(filename, bro_path(), "bro")); string path(find_script_file(filename, bro_path()));
if ( path.empty() ) if ( path.empty() )
{ {

View file

@ -295,7 +295,7 @@ void OSFingerprint::load_config(const char* file)
char buf[MAXLINE]; char buf[MAXLINE];
char* p; char* p;
FILE* c = open_file(find_file(file, bro_path(), "osf")); FILE* c = open_file(find_file(file, bro_path(), ".osf"));
if (!c) if (!c)
{ {

View file

@ -235,7 +235,7 @@ bool RuleMatcher::ReadFiles(const name_list& files)
for ( int i = 0; i < files.length(); ++i ) for ( int i = 0; i < files.length(); ++i )
{ {
rules_in = open_file(find_file(files[i], bro_path(), "sig")); rules_in = open_file(find_file(files[i], bro_path(), ".sig"));
if ( ! rules_in ) if ( ! rules_in )
{ {

View file

@ -158,7 +158,7 @@ static string make_redef_details(const string& heading, char underline,
ScriptInfo::ScriptInfo(const string& arg_name, const string& arg_path) ScriptInfo::ScriptInfo(const string& arg_name, const string& arg_path)
: Info(), : Info(),
name(arg_name), path(arg_path), name(arg_name), path(arg_path),
is_pkg_loader(SafeBasename(name).result == PACKAGE_LOADER), is_pkg_loader(is_package_loader(SafeBasename(name).result)),
dependencies(), module_usages(), comments(), id_info(), dependencies(), module_usages(), comments(), id_info(),
redef_options(), constants(), state_vars(), types(), events(), hooks(), redef_options(), constants(), state_vars(), types(), events(), hooks(),
functions(), redefs() functions(), redefs()
@ -314,7 +314,7 @@ string ScriptInfo::DoReStructuredText(bool roles_only) const
if ( it != dependencies.begin() ) if ( it != dependencies.begin() )
rval += ", "; rval += ", ";
string path = find_file(*it, bro_path(), "bro"); string path = find_script_file(*it, bro_path());
string doc = *it; string doc = *it;
if ( ! path.empty() && is_dir(path.c_str()) ) if ( ! path.empty() && is_dir(path.c_str()) )
@ -365,8 +365,13 @@ time_t ScriptInfo::DoGetModificationTime() const
if ( ! info ) if ( ! info )
{ {
string pkg_name = *it + "/" + PACKAGE_LOADER; for (const string& ext : script_extensions)
info = broxygen_mgr->GetScriptInfo(pkg_name); {
string pkg_name = *it + "/__load__" + ext;
info = broxygen_mgr->GetScriptInfo(pkg_name);
if ( info )
break;
}
if ( ! info ) if ( ! info )
reporter->InternalWarning("Broxygen failed to get mtime of %s", reporter->InternalWarning("Broxygen failed to get mtime of %s",

View file

@ -410,7 +410,7 @@ void ScriptTarget::DoFindDependencies(const vector<Info*>& infos)
for ( size_t i = 0; i < script_deps.size(); ++i ) for ( size_t i = 0; i < script_deps.size(); ++i )
{ {
if ( SafeBasename(script_deps[i]->Name()).result == PACKAGE_LOADER ) if ( is_package_loader(SafeBasename(script_deps[i]->Name()).result) )
{ {
string pkg_dir = SafeDirname(script_deps[i]->Name()).result; string pkg_dir = SafeDirname(script_deps[i]->Name()).result;
string target_file = Name() + pkg_dir + "/index.rst"; string target_file = Name() + pkg_dir + "/index.rst";

View file

@ -13,6 +13,7 @@
#include "../Reporter.h" #include "../Reporter.h"
#include "../Func.h" #include "../Func.h"
#include "../Event.h" #include "../Event.h"
#include "../util.h"
using namespace plugin; using namespace plugin;
@ -182,30 +183,44 @@ bool Manager::ActivateDynamicPluginInternal(const std::string& name, bool ok_if_
add_to_bro_path(scripts); add_to_bro_path(scripts);
} }
// First load {scripts}/__preload__.bro automatically. string init;
string init = dir + "scripts/__preload__.bro";
if ( is_file(init) ) // First load {scripts}/__preload__.bro automatically.
for (const string& ext : script_extensions)
{ {
DBG_LOG(DBG_PLUGINS, " Loading %s", init.c_str()); init = dir + "scripts/__preload__" + ext;
scripts_to_load.push_back(init);
if ( is_file(init) )
{
DBG_LOG(DBG_PLUGINS, " Loading %s", init.c_str());
scripts_to_load.push_back(init);
break;
}
} }
// Load {bif,scripts}/__load__.bro automatically. // Load {bif,scripts}/__load__.bro automatically.
init = dir + "lib/bif/__load__.bro"; for (const string& ext : script_extensions)
if ( is_file(init) )
{ {
DBG_LOG(DBG_PLUGINS, " Loading %s", init.c_str()); init = dir + "lib/bif/__load__" + ext;
scripts_to_load.push_back(init);
if ( is_file(init) )
{
DBG_LOG(DBG_PLUGINS, " Loading %s", init.c_str());
scripts_to_load.push_back(init);
break;
}
} }
init = dir + "scripts/__load__.bro"; for (const string& ext : script_extensions)
if ( is_file(init) )
{ {
DBG_LOG(DBG_PLUGINS, " Loading %s", init.c_str()); init = dir + "scripts/__load__" + ext;
scripts_to_load.push_back(init);
if ( is_file(init) )
{
DBG_LOG(DBG_PLUGINS, " Loading %s", init.c_str());
scripts_to_load.push_back(init);
break;
}
} }
// Load shared libraries. // Load shared libraries.

View file

@ -77,6 +77,17 @@ static string find_relative_file(const string& filename, const string& ext)
return find_file(filename, bro_path(), ext); return find_file(filename, bro_path(), ext);
} }
static string find_relative_script_file(const string& filename)
{
if ( filename.empty() )
return string();
if ( filename[0] == '.' )
return find_script_file(filename, SafeDirname(::filename).result);
else
return find_script_file(filename, bro_path());
}
static ino_t get_inode_num(FILE* f, const string& path) static ino_t get_inode_num(FILE* f, const string& path)
{ {
struct stat b; struct stat b;
@ -363,14 +374,14 @@ when return TOK_WHEN;
@load{WS}{FILE} { @load{WS}{FILE} {
const char* new_file = skip_whitespace(yytext + 5); // Skip "@load". const char* new_file = skip_whitespace(yytext + 5); // Skip "@load".
string loader = ::filename; // load_files may change ::filename, save copy string loader = ::filename; // load_files may change ::filename, save copy
string loading = find_relative_file(new_file, "bro"); string loading = find_relative_script_file(new_file);
(void) load_files(new_file); (void) load_files(new_file);
broxygen_mgr->ScriptDependency(loader, loading); broxygen_mgr->ScriptDependency(loader, loading);
} }
@load-sigs{WS}{FILE} { @load-sigs{WS}{FILE} {
const char* file = skip_whitespace(yytext + 10); const char* file = skip_whitespace(yytext + 10);
string path = find_relative_file(file, "sig"); string path = find_relative_file(file, ".sig");
int rc = PLUGIN_HOOK_WITH_RESULT(HOOK_LOAD_FILE, HookLoadFile(plugin::Plugin::SIGNATURES, file, path), -1); int rc = PLUGIN_HOOK_WITH_RESULT(HOOK_LOAD_FILE, HookLoadFile(plugin::Plugin::SIGNATURES, file, path), -1);
switch ( rc ) { switch ( rc ) {
@ -430,7 +441,7 @@ when return TOK_WHEN;
@unload{WS}{FILE} { @unload{WS}{FILE} {
// Skip "@unload". // Skip "@unload".
const char* file = skip_whitespace(yytext + 7); const char* file = skip_whitespace(yytext + 7);
string path = find_relative_file(file, "bro"); string path = find_relative_script_file(file);
if ( path.empty() ) if ( path.empty() )
reporter->Error("failed find file associated with @unload %s", file); reporter->Error("failed find file associated with @unload %s", file);
@ -624,7 +635,7 @@ static bool already_scanned(const string& path)
static int load_files(const char* orig_file) static int load_files(const char* orig_file)
{ {
string file_path = find_relative_file(orig_file, "bro"); string file_path = find_relative_script_file(orig_file);
int rc = PLUGIN_HOOK_WITH_RESULT(HOOK_LOAD_FILE, HookLoadFile(plugin::Plugin::SCRIPT, orig_file, file_path), -1); int rc = PLUGIN_HOOK_WITH_RESULT(HOOK_LOAD_FILE, HookLoadFile(plugin::Plugin::SCRIPT, orig_file, file_path), -1);
if ( rc == 1 ) if ( rc == 1 )
@ -970,7 +981,7 @@ int yywrap()
string canon = without_bropath_component(it->name); string canon = without_bropath_component(it->name);
string flat = flatten_script_name(canon, prefixes[i]); string flat = flatten_script_name(canon, prefixes[i]);
string path = find_relative_file(flat, "bro"); string path = find_relative_script_file(flat);
if ( ! path.empty() ) if ( ! path.empty() )
{ {

View file

@ -20,6 +20,7 @@
#endif #endif
#include <string> #include <string>
#include <array>
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
#include <ctype.h> #include <ctype.h>
@ -1007,7 +1008,18 @@ string bro_prefixes()
return rval; return rval;
} }
const char* PACKAGE_LOADER = "__load__.bro"; const array<string, 2> script_extensions = {".zeek", ".bro"};
bool is_package_loader(const string& path)
{
for (const string& ext : script_extensions)
{
if (path == "__load__" + ext)
return true;
}
return false;
}
FILE* open_file(const string& path, const string& mode) FILE* open_file(const string& path, const string& mode)
{ {
@ -1034,13 +1046,22 @@ static bool can_read(const string& path)
FILE* open_package(string& path, const string& mode) FILE* open_package(string& path, const string& mode)
{ {
string arg_path = path; string arg_path = path;
path.append("/").append(PACKAGE_LOADER); path.append("/__load__");
if ( can_read(path) ) for (const string& ext : script_extensions)
return open_file(path, mode); {
string p = path + ext;
if ( can_read(p) )
{
path.append(ext);
return open_file(path, mode);
}
}
path.append(script_extensions[0]);
string package_loader = "__load__" + script_extensions[0];
reporter->Error("Failed to open package '%s': missing '%s' file", reporter->Error("Failed to open package '%s': missing '%s' file",
arg_path.c_str(), PACKAGE_LOADER); arg_path.c_str(), package_loader.c_str());
return 0; return 0;
} }
@ -1123,7 +1144,7 @@ string flatten_script_name(const string& name, const string& prefix)
if ( ! rval.empty() ) if ( ! rval.empty() )
rval.append("."); rval.append(".");
if ( SafeBasename(name).result == PACKAGE_LOADER ) if ( is_package_loader(SafeBasename(name).result) )
rval.append(SafeDirname(name).result); rval.append(SafeDirname(name).result);
else else
rval.append(name); rval.append(name);
@ -1221,7 +1242,7 @@ string without_bropath_component(const string& path)
} }
static string find_file_in_path(const string& filename, const string& path, static string find_file_in_path(const string& filename, const string& path,
const string& opt_ext = "") const vector<string>& opt_ext)
{ {
if ( filename.empty() ) if ( filename.empty() )
return string(); return string();
@ -1239,10 +1260,13 @@ static string find_file_in_path(const string& filename, const string& path,
if ( ! opt_ext.empty() ) if ( ! opt_ext.empty() )
{ {
string with_ext = abs_path + '.' + opt_ext; for (const string& ext : opt_ext)
{
string with_ext = abs_path + ext;
if ( can_read(with_ext) ) if ( can_read(with_ext) )
return with_ext; return with_ext;
}
} }
if ( can_read(abs_path) ) if ( can_read(abs_path) )
@ -1257,9 +1281,31 @@ string find_file(const string& filename, const string& path_set,
vector<string> paths; vector<string> paths;
tokenize_string(path_set, ":", &paths); tokenize_string(path_set, ":", &paths);
vector<string> ext;
if ( ! opt_ext.empty() )
ext.push_back(opt_ext);
for ( size_t n = 0; n < paths.size(); ++n ) for ( size_t n = 0; n < paths.size(); ++n )
{ {
string f = find_file_in_path(filename, paths[n], opt_ext); string f = find_file_in_path(filename, paths[n], ext);
if ( ! f.empty() )
return f;
}
return string();
}
string find_script_file(const string& filename, const string& path_set)
{
vector<string> paths;
tokenize_string(path_set, ":", &paths);
vector<string> ext(script_extensions.begin(), script_extensions.end());
for ( size_t n = 0; n < paths.size(); ++n )
{
string f = find_file_in_path(filename, paths[n], ext);
if ( ! f.empty() ) if ( ! f.empty() )
return f; return f;

View file

@ -26,6 +26,7 @@
#include <stdint.h> #include <stdint.h>
#include <string> #include <string>
#include <array>
#include <vector> #include <vector>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -248,16 +249,16 @@ static const SourceID SOURCE_BROKER = 0xffffffff;
extern void pinpoint(); extern void pinpoint();
extern int int_list_cmp(const void* v1, const void* v2); extern int int_list_cmp(const void* v1, const void* v2);
// Contains the name of the script file that gets read
// when a package is loaded (i.e., "__load__.bro).
extern const char* PACKAGE_LOADER;
extern const std::string& bro_path(); extern const std::string& bro_path();
extern const char* bro_magic_path(); extern const char* bro_magic_path();
extern const char* bro_plugin_path(); extern const char* bro_plugin_path();
extern const char* bro_plugin_activate(); extern const char* bro_plugin_activate();
extern std::string bro_prefixes(); extern std::string bro_prefixes();
extern const std::array<std::string, 2> script_extensions;
bool is_package_loader(const std::string& path);
extern void add_to_bro_path(const std::string& dir); extern void add_to_bro_path(const std::string& dir);
@ -341,6 +342,14 @@ std::string without_bropath_component(const std::string& path);
std::string find_file(const std::string& filename, const std::string& path_set, std::string find_file(const std::string& filename, const std::string& path_set,
const std::string& opt_ext = ""); const std::string& opt_ext = "");
/**
* Locate a script file within a given search path.
* @param filename Name of a file to find.
* @param path_set Colon-delimited set of paths to search for the file.
* @return Path to the found file, or an empty string if not found.
*/
std::string find_script_file(const std::string& filename, const std::string& path_set);
// Wrapper around fopen(3). Emits an error when failing to open. // Wrapper around fopen(3). Emits an error when failing to open.
FILE* open_file(const std::string& path, const std::string& mode = "r"); FILE* open_file(const std::string& path, const std::string& mode = "r");