diff options
author | Stef Walter <stef@memberwebs.com> | 2006-03-11 19:38:11 +0000 |
---|---|---|
committer | Stef Walter <stef@memberwebs.com> | 2006-03-11 19:38:11 +0000 |
commit | 5f88ca4b71e02bfba1c708d6ca54cc720020dfa7 (patch) | |
tree | 6994fc45ebe34cae9ba91ead39085f6e191443c1 | |
parent | 002625eac4f169cbcc36887075b10786c181835c (diff) |
Regular expression pattern matching and replacements
-rw-r--r-- | src/bsnmp-regex.c | 120 |
1 files changed, 110 insertions, 10 deletions
diff --git a/src/bsnmp-regex.c b/src/bsnmp-regex.c index 93b9ac2..72b12b2 100644 --- a/src/bsnmp-regex.c +++ b/src/bsnmp-regex.c @@ -123,7 +123,114 @@ strtrim (char* data) } /* ----------------------------------------------------------------------------- - * LOG READING AND MATCHING + * MATCHING + */ + +static int +process_match (struct data_entry *data, char *result) +{ +fprintf (stderr, "match for %s: %s\n", data->descr, result ? result : "MATCH"); + return 0; +} + +static char* +process_result (struct data_entry *data, char *line, int len, + int *ovector, int substrings) +{ + char *result; + char *p, *t; + int rlen, l; + int idx; + + /* Some nice little optimizations */ + if (!data->result) + return NULL; + if (strchr (data->result, '\\') == NULL) + return strdup (data->result); + + /* Figure out the string length */ + rlen = strlen (data->result) + 1; + for (p = data->result; *p; p++) { + if(p[0] == '\\') { + p++; + if(p[0] == '\\' || !isdigit(p[0])) + continue; + idx = p[0] - '0'; + ASSERT (idx >= 0 && idx <= 9); + if (idx < substrings) { + ASSERT (ovector[(idx * 2) + 1] >= ovector[idx * 2]); + ASSERT (ovector[(idx * 2) + 1] < len); + ASSERT (ovector[idx * 2] < len); + rlen += (ovector[(idx * 2) + 1]) - (ovector[idx * 2]); + rlen += 1; + } + } + } + + result = (char*)calloc(rlen, 1); + if (!result) { + emsg ("out of memory"); + return NULL; + } + + for (p = data->result, t = result; *p; p++) { + if (p[0] == '\\') { + p++; + if (isdigit(p[0])) { + idx = p[0] - '0'; + if (idx < substrings) { + l = (ovector[(idx * 2) + 1]) - (ovector[idx * 2]); + memcpy (t, line + (ovector[idx * 2]), l); + t += l; + } + continue; + } + } + + *t++ = *p; + } + + *t = 0; + return result; +} + +static void +process_log (char *line, int len) +{ + struct data_entry *data; + int ovector[30]; + char *result; + int r; + + for (data = TAILQ_FIRST (&entries); data; + data = TAILQ_NEXT (data, link)) { + + memset (ovector, 0, sizeof (ovector)); + result = NULL; + + r = pcre_exec (data->regex, data->extra, line, len, 0, + PCRE_NOTEMPTY | PCRE_NO_UTF8_CHECK, ovector, 30); + + if (r == PCRE_ERROR_NOMATCH) + continue; + else if (r == PCRE_ERROR_NOMEMORY) { + emsg ("out of memory"); + return; + } else if (r < 0) { + emsg ("internal error in matching code: %d", r); + return; + } + + result = process_result (data, line, len, ovector, r); + process_match (data, result); + free (result); + } + + fprintf (stderr, "log line: %s\n", line); +} + +/* ----------------------------------------------------------------------------- + * LOG READING */ static void @@ -143,12 +250,6 @@ close_fifo () } static void -process_log (char *line) -{ - fprintf (stderr, "log line: %s\n", line); -} - -static void receive_log (int fd, void *data) { char *t; @@ -187,12 +288,12 @@ receive_log (int fd, void *data) *t = 0; if (line_buffer != t && *(t - 1) == '\r') *(t - 1) = 0; + l = (t + 1) - line_buffer; /* Send it off */ - process_log (line_buffer); + process_log (line_buffer, l); /* Move data to front of buffer */ - l = (t + 1) - line_buffer; ASSERT (l <= len); memmove (line_buffer, t + 1, (len - l) + 1); len -= l; @@ -730,7 +831,6 @@ module_fini (void) close_fifo (); config_free_all (); - return 0; } |