summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbapt <bapt@FreeBSD.org>2016-11-16 07:04:49 +0000
committerbapt <bapt@FreeBSD.org>2016-11-16 07:04:49 +0000
commit6cdfcd5230da6d451be1e4fdb48eff13b7057301 (patch)
tree3f208b1399042db08e884f1a25390f0d529196a8
parent1f6a31cefa15fc288e68fd28341349da9769513b (diff)
downloadFreeBSD-src-6cdfcd5230da6d451be1e4fdb48eff13b7057301.zip
FreeBSD-src-6cdfcd5230da6d451be1e4fdb48eff13b7057301.tar.gz
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
-rw-r--r--etc/mtree/BSD.root.dist2
-rw-r--r--etc/syslog.conf2
-rw-r--r--usr.sbin/syslogd/syslog.conf.58
-rw-r--r--usr.sbin/syslogd/syslogd.c236
4 files changed, 166 insertions, 82 deletions
diff --git a/etc/mtree/BSD.root.dist b/etc/mtree/BSD.root.dist
index 3a7bdeb..6e336ee 100644
--- a/etc/mtree/BSD.root.dist
+++ b/etc/mtree/BSD.root.dist
@@ -78,6 +78,8 @@
..
ssl
..
+ syslog.d
+ ..
zfs
..
..
diff --git a/etc/syslog.conf b/etc/syslog.conf
index e65db53..a137bdc 100644
--- a/etc/syslog.conf
+++ b/etc/syslog.conf
@@ -34,3 +34,5 @@ cron.* /var/log/cron
!ppp
*.* /var/log/ppp.log
!*
+include /etc/syslog.d
+include /usr/local/etc/syslog.d
diff --git a/usr.sbin/syslogd/syslog.conf.5 b/usr.sbin/syslogd/syslog.conf.5
index 3378aa0..94c1cd4 100644
--- a/usr.sbin/syslogd/syslog.conf.5
+++ b/usr.sbin/syslogd/syslog.conf.5
@@ -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.
diff --git a/usr.sbin/syslogd/syslogd.c b/usr.sbin/syslogd/syslogd.c
index 5562781..4c415fa 100644
--- a/usr.sbin/syslogd/syslogd.c
+++ b/usr.sbin/syslogd/syslogd.c
@@ -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);
OpenPOWER on IntegriCloud