aboutsummaryrefslogtreecommitdiffstats
path: root/main/busybox/0011-sysklogd-add-Z-option-to-adjust-message-timezones.patch
blob: 3ec16592595cc047da6b7c2d84366c653b88261c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
From 7282c6ce8ec6cc3e817ed948d8ce2d0df2a08e5b Mon Sep 17 00:00:00 2001
From: Shiz <hi@shiz.me>
Date: Mon, 8 May 2017 23:09:13 +0200
Subject: [PATCH] sysklogd: add -Z option to adjust message timezones

Some syslog() implementations like musl's[1] always send timestamps in UTC.
This change adds a new option to syslogd, -Z, to assume incoming timestamps
are always UTC and adjust them to the local timezone (of the syslogd) before
logging.

[1]: http://www.openwall.com/lists/musl/2014/01/29/1

Signed-off-by: Shiz <hi@shiz.me>
---
 sysklogd/syslogd.c | 23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c
index 4265f4f90..eca955891 100644
--- a/sysklogd/syslogd.c
+++ b/sysklogd/syslogd.c
@@ -122,6 +122,7 @@
 //usage:       "(this version of syslogd ignores /etc/syslog.conf)\n"
 //usage:	)
 //usage:     "\n	-n		Run in foreground"
+//usage:     "\n	-Z		Adjust incoming UTC times to local time"
 //usage:	IF_FEATURE_REMOTE_LOG(
 //usage:     "\n	-R HOST[:PORT]	Log to HOST:PORT (default PORT:514)"
 //usage:     "\n	-L		Log locally and via network (default is network only if -R)"
@@ -233,6 +234,8 @@ typedef struct logRule_t {
 	/*int markInterval;*/                   \
 	/* level of messages to be logged */    \
 	int logLevel;                           \
+	/* whether to adjust message timezone */\
+	int adjustTimezone;                     \
 IF_FEATURE_ROTATE_LOGFILE( \
 	/* max size of file before rotation */  \
 	unsigned logFileSize;                   \
@@ -316,6 +319,7 @@ enum {
 	OPTBIT_outfile, // -O
 	OPTBIT_loglevel, // -l
 	OPTBIT_small, // -S
+	OPTBIT_adjusttz, // -Z
 	IF_FEATURE_ROTATE_LOGFILE(OPTBIT_filesize   ,)	// -s
 	IF_FEATURE_ROTATE_LOGFILE(OPTBIT_rotatecnt  ,)	// -b
 	IF_FEATURE_REMOTE_LOG(    OPTBIT_remotelog  ,)	// -R
@@ -330,6 +334,7 @@ enum {
 	OPT_outfile     = 1 << OPTBIT_outfile ,
 	OPT_loglevel    = 1 << OPTBIT_loglevel,
 	OPT_small       = 1 << OPTBIT_small   ,
+	OPT_adjusttz    = 1 << OPTBIT_adjusttz,
 	OPT_filesize    = IF_FEATURE_ROTATE_LOGFILE((1 << OPTBIT_filesize   )) + 0,
 	OPT_rotatecnt   = IF_FEATURE_ROTATE_LOGFILE((1 << OPTBIT_rotatecnt  )) + 0,
 	OPT_remotelog   = IF_FEATURE_REMOTE_LOG(    (1 << OPTBIT_remotelog  )) + 0,
@@ -339,7 +344,7 @@ enum {
 	OPT_cfg         = IF_FEATURE_SYSLOGD_CFG(   (1 << OPTBIT_cfg        )) + 0,
 	OPT_kmsg        = IF_FEATURE_KMSG_SYSLOG(   (1 << OPTBIT_kmsg       )) + 0,
 };
-#define OPTION_STR "m:nO:l:S" \
+#define OPTION_STR "m:nO:l:SZ" \
 	IF_FEATURE_ROTATE_LOGFILE("s:" ) \
 	IF_FEATURE_ROTATE_LOGFILE("b:" ) \
 	IF_FEATURE_REMOTE_LOG(    "R:*") \
@@ -815,17 +820,23 @@ static void timestamp_and_log(int pri, char *msg, int len)
 {
 	char *timestamp;
 	time_t now;
+	struct tm nowtm = { .tm_isdst = 0 };
 
 	/* Jan 18 00:11:22 msg... */
 	/* 01234567890123456 */
 	if (len < 16 || msg[3] != ' ' || msg[6] != ' '
 	 || msg[9] != ':' || msg[12] != ':' || msg[15] != ' '
 	) {
-		time(&now);
+		now = time(NULL);
 		timestamp = ctime(&now) + 4; /* skip day of week */
 	} else {
-		now = 0;
-		timestamp = msg;
+		if (G.adjustTimezone && strptime(msg, "%b %e %T", &nowtm)) {
+			now = mktime(&nowtm) - timezone;
+			timestamp = ctime(&now) + 4; /* skip day of week */
+		} else {
+			now = 0;
+			timestamp = msg;
+		}
 		msg += 16;
 	}
 	timestamp[15] = '\0';
@@ -1129,6 +1140,10 @@ int syslogd_main(int argc UNUSED_PARAM, char **argv)
 	if (opts & OPT_loglevel) // -l
 		G.logLevel = xatou_range(opt_l, 1, 8);
 	//if (opts & OPT_small) // -S
+	if (opts & OPT_adjusttz) { // -Z
+		G.adjustTimezone = 1;
+		tzset();
+	}
 #if ENABLE_FEATURE_ROTATE_LOGFILE
 	if (opts & OPT_filesize) // -s
 		G.logFileSize = xatou_range(opt_s, 0, INT_MAX/1024) * 1024;