[PATCH v5 2/2] syslogd: allow to include other config files/dirs
Alexander Vickberg
wickbergster at gmail.com
Tue Mar 16 13:36:39 UTC 2021
Signed-off-by: Alexander Vickberg <wickbergster at gmail.com>
---
sysklogd/syslogd.c | 88 ++++++++++++++++++++++++++++------------------
1 file changed, 54 insertions(+), 34 deletions(-)
diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c
index cf9d1b61f..e33b9fbd5 100644
--- a/sysklogd/syslogd.c
+++ b/sysklogd/syslogd.c
@@ -227,6 +227,8 @@ typedef struct logFile_t {
} logFile_t;
#if ENABLE_FEATURE_SYSLOGD_CFG
+static void read_config(const char *path);
+
typedef struct stringMatch_t {
char *str;
int len;
@@ -238,7 +240,7 @@ typedef struct logRule_t {
uint8_t enabled_facility_priomap[LOG_NFACILITIES];
struct logFile_t *file;
struct stringMatch_t *strmatch;
- struct logRule_t *next;
+ struct logRule_t *prev;
} logRule_t;
#endif
@@ -399,35 +401,52 @@ static const CODE* find_by_val(int val, const CODE* c_set)
}
#if ENABLE_FEATURE_SYSLOGD_CFG
-static void parse_syslogdcfg(const char *file)
+static int FAST_FUNC parse_syslogdcfg(struct recursive_state *state,
+ const char *file, struct stat *statbuf UNUSED_PARAM)
{
char *t;
- logRule_t **pp_rule;
/* tok[0] set of selectors */
/* tok[1] file name */
/* tok[2] has to be NULL */
char *tok[3];
parser_t *parser;
+ const char *base;
+
+ /* Skip files that begin with a "." */
+ base = bb_basename(file);
+ if (base[0] == '.')
+ return TRUE;
+
+ /* only recurse one level */
+ if (state->depth > 1)
+ return SKIP; /* stop recursing */
+
+ if (state->depth != 0) {
+ if (!is_suffixed_with(base, ".conf"))
+ return TRUE;
+ }
- parser = config_open2(file ? file : "/etc/syslog.conf",
- file ? xfopen_for_read : fopen_for_read);
+ parser = config_open2(file, fopen_for_read);
if (!parser)
- /* didn't find default /etc/syslog.conf */
- /* proceed as if we built busybox without config support */
- return;
+ return FALSE;
- /* use ptr to ptr to avoid checking whether head was initialized */
- pp_rule = &G.log_rules;
/* iterate through lines of config, skipping comments */
while (config_read(parser, tok, 3, 2, "# \t", PARSE_NORMAL | PARSE_MIN_DIE)) {
char *cur_selector;
- logRule_t *cur_rule;
+ logRule_t *cur_rule, *tmp;
/* unexpected trailing token? */
if (tok[2])
goto cfgerr;
- cur_rule = *pp_rule = xzalloc(sizeof(*cur_rule));
+ if (strcmp(tok[0], "include") == 0) {
+ read_config(tok[1]);
+ continue;
+ }
+
+ cur_rule = xzalloc(sizeof(*cur_rule));
+ cur_rule->prev = G.log_rules;
+ G.log_rules = cur_rule;
cur_selector = tok[0];
/* iterate through selectors: "kern.info;kern.!err;..." */
@@ -543,33 +562,34 @@ static void parse_syslogdcfg(const char *file)
*/
if (strcmp(G.logFile.path, tok[1]) == 0) {
cur_rule->file = &G.logFile;
- goto found;
+ continue;
}
- /* temporarily use cur_rule as iterator, but *pp_rule still points
- * to currently processing rule entry.
- * NOTE: *pp_rule points to the current (and last in the list) rule.
- */
- for (cur_rule = G.log_rules; cur_rule != *pp_rule; cur_rule = cur_rule->next) {
- if (strcmp(cur_rule->file->path, tok[1]) == 0) {
- /* found - reuse the same file structure */
- (*pp_rule)->file = cur_rule->file;
- cur_rule = *pp_rule;
- goto found;
+
+ for (tmp = cur_rule->prev; tmp; tmp = tmp->prev) {
+ if (strcmp(tmp->file->path, tok[1]) == 0) {
+ break;
}
}
- cur_rule->file = xzalloc(sizeof(*cur_rule->file));
- cur_rule->file->fd = -1;
- cur_rule->file->path = xstrdup(tok[1]);
- found:
- pp_rule = &cur_rule->next;
+ if (tmp) {
+ /* found - reuse the same file structure */
+ cur_rule->file = tmp->file;
+ } else {
+ cur_rule->file = xzalloc(sizeof(*cur_rule->file));
+ cur_rule->file->fd = -1;
+ cur_rule->file->path = xstrdup(tok[1]);
+ }
}
config_close(parser);
- return;
+ return TRUE;
cfgerr:
- bb_error_msg_and_die("error in '%s' at line %d",
- file ? file : "/etc/syslog.conf",
- parser->lineno);
+ bb_error_msg_and_die("error in '%s' at line %d", file, parser->lineno);
+}
+
+static void read_config(const char *path)
+{
+ recursive_action(path, ACTION_RECURSE | ACTION_QUIET,
+ parse_syslogdcfg, NULL, NULL);
}
#endif
@@ -904,7 +924,7 @@ static void timestamp_and_log(int pri, char *msg, int len)
uint8_t facility = LOG_FAC(pri);
uint8_t prio_bit = 1 << LOG_PRI(pri);
- for (rule = G.log_rules; rule; rule = rule->next) {
+ for (rule = G.log_rules; rule; rule = rule->prev) {
if (rule->enabled_facility_priomap[facility] & prio_bit) {
log_locally(now, G.printbuf, rule->file);
match = 1;
@@ -1207,7 +1227,7 @@ int syslogd_main(int argc UNUSED_PARAM, char **argv)
if (ENABLE_FEATURE_REMOTE_LOG && !(opts & OPT_remotelog)) // -R
option_mask32 |= OPT_locallog;
#if ENABLE_FEATURE_SYSLOGD_CFG
- parse_syslogdcfg(opt_f);
+ read_config(opt_f ? opt_f : "/etc/syslog.conf");
#endif
/* Store away localhost's name before the fork */
--
2.25.1
More information about the busybox
mailing list