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) )
plr.type = plrUnknown;
string path(find_file(filename, bro_path(), "bro"));
string path(find_script_file(filename, bro_path()));
if ( path.empty() )
{

View file

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

View file

@ -235,7 +235,7 @@ bool RuleMatcher::ReadFiles(const name_list& files)
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 )
{

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)
: Info(),
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(),
redef_options(), constants(), state_vars(), types(), events(), hooks(),
functions(), redefs()
@ -314,7 +314,7 @@ string ScriptInfo::DoReStructuredText(bool roles_only) const
if ( it != dependencies.begin() )
rval += ", ";
string path = find_file(*it, bro_path(), "bro");
string path = find_script_file(*it, bro_path());
string doc = *it;
if ( ! path.empty() && is_dir(path.c_str()) )
@ -365,8 +365,13 @@ time_t ScriptInfo::DoGetModificationTime() const
if ( ! info )
{
string pkg_name = *it + "/" + PACKAGE_LOADER;
info = broxygen_mgr->GetScriptInfo(pkg_name);
for (const string& ext : script_extensions)
{
string pkg_name = *it + "/__load__" + ext;
info = broxygen_mgr->GetScriptInfo(pkg_name);
if ( info )
break;
}
if ( ! info )
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 )
{
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 target_file = Name() + pkg_dir + "/index.rst";

View file

@ -13,6 +13,7 @@
#include "../Reporter.h"
#include "../Func.h"
#include "../Event.h"
#include "../util.h"
using namespace plugin;
@ -182,30 +183,44 @@ bool Manager::ActivateDynamicPluginInternal(const std::string& name, bool ok_if_
add_to_bro_path(scripts);
}
// First load {scripts}/__preload__.bro automatically.
string init = dir + "scripts/__preload__.bro";
string init;
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());
scripts_to_load.push_back(init);
init = dir + "scripts/__preload__" + ext;
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.
init = dir + "lib/bif/__load__.bro";
if ( is_file(init) )
for (const string& ext : script_extensions)
{
DBG_LOG(DBG_PLUGINS, " Loading %s", init.c_str());
scripts_to_load.push_back(init);
init = dir + "lib/bif/__load__" + ext;
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";
if ( is_file(init) )
for (const string& ext : script_extensions)
{
DBG_LOG(DBG_PLUGINS, " Loading %s", init.c_str());
scripts_to_load.push_back(init);
init = dir + "scripts/__load__" + ext;
if ( is_file(init) )
{
DBG_LOG(DBG_PLUGINS, " Loading %s", init.c_str());
scripts_to_load.push_back(init);
break;
}
}
// 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);
}
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)
{
struct stat b;
@ -363,14 +374,14 @@ when return TOK_WHEN;
@load{WS}{FILE} {
const char* new_file = skip_whitespace(yytext + 5); // Skip "@load".
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);
broxygen_mgr->ScriptDependency(loader, loading);
}
@load-sigs{WS}{FILE} {
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);
switch ( rc ) {
@ -430,7 +441,7 @@ when return TOK_WHEN;
@unload{WS}{FILE} {
// Skip "@unload".
const char* file = skip_whitespace(yytext + 7);
string path = find_relative_file(file, "bro");
string path = find_relative_script_file(file);
if ( path.empty() )
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)
{
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);
if ( rc == 1 )
@ -970,7 +981,7 @@ int yywrap()
string canon = without_bropath_component(it->name);
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() )
{

View file

@ -20,6 +20,7 @@
#endif
#include <string>
#include <array>
#include <vector>
#include <algorithm>
#include <ctype.h>
@ -1007,7 +1008,18 @@ string bro_prefixes()
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)
{
@ -1034,13 +1046,22 @@ static bool can_read(const string& path)
FILE* open_package(string& path, const string& mode)
{
string arg_path = path;
path.append("/").append(PACKAGE_LOADER);
path.append("/__load__");
if ( can_read(path) )
return open_file(path, mode);
for (const string& ext : script_extensions)
{
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",
arg_path.c_str(), PACKAGE_LOADER);
arg_path.c_str(), package_loader.c_str());
return 0;
}
@ -1123,7 +1144,7 @@ string flatten_script_name(const string& name, const string& prefix)
if ( ! rval.empty() )
rval.append(".");
if ( SafeBasename(name).result == PACKAGE_LOADER )
if ( is_package_loader(SafeBasename(name).result) )
rval.append(SafeDirname(name).result);
else
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,
const string& opt_ext = "")
const vector<string>& opt_ext)
{
if ( filename.empty() )
return string();
@ -1239,10 +1260,13 @@ static string find_file_in_path(const string& filename, const string& path,
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) )
return with_ext;
if ( can_read(with_ext) )
return with_ext;
}
}
if ( can_read(abs_path) )
@ -1257,9 +1281,31 @@ string find_file(const string& filename, const string& path_set,
vector<string> 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 )
{
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() )
return f;

View file

@ -26,6 +26,7 @@
#include <stdint.h>
#include <string>
#include <array>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
@ -248,16 +249,16 @@ static const SourceID SOURCE_BROKER = 0xffffffff;
extern void pinpoint();
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 char* bro_magic_path();
extern const char* bro_plugin_path();
extern const char* bro_plugin_activate();
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);
@ -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,
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.
FILE* open_file(const std::string& path, const std::string& mode = "r");