diff --git a/CHANGELOG b/CHANGELOG
index dbb33d852..32fd692e4 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,10 @@
# Nmap Changelog ($Id$); -*-text-*-
+o The new --stats-every option takes a time interval that controls how
+ often timing status updates are printed. It's intended to be used
+ when Nmap is run by another program as a subprocess. Thanks to
+ Aleksandar Petrinic for the initial implementation. [David]
+
o [Ncat] The syntax accepted by the --allow, --deny, --allowfile, and
--denyfile options is now the same as Nmap's target specifications.
Additionally any errors in the allow or deny specifications are
diff --git a/NmapOps.cc b/NmapOps.cc
index 54c3e068e..7aca68d70 100644
--- a/NmapOps.cc
+++ b/NmapOps.cc
@@ -222,6 +222,7 @@ void NmapOps::Initialize() {
verbose = 0;
min_packet_send_rate = 0.0; /* Unset. */
max_packet_send_rate = 0.0; /* Unset. */
+ stats_interval = 0.0; /* Unset. */
randomize_hosts = 0;
sendpref = PACKET_SEND_NOPREF;
spoofsource = 0;
diff --git a/NmapOps.h b/NmapOps.h
index 467ad415b..b6dd8b132 100644
--- a/NmapOps.h
+++ b/NmapOps.h
@@ -184,6 +184,8 @@ class NmapOps {
float min_packet_send_rate;
/* The requested maximum packet sending rate, or 0.0 if unset. */
float max_packet_send_rate;
+ /* The requested auto stats printing interval, or 0.0 if unset. */
+ float stats_interval;
int randomize_hosts;
int spoofsource; /* -S used */
int fastscan;
diff --git a/docs/refguide.xml b/docs/refguide.xml
index dac87bd56..21e1bf5ef 100644
--- a/docs/refguide.xml
+++ b/docs/refguide.xml
@@ -3402,6 +3402,23 @@ even if this option is not specified.
+
+
+ (Print periodic timing stats)
+
+
+
+
+ Periodically prints a timing status message after each
+ interval of time. The time is a
+ specification of the kind described in
+ ; so for example, use
+ --stats-every 10s to get a status update
+ every 10 seconds. Updates are printed to interactive output
+ (the screen) and XML output.
+
+
+
diff --git a/nmap.cc b/nmap.cc
index b86871606..f5ee686e9 100644
--- a/nmap.cc
+++ b/nmap.cc
@@ -674,6 +674,8 @@ int nmap_main(int argc, char *argv[]) {
{"min-rate", required_argument, 0, 0},
{"max_rate", required_argument, 0, 0},
{"max-rate", required_argument, 0, 0},
+ {"stats_every", required_argument, 0, 0},
+ {"stats-every", required_argument, 0, 0},
{0, 0, 0, 0}
};
@@ -937,6 +939,10 @@ int nmap_main(int argc, char *argv[]) {
} else if(optcmp(long_options[option_index].name, "max-rate") == 0) {
if (sscanf(optarg, "%f", &o.max_packet_send_rate) != 1 || o.max_packet_send_rate <= 0.0)
fatal("Argument to --max-rate must be a positive floating-point number");
+ } else if(optcmp(long_options[option_index].name, "stats-every") == 0) {
+ l = tval2msecs(optarg);
+ if (l < 0) fatal("Argument to --stats-every cannot be negative.");
+ o.stats_interval = (double) l / 1000.0;
} else {
fatal("Unknown long option (%s) given@#!$#$", long_options[option_index].name);
}
diff --git a/nmap_tty.cc b/nmap_tty.cc
index 5d2f24d57..ed087fb25 100644
--- a/nmap_tty.cc
+++ b/nmap_tty.cc
@@ -116,6 +116,7 @@
#include
#include "nmap_tty.h"
+#include "utils.h"
#include "NmapOps.h"
extern NmapOps o;
@@ -240,6 +241,8 @@ void tty_init()
print a status message */
bool keyWasPressed()
{
+ /* Where we keep the automatic stats printing schedule. */
+ static struct timeval stats_time = { 0 };
int c;
if (o.noninteractive)
@@ -282,5 +285,30 @@ bool keyWasPressed()
return true;
}
}
+
+ /* Check if we need to print a status update according to the --stats-every
+ option. */
+ if (o.stats_interval != 0.0) {
+ struct timeval now;
+
+ gettimeofday(&now, NULL);
+ if (stats_time.tv_sec == 0) {
+ /* Initialize the scheduled stats time. */
+ stats_time = *o.getStartTime();
+ TIMEVAL_ADD(stats_time, stats_time, (time_t) (o.stats_interval * 1000000));
+ }
+
+ if (TIMEVAL_AFTER(now, stats_time)) {
+ /* Advance to the next print time. */
+ TIMEVAL_ADD(stats_time, stats_time, (time_t) (o.stats_interval * 1000000));
+ /* If it's still in the past, catch it up to the present. */
+ if (TIMEVAL_AFTER(now, stats_time))
+ stats_time = now;
+ printStatusMessage();
+ /* Instruct the caller to print status too. */
+ return true;
+ }
+ }
+
return false;
}