xref: /openbsd-src/usr.sbin/syslogd/syslogd.c (revision fb8aa7497fded39583f40e800732f9c046411717)
1 /*	$OpenBSD: syslogd.c,v 1.207 2016/07/01 15:47:15 millert 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 if (f->f_lasttime[0] != '\0') {
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 	} else {
1749 		v->iov_base = "";
1750 		v->iov_len = 0;
1751 		v++;
1752 		v->iov_base = "";
1753 		v->iov_len = 0;
1754 		v++;
1755 	}
1756 	if (f->f_prevhost[0] != '\0') {
1757 		v->iov_base = f->f_prevhost;
1758 		v->iov_len = strlen(v->iov_base);
1759 		v++;
1760 		v->iov_base = " ";
1761 		v->iov_len = 1;
1762 		v++;
1763 	} else {
1764 		v->iov_base = "";
1765 		v->iov_len = 0;
1766 		v++;
1767 		v->iov_base = "";
1768 		v->iov_len = 0;
1769 		v++;
1770 	}
1771 
1772 	if (msg) {
1773 		v->iov_base = msg;
1774 		v->iov_len = strlen(msg);
1775 	} else if (f->f_prevcount > 1) {
1776 		l = snprintf(repbuf, sizeof(repbuf),
1777 		    "last message repeated %d times", f->f_prevcount);
1778 		if (l < 0 || (size_t)l >= sizeof(repbuf))
1779 			l = strlen(repbuf);
1780 		v->iov_base = repbuf;
1781 		v->iov_len = l;
1782 	} else {
1783 		v->iov_base = f->f_prevline;
1784 		v->iov_len = f->f_prevlen;
1785 	}
1786 	v++;
1787 
1788 	logdebug("Logging to %s", TypeNames[f->f_type]);
1789 	f->f_time = now;
1790 
1791 	switch (f->f_type) {
1792 	case F_UNUSED:
1793 		logdebug("\n");
1794 		break;
1795 
1796 	case F_FORWUDP:
1797 		logdebug(" %s\n", f->f_un.f_forw.f_loghost);
1798 		l = snprintf(line, MINIMUM(MAX_UDPMSG + 1, sizeof(line)),
1799 		    "<%d>%.15s %s%s%s", f->f_prevpri, (char *)iov[0].iov_base,
1800 		    IncludeHostname ? LocalHostName : "",
1801 		    IncludeHostname ? " " : "",
1802 		    (char *)iov[4].iov_base);
1803 		if (l < 0 || (size_t)l > MINIMUM(MAX_UDPMSG, sizeof(line)))
1804 			l = MINIMUM(MAX_UDPMSG, sizeof(line));
1805 		if (sendto(f->f_file, line, l, 0,
1806 		    (struct sockaddr *)&f->f_un.f_forw.f_addr,
1807 		    f->f_un.f_forw.f_addr.ss_len) != l) {
1808 			switch (errno) {
1809 			case EHOSTDOWN:
1810 			case EHOSTUNREACH:
1811 			case ENETDOWN:
1812 			case ENETUNREACH:
1813 			case ENOBUFS:
1814 			case EWOULDBLOCK:
1815 				/* silently dropped */
1816 				break;
1817 			default:
1818 				f->f_type = F_UNUSED;
1819 				logerror("sendto");
1820 				break;
1821 			}
1822 		}
1823 		break;
1824 
1825 	case F_FORWTCP:
1826 	case F_FORWTLS:
1827 		logdebug(" %s", f->f_un.f_forw.f_loghost);
1828 		if (EVBUFFER_LENGTH(f->f_un.f_forw.f_bufev->output) >=
1829 		    MAX_TCPBUF) {
1830 			logdebug(" (dropped)\n");
1831 			f->f_un.f_forw.f_dropped++;
1832 			break;
1833 		}
1834 		/*
1835 		 * Syslog over TLS  RFC 5425  4.3.  Sending Data
1836 		 * Syslog over TCP  RFC 6587  3.4.1.  Octet Counting
1837 		 * Use an additional '\n' to split messages.  This allows
1838 		 * buffer synchronisation, helps legacy implementations,
1839 		 * and makes line based testing easier.
1840 		 */
1841 		l = snprintf(line, sizeof(line), "<%d>%.15s %s%s\n",
1842 		    f->f_prevpri, (char *)iov[0].iov_base,
1843 		    IncludeHostname ? LocalHostName : "",
1844 		    IncludeHostname ? " " : "");
1845 		if (l < 0) {
1846 			logdebug(" (dropped snprintf)\n");
1847 			f->f_un.f_forw.f_dropped++;
1848 			break;
1849 		}
1850 		l = evbuffer_add_printf(f->f_un.f_forw.f_bufev->output,
1851 		    "%zu <%d>%.15s %s%s%s\n",
1852 		    (size_t)l + strlen(iov[4].iov_base),
1853 		    f->f_prevpri, (char *)iov[0].iov_base,
1854 		    IncludeHostname ? LocalHostName : "",
1855 		    IncludeHostname ? " " : "",
1856 		    (char *)iov[4].iov_base);
1857 		if (l < 0) {
1858 			logdebug(" (dropped evbuffer_add_printf)\n");
1859 			f->f_un.f_forw.f_dropped++;
1860 			break;
1861 		}
1862 		bufferevent_enable(f->f_un.f_forw.f_bufev, EV_WRITE);
1863 		logdebug("\n");
1864 		break;
1865 
1866 	case F_CONSOLE:
1867 		if (flags & IGN_CONS) {
1868 			logdebug(" (ignored)\n");
1869 			break;
1870 		}
1871 		/* FALLTHROUGH */
1872 
1873 	case F_TTY:
1874 	case F_FILE:
1875 	case F_PIPE:
1876 		logdebug(" %s\n", f->f_un.f_fname);
1877 		if (f->f_type != F_FILE && f->f_type != F_PIPE) {
1878 			v->iov_base = "\r\n";
1879 			v->iov_len = 2;
1880 		} else {
1881 			v->iov_base = "\n";
1882 			v->iov_len = 1;
1883 		}
1884 		retryonce = 0;
1885 	again:
1886 		if (writev(f->f_file, iov, 6) < 0) {
1887 			int e = errno;
1888 
1889 			/* pipe is non-blocking. log and drop message if full */
1890 			if (e == EAGAIN && f->f_type == F_PIPE) {
1891 				if (now - f->f_lasterrtime > 120) {
1892 					f->f_lasterrtime = now;
1893 					logerror(f->f_un.f_fname);
1894 				}
1895 				break;
1896 			}
1897 
1898 			(void)close(f->f_file);
1899 			/*
1900 			 * Check for errors on TTY's or program pipes.
1901 			 * Errors happen due to loss of tty or died programs.
1902 			 */
1903 			if (e == EAGAIN) {
1904 				/*
1905 				 * Silently drop messages on blocked write.
1906 				 * This can happen when logging to a locked tty.
1907 				 */
1908 				break;
1909 			} else if ((e == EIO || e == EBADF) &&
1910 			    f->f_type != F_FILE && f->f_type != F_PIPE &&
1911 			    !retryonce) {
1912 				f->f_file = priv_open_tty(f->f_un.f_fname);
1913 				retryonce = 1;
1914 				if (f->f_file < 0) {
1915 					f->f_type = F_UNUSED;
1916 					logerror(f->f_un.f_fname);
1917 				} else
1918 					goto again;
1919 			} else if ((e == EPIPE || e == EBADF) &&
1920 			    f->f_type == F_PIPE && !retryonce) {
1921 				f->f_file = priv_open_log(f->f_un.f_fname);
1922 				retryonce = 1;
1923 				if (f->f_file < 0) {
1924 					f->f_type = F_UNUSED;
1925 					logerror(f->f_un.f_fname);
1926 				} else
1927 					goto again;
1928 			} else {
1929 				f->f_type = F_UNUSED;
1930 				f->f_file = -1;
1931 				errno = e;
1932 				logerror(f->f_un.f_fname);
1933 			}
1934 		} else if (flags & SYNC_FILE)
1935 			(void)fsync(f->f_file);
1936 		break;
1937 
1938 	case F_USERS:
1939 	case F_WALL:
1940 		logdebug("\n");
1941 		v->iov_base = "\r\n";
1942 		v->iov_len = 2;
1943 		wallmsg(f, iov);
1944 		break;
1945 
1946 	case F_MEMBUF:
1947 		logdebug("\n");
1948 		snprintf(line, sizeof(line), "%.15s %s %s",
1949 		    (char *)iov[0].iov_base, (char *)iov[2].iov_base,
1950 		    (char *)iov[4].iov_base);
1951 		if (ringbuf_append_line(f->f_un.f_mb.f_rb, line) == 1)
1952 			f->f_un.f_mb.f_overflow = 1;
1953 		if (f->f_un.f_mb.f_attached)
1954 			ctlconn_logto(line);
1955 		break;
1956 	}
1957 	f->f_prevcount = 0;
1958 }
1959 
1960 /*
1961  *  WALLMSG -- Write a message to the world at large
1962  *
1963  *	Write the specified message to either the entire
1964  *	world, or a list of approved users.
1965  */
1966 void
1967 wallmsg(struct filed *f, struct iovec *iov)
1968 {
1969 	struct utmp ut;
1970 	char utline[sizeof(ut.ut_line) + 1], *p;
1971 	static int reenter;			/* avoid calling ourselves */
1972 	FILE *uf;
1973 	int i;
1974 
1975 	if (reenter++)
1976 		return;
1977 	if ((uf = priv_open_utmp()) == NULL) {
1978 		logerror(_PATH_UTMP);
1979 		reenter = 0;
1980 		return;
1981 	}
1982 	while (fread(&ut, sizeof(ut), 1, uf) == 1) {
1983 		if (ut.ut_name[0] == '\0')
1984 			continue;
1985 		/* must use strncpy since ut_* may not be NUL terminated */
1986 		strncpy(utline, ut.ut_line, sizeof(utline) - 1);
1987 		utline[sizeof(utline) - 1] = '\0';
1988 		if (f->f_type == F_WALL) {
1989 			if ((p = ttymsg(iov, 6, utline)) != NULL)
1990 				logerrorx(p);
1991 			continue;
1992 		}
1993 		/* should we send the message to this user? */
1994 		for (i = 0; i < MAXUNAMES; i++) {
1995 			if (!f->f_un.f_uname[i][0])
1996 				break;
1997 			if (!strncmp(f->f_un.f_uname[i], ut.ut_name,
1998 			    UT_NAMESIZE)) {
1999 				if ((p = ttymsg(iov, 6, utline)) != NULL)
2000 					logerrorx(p);
2001 				break;
2002 			}
2003 		}
2004 	}
2005 	(void)fclose(uf);
2006 	reenter = 0;
2007 }
2008 
2009 /*
2010  * Return a printable representation of a host address.
2011  */
2012 void
2013 cvthname(struct sockaddr *f, char *result, size_t res_len)
2014 {
2015 	if (getnameinfo(f, f->sa_len, result, res_len, NULL, 0,
2016 	    NI_NUMERICHOST|NI_NUMERICSERV|NI_DGRAM) != 0) {
2017 		logdebug("Malformed from address\n");
2018 		strlcpy(result, hostname_unknown, res_len);
2019 		return;
2020 	}
2021 	logdebug("cvthname(%s)\n", result);
2022 	if (NoDNS)
2023 		return;
2024 
2025 	if (priv_getnameinfo(f, f->sa_len, result, res_len) != 0)
2026 		logdebug("Host name for from address (%s) unknown\n", result);
2027 }
2028 
2029 void
2030 die_signalcb(int signum, short event, void *arg)
2031 {
2032 	die(signum);
2033 }
2034 
2035 void
2036 mark_timercb(int unused, short event, void *arg)
2037 {
2038 	struct event		*ev = arg;
2039 	struct timeval		 to;
2040 
2041 	markit();
2042 
2043 	to.tv_sec = TIMERINTVL;
2044 	to.tv_usec = 0;
2045 	evtimer_add(ev, &to);
2046 }
2047 
2048 void
2049 init_signalcb(int signum, short event, void *arg)
2050 {
2051 	char	 ebuf[ERRBUFSIZE];
2052 
2053 	init();
2054 
2055 	logmsg(LOG_SYSLOG|LOG_INFO, "syslogd: restart",
2056 	    LocalHostName, ADDDATE);
2057 	logdebug("syslogd: restarted\n");
2058 
2059 	if (tcpbuf_dropped > 0) {
2060 		snprintf(ebuf, sizeof(ebuf),
2061 		    "syslogd: dropped %d message%s to remote loghost",
2062 		    tcpbuf_dropped, tcpbuf_dropped == 1 ? "" : "s");
2063 		tcpbuf_dropped = 0;
2064 		logmsg(LOG_SYSLOG|LOG_WARNING, ebuf, LocalHostName, ADDDATE);
2065 	}
2066 }
2067 
2068 void
2069 logevent(int severity, const char *msg)
2070 {
2071 	logdebug("libevent: [%d] %s\n", severity, msg);
2072 }
2073 
2074 void
2075 logdebug(const char *fmt, ...)
2076 {
2077 	va_list ap;
2078 
2079 	if (Debug) {
2080 		va_start(ap, fmt);
2081 		vprintf(fmt, ap);
2082 		va_end(ap);
2083 	}
2084 }
2085 
2086 void
2087 logerror(const char *message)
2088 {
2089 	logerror_reason(message, errno ? strerror(errno) : NULL);
2090 }
2091 
2092 void
2093 logerrorx(const char *message)
2094 {
2095 	logerror_reason(message, NULL);
2096 }
2097 
2098 void
2099 logerrorctx(const char *message, struct tls *ctx)
2100 {
2101 	logerror_reason(message, ctx ? tls_error(ctx) : NULL);
2102 }
2103 
2104 void
2105 logerror_reason(const char *message, const char *reason)
2106 {
2107 	char ebuf[ERRBUFSIZE];
2108 
2109 	if (reason)
2110 		(void)snprintf(ebuf, sizeof(ebuf), "syslogd: %s: %s",
2111 		    message, reason);
2112 	else
2113 		(void)snprintf(ebuf, sizeof(ebuf), "syslogd: %s", message);
2114 	errno = 0;
2115 	logdebug("%s\n", ebuf);
2116 	if (Startup)
2117 		fprintf(stderr, "%s\n", ebuf);
2118 	else
2119 		logmsg(LOG_SYSLOG|LOG_ERR, ebuf, LocalHostName, ADDDATE);
2120 }
2121 
2122 void
2123 die(int signo)
2124 {
2125 	struct filed *f;
2126 	int was_initialized = Initialized;
2127 	char ebuf[ERRBUFSIZE];
2128 
2129 	Initialized = 0;		/* Don't log SIGCHLDs */
2130 	SIMPLEQ_FOREACH(f, &Files, f_next) {
2131 		/* flush any pending output */
2132 		if (f->f_prevcount)
2133 			fprintlog(f, 0, (char *)NULL);
2134 		if (f->f_type == F_FORWTLS || f->f_type == F_FORWTCP) {
2135 			tcpbuf_dropped += f->f_un.f_forw.f_dropped +
2136 			    tcpbuf_countmsg(f->f_un.f_forw.f_bufev);
2137 			f->f_un.f_forw.f_dropped = 0;
2138 		}
2139 	}
2140 	Initialized = was_initialized;
2141 
2142 	if (tcpbuf_dropped > 0) {
2143 		snprintf(ebuf, sizeof(ebuf),
2144 		    "syslogd: dropped %d message%s to remote loghost",
2145 		    tcpbuf_dropped, tcpbuf_dropped == 1 ? "" : "s");
2146 		tcpbuf_dropped = 0;
2147 		logmsg(LOG_SYSLOG|LOG_WARNING, ebuf, LocalHostName, ADDDATE);
2148 	}
2149 
2150 	if (signo) {
2151 		logdebug("syslogd: exiting on signal %d\n", signo);
2152 		(void)snprintf(ebuf, sizeof(ebuf), "exiting on signal %d",
2153 		    signo);
2154 		logerrorx(ebuf);
2155 	}
2156 	logdebug("[unpriv] syslogd child about to exit\n");
2157 	exit(0);
2158 }
2159 
2160 /*
2161  *  INIT -- Initialize syslogd from configuration table
2162  */
2163 void
2164 init(void)
2165 {
2166 	char progblock[NAME_MAX+1], hostblock[NAME_MAX+1], *cline, *p, *q;
2167 	struct filed_list mb;
2168 	struct filed *f, *m;
2169 	FILE *cf;
2170 	int i;
2171 	size_t s;
2172 
2173 	logdebug("init\n");
2174 
2175 	/* If config file has been modified, then just die to restart */
2176 	if (priv_config_modified()) {
2177 		logdebug("config file changed: dying\n");
2178 		die(0);
2179 	}
2180 
2181 	/*
2182 	 *  Close all open log files.
2183 	 */
2184 	Initialized = 0;
2185 	SIMPLEQ_INIT(&mb);
2186 	while (!SIMPLEQ_EMPTY(&Files)) {
2187 		f = SIMPLEQ_FIRST(&Files);
2188 		SIMPLEQ_REMOVE_HEAD(&Files, f_next);
2189 		/* flush any pending output */
2190 		if (f->f_prevcount)
2191 			fprintlog(f, 0, (char *)NULL);
2192 
2193 		switch (f->f_type) {
2194 		case F_FORWTLS:
2195 			if (f->f_un.f_forw.f_ctx) {
2196 				tls_close(f->f_un.f_forw.f_ctx);
2197 				tls_free(f->f_un.f_forw.f_ctx);
2198 			}
2199 			free(f->f_un.f_forw.f_host);
2200 			/* FALLTHROUGH */
2201 		case F_FORWTCP:
2202 			tcpbuf_dropped += f->f_un.f_forw.f_dropped +
2203 			     tcpbuf_countmsg(f->f_un.f_forw.f_bufev);
2204 			bufferevent_free(f->f_un.f_forw.f_bufev);
2205 			/* FALLTHROUGH */
2206 		case F_FILE:
2207 		case F_TTY:
2208 		case F_CONSOLE:
2209 		case F_PIPE:
2210 			(void)close(f->f_file);
2211 			break;
2212 		}
2213 		free(f->f_program);
2214 		free(f->f_hostname);
2215 		if (f->f_type == F_MEMBUF) {
2216 			f->f_program = NULL;
2217 			f->f_hostname = NULL;
2218 			logdebug("add %p to mb\n", f);
2219 			SIMPLEQ_INSERT_HEAD(&mb, f, f_next);
2220 		} else
2221 			free(f);
2222 	}
2223 	SIMPLEQ_INIT(&Files);
2224 
2225 	/* open the configuration file */
2226 	if ((cf = priv_open_config()) == NULL) {
2227 		logdebug("cannot open %s\n", ConfFile);
2228 		SIMPLEQ_INSERT_TAIL(&Files,
2229 		    cfline("*.ERR\t/dev/console", "*", "*"), f_next);
2230 		SIMPLEQ_INSERT_TAIL(&Files,
2231 		    cfline("*.PANIC\t*", "*", "*"), f_next);
2232 		Initialized = 1;
2233 		return;
2234 	}
2235 
2236 	/*
2237 	 *  Foreach line in the conf table, open that file.
2238 	 */
2239 	cline = NULL;
2240 	s = 0;
2241 	strlcpy(progblock, "*", sizeof(progblock));
2242 	strlcpy(hostblock, "*", sizeof(hostblock));
2243 	while (getline(&cline, &s, cf) != -1) {
2244 		/*
2245 		 * check for end-of-section, comments, strip off trailing
2246 		 * spaces and newline character. !progblock and +hostblock
2247 		 * are treated specially: the following lines apply only to
2248 		 * that program.
2249 		 */
2250 		for (p = cline; isspace((unsigned char)*p); ++p)
2251 			continue;
2252 		if (*p == '\0' || *p == '#')
2253 			continue;
2254 		if (*p == '!' || *p == '+') {
2255 			q = (*p == '!') ? progblock : hostblock;
2256 			p++;
2257 			while (isspace((unsigned char)*p))
2258 				p++;
2259 			if (*p == '\0' || (*p == '*' && (p[1] == '\0' ||
2260 			    isspace((unsigned char)p[1])))) {
2261 				strlcpy(q, "*", NAME_MAX+1);
2262 				continue;
2263 			}
2264 			for (i = 0; i < NAME_MAX; i++) {
2265 				if (*p == '\0' || isspace((unsigned char)*p))
2266 					break;
2267 				*q++ = *p++;
2268 			}
2269 			*q = '\0';
2270 			continue;
2271 		}
2272 
2273 		p = cline + strlen(cline);
2274 		while (p > cline)
2275 			if (!isspace((unsigned char)*--p)) {
2276 				p++;
2277 				break;
2278 			}
2279 		*p = '\0';
2280 		f = cfline(cline, progblock, hostblock);
2281 		if (f != NULL)
2282 			SIMPLEQ_INSERT_TAIL(&Files, f, f_next);
2283 	}
2284 	free(cline);
2285 	if (!feof(cf)) {
2286 		logerror("Unable to read config file");
2287 		die(0);
2288 	}
2289 
2290 	/* Match and initialize the memory buffers */
2291 	SIMPLEQ_FOREACH(f, &Files, f_next) {
2292 		if (f->f_type != F_MEMBUF)
2293 			continue;
2294 		logdebug("Initialize membuf %s at %p\n",
2295 		    f->f_un.f_mb.f_mname, f);
2296 
2297 		SIMPLEQ_FOREACH(m, &mb, f_next) {
2298 			if (m->f_un.f_mb.f_rb == NULL)
2299 				continue;
2300 			if (strcmp(m->f_un.f_mb.f_mname,
2301 			    f->f_un.f_mb.f_mname) == 0)
2302 				break;
2303 		}
2304 		if (m == NULL) {
2305 			logdebug("Membuf no match\n");
2306 			f->f_un.f_mb.f_rb = ringbuf_init(f->f_un.f_mb.f_len);
2307 			if (f->f_un.f_mb.f_rb == NULL) {
2308 				f->f_type = F_UNUSED;
2309 				logerror("Failed to allocate membuf");
2310 			}
2311 		} else {
2312 			logdebug("Membuf match f:%p, m:%p\n", f, m);
2313 			f->f_un = m->f_un;
2314 			m->f_un.f_mb.f_rb = NULL;
2315 		}
2316 	}
2317 
2318 	/* make sure remaining buffers are freed */
2319 	while (!SIMPLEQ_EMPTY(&mb)) {
2320 		m = SIMPLEQ_FIRST(&mb);
2321 		SIMPLEQ_REMOVE_HEAD(&mb, f_next);
2322 		if (m->f_un.f_mb.f_rb != NULL) {
2323 			logerrorx("Mismatched membuf");
2324 			ringbuf_free(m->f_un.f_mb.f_rb);
2325 		}
2326 		logdebug("Freeing membuf %p\n", m);
2327 
2328 		free(m);
2329 	}
2330 
2331 	/* close the configuration file */
2332 	(void)fclose(cf);
2333 
2334 	Initialized = 1;
2335 
2336 	if (Debug) {
2337 		SIMPLEQ_FOREACH(f, &Files, f_next) {
2338 			for (i = 0; i <= LOG_NFACILITIES; i++)
2339 				if (f->f_pmask[i] == INTERNAL_NOPRI)
2340 					printf("X ");
2341 				else
2342 					printf("%d ", f->f_pmask[i]);
2343 			printf("%s: ", TypeNames[f->f_type]);
2344 			switch (f->f_type) {
2345 			case F_FILE:
2346 			case F_TTY:
2347 			case F_CONSOLE:
2348 			case F_PIPE:
2349 				printf("%s", f->f_un.f_fname);
2350 				break;
2351 
2352 			case F_FORWUDP:
2353 			case F_FORWTCP:
2354 			case F_FORWTLS:
2355 				printf("%s", f->f_un.f_forw.f_loghost);
2356 				break;
2357 
2358 			case F_USERS:
2359 				for (i = 0; i < MAXUNAMES && *f->f_un.f_uname[i]; i++)
2360 					printf("%s, ", f->f_un.f_uname[i]);
2361 				break;
2362 
2363 			case F_MEMBUF:
2364 				printf("%s", f->f_un.f_mb.f_mname);
2365 				break;
2366 
2367 			}
2368 			if (f->f_program || f->f_hostname)
2369 				printf(" (%s, %s)",
2370 				    f->f_program ? f->f_program : "*",
2371 				    f->f_hostname ? f->f_hostname : "*");
2372 			printf("\n");
2373 		}
2374 	}
2375 }
2376 
2377 #define progmatches(p1, p2) \
2378 	(p1 == p2 || (p1 != NULL && p2 != NULL && strcmp(p1, p2) == 0))
2379 
2380 /*
2381  * Spot a line with a duplicate file, pipe, console, tty, or membuf target.
2382  */
2383 struct filed *
2384 find_dup(struct filed *f)
2385 {
2386 	struct filed *list;
2387 
2388 	SIMPLEQ_FOREACH(list, &Files, f_next) {
2389 		if (list->f_quick || f->f_quick)
2390 			continue;
2391 		switch (list->f_type) {
2392 		case F_FILE:
2393 		case F_TTY:
2394 		case F_CONSOLE:
2395 		case F_PIPE:
2396 			if (strcmp(list->f_un.f_fname, f->f_un.f_fname) == 0 &&
2397 			    progmatches(list->f_program, f->f_program) &&
2398 			    progmatches(list->f_hostname, f->f_hostname)) {
2399 				logdebug("duplicate %s\n", f->f_un.f_fname);
2400 				return (list);
2401 			}
2402 			break;
2403 		case F_MEMBUF:
2404 			if (strcmp(list->f_un.f_mb.f_mname,
2405 			    f->f_un.f_mb.f_mname) == 0 &&
2406 			    progmatches(list->f_program, f->f_program) &&
2407 			    progmatches(list->f_hostname, f->f_hostname)) {
2408 				logdebug("duplicate membuf %s\n",
2409 				    f->f_un.f_mb.f_mname);
2410 				return (list);
2411 			}
2412 			break;
2413 		}
2414 	}
2415 	return (NULL);
2416 }
2417 
2418 /*
2419  * Crack a configuration file line
2420  */
2421 struct filed *
2422 cfline(char *line, char *progblock, char *hostblock)
2423 {
2424 	int i, pri;
2425 	size_t rb_len;
2426 	char *bp, *p, *q, *proto, *host, *port, *ipproto;
2427 	char buf[MAXLINE], ebuf[ERRBUFSIZE];
2428 	struct filed *xf, *f, *d;
2429 	struct timeval to;
2430 
2431 	logdebug("cfline(\"%s\", f, \"%s\", \"%s\")\n",
2432 	    line, progblock, hostblock);
2433 
2434 	if ((f = calloc(1, sizeof(*f))) == NULL) {
2435 		logerror("Couldn't allocate struct filed");
2436 		die(0);
2437 	}
2438 	for (i = 0; i <= LOG_NFACILITIES; i++)
2439 		f->f_pmask[i] = INTERNAL_NOPRI;
2440 
2441 	/* save program name if any */
2442 	f->f_quick = 0;
2443 	if (*progblock == '!') {
2444 		progblock++;
2445 		f->f_quick = 1;
2446 	}
2447 	if (*hostblock == '+') {
2448 		hostblock++;
2449 		f->f_quick = 1;
2450 	}
2451 	if (strcmp(progblock, "*") != 0)
2452 		f->f_program = strdup(progblock);
2453 	if (strcmp(hostblock, "*") != 0)
2454 		f->f_hostname = strdup(hostblock);
2455 
2456 	/* scan through the list of selectors */
2457 	for (p = line; *p && *p != '\t';) {
2458 
2459 		/* find the end of this facility name list */
2460 		for (q = p; *q && *q != '\t' && *q++ != '.'; )
2461 			continue;
2462 
2463 		/* collect priority name */
2464 		for (bp = buf; *q && !strchr("\t,;", *q); )
2465 			*bp++ = *q++;
2466 		*bp = '\0';
2467 
2468 		/* skip cruft */
2469 		while (*q && strchr(", ;", *q))
2470 			q++;
2471 
2472 		/* decode priority name */
2473 		if (*buf == '*')
2474 			pri = LOG_PRIMASK + 1;
2475 		else {
2476 			/* ignore trailing spaces */
2477 			for (i=strlen(buf)-1; i >= 0 && buf[i] == ' '; i--) {
2478 				buf[i]='\0';
2479 			}
2480 
2481 			pri = decode(buf, prioritynames);
2482 			if (pri < 0) {
2483 				(void)snprintf(ebuf, sizeof ebuf,
2484 				    "unknown priority name \"%s\"", buf);
2485 				logerrorx(ebuf);
2486 				free(f);
2487 				return (NULL);
2488 			}
2489 		}
2490 
2491 		/* scan facilities */
2492 		while (*p && !strchr("\t.;", *p)) {
2493 			for (bp = buf; *p && !strchr("\t,;.", *p); )
2494 				*bp++ = *p++;
2495 			*bp = '\0';
2496 			if (*buf == '*')
2497 				for (i = 0; i < LOG_NFACILITIES; i++)
2498 					f->f_pmask[i] = pri;
2499 			else {
2500 				i = decode(buf, facilitynames);
2501 				if (i < 0) {
2502 					(void)snprintf(ebuf, sizeof(ebuf),
2503 					    "unknown facility name \"%s\"",
2504 					    buf);
2505 					logerrorx(ebuf);
2506 					free(f);
2507 					return (NULL);
2508 				}
2509 				f->f_pmask[i >> 3] = pri;
2510 			}
2511 			while (*p == ',' || *p == ' ')
2512 				p++;
2513 		}
2514 
2515 		p = q;
2516 	}
2517 
2518 	/* skip to action part */
2519 	while (*p == '\t')
2520 		p++;
2521 
2522 	switch (*p) {
2523 	case '@':
2524 		if ((strlcpy(f->f_un.f_forw.f_loghost, p,
2525 		    sizeof(f->f_un.f_forw.f_loghost)) >=
2526 		    sizeof(f->f_un.f_forw.f_loghost))) {
2527 			snprintf(ebuf, sizeof(ebuf), "loghost too long \"%s\"",
2528 			    p);
2529 			logerrorx(ebuf);
2530 			break;
2531 		}
2532 		if (loghost_parse(++p, &proto, &host, &port) == -1) {
2533 			snprintf(ebuf, sizeof(ebuf), "bad loghost \"%s\"",
2534 			    f->f_un.f_forw.f_loghost);
2535 			logerrorx(ebuf);
2536 			break;
2537 		}
2538 		if (proto == NULL)
2539 			proto = "udp";
2540 		ipproto = proto;
2541 		if (strcmp(proto, "udp") == 0) {
2542 			if (fd_udp == -1)
2543 				proto = "udp6";
2544 			if (fd_udp6 == -1)
2545 				proto = "udp4";
2546 			ipproto = proto;
2547 		} else if (strcmp(proto, "udp4") == 0) {
2548 			if (fd_udp == -1) {
2549 				snprintf(ebuf, sizeof(ebuf), "no udp4 \"%s\"",
2550 				    f->f_un.f_forw.f_loghost);
2551 				logerrorx(ebuf);
2552 				break;
2553 			}
2554 		} else if (strcmp(proto, "udp6") == 0) {
2555 			if (fd_udp6 == -1) {
2556 				snprintf(ebuf, sizeof(ebuf), "no udp6 \"%s\"",
2557 				    f->f_un.f_forw.f_loghost);
2558 				logerrorx(ebuf);
2559 				break;
2560 			}
2561 		} else if (strcmp(proto, "tcp") == 0 ||
2562 		    strcmp(proto, "tcp4") == 0 || strcmp(proto, "tcp6") == 0) {
2563 			;
2564 		} else if (strcmp(proto, "tls") == 0) {
2565 			ipproto = "tcp";
2566 		} else if (strcmp(proto, "tls4") == 0) {
2567 			ipproto = "tcp4";
2568 		} else if (strcmp(proto, "tls6") == 0) {
2569 			ipproto = "tcp6";
2570 		} else {
2571 			snprintf(ebuf, sizeof(ebuf), "bad protocol \"%s\"",
2572 			    f->f_un.f_forw.f_loghost);
2573 			logerrorx(ebuf);
2574 			break;
2575 		}
2576 		if (strlen(host) >= NI_MAXHOST) {
2577 			snprintf(ebuf, sizeof(ebuf), "host too long \"%s\"",
2578 			    f->f_un.f_forw.f_loghost);
2579 			logerrorx(ebuf);
2580 			break;
2581 		}
2582 		if (port == NULL)
2583 			port = strncmp(proto, "tls", 3) == 0 ?
2584 			    "syslog-tls" : "syslog";
2585 		if (strlen(port) >= NI_MAXSERV) {
2586 			snprintf(ebuf, sizeof(ebuf), "port too long \"%s\"",
2587 			    f->f_un.f_forw.f_loghost);
2588 			logerrorx(ebuf);
2589 			break;
2590 		}
2591 		if (priv_getaddrinfo(ipproto, host, port,
2592 		    (struct sockaddr*)&f->f_un.f_forw.f_addr,
2593 		    sizeof(f->f_un.f_forw.f_addr)) != 0) {
2594 			snprintf(ebuf, sizeof(ebuf), "bad hostname \"%s\"",
2595 			    f->f_un.f_forw.f_loghost);
2596 			logerrorx(ebuf);
2597 			break;
2598 		}
2599 		f->f_file = -1;
2600 		if (strncmp(proto, "udp", 3) == 0) {
2601 			switch (f->f_un.f_forw.f_addr.ss_family) {
2602 			case AF_INET:
2603 				f->f_file = fd_udp;
2604 				break;
2605 			case AF_INET6:
2606 				f->f_file = fd_udp6;
2607 				break;
2608 			}
2609 			f->f_type = F_FORWUDP;
2610 		} else if (strncmp(ipproto, "tcp", 3) == 0) {
2611 			if ((f->f_un.f_forw.f_bufev = bufferevent_new(-1,
2612 			    tcp_dropcb, tcp_writecb, tcp_errorcb, f)) == NULL) {
2613 				snprintf(ebuf, sizeof(ebuf),
2614 				    "bufferevent \"%s\"",
2615 				    f->f_un.f_forw.f_loghost);
2616 				logerror(ebuf);
2617 				break;
2618 			}
2619 			if (strncmp(proto, "tls", 3) == 0) {
2620 				f->f_un.f_forw.f_host = strdup(host);
2621 				f->f_type = F_FORWTLS;
2622 			} else {
2623 				f->f_type = F_FORWTCP;
2624 			}
2625 			/*
2626 			 * If we try to connect to a TLS server immediately
2627 			 * syslogd gets an SIGPIPE as the signal handlers have
2628 			 * not been set up.  Delay the connection until the
2629 			 * event loop is started.  We can reuse the write event
2630 			 * for that as bufferevent is still disabled.
2631 			 */
2632 			to.tv_sec = 0;
2633 			to.tv_usec = 1;
2634 			evtimer_set(&f->f_un.f_forw.f_bufev->ev_write,
2635 			    tcp_connectcb, f);
2636 			evtimer_add(&f->f_un.f_forw.f_bufev->ev_write, &to);
2637 		}
2638 		break;
2639 
2640 	case '/':
2641 	case '|':
2642 		(void)strlcpy(f->f_un.f_fname, p, sizeof(f->f_un.f_fname));
2643 		d = find_dup(f);
2644 		if (d != NULL) {
2645 			for (i = 0; i <= LOG_NFACILITIES; i++)
2646 				if (f->f_pmask[i] != INTERNAL_NOPRI)
2647 					d->f_pmask[i] = f->f_pmask[i];
2648 			free(f);
2649 			return (NULL);
2650 		}
2651 		if (strcmp(p, ctty) == 0)
2652 			f->f_file = priv_open_tty(p);
2653 		else
2654 			f->f_file = priv_open_log(p);
2655 		if (f->f_file < 0) {
2656 			f->f_type = F_UNUSED;
2657 			logerror(p);
2658 			break;
2659 		}
2660 		if (isatty(f->f_file)) {
2661 			if (strcmp(p, ctty) == 0)
2662 				f->f_type = F_CONSOLE;
2663 			else
2664 				f->f_type = F_TTY;
2665 		} else {
2666 			if (*p == '|')
2667 				f->f_type = F_PIPE;
2668 			else {
2669 				f->f_type = F_FILE;
2670 
2671 				/* Clear O_NONBLOCK flag on f->f_file */
2672 				if ((i = fcntl(f->f_file, F_GETFL)) != -1) {
2673 					i &= ~O_NONBLOCK;
2674 					fcntl(f->f_file, F_SETFL, i);
2675 				}
2676 			}
2677 		}
2678 		break;
2679 
2680 	case '*':
2681 		f->f_type = F_WALL;
2682 		break;
2683 
2684 	case ':':
2685 		f->f_type = F_MEMBUF;
2686 
2687 		/* Parse buffer size (in kb) */
2688 		errno = 0;
2689 		rb_len = strtoul(++p, &q, 0);
2690 		if (*p == '\0' || (errno == ERANGE && rb_len == ULONG_MAX) ||
2691 		    *q != ':' || rb_len == 0) {
2692 			f->f_type = F_UNUSED;
2693 			logerror(p);
2694 			break;
2695 		}
2696 		q++;
2697 		rb_len *= 1024;
2698 
2699 		/* Copy buffer name */
2700 		for(i = 0; (size_t)i < sizeof(f->f_un.f_mb.f_mname) - 1; i++) {
2701 			if (!isalnum((unsigned char)q[i]))
2702 				break;
2703 			f->f_un.f_mb.f_mname[i] = q[i];
2704 		}
2705 
2706 		/* Make sure buffer name is unique */
2707 		xf = find_dup(f);
2708 
2709 		/* Error on missing or non-unique name, or bad buffer length */
2710 		if (i == 0 || rb_len > MAX_MEMBUF || xf != NULL) {
2711 			f->f_type = F_UNUSED;
2712 			logerrorx(p);
2713 			break;
2714 		}
2715 
2716 		/* Set buffer length */
2717 		rb_len = MAXIMUM(rb_len, MIN_MEMBUF);
2718 		f->f_un.f_mb.f_len = rb_len;
2719 		f->f_un.f_mb.f_overflow = 0;
2720 		f->f_un.f_mb.f_attached = 0;
2721 		break;
2722 
2723 	default:
2724 		for (i = 0; i < MAXUNAMES && *p; i++) {
2725 			for (q = p; *q && *q != ','; )
2726 				q++;
2727 			(void)strncpy(f->f_un.f_uname[i], p, UT_NAMESIZE);
2728 			if ((q - p) > UT_NAMESIZE)
2729 				f->f_un.f_uname[i][UT_NAMESIZE] = '\0';
2730 			else
2731 				f->f_un.f_uname[i][q - p] = '\0';
2732 			while (*q == ',' || *q == ' ')
2733 				q++;
2734 			p = q;
2735 		}
2736 		f->f_type = F_USERS;
2737 		break;
2738 	}
2739 	return (f);
2740 }
2741 
2742 /*
2743  * Parse the host and port parts from a loghost string.
2744  */
2745 int
2746 loghost_parse(char *str, char **proto, char **host, char **port)
2747 {
2748 	char *prefix = NULL;
2749 
2750 	if ((*host = strchr(str, ':')) &&
2751 	    (*host)[1] == '/' && (*host)[2] == '/') {
2752 		prefix = str;
2753 		**host = '\0';
2754 		str = *host + 3;
2755 	}
2756 	if (proto)
2757 		*proto = prefix;
2758 	else if (prefix)
2759 		return (-1);
2760 
2761 	*host = str;
2762 	if (**host == '[') {
2763 		(*host)++;
2764 		str = strchr(*host, ']');
2765 		if (str == NULL)
2766 			return (-1);
2767 		*str++ = '\0';
2768 	}
2769 	*port = strrchr(str, ':');
2770 	if (*port != NULL)
2771 		*(*port)++ = '\0';
2772 
2773 	return (0);
2774 }
2775 
2776 /*
2777  * Retrieve the size of the kernel message buffer, via sysctl.
2778  */
2779 int
2780 getmsgbufsize(void)
2781 {
2782 	int msgbufsize, mib[2];
2783 	size_t size;
2784 
2785 	mib[0] = CTL_KERN;
2786 	mib[1] = KERN_MSGBUFSIZE;
2787 	size = sizeof msgbufsize;
2788 	if (sysctl(mib, 2, &msgbufsize, &size, NULL, 0) == -1) {
2789 		logdebug("couldn't get kern.msgbufsize\n");
2790 		return (0);
2791 	}
2792 	return (msgbufsize);
2793 }
2794 
2795 /*
2796  *  Decode a symbolic name to a numeric value
2797  */
2798 int
2799 decode(const char *name, const CODE *codetab)
2800 {
2801 	const CODE *c;
2802 	char *p, buf[40];
2803 
2804 	for (p = buf; *name && p < &buf[sizeof(buf) - 1]; p++, name++) {
2805 		if (isupper((unsigned char)*name))
2806 			*p = tolower((unsigned char)*name);
2807 		else
2808 			*p = *name;
2809 	}
2810 	*p = '\0';
2811 	for (c = codetab; c->c_name; c++)
2812 		if (!strcmp(buf, c->c_name))
2813 			return (c->c_val);
2814 
2815 	return (-1);
2816 }
2817 
2818 void
2819 markit(void)
2820 {
2821 	struct filed *f;
2822 
2823 	now = time(NULL);
2824 	MarkSeq += TIMERINTVL;
2825 	if (MarkSeq >= MarkInterval) {
2826 		logmsg(LOG_INFO, "-- MARK --",
2827 		    LocalHostName, ADDDATE|MARK);
2828 		MarkSeq = 0;
2829 	}
2830 
2831 	SIMPLEQ_FOREACH(f, &Files, f_next) {
2832 		if (f->f_prevcount && now >= REPEATTIME(f)) {
2833 			logdebug("flush %s: repeated %d times, %d sec.\n",
2834 			    TypeNames[f->f_type], f->f_prevcount,
2835 			    repeatinterval[f->f_repeatcount]);
2836 			fprintlog(f, 0, (char *)NULL);
2837 			BACKOFF(f);
2838 		}
2839 	}
2840 }
2841 
2842 int
2843 unix_socket(char *path, int type, mode_t mode)
2844 {
2845 	struct sockaddr_un s_un;
2846 	char ebuf[512];
2847 	int fd, optval;
2848 	mode_t old_umask;
2849 
2850 	memset(&s_un, 0, sizeof(s_un));
2851 	s_un.sun_family = AF_UNIX;
2852 	if (strlcpy(s_un.sun_path, path, sizeof(s_un.sun_path)) >=
2853 	    sizeof(s_un.sun_path)) {
2854 		snprintf(ebuf, sizeof(ebuf), "socket path too long: %s", path);
2855 		logerrorx(ebuf);
2856 		die(0);
2857 	}
2858 
2859 	if ((fd = socket(AF_UNIX, type, 0)) == -1) {
2860 		logerror("socket");
2861 		return (-1);
2862 	}
2863 
2864 	if (Debug) {
2865 		if (connect(fd, (struct sockaddr *)&s_un, sizeof(s_un)) == 0 ||
2866 		    errno == EPROTOTYPE) {
2867 			close(fd);
2868 			errno = EISCONN;
2869 			logerror("connect");
2870 			return (-1);
2871 		}
2872 	}
2873 
2874 	old_umask = umask(0177);
2875 
2876 	unlink(path);
2877 	if (bind(fd, (struct sockaddr *)&s_un, sizeof(s_un)) == -1) {
2878 		snprintf(ebuf, sizeof(ebuf), "cannot bind %s", path);
2879 		logerror(ebuf);
2880 		umask(old_umask);
2881 		close(fd);
2882 		return (-1);
2883 	}
2884 
2885 	umask(old_umask);
2886 
2887 	if (chmod(path, mode) == -1) {
2888 		snprintf(ebuf, sizeof(ebuf), "cannot chmod %s", path);
2889 		logerror(ebuf);
2890 		close(fd);
2891 		unlink(path);
2892 		return (-1);
2893 	}
2894 
2895 	optval = MAXLINE + PATH_MAX;
2896 	if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &optval, sizeof(optval))
2897 	    == -1)
2898 		logerror("setsockopt unix");
2899 
2900 	return (fd);
2901 }
2902 
2903 void
2904 double_sockbuf(int fd, int optname)
2905 {
2906 	socklen_t len;
2907 	int i, newsize, oldsize = 0;
2908 
2909 	len = sizeof(oldsize);
2910 	if (getsockopt(fd, SOL_SOCKET, optname, &oldsize, &len) == -1)
2911 		logerror("getsockopt bufsize");
2912 	len = sizeof(newsize);
2913 	newsize =  MAXLINE + 128;  /* data + control */
2914 	/* allow 8 full length messages */
2915 	for (i = 0; i < 4; i++, newsize *= 2) {
2916 		if (newsize <= oldsize)
2917 			continue;
2918 		if (setsockopt(fd, SOL_SOCKET, optname, &newsize, len) == -1)
2919 			logerror("setsockopt bufsize");
2920 	}
2921 }
2922 
2923 void
2924 ctlconn_cleanup(void)
2925 {
2926 	struct filed *f;
2927 
2928 	if (close(fd_ctlconn) == -1)
2929 		logerror("close ctlconn");
2930 	fd_ctlconn = -1;
2931 	event_del(ev_ctlread);
2932 	event_del(ev_ctlwrite);
2933 	event_add(ev_ctlaccept, NULL);
2934 
2935 	if (ctl_state == CTL_WRITING_CONT_REPLY)
2936 		SIMPLEQ_FOREACH(f, &Files, f_next)
2937 			if (f->f_type == F_MEMBUF)
2938 				f->f_un.f_mb.f_attached = 0;
2939 
2940 	ctl_state = ctl_cmd_bytes = ctl_reply_offset = ctl_reply_size = 0;
2941 }
2942 
2943 void
2944 ctlsock_acceptcb(int fd, short event, void *arg)
2945 {
2946 	struct event		*ev = arg;
2947 
2948 	if ((fd = reserve_accept4(fd, event, ev, ctlsock_acceptcb,
2949 	    NULL, NULL, SOCK_NONBLOCK)) == -1) {
2950 		if (errno != ENFILE && errno != EMFILE &&
2951 		    errno != EINTR && errno != EWOULDBLOCK &&
2952 		    errno != ECONNABORTED)
2953 			logerror("accept ctlsock");
2954 		return;
2955 	}
2956 	logdebug("Accepting control connection\n");
2957 
2958 	if (fd_ctlconn != -1)
2959 		ctlconn_cleanup();
2960 
2961 	/* Only one connection at a time */
2962 	event_del(ev);
2963 
2964 	fd_ctlconn = fd;
2965 	/* file descriptor has changed, reset event */
2966 	event_set(ev_ctlread, fd_ctlconn, EV_READ|EV_PERSIST,
2967 	    ctlconn_readcb, ev_ctlread);
2968 	event_set(ev_ctlwrite, fd_ctlconn, EV_WRITE|EV_PERSIST,
2969 	    ctlconn_writecb, ev_ctlwrite);
2970 	event_add(ev_ctlread, NULL);
2971 	ctl_state = CTL_READING_CMD;
2972 	ctl_cmd_bytes = 0;
2973 }
2974 
2975 static struct filed
2976 *find_membuf_log(const char *name)
2977 {
2978 	struct filed *f;
2979 
2980 	SIMPLEQ_FOREACH(f, &Files, f_next) {
2981 		if (f->f_type == F_MEMBUF &&
2982 		    strcmp(f->f_un.f_mb.f_mname, name) == 0)
2983 			break;
2984 	}
2985 	return (f);
2986 }
2987 
2988 void
2989 ctlconn_readcb(int fd, short event, void *arg)
2990 {
2991 	struct filed		*f;
2992 	struct ctl_reply_hdr	*reply_hdr = (struct ctl_reply_hdr *)ctl_reply;
2993 	ssize_t			 n;
2994 	u_int32_t		 flags = 0;
2995 
2996 	if (ctl_state == CTL_WRITING_REPLY ||
2997 	    ctl_state == CTL_WRITING_CONT_REPLY) {
2998 		/* client has closed the connection */
2999 		ctlconn_cleanup();
3000 		return;
3001 	}
3002 
3003  retry:
3004 	n = read(fd, (char*)&ctl_cmd + ctl_cmd_bytes,
3005 	    sizeof(ctl_cmd) - ctl_cmd_bytes);
3006 	switch (n) {
3007 	case -1:
3008 		if (errno == EINTR)
3009 			goto retry;
3010 		if (errno == EWOULDBLOCK)
3011 			return;
3012 		logerror("ctlconn read");
3013 		/* FALLTHROUGH */
3014 	case 0:
3015 		ctlconn_cleanup();
3016 		return;
3017 	default:
3018 		ctl_cmd_bytes += n;
3019 	}
3020 	if (ctl_cmd_bytes < sizeof(ctl_cmd))
3021 		return;
3022 
3023 	if (ntohl(ctl_cmd.version) != CTL_VERSION) {
3024 		logerrorx("Unknown client protocol version");
3025 		ctlconn_cleanup();
3026 		return;
3027 	}
3028 
3029 	/* Ensure that logname is \0 terminated */
3030 	if (memchr(ctl_cmd.logname, '\0', sizeof(ctl_cmd.logname)) == NULL) {
3031 		logerrorx("Corrupt ctlsock command");
3032 		ctlconn_cleanup();
3033 		return;
3034 	}
3035 
3036 	*reply_text = '\0';
3037 
3038 	ctl_reply_size = ctl_reply_offset = 0;
3039 	memset(reply_hdr, '\0', sizeof(*reply_hdr));
3040 
3041 	ctl_cmd.cmd = ntohl(ctl_cmd.cmd);
3042 	logdebug("ctlcmd %x logname \"%s\"\n", ctl_cmd.cmd, ctl_cmd.logname);
3043 
3044 	switch (ctl_cmd.cmd) {
3045 	case CMD_READ:
3046 	case CMD_READ_CLEAR:
3047 	case CMD_READ_CONT:
3048 	case CMD_FLAGS:
3049 		f = find_membuf_log(ctl_cmd.logname);
3050 		if (f == NULL) {
3051 			strlcpy(reply_text, "No such log\n", MAX_MEMBUF);
3052 		} else {
3053 			if (ctl_cmd.cmd != CMD_FLAGS) {
3054 				ringbuf_to_string(reply_text, MAX_MEMBUF,
3055 				    f->f_un.f_mb.f_rb);
3056 			}
3057 			if (f->f_un.f_mb.f_overflow)
3058 				flags |= CTL_HDR_FLAG_OVERFLOW;
3059 			if (ctl_cmd.cmd == CMD_READ_CLEAR) {
3060 				ringbuf_clear(f->f_un.f_mb.f_rb);
3061 				f->f_un.f_mb.f_overflow = 0;
3062 			}
3063 			if (ctl_cmd.cmd == CMD_READ_CONT) {
3064 				f->f_un.f_mb.f_attached = 1;
3065 				tailify_replytext(reply_text,
3066 				    ctl_cmd.lines > 0 ? ctl_cmd.lines : 10);
3067 			} else if (ctl_cmd.lines > 0) {
3068 				tailify_replytext(reply_text, ctl_cmd.lines);
3069 			}
3070 		}
3071 		break;
3072 	case CMD_CLEAR:
3073 		f = find_membuf_log(ctl_cmd.logname);
3074 		if (f == NULL) {
3075 			strlcpy(reply_text, "No such log\n", MAX_MEMBUF);
3076 		} else {
3077 			ringbuf_clear(f->f_un.f_mb.f_rb);
3078 			if (f->f_un.f_mb.f_overflow)
3079 				flags |= CTL_HDR_FLAG_OVERFLOW;
3080 			f->f_un.f_mb.f_overflow = 0;
3081 			strlcpy(reply_text, "Log cleared\n", MAX_MEMBUF);
3082 		}
3083 		break;
3084 	case CMD_LIST:
3085 		SIMPLEQ_FOREACH(f, &Files, f_next) {
3086 			if (f->f_type == F_MEMBUF) {
3087 				strlcat(reply_text, f->f_un.f_mb.f_mname,
3088 				    MAX_MEMBUF);
3089 				if (f->f_un.f_mb.f_overflow) {
3090 					strlcat(reply_text, "*", MAX_MEMBUF);
3091 					flags |= CTL_HDR_FLAG_OVERFLOW;
3092 				}
3093 				strlcat(reply_text, " ", MAX_MEMBUF);
3094 			}
3095 		}
3096 		strlcat(reply_text, "\n", MAX_MEMBUF);
3097 		break;
3098 	default:
3099 		logerrorx("Unsupported ctlsock command");
3100 		ctlconn_cleanup();
3101 		return;
3102 	}
3103 	reply_hdr->version = htonl(CTL_VERSION);
3104 	reply_hdr->flags = htonl(flags);
3105 
3106 	ctl_reply_size = CTL_REPLY_SIZE;
3107 	logdebug("ctlcmd reply length %lu\n", (u_long)ctl_reply_size);
3108 
3109 	/* Otherwise, set up to write out reply */
3110 	ctl_state = (ctl_cmd.cmd == CMD_READ_CONT) ?
3111 	    CTL_WRITING_CONT_REPLY : CTL_WRITING_REPLY;
3112 
3113 	event_add(ev_ctlwrite, NULL);
3114 
3115 	/* another syslogc can kick us out */
3116 	if (ctl_state == CTL_WRITING_CONT_REPLY)
3117 		event_add(ev_ctlaccept, NULL);
3118 }
3119 
3120 void
3121 ctlconn_writecb(int fd, short event, void *arg)
3122 {
3123 	struct event		*ev = arg;
3124 	ssize_t			 n;
3125 
3126 	if (!(ctl_state == CTL_WRITING_REPLY ||
3127 	    ctl_state == CTL_WRITING_CONT_REPLY)) {
3128 		/* Shouldn't be here! */
3129 		logerrorx("ctlconn_write with bad ctl_state");
3130 		ctlconn_cleanup();
3131 		return;
3132 	}
3133 
3134  retry:
3135 	n = write(fd, ctl_reply + ctl_reply_offset,
3136 	    ctl_reply_size - ctl_reply_offset);
3137 	switch (n) {
3138 	case -1:
3139 		if (errno == EINTR)
3140 			goto retry;
3141 		if (errno == EWOULDBLOCK)
3142 			return;
3143 		if (errno != EPIPE)
3144 			logerror("ctlconn write");
3145 		/* FALLTHROUGH */
3146 	case 0:
3147 		ctlconn_cleanup();
3148 		return;
3149 	default:
3150 		ctl_reply_offset += n;
3151 	}
3152 	if (ctl_reply_offset < ctl_reply_size)
3153 		return;
3154 
3155 	if (ctl_state != CTL_WRITING_CONT_REPLY) {
3156 		ctlconn_cleanup();
3157 		return;
3158 	}
3159 
3160 	/*
3161 	 * Make space in the buffer for continous writes.
3162 	 * Set offset behind reply header to skip it
3163 	 */
3164 	*reply_text = '\0';
3165 	ctl_reply_offset = ctl_reply_size = CTL_REPLY_SIZE;
3166 
3167 	/* Now is a good time to report dropped lines */
3168 	if (membuf_drop) {
3169 		strlcat(reply_text, "<ENOBUFS>\n", MAX_MEMBUF);
3170 		ctl_reply_size = CTL_REPLY_SIZE;
3171 		membuf_drop = 0;
3172 	} else {
3173 		/* Nothing left to write */
3174 		event_del(ev);
3175 	}
3176 }
3177 
3178 /* Shorten replytext to number of lines */
3179 void
3180 tailify_replytext(char *replytext, int lines)
3181 {
3182 	char *start, *nl;
3183 	int count = 0;
3184 	start = nl = replytext;
3185 
3186 	while ((nl = strchr(nl, '\n')) != NULL) {
3187 		nl++;
3188 		if (++count > lines) {
3189 			start = strchr(start, '\n');
3190 			start++;
3191 		}
3192 	}
3193 	if (start != replytext) {
3194 		int len = strlen(start);
3195 		memmove(replytext, start, len);
3196 		*(replytext + len) = '\0';
3197 	}
3198 }
3199 
3200 void
3201 ctlconn_logto(char *line)
3202 {
3203 	size_t l;
3204 
3205 	if (membuf_drop)
3206 		return;
3207 
3208 	l = strlen(line);
3209 	if (l + 2 > (CTL_REPLY_MAXSIZE - ctl_reply_size)) {
3210 		/* remember line drops for later report */
3211 		membuf_drop = 1;
3212 		return;
3213 	}
3214 	memcpy(ctl_reply + ctl_reply_size, line, l);
3215 	memcpy(ctl_reply + ctl_reply_size + l, "\n", 2);
3216 	ctl_reply_size += l + 1;
3217 	event_add(ev_ctlwrite, NULL);
3218 }
3219