From 84a50b0b46050ea9910532d02b516ba2fa3d61d5 Mon Sep 17 00:00:00 2001 From: ngie Date: Wed, 19 Jul 2017 19:30:13 +0000 Subject: [PATCH] MFC r308160,r309194,r309216: r308160 (by bapt): 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. Relnotes: yes r309194 (by bapt): initialize *nextp which could be left uninitialized in case the configuration file cannot be open/read CID: 1365665 r309216 (by bapt): Properly initialize nextp git-svn-id: svn://svn.freebsd.org/base/stable/10@321234 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- etc/mtree/BSD.root.dist | 2 + etc/syslog.conf | 2 + usr.sbin/syslogd/syslog.conf.5 | 8 +- usr.sbin/syslogd/syslogd.c | 227 ++++++++++++++++++++++----------- 4 files changed, 162 insertions(+), 77 deletions(-) diff --git a/etc/mtree/BSD.root.dist b/etc/mtree/BSD.root.dist index 4f3bdfc69..5e507c8da 100644 --- a/etc/mtree/BSD.root.dist +++ b/etc/mtree/BSD.root.dist @@ -72,6 +72,8 @@ .. ssl .. + syslog.d + .. zfs .. .. diff --git a/etc/syslog.conf b/etc/syslog.conf index e65db5347..a137bdcae 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 3378aa08c..94c1cd415 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 d09ec0258..2e16c57a0 100644 --- a/usr.sbin/syslogd/syslogd.c +++ b/usr.sbin/syslogd/syslogd.c @@ -97,6 +97,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -120,6 +121,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 @@ -1553,93 +1556,46 @@ die(int signo) exit(1); } -/* - * INIT -- Initialize syslogd from configuration table - */ -static void -init(int signo) +static int +configfiles(const struct dirent *dp) { - int i; - 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]; + const char *p; + size_t ext_len; - dprintf("init\n"); + if (dp->d_name[0] == '.') + return (0); - /* - * Load hostname (may have changed). - */ - if (signo != 0) - (void)strlcpy(oldLocalHostName, LocalHostName, - sizeof(oldLocalHostName)); - if (gethostname(LocalHostName, sizeof(LocalHostName))) - err(EX_OSERR, "gethostname() failed"); - if ((p = strchr(LocalHostName, '.')) != NULL) { - *p++ = '\0'; - LocalDomain = p; - } else { - LocalDomain = ""; - } + ext_len = sizeof(include_ext) -1; - /* - * Close all open log files. - */ - Initialized = 0; - for (f = Files; f != NULL; f = next) { - /* flush any pending output */ - if (f->f_prevcount) - fprintlog(f, 0, (char *)NULL); + if (dp->d_namlen <= ext_len) + return (0); - switch (f->f_type) { - case F_FILE: - case F_FORW: - case F_CONSOLE: - case F_TTY: - close_filed(f); - break; - case F_PIPE: - close_filed(f); - deadq_enter(f->f_un.f_pipe.f_pid, - f->f_un.f_pipe.f_pname); - break; - } - next = f->f_next; - if (f->f_program) free(f->f_program); - if (f->f_host) free(f->f_host); - free((char *)f); - } - Files = NULL; - nextp = &Files; + p = &dp->d_name[dp->d_namlen - ext_len]; + if (strcmp(p, include_ext) != 0) + return (0); - /* open the configuration file */ - if ((cf = fopen(ConfFile, "r")) == NULL) { - dprintf("cannot open %s\n", ConfFile); - *nextp = (struct filed *)calloc(1, sizeof(*f)); - if (*nextp == NULL) { - logerror("calloc"); - exit(1); - } - cfline("*.ERR\t/dev/console", *nextp, "*", "*"); - (*nextp)->f_next = (struct filed *)calloc(1, sizeof(*f)); - if ((*nextp)->f_next == NULL) { - logerror("calloc"); - exit(1); - } - cfline("*.PANIC\t*", (*nextp)->f_next, "*", "*"); - Initialized = 1; - return; - } + 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) { @@ -1652,6 +1608,42 @@ init(int signo) 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 != '-') @@ -1713,6 +1705,89 @@ init(int signo) nextp = &f->f_next; cfline(cline, f, prog, host); } +} + +/* + * INIT -- Initialize syslogd from configuration table + */ +static void +init(int signo) +{ + int i; + FILE *cf; + struct filed *f, *next, **nextp; + char *p; + char oldLocalHostName[MAXHOSTNAMELEN]; + char hostMsg[2*MAXHOSTNAMELEN+40]; + char bootfileMsg[LINE_MAX]; + + dprintf("init\n"); + + /* + * Load hostname (may have changed). + */ + if (signo != 0) + (void)strlcpy(oldLocalHostName, LocalHostName, + sizeof(oldLocalHostName)); + if (gethostname(LocalHostName, sizeof(LocalHostName))) + err(EX_OSERR, "gethostname() failed"); + if ((p = strchr(LocalHostName, '.')) != NULL) { + *p++ = '\0'; + LocalDomain = p; + } else { + LocalDomain = ""; + } + + /* + * Close all open log files. + */ + Initialized = 0; + for (f = Files; f != NULL; f = next) { + /* flush any pending output */ + if (f->f_prevcount) + fprintlog(f, 0, (char *)NULL); + + switch (f->f_type) { + case F_FILE: + case F_FORW: + case F_CONSOLE: + case F_TTY: + close_filed(f); + break; + case F_PIPE: + close_filed(f); + deadq_enter(f->f_un.f_pipe.f_pid, + f->f_un.f_pipe.f_pname); + break; + } + next = f->f_next; + if (f->f_program) free(f->f_program); + if (f->f_host) free(f->f_host); + free((char *)f); + } + Files = NULL; + nextp = &Files; + + /* open the configuration file */ + if ((cf = fopen(ConfFile, "r")) == NULL) { + dprintf("cannot open %s\n", ConfFile); + *nextp = (struct filed *)calloc(1, sizeof(*f)); + if (*nextp == NULL) { + logerror("calloc"); + exit(1); + } + cfline("*.ERR\t/dev/console", *nextp, "*", "*"); + (*nextp)->f_next = (struct filed *)calloc(1, sizeof(*f)); + if ((*nextp)->f_next == NULL) { + logerror("calloc"); + exit(1); + } + cfline("*.PANIC\t*", (*nextp)->f_next, "*", "*"); + Initialized = 1; + return; + } + + readconfigfile(cf, &Files, 1); /* close the configuration file */ (void)fclose(cf); -- 2.42.0