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