| diff -aruN a/sysklogd/syslogd.c b/sysklogd/syslogd.c |
| --- a/sysklogd/syslogd.c 2012-01-04 10:13:07.989873065 -0800 |
| +++ b/sysklogd/syslogd.c 2012-01-04 10:08:05.000000000 -0800 |
| @@ -165,10 +165,10 @@ |
| /* ...then copy to parsebuf, escaping control chars */ |
| /* (can grow x2 max) */ |
| char parsebuf[MAX_READ*2]; |
| - /* ...then sprintf into printbuf, adding timestamp (15 chars), |
| + /* ...then sprintf into printbuf, adding timestamp (26 chars), |
| * host (64), fac.prio (20) to the message */ |
| - /* (growth by: 15 + 64 + 20 + delims = ~110) */ |
| - char printbuf[MAX_READ*2 + 128]; |
| + /* (growth by: 26 + 64 + 20 + delims = ~121) */ |
| + char printbuf[MAX_READ*2 + 139]; |
| }; |
| |
| static const struct init_globals init_data = { |
| @@ -638,47 +638,62 @@ |
| snprintf(res20, 20, "<%d>", pri); |
| } |
| |
| +static struct tm * generate_time(struct timeval *tvp, struct tm *tmp) |
| +{ |
| + struct tm *tm; |
| + |
| + gettimeofday(tvp, NULL); |
| + |
| + if (option_mask32 & OPT_utc) { |
| + tm = gmtime_r(&tvp->tv_sec, tmp); |
| + } else { |
| + tm = localtime_r(&tvp->tv_sec, tmp); |
| + } |
| + |
| + return tm; |
| +} |
| + |
| /* len parameter is used only for "is there a timestamp?" check. |
| * NB: some callers cheat and supply len==0 when they know |
| * that there is no timestamp, short-circuiting the test. */ |
| static void timestamp_and_log(int pri, char *msg, int len) |
| { |
| - char *timestamp; |
| - time_t now; |
| + char timestamp[27]; |
| + struct timeval tvnow; |
| + struct tm parsed, tmnow, *tmp; |
| + size_t n; |
| |
| /* Jan 18 00:11:22 msg... */ |
| /* 01234567890123456 */ |
| if (len < 16 || msg[3] != ' ' || msg[6] != ' ' |
| || msg[9] != ':' || msg[12] != ':' || msg[15] != ' ' |
| ) { |
| - time(&now); |
| - if (option_mask32 & OPT_utc) |
| - timestamp = asctime(gmtime(&now)); |
| - else |
| - timestamp = asctime(localtime(&now)); |
| - timestamp += 4; /* skip day of week */ |
| + tmp = generate_time(&tvnow, &tmnow); |
| } else { |
| - if (option_mask32 & OPT_utc) { |
| - struct tm parsed, local; |
| - now = time(NULL); |
| - localtime_r(&now, &local); |
| - if (strptime(msg, "%h %e %T", &parsed) != NULL) { |
| - parsed.tm_gmtoff = local.tm_gmtoff; |
| - parsed.tm_zone = local.tm_zone; |
| - parsed.tm_year = local.tm_year; |
| - parsed.tm_isdst = local.tm_isdst; |
| - now = mktime(&parsed); |
| - timestamp = asctime(gmtime(&now)) + 4; |
| + struct tm local; |
| + tvnow.tv_sec = time(NULL); |
| + localtime_r(&tvnow.tv_sec, &local); |
| + if (strptime(msg, "%h %e %T", &parsed) != NULL) { |
| + |
| + parsed.tm_gmtoff = local.tm_gmtoff; |
| + parsed.tm_zone = local.tm_zone; |
| + parsed.tm_year = local.tm_year; |
| + parsed.tm_isdst = local.tm_isdst; |
| + tvnow.tv_sec = mktime(&parsed); |
| + tvnow.tv_usec = 0; |
| + |
| + if (option_mask32 & OPT_utc) { |
| + tmp = gmtime_r(&tvnow.tv_sec, &tmnow); |
| } else { |
| - timestamp = msg; |
| + tmp = &parsed; |
| } |
| } else { |
| - now = 0; |
| - timestamp = msg; |
| + tmp = generate_time(&tvnow, &tmnow); |
| } |
| msg += 16; |
| } |
| - timestamp[15] = '\0'; |
| + n = strftime(timestamp, sizeof(timestamp), "%F %T", tmp); |
| + snprintf(timestamp + n, sizeof(timestamp) - n, ".%06ld", tvnow.tv_usec); |
| |
| if (option_mask32 & OPT_small) |
| sprintf(G.printbuf, "%s %s\n", timestamp, msg); |
| @@ -698,7 +713,7 @@ |
| |
| for (rule = G.log_rules; rule; rule = rule->next) { |
| if (rule->enabled_facility_priomap[facility] & prio_bit) { |
| - log_locally(now, G.printbuf, rule->file); |
| + log_locally(tvnow.tv_sec, G.printbuf, rule->file); |
| match = 1; |
| } |
| } |
| @@ -713,7 +728,7 @@ |
| return; |
| } |
| #endif |
| - log_locally(now, G.printbuf, &G.logFile); |
| + log_locally(tvnow.tv_sec, G.printbuf, &G.logFile); |
| } |
| } |
| |