Cool – that did the trick. This is really good stuff.
I decided to try using this against other bro events, besides just bro_init():
$ cat exec-test.bro
@load ./exec
event dns_message(c: connection, is_orig: bool, msg: dns_msg, len: count)
{
Exec::run("./hello", function(r: Exec::Result)
{
if ( ! r?$stdout )
{
print “nothing?!?”;
return;
}
for ( i in r$stdout )
{
print r$stdout[i];
}
});
}
./hello is just a hello world program.
So, when I test that, I see the following.
$ bro -r test.pcap exec-test.bro
Hello World
Hello World
Hello World
nothing?!?
ERROR: 1361476370.202590 no such index (Exec::results[Exec::name]) (././exec.bro, line 25)
[…]
This got me wondering – why would exec-test.bro ever have a case where (! r?$stdout) is true, when I have a program that absolutely returns output every time it’s run? (And then print out “nothing?!?”)
For convenience:
exec.bro
21 event Exec::stdout_line(description: Input::EventDescription, tpe: Input::Event, s: string)
22 {
23 local name = sub(description$name, /[^]*$/, “”);
24
25 if ( ! results[name]?$stdout )
26 results[name]$stdout = vector(s);
27 else
28 results[name]$stdout[|results[name]$stdout|] = s;
29 }
It’s also worth noting that exec.bro really trashes the /tmp directory at this point.
exec.bro
94 function run(cmd: string, cb: function(r: Result))
95 {
96 local tmpfile = “/tmp/bro-exec-” + unique_id("");
97 system(fmt(“touch %s_done”, tmpfile));
98 system(fmt(“touch %s_stdout”, tmpfile));
99 system(fmt(“touch %s_stderr”, tmpfile));
100 # Sleep for 1 sec before writing to the done file to avoid race conditions
101 # This makes sure that all of the data is read from
102 system(fmt("%s 2>>%s_stderr 1>> %s_stdout; echo “exit_code:${?}” > %s_done; sleep 1; echo “done” >> %s_done", cmd, tmpf
103
104 results[tmpfile] = [];
105 callbacks[tmpfile] = cb;
106
107 schedule 1msec { start_watching_files(tmpfile) };
108 }
That chunk of code probably needs something like this:
system(fmt(“rm %s_done”, tmpfile));
system(fmt(“rm %s_stdout”, tmpfile));
system(fmt(“rm %s_stderr”, tmpfile));
I’m just not sure where it should go.
-Chris