Index: usr.sbin/syslogd/syslogd.8
===================================================================
RCS file: /cvsroot/src/usr.sbin/syslogd/syslogd.8,v
retrieving revision 1.37.2.1
diff -u -p -r1.37.2.1 syslogd.8
--- usr.sbin/syslogd/syslogd.8	26 Feb 2009 08:20:20 -0000	1.37.2.1
+++ usr.sbin/syslogd/syslogd.8	3 May 2010 15:11:30 -0000
@@ -1,4 +1,4 @@
-.\"	$NetBSD: syslogd.8,v 1.37.2.1 2009/02/26 08:20:20 snj Exp $
+.\"	$NetBSD: syslogd.8,v 1.42 2006/09/15 20:32:59 christos Exp $
 .\"
 .\" Copyright (c) 1983, 1986, 1991, 1993
 .\"	The Regents of the University of California.  All rights reserved.
@@ -29,7 +29,7 @@
 .\"
 .\"     from: @(#)syslogd.8	8.1 (Berkeley) 6/6/93
 .\"
-.Dd February 1, 2008
+.Dd September 15, 2006
 .Dt SYSLOGD 8
 .Os
 .Sh NAME
@@ -37,7 +37,10 @@
 .Nd log systems messages
 .Sh SYNOPSIS
 .Nm
-.Op Fl dnrSsUv
+.Op Fl dnrSsTUv
+.Bk -words
+.Op Fl b Ar bind_address
+.Ek
 .Bk -words
 .Op Fl f Ar config_file
 .Ek
@@ -68,6 +71,10 @@ reads and logs messages to the system co
 machines and/or users as specified by its configuration file.
 The options are as follows:
 .Bl -tag -width 15n
+.It Fl b Ar bind_address
+Specify one specific IP address or hostname to bind to.
+If a hostname is specified, the IPv4 or IPv6 address
+which corresponds to it is used.
 .It Fl d
 Enable debugging to the standard output,
 and do not disassociate from the controlling terminal.
@@ -123,6 +130,12 @@ and similar attacks.
 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 +201,13 @@ The logged message includes the date, ti
 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 overridden by the
+.Fl T
+flag.
+.Pp
 Accesses from UDP socket can be filtered by libwrap configuration files, like
 .Pa /etc/hosts.deny .
 Specify
@@ -208,6 +228,7 @@ decimal number in angle braces, for exam
 This priority code should map into the priorities defined in the
 include file
 .Aq Pa sys/syslog.h .
+See RFC 3164 for detailed description of the message format.
 .Pp
 Messages from the local kernel that are not tagged with a priority code
 receive the default facility
@@ -238,6 +259,12 @@ The kernel log device.
 .Xr services 5 ,
 .Xr syslog.conf 5 ,
 .Xr newsyslog 8
+.Rs
+.%R RFC
+.%N 3164
+.%D August 2001
+.%T The BSD syslog Protocol
+.Re
 .Sh HISTORY
 The
 .Nm
Index: usr.sbin/syslogd/syslogd.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/syslogd/syslogd.c,v
retrieving revision 1.75
diff -u -p -r1.75 syslogd.c
--- usr.sbin/syslogd/syslogd.c	9 Jan 2005 00:07:27 -0000	1.75
+++ usr.sbin/syslogd/syslogd.c	3 May 2010 15:11:31 -0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: syslogd.c,v 1.75 2005/01/09 00:07:27 christos Exp $	*/
+/*	$NetBSD: syslogd.c,v 1.84 2006/11/13 20:24:00 christos Exp $	*/
 
 /*
  * Copyright (c) 1983, 1988, 1993, 1994
@@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1983, 19
 #if 0
 static char sccsid[] = "@(#)syslogd.c	8.3 (Berkeley) 4/4/94";
 #else
-__RCSID("$NetBSD: syslogd.c,v 1.75 2005/01/09 00:07:27 christos Exp $");
+__RCSID("$NetBSD: syslogd.c,v 1.84 2006/11/13 20:24:00 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -242,6 +242,7 @@ int	UseNameService = 1;	/* make domain n
 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: */
@@ -256,14 +257,14 @@ void	die(struct kevent *);	/* SIGTERM ke
 void	domark(struct kevent *);/* timer kevent dispatch routine */
 void	fprintlog(struct filed *, int, char *);
 int	getmsgbufsize(void);
-int*	socksetup(int);
+int*	socksetup(int, const char *);
 void	init(struct kevent *);	/* SIGHUP kevent dispatch routine */
 void	logerror(const char *, ...);
 void	logmsg(int, char *, char *, int);
 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 *);
@@ -289,6 +290,7 @@ static void dispatch_read_funix(struct k
  */
 static char *linebuf;
 static size_t linebufsize;
+static const char *bindhostname = NULL;
 
 #define	A_CNT(x)	(sizeof((x)) / sizeof((x)[0]))
 
@@ -313,8 +315,11 @@ main(int argc, char *argv[])
 
 	(void)setlocale(LC_ALL, "");
 
-	while ((ch = getopt(argc, argv, "dnsSf:m:p:P:ru:g:t:Uv")) != -1)
+	while ((ch = getopt(argc, argv, "b:dnsSf:m:p:P:ru:g:t:TUv")) != -1)
 		switch(ch) {
+		case 'b':
+			bindhostname = optarg;
+			break;
 		case 'd':		/* debug */
 			Debug++;
 			break;
@@ -354,6 +359,9 @@ main(int argc, char *argv[])
 			if (*root == '\0')
 				usage();
 			break;
+		case 'T':
+			RemoteAddDate = 1;
+			break;
 		case 'u':
 			user = optarg;
 			if (*user == '\0')
@@ -601,9 +609,10 @@ usage(void)
 {
 
 	(void)fprintf(stderr,
-	    "usage: %s [-dnrSsUv] [-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());
+	    "usage: %s [-dnrSsTUv] [-b bind_address] [-f config_file] [-g group]\n"
+	    "\t[-m mark_interval] [-P file_list] [-p log_socket\n"
+	    "\t[-p log_socket2 ...]] [-t chroot_dir] [-u user]\n",
+	    getprogname());
 	exit(1);
 }
 
@@ -665,7 +674,7 @@ dispatch_read_funix(struct kevent *ev)
 	    (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,11 +717,12 @@ dispatch_read_finet(struct kevent *ev)
 
 	linebuf[rv] = '\0';
 	if (!reject)
-		printline(cvthname(&frominet), linebuf);
+		printline(cvthname(&frominet), linebuf,
+			  RemoteAddDate ? ADDDATE : 0);
 }
 
 /*
- * given a pointer to an array of char *'s, a pointer to it's current
+ * given a pointer to an array of char *'s, a pointer to its current
  * size and current allocated max size, and a new char * to add, add
  * it, update everything as necessary, possibly allocating a new array
  */
@@ -770,7 +780,7 @@ logpath_fileadd(char ***lp, int *szp, in
  * 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 +827,7 @@ printline(char *hname, char *msg)
 	}
 	*q = '\0';
 
-	logmsg(pri, line, hname, 0);
+	logmsg(pri, line, hname, flags);
 }
 
 /*
@@ -870,11 +880,22 @@ matches_spec(const char *name, const cha
     char *(*check)(const char *, const char *))
 {
 	const char *s;
+	const char *cursor;
 	char prev, next;
+	size_t len;
+
+	if (name[0] == '\0')
+		return (0);
 
-	if ((s = (*check)(spec, name)) != NULL) {
+	if (strchr(name, ',')) /* sanity */
+		return (0);
+
+	len = strlen(name);
+	cursor = spec;
+	while ((s = (*check)(cursor, name)) != NULL) {
 		prev = s == spec ? ',' : *(s - 1);
-		next = *(s + strlen(name));
+		cursor = s + len;
+		next = *cursor;
 
 		if (prev == ',' && (next == '\0' || next == ','))
 			return (1);
@@ -1066,7 +1087,7 @@ fprintlog(struct filed *f, int flags, ch
 	struct iovec iov[10];
 	struct iovec *v;
 	struct addrinfo *r;
-	int j, l, lsent;
+	int j, l, lsent, fail, retry;
 	char line[MAXLINE + 1], repbuf[80], greetings[200];
 #define ADDEV() assert(++v - iov < A_CNT(iov))
 
@@ -1176,7 +1197,10 @@ fprintlog(struct filed *f, int flags, ch
 		if (l > MAXLINE)
 			l = MAXLINE;
 		if (finet) {
+			lsent = -1;
+			fail = 0;
 			for (r = f->f_un.f_forw.f_addr; r; r = r->ai_next) {
+				retry = 0;
 				for (j = 0; j < *finet; j++) {
 #if 0 
 					/*
@@ -1186,13 +1210,33 @@ fprintlog(struct filed *f, int flags, ch
 					if (r->ai_family ==
 					    address_family_of(finet[j+1])) 
 #endif
+sendagain:
 					lsent = sendto(finet[j+1], line, l, 0,
 					    r->ai_addr, r->ai_addrlen);
-					if (lsent == l) 
+					if (lsent == -1) {
+						switch (errno) {
+						case ENOBUFS:
+							/* wait/retry/drop */
+							if (++retry < 5) {
+								usleep(1000);
+								goto sendagain;
+							}
+							break;
+						case EHOSTDOWN:
+						case EHOSTUNREACH:
+						case ENETDOWN:
+							/* drop */
+							break;
+						default:
+							/* busted */
+							fail++;
+							break;
+						}
+					} else if (lsent == l) 
 						break;
 				}
 			}
-			if (lsent != l) {
+			if (lsent != l && fail) {
 				f->f_type = F_UNUSED;
 				logerror("sendto() failed");
 			}
@@ -1584,7 +1628,7 @@ die(struct kevent *ev)
 void
 init(struct kevent *ev)
 {
-	int i;
+	size_t i;
 	FILE *cf;
 	struct filed *f, *next, **nextp;
 	char *p;
@@ -1702,9 +1746,15 @@ init(struct kevent *ev)
 				strcpy(host, "*");
 				continue;
 			}
-			if (*p == '@')
-				p = LocalHostName;
 			for (i = 1; i < MAXHOSTNAMELEN - 1; i++) {
+				if (*p == '@') {
+					(void)strncpy(&host[i], LocalHostName,
+					    sizeof(host) - 1 - i);
+					host[sizeof(host) - 1] = '\0';
+					i = strlen(host) - 1;
+					p++;
+					continue;
+				}
 				if (!isalnum((unsigned char)*p) &&
 				    *p != '.' && *p != '-' && *p != ',')
 					break;
@@ -1778,7 +1828,7 @@ init(struct kevent *ev)
 		}
 	}
 
-	finet = socksetup(PF_UNSPEC);
+	finet = socksetup(PF_UNSPEC, bindhostname);
 	if (finet) {
 		if (SecureMode) {
 			for (i = 0; i < *finet; i++) {
@@ -2087,7 +2137,7 @@ getmsgbufsize(void)
 }
 
 int *
-socksetup(int af)
+socksetup(int af, const char *hostname)
 {
 	struct addrinfo hints, *res, *r;
 	struct kevent *ev;
@@ -2101,7 +2151,7 @@ socksetup(int af)
 	hints.ai_flags = AI_PASSIVE;
 	hints.ai_family = af;
 	hints.ai_socktype = SOCK_DGRAM;
-	error = getaddrinfo(NULL, "syslog", &hints, &res);
+	error = getaddrinfo(hostname, "syslog", &hints, &res);
 	if (error) {
 		logerror(gai_strerror(error));
 		errno = 0;
