Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 13 Jun 2018 13:41:23 +0000 (UTC)
From:      Ed Schouten <ed@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r335059 - in stable/11: usr.bin/wall usr.sbin/syslogd
Message-ID:  <201806131341.w5DDfN7T043988@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ed
Date: Wed Jun 13 13:41:23 2018
New Revision: 335059
URL: https://svnweb.freebsd.org/changeset/base/335059

Log:
  MFC r309925, r309931, r309933, r310035, r310278, r310310, r310311,
      r310323, r310349, r310350, r310351, r310352, r310383, r310384,
      r310385, r310386, r310393, r310453, r310456, r310494, r310504,
      r310528, r310890, r310893, r310974, r311918, r312921, r313357,
      r314563, r314585, r314642, r315322, r315618, r315620, r315622,
      r315643, r316951, r316973, r326338, r326339, r326573, r331270,
      r332099, r332110, r332111, r332118, r332165, r332510 and r332511.
  
  This commit brings syslogd(8) in sync with the copy in HEAD. The key
  improvement of this change is that it adds support for RFC 5424 log
  ingestion and exposition (enabled by passing in -O rfc5424). This allows
  for saner logging in environments with multiple time zones.
  
  The list of changes to merge back were obtained by running:
  
      svn mergeinfo --show-revs eligible \
          ^/head/usr.sbin/syslogd ^/stable/11/usr.sbin/syslogd
  
  Of the commits listed, r314436, r325188 and r326025 were excluded, as
  they affect a significant number of unrelated files (SPDX and 4-clause
  license renumbering). Due to the large number of directly committed
  changes on this branch, I had no choice but to perform the merge as
  follows:
  
      svn merge --accept=theirs-full -c <list of revisions> ^/head .
  
  This would, however, cause some unrelated changes, such as undoing the
  r333356 (MFC of r332877) and still adding the SPDX tag to syslogd.c.
  These have been reverted manually.
  
  Requested by:	Dave Cottlehuber
  Thanks to:	dim@ for sharing his insight on hackers@

Modified:
  stable/11/usr.bin/wall/ttymsg.c
  stable/11/usr.bin/wall/ttymsg.h
  stable/11/usr.sbin/syslogd/Makefile
  stable/11/usr.sbin/syslogd/syslogd.8
  stable/11/usr.sbin/syslogd/syslogd.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/usr.bin/wall/ttymsg.c
==============================================================================
--- stable/11/usr.bin/wall/ttymsg.c	Wed Jun 13 13:15:04 2018	(r335058)
+++ stable/11/usr.bin/wall/ttymsg.c	Wed Jun 13 13:41:23 2018	(r335059)
@@ -59,7 +59,7 @@ static const char sccsid[] = "@(#)ttymsg.c	8.2 (Berkel
 const char *
 ttymsg(struct iovec *iov, int iovcnt, const char *line, int tmout)
 {
-	struct iovec localiov[7];
+	struct iovec localiov[TTYMSG_IOV_MAX];
 	ssize_t left, wret;
 	int cnt, fd;
 	char device[MAXNAMLEN] = _PATH_DEV;

Modified: stable/11/usr.bin/wall/ttymsg.h
==============================================================================
--- stable/11/usr.bin/wall/ttymsg.h	Wed Jun 13 13:15:04 2018	(r335058)
+++ stable/11/usr.bin/wall/ttymsg.h	Wed Jun 13 13:41:23 2018	(r335059)
@@ -1,3 +1,5 @@
 /* $FreeBSD$ */
 
+#define	TTYMSG_IOV_MAX	32
+
 const char	*ttymsg(struct iovec *, int, const char *, int);

Modified: stable/11/usr.sbin/syslogd/Makefile
==============================================================================
--- stable/11/usr.sbin/syslogd/Makefile	Wed Jun 13 13:15:04 2018	(r335058)
+++ stable/11/usr.sbin/syslogd/Makefile	Wed Jun 13 13:41:23 2018	(r335059)
@@ -11,8 +11,9 @@ SRCS=	syslogd.c ttymsg.c
 
 LIBADD=	util
 
-WARNS?= 3
-
+.if ${MK_INET_SUPPORT} != "no"
+CFLAGS+= -DINET
+.endif
 .if ${MK_INET6_SUPPORT} != "no"
 CFLAGS+= -DINET6
 .endif

Modified: stable/11/usr.sbin/syslogd/syslogd.8
==============================================================================
--- stable/11/usr.sbin/syslogd/syslogd.8	Wed Jun 13 13:15:04 2018	(r335058)
+++ stable/11/usr.sbin/syslogd/syslogd.8	Wed Jun 13 13:41:23 2018	(r335059)
@@ -28,7 +28,7 @@
 .\"     @(#)syslogd.8	8.1 (Berkeley) 6/6/93
 .\" $FreeBSD$
 .\"
-.Dd June 16, 2015
+.Dd April 15, 2018
 .Dt SYSLOGD 8
 .Os
 .Sh NAME
@@ -36,18 +36,22 @@
 .Nd log systems messages
 .Sh SYNOPSIS
 .Nm
-.Op Fl 468ACcdFkNnosTuv
+.Op Fl 468ACcdFHkNnosTuv
 .Op Fl a Ar allowed_peer
 .Op Fl b Ar bind_address
 .Op Fl f Ar config_file
-.Op Fl l Oo Ar mode : Oc Ns Ar path
+.Op Fl l Oo Ar mode Ns \&: Oc Ns Ar path
 .Op Fl m Ar mark_interval
+.Op Fl O Ar format
 .Op Fl P Ar pid_file
 .Op Fl p Ar log_socket
+.Op Fl S Ar logpriv_socket
 .Sh DESCRIPTION
 The
 .Nm
-utility reads and logs messages to the system console, log files, other
+utility reads and logs messages to the system console,
+log files,
+other
 machines and/or users as specified by its configuration file.
 .Pp
 The options are as follows:
@@ -63,7 +67,8 @@ to use IPv6 addresses only.
 .It Fl 8
 Tells
 .Nm
-not to interfere with 8-bit data.  Normally
+not to interfere with 8-bit data.
+Normally
 .Nm
 will replace C1 control characters
 .Pq ISO 8859 and Unicode characters
@@ -98,21 +103,23 @@ options may be specified.
 The
 .Ar allowed_peer
 option may be any of the following:
-.Bl -tag -width "ipaddr/masklen[:service]XX"
+.Bl -tag -width "ipaddr[/prefixlen][:service]XX"
 .It Xo
 .Sm off
 .Ar ipaddr
-.No / Ar masklen
-.Op : Ar service
+.Op / Ar masklen
+.Op \&: Ar service
+.Pp
+.Ar ipaddr
+.Op / Ar prefixlen
+.Op \&: Ar service
 .Sm on
 .Xc
 Accept datagrams from
+.Ar ipaddr ,
 .Ar ipaddr
-(in the usual dotted quad notation) with
-.Ar masklen
-bits being taken into account when doing the address comparison.
-.Ar ipaddr
-can be also IPv6 address by enclosing the address with
+can be specified as an IPv4 address or as an IPv6
+address enclosed with
 .Ql \&[
 and
 .Ql \&] .
@@ -125,7 +132,7 @@ A
 .Ar service
 of
 .Ql \&*
-allows packets being sent from any UDP port.
+accepts UDP packets from any source port.
 The default
 .Ar service
 is
@@ -136,16 +143,18 @@ is IPv4 address, a missing
 .Ar masklen
 will be substituted by the historic class A or class B netmasks if
 .Ar ipaddr
-belongs into the address range of class A or B, respectively, or
-by 24 otherwise.
+belongs into the address range of class A or B,
+respectively,
+or by 24 otherwise.
 If
 .Ar ipaddr
-is IPv6 address, a missing
+is IPv6 address,
+a missing
 .Ar masklen
 will be substituted by 128.
 .It Xo
 .Sm off
-.Ar domainname Op : Ar service
+.Ar domainname Op \&: Ar service
 .Sm on
 .Xc
 Accept datagrams where the reverse address lookup yields
@@ -154,16 +163,9 @@ for the sender address.
 The meaning of
 .Ar service
 is as explained above.
-.It Xo
-.Sm off
-.No * Ar domainname Op : Ar service
-.Sm on
-.Xc
-Same as before, except that any source host whose name
-.Em ends
-in
 .Ar domainname
-will get permission.
+can contain special characters of a shell-style pattern such as
+.Ql Li \&* .
 .El
 .Pp
 The
@@ -174,13 +176,13 @@ option is also specified.
 .It Xo
 .Fl b
 .Sm off
-.Ar bind_address Op : Ar service
+.Ar bind_address Op \&: Ar service
 .Sm on
 .Xc
 .It Xo
 .Fl b
 .Sm off
-.Li : Ar service
+.Li \&: Ar service
 .Sm on
 .Xc
 Bind to a specific address and/or port.
@@ -197,35 +199,40 @@ is
 This option can be specified multiple times to bind to
 multiple addresses and/or ports.
 .It Fl C
-Create log files that do not exist (permission is set to
-.Li 0600 ) .
+Create log files that do not exist
+.Pq permission is set to Ql Li 0600 .
 .It Fl c
 Disable the compression of repeated instances of the same line
 into a single line of the form
 .Dq Li "last message repeated N times"
 when the output is a pipe to another program.
-If specified twice, disable this compression in all cases.
+If specified twice,
+disable this compression in all cases.
 .It Fl d
 Put
 .Nm
 into debugging mode.
 This is probably only of use to developers working on
 .Nm .
-.It Fl f
+.It Fl f Ar config_file
 Specify the pathname of an alternate configuration file;
 the default is
 .Pa /etc/syslog.conf .
 .It Fl F
 Run
 .Nm
-in the foreground, rather than going into daemon mode. This is useful if
-some other process uses
+in the foreground,
+rather than going into daemon mode.
+This is useful if some other process uses
 .Xr fork 2
 and
 .Xr exec 3
 to run
 .Nm ,
 and wants to monitor when and how it exits.
+.It Fl H
+When logging remote messages use hostname from the message (if supplied)
+instead of using address from which the message was received.
 .It Fl k
 Disable the translation of
 messages received with facility
@@ -236,68 +243,107 @@ Usually the
 .Dq kern
 facility is reserved for messages read directly from
 .Pa /dev/klog .
-.It Fl m
+.It Fl m Ar mark_interval
 Select the number of minutes between
 .Dq mark
-messages; the default is 20 minutes.
+messages;
+the default is 20 minutes.
 .It Fl N
-Disable binding on UDP sockets.  RFC 3164 recommends that outgoing
-syslogd messages should originate from the privileged port, this
-option
+Disable binding on UDP sockets.
+RFC 3164 recommends that outgoing
+.Nm
+messages should originate from the privileged port,
+this option
 .Em disables
-the recommended behavior.  This option inherits
+the recommended behavior.
+This option inherits
 .Fl s .
 .It Fl n
-Disable dns query for every request.
+Disable DNS query for every request.
+.It Fl O Ar format
+Select the output format of generated log messages.
+The values
+.Ar bsd
+and
+.Ar rfc3164
+are used to generate RFC 3164 log messages.
+The values
+.Ar syslog
+and
+.Ar rfc5424
+are used to generate RFC 5424 log messages,
+having RFC 3339 timestamps with microsecond precision.
+The default is to generate RFC 3164 log messages.
 .It Fl o
 Prefix kernel messages with the full kernel boot file as determined by
 .Xr getbootfile 3 .
 Without this, the kernel message prefix is always
 .Dq Li kernel: .
-.It Fl p
+.It Fl p Ar log_socket
 Specify the pathname of an alternate log socket to be used instead;
 the default is
 .Pa /var/run/log .
-.It Fl P
+When a single
+.Fl p
+option is specified,
+the default pathname is replaced with the specified one.
+When two or more
+.Fl p
+options are specified,
+the remaining pathnames are treated as additional log sockets.
+.It Fl P Ar pid_file
 Specify an alternative file in which to store the process ID.
 The default is
 .Pa /var/run/syslog.pid .
-.It Fl S
+.It Fl S Ar logpriv_socket
 Specify the pathname of an alternate log socket for privileged
-applications to be used instead; the default is
+applications to be used instead;
+the default is
 .Pa /var/run/logpriv .
-.It Fl l
+When a single
+.Fl S
+option is specified,
+the default pathname is replaced with the specified one.
+When two or more
+.Fl S
+options are specified,
+the remaining pathnames are treated as additional log sockets.
+.It Fl l Oo Ar mode Ns \&: Oc Ns Ar path
 Specify a location where
 .Nm
 should place an additional log socket.
 The primary use for this is to place additional log sockets in
 .Pa /var/run/log
 of various chroot filespaces.
-File permissions for socket can be specified in octal representation
-before socket name, delimited with a colon.
-Path to socket location must be absolute.
+File permissions for socket can be specified in octal representation in
+.Ar mode ,
+delimited with a colon.
+The socket location must be specified as an absolute pathname in
+.Ar path .
 .It Fl s
 Operate in secure mode.
 Do not log messages from remote machines.
-If
-specified twice, no network socket will be opened at all, which also
-disables logging to remote machines.
+If specified twice,
+no network socket will be opened at all,
+which also disables logging to remote machines.
 .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
+This is useful if some of the originating hosts cannot keep time properly
 or are unable to generate a correct timestamp.
 .It Fl u
 Unique priority logging.
 Only log messages at the specified priority.
-Without this option, messages at the stated priority or higher are logged.
+Without this option,
+messages at the stated priority or higher are logged.
 This option changes the default comparison from
 .Dq =>
 to
 .Dq = .
 .It Fl v
 Verbose logging.
-If specified once, the numeric facility and priority are
+If specified once,
+the numeric facility and priority are
 logged with each locally-written message.
 If specified more than once,
 the names of the facility and priority are logged with each locally-written
@@ -324,7 +370,7 @@ from an Internet domain socket specified in
 .Pa /etc/services ,
 and from the special device
 .Pa /dev/klog
-(to read kernel messages).
+.Pq to read kernel messages .
 .Pp
 The
 .Nm
@@ -339,8 +385,10 @@ This can be used to kill or reconfigure
 The message sent to
 .Nm
 should consist of a single line.
-The message can contain a priority code, which should be a preceding
-decimal number in angle braces, for example,
+The message can contain a priority code,
+which should be a preceding
+decimal number in angle braces,
+for example,
 .Sq Aq 5 .
 This priority code should map into the priorities defined in the
 include file
@@ -348,9 +396,10 @@ include file
 .Pp
 For security reasons,
 .Nm
-will not append to log files that do not exist (unless
-.Fl C
-option is specified);
+will not append to log files that do not exist
+.Po unless Fl C
+option is specified
+.Pc ;
 therefore, they must be created manually before running
 .Nm .
 .Pp
@@ -399,23 +448,23 @@ options are
 extensions.
 .Sh BUGS
 The ability to log messages received in UDP packets is equivalent to
-an unauthenticated remote disk-filling service, and should probably be
-disabled by default.
+an unauthenticated remote disk-filling service,
+and should probably be disabled by default.
 Some sort of
 .No inter- Ns Nm syslogd
 authentication mechanism ought to be worked out.
-To prevent the worst
-abuse, use of the
+To prevent the worst abuse,
+use of the
 .Fl a
 option is therefore highly recommended.
 .Pp
 The
 .Fl a
-matching algorithm does not pretend to be very efficient; use of numeric
-IP addresses is faster than domain name comparison.
-Since the allowed
-peer list is being walked linearly, peer groups where frequent messages
-are being anticipated from should be put early into the
+matching algorithm does not pretend to be very efficient;
+use of numeric IP addresses is faster than domain name comparison.
+Since the allowed peer list is being walked linearly,
+peer groups where frequent messages are being anticipated
+from should be put early into the
 .Fl a
 list.
 .Pp

Modified: stable/11/usr.sbin/syslogd/syslogd.c
==============================================================================
--- stable/11/usr.sbin/syslogd/syslogd.c	Wed Jun 13 13:15:04 2018	(r335058)
+++ stable/11/usr.sbin/syslogd/syslogd.c	Wed Jun 13 13:41:23 2018	(r335059)
@@ -26,6 +26,33 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2018 Prodrive Technologies, https://prodrive-technologies.com/
+ * Author: Ed Schouten <ed@FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
 
 #ifndef lint
 static const char copyright[] =
@@ -69,8 +96,7 @@ __FBSDID("$FreeBSD$");
  */
 
 /* Maximum number of characters in time of last occurrence */
-#define	MAXDATELEN	16
-#define	MAXLINE		1024		/* maximum line length */
+#define	MAXLINE		2048		/* maximum line length */
 #define	MAXSVLINE	MAXLINE		/* maximum saved line length */
 #define	DEFUPRI		(LOG_USER|LOG_NOTICE)
 #define	DEFSPRI		(LOG_KERN|LOG_CRIT)
@@ -90,21 +116,25 @@ __FBSDID("$FreeBSD$");
 #include <sys/uio.h>
 #include <sys/un.h>
 #include <sys/wait.h>
-#include <sys/types.h>
 
+#if defined(INET) || defined(INET6)
 #include <netinet/in.h>
-#include <netdb.h>
 #include <arpa/inet.h>
+#endif
 
+#include <assert.h>
 #include <ctype.h>
 #include <dirent.h>
 #include <err.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <fnmatch.h>
 #include <libutil.h>
 #include <limits.h>
+#include <netdb.h>
 #include <paths.h>
 #include <signal.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -118,54 +148,69 @@ __FBSDID("$FreeBSD$");
 #define SYSLOG_NAMES
 #include <sys/syslog.h>
 
-const char	*ConfFile = _PATH_LOGCONF;
-const char	*PidFile = _PATH_LOGPID;
-const char	ctty[] = _PATH_CONSOLE;
-static const char	include_str[] = "include";
-static const char	include_ext[] = ".conf";
+static const char *ConfFile = _PATH_LOGCONF;
+static const char *PidFile = _PATH_LOGPID;
+static const char ctty[] = _PATH_CONSOLE;
+static const char include_str[] = "include";
+static const char include_ext[] = ".conf";
 
 #define	dprintf		if (Debug) printf
 
 #define	MAXUNAMES	20	/* maximum number of user names */
 
+#define	sstosa(ss)	((struct sockaddr *)(ss))
+#ifdef INET
+#define	sstosin(ss)	((struct sockaddr_in *)(void *)(ss))
+#define	satosin(sa)	((struct sockaddr_in *)(void *)(sa))
+#endif
+#ifdef INET6
+#define	sstosin6(ss)	((struct sockaddr_in6 *)(void *)(ss))
+#define	satosin6(sa)	((struct sockaddr_in6 *)(void *)(sa))
+#define	s6_addr32	__u6_addr.__u6_addr32
+#define	IN6_ARE_MASKED_ADDR_EQUAL(d, a, m)	(	\
+	(((d)->s6_addr32[0] ^ (a)->s6_addr32[0]) & (m)->s6_addr32[0]) == 0 && \
+	(((d)->s6_addr32[1] ^ (a)->s6_addr32[1]) & (m)->s6_addr32[1]) == 0 && \
+	(((d)->s6_addr32[2] ^ (a)->s6_addr32[2]) & (m)->s6_addr32[2]) == 0 && \
+	(((d)->s6_addr32[3] ^ (a)->s6_addr32[3]) & (m)->s6_addr32[3]) == 0 )
+#endif
 /*
- * List of hosts for binding.
+ * List of peers and sockets for binding.
  */
-static STAILQ_HEAD(, host) hqueue;
-struct host {
-	char			*name;
-	STAILQ_ENTRY(host)	next;
+struct peer {
+	const char	*pe_name;
+	const char	*pe_serv;
+	mode_t		pe_mode;
+	STAILQ_ENTRY(peer)	next;
 };
+static STAILQ_HEAD(, peer) pqueue = STAILQ_HEAD_INITIALIZER(pqueue);
 
-/*
- * Unix sockets.
- * We have two default sockets, one with 666 permissions,
- * and one for privileged programs.
- */
-struct funix {
-	int			s;
-	const char		*name;
-	mode_t			mode;
-	STAILQ_ENTRY(funix)	next;
+struct socklist {
+	struct sockaddr_storage	sl_ss;
+	int			sl_socket;
+	struct peer		*sl_peer;
+	int			(*sl_recv)(struct socklist *);
+	STAILQ_ENTRY(socklist)	next;
 };
-struct funix funix_secure =	{ -1, _PATH_LOG_PRIV, S_IRUSR | S_IWUSR,
-				{ NULL } };
-struct funix funix_default =	{ -1, _PATH_LOG, DEFFILEMODE,
-				{ &funix_secure } };
+static STAILQ_HEAD(, socklist) shead = STAILQ_HEAD_INITIALIZER(shead);
 
-STAILQ_HEAD(, funix) funixes =	{ &funix_default,
-				&(funix_secure.next.stqe_next) };
-
 /*
  * Flags to logmsg().
  */
 
 #define	IGN_CONS	0x001	/* don't print on console */
 #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	ISKERNEL	0x010	/* kernel generated message */
 
+/* Timestamps of log entries. */
+struct logtime {
+	struct tm	tm;
+	suseconds_t	usec;
+};
+
+/* Traditional syslog timestamp format. */
+#define	RFC3164_DATELEN	15
+#define	RFC3164_DATEFMT	"%b %e %H:%M:%S"
+
 /*
  * This structure represents the files that will have log
  * copies printed.
@@ -174,7 +219,7 @@ STAILQ_HEAD(, funix) funixes =	{ &funix_default,
  */
 
 struct filed {
-	struct	filed *f_next;		/* next in linked list */
+	STAILQ_ENTRY(filed)	next;	/* next in linked list */
 	short	f_type;			/* entry type, see below */
 	short	f_file;			/* file descriptor */
 	time_t	f_time;			/* time this was last written */
@@ -198,11 +243,16 @@ struct filed {
 			pid_t	f_pid;
 		} f_pipe;
 	} f_un;
+#define	fu_uname	f_un.f_uname
+#define	fu_forw_hname	f_un.f_forw.f_hname
+#define	fu_forw_addr	f_un.f_forw.f_addr
+#define	fu_fname	f_un.f_fname
+#define	fu_pipe_pname	f_un.f_pipe.f_pname
+#define	fu_pipe_pid	f_un.f_pipe.f_pid
 	char	f_prevline[MAXSVLINE];		/* last message logged */
-	char	f_lasttime[MAXDATELEN];		/* time of last occurrence */
-	char	f_prevhost[MAXHOSTNAMELEN];	/* host from which recd. */
+	struct logtime f_lasttime;		/* time of last occurrence */
 	int	f_prevpri;			/* pri of f_prevline */
-	int	f_prevlen;			/* length of f_prevline */
+	size_t	f_prevlen;			/* length of f_prevline */
 	int	f_prevcount;			/* repetition cnt of prevline */
 	u_int	f_repeatcount;			/* number of "repeated" msgs */
 	int	f_flags;			/* file-specific flags */
@@ -213,15 +263,13 @@ struct filed {
 /*
  * Queue of about-to-be dead processes we should watch out for.
  */
-
-TAILQ_HEAD(stailhead, deadq_entry) deadq_head;
-struct stailhead *deadq_headp;
-
 struct deadq_entry {
 	pid_t				dq_pid;
 	int				dq_timeout;
 	TAILQ_ENTRY(deadq_entry)	dq_entries;
 };
+static TAILQ_HEAD(, deadq_entry) deadq_head =
+    TAILQ_HEAD_INITIALIZER(deadq_head);
 
 /*
  * The timeout to apply to processes waiting on the dead queue.  Unit
@@ -231,9 +279,6 @@ struct deadq_entry {
 
 #define	 DQ_TIMO_INIT	2
 
-typedef struct deadq_entry *dq_t;
-
-
 /*
  * Struct to hold records of network addresses that are allowed to log
  * to us.
@@ -251,7 +296,9 @@ struct allowedpeer {
 #define a_addr u.numeric.addr
 #define a_mask u.numeric.mask
 #define a_name u.name
+	STAILQ_ENTRY(allowedpeer)	next;
 };
+static STAILQ_HEAD(, allowedpeer) aphead = STAILQ_HEAD_INITIALIZER(aphead);
 
 
 /*
@@ -259,12 +306,13 @@ struct allowedpeer {
  * in seconds after previous message is logged.  After each flush,
  * we move to the next interval until we reach the largest.
  */
-int	repeatinterval[] = { 30, 120, 600 };	/* # of secs before flush */
-#define	MAXREPEAT ((sizeof(repeatinterval) / sizeof(repeatinterval[0])) - 1)
+static int repeatinterval[] = { 30, 120, 600 };	/* # of secs before flush */
+#define	MAXREPEAT	(nitems(repeatinterval) - 1)
 #define	REPEATTIME(f)	((f)->f_time + repeatinterval[(f)->f_repeatcount])
-#define	BACKOFF(f)	{ if (++(f)->f_repeatcount > MAXREPEAT) \
-				 (f)->f_repeatcount = MAXREPEAT; \
-			}
+#define	BACKOFF(f)	do {						\
+				if (++(f)->f_repeatcount > MAXREPEAT)	\
+					(f)->f_repeatcount = MAXREPEAT;	\
+			} while (0)
 
 /* values for f_type */
 #define F_UNUSED	0		/* unused entry */
@@ -276,12 +324,13 @@ int	repeatinterval[] = { 30, 120, 600 };	/* # of secs 
 #define F_WALL		6		/* everyone logged on */
 #define F_PIPE		7		/* pipe to program */
 
-const char *TypeNames[8] = {
+static const char *TypeNames[] = {
 	"UNUSED",	"FILE",		"TTY",		"CONSOLE",
 	"FORW",		"USERS",	"WALL",		"PIPE"
 };
 
-static struct filed *Files;	/* Log files that we write to */
+static STAILQ_HEAD(, filed) fhead =
+    STAILQ_HEAD_INITIALIZER(fhead);	/* Log files that we write to */
 static struct filed consfile;	/* Console */
 
 static int	Debug;		/* debug flag */
@@ -289,8 +338,6 @@ static int	Foreground = 0;	/* Run in foreground, inste
 static int	resolve = 1;	/* resolve hostname */
 static char	LocalHostName[MAXHOSTNAMELEN];	/* our hostname */
 static const char *LocalDomain;	/* our local domain name */
-static int	*finet;		/* Internet datagram sockets */
-static int	fklog = -1;	/* /dev/klog */
 static int	Initialized;	/* set when we have initialized ourselves */
 static int	MarkInterval = 20 * 60;	/* interval between marks in seconds */
 static int	MarkSeq;	/* mark sequence number */
@@ -309,9 +356,8 @@ static int	logflags = O_WRONLY|O_APPEND; /* flags used
 
 static char	bootfile[MAXLINE+1]; /* booted kernel file */
 
-struct allowedpeer *AllowedPeers; /* List of allowed peers */
-static int	NumAllowed;	/* Number of entries in AllowedPeers */
 static int	RemoteAddDate;	/* Always set the date on remote messages */
+static int	RemoteHostname;	/* Log remote hostname from the message */
 
 static int	UniquePriority;	/* Only log specified priority? */
 static int	LogFacPri;	/* Put facility and priority in log message: */
@@ -319,39 +365,53 @@ static int	LogFacPri;	/* Put facility and priority in 
 static int	KeepKernFac;	/* Keep remotely logged kernel facility */
 static int	needdofsync = 0; /* Are any file(s) waiting to be fsynced? */
 static struct pidfh *pfh;
+static int	sigpipe[2];	/* Pipe to catch a signal during select(). */
+static bool	RFC3164OutputFormat = true; /* Use legacy format by default. */
 
-volatile sig_atomic_t MarkSet, WantDie;
+static volatile sig_atomic_t MarkSet, WantDie, WantInitialize, WantReapchild;
 
+struct iovlist;
+
 static int	allowaddr(char *);
-static void	cfline(const char *, struct filed *,
-		    const char *, const char *);
+static int	addfile(struct filed *);
+static int	addpeer(struct peer *);
+static int	addsock(struct sockaddr *, socklen_t, struct socklist *);
+static struct filed *cfline(const char *, const char *, const char *);
 static const char *cvthname(struct sockaddr *);
 static void	deadq_enter(pid_t, const char *);
-static int	deadq_remove(pid_t);
+static int	deadq_remove(struct deadq_entry *);
+static int	deadq_removebypid(pid_t);
 static int	decode(const char *, const CODE *);
 static void	die(int) __dead2;
 static void	dodie(int);
 static void	dofsync(void);
 static void	domark(int);
-static void	fprintlog(struct filed *, int, const char *);
-static int	*socksetup(int, char *);
+static void	fprintlog_first(struct filed *, const char *, const char *,
+    const char *, const char *, const char *, const char *, int);
+static void	fprintlog_write(struct filed *, struct iovlist *, int);
+static void	fprintlog_successive(struct filed *, int);
 static void	init(int);
 static void	logerror(const char *);
-static void	logmsg(int, const char *, const char *, int);
+static void	logmsg(int, const struct logtime *, const char *, const char *,
+    const char *, const char *, const char *, const char *, int);
 static void	log_deadchild(pid_t, int, const char *);
 static void	markit(void);
+static int	socksetup(struct peer *);
+static int	socklist_recv_file(struct socklist *);
+static int	socklist_recv_sock(struct socklist *);
+static int	socklist_recv_signal(struct socklist *);
+static void	sighandler(int);
 static int	skip_message(const char *, const char *, int);
-static void	printline(const char *, char *, int);
+static void	parsemsg(const char *, char *);
 static void	printsys(char *);
 static int	p_open(const char *, pid_t *);
-static void	readklog(void);
 static void	reapchild(int);
 static const char *ttymsg_check(struct iovec *, int, char *, int);
 static void	usage(void);
 static int	validate(struct sockaddr *, const char *);
 static void	unmapped(struct sockaddr *);
 static void	wallmsg(struct filed *, struct iovec *, const int iovlen);
-static int	waitdaemon(int, int, int);
+static int	waitdaemon(int);
 static void	timedout(int);
 static void	increase_rcvbuf(int);
 
@@ -364,11 +424,11 @@ close_filed(struct filed *f)
 
 	switch (f->f_type) {
 	case F_FORW:
-            if (f->f_un.f_forw.f_addr) {
-                freeaddrinfo(f->f_un.f_forw.f_addr);
-                f->f_un.f_forw.f_addr = NULL;
-            }
-            /*FALLTHROUGH*/
+		if (f->f_un.f_forw.f_addr) {
+			freeaddrinfo(f->f_un.f_forw.f_addr);
+			f->f_un.f_forw.f_addr = NULL;
+		}
+		/* FALLTHROUGH */
 
 	case F_FILE:
 	case F_TTY:
@@ -376,41 +436,79 @@ close_filed(struct filed *f)
 		f->f_type = F_UNUSED;
 		break;
 	case F_PIPE:
-		f->f_un.f_pipe.f_pid = 0;
+		f->fu_pipe_pid = 0;
 		break;
 	}
 	(void)close(f->f_file);
 	f->f_file = -1;
 }
 
+static int
+addfile(struct filed *f0)
+{
+	struct filed *f;
+
+	f = calloc(1, sizeof(*f));
+	if (f == NULL)
+		err(1, "malloc failed");
+	*f = *f0;
+	STAILQ_INSERT_TAIL(&fhead, f, next);
+
+	return (0);
+}
+
+static int
+addpeer(struct peer *pe0)
+{
+	struct peer *pe;
+
+	pe = calloc(1, sizeof(*pe));
+	if (pe == NULL)
+		err(1, "malloc failed");
+	*pe = *pe0;
+	STAILQ_INSERT_TAIL(&pqueue, pe, next);
+
+	return (0);
+}
+
+static int
+addsock(struct sockaddr *sa, socklen_t sa_len, struct socklist *sl0)
+{
+	struct socklist *sl;
+
+	sl = calloc(1, sizeof(*sl));
+	if (sl == NULL)
+		err(1, "malloc failed");
+	*sl = *sl0;
+	if (sa != NULL && sa_len > 0)
+		memcpy(&sl->sl_ss, sa, sa_len);
+	STAILQ_INSERT_TAIL(&shead, sl, next);
+
+	return (0);
+}
+
 int
 main(int argc, char *argv[])
 {
-	int ch, i, fdsrmax = 0, l;
-	struct sockaddr_un sunx, fromunix;
-	struct sockaddr_storage frominet;
+	int ch, i, s, fdsrmax = 0, bflag = 0, pflag = 0, Sflag = 0;
 	fd_set *fdsr = NULL;
-	char line[MAXLINE + 1];
-	const char *hname;
 	struct timeval tv, *tvp;
-	struct sigaction sact;
-	struct host *host;
-	struct funix *fx, *fx1;
-	sigset_t mask;
+	struct peer *pe;
+	struct socklist *sl;
 	pid_t ppid = 1, spid;
-	socklen_t len;
+	char *p;
 
 	if (madvise(NULL, 0, MADV_PROTECT) != 0)
 		dprintf("madvise() failed: %s\n", strerror(errno));
 
-	STAILQ_INIT(&hqueue);
-
-	while ((ch = getopt(argc, argv, "468Aa:b:cCdf:Fkl:m:nNop:P:sS:Tuv"))
+	while ((ch = getopt(argc, argv, "468Aa:b:cCdf:FHkl:m:nNoO:p:P:sS:Tuv"))
 	    != -1)
 		switch (ch) {
+#ifdef INET
 		case '4':
 			family = PF_INET;
 			break;
+#endif
 #ifdef INET6
 		case '6':
 			family = PF_INET6;
@@ -427,13 +525,31 @@ main(int argc, char *argv[])
 				usage();
 			break;
 		case 'b':
-		   {
-			if ((host = malloc(sizeof(struct host))) == NULL)
-				err(1, "malloc failed");
-			host->name = optarg;
-			STAILQ_INSERT_TAIL(&hqueue, host, next);
+			bflag = 1;
+			p = strchr(optarg, ']');
+			if (p != NULL)
+				p = strchr(p + 1, ':');
+			else {
+				p = strchr(optarg, ':');
+				if (p != NULL && strchr(p + 1, ':') != NULL)
+					p = NULL; /* backward compatibility */
+			}
+			if (p == NULL) {
+				/* A hostname or filename only. */
+				addpeer(&(struct peer){
+					.pe_name = optarg,
+					.pe_serv = "syslog"
+				});
+			} else {
+				/* The case of "name:service". */
+				*p++ = '\0';
+				addpeer(&(struct peer){
+					.pe_serv = p,
+					.pe_name = (strlen(optarg) == 0) ?
+					    NULL : optarg,
+				});
+			}
 			break;
-		   }
 		case 'c':
 			no_compress++;
 			break;
@@ -449,19 +565,32 @@ main(int argc, char *argv[])
 		case 'F':		/* run in foreground instead of daemon */
 			Foreground++;
 			break;
+		case 'H':
+			RemoteHostname = 1;
+			break;
 		case 'k':		/* keep remote kern fac */
 			KeepKernFac = 1;
 			break;
 		case 'l':
+		case 'p':
+		case 'S':
 		    {
 			long	perml;
 			mode_t	mode;
 			char	*name, *ep;
 
-			if (optarg[0] == '/') {
+			if (ch == 'l')
 				mode = DEFFILEMODE;
+			else if (ch == 'p') {
+				mode = DEFFILEMODE;
+				pflag = 1;
+			} else {
+				mode = S_IRUSR | S_IWUSR;
+				Sflag = 1;
+			}
+			if (optarg[0] == '/')
 				name = optarg;
-			} else if ((name = strchr(optarg, ':')) != NULL) {
+			else if ((name = strchr(optarg, ':')) != NULL) {
 				*name++ = '\0';
 				if (name[0] != '/')
 					errx(1, "socket name must be absolute "
@@ -476,17 +605,13 @@ main(int argc, char *argv[])
 				} else
 					errx(1, "invalid mode %s, exiting",
 					    optarg);
-			} else	/* doesn't begin with '/', and no ':' */
-				errx(1, "can't parse path %s", optarg);
-
-			if (strlen(name) >= sizeof(sunx.sun_path))
-				errx(1, "%s path too long, exiting", name);
-			if ((fx = malloc(sizeof(struct funix))) == NULL)
-				err(1, "malloc failed");
-			fx->s = -1;
-			fx->name = name;
-			fx->mode = mode;
-			STAILQ_INSERT_TAIL(&funixes, fx, next);
+			} else
+				errx(1, "invalid filename %s, exiting",
+				    optarg);
+			addpeer(&(struct peer){
+				.pe_name = name,
+				.pe_mode = mode
+			});
 			break;
 		   }
 		case 'm':		/* mark interval */
@@ -499,25 +624,25 @@ main(int argc, char *argv[])
 		case 'n':
 			resolve = 0;
 			break;
+		case 'O':
+			if (strcmp(optarg, "bsd") == 0 ||
+			    strcmp(optarg, "rfc3164") == 0)
+				RFC3164OutputFormat = true;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201806131341.w5DDfN7T043988>