From bcf298e7eca07a8869d184ad44c01232a11ba9ea Mon Sep 17 00:00:00 2001 From: Martin Schwenke Date: Fri, 10 Oct 2014 18:46:31 +1100 Subject: [PATCH] lib/util: Add RFC3339 timestamp support to timeval_str_buf() Note that this can't be done more simply or portably with strftime(3) since "%z" isn't portable. Signed-off-by: Martin Schwenke Pair-programmed-with: Amitay Isaacs Reviewed-by: Volker Lendecke Autobuild-User(master): Volker Lendecke Autobuild-Date(master): Mon Oct 13 12:27:04 CEST 2014 on sn-devel-104 --- lib/util/debug.c | 3 ++- lib/util/time.c | 2 +- lib/util/time_basic.c | 30 ++++++++++++++++++++++++++---- lib/util/time_basic.h | 5 ++++- 4 files changed, 33 insertions(+), 7 deletions(-) diff --git a/lib/util/debug.c b/lib/util/debug.c index 00595957aa6..750ad259759 100644 --- a/lib/util/debug.c +++ b/lib/util/debug.c @@ -983,7 +983,8 @@ bool dbghdrclass(int level, int cls, const char *location, const char *func) } GetTimeOfDay(&tv); - timeval_str_buf(&tv, state.settings.debug_hires_timestamp, &tvbuf); + timeval_str_buf(&tv, false, state.settings.debug_hires_timestamp, + &tvbuf); hs_len = snprintf(header_str, sizeof(header_str), "[%s, %2d", tvbuf.buf, level); diff --git a/lib/util/time.c b/lib/util/time.c index 4b78e71a789..3c709af6b11 100644 --- a/lib/util/time.c +++ b/lib/util/time.c @@ -341,7 +341,7 @@ char *timeval_string(TALLOC_CTX *ctx, const struct timeval *tp, bool hires) struct timeval_buf tmp; char *result; - result = talloc_strdup(ctx, timeval_str_buf(tp, hires, &tmp)); + result = talloc_strdup(ctx, timeval_str_buf(tp, false, hires, &tmp)); if (result == NULL) { return NULL; } diff --git a/lib/util/time_basic.c b/lib/util/time_basic.c index 13d0bfdb5e6..0eeb4413717 100644 --- a/lib/util/time_basic.c +++ b/lib/util/time_basic.c @@ -40,7 +40,7 @@ _PUBLIC_ void GetTimeOfDay(struct timeval *tval) Return the date and time as a string ****************************************************************************/ -char *timeval_str_buf(const struct timeval *tp, bool hires, +char *timeval_str_buf(const struct timeval *tp, bool rfc5424, bool hires, struct timeval_buf *dst) { time_t t; @@ -63,13 +63,35 @@ char *timeval_str_buf(const struct timeval *tp, bool hires, } len = snprintf(dst->buf, sizeof(dst->buf), - "%04d/%02d/%02d %02d:%02d:%02d", + (rfc5424 ? + "%04d-%02d-%02dT%02d:%02d:%02d" : + "%04d/%02d/%02d %02d:%02d:%02d"), 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); - if (hires && (len < sizeof(dst->buf))) { + if ((rfc5424 || hires) && (len < sizeof(dst->buf))) { + len += snprintf(dst->buf + len, sizeof(dst->buf) - len, + ".%06ld", (long)tp->tv_usec); + } + + if (rfc5424 && (len < sizeof(dst->buf))) { + struct tm tm_utc, tm_local; + int offset; + + tm_local = *tm; + /* It is reasonable to assume that if localtime() + * worked above, then gmtime() should also work + * without error. */ + tm_utc = *gmtime(&t); + + offset = (tm_local.tm_hour - tm_utc.tm_hour) * 60 + + (tm_local.tm_min - tm_utc.tm_min); + snprintf(dst->buf + len, sizeof(dst->buf) - len, - ".%06ld", (long)tp->tv_usec); + "%c%02d:%02d", + (offset >=0 ? '+' : '-'), + abs(offset) / 60, + abs(offset) % 60); } return dst->buf; diff --git a/lib/util/time_basic.h b/lib/util/time_basic.h index b04dead1009..d1bb3b59bbc 100644 --- a/lib/util/time_basic.h +++ b/lib/util/time_basic.h @@ -35,8 +35,11 @@ struct timeval_buf { char buf[128]; }; Put a date and time into dst->buf, return it dst->buf (optionally with microseconds) + If rfc5424 is true then produce the RFC5424 timestamp format (which + is a stricter instance of RFC3339 and is used for syslog). For + example: 2003-08-24T05:14:15.000003-07:00. Otherwise, format is %Y/%m/%d %H:%M:%S **/ -char *timeval_str_buf(const struct timeval *tp, bool hires, +char *timeval_str_buf(const struct timeval *tp, bool rfc5424, bool hires, struct timeval_buf *dst); -- 2.11.4.GIT