From: Vsevolod Stakhov Date: Thu, 14 Aug 2008 13:14:02 +0000 (+0400) Subject: * Add initial implementation of C modules API X-Git-Tag: 0.2.7~394 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=8b8ae0cf7aeaff5d202ebb084e67fabaeb67d055;p=rspamd.git * Add initial implementation of C modules API --- diff --git a/Makefile.in b/Makefile.in index 1bf77d694..aa9112e70 100644 --- a/Makefile.in +++ b/Makefile.in @@ -21,7 +21,7 @@ clean: dist-clean: clean rm -f Makefile rm -f config.log - rm -f md5.h md5.c strlcpy.h strlcpy.c queue.h + rm -f md5.h md5.c strlcpy.h strlcpy.c queue.h config.h modules.c creategroup: @echo "Create group $(RSPAMD_GROUP) before installing!" diff --git a/cfg_file.h b/cfg_file.h index bc61cf8b7..bf532c588 100644 --- a/cfg_file.h +++ b/cfg_file.h @@ -15,6 +15,7 @@ #include #include #include +#include #include "upstream.h" #include "memcached.h" @@ -54,6 +55,8 @@ enum script_type { SCRIPT_CHAIN, }; +struct uri; + struct memcached_server { struct upstream up; struct in_addr addr; @@ -63,13 +66,27 @@ struct memcached_server { }; struct perl_module { - const char *path; + char *path; LIST_ENTRY (perl_module) next; }; +struct module_ctx { + int (*header_filter)(const char *header_name, const char *header_value); + int (*mime_filter)(GByteArray *content); + int (*message_filter)(GByteArray *content); + int (*uri_filter)(struct uri *uri); + int (*chain_filter)(GArray *results); +}; + +struct c_module { + const char *name; + struct module_ctx *ctx; + LIST_ENTRY (c_module) next; +}; + struct script_param { - const char *symbol; - const char *function; + char *symbol; + char *function; enum script_type type; LIST_ENTRY (script_param) next; }; @@ -102,7 +119,8 @@ struct config_file { unsigned int memcached_connect_timeout; LIST_HEAD (perlq, filter_chain) filters; - LIST_HEAD (modulesq, perl_module) modules; + LIST_HEAD (modulesq, perl_module) perl_modules; + LIST_HEAD (cmodulesq, c_module) c_modules; }; int add_memcached_server (struct config_file *cf, char *str); diff --git a/cfg_file.y b/cfg_file.y index 2af513eb6..0c6038f60 100644 --- a/cfg_file.y +++ b/cfg_file.y @@ -366,7 +366,7 @@ requirecmd: YYERROR; } cur->path = $3; - LIST_INSERT_HEAD (&cfg->modules, cur, next); + LIST_INSERT_HEAD (&cfg->perl_modules, cur, next); } ; diff --git a/cfg_utils.c b/cfg_utils.c index afaa6a262..78c37dabd 100644 --- a/cfg_utils.c +++ b/cfg_utils.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -10,8 +11,8 @@ #include #include #include -#include -#ifndef OWN_QUEUE_H +#include "config.h" +#ifndef HAVE_OWN_QUEUE_H #include #else #include "queue.h" @@ -127,7 +128,8 @@ init_defaults (struct config_file *cfg) cfg->workers_number = DEFAULT_WORKERS_NUM; LIST_INIT (&cfg->filters); - LIST_INIT (&cfg->modules); + LIST_INIT (&cfg->perl_modules); + LIST_INIT (&cfg->c_modules); } void @@ -136,6 +138,7 @@ free_config (struct config_file *cfg) struct filter_chain *chain, *tmp_chain; struct script_param *param, *tmp_param; struct perl_module *module, *tmp_module; + struct c_module *cmodule, *tmp_cmodule; if (cfg->pid_file) { g_free (cfg->pid_file); @@ -150,10 +153,10 @@ free_config (struct config_file *cfg) LIST_FOREACH_SAFE (chain, &cfg->filters, next, tmp_chain) { LIST_FOREACH_SAFE (param, chain->scripts, next, tmp_param) { if (param->symbol) { - g_free (param->symbol); + free (param->symbol); } if (param->function) { - g_free (param->function); + free (param->function); } LIST_REMOVE (param, next); free (param); @@ -161,14 +164,20 @@ free_config (struct config_file *cfg) LIST_REMOVE (chain, next); free (chain); } - LIST_FOREACH_SAFE (module, &cfg->modules, next, tmp_module) { + LIST_FOREACH_SAFE (module, &cfg->perl_modules, next, tmp_module) { if (module->path) { - g_free (module->path); + free (module->path); } LIST_REMOVE (module, next); free (module); } + LIST_FOREACH_SAFE (cmodule, &cfg->c_modules, next, tmp_cmodule) { + if (cmodule->ctx) { + free (cmodule->ctx); + } + free (cmodule); + } } int diff --git a/config.h.in b/config.h.in new file mode 100644 index 000000000..7b17b3427 --- /dev/null +++ b/config.h.in @@ -0,0 +1,11 @@ +#include + +/* Forwarded declaration */ +struct module_ctx; + +typedef struct module_s { + const char *name; + int (*module_init_func)(struct module_ctx *ctx); +} module_t; + +extern module_t modules[]; diff --git a/configure b/configure index 7748a2daf..1a822576d 100755 --- a/configure +++ b/configure @@ -19,8 +19,10 @@ YACC_SRC="cfg_file.y" LEX_SRC="cfg_file.l" YACC_OUTPUT="cfg_yacc.c" LEX_OUTPUT="cfg_lex.c" +CONFIG="config.h" SOURCES="upstream.c cfg_utils.c memcached.c main.c util.c worker.c fstring.c url.c perl.c ${LEX_OUTPUT} ${YACC_OUTPUT}" +MODULES="" CFLAGS="$CFLAGS -W -Wpointer-arith -Wno-unused-parameter" CFLAGS="$CFLAGS -Wno-unused-function -Wunused-variable -Wno-sign-compare" @@ -28,7 +30,7 @@ CFLAGS="$CFLAGS -Wunused-value -ggdb -I${LOCALBASE}/include" CFLAGS="$CFLAGS " LDFLAGS="$LDFLAGS -L/usr/lib -L${LOCALBASE}/lib" OPT_FLAGS="-O -pipe -fno-omit-frame-pointer" -DEPS="cfg_file.h memcached.h util.h main.h upstream.h fstring.h url.h perl.h ${LEX_OUTPUT} ${YACC_OUTPUT}" +DEPS="config.h cfg_file.h memcached.h util.h main.h upstream.h fstring.h url.h perl.h ${LEX_OUTPUT} ${YACC_OUTPUT}" EXEC=rspamd USER=postfix GROUP=postfix @@ -41,6 +43,18 @@ MAKEFILE_IN="Makefile.in" TARGETS="${EXEC}" +prepare_config() +{ + echo "#ifndef CONFIG_H_IN" > $CONFIG + echo "#define CONFIG_H_IN" >> $CONFIG + cat "$CONFIG.in" >> $CONFIG +} + +finish_config() +{ + echo "#endif" >> $CONFIG +} + cleanup() { rm -f autotest.c @@ -48,6 +62,11 @@ cleanup() INCLUDE="" } +have_opt() +{ + echo "#define HAVE_$1" >> $CONFIG +} + check_compiler() { GCC=`PATH="$PATH:$PREFIX/bin:$LOCALBASE/bin" which gcc` @@ -157,8 +176,8 @@ check_include() if [ $? -eq 0 ] ; then echo "found" echo "-> OK" >> config.log - _CFLAG=`echo "-DHAVE_$INCLUDE" | sed -e 's/[./]/_/g' | tr '[:lower:]' '[:upper:]'` - CFLAGS="$CFLAGS $_CFLAG" + _CFLAG=`echo "HAVE_$INCLUDE" | sed -e 's/[./]/_/g' | tr '[:lower:]' '[:upper:]'` + have_opt $_CFLAG cleanup return 0 else @@ -342,12 +361,15 @@ check_os() case "$_OS" in FreeBSD*) OS="freebsd" - CFLAGS="${CFLAGS} -DFREEBSD" + CFLAGS="${CFLAGS}" INSTALL="/usr/bin/install -C -S -v" MKDIR="/usr/bin/install -d -v" - MANPATH="${PREFIX}/man" ;; - Linux*) OS="linux" CFLAGS="${CFLAGS} -DLINUX -D_GNU_SOURCE" ;; - Solaris*) OS="solaris" CFLAGS="${CFLAGS} -DSOLARIS" ;; + MANPATH="${PREFIX}/man" + echo "#define FREEBSD" >> $CONFIG ;; + Linux*) OS="linux" CFLAGS="${CFLAGS} -D_GNU_SOURCE" + echo "#define LINUX" >> $CONFIG ;; + Solaris*) OS="solaris" CFLAGS="${CFLAGS}" + echo "#define SOLARIS" >> $CONFIG ;; *) OS="unknown" ;; esac } @@ -388,9 +410,21 @@ write_result() echo "Cflags: $CFLAGS" >> config.log echo "Ldflags: $LDFLAGS" >> config.log echo "Libs: $LIBS" >> config.log + echo "#define RVERSION \"${VERSION}\"" >> $CONFIG + echo "#define HASH_COMPAT" >> $CONFIG + # Write modules init function + echo "#include \"config.h\"" > modules.c + echo "module_t modules[] = {" >> modules.c; + modules_num=0 + for m in $MODULES ; do + echo "{\"${m}\", ${m}_module_init}," >> modules.c + modules_num=`expr $modules_num + 1` + done + echo "};" >> modules.c + echo "#define MODULES_NUM $modules_num" >> $CONFIG + SOURCES="$SOURCES modules.c" OBJECTS=`echo $SOURCES | sed -e 's/\.c/\.o/g'` # Make CFLAGS more readable - CFLAGS="$CFLAGS -DRVERSION=\\\"${VERSION}\\\" -DHASH_COMPAT" CFLAGS=`echo $CFLAGS | tr [:space:] \\\n | sed -e 's/$/ \\\/' | sed -e '$,$s/\\\//' | sort -r -k2 | uniq` LDFLAGS=`echo $LDLAGS | tr [:space:] \\\n | sed -e 's/$/ \\\/' | sed -e '$,$s/\\\//' | sort -r -k2 | uniq` LIBS=`echo $LIBS | tr [:space:] \\\n | sed -e 's/$/ \\\/' | sed -e '$,$s/\\\//' | sort -r -k2 | uniq` @@ -481,6 +515,19 @@ do --group) GROUP=$value ;; --enable-debug) CFLAGS="$CFLAGS -DWITH_DEBUG" OPT_FLAGS="" ;; --enable-opt) OPT_FLAGS="-O3 -pipe" ;; + --add-module) SOURCES="$SOURCES $value" + if [ ! -f $value ] ; then + echo "Cannot find $value, please check path" + exit 1 + fi + modline=`grep '/***MODULE:' $value` + if [ F"$modline" = "F" ] ; then + echo "Cannot find /***MODULE line in $value, please check syntax" + exit 1 + fi + + name=`echo $modline | sed 's/.*MODULE:\([^: ]*\).*/\1/'` + MODULES="$MODULES $name" ;; *) echo "$0: error: invalid option \"$option\"" exit 1 @@ -496,6 +543,7 @@ if [ "F$help" = "Fyes" ] ; then --prefix=PATH set the installation prefix --enable-debug turn on extra debug messages --enable-opt turn on extra optimization + --add-module add additional C module --user=USER set user to use --group=GROUP set group to use END @@ -508,6 +556,7 @@ LDFLAGS="$LDFLAGS -L$PREFIX/lib" echo "Starting configure for rmilter" >config.log echo $0 $@ >> config.log +prepare_config check_compiler check_make check_lex @@ -533,18 +582,18 @@ if [ $? -eq 1 ] ; then cp $COMPAT_DIR/md5.c . cp $COMPAT_DIR/md5.h . SOURCES="$SOURCES md5.c" - CFLAGS="$CFLAGS -DHAVE_OWN_MD5" DEPS="$DEPS md5.h" + have_opt "OWN_MD5" fi check_lib "util" if [ $? -eq 0 ] ; then - CFLAGS="$CFLAGS -DHAVE_LIBUTIL" + have_opt "LIBUTIL" fi check_function "pidfile_open" "sys/param.h" "libutil.h" if [ $? -eq 0 ] ; then - CFLAGS="$CFLAGS -DHAVE_PIDFILE" + have_opt "PIDFILE" fi check_function "strlcpy" "string.h" @@ -552,18 +601,18 @@ if [ $? -eq 1 ] ; then cp $COMPAT_DIR/strlcpy.c . cp $COMPAT_DIR/strlcpy.h . SOURCES="$SOURCES strlcpy.c" - CFLAGS="$CFLAGS -DHAVE_STRLCPY_H" DEPS="$DEPS strlcpy.h" + have_opt "STRLCPY_H" fi check_function "bzero" "string.h" check_function "srandomdev" if [ $? -eq 0 ] ; then - CFLAGS="$CFLAGS -DHAVE_SRANDOMDEV" + have_opt "SRANDOMDEV" fi check_function "setproctitle" "unistd.h" if [ $? -eq 0 ] ; then - CFLAGS="$CFLAGS -DHAVE_SETPROCTITLE" + have_opt "SETPROCTITLE" fi check_include "endian.h" @@ -585,20 +634,21 @@ fi check_macro "SLIST_FOREACH_SAFE" "sys/queue.h" if [ $? -eq 1 ] ; then cp $COMPAT_DIR/queue.h . - CFLAGS="$CFLAGS -DOWN_QUEUE_H" DEPS="$DEPS queue.h" + have_opt "OWN_QUEUE_H" fi check_macro "PATH_MAX" "limits.h" if [ $? -eq 1 ] ; then check_macro "MAXPATHLEN" "sys/param.h" if [ $? -eq 1 ] ; then - CFLAGS="$CFLAGS -DHAVE_MAXPATHLEN -DMAXPATHLEN=4096" + have_opt "MAXPATHLEN" + echo "#define MAXPATHLEN 4096" >> $CONFIG else - CFLAGS="$CFLAGS -DHAVE_MAXPATHLEN" + have_opt "MAXPATHLEN" fi else - CFLAGS="$CFLAGS -DHAVE_PATH_MAX" + have_opt "PATH_MAX" fi check_package "glib-2.0" "glib.h" @@ -623,3 +673,4 @@ if [ $? -ne 0 ] ; then TARGETS="$TARGETS createuser" fi write_result +finish_config diff --git a/main.c b/main.c index e53f7daf2..ecae9f139 100644 --- a/main.c +++ b/main.c @@ -75,7 +75,7 @@ init_filters (struct config_file *cfg) { struct perl_module *module; - LIST_FOREACH (module, &cfg->modules, next) { + LIST_FOREACH (module, &cfg->perl_modules, next) { if (module->path) { require_pv (module->path); } @@ -152,6 +152,7 @@ int main (int argc, char **argv) { struct rspamd_main *rspamd; + struct c_module *cur_module = NULL; int res = 0, i, listen_sock; struct sigaction signals; struct rspamd_worker *cur, *cur_tmp, *active_worker; @@ -225,6 +226,15 @@ main (int argc, char **argv) exit (-errno); } + /* Init C modules */ + for (i = 0; i < MODULES_NUM; i ++) { + cur_module = g_malloc (sizeof (struct c_module)); + cur_module->name = modules[i].name; + if (modules[i].module_init_func(cur_module->ctx) == 0) { + LIST_INSERT_HEAD (&cfg->c_modules, cur_module, next); + } + } + rspamd->pid = getpid(); rspamd->type = TYPE_MAIN; diff --git a/main.h b/main.h index 3eaad29c5..62a5244c9 100644 --- a/main.h +++ b/main.h @@ -1,9 +1,11 @@ #ifndef RPOP_MAIN_H #define RPOP_MAIN_H +#include "config.h" + #include #include -#ifndef OWN_QUEUE_H +#ifndef HAVE_OWN_QUEUE_H #include #else #include "queue.h" diff --git a/perl.c b/perl.c index 78a2c7670..e954292a3 100644 --- a/perl.c +++ b/perl.c @@ -17,7 +17,7 @@ extern PerlInterpreter *my_perl; int -call_header_filter (const char *function, const char *header_name, const char *header_value) +perl_call_header_filter (const char *function, const char *header_name, const char *header_value) { int result; dSP; @@ -45,7 +45,7 @@ call_header_filter (const char *function, const char *header_name, const char *h } int -call_mime_filter (const char *function, GByteArray *content) +perl_call_mime_filter (const char *function, GByteArray *content) { int result; dSP; @@ -72,7 +72,7 @@ call_mime_filter (const char *function, GByteArray *content) } int -call_message_filter (const char *function, GByteArray *content) +perl_call_message_filter (const char *function, GByteArray *content) { int result; dSP; @@ -99,7 +99,7 @@ call_message_filter (const char *function, GByteArray *content) } int -call_url_filter (const char *function, struct uri *uri) +perl_call_url_filter (const char *function, struct uri *uri) { int result; dSP; @@ -133,7 +133,7 @@ call_url_filter (const char *function, struct uri *uri) } int -call_chain_filter (const char *function, GArray *results) +perl_call_chain_filter (const char *function, GArray *results) { int result, i; diff --git a/perl.h b/perl.h index 6f74cae29..3a659bbe1 100644 --- a/perl.h +++ b/perl.h @@ -6,10 +6,10 @@ struct uri; -int call_header_filter (const char *function, const char *header_name, const char *header_value); -int call_mime_filter (const char *function, GByteArray *content); -int call_message_filter (const char *function, GByteArray *content); -int call_url_filter (const char *function, struct uri *uri); -int call_chain_filter (const char *function, GArray *results); +int perl_call_header_filter (const char *function, const char *header_name, const char *header_value); +int perl_call_mime_filter (const char *function, GByteArray *content); +int perl_call_message_filter (const char *function, GByteArray *content); +int perl_call_url_filter (const char *function, struct uri *uri); +int perl_call_chain_filter (const char *function, GArray *results); #endif diff --git a/upstream.h b/upstream.h index ad2ac4f4b..a6c6b2200 100644 --- a/upstream.h +++ b/upstream.h @@ -2,7 +2,7 @@ #define UPSTREAM_H #include - +#include struct upstream { unsigned int errors;