svn commit: r335059 - in stable/11: usr.bin/wall usr.sbin/syslogd

Rodney W. Grimes freebsd at pdx.rh.CN85.dnsmgr.net
Wed Jun 13 13:57:36 UTC 2018


> 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

Thank you very much for avoiding the SPDX area!  I have pending
clean up in stable/11 around those.


>   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

I see no mention of any changes to wall in the commit,
was this intentional?  The changes don't seem to be
related to syslogd directly.

>   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 at 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 ***
> 
> 

-- 
Rod Grimes                                                 rgrimes at freebsd.org


More information about the svn-src-all mailing list