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

diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c
index 6ddfd771a..cf9d1b61f 100644
--- a/sysklogd/syslogd.c
+++ b/sysklogd/syslogd.c
@@ -227,9 +227,17 @@ 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 stringMatch_t *strmatch;
        struct logRule_t *next;
 } logRule_t;
 #endif
@@ -491,11 +499,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);
                        }
@@ -818,8 +843,7 @@ static void parse_fac_prio_20(int pri, char *res20)
        snprintf(res20, 20, "<%d>", pri);
 }
 
-/* len parameter is used only for "is there a timestamp?" check.
- * NB: some callers cheat and supply len==0 when they know
+/* NB: some callers cheat and supply len==0 when they know
  * that there is no timestamp, short-circuiting the test. */
 static void timestamp_and_log(int pri, char *msg, int len)
 {
@@ -837,6 +861,7 @@ static void timestamp_and_log(int pri, char *msg, int len)
                        now = 0;
                }
                msg += 16;
+               len -= 16;
        }
 
 #if ENABLE_FEATURE_SYSLOGD_PRECISE_TIMESTAMPS
@@ -883,6 +908,16 @@ static void timestamp_and_log(int pri, char *msg, int len)
                        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 (len > strmatch->len && 
strmatch->enabled_priomap & prio_bit &&
+                                                !memcmp(strmatch->str, msg, 
strmatch->len) &&
+                                                (msg[strmatch->len] == ':' || 
msg[strmatch->len] == '[')) {
+                                               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