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