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