Author: hrs
Date: Wed Dec 21 06:42:30 2016
New Revision: 310350
URL: https://svnweb.freebsd.org/changeset/base/310350

Log:
  - Add fklog into struct socklist.  Files and local/remote sockets are
    now processed in struct socklist in a consistent manner.
  - Add helper functions to add a new entry of struct socklist, filed, or peer.
  - Use the same routine for -l, -p, and -S.
  - Close /dev/klog when read(2) failed.

Modified:
  head/usr.sbin/syslogd/syslogd.c

Modified: head/usr.sbin/syslogd/syslogd.c
==============================================================================
--- head/usr.sbin/syslogd/syslogd.c     Wed Dec 21 05:45:59 2016        
(r310349)
+++ head/usr.sbin/syslogd/syslogd.c     Wed Dec 21 06:42:30 2016        
(r310350)
@@ -144,29 +144,17 @@ struct peer {
        mode_t          pe_mode;
        STAILQ_ENTRY(peer)      next;
 };
+static STAILQ_HEAD(, peer) pqueue = STAILQ_HEAD_INITIALIZER(pqueue);
+
 struct socklist {
        struct sockaddr_storage sl_ss;
        int                     sl_socket;
        struct peer             *sl_peer;
+       int                     (*sl_recv)(struct socklist *);
        STAILQ_ENTRY(socklist)  next;
 };
 static STAILQ_HEAD(, socklist) shead = STAILQ_HEAD_INITIALIZER(shead);
 
-static struct peer funix_secure = {
-       .pe_name = _PATH_LOG_PRIV,
-       .pe_mode = S_IRUSR | S_IWUSR,
-       .next = {NULL},
-};
-static struct peer funix_default = {
-       .pe_name = _PATH_LOG,
-       .pe_mode = DEFFILEMODE,
-       .next = {&funix_secure},
-};
-static STAILQ_HEAD(, peer) pqueue = {
-       &funix_default,
-       &funix_secure.next.stqe_next,
-};
-
 /*
  * Flags to logmsg().
  */
@@ -306,7 +294,6 @@ static int  Foreground = 0; /* Run in for
 static int     resolve = 1;    /* resolve hostname */
 static char    LocalHostName[MAXHOSTNAMELEN];  /* our hostname */
 static const char *LocalDomain;        /* our local domain name */
-static int     fklog = -1;     /* /dev/klog */
 static int     Initialized;    /* set when we have initialized ourselves */
 static int     MarkInterval = 20 * 60; /* interval between marks in seconds */
 static int     MarkSeq;        /* mark sequence number */
@@ -337,8 +324,10 @@ static struct pidfh *pfh;
 static volatile sig_atomic_t MarkSet, WantDie;
 
 static int     allowaddr(char *);
-static void    cfline(const char *, struct filed *,
-                   const char *, const char *);
+static int     addfile(struct filed *);
+static int     addpeer(struct peer *);
+static int     addsock(struct sockaddr *, socklen_t, struct socklist *);
+static struct filed *cfline(const char *, const char *, const char *);
 static const char *cvthname(struct sockaddr *);
 static void    deadq_enter(pid_t, const char *);
 static int     deadq_remove(pid_t);
@@ -354,11 +343,12 @@ static void       logmsg(int, const char *, co
 static void    log_deadchild(pid_t, int, const char *);
 static void    markit(void);
 static int     socksetup(struct peer *);
+static int     socklist_recv_file(struct socklist *);
+static int     socklist_recv_sock(struct socklist *);
 static int     skip_message(const char *, const char *, int);
 static void    printline(const char *, char *, int);
 static void    printsys(char *);
 static int     p_open(const char *, pid_t *);
-static void    readklog(void);
 static void    reapchild(int);
 static const char *ttymsg_check(struct iovec *, int, char *, int);
 static void    usage(void);
@@ -381,21 +371,61 @@ close_filed(struct filed *f)
        f->f_type = F_UNUSED;
 }
 
+static int
+addfile(struct filed *f0)
+{
+       struct filed *f;
+
+       f = calloc(1, sizeof(*f));
+       if (f == NULL)
+               err(1, "malloc failed");
+       *f = *f0;
+       STAILQ_INSERT_TAIL(&fhead, f, next);
+
+       return (0);
+}
+
+static int
+addpeer(struct peer *pe0)
+{
+       struct peer *pe;
+
+       pe = calloc(1, sizeof(*pe));
+       if (pe == NULL)
+               err(1, "malloc failed");
+       *pe = *pe0;
+       STAILQ_INSERT_TAIL(&pqueue, pe, next);
+
+       return (0);
+}
+
+static int
+addsock(struct sockaddr *sa, socklen_t sa_len, struct socklist *sl0)
+{
+       struct socklist *sl;
+
+       sl = calloc(1, sizeof(*sl));
+       if (sl == NULL)
+               err(1, "malloc failed");
+       *sl = *sl0;
+       if (sa != NULL && sa_len > 0)
+               memcpy(&sl->sl_ss, sa, sa_len);
+       STAILQ_INSERT_TAIL(&shead, sl, next);
+
+       return (0);
+}
+
 int
 main(int argc, char *argv[])
 {
-       int ch, i, fdsrmax = 0, bflag = 0;
-       struct sockaddr_storage ss;
+       int ch, i, s, fdsrmax = 0, bflag = 0, pflag = 0, Sflag = 0;
        fd_set *fdsr = NULL;
-       char line[MAXLINE + 1];
-       const char *hname;
        struct timeval tv, *tvp;
        struct sigaction sact;
        struct peer *pe;
        struct socklist *sl;
        sigset_t mask;
        pid_t ppid = 1, spid;
-       socklen_t sslen;
        char *p;
 
        if (madvise(NULL, 0, MADV_PROTECT) != 0)
@@ -425,21 +455,22 @@ main(int argc, char *argv[])
                                usage();
                        break;
                case 'b':
-                       if ((pe = calloc(1, sizeof(*pe))) == NULL)
-                               err(1, "malloc failed");
+                       bflag = 1;
                        if ((p = strchr(optarg, ':')) == NULL) {
                                /* A hostname or filename only. */
-                               pe->pe_name = optarg;
-                               pe->pe_serv = "syslog";
+                               addpeer(&(struct peer){
+                                       .pe_name = optarg,
+                                       .pe_serv = "syslog"
+                               });
                        } else {
                                /* The case of "name:service". */
                                *p++ = '\0';
-                               pe->pe_serv = p;
-                               pe->pe_name = (strlen(optarg) == 0) ?
-                                   NULL : optarg;
+                               addpeer(&(struct peer){
+                                       .pe_serv = p,
+                                       .pe_name = (strlen(optarg) == 0) ?
+                                           NULL : optarg,
+                               });
                        }
-                       bflag = 1;
-                       STAILQ_INSERT_TAIL(&pqueue, pe, next);
                        break;
                case 'c':
                        no_compress++;
@@ -460,15 +491,25 @@ main(int argc, char *argv[])
                        KeepKernFac = 1;
                        break;
                case 'l':
+               case 'p':
+               case 'S':
                    {
                        long    perml;
                        mode_t  mode;
                        char    *name, *ep;
 
-                       if (optarg[0] == '/') {
+                       if (ch == 'l')
                                mode = DEFFILEMODE;
+                       else if (ch == 'p') {
+                               mode = DEFFILEMODE;
+                               pflag = 1;
+                       } else if (ch == 'S') {
+                               mode = S_IRUSR | S_IWUSR;
+                               Sflag = 1;
+                       }
+                       if (optarg[0] == '/')
                                name = optarg;
-                       } else if ((name = strchr(optarg, ':')) != NULL) {
+                       else if ((name = strchr(optarg, ':')) != NULL) {
                                *name++ = '\0';
                                if (name[0] != '/')
                                        errx(1, "socket name must be absolute "
@@ -483,12 +524,13 @@ main(int argc, char *argv[])
                                } else
                                        errx(1, "invalid mode %s, exiting",
                                            optarg);
-                       }
-                       if ((pe = calloc(1, sizeof(*pe))) == NULL)
-                               err(1, "malloc failed");
-                       pe->pe_name = name;
-                       pe->pe_mode = mode;
-                       STAILQ_INSERT_TAIL(&pqueue, pe, next);
+                       } else
+                               errx(1, "invalid filename %s, exiting",
+                                   optarg);
+                       addpeer(&(struct peer){
+                               .pe_name = name,
+                               .pe_mode = mode
+                       });
                        break;
                   }
                case 'm':               /* mark interval */
@@ -504,18 +546,12 @@ main(int argc, char *argv[])
                case 'o':
                        use_bootfile = 1;
                        break;
-               case 'p':               /* path */
-                       funix_default.pe_name = optarg;
-                       break;
                case 'P':               /* path for alt. PID */
                        PidFile = optarg;
                        break;
                case 's':               /* no network mode */
                        SecureMode++;
                        break;
-               case 'S':               /* path for privileged originator */
-                       funix_secure.pe_name = optarg;
-                       break;
                case 'T':
                        RemoteAddDate = 1;
                        break;
@@ -531,15 +567,33 @@ main(int argc, char *argv[])
        if ((argc -= optind) != 0)
                usage();
 
-       if (bflag == 0) {
-               pe = calloc(1, sizeof(*pe));
-               if (pe == NULL)
-                       err(1, "malloc failed");
-               *pe = (struct peer) {
+       /* Listen by default: /dev/klog. */
+       s = open(_PATH_KLOG, O_RDONLY|O_NONBLOCK, 0);
+       if (s < 0) {
+               dprintf("can't open %s (%d)\n", _PATH_KLOG, errno);
+       } else {
+               addsock(NULL, 0, &(struct socklist){
+                       .sl_socket = s,
+                       .sl_recv = socklist_recv_file,
+               });
+       }
+       /* Listen by default: *:514 if no -b flag. */
+       if (bflag == 0)
+               addpeer(&(struct peer){
                        .pe_serv = "syslog"
-               };
-               STAILQ_INSERT_TAIL(&pqueue, pe, next);
-       }
+               });
+       /* Listen by default: /var/run/log if no -p flag. */
+       if (pflag == 0)
+               addpeer(&(struct peer){
+                       .pe_name = _PATH_LOG,
+                       .pe_mode = DEFFILEMODE,
+               });
+       /* Listen by default: /var/run/logpriv if no -S flag. */
+       if (Sflag == 0)
+               addpeer(&(struct peer){
+                       .pe_name = _PATH_LOG_PRIV,
+                       .pe_mode = S_IRUSR | S_IWUSR,
+               });
        STAILQ_FOREACH(pe, &pqueue, next)
                socksetup(pe);
 
@@ -585,9 +639,6 @@ main(int argc, char *argv[])
 
        TAILQ_INIT(&deadq_head);
 
-       if ((fklog = open(_PATH_KLOG, O_RDONLY|O_NONBLOCK, 0)) < 0)
-               dprintf("can't open %s (%d)\n", _PATH_KLOG, errno);
-
        /* tuck my process id away */
        pidfile_write(pfh);
 
@@ -605,13 +656,10 @@ main(int argc, char *argv[])
        tvp = &tv;
        tv.tv_sec = tv.tv_usec = 0;
 
-       if (fklog != -1 && fklog > fdsrmax)
-               fdsrmax = fklog;
        STAILQ_FOREACH(sl, &shead, next) {
                if (sl->sl_socket > fdsrmax)
                        fdsrmax = sl->sl_socket;
        }
-
        fdsr = (fd_set *)calloc(howmany(fdsrmax+1, NFDBITS),
            sizeof(fd_mask));
        if (fdsr == NULL)
@@ -626,8 +674,6 @@ main(int argc, char *argv[])
                bzero(fdsr, howmany(fdsrmax+1, NFDBITS) *
                    sizeof(fd_mask));
 
-               if (fklog != -1)
-                       FD_SET(fklog, fdsr);
                STAILQ_FOREACH(sl, &shead, next) {
                        if (sl->sl_socket != -1)
                                FD_SET(sl->sl_socket, fdsr);
@@ -649,49 +695,55 @@ main(int argc, char *argv[])
                                logerror("select");
                        continue;
                }
-               if (fklog != -1 && FD_ISSET(fklog, fdsr))
-                       readklog();
                STAILQ_FOREACH(sl, &shead, next) {
-                       int date, len;
-
-                       if (FD_ISSET(sl->sl_socket, fdsr)) {
-                               sslen = sizeof(ss);
-                               dprintf("sslen(1) = %d\n", sslen);
-                               len = recvfrom(sl->sl_socket, line,
-                                   sizeof(line) - 1, 0,
-                                   sstosa(&ss), &sslen);
-                               dprintf("sslen(2) = %d\n", sslen);
-                               if (len == 0)
-                                       continue;
-                               if (len < 0) {
-                                       if (errno != EINTR)
-                                               logerror("recvfrom");
-                                       continue;
-                               }
-                               /* Received valid data. */
-                               line[len] = '\0';
-                               if (sl->sl_ss.ss_family == AF_LOCAL) {
-                                       hname = LocalHostName;
-                                       date = 0;
-                               } else {
-                                       hname = cvthname(sstosa(&ss));
-                                       unmapped(sstosa(&ss));
-                                       if (validate(sstosa(&ss), hname) == 0)
-                                               hname = NULL;
-                                       date = RemoteAddDate ? ADDDATE : 0;
-                               }
-                               if (hname != NULL)
-                                       printline(hname, line, date);
-                               else
-                                       dprintf("Invalid msg from "
-                                           "%s was ignored.", hname);
-                       }
+                       if (FD_ISSET(sl->sl_socket, fdsr))
+                               (*sl->sl_recv)(sl);
                }
        }
        if (fdsr)
                free(fdsr);
 }
 
+static int
+socklist_recv_sock(struct socklist *sl)
+{
+       struct sockaddr_storage ss;
+       struct sockaddr *sa = (struct sockaddr *)&ss;
+       socklen_t sslen;
+       const char *hname;
+       char line[MAXLINE + 1];
+       int date, len;
+
+       sslen = sizeof(ss);
+       len = recvfrom(sl->sl_socket, line, sizeof(line) - 1, 0, sa, &sslen);
+       dprintf("received sa_len = %d\n", sslen);
+       if (len == 0)
+               return (-1);
+       if (len < 0) {
+               if (errno != EINTR)
+                       logerror("recvfrom");
+               return (-1);
+       }
+       /* Received valid data. */
+       line[len] = '\0';
+       if (sl->sl_ss.ss_family == AF_LOCAL) {
+               hname = LocalHostName;
+               date = 0;
+       } else {
+               hname = cvthname(sa);
+               unmapped(sa);
+               if (validate(sa, hname) == 0)
+                       hname = NULL;
+               date = RemoteAddDate ? ADDDATE : 0;
+       }
+       if (hname != NULL)
+               printline(hname, line, date);
+       else
+               dprintf("Invalid msg from %s was ignored.", hname);
+
+       return (0);
+}
+
 static void
 unmapped(struct sockaddr *sa)
 {
@@ -792,21 +844,22 @@ printline(const char *hname, char *msg, 
 /*
  * Read /dev/klog while data are available, split into lines.
  */
-static void
-readklog(void)
+static int
+socklist_recv_file(struct socklist *sl)
 {
        char *p, *q, line[MAXLINE + 1];
        int len, i;
 
        len = 0;
        for (;;) {
-               i = read(fklog, line + len, MAXLINE - 1 - len);
+               i = read(sl->sl_socket, line + len, MAXLINE - 1 - len);
                if (i > 0) {
                        line[i + len] = '\0';
                } else {
                        if (i < 0 && errno != EINTR && errno != EAGAIN) {
                                logerror("klog");
-                               fklog = -1;
+                               close(sl->sl_socket);
+                               sl->sl_socket = -1;
                        }
                        break;
                }
@@ -825,6 +878,8 @@ readklog(void)
        }
        if (len > 0)
                printsys(line);
+
+       return (len);
 }
 
 /*
@@ -1225,7 +1280,9 @@ fprintlog(struct filed *f, int flags, co
                        struct socklist *sl;
 
                        STAILQ_FOREACH(sl, &shead, next) {
-                               if (sl->sl_ss.ss_family == AF_LOCAL)
+                               if (sl->sl_ss.ss_family == AF_LOCAL ||
+                                   sl->sl_ss.ss_family == AF_UNSPEC ||
+                                   sl->sl_socket < 0)
                                        continue;
                                lsent = sendto(sl->sl_socket, line, l, 0,
                                    r->ai_addr, r->ai_addrlen);
@@ -1591,7 +1648,6 @@ readconfigfile(FILE *cf, int allow_inclu
        /*
         *  Foreach line in the conf table, open that file.
         */
-       f = NULL;
        include_len = sizeof(include_str) -1;
        (void)strlcpy(host, "*", sizeof(host));
        (void)strlcpy(prog, "*", sizeof(prog));
@@ -1693,13 +1749,9 @@ readconfigfile(FILE *cf, int allow_inclu
                }
                for (i = strlen(cline) - 1; i >= 0 && isspace(cline[i]); i--)
                        cline[i] = '\0';
-               f = (struct filed *)calloc(1, sizeof(*f));
-               if (f == NULL) {
-                       logerror("calloc");
-                       exit(1);
-               }
-               STAILQ_INSERT_TAIL(&fhead, f, next);
-               cfline(cline, f, prog, host);
+               f = cfline(cline, prog, host);
+               if (f != NULL)
+                       addfile(f);
        }
 }
 
@@ -1789,23 +1841,14 @@ init(int signo)
        /* open the configuration file */
        if ((cf = fopen(ConfFile, "r")) == NULL) {
                dprintf("cannot open %s\n", ConfFile);
-               f = calloc(1, sizeof(*f));
-               if (f == NULL) {
-                       logerror("calloc");
-                       exit(1);
-               }
-               cfline("*.ERR\t/dev/console", f, "*", "*");
-               STAILQ_INSERT_TAIL(&fhead, f, next);
-
-               f = calloc(1, sizeof(*f));
-               if (f == NULL) {
-                       logerror("calloc");
-                       exit(1);
-               }
-               cfline("*.PANIC\t*", f, "*", "*");
-               STAILQ_INSERT_TAIL(&fhead, f, next);
-
+               f = cfline("*.ERR\t/dev/console", "*", "*");
+               if (f != NULL)
+                       addfile(f);
+               f = cfline("*.PANIC\t*", "*", "*");
+               if (f != NULL)
+                       addfile(f);
                Initialized = 1;
+
                return;
        }
 
@@ -1887,9 +1930,10 @@ init(int signo)
 /*
  * Crack a configuration file line
  */
-static void
-cfline(const char *line, struct filed *f, const char *prog, const char *host)
+static struct filed *
+cfline(const char *line, const char *prog, const char *host)
 {
+       struct filed *f;
        struct addrinfo hints, *res;
        int error, i, pri, syncfile;
        const char *p, *q;
@@ -1898,10 +1942,13 @@ cfline(const char *line, struct filed *f
 
        dprintf("cfline(\"%s\", f, \"%s\", \"%s\")\n", line, prog, host);
 
+       f = calloc(1, sizeof(*f));
+       if (f == NULL) {
+               logerror("malloc");
+               exit(1);
+       }
        errno = 0;      /* keep strerror() stuff out of logerror messages */
 
-       /* clear out file entry */
-       memset(f, 0, sizeof(*f));
        for (i = 0; i <= LOG_NFACILITIES; i++)
                f->f_pmask[i] = INTERNAL_NOPRI;
 
@@ -1995,7 +2042,7 @@ cfline(const char *line, struct filed *f
                                (void)snprintf(ebuf, sizeof ebuf,
                                    "unknown priority name \"%s\"", buf);
                                logerror(ebuf);
-                               return;
+                               return (NULL);
                        }
                }
                if (!pri_cmp)
@@ -2025,7 +2072,7 @@ cfline(const char *line, struct filed *f
                                            "unknown facility name \"%s\"",
                                            buf);
                                        logerror(ebuf);
-                                       return;
+                                       return (NULL);
                                }
                                f->f_pmask[i >> 3] = pri;
                                f->f_pcmp[i >> 3] = pri_cmp;
@@ -2142,6 +2189,7 @@ cfline(const char *line, struct filed *f
                f->f_type = F_USERS;
                break;
        }
+       return (f);
 }
 
 
@@ -2731,7 +2779,6 @@ static int
 socksetup(struct peer *pe)
 {
        struct addrinfo hints, *res, *res0;
-       struct socklist *sl;
        int error;
        char *cp;
        /*
@@ -2853,13 +2900,12 @@ socksetup(struct peer *pe)
                        dprintf("listening on inet socket\n");
                } else
                        dprintf("sending on inet socket\n");
-               sl = calloc(1, sizeof(*sl));
-               if (sl == NULL)
-                       err(1, "malloc failed");
-               sl->sl_socket = s;
-               memcpy(&sl->sl_ss, res->ai_addr, res->ai_addrlen);
-               sl->sl_peer = pe;
-               STAILQ_INSERT_TAIL(&shead, sl, next);
+               addsock(res->ai_addr, res->ai_addrlen,
+                   &(struct socklist){
+                       .sl_socket = s,
+                       .sl_peer = pe,
+                       .sl_recv = socklist_recv_sock
+               });
        }
        freeaddrinfo(res0);
 
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to