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