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