Author: bapt
Date: Wed Nov 16 07:04:49 2016
New Revision: 308721
URL: https://svnweb.freebsd.org/changeset/base/308721

Log:
  MFC r308160:
  
  syslogd(8): add an 'include' keyword
  
  All the '.conf' files not beginning with a '.' contained int he directory
  following the keyword will be included.
  
  This keyword can only be used in the first level configuration files.
  
  Modify the default syslogd.conf to 'include' /etc/syslog.d and
  /usr/local/etc/syslog.d
  
  It simplify a lot handling of syslog from automation tools.
  
  Reviewed by:  markj, kib (via irc)
  Approved by:  markj
  MFC after:    2 weeks
  Relnotes:     yes
  Differential Revision:        https://reviews.freebsd.org/D8402

Modified:
  stable/11/etc/mtree/BSD.root.dist
  stable/11/etc/syslog.conf
  stable/11/usr.sbin/syslogd/syslog.conf.5
  stable/11/usr.sbin/syslogd/syslogd.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/etc/mtree/BSD.root.dist
==============================================================================
--- stable/11/etc/mtree/BSD.root.dist   Wed Nov 16 07:03:24 2016        
(r308720)
+++ stable/11/etc/mtree/BSD.root.dist   Wed Nov 16 07:04:49 2016        
(r308721)
@@ -78,6 +78,8 @@
         ..
         ssl
         ..
+        syslog.d
+        ..
         zfs
         ..
     ..

Modified: stable/11/etc/syslog.conf
==============================================================================
--- stable/11/etc/syslog.conf   Wed Nov 16 07:03:24 2016        (r308720)
+++ stable/11/etc/syslog.conf   Wed Nov 16 07:04:49 2016        (r308721)
@@ -34,3 +34,5 @@ cron.*                                                
/var/log/cron
 !ppp
 *.*                                            /var/log/ppp.log
 !*
+include                                                /etc/syslog.d
+include                                                /usr/local/etc/syslog.d

Modified: stable/11/usr.sbin/syslogd/syslog.conf.5
==============================================================================
--- stable/11/usr.sbin/syslogd/syslog.conf.5    Wed Nov 16 07:03:24 2016        
(r308720)
+++ stable/11/usr.sbin/syslogd/syslog.conf.5    Wed Nov 16 07:04:49 2016        
(r308721)
@@ -28,7 +28,7 @@
 .\"     @(#)syslog.conf.5      8.1 (Berkeley) 6/9/93
 .\" $FreeBSD$
 .\"
-.Dd September 12, 2012
+.Dd November 1, 2016
 .Dt SYSLOG.CONF 5
 .Os
 .Sh NAME
@@ -62,6 +62,12 @@ field is separated from the
 .Em action
 field by one or more tab characters or spaces.
 .Pp
+A special
+.Em include
+keyword can be used to include all files with names ending in '.conf' and not
+beginning with a '.' contained in the directory following the keyword.
+This keyword can only be used in the first level configuration file.
+.Pp
 Note that if you use spaces as separators, your
 .Nm
 might be incompatible with other Unices or Unix-like systems.

Modified: stable/11/usr.sbin/syslogd/syslogd.c
==============================================================================
--- stable/11/usr.sbin/syslogd/syslogd.c        Wed Nov 16 07:03:24 2016        
(r308720)
+++ stable/11/usr.sbin/syslogd/syslogd.c        Wed Nov 16 07:04:49 2016        
(r308721)
@@ -95,6 +95,7 @@ __FBSDID("$FreeBSD$");
 #include <arpa/inet.h>
 
 #include <ctype.h>
+#include <dirent.h>
 #include <err.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -118,6 +119,8 @@ __FBSDID("$FreeBSD$");
 const char     *ConfFile = _PATH_LOGCONF;
 const char     *PidFile = _PATH_LOGPID;
 const char     ctty[] = _PATH_CONSOLE;
+static const char      include_str[] = "include";
+static const char      include_ext[] = ".conf";
 
 #define        dprintf         if (Debug) printf
 
@@ -1601,6 +1604,157 @@ die(int signo)
        exit(1);
 }
 
+static int
+configfiles(const struct dirent *dp)
+{
+       const char *p;
+       size_t ext_len;
+
+       if (dp->d_name[0] == '.')
+               return (0);
+
+       ext_len = sizeof(include_ext) -1;
+
+       if (dp->d_namlen <= ext_len)
+               return (0);
+
+       p = &dp->d_name[dp->d_namlen - ext_len];
+       if (strcmp(p, include_ext) != 0)
+               return (0);
+
+       return (1);
+}
+
+static void
+readconfigfile(FILE *cf, struct filed **nextp, int allow_includes)
+{
+       FILE *cf2;
+       struct filed *f;
+       struct dirent **ent;
+       char cline[LINE_MAX];
+       char host[MAXHOSTNAMELEN];
+       char prog[LINE_MAX];
+       char file[MAXPATHLEN];
+       char *p, *tmp;
+       int i, nents;
+       size_t include_len;
+
+       /*
+        *  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));
+       while (fgets(cline, sizeof(cline), cf) != NULL) {
+               /*
+                * check for end-of-section, comments, strip off trailing
+                * spaces and newline character. #!prog is treated specially:
+                * following lines apply only to that program.
+                */
+               for (p = cline; isspace(*p); ++p)
+                       continue;
+               if (*p == 0)
+                       continue;
+               if (allow_includes &&
+                   strncmp(p, include_str, include_len) == 0 &&
+                   isspace(p[include_len])) {
+                       p += include_len;
+                       while (isspace(*p))
+                               p++;
+                       tmp = p;
+                       while (*tmp != '\0' && !isspace(*tmp))
+                               tmp++;
+                       *tmp = '\0';
+                       dprintf("Trying to include files in '%s'\n", p);
+                       nents = scandir(p, &ent, configfiles, alphasort);
+                       if (nents == -1) {
+                               dprintf("Unable to open '%s': %s\n", p,
+                                   strerror(errno));
+                               continue;
+                       }
+                       for (i = 0; i < nents; i++) {
+                               if (snprintf(file, sizeof(file), "%s/%s", p,
+                                   ent[i]->d_name) >= (int)sizeof(file)) {
+                                       dprintf("ignoring path too long: "
+                                           "'%s/%s'\n", p, ent[i]->d_name);
+                                       free(ent[i]);
+                                       continue;
+                               }
+                               free(ent[i]);
+                               cf2 = fopen(file, "r");
+                               if (cf2 == NULL)
+                                       continue;
+                               dprintf("reading %s\n", file);
+                               readconfigfile(cf2, nextp, 0);
+                               fclose(cf2);
+                       }
+                       free(ent);
+                       continue;
+               }
+               if (*p == '#') {
+                       p++;
+                       if (*p != '!' && *p != '+' && *p != '-')
+                               continue;
+               }
+               if (*p == '+' || *p == '-') {
+                       host[0] = *p++;
+                       while (isspace(*p))
+                               p++;
+                       if ((!*p) || (*p == '*')) {
+                               (void)strlcpy(host, "*", sizeof(host));
+                               continue;
+                       }
+                       if (*p == '@')
+                               p = LocalHostName;
+                       for (i = 1; i < MAXHOSTNAMELEN - 1; i++) {
+                               if (!isalnum(*p) && *p != '.' && *p != '-'
+                                   && *p != ',' && *p != ':' && *p != '%')
+                                       break;
+                               host[i] = *p++;
+                       }
+                       host[i] = '\0';
+                       continue;
+               }
+               if (*p == '!') {
+                       p++;
+                       while (isspace(*p)) p++;
+                       if ((!*p) || (*p == '*')) {
+                               (void)strlcpy(prog, "*", sizeof(prog));
+                               continue;
+                       }
+                       for (i = 0; i < LINE_MAX - 1; i++) {
+                               if (!isprint(p[i]) || isspace(p[i]))
+                                       break;
+                               prog[i] = p[i];
+                       }
+                       prog[i] = 0;
+                       continue;
+               }
+               for (p = cline + 1; *p != '\0'; p++) {
+                       if (*p != '#')
+                               continue;
+                       if (*(p - 1) == '\\') {
+                               strcpy(p - 1, p);
+                               p--;
+                               continue;
+                       }
+                       *p = '\0';
+                       break;
+               }
+               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);
+               }
+               *nextp = f;
+               nextp = &f->f_next;
+               cfline(cline, f, prog, host);
+       }
+}
+
 /*
  *  INIT -- Initialize syslogd from configuration table
  */
@@ -1611,9 +1765,6 @@ init(int signo)
        FILE *cf;
        struct filed *f, *next, **nextp;
        char *p;
-       char cline[LINE_MAX];
-       char prog[LINE_MAX];
-       char host[MAXHOSTNAMELEN];
        char oldLocalHostName[MAXHOSTNAMELEN];
        char hostMsg[2*MAXHOSTNAMELEN+40];
        char bootfileMsg[LINE_MAX];
@@ -1684,7 +1835,6 @@ init(int signo)
                free((char *)f);
        }
        Files = NULL;
-       nextp = &Files;
 
        /* open the configuration file */
        if ((cf = fopen(ConfFile, "r")) == NULL) {
@@ -1705,83 +1855,7 @@ init(int signo)
                return;
        }
 
-       /*
-        *  Foreach line in the conf table, open that file.
-        */
-       f = NULL;
-       (void)strlcpy(host, "*", sizeof(host));
-       (void)strlcpy(prog, "*", sizeof(prog));
-       while (fgets(cline, sizeof(cline), cf) != NULL) {
-               /*
-                * check for end-of-section, comments, strip off trailing
-                * spaces and newline character. #!prog is treated specially:
-                * following lines apply only to that program.
-                */
-               for (p = cline; isspace(*p); ++p)
-                       continue;
-               if (*p == 0)
-                       continue;
-               if (*p == '#') {
-                       p++;
-                       if (*p != '!' && *p != '+' && *p != '-')
-                               continue;
-               }
-               if (*p == '+' || *p == '-') {
-                       host[0] = *p++;
-                       while (isspace(*p))
-                               p++;
-                       if ((!*p) || (*p == '*')) {
-                               (void)strlcpy(host, "*", sizeof(host));
-                               continue;
-                       }
-                       if (*p == '@')
-                               p = LocalHostName;
-                       for (i = 1; i < MAXHOSTNAMELEN - 1; i++) {
-                               if (!isalnum(*p) && *p != '.' && *p != '-'
-                                   && *p != ',' && *p != ':' && *p != '%')
-                                       break;
-                               host[i] = *p++;
-                       }
-                       host[i] = '\0';
-                       continue;
-               }
-               if (*p == '!') {
-                       p++;
-                       while (isspace(*p)) p++;
-                       if ((!*p) || (*p == '*')) {
-                               (void)strlcpy(prog, "*", sizeof(prog));
-                               continue;
-                       }
-                       for (i = 0; i < LINE_MAX - 1; i++) {
-                               if (!isprint(p[i]) || isspace(p[i]))
-                                       break;
-                               prog[i] = p[i];
-                       }
-                       prog[i] = 0;
-                       continue;
-               }
-               for (p = cline + 1; *p != '\0'; p++) {
-                       if (*p != '#')
-                               continue;
-                       if (*(p - 1) == '\\') {
-                               strcpy(p - 1, p);
-                               p--;
-                               continue;
-                       }
-                       *p = '\0';
-                       break;
-               }
-               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);
-               }
-               *nextp = f;
-               nextp = &f->f_next;
-               cfline(cline, f, prog, host);
-       }
+       readconfigfile(cf, &Files, 1);
 
        /* close the configuration file */
        (void)fclose(cf);
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to