From 65ac085a97b434d04c0a9361bf5d8989bef59cc9 Mon Sep 17 00:00:00 2001 From: Joachim Nilsson Date: Wed, 6 Nov 2019 12:08:42 +0100 Subject: [PATCH] Add backwards compatibility handling with sysklogd v1.6 This patch adds compatibility with sysklgd v1.6 and also adds the new action flag "RFC3164" to explicitly be able to set old format. This format is the default, except for remote syslog. Also, the rotation support added in v1.6 has chnaged syntax which this patch addresses. - Remote syslog defaults to BSD format, w/o timestamp and hostname - Support reading log rotation without ';rotate=' prefix Signed-off-by: Joachim Nilsson --- src/syslogd.c | 73 ++++++++++++++++++++++++++++++++++++++------------- src/syslogd.h | 10 ++++++- 2 files changed, 64 insertions(+), 19 deletions(-) diff --git a/src/syslogd.c b/src/syslogd.c index 35f78a5..d5d86fc 100644 --- a/src/syslogd.c +++ b/src/syslogd.c @@ -1448,23 +1448,28 @@ void logrotate(struct filed *f) bm->pri, bm->flags, bm->hostname, bm->app_name, \ bm->proc_id, bm->msgid, bm->sd, bm->msg) -static int fmt3164(struct buf_msg *buffer, struct iovec *iov, size_t iovmax) +static int fmt3164(struct buf_msg *buffer, char *fmt, struct iovec *iov, size_t iovmax) { int i = 0; fmtlogit(buffer); - strftime(buffer->timebuf, sizeof(buffer->timebuf), RFC3164_DATEFMT, - &buffer->timestamp.tm); snprintf(buffer->pribuf, sizeof(buffer->pribuf), "<%d>", buffer->pri); pushiov(iov, i, buffer->pribuf); pushsp(iov, i); - pushiov(iov, i, buffer->timebuf); - pushsp(iov, i); + /* + * sysklogd < 2.0 had the traditional BSD format for remote syslog + * which did not include the timestamp or the hostname. + */ + if (fmt) { + strftime(buffer->timebuf, sizeof(buffer->timebuf), fmt, &buffer->timestamp.tm); + pushiov(iov, i, buffer->timebuf); + pushsp(iov, i); - pushiov(iov, i, buffer->hostname ? buffer->hostname : buffer->recvhost); - pushsp(iov, i); + pushiov(iov, i, buffer->hostname ? buffer->hostname : buffer->recvhost); + pushsp(iov, i); + } if (buffer->app_name) { pushiov(iov, i, buffer->app_name); @@ -1481,14 +1486,14 @@ static int fmt3164(struct buf_msg *buffer, struct iovec *iov, size_t iovmax) return i; } -static int fmt5424(struct buf_msg *buffer, struct iovec *iov, size_t iovmax) +/* 1 2003-08-24T05:14:15.000003-07:00 hostname app-name procid msgid sd msg */ +static int fmt5424(struct buf_msg *buffer, char *fmt, struct iovec *iov, size_t iovmax) { suseconds_t usec; int i = 0; fmtlogit(buffer); - strftime(buffer->timebuf, sizeof(buffer->timebuf), "%FT%T.______%z", - &buffer->timestamp.tm); + strftime(buffer->timebuf, sizeof(buffer->timebuf), fmt, &buffer->timestamp.tm); /* Add colon to the time zone offset, which %z doesn't do */ buffer->timebuf[32] = '\0'; @@ -1576,9 +1581,11 @@ void fprintlog(struct filed *f, struct buf_msg *buffer) } if (f->f_flags & RFC5424) - iovcnt = fmt5424(buffer, iov, NELEMS(iov)); + iovcnt = fmt5424(buffer, RFC5424_DATEFMT, iov, NELEMS(iov)); + else if (f->f_flags & RFC3164) + iovcnt = fmt3164(buffer, RFC3164_DATEFMT, iov, NELEMS(iov)); else - iovcnt = fmt3164(buffer, iov, NELEMS(iov)); + iovcnt = fmt3164(buffer, BSDFMT_DATEFMT, iov, NELEMS(iov)); /* Save actual message for future repeats */ // if (iovcnt > 0) @@ -2400,19 +2407,25 @@ static void cfopts(char *ptr, struct filed *f) if (!ptr) return; - /* Insert NUL character after action */ + /* Insert NUL character to terminate file/host names */ if (*ptr != ';') *ptr++ = 0; - /* Parse options */ opt = strtok(ptr, ";"); + if (!opt) + return; + while (opt) { - if (cfopt(&opt, "RFC5424")) - f->f_flags |= RFC5424; - else if (cfopt(&opt, "RFC3164")) + if (cfopt(&opt, "RFC5424")) { + f->f_flags |= RFC5424; + f->f_flags &= ~RFC3164; + } else if (cfopt(&opt, "RFC3164")) { f->f_flags &= ~RFC5424; - else if (cfopt(&opt, "rotate=")) + f->f_flags |= RFC3164; + } else if (cfopt(&opt, "rotate=")) cfrot(opt, f); + else + cfrot(ptr, f); /* Compat v1.6 syntax */ opt = strtok(NULL, ","); } @@ -2650,6 +2663,30 @@ static struct filed *cfline(char *line) break; } + /* Set default log format, unless format was already specified */ + switch (f->f_type) { + case F_FORW: + case F_FORW_UNKN: + /* Remote syslog defaults to BSD style, i.e. no timestamp or hostname */ + break; + + default: + /* All other targets default to RFC3164 */ + if (f->f_flags & (RFC3164 | RFC5424)) { + logit("%s has %s format logging enabled\n", + (f->f_flags & RFC3164) ? "RFC3164" : "RFC5424"); + break; + } + + f->f_flags = RFC3164; + break; + } + + if (f->f_flags & (RFC3164 | RFC5424)) + logit("%s format enabled\n", (f->f_flags & RFC3164) ? "RFC3164" : "RFC5424"); + else + logit("BSD format enabled\n"); + return f; } diff --git a/src/syslogd.h b/src/syslogd.h index 5f179bc..9e73921 100644 --- a/src/syslogd.h +++ b/src/syslogd.h @@ -112,11 +112,19 @@ #define SYNC_FILE 0x002 /* do fsync on file after printing */ #define ADDDATE 0x004 /* add a date to the message */ #define MARK 0x008 /* this message is a mark */ -#define RFC5424 0x010 /* format log message according to RFC 5424 */ +#define RFC3164 0x010 /* format log message according to RFC 3164 */ +#define RFC5424 0x020 /* format log message according to RFC 5424 */ + +/* Syslog timestamp formats. */ +#define BSDFMT_DATELEN 0 +#define BSDFMT_DATEFMT NULL #define RFC3164_DATELEN 15 #define RFC3164_DATEFMT "%b %e %H:%M:%S" +#define RFC5424_DATELEN 32 +#define RFC5424_DATEFMT "%FT%T.______%z" + /* * Helper macros for "message repeated" messages */