Signed-off-by: Alexander Vickberg <wickbergs...@gmail.com> --- sysklogd/syslogd.c | 88 ++++++++++++++++++++++++++++------------------ 1 file changed, 54 insertions(+), 34 deletions(-)
diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c index 95ef3c815..cdb96f8d8 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 _______________________________________________ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox