svn commit: r308160 - in head: etc etc/mtree usr.sbin/syslogd

Baptiste Daroussin bapt at FreeBSD.org
Tue Nov 1 01:41:26 UTC 2016


Author: bapt
Date: Tue Nov  1 01:41:24 2016
New Revision: 308160
URL: https://svnweb.freebsd.org/changeset/base/308160

Log:
  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:
  head/etc/mtree/BSD.root.dist
  head/etc/syslog.conf
  head/usr.sbin/syslogd/syslog.conf.5
  head/usr.sbin/syslogd/syslogd.c

Modified: head/etc/mtree/BSD.root.dist
==============================================================================
--- head/etc/mtree/BSD.root.dist	Tue Nov  1 01:19:48 2016	(r308159)
+++ head/etc/mtree/BSD.root.dist	Tue Nov  1 01:41:24 2016	(r308160)
@@ -78,6 +78,8 @@
         ..
         ssl
         ..
+        syslog.d
+        ..
         zfs
         ..
     ..

Modified: head/etc/syslog.conf
==============================================================================
--- head/etc/syslog.conf	Tue Nov  1 01:19:48 2016	(r308159)
+++ head/etc/syslog.conf	Tue Nov  1 01:41:24 2016	(r308160)
@@ -34,3 +34,5 @@ cron.*						/var/log/cron
 !ppp
 *.*						/var/log/ppp.log
 !*
+include						/etc/syslog.d
+include						/usr/local/etc/syslog.d

Modified: head/usr.sbin/syslogd/syslog.conf.5
==============================================================================
--- head/usr.sbin/syslogd/syslog.conf.5	Tue Nov  1 01:19:48 2016	(r308159)
+++ head/usr.sbin/syslogd/syslog.conf.5	Tue Nov  1 01:41:24 2016	(r308160)
@@ -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: head/usr.sbin/syslogd/syslogd.c
==============================================================================
--- head/usr.sbin/syslogd/syslogd.c	Tue Nov  1 01:19:48 2016	(r308159)
+++ head/usr.sbin/syslogd/syslogd.c	Tue Nov  1 01:41:24 2016	(r308160)
@@ -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);


More information about the svn-src-all mailing list