[PATCH v5 1/2] syslogd: add ability to filter based on start of message

Alexander Vickberg wickbergster at gmail.com
Tue Mar 16 13:36:38 UTC 2021


Signed-off-by: Alexander Vickberg <wickbergster at gmail.com>
---
 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



More information about the busybox mailing list