Subject: bin/32579: enhancement to syslogd - always printing the local time
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: Pavel Cahyna <pcah8322@artax.karlin.mff.cuni.cz>
List: netbsd-bugs
Date: 01/20/2006 09:50:00
>Number:         32579
>Category:       bin
>Synopsis:       patch for syslogd - always printing the local time
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Fri Jan 20 09:50:00 +0000 2006
>Originator:     Pavel Cahyna
>Release:        NetBSD 3.0_RC5
>Organization:
>Environment:
System: NetBSD beta 3.0_RC5 NetBSD 3.0_RC5 (EV56) #3: Mon Dec 12 20:28:20 CET 2005 pavel@beta:/usr/src/sys/arch/alpha/compile/EV56 alpha
Architecture: alpha
Machine: alpha
>Description:
(see also
http://mail-index.netbsd.org/tech-userlevel/2006/01/09/0009.html )
syslogd has currently an undocumented feature - if it does not recognize
the timestamp field in the received message, it generates it, based on the
local time.

Some devices which are logging over UDP are unable to keep correct
time or generate a timestamp field with incorrect format. It would
make sense to add a timestamp field always, so that the correct time
is available for messages generated by devices whose clock is not
synchronized, and log files are consistent in the case when some
received messages have the timestamp field in the correct format and
others don't.

This patch adds a -T option to syslogd which causes it to generate a
timestamp for all messages received over the network. The default
behavior is unchanged.

The patch also documents the curret behavior.
>How-To-Repeat:
Use devices with problems mentioned above. E.g. switches without NTP.
>Fix:
Index: syslogd.8
===================================================================
RCS file: /home/pavel/cvs/src/usr.sbin/syslogd/syslogd.8,v
retrieving revision 1.37
diff -u -u -r1.37 syslogd.8
--- syslogd.8	19 Nov 2004 18:48:29 -0000	1.37
+++ syslogd.8	7 Jan 2006 14:25:38 -0000
@@ -123,6 +123,12 @@
 to
 .Ar chroot_dir
 after the sockets and log files have been opened.
+.It Fl T
+Always use the local time and date for messages received from the
+network, instead of the timestamp field supplied in the message
+by the remote host.
+This is useful if some of the originating hosts can't keep time
+properly or are unable to generate a correct timestamp.
 .It Fl u Ar user
 Set UID to
 .Ar user
@@ -188,6 +194,13 @@
 the log socket).
 Commonly, the program name and the process id is included.
 .Pp
+The date and time are taken from the received message.
+If the format of the timestamp field is incorrect, time obtained from
+the local host is used instead.
+This can be overriden by the
+.Fl T
+flag.
+.Pp
 Accesses from UDP socket can be filtered by libwrap configuration files, like
 .Pa /etc/hosts.deny .
 Specify
Index: syslogd.c
===================================================================
RCS file: /home/pavel/cvs/src/usr.sbin/syslogd/syslogd.c,v
retrieving revision 1.75
diff -u -u -r1.75 syslogd.c
--- syslogd.c	9 Jan 2005 00:07:27 -0000	1.75
+++ syslogd.c	7 Jan 2006 14:34:05 -0000
@@ -242,6 +242,7 @@
 int	NumForwards = 0;	/* number of forwarding actions in conf file */
 char	**LogPaths;		/* array of pathnames to read messages from */
 int	NoRepeat = 0;		/* disable "repeated"; log always */
+int	RemoteAddDate = 0;	/* always add date to messages from network */
 int	SyncKernel = 0;		/* write kernel messages synchronously */
 int	UniquePriority = 0;	/* only log specified priority */
 int	LogFacPri = 0;		/* put facility and priority in log messages: */
@@ -263,7 +264,7 @@
 void	log_deadchild(pid_t, int, const char *);
 int	matches_spec(const char *, const char *,
 		     char *(*)(const char *, const char *));
-void	printline(char *, char *);
+void	printline(char *, char *, int);
 void	printsys(char *);
 int	p_open(char *, pid_t *);
 void	trim_localdomain(char *);
@@ -313,7 +314,7 @@
 
 	(void)setlocale(LC_ALL, "");
 
-	while ((ch = getopt(argc, argv, "dnsSf:m:p:P:ru:g:t:Uv")) != -1)
+	while ((ch = getopt(argc, argv, "dnsSf:m:p:P:ru:g:t:TUv")) != -1)
 		switch(ch) {
 		case 'd':		/* debug */
 			Debug++;
@@ -354,6 +355,9 @@
 			if (*root == '\0')
 				usage();
 			break;
+		case 'T':
+			RemoteAddDate = 1;
+			break;
 		case 'u':
 			user = optarg;
 			if (*user == '\0')
@@ -601,7 +605,7 @@
 {
 
 	(void)fprintf(stderr,
-	    "usage: %s [-dnrSsUv] [-f config_file] [-g group] [-m mark_interval]\n"
+	    "usage: %s [-dnrSsTUv] [-f config_file] [-g group] [-m mark_interval]\n"
 	    "\t[-P file_list] [-p log_socket [-p log_socket2 ...]]\n"
 	    "\t[-t chroot_dir] [-u user]\n", getprogname());
 	exit(1);
@@ -665,7 +669,7 @@
 	    (struct sockaddr *)&fromunix, &sunlen);
 	if (rv > 0) {
 		linebuf[rv] = '\0';
-		printline(LocalHostName, linebuf);
+		printline(LocalHostName, linebuf, 0);
 	} else if (rv < 0 && errno != EINTR) {
 		logerror("recvfrom() unix `%s'", myname.sun_path);
 	}
@@ -708,7 +712,8 @@
 
 	linebuf[rv] = '\0';
 	if (!reject)
-		printline(cvthname(&frominet), linebuf);
+		printline(cvthname(&frominet), linebuf,
+			  RemoteAddDate ? ADDDATE : 0);
 }
 
 /*
@@ -770,7 +775,7 @@
  * on the appropriate log files.
  */
 void
-printline(char *hname, char *msg)
+printline(char *hname, char *msg, int flags)
 {
 	int c, pri;
 	char *p, *q, line[MAXLINE + 1];
@@ -817,7 +822,7 @@
 	}
 	*q = '\0';
 
-	logmsg(pri, line, hname, 0);
+	logmsg(pri, line, hname, flags);
 }
 
 /*