mirror of
https://github.com/zeek/zeek.git
synced 2025-10-08 09:38:19 +00:00
many helper functions
This commit is contained in:
parent
3654060246
commit
d7a3b85fcd
6 changed files with 245 additions and 31 deletions
|
@ -100,31 +100,62 @@ InputReader* InputMgr::CreateReader(EnumVal* reader, RecordVal* description)
|
||||||
|
|
||||||
void InputMgr::Error(InputReader* reader, const char* msg)
|
void InputMgr::Error(InputReader* reader, const char* msg)
|
||||||
{
|
{
|
||||||
reporter->Error(fmt("error with input reader for %s: %s",
|
reporter->Error("error with input reader for %s: %s", reader->Source().c_str(), msg);
|
||||||
reader->Source().c_str(), msg));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
TODO:
|
|
||||||
|
|
||||||
void InputMgr::SendEvent(string name) {
|
void InputMgr::SendEvent(const string& name, const int num_vals, const LogVal* const *vals)
|
||||||
//EventHandler* handler = event_registry->Lookup(eventName.c_str());
|
{
|
||||||
|
EventHandler* handler = event_registry->Lookup(name.c_str());
|
||||||
//if ( handler == 0 ) {
|
if ( handler == 0 ) {
|
||||||
// reporter->Error("Event %s not found", eventName.c_str());
|
reporter->Error("Event %s not found", name.c_str());
|
||||||
// return false;
|
return;
|
||||||
//}
|
}
|
||||||
|
|
||||||
//val_list* vl = new val_list;
|
|
||||||
//vl->append(new Val(12, TYPE_COUNT));
|
|
||||||
|
|
||||||
//mgr.Dispatch(new Event(handler, vl));
|
|
||||||
|
|
||||||
|
val_list* vl = new val_list;
|
||||||
|
for ( int i = 0; i < num_vals; i++) {
|
||||||
|
vl->append(LogValToVal(vals[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
mgr.Dispatch(new Event(handler, vl));
|
||||||
}
|
}
|
||||||
|
|
||||||
*/
|
Val* InputMgr::LogValToVal(const LogVal* val) {
|
||||||
|
switch ( val->type ) {
|
||||||
|
case TYPE_BOOL:
|
||||||
|
case TYPE_INT:
|
||||||
|
return new Val(val->val.int_val, val->type);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TYPE_COUNT:
|
||||||
|
case TYPE_COUNTER:
|
||||||
|
return new Val(val->val.uint_val, val->type);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TYPE_DOUBLE:
|
||||||
|
case TYPE_TIME:
|
||||||
|
case TYPE_INTERVAL:
|
||||||
|
return new Val(val->val.double_val, val->type);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TYPE_STRING:
|
||||||
|
{
|
||||||
|
BroString *s = new BroString(*(val->val.string_val));
|
||||||
|
return new StringVal(s);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TYPE_PORT:
|
||||||
|
return new PortVal(val->val.uint_val);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
reporter->InternalError("unsupported type for input_read");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
reporter->InternalError("Impossible error");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
|
|
||||||
class InputReader;
|
class InputReader;
|
||||||
|
|
||||||
|
|
||||||
class InputMgr {
|
class InputMgr {
|
||||||
public:
|
public:
|
||||||
InputMgr();
|
InputMgr();
|
||||||
|
@ -29,6 +28,9 @@ protected:
|
||||||
private:
|
private:
|
||||||
// required functionality
|
// required functionality
|
||||||
// InputValsToRecord to convert received inputvals back to bro records / tables / whatever
|
// InputValsToRecord to convert received inputvals back to bro records / tables / whatever
|
||||||
|
Val* LogValToVal(const LogVal* val);
|
||||||
|
|
||||||
|
void SendEvent(const string& name, const int num_vals, const LogVal* const *vals);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -33,3 +33,34 @@ bool InputReader::Init(string arg_source, int arg_num_fields,
|
||||||
void InputReader::Finish() {
|
void InputReader::Finish() {
|
||||||
DoFinish();
|
DoFinish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool InputReader::Update() {
|
||||||
|
return DoUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// stolen from logwriter
|
||||||
|
const char* InputReader::Fmt(const char* format, ...)
|
||||||
|
{
|
||||||
|
if ( ! buf )
|
||||||
|
buf = (char*) malloc(buf_len);
|
||||||
|
|
||||||
|
va_list al;
|
||||||
|
va_start(al, format);
|
||||||
|
int n = safe_vsnprintf(buf, buf_len, format, al);
|
||||||
|
va_end(al);
|
||||||
|
|
||||||
|
if ( (unsigned int) n >= buf_len )
|
||||||
|
{ // Not enough room, grow the buffer.
|
||||||
|
buf_len = n + 32;
|
||||||
|
buf = (char*) realloc(buf, buf_len);
|
||||||
|
|
||||||
|
// Is it portable to restart?
|
||||||
|
va_start(al, format);
|
||||||
|
n = safe_vsnprintf(buf, buf_len, format, al);
|
||||||
|
va_end(al);
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -19,18 +19,26 @@ public:
|
||||||
|
|
||||||
void Finish();
|
void Finish();
|
||||||
|
|
||||||
|
bool Update();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Methods that have to be overwritten by the individual readers
|
// Methods that have to be overwritten by the individual readers
|
||||||
virtual bool DoInit(string arg_source, int num_fields, const LogField* const * fields) = 0;
|
virtual bool DoInit(string arg_source, int num_fields, const LogField* const * fields) = 0;
|
||||||
|
|
||||||
virtual void DoFinish() = 0;
|
virtual void DoFinish() = 0;
|
||||||
|
|
||||||
|
// update file contents to logmgr
|
||||||
|
virtual bool DoUpdate() = 0;
|
||||||
|
|
||||||
// Reports an error to the user.
|
// Reports an error to the user.
|
||||||
void Error(const char *msg);
|
void Error(const char *msg);
|
||||||
|
|
||||||
// The following methods return the information as passed to Init().
|
// The following methods return the information as passed to Init().
|
||||||
const string Source() const { return source; }
|
const string Source() const { return source; }
|
||||||
|
|
||||||
|
// A thread-safe version of fmt(). (stolen from logwriter)
|
||||||
|
const char* Fmt(const char* format, ...);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class InputMgr;
|
friend class InputMgr;
|
||||||
|
|
||||||
|
@ -44,6 +52,10 @@ private:
|
||||||
bool disabled;
|
bool disabled;
|
||||||
|
|
||||||
bool Disabled() { return disabled; }
|
bool Disabled() { return disabled; }
|
||||||
|
|
||||||
|
// For implementing Fmt().
|
||||||
|
char* buf;
|
||||||
|
unsigned int buf_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,22 @@
|
||||||
|
// See the file "COPYING" in the main distribution directory for copyright.
|
||||||
|
|
||||||
#include "InputReaderAscii.h"
|
#include "InputReaderAscii.h"
|
||||||
#include "DebugLogger.h"
|
#include "DebugLogger.h"
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
FieldMapping::FieldMapping(const string& arg_name, const TypeTag& arg_type, int arg_position)
|
||||||
|
: name(arg_name), type(arg_type)
|
||||||
|
{
|
||||||
|
position = arg_position;
|
||||||
|
}
|
||||||
|
|
||||||
|
FieldMapping::FieldMapping(const FieldMapping& arg)
|
||||||
|
: name(arg.name), type(arg.type)
|
||||||
|
{
|
||||||
|
position = arg.position;
|
||||||
|
}
|
||||||
|
|
||||||
InputReaderAscii::InputReaderAscii()
|
InputReaderAscii::InputReaderAscii()
|
||||||
{
|
{
|
||||||
//DBG_LOG(DBG_LOGGING, "input reader initialized");
|
//DBG_LOG(DBG_LOGGING, "input reader initialized");
|
||||||
|
@ -18,31 +31,134 @@ void InputReaderAscii::DoFinish()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InputReaderAscii::DoInit(string path, int num_fields,
|
bool InputReaderAscii::DoInit(string path, int num_fields, const LogField* const * fields)
|
||||||
const LogField* const * fields)
|
|
||||||
{
|
{
|
||||||
fname = path;
|
fname = path;
|
||||||
|
|
||||||
file = new ifstream(path.c_str());
|
file = new ifstream(path.c_str());
|
||||||
if ( !file->is_open() ) {
|
if ( !file->is_open() ) {
|
||||||
|
Error(Fmt("cannot open %s", path.c_str()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// try to read the header line...
|
// try to read the header line...
|
||||||
string line;
|
string line;
|
||||||
if ( !getline(*file, line) )
|
if ( !getline(*file, line) ) {
|
||||||
|
Error("could not read first line");
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// split on tabs...
|
// split on tabs...
|
||||||
istringstream ss(line);
|
istringstream splitstream(line);
|
||||||
while ( ss ) {
|
unsigned int currTab = 0;
|
||||||
|
int wantFields = 0;
|
||||||
|
while ( splitstream ) {
|
||||||
string s;
|
string s;
|
||||||
if ( !getline(ss, s, '\t'))
|
if ( !getline(splitstream, s, '\t'))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// current found heading in s... compare if we want it
|
||||||
|
for ( int i = 0; i < num_fields; i++ ) {
|
||||||
|
const LogField* field = fields[i];
|
||||||
|
if ( field->name == s ) {
|
||||||
|
// cool, found field. note position
|
||||||
|
FieldMapping f(field->name, field->type, i);
|
||||||
|
columnMap.push_back(f);
|
||||||
|
wantFields++;
|
||||||
|
break; // done with searching
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// look if we did push something...
|
||||||
|
if ( columnMap.size() == currTab ) {
|
||||||
|
// no, we didn't. note that...
|
||||||
|
FieldMapping empty;
|
||||||
|
columnMap.push_back(empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
// done
|
||||||
|
currTab++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( wantFields != num_fields ) {
|
||||||
|
// we did not find all fields?
|
||||||
|
// :(
|
||||||
|
Error("wantFields != num_fields");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return false;
|
this->num_fields = num_fields;
|
||||||
|
|
||||||
|
// well, that seems to have worked...
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// read the entire file and send appropriate thingies back to InputMgr
|
||||||
|
bool InputReaderAscii::DoUpdate() {
|
||||||
|
// TODO: all the stuff we need for a second reading.
|
||||||
|
// *cough*
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
string line;
|
||||||
|
while ( getline(*file, line ) ) {
|
||||||
|
// split on tabs
|
||||||
|
|
||||||
|
istringstream splitstream(line);
|
||||||
|
string s;
|
||||||
|
|
||||||
|
LogVal fields[num_fields];
|
||||||
|
|
||||||
|
unsigned int currTab = 0;
|
||||||
|
unsigned int currField = 0;
|
||||||
|
while ( splitstream ) {
|
||||||
|
if ( !getline(splitstream, s, '\t') )
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
if ( currTab >= columnMap.size() ) {
|
||||||
|
Error("Tabs in heading do not match tabs in data?");
|
||||||
|
//disabled = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
FieldMapping currMapping = columnMap[currTab];
|
||||||
|
currTab++;
|
||||||
|
|
||||||
|
if ( currMapping.IsEmpty() ) {
|
||||||
|
// well, that was easy
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( currField >= num_fields ) {
|
||||||
|
Error("internal error - fieldnum greater as possible");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogVal val(currMapping.type, true);
|
||||||
|
|
||||||
|
switch ( currMapping.type ) {
|
||||||
|
case TYPE_STRING:
|
||||||
|
val.val.string_val = new string(s);
|
||||||
|
|
||||||
|
default:
|
||||||
|
Error(Fmt("unsupported field format %d for %s", currMapping.type,
|
||||||
|
currMapping.name.c_str()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
currField++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( currField != num_fields ) {
|
||||||
|
Error("curr_field != num_fields in DoUpdate");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ok, now we have built our line. send it back to... whomever.
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
// See the file "COPYING" in the main distribution directory for copyright.
|
||||||
|
|
||||||
#ifndef INPUTREADERASCII_H
|
#ifndef INPUTREADERASCII_H
|
||||||
#define INPUTREADERASCII_H
|
#define INPUTREADERASCII_H
|
||||||
|
@ -5,6 +6,19 @@
|
||||||
#include "InputReader.h"
|
#include "InputReader.h"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
// Description for input field mapping
|
||||||
|
struct FieldMapping {
|
||||||
|
string name;
|
||||||
|
TypeTag type;
|
||||||
|
int position;
|
||||||
|
|
||||||
|
FieldMapping(const string& arg_name, const TypeTag& arg_type, int arg_position);
|
||||||
|
FieldMapping(const FieldMapping& arg);
|
||||||
|
FieldMapping() { position = -1; }
|
||||||
|
bool IsEmpty() { return position == -1; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class InputReaderAscii : public InputReader {
|
class InputReaderAscii : public InputReader {
|
||||||
|
@ -20,10 +34,18 @@ protected:
|
||||||
const LogField* const * fields);
|
const LogField* const * fields);
|
||||||
virtual void DoFinish();
|
virtual void DoFinish();
|
||||||
|
|
||||||
|
virtual bool DoUpdate();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
ifstream* file;
|
ifstream* file;
|
||||||
string fname;
|
string fname;
|
||||||
|
|
||||||
|
unsigned int num_fields;
|
||||||
|
|
||||||
|
// map columns in the file to columns to send back to the manager
|
||||||
|
vector<FieldMapping> columnMap;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue