Add thread-safe wrapper for ctime.

This commit is contained in:
dmiller 2019-12-20 20:53:32 +00:00
parent 20f47dd6f2
commit e356ad1123
4 changed files with 106 additions and 38 deletions

View file

@ -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

View file

@ -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 <errno.h>
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)

View file

@ -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) {

View file

@ -2041,17 +2041,23 @@ void printosscanoutput(Target *currenths) {
char tmbuf[128];
struct timeval tv;
double uptime;
strncpy(tmbuf, ctime(&currenths->seq.lastboot), sizeof(tmbuf));
int err = n_ctime(tmbuf, sizeof(tmbuf), &currenths->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();