Signed-off-by: Alexander Vickberg <[email protected]>
---
 sysklogd/syslogd.c | 74 +++++++++++++++++++++++++++++++---------------
 1 file changed, 50 insertions(+), 24 deletions(-)

diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c
index 6ddfd771a..d1ecf5e5e 100644
--- a/sysklogd/syslogd.c
+++ b/sysklogd/syslogd.c
@@ -227,10 +227,18 @@ typedef struct logFile_t {
 } logFile_t;
 
 #if ENABLE_FEATURE_SYSLOGD_CFG
+typedef struct stringMatch_t {
+       char *str;
+       int len;
+       uint8_t enabled_priomap;
+       struct stringMatch_t *prev;
+} stringMatch_t;
+
 typedef struct logRule_t {
        uint8_t enabled_facility_priomap[LOG_NFACILITIES];
        struct logFile_t *file;
-       struct logRule_t *next;
+       struct stringMatch_t *strmatch;
+       struct logRule_t *prev;
 } logRule_t;
 #endif
 
@@ -394,7 +402,6 @@ static const CODE* find_by_val(int val, const CODE* c_set)
 static void parse_syslogdcfg(const char *file)
 {
        char *t;
-       logRule_t **pp_rule;
        /* tok[0] set of selectors */
        /* tok[1] file name */
        /* tok[2] has to be NULL */
@@ -408,18 +415,18 @@ static void parse_syslogdcfg(const char *file)
                /* proceed as if we built busybox without config support */
                return;
 
-       /* 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));
+               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;..." */
@@ -491,11 +498,28 @@ static void parse_syslogdcfg(const char *file)
                                        if (next_facility)
                                                *next_facility++ = '\0';
                                        code = find_by_name(t, 
bb_facilitynames);
-                                       if (!code)
-                                               goto cfgerr;
-                                       /* "mark" is not a real facility, skip 
it */
-                                       if (code->c_val != INTERNAL_MARK)
-                                               facmap |= 
1<<(LOG_FAC(code->c_val));
+                                       if (code) {
+                                               /* "mark" is not a real 
facility, skip it */
+                                               if (code->c_val != 
INTERNAL_MARK)
+                                                       facmap |= 
1<<(LOG_FAC(code->c_val));
+                                       } else { /* Treat this as string match 
filter */
+                                               stringMatch_t *strmatch;
+                                               /* Merge if previously found */
+                                               for (strmatch = 
cur_rule->strmatch; strmatch; strmatch = strmatch->prev)
+                                                       if 
(!strcmp(strmatch->str, t))
+                                                               break;
+                                               if (!strmatch) {
+                                                       strmatch = 
xzalloc(sizeof(struct stringMatch_t));
+                                                       strmatch->str = 
xstrdup(t);
+                                                       strmatch->len = 
strlen(t);
+                                                       strmatch->prev = 
cur_rule->strmatch;
+                                                       cur_rule->strmatch = 
strmatch;
+                                               }
+                                               if (negated_prio)
+                                                       
strmatch->enabled_priomap &= primap;
+                                               else
+                                                       
strmatch->enabled_priomap |= primap;
+                                       }
                                        t = next_facility;
                                } while (t);
                        }
@@ -518,25 +542,19 @@ 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) {
+
+               for (tmp = cur_rule->prev; tmp; tmp = tmp->prev) {
+                       if (strcmp(tmp->file->path, tok[1]) == 0) {
                                /* found - reuse the same file structure */
-                               (*pp_rule)->file = cur_rule->file;
-                               cur_rule = *pp_rule;
-                               goto found;
+                               cur_rule->file = tmp->file;
+                               continue;
                        }
                }
                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;
        }
        config_close(parser);
        return;
@@ -879,10 +897,18 @@ 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;
+                       } else { /* check if message starts with any string in 
list rule->strmatch */
+                               stringMatch_t *strmatch;
+                               for (strmatch = rule->strmatch; strmatch; 
strmatch = strmatch->prev) {
+                                       if (!memcmp(strmatch->str, msg, 
strmatch->len) && strmatch->enabled_priomap & prio_bit) {
+                                               log_locally(now, G.printbuf, 
rule->file);
+                                               match = 1;
+                                       }
+                               }
                        }
                }
                if (match)
-- 
2.25.1

_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to