xref: /openbsd-src/usr.sbin/syslogd/syslogd.c (revision d4741794dd2f512d997014f8bd85fbb24d935059)
1 /*	$OpenBSD: syslogd.c,v 1.227 2017/01/02 15:58:02 bluhm Exp $	*/
2 
3 /*
4  * Copyright (c) 1983, 1988, 1993, 1994
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the University nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 
32 /*
33  *  syslogd -- log system messages
34  *
35  * This program implements a system log. It takes a series of lines.
36  * Each line may have a priority, signified as "<n>" as
37  * the first characters of the line.  If this is
38  * not present, a default priority is used.
39  *
40  * To kill syslogd, send a signal 15 (terminate).  A signal 1 (hup) will
41  * cause it to reread its configuration file.
42  *
43  * Defined Constants:
44  *
45  * MAXLINE -- the maximum line length that can be handled.
46  * DEFUPRI -- the default priority for user messages
47  * DEFSPRI -- the default priority for kernel messages
48  *
49  * Author: Eric Allman
50  * extensive changes by Ralph Campbell
51  * more extensive changes by Eric Allman (again)
52  * memory buffer logging by Damien Miller
53  * IPv6, libevent, syslog over TCP and TLS by Alexander Bluhm
54  */
55 
56 #define MAX_UDPMSG	1180		/* maximum UDP send size */
57 #define MIN_MEMBUF	(MAXLINE * 4)	/* Minimum memory buffer size */
58 #define MAX_MEMBUF	(256 * 1024)	/* Maximum memory buffer size */
59 #define MAX_MEMBUF_NAME	64		/* Max length of membuf log name */
60 #define MAX_TCPBUF	(256 * 1024)	/* Maximum tcp event buffer size */
61 #define	MAXSVLINE	120		/* maximum saved line length */
62 #define FD_RESERVE	5		/* file descriptors not accepted */
63 #define DEFUPRI		(LOG_USER|LOG_NOTICE)
64 #define DEFSPRI		(LOG_KERN|LOG_CRIT)
65 #define TIMERINTVL	30		/* interval for checking flush, mark */
66 
67 #include <sys/ioctl.h>
68 #include <sys/stat.h>
69 #include <sys/msgbuf.h>
70 #include <sys/queue.h>
71 #include <sys/sysctl.h>
72 #include <sys/un.h>
73 #include <sys/time.h>
74 #include <sys/resource.h>
75 
76 #include <netinet/in.h>
77 #include <netdb.h>
78 #include <arpa/inet.h>
79 
80 #include <ctype.h>
81 #include <err.h>
82 #include <errno.h>
83 #include <event.h>
84 #include <fcntl.h>
85 #include <limits.h>
86 #include <paths.h>
87 #include <signal.h>
88 #include <stdio.h>
89 #include <stdlib.h>
90 #include <string.h>
91 #include <tls.h>
92 #include <unistd.h>
93 #include <utmp.h>
94 #include <vis.h>
95 
96 #define MAXIMUM(a, b)	(((a) > (b)) ? (a) : (b))
97 #define MINIMUM(a, b)	(((a) < (b)) ? (a) : (b))
98 
99 #define SYSLOG_NAMES
100 #include <sys/syslog.h>
101 
102 #include "syslogd.h"
103 #include "evbuffer_tls.h"
104 
105 char *ConfFile = _PATH_LOGCONF;
106 const char ctty[] = _PATH_CONSOLE;
107 
108 #define MAXUNAMES	20	/* maximum number of user names */
109 
110 
111 /*
112  * Flags to logmsg().
113  */
114 
115 #define IGN_CONS	0x001	/* don't print on console */
116 #define SYNC_FILE	0x002	/* do fsync on file after printing */
117 #define ADDDATE		0x004	/* add a date to the message */
118 #define MARK		0x008	/* this message is a mark */
119 
120 /*
121  * This structure represents the files that will have log
122  * copies printed.
123  */
124 
125 struct filed {
126 	SIMPLEQ_ENTRY(filed) f_next;	/* next in linked list */
127 	int	f_type;			/* entry type, see below */
128 	int	f_file;			/* file descriptor */
129 	time_t	f_time;			/* time this was last written */
130 	u_char	f_pmask[LOG_NFACILITIES+1];	/* priority mask */
131 	char	*f_program;		/* program this applies to */
132 	char	*f_hostname;		/* host this applies to */
133 	union {
134 		char	f_uname[MAXUNAMES][UT_NAMESIZE+1];
135 		struct {
136 			char	f_loghost[1+4+3+1+NI_MAXHOST+1+NI_MAXSERV];
137 				/* @proto46://[hostname]:servname\0 */
138 			struct sockaddr_storage	 f_addr;
139 			struct buffertls	 f_buftls;
140 			struct bufferevent	*f_bufev;
141 			struct tls		*f_ctx;
142 			char			*f_host;
143 			int			 f_reconnectwait;
144 			int			 f_dropped;
145 		} f_forw;		/* forwarding address */
146 		char	f_fname[PATH_MAX];
147 		struct {
148 			char	f_mname[MAX_MEMBUF_NAME];
149 			struct ringbuf *f_rb;
150 			int	f_overflow;
151 			int	f_attached;
152 			size_t	f_len;
153 		} f_mb;		/* Memory buffer */
154 	} f_un;
155 	char	f_prevline[MAXSVLINE];		/* last message logged */
156 	char	f_lasttime[33];			/* time of last occurrence */
157 	char	f_prevhost[HOST_NAME_MAX+1];	/* host from which recd. */
158 	int	f_prevpri;			/* pri of f_prevline */
159 	int	f_prevlen;			/* length of f_prevline */
160 	int	f_prevcount;			/* repetition cnt of prevline */
161 	unsigned int f_repeatcount;		/* number of "repeated" msgs */
162 	int	f_quick;			/* abort when matched */
163 	time_t	f_lasterrtime;			/* last error was reported */
164 };
165 
166 /*
167  * Intervals at which we flush out "message repeated" messages,
168  * in seconds after previous message is logged.  After each flush,
169  * we move to the next interval until we reach the largest.
170  */
171 int	repeatinterval[] = { 30, 120, 600 };	/* # of secs before flush */
172 #define	MAXREPEAT ((sizeof(repeatinterval) / sizeof(repeatinterval[0])) - 1)
173 #define	REPEATTIME(f)	((f)->f_time + repeatinterval[(f)->f_repeatcount])
174 #define	BACKOFF(f)	{ if (++(f)->f_repeatcount > MAXREPEAT) \
175 				(f)->f_repeatcount = MAXREPEAT; \
176 			}
177 
178 /* values for f_type */
179 #define F_UNUSED	0		/* unused entry */
180 #define F_FILE		1		/* regular file */
181 #define F_TTY		2		/* terminal */
182 #define F_CONSOLE	3		/* console terminal */
183 #define F_FORWUDP	4		/* remote machine via UDP */
184 #define F_USERS		5		/* list of users */
185 #define F_WALL		6		/* everyone logged on */
186 #define F_MEMBUF	7		/* memory buffer */
187 #define F_PIPE		8		/* pipe to external program */
188 #define F_FORWTCP	9		/* remote machine via TCP */
189 #define F_FORWTLS	10		/* remote machine via TLS */
190 
191 char	*TypeNames[] = {
192 	"UNUSED",	"FILE",		"TTY",		"CONSOLE",
193 	"FORWUDP",	"USERS",	"WALL",		"MEMBUF",
194 	"PIPE",		"FORWTCP",	"FORWTLS",
195 };
196 
197 SIMPLEQ_HEAD(filed_list, filed) Files;
198 struct	filed consfile;
199 
200 int	nunix;			/* Number of Unix domain sockets requested */
201 char	**path_unix;		/* Paths to Unix domain sockets */
202 int	Debug;			/* debug flag */
203 int	Foreground;		/* run in foreground, instead of daemonizing */
204 int	Startup = 1;		/* startup flag */
205 char	LocalHostName[HOST_NAME_MAX+1];	/* our hostname */
206 char	*LocalDomain;		/* our local domain name */
207 int	Initialized = 0;	/* set when we have initialized ourselves */
208 
209 int	MarkInterval = 20 * 60;	/* interval between marks in seconds */
210 int	MarkSeq = 0;		/* mark sequence number */
211 int	PrivChild = 0;		/* Exec the privileged parent process */
212 int	SecureMode = 1;		/* when true, speak only unix domain socks */
213 int	NoDNS = 0;		/* when true, refrain from doing DNS lookups */
214 int	ZuluTime = 0;		/* display date and time in UTC ISO format */
215 int	IncludeHostname = 0;	/* include RFC 3164 hostnames when forwarding */
216 int	Family = PF_UNSPEC;	/* protocol family, may disable IPv4 or IPv6 */
217 char	*path_ctlsock = NULL;	/* Path to control socket */
218 
219 struct	tls *server_ctx;
220 struct	tls_config *client_config, *server_config;
221 const char *CAfile = "/etc/ssl/cert.pem"; /* file containing CA certificates */
222 int	NoVerify = 0;		/* do not verify TLS server x509 certificate */
223 const char *ClientCertfile = NULL;
224 const char *ClientKeyfile = NULL;
225 const char *ServerCAfile = NULL;
226 int	tcpbuf_dropped = 0;	/* count messages dropped from TCP or TLS */
227 
228 #define CTL_READING_CMD		1
229 #define CTL_WRITING_REPLY	2
230 #define CTL_WRITING_CONT_REPLY	3
231 int	ctl_state = 0;		/* What the control socket is up to */
232 int	membuf_drop = 0;	/* logs dropped in continuous membuf read */
233 
234 /*
235  * Client protocol NB. all numeric fields in network byte order
236  */
237 #define CTL_VERSION		2
238 
239 /* Request */
240 struct	{
241 	u_int32_t	version;
242 #define CMD_READ	1	/* Read out log */
243 #define CMD_READ_CLEAR	2	/* Read and clear log */
244 #define CMD_CLEAR	3	/* Clear log */
245 #define CMD_LIST	4	/* List available logs */
246 #define CMD_FLAGS	5	/* Query flags only */
247 #define CMD_READ_CONT	6	/* Read out log continuously */
248 	u_int32_t	cmd;
249 	u_int32_t	lines;
250 	char		logname[MAX_MEMBUF_NAME];
251 }	ctl_cmd;
252 
253 size_t	ctl_cmd_bytes = 0;	/* number of bytes of ctl_cmd read */
254 
255 /* Reply */
256 struct ctl_reply_hdr {
257 	u_int32_t	version;
258 #define CTL_HDR_FLAG_OVERFLOW	0x01
259 	u_int32_t	flags;
260 	/* Reply text follows, up to MAX_MEMBUF long */
261 };
262 
263 #define CTL_HDR_LEN		(sizeof(struct ctl_reply_hdr))
264 #define CTL_REPLY_MAXSIZE	(CTL_HDR_LEN + MAX_MEMBUF)
265 #define CTL_REPLY_SIZE		(strlen(reply_text) + CTL_HDR_LEN)
266 
267 char	*ctl_reply = NULL;	/* Buffer for control connection reply */
268 char	*reply_text;		/* Start of reply text in buffer */
269 size_t	ctl_reply_size = 0;	/* Number of bytes used in reply */
270 size_t	ctl_reply_offset = 0;	/* Number of bytes of reply written so far */
271 
272 char	*linebuf;
273 int	 linesize;
274 
275 int		 fd_ctlconn, fd_udp, fd_udp6, fd_tls;
276 struct event	*ev_ctlaccept, *ev_ctlread, *ev_ctlwrite;
277 
278 struct peer {
279 	struct buffertls	 p_buftls;
280 	struct bufferevent	*p_bufev;
281 	struct tls		*p_ctx;
282 	char			*p_peername;
283 	char			*p_hostname;
284 	int			 p_fd;
285 };
286 char hostname_unknown[] = "???";
287 
288 void	 klog_readcb(int, short, void *);
289 void	 udp_readcb(int, short, void *);
290 void	 unix_readcb(int, short, void *);
291 int	 reserve_accept4(int, int, struct event *,
292     void (*)(int, short, void *), struct sockaddr *, socklen_t *, int);
293 void	 tcp_acceptcb(int, short, void *);
294 int	 octet_counting(struct evbuffer *, char **, int);
295 int	 non_transparent_framing(struct evbuffer *, char **);
296 void	 tcp_readcb(struct bufferevent *, void *);
297 void	 tcp_closecb(struct bufferevent *, short, void *);
298 int	 tcp_socket(struct filed *);
299 void	 tcp_dropcb(struct bufferevent *, void *);
300 void	 tcp_writecb(struct bufferevent *, void *);
301 void	 tcp_errorcb(struct bufferevent *, short, void *);
302 void	 tcp_connectcb(int, short, void *);
303 void	 tcp_connect_retry(struct bufferevent *, struct filed *);
304 int	 tcpbuf_countmsg(struct bufferevent *bufev);
305 void	 die_signalcb(int, short, void *);
306 void	 mark_timercb(int, short, void *);
307 void	 init_signalcb(int, short, void *);
308 void	 ctlsock_acceptcb(int, short, void *);
309 void	 ctlconn_readcb(int, short, void *);
310 void	 ctlconn_writecb(int, short, void *);
311 void	 ctlconn_logto(char *);
312 void	 ctlconn_cleanup(void);
313 
314 struct filed *cfline(char *, char *, char *);
315 void	cvthname(struct sockaddr *, char *, size_t);
316 int	decode(const char *, const CODE *);
317 void	die(int);
318 void	markit(void);
319 void	fprintlog(struct filed *, int, char *);
320 void	init(void);
321 void	logevent(int, const char *);
322 void	logerror(const char *);
323 void	logerrorx(const char *);
324 void	logerrorctx(const char *, struct tls *);
325 void	logerrortlsconf(const char *, struct tls_config *);
326 void	logerror_reason(const char *, const char *);
327 void	logmsg(int, char *, char *, int);
328 struct filed *find_dup(struct filed *);
329 size_t	parsepriority(const char *, int *);
330 void	printline(char *, char *);
331 void	printsys(char *);
332 void	usage(void);
333 void	wallmsg(struct filed *, struct iovec *);
334 int	loghost_parse(char *, char **, char **, char **);
335 int	getmsgbufsize(void);
336 void	address_alloc(const char *, const char *, char ***, char ***, int *);
337 int	socket_bind(const char *, const char *, const char *, int,
338     int *, int *);
339 int	unix_socket(char *, int, mode_t);
340 void	double_sockbuf(int, int);
341 void	set_sockbuf(int);
342 void	tailify_replytext(char *, int);
343 
344 int
345 main(int argc, char *argv[])
346 {
347 	struct timeval	 to;
348 	struct event	*ev_klog, *ev_sendsys, *ev_udp, *ev_udp6,
349 			*ev_bind, *ev_listen, *ev_tls, *ev_unix,
350 			*ev_hup, *ev_int, *ev_quit, *ev_term, *ev_mark;
351 	sigset_t	 sigmask;
352 	const char	*errstr;
353 	char		*p;
354 	int		 ch, i;
355 	int		 lockpipe[2] = { -1, -1}, pair[2], nullfd, fd;
356 	int		 fd_ctlsock, fd_klog, fd_sendsys, *fd_bind, *fd_listen;
357 	int		*fd_unix, nbind, nlisten;
358 	char		**bind_host, **bind_port, **listen_host, **listen_port;
359 	char		*tls_hostport, *tls_host, *tls_port;
360 
361 	/* block signal until handler is set up */
362 	sigemptyset(&sigmask);
363 	sigaddset(&sigmask, SIGHUP);
364 	if (sigprocmask(SIG_SETMASK, &sigmask, NULL) == -1)
365 		err(1, "sigprocmask block");
366 
367 	if ((path_unix = malloc(sizeof(*path_unix))) == NULL)
368 		err(1, "malloc %s", _PATH_LOG);
369 	path_unix[0] = _PATH_LOG;
370 	nunix = 1;
371 
372 	bind_host = bind_port = listen_host = listen_port = NULL;
373 	tls_hostport = tls_host = NULL;
374 	nbind = nlisten = 0;
375 
376 	while ((ch = getopt(argc, argv, "46a:C:c:dFf:hK:k:m:nP:p:S:s:T:U:uVZ"))
377 	    != -1)
378 		switch (ch) {
379 		case '4':		/* disable IPv6 */
380 			Family = PF_INET;
381 			break;
382 		case '6':		/* disable IPv4 */
383 			Family = PF_INET6;
384 			break;
385 		case 'a':
386 			if ((path_unix = reallocarray(path_unix, nunix + 1,
387 			    sizeof(*path_unix))) == NULL)
388 				err(1, "unix path %s", optarg);
389 			path_unix[nunix++] = optarg;
390 			break;
391 		case 'C':		/* file containing CA certificates */
392 			CAfile = optarg;
393 			break;
394 		case 'c':		/* file containing client certificate */
395 			ClientCertfile = optarg;
396 			break;
397 		case 'd':		/* debug */
398 			Debug++;
399 			break;
400 		case 'F':		/* foreground */
401 			Foreground = 1;
402 			break;
403 		case 'f':		/* configuration file */
404 			ConfFile = optarg;
405 			break;
406 		case 'h':		/* RFC 3164 hostnames */
407 			IncludeHostname = 1;
408 			break;
409 		case 'K':		/* verify client with CA file */
410 			ServerCAfile = optarg;
411 			break;
412 		case 'k':		/* file containing client key */
413 			ClientKeyfile = optarg;
414 			break;
415 		case 'm':		/* mark interval */
416 			MarkInterval = strtonum(optarg, 0, 365*24*60, &errstr);
417 			if (errstr)
418 				errx(1, "mark_interval %s: %s", errstr, optarg);
419 			MarkInterval *= 60;
420 			break;
421 		case 'n':		/* don't do DNS lookups */
422 			NoDNS = 1;
423 			break;
424 		case 'P':		/* used internally, exec the parent */
425 			PrivChild = strtonum(optarg, 2, INT_MAX, &errstr);
426 			if (errstr)
427 				errx(1, "priv child %s: %s", errstr, optarg);
428 			break;
429 		case 'p':		/* path */
430 			path_unix[0] = optarg;
431 			break;
432 		case 'S':		/* allow tls and listen on address */
433 			tls_hostport = optarg;
434 			if ((p = strdup(optarg)) == NULL)
435 				err(1, "strdup tls address");
436 			if (loghost_parse(p, NULL, &tls_host, &tls_port) == -1)
437 				errx(1, "bad tls address: %s", optarg);
438 			break;
439 		case 's':
440 			path_ctlsock = optarg;
441 			break;
442 		case 'T':		/* allow tcp and listen on address */
443 			address_alloc("listen", optarg, &listen_host,
444 			    &listen_port, &nlisten);
445 			break;
446 		case 'U':		/* allow udp only from address */
447 			address_alloc("bind", optarg, &bind_host, &bind_port,
448 			    &nbind);
449 			break;
450 		case 'u':		/* allow udp input port */
451 			SecureMode = 0;
452 			break;
453 		case 'V':		/* do not verify certificates */
454 			NoVerify = 1;
455 			break;
456 		case 'Z':		/* time stamps in UTC ISO format */
457 			ZuluTime = 1;
458 			break;
459 		default:
460 			usage();
461 		}
462 	if (argc != optind)
463 		usage();
464 
465 	if (Debug)
466 		setvbuf(stdout, NULL, _IOLBF, 0);
467 
468 	if ((nullfd = open(_PATH_DEVNULL, O_RDWR)) == -1) {
469 		logerror("Couldn't open /dev/null");
470 		die(0);
471 	}
472 	for (fd = nullfd + 1; fd <= STDERR_FILENO; fd++) {
473 		if (fcntl(fd, F_GETFL) == -1 && errno == EBADF)
474 			if (dup2(nullfd, fd) == -1) {
475 				logerror("dup2");
476 				die(0);
477 			}
478 	}
479 
480 	if (PrivChild > 1)
481 		priv_exec(ConfFile, NoDNS, PrivChild, argc, argv);
482 
483 	consfile.f_type = F_CONSOLE;
484 	(void)strlcpy(consfile.f_un.f_fname, ctty,
485 	    sizeof(consfile.f_un.f_fname));
486 	(void)gethostname(LocalHostName, sizeof(LocalHostName));
487 	if ((p = strchr(LocalHostName, '.')) != NULL) {
488 		*p++ = '\0';
489 		LocalDomain = p;
490 	} else
491 		LocalDomain = "";
492 
493 	/* Reserve space for kernel message buffer plus buffer full message. */
494 	linesize = getmsgbufsize() + 64;
495 	if (linesize < MAXLINE)
496 		linesize = MAXLINE;
497 	linesize++;
498 	if ((linebuf = malloc(linesize)) == NULL) {
499 		logerror("Couldn't allocate line buffer");
500 		die(0);
501 	}
502 
503 	if (socket_bind("udp", NULL, "syslog", SecureMode,
504 	    &fd_udp, &fd_udp6) == -1) {
505 		logerrorx("socket bind *");
506 		if (!Debug)
507 			die(0);
508 	}
509 	if ((fd_bind = reallocarray(NULL, nbind, sizeof(*fd_bind))) == NULL)
510 		err(1, "bind fd");
511 	for (i = 0; i < nbind; i++) {
512 		if (socket_bind("udp", bind_host[i], bind_port[i], 0,
513 		    &fd_bind[i], &fd_bind[i]) == -1) {
514 			logerrorx("socket bind udp");
515 			if (!Debug)
516 				die(0);
517 		}
518 	}
519 	if ((fd_listen = reallocarray(NULL, nlisten, sizeof(*fd_listen)))
520 	    == NULL)
521 		err(1, "listen fd");
522 	for (i = 0; i < nlisten; i++) {
523 		if (socket_bind("tcp", listen_host[i], listen_port[i], 0,
524 		    &fd_listen[i], &fd_listen[i]) == -1) {
525 			logerrorx("socket listen tcp");
526 			if (!Debug)
527 				die(0);
528 		}
529 	}
530 	fd_tls = -1;
531 	if (tls_host && socket_bind("tls", tls_host, tls_port, 0,
532 	    &fd_tls, &fd_tls) == -1) {
533 		logerrorx("socket listen tls");
534 		if (!Debug)
535 			die(0);
536 	}
537 
538 	if ((fd_unix = reallocarray(NULL, nunix, sizeof(*fd_unix))) == NULL)
539 		err(1, "malloc unix");
540 	for (i = 0; i < nunix; i++) {
541 		fd_unix[i] = unix_socket(path_unix[i], SOCK_DGRAM, 0666);
542 		if (fd_unix[i] == -1) {
543 			if (i == 0 && !Debug)
544 				die(0);
545 			continue;
546 		}
547 		double_sockbuf(fd_unix[i], SO_RCVBUF);
548 	}
549 
550 	if (socketpair(AF_UNIX, SOCK_DGRAM, PF_UNSPEC, pair) == -1) {
551 		logerror("socketpair");
552 		die(0);
553 	}
554 	double_sockbuf(pair[0], SO_RCVBUF);
555 	double_sockbuf(pair[1], SO_SNDBUF);
556 	fd_sendsys = pair[0];
557 
558 	fd_ctlsock = fd_ctlconn = -1;
559 	if (path_ctlsock != NULL) {
560 		fd_ctlsock = unix_socket(path_ctlsock, SOCK_STREAM, 0600);
561 		if (fd_ctlsock == -1) {
562 			logdebug("can't open %s (%d)\n", path_ctlsock, errno);
563 			if (!Debug)
564 				die(0);
565 		} else {
566 			if (listen(fd_ctlsock, 5) == -1) {
567 				logerror("ctlsock listen");
568 				die(0);
569 			}
570 		}
571 	}
572 
573 	fd_klog = open(_PATH_KLOG, O_RDONLY, 0);
574 	if (fd_klog == -1) {
575 		logdebug("can't open %s (%d)\n", _PATH_KLOG, errno);
576 	} else {
577 		if (ioctl(fd_klog, LIOCSFD, &pair[1]) == -1)
578 			logdebug("LIOCSFD errno %d\n", errno);
579 	}
580 	close(pair[1]);
581 
582 	if (tls_init() == -1) {
583 		logerrorx("tls_init");
584 	} else {
585 		if ((client_config = tls_config_new()) == NULL)
586 			logerror("tls_config_new client");
587 		if (tls_hostport) {
588 			if ((server_config = tls_config_new()) == NULL)
589 				logerror("tls_config_new server");
590 			if ((server_ctx = tls_server()) == NULL) {
591 				logerror("tls_server");
592 				close(fd_tls);
593 				fd_tls = -1;
594 			}
595 		}
596 	}
597 	if (client_config) {
598 		if (NoVerify) {
599 			tls_config_insecure_noverifycert(client_config);
600 			tls_config_insecure_noverifyname(client_config);
601 		} else {
602 			if (tls_config_set_ca_file(client_config,
603 			    CAfile) == -1) {
604 				logerrortlsconf("Load client TLS CA failed",
605 				    client_config);
606 				/* avoid reading default certs in chroot */
607 				tls_config_set_ca_mem(client_config, "", 0);
608 			} else
609 				logdebug("CAfile %s\n", CAfile);
610 		}
611 		if (ClientCertfile && ClientKeyfile) {
612 			if (tls_config_set_cert_file(client_config,
613 			    ClientCertfile) == -1)
614 				logerrortlsconf("Load client TLS cert failed",
615 				    client_config);
616 			else
617 				logdebug("ClientCertfile %s\n", ClientCertfile);
618 
619 			if (tls_config_set_key_file(client_config,
620 			    ClientKeyfile) == -1)
621 				logerrortlsconf("Load client TLS key failed",
622 				    client_config);
623 			else
624 				logdebug("ClientKeyfile %s\n", ClientKeyfile);
625 		} else if (ClientCertfile || ClientKeyfile) {
626 			logerrorx("options -c and -k must be used together");
627 		}
628 		if (tls_config_set_protocols(client_config,
629 		    TLS_PROTOCOLS_ALL) != 0)
630 			logerrortlsconf("Set client TLS protocols failed",
631 			    client_config);
632 		if (tls_config_set_ciphers(client_config, "all") != 0)
633 			logerrortlsconf("Set client TLS ciphers failed",
634 			    client_config);
635 	}
636 	if (server_config && server_ctx) {
637 		const char *names[2];
638 
639 		names[0] = tls_hostport;
640 		names[1] = tls_host;
641 
642 		for (i = 0; i < 2; i++) {
643 			if (asprintf(&p, "/etc/ssl/private/%s.key", names[i])
644 			    == -1)
645 				continue;
646 			if (tls_config_set_key_file(server_config, p) == -1) {
647 				logerrortlsconf("Load server TLS key failed",
648 				    server_config);
649 				free(p);
650 				continue;
651 			}
652 			logdebug("Keyfile %s\n", p);
653 			free(p);
654 			if (asprintf(&p, "/etc/ssl/%s.crt", names[i]) == -1)
655 				continue;
656 			if (tls_config_set_cert_file(server_config, p) == -1) {
657 				logerrortlsconf("Load server TLS cert failed",
658 				    server_config);
659 				free(p);
660 				continue;
661 			}
662 			logdebug("Certfile %s\n", p);
663 			free(p);
664 			break;
665 		}
666 
667 		if (ServerCAfile) {
668 			if (tls_config_set_ca_file(server_config,
669 			    ServerCAfile) == -1) {
670 				logerrortlsconf("Load server TLS CA failed",
671 				    server_config);
672 				/* avoid reading default certs in chroot */
673 				tls_config_set_ca_mem(server_config, "", 0);
674 			} else
675 				logdebug("Server CAfile %s\n", ServerCAfile);
676 			tls_config_verify_client(server_config);
677 		}
678 		if (tls_config_set_protocols(server_config,
679 		    TLS_PROTOCOLS_ALL) != 0)
680 			logerrortlsconf("Set server TLS protocols failed",
681 			    server_config);
682 		if (tls_config_set_ciphers(server_config, "compat") != 0)
683 			logerrortlsconf("Set server TLS ciphers failed",
684 			    server_config);
685 		if (tls_configure(server_ctx, server_config) != 0) {
686 			logerrorctx("tls_configure server", server_ctx);
687 			tls_free(server_ctx);
688 			server_ctx = NULL;
689 			close(fd_tls);
690 			fd_tls = -1;
691 		}
692 	}
693 
694 	logdebug("off & running....\n");
695 
696 	tzset();
697 
698 	if (!Debug && !Foreground) {
699 		char c;
700 
701 		pipe(lockpipe);
702 
703 		switch(fork()) {
704 		case -1:
705 			err(1, "fork");
706 		case 0:
707 			setsid();
708 			close(lockpipe[0]);
709 			break;
710 		default:
711 			close(lockpipe[1]);
712 			read(lockpipe[0], &c, 1);
713 			_exit(0);
714 		}
715 	}
716 
717 	/* tuck my process id away */
718 	if (!Debug) {
719 		FILE *fp;
720 
721 		fp = fopen(_PATH_LOGPID, "w");
722 		if (fp != NULL) {
723 			fprintf(fp, "%ld\n", (long)getpid());
724 			(void) fclose(fp);
725 		}
726 	}
727 
728 	/* Privilege separation begins here */
729 	priv_init(lockpipe[1], nullfd, argc, argv);
730 
731 	if (pledge("stdio unix inet recvfd", NULL) == -1)
732 		err(1, "pledge");
733 
734 	/* Process is now unprivileged and inside a chroot */
735 	if (Debug)
736 		event_set_log_callback(logevent);
737 	event_init();
738 
739 	if ((ev_ctlaccept = malloc(sizeof(struct event))) == NULL ||
740 	    (ev_ctlread = malloc(sizeof(struct event))) == NULL ||
741 	    (ev_ctlwrite = malloc(sizeof(struct event))) == NULL ||
742 	    (ev_klog = malloc(sizeof(struct event))) == NULL ||
743 	    (ev_sendsys = malloc(sizeof(struct event))) == NULL ||
744 	    (ev_udp = malloc(sizeof(struct event))) == NULL ||
745 	    (ev_udp6 = malloc(sizeof(struct event))) == NULL ||
746 	    (ev_bind = reallocarray(NULL,nbind,sizeof(struct event))) == NULL ||
747 	    (ev_listen = reallocarray(NULL,nlisten,sizeof(struct event)))
748 		== NULL ||
749 	    (ev_tls = malloc(sizeof(struct event))) == NULL ||
750 	    (ev_unix = reallocarray(NULL,nunix,sizeof(struct event))) == NULL ||
751 	    (ev_hup = malloc(sizeof(struct event))) == NULL ||
752 	    (ev_int = malloc(sizeof(struct event))) == NULL ||
753 	    (ev_quit = malloc(sizeof(struct event))) == NULL ||
754 	    (ev_term = malloc(sizeof(struct event))) == NULL ||
755 	    (ev_mark = malloc(sizeof(struct event))) == NULL)
756 		err(1, "malloc");
757 
758 	event_set(ev_ctlaccept, fd_ctlsock, EV_READ|EV_PERSIST,
759 	    ctlsock_acceptcb, ev_ctlaccept);
760 	event_set(ev_ctlread, fd_ctlconn, EV_READ|EV_PERSIST,
761 	    ctlconn_readcb, ev_ctlread);
762 	event_set(ev_ctlwrite, fd_ctlconn, EV_WRITE|EV_PERSIST,
763 	    ctlconn_writecb, ev_ctlwrite);
764 	event_set(ev_klog, fd_klog, EV_READ|EV_PERSIST, klog_readcb, ev_klog);
765 	event_set(ev_sendsys, fd_sendsys, EV_READ|EV_PERSIST, unix_readcb,
766 	    ev_sendsys);
767 	event_set(ev_udp, fd_udp, EV_READ|EV_PERSIST, udp_readcb, ev_udp);
768 	event_set(ev_udp6, fd_udp6, EV_READ|EV_PERSIST, udp_readcb, ev_udp6);
769 	for (i = 0; i < nbind; i++)
770 		event_set(&ev_bind[i], fd_bind[i], EV_READ|EV_PERSIST,
771 		    udp_readcb, &ev_bind[i]);
772 	for (i = 0; i < nlisten; i++)
773 		event_set(&ev_listen[i], fd_listen[i], EV_READ|EV_PERSIST,
774 		    tcp_acceptcb, &ev_listen[i]);
775 	event_set(ev_tls, fd_tls, EV_READ|EV_PERSIST, tcp_acceptcb, ev_tls);
776 	for (i = 0; i < nunix; i++)
777 		event_set(&ev_unix[i], fd_unix[i], EV_READ|EV_PERSIST,
778 		    unix_readcb, &ev_unix[i]);
779 
780 	signal_set(ev_hup, SIGHUP, init_signalcb, ev_hup);
781 	signal_set(ev_int, SIGINT, die_signalcb, ev_int);
782 	signal_set(ev_quit, SIGQUIT, die_signalcb, ev_quit);
783 	signal_set(ev_term, SIGTERM, die_signalcb, ev_term);
784 
785 	evtimer_set(ev_mark, mark_timercb, ev_mark);
786 
787 	init();
788 
789 	Startup = 0;
790 
791 	/* Allocate ctl socket reply buffer if we have a ctl socket */
792 	if (fd_ctlsock != -1 &&
793 	    (ctl_reply = malloc(CTL_REPLY_MAXSIZE)) == NULL) {
794 		logerror("Couldn't allocate ctlsock reply buffer");
795 		die(0);
796 	}
797 	reply_text = ctl_reply + CTL_HDR_LEN;
798 
799 	if (!Debug) {
800 		close(lockpipe[1]);
801 		dup2(nullfd, STDIN_FILENO);
802 		dup2(nullfd, STDOUT_FILENO);
803 		dup2(nullfd, STDERR_FILENO);
804 	}
805 	if (nullfd > 2)
806 		close(nullfd);
807 
808 	/*
809 	 * Signal to the priv process that the initial config parsing is done
810 	 * so that it will reject any future attempts to open more files
811 	 */
812 	priv_config_parse_done();
813 
814 	if (fd_ctlsock != -1)
815 		event_add(ev_ctlaccept, NULL);
816 	if (fd_klog != -1)
817 		event_add(ev_klog, NULL);
818 	if (fd_sendsys != -1)
819 		event_add(ev_sendsys, NULL);
820 	if (!SecureMode) {
821 		if (fd_udp != -1)
822 			event_add(ev_udp, NULL);
823 		if (fd_udp6 != -1)
824 			event_add(ev_udp6, NULL);
825 	}
826 	for (i = 0; i < nbind; i++)
827 		if (fd_bind[i] != -1)
828 			event_add(&ev_bind[i], NULL);
829 	for (i = 0; i < nlisten; i++)
830 		if (fd_listen[i] != -1)
831 			event_add(&ev_listen[i], NULL);
832 	if (fd_tls != -1)
833 		event_add(ev_tls, NULL);
834 	for (i = 0; i < nunix; i++)
835 		if (fd_unix[i] != -1)
836 			event_add(&ev_unix[i], NULL);
837 
838 	signal_add(ev_hup, NULL);
839 	signal_add(ev_term, NULL);
840 	if (Debug) {
841 		signal_add(ev_int, NULL);
842 		signal_add(ev_quit, NULL);
843 	} else {
844 		(void)signal(SIGINT, SIG_IGN);
845 		(void)signal(SIGQUIT, SIG_IGN);
846 	}
847 	(void)signal(SIGCHLD, SIG_IGN);
848 	(void)signal(SIGPIPE, SIG_IGN);
849 
850 	to.tv_sec = TIMERINTVL;
851 	to.tv_usec = 0;
852 	evtimer_add(ev_mark, &to);
853 
854 	logmsg(LOG_SYSLOG|LOG_INFO, "syslogd: start", LocalHostName, ADDDATE);
855 	logdebug("syslogd: started\n");
856 
857 	sigemptyset(&sigmask);
858 	if (sigprocmask(SIG_SETMASK, &sigmask, NULL) == -1)
859 		err(1, "sigprocmask unblock");
860 
861 	event_dispatch();
862 	/* NOTREACHED */
863 	return (0);
864 }
865 
866 void
867 address_alloc(const char *name, const char *address, char ***host,
868     char ***port, int *num)
869 {
870 	char *p;
871 
872 	/* do not care about memory leak, argv has to be preserved */
873 	if ((p = strdup(address)) == NULL)
874 		err(1, "%s address %s", name, address);
875 	if ((*host = reallocarray(*host, *num + 1, sizeof(**host))) == NULL)
876 		err(1, "%s host %s", name, address);
877 	if ((*port = reallocarray(*port, *num + 1, sizeof(**port))) == NULL)
878 		err(1, "%s port %s", name, address);
879 	if (loghost_parse(p, NULL, *host + *num, *port + *num) == -1)
880 		errx(1, "bad %s address: %s", name, address);
881 	(*num)++;
882 }
883 
884 int
885 socket_bind(const char *proto, const char *host, const char *port,
886     int shutread, int *fd, int *fd6)
887 {
888 	struct addrinfo	 hints, *res, *res0;
889 	char		 hostname[NI_MAXHOST], servname[NI_MAXSERV];
890 	char		 ebuf[ERRBUFSIZE];
891 	int		*fdp, error, reuseaddr;
892 
893 	*fd = *fd6 = -1;
894 	if (proto == NULL)
895 		proto = "udp";
896 	if (port == NULL)
897 		port = strcmp(proto, "tls") == 0 ? "syslog-tls" : "syslog";
898 
899 	memset(&hints, 0, sizeof(hints));
900 	hints.ai_family = Family;
901 	if (strcmp(proto, "udp") == 0) {
902 		hints.ai_socktype = SOCK_DGRAM;
903 		hints.ai_protocol = IPPROTO_UDP;
904 	} else {
905 		hints.ai_socktype = SOCK_STREAM;
906 		hints.ai_protocol = IPPROTO_TCP;
907 	}
908 	hints.ai_flags = AI_PASSIVE;
909 
910 	if ((error = getaddrinfo(host, port, &hints, &res0))) {
911 		snprintf(ebuf, sizeof(ebuf), "getaddrinfo "
912 		    "proto %s, host %s, port %s: %s",
913 		    proto, host ? host : "*", port, gai_strerror(error));
914 		logerrorx(ebuf);
915 		die(0);
916 	}
917 
918 	for (res = res0; res; res = res->ai_next) {
919 		switch (res->ai_family) {
920 		case AF_INET:
921 			fdp = fd;
922 			break;
923 		case AF_INET6:
924 			fdp = fd6;
925 			break;
926 		default:
927 			continue;
928 		}
929 		if (*fdp >= 0)
930 			continue;
931 
932 		if ((*fdp = socket(res->ai_family,
933 		    res->ai_socktype | SOCK_NONBLOCK, res->ai_protocol)) == -1)
934 			continue;
935 
936 		if (getnameinfo(res->ai_addr, res->ai_addrlen, hostname,
937 		    sizeof(hostname), servname, sizeof(servname),
938 		    NI_NUMERICHOST | NI_NUMERICSERV |
939 		    (res->ai_socktype == SOCK_DGRAM ? NI_DGRAM : 0)) != 0) {
940 			logdebug("Malformed bind address\n");
941 			hostname[0] = servname[0] = '\0';
942 		}
943 		if (shutread && shutdown(*fdp, SHUT_RD) == -1) {
944 			snprintf(ebuf, sizeof(ebuf), "shutdown SHUT_RD "
945 			    "protocol %d, address %s, portnum %s",
946 			    res->ai_protocol, hostname, servname);
947 			logerror(ebuf);
948 			close(*fdp);
949 			*fdp = -1;
950 			continue;
951 		}
952 		if (!shutread && res->ai_protocol == IPPROTO_UDP)
953 			double_sockbuf(*fdp, SO_RCVBUF);
954 		else if (res->ai_protocol == IPPROTO_TCP)
955 			set_sockbuf(*fdp);
956 		reuseaddr = 1;
957 		if (setsockopt(*fdp, SOL_SOCKET, SO_REUSEADDR, &reuseaddr,
958 		    sizeof(reuseaddr)) == -1) {
959 			snprintf(ebuf, sizeof(ebuf), "setsockopt SO_REUSEADDR "
960 			    "protocol %d, address %s, portnum %s",
961 			    res->ai_protocol, hostname, servname);
962 			logerror(ebuf);
963 			close(*fdp);
964 			*fdp = -1;
965 			continue;
966 		}
967 		if (bind(*fdp, res->ai_addr, res->ai_addrlen) == -1) {
968 			snprintf(ebuf, sizeof(ebuf), "bind "
969 			    "protocol %d, address %s, portnum %s",
970 			    res->ai_protocol, hostname, servname);
971 			logerror(ebuf);
972 			close(*fdp);
973 			*fdp = -1;
974 			continue;
975 		}
976 		if (!shutread && res->ai_protocol == IPPROTO_TCP &&
977 		    listen(*fdp, 10) == -1) {
978 			snprintf(ebuf, sizeof(ebuf), "listen "
979 			    "protocol %d, address %s, portnum %s",
980 			    res->ai_protocol, hostname, servname);
981 			logerror(ebuf);
982 			close(*fdp);
983 			*fdp = -1;
984 			continue;
985 		}
986 	}
987 
988 	freeaddrinfo(res0);
989 
990 	if (*fd == -1 && *fd6 == -1)
991 		return (-1);
992 	return (0);
993 }
994 
995 void
996 klog_readcb(int fd, short event, void *arg)
997 {
998 	struct event		*ev = arg;
999 	ssize_t			 n;
1000 
1001 	n = read(fd, linebuf, linesize - 1);
1002 	if (n > 0) {
1003 		linebuf[n] = '\0';
1004 		printsys(linebuf);
1005 	} else if (n < 0 && errno != EINTR) {
1006 		logerror("klog");
1007 		event_del(ev);
1008 	}
1009 }
1010 
1011 void
1012 udp_readcb(int fd, short event, void *arg)
1013 {
1014 	struct sockaddr_storage	 sa;
1015 	socklen_t		 salen;
1016 	ssize_t			 n;
1017 
1018 	salen = sizeof(sa);
1019 	n = recvfrom(fd, linebuf, MAXLINE, 0, (struct sockaddr *)&sa, &salen);
1020 	if (n > 0) {
1021 		char	 resolve[NI_MAXHOST];
1022 
1023 		linebuf[n] = '\0';
1024 		cvthname((struct sockaddr *)&sa, resolve, sizeof(resolve));
1025 		logdebug("cvthname res: %s\n", resolve);
1026 		printline(resolve, linebuf);
1027 	} else if (n < 0 && errno != EINTR && errno != EWOULDBLOCK)
1028 		logerror("recvfrom udp");
1029 }
1030 
1031 void
1032 unix_readcb(int fd, short event, void *arg)
1033 {
1034 	struct sockaddr_un	 sa;
1035 	socklen_t		 salen;
1036 	ssize_t			 n;
1037 
1038 	salen = sizeof(sa);
1039 	n = recvfrom(fd, linebuf, MAXLINE, 0, (struct sockaddr *)&sa, &salen);
1040 	if (n > 0) {
1041 		linebuf[n] = '\0';
1042 		printline(LocalHostName, linebuf);
1043 	} else if (n < 0 && errno != EINTR && errno != EWOULDBLOCK)
1044 		logerror("recvfrom unix");
1045 }
1046 
1047 int
1048 reserve_accept4(int lfd, int event, struct event *ev,
1049     void (*cb)(int, short, void *),
1050     struct sockaddr *sa, socklen_t *salen, int flags)
1051 {
1052 	struct timeval	 to = { 1, 0 };
1053 	char		 ebuf[ERRBUFSIZE];
1054 	int		 afd;
1055 
1056 	if (event & EV_TIMEOUT) {
1057 		logdebug("Listen again\n");
1058 		/* Enable the listen event, there is no timeout anymore. */
1059 		event_set(ev, lfd, EV_READ|EV_PERSIST, cb, ev);
1060 		event_add(ev, NULL);
1061 		errno = EWOULDBLOCK;
1062 		return (-1);
1063 	}
1064 
1065 	if (getdtablecount() + FD_RESERVE >= getdtablesize()) {
1066 		afd = -1;
1067 		errno = EMFILE;
1068 	} else
1069 		afd = accept4(lfd, sa, salen, flags);
1070 
1071 	if (afd == -1 && (errno == ENFILE || errno == EMFILE)) {
1072 		snprintf(ebuf, sizeof(ebuf), "syslogd: accept deferred: %s",
1073 		    strerror(errno));
1074 		logmsg(LOG_SYSLOG|LOG_WARNING, ebuf, LocalHostName, ADDDATE);
1075 		/*
1076 		 * Disable the listen event and convert it to a timeout.
1077 		 * Pass the listen file descriptor to the callback.
1078 		 */
1079 		event_del(ev);
1080 		event_set(ev, lfd, 0, cb, ev);
1081 		event_add(ev, &to);
1082 		return (-1);
1083 	}
1084 
1085 	return (afd);
1086 }
1087 
1088 void
1089 tcp_acceptcb(int lfd, short event, void *arg)
1090 {
1091 	struct event		*ev = arg;
1092 	struct peer		*p;
1093 	struct sockaddr_storage	 ss;
1094 	socklen_t		 sslen;
1095 	char			 hostname[NI_MAXHOST], servname[NI_MAXSERV];
1096 	char			*peername, ebuf[ERRBUFSIZE];
1097 	int			 fd;
1098 
1099 	sslen = sizeof(ss);
1100 	if ((fd = reserve_accept4(lfd, event, ev, tcp_acceptcb,
1101 	    (struct sockaddr *)&ss, &sslen, SOCK_NONBLOCK)) == -1) {
1102 		if (errno != ENFILE && errno != EMFILE &&
1103 		    errno != EINTR && errno != EWOULDBLOCK &&
1104 		    errno != ECONNABORTED)
1105 			logerror("accept tcp socket");
1106 		return;
1107 	}
1108 	logdebug("Accepting tcp connection\n");
1109 
1110 	if (getnameinfo((struct sockaddr *)&ss, sslen, hostname,
1111 	    sizeof(hostname), servname, sizeof(servname),
1112 	    NI_NUMERICHOST | NI_NUMERICSERV) != 0 ||
1113 	    asprintf(&peername, ss.ss_family == AF_INET6 ?
1114 	    "[%s]:%s" : "%s:%s", hostname, servname) == -1) {
1115 		logdebug("Malformed accept address\n");
1116 		peername = hostname_unknown;
1117 	}
1118 	logdebug("Peer addresss and port %s\n", peername);
1119 	if ((p = malloc(sizeof(*p))) == NULL) {
1120 		snprintf(ebuf, sizeof(ebuf), "malloc \"%s\"", peername);
1121 		logerror(ebuf);
1122 		close(fd);
1123 		return;
1124 	}
1125 	p->p_fd = fd;
1126 	if ((p->p_bufev = bufferevent_new(fd, tcp_readcb, NULL, tcp_closecb,
1127 	    p)) == NULL) {
1128 		snprintf(ebuf, sizeof(ebuf), "bufferevent \"%s\"", peername);
1129 		logerror(ebuf);
1130 		free(p);
1131 		close(fd);
1132 		return;
1133 	}
1134 	p->p_ctx = NULL;
1135 	if (lfd == fd_tls) {
1136 		if (tls_accept_socket(server_ctx, &p->p_ctx, fd) < 0) {
1137 			snprintf(ebuf, sizeof(ebuf), "tls_accept_socket \"%s\"",
1138 			    peername);
1139 			logerrorctx(ebuf, server_ctx);
1140 			bufferevent_free(p->p_bufev);
1141 			free(p);
1142 			close(fd);
1143 			return;
1144 		}
1145 		buffertls_set(&p->p_buftls, p->p_bufev, p->p_ctx, fd);
1146 		buffertls_accept(&p->p_buftls, fd);
1147 		logdebug("tcp accept callback: tls context success\n");
1148 	}
1149 	if (!NoDNS && peername != hostname_unknown &&
1150 	    priv_getnameinfo((struct sockaddr *)&ss, ss.ss_len, hostname,
1151 	    sizeof(hostname)) != 0) {
1152 		logdebug("Host name for accept address (%s) unknown\n",
1153 		    hostname);
1154 	}
1155 	if (peername == hostname_unknown ||
1156 	    (p->p_hostname = strdup(hostname)) == NULL)
1157 		p->p_hostname = hostname_unknown;
1158 	logdebug("Peer hostname %s\n", hostname);
1159 	p->p_peername = peername;
1160 	bufferevent_enable(p->p_bufev, EV_READ);
1161 
1162 	snprintf(ebuf, sizeof(ebuf), "syslogd: %s logger \"%s\" accepted",
1163 	    p->p_ctx ? "tls" : "tcp", peername);
1164 	logmsg(LOG_SYSLOG|LOG_INFO, ebuf, LocalHostName, ADDDATE);
1165 }
1166 
1167 /*
1168  * Syslog over TCP  RFC 6587  3.4.1. Octet Counting
1169  */
1170 int
1171 octet_counting(struct evbuffer *evbuf, char **msg, int drain)
1172 {
1173 	char	*p, *buf, *end;
1174 	int	 len;
1175 
1176 	buf = EVBUFFER_DATA(evbuf);
1177 	end = buf + EVBUFFER_LENGTH(evbuf);
1178 	/*
1179 	 * It can be assumed that octet-counting framing is used if a syslog
1180 	 * frame starts with a digit.
1181 	 */
1182 	if (buf >= end || !isdigit((unsigned char)*buf))
1183 		return (-1);
1184 	/*
1185 	 * SYSLOG-FRAME = MSG-LEN SP SYSLOG-MSG
1186 	 * MSG-LEN is the octet count of the SYSLOG-MSG in the SYSLOG-FRAME.
1187 	 * We support up to 5 digits in MSG-LEN, so the maximum is 99999.
1188 	 */
1189 	for (p = buf; p < end && p < buf + 5; p++) {
1190 		if (!isdigit((unsigned char)*p))
1191 			break;
1192 	}
1193 	if (buf >= p || p >= end || *p != ' ')
1194 		return (-1);
1195 	p++;
1196 	/* Using atoi() is safe as buf starts with 1 to 5 digits and a space. */
1197 	len = atoi(buf);
1198 	if (drain)
1199 		logdebug(" octet counting %d", len);
1200 	if (p + len > end)
1201 		return (0);
1202 	if (drain)
1203 		evbuffer_drain(evbuf, p - buf);
1204 	if (msg)
1205 		*msg = p;
1206 	return (len);
1207 }
1208 
1209 /*
1210  * Syslog over TCP  RFC 6587  3.4.2. Non-Transparent-Framing
1211  */
1212 int
1213 non_transparent_framing(struct evbuffer *evbuf, char **msg)
1214 {
1215 	char	*p, *buf, *end;
1216 
1217 	buf = EVBUFFER_DATA(evbuf);
1218 	end = buf + EVBUFFER_LENGTH(evbuf);
1219 	/*
1220 	 * The TRAILER has usually been a single character and most often
1221 	 * is ASCII LF (%d10).  However, other characters have also been
1222 	 * seen, with ASCII NUL (%d00) being a prominent example.
1223 	 */
1224 	for (p = buf; p < end; p++) {
1225 		if (*p == '\0' || *p == '\n')
1226 			break;
1227 	}
1228 	if (p + 1 - buf >= INT_MAX)
1229 		return (-1);
1230 	logdebug(" non transparent framing");
1231 	if (p >= end)
1232 		return (0);
1233 	/*
1234 	 * Some devices have also been seen to emit a two-character
1235 	 * TRAILER, which is usually CR and LF.
1236 	 */
1237 	if (buf < p && p[0] == '\n' && p[-1] == '\r')
1238 		p[-1] = '\0';
1239 	if (msg)
1240 		*msg = buf;
1241 	return (p + 1 - buf);
1242 }
1243 
1244 void
1245 tcp_readcb(struct bufferevent *bufev, void *arg)
1246 {
1247 	struct peer		*p = arg;
1248 	char			*msg;
1249 	int			 len;
1250 
1251 	while (EVBUFFER_LENGTH(bufev->input) > 0) {
1252 		logdebug("%s logger \"%s\"", p->p_ctx ? "tls" : "tcp",
1253 		    p->p_peername);
1254 		msg = NULL;
1255 		len = octet_counting(bufev->input, &msg, 1);
1256 		if (len < 0)
1257 			len = non_transparent_framing(bufev->input, &msg);
1258 		if (len < 0)
1259 			logdebug("unknown method");
1260 		if (msg == NULL) {
1261 			logdebug(", incomplete frame");
1262 			break;
1263 		}
1264 		logdebug(", use %d bytes\n", len);
1265 		if (len > 0 && msg[len-1] == '\n')
1266 			msg[len-1] = '\0';
1267 		if (len == 0 || msg[len-1] != '\0') {
1268 			memcpy(linebuf, msg, MINIMUM(len, MAXLINE));
1269 			linebuf[MINIMUM(len, MAXLINE)] = '\0';
1270 			msg = linebuf;
1271 		}
1272 		printline(p->p_hostname, msg);
1273 		evbuffer_drain(bufev->input, len);
1274 	}
1275 	/* Maximum frame has 5 digits, 1 space, MAXLINE chars, 1 new line. */
1276 	if (EVBUFFER_LENGTH(bufev->input) >= 5 + 1 + MAXLINE + 1) {
1277 		logdebug(", use %zu bytes\n", EVBUFFER_LENGTH(bufev->input));
1278 		printline(p->p_hostname, EVBUFFER_DATA(bufev->input));
1279 		evbuffer_drain(bufev->input, -1);
1280 	} else if (EVBUFFER_LENGTH(bufev->input) > 0)
1281 		logdebug(", buffer %zu bytes\n", EVBUFFER_LENGTH(bufev->input));
1282 }
1283 
1284 void
1285 tcp_closecb(struct bufferevent *bufev, short event, void *arg)
1286 {
1287 	struct peer		*p = arg;
1288 	char			 ebuf[ERRBUFSIZE];
1289 
1290 	if (event & EVBUFFER_EOF) {
1291 		snprintf(ebuf, sizeof(ebuf), "syslogd: %s logger \"%s\" "
1292 		    "connection close", p->p_ctx ? "tls" : "tcp",
1293 		    p->p_peername);
1294 		logmsg(LOG_SYSLOG|LOG_INFO, ebuf, LocalHostName, ADDDATE);
1295 	} else {
1296 		snprintf(ebuf, sizeof(ebuf), "syslogd: %s logger \"%s\" "
1297 		    "connection error: %s", p->p_ctx ? "tls" : "tcp",
1298 		    p->p_peername,
1299 		    p->p_ctx ? tls_error(p->p_ctx) : strerror(errno));
1300 		logmsg(LOG_SYSLOG|LOG_NOTICE, ebuf, LocalHostName, ADDDATE);
1301 	}
1302 
1303 	if (p->p_peername != hostname_unknown)
1304 		free(p->p_peername);
1305 	if (p->p_hostname != hostname_unknown)
1306 		free(p->p_hostname);
1307 	bufferevent_free(p->p_bufev);
1308 	close(p->p_fd);
1309 	free(p);
1310 }
1311 
1312 int
1313 tcp_socket(struct filed *f)
1314 {
1315 	int	 s;
1316 	char	 ebuf[ERRBUFSIZE];
1317 
1318 	if ((s = socket(f->f_un.f_forw.f_addr.ss_family,
1319 	    SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP)) == -1) {
1320 		snprintf(ebuf, sizeof(ebuf), "socket \"%s\"",
1321 		    f->f_un.f_forw.f_loghost);
1322 		logerror(ebuf);
1323 		return (-1);
1324 	}
1325 	set_sockbuf(s);
1326 	if (connect(s, (struct sockaddr *)&f->f_un.f_forw.f_addr,
1327 	    f->f_un.f_forw.f_addr.ss_len) == -1 && errno != EINPROGRESS) {
1328 		snprintf(ebuf, sizeof(ebuf), "connect \"%s\"",
1329 		    f->f_un.f_forw.f_loghost);
1330 		logerror(ebuf);
1331 		close(s);
1332 		return (-1);
1333 	}
1334 	return (s);
1335 }
1336 
1337 void
1338 tcp_dropcb(struct bufferevent *bufev, void *arg)
1339 {
1340 	struct filed	*f = arg;
1341 
1342 	/*
1343 	 * Drop data received from the forward log server.
1344 	 */
1345 	logdebug("loghost \"%s\" did send %zu bytes back\n",
1346 	    f->f_un.f_forw.f_loghost, EVBUFFER_LENGTH(bufev->input));
1347 	evbuffer_drain(bufev->input, -1);
1348 }
1349 
1350 void
1351 tcp_writecb(struct bufferevent *bufev, void *arg)
1352 {
1353 	struct filed	*f = arg;
1354 	char		 ebuf[ERRBUFSIZE];
1355 
1356 	/*
1357 	 * Successful write, connection to server is good, reset wait time.
1358 	 */
1359 	logdebug("loghost \"%s\" successful write\n", f->f_un.f_forw.f_loghost);
1360 	f->f_un.f_forw.f_reconnectwait = 0;
1361 
1362 	if (f->f_un.f_forw.f_dropped > 0 &&
1363 	    EVBUFFER_LENGTH(f->f_un.f_forw.f_bufev->output) < MAX_TCPBUF) {
1364 		snprintf(ebuf, sizeof(ebuf),
1365 		    "syslogd: dropped %d message%s to loghost \"%s\"",
1366 		    f->f_un.f_forw.f_dropped,
1367 		    f->f_un.f_forw.f_dropped == 1 ? "" : "s",
1368 		    f->f_un.f_forw.f_loghost);
1369 		f->f_un.f_forw.f_dropped = 0;
1370 		logmsg(LOG_SYSLOG|LOG_WARNING, ebuf, LocalHostName, ADDDATE);
1371 	}
1372 }
1373 
1374 void
1375 tcp_errorcb(struct bufferevent *bufev, short event, void *arg)
1376 {
1377 	struct filed	*f = arg;
1378 	char		*p, *buf, *end;
1379 	int		 l;
1380 	char		 ebuf[ERRBUFSIZE];
1381 
1382 	if (event & EVBUFFER_EOF)
1383 		snprintf(ebuf, sizeof(ebuf),
1384 		    "syslogd: loghost \"%s\" connection close",
1385 		    f->f_un.f_forw.f_loghost);
1386 	else
1387 		snprintf(ebuf, sizeof(ebuf),
1388 		    "syslogd: loghost \"%s\" connection error: %s",
1389 		    f->f_un.f_forw.f_loghost, f->f_un.f_forw.f_ctx ?
1390 		    tls_error(f->f_un.f_forw.f_ctx) : strerror(errno));
1391 	logdebug("%s\n", ebuf);
1392 
1393 	/* The SIGHUP handler may also close the socket, so invalidate it. */
1394 	if (f->f_un.f_forw.f_ctx) {
1395 		tls_close(f->f_un.f_forw.f_ctx);
1396 		tls_free(f->f_un.f_forw.f_ctx);
1397 		f->f_un.f_forw.f_ctx = NULL;
1398 	}
1399 	close(f->f_file);
1400 	f->f_file = -1;
1401 
1402 	/*
1403 	 * The messages in the output buffer may be out of sync.
1404 	 * Check that the buffer starts with "1234 <1234 octets>\n".
1405 	 * Otherwise remove the partial message from the beginning.
1406 	 */
1407 	buf = EVBUFFER_DATA(bufev->output);
1408 	end = buf + EVBUFFER_LENGTH(bufev->output);
1409 	if (buf < end && !((l = octet_counting(bufev->output, &p, 0)) > 0 &&
1410 	    p[l-1] == '\n')) {
1411 		for (p = buf; p < end; p++) {
1412 			if (*p == '\n') {
1413 				evbuffer_drain(bufev->output, p - buf + 1);
1414 				break;
1415 			}
1416 		}
1417 		/* Without '\n' discard everything. */
1418 		if (p == end)
1419 			evbuffer_drain(bufev->output, -1);
1420 		logdebug("loghost \"%s\" dropped partial message\n",
1421 		    f->f_un.f_forw.f_loghost);
1422 		f->f_un.f_forw.f_dropped++;
1423 	}
1424 
1425 	tcp_connect_retry(bufev, f);
1426 
1427 	/* Log the connection error to the fresh buffer after reconnecting. */
1428 	logmsg(LOG_SYSLOG|LOG_WARNING, ebuf, LocalHostName, ADDDATE);
1429 }
1430 
1431 void
1432 tcp_connectcb(int fd, short event, void *arg)
1433 {
1434 	struct filed		*f = arg;
1435 	struct bufferevent	*bufev = f->f_un.f_forw.f_bufev;
1436 	char			 ebuf[ERRBUFSIZE];
1437 	int			 s;
1438 
1439 	if ((s = tcp_socket(f)) == -1) {
1440 		tcp_connect_retry(bufev, f);
1441 		return;
1442 	}
1443 	logdebug("tcp connect callback: socket success, event %#x\n", event);
1444 	f->f_file = s;
1445 
1446 	bufferevent_setfd(bufev, s);
1447 	bufferevent_setcb(bufev, tcp_dropcb, tcp_writecb, tcp_errorcb, f);
1448 	/*
1449 	 * Although syslog is a write only protocol, enable reading from
1450 	 * the socket to detect connection close and errors.
1451 	 */
1452 	bufferevent_enable(bufev, EV_READ|EV_WRITE);
1453 
1454 	if (f->f_type == F_FORWTLS) {
1455 		if ((f->f_un.f_forw.f_ctx = tls_client()) == NULL) {
1456 			snprintf(ebuf, sizeof(ebuf), "tls_client \"%s\"",
1457 			    f->f_un.f_forw.f_loghost);
1458 			logerror(ebuf);
1459 			goto error;
1460 		}
1461 		if (client_config &&
1462 		    tls_configure(f->f_un.f_forw.f_ctx, client_config) == -1) {
1463 			snprintf(ebuf, sizeof(ebuf), "tls_configure \"%s\"",
1464 			    f->f_un.f_forw.f_loghost);
1465 			logerrorctx(ebuf, f->f_un.f_forw.f_ctx);
1466 			goto error;
1467 		}
1468 		if (tls_connect_socket(f->f_un.f_forw.f_ctx, s,
1469 		    f->f_un.f_forw.f_host) == -1) {
1470 			snprintf(ebuf, sizeof(ebuf), "tls_connect_socket "
1471 			    "\"%s\"", f->f_un.f_forw.f_loghost);
1472 			logerrorctx(ebuf, f->f_un.f_forw.f_ctx);
1473 			goto error;
1474 		}
1475 		logdebug("tcp connect callback: tls context success\n");
1476 
1477 		buffertls_set(&f->f_un.f_forw.f_buftls, bufev,
1478 		    f->f_un.f_forw.f_ctx, s);
1479 		buffertls_connect(&f->f_un.f_forw.f_buftls, s);
1480 	}
1481 
1482 	return;
1483 
1484  error:
1485 	if (f->f_un.f_forw.f_ctx) {
1486 		tls_free(f->f_un.f_forw.f_ctx);
1487 		f->f_un.f_forw.f_ctx = NULL;
1488 	}
1489 	close(f->f_file);
1490 	f->f_file = -1;
1491 	tcp_connect_retry(bufev, f);
1492 }
1493 
1494 void
1495 tcp_connect_retry(struct bufferevent *bufev, struct filed *f)
1496 {
1497 	struct timeval		 to;
1498 
1499 	if (f->f_un.f_forw.f_reconnectwait == 0)
1500 		f->f_un.f_forw.f_reconnectwait = 1;
1501 	else
1502 		f->f_un.f_forw.f_reconnectwait <<= 1;
1503 	if (f->f_un.f_forw.f_reconnectwait > 600)
1504 		f->f_un.f_forw.f_reconnectwait = 600;
1505 	to.tv_sec = f->f_un.f_forw.f_reconnectwait;
1506 	to.tv_usec = 0;
1507 
1508 	logdebug("tcp connect retry: wait %d\n",
1509 	    f->f_un.f_forw.f_reconnectwait);
1510 	bufferevent_setfd(bufev, -1);
1511 	/* We can reuse the write event as bufferevent is disabled. */
1512 	evtimer_set(&bufev->ev_write, tcp_connectcb, f);
1513 	evtimer_add(&bufev->ev_write, &to);
1514 }
1515 
1516 int
1517 tcpbuf_countmsg(struct bufferevent *bufev)
1518 {
1519 	char	*p, *buf, *end;
1520 	int	 i = 0;
1521 
1522 	buf = EVBUFFER_DATA(bufev->output);
1523 	end = buf + EVBUFFER_LENGTH(bufev->output);
1524 	for (p = buf; p < end; p++) {
1525 		if (*p == '\n')
1526 			i++;
1527 	}
1528 	return (i);
1529 }
1530 
1531 void
1532 usage(void)
1533 {
1534 
1535 	(void)fprintf(stderr,
1536 	    "usage: syslogd [-46dFhnuVZ] [-a path] [-C CAfile] [-c cert_file]\n"
1537 	    "\t[-f config_file] [-K CAfile] [-k key_file] [-m mark_interval]\n"
1538 	    "\t[-p log_socket] [-S listen_address] [-s reporting_socket]\n"
1539 	    "\t[-T listen_address] [-U bind_address]\n");
1540 	exit(1);
1541 }
1542 
1543 /*
1544  * Parse a priority code of the form "<123>" into pri, and return the
1545  * length of the priority code including the surrounding angle brackets.
1546  */
1547 size_t
1548 parsepriority(const char *msg, int *pri)
1549 {
1550 	size_t nlen;
1551 	char buf[11];
1552 	const char *errstr;
1553 	int maybepri;
1554 
1555 	if (*msg++ == '<') {
1556 		nlen = strspn(msg, "1234567890");
1557 		if (nlen > 0 && nlen < sizeof(buf) && msg[nlen] == '>') {
1558 			strlcpy(buf, msg, nlen + 1);
1559 			maybepri = strtonum(buf, 0, INT_MAX, &errstr);
1560 			if (errstr == NULL) {
1561 				*pri = maybepri;
1562 				return nlen + 2;
1563 			}
1564 		}
1565 	}
1566 
1567 	return 0;
1568 }
1569 
1570 /*
1571  * Take a raw input line, decode the message, and print the message
1572  * on the appropriate log files.
1573  */
1574 void
1575 printline(char *hname, char *msg)
1576 {
1577 	int pri;
1578 	char *p, *q, line[MAXLINE + 4 + 1];  /* message, encoding, NUL */
1579 
1580 	/* test for special codes */
1581 	pri = DEFUPRI;
1582 	p = msg;
1583 	p += parsepriority(p, &pri);
1584 	if (pri &~ (LOG_FACMASK|LOG_PRIMASK))
1585 		pri = DEFUPRI;
1586 
1587 	/*
1588 	 * Don't allow users to log kernel messages.
1589 	 * NOTE: since LOG_KERN == 0 this will also match
1590 	 * messages with no facility specified.
1591 	 */
1592 	if (LOG_FAC(pri) == LOG_KERN)
1593 		pri = LOG_USER | LOG_PRI(pri);
1594 
1595 	for (q = line; *p && q < &line[MAXLINE]; p++) {
1596 		if (*p == '\n')
1597 			*q++ = ' ';
1598 		else
1599 			q = vis(q, *p, 0, 0);
1600 	}
1601 	line[MAXLINE] = *q = '\0';
1602 
1603 	logmsg(pri, line, hname, 0);
1604 }
1605 
1606 /*
1607  * Take a raw input line from /dev/klog, split and format similar to syslog().
1608  */
1609 void
1610 printsys(char *msg)
1611 {
1612 	int c, pri, flags;
1613 	char *lp, *p, *q, line[MAXLINE + 1];
1614 	size_t prilen;
1615 
1616 	(void)snprintf(line, sizeof line, "%s: ", _PATH_UNIX);
1617 	lp = line + strlen(line);
1618 	for (p = msg; *p != '\0'; ) {
1619 		flags = SYNC_FILE | ADDDATE;	/* fsync file after write */
1620 		pri = DEFSPRI;
1621 		prilen = parsepriority(p, &pri);
1622 		p += prilen;
1623 		if (prilen == 0) {
1624 			/* kernel printf's come out on console */
1625 			flags |= IGN_CONS;
1626 		}
1627 		if (pri &~ (LOG_FACMASK|LOG_PRIMASK))
1628 			pri = DEFSPRI;
1629 
1630 		q = lp;
1631 		while (*p && (c = *p++) != '\n' && q < &line[sizeof(line) - 4])
1632 			q = vis(q, c, 0, 0);
1633 
1634 		logmsg(pri, line, LocalHostName, flags);
1635 	}
1636 }
1637 
1638 struct timeval	now;
1639 
1640 /*
1641  * Log a message to the appropriate log files, users, etc. based on
1642  * the priority.
1643  */
1644 void
1645 logmsg(int pri, char *msg, char *from, int flags)
1646 {
1647 	struct filed *f;
1648 	int fac, msglen, prilev, i;
1649 	char timestamp[33];
1650 	char prog[NAME_MAX+1];
1651 
1652 	logdebug("logmsg: pri 0%o, flags 0x%x, from %s, msg %s\n",
1653 	    pri, flags, from, msg);
1654 
1655 	/*
1656 	 * Check to see if msg looks non-standard.
1657 	 */
1658 	timestamp[0] = '\0';
1659 	msglen = strlen(msg);
1660 	if ((flags & ADDDATE) == 0) {
1661 		if (msglen >= 16 && msg[3] == ' ' && msg[6] == ' ' &&
1662 		    msg[9] == ':' && msg[12] == ':' && msg[15] == ' ') {
1663 			/* BSD syslog TIMESTAMP, RFC 3164 */
1664 			strlcpy(timestamp, msg, 16);
1665 			msg += 16;
1666 			msglen -= 16;
1667 			if (ZuluTime)
1668 				flags |= ADDDATE;
1669 		} else if (msglen >= 20 &&
1670 		    isdigit(msg[0]) && isdigit(msg[1]) && isdigit(msg[2]) &&
1671 		    isdigit(msg[3]) && msg[4] == '-' &&
1672 		    isdigit(msg[5]) && isdigit(msg[6]) && msg[7] == '-' &&
1673 		    isdigit(msg[8]) && isdigit(msg[9]) && msg[10] == 'T' &&
1674 		    isdigit(msg[11]) && isdigit(msg[12]) && msg[13] == ':' &&
1675 		    isdigit(msg[14]) && isdigit(msg[15]) && msg[16] == ':' &&
1676 		    isdigit(msg[17]) && isdigit(msg[18]) && (msg[19] == '.' ||
1677 		    msg[19] == 'Z' || msg[19] == '+' || msg[19] == '-')) {
1678 			/* FULL-DATE "T" FULL-TIME, RFC 5424 */
1679 			strlcpy(timestamp, msg, sizeof(timestamp));
1680 			msg += 19;
1681 			msglen -= 19;
1682 			i = 0;
1683 			if (msglen >= 3 && msg[0] == '.' && isdigit(msg[1])) {
1684 				/* TIME-SECFRAC */
1685 				msg += 2;
1686 				msglen -= 2;
1687 				i += 2;
1688 				while(i < 7 && msglen >= 1 && isdigit(msg[0])) {
1689 					msg++;
1690 					msglen--;
1691 					i++;
1692 				}
1693 			}
1694 			if (msglen >= 2 && msg[0] == 'Z' && msg[1] == ' ') {
1695 				/* "Z" */
1696 				timestamp[20+i] = '\0';
1697 				msg += 2;
1698 				msglen -= 2;
1699 			} else if (msglen >= 7 &&
1700 			    (msg[0] == '+' || msg[0] == '-') &&
1701 			    isdigit(msg[1]) && isdigit(msg[2]) &&
1702 			    msg[3] == ':' &&
1703 			    isdigit(msg[4]) && isdigit(msg[5]) &&
1704 			    msg[6] == ' ') {
1705 				/* TIME-NUMOFFSET */
1706 				timestamp[25+i] = '\0';
1707 				msg += 7;
1708 				msglen -= 7;
1709 			} else {
1710 				/* invalid time format, roll back */
1711 				timestamp[0] = '\0';
1712 				msg -= 19 + i;
1713 				msglen += 19 + i;
1714 				flags |= ADDDATE;
1715 			}
1716 		} else if (msglen >= 2 && msg[0] == '-' && msg[1] == ' ') {
1717 			/* NILVALUE, RFC 5424 */
1718 			msg += 2;
1719 			msglen -= 2;
1720 			flags |= ADDDATE;
1721 		} else
1722 			flags |= ADDDATE;
1723 	}
1724 
1725 	(void)gettimeofday(&now, NULL);
1726 	if (flags & ADDDATE) {
1727 		if (ZuluTime) {
1728 			struct tm *tm;
1729 			size_t l;
1730 
1731 			tm = gmtime(&now.tv_sec);
1732 			l = strftime(timestamp, sizeof(timestamp), "%FT%T", tm);
1733 			/*
1734 			 * Use only millisecond precision as some time has
1735 			 * passed since syslog(3) was called.
1736 			 */
1737 			snprintf(timestamp + l, sizeof(timestamp) - l,
1738 			    ".%03ldZ", now.tv_usec / 1000);
1739 		} else
1740 			strlcpy(timestamp, ctime(&now.tv_sec) + 4, 16);
1741 	}
1742 
1743 	/* extract facility and priority level */
1744 	if (flags & MARK)
1745 		fac = LOG_NFACILITIES;
1746 	else {
1747 		fac = LOG_FAC(pri);
1748 		if (fac >= LOG_NFACILITIES || fac < 0)
1749 			fac = LOG_USER;
1750 	}
1751 	prilev = LOG_PRI(pri);
1752 
1753 	/* extract program name */
1754 	while (isspace((unsigned char)*msg)) {
1755 		msg++;
1756 		msglen--;
1757 	}
1758 	for (i = 0; i < NAME_MAX; i++) {
1759 		if (!isalnum((unsigned char)msg[i]) && msg[i] != '-')
1760 			break;
1761 		prog[i] = msg[i];
1762 	}
1763 	prog[i] = 0;
1764 
1765 	/* log the message to the particular outputs */
1766 	if (!Initialized) {
1767 		f = &consfile;
1768 		f->f_file = priv_open_tty(ctty);
1769 
1770 		if (f->f_file >= 0) {
1771 			fprintlog(f, flags, msg);
1772 			(void)close(f->f_file);
1773 			f->f_file = -1;
1774 		}
1775 		return;
1776 	}
1777 	SIMPLEQ_FOREACH(f, &Files, f_next) {
1778 		/* skip messages that are incorrect priority */
1779 		if (f->f_pmask[fac] < prilev ||
1780 		    f->f_pmask[fac] == INTERNAL_NOPRI)
1781 			continue;
1782 
1783 		/* skip messages with the incorrect program or hostname */
1784 		if (f->f_program && strcmp(prog, f->f_program) != 0)
1785 			continue;
1786 		if (f->f_hostname && strcmp(from, f->f_hostname) != 0)
1787 			continue;
1788 
1789 		if (f->f_type == F_CONSOLE && (flags & IGN_CONS))
1790 			continue;
1791 
1792 		/* don't output marks to recently written files */
1793 		if ((flags & MARK) &&
1794 		    (now.tv_sec - f->f_time) < MarkInterval / 2)
1795 			continue;
1796 
1797 		/*
1798 		 * suppress duplicate lines to this file
1799 		 */
1800 		if ((flags & MARK) == 0 && msglen == f->f_prevlen &&
1801 		    !strcmp(msg, f->f_prevline) &&
1802 		    !strcmp(from, f->f_prevhost)) {
1803 			strlcpy(f->f_lasttime, timestamp,
1804 			    sizeof(f->f_lasttime));
1805 			f->f_prevcount++;
1806 			logdebug("msg repeated %d times, %ld sec of %d\n",
1807 			    f->f_prevcount, (long)(now.tv_sec - f->f_time),
1808 			    repeatinterval[f->f_repeatcount]);
1809 			/*
1810 			 * If domark would have logged this by now,
1811 			 * flush it now (so we don't hold isolated messages),
1812 			 * but back off so we'll flush less often
1813 			 * in the future.
1814 			 */
1815 			if (now.tv_sec > REPEATTIME(f)) {
1816 				fprintlog(f, flags, (char *)NULL);
1817 				BACKOFF(f);
1818 			}
1819 		} else {
1820 			/* new line, save it */
1821 			if (f->f_prevcount)
1822 				fprintlog(f, 0, (char *)NULL);
1823 			f->f_repeatcount = 0;
1824 			f->f_prevpri = pri;
1825 			strlcpy(f->f_lasttime, timestamp,
1826 			    sizeof(f->f_lasttime));
1827 			strlcpy(f->f_prevhost, from,
1828 			    sizeof(f->f_prevhost));
1829 			if (msglen < MAXSVLINE) {
1830 				f->f_prevlen = msglen;
1831 				strlcpy(f->f_prevline, msg,
1832 				    sizeof(f->f_prevline));
1833 				fprintlog(f, flags, (char *)NULL);
1834 			} else {
1835 				f->f_prevline[0] = 0;
1836 				f->f_prevlen = 0;
1837 				fprintlog(f, flags, msg);
1838 			}
1839 		}
1840 
1841 		if (f->f_quick)
1842 			break;
1843 	}
1844 }
1845 
1846 void
1847 fprintlog(struct filed *f, int flags, char *msg)
1848 {
1849 	struct iovec iov[6];
1850 	struct iovec *v;
1851 	int l, retryonce;
1852 	char line[MAXLINE + 1], repbuf[80], greetings[500];
1853 
1854 	v = iov;
1855 	if (f->f_type == F_WALL) {
1856 		l = snprintf(greetings, sizeof(greetings),
1857 		    "\r\n\7Message from syslogd@%s at %.24s ...\r\n",
1858 		    f->f_prevhost, ctime(&now.tv_sec));
1859 		if (l < 0 || (size_t)l >= sizeof(greetings))
1860 			l = strlen(greetings);
1861 		v->iov_base = greetings;
1862 		v->iov_len = l;
1863 		v++;
1864 		v->iov_base = "";
1865 		v->iov_len = 0;
1866 		v++;
1867 	} else if (f->f_lasttime[0] != '\0') {
1868 		v->iov_base = f->f_lasttime;
1869 		v->iov_len = strlen(f->f_lasttime);
1870 		v++;
1871 		v->iov_base = " ";
1872 		v->iov_len = 1;
1873 		v++;
1874 	} else {
1875 		v->iov_base = "";
1876 		v->iov_len = 0;
1877 		v++;
1878 		v->iov_base = "";
1879 		v->iov_len = 0;
1880 		v++;
1881 	}
1882 	if (f->f_prevhost[0] != '\0') {
1883 		v->iov_base = f->f_prevhost;
1884 		v->iov_len = strlen(v->iov_base);
1885 		v++;
1886 		v->iov_base = " ";
1887 		v->iov_len = 1;
1888 		v++;
1889 	} else {
1890 		v->iov_base = "";
1891 		v->iov_len = 0;
1892 		v++;
1893 		v->iov_base = "";
1894 		v->iov_len = 0;
1895 		v++;
1896 	}
1897 
1898 	if (msg) {
1899 		v->iov_base = msg;
1900 		v->iov_len = strlen(msg);
1901 	} else if (f->f_prevcount > 1) {
1902 		l = snprintf(repbuf, sizeof(repbuf),
1903 		    "last message repeated %d times", f->f_prevcount);
1904 		if (l < 0 || (size_t)l >= sizeof(repbuf))
1905 			l = strlen(repbuf);
1906 		v->iov_base = repbuf;
1907 		v->iov_len = l;
1908 	} else {
1909 		v->iov_base = f->f_prevline;
1910 		v->iov_len = f->f_prevlen;
1911 	}
1912 	v++;
1913 
1914 	logdebug("Logging to %s", TypeNames[f->f_type]);
1915 	f->f_time = now.tv_sec;
1916 
1917 	switch (f->f_type) {
1918 	case F_UNUSED:
1919 		logdebug("\n");
1920 		break;
1921 
1922 	case F_FORWUDP:
1923 		logdebug(" %s\n", f->f_un.f_forw.f_loghost);
1924 		l = snprintf(line, MINIMUM(MAX_UDPMSG + 1, sizeof(line)),
1925 		    "<%d>%.32s %s%s%s", f->f_prevpri, (char *)iov[0].iov_base,
1926 		    IncludeHostname ? LocalHostName : "",
1927 		    IncludeHostname ? " " : "",
1928 		    (char *)iov[4].iov_base);
1929 		if (l < 0 || (size_t)l > MINIMUM(MAX_UDPMSG, sizeof(line)))
1930 			l = MINIMUM(MAX_UDPMSG, sizeof(line));
1931 		if (sendto(f->f_file, line, l, 0,
1932 		    (struct sockaddr *)&f->f_un.f_forw.f_addr,
1933 		    f->f_un.f_forw.f_addr.ss_len) != l) {
1934 			switch (errno) {
1935 			case EHOSTDOWN:
1936 			case EHOSTUNREACH:
1937 			case ENETDOWN:
1938 			case ENETUNREACH:
1939 			case ENOBUFS:
1940 			case EWOULDBLOCK:
1941 				/* silently dropped */
1942 				break;
1943 			default:
1944 				f->f_type = F_UNUSED;
1945 				logerror("sendto");
1946 				break;
1947 			}
1948 		}
1949 		break;
1950 
1951 	case F_FORWTCP:
1952 	case F_FORWTLS:
1953 		logdebug(" %s", f->f_un.f_forw.f_loghost);
1954 		if (EVBUFFER_LENGTH(f->f_un.f_forw.f_bufev->output) >=
1955 		    MAX_TCPBUF) {
1956 			logdebug(" (dropped)\n");
1957 			f->f_un.f_forw.f_dropped++;
1958 			break;
1959 		}
1960 		/*
1961 		 * Syslog over TLS  RFC 5425  4.3.  Sending Data
1962 		 * Syslog over TCP  RFC 6587  3.4.1.  Octet Counting
1963 		 * Use an additional '\n' to split messages.  This allows
1964 		 * buffer synchronisation, helps legacy implementations,
1965 		 * and makes line based testing easier.
1966 		 */
1967 		l = snprintf(line, sizeof(line), "<%d>%.32s %s%s\n",
1968 		    f->f_prevpri, (char *)iov[0].iov_base,
1969 		    IncludeHostname ? LocalHostName : "",
1970 		    IncludeHostname ? " " : "");
1971 		if (l < 0) {
1972 			logdebug(" (dropped snprintf)\n");
1973 			f->f_un.f_forw.f_dropped++;
1974 			break;
1975 		}
1976 		l = evbuffer_add_printf(f->f_un.f_forw.f_bufev->output,
1977 		    "%zu <%d>%.32s %s%s%s\n",
1978 		    (size_t)l + strlen(iov[4].iov_base),
1979 		    f->f_prevpri, (char *)iov[0].iov_base,
1980 		    IncludeHostname ? LocalHostName : "",
1981 		    IncludeHostname ? " " : "",
1982 		    (char *)iov[4].iov_base);
1983 		if (l < 0) {
1984 			logdebug(" (dropped evbuffer_add_printf)\n");
1985 			f->f_un.f_forw.f_dropped++;
1986 			break;
1987 		}
1988 		bufferevent_enable(f->f_un.f_forw.f_bufev, EV_WRITE);
1989 		logdebug("\n");
1990 		break;
1991 
1992 	case F_CONSOLE:
1993 		if (flags & IGN_CONS) {
1994 			logdebug(" (ignored)\n");
1995 			break;
1996 		}
1997 		/* FALLTHROUGH */
1998 
1999 	case F_TTY:
2000 	case F_FILE:
2001 	case F_PIPE:
2002 		logdebug(" %s\n", f->f_un.f_fname);
2003 		if (f->f_type != F_FILE && f->f_type != F_PIPE) {
2004 			v->iov_base = "\r\n";
2005 			v->iov_len = 2;
2006 		} else {
2007 			v->iov_base = "\n";
2008 			v->iov_len = 1;
2009 		}
2010 		retryonce = 0;
2011 	again:
2012 		if (writev(f->f_file, iov, 6) < 0) {
2013 			int e = errno;
2014 
2015 			/* pipe is non-blocking. log and drop message if full */
2016 			if (e == EAGAIN && f->f_type == F_PIPE) {
2017 				if (now.tv_sec - f->f_lasterrtime > 120) {
2018 					f->f_lasterrtime = now.tv_sec;
2019 					logerror(f->f_un.f_fname);
2020 				}
2021 				break;
2022 			}
2023 
2024 			(void)close(f->f_file);
2025 			/*
2026 			 * Check for errors on TTY's or program pipes.
2027 			 * Errors happen due to loss of tty or died programs.
2028 			 */
2029 			if (e == EAGAIN) {
2030 				/*
2031 				 * Silently drop messages on blocked write.
2032 				 * This can happen when logging to a locked tty.
2033 				 */
2034 				break;
2035 			} else if ((e == EIO || e == EBADF) &&
2036 			    f->f_type != F_FILE && f->f_type != F_PIPE &&
2037 			    !retryonce) {
2038 				f->f_file = priv_open_tty(f->f_un.f_fname);
2039 				retryonce = 1;
2040 				if (f->f_file < 0) {
2041 					f->f_type = F_UNUSED;
2042 					logerror(f->f_un.f_fname);
2043 				} else
2044 					goto again;
2045 			} else if ((e == EPIPE || e == EBADF) &&
2046 			    f->f_type == F_PIPE && !retryonce) {
2047 				f->f_file = priv_open_log(f->f_un.f_fname);
2048 				retryonce = 1;
2049 				if (f->f_file < 0) {
2050 					f->f_type = F_UNUSED;
2051 					logerror(f->f_un.f_fname);
2052 				} else
2053 					goto again;
2054 			} else {
2055 				f->f_type = F_UNUSED;
2056 				f->f_file = -1;
2057 				errno = e;
2058 				logerror(f->f_un.f_fname);
2059 			}
2060 		} else if (flags & SYNC_FILE)
2061 			(void)fsync(f->f_file);
2062 		break;
2063 
2064 	case F_USERS:
2065 	case F_WALL:
2066 		logdebug("\n");
2067 		v->iov_base = "\r\n";
2068 		v->iov_len = 2;
2069 		wallmsg(f, iov);
2070 		break;
2071 
2072 	case F_MEMBUF:
2073 		logdebug("\n");
2074 		snprintf(line, sizeof(line), "%.32s %s %s",
2075 		    (char *)iov[0].iov_base, (char *)iov[2].iov_base,
2076 		    (char *)iov[4].iov_base);
2077 		if (ringbuf_append_line(f->f_un.f_mb.f_rb, line) == 1)
2078 			f->f_un.f_mb.f_overflow = 1;
2079 		if (f->f_un.f_mb.f_attached)
2080 			ctlconn_logto(line);
2081 		break;
2082 	}
2083 	f->f_prevcount = 0;
2084 }
2085 
2086 /*
2087  *  WALLMSG -- Write a message to the world at large
2088  *
2089  *	Write the specified message to either the entire
2090  *	world, or a list of approved users.
2091  */
2092 void
2093 wallmsg(struct filed *f, struct iovec *iov)
2094 {
2095 	struct utmp ut;
2096 	char utline[sizeof(ut.ut_line) + 1], *p;
2097 	static int reenter;			/* avoid calling ourselves */
2098 	FILE *uf;
2099 	int i;
2100 
2101 	if (reenter++)
2102 		return;
2103 	if ((uf = priv_open_utmp()) == NULL) {
2104 		logerror(_PATH_UTMP);
2105 		reenter = 0;
2106 		return;
2107 	}
2108 	while (fread(&ut, sizeof(ut), 1, uf) == 1) {
2109 		if (ut.ut_name[0] == '\0')
2110 			continue;
2111 		/* must use strncpy since ut_* may not be NUL terminated */
2112 		strncpy(utline, ut.ut_line, sizeof(utline) - 1);
2113 		utline[sizeof(utline) - 1] = '\0';
2114 		if (f->f_type == F_WALL) {
2115 			if ((p = ttymsg(iov, 6, utline)) != NULL)
2116 				logerrorx(p);
2117 			continue;
2118 		}
2119 		/* should we send the message to this user? */
2120 		for (i = 0; i < MAXUNAMES; i++) {
2121 			if (!f->f_un.f_uname[i][0])
2122 				break;
2123 			if (!strncmp(f->f_un.f_uname[i], ut.ut_name,
2124 			    UT_NAMESIZE)) {
2125 				if ((p = ttymsg(iov, 6, utline)) != NULL)
2126 					logerrorx(p);
2127 				break;
2128 			}
2129 		}
2130 	}
2131 	(void)fclose(uf);
2132 	reenter = 0;
2133 }
2134 
2135 /*
2136  * Return a printable representation of a host address.
2137  */
2138 void
2139 cvthname(struct sockaddr *f, char *result, size_t res_len)
2140 {
2141 	if (getnameinfo(f, f->sa_len, result, res_len, NULL, 0,
2142 	    NI_NUMERICHOST|NI_NUMERICSERV|NI_DGRAM) != 0) {
2143 		logdebug("Malformed from address\n");
2144 		strlcpy(result, hostname_unknown, res_len);
2145 		return;
2146 	}
2147 	logdebug("cvthname(%s)\n", result);
2148 	if (NoDNS)
2149 		return;
2150 
2151 	if (priv_getnameinfo(f, f->sa_len, result, res_len) != 0)
2152 		logdebug("Host name for from address (%s) unknown\n", result);
2153 }
2154 
2155 void
2156 die_signalcb(int signum, short event, void *arg)
2157 {
2158 	die(signum);
2159 }
2160 
2161 void
2162 mark_timercb(int unused, short event, void *arg)
2163 {
2164 	struct event		*ev = arg;
2165 	struct timeval		 to;
2166 
2167 	markit();
2168 
2169 	to.tv_sec = TIMERINTVL;
2170 	to.tv_usec = 0;
2171 	evtimer_add(ev, &to);
2172 }
2173 
2174 void
2175 init_signalcb(int signum, short event, void *arg)
2176 {
2177 	char	 ebuf[ERRBUFSIZE];
2178 
2179 	init();
2180 
2181 	logmsg(LOG_SYSLOG|LOG_INFO, "syslogd: restart",
2182 	    LocalHostName, ADDDATE);
2183 	logdebug("syslogd: restarted\n");
2184 
2185 	if (tcpbuf_dropped > 0) {
2186 		snprintf(ebuf, sizeof(ebuf),
2187 		    "syslogd: dropped %d message%s to remote loghost",
2188 		    tcpbuf_dropped, tcpbuf_dropped == 1 ? "" : "s");
2189 		tcpbuf_dropped = 0;
2190 		logmsg(LOG_SYSLOG|LOG_WARNING, ebuf, LocalHostName, ADDDATE);
2191 	}
2192 }
2193 
2194 void
2195 logevent(int severity, const char *msg)
2196 {
2197 	logdebug("libevent: [%d] %s\n", severity, msg);
2198 }
2199 
2200 void
2201 logdebug(const char *fmt, ...)
2202 {
2203 	va_list ap;
2204 
2205 	if (Debug) {
2206 		va_start(ap, fmt);
2207 		vprintf(fmt, ap);
2208 		va_end(ap);
2209 	}
2210 }
2211 
2212 void
2213 logerror(const char *message)
2214 {
2215 	logerror_reason(message, errno ? strerror(errno) : NULL);
2216 }
2217 
2218 void
2219 logerrorx(const char *message)
2220 {
2221 	logerror_reason(message, NULL);
2222 }
2223 
2224 void
2225 logerrorctx(const char *message, struct tls *ctx)
2226 {
2227 	logerror_reason(message, ctx ? tls_error(ctx) : NULL);
2228 }
2229 
2230 void
2231 logerrortlsconf(const char *message, struct tls_config *config)
2232 {
2233 	logerror_reason(message, config ? tls_config_error(config) : NULL);
2234 }
2235 
2236 void
2237 logerror_reason(const char *message, const char *reason)
2238 {
2239 	char ebuf[ERRBUFSIZE];
2240 
2241 	if (reason)
2242 		(void)snprintf(ebuf, sizeof(ebuf), "syslogd: %s: %s",
2243 		    message, reason);
2244 	else
2245 		(void)snprintf(ebuf, sizeof(ebuf), "syslogd: %s", message);
2246 	errno = 0;
2247 	logdebug("%s\n", ebuf);
2248 	if (Startup)
2249 		fprintf(stderr, "%s\n", ebuf);
2250 	else
2251 		logmsg(LOG_SYSLOG|LOG_ERR, ebuf, LocalHostName, ADDDATE);
2252 }
2253 
2254 void
2255 die(int signo)
2256 {
2257 	struct filed *f;
2258 	int was_initialized = Initialized;
2259 	char ebuf[ERRBUFSIZE];
2260 
2261 	Initialized = 0;		/* Don't log SIGCHLDs */
2262 	SIMPLEQ_FOREACH(f, &Files, f_next) {
2263 		/* flush any pending output */
2264 		if (f->f_prevcount)
2265 			fprintlog(f, 0, (char *)NULL);
2266 		if (f->f_type == F_FORWTLS || f->f_type == F_FORWTCP) {
2267 			tcpbuf_dropped += f->f_un.f_forw.f_dropped +
2268 			    tcpbuf_countmsg(f->f_un.f_forw.f_bufev);
2269 			f->f_un.f_forw.f_dropped = 0;
2270 		}
2271 	}
2272 	Initialized = was_initialized;
2273 
2274 	if (tcpbuf_dropped > 0) {
2275 		snprintf(ebuf, sizeof(ebuf),
2276 		    "syslogd: dropped %d message%s to remote loghost",
2277 		    tcpbuf_dropped, tcpbuf_dropped == 1 ? "" : "s");
2278 		tcpbuf_dropped = 0;
2279 		logmsg(LOG_SYSLOG|LOG_WARNING, ebuf, LocalHostName, ADDDATE);
2280 	}
2281 
2282 	if (signo) {
2283 		logdebug("syslogd: exiting on signal %d\n", signo);
2284 		(void)snprintf(ebuf, sizeof(ebuf), "exiting on signal %d",
2285 		    signo);
2286 		logerrorx(ebuf);
2287 	}
2288 	logdebug("[unpriv] syslogd child about to exit\n");
2289 	exit(0);
2290 }
2291 
2292 /*
2293  *  INIT -- Initialize syslogd from configuration table
2294  */
2295 void
2296 init(void)
2297 {
2298 	char progblock[NAME_MAX+1], hostblock[NAME_MAX+1], *cline, *p, *q;
2299 	struct filed_list mb;
2300 	struct filed *f, *m;
2301 	FILE *cf;
2302 	int i;
2303 	size_t s;
2304 
2305 	logdebug("init\n");
2306 
2307 	/* If config file has been modified, then just die to restart */
2308 	if (priv_config_modified()) {
2309 		logdebug("config file changed: dying\n");
2310 		die(0);
2311 	}
2312 
2313 	/*
2314 	 *  Close all open log files.
2315 	 */
2316 	Initialized = 0;
2317 	SIMPLEQ_INIT(&mb);
2318 	while (!SIMPLEQ_EMPTY(&Files)) {
2319 		f = SIMPLEQ_FIRST(&Files);
2320 		SIMPLEQ_REMOVE_HEAD(&Files, f_next);
2321 		/* flush any pending output */
2322 		if (f->f_prevcount)
2323 			fprintlog(f, 0, (char *)NULL);
2324 
2325 		switch (f->f_type) {
2326 		case F_FORWTLS:
2327 			if (f->f_un.f_forw.f_ctx) {
2328 				tls_close(f->f_un.f_forw.f_ctx);
2329 				tls_free(f->f_un.f_forw.f_ctx);
2330 			}
2331 			free(f->f_un.f_forw.f_host);
2332 			/* FALLTHROUGH */
2333 		case F_FORWTCP:
2334 			tcpbuf_dropped += f->f_un.f_forw.f_dropped +
2335 			     tcpbuf_countmsg(f->f_un.f_forw.f_bufev);
2336 			bufferevent_free(f->f_un.f_forw.f_bufev);
2337 			/* FALLTHROUGH */
2338 		case F_FILE:
2339 		case F_TTY:
2340 		case F_CONSOLE:
2341 		case F_PIPE:
2342 			(void)close(f->f_file);
2343 			break;
2344 		}
2345 		free(f->f_program);
2346 		free(f->f_hostname);
2347 		if (f->f_type == F_MEMBUF) {
2348 			f->f_program = NULL;
2349 			f->f_hostname = NULL;
2350 			logdebug("add %p to mb\n", f);
2351 			SIMPLEQ_INSERT_HEAD(&mb, f, f_next);
2352 		} else
2353 			free(f);
2354 	}
2355 	SIMPLEQ_INIT(&Files);
2356 
2357 	/* open the configuration file */
2358 	if ((cf = priv_open_config()) == NULL) {
2359 		logdebug("cannot open %s\n", ConfFile);
2360 		SIMPLEQ_INSERT_TAIL(&Files,
2361 		    cfline("*.ERR\t/dev/console", "*", "*"), f_next);
2362 		SIMPLEQ_INSERT_TAIL(&Files,
2363 		    cfline("*.PANIC\t*", "*", "*"), f_next);
2364 		Initialized = 1;
2365 		return;
2366 	}
2367 
2368 	/*
2369 	 *  Foreach line in the conf table, open that file.
2370 	 */
2371 	cline = NULL;
2372 	s = 0;
2373 	strlcpy(progblock, "*", sizeof(progblock));
2374 	strlcpy(hostblock, "*", sizeof(hostblock));
2375 	while (getline(&cline, &s, cf) != -1) {
2376 		/*
2377 		 * check for end-of-section, comments, strip off trailing
2378 		 * spaces and newline character. !progblock and +hostblock
2379 		 * are treated specially: the following lines apply only to
2380 		 * that program.
2381 		 */
2382 		for (p = cline; isspace((unsigned char)*p); ++p)
2383 			continue;
2384 		if (*p == '\0' || *p == '#')
2385 			continue;
2386 		if (*p == '!' || *p == '+') {
2387 			q = (*p == '!') ? progblock : hostblock;
2388 			p++;
2389 			while (isspace((unsigned char)*p))
2390 				p++;
2391 			if (*p == '\0' || (*p == '*' && (p[1] == '\0' ||
2392 			    isspace((unsigned char)p[1])))) {
2393 				strlcpy(q, "*", NAME_MAX+1);
2394 				continue;
2395 			}
2396 			for (i = 0; i < NAME_MAX; i++) {
2397 				if (*p == '\0' || isspace((unsigned char)*p))
2398 					break;
2399 				*q++ = *p++;
2400 			}
2401 			*q = '\0';
2402 			continue;
2403 		}
2404 
2405 		p = cline + strlen(cline);
2406 		while (p > cline)
2407 			if (!isspace((unsigned char)*--p)) {
2408 				p++;
2409 				break;
2410 			}
2411 		*p = '\0';
2412 		f = cfline(cline, progblock, hostblock);
2413 		if (f != NULL)
2414 			SIMPLEQ_INSERT_TAIL(&Files, f, f_next);
2415 	}
2416 	free(cline);
2417 	if (!feof(cf)) {
2418 		logerror("Unable to read config file");
2419 		die(0);
2420 	}
2421 
2422 	/* Match and initialize the memory buffers */
2423 	SIMPLEQ_FOREACH(f, &Files, f_next) {
2424 		if (f->f_type != F_MEMBUF)
2425 			continue;
2426 		logdebug("Initialize membuf %s at %p\n",
2427 		    f->f_un.f_mb.f_mname, f);
2428 
2429 		SIMPLEQ_FOREACH(m, &mb, f_next) {
2430 			if (m->f_un.f_mb.f_rb == NULL)
2431 				continue;
2432 			if (strcmp(m->f_un.f_mb.f_mname,
2433 			    f->f_un.f_mb.f_mname) == 0)
2434 				break;
2435 		}
2436 		if (m == NULL) {
2437 			logdebug("Membuf no match\n");
2438 			f->f_un.f_mb.f_rb = ringbuf_init(f->f_un.f_mb.f_len);
2439 			if (f->f_un.f_mb.f_rb == NULL) {
2440 				f->f_type = F_UNUSED;
2441 				logerror("Failed to allocate membuf");
2442 			}
2443 		} else {
2444 			logdebug("Membuf match f:%p, m:%p\n", f, m);
2445 			f->f_un = m->f_un;
2446 			m->f_un.f_mb.f_rb = NULL;
2447 		}
2448 	}
2449 
2450 	/* make sure remaining buffers are freed */
2451 	while (!SIMPLEQ_EMPTY(&mb)) {
2452 		m = SIMPLEQ_FIRST(&mb);
2453 		SIMPLEQ_REMOVE_HEAD(&mb, f_next);
2454 		if (m->f_un.f_mb.f_rb != NULL) {
2455 			logerrorx("Mismatched membuf");
2456 			ringbuf_free(m->f_un.f_mb.f_rb);
2457 		}
2458 		logdebug("Freeing membuf %p\n", m);
2459 
2460 		free(m);
2461 	}
2462 
2463 	/* close the configuration file */
2464 	(void)fclose(cf);
2465 
2466 	Initialized = 1;
2467 
2468 	if (Debug) {
2469 		SIMPLEQ_FOREACH(f, &Files, f_next) {
2470 			for (i = 0; i <= LOG_NFACILITIES; i++)
2471 				if (f->f_pmask[i] == INTERNAL_NOPRI)
2472 					printf("X ");
2473 				else
2474 					printf("%d ", f->f_pmask[i]);
2475 			printf("%s: ", TypeNames[f->f_type]);
2476 			switch (f->f_type) {
2477 			case F_FILE:
2478 			case F_TTY:
2479 			case F_CONSOLE:
2480 			case F_PIPE:
2481 				printf("%s", f->f_un.f_fname);
2482 				break;
2483 
2484 			case F_FORWUDP:
2485 			case F_FORWTCP:
2486 			case F_FORWTLS:
2487 				printf("%s", f->f_un.f_forw.f_loghost);
2488 				break;
2489 
2490 			case F_USERS:
2491 				for (i = 0; i < MAXUNAMES &&
2492 				    *f->f_un.f_uname[i]; i++)
2493 					printf("%s, ", f->f_un.f_uname[i]);
2494 				break;
2495 
2496 			case F_MEMBUF:
2497 				printf("%s", f->f_un.f_mb.f_mname);
2498 				break;
2499 
2500 			}
2501 			if (f->f_program || f->f_hostname)
2502 				printf(" (%s, %s)",
2503 				    f->f_program ? f->f_program : "*",
2504 				    f->f_hostname ? f->f_hostname : "*");
2505 			printf("\n");
2506 		}
2507 	}
2508 }
2509 
2510 #define progmatches(p1, p2) \
2511 	(p1 == p2 || (p1 != NULL && p2 != NULL && strcmp(p1, p2) == 0))
2512 
2513 /*
2514  * Spot a line with a duplicate file, pipe, console, tty, or membuf target.
2515  */
2516 struct filed *
2517 find_dup(struct filed *f)
2518 {
2519 	struct filed *list;
2520 
2521 	SIMPLEQ_FOREACH(list, &Files, f_next) {
2522 		if (list->f_quick || f->f_quick)
2523 			continue;
2524 		switch (list->f_type) {
2525 		case F_FILE:
2526 		case F_TTY:
2527 		case F_CONSOLE:
2528 		case F_PIPE:
2529 			if (strcmp(list->f_un.f_fname, f->f_un.f_fname) == 0 &&
2530 			    progmatches(list->f_program, f->f_program) &&
2531 			    progmatches(list->f_hostname, f->f_hostname)) {
2532 				logdebug("duplicate %s\n", f->f_un.f_fname);
2533 				return (list);
2534 			}
2535 			break;
2536 		case F_MEMBUF:
2537 			if (strcmp(list->f_un.f_mb.f_mname,
2538 			    f->f_un.f_mb.f_mname) == 0 &&
2539 			    progmatches(list->f_program, f->f_program) &&
2540 			    progmatches(list->f_hostname, f->f_hostname)) {
2541 				logdebug("duplicate membuf %s\n",
2542 				    f->f_un.f_mb.f_mname);
2543 				return (list);
2544 			}
2545 			break;
2546 		}
2547 	}
2548 	return (NULL);
2549 }
2550 
2551 /*
2552  * Crack a configuration file line
2553  */
2554 struct filed *
2555 cfline(char *line, char *progblock, char *hostblock)
2556 {
2557 	int i, pri;
2558 	size_t rb_len;
2559 	char *bp, *p, *q, *proto, *host, *port, *ipproto;
2560 	char buf[MAXLINE], ebuf[ERRBUFSIZE];
2561 	struct filed *xf, *f, *d;
2562 	struct timeval to;
2563 
2564 	logdebug("cfline(\"%s\", f, \"%s\", \"%s\")\n",
2565 	    line, progblock, hostblock);
2566 
2567 	if ((f = calloc(1, sizeof(*f))) == NULL) {
2568 		logerror("Couldn't allocate struct filed");
2569 		die(0);
2570 	}
2571 	for (i = 0; i <= LOG_NFACILITIES; i++)
2572 		f->f_pmask[i] = INTERNAL_NOPRI;
2573 
2574 	/* save program name if any */
2575 	f->f_quick = 0;
2576 	if (*progblock == '!') {
2577 		progblock++;
2578 		f->f_quick = 1;
2579 	}
2580 	if (*hostblock == '+') {
2581 		hostblock++;
2582 		f->f_quick = 1;
2583 	}
2584 	if (strcmp(progblock, "*") != 0)
2585 		f->f_program = strdup(progblock);
2586 	if (strcmp(hostblock, "*") != 0)
2587 		f->f_hostname = strdup(hostblock);
2588 
2589 	/* scan through the list of selectors */
2590 	for (p = line; *p && *p != '\t' && *p != ' ';) {
2591 
2592 		/* find the end of this facility name list */
2593 		for (q = p; *q && *q != '\t' && *q != ' ' && *q++ != '.'; )
2594 			continue;
2595 
2596 		/* collect priority name */
2597 		for (bp = buf; *q && !strchr("\t,; ", *q); )
2598 			*bp++ = *q++;
2599 		*bp = '\0';
2600 
2601 		/* skip cruft */
2602 		while (*q && strchr(",;", *q))
2603 			q++;
2604 
2605 		/* decode priority name */
2606 		if (*buf == '*')
2607 			pri = LOG_PRIMASK + 1;
2608 		else {
2609 			/* ignore trailing spaces */
2610 			for (i=strlen(buf)-1; i >= 0 && buf[i] == ' '; i--) {
2611 				buf[i]='\0';
2612 			}
2613 
2614 			pri = decode(buf, prioritynames);
2615 			if (pri < 0) {
2616 				(void)snprintf(ebuf, sizeof ebuf,
2617 				    "unknown priority name \"%s\"", buf);
2618 				logerrorx(ebuf);
2619 				free(f);
2620 				return (NULL);
2621 			}
2622 		}
2623 
2624 		/* scan facilities */
2625 		while (*p && !strchr("\t.; ", *p)) {
2626 			for (bp = buf; *p && !strchr("\t,;. ", *p); )
2627 				*bp++ = *p++;
2628 			*bp = '\0';
2629 			if (*buf == '*')
2630 				for (i = 0; i < LOG_NFACILITIES; i++)
2631 					f->f_pmask[i] = pri;
2632 			else {
2633 				i = decode(buf, facilitynames);
2634 				if (i < 0) {
2635 					(void)snprintf(ebuf, sizeof(ebuf),
2636 					    "unknown facility name \"%s\"",
2637 					    buf);
2638 					logerrorx(ebuf);
2639 					free(f);
2640 					return (NULL);
2641 				}
2642 				f->f_pmask[i >> 3] = pri;
2643 			}
2644 			while (*p == ',' || *p == ' ')
2645 				p++;
2646 		}
2647 
2648 		p = q;
2649 	}
2650 
2651 	/* skip to action part */
2652 	while (*p == '\t' || *p == ' ')
2653 		p++;
2654 
2655 	switch (*p) {
2656 	case '@':
2657 		if ((strlcpy(f->f_un.f_forw.f_loghost, p,
2658 		    sizeof(f->f_un.f_forw.f_loghost)) >=
2659 		    sizeof(f->f_un.f_forw.f_loghost))) {
2660 			snprintf(ebuf, sizeof(ebuf), "loghost too long \"%s\"",
2661 			    p);
2662 			logerrorx(ebuf);
2663 			break;
2664 		}
2665 		if (loghost_parse(++p, &proto, &host, &port) == -1) {
2666 			snprintf(ebuf, sizeof(ebuf), "bad loghost \"%s\"",
2667 			    f->f_un.f_forw.f_loghost);
2668 			logerrorx(ebuf);
2669 			break;
2670 		}
2671 		if (proto == NULL)
2672 			proto = "udp";
2673 		ipproto = proto;
2674 		if (strcmp(proto, "udp") == 0) {
2675 			if (fd_udp == -1)
2676 				proto = "udp6";
2677 			if (fd_udp6 == -1)
2678 				proto = "udp4";
2679 			ipproto = proto;
2680 		} else if (strcmp(proto, "udp4") == 0) {
2681 			if (fd_udp == -1) {
2682 				snprintf(ebuf, sizeof(ebuf), "no udp4 \"%s\"",
2683 				    f->f_un.f_forw.f_loghost);
2684 				logerrorx(ebuf);
2685 				break;
2686 			}
2687 		} else if (strcmp(proto, "udp6") == 0) {
2688 			if (fd_udp6 == -1) {
2689 				snprintf(ebuf, sizeof(ebuf), "no udp6 \"%s\"",
2690 				    f->f_un.f_forw.f_loghost);
2691 				logerrorx(ebuf);
2692 				break;
2693 			}
2694 		} else if (strcmp(proto, "tcp") == 0 ||
2695 		    strcmp(proto, "tcp4") == 0 || strcmp(proto, "tcp6") == 0) {
2696 			;
2697 		} else if (strcmp(proto, "tls") == 0) {
2698 			ipproto = "tcp";
2699 		} else if (strcmp(proto, "tls4") == 0) {
2700 			ipproto = "tcp4";
2701 		} else if (strcmp(proto, "tls6") == 0) {
2702 			ipproto = "tcp6";
2703 		} else {
2704 			snprintf(ebuf, sizeof(ebuf), "bad protocol \"%s\"",
2705 			    f->f_un.f_forw.f_loghost);
2706 			logerrorx(ebuf);
2707 			break;
2708 		}
2709 		if (strlen(host) >= NI_MAXHOST) {
2710 			snprintf(ebuf, sizeof(ebuf), "host too long \"%s\"",
2711 			    f->f_un.f_forw.f_loghost);
2712 			logerrorx(ebuf);
2713 			break;
2714 		}
2715 		if (port == NULL)
2716 			port = strncmp(proto, "tls", 3) == 0 ?
2717 			    "syslog-tls" : "syslog";
2718 		if (strlen(port) >= NI_MAXSERV) {
2719 			snprintf(ebuf, sizeof(ebuf), "port too long \"%s\"",
2720 			    f->f_un.f_forw.f_loghost);
2721 			logerrorx(ebuf);
2722 			break;
2723 		}
2724 		if (priv_getaddrinfo(ipproto, host, port,
2725 		    (struct sockaddr*)&f->f_un.f_forw.f_addr,
2726 		    sizeof(f->f_un.f_forw.f_addr)) != 0) {
2727 			snprintf(ebuf, sizeof(ebuf), "bad hostname \"%s\"",
2728 			    f->f_un.f_forw.f_loghost);
2729 			logerrorx(ebuf);
2730 			break;
2731 		}
2732 		f->f_file = -1;
2733 		if (strncmp(proto, "udp", 3) == 0) {
2734 			switch (f->f_un.f_forw.f_addr.ss_family) {
2735 			case AF_INET:
2736 				f->f_file = fd_udp;
2737 				break;
2738 			case AF_INET6:
2739 				f->f_file = fd_udp6;
2740 				break;
2741 			}
2742 			f->f_type = F_FORWUDP;
2743 		} else if (strncmp(ipproto, "tcp", 3) == 0) {
2744 			if ((f->f_un.f_forw.f_bufev = bufferevent_new(-1,
2745 			    tcp_dropcb, tcp_writecb, tcp_errorcb, f)) == NULL) {
2746 				snprintf(ebuf, sizeof(ebuf),
2747 				    "bufferevent \"%s\"",
2748 				    f->f_un.f_forw.f_loghost);
2749 				logerror(ebuf);
2750 				break;
2751 			}
2752 			if (strncmp(proto, "tls", 3) == 0) {
2753 				f->f_un.f_forw.f_host = strdup(host);
2754 				f->f_type = F_FORWTLS;
2755 			} else {
2756 				f->f_type = F_FORWTCP;
2757 			}
2758 			/*
2759 			 * If we try to connect to a TLS server immediately
2760 			 * syslogd gets an SIGPIPE as the signal handlers have
2761 			 * not been set up.  Delay the connection until the
2762 			 * event loop is started.  We can reuse the write event
2763 			 * for that as bufferevent is still disabled.
2764 			 */
2765 			to.tv_sec = 0;
2766 			to.tv_usec = 1;
2767 			evtimer_set(&f->f_un.f_forw.f_bufev->ev_write,
2768 			    tcp_connectcb, f);
2769 			evtimer_add(&f->f_un.f_forw.f_bufev->ev_write, &to);
2770 		}
2771 		break;
2772 
2773 	case '/':
2774 	case '|':
2775 		(void)strlcpy(f->f_un.f_fname, p, sizeof(f->f_un.f_fname));
2776 		d = find_dup(f);
2777 		if (d != NULL) {
2778 			for (i = 0; i <= LOG_NFACILITIES; i++)
2779 				if (f->f_pmask[i] != INTERNAL_NOPRI)
2780 					d->f_pmask[i] = f->f_pmask[i];
2781 			free(f);
2782 			return (NULL);
2783 		}
2784 		if (strcmp(p, ctty) == 0)
2785 			f->f_file = priv_open_tty(p);
2786 		else
2787 			f->f_file = priv_open_log(p);
2788 		if (f->f_file < 0) {
2789 			f->f_type = F_UNUSED;
2790 			logerror(p);
2791 			break;
2792 		}
2793 		if (isatty(f->f_file)) {
2794 			if (strcmp(p, ctty) == 0)
2795 				f->f_type = F_CONSOLE;
2796 			else
2797 				f->f_type = F_TTY;
2798 		} else {
2799 			if (*p == '|')
2800 				f->f_type = F_PIPE;
2801 			else {
2802 				f->f_type = F_FILE;
2803 
2804 				/* Clear O_NONBLOCK flag on f->f_file */
2805 				if ((i = fcntl(f->f_file, F_GETFL)) != -1) {
2806 					i &= ~O_NONBLOCK;
2807 					fcntl(f->f_file, F_SETFL, i);
2808 				}
2809 			}
2810 		}
2811 		break;
2812 
2813 	case '*':
2814 		f->f_type = F_WALL;
2815 		break;
2816 
2817 	case ':':
2818 		f->f_type = F_MEMBUF;
2819 
2820 		/* Parse buffer size (in kb) */
2821 		errno = 0;
2822 		rb_len = strtoul(++p, &q, 0);
2823 		if (*p == '\0' || (errno == ERANGE && rb_len == ULONG_MAX) ||
2824 		    *q != ':' || rb_len == 0) {
2825 			f->f_type = F_UNUSED;
2826 			logerror(p);
2827 			break;
2828 		}
2829 		q++;
2830 		rb_len *= 1024;
2831 
2832 		/* Copy buffer name */
2833 		for(i = 0; (size_t)i < sizeof(f->f_un.f_mb.f_mname) - 1; i++) {
2834 			if (!isalnum((unsigned char)q[i]))
2835 				break;
2836 			f->f_un.f_mb.f_mname[i] = q[i];
2837 		}
2838 
2839 		/* Make sure buffer name is unique */
2840 		xf = find_dup(f);
2841 
2842 		/* Error on missing or non-unique name, or bad buffer length */
2843 		if (i == 0 || rb_len > MAX_MEMBUF || xf != NULL) {
2844 			f->f_type = F_UNUSED;
2845 			logerrorx(p);
2846 			break;
2847 		}
2848 
2849 		/* Set buffer length */
2850 		rb_len = MAXIMUM(rb_len, MIN_MEMBUF);
2851 		f->f_un.f_mb.f_len = rb_len;
2852 		f->f_un.f_mb.f_overflow = 0;
2853 		f->f_un.f_mb.f_attached = 0;
2854 		break;
2855 
2856 	default:
2857 		for (i = 0; i < MAXUNAMES && *p; i++) {
2858 			for (q = p; *q && *q != ','; )
2859 				q++;
2860 			(void)strncpy(f->f_un.f_uname[i], p, UT_NAMESIZE);
2861 			if ((q - p) > UT_NAMESIZE)
2862 				f->f_un.f_uname[i][UT_NAMESIZE] = '\0';
2863 			else
2864 				f->f_un.f_uname[i][q - p] = '\0';
2865 			while (*q == ',' || *q == ' ')
2866 				q++;
2867 			p = q;
2868 		}
2869 		f->f_type = F_USERS;
2870 		break;
2871 	}
2872 	return (f);
2873 }
2874 
2875 /*
2876  * Parse the host and port parts from a loghost string.
2877  */
2878 int
2879 loghost_parse(char *str, char **proto, char **host, char **port)
2880 {
2881 	char *prefix = NULL;
2882 
2883 	if ((*host = strchr(str, ':')) &&
2884 	    (*host)[1] == '/' && (*host)[2] == '/') {
2885 		prefix = str;
2886 		**host = '\0';
2887 		str = *host + 3;
2888 	}
2889 	if (proto)
2890 		*proto = prefix;
2891 	else if (prefix)
2892 		return (-1);
2893 
2894 	*host = str;
2895 	if (**host == '[') {
2896 		(*host)++;
2897 		str = strchr(*host, ']');
2898 		if (str == NULL)
2899 			return (-1);
2900 		*str++ = '\0';
2901 	}
2902 	*port = strrchr(str, ':');
2903 	if (*port != NULL)
2904 		*(*port)++ = '\0';
2905 
2906 	return (0);
2907 }
2908 
2909 /*
2910  * Retrieve the size of the kernel message buffer, via sysctl.
2911  */
2912 int
2913 getmsgbufsize(void)
2914 {
2915 	int msgbufsize, mib[2];
2916 	size_t size;
2917 
2918 	mib[0] = CTL_KERN;
2919 	mib[1] = KERN_MSGBUFSIZE;
2920 	size = sizeof msgbufsize;
2921 	if (sysctl(mib, 2, &msgbufsize, &size, NULL, 0) == -1) {
2922 		logdebug("couldn't get kern.msgbufsize\n");
2923 		return (0);
2924 	}
2925 	return (msgbufsize);
2926 }
2927 
2928 /*
2929  *  Decode a symbolic name to a numeric value
2930  */
2931 int
2932 decode(const char *name, const CODE *codetab)
2933 {
2934 	const CODE *c;
2935 	char *p, buf[40];
2936 
2937 	for (p = buf; *name && p < &buf[sizeof(buf) - 1]; p++, name++) {
2938 		if (isupper((unsigned char)*name))
2939 			*p = tolower((unsigned char)*name);
2940 		else
2941 			*p = *name;
2942 	}
2943 	*p = '\0';
2944 	for (c = codetab; c->c_name; c++)
2945 		if (!strcmp(buf, c->c_name))
2946 			return (c->c_val);
2947 
2948 	return (-1);
2949 }
2950 
2951 void
2952 markit(void)
2953 {
2954 	struct filed *f;
2955 
2956 	(void)gettimeofday(&now, NULL);
2957 	MarkSeq += TIMERINTVL;
2958 	if (MarkSeq >= MarkInterval) {
2959 		logmsg(LOG_INFO, "-- MARK --",
2960 		    LocalHostName, ADDDATE|MARK);
2961 		MarkSeq = 0;
2962 	}
2963 
2964 	SIMPLEQ_FOREACH(f, &Files, f_next) {
2965 		if (f->f_prevcount && now.tv_sec >= REPEATTIME(f)) {
2966 			logdebug("flush %s: repeated %d times, %d sec.\n",
2967 			    TypeNames[f->f_type], f->f_prevcount,
2968 			    repeatinterval[f->f_repeatcount]);
2969 			fprintlog(f, 0, (char *)NULL);
2970 			BACKOFF(f);
2971 		}
2972 	}
2973 }
2974 
2975 int
2976 unix_socket(char *path, int type, mode_t mode)
2977 {
2978 	struct sockaddr_un s_un;
2979 	char ebuf[512];
2980 	int fd, optval;
2981 	mode_t old_umask;
2982 
2983 	memset(&s_un, 0, sizeof(s_un));
2984 	s_un.sun_family = AF_UNIX;
2985 	if (strlcpy(s_un.sun_path, path, sizeof(s_un.sun_path)) >=
2986 	    sizeof(s_un.sun_path)) {
2987 		snprintf(ebuf, sizeof(ebuf), "socket path too long: %s", path);
2988 		logerrorx(ebuf);
2989 		die(0);
2990 	}
2991 
2992 	if ((fd = socket(AF_UNIX, type, 0)) == -1) {
2993 		logerror("socket");
2994 		return (-1);
2995 	}
2996 
2997 	if (Debug) {
2998 		if (connect(fd, (struct sockaddr *)&s_un, sizeof(s_un)) == 0 ||
2999 		    errno == EPROTOTYPE) {
3000 			close(fd);
3001 			errno = EISCONN;
3002 			logerror("connect");
3003 			return (-1);
3004 		}
3005 	}
3006 
3007 	old_umask = umask(0177);
3008 
3009 	unlink(path);
3010 	if (bind(fd, (struct sockaddr *)&s_un, sizeof(s_un)) == -1) {
3011 		snprintf(ebuf, sizeof(ebuf), "cannot bind %s", path);
3012 		logerror(ebuf);
3013 		umask(old_umask);
3014 		close(fd);
3015 		return (-1);
3016 	}
3017 
3018 	umask(old_umask);
3019 
3020 	if (chmod(path, mode) == -1) {
3021 		snprintf(ebuf, sizeof(ebuf), "cannot chmod %s", path);
3022 		logerror(ebuf);
3023 		close(fd);
3024 		unlink(path);
3025 		return (-1);
3026 	}
3027 
3028 	optval = MAXLINE + PATH_MAX;
3029 	if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &optval, sizeof(optval))
3030 	    == -1)
3031 		logerror("setsockopt unix");
3032 
3033 	return (fd);
3034 }
3035 
3036 void
3037 double_sockbuf(int fd, int optname)
3038 {
3039 	socklen_t len;
3040 	int i, newsize, oldsize = 0;
3041 
3042 	len = sizeof(oldsize);
3043 	if (getsockopt(fd, SOL_SOCKET, optname, &oldsize, &len) == -1)
3044 		logerror("getsockopt bufsize");
3045 	len = sizeof(newsize);
3046 	newsize =  MAXLINE + 128;  /* data + control */
3047 	/* allow 8 full length messages */
3048 	for (i = 0; i < 4; i++, newsize *= 2) {
3049 		if (newsize <= oldsize)
3050 			continue;
3051 		if (setsockopt(fd, SOL_SOCKET, optname, &newsize, len) == -1)
3052 			logerror("setsockopt bufsize");
3053 	}
3054 }
3055 
3056 void
3057 set_sockbuf(int fd)
3058 {
3059 	int size = 65536;
3060 
3061 	if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)) == -1)
3062 		logerror("setsockopt sndbufsize");
3063 	if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)) == -1)
3064 		logerror("setsockopt rcvbufsize");
3065 }
3066 
3067 void
3068 ctlconn_cleanup(void)
3069 {
3070 	struct filed *f;
3071 
3072 	if (close(fd_ctlconn) == -1)
3073 		logerror("close ctlconn");
3074 	fd_ctlconn = -1;
3075 	event_del(ev_ctlread);
3076 	event_del(ev_ctlwrite);
3077 	event_add(ev_ctlaccept, NULL);
3078 
3079 	if (ctl_state == CTL_WRITING_CONT_REPLY)
3080 		SIMPLEQ_FOREACH(f, &Files, f_next)
3081 			if (f->f_type == F_MEMBUF)
3082 				f->f_un.f_mb.f_attached = 0;
3083 
3084 	ctl_state = ctl_cmd_bytes = ctl_reply_offset = ctl_reply_size = 0;
3085 }
3086 
3087 void
3088 ctlsock_acceptcb(int fd, short event, void *arg)
3089 {
3090 	struct event		*ev = arg;
3091 
3092 	if ((fd = reserve_accept4(fd, event, ev, ctlsock_acceptcb,
3093 	    NULL, NULL, SOCK_NONBLOCK)) == -1) {
3094 		if (errno != ENFILE && errno != EMFILE &&
3095 		    errno != EINTR && errno != EWOULDBLOCK &&
3096 		    errno != ECONNABORTED)
3097 			logerror("accept ctlsock");
3098 		return;
3099 	}
3100 	logdebug("Accepting control connection\n");
3101 
3102 	if (fd_ctlconn != -1)
3103 		ctlconn_cleanup();
3104 
3105 	/* Only one connection at a time */
3106 	event_del(ev);
3107 
3108 	fd_ctlconn = fd;
3109 	/* file descriptor has changed, reset event */
3110 	event_set(ev_ctlread, fd_ctlconn, EV_READ|EV_PERSIST,
3111 	    ctlconn_readcb, ev_ctlread);
3112 	event_set(ev_ctlwrite, fd_ctlconn, EV_WRITE|EV_PERSIST,
3113 	    ctlconn_writecb, ev_ctlwrite);
3114 	event_add(ev_ctlread, NULL);
3115 	ctl_state = CTL_READING_CMD;
3116 	ctl_cmd_bytes = 0;
3117 }
3118 
3119 static struct filed
3120 *find_membuf_log(const char *name)
3121 {
3122 	struct filed *f;
3123 
3124 	SIMPLEQ_FOREACH(f, &Files, f_next) {
3125 		if (f->f_type == F_MEMBUF &&
3126 		    strcmp(f->f_un.f_mb.f_mname, name) == 0)
3127 			break;
3128 	}
3129 	return (f);
3130 }
3131 
3132 void
3133 ctlconn_readcb(int fd, short event, void *arg)
3134 {
3135 	struct filed		*f;
3136 	struct ctl_reply_hdr	*reply_hdr = (struct ctl_reply_hdr *)ctl_reply;
3137 	ssize_t			 n;
3138 	u_int32_t		 flags = 0;
3139 
3140 	if (ctl_state == CTL_WRITING_REPLY ||
3141 	    ctl_state == CTL_WRITING_CONT_REPLY) {
3142 		/* client has closed the connection */
3143 		ctlconn_cleanup();
3144 		return;
3145 	}
3146 
3147  retry:
3148 	n = read(fd, (char*)&ctl_cmd + ctl_cmd_bytes,
3149 	    sizeof(ctl_cmd) - ctl_cmd_bytes);
3150 	switch (n) {
3151 	case -1:
3152 		if (errno == EINTR)
3153 			goto retry;
3154 		if (errno == EWOULDBLOCK)
3155 			return;
3156 		logerror("ctlconn read");
3157 		/* FALLTHROUGH */
3158 	case 0:
3159 		ctlconn_cleanup();
3160 		return;
3161 	default:
3162 		ctl_cmd_bytes += n;
3163 	}
3164 	if (ctl_cmd_bytes < sizeof(ctl_cmd))
3165 		return;
3166 
3167 	if (ntohl(ctl_cmd.version) != CTL_VERSION) {
3168 		logerrorx("Unknown client protocol version");
3169 		ctlconn_cleanup();
3170 		return;
3171 	}
3172 
3173 	/* Ensure that logname is \0 terminated */
3174 	if (memchr(ctl_cmd.logname, '\0', sizeof(ctl_cmd.logname)) == NULL) {
3175 		logerrorx("Corrupt ctlsock command");
3176 		ctlconn_cleanup();
3177 		return;
3178 	}
3179 
3180 	*reply_text = '\0';
3181 
3182 	ctl_reply_size = ctl_reply_offset = 0;
3183 	memset(reply_hdr, '\0', sizeof(*reply_hdr));
3184 
3185 	ctl_cmd.cmd = ntohl(ctl_cmd.cmd);
3186 	logdebug("ctlcmd %x logname \"%s\"\n", ctl_cmd.cmd, ctl_cmd.logname);
3187 
3188 	switch (ctl_cmd.cmd) {
3189 	case CMD_READ:
3190 	case CMD_READ_CLEAR:
3191 	case CMD_READ_CONT:
3192 	case CMD_FLAGS:
3193 		f = find_membuf_log(ctl_cmd.logname);
3194 		if (f == NULL) {
3195 			strlcpy(reply_text, "No such log\n", MAX_MEMBUF);
3196 		} else {
3197 			if (ctl_cmd.cmd != CMD_FLAGS) {
3198 				ringbuf_to_string(reply_text, MAX_MEMBUF,
3199 				    f->f_un.f_mb.f_rb);
3200 			}
3201 			if (f->f_un.f_mb.f_overflow)
3202 				flags |= CTL_HDR_FLAG_OVERFLOW;
3203 			if (ctl_cmd.cmd == CMD_READ_CLEAR) {
3204 				ringbuf_clear(f->f_un.f_mb.f_rb);
3205 				f->f_un.f_mb.f_overflow = 0;
3206 			}
3207 			if (ctl_cmd.cmd == CMD_READ_CONT) {
3208 				f->f_un.f_mb.f_attached = 1;
3209 				tailify_replytext(reply_text,
3210 				    ctl_cmd.lines > 0 ? ctl_cmd.lines : 10);
3211 			} else if (ctl_cmd.lines > 0) {
3212 				tailify_replytext(reply_text, ctl_cmd.lines);
3213 			}
3214 		}
3215 		break;
3216 	case CMD_CLEAR:
3217 		f = find_membuf_log(ctl_cmd.logname);
3218 		if (f == NULL) {
3219 			strlcpy(reply_text, "No such log\n", MAX_MEMBUF);
3220 		} else {
3221 			ringbuf_clear(f->f_un.f_mb.f_rb);
3222 			if (f->f_un.f_mb.f_overflow)
3223 				flags |= CTL_HDR_FLAG_OVERFLOW;
3224 			f->f_un.f_mb.f_overflow = 0;
3225 			strlcpy(reply_text, "Log cleared\n", MAX_MEMBUF);
3226 		}
3227 		break;
3228 	case CMD_LIST:
3229 		SIMPLEQ_FOREACH(f, &Files, f_next) {
3230 			if (f->f_type == F_MEMBUF) {
3231 				strlcat(reply_text, f->f_un.f_mb.f_mname,
3232 				    MAX_MEMBUF);
3233 				if (f->f_un.f_mb.f_overflow) {
3234 					strlcat(reply_text, "*", MAX_MEMBUF);
3235 					flags |= CTL_HDR_FLAG_OVERFLOW;
3236 				}
3237 				strlcat(reply_text, " ", MAX_MEMBUF);
3238 			}
3239 		}
3240 		strlcat(reply_text, "\n", MAX_MEMBUF);
3241 		break;
3242 	default:
3243 		logerrorx("Unsupported ctlsock command");
3244 		ctlconn_cleanup();
3245 		return;
3246 	}
3247 	reply_hdr->version = htonl(CTL_VERSION);
3248 	reply_hdr->flags = htonl(flags);
3249 
3250 	ctl_reply_size = CTL_REPLY_SIZE;
3251 	logdebug("ctlcmd reply length %lu\n", (u_long)ctl_reply_size);
3252 
3253 	/* Otherwise, set up to write out reply */
3254 	ctl_state = (ctl_cmd.cmd == CMD_READ_CONT) ?
3255 	    CTL_WRITING_CONT_REPLY : CTL_WRITING_REPLY;
3256 
3257 	event_add(ev_ctlwrite, NULL);
3258 
3259 	/* another syslogc can kick us out */
3260 	if (ctl_state == CTL_WRITING_CONT_REPLY)
3261 		event_add(ev_ctlaccept, NULL);
3262 }
3263 
3264 void
3265 ctlconn_writecb(int fd, short event, void *arg)
3266 {
3267 	struct event		*ev = arg;
3268 	ssize_t			 n;
3269 
3270 	if (!(ctl_state == CTL_WRITING_REPLY ||
3271 	    ctl_state == CTL_WRITING_CONT_REPLY)) {
3272 		/* Shouldn't be here! */
3273 		logerrorx("ctlconn_write with bad ctl_state");
3274 		ctlconn_cleanup();
3275 		return;
3276 	}
3277 
3278  retry:
3279 	n = write(fd, ctl_reply + ctl_reply_offset,
3280 	    ctl_reply_size - ctl_reply_offset);
3281 	switch (n) {
3282 	case -1:
3283 		if (errno == EINTR)
3284 			goto retry;
3285 		if (errno == EWOULDBLOCK)
3286 			return;
3287 		if (errno != EPIPE)
3288 			logerror("ctlconn write");
3289 		/* FALLTHROUGH */
3290 	case 0:
3291 		ctlconn_cleanup();
3292 		return;
3293 	default:
3294 		ctl_reply_offset += n;
3295 	}
3296 	if (ctl_reply_offset < ctl_reply_size)
3297 		return;
3298 
3299 	if (ctl_state != CTL_WRITING_CONT_REPLY) {
3300 		ctlconn_cleanup();
3301 		return;
3302 	}
3303 
3304 	/*
3305 	 * Make space in the buffer for continous writes.
3306 	 * Set offset behind reply header to skip it
3307 	 */
3308 	*reply_text = '\0';
3309 	ctl_reply_offset = ctl_reply_size = CTL_REPLY_SIZE;
3310 
3311 	/* Now is a good time to report dropped lines */
3312 	if (membuf_drop) {
3313 		strlcat(reply_text, "<ENOBUFS>\n", MAX_MEMBUF);
3314 		ctl_reply_size = CTL_REPLY_SIZE;
3315 		membuf_drop = 0;
3316 	} else {
3317 		/* Nothing left to write */
3318 		event_del(ev);
3319 	}
3320 }
3321 
3322 /* Shorten replytext to number of lines */
3323 void
3324 tailify_replytext(char *replytext, int lines)
3325 {
3326 	char *start, *nl;
3327 	int count = 0;
3328 	start = nl = replytext;
3329 
3330 	while ((nl = strchr(nl, '\n')) != NULL) {
3331 		nl++;
3332 		if (++count > lines) {
3333 			start = strchr(start, '\n');
3334 			start++;
3335 		}
3336 	}
3337 	if (start != replytext) {
3338 		int len = strlen(start);
3339 		memmove(replytext, start, len);
3340 		*(replytext + len) = '\0';
3341 	}
3342 }
3343 
3344 void
3345 ctlconn_logto(char *line)
3346 {
3347 	size_t l;
3348 
3349 	if (membuf_drop)
3350 		return;
3351 
3352 	l = strlen(line);
3353 	if (l + 2 > (CTL_REPLY_MAXSIZE - ctl_reply_size)) {
3354 		/* remember line drops for later report */
3355 		membuf_drop = 1;
3356 		return;
3357 	}
3358 	memcpy(ctl_reply + ctl_reply_size, line, l);
3359 	memcpy(ctl_reply + ctl_reply_size + l, "\n", 2);
3360 	ctl_reply_size += l + 1;
3361 	event_add(ev_ctlwrite, NULL);
3362 }
3363