diff --git a/nbase/nbase.h b/nbase/nbase.h index 950a5d782..9298e0214 100644 --- a/nbase/nbase.h +++ b/nbase/nbase.h @@ -458,6 +458,7 @@ void usleep(unsigned long usec); /* localtime is not thread safe. This will use a thread safe alternative on * supported platforms. */ int n_localtime(const time_t *timer, struct tm *result); +int n_ctime(char *buffer, size_t bufsz, const time_t *timer); /***************** String functions -- See nbase_str.c ******************/ /* I modified this conditional because !@# Redhat does not easily provide diff --git a/nbase/nbase_time.c b/nbase/nbase_time.c index 8aa617444..6bdd1896f 100644 --- a/nbase/nbase_time.c +++ b/nbase/nbase_time.c @@ -165,33 +165,71 @@ int n_localtime(const time_t *timer, struct tm *result) { return localtime_s(result, timer); } -#else +int n_ctime(char *buffer, size_t bufsz, const time_t *timer) { + return ctime_s(buffer, bufsz, timer); +} + +#else //WIN32 + #include -int n_localtime(const time_t *timer, struct tm *result) { #ifdef HAVE_LOCALTIME_S /* C11 localtime_s similar to Posix localtime_r, but with validity checking: * struct tm *localtime_s(const time_t *restrict time, struct tm *restrict result); */ +int n_localtime(const time_t *timer, struct tm *result) { struct tm *tmp = localtime_s(timer, result); -#else -#ifdef HAVE_LOCALTIME_R -/* POSIX localtime_r thread-safe localtime function: - * struct tm *localtime_r(const time_t *timep, struct tm *result); - */ - struct tm *tmp = localtime_r(timer, result); -#else -/* No thread-safe alternative; use localtime. */ - struct tm *tmp = localtime(timer); - if (tmp) - *result = *tmp; -#endif -#endif if (!tmp) { return errno; } return 0; } -#endif + +int n_ctime(char *buffer, size_t bufsz, const time_t *timer) { + return ctime_s(buffer, bufsz, timer); +} +#else +#ifdef HAVE_LOCALTIME_R +/* POSIX localtime_r thread-safe localtime function: + * struct tm *localtime_r(const time_t *timep, struct tm *result); + */ +int n_localtime(const time_t *timer, struct tm *result) { + struct tm *tmp = localtime_r(timer, result); + if (!tmp) { + return errno; + } + return 0; +} + +int n_ctime(char *buffer, size_t bufsz, const time_t *timer) { + char *tmp = ctime_r(timer, buffer); + if (!tmp) { + return errno; + } + return 0; +} + +#else +/* No thread-safe alternatives. */ +int n_localtime(const time_t *timer, struct tm *result) { + struct tm *tmp = localtime(timer); /* lgtm [cpp/potentially-dangerous-function] */ + if (tmp) + *result = *tmp; + else + return errno; + return 0; +} + +int n_ctime(char *buffer, size_t bufsz, const time_t *timer) { + char *tmp = ctime(timer); /* lgtm [cpp/potentially-dangerous-function] */ + if (tmp) + Strncpy(buffer, tmp, bufsz); + else + return errno; + return 0; +} +#endif //HAVE_LOCALTIME_R +#endif //HAVE_LOCALTIME_S +#endif //WIN32 #ifdef WIN32 int gettimeofday(struct timeval *tv, struct timeval *tz) diff --git a/nmap.cc b/nmap.cc index 6af19e955..6f9d36f53 100644 --- a/nmap.cc +++ b/nmap.cc @@ -1919,7 +1919,10 @@ int nmap_main(int argc, char *argv[]) { fflush(stderr); timep = time(NULL); - Strncpy(mytime, ctime(&timep), sizeof(mytime)); + err = n_ctime(mytime, sizeof(mytime), &timep); + if (err) { + fatal("n_ctime failed: %s", strerror(err)); + } chomp(mytime); if (!o.resuming) { diff --git a/output.cc b/output.cc index 80e3bc1bf..41cfbf554 100644 --- a/output.cc +++ b/output.cc @@ -2041,17 +2041,23 @@ void printosscanoutput(Target *currenths) { char tmbuf[128]; struct timeval tv; double uptime; - strncpy(tmbuf, ctime(¤ths->seq.lastboot), sizeof(tmbuf)); + int err = n_ctime(tmbuf, sizeof(tmbuf), ¤ths->seq.lastboot); chomp(tmbuf); gettimeofday(&tv, NULL); uptime = difftime(tv.tv_sec, currenths->seq.lastboot); - if (o.verbose) - log_write(LOG_PLAIN, "Uptime guess: %.3f days (since %s)\n", + if (o.verbose) { + if (err) + log_write(LOG_PLAIN, "Uptime guess: %.3f days\n", + uptime / 86400); + else + log_write(LOG_PLAIN, "Uptime guess: %.3f days (since %s)\n", uptime / 86400, tmbuf); + } xml_open_start_tag("uptime"); xml_attribute("seconds", "%.0f", uptime); - xml_attribute("lastboot", "%s", tmbuf); + if (!err) + xml_attribute("lastboot", "%s", tmbuf); xml_close_empty_tag(); xml_newline(); } @@ -2526,20 +2532,30 @@ void printStatusMessage() { You have to close the tag with xml_close_empty_tag. */ void print_xml_finished_open(time_t timep, const struct timeval *tv) { char mytime[128]; + int err = n_ctime(mytime, sizeof(mytime), &timep); - Strncpy(mytime, ctime(&timep), sizeof(mytime)); chomp(mytime); xml_open_start_tag("finished"); xml_attribute("time", "%lu", (unsigned long) timep); - xml_attribute("timestr", "%s", mytime); + if (!err) { + xml_attribute("timestr", "%s", mytime); + xml_attribute("summary", + "Nmap done at %s; %u %s (%u %s up) scanned in %.2f seconds", + mytime, o.numhosts_scanned, + (o.numhosts_scanned == 1) ? "IP address" : "IP addresses", + o.numhosts_up, (o.numhosts_up == 1) ? "host" : "hosts", + o.TimeSinceStart(tv)); + } + else { + xml_attribute("summary", + "Nmap done; %u %s (%u %s up) scanned in %.2f seconds", + o.numhosts_scanned, + (o.numhosts_scanned == 1) ? "IP address" : "IP addresses", + o.numhosts_up, (o.numhosts_up == 1) ? "host" : "hosts", + o.TimeSinceStart(tv)); + } xml_attribute("elapsed", "%.2f", o.TimeSinceStart(tv)); - xml_attribute("summary", - "Nmap done at %s; %u %s (%u %s up) scanned in %.2f seconds", - mytime, o.numhosts_scanned, - (o.numhosts_scanned == 1) ? "IP address" : "IP addresses", - o.numhosts_up, (o.numhosts_up == 1) ? "host" : "hosts", - o.TimeSinceStart(tv)); } void print_xml_hosts() { @@ -2555,6 +2571,7 @@ void print_xml_hosts() { void printfinaloutput() { time_t timep; char mytime[128]; + int err = 0; struct timeval tv; char statbuf[128]; @@ -2592,9 +2609,6 @@ void printfinaloutput() { log_write(LOG_STDOUT | LOG_SKID, " %s\n", getFinalPacketStats(statbuf, sizeof(statbuf))); - Strncpy(mytime, ctime(&timep), sizeof(mytime)); - chomp(mytime); - xml_start_tag("runstats"); print_xml_finished_open(timep, &tv); xml_attribute("exit", "success"); @@ -2604,12 +2618,24 @@ void printfinaloutput() { xml_end_tag(); xml_newline(); - log_write(LOG_NORMAL | LOG_MACHINE, - "# Nmap done at %s -- %u %s (%u %s up) scanned in %.2f seconds\n", - mytime, o.numhosts_scanned, - (o.numhosts_scanned == 1) ? "IP address" : "IP addresses", - o.numhosts_up, (o.numhosts_up == 1) ? "host" : "hosts", - o.TimeSinceStart(&tv)); + err = n_ctime(mytime, sizeof(mytime), &timep); + if (!err) { + chomp(mytime); + log_write(LOG_NORMAL | LOG_MACHINE, + "# Nmap done at %s -- %u %s (%u %s up) scanned in %.2f seconds\n", + mytime, o.numhosts_scanned, + (o.numhosts_scanned == 1) ? "IP address" : "IP addresses", + o.numhosts_up, (o.numhosts_up == 1) ? "host" : "hosts", + o.TimeSinceStart(&tv)); + } + else { + log_write(LOG_NORMAL | LOG_MACHINE, + "# Nmap done -- %u %s (%u %s up) scanned in %.2f seconds\n", + o.numhosts_scanned, + (o.numhosts_scanned == 1) ? "IP address" : "IP addresses", + o.numhosts_up, (o.numhosts_up == 1) ? "host" : "hosts", + o.TimeSinceStart(&tv)); + } xml_end_tag(); /* nmaprun */ xml_newline();