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

Reply via email to