From 05c379a163fa84ac1ebfb28f93e31e9b8e8f6489 Mon Sep 17 00:00:00 2001 From: SJ Date: Sat, 7 Jan 2012 00:00:36 +0100 Subject: [PATCH] switched to preforking daemon --- Makefile.in | 3 +- configure | 175 +++------------------------- configure.in | 74 +++--------- etc/example.conf | 26 ++++- etc/sphinx.conf | 10 +- src/Makefile.in | 1 + src/cfg.c | 5 +- src/cfg.h | 4 +- src/config.h | 4 +- src/counters.c | 7 +- src/memcached.c | 204 --------------------------------- src/message.c | 2 +- src/parser_utils.c | 118 ++++++++++--------- src/piler.c | 280 ++++++++++++++++++++++++++++++++++----------- src/piler.h | 7 +- src/pilerimport.c | 13 +-- src/session.c | 26 +---- src/session.h | 10 -- src/test.c | 2 + 19 files changed, 368 insertions(+), 603 deletions(-) delete mode 100644 src/memcached.c delete mode 100644 src/session.h diff --git a/Makefile.in b/Makefile.in index 08dc4bf8..860a3705 100644 --- a/Makefile.in +++ b/Makefile.in @@ -68,11 +68,12 @@ installdirs: mkinstalldirs $(srcdir)/mkinstalldirs \ $(DESTDIR)$(bindir) $(DESTDIR)$(sbindir) $(DESTDIR)$(libdir) $(DESTDIR)$(libexecdir)/piler $(DESTDIR)$(sysconfdir) \ $(DESTDIR)$(datarootdir)/piler $(DESTDIR)$(includedir)/piler $(DESTDIR)$(localstatedir)/piler/store \ - $(DESTDIR)$(localstatedir)/piler/stat $(DESTDIR)$(localstatedir)/spool + $(DESTDIR)$(localstatedir)/piler/stat $(DESTDIR)$(localstatedir)/piler/tmp $(INSTALL) -d -m 0755 -o $(RUNNING_USER) -g $(RUNNING_GROUP) $(DESTDIR)$(localstatedir)/run/piler $(INSTALL) -d -m 0755 -o $(RUNNING_USER) -g $(RUNNING_GROUP) $(DESTDIR)$(localstatedir)/piler/store $(INSTALL) -d -m 0755 -o $(RUNNING_USER) -g $(RUNNING_GROUP) $(DESTDIR)$(localstatedir)/piler/stat + $(INSTALL) -d -m 0711 -o $(RUNNING_USER) -g $(RUNNING_GROUP) $(DESTDIR)$(localstatedir)/piler/tmp install-am: diff --git a/configure b/configure index 1d593da0..c69742c1 100755 --- a/configure +++ b/configure @@ -605,7 +605,6 @@ DATADIR CFGDIR MYSQL_CONFIG id_bin -sqlite3_batch libclamav_extra_libs mysql_obj mysql_libs @@ -673,8 +672,7 @@ ac_user_opts=' enable_option_checking enable_static_build enable_clamd -enable_whitelist -enable_blacklist +enable_memcached with_piler_user ' ac_precious_vars='build_alias @@ -1297,8 +1295,7 @@ Optional Features: --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-static-build build statically linked executables (default: dynamically linked) --enable-clamd build clamd antivirus support - --enable-whitelist use whitelist - --enable-blacklist use blacklist (this is _NOT_ RBL) + --enable-memcached build memcached support Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] @@ -3403,17 +3400,14 @@ done - have_libclamav="no" have_libtool="no" have_clamd="no" have_antivirus="no" have_mysql="no" -have_sqlite3="no" +have_tre="no" have_zlib="no" -have_whitelist="no" -have_blacklist="no" have_static_build="no" @@ -3423,7 +3417,6 @@ defs="" objs="" user_obj="" mysql_obj="" -sqlite3_batch="" os=`uname -s` id_bin="id" @@ -3456,34 +3449,14 @@ fi fi - -# Check whether --enable-whitelist was given. -if test "${enable_whitelist+set}" = set; then : - enableval=$enable_whitelist; want_whitelist=$enableval -else - want_whitelist="no" -fi - - - if test "$want_whitelist" = "yes"; then - have_whitelist="yes" - fi - - - -# Check whether --enable-blacklist was given. -if test "${enable_blacklist+set}" = set; then : - enableval=$enable_blacklist; want_blacklist=$enableval +# Check whether --enable-memcached was given. +if test "${enable_memcached+set}" = set; then : + enableval=$enable_memcached; want_memcached=$enableval else - want_blacklist="no" + want_memcached="no" fi - if test "$want_blacklist" = "yes"; then - have_blacklist="yes" - fi - - for ac_header in math.h @@ -3780,6 +3753,12 @@ fi fi ac_cv_lib_tre=ac_cv_lib_tre_main +if test "$have_tre" = "no"; then + echo "please install the tre development packages" + exit 1; +fi + + for ac_header in zlib.h @@ -4007,105 +3986,6 @@ else fi -for ac_header in sqlite3.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "sqlite3.h" "ac_cv_header_sqlite3_h" "$ac_includes_default" -if test "x$ac_cv_header_sqlite3_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_SQLITE3_H 1 -_ACEOF - have_sqlite3=yes -else - echo "sqlite3.h is not found" -fi - -done - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lsqlite3" >&5 -$as_echo_n "checking for main in -lsqlite3... " >&6; } -if ${ac_cv_lib_sqlite3_main+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsqlite3 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - -int -main () -{ -return main (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_sqlite3_main=yes -else - ac_cv_lib_sqlite3_main=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_main" >&5 -$as_echo "$ac_cv_lib_sqlite3_main" >&6; } -if test "x$ac_cv_lib_sqlite3_main" = xyes; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqlite3_open in -lsqlite3" >&5 -$as_echo_n "checking for sqlite3_open in -lsqlite3... " >&6; } -if ${ac_cv_lib_sqlite3_sqlite3_open+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsqlite3 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char sqlite3_open (); -int -main () -{ -return sqlite3_open (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_sqlite3_sqlite3_open=yes -else - ac_cv_lib_sqlite3_sqlite3_open=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_open" >&5 -$as_echo "$ac_cv_lib_sqlite3_sqlite3_open" >&6; } -if test "x$ac_cv_lib_sqlite3_sqlite3_open" = xyes; then : - have_sqlite3=yes -else - have_sqlite3=no -fi - -fi -ac_cv_lib_sqlite3=ac_cv_lib_sqlite3_main - - -if test "$have_sqlite3" = "no"; then - echo "sqlite3 not found"; - fi - - - -if test `sqlite3 -help 2>&1| grep -c -- -batch` -gt 0; then sqlite3_batch="-batch"; fi - @@ -4222,23 +4102,9 @@ if test "$have_clamd" = "yes"; then defs="$defs -DHAVE_CLAMD" fi -if test "$have_whitelist" = "yes"; then - echo "whitelist: yes" - defs="$defs -DHAVE_WHITELIST" -else - echo "whitelist: no" -fi - -if test "$have_blacklist" = "yes"; then - echo "blacklist: yes" - defs="$defs -DHAVE_BLACKLIST" -else - echo "blacklist: no" -fi - if test "$want_memcached" = "yes"; then echo "memcached support: yes" - objs="$objs memc.o memcached.o" + objs="$objs memc.o" defs="$defs -DHAVE_MEMCACHED" fi @@ -4261,12 +4127,6 @@ if test "$have_mysql" = "yes"; then defs="$defs -DNEED_MYSQL" fi -if test "$have_sqlite3" = "yes"; then - defs="$defs -DNEED_SQLITE3" - sqlite3_libs="-lsqlite3 -lpthread" -fi - - if test "$have_icc_guide" = "yes" && test "$have_mysql" = "yes"; then mysql_libs="$mysql_libs -lguide" fi @@ -4281,13 +4141,15 @@ if test "$have_clamd" = "no" ; then echo "piler will not protect you from hostile code coming in e-mail" fi +echo "piler data directory: $data_dir/piler" + echo; echo CFLAGS="$static -O2 -Wall -g" -LIBS="$antispam_libs $sunos_libs $sqlite3_libs" +LIBS="$antispam_libs $sunos_libs " OBJS="dirs.o misc.o counters.o cfg.o sig.o decoder.o list.o parser.o parser_utils.o rules.o session.o message.o attachment.o digest.o store.o tai.o $objs" -ac_config_files="$ac_config_files Makefile src/Makefile" +ac_config_files="$ac_config_files Makefile src/Makefile etc/Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -4994,6 +4856,7 @@ do "piler-config.h") CONFIG_HEADERS="$CONFIG_HEADERS piler-config.h" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; + "etc/Makefile") CONFIG_FILES="$CONFIG_FILES etc/Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac diff --git a/configure.in b/configure.in index 15269231..07b6ce00 100644 --- a/configure.in +++ b/configure.in @@ -26,7 +26,6 @@ AC_SUBST(mysql_includes) AC_SUBST(mysql_libs) AC_SUBST(mysql_obj) AC_SUBST(libclamav_extra_libs) -AC_SUBST(sqlite3_batch) AC_SUBST(id_bin) have_libclamav="no" @@ -35,10 +34,8 @@ have_clamd="no" have_antivirus="no" have_mysql="no" -have_sqlite3="no" +have_tre="no" have_zlib="no" -have_whitelist="no" -have_blacklist="no" have_static_build="no" @@ -48,7 +45,6 @@ defs="" objs="" user_obj="" mysql_obj="" -sqlite3_batch="" os=`uname -s` id_bin="id" @@ -74,25 +70,8 @@ AC_ARG_ENABLE(clamd, fi -dnl use whitelist - -AC_ARG_ENABLE(whitelist, - [ --enable-whitelist use whitelist], want_whitelist=$enableval, want_whitelist="no") - - if test "$want_whitelist" = "yes"; then - have_whitelist="yes" - fi - - -dnl use blacklist - -AC_ARG_ENABLE(blacklist, - [ --enable-blacklist use blacklist (this is _NOT_ RBL)], want_blacklist=$enableval, want_blacklist="no") - - if test "$want_blacklist" = "yes"; then - have_blacklist="yes" - fi - +AC_ARG_ENABLE(memcached, + [ --enable-memcached build memcached support], want_memcached=$enableval, want_memcached="no") dnl math library @@ -115,6 +94,12 @@ dnl TRE library AC_CHECK_HEADERS(tre/tre.h, have_tre=yes, echo "tre.h is not found") AC_CHECK_LIB([tre],[main],[AC_CHECK_LIB(tre, regcomp, have_tre=yes, echo "libtre.so is not found"; have_tre=no)],[],[])ac_cv_lib_tre=ac_cv_lib_tre_main +if test "$have_tre" = "no"; then + echo "please install the tre development packages" + exit 1; +fi + + dnl zlib @@ -146,19 +131,6 @@ else fi -AC_CHECK_HEADERS(sqlite3.h, have_sqlite3=yes, echo "sqlite3.h is not found") -AC_CHECK_LIB([sqlite3],[main],[AC_CHECK_LIB(sqlite3, sqlite3_open, have_sqlite3=yes, have_sqlite3=no)],[],[])ac_cv_lib_sqlite3=ac_cv_lib_sqlite3_main - - -if test "$have_sqlite3" = "no"; then - echo "sqlite3 not found"; - dnl exit 1; -fi - - - -if test `sqlite3 -help 2>&1| grep -c -- -batch` -gt 0; then sqlite3_batch="-batch"; fi - dnl user running piler @@ -254,23 +226,9 @@ if test "$have_clamd" = "yes"; then defs="$defs -DHAVE_CLAMD" fi -if test "$have_whitelist" = "yes"; then - echo "whitelist: yes" - defs="$defs -DHAVE_WHITELIST" -else - echo "whitelist: no" -fi - -if test "$have_blacklist" = "yes"; then - echo "blacklist: yes" - defs="$defs -DHAVE_BLACKLIST" -else - echo "blacklist: no" -fi - if test "$want_memcached" = "yes"; then echo "memcached support: yes" - objs="$objs memc.o memcached.o" + objs="$objs memc.o" defs="$defs -DHAVE_MEMCACHED" fi @@ -293,12 +251,6 @@ if test "$have_mysql" = "yes"; then defs="$defs -DNEED_MYSQL" fi -if test "$have_sqlite3" = "yes"; then - defs="$defs -DNEED_SQLITE3" - sqlite3_libs="-lsqlite3 -lpthread" -fi - - if test "$have_icc_guide" = "yes" && test "$have_mysql" = "yes"; then mysql_libs="$mysql_libs -lguide" fi @@ -313,12 +265,14 @@ if test "$have_clamd" = "no" ; then echo "piler will not protect you from hostile code coming in e-mail" fi +echo "piler data directory: $data_dir/piler" + echo; echo CFLAGS="$static -O2 -Wall -g" -LIBS="$antispam_libs $sunos_libs $sqlite3_libs" +LIBS="$antispam_libs $sunos_libs " OBJS="dirs.o misc.o counters.o cfg.o sig.o decoder.o list.o parser.o parser_utils.o rules.o session.o message.o attachment.o digest.o store.o tai.o $objs" -AC_CONFIG_FILES([Makefile src/Makefile]) +AC_CONFIG_FILES([Makefile src/Makefile etc/Makefile]) AC_OUTPUT diff --git a/etc/example.conf b/etc/example.conf index e6b81b4d..0ef94470 100644 --- a/etc/example.conf +++ b/etc/example.conf @@ -12,10 +12,10 @@ verbosity=1 username=piler ; number of worker processes, ie. the number of simultaneous smtp connections to piler. -number_of_worker_processes=5 +number_of_worker_processes=10 ; number of processed emails per each piler process -max_requests_per_child=50 +max_requests_per_child=1000 ; SMTP HELO identification string hostid=av-engine.localhost @@ -36,7 +36,13 @@ session_timeout=420 ; Please also note that the meaning of this variable depends on your Unix implementation backlog=20 -workdir=/var/spool/piler/tmp +workdir=/var/piler/tmp + + +; piler's own header to indicate previously archived messages +piler_header_field=X-piler: piler already archived this email + + ; comma separated list of your domains. piler uses this information to determine ; the direction of the given email @@ -53,7 +59,19 @@ memcached_servers=127.0.0.1 ; 0 means records don't expire memcached_ttl=86400 -piler_header_field=X-piler: ahahahahaha +; whether to update counters to memcached (1) or to the database (0) +update_counters_to_memcached=0 + +; interval to sync memcached data (eg. counters) to database +; this setting is only effective if you have update_counters_to_memcached=1 +; +; hint: if you are using a mysql replicated environment and you do _not_ want +; clapf to write to the replicated database (because you do sync it some other +; way to the master database or you are not interested in keeping the counters +; persistantly at all), then specify a big number here, that fits to the +; "long int" size, eg. 2147483647 +memcached_to_db_interval=900 + ; ; mysql stuff diff --git a/etc/sphinx.conf b/etc/sphinx.conf index f18f5b40..fc96d434 100644 --- a/etc/sphinx.conf +++ b/etc/sphinx.conf @@ -11,7 +11,7 @@ source main sql_pass = sphinx sql_query_pre = SET NAMES utf8 - sql_query = SELECT id, `from`, `to`, `subject`, `arrived`, `sent`, `body`, `size`, `direction`, `attachments`, `deleted` FROM sph_index \ + sql_query = SELECT id, `from`, `to`, `subject`, `arrived`, `sent`, `body`, `size`, `direction`, `attachments` FROM sph_index \ WHERE id<=( SELECT max_doc_id FROM sph_counter WHERE counter_id=1 ) sql_attr_uint = size @@ -19,7 +19,6 @@ source main sql_attr_uint = sent sql_attr_uint = direction sql_attr_uint = attachments - sql_attr_bool = deleted } @@ -34,7 +33,7 @@ source delta sql_query_pre = SET NAMES utf8 sql_query_pre = REPLACE INTO sph_counter SELECT 1, MAX(id) FROM sph_index sql_query_post_index = DELETE FROM sph_index WHERE id<=(SELECT max_doc_id FROM sph_counter WHERE counter_id=1) - sql_query = SELECT id, `from`, `to`, `subject`, `arrived`, `sent`, `body`, `size`, `direction`, `attachments`, `deleted` FROM sph_index \ + sql_query = SELECT id, `from`, `to`, `subject`, `arrived`, `sent`, `body`, `size`, `direction`, `attachments` FROM sph_index \ WHERE id <= (SELECT max_doc_id FROM sph_counter WHERE counter_id=1) sql_attr_uint = size @@ -42,10 +41,13 @@ source delta sql_attr_uint = sent sql_attr_uint = direction sql_attr_uint = attachments - sql_attr_bool = deleted + + sql_query_killlist = SELECT `id` FROM `metadata` WHERE `deleted`=1 } + + source tag { type = mysql diff --git a/src/Makefile.in b/src/Makefile.in index e8703169..bee051f4 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -80,6 +80,7 @@ install-piler: $(INSTALL) -m 0755 piler $(DESTDIR)$(sbindir) $(INSTALL) -m 0755 pilerconf $(DESTDIR)$(sbindir) $(INSTALL) -m 0755 pilerget $(DESTDIR)$(bindir) + $(INSTALL) -m 0755 pilerimport $(DESTDIR)$(bindir) clean: rm -f *.o *.a libpiler.so* piler pilerconf pilerget pilerimport pilertest diff --git a/src/cfg.c b/src/cfg.c index a7512b67..d8f8564a 100644 --- a/src/cfg.c +++ b/src/cfg.c @@ -68,9 +68,9 @@ struct _parse_rule config_parse_rules[] = { "listen_addr", "string", (void*) string_parser, offsetof(struct __config, listen_addr), "127.0.0.1", MAXVAL-1}, { "listen_port", "integer", (void*) int_parser, offsetof(struct __config, listen_port), "10025", sizeof(int)}, { "locale", "string", (void*) string_parser, offsetof(struct __config, locale), "", MAXVAL-1}, - { "max_connections", "integer", (void*) int_parser, offsetof(struct __config, max_connections), "30", sizeof(int)}, - { "max_requests_per_child", "integer", (void*) int_parser, offsetof(struct __config, max_requests_per_child), "200", sizeof(int)}, + { "max_requests_per_child", "integer", (void*) int_parser, offsetof(struct __config, max_requests_per_child), "1000", sizeof(int)}, { "memcached_servers", "string", (void*) string_parser, offsetof(struct __config, memcached_servers), "127.0.0.1", MAXVAL-1}, + { "memcached_to_db_interval", "integer", (void*) int_parser, offsetof(struct __config, memcached_to_db_interval), "900", sizeof(int)}, { "memcached_ttl", "integer", (void*) int_parser, offsetof(struct __config, memcached_ttl), "86400", sizeof(int)}, { "mydomains", "string", (void*) string_parser, offsetof(struct __config, mydomains), "", MAXVAL-1}, { "mysqlhost", "string", (void*) string_parser, offsetof(struct __config, mysqlhost), "", MAXVAL-1}, @@ -86,6 +86,7 @@ struct _parse_rule config_parse_rules[] = { "queuedir", "string", (void*) string_parser, offsetof(struct __config, queuedir), QUEUE_DIR, MAXVAL-1}, { "session_timeout", "integer", (void*) int_parser, offsetof(struct __config, session_timeout), "420", sizeof(int)}, { "sqlite3_pragma", "string", (void*) string_parser, offsetof(struct __config, sqlite3_pragma), "", MAXVAL-1}, + { "update_counters_to_memcached", "integer", (void*) int_parser, offsetof(struct __config, update_counters_to_memcached), "0", sizeof(int)}, { "username", "string", (void*) string_parser, offsetof(struct __config, username), "piler", MAXVAL-1}, { "use_antivirus", "integer", (void*) int_parser, offsetof(struct __config, use_antivirus), "1", sizeof(int)}, { "verbosity", "integer", (void*) int_parser, offsetof(struct __config, verbosity), "1", sizeof(int)}, diff --git a/src/cfg.h b/src/cfg.h index 557b40ce..3c44d1cb 100644 --- a/src/cfg.h +++ b/src/cfg.h @@ -27,7 +27,6 @@ struct __config { int number_of_worker_processes; int max_requests_per_child; - int max_connections; int backlog; @@ -61,6 +60,9 @@ struct __config { char sqlite3[MAXVAL]; char sqlite3_pragma[MAXVAL]; + int update_counters_to_memcached; + int memcached_to_db_interval; + }; diff --git a/src/config.h b/src/config.h index 18e44780..aeddeb64 100644 --- a/src/config.h +++ b/src/config.h @@ -11,14 +11,14 @@ #define PROGNAME "piler" -#define VERSION "0.1.11" +#define VERSION "0.1.12" #define PROGINFO VERSION ", Janos SUTO \n\n" CONFIGURE_PARAMS "\n" #define HOSTID "mailarchiver" #define CONFIG_FILE CONFDIR "/piler.conf" -#define WORK_DIR DATADIR "/spool/piler/tmp" +#define WORK_DIR DATADIR "/piler/tmp" #define QUEUE_DIR DATADIR "/piler/store" #define CLAMD_SOCKET "/tmp/clamd" diff --git a/src/counters.c b/src/counters.c index 5aa6bf54..75dc2359 100644 --- a/src/counters.c +++ b/src/counters.c @@ -42,7 +42,7 @@ struct __counters loadCounters(struct session_data *sdata, struct __config *cfg) } -void updateCounters(struct session_data *sdata, struct __data *data, struct __counters *counters, struct __config *cfg){ +void update_counters(struct session_data *sdata, struct __data *data, struct __counters *counters, struct __config *cfg){ char buf[MAXBUFSIZE]; #ifdef HAVE_MEMCACHED unsigned long long mc, rcvd; @@ -57,10 +57,9 @@ void updateCounters(struct session_data *sdata, struct __data *data, struct __co if(memcached_increment(&(data->memc), MEMCACHED_MSGS_RCVD, strlen(MEMCACHED_MSGS_RCVD), counters->c_rcvd, &mc) == MEMCACHED_SUCCESS){ rcvd = mc; - if(counters->c_ham > 0) memcached_increment(&(data->memc), MEMCACHED_MSGS_HAM, strlen(MEMCACHED_MSGS_HAM), counters->c_ham, &mc); if(counters->c_virus > 0) memcached_increment(&(data->memc), MEMCACHED_MSGS_VIRUS, strlen(MEMCACHED_MSGS_VIRUS), counters->c_virus, &mc); if(counters->c_duplicate > 0) memcached_increment(&(data->memc), MEMCACHED_MSGS_DUPLICATE, strlen(MEMCACHED_MSGS_DUPLICATE), counters->c_duplicate, &mc); - if(counters->c_duplicate > 0) memcached_increment(&(data->memc), MEMCACHED_MSGS_IGNORE, strlen(MEMCACHED_MSGS_IGNORE), counters->c_ignore, &mc); + if(counters->c_ignore > 0) memcached_increment(&(data->memc), MEMCACHED_MSGS_IGNORE, strlen(MEMCACHED_MSGS_IGNORE), counters->c_ignore, &mc); bzero(&c, sizeof(c)); @@ -80,7 +79,7 @@ void updateCounters(struct session_data *sdata, struct __data *data, struct __co if(sdata->now - mc > cfg->memcached_to_db_interval && c.c_rcvd > 0 && c.c_rcvd >= rcvd){ snprintf(buf, SMALLBUFSIZE-1, "%ld", sdata->now); memcached_set(&(data->memc), MEMCACHED_COUNTERS_LAST_UPDATE, strlen(MEMCACHED_COUNTERS_LAST_UPDATE), buf, strlen(buf), 0, 0); - snprintf(buf, SMALLBUFSIZE-1, "UPDATE `%s` SET rcvd=%llu, virus=%llu, duplicate=%llu, ignore=%llu", c.c_rcvd, c.c_virus, c.c_duplicate, c.c_ignore); + snprintf(buf, SMALLBUFSIZE-1, "UPDATE `%s` SET rcvd=%llu, virus=%llu, duplicate=%llu, ignore=%llu", SQL_COUNTER_TABLE, c.c_rcvd, c.c_virus, c.c_duplicate, c.c_ignore); //if(cfg->verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "%s: update counters: %s", sdata->ttmpfile, buf); diff --git a/src/memcached.c b/src/memcached.c deleted file mode 100644 index 7c6c781d..00000000 --- a/src/memcached.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * memcached.c, SJ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -int getUserdataFromMemcached(struct session_data *sdata, struct __data *data, char *email, struct __config *cfg){ - unsigned int len=0; - uint32_t flags = 0; - char key[SMALLBUFSIZE], *s=NULL, *p; - - //if(data->memc.initialised == 0) return 0; - - snprintf(key, SMALLBUFSIZE-1, "%s:%s", MEMCACHED_CLAPF_PREFIX, email); - - s = memcached_get(&(data->memc), key, &len, &flags); - - if(cfg->verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "%s: memcached user query=%s, data=%s (%d)", sdata->ttmpfile, key, s, len); - - if(len > 0){ - /* 1000:8:sj:acts.hu:1 */ - - if(len == 1 && s[0] == 'U'){ - if(cfg->verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "%s: %s is unknown", sdata->ttmpfile, email); - return 1; - } - - p = strchr(s, ':'); - if(p){ *p = '\0'; sdata->uid = atol(s); s = p+1; } - - p = strchr(s, ':'); - if(p){ *p = '\0'; sdata->gid = atol(s); s = p+1; } - - p = strchr(s, ':'); - if(p){ *p = '\0'; snprintf(sdata->name, SMALLBUFSIZE-1, "%s", s); s = p+1; } - - p = strchr(s, ':'); - if(p){ *p = '\0'; snprintf(sdata->domain, SMALLBUFSIZE-1, "%s", s); s = p+1; } - - sdata->policy_group = atoi(s); - - if(cfg->verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "%s: memcached parsed user data: uid: %ld, gid: %ld, name: %s, domain: %s, policy group: %d", sdata->ttmpfile, sdata->uid, sdata->gid, sdata->name, sdata->domain, sdata->policy_group); - - return 1; - } - - return 0; -} - - -int putUserdataToMemcached(struct session_data *sdata, struct __data *data, char *email, struct __config *cfg){ - uint32_t flags = 0; - char key[SMALLBUFSIZE], value[SMALLBUFSIZE]; - - snprintf(key, SMALLBUFSIZE-1, "%s:%s", MEMCACHED_CLAPF_PREFIX, email); - if(sdata->uid == 0) - strcpy(value, "U"); - else - snprintf(value, SMALLBUFSIZE-1, "%ld:%ld:%s:%s:%d", sdata->uid, sdata->gid, sdata->name, sdata->domain, sdata->policy_group); - - if(memcached_add(&(data->memc), key, strlen(key), value, strlen(value), cfg->memcached_ttl, flags) == MEMCACHED_SUCCESS) return 1; - - return 0; -} - - -int getPolicyFromMemcached(struct session_data *sdata, struct __data *data, struct __config *cfg, struct __config *my_cfg){ - unsigned int len=0; - uint32_t flags = 0; - char key[SMALLBUFSIZE], *s=NULL, *p; - - if(sdata->policy_group <= 0) return 0; - - snprintf(key, SMALLBUFSIZE-1, "%s:%d", MEMCACHED_CLAPF_PREFIX, sdata->policy_group); - - s = memcached_get(&(data->memc), key, &len, &flags); - - if(cfg->verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "%s: memcached policy query=%s, data=%s (%d)", sdata->ttmpfile, key, s, len); - - if(len > 0){ - - p = strchr(s, ':'); if(p){ *p = '\0'; my_cfg->deliver_infected_email = atoi(s); s = p+1; } - p = strchr(s, ':'); if(p){ *p = '\0'; my_cfg->silently_discard_infected_email = atoi(s); s = p+1; } - p = strchr(s, ':'); if(p){ *p = '\0'; my_cfg->use_antispam = atoi(s); s = p+1; } - p = strchr(s, ':'); if(p){ *p = '\0'; snprintf(my_cfg->spam_subject_prefix, MAXVAL-1, "%s", s); s = p+1; } - p = strchr(s, ':'); if(p){ *p = '\0'; my_cfg->enable_auto_white_list = atoi(s); s = p+1; } - p = strchr(s, ':'); if(p){ *p = '\0'; my_cfg->max_message_size_to_filter = atoi(s); s = p+1; } - p = strchr(s, ':'); if(p){ *p = '\0'; snprintf(my_cfg->rbl_domain, MAXVAL-1, "%s", s); s = p+1; } - p = strchr(s, ':'); if(p){ *p = '\0'; snprintf(my_cfg->surbl_domain, MAXVAL-1, "%s", s); s = p+1; } - p = strchr(s, ':'); if(p){ *p = '\0'; my_cfg->spam_overall_limit = atof(s); s = p+1; } - p = strchr(s, ':'); if(p){ *p = '\0'; my_cfg->spaminess_oblivion_limit = atof(s); s = p+1; } - p = strchr(s, ':'); if(p){ *p = '\0'; my_cfg->replace_junk_characters = atoi(s); s = p+1; } - p = strchr(s, ':'); if(p){ *p = '\0'; my_cfg->invalid_junk_limit = atoi(s); s = p+1; } - p = strchr(s, ':'); if(p){ *p = '\0'; my_cfg->invalid_junk_line = atoi(s); s = p+1; } - p = strchr(s, ':'); if(p){ *p = '\0'; my_cfg->penalize_images = atoi(s); s = p+1; } - p = strchr(s, ':'); if(p){ *p = '\0'; my_cfg->penalize_embed_images = atoi(s); s = p+1; } - p = strchr(s, ':'); if(p){ *p = '\0'; my_cfg->penalize_octet_stream = atoi(s); s = p+1; } - p = strchr(s, ':'); if(p){ *p = '\0'; my_cfg->training_mode = atoi(s); s = p+1; } - p = strchr(s, ':'); if(p){ *p = '\0'; my_cfg->initial_1000_learning = atoi(s); s = p+1; } - p = strchr(s, ':'); if(p){ *p = '\0'; my_cfg->store_metadata = atoi(s); s = p+1; } - p = strchr(s, ':'); if(p){ *p = '\0'; my_cfg->store_only_spam = atoi(s); s = p+1; } - p = strchr(s, ':'); if(p){ *p = '\0'; my_cfg->message_from_a_zombie = atoi(s); } - - if(cfg->verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "%s: memcached parsed policy data: spam limit: %.4f, oblivion: %.4f, subject prefix: *%s*, rbl: *%s*, training mode: %d, meta: %d", - sdata->ttmpfile, my_cfg->spam_overall_limit, my_cfg->spaminess_oblivion_limit, my_cfg->spam_subject_prefix, my_cfg->rbl_domain, my_cfg->training_mode, my_cfg->store_metadata); - - return 1; - } - - return 0; -} - - -int putPolicyToMemcached(struct session_data *sdata, struct __data *data, struct __config *my_cfg){ - uint32_t flags = 0; - char key[SMALLBUFSIZE], value[SMALLBUFSIZE]; - - if(sdata->policy_group <= 0) return 0; - - snprintf(key, SMALLBUFSIZE-1, "%s:%d", MEMCACHED_CLAPF_PREFIX, sdata->policy_group); - - snprintf(value, SMALLBUFSIZE-1, "%d:%d:%d:%s:%d:%ld:%s:%s:%.4f:%.4f:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d", - my_cfg->deliver_infected_email, - my_cfg->silently_discard_infected_email, - my_cfg->use_antispam, - my_cfg->spam_subject_prefix, - my_cfg->enable_auto_white_list, - my_cfg->max_message_size_to_filter, - my_cfg->rbl_domain, - my_cfg->surbl_domain, - my_cfg->spam_overall_limit, - my_cfg->spaminess_oblivion_limit, - my_cfg->replace_junk_characters, - my_cfg->invalid_junk_limit, - my_cfg->invalid_junk_line, - my_cfg->penalize_images, - my_cfg->penalize_embed_images, - my_cfg->penalize_octet_stream, - my_cfg->training_mode, - my_cfg->initial_1000_learning, - my_cfg->store_metadata, - my_cfg->store_only_spam, - my_cfg->message_from_a_zombie - ); - - - if(memcached_add(&(data->memc), key, strlen(key), value, strlen(value), my_cfg->memcached_ttl, flags) == MEMCACHED_SUCCESS) return 1; - - return 0; -} - - -int getWBLFromMemcached(struct session_data *sdata, struct __data *data, struct __config *cfg){ - unsigned int len=0; - uint32_t flags = 0; - char key[SMALLBUFSIZE], *s=NULL, *p; - - snprintf(key, SMALLBUFSIZE-1, "%s:wbl%ld", MEMCACHED_CLAPF_PREFIX, sdata->uid); - - s = memcached_get(&(data->memc), key, &len, &flags); - - if(cfg->verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "%s: memcached wbl query=%s, data=%s (%d)", sdata->ttmpfile, key, s, len); - - if(len > 0){ - /* whiteemail1,whiteemail2:blackemail1,blackemail2 */ - - p = strchr(s, ':'); - if(p){ - *p = '\0'; - snprintf(sdata->whitelist, MAXBUFSIZE-1, "%s", s); - snprintf(sdata->blacklist, MAXBUFSIZE-1, "%s", p+1); - } - - return 1; - } - - return 0; -} - - -int putWBLToMemcached(struct session_data *sdata, struct __data *data, struct __config *cfg){ - uint32_t flags = 0; - char key[SMALLBUFSIZE], value[2*MAXBUFSIZE]; - - if(sdata->uid <= 0) return 0; - - snprintf(key, SMALLBUFSIZE-1, "%s:wbl%ld", MEMCACHED_CLAPF_PREFIX, sdata->uid); - snprintf(value, 2*MAXBUFSIZE-1, "%s:%s", sdata->whitelist, sdata->blacklist); - - if(memcached_add(&(data->memc), key, strlen(key), value, strlen(value), cfg->memcached_ttl, flags) == MEMCACHED_SUCCESS) return 1; - - return 0; -} - - diff --git a/src/message.c b/src/message.c index ba5ca6c8..0df9ec10 100644 --- a/src/message.c +++ b/src/message.c @@ -329,7 +329,7 @@ int store_meta_data(struct session_data *sdata, struct _state *state, struct __c } -int processMessage(struct session_data *sdata, struct _state *state, struct __config *cfg){ +int process_message(struct session_data *sdata, struct _state *state, struct __config *cfg){ int i, rc; /* discard if existing message_id */ diff --git a/src/parser_utils.c b/src/parser_utils.c index 2f325c11..d9e07804 100644 --- a/src/parser_utils.c +++ b/src/parser_utils.c @@ -80,65 +80,79 @@ void init_state(struct _state *state){ } -unsigned long parse_date_header(char *s){ - char *p; +unsigned long parse_date_header(char *datestr){ + int n=0; + char *p, *q, *r, s[SMALLBUFSIZE]; unsigned long ts=0; struct tm tm; - s += 5; - p = s; - - if(*p == ' '){ p++; s++; } - - p = strchr(s, ','); - if(!p) goto ENDE; - - *p = '\0'; - if(strcmp(s, "Mon") == 0) tm.tm_wday = 1; - else if(strcmp(s, "Tue") == 0) tm.tm_wday = 2; - else if(strcmp(s, "Wed") == 0) tm.tm_wday = 3; - else if(strcmp(s, "Thu") == 0) tm.tm_wday = 4; - else if(strcmp(s, "Fri") == 0) tm.tm_wday = 5; - else if(strcmp(s, "Sat") == 0) tm.tm_wday = 6; - else if(strcmp(s, "Sun") == 0) tm.tm_wday = 0; - s += 5; - - p = strchr(s, ' '); if(!p) goto ENDE; - *p = '\0'; tm.tm_mday = atoi(s); s += 3; - - p = strchr(s, ' '); if(!p) goto ENDE; - *p = '\0'; - if(strcmp(s, "Jan") == 0) tm.tm_mon = 0; - else if(strcmp(s, "Feb") == 0) tm.tm_mon = 1; - else if(strcmp(s, "Mar") == 0) tm.tm_mon = 2; - else if(strcmp(s, "Apr") == 0) tm.tm_mon = 3; - else if(strcmp(s, "May") == 0) tm.tm_mon = 4; - else if(strcmp(s, "Jun") == 0) tm.tm_mon = 5; - else if(strcmp(s, "Jul") == 0) tm.tm_mon = 6; - else if(strcmp(s, "Aug") == 0) tm.tm_mon = 7; - else if(strcmp(s, "Sep") == 0) tm.tm_mon = 8; - else if(strcmp(s, "Oct") == 0) tm.tm_mon = 9; - else if(strcmp(s, "Nov") == 0) tm.tm_mon = 10; - else if(strcmp(s, "Dec") == 0) tm.tm_mon = 11; - s = p+1; - - p = strchr(s, ' '); if(!p) goto ENDE; - tm.tm_year = atoi(s) - 1900; s = p+1; - - p = strchr(s, ':'); if(!p) goto ENDE; - *p = '\0'; tm.tm_hour = atoi(s); s = p+1; - - p = strchr(s, ':'); if(!p) goto ENDE; - *p = '\0'; tm.tm_min = atoi(s); s = p+1; - - p = strchr(s, ' '); if(!p) goto ENDE; - *p = '\0'; tm.tm_sec = atoi(s); s = p+1; + datestr += 5; + p = datestr; - tm.tm_isdst = -1; + for(; *datestr; datestr++){ + if(isspace(*datestr)) *datestr = ' '; + } + + + if(*p == ' '){ p++; } + + do { + p = split_str(p, " ", s, sizeof(s)-1); + if(strlen(s) > 0){ + n++; + + q = strchr(s, ','); if(q) *q='\0'; + + if(strlen(s) <= 2){ tm.tm_mday = atoi(s); continue; } + + if(strlen(s) == 4){ tm.tm_year = atoi(s) - 1900; continue; } + + if(strlen(s) == 3){ + if(strcmp(s, "Mon") == 0) tm.tm_wday = 1; + else if(strcmp(s, "Tue") == 0) tm.tm_wday = 2; + else if(strcmp(s, "Wed") == 0) tm.tm_wday = 3; + else if(strcmp(s, "Thu") == 0) tm.tm_wday = 4; + else if(strcmp(s, "Fri") == 0) tm.tm_wday = 5; + else if(strcmp(s, "Sat") == 0) tm.tm_wday = 6; + else if(strcmp(s, "Sun") == 0) tm.tm_wday = 0; + + + if(strcmp(s, "Jan") == 0) tm.tm_mon = 0; + else if(strcmp(s, "Feb") == 0) tm.tm_mon = 1; + else if(strcmp(s, "Mar") == 0) tm.tm_mon = 2; + else if(strcmp(s, "Apr") == 0) tm.tm_mon = 3; + else if(strcmp(s, "May") == 0) tm.tm_mon = 4; + else if(strcmp(s, "Jun") == 0) tm.tm_mon = 5; + else if(strcmp(s, "Jul") == 0) tm.tm_mon = 6; + else if(strcmp(s, "Aug") == 0) tm.tm_mon = 7; + else if(strcmp(s, "Sep") == 0) tm.tm_mon = 8; + else if(strcmp(s, "Oct") == 0) tm.tm_mon = 9; + else if(strcmp(s, "Nov") == 0) tm.tm_mon = 10; + else if(strcmp(s, "Dec") == 0) tm.tm_mon = 11; + + continue; + } + + if(strlen(s) == 8){ + r = &s[0]; + + q = strchr(r, ':'); if(!q) break; + *q = '\0'; tm.tm_hour = atoi(r); r = q+1; + + q = strchr(r, ':'); if(!q) break; + *q = '\0'; tm.tm_min = atoi(r); r = q+1; + + tm.tm_sec = atoi(r); + break; + } + } + + } while(p); + + tm.tm_isdst = -1; ts = mktime(&tm); -ENDE: return ts; } diff --git a/src/piler.c b/src/piler.c index e9062822..f4f9ef97 100644 --- a/src/piler.c +++ b/src/piler.c @@ -28,16 +28,216 @@ extern char *optarg; extern int optind; int sd; -int nconn = 0; +int quit = 0; +int received_sighup = 0; char *configfile = CONFIG_FILE; struct __config cfg; struct __data data; struct passwd *pwd; +struct child children[MAXCHILDREN]; + + +signal_func *set_signal_handler(int signo, signal_func * func); +static void takesig(int sig); +static void child_sighup_handler(int sig); +static void child_main(struct child *ptr); +static pid_t child_make(struct child *ptr); +int search_slot_by_pid(pid_t pid); +void kill_children(int sig); +void clean_exit(); +void initialise_configuration(); + + + + +/* + * most of the preforking code was taken from the tinyproxy project + */ + +signal_func *set_signal_handler(int signo, signal_func * func){ + struct sigaction act, oact; + + act.sa_handler = func; + sigemptyset (&act.sa_mask); + act.sa_flags = 0; + + if(sigaction(signo, &act, &oact) < 0) return SIG_ERR; + + return oact.sa_handler; +} + + +static void takesig(int sig){ + int i, status; + pid_t pid; + + switch(sig){ + case SIGHUP: + initialise_configuration(); + kill_children(SIGHUP); + break; + + case SIGTERM: + case SIGKILL: + quit = 1; + clean_exit(); + break; + + case SIGCHLD: + while((pid = waitpid (-1, &status, WNOHANG)) > 0){ + + //syslog(LOG_PRIORITY, "child (pid: %d) has died", pid); + + if(quit == 0){ + i = search_slot_by_pid(pid); + if(i >= 0){ + children[i].status = READY; + children[i].pid = child_make(&children[i]); + } + else syslog(LOG_PRIORITY, "error: couldn't find slot for pid %d", pid); + + } + } + break; + } + + return; +} + + +static void child_sighup_handler(int sig){ + if(sig == SIGHUP){ + received_sighup = 1; + } +} + + +static void child_main(struct child *ptr){ + int new_sd; + unsigned int clen; + struct sockaddr_in client_addr; + + ptr->messages = 0; + + if(cfg.verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "child (pid: %d) started main()", getpid()); + + while(1){ + if(received_sighup == 1){ + if(cfg.verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "child (pid: %d) caught HUP signal", getpid()); + break; + } + + ptr->status = READY; + + clen = sizeof(client_addr); + + new_sd = accept(sd, (struct sockaddr *)&client_addr, &clen); + + if(new_sd == -1) continue; + + ptr->status = BUSY; + + syslog(LOG_PRIORITY, "child (pid: %d) connection from %s", getpid(), inet_ntoa(client_addr.sin_addr)); + + sig_block(SIGHUP); + ptr->messages += handle_smtp_session(new_sd, &data, &cfg); + sig_unblock(SIGHUP); + + close(new_sd); + + if(cfg.max_requests_per_child > 0 && ptr->messages >= cfg.max_requests_per_child){ + if(cfg.verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "child (pid: %d) served enough: %d", getpid(), ptr->messages); + break; + } + + } + + ptr->status = UNDEF; + +#ifdef HAVE_MEMCACHED + memcached_shutdown(&(data.memc)); +#endif + + if(cfg.verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "child decides to exit (pid: %d)", getpid()); + + exit(0); +} + + +static pid_t child_make(struct child *ptr){ + pid_t pid; + + if((pid = fork()) > 0) return pid; + + if(pid == -1) return -1; + + if(cfg.verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "forked a child (pid: %d)", getpid()); + + /* reset signals */ + + set_signal_handler(SIGCHLD, SIG_DFL); + set_signal_handler(SIGTERM, SIG_DFL); + set_signal_handler(SIGHUP, child_sighup_handler); + + child_main(ptr); + + return -1; +} + + + +int child_pool_create(){ + int i; + + for(i=0; i 1){ + if(cfg.verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "sending signal to child (pid: %d)", children[i].pid); + kill(children[i].pid, sig); + } + } +} + void clean_exit(){ if(sd != -1) close(sd); + kill_children(SIGTERM); + free_rule(data.rules); syslog(LOG_PRIORITY, "%s has been terminated", PROGNAME); @@ -54,20 +254,14 @@ void fatal(char *s){ } -void sigchld(){ - int pid, wstat; - - while((pid = wait_nohang(&wstat)) > 0){ - if(nconn > 0) nconn--; - } -} - - void initialise_configuration(){ struct session_data sdata; cfg = read_config(configfile); + if(cfg.number_of_worker_processes < 5) cfg.number_of_worker_processes = 5; + if(cfg.number_of_worker_processes > MAXCHILDREN) cfg.number_of_worker_processes = MAXCHILDREN; + if(strlen(cfg.username) > 1){ pwd = getpwnam(cfg.username); if(!pwd) fatal(ERR_NON_EXISTENT_USER); @@ -112,9 +306,8 @@ void initialise_configuration(){ int main(int argc, char **argv){ - int i, new_sd, yes=1, pid, daemonise=0; - unsigned int clen; - struct sockaddr_in client_addr, serv_addr; + int i, yes=1, daemonise=0; + struct sockaddr_in serv_addr; struct in_addr addr; while((i = getopt(argc, argv, "c:dvVh")) > 0){ @@ -141,22 +334,13 @@ int main(int argc, char **argv){ (void) openlog(PROGNAME, LOG_PID, LOG_MAIL); - sig_catch(SIGINT, clean_exit); - sig_catch(SIGQUIT, clean_exit); - sig_catch(SIGKILL, clean_exit); - sig_catch(SIGTERM, clean_exit); - sig_catch(SIGHUP, initialise_configuration); - - data.rules = NULL; - sig_block(SIGCHLD); - sig_catch(SIGCHLD, sigchld); - - initialise_configuration(); + set_signal_handler (SIGPIPE, SIG_IGN); + if(read_key(&cfg)) fatal(ERR_READING_KEY); @@ -193,51 +377,17 @@ int main(int argc, char **argv){ write_pid_file(cfg.pidfile); - /* main accept loop */ - - for(;;){ + child_pool_create(); - /* let new connections wait if we are too busy now */ + set_signal_handler(SIGCHLD, takesig); + set_signal_handler(SIGTERM, takesig); + set_signal_handler(SIGKILL, takesig); + set_signal_handler(SIGHUP, takesig); - if(nconn >= cfg.max_connections) sig_pause(); - clen = sizeof(client_addr); - - sig_unblock(SIGCHLD); - new_sd = accept(sd, (struct sockaddr *)&client_addr, &clen); - sig_block(SIGCHLD); + for(;;){ sleep(1); } - if(new_sd == -1) continue; - - pid = fork(); - - if(pid == 0){ - sig_uncatch(SIGCHLD); - sig_unblock(SIGCHLD); - - sig_uncatch(SIGINT); - sig_uncatch(SIGQUIT); - sig_uncatch(SIGKILL); - sig_uncatch(SIGTERM); - sig_block(SIGHUP); - - syslog(LOG_PRIORITY, "connection from client: %s", inet_ntoa(client_addr.sin_addr)); - - handle_smtp_session(new_sd, &data, &cfg); - - _exit(0); - } - - else if(pid > 0){ - nconn++; - } - - else { - syslog(LOG_PRIORITY, "%s", ERR_FORK_FAILED); - } - - close(new_sd); - } + clean_exit(); return 0; } diff --git a/src/piler.h b/src/piler.h index a0cc457e..5c14e7d2 100644 --- a/src/piler.h +++ b/src/piler.h @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -33,7 +32,9 @@ int do_av_check(struct session_data *sdata, char *rcpttoemail, char *fromemail, int make_digests(struct session_data *sdata, struct __config *cfg); void digest_file(char *filename, char *digest); -int processMessage(struct session_data *sdata, struct _state *sstate, struct __config *cfg); +int handle_smtp_session(int new_sd, struct __data *data, struct __config *cfg); + +int process_message(struct session_data *sdata, struct _state *sstate, struct __config *cfg); int store_file(struct session_data *sdata, char *filename, int startpos, int len, struct __config *cfg); int store_attachments(struct session_data *sdata, struct _state *state, struct __config *cfg); int query_attachments(struct session_data *sdata, struct ptr_array *ptr_arr, struct __config *cfg); @@ -42,7 +43,7 @@ struct __config read_config(char *configfile); void check_and_create_directories(struct __config *cfg, uid_t uid, gid_t gid); -void updateCounters(struct session_data *sdata, struct __data *data, struct __counters *counters, struct __config *cfg); +void update_counters(struct session_data *sdata, struct __data *data, struct __counters *counters, struct __config *cfg); #endif /* _PILER_H */ diff --git a/src/pilerimport.c b/src/pilerimport.c index f037b328..13525ca6 100644 --- a/src/pilerimport.c +++ b/src/pilerimport.c @@ -48,15 +48,6 @@ int import_message(char *filename, struct session_data *sdata, struct __data *da if(sdata->sent > sdata->now) sdata->sent = sdata->now; - /*printf("message-id: %s\n", state.message_id); - printf("from: *%s*\n", state.b_from); - printf("to: *%s*\n", state.b_to); - printf("subject: *%s*\n", state.b_subject); - printf("attachments:%s\n", sdata->attachments); - printf("direction: %d\n", sdata->direction);*/ - - - rule = check_againt_ruleset(data->rules, &state, st.st_size); @@ -68,7 +59,7 @@ int import_message(char *filename, struct session_data *sdata, struct __data *da make_digests(sdata, cfg); - rc = processMessage(sdata, &state, cfg); + rc = process_message(sdata, &state, cfg); ENDE: unlink(sdata->tmpframe); @@ -87,8 +78,6 @@ int import_message(char *filename, struct session_data *sdata, struct __data *da break; } - printf("\n\n"); - return rc; } diff --git a/src/session.c b/src/session.c index 766e631b..a8621f61 100644 --- a/src/session.c +++ b/src/session.c @@ -16,7 +16,7 @@ #include -void handle_smtp_session(int new_sd, struct __data *data, struct __config *cfg){ +int handle_smtp_session(int new_sd, struct __data *data, struct __config *cfg){ int i, ret, pos, n, inj=ERR, state, prevlen=0; char *p, buf[MAXBUFSIZE], puf[MAXBUFSIZE], resp[MAXBUFSIZE], prevbuf[MAXBUFSIZE], last2buf[2*MAXBUFSIZE+1]; char rctptoemail[SMALLBUFSIZE], fromemail[SMALLBUFSIZE], virusinfo[SMALLBUFSIZE], reason[SMALLBUFSIZE]; @@ -31,9 +31,6 @@ void handle_smtp_session(int new_sd, struct __data *data, struct __config *cfg){ struct timeval tv1, tv2; - alarm(cfg->session_timeout); - sig_catch(SIGALRM, killChild); - state = SMTP_STATE_INIT; init_session_data(&sdata); @@ -60,8 +57,6 @@ void handle_smtp_session(int new_sd, struct __data *data, struct __config *cfg){ syslog(LOG_PRIORITY, "%s", ERR_MYSQL_CONNECT); #endif - if(cfg->verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "%s: fork()", sdata.ttmpfile); - gettimeofday(&tv1, &tz); @@ -206,7 +201,7 @@ void handle_smtp_session(int new_sd, struct __data *data, struct __config *cfg){ counters.c_ignore++; } else { - inj = processMessage(&sdata, &sstate, cfg); + inj = process_message(&sdata, &sstate, cfg); } } @@ -248,8 +243,6 @@ void handle_smtp_session(int new_sd, struct __data *data, struct __config *cfg){ unlink(sdata.tmpframe); - alarm(cfg->session_timeout); - /* if we have nothing after the trailing (.), we can read the next command from the network */ @@ -467,26 +460,15 @@ void handle_smtp_session(int new_sd, struct __data *data, struct __config *cfg){ QUITTING: - updateCounters(&sdata, data, &counters, cfg); + update_counters(&sdata, data, &counters, cfg); #ifdef NEED_MYSQL mysql_close(&(sdata.mysql)); #endif -#ifdef HAVE_MEMCACHED - memcached_shutdown(&(data->memc)); -#endif - - if(cfg->verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "child has finished"); - if(cfg->verbosity >= _LOG_INFO) syslog(LOG_PRIORITY, "processed %llu messages", counters.c_rcvd); -} - - -void killChild(){ - syslog(LOG_PRIORITY, "child is killed by force"); - exit(0); + return (int)counters.c_rcvd; } diff --git a/src/session.h b/src/session.h deleted file mode 100644 index 24cb50f9..00000000 --- a/src/session.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * session.h, SJ - */ - -#include "defs.h" - -void handle_smtp_session(int new_sd, struct __data *data, struct __config *cfg); -void initSessionData(struct session_data *sdata); -void killChild(); - diff --git a/src/test.c b/src/test.c index 4c009318..80536045 100644 --- a/src/test.c +++ b/src/test.c @@ -75,6 +75,8 @@ int main(int argc, char **argv){ printf("subject: *%s*\n", state.b_subject); //printf("body: *%s*\n", state.b_body); + printf("sent: %ld\n", sdata.sent); + make_digests(&sdata, &cfg); printf("hdr len: %d\n", sdata.hdr_len);