]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/syslogd/syslogd.c
Merge llvm trunk r321017 to contrib/llvm.
[FreeBSD/FreeBSD.git] / usr.sbin / syslogd / syslogd.c
1 /*-
2  * SPDX-License-Identifier: BSD-3-Clause
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 #ifndef lint
33 static const char copyright[] =
34 "@(#) Copyright (c) 1983, 1988, 1993, 1994\n\
35         The Regents of the University of California.  All rights reserved.\n";
36 #endif /* not lint */
37
38 #ifndef lint
39 #if 0
40 static char sccsid[] = "@(#)syslogd.c   8.3 (Berkeley) 4/4/94";
41 #endif
42 #endif /* not lint */
43
44 #include <sys/cdefs.h>
45 __FBSDID("$FreeBSD$");
46
47 /*
48  *  syslogd -- log system messages
49  *
50  * This program implements a system log. It takes a series of lines.
51  * Each line may have a priority, signified as "<n>" as
52  * the first characters of the line.  If this is
53  * not present, a default priority is used.
54  *
55  * To kill syslogd, send a signal 15 (terminate).  A signal 1 (hup) will
56  * cause it to reread its configuration file.
57  *
58  * Defined Constants:
59  *
60  * MAXLINE -- the maximum line length that can be handled.
61  * DEFUPRI -- the default priority for user messages
62  * DEFSPRI -- the default priority for kernel messages
63  *
64  * Author: Eric Allman
65  * extensive changes by Ralph Campbell
66  * more extensive changes by Eric Allman (again)
67  * Extension to log by program name as well as facility and priority
68  *   by Peter da Silva.
69  * -u and -v by Harlan Stenn.
70  * Priority comparison code by Harlan Stenn.
71  */
72
73 /* Maximum number of characters in time of last occurrence */
74 #define MAXDATELEN      16
75 #define MAXLINE         1024            /* maximum line length */
76 #define MAXSVLINE       MAXLINE         /* maximum saved line length */
77 #define DEFUPRI         (LOG_USER|LOG_NOTICE)
78 #define DEFSPRI         (LOG_KERN|LOG_CRIT)
79 #define TIMERINTVL      30              /* interval for checking flush, mark */
80 #define TTYMSGTIME      1               /* timeout passed to ttymsg */
81 #define RCVBUF_MINSIZE  (80 * 1024)     /* minimum size of dgram rcv buffer */
82
83 #include <sys/param.h>
84 #include <sys/ioctl.h>
85 #include <sys/mman.h>
86 #include <sys/queue.h>
87 #include <sys/resource.h>
88 #include <sys/socket.h>
89 #include <sys/stat.h>
90 #include <sys/syslimits.h>
91 #include <sys/time.h>
92 #include <sys/uio.h>
93 #include <sys/un.h>
94 #include <sys/wait.h>
95
96 #if defined(INET) || defined(INET6)
97 #include <netinet/in.h>
98 #include <arpa/inet.h>
99 #endif
100 #include <netdb.h>
101
102 #include <ctype.h>
103 #include <dirent.h>
104 #include <err.h>
105 #include <errno.h>
106 #include <fcntl.h>
107 #include <fnmatch.h>
108 #include <libutil.h>
109 #include <limits.h>
110 #include <paths.h>
111 #include <signal.h>
112 #include <stdio.h>
113 #include <stdlib.h>
114 #include <string.h>
115 #include <sysexits.h>
116 #include <unistd.h>
117 #include <utmpx.h>
118
119 #include "pathnames.h"
120 #include "ttymsg.h"
121
122 #define SYSLOG_NAMES
123 #include <sys/syslog.h>
124
125 static const char *ConfFile = _PATH_LOGCONF;
126 static const char *PidFile = _PATH_LOGPID;
127 static const char ctty[] = _PATH_CONSOLE;
128 static const char include_str[] = "include";
129 static const char include_ext[] = ".conf";
130
131 #define dprintf         if (Debug) printf
132
133 #define MAXUNAMES       20      /* maximum number of user names */
134
135 #define sstosa(ss)      ((struct sockaddr *)(ss))
136 #ifdef INET
137 #define sstosin(ss)     ((struct sockaddr_in *)(void *)(ss))
138 #define satosin(sa)     ((struct sockaddr_in *)(void *)(sa))
139 #endif
140 #ifdef INET6
141 #define sstosin6(ss)    ((struct sockaddr_in6 *)(void *)(ss))
142 #define satosin6(sa)    ((struct sockaddr_in6 *)(void *)(sa))
143 #define s6_addr32       __u6_addr.__u6_addr32
144 #define IN6_ARE_MASKED_ADDR_EQUAL(d, a, m)      (       \
145         (((d)->s6_addr32[0] ^ (a)->s6_addr32[0]) & (m)->s6_addr32[0]) == 0 && \
146         (((d)->s6_addr32[1] ^ (a)->s6_addr32[1]) & (m)->s6_addr32[1]) == 0 && \
147         (((d)->s6_addr32[2] ^ (a)->s6_addr32[2]) & (m)->s6_addr32[2]) == 0 && \
148         (((d)->s6_addr32[3] ^ (a)->s6_addr32[3]) & (m)->s6_addr32[3]) == 0 )
149 #endif
150 /*
151  * List of peers and sockets for binding.
152  */
153 struct peer {
154         const char      *pe_name;
155         const char      *pe_serv;
156         mode_t          pe_mode;
157         STAILQ_ENTRY(peer)      next;
158 };
159 static STAILQ_HEAD(, peer) pqueue = STAILQ_HEAD_INITIALIZER(pqueue);
160
161 struct socklist {
162         struct sockaddr_storage sl_ss;
163         int                     sl_socket;
164         struct peer             *sl_peer;
165         int                     (*sl_recv)(struct socklist *);
166         STAILQ_ENTRY(socklist)  next;
167 };
168 static STAILQ_HEAD(, socklist) shead = STAILQ_HEAD_INITIALIZER(shead);
169
170 /*
171  * Flags to logmsg().
172  */
173
174 #define IGN_CONS        0x001   /* don't print on console */
175 #define SYNC_FILE       0x002   /* do fsync on file after printing */
176 #define MARK            0x008   /* this message is a mark */
177 #define ISKERNEL        0x010   /* kernel generated message */
178
179 /*
180  * This structure represents the files that will have log
181  * copies printed.
182  * We require f_file to be valid if f_type is F_FILE, F_CONSOLE, F_TTY
183  * or if f_type if F_PIPE and f_pid > 0.
184  */
185
186 struct filed {
187         STAILQ_ENTRY(filed)     next;   /* next in linked list */
188         short   f_type;                 /* entry type, see below */
189         short   f_file;                 /* file descriptor */
190         time_t  f_time;                 /* time this was last written */
191         char    *f_host;                /* host from which to recd. */
192         u_char  f_pmask[LOG_NFACILITIES+1];     /* priority mask */
193         u_char  f_pcmp[LOG_NFACILITIES+1];      /* compare priority */
194 #define PRI_LT  0x1
195 #define PRI_EQ  0x2
196 #define PRI_GT  0x4
197         char    *f_program;             /* program this applies to */
198         union {
199                 char    f_uname[MAXUNAMES][MAXLOGNAME];
200                 struct {
201                         char    f_hname[MAXHOSTNAMELEN];
202                         struct addrinfo *f_addr;
203
204                 } f_forw;               /* forwarding address */
205                 char    f_fname[MAXPATHLEN];
206                 struct {
207                         char    f_pname[MAXPATHLEN];
208                         pid_t   f_pid;
209                 } f_pipe;
210         } f_un;
211 #define fu_uname        f_un.f_uname
212 #define fu_forw_hname   f_un.f_forw.f_hname
213 #define fu_forw_addr    f_un.f_forw.f_addr
214 #define fu_fname        f_un.f_fname
215 #define fu_pipe_pname   f_un.f_pipe.f_pname
216 #define fu_pipe_pid     f_un.f_pipe.f_pid
217         char    f_prevline[MAXSVLINE];          /* last message logged */
218         char    f_lasttime[MAXDATELEN];         /* time of last occurrence */
219         char    f_prevhost[MAXHOSTNAMELEN];     /* host from which recd. */
220         int     f_prevpri;                      /* pri of f_prevline */
221         int     f_prevlen;                      /* length of f_prevline */
222         int     f_prevcount;                    /* repetition cnt of prevline */
223         u_int   f_repeatcount;                  /* number of "repeated" msgs */
224         int     f_flags;                        /* file-specific flags */
225 #define FFLAG_SYNC 0x01
226 #define FFLAG_NEEDSYNC  0x02
227 };
228
229 /*
230  * Queue of about-to-be dead processes we should watch out for.
231  */
232 struct deadq_entry {
233         pid_t                           dq_pid;
234         int                             dq_timeout;
235         TAILQ_ENTRY(deadq_entry)        dq_entries;
236 };
237 static TAILQ_HEAD(, deadq_entry) deadq_head =
238     TAILQ_HEAD_INITIALIZER(deadq_head);
239
240 /*
241  * The timeout to apply to processes waiting on the dead queue.  Unit
242  * of measure is `mark intervals', i.e. 20 minutes by default.
243  * Processes on the dead queue will be terminated after that time.
244  */
245
246 #define  DQ_TIMO_INIT   2
247
248 /*
249  * Struct to hold records of network addresses that are allowed to log
250  * to us.
251  */
252 struct allowedpeer {
253         int isnumeric;
254         u_short port;
255         union {
256                 struct {
257                         struct sockaddr_storage addr;
258                         struct sockaddr_storage mask;
259                 } numeric;
260                 char *name;
261         } u;
262 #define a_addr u.numeric.addr
263 #define a_mask u.numeric.mask
264 #define a_name u.name
265         STAILQ_ENTRY(allowedpeer)       next;
266 };
267 static STAILQ_HEAD(, allowedpeer) aphead = STAILQ_HEAD_INITIALIZER(aphead);
268
269
270 /*
271  * Intervals at which we flush out "message repeated" messages,
272  * in seconds after previous message is logged.  After each flush,
273  * we move to the next interval until we reach the largest.
274  */
275 static int repeatinterval[] = { 30, 120, 600 }; /* # of secs before flush */
276 #define MAXREPEAT       (nitems(repeatinterval) - 1)
277 #define REPEATTIME(f)   ((f)->f_time + repeatinterval[(f)->f_repeatcount])
278 #define BACKOFF(f)      do {                                            \
279                                 if (++(f)->f_repeatcount > MAXREPEAT)   \
280                                         (f)->f_repeatcount = MAXREPEAT; \
281                         } while (0)
282
283 /* values for f_type */
284 #define F_UNUSED        0               /* unused entry */
285 #define F_FILE          1               /* regular file */
286 #define F_TTY           2               /* terminal */
287 #define F_CONSOLE       3               /* console terminal */
288 #define F_FORW          4               /* remote machine */
289 #define F_USERS         5               /* list of users */
290 #define F_WALL          6               /* everyone logged on */
291 #define F_PIPE          7               /* pipe to program */
292
293 static const char *TypeNames[] = {
294         "UNUSED",       "FILE",         "TTY",          "CONSOLE",
295         "FORW",         "USERS",        "WALL",         "PIPE"
296 };
297
298 static STAILQ_HEAD(, filed) fhead =
299     STAILQ_HEAD_INITIALIZER(fhead);     /* Log files that we write to */
300 static struct filed consfile;   /* Console */
301
302 static int      Debug;          /* debug flag */
303 static int      Foreground = 0; /* Run in foreground, instead of daemonizing */
304 static int      resolve = 1;    /* resolve hostname */
305 static char     LocalHostName[MAXHOSTNAMELEN];  /* our hostname */
306 static const char *LocalDomain; /* our local domain name */
307 static int      Initialized;    /* set when we have initialized ourselves */
308 static int      MarkInterval = 20 * 60; /* interval between marks in seconds */
309 static int      MarkSeq;        /* mark sequence number */
310 static int      NoBind;         /* don't bind() as suggested by RFC 3164 */
311 static int      SecureMode;     /* when true, receive only unix domain socks */
312 #ifdef INET6
313 static int      family = PF_UNSPEC; /* protocol family (IPv4, IPv6 or both) */
314 #else
315 static int      family = PF_INET; /* protocol family (IPv4 only) */
316 #endif
317 static int      mask_C1 = 1;    /* mask characters from 0x80 - 0x9F */
318 static int      send_to_all;    /* send message to all IPv4/IPv6 addresses */
319 static int      use_bootfile;   /* log entire bootfile for every kern msg */
320 static int      no_compress;    /* don't compress messages (1=pipes, 2=all) */
321 static int      logflags = O_WRONLY|O_APPEND; /* flags used to open log files */
322
323 static char     bootfile[MAXLINE+1]; /* booted kernel file */
324
325 static int      RemoteAddDate;  /* Always set the date on remote messages */
326 static int      RemoteHostname; /* Log remote hostname from the message */
327
328 static int      UniquePriority; /* Only log specified priority? */
329 static int      LogFacPri;      /* Put facility and priority in log message: */
330                                 /* 0=no, 1=numeric, 2=names */
331 static int      KeepKernFac;    /* Keep remotely logged kernel facility */
332 static int      needdofsync = 0; /* Are any file(s) waiting to be fsynced? */
333 static struct pidfh *pfh;
334 static int      sigpipe[2];     /* Pipe to catch a signal during select(). */
335
336 static volatile sig_atomic_t MarkSet, WantDie, WantInitialize, WantReapchild;
337
338 static int      allowaddr(char *);
339 static int      addfile(struct filed *);
340 static int      addpeer(struct peer *);
341 static int      addsock(struct sockaddr *, socklen_t, struct socklist *);
342 static struct filed *cfline(const char *, const char *, const char *);
343 static const char *cvthname(struct sockaddr *);
344 static void     deadq_enter(pid_t, const char *);
345 static int      deadq_remove(struct deadq_entry *);
346 static int      deadq_removebypid(pid_t);
347 static int      decode(const char *, const CODE *);
348 static void     die(int) __dead2;
349 static void     dodie(int);
350 static void     dofsync(void);
351 static void     domark(int);
352 static void     fprintlog(struct filed *, int, const char *);
353 static void     init(int);
354 static void     logerror(const char *);
355 static void     logmsg(int, const char *, const char *, const char *, int);
356 static void     log_deadchild(pid_t, int, const char *);
357 static void     markit(void);
358 static int      socksetup(struct peer *);
359 static int      socklist_recv_file(struct socklist *);
360 static int      socklist_recv_sock(struct socklist *);
361 static int      socklist_recv_signal(struct socklist *);
362 static void     sighandler(int);
363 static int      skip_message(const char *, const char *, int);
364 static void     parsemsg(const char *, char *);
365 static void     printsys(char *);
366 static int      p_open(const char *, pid_t *);
367 static void     reapchild(int);
368 static const char *ttymsg_check(struct iovec *, int, char *, int);
369 static void     usage(void);
370 static int      validate(struct sockaddr *, const char *);
371 static void     unmapped(struct sockaddr *);
372 static void     wallmsg(struct filed *, struct iovec *, const int iovlen);
373 static int      waitdaemon(int);
374 static void     timedout(int);
375 static void     increase_rcvbuf(int);
376
377 static void
378 close_filed(struct filed *f)
379 {
380
381         if (f == NULL || f->f_file == -1)
382                 return;
383
384         switch (f->f_type) {
385         case F_FILE:
386         case F_TTY:
387         case F_CONSOLE:
388         case F_FORW:
389                 f->f_type = F_UNUSED;
390                 break;
391         case F_PIPE:
392                 f->fu_pipe_pid = 0;
393                 break;
394         }
395         (void)close(f->f_file);
396         f->f_file = -1;
397 }
398
399 static int
400 addfile(struct filed *f0)
401 {
402         struct filed *f;
403
404         f = calloc(1, sizeof(*f));
405         if (f == NULL)
406                 err(1, "malloc failed");
407         *f = *f0;
408         STAILQ_INSERT_TAIL(&fhead, f, next);
409
410         return (0);
411 }
412
413 static int
414 addpeer(struct peer *pe0)
415 {
416         struct peer *pe;
417
418         pe = calloc(1, sizeof(*pe));
419         if (pe == NULL)
420                 err(1, "malloc failed");
421         *pe = *pe0;
422         STAILQ_INSERT_TAIL(&pqueue, pe, next);
423
424         return (0);
425 }
426
427 static int
428 addsock(struct sockaddr *sa, socklen_t sa_len, struct socklist *sl0)
429 {
430         struct socklist *sl;
431
432         sl = calloc(1, sizeof(*sl));
433         if (sl == NULL)
434                 err(1, "malloc failed");
435         *sl = *sl0;
436         if (sa != NULL && sa_len > 0)
437                 memcpy(&sl->sl_ss, sa, sa_len);
438         STAILQ_INSERT_TAIL(&shead, sl, next);
439
440         return (0);
441 }
442
443 int
444 main(int argc, char *argv[])
445 {
446         int ch, i, s, fdsrmax = 0, bflag = 0, pflag = 0, Sflag = 0;
447         fd_set *fdsr = NULL;
448         struct timeval tv, *tvp;
449         struct peer *pe;
450         struct socklist *sl;
451         pid_t ppid = 1, spid;
452         char *p;
453
454         if (madvise(NULL, 0, MADV_PROTECT) != 0)
455                 dprintf("madvise() failed: %s\n", strerror(errno));
456
457         while ((ch = getopt(argc, argv, "468Aa:b:cCdf:FHkl:m:nNop:P:sS:Tuv"))
458             != -1)
459                 switch (ch) {
460 #ifdef INET
461                 case '4':
462                         family = PF_INET;
463                         break;
464 #endif
465 #ifdef INET6
466                 case '6':
467                         family = PF_INET6;
468                         break;
469 #endif
470                 case '8':
471                         mask_C1 = 0;
472                         break;
473                 case 'A':
474                         send_to_all++;
475                         break;
476                 case 'a':               /* allow specific network addresses only */
477                         if (allowaddr(optarg) == -1)
478                                 usage();
479                         break;
480                 case 'b':
481                         bflag = 1;
482                         p = strchr(optarg, ']');
483                         if (p != NULL)
484                                 p = strchr(p + 1, ':');
485                         else {
486                                 p = strchr(optarg, ':');
487                                 if (p != NULL && strchr(p + 1, ':') != NULL)
488                                         p = NULL; /* backward compatibility */
489                         }
490                         if (p == NULL) {
491                                 /* A hostname or filename only. */
492                                 addpeer(&(struct peer){
493                                         .pe_name = optarg,
494                                         .pe_serv = "syslog"
495                                 });
496                         } else {
497                                 /* The case of "name:service". */
498                                 *p++ = '\0';
499                                 addpeer(&(struct peer){
500                                         .pe_serv = p,
501                                         .pe_name = (strlen(optarg) == 0) ?
502                                             NULL : optarg,
503                                 });
504                         }
505                         break;
506                 case 'c':
507                         no_compress++;
508                         break;
509                 case 'C':
510                         logflags |= O_CREAT;
511                         break;
512                 case 'd':               /* debug */
513                         Debug++;
514                         break;
515                 case 'f':               /* configuration file */
516                         ConfFile = optarg;
517                         break;
518                 case 'F':               /* run in foreground instead of daemon */
519                         Foreground++;
520                         break;
521                 case 'H':
522                         RemoteHostname = 1;
523                         break;
524                 case 'k':               /* keep remote kern fac */
525                         KeepKernFac = 1;
526                         break;
527                 case 'l':
528                 case 'p':
529                 case 'S':
530                     {
531                         long    perml;
532                         mode_t  mode;
533                         char    *name, *ep;
534
535                         if (ch == 'l')
536                                 mode = DEFFILEMODE;
537                         else if (ch == 'p') {
538                                 mode = DEFFILEMODE;
539                                 pflag = 1;
540                         } else if (ch == 'S') {
541                                 mode = S_IRUSR | S_IWUSR;
542                                 Sflag = 1;
543                         }
544                         if (optarg[0] == '/')
545                                 name = optarg;
546                         else if ((name = strchr(optarg, ':')) != NULL) {
547                                 *name++ = '\0';
548                                 if (name[0] != '/')
549                                         errx(1, "socket name must be absolute "
550                                             "path");
551                                 if (isdigit(*optarg)) {
552                                         perml = strtol(optarg, &ep, 8);
553                                     if (*ep || perml < 0 ||
554                                         perml & ~(S_IRWXU|S_IRWXG|S_IRWXO))
555                                             errx(1, "invalid mode %s, exiting",
556                                                 optarg);
557                                     mode = (mode_t )perml;
558                                 } else
559                                         errx(1, "invalid mode %s, exiting",
560                                             optarg);
561                         } else
562                                 errx(1, "invalid filename %s, exiting",
563                                     optarg);
564                         addpeer(&(struct peer){
565                                 .pe_name = name,
566                                 .pe_mode = mode
567                         });
568                         break;
569                    }
570                 case 'm':               /* mark interval */
571                         MarkInterval = atoi(optarg) * 60;
572                         break;
573                 case 'N':
574                         NoBind = 1;
575                         SecureMode = 1;
576                         break;
577                 case 'n':
578                         resolve = 0;
579                         break;
580                 case 'o':
581                         use_bootfile = 1;
582                         break;
583                 case 'P':               /* path for alt. PID */
584                         PidFile = optarg;
585                         break;
586                 case 's':               /* no network mode */
587                         SecureMode++;
588                         break;
589                 case 'T':
590                         RemoteAddDate = 1;
591                         break;
592                 case 'u':               /* only log specified priority */
593                         UniquePriority++;
594                         break;
595                 case 'v':               /* log facility and priority */
596                         LogFacPri++;
597                         break;
598                 default:
599                         usage();
600                 }
601         if ((argc -= optind) != 0)
602                 usage();
603
604         /* Pipe to catch a signal during select(). */
605         s = pipe2(sigpipe, O_CLOEXEC);
606         if (s < 0) {
607                 err(1, "cannot open a pipe for signals");
608         } else {
609                 addsock(NULL, 0, &(struct socklist){
610                     .sl_socket = sigpipe[0],
611                     .sl_recv = socklist_recv_signal
612                 });
613         }
614
615         /* Listen by default: /dev/klog. */
616         s = open(_PATH_KLOG, O_RDONLY | O_NONBLOCK | O_CLOEXEC, 0);
617         if (s < 0) {
618                 dprintf("can't open %s (%d)\n", _PATH_KLOG, errno);
619         } else {
620                 addsock(NULL, 0, &(struct socklist){
621                         .sl_socket = s,
622                         .sl_recv = socklist_recv_file,
623                 });
624         }
625         /* Listen by default: *:514 if no -b flag. */
626         if (bflag == 0)
627                 addpeer(&(struct peer){
628                         .pe_serv = "syslog"
629                 });
630         /* Listen by default: /var/run/log if no -p flag. */
631         if (pflag == 0)
632                 addpeer(&(struct peer){
633                         .pe_name = _PATH_LOG,
634                         .pe_mode = DEFFILEMODE,
635                 });
636         /* Listen by default: /var/run/logpriv if no -S flag. */
637         if (Sflag == 0)
638                 addpeer(&(struct peer){
639                         .pe_name = _PATH_LOG_PRIV,
640                         .pe_mode = S_IRUSR | S_IWUSR,
641                 });
642         STAILQ_FOREACH(pe, &pqueue, next)
643                 socksetup(pe);
644
645         pfh = pidfile_open(PidFile, 0600, &spid);
646         if (pfh == NULL) {
647                 if (errno == EEXIST)
648                         errx(1, "syslogd already running, pid: %d", spid);
649                 warn("cannot open pid file");
650         }
651
652         if ((!Foreground) && (!Debug)) {
653                 ppid = waitdaemon(30);
654                 if (ppid < 0) {
655                         warn("could not become daemon");
656                         pidfile_remove(pfh);
657                         exit(1);
658                 }
659         } else if (Debug)
660                 setlinebuf(stdout);
661
662         consfile.f_type = F_CONSOLE;
663         (void)strlcpy(consfile.fu_fname, ctty + sizeof _PATH_DEV - 1,
664             sizeof(consfile.fu_fname));
665         (void)strlcpy(bootfile, getbootfile(), sizeof(bootfile));
666         (void)signal(SIGTERM, dodie);
667         (void)signal(SIGINT, Debug ? dodie : SIG_IGN);
668         (void)signal(SIGQUIT, Debug ? dodie : SIG_IGN);
669         (void)signal(SIGHUP, sighandler);
670         (void)signal(SIGCHLD, sighandler);
671         (void)signal(SIGALRM, domark);
672         (void)signal(SIGPIPE, SIG_IGN); /* We'll catch EPIPE instead. */
673         (void)alarm(TIMERINTVL);
674
675         /* tuck my process id away */
676         pidfile_write(pfh);
677
678         dprintf("off & running....\n");
679
680         tvp = &tv;
681         tv.tv_sec = tv.tv_usec = 0;
682
683         STAILQ_FOREACH(sl, &shead, next) {
684                 if (sl->sl_socket > fdsrmax)
685                         fdsrmax = sl->sl_socket;
686         }
687         fdsr = (fd_set *)calloc(howmany(fdsrmax+1, NFDBITS),
688             sizeof(fd_mask));
689         if (fdsr == NULL)
690                 errx(1, "calloc fd_set");
691
692         for (;;) {
693                 if (Initialized == 0)
694                         init(0);
695                 else if (WantInitialize)
696                         init(WantInitialize);
697                 if (WantReapchild)
698                         reapchild(WantReapchild);
699                 if (MarkSet)
700                         markit();
701                 if (WantDie) {
702                         free(fdsr);
703                         die(WantDie);
704                 }
705
706                 bzero(fdsr, howmany(fdsrmax+1, NFDBITS) *
707                     sizeof(fd_mask));
708
709                 STAILQ_FOREACH(sl, &shead, next) {
710                         if (sl->sl_socket != -1 && sl->sl_recv != NULL)
711                                 FD_SET(sl->sl_socket, fdsr);
712                 }
713                 i = select(fdsrmax + 1, fdsr, NULL, NULL,
714                     needdofsync ? &tv : tvp);
715                 switch (i) {
716                 case 0:
717                         dofsync();
718                         needdofsync = 0;
719                         if (tvp) {
720                                 tvp = NULL;
721                                 if (ppid != 1)
722                                         kill(ppid, SIGALRM);
723                         }
724                         continue;
725                 case -1:
726                         if (errno != EINTR)
727                                 logerror("select");
728                         continue;
729                 }
730                 STAILQ_FOREACH(sl, &shead, next) {
731                         if (FD_ISSET(sl->sl_socket, fdsr))
732                                 (*sl->sl_recv)(sl);
733                 }
734         }
735         free(fdsr);
736 }
737
738 static int
739 socklist_recv_signal(struct socklist *sl __unused)
740 {
741         ssize_t len;
742         int i, nsig, signo;
743
744         if (ioctl(sigpipe[0], FIONREAD, &i) != 0) {
745                 logerror("ioctl(FIONREAD)");
746                 err(1, "signal pipe read failed");
747         }
748         nsig = i / sizeof(signo);
749         dprintf("# of received signals = %d\n", nsig);
750         for (i = 0; i < nsig; i++) {
751                 len = read(sigpipe[0], &signo, sizeof(signo));
752                 if (len != sizeof(signo)) {
753                         logerror("signal pipe read failed");
754                         err(1, "signal pipe read failed");
755                 }
756                 dprintf("Received signal: %d from fd=%d\n", signo,
757                     sigpipe[0]);
758                 switch (signo) {
759                 case SIGHUP:
760                         WantInitialize = 1;
761                         break;
762                 case SIGCHLD:
763                         WantReapchild = 1;
764                         break;
765                 }
766         }
767         return (0);
768 }
769
770 static int
771 socklist_recv_sock(struct socklist *sl)
772 {
773         struct sockaddr_storage ss;
774         struct sockaddr *sa = (struct sockaddr *)&ss;
775         socklen_t sslen;
776         const char *hname;
777         char line[MAXLINE + 1];
778         int len;
779
780         sslen = sizeof(ss);
781         len = recvfrom(sl->sl_socket, line, sizeof(line) - 1, 0, sa, &sslen);
782         dprintf("received sa_len = %d\n", sslen);
783         if (len == 0)
784                 return (-1);
785         if (len < 0) {
786                 if (errno != EINTR)
787                         logerror("recvfrom");
788                 return (-1);
789         }
790         /* Received valid data. */
791         line[len] = '\0';
792         if (sl->sl_ss.ss_family == AF_LOCAL)
793                 hname = LocalHostName;
794         else {
795                 hname = cvthname(sa);
796                 unmapped(sa);
797                 if (validate(sa, hname) == 0) {
798                         dprintf("Message from %s was ignored.", hname);
799                         return (-1);
800                 }
801         }
802         parsemsg(hname, line);
803
804         return (0);
805 }
806
807 static void
808 unmapped(struct sockaddr *sa)
809 {
810 #if defined(INET) && defined(INET6)
811         struct sockaddr_in6 *sin6;
812         struct sockaddr_in sin;
813
814         if (sa == NULL ||
815             sa->sa_family != AF_INET6 ||
816             sa->sa_len != sizeof(*sin6))
817                 return;
818         sin6 = satosin6(sa);
819         if (!IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr))
820                 return;
821         sin = (struct sockaddr_in){
822                 .sin_family = AF_INET,
823                 .sin_len = sizeof(sin),
824                 .sin_port = sin6->sin6_port
825         };
826         memcpy(&sin.sin_addr, &sin6->sin6_addr.s6_addr[12],
827             sizeof(sin.sin_addr));
828         memcpy(sa, &sin, sizeof(sin));
829 #else
830         if (sa == NULL)
831                 return;
832 #endif
833 }
834
835 static void
836 usage(void)
837 {
838
839         fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n",
840                 "usage: syslogd [-468ACcdFHknosTuv] [-a allowed_peer]",
841                 "               [-b bind_address] [-f config_file]",
842                 "               [-l [mode:]path] [-m mark_interval]",
843                 "               [-P pid_file] [-p log_socket]",
844                 "               [-S logpriv_socket]");
845         exit(1);
846 }
847
848 /*
849  * Take a raw input line, extract PRI, TIMESTAMP and HOSTNAME from the message,
850  * and print the message on the appropriate log files.
851  */
852 static void
853 parsemsg(const char *from, char *msg)
854 {
855         const char *timestamp;
856         char *q;
857         long n;
858         int i, c, pri, msglen;
859         char line[MAXLINE + 1];
860
861         /* Parse PRI. */
862         if (msg[0] != '<' || !isdigit(msg[1])) {
863                 dprintf("Invalid PRI from %s\n", from);
864                 return;
865         }
866         for (i = 2; i <= 4; i++) {
867                 if (msg[i] == '>')
868                         break;
869                 if (!isdigit(msg[i])) {
870                         dprintf("Invalid PRI header from %s\n", from);
871                         return;
872                 }
873         }
874         if (msg[i] != '>') {
875                 dprintf("Invalid PRI header from %s\n", from);
876                 return;
877         }
878         errno = 0;
879         n = strtol(msg + 1, &q, 10);
880         if (errno != 0 || *q != msg[i] || n < 0 || n >= INT_MAX) {
881                 dprintf("Invalid PRI %ld from %s: %s\n",
882                     n, from, strerror(errno));
883                 return;
884         }
885         pri = n;
886         if (pri &~ (LOG_FACMASK|LOG_PRIMASK))
887                 pri = DEFUPRI;
888
889         /*
890          * Don't allow users to log kernel messages.
891          * NOTE: since LOG_KERN == 0 this will also match
892          *       messages with no facility specified.
893          */
894         if ((pri & LOG_FACMASK) == LOG_KERN && !KeepKernFac)
895                 pri = LOG_MAKEPRI(LOG_USER, LOG_PRI(pri));
896
897         /*
898          * The TIMESTAMP field is the local time and is in the format of
899          * "Mmm dd hh:mm:ss" (without the quote marks).
900          * A single space character MUST follow the TIMESTAMP field.
901          *
902          * XXXGL: the check can be improved.
903          */
904         msg += i + 1;
905         msglen = strlen(msg);
906         if (msglen < MAXDATELEN || msg[3] != ' ' || msg[6] != ' ' ||
907             msg[9] != ':' || msg[12] != ':' || msg[15] != ' ') {
908                 dprintf("Invalid TIMESTAMP from %s: %s\n", from, msg);
909                 return;
910         }
911
912         if (!RemoteAddDate)
913                 timestamp = msg;
914         else
915                 timestamp = NULL;
916         msg += MAXDATELEN;
917         msglen -= MAXDATELEN;
918
919         /*
920          * A single space character MUST also follow the HOSTNAME field.
921          */
922         for (i = 0; i < MIN(MAXHOSTNAMELEN, msglen); i++) {
923                 if (msg[i] == ' ') {
924                         if (RemoteHostname) {
925                                 msg[i] = '\0';
926                                 from = msg;
927                         }
928                         msg += i + 1;
929                         break;
930                 }
931                 /*
932                  * Support non RFC compliant messages, without hostname.
933                  */
934                 if (msg[i] == ':')
935                         break;
936         }
937         if (i == MIN(MAXHOSTNAMELEN, msglen)) {
938                 dprintf("Invalid HOSTNAME from %s: %s\n", from, msg);
939                 return;
940         }
941
942         q = line;
943         while ((c = (unsigned char)*msg++) != '\0' &&
944             q < &line[sizeof(line) - 4]) {
945                 if (mask_C1 && (c & 0x80) && c < 0xA0) {
946                         c &= 0x7F;
947                         *q++ = 'M';
948                         *q++ = '-';
949                 }
950                 if (isascii(c) && iscntrl(c)) {
951                         if (c == '\n') {
952                                 *q++ = ' ';
953                         } else if (c == '\t') {
954                                 *q++ = '\t';
955                         } else {
956                                 *q++ = '^';
957                                 *q++ = c ^ 0100;
958                         }
959                 } else {
960                         *q++ = c;
961                 }
962         }
963         *q = '\0';
964
965         logmsg(pri, timestamp, line, from, 0);
966 }
967
968 /*
969  * Read /dev/klog while data are available, split into lines.
970  */
971 static int
972 socklist_recv_file(struct socklist *sl)
973 {
974         char *p, *q, line[MAXLINE + 1];
975         int len, i;
976
977         len = 0;
978         for (;;) {
979                 i = read(sl->sl_socket, line + len, MAXLINE - 1 - len);
980                 if (i > 0) {
981                         line[i + len] = '\0';
982                 } else {
983                         if (i < 0 && errno != EINTR && errno != EAGAIN) {
984                                 logerror("klog");
985                                 close(sl->sl_socket);
986                                 sl->sl_socket = -1;
987                         }
988                         break;
989                 }
990
991                 for (p = line; (q = strchr(p, '\n')) != NULL; p = q + 1) {
992                         *q = '\0';
993                         printsys(p);
994                 }
995                 len = strlen(p);
996                 if (len >= MAXLINE - 1) {
997                         printsys(p);
998                         len = 0;
999                 }
1000                 if (len > 0)
1001                         memmove(line, p, len + 1);
1002         }
1003         if (len > 0)
1004                 printsys(line);
1005
1006         return (len);
1007 }
1008
1009 /*
1010  * Take a raw input line from /dev/klog, format similar to syslog().
1011  */
1012 static void
1013 printsys(char *msg)
1014 {
1015         char *p, *q;
1016         long n;
1017         int flags, isprintf, pri;
1018
1019         flags = ISKERNEL | SYNC_FILE;   /* fsync after write */
1020         p = msg;
1021         pri = DEFSPRI;
1022         isprintf = 1;
1023         if (*p == '<') {
1024                 errno = 0;
1025                 n = strtol(p + 1, &q, 10);
1026                 if (*q == '>' && n >= 0 && n < INT_MAX && errno == 0) {
1027                         p = q + 1;
1028                         pri = n;
1029                         isprintf = 0;
1030                 }
1031         }
1032         /*
1033          * Kernel printf's and LOG_CONSOLE messages have been displayed
1034          * on the console already.
1035          */
1036         if (isprintf || (pri & LOG_FACMASK) == LOG_CONSOLE)
1037                 flags |= IGN_CONS;
1038         if (pri &~ (LOG_FACMASK|LOG_PRIMASK))
1039                 pri = DEFSPRI;
1040         logmsg(pri, NULL, p, LocalHostName, flags);
1041 }
1042
1043 static time_t   now;
1044
1045 /*
1046  * Match a program or host name against a specification.
1047  * Return a non-0 value if the message must be ignored
1048  * based on the specification.
1049  */
1050 static int
1051 skip_message(const char *name, const char *spec, int checkcase)
1052 {
1053         const char *s;
1054         char prev, next;
1055         int exclude = 0;
1056         /* Behaviour on explicit match */
1057
1058         if (spec == NULL)
1059                 return 0;
1060         switch (*spec) {
1061         case '-':
1062                 exclude = 1;
1063                 /*FALLTHROUGH*/
1064         case '+':
1065                 spec++;
1066                 break;
1067         default:
1068                 break;
1069         }
1070         if (checkcase)
1071                 s = strstr (spec, name);
1072         else
1073                 s = strcasestr (spec, name);
1074
1075         if (s != NULL) {
1076                 prev = (s == spec ? ',' : *(s - 1));
1077                 next = *(s + strlen (name));
1078
1079                 if (prev == ',' && (next == '\0' || next == ','))
1080                         /* Explicit match: skip iff the spec is an
1081                            exclusive one. */
1082                         return exclude;
1083         }
1084
1085         /* No explicit match for this name: skip the message iff
1086            the spec is an inclusive one. */
1087         return !exclude;
1088 }
1089
1090 /*
1091  * Log a message to the appropriate log files, users, etc. based on
1092  * the priority.
1093  */
1094 static void
1095 logmsg(int pri, const char *timestamp, const char *msg, const char *from,
1096     int flags)
1097 {
1098         struct filed *f;
1099         int i, fac, msglen, prilev;
1100         char prog[NAME_MAX+1];
1101         char buf[MAXLINE+1];
1102
1103         dprintf("logmsg: pri %o, flags %x, from %s, msg %s\n",
1104             pri, flags, from, msg);
1105
1106         (void)time(&now);
1107         if (timestamp == NULL)
1108                 timestamp = ctime(&now) + 4;
1109
1110         /* extract facility and priority level */
1111         if (flags & MARK)
1112                 fac = LOG_NFACILITIES;
1113         else
1114                 fac = LOG_FAC(pri);
1115
1116         /* Check maximum facility number. */
1117         if (fac > LOG_NFACILITIES)
1118                 return;
1119
1120         prilev = LOG_PRI(pri);
1121
1122         /* Extract TAG part of the message (usually program name). */
1123         for (i = 0; i < NAME_MAX; i++) {
1124                 if (!isprint(msg[i]) || msg[i] == ':' || msg[i] == '[' ||
1125                     msg[i] == '/' || isspace(msg[i]))
1126                         break;
1127                 prog[i] = msg[i];
1128         }
1129         prog[i] = 0;
1130
1131         /* add kernel prefix for kernel messages */
1132         if (flags & ISKERNEL) {
1133                 snprintf(buf, sizeof(buf), "%s: %s",
1134                     use_bootfile ? bootfile : "kernel", msg);
1135                 msg = buf;
1136         }
1137         msglen = strlen(msg);
1138
1139         /* log the message to the particular outputs */
1140         if (!Initialized) {
1141                 f = &consfile;
1142                 /*
1143                  * Open in non-blocking mode to avoid hangs during open
1144                  * and close(waiting for the port to drain).
1145                  */
1146                 f->f_file = open(ctty, O_WRONLY | O_NONBLOCK, 0);
1147
1148                 if (f->f_file >= 0) {
1149                         (void)strlcpy(f->f_lasttime, timestamp,
1150                                 sizeof(f->f_lasttime));
1151                         fprintlog(f, flags, msg);
1152                         close(f->f_file);
1153                         f->f_file = -1;
1154                 }
1155                 return;
1156         }
1157         STAILQ_FOREACH(f, &fhead, next) {
1158                 /* skip messages that are incorrect priority */
1159                 if (!(((f->f_pcmp[fac] & PRI_EQ) && (f->f_pmask[fac] == prilev))
1160                      ||((f->f_pcmp[fac] & PRI_LT) && (f->f_pmask[fac] < prilev))
1161                      ||((f->f_pcmp[fac] & PRI_GT) && (f->f_pmask[fac] > prilev))
1162                      )
1163                     || f->f_pmask[fac] == INTERNAL_NOPRI)
1164                         continue;
1165
1166                 /* skip messages with the incorrect hostname */
1167                 if (skip_message(from, f->f_host, 0))
1168                         continue;
1169
1170                 /* skip messages with the incorrect program name */
1171                 if (skip_message(prog, f->f_program, 1))
1172                         continue;
1173
1174                 /* skip message to console if it has already been printed */
1175                 if (f->f_type == F_CONSOLE && (flags & IGN_CONS))
1176                         continue;
1177
1178                 /* don't output marks to recently written files */
1179                 if ((flags & MARK) && (now - f->f_time) < MarkInterval / 2)
1180                         continue;
1181
1182                 /*
1183                  * suppress duplicate lines to this file
1184                  */
1185                 if (no_compress - (f->f_type != F_PIPE) < 1 &&
1186                     (flags & MARK) == 0 && msglen == f->f_prevlen &&
1187                     !strcmp(msg, f->f_prevline) &&
1188                     !strcasecmp(from, f->f_prevhost)) {
1189                         (void)strlcpy(f->f_lasttime, timestamp,
1190                                 sizeof(f->f_lasttime));
1191                         f->f_prevcount++;
1192                         dprintf("msg repeated %d times, %ld sec of %d\n",
1193                             f->f_prevcount, (long)(now - f->f_time),
1194                             repeatinterval[f->f_repeatcount]);
1195                         /*
1196                          * If domark would have logged this by now,
1197                          * flush it now (so we don't hold isolated messages),
1198                          * but back off so we'll flush less often
1199                          * in the future.
1200                          */
1201                         if (now > REPEATTIME(f)) {
1202                                 fprintlog(f, flags, (char *)NULL);
1203                                 BACKOFF(f);
1204                         }
1205                 } else {
1206                         /* new line, save it */
1207                         if (f->f_prevcount)
1208                                 fprintlog(f, 0, (char *)NULL);
1209                         f->f_repeatcount = 0;
1210                         f->f_prevpri = pri;
1211                         (void)strlcpy(f->f_lasttime, timestamp,
1212                                 sizeof(f->f_lasttime));
1213                         (void)strlcpy(f->f_prevhost, from,
1214                             sizeof(f->f_prevhost));
1215                         if (msglen < MAXSVLINE) {
1216                                 f->f_prevlen = msglen;
1217                                 (void)strlcpy(f->f_prevline, msg, sizeof(f->f_prevline));
1218                                 fprintlog(f, flags, (char *)NULL);
1219                         } else {
1220                                 f->f_prevline[0] = 0;
1221                                 f->f_prevlen = 0;
1222                                 fprintlog(f, flags, msg);
1223                         }
1224                 }
1225         }
1226 }
1227
1228 static void
1229 dofsync(void)
1230 {
1231         struct filed *f;
1232
1233         STAILQ_FOREACH(f, &fhead, next) {
1234                 if ((f->f_type == F_FILE) &&
1235                     (f->f_flags & FFLAG_NEEDSYNC)) {
1236                         f->f_flags &= ~FFLAG_NEEDSYNC;
1237                         (void)fsync(f->f_file);
1238                 }
1239         }
1240 }
1241
1242 #define IOV_SIZE 7
1243 static void
1244 fprintlog(struct filed *f, int flags, const char *msg)
1245 {
1246         struct iovec iov[IOV_SIZE];
1247         struct addrinfo *r;
1248         int l, lsent = 0;
1249         char line[MAXLINE + 1], repbuf[80], greetings[200], *wmsg = NULL;
1250         char nul[] = "", space[] = " ", lf[] = "\n", crlf[] = "\r\n";
1251         const char *msgret;
1252
1253         if (f->f_type == F_WALL) {
1254                 /* The time displayed is not synchornized with the other log
1255                  * destinations (like messages).  Following fragment was using
1256                  * ctime(&now), which was updating the time every 30 sec.
1257                  * With f_lasttime, time is synchronized correctly.
1258                  */
1259                 iov[0] = (struct iovec){
1260                         .iov_base = greetings,
1261                         .iov_len = snprintf(greetings, sizeof(greetings),
1262                                     "\r\n\7Message from syslogd@%s "
1263                                     "at %.24s ...\r\n",
1264                                     f->f_prevhost, f->f_lasttime)
1265                 };
1266                 if (iov[0].iov_len >= sizeof(greetings))
1267                         iov[0].iov_len = sizeof(greetings) - 1;
1268                 iov[1] = (struct iovec){
1269                         .iov_base = nul,
1270                         .iov_len = 0
1271                 };
1272         } else {
1273                 iov[0] = (struct iovec){
1274                         .iov_base = f->f_lasttime,
1275                         .iov_len = strlen(f->f_lasttime)
1276                 };
1277                 iov[1] = (struct iovec){
1278                         .iov_base = space,
1279                         .iov_len = 1
1280                 };
1281         }
1282
1283         if (LogFacPri) {
1284                 static char fp_buf[30]; /* Hollow laugh */
1285                 int fac = f->f_prevpri & LOG_FACMASK;
1286                 int pri = LOG_PRI(f->f_prevpri);
1287                 const char *f_s = NULL;
1288                 char f_n[5];    /* Hollow laugh */
1289                 const char *p_s = NULL;
1290                 char p_n[5];    /* Hollow laugh */
1291
1292                 if (LogFacPri > 1) {
1293                   const CODE *c;
1294
1295                   for (c = facilitynames; c->c_name; c++) {
1296                     if (c->c_val == fac) {
1297                       f_s = c->c_name;
1298                       break;
1299                     }
1300                   }
1301                   for (c = prioritynames; c->c_name; c++) {
1302                     if (c->c_val == pri) {
1303                       p_s = c->c_name;
1304                       break;
1305                     }
1306                   }
1307                 }
1308                 if (!f_s) {
1309                   snprintf(f_n, sizeof f_n, "%d", LOG_FAC(fac));
1310                   f_s = f_n;
1311                 }
1312                 if (!p_s) {
1313                   snprintf(p_n, sizeof p_n, "%d", pri);
1314                   p_s = p_n;
1315                 }
1316                 snprintf(fp_buf, sizeof fp_buf, "<%s.%s> ", f_s, p_s);
1317                 iov[2] = (struct iovec){
1318                         .iov_base = fp_buf,
1319                         .iov_len = strlen(fp_buf)
1320                 };
1321         } else {
1322                 iov[2] = (struct iovec){
1323                         .iov_base = nul,
1324                         .iov_len = 0
1325                 };
1326         }
1327         iov[3] = (struct iovec){
1328                 .iov_base = f->f_prevhost,
1329                 .iov_len = strlen(f->f_prevhost)
1330         };
1331         iov[4] = (struct iovec){
1332                 .iov_base = space,
1333                 .iov_len = 1
1334         };
1335         if (msg) {
1336                 wmsg = strdup(msg); /* XXX iov_base needs a `const' sibling. */
1337                 if (wmsg == NULL) {
1338                         logerror("strdup");
1339                         exit(1);
1340                 }
1341                 iov[5] = (struct iovec){
1342                         .iov_base = wmsg,
1343                         .iov_len = strlen(msg)
1344                 };
1345         } else if (f->f_prevcount > 1) {
1346                 iov[5] = (struct iovec){
1347                         .iov_base = repbuf,
1348                         .iov_len = snprintf(repbuf, sizeof(repbuf),
1349                             "last message repeated %d times", f->f_prevcount)
1350                 };
1351         } else {
1352                 iov[5] = (struct iovec){
1353                         .iov_base = f->f_prevline,
1354                         .iov_len = f->f_prevlen
1355                 };
1356         }
1357         dprintf("Logging to %s", TypeNames[f->f_type]);
1358         f->f_time = now;
1359
1360         switch (f->f_type) {
1361         case F_UNUSED:
1362                 dprintf("\n");
1363                 break;
1364
1365         case F_FORW:
1366                 dprintf(" %s", f->fu_forw_hname);
1367                 switch (f->fu_forw_addr->ai_addr->sa_family) {
1368 #ifdef INET
1369                 case AF_INET:
1370                         dprintf(":%d\n",
1371                             ntohs(satosin(f->fu_forw_addr->ai_addr)->sin_port));
1372                         break;
1373 #endif
1374 #ifdef INET6
1375                 case AF_INET6:
1376                         dprintf(":%d\n",
1377                             ntohs(satosin6(f->fu_forw_addr->ai_addr)->sin6_port));
1378                         break;
1379 #endif
1380                 default:
1381                         dprintf("\n");
1382                 }
1383                 /* check for local vs remote messages */
1384                 if (strcasecmp(f->f_prevhost, LocalHostName))
1385                         l = snprintf(line, sizeof line - 1,
1386                             "<%d>%.15s Forwarded from %s: %s",
1387                             f->f_prevpri, (char *)iov[0].iov_base,
1388                             f->f_prevhost, (char *)iov[5].iov_base);
1389                 else
1390                         l = snprintf(line, sizeof line - 1, "<%d>%.15s %s",
1391                              f->f_prevpri, (char *)iov[0].iov_base,
1392                             (char *)iov[5].iov_base);
1393                 if (l < 0)
1394                         l = 0;
1395                 else if (l > MAXLINE)
1396                         l = MAXLINE;
1397
1398                 for (r = f->fu_forw_addr; r; r = r->ai_next) {
1399                         struct socklist *sl;
1400
1401                         STAILQ_FOREACH(sl, &shead, next) {
1402                                 if (sl->sl_ss.ss_family == AF_LOCAL ||
1403                                     sl->sl_ss.ss_family == AF_UNSPEC ||
1404                                     sl->sl_socket < 0)
1405                                         continue;
1406                                 lsent = sendto(sl->sl_socket, line, l, 0,
1407                                     r->ai_addr, r->ai_addrlen);
1408                                 if (lsent == l)
1409                                         break;
1410                         }
1411                         if (lsent == l && !send_to_all)
1412                                 break;
1413                 }
1414                 dprintf("lsent/l: %d/%d\n", lsent, l);
1415                 if (lsent != l) {
1416                         int e = errno;
1417                         logerror("sendto");
1418                         errno = e;
1419                         switch (errno) {
1420                         case ENOBUFS:
1421                         case ENETDOWN:
1422                         case ENETUNREACH:
1423                         case EHOSTUNREACH:
1424                         case EHOSTDOWN:
1425                         case EADDRNOTAVAIL:
1426                                 break;
1427                         /* case EBADF: */
1428                         /* case EACCES: */
1429                         /* case ENOTSOCK: */
1430                         /* case EFAULT: */
1431                         /* case EMSGSIZE: */
1432                         /* case EAGAIN: */
1433                         /* case ENOBUFS: */
1434                         /* case ECONNREFUSED: */
1435                         default:
1436                                 dprintf("removing entry: errno=%d\n", e);
1437                                 f->f_type = F_UNUSED;
1438                                 break;
1439                         }
1440                 }
1441                 break;
1442
1443         case F_FILE:
1444                 dprintf(" %s\n", f->fu_fname);
1445                 iov[6] = (struct iovec){
1446                         .iov_base = lf,
1447                         .iov_len = 1
1448                 };
1449                 if (writev(f->f_file, iov, nitems(iov)) < 0) {
1450                         /*
1451                          * If writev(2) fails for potentially transient errors
1452                          * like the filesystem being full, ignore it.
1453                          * Otherwise remove this logfile from the list.
1454                          */
1455                         if (errno != ENOSPC) {
1456                                 int e = errno;
1457                                 close_filed(f);
1458                                 errno = e;
1459                                 logerror(f->fu_fname);
1460                         }
1461                 } else if ((flags & SYNC_FILE) && (f->f_flags & FFLAG_SYNC)) {
1462                         f->f_flags |= FFLAG_NEEDSYNC;
1463                         needdofsync = 1;
1464                 }
1465                 break;
1466
1467         case F_PIPE:
1468                 dprintf(" %s\n", f->fu_pipe_pname);
1469                 iov[6] = (struct iovec){
1470                         .iov_base = lf,
1471                         .iov_len = 1
1472                 };
1473                 if (f->fu_pipe_pid == 0) {
1474                         if ((f->f_file = p_open(f->fu_pipe_pname,
1475                                                 &f->fu_pipe_pid)) < 0) {
1476                                 logerror(f->fu_pipe_pname);
1477                                 break;
1478                         }
1479                 }
1480                 if (writev(f->f_file, iov, nitems(iov)) < 0) {
1481                         int e = errno;
1482
1483                         deadq_enter(f->fu_pipe_pid, f->fu_pipe_pname);
1484                         close_filed(f);
1485                         errno = e;
1486                         logerror(f->fu_pipe_pname);
1487                 }
1488                 break;
1489
1490         case F_CONSOLE:
1491                 if (flags & IGN_CONS) {
1492                         dprintf(" (ignored)\n");
1493                         break;
1494                 }
1495                 /* FALLTHROUGH */
1496
1497         case F_TTY:
1498                 dprintf(" %s%s\n", _PATH_DEV, f->fu_fname);
1499                 iov[6] = (struct iovec){
1500                         .iov_base = crlf,
1501                         .iov_len = 2
1502                 };
1503                 errno = 0;      /* ttymsg() only sometimes returns an errno */
1504                 if ((msgret = ttymsg(iov, nitems(iov), f->fu_fname, 10))) {
1505                         f->f_type = F_UNUSED;
1506                         logerror(msgret);
1507                 }
1508                 break;
1509
1510         case F_USERS:
1511         case F_WALL:
1512                 dprintf("\n");
1513                 iov[6] = (struct iovec){
1514                         .iov_base = crlf,
1515                         .iov_len = 2
1516                 };
1517                 wallmsg(f, iov, nitems(iov));
1518                 break;
1519         }
1520         f->f_prevcount = 0;
1521         free(wmsg);
1522 }
1523
1524 /*
1525  *  WALLMSG -- Write a message to the world at large
1526  *
1527  *      Write the specified message to either the entire
1528  *      world, or a list of approved users.
1529  */
1530 static void
1531 wallmsg(struct filed *f, struct iovec *iov, const int iovlen)
1532 {
1533         static int reenter;                     /* avoid calling ourselves */
1534         struct utmpx *ut;
1535         int i;
1536         const char *p;
1537
1538         if (reenter++)
1539                 return;
1540         setutxent();
1541         /* NOSTRICT */
1542         while ((ut = getutxent()) != NULL) {
1543                 if (ut->ut_type != USER_PROCESS)
1544                         continue;
1545                 if (f->f_type == F_WALL) {
1546                         if ((p = ttymsg(iov, iovlen, ut->ut_line,
1547                             TTYMSGTIME)) != NULL) {
1548                                 errno = 0;      /* already in msg */
1549                                 logerror(p);
1550                         }
1551                         continue;
1552                 }
1553                 /* should we send the message to this user? */
1554                 for (i = 0; i < MAXUNAMES; i++) {
1555                         if (!f->fu_uname[i][0])
1556                                 break;
1557                         if (!strcmp(f->fu_uname[i], ut->ut_user)) {
1558                                 if ((p = ttymsg_check(iov, iovlen, ut->ut_line,
1559                                     TTYMSGTIME)) != NULL) {
1560                                         errno = 0;      /* already in msg */
1561                                         logerror(p);
1562                                 }
1563                                 break;
1564                         }
1565                 }
1566         }
1567         endutxent();
1568         reenter = 0;
1569 }
1570
1571 /*
1572  * Wrapper routine for ttymsg() that checks the terminal for messages enabled.
1573  */
1574 static const char *
1575 ttymsg_check(struct iovec *iov, int iovcnt, char *line, int tmout)
1576 {
1577         static char device[1024];
1578         static char errbuf[1024];
1579         struct stat sb;
1580
1581         (void) snprintf(device, sizeof(device), "%s%s", _PATH_DEV, line);
1582
1583         if (stat(device, &sb) < 0) {
1584                 (void) snprintf(errbuf, sizeof(errbuf),
1585                     "%s: %s", device, strerror(errno));
1586                 return (errbuf);
1587         }
1588         if ((sb.st_mode & S_IWGRP) == 0)
1589                 /* Messages disabled. */
1590                 return (NULL);
1591         return ttymsg(iov, iovcnt, line, tmout);
1592 }
1593
1594 static void
1595 reapchild(int signo __unused)
1596 {
1597         int status;
1598         pid_t pid;
1599         struct filed *f;
1600
1601         while ((pid = wait3(&status, WNOHANG, (struct rusage *)NULL)) > 0) {
1602                 /* First, look if it's a process from the dead queue. */
1603                 if (deadq_removebypid(pid))
1604                         continue;
1605
1606                 /* Now, look in list of active processes. */
1607                 STAILQ_FOREACH(f, &fhead, next) {
1608                         if (f->f_type == F_PIPE &&
1609                             f->fu_pipe_pid == pid) {
1610                                 close_filed(f);
1611                                 log_deadchild(pid, status, f->fu_pipe_pname);
1612                                 break;
1613                         }
1614                 }
1615         }
1616         WantReapchild = 0;
1617 }
1618
1619 /*
1620  * Return a printable representation of a host address.
1621  */
1622 static const char *
1623 cvthname(struct sockaddr *f)
1624 {
1625         int error, hl;
1626         static char hname[NI_MAXHOST], ip[NI_MAXHOST];
1627
1628         dprintf("cvthname(%d) len = %d\n", f->sa_family, f->sa_len);
1629         error = getnameinfo(f, f->sa_len, ip, sizeof(ip), NULL, 0,
1630                     NI_NUMERICHOST);
1631         if (error) {
1632                 dprintf("Malformed from address %s\n", gai_strerror(error));
1633                 return ("???");
1634         }
1635         dprintf("cvthname(%s)\n", ip);
1636
1637         if (!resolve)
1638                 return (ip);
1639
1640         error = getnameinfo(f, f->sa_len, hname, sizeof(hname),
1641                     NULL, 0, NI_NAMEREQD);
1642         if (error) {
1643                 dprintf("Host name for your address (%s) unknown\n", ip);
1644                 return (ip);
1645         }
1646         hl = strlen(hname);
1647         if (hl > 0 && hname[hl-1] == '.')
1648                 hname[--hl] = '\0';
1649         trimdomain(hname, hl);
1650         return (hname);
1651 }
1652
1653 static void
1654 dodie(int signo)
1655 {
1656
1657         WantDie = signo;
1658 }
1659
1660 static void
1661 domark(int signo __unused)
1662 {
1663
1664         MarkSet = 1;
1665 }
1666
1667 /*
1668  * Print syslogd errors some place.
1669  */
1670 static void
1671 logerror(const char *type)
1672 {
1673         char buf[512];
1674         static int recursed = 0;
1675
1676         /* If there's an error while trying to log an error, give up. */
1677         if (recursed)
1678                 return;
1679         recursed++;
1680         if (errno)
1681                 (void)snprintf(buf,
1682                     sizeof buf, "syslogd: %s: %s", type, strerror(errno));
1683         else
1684                 (void)snprintf(buf, sizeof buf, "syslogd: %s", type);
1685         errno = 0;
1686         dprintf("%s\n", buf);
1687         logmsg(LOG_SYSLOG|LOG_ERR, NULL, buf, LocalHostName, 0);
1688         recursed--;
1689 }
1690
1691 static void
1692 die(int signo)
1693 {
1694         struct filed *f;
1695         struct socklist *sl;
1696         char buf[100];
1697
1698         STAILQ_FOREACH(f, &fhead, next) {
1699                 /* flush any pending output */
1700                 if (f->f_prevcount)
1701                         fprintlog(f, 0, (char *)NULL);
1702                 if (f->f_type == F_PIPE && f->fu_pipe_pid > 0)
1703                         close_filed(f);
1704         }
1705         if (signo) {
1706                 dprintf("syslogd: exiting on signal %d\n", signo);
1707                 (void)snprintf(buf, sizeof(buf), "exiting on signal %d", signo);
1708                 errno = 0;
1709                 logerror(buf);
1710         }
1711         STAILQ_FOREACH(sl, &shead, next) {
1712                 if (sl->sl_ss.ss_family == AF_LOCAL)
1713                         unlink(sl->sl_peer->pe_name);
1714         }
1715         pidfile_remove(pfh);
1716
1717         exit(1);
1718 }
1719
1720 static int
1721 configfiles(const struct dirent *dp)
1722 {
1723         const char *p;
1724         size_t ext_len;
1725
1726         if (dp->d_name[0] == '.')
1727                 return (0);
1728
1729         ext_len = sizeof(include_ext) -1;
1730
1731         if (dp->d_namlen <= ext_len)
1732                 return (0);
1733
1734         p = &dp->d_name[dp->d_namlen - ext_len];
1735         if (strcmp(p, include_ext) != 0)
1736                 return (0);
1737
1738         return (1);
1739 }
1740
1741 static void
1742 readconfigfile(FILE *cf, int allow_includes)
1743 {
1744         FILE *cf2;
1745         struct filed *f;
1746         struct dirent **ent;
1747         char cline[LINE_MAX];
1748         char host[MAXHOSTNAMELEN];
1749         char prog[LINE_MAX];
1750         char file[MAXPATHLEN];
1751         char *p, *tmp;
1752         int i, nents;
1753         size_t include_len;
1754
1755         /*
1756          *  Foreach line in the conf table, open that file.
1757          */
1758         include_len = sizeof(include_str) -1;
1759         (void)strlcpy(host, "*", sizeof(host));
1760         (void)strlcpy(prog, "*", sizeof(prog));
1761         while (fgets(cline, sizeof(cline), cf) != NULL) {
1762                 /*
1763                  * check for end-of-section, comments, strip off trailing
1764                  * spaces and newline character. #!prog is treated specially:
1765                  * following lines apply only to that program.
1766                  */
1767                 for (p = cline; isspace(*p); ++p)
1768                         continue;
1769                 if (*p == 0)
1770                         continue;
1771                 if (allow_includes &&
1772                     strncmp(p, include_str, include_len) == 0 &&
1773                     isspace(p[include_len])) {
1774                         p += include_len;
1775                         while (isspace(*p))
1776                                 p++;
1777                         tmp = p;
1778                         while (*tmp != '\0' && !isspace(*tmp))
1779                                 tmp++;
1780                         *tmp = '\0';
1781                         dprintf("Trying to include files in '%s'\n", p);
1782                         nents = scandir(p, &ent, configfiles, alphasort);
1783                         if (nents == -1) {
1784                                 dprintf("Unable to open '%s': %s\n", p,
1785                                     strerror(errno));
1786                                 continue;
1787                         }
1788                         for (i = 0; i < nents; i++) {
1789                                 if (snprintf(file, sizeof(file), "%s/%s", p,
1790                                     ent[i]->d_name) >= (int)sizeof(file)) {
1791                                         dprintf("ignoring path too long: "
1792                                             "'%s/%s'\n", p, ent[i]->d_name);
1793                                         free(ent[i]);
1794                                         continue;
1795                                 }
1796                                 free(ent[i]);
1797                                 cf2 = fopen(file, "r");
1798                                 if (cf2 == NULL)
1799                                         continue;
1800                                 dprintf("reading %s\n", file);
1801                                 readconfigfile(cf2, 0);
1802                                 fclose(cf2);
1803                         }
1804                         free(ent);
1805                         continue;
1806                 }
1807                 if (*p == '#') {
1808                         p++;
1809                         if (*p != '!' && *p != '+' && *p != '-')
1810                                 continue;
1811                 }
1812                 if (*p == '+' || *p == '-') {
1813                         host[0] = *p++;
1814                         while (isspace(*p))
1815                                 p++;
1816                         if ((!*p) || (*p == '*')) {
1817                                 (void)strlcpy(host, "*", sizeof(host));
1818                                 continue;
1819                         }
1820                         if (*p == '@')
1821                                 p = LocalHostName;
1822                         for (i = 1; i < MAXHOSTNAMELEN - 1; i++) {
1823                                 if (!isalnum(*p) && *p != '.' && *p != '-'
1824                                     && *p != ',' && *p != ':' && *p != '%')
1825                                         break;
1826                                 host[i] = *p++;
1827                         }
1828                         host[i] = '\0';
1829                         continue;
1830                 }
1831                 if (*p == '!') {
1832                         p++;
1833                         while (isspace(*p)) p++;
1834                         if ((!*p) || (*p == '*')) {
1835                                 (void)strlcpy(prog, "*", sizeof(prog));
1836                                 continue;
1837                         }
1838                         for (i = 0; i < LINE_MAX - 1; i++) {
1839                                 if (!isprint(p[i]) || isspace(p[i]))
1840                                         break;
1841                                 prog[i] = p[i];
1842                         }
1843                         prog[i] = 0;
1844                         continue;
1845                 }
1846                 for (p = cline + 1; *p != '\0'; p++) {
1847                         if (*p != '#')
1848                                 continue;
1849                         if (*(p - 1) == '\\') {
1850                                 strcpy(p - 1, p);
1851                                 p--;
1852                                 continue;
1853                         }
1854                         *p = '\0';
1855                         break;
1856                 }
1857                 for (i = strlen(cline) - 1; i >= 0 && isspace(cline[i]); i--)
1858                         cline[i] = '\0';
1859                 f = cfline(cline, prog, host);
1860                 if (f != NULL)
1861                         addfile(f);
1862         }
1863 }
1864
1865 static void
1866 sighandler(int signo)
1867 {
1868
1869         /* Send an wake-up signal to the select() loop. */
1870         write(sigpipe[1], &signo, sizeof(signo));
1871 }
1872
1873 /*
1874  *  INIT -- Initialize syslogd from configuration table
1875  */
1876 static void
1877 init(int signo)
1878 {
1879         int i;
1880         FILE *cf;
1881         struct filed *f;
1882         char *p;
1883         char oldLocalHostName[MAXHOSTNAMELEN];
1884         char hostMsg[2*MAXHOSTNAMELEN+40];
1885         char bootfileMsg[LINE_MAX];
1886
1887         dprintf("init\n");
1888         WantInitialize = 0;
1889
1890         /*
1891          * Load hostname (may have changed).
1892          */
1893         if (signo != 0)
1894                 (void)strlcpy(oldLocalHostName, LocalHostName,
1895                     sizeof(oldLocalHostName));
1896         if (gethostname(LocalHostName, sizeof(LocalHostName)))
1897                 err(EX_OSERR, "gethostname() failed");
1898         if ((p = strchr(LocalHostName, '.')) != NULL) {
1899                 *p++ = '\0';
1900                 LocalDomain = p;
1901         } else {
1902                 LocalDomain = "";
1903         }
1904
1905         /*
1906          * Load / reload timezone data (in case it changed).
1907          *
1908          * Just calling tzset() again does not work, the timezone code
1909          * caches the result.  However, by setting the TZ variable, one
1910          * can defeat the caching and have the timezone code really
1911          * reload the timezone data.  Respect any initial setting of
1912          * TZ, in case the system is configured specially.
1913          */
1914         dprintf("loading timezone data via tzset()\n");
1915         if (getenv("TZ")) {
1916                 tzset();
1917         } else {
1918                 setenv("TZ", ":/etc/localtime", 1);
1919                 tzset();
1920                 unsetenv("TZ");
1921         }
1922
1923         /*
1924          *  Close all open log files.
1925          */
1926         Initialized = 0;
1927         STAILQ_FOREACH(f, &fhead, next) {
1928                 /* flush any pending output */
1929                 if (f->f_prevcount)
1930                         fprintlog(f, 0, (char *)NULL);
1931
1932                 switch (f->f_type) {
1933                 case F_FILE:
1934                 case F_FORW:
1935                 case F_CONSOLE:
1936                 case F_TTY:
1937                         close_filed(f);
1938                         break;
1939                 case F_PIPE:
1940                         deadq_enter(f->fu_pipe_pid, f->fu_pipe_pname);
1941                         close_filed(f);
1942                         break;
1943                 }
1944         }
1945         while(!STAILQ_EMPTY(&fhead)) {
1946                 f = STAILQ_FIRST(&fhead);
1947                 STAILQ_REMOVE_HEAD(&fhead, next);
1948                 free(f->f_program);
1949                 free(f->f_host);
1950                 free(f);
1951         }
1952
1953         /* open the configuration file */
1954         if ((cf = fopen(ConfFile, "r")) == NULL) {
1955                 dprintf("cannot open %s\n", ConfFile);
1956                 f = cfline("*.ERR\t/dev/console", "*", "*");
1957                 if (f != NULL)
1958                         addfile(f);
1959                 f = cfline("*.PANIC\t*", "*", "*");
1960                 if (f != NULL)
1961                         addfile(f);
1962                 Initialized = 1;
1963
1964                 return;
1965         }
1966
1967         readconfigfile(cf, 1);
1968
1969         /* close the configuration file */
1970         (void)fclose(cf);
1971
1972         Initialized = 1;
1973
1974         if (Debug) {
1975                 int port;
1976                 STAILQ_FOREACH(f, &fhead, next) {
1977                         for (i = 0; i <= LOG_NFACILITIES; i++)
1978                                 if (f->f_pmask[i] == INTERNAL_NOPRI)
1979                                         printf("X ");
1980                                 else
1981                                         printf("%d ", f->f_pmask[i]);
1982                         printf("%s: ", TypeNames[f->f_type]);
1983                         switch (f->f_type) {
1984                         case F_FILE:
1985                                 printf("%s", f->fu_fname);
1986                                 break;
1987
1988                         case F_CONSOLE:
1989                         case F_TTY:
1990                                 printf("%s%s", _PATH_DEV, f->fu_fname);
1991                                 break;
1992
1993                         case F_FORW:
1994                                 switch (f->fu_forw_addr->ai_addr->sa_family) {
1995 #ifdef INET
1996                                 case AF_INET:
1997                                         port = ntohs(satosin(f->fu_forw_addr->ai_addr)->sin_port);
1998                                         break;
1999 #endif
2000 #ifdef INET6
2001                                 case AF_INET6:
2002                                         port = ntohs(satosin6(f->fu_forw_addr->ai_addr)->sin6_port);
2003                                         break;
2004 #endif
2005                                 default:
2006                                         port = 0;
2007                                 }
2008                                 if (port != 514) {
2009                                         printf("%s:%d",
2010                                                 f->fu_forw_hname, port);
2011                                 } else {
2012                                         printf("%s", f->fu_forw_hname);
2013                                 }
2014                                 break;
2015
2016                         case F_PIPE:
2017                                 printf("%s", f->fu_pipe_pname);
2018                                 break;
2019
2020                         case F_USERS:
2021                                 for (i = 0; i < MAXUNAMES && *f->fu_uname[i]; i++)
2022                                         printf("%s, ", f->fu_uname[i]);
2023                                 break;
2024                         }
2025                         if (f->f_program)
2026                                 printf(" (%s)", f->f_program);
2027                         printf("\n");
2028                 }
2029         }
2030
2031         logmsg(LOG_SYSLOG|LOG_INFO, NULL, "syslogd: restart", LocalHostName, 0);
2032         dprintf("syslogd: restarted\n");
2033         /*
2034          * Log a change in hostname, but only on a restart.
2035          */
2036         if (signo != 0 && strcmp(oldLocalHostName, LocalHostName) != 0) {
2037                 (void)snprintf(hostMsg, sizeof(hostMsg),
2038                     "syslogd: hostname changed, \"%s\" to \"%s\"",
2039                     oldLocalHostName, LocalHostName);
2040                 logmsg(LOG_SYSLOG|LOG_INFO, NULL, hostMsg, LocalHostName, 0);
2041                 dprintf("%s\n", hostMsg);
2042         }
2043         /*
2044          * Log the kernel boot file if we aren't going to use it as
2045          * the prefix, and if this is *not* a restart.
2046          */
2047         if (signo == 0 && !use_bootfile) {
2048                 (void)snprintf(bootfileMsg, sizeof(bootfileMsg),
2049                     "syslogd: kernel boot file is %s", bootfile);
2050                 logmsg(LOG_KERN|LOG_INFO, NULL, bootfileMsg, LocalHostName, 0);
2051                 dprintf("%s\n", bootfileMsg);
2052         }
2053 }
2054
2055 /*
2056  * Crack a configuration file line
2057  */
2058 static struct filed *
2059 cfline(const char *line, const char *prog, const char *host)
2060 {
2061         struct filed *f;
2062         struct addrinfo hints, *res;
2063         int error, i, pri, syncfile;
2064         const char *p, *q;
2065         char *bp;
2066         char buf[MAXLINE], ebuf[100];
2067
2068         dprintf("cfline(\"%s\", f, \"%s\", \"%s\")\n", line, prog, host);
2069
2070         f = calloc(1, sizeof(*f));
2071         if (f == NULL) {
2072                 logerror("malloc");
2073                 exit(1);
2074         }
2075         errno = 0;      /* keep strerror() stuff out of logerror messages */
2076
2077         for (i = 0; i <= LOG_NFACILITIES; i++)
2078                 f->f_pmask[i] = INTERNAL_NOPRI;
2079
2080         /* save hostname if any */
2081         if (host && *host == '*')
2082                 host = NULL;
2083         if (host) {
2084                 int hl;
2085
2086                 f->f_host = strdup(host);
2087                 if (f->f_host == NULL) {
2088                         logerror("strdup");
2089                         exit(1);
2090                 }
2091                 hl = strlen(f->f_host);
2092                 if (hl > 0 && f->f_host[hl-1] == '.')
2093                         f->f_host[--hl] = '\0';
2094                 trimdomain(f->f_host, hl);
2095         }
2096
2097         /* save program name if any */
2098         if (prog && *prog == '*')
2099                 prog = NULL;
2100         if (prog) {
2101                 f->f_program = strdup(prog);
2102                 if (f->f_program == NULL) {
2103                         logerror("strdup");
2104                         exit(1);
2105                 }
2106         }
2107
2108         /* scan through the list of selectors */
2109         for (p = line; *p && *p != '\t' && *p != ' ';) {
2110                 int pri_done;
2111                 int pri_cmp;
2112                 int pri_invert;
2113
2114                 /* find the end of this facility name list */
2115                 for (q = p; *q && *q != '\t' && *q != ' ' && *q++ != '.'; )
2116                         continue;
2117
2118                 /* get the priority comparison */
2119                 pri_cmp = 0;
2120                 pri_done = 0;
2121                 pri_invert = 0;
2122                 if (*q == '!') {
2123                         pri_invert = 1;
2124                         q++;
2125                 }
2126                 while (!pri_done) {
2127                         switch (*q) {
2128                         case '<':
2129                                 pri_cmp |= PRI_LT;
2130                                 q++;
2131                                 break;
2132                         case '=':
2133                                 pri_cmp |= PRI_EQ;
2134                                 q++;
2135                                 break;
2136                         case '>':
2137                                 pri_cmp |= PRI_GT;
2138                                 q++;
2139                                 break;
2140                         default:
2141                                 pri_done++;
2142                                 break;
2143                         }
2144                 }
2145
2146                 /* collect priority name */
2147                 for (bp = buf; *q && !strchr("\t,; ", *q); )
2148                         *bp++ = *q++;
2149                 *bp = '\0';
2150
2151                 /* skip cruft */
2152                 while (strchr(",;", *q))
2153                         q++;
2154
2155                 /* decode priority name */
2156                 if (*buf == '*') {
2157                         pri = LOG_PRIMASK;
2158                         pri_cmp = PRI_LT | PRI_EQ | PRI_GT;
2159                 } else {
2160                         /* Ignore trailing spaces. */
2161                         for (i = strlen(buf) - 1; i >= 0 && buf[i] == ' '; i--)
2162                                 buf[i] = '\0';
2163
2164                         pri = decode(buf, prioritynames);
2165                         if (pri < 0) {
2166                                 errno = 0;
2167                                 (void)snprintf(ebuf, sizeof ebuf,
2168                                     "unknown priority name \"%s\"", buf);
2169                                 logerror(ebuf);
2170                                 free(f);
2171                                 return (NULL);
2172                         }
2173                 }
2174                 if (!pri_cmp)
2175                         pri_cmp = (UniquePriority)
2176                                   ? (PRI_EQ)
2177                                   : (PRI_EQ | PRI_GT)
2178                                   ;
2179                 if (pri_invert)
2180                         pri_cmp ^= PRI_LT | PRI_EQ | PRI_GT;
2181
2182                 /* scan facilities */
2183                 while (*p && !strchr("\t.; ", *p)) {
2184                         for (bp = buf; *p && !strchr("\t,;. ", *p); )
2185                                 *bp++ = *p++;
2186                         *bp = '\0';
2187
2188                         if (*buf == '*') {
2189                                 for (i = 0; i < LOG_NFACILITIES; i++) {
2190                                         f->f_pmask[i] = pri;
2191                                         f->f_pcmp[i] = pri_cmp;
2192                                 }
2193                         } else {
2194                                 i = decode(buf, facilitynames);
2195                                 if (i < 0) {
2196                                         errno = 0;
2197                                         (void)snprintf(ebuf, sizeof ebuf,
2198                                             "unknown facility name \"%s\"",
2199                                             buf);
2200                                         logerror(ebuf);
2201                                         free(f);
2202                                         return (NULL);
2203                                 }
2204                                 f->f_pmask[i >> 3] = pri;
2205                                 f->f_pcmp[i >> 3] = pri_cmp;
2206                         }
2207                         while (*p == ',' || *p == ' ')
2208                                 p++;
2209                 }
2210
2211                 p = q;
2212         }
2213
2214         /* skip to action part */
2215         while (*p == '\t' || *p == ' ')
2216                 p++;
2217
2218         if (*p == '-') {
2219                 syncfile = 0;
2220                 p++;
2221         } else
2222                 syncfile = 1;
2223
2224         switch (*p) {
2225         case '@':
2226                 {
2227                         char *tp;
2228                         char endkey = ':';
2229                         /*
2230                          * scan forward to see if there is a port defined.
2231                          * so we can't use strlcpy..
2232                          */
2233                         i = sizeof(f->fu_forw_hname);
2234                         tp = f->fu_forw_hname;
2235                         p++;
2236
2237                         /*
2238                          * an ipv6 address should start with a '[' in that case
2239                          * we should scan for a ']'
2240                          */
2241                         if (*p == '[') {
2242                                 p++;
2243                                 endkey = ']';
2244                         }
2245                         while (*p && (*p != endkey) && (i-- > 0)) {
2246                                 *tp++ = *p++;
2247                         }
2248                         if (endkey == ']' && *p == endkey)
2249                                 p++;
2250                         *tp = '\0';
2251                 }
2252                 /* See if we copied a domain and have a port */
2253                 if (*p == ':')
2254                         p++;
2255                 else
2256                         p = NULL;
2257
2258                 hints = (struct addrinfo){
2259                         .ai_family = family,
2260                         .ai_socktype = SOCK_DGRAM
2261                 };
2262                 error = getaddrinfo(f->fu_forw_hname,
2263                                 p ? p : "syslog", &hints, &res);
2264                 if (error) {
2265                         logerror(gai_strerror(error));
2266                         break;
2267                 }
2268                 f->fu_forw_addr = res;
2269                 f->f_type = F_FORW;
2270                 break;
2271
2272         case '/':
2273                 if ((f->f_file = open(p, logflags, 0600)) < 0) {
2274                         f->f_type = F_UNUSED;
2275                         logerror(p);
2276                         break;
2277                 }
2278                 if (syncfile)
2279                         f->f_flags |= FFLAG_SYNC;
2280                 if (isatty(f->f_file)) {
2281                         if (strcmp(p, ctty) == 0)
2282                                 f->f_type = F_CONSOLE;
2283                         else
2284                                 f->f_type = F_TTY;
2285                         (void)strlcpy(f->fu_fname, p + sizeof(_PATH_DEV) - 1,
2286                             sizeof(f->fu_fname));
2287                 } else {
2288                         (void)strlcpy(f->fu_fname, p, sizeof(f->fu_fname));
2289                         f->f_type = F_FILE;
2290                 }
2291                 break;
2292
2293         case '|':
2294                 f->fu_pipe_pid = 0;
2295                 (void)strlcpy(f->fu_pipe_pname, p + 1,
2296                     sizeof(f->fu_pipe_pname));
2297                 f->f_type = F_PIPE;
2298                 break;
2299
2300         case '*':
2301                 f->f_type = F_WALL;
2302                 break;
2303
2304         default:
2305                 for (i = 0; i < MAXUNAMES && *p; i++) {
2306                         for (q = p; *q && *q != ','; )
2307                                 q++;
2308                         (void)strncpy(f->fu_uname[i], p, MAXLOGNAME - 1);
2309                         if ((q - p) >= MAXLOGNAME)
2310                                 f->fu_uname[i][MAXLOGNAME - 1] = '\0';
2311                         else
2312                                 f->fu_uname[i][q - p] = '\0';
2313                         while (*q == ',' || *q == ' ')
2314                                 q++;
2315                         p = q;
2316                 }
2317                 f->f_type = F_USERS;
2318                 break;
2319         }
2320         return (f);
2321 }
2322
2323
2324 /*
2325  *  Decode a symbolic name to a numeric value
2326  */
2327 static int
2328 decode(const char *name, const CODE *codetab)
2329 {
2330         const CODE *c;
2331         char *p, buf[40];
2332
2333         if (isdigit(*name))
2334                 return (atoi(name));
2335
2336         for (p = buf; *name && p < &buf[sizeof(buf) - 1]; p++, name++) {
2337                 if (isupper(*name))
2338                         *p = tolower(*name);
2339                 else
2340                         *p = *name;
2341         }
2342         *p = '\0';
2343         for (c = codetab; c->c_name; c++)
2344                 if (!strcmp(buf, c->c_name))
2345                         return (c->c_val);
2346
2347         return (-1);
2348 }
2349
2350 static void
2351 markit(void)
2352 {
2353         struct filed *f;
2354         struct deadq_entry *dq, *dq0;
2355
2356         now = time((time_t *)NULL);
2357         MarkSeq += TIMERINTVL;
2358         if (MarkSeq >= MarkInterval) {
2359                 logmsg(LOG_INFO, NULL, "-- MARK --", LocalHostName, MARK);
2360                 MarkSeq = 0;
2361         }
2362
2363         STAILQ_FOREACH(f, &fhead, next) {
2364                 if (f->f_prevcount && now >= REPEATTIME(f)) {
2365                         dprintf("flush %s: repeated %d times, %d sec.\n",
2366                             TypeNames[f->f_type], f->f_prevcount,
2367                             repeatinterval[f->f_repeatcount]);
2368                         fprintlog(f, 0, (char *)NULL);
2369                         BACKOFF(f);
2370                 }
2371         }
2372
2373         /* Walk the dead queue, and see if we should signal somebody. */
2374         TAILQ_FOREACH_SAFE(dq, &deadq_head, dq_entries, dq0) {
2375                 switch (dq->dq_timeout) {
2376                 case 0:
2377                         /* Already signalled once, try harder now. */
2378                         if (kill(dq->dq_pid, SIGKILL) != 0)
2379                                 (void)deadq_remove(dq);
2380                         break;
2381
2382                 case 1:
2383                         /*
2384                          * Timed out on dead queue, send terminate
2385                          * signal.  Note that we leave the removal
2386                          * from the dead queue to reapchild(), which
2387                          * will also log the event (unless the process
2388                          * didn't even really exist, in case we simply
2389                          * drop it from the dead queue).
2390                          */
2391                         if (kill(dq->dq_pid, SIGTERM) != 0)
2392                                 (void)deadq_remove(dq);
2393                         else
2394                                 dq->dq_timeout--;
2395                         break;
2396                 default:
2397                         dq->dq_timeout--;
2398                 }
2399         }
2400         MarkSet = 0;
2401         (void)alarm(TIMERINTVL);
2402 }
2403
2404 /*
2405  * fork off and become a daemon, but wait for the child to come online
2406  * before returning to the parent, or we get disk thrashing at boot etc.
2407  * Set a timer so we don't hang forever if it wedges.
2408  */
2409 static int
2410 waitdaemon(int maxwait)
2411 {
2412         int fd;
2413         int status;
2414         pid_t pid, childpid;
2415
2416         switch (childpid = fork()) {
2417         case -1:
2418                 return (-1);
2419         case 0:
2420                 break;
2421         default:
2422                 signal(SIGALRM, timedout);
2423                 alarm(maxwait);
2424                 while ((pid = wait3(&status, 0, NULL)) != -1) {
2425                         if (WIFEXITED(status))
2426                                 errx(1, "child pid %d exited with return code %d",
2427                                         pid, WEXITSTATUS(status));
2428                         if (WIFSIGNALED(status))
2429                                 errx(1, "child pid %d exited on signal %d%s",
2430                                         pid, WTERMSIG(status),
2431                                         WCOREDUMP(status) ? " (core dumped)" :
2432                                         "");
2433                         if (pid == childpid)    /* it's gone... */
2434                                 break;
2435                 }
2436                 exit(0);
2437         }
2438
2439         if (setsid() == -1)
2440                 return (-1);
2441
2442         (void)chdir("/");
2443         if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
2444                 (void)dup2(fd, STDIN_FILENO);
2445                 (void)dup2(fd, STDOUT_FILENO);
2446                 (void)dup2(fd, STDERR_FILENO);
2447                 if (fd > STDERR_FILENO)
2448                         (void)close(fd);
2449         }
2450         return (getppid());
2451 }
2452
2453 /*
2454  * We get a SIGALRM from the child when it's running and finished doing it's
2455  * fsync()'s or O_SYNC writes for all the boot messages.
2456  *
2457  * We also get a signal from the kernel if the timer expires, so check to
2458  * see what happened.
2459  */
2460 static void
2461 timedout(int sig __unused)
2462 {
2463         int left;
2464         left = alarm(0);
2465         signal(SIGALRM, SIG_DFL);
2466         if (left == 0)
2467                 errx(1, "timed out waiting for child");
2468         else
2469                 _exit(0);
2470 }
2471
2472 /*
2473  * Add `s' to the list of allowable peer addresses to accept messages
2474  * from.
2475  *
2476  * `s' is a string in the form:
2477  *
2478  *    [*]domainname[:{servicename|portnumber|*}]
2479  *
2480  * or
2481  *
2482  *    netaddr/maskbits[:{servicename|portnumber|*}]
2483  *
2484  * Returns -1 on error, 0 if the argument was valid.
2485  */
2486 static int
2487 allowaddr(char *s)
2488 {
2489 #if defined(INET) || defined(INET6)
2490         char *cp1, *cp2;
2491         struct allowedpeer *ap;
2492         struct servent *se;
2493         int masklen = -1;
2494         struct addrinfo hints, *res = NULL;
2495 #ifdef INET
2496         in_addr_t *addrp, *maskp;
2497 #endif
2498 #ifdef INET6
2499         uint32_t *addr6p, *mask6p;
2500 #endif
2501         char ip[NI_MAXHOST];
2502
2503         ap = calloc(1, sizeof(*ap));
2504         if (ap == NULL)
2505                 err(1, "malloc failed");
2506
2507 #ifdef INET6
2508         if (*s != '[' || (cp1 = strchr(s + 1, ']')) == NULL)
2509 #endif
2510                 cp1 = s;
2511         if ((cp1 = strrchr(cp1, ':'))) {
2512                 /* service/port provided */
2513                 *cp1++ = '\0';
2514                 if (strlen(cp1) == 1 && *cp1 == '*')
2515                         /* any port allowed */
2516                         ap->port = 0;
2517                 else if ((se = getservbyname(cp1, "udp"))) {
2518                         ap->port = ntohs(se->s_port);
2519                 } else {
2520                         ap->port = strtol(cp1, &cp2, 0);
2521                         /* port not numeric */
2522                         if (*cp2 != '\0')
2523                                 goto err;
2524                 }
2525         } else {
2526                 if ((se = getservbyname("syslog", "udp")))
2527                         ap->port = ntohs(se->s_port);
2528                 else
2529                         /* sanity, should not happen */
2530                         ap->port = 514;
2531         }
2532
2533         if ((cp1 = strchr(s, '/')) != NULL &&
2534             strspn(cp1 + 1, "0123456789") == strlen(cp1 + 1)) {
2535                 *cp1 = '\0';
2536                 if ((masklen = atoi(cp1 + 1)) < 0)
2537                         goto err;
2538         }
2539 #ifdef INET6
2540         if (*s == '[') {
2541                 cp2 = s + strlen(s) - 1;
2542                 if (*cp2 == ']') {
2543                         ++s;
2544                         *cp2 = '\0';
2545                 } else {
2546                         cp2 = NULL;
2547                 }
2548         } else {
2549                 cp2 = NULL;
2550         }
2551 #endif
2552         hints = (struct addrinfo){
2553                 .ai_family = PF_UNSPEC,
2554                 .ai_socktype = SOCK_DGRAM,
2555                 .ai_flags = AI_PASSIVE | AI_NUMERICHOST
2556         };
2557         if (getaddrinfo(s, NULL, &hints, &res) == 0) {
2558                 ap->isnumeric = 1;
2559                 memcpy(&ap->a_addr, res->ai_addr, res->ai_addrlen);
2560                 ap->a_mask = (struct sockaddr_storage){
2561                         .ss_family = res->ai_family,
2562                         .ss_len = res->ai_addrlen
2563                 };
2564                 switch (res->ai_family) {
2565 #ifdef INET
2566                 case AF_INET:
2567                         maskp = &sstosin(&ap->a_mask)->sin_addr.s_addr;
2568                         addrp = &sstosin(&ap->a_addr)->sin_addr.s_addr;
2569                         if (masklen < 0) {
2570                                 /* use default netmask */
2571                                 if (IN_CLASSA(ntohl(*addrp)))
2572                                         *maskp = htonl(IN_CLASSA_NET);
2573                                 else if (IN_CLASSB(ntohl(*addrp)))
2574                                         *maskp = htonl(IN_CLASSB_NET);
2575                                 else
2576                                         *maskp = htonl(IN_CLASSC_NET);
2577                         } else if (masklen == 0) {
2578                                 *maskp = 0;
2579                         } else if (masklen <= 32) {
2580                                 /* convert masklen to netmask */
2581                                 *maskp = htonl(~((1 << (32 - masklen)) - 1));
2582                         } else {
2583                                 goto err;
2584                         }
2585                         /* Lose any host bits in the network number. */
2586                         *addrp &= *maskp;
2587                         break;
2588 #endif
2589 #ifdef INET6
2590                 case AF_INET6:
2591                         if (masklen > 128)
2592                                 goto err;
2593
2594                         if (masklen < 0)
2595                                 masklen = 128;
2596                         mask6p = (uint32_t *)&sstosin6(&ap->a_mask)->sin6_addr.s6_addr32[0];
2597                         addr6p = (uint32_t *)&sstosin6(&ap->a_addr)->sin6_addr.s6_addr32[0];
2598                         /* convert masklen to netmask */
2599                         while (masklen > 0) {
2600                                 if (masklen < 32) {
2601                                         *mask6p =
2602                                             htonl(~(0xffffffff >> masklen));
2603                                         *addr6p &= *mask6p;
2604                                         break;
2605                                 } else {
2606                                         *mask6p++ = 0xffffffff;
2607                                         addr6p++;
2608                                         masklen -= 32;
2609                                 }
2610                         }
2611                         break;
2612 #endif
2613                 default:
2614                         goto err;
2615                 }
2616                 freeaddrinfo(res);
2617         } else {
2618                 /* arg `s' is domain name */
2619                 ap->isnumeric = 0;
2620                 ap->a_name = s;
2621                 if (cp1)
2622                         *cp1 = '/';
2623 #ifdef INET6
2624                 if (cp2) {
2625                         *cp2 = ']';
2626                         --s;
2627                 }
2628 #endif
2629         }
2630         STAILQ_INSERT_TAIL(&aphead, ap, next);
2631
2632         if (Debug) {
2633                 printf("allowaddr: rule ");
2634                 if (ap->isnumeric) {
2635                         printf("numeric, ");
2636                         getnameinfo(sstosa(&ap->a_addr),
2637                                     (sstosa(&ap->a_addr))->sa_len,
2638                                     ip, sizeof ip, NULL, 0, NI_NUMERICHOST);
2639                         printf("addr = %s, ", ip);
2640                         getnameinfo(sstosa(&ap->a_mask),
2641                                     (sstosa(&ap->a_mask))->sa_len,
2642                                     ip, sizeof ip, NULL, 0, NI_NUMERICHOST);
2643                         printf("mask = %s; ", ip);
2644                 } else {
2645                         printf("domainname = %s; ", ap->a_name);
2646                 }
2647                 printf("port = %d\n", ap->port);
2648         }
2649 #endif
2650
2651         return (0);
2652 err:
2653         if (res != NULL)
2654                 freeaddrinfo(res);
2655         free(ap);
2656         return (-1);
2657 }
2658
2659 /*
2660  * Validate that the remote peer has permission to log to us.
2661  */
2662 static int
2663 validate(struct sockaddr *sa, const char *hname)
2664 {
2665         int i;
2666         char name[NI_MAXHOST], ip[NI_MAXHOST], port[NI_MAXSERV];
2667         struct allowedpeer *ap;
2668 #ifdef INET
2669         struct sockaddr_in *sin4, *a4p = NULL, *m4p = NULL;
2670 #endif
2671 #ifdef INET6
2672         struct sockaddr_in6 *sin6, *a6p = NULL, *m6p = NULL;
2673 #endif
2674         struct addrinfo hints, *res;
2675         u_short sport;
2676         int num = 0;
2677
2678         STAILQ_FOREACH(ap, &aphead, next) {
2679                 num++;
2680         }
2681         dprintf("# of validation rule: %d\n", num);
2682         if (num == 0)
2683                 /* traditional behaviour, allow everything */
2684                 return (1);
2685
2686         (void)strlcpy(name, hname, sizeof(name));
2687         hints = (struct addrinfo){
2688                 .ai_family = PF_UNSPEC,
2689                 .ai_socktype = SOCK_DGRAM,
2690                 .ai_flags = AI_PASSIVE | AI_NUMERICHOST
2691         };
2692         if (getaddrinfo(name, NULL, &hints, &res) == 0)
2693                 freeaddrinfo(res);
2694         else if (strchr(name, '.') == NULL) {
2695                 strlcat(name, ".", sizeof name);
2696                 strlcat(name, LocalDomain, sizeof name);
2697         }
2698         if (getnameinfo(sa, sa->sa_len, ip, sizeof(ip), port, sizeof(port),
2699                         NI_NUMERICHOST | NI_NUMERICSERV) != 0)
2700                 return (0);     /* for safety, should not occur */
2701         dprintf("validate: dgram from IP %s, port %s, name %s;\n",
2702                 ip, port, name);
2703         sport = atoi(port);
2704
2705         /* now, walk down the list */
2706         i = 0;
2707         STAILQ_FOREACH(ap, &aphead, next) {
2708                 i++;
2709                 if (ap->port != 0 && ap->port != sport) {
2710                         dprintf("rejected in rule %d due to port mismatch.\n",
2711                             i);
2712                         continue;
2713                 }
2714
2715                 if (ap->isnumeric) {
2716                         if (ap->a_addr.ss_family != sa->sa_family) {
2717                                 dprintf("rejected in rule %d due to address family mismatch.\n", i);
2718                                 continue;
2719                         }
2720 #ifdef INET
2721                         else if (ap->a_addr.ss_family == AF_INET) {
2722                                 sin4 = satosin(sa);
2723                                 a4p = satosin(&ap->a_addr);
2724                                 m4p = satosin(&ap->a_mask);
2725                                 if ((sin4->sin_addr.s_addr & m4p->sin_addr.s_addr)
2726                                     != a4p->sin_addr.s_addr) {
2727                                         dprintf("rejected in rule %d due to IP mismatch.\n", i);
2728                                         continue;
2729                                 }
2730                         }
2731 #endif
2732 #ifdef INET6
2733                         else if (ap->a_addr.ss_family == AF_INET6) {
2734                                 sin6 = satosin6(sa);
2735                                 a6p = satosin6(&ap->a_addr);
2736                                 m6p = satosin6(&ap->a_mask);
2737                                 if (a6p->sin6_scope_id != 0 &&
2738                                     sin6->sin6_scope_id != a6p->sin6_scope_id) {
2739                                         dprintf("rejected in rule %d due to scope mismatch.\n", i);
2740                                         continue;
2741                                 }
2742                                 if (IN6_ARE_MASKED_ADDR_EQUAL(&sin6->sin6_addr,
2743                                     &a6p->sin6_addr, &m6p->sin6_addr) != 0) {
2744                                         dprintf("rejected in rule %d due to IP mismatch.\n", i);
2745                                         continue;
2746                                 }
2747                         }
2748 #endif
2749                         else
2750                                 continue;
2751                 } else {
2752                         if (fnmatch(ap->a_name, name, FNM_NOESCAPE) ==
2753                             FNM_NOMATCH) {
2754                                 dprintf("rejected in rule %d due to name "
2755                                     "mismatch.\n", i);
2756                                 continue;
2757                         }
2758                 }
2759                 dprintf("accepted in rule %d.\n", i);
2760                 return (1);     /* hooray! */
2761         }
2762         return (0);
2763 }
2764
2765 /*
2766  * Fairly similar to popen(3), but returns an open descriptor, as
2767  * opposed to a FILE *.
2768  */
2769 static int
2770 p_open(const char *prog, pid_t *rpid)
2771 {
2772         int pfd[2], nulldesc;
2773         pid_t pid;
2774         char *argv[4]; /* sh -c cmd NULL */
2775         char errmsg[200];
2776
2777         if (pipe(pfd) == -1)
2778                 return (-1);
2779         if ((nulldesc = open(_PATH_DEVNULL, O_RDWR)) == -1)
2780                 /* we are royally screwed anyway */
2781                 return (-1);
2782
2783         switch ((pid = fork())) {
2784         case -1:
2785                 close(nulldesc);
2786                 return (-1);
2787
2788         case 0:
2789                 (void)setsid(); /* Avoid catching SIGHUPs. */
2790                 argv[0] = strdup("sh");
2791                 argv[1] = strdup("-c");
2792                 argv[2] = strdup(prog);
2793                 argv[3] = NULL;
2794                 if (argv[0] == NULL || argv[1] == NULL || argv[2] == NULL) {
2795                         logerror("strdup");
2796                         exit(1);
2797                 }
2798
2799                 alarm(0);
2800
2801                 /* Restore signals marked as SIG_IGN. */
2802                 (void)signal(SIGINT, SIG_DFL);
2803                 (void)signal(SIGQUIT, SIG_DFL);
2804                 (void)signal(SIGPIPE, SIG_DFL);
2805
2806                 dup2(pfd[0], STDIN_FILENO);
2807                 dup2(nulldesc, STDOUT_FILENO);
2808                 dup2(nulldesc, STDERR_FILENO);
2809                 closefrom(STDERR_FILENO + 1);
2810
2811                 (void)execvp(_PATH_BSHELL, argv);
2812                 _exit(255);
2813         }
2814         close(nulldesc);
2815         close(pfd[0]);
2816         /*
2817          * Avoid blocking on a hung pipe.  With O_NONBLOCK, we are
2818          * supposed to get an EWOULDBLOCK on writev(2), which is
2819          * caught by the logic above anyway, which will in turn close
2820          * the pipe, and fork a new logging subprocess if necessary.
2821          * The stale subprocess will be killed some time later unless
2822          * it terminated itself due to closing its input pipe (so we
2823          * get rid of really dead puppies).
2824          */
2825         if (fcntl(pfd[1], F_SETFL, O_NONBLOCK) == -1) {
2826                 /* This is bad. */
2827                 (void)snprintf(errmsg, sizeof errmsg,
2828                                "Warning: cannot change pipe to PID %d to "
2829                                "non-blocking behaviour.",
2830                                (int)pid);
2831                 logerror(errmsg);
2832         }
2833         *rpid = pid;
2834         return (pfd[1]);
2835 }
2836
2837 static void
2838 deadq_enter(pid_t pid, const char *name)
2839 {
2840         struct deadq_entry *dq;
2841         int status;
2842
2843         if (pid == 0)
2844                 return;
2845         /*
2846          * Be paranoid, if we can't signal the process, don't enter it
2847          * into the dead queue (perhaps it's already dead).  If possible,
2848          * we try to fetch and log the child's status.
2849          */
2850         if (kill(pid, 0) != 0) {
2851                 if (waitpid(pid, &status, WNOHANG) > 0)
2852                         log_deadchild(pid, status, name);
2853                 return;
2854         }
2855
2856         dq = malloc(sizeof(*dq));
2857         if (dq == NULL) {
2858                 logerror("malloc");
2859                 exit(1);
2860         }
2861         *dq = (struct deadq_entry){
2862                 .dq_pid = pid,
2863                 .dq_timeout = DQ_TIMO_INIT
2864         };
2865         TAILQ_INSERT_TAIL(&deadq_head, dq, dq_entries);
2866 }
2867
2868 static int
2869 deadq_remove(struct deadq_entry *dq)
2870 {
2871         if (dq != NULL) {
2872                 TAILQ_REMOVE(&deadq_head, dq, dq_entries);
2873                 free(dq);
2874                 return (1);
2875         }
2876
2877         return (0);
2878 }
2879
2880 static int
2881 deadq_removebypid(pid_t pid)
2882 {
2883         struct deadq_entry *dq;
2884
2885         TAILQ_FOREACH(dq, &deadq_head, dq_entries) {
2886                 if (dq->dq_pid == pid)
2887                         break;
2888         }
2889         return (deadq_remove(dq));
2890 }
2891
2892 static void
2893 log_deadchild(pid_t pid, int status, const char *name)
2894 {
2895         int code;
2896         char buf[256];
2897         const char *reason;
2898
2899         errno = 0; /* Keep strerror() stuff out of logerror messages. */
2900         if (WIFSIGNALED(status)) {
2901                 reason = "due to signal";
2902                 code = WTERMSIG(status);
2903         } else {
2904                 reason = "with status";
2905                 code = WEXITSTATUS(status);
2906                 if (code == 0)
2907                         return;
2908         }
2909         (void)snprintf(buf, sizeof buf,
2910                        "Logging subprocess %d (%s) exited %s %d.",
2911                        pid, name, reason, code);
2912         logerror(buf);
2913 }
2914
2915 static int
2916 socksetup(struct peer *pe)
2917 {
2918         struct addrinfo hints, *res, *res0;
2919         int error;
2920         char *cp;
2921         int (*sl_recv)(struct socklist *);
2922         /*
2923          * We have to handle this case for backwards compatibility:
2924          * If there are two (or more) colons but no '[' and ']',
2925          * assume this is an inet6 address without a service.
2926          */
2927         if (pe->pe_name != NULL) {
2928 #ifdef INET6
2929                 if (pe->pe_name[0] == '[' &&
2930                     (cp = strchr(pe->pe_name + 1, ']')) != NULL) {
2931                         pe->pe_name = &pe->pe_name[1];
2932                         *cp = '\0';
2933                         if (cp[1] == ':' && cp[2] != '\0')
2934                                 pe->pe_serv = cp + 2;
2935                 } else {
2936 #endif
2937                         cp = strchr(pe->pe_name, ':');
2938                         if (cp != NULL && strchr(cp + 1, ':') == NULL) {
2939                                 *cp = '\0';
2940                                 if (cp[1] != '\0')
2941                                         pe->pe_serv = cp + 1;
2942                                 if (cp == pe->pe_name)
2943                                         pe->pe_name = NULL;
2944                         }
2945 #ifdef INET6
2946                 }
2947 #endif
2948         }
2949         hints = (struct addrinfo){
2950                 .ai_family = AF_UNSPEC,
2951                 .ai_socktype = SOCK_DGRAM,
2952                 .ai_flags = AI_PASSIVE
2953         };
2954         if (pe->pe_name != NULL)
2955                 dprintf("Trying peer: %s\n", pe->pe_name);
2956         if (pe->pe_serv == NULL)
2957                 pe->pe_serv = "syslog";
2958         error = getaddrinfo(pe->pe_name, pe->pe_serv, &hints, &res0);
2959         if (error) {
2960                 char *msgbuf;
2961
2962                 asprintf(&msgbuf, "getaddrinfo failed for %s%s: %s",
2963                     pe->pe_name == NULL ? "" : pe->pe_name, pe->pe_serv,
2964                     gai_strerror(error));
2965                 errno = 0;
2966                 if (msgbuf == NULL)
2967                         logerror(gai_strerror(error));
2968                 else
2969                         logerror(msgbuf);
2970                 free(msgbuf);
2971                 die(0);
2972         }
2973         for (res = res0; res != NULL; res = res->ai_next) {
2974                 int s;
2975
2976                 if (res->ai_family != AF_LOCAL &&
2977                     SecureMode > 1) {
2978                         /* Only AF_LOCAL in secure mode. */
2979                         continue;
2980                 }
2981                 if (family != AF_UNSPEC &&
2982                     res->ai_family != AF_LOCAL && res->ai_family != family)
2983                         continue;
2984
2985                 s = socket(res->ai_family, res->ai_socktype,
2986                     res->ai_protocol);
2987                 if (s < 0) {
2988                         logerror("socket");
2989                         error++;
2990                         continue;
2991                 }
2992 #ifdef INET6
2993                 if (res->ai_family == AF_INET6) {
2994                         if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
2995                                &(int){1}, sizeof(int)) < 0) {
2996                                 logerror("setsockopt(IPV6_V6ONLY)");
2997                                 close(s);
2998                                 error++;
2999                                 continue;
3000                         }
3001                 }
3002 #endif
3003                 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
3004                     &(int){1}, sizeof(int)) < 0) {
3005                         logerror("setsockopt(SO_REUSEADDR)");
3006                         close(s);
3007                         error++;
3008                         continue;
3009                 }
3010
3011                 /*
3012                  * Bind INET and UNIX-domain sockets.
3013                  *
3014                  * A UNIX-domain socket is always bound to a pathname
3015                  * regardless of -N flag.
3016                  *
3017                  * For INET sockets, RFC 3164 recommends that client
3018                  * side message should come from the privileged syslogd port.
3019                  *
3020                  * If the system administrator chooses not to obey
3021                  * this, we can skip the bind() step so that the
3022                  * system will choose a port for us.
3023                  */
3024                 if (res->ai_family == AF_LOCAL)
3025                         unlink(pe->pe_name);
3026                 if (res->ai_family == AF_LOCAL ||
3027                     NoBind == 0 || pe->pe_name != NULL) {
3028                         if (bind(s, res->ai_addr, res->ai_addrlen) < 0) {
3029                                 logerror("bind");
3030                                 close(s);
3031                                 error++;
3032                                 continue;
3033                         }
3034                         if (res->ai_family == AF_LOCAL ||
3035                             SecureMode == 0)
3036                                 increase_rcvbuf(s);
3037                 }
3038                 if (res->ai_family == AF_LOCAL &&
3039                     chmod(pe->pe_name, pe->pe_mode) < 0) {
3040                         dprintf("chmod %s: %s\n", pe->pe_name,
3041                             strerror(errno));
3042                         close(s);
3043                         error++;
3044                         continue;
3045                 }
3046                 dprintf("new socket fd is %d\n", s);
3047                 if (res->ai_socktype != SOCK_DGRAM) {
3048                         listen(s, 5);
3049                 }
3050                 sl_recv = socklist_recv_sock;
3051 #if defined(INET) || defined(INET6)
3052                 if (SecureMode && (res->ai_family == AF_INET ||
3053                     res->ai_family == AF_INET6)) {
3054                         dprintf("shutdown\n");
3055                         /* Forbid communication in secure mode. */
3056                         if (shutdown(s, SHUT_RD) < 0 &&
3057                             errno != ENOTCONN) {
3058                                 logerror("shutdown");
3059                                 if (!Debug)
3060                                         die(0);
3061                         }
3062                         sl_recv = NULL;
3063                 } else
3064 #endif
3065                         dprintf("listening on socket\n");
3066                 dprintf("sending on socket\n");
3067                 addsock(res->ai_addr, res->ai_addrlen,
3068                     &(struct socklist){
3069                         .sl_socket = s,
3070                         .sl_peer = pe,
3071                         .sl_recv = sl_recv
3072                 });
3073         }
3074         freeaddrinfo(res0);
3075
3076         return(error);
3077 }
3078
3079 static void
3080 increase_rcvbuf(int fd)
3081 {
3082         socklen_t len;
3083
3084         if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &len,
3085             &(socklen_t){sizeof(len)}) == 0) {
3086                 if (len < RCVBUF_MINSIZE) {
3087                         len = RCVBUF_MINSIZE;
3088                         setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &len, sizeof(len));
3089                 }
3090         }
3091 }