add seeking functionality to raw reader.

one can now add an option "offset" to the config map. Positive offsets
are interpreted to be from the beginning of the file, negative from the
end of the file (-1 is end of file).

Only works for raw reader in streaming or manual mode. Does not work
with executables.

Addresses BIT-985
This commit is contained in:
Johanna Amann 2015-04-17 11:16:31 -07:00
parent ee5f87c634
commit cbba73ab12
4 changed files with 75 additions and 0 deletions

View file

@ -8,6 +8,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <errno.h> #include <errno.h>
#include <signal.h> #include <signal.h>
#include <stdlib.h>
#include "Raw.h" #include "Raw.h"
#include "Plugin.h" #include "Plugin.h"
@ -298,6 +299,17 @@ bool Raw::OpenInput()
Warning(Fmt("Init: cannot set close-on-exec for %s", fname.c_str())); Warning(Fmt("Init: cannot set close-on-exec for %s", fname.c_str()));
} }
if ( offset )
{
int whence = ( offset > 0 ) ? SEEK_SET : SEEK_END;
if ( fseek(file, offset, whence) < 0 )
{
char buf[256];
strerror_r(errno, buf, sizeof(buf));
Error(Fmt("Seek failed in init: %s", buf));
}
}
return true; return true;
} }
@ -377,6 +389,20 @@ bool Raw::DoInit(const ReaderInfo& info, int num_fields, const Field* const* fie
forcekill = true; forcekill = true;
} }
it = info.config.find("offset"); // we want to be sure that our child is dead when we exit
if ( it != info.config.end() && ! execute && ( Info().mode == MODE_STREAM || Info().mode == MODE_MANUAL ) )
{
string offset_s = it->second;
offset = strtoll(offset_s.c_str(), 0, 10);
if ( offset < 0 )
offset++; // we want -1 to be the end of the file
}
else if ( it != info.config.end() )
{
Error("Offset only is supported for MODE_STREAM and MODE_MANUAL; it is also not supported when executing a command");
return false;
}
if ( num_fields != want_fields ) if ( num_fields != want_fields )
{ {
Error(Fmt("Filter for raw reader contains wrong number of fields -- got %d, expected %d. " Error(Fmt("Filter for raw reader contains wrong number of fields -- got %d, expected %d. "

View file

@ -65,6 +65,8 @@ private:
bool forcekill; bool forcekill;
int64_t offset;
int pipes[6]; int pipes[6];
pid_t childpid; pid_t childpid;

View file

@ -0,0 +1,2 @@
fkh:KH;fdkncv;ISEUp34:Fkdj;YVpIODhfDF
F

View file

@ -0,0 +1,45 @@
# @TEST-EXEC: btest-bg-run bro bro -b %INPUT
# @TEST-EXEC: btest-bg-wait 5
# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-sort btest-diff out
@TEST-START-FILE input.log
sdfkh:KH;fdkncv;ISEUp34:Fkdj;YVpIODhfDF
@TEST-END-FILE
redef exit_only_after_terminate = T;
global outfile: file;
global try: count;
module A;
type Val: record {
s: string;
};
event line(description: Input::EventDescription, tpe: Input::Event, s: string)
{
print outfile, s;
try = try + 1;
if ( try == 2 )
{
Input::remove("input");
close(outfile);
terminate();
}
}
event bro_init()
{
try = 0;
outfile = open("../out");
local config_strings: table[string] of string = {
["offset"] = "2",
};
local config_strings_two: table[string] of string = {
["offset"] = "-3", # 2 characters before end, last char is newline.
};
Input::add_event([$source="../input.log", $config=config_strings, $reader=Input::READER_RAW, $mode=Input::STREAM, $name="input", $fields=Val, $ev=line, $want_record=F]);
Input::add_event([$source="../input.log", $config=config_strings_two, $reader=Input::READER_RAW, $mode=Input::STREAM, $name="input2", $fields=Val, $ev=line, $want_record=F]);
}