mirror of
https://bitbucket.org/jsuto/piler.git
synced 2024-11-07 23:21:59 +01:00
switched to preforking daemon
This commit is contained in:
parent
0353b27f68
commit
05c379a163
@ -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:
|
||||
|
175
configure
vendored
175
configure
vendored
@ -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,31 +3449,11 @@ fi
|
||||
fi
|
||||
|
||||
|
||||
|
||||
# Check whether --enable-whitelist was given.
|
||||
if test "${enable_whitelist+set}" = set; then :
|
||||
enableval=$enable_whitelist; want_whitelist=$enableval
|
||||
# Check whether --enable-memcached was given.
|
||||
if test "${enable_memcached+set}" = set; then :
|
||||
enableval=$enable_memcached; want_memcached=$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
|
||||
else
|
||||
want_blacklist="no"
|
||||
fi
|
||||
|
||||
|
||||
if test "$want_blacklist" = "yes"; then
|
||||
have_blacklist="yes"
|
||||
want_memcached="no"
|
||||
fi
|
||||
|
||||
|
||||
@ -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
|
||||
|
74
configure.in
74
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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)},
|
||||
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -11,14 +11,14 @@
|
||||
|
||||
#define PROGNAME "piler"
|
||||
|
||||
#define VERSION "0.1.11"
|
||||
#define VERSION "0.1.12"
|
||||
|
||||
#define PROGINFO VERSION ", Janos SUTO <sj@acts.hu>\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"
|
||||
|
@ -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);
|
||||
|
||||
|
204
src/memcached.c
204
src/memcached.c
@ -1,204 +0,0 @@
|
||||
/*
|
||||
* memcached.c, SJ
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <syslog.h>
|
||||
#include <piler.h>
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -80,20 +80,35 @@ 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;
|
||||
datestr += 5;
|
||||
p = datestr;
|
||||
|
||||
if(*p == ' '){ p++; s++; }
|
||||
|
||||
p = strchr(s, ',');
|
||||
if(!p) goto ENDE;
|
||||
for(; *datestr; datestr++){
|
||||
if(isspace(*datestr)) *datestr = ' ';
|
||||
}
|
||||
|
||||
*p = '\0';
|
||||
|
||||
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;
|
||||
@ -101,13 +116,8 @@ unsigned long parse_date_header(char *s){
|
||||
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;
|
||||
@ -120,25 +130,29 @@ unsigned long parse_date_header(char *s){
|
||||
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;
|
||||
continue;
|
||||
}
|
||||
|
||||
p = strchr(s, ':'); if(!p) goto ENDE;
|
||||
*p = '\0'; tm.tm_hour = atoi(s); s = p+1;
|
||||
if(strlen(s) == 8){
|
||||
r = &s[0];
|
||||
|
||||
p = strchr(s, ':'); if(!p) goto ENDE;
|
||||
*p = '\0'; tm.tm_min = atoi(s); s = p+1;
|
||||
q = strchr(r, ':'); if(!q) break;
|
||||
*q = '\0'; tm.tm_hour = atoi(r); r = q+1;
|
||||
|
||||
p = strchr(s, ' '); if(!p) goto ENDE;
|
||||
*p = '\0'; tm.tm_sec = atoi(s); s = p+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;
|
||||
}
|
||||
|
||||
|
280
src/piler.c
280
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<MAXCHILDREN; i++){
|
||||
children[i].pid = 0;
|
||||
children[i].messages = 0;
|
||||
children[i].status = UNDEF;
|
||||
}
|
||||
|
||||
for(i=0; i<cfg.number_of_worker_processes; i++){
|
||||
children[i].status = READY;
|
||||
children[i].pid = child_make(&children[i]);
|
||||
|
||||
if(children[i].pid == -1){
|
||||
syslog(LOG_PRIORITY, "error: failed to fork a child");
|
||||
clean_exit();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int search_slot_by_pid(pid_t pid){
|
||||
int i;
|
||||
|
||||
for(i=0; i<MAXCHILDREN; i++){
|
||||
if(children[i].pid == pid) return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void kill_children(int sig){
|
||||
int i;
|
||||
|
||||
for(i=0; i<MAXCHILDREN; i++){
|
||||
if(children[i].status != UNDEF && children[i].pid > 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 */
|
||||
child_pool_create();
|
||||
|
||||
for(;;){
|
||||
set_signal_handler(SIGCHLD, takesig);
|
||||
set_signal_handler(SIGTERM, takesig);
|
||||
set_signal_handler(SIGKILL, takesig);
|
||||
set_signal_handler(SIGHUP, takesig);
|
||||
|
||||
/* let new connections wait if we are too busy now */
|
||||
|
||||
if(nconn >= cfg.max_connections) sig_pause();
|
||||
for(;;){ sleep(1); }
|
||||
|
||||
clen = sizeof(client_addr);
|
||||
|
||||
sig_unblock(SIGCHLD);
|
||||
new_sd = accept(sd, (struct sockaddr *)&client_addr, &clen);
|
||||
sig_block(SIGCHLD);
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include <parser.h>
|
||||
#include <errmsg.h>
|
||||
#include <smtpcodes.h>
|
||||
#include <session.h>
|
||||
#include <decoder.h>
|
||||
#include <list.h>
|
||||
#include <rules.h>
|
||||
@ -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 */
|
||||
|
||||
|
@ -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 @@ ENDE:
|
||||
break;
|
||||
}
|
||||
|
||||
printf("\n\n");
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include <piler.h>
|
||||
|
||||
|
||||
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 @@ AFTER_PERIOD:
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user