Merge branch 'develop' into MXS-544

This commit is contained in:
Markus Makela
2016-02-29 10:18:49 +02:00
128 changed files with 6094 additions and 3949 deletions

View File

@ -2,7 +2,7 @@ if(BUILD_RABBITMQ)
if(RABBITMQ_FOUND)
include_directories(${RABBITMQ_HEADERS})
add_library(mqfilter SHARED mqfilter.c)
target_link_libraries(mqfilter query_classifier maxscale-common ${RABBITMQ_LIBRARIES})
target_link_libraries(mqfilter maxscale-common ${RABBITMQ_LIBRARIES})
add_dependencies(mqfilter pcre2)
install(TARGETS mqfilter DESTINATION ${MAXSCALE_LIBDIR})
else()
@ -36,11 +36,6 @@ target_link_libraries(topfilter maxscale-common)
set_target_properties(topfilter PROPERTIES VERSION "1.0.1")
install(TARGETS topfilter DESTINATION ${MAXSCALE_LIBDIR})
add_library(dbfwfilter SHARED dbfwfilter.c)
target_link_libraries(dbfwfilter maxscale-common query_classifier)
set_target_properties(dbfwfilter PROPERTIES VERSION "1.0.0")
install(TARGETS dbfwfilter DESTINATION ${MAXSCALE_LIBDIR})
add_library(namedserverfilter SHARED namedserverfilter.c)
target_link_libraries(namedserverfilter maxscale-common)
set_target_properties(namedserverfilter PROPERTIES VERSION "1.1.0")
@ -49,7 +44,7 @@ install(TARGETS namedserverfilter DESTINATION ${MAXSCALE_LIBDIR})
if(BUILD_SLAVELAG)
add_library(slavelag SHARED slavelag.c)
target_link_libraries(slavelag maxscale-common query_classifier)
target_link_libraries(slavelag maxscale-common)
set_target_properties(slavelag PROPERTIES VERSION "1.1.0")
install(TARGETS slavelag DESTINATION ${MAXSCALE_LIBDIR})
endif()
@ -57,11 +52,12 @@ endif()
if(BUILD_TOOLS)
add_executable(ruleparser dbfwfilter.c)
target_compile_definitions(ruleparser PUBLIC "BUILD_RULE_PARSER")
target_link_libraries(ruleparser maxscale-common query_classifier)
target_link_libraries(ruleparser maxscale-common)
install(TARGETS ruleparser DESTINATION ${MAXSCALE_BINDIR})
endif()
add_subdirectory(hint)
add_subdirectory(dbfwfilter)
if(BUILD_TESTS)
add_subdirectory(test)

View File

@ -0,0 +1,15 @@
find_package(FLEX)
find_package(BISON)
if(BISON_FOUND AND FLEX_FOUND)
bison_target(ruleparser ruleparser.y ${CMAKE_CURRENT_BINARY_DIR}/ruleparser.c COMPILE_FLAGS "--defines=${CMAKE_CURRENT_BINARY_DIR}/ruleparser.yy.h")
flex_target(token token.l ${CMAKE_CURRENT_BINARY_DIR}/token.c COMPILE_FLAGS "--header-file=${CMAKE_CURRENT_BINARY_DIR}/lex.yy.h")
add_flex_bison_dependency(token ruleparser)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
add_library(dbfwfilter SHARED dbfwfilter.c ${BISON_ruleparser_OUTPUTS} ${FLEX_token_OUTPUTS})
target_link_libraries(dbfwfilter maxscale-common)
set_target_properties(dbfwfilter PROPERTIES VERSION "1.0.0")
install(TARGETS dbfwfilter DESTINATION ${MAXSCALE_LIBDIR})
else()
mesage(FATAL_ERROR "Could not find Bison or Flex: ${BISON_EXECUTABLE} ${FLEX_EXECUTABLE}")
endif()

View File

@ -0,0 +1,58 @@
#ifndef _DBFWFILTER_H
#define _DBFWFILTER_H
/*
* This file is distributed as part of MaxScale by MariaDB Corporation. It is free
* software: you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation,
* version 2.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright MariaDB Corporation Ab 2016
*/
/**
* @file dbfwfilter.h - Database firewall filter
*
* External functions used by the rule parser. These functions are called from
* the generater parser which is created from the ruleparser.y and token.l files.
*/
#include <stdbool.h>
/** Matching type */
enum match_type
{
FWTOK_MATCH_ANY,
FWTOK_MATCH_ALL,
FWTOK_MATCH_STRICT_ALL
};
/** Prototype for the parser's error handler */
void dbfw_yyerror(void* scanner, const char* error);
/** Rule creation and definition functions */
bool create_rule(void* scanner, const char* name);
void define_wildcard_rule(void* scanner);
void define_where_clause_rule(void* scanner);
bool define_regex_rule(void* scanner, char* pattern);
bool define_columns_rule(void* scanner, char* columns);
bool define_limit_queries_rule(void* scanner, int max, int timeperiod, int holdoff);
bool add_at_times_rule(void* scanner, const char* range);
void add_on_queries_rule(void* scanner, const char* sql);
/** User creation functions */
bool add_active_user(void* scanner, const char* name);
bool add_active_rule(void* scanner, const char* name);
void set_matching_mode(void* scanner, enum match_type mode);
bool create_user_templates(void* scanner);
#endif

View File

@ -0,0 +1,131 @@
/*
* This file is distributed as part of MaxScale by MariaDB Corporation. It is free
* software: you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation,
* version 2.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright MariaDB Corporation Ab 2016
*/
%union{
int intval;
char* strval;
float floatval;
}
%{
#include <lex.yy.h>
#include <dbfwfilter.h>
%}
/** We need a reentrant scanner so no global variables are used */
%pure-parser
/** Prefix all functions */
%name-prefix="dbfw_yy"
/** The pure parser requires one extra parameter */
%parse-param {void* scanner}
%lex-param {void* scanner}
/** Terminal symbols */
%token FWTOK_RULE <strval>FWTOK_RULENAME FWTOK_USERS <strval>FWTOK_USER FWTOK_RULES FWTOK_MATCH FWTOK_ANY FWTOK_ALL FWTOK_STRICT_ALL FWTOK_DENY
%token FWTOK_WILDCARD FWTOK_COLUMNS FWTOK_REGEX FWTOK_LIMIT_QUERIES FWTOK_WHERE_CLAUSE FWTOK_AT_TIMES FWTOK_ON_QUERIES
%token <strval>FWTOK_SQLOP FWTOK_COMMENT <intval>FWTOK_INT <floatval>FWTOK_FLOAT FWTOK_PIPE <strval>FWTOK_TIME
%token <strval>FWTOK_BTSTR <strval>FWTOK_QUOTEDSTR <strval>FWTOK_STR
/** Non-terminal symbols */
%type <strval>rulename
%type <strval>cond
%type <strval>columnlist
%type <strval>orlist
%%
input:
| input line
;
line:
'\n'
| rule '\n'
| user '\n'
| FWTOK_COMMENT '\n'
;
rule:
FWTOK_RULE rulename {if (!create_rule(scanner, $2)){YYERROR;}} FWTOK_DENY ruleparams
;
ruleparams:
mandatory optional optional
| mandatory optional
| mandatory
| optional
;
rulename:
FWTOK_RULENAME
| FWTOK_STR
;
user:
FWTOK_USERS userlist FWTOK_MATCH cond FWTOK_RULES namelist
{if (!create_user_templates(scanner)){YYERROR;}}
;
userlist:
FWTOK_USER {if (!add_active_user(scanner, $1)){YYERROR;}}
| userlist FWTOK_USER {if (!add_active_user(scanner, $2)){YYERROR;}}
;
namelist:
rulename {if (!add_active_rule(scanner, $1)){YYERROR;}}
| namelist rulename {if (!add_active_rule(scanner, $2)){YYERROR;}}
;
cond:
FWTOK_ANY {set_matching_mode(scanner, FWTOK_MATCH_ANY);}
| FWTOK_ALL {set_matching_mode(scanner, FWTOK_MATCH_ALL);}
| FWTOK_STRICT_ALL {set_matching_mode(scanner, FWTOK_MATCH_STRICT_ALL);}
;
mandatory:
FWTOK_WILDCARD {define_wildcard_rule(scanner);}
| FWTOK_WHERE_CLAUSE {define_where_clause_rule(scanner);}
| FWTOK_LIMIT_QUERIES FWTOK_INT FWTOK_INT FWTOK_INT
{if (!define_limit_queries_rule(scanner, $2, $3, $4)){YYERROR;}}
| FWTOK_REGEX FWTOK_QUOTEDSTR {if (!define_regex_rule(scanner, $2)){YYERROR;}}
| FWTOK_COLUMNS columnlist
;
columnlist:
FWTOK_BTSTR {if (!define_columns_rule(scanner, $1)){YYERROR;}}
| FWTOK_STR {if (!define_columns_rule(scanner, $1)){YYERROR;}}
| columnlist FWTOK_BTSTR {if (!define_columns_rule(scanner, $2)){YYERROR;}}
| columnlist FWTOK_STR {if (!define_columns_rule(scanner, $2)){YYERROR;}}
;
optional:
FWTOK_AT_TIMES timelist
| FWTOK_ON_QUERIES orlist
;
timelist:
FWTOK_TIME {if (!add_at_times_rule(scanner, $1)){YYERROR;}}
| timelist FWTOK_TIME {if (!add_at_times_rule(scanner, $2)){YYERROR;}}
;
orlist:
FWTOK_SQLOP {add_on_queries_rule(scanner, $1);}
| orlist FWTOK_PIPE FWTOK_SQLOP {add_on_queries_rule(scanner, $3);}
;

View File

@ -0,0 +1,76 @@
/*
* This file is distributed as part of MaxScale by MariaDB Corporation. It is free
* software: you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation,
* version 2.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright MariaDB Corporation Ab 2016
*/
%{
#include <ruleparser.yy.h>
%}
%option reentrant noyywrap bison-bridge prefix="dbfw_yy"
%option yylineno
RULENAME [-_[:alnum:][:punct:]]+
STR [_[:alnum:]]+
TIME [0-9]{2}:[0-9]{2}:[0-9]{2}-[0-9]{2}:[0-9]{2}:[0-9]{2}
QSTR (\"[^\"]*\")|('[^']*')
SPACE [[:space:]]*
COMMENT ^[[:space:]]*#.*
INT [0-9]+
FLOAT [0-9]+[.][0-9]+
SQL select|insert|update|delete
PIPE [|]
USER [^[:space:]]*[@]
IP [0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}
BTSTR `[^`]*`
USTR [%-_[:alnum:][:punct:]]+
%%
"\n"+ return '\n';
{COMMENT} return FWTOK_COMMENT;
deny|allow return FWTOK_DENY; /** This should be removed at some point */
rule return FWTOK_RULE;
no_where_clause return FWTOK_WHERE_CLAUSE;
wildcard return FWTOK_WILDCARD;
columns return FWTOK_COLUMNS;
regex return FWTOK_REGEX;
limit_queries return FWTOK_LIMIT_QUERIES;
at_times return FWTOK_AT_TIMES;
on_queries return FWTOK_ON_QUERIES;
users return FWTOK_USERS;
rules return FWTOK_RULES;
match return FWTOK_MATCH;
any return FWTOK_ANY;
all return FWTOK_ALL;
strict_all return FWTOK_STRICT_ALL;
{USTR}@{USTR} yylval->strval = yytext;return FWTOK_USER;
{BTSTR}@{BTSTR} yylval->strval = yytext;return FWTOK_USER;
{QSTR}@{QSTR} yylval->strval = yytext;return FWTOK_USER;
({SQL}{SPACE}{PIPE}{SPACE})*{SQL} {
yylval->strval = yytext;return FWTOK_SQLOP;
}
{TIME} yylval->strval = yytext;return FWTOK_TIME;
{PIPE} return FWTOK_PIPE;
{INT} yylval->intval = atoi(yytext);return FWTOK_INT;
{FLOAT} yylval->floatval = atof(yytext);return FWTOK_FLOAT;
{QSTR} yylval->strval = yytext;return FWTOK_QUOTEDSTR;
{BTSTR} yylval->strval = yytext;return FWTOK_BTSTR;
{STR} yylval->strval = yytext;return FWTOK_STR;
{RULENAME} yylval->strval = yytext;return FWTOK_RULENAME;
{SPACE} ;
%%

View File

@ -80,7 +80,6 @@
#include <query_classifier.h>
#include <spinlock.h>
#include <session.h>
#include <plugin.h>
#include <housekeeper.h>
MODULE_INFO info =

View File

@ -85,7 +85,6 @@ typedef struct
char *user; /* User name to restrict matches */
char *match; /* Regular expression to match */
char *server; /* Server to route to */
int cflags; /* Regexec compile flags */
regex_t re; /* Compiled regex text */
} REGEXHINT_INSTANCE;
@ -147,14 +146,17 @@ static FILTER *
createInstance(char **options, FILTER_PARAMETER **params)
{
REGEXHINT_INSTANCE *my_instance;
int i, cflags = REG_ICASE;
int cflags = REG_ICASE;
if ((my_instance = calloc(1, sizeof(REGEXHINT_INSTANCE))) != NULL)
if ((my_instance = malloc(sizeof(REGEXHINT_INSTANCE))) != NULL)
{
my_instance->match = NULL;
my_instance->server = NULL;
my_instance->source = NULL;
my_instance->user = NULL;
bool error = false;
for (i = 0; params && params[i]; i++)
for (int i = 0; params && params[i]; i++)
{
if (!strcmp(params[i]->name, "match"))
{
@ -176,12 +178,13 @@ createInstance(char **options, FILTER_PARAMETER **params)
{
MXS_ERROR("namedserverfilter: Unexpected parameter '%s'.",
params[i]->name);
error = true;
}
}
if (options)
{
for (i = 0; options[i]; i++)
for (int i = 0; options[i]; i++)
{
if (!strcasecmp(options[i], "ignorecase"))
{
@ -191,34 +194,54 @@ createInstance(char **options, FILTER_PARAMETER **params)
{
cflags &= ~REG_ICASE;
}
else if (!strcasecmp(options[i], "extended"))
{
cflags |= REG_EXTENDED;
}
else
{
MXS_ERROR("namedserverfilter: unsupported option '%s'.",
MXS_ERROR("namedserverfilter: Unsupported option '%s'.",
options[i]);
error = true;
}
}
}
my_instance->cflags = cflags;
if (my_instance->match == NULL || my_instance->server == NULL)
if (my_instance->match == NULL)
{
MXS_ERROR("namedserverfilter: Missing required configured"
" option. You must specify a match and server "
"option as a minimum.");
free(my_instance);
return NULL;
MXS_ERROR("namedserverfilter: Missing required parameters 'match'.");
error = true;
}
if (regcomp(&my_instance->re, my_instance->match,
my_instance->cflags))
if (my_instance->server == NULL)
{
MXS_ERROR("namedserverfilter: Missing required parameters 'server'.");
error = true;
}
if (my_instance->server && my_instance->match &&
regcomp(&my_instance->re, my_instance->match, cflags))
{
MXS_ERROR("namedserverfilter: Invalid regular expression '%s'.\n",
my_instance->match);
free(my_instance->match);
free(my_instance->server);
free(my_instance);
return NULL;
my_instance->match = NULL;
error = true;
}
if (error)
{
if (my_instance->match)
{
regfree(&my_instance->re);
free(my_instance->match);
}
free(my_instance->server);
free(my_instance->source);
free(my_instance->user);
free(my_instance);
my_instance = NULL;
}
}
return(FILTER *) my_instance;
}

View File

@ -175,20 +175,15 @@ createInstance(char **options, FILTER_PARAMETER **params)
QLA_INSTANCE *my_instance;
int i;
if ((my_instance = calloc(1, sizeof(QLA_INSTANCE))) != NULL)
if ((my_instance = malloc(sizeof(QLA_INSTANCE))) != NULL)
{
if (options)
{
my_instance->filebase = strdup(options[0]);
}
else
{
my_instance->filebase = strdup("qla");
}
my_instance->source = NULL;
my_instance->userName = NULL;
my_instance->match = NULL;
my_instance->nomatch = NULL;
my_instance->filebase = NULL;
bool error = false;
if (params)
{
for (i = 0; params[i]; i++)
@ -211,55 +206,90 @@ createInstance(char **options, FILTER_PARAMETER **params)
}
else if (!strcmp(params[i]->name, "filebase"))
{
if (my_instance->filebase)
{
free(my_instance->filebase);
my_instance->filebase = NULL;
}
my_instance->filebase = strdup(params[i]->value);
}
else if (!filter_standard_parameter(params[i]->name))
{
MXS_ERROR("qlafilter: Unexpected parameter '%s'.",
params[i]->name);
error = true;
}
}
}
int cflags = REG_ICASE;
if (options)
{
for (i = 0; options[i]; i++)
{
if (!strcasecmp(options[i], "ignorecase"))
{
cflags |= REG_ICASE;
}
else if (!strcasecmp(options[i], "case"))
{
cflags &= ~REG_ICASE;
}
else if (!strcasecmp(options[i], "extended"))
{
cflags |= REG_EXTENDED;
}
else
{
MXS_ERROR("qlafilter: Unsupported option '%s'.",
options[i]);
error = true;
}
}
}
if (my_instance->filebase == NULL)
{
MXS_ERROR("qlafilter: No 'filebase' parameter defined.");
error = true;
}
my_instance->sessions = 0;
if (my_instance->match &&
regcomp(&my_instance->re, my_instance->match, REG_ICASE))
regcomp(&my_instance->re, my_instance->match, cflags))
{
MXS_ERROR("qlafilter: Invalid regular expression '%s'"
" for the match parameter.\n",
" for the 'match' parameter.\n",
my_instance->match);
free(my_instance->match);
free(my_instance->source);
if (my_instance->filebase)
{
free(my_instance->filebase);
}
free(my_instance);
return NULL;
my_instance->match = NULL;
error = true;
}
if (my_instance->nomatch &&
regcomp(&my_instance->nore, my_instance->nomatch,
REG_ICASE))
regcomp(&my_instance->nore, my_instance->nomatch, cflags))
{
MXS_ERROR("qlafilter: Invalid regular expression '%s'"
" for the nomatch paramter.",
my_instance->match);
" for the 'nomatch' parameter.",
my_instance->nomatch);
free(my_instance->nomatch);
my_instance->nomatch = NULL;
error = true;
}
if (error)
{
if (my_instance->match)
{
free(my_instance->match);
regfree(&my_instance->re);
}
free(my_instance->match);
free(my_instance->source);
if (my_instance->filebase)
if (my_instance->match)
{
free(my_instance->filebase);
free(my_instance->match);
regfree(&my_instance->re);
}
free(my_instance->filebase);
free(my_instance->source);
free(my_instance->userName);
free(my_instance);
return NULL;
my_instance = NULL;
}
}
return(FILTER *) my_instance;

View File

@ -407,6 +407,33 @@ createInstance(char **options, FILTER_PARAMETER **params)
}
}
}
int cflags = REG_ICASE;
if (options)
{
for (i = 0; options[i]; i++)
{
if (!strcasecmp(options[i], "ignorecase"))
{
cflags |= REG_ICASE;
}
else if (!strcasecmp(options[i], "case"))
{
cflags &= ~REG_ICASE;
}
else if (!strcasecmp(options[i], "extended"))
{
cflags |= REG_EXTENDED;
}
else
{
MXS_ERROR("tee: unsupported option '%s'.",
options[i]);
}
}
}
if (my_instance->service == NULL)
{
free(my_instance->match);
@ -416,7 +443,7 @@ createInstance(char **options, FILTER_PARAMETER **params)
}
if (my_instance->match &&
regcomp(&my_instance->re, my_instance->match, REG_ICASE))
regcomp(&my_instance->re, my_instance->match, cflags))
{
MXS_ERROR("tee: Invalid regular expression '%s'"
" for the match parameter.",
@ -427,8 +454,7 @@ createInstance(char **options, FILTER_PARAMETER **params)
return NULL;
}
if (my_instance->nomatch &&
regcomp(&my_instance->nore, my_instance->nomatch,
REG_ICASE))
regcomp(&my_instance->nore, my_instance->nomatch, cflags))
{
MXS_ERROR("tee: Invalid regular expression '%s'"
" for the nomatch paramter.\n",

View File

@ -176,7 +176,6 @@ GetModuleObject()
{
return &MyObject;
}
/**
* Create an instance of the filter for a particular service
* within MaxScale.
@ -192,14 +191,16 @@ createInstance(char **options, FILTER_PARAMETER **params)
int i;
TOPN_INSTANCE *my_instance;
if ((my_instance = calloc(1, sizeof(TOPN_INSTANCE))) != NULL)
if ((my_instance = malloc(sizeof(TOPN_INSTANCE))) != NULL)
{
my_instance->topN = 10;
my_instance->match = NULL;
my_instance->exclude = NULL;
my_instance->source = NULL;
my_instance->user = NULL;
my_instance->filebase = strdup("top");
my_instance->filebase = NULL;
bool error = false;
for (i = 0; params && params[i]; i++)
{
if (!strcmp(params[i]->name, "count"))
@ -208,7 +209,6 @@ createInstance(char **options, FILTER_PARAMETER **params)
}
else if (!strcmp(params[i]->name, "filebase"))
{
free(my_instance->filebase);
my_instance->filebase = strdup(params[i]->value);
}
else if (!strcmp(params[i]->name, "match"))
@ -231,41 +231,84 @@ createInstance(char **options, FILTER_PARAMETER **params)
{
MXS_ERROR("topfilter: Unexpected parameter '%s'.",
params[i]->name);
error = true;
}
}
int cflags = REG_ICASE;
if (options)
{
MXS_ERROR("topfilter: Options are not supported by this "
" filter. They will be ignored.");
for (i = 0; options[i]; i++)
{
if (!strcasecmp(options[i], "ignorecase"))
{
cflags |= REG_ICASE;
}
else if (!strcasecmp(options[i], "case"))
{
cflags &= ~REG_ICASE;
}
else if (!strcasecmp(options[i], "extended"))
{
cflags |= REG_EXTENDED;
}
else
{
MXS_ERROR("topfilter: Unsupported option '%s'.",
options[i]);
error = true;
}
}
}
if (my_instance->filebase == NULL)
{
MXS_ERROR("topfilter: No 'filebase' parameter defined.");
error = true;
}
my_instance->sessions = 0;
if (my_instance->match &&
regcomp(&my_instance->re, my_instance->match, REG_ICASE))
regcomp(&my_instance->re, my_instance->match, cflags))
{
MXS_ERROR("topfilter: Invalid regular expression '%s'"
" for the match parameter.",
my_instance->match);
free(my_instance->match);
free(my_instance->source);
free(my_instance->user);
free(my_instance->filebase);
free(my_instance);
return NULL;
}
if (my_instance->exclude &&
regcomp(&my_instance->exre, my_instance->exclude,
REG_ICASE))
{
MXS_ERROR("qlafilter: Invalid regular expression '%s'"
" for the nomatch paramter.\n",
" for the 'match' parameter.",
my_instance->match);
regfree(&my_instance->re);
free(my_instance->match);
my_instance->match = NULL;
error = true;
}
if (my_instance->exclude &&
regcomp(&my_instance->exre, my_instance->exclude, cflags))
{
MXS_ERROR("topfilter: Invalid regular expression '%s'"
" for the 'nomatch' parameter.\n",
my_instance->exclude);
regfree(&my_instance->exre);
free(my_instance->exclude);
my_instance->exclude = NULL;
error = true;
}
if (error)
{
if (my_instance->exclude)
{
regfree(&my_instance->exre);
free(my_instance->exclude);
}
if (my_instance->match)
{
regfree(&my_instance->re);
free(my_instance->match);
}
free(my_instance->filebase);
free(my_instance->source);
free(my_instance->user);
free(my_instance->filebase);
free(my_instance);
return NULL;
my_instance = NULL;
}
}
return(FILTER *) my_instance;