mirror of
https://github.com/nmap/nmap.git
synced 2025-12-18 13:39:02 +00:00
Adding my strftime()-like conversion extensions to the logging functions (-oA, -oX, etc). This contains a CHANGELOG entry and refguide changes which (hopefully) sum it up pretty well.
This commit is contained in:
@@ -1,4 +1,12 @@
|
||||
# Nmap Changelog ($Id$); -*-text-*-
|
||||
|
||||
o Nmap's output options (-oA, -oX, etc.) now support strftime()-like
|
||||
conversions in the filename. %H, %M, %S, %T, %R, %m, %d, %y, and
|
||||
%Y are all the same as in strftime(). %t is the same as %H%M%S,
|
||||
%r is the same as %H%M, and %D is the same as %m%d%y. This means
|
||||
that "-oX 'scan-%T-%D.xml'" uses an XML file in the form of
|
||||
"scan-14:48:40-121307.xml". [Kris]
|
||||
|
||||
4.50
|
||||
|
||||
o Bumped up the version number to the big 4.50!
|
||||
|
||||
@@ -2868,6 +2868,18 @@ compatibility feature of Nmap will cause the creation of
|
||||
<filename>G-</filename> and <filename>Xscan.xml</filename>
|
||||
respectively.</para>
|
||||
|
||||
<para>All of these arguments support <function>strftime()</function>-like
|
||||
conversions in the filename. <literal>%H</literal>, <literal>%M</literal>,
|
||||
<literal>%S</literal>, <literal>%T</literal>, <literal>%R</literal>,
|
||||
<literal>%m</literal>, <literal>%d</literal>, <literal>%y</literal>,
|
||||
and <literal>%Y</literal> are all exactly the same as in
|
||||
<function>strftime()</function>. <literal>%t</literal> is the same as
|
||||
<literal>%H%M%S</literal>, <literal>%r</literal> is the same as
|
||||
<literal>%H%M</literal>, and <literal>%D</literal> is the same as
|
||||
<literal>%m%d%y</literal>. So <option>-oX 'scan-%T-%D.xml'</option>
|
||||
will use an XML file in the form of
|
||||
<filename>scan-14:48:40-121307.xml</filename>.</para>
|
||||
|
||||
<para>Nmap also offers options to control scan verbosity and to append
|
||||
to output files rather than clobbering them. All of these options are
|
||||
described below.</para>
|
||||
|
||||
25
nmap.cc
25
nmap.cc
@@ -472,6 +472,8 @@ int nmap_main(int argc, char *argv[]) {
|
||||
int num_host_exp_groups;
|
||||
char *machinefilename = NULL, *kiddiefilename = NULL,
|
||||
*normalfilename = NULL, *xmlfilename = NULL;
|
||||
time_t now;
|
||||
struct tm *tm;
|
||||
HostGroupState *hstate = NULL;
|
||||
char *endptr = NULL;
|
||||
struct scan_lists *ports = NULL;
|
||||
@@ -647,6 +649,9 @@ int nmap_main(int argc, char *argv[]) {
|
||||
win_pre_init();
|
||||
#endif
|
||||
|
||||
now = time(NULL);
|
||||
tm = localtime(&now);
|
||||
|
||||
/* OK, lets parse these args! */
|
||||
optind = 1; /* so it can be called multiple times */
|
||||
while((arg = getopt_long_only(argc,fakeargv,"6Ab:D:d::e:Ffg:hIi:M:m:nO::o:P:p:qRrS:s:T:Vv", long_options, &option_index)) != EOF) {
|
||||
@@ -816,23 +821,23 @@ int nmap_main(int argc, char *argv[]) {
|
||||
} else if (strcmp(long_options[option_index].name, "webxml") == 0) {
|
||||
o.setXSLStyleSheet("http://www.insecure.org/nmap/data/nmap.xsl");
|
||||
} else if (strcmp(long_options[option_index].name, "oN") == 0) {
|
||||
normalfilename = optarg;
|
||||
normalfilename = logfilename(optarg, tm);
|
||||
} else if (strcmp(long_options[option_index].name, "oG") == 0 ||
|
||||
strcmp(long_options[option_index].name, "oM") == 0) {
|
||||
machinefilename = optarg;
|
||||
machinefilename = logfilename(optarg, tm);
|
||||
} else if (strcmp(long_options[option_index].name, "oS") == 0) {
|
||||
kiddiefilename = optarg;
|
||||
kiddiefilename = logfilename(optarg, tm);
|
||||
} else if (strcmp(long_options[option_index].name, "oH") == 0) {
|
||||
fatal("HTML output is not directly supported, though Nmap includes an XSL for transforming XML output into HTML. See the man page.");
|
||||
} else if (strcmp(long_options[option_index].name, "oX") == 0) {
|
||||
xmlfilename = optarg;
|
||||
xmlfilename = logfilename(optarg, tm);
|
||||
} else if (strcmp(long_options[option_index].name, "oA") == 0) {
|
||||
char buf[MAXPATHLEN];
|
||||
Snprintf(buf, sizeof(buf), "%s.nmap", optarg);
|
||||
Snprintf(buf, sizeof(buf), "%s.nmap", logfilename(optarg, tm));
|
||||
normalfilename = strdup(buf);
|
||||
Snprintf(buf, sizeof(buf), "%s.gnmap", optarg);
|
||||
Snprintf(buf, sizeof(buf), "%s.gnmap", logfilename(optarg, tm));
|
||||
machinefilename = strdup(buf);
|
||||
Snprintf(buf, sizeof(buf), "%s.xml", optarg);
|
||||
Snprintf(buf, sizeof(buf), "%s.xml", logfilename(optarg, tm));
|
||||
xmlfilename = strdup(buf);
|
||||
} else if (strcmp(long_options[option_index].name, "thc") == 0) {
|
||||
printf("!!Greets to Van Hauser, Plasmoid, Skyper and the rest of THC!!\n");
|
||||
@@ -1008,7 +1013,7 @@ int nmap_main(int argc, char *argv[]) {
|
||||
fatal("Unknown argument to -O.");
|
||||
break;
|
||||
case 'o':
|
||||
normalfilename = optarg;
|
||||
normalfilename = logfilename(optarg, tm);
|
||||
break;
|
||||
case 'P':
|
||||
if (*optarg == '\0' || *optarg == 'I' || *optarg == 'E')
|
||||
@@ -1244,10 +1249,6 @@ int nmap_main(int argc, char *argv[]) {
|
||||
|
||||
if (!o.interactivemode) {
|
||||
char tbuf[128];
|
||||
struct tm *tm;
|
||||
time_t now = time(NULL);
|
||||
if (!(tm = localtime(&now)))
|
||||
fatal("Unable to get current localtime()#!#");
|
||||
// ISO 8601 date/time -- http://www.cl.cam.ac.uk/~mgk25/iso-time.html
|
||||
if (strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %H:%M %Z", tm) <= 0)
|
||||
fatal("Unable to properly format time");
|
||||
|
||||
71
output.cc
71
output.cc
@@ -830,6 +830,77 @@ char* xml_convert (const char* str) {
|
||||
return temp;
|
||||
}
|
||||
|
||||
char *logfilename(const char *str, struct tm *tm)
|
||||
{
|
||||
char *ret, *end, *p;
|
||||
char tbuf[10];
|
||||
int retlen = strlen(str) * 6 + 1;
|
||||
|
||||
ret = (char *) safe_malloc(retlen);
|
||||
end = ret + retlen;
|
||||
|
||||
for (p = ret; *str; str++) {
|
||||
if (*str == '%') {
|
||||
str++;
|
||||
|
||||
if (!*str)
|
||||
break;
|
||||
|
||||
switch (*str) {
|
||||
case 'H':
|
||||
strftime(tbuf, sizeof tbuf, "%H", tm);
|
||||
break;
|
||||
case 'M':
|
||||
strftime(tbuf, sizeof tbuf, "%M", tm);
|
||||
break;
|
||||
case 'S':
|
||||
strftime(tbuf, sizeof tbuf, "%S", tm);
|
||||
break;
|
||||
case 'T':
|
||||
strftime(tbuf, sizeof tbuf, "%T", tm);
|
||||
break;
|
||||
case 't':
|
||||
strftime(tbuf, sizeof tbuf, "%H%M%S", tm);
|
||||
break;
|
||||
case 'R':
|
||||
strftime(tbuf, sizeof tbuf, "%R", tm);
|
||||
break;
|
||||
case 'r':
|
||||
strftime(tbuf, sizeof tbuf, "%H%M", tm);
|
||||
break;
|
||||
case 'm':
|
||||
strftime(tbuf, sizeof tbuf, "%m", tm);
|
||||
break;
|
||||
case 'd':
|
||||
strftime(tbuf, sizeof tbuf, "%d", tm);
|
||||
break;
|
||||
case 'y':
|
||||
strftime(tbuf, sizeof tbuf, "%y", tm);
|
||||
break;
|
||||
case 'Y':
|
||||
strftime(tbuf, sizeof tbuf, "%Y", tm);
|
||||
break;
|
||||
case 'D':
|
||||
strftime(tbuf, sizeof tbuf, "%m%d%y", tm);
|
||||
break;
|
||||
default:
|
||||
*p++ = *str;
|
||||
continue;
|
||||
}
|
||||
|
||||
assert(end - p > 1);
|
||||
Strncpy(p, tbuf, end - p - 1);
|
||||
p += strlen(tbuf);
|
||||
} else {
|
||||
*p++ = *str;
|
||||
}
|
||||
}
|
||||
|
||||
*p = 0;
|
||||
|
||||
return (char *) safe_realloc(ret, strlen(ret) + 1);
|
||||
}
|
||||
|
||||
/* This is the workhorse of the logging functions. Usually it is
|
||||
called through log_write(), but it can be called directly if you
|
||||
are dealing with a vfprintf-style va_list. Unlike log_write, YOU
|
||||
|
||||
2
output.h
2
output.h
@@ -138,6 +138,8 @@ void printportoutput(Target *currenths, PortList *plist);
|
||||
in a certain place to conform to DTD. */
|
||||
void printmacinfo(Target *currenths);
|
||||
|
||||
char *logfilename(const char *str, struct tm *tm);
|
||||
|
||||
/* Write some information (printf style args) to the given log stream(s).
|
||||
Remember to watch out for format string bugs. */
|
||||
void log_write(int logt, const char *fmt, ...)
|
||||
|
||||
Reference in New Issue
Block a user