mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-30 16:51:41 +00:00
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
This commit is contained in:
parent
569b917590
commit
fdec22c37d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=308160
@ -78,6 +78,8 @@
|
||||
..
|
||||
ssl
|
||||
..
|
||||
syslog.d
|
||||
..
|
||||
zfs
|
||||
..
|
||||
..
|
||||
|
@ -34,3 +34,5 @@ cron.* /var/log/cron
|
||||
!ppp
|
||||
*.* /var/log/ppp.log
|
||||
!*
|
||||
include /etc/syslog.d
|
||||
include /usr/local/etc/syslog.d
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user