Alex 'AdUser' Z
9 years ago
8 changed files with 153 additions and 168 deletions
@ -0,0 +1,3 @@
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON) |
||||
|
||||
add_library("f2b_f_preg" SHARED "preg.c") |
@ -0,0 +1,12 @@
|
||||
#include <stdbool.h> |
||||
|
||||
#define HOST_TOKEN "<HOST>" |
||||
|
||||
typedef struct _config cfg_t; |
||||
|
||||
extern cfg_t *create(const char *id); |
||||
extern bool config(cfg_t *c, const char *key, const char *value); |
||||
extern bool append(cfg_t *c, const char *pattern); |
||||
extern bool ready(cfg_t *c); |
||||
extern bool match(cfg_t *c, const char *line, char *buf, size_t buf_size); |
||||
extern void destroy(cfg_t *c); |
@ -0,0 +1,132 @@
|
||||
#include <alloca.h> |
||||
#include <assert.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
|
||||
#include "filter.h" |
||||
|
||||
#include <regex.h> |
||||
|
||||
/* draft */ |
||||
#define HOST_REGEX "([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3})" |
||||
|
||||
typedef struct f2b_regex_t { |
||||
struct f2b_regex_t *next; |
||||
int matches; |
||||
regex_t regex; |
||||
} f2b_regex_t; |
||||
|
||||
struct _config { |
||||
char id[32]; |
||||
bool icase; |
||||
f2b_regex_t *regexps; |
||||
}; |
||||
|
||||
cfg_t * |
||||
create(const char *id) { |
||||
cfg_t *cfg = NULL; |
||||
|
||||
if ((cfg = calloc(1, sizeof(cfg_t))) == NULL) |
||||
return NULL; |
||||
strncpy(cfg->id, id, sizeof(cfg->id)); |
||||
cfg->id[sizeof(cfg->id)] = '\0'; |
||||
|
||||
return cfg; |
||||
} |
||||
|
||||
bool |
||||
config(cfg_t *cfg, const char *key, const char *value) { |
||||
assert(cfg != NULL); |
||||
assert(key != NULL); |
||||
assert(value != NULL); |
||||
|
||||
if (strcmp(key, "icase") == 0) { |
||||
cfg->icase = (strcmp(value, "yes") == 0) ? true : false; |
||||
return true; |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
bool |
||||
append(cfg_t *cfg, const char *pattern) { |
||||
f2b_regex_t *regex = NULL; |
||||
int flags = REG_EXTENDED; |
||||
size_t bufsize; |
||||
char *buf = NULL; |
||||
char *token = NULL; |
||||
|
||||
assert(pattern != NULL); |
||||
|
||||
if (cfg->icase) |
||||
flags |= REG_ICASE; |
||||
|
||||
if ((token = strstr(pattern, HOST_TOKEN)) == NULL) |
||||
return false; |
||||
|
||||
bufsize = strlen(pattern) + strlen(HOST_REGEX) + 1; |
||||
if ((buf = alloca(bufsize)) == NULL) |
||||
return false; |
||||
|
||||
memset(buf, 0x0, bufsize); |
||||
strncpy(buf, pattern, token - pattern); |
||||
strcat(buf, HOST_REGEX); |
||||
strcat(buf, token + strlen(HOST_TOKEN)); |
||||
|
||||
if ((regex = calloc(1, sizeof(f2b_regex_t))) == NULL) |
||||
return false; |
||||
|
||||
if (regcomp(®ex->regex, buf, flags) == 0) { |
||||
regex->next = cfg->regexps; |
||||
cfg->regexps = regex; |
||||
return true; |
||||
} |
||||
|
||||
free(regex); |
||||
return false; |
||||
} |
||||
|
||||
bool |
||||
ready(cfg_t *cfg) { |
||||
assert(cfg != NULL); |
||||
if (cfg->regexps) |
||||
return true; |
||||
return false; |
||||
} |
||||
|
||||
bool |
||||
match(cfg_t *cfg, const char *line, char *buf, size_t buf_size) { |
||||
f2b_regex_t *r = NULL; |
||||
size_t match_len = 0; |
||||
regmatch_t match[2]; |
||||
|
||||
assert(cfg != NULL); |
||||
assert(line != NULL); |
||||
assert(buf != NULL); |
||||
|
||||
for (r = cfg->regexps; r != NULL; r = r->next) { |
||||
if (regexec(&r->regex, line, 2, &match[0], 0) != 0) |
||||
continue; |
||||
/* matched */ |
||||
r->matches++; |
||||
match_len = match[1].rm_eo - match[1].rm_so; |
||||
assert(buf_size > match_len); |
||||
strncpy(buf, &line[match[1].rm_so], match_len); |
||||
buf[match_len] = '\0'; |
||||
return true; |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
void |
||||
destroy(cfg_t *cfg) { |
||||
f2b_regex_t *next = NULL, *r = NULL; |
||||
|
||||
for (r = cfg->regexps; r != NULL; r = next) { |
||||
next = r->next; |
||||
regfree(&r->regex); |
||||
free(r); |
||||
} |
||||
free(cfg); |
||||
} |
@ -1,85 +0,0 @@
|
||||
/* this file should not be used directly, only with `#include "regexps.c"` */ |
||||
|
||||
#include "log.h" |
||||
|
||||
f2b_regex_t * |
||||
f2b_regexlist_append(f2b_regex_t *list, f2b_regex_t *regex) { |
||||
assert(regex != NULL); |
||||
|
||||
regex->next = list; |
||||
return regex; |
||||
} |
||||
|
||||
bool |
||||
f2b_regexlist_match(f2b_regex_t *list, const char *line, char *buf, size_t buf_size) { |
||||
for (; list != NULL; list = list->next) { |
||||
if (f2b_regex_match(list, line, buf, buf_size)) |
||||
return true; |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
f2b_regex_t * |
||||
f2b_regexlist_from_file(const char *path) { |
||||
f2b_regex_t *list = NULL, *regex = NULL; |
||||
FILE *f = NULL; |
||||
size_t linenum = 0; |
||||
char line[REGEX_LINE_MAX] = ""; |
||||
char *p, *q; |
||||
|
||||
if ((f = fopen(path, "r")) == NULL) { |
||||
f2b_log_msg(log_error, "can't open regex list '%s': %s", path, strerror(errno)); |
||||
return NULL; |
||||
} |
||||
|
||||
while (1) { |
||||
p = fgets(line, sizeof(line), f); |
||||
if (!p && (feof(f) || ferror(f))) |
||||
break; |
||||
linenum++; |
||||
/* strip leading spaces */ |
||||
while (isblank(*p)) |
||||
p++; |
||||
/* strip trailing spaces */ |
||||
if ((q = strchr(p, '\r')) || (q = strchr(p, '\n'))) { |
||||
while(q > p && isspace(*q)) { |
||||
*q = '\0'; |
||||
q--; |
||||
} |
||||
} |
||||
switch(*p) { |
||||
case '\r': |
||||
case '\n': |
||||
case '\0': |
||||
/* empty line */ |
||||
break; |
||||
case ';': |
||||
case '#': |
||||
/* comment line */ |
||||
break; |
||||
default: |
||||
/* TODO: icase */ |
||||
if ((regex = f2b_regex_create(p, false)) == NULL) { |
||||
f2b_log_msg(log_warn, "can't create regex from pattern at %s:%d: %s", path, linenum, p); |
||||
continue; |
||||
} |
||||
list = f2b_regexlist_append(list, regex); |
||||
break; |
||||
} |
||||
} |
||||
|
||||
return list; |
||||
} |
||||
|
||||
f2b_regex_t * |
||||
f2b_regexlist_destroy(f2b_regex_t *list) { |
||||
f2b_regex_t *next; |
||||
|
||||
for (; list != NULL; list = next) { |
||||
next = list->next; |
||||
f2b_regex_destroy(list); |
||||
} |
||||
|
||||
return NULL; |
||||
} |
@ -1,78 +0,0 @@
|
||||
#include "common.h" |
||||
#include "regexps.h" |
||||
|
||||
#include <regex.h> |
||||
|
||||
/* draft */ |
||||
#define HOST_REGEX "([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3})" |
||||
|
||||
struct _regex { |
||||
struct _regex *next; |
||||
int matches; |
||||
regex_t regex; |
||||
}; |
||||
|
||||
f2b_regex_t * |
||||
f2b_regex_create(const char *pattern, bool icase) { |
||||
f2b_regex_t *regex = NULL; |
||||
int flags = REG_EXTENDED; |
||||
size_t bufsize; |
||||
char *buf = NULL; |
||||
char *token = NULL; |
||||
|
||||
assert(pattern != NULL); |
||||
|
||||
if (icase) |
||||
flags |= REG_ICASE; |
||||
|
||||
if ((token = strstr(pattern, HOST_TOKEN)) == NULL) |
||||
return NULL; |
||||
|
||||
bufsize = strlen(pattern) + strlen(HOST_REGEX) + 1; |
||||
if ((buf = alloca(bufsize)) == NULL) |
||||
return NULL; |
||||
|
||||
memset(buf, 0x0, bufsize); |
||||
strncpy(buf, pattern, token - pattern); |
||||
strcat(buf, HOST_REGEX); |
||||
strcat(buf, token + strlen(HOST_TOKEN)); |
||||
|
||||
if ((regex = calloc(1, sizeof(f2b_regex_t))) == NULL) |
||||
return NULL; |
||||
|
||||
if (regcomp(®ex->regex, buf, flags) == 0) |
||||
return regex; |
||||
|
||||
FREE(regex); |
||||
return NULL; |
||||
} |
||||
|
||||
void |
||||
f2b_regex_destroy(f2b_regex_t * regex) { |
||||
regfree(®ex->regex); |
||||
FREE(regex); |
||||
} |
||||
|
||||
bool |
||||
f2b_regex_match(f2b_regex_t *regex, const char *line, char *buf, size_t buf_size) { |
||||
size_t match_len = 0; |
||||
regmatch_t match[2]; |
||||
|
||||
assert(regex != NULL); |
||||
assert(line != NULL); |
||||
assert(buf != NULL); |
||||
|
||||
if (regexec(®ex->regex, line, 2, &match[0], 0) != 0) |
||||
return false; |
||||
|
||||
regex->matches++; |
||||
match_len = match[1].rm_eo - match[1].rm_so; |
||||
assert(buf_size > match_len); |
||||
strncpy(buf, &line[match[1].rm_so], match_len); |
||||
buf[match_len] = '\0'; |
||||
|
||||
return true; |
||||
} |
||||
|
||||
/* common f2b_regexlist_*() functions */ |
||||
#include "regexps.c" |
Loading…
Reference in new issue