Source file path control for Input and Intel frameworks

This introduces the following redefinable string constants, empty by
default:

- InputAscii::path_prefix
- InputBinary::path_prefix
- Intel::path_prefix

When using ASCII or binary reades in the Input/Intel Framework with an
input stream source that does not have an absolute path, these
constants cause Zeek to prefix the resulting paths accordingly. For
example, in the following the location on disk from which Zeek loads
the input becomes "/path/to/input/whitelist.data":

redef InputAscii::path_prefix = "/path/to/input";

event bro_init()
        {
        Input::add_table([$source="whitelist.data", ...]);
	}

These path prefixes can be absolute or relative. When an input stream
source already uses an absolute path, this path is preserved and the
new variables have no effect (i.e., we do not affect configurations
already using absolute paths).

Since the Intel framework builds upon the Input framework, the first
two paths also affect Intel file locations. If this is undesirable,
the Intel::path_prefix variable allows specifying a separate path:
when its value is absolute, the resulting source seen by the Input
framework is absolute, therefore no further changes to the paths
happen.
This commit is contained in:
Christian Kreibich 2019-03-13 23:14:14 -07:00
parent 389fe2bc2a
commit 3f02c0a67c
37 changed files with 483 additions and 8 deletions

View file

@ -82,6 +82,9 @@ bool Ascii::DoInit(const ReaderInfo& info, int num_fields, const Field* const* f
fail_on_invalid_lines = BifConst::InputAscii::fail_on_invalid_lines;
fail_on_file_problem = BifConst::InputAscii::fail_on_file_problem;
path_prefix.assign( (const char*) BifConst::InputAscii::path_prefix->Bytes(),
BifConst::InputAscii::path_prefix->Len());
// Set per-filter configuration options.
for ( ReaderInfo::config_map::const_iterator i = info.config.begin(); i != info.config.end(); i++ )
{
@ -137,18 +140,34 @@ bool Ascii::OpenFile()
if ( file.is_open() )
return true;
file.open(Info().source);
// Handle path-prefixing. See similar logic in Binary::DoInit().
fname = Info().source;
if ( fname.front() != '/' && ! path_prefix.empty() )
{
string path = path_prefix;
std::size_t last = path.find_last_not_of("/");
if ( last == string::npos ) // Nothing but slashes -- weird but ok...
path = "/";
else
path.erase(last + 1);
fname = path + "/" + fname;
}
file.open(fname);
if ( ! file.is_open() )
{
FailWarn(fail_on_file_problem, Fmt("Init: cannot open %s", Info().source), true);
FailWarn(fail_on_file_problem, Fmt("Init: cannot open %s", fname.c_str()), true);
return ! fail_on_file_problem;
}
if ( ReadHeader(false) == false )
{
FailWarn(fail_on_file_problem, Fmt("Init: cannot open %s; problem reading file header", Info().source), true);
FailWarn(fail_on_file_problem, Fmt("Init: cannot open %s; problem reading file header", fname.c_str()), true);
file.close();
return ! fail_on_file_problem;
@ -169,7 +188,7 @@ bool Ascii::ReadHeader(bool useCached)
if ( ! GetLine(line) )
{
FailWarn(fail_on_file_problem, Fmt("Could not read input data file %s; first line could not be read",
Info().source), true);
fname.c_str()), true);
return false;
}
@ -212,7 +231,7 @@ bool Ascii::ReadHeader(bool useCached)
}
FailWarn(fail_on_file_problem, Fmt("Did not find requested field %s in input data file %s.",
field->name, Info().source), true);
field->name, fname.c_str()), true);
return false;
}
@ -274,9 +293,9 @@ bool Ascii::DoUpdate()
{
// check if the file has changed
struct stat sb;
if ( stat(Info().source, &sb) == -1 )
if ( stat(fname.c_str(), &sb) == -1 )
{
FailWarn(fail_on_file_problem, Fmt("Could not get stat for %s", Info().source), true);
FailWarn(fail_on_file_problem, Fmt("Could not get stat for %s", fname.c_str()), true);
file.close();
return ! fail_on_file_problem;