diff options
-rw-r--r-- | ChangeLog | 53 | ||||
-rw-r--r-- | NEWS | 30 | ||||
-rw-r--r-- | README | 84 | ||||
-rw-r--r-- | THANKS | 2 | ||||
-rw-r--r-- | configure.ac | 28 | ||||
-rw-r--r-- | doc/mailfromd.texi | 106 | ||||
-rw-r--r-- | etc/Makefile.am | 4 | ||||
-rw-r--r-- | etc/sendmail-8.13.1.diff | 384 | ||||
-rw-r--r-- | src/Makefile.am | 8 | ||||
-rw-r--r-- | src/gram.y | 30 | ||||
-rw-r--r-- | src/lex.l | 5 | ||||
-rw-r--r-- | src/mailfrom.h | 11 | ||||
-rw-r--r-- | src/main.c | 122 |
13 files changed, 797 insertions, 70 deletions
@@ -1,3 +1,56 @@ +2006-02-08 Sergey Poznyakoff <gray@gnu.org.ua> + + * src/main.c (listens_on): New function + * src/mailfrom.h (listens_on): New prototype + * src/lex.l: New token "listens" + * src/gram.y: Implement `listens' expression. + * src/Makefile.am (LDADD): Use $(MILTER) instead of hardcoding + the library name. + * etc/sendmail-8.13.1.diff: New file. Patch to Sendmail to make + milter use sub-programs instead of threads. + * etc/Makefile.am (EXTRA_DIST): Add sendmail-8.13.1.diff + * doc/mailfromd.texi (Building): Document --with-forks. + (Literals): Document `listens' expression. + * configure.ac: Implement --with-forks option. Raise version + number to 1.4 + + * THANKS: Add Jan Rafaj + * README: Updated + * NEWS: Updated + +2006-01-19 Sergey Poznyakoff <gray@gnu.org.ua> + + * src/main.c (struct option_cache): New member `cumulative'. + (set_option): Do not check override for cumulative options. + +2006-01-11 Sergey Poznyakoff <gray@gnu.org.ua> + + * src/gram.y (eval_poll): Fix typo. ehlo was used instead of + mailfrom + * src/main.c (check_portspec): Fix eventual coredump and add more + checks. + +2006-01-06 Sergey Poznyakoff <gray@gnu.org.ua> + + -= Release 1.3 =- + +2006-01-06 Sergey Poznyakoff <gray@gnu.org.ua> + + * src/lex.l: Remove leftover argc_unquote_char + +2006-01-05 Sergey Poznyakoff <gray@gnu.org.ua> + + * configure.ac: Raise version number to 1.3 + * NEWS: Updated + * README: Mention BROKEN_PTHREAD_SLEEP Sendmail variable + * doc/mailfromd.texi: Likewise + * src/main.c (check_portspec): New function. + +2005-11-24 Sergey Poznyakoff <gray@gnu.org.ua> + + * src/Makefile.am (AM_CPPFLAGS): Define MU_COMPAT, needed for + latest mailutils. + 2005-09-20 Sergey Poznyakoff <gray@gnu.org.ua> * src/dns.c (resolve_ipstr): New implementation, taking into @@ -1,9 +1,35 @@ -Mailfromd NEWS -- history of user-visible changes. 2005-08-17 -Copyright (C) 2005 Sergey Poznyakoff +Mailfromd NEWS -- history of user-visible changes. 2006-02-08 +Copyright (C) 2005, 2006 Sergey Poznyakoff See the end of file for copying conditions. Please send radius bug reports to <bug-mailfromd@gnu.org.ua> +Version 1.4 + +* Configuration + +Added possibility to link against the forked version of libmilter +(--with-forks). The patch for sendmail-8.13.1 is included +(etc/sendmail-8.13.1.diff). + +* Configuration file + +** New unary expression `listens' checks if the host listens on port 25. +** Several `#pragma option relay' statements accumulate + +* Bugfixes + +** Fixed coredump on incorrect libmilter socket specification. +** Fixed `poll for EMAIL as EMAIL'. + + +Version 1.3 + +* Rewritten DNS resolver functions in order to take into account CNAMEs. +* Updated Makefiles to allow for compilation with the CVS Mailutils +* Improved documentation. + + Version 1.2 * Implemented sending rate control. @@ -1,5 +1,5 @@ Mailfromd README -Copyright (C) 2005 Sergey Poznyakoff +Copyright (C) 2005, 2006 Sergey Poznyakoff See the end of file for copying conditions. * Introduction @@ -32,6 +32,11 @@ interface. * Building +Building the package is described in detail in the accompanying +documentation (chapter `Building'). To simplify the task for those of +you who do not have GNU info installed (you should, anyway), here is +the copy of this chapter: + 1. Make sure you have the necessary software installed. To build `mailfromd' you will need to have following packages on @@ -41,7 +46,51 @@ interface. B. `libmilter' library. - It comes with Sendmail, but is not built by default. + It comes with Sendmail, but is not built by default. To build + Sendmail with `libmilter' support, add following two lines to + your `devtools/Site/site.config.m4': + + APPENDDEF(`conf_sendmail_ENVDEF', `-DMILTER') + APPENDDEF(`confENVDEF', `-DBROKEN_PTHREAD_SLEEP') + + After running `make install', change to the directory + `libmilter' and run `make' there. + + _Important note:_ make sure that `libmilter' is compiled with + `BROKEN_PTHREAD_SLEEP' defined. If this symbol is not defined, + `libmilter' will use `sleep' in signal-handler thread, which + may cause various program misbehaviors, including coredumps. + This problem has been asserted on (at least) GNU/Linux and + FreeBSD systems. + + The `mailfromd' package comes with a patch to `libmilter' + that changes its multi-process model from "pthreads" to + "forks". It has been reported that `mailfromd' shows better + performance when linked with this modified version. If you + decide to try it, notice that it will be installed under the + name `libmilter-fork.a', so that your original version of + `libmilter.a' remains untouched. The patch was created for + Sendmail version 8.13.1 and is located in the `etc' + subdirectory of `mailfromd' distribution, in file + `sendmail-8.13.1.diff' + + To apply the patch: + + cd sendmail-8.13.1 + patch -p0 < PATH-TO/mailfromd-1.3/etc/sendmail-8.13.1.diff + + Then, proceed as described above in this section. + + To build `mailfromd' with the modified version of `libmilter' + use `--with-forks' option to `configure': + + ./configure --with-forks + + If you installed `libmilter-fork.a' to an unusual location, + or renamed it, you can specify its full file name with this + option, e.g.: + + ./configure --with-forks=/usr/local/lib/libmilter-fork.a C. GNU mailutils version 0.6 or newer. @@ -54,14 +103,17 @@ interface. that you can compile `mailfromd' without DBM too, but this is not recommended, since it will disable caching. Using `mailfromd' without caching can lead to increase in CPU - usage, traffic outage and other disastrous effects. You have - been warned. + usage, traffic outage and other disastrous effects. Besides, + DBM is necessary for limiting user send rates. You have been + warned. So, you want to select DBM implementation to use. The following table will help you do that. Column `DB type' lists types of DBM databases supported by `mailfromd'. Column `confMAPDEF' lists the value of `confMAPDEF' Sendmail - configuration variable corresponding to that database type + configuration variable corresponding to that database type. + It is here because it is usually wise to configure + `mailfromd' to use the same database type as your Sendmail (If you don't know what `confMAPDEF' is, you probably are wasting your time reading this. Refer to Sendmail configuration guide first). `N/A' in this column means there @@ -98,16 +150,23 @@ interface. File Purpose `PREFIX/libexec/mailfromd' Main daemon - `PREFIX/etc/mailfromd.rc' Configuration file + `PREFIX/etc/mailfromd.rc' Configuration file(1) `PREFIX/info/mailfromd.info' Documentation + ---------- Footnotes ---------- + (1) The configuration file will be installed only if it is not + already there. Thus, if you are upgrading to a newer version of + `mailfromd', your old configuration file will be preserved with all + your changes. + ------------------------------- + At startup, `mailfromd' will look up its configuration defaults in - file `PREFIX/etc/mailutils.rc'. + file `PREFIX/etc/mailfromd.rc'. It is advisable to use the same settings for file name prefixes as those you used when configuring `mailutils'. In particular, try to use the same `--sysconfdir', since it will facilitate configuring - entire system. + the whole system. Another important point is the location of "local state directory", i.e. a directory where `mailfromd' will keep its data @@ -143,9 +202,10 @@ interface. 9. Make sure `LOCALSTATEDIR/mailfromd' has right owner and mode. - 10. Edit SYSCONFDIR/mailfromd.rc to you liking. Make sure you have - read and understood the documentation! - + 10. Examine configuration file (`SYSCONFDIR/mailfromd.etc') and edit + it, if necessary. If you are upgrading from an oldest copy of + `mailfromd', your configuration file will remain untouched. + * Configuring and Running Please, see mailfromd documentation. @@ -157,7 +217,7 @@ Send bug reports to <bug-mailfromd@gnu.org.ua>. * Copyright information: -Copyright (C) 2005 Sergey Poznyakoff +Copyright (C) 2005, 2006 Sergey Poznyakoff Permission is granted to anyone to make or distribute verbatim copies of this document as received, in any medium, provided that the @@ -4,5 +4,5 @@ Many people further contributed to mailfromd by reporting problems, suggesting various improvements or submitting actual code. Here is a list of these people. Help us keep it complete and exempt of errors. +Jan Rafaj [email hidden on request by Jan] Peter Markeloff <magic@farlep.net> - diff --git a/configure.ac b/configure.ac index 5851c5e1..720ef232 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ # This file is part of mailfrom filter. -# Copyright (C) 2005, Sergey Poznyakoff +# Copyright (C) 2005, 2006 Sergey Poznyakoff # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -17,7 +17,7 @@ # MA 02110-1301 USA AC_PREREQ(2.59) -AC_INIT([mailfromd], [1.2], [bug-mailfromd@gnu.org.ua]) +AC_INIT([mailfromd], [1.4], [bug-mailfromd@gnu.org.ua]) AC_CONFIG_SRCDIR([src/main.c]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_LIBOBJ_DIR([src]) @@ -68,7 +68,7 @@ AC_CHECK_LIB(pthread, pthread_self, [HAVE_PTHREAD=yes]) ]) if test $HAVE_PTHREAD != yes; then - AC_MSG_ERROR("POSIX threads library not found. Please install one and then reconfigure") + AC_MSG_ERROR([POSIX threads library not found. Please install one and then reconfigure]) fi # Check for GNU Mailutils @@ -113,6 +113,28 @@ AH_BOTTOM([#ifndef HAVE_ARGCV_UNESCAPE_CHAR #endif ]) +AC_SUBST(MILTER) +MILTER=-lmilter +AC_MSG_CHECKING(for libmilter variant to use) +AC_ARG_WITH([forks], + AC_HELP_STRING([--with-forks@<:@=FILENAME@:>@], + [link with forked version of libmilter (Recommended. See chapter 'Building' in the docs.)]), + [case $withval in + yes) MILTER=-lmilter-fork;; + no) ;; + /*) MILTER=$withval;; + *) AC_MSG_ERROR([Invalid --with-forks option.]) + esac]) +AC_MSG_RESULT($MILTER) + +save_LIBS=$LIBS +LIBS="$LIBS $MILTER" +AC_LINK_IFELSE(AC_LANG_PROGRAM([#include <libmilter/mfapi.h>], + [return smfi_main();]), + [:], + [AC_MSG_ERROR(Required library $MILTER not found or unusable)]) +LIBS=$save_LIBS + # Check for DBM flavor AH_TEMPLATE(BDB2_CURSOR_LASTARG, [Last argument to the cursor member of Berkeley 2 DB structure]) diff --git a/doc/mailfromd.texi b/doc/mailfromd.texi index e3e5166a..6936c74f 100644 --- a/doc/mailfromd.texi +++ b/doc/mailfromd.texi @@ -6,6 +6,12 @@ @c %**end of header @setchapternewpage odd +@syncodeindex fn cp +@syncodeindex vr cp +@syncodeindex ky cp +@syncodeindex pg cp +@syncodeindex tp cp + @include version.texi @include rendition.texi @@ -21,7 +27,7 @@ Published by the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -Copyright @copyright{} 2005 Sergey Poznyakoff +Copyright @copyright{} 2005, 2006 Sergey Poznyakoff Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or @@ -255,7 +261,71 @@ packages on your machine: @item @command{libmilter} library. -It comes with Sendmail, but is not built by default. +@vindex BROKEN_PTHREAD_SLEEP +@cindex libmilter, compiling +It comes with Sendmail, but is not built by default. To build Sendmail +with @command{libmilter} support, add following two lines to your +@file{devtools/Site/site.config.m4}: + +@smallexample +@group +APPENDDEF(`conf_sendmail_ENVDEF', `-DMILTER') +APPENDDEF(`confENVDEF', `-DBROKEN_PTHREAD_SLEEP') +@end group +@end smallexample + +@noindent +After running @command{make install}, change to the directory +@file{libmilter} and run @command{make} there. + +@emph{Important note:} make sure that @command{libmilter} is compiled with +@code{BROKEN_PTHREAD_SLEEP} defined. If this symbol is not defined, +@command{libmilter} will use @code{sleep} in signal-handler thread, +which may cause various program misbehaviors, including +coredumps. This problem has been asserted on (at least) GNU/Linux and +FreeBSD systems. + +@cindex libmilter, forked version +@cindex Patching libmilter + The @command{mailfromd} package comes with a patch to +@command{libmilter} that changes its multi-process model from +@dfn{pthreads} to @dfn{forks}. It has been reported that +@command{mailfromd} shows better performance when linked with this +modified version. If you decide to try it, notice that it +will be installed under the name @file{libmilter-fork.a}, so that your +original version of @file{libmilter.a} remains untouched. The patch +was created for Sendmail version 8.13.1 and is located in the +@file{etc} subdirectory of @command{mailfromd} distribution, in file +@file{sendmail-8.13.1.diff} + +To apply the patch: + +@smallexample +@group +cd sendmail-8.13.1 +patch -p0 < @var{path-to/}mailfromd-@value{VERSION}/etc/sendmail-8.13.1.diff +@end group +@end smallexample + +@noindent +Then, proceed as described above in this section. + +@cindex @option{--with-forks} option, configure + To build @command{mailfromd} with the modified version of +@command{libmilter} use @option{--with-forks} option to +@command{configure}: + +@smallexample +./configure --with-forks +@end smallexample + + If you installed @command{libmilter-fork.a} to an unusual +location, or renamed it, you can specify its full file name with this +option, e.g.: + +@smallexample +./configure --with-forks=/usr/local/lib/libmilter-fork.a +@end smallexample @item GNU mailutils version 0.6 or newer. @@ -329,7 +399,7 @@ with all your changes.} @end multitable At startup, @command{mailfromd} will look up its configuration -defaults in file @file{@var{prefix}/etc/mailutils.rc}. +defaults in file @file{@var{prefix}/etc/mailfromd.rc}. It is advisable to use the same settings for file name prefixes as those you used when configuring @command{mailutils}. In particular, @@ -410,6 +480,7 @@ configuration file should be preferred. @menu * mailfromd.rc:: @command{Mailfromd} Configuration File. * options:: Command Line Options. +* signals:: How to Stop @command{Mailfromd} @end menu @node mailfromd.rc @@ -666,15 +737,16 @@ configuration file, you should make sure that Sendmail exports this variable to @command{mailfromd} (@pxref{Sendmail Configuration}). @cindex Expressions +@anchor{Expressions} Expressions operate on atoms and return literal values. Think of -them as if they are functions. Currently there are two expressions +them as if they are functions. Currently there are three expressions implemented: @table @code @item hostname @var{atom} @cindex @code{hostname} @var{atom} should be a string representing an IP address in -@dfn{dotted-quad} notation. The result of this expression is the +@samp{dotted-quad} notation. The result of this expression is the canonical name of host with this IP address obtained from DNS lookup. For example @@ -690,6 +762,12 @@ Sendmail variable @samp{client_addr}. no matter how many times @code{hostname $@{client_addr@}} will be used in @file{mailfromd.rc}, it will result in at most one DNS lookup. +@item listens @var{atom} +@cindex @code{listens} + @var{atom} is a valid host name in symbolic or @samp{dotted-quad} +notation. The @code{listens} expression returns @code{true} if the +host listens on TCP port 25 and @code{false} otherwise. + @item relayed @var{atom} @cindex @code{relayed} @anchor{relayed} @@ -817,7 +895,8 @@ are optional. Conditional statements may be nested to any depth. @cindex Conditions A @dfn{condition}, represented in the above example as -@var{condition} consists of following parts: +@var{condition}, is either a unary expression (@pxref{Expressions}) or +a binary statement in the following form: @smallexample @var{atom} @var{operation} @var{atom} @@ -1340,7 +1419,20 @@ Give a short usage message. @itemx --version Print program version. @end table - + +@node signals +@section How to Stop @command{Mailfromd} + +@cindex Signals +@cindex SIGHUP +@cindex SIGTERM +@cindex SIGINT + Use one of the following signals to stop a running instance of +@command{mailfromd}: @code{SIGHUP}, @code{SIGTERM}, @code{SIGINT}. All +three signals have the same effect: the program cancels handling any +pending requests, uninitializes the communitation socket (if it is a +UNIX socket, the program unlinks it) and exits. + @node Sendmail Configuration, Cache Database, Mailfromd Configuration, Top @chapter Configuring Sendmail to use @command{mailfromd} diff --git a/etc/Makefile.am b/etc/Makefile.am index be7f5200..3168592e 100644 --- a/etc/Makefile.am +++ b/etc/Makefile.am @@ -1,5 +1,5 @@ # This file is part of mailfrom filter. -# Copyright (C) 2005, Sergey Poznyakoff +# Copyright (C) 2005, 2006 Sergey Poznyakoff # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301 USA -EXTRA_DIST = mailfromd.rc rc.in +EXTRA_DIST = mailfromd.rc rc.in sendmail-8.13.1.diff noinst_SCRIPTS = rc.mailfromd DEFAULT_PIDFILE = $(MAILFROMSTATEDIR)/mailfromd.pid diff --git a/etc/sendmail-8.13.1.diff b/etc/sendmail-8.13.1.diff new file mode 100644 index 00000000..5f12bef6 --- /dev/null +++ b/etc/sendmail-8.13.1.diff @@ -0,0 +1,384 @@ +Index: libmilter/Makefile.m4 +diff -pu libmilter.orig/Makefile.m4 libmilter/Makefile.m4 +--- libmilter.orig/Makefile.m4 2006-01-30 12:37:56.000000000 +0200 ++++ libmilter/Makefile.m4 2006-02-08 16:05:52.000000000 +0200 +@@ -9,11 +9,11 @@ define(`confMT', `true') + SMSRCDIR= ifdef(`confSMSRCDIR', `confSMSRCDIR', `${SRCDIR}/sendmail') + PREPENDDEF(`confINCDIRS', `-I${SMSRCDIR} ') + +-bldPRODUCT_START(`library', `libmilter') ++bldPRODUCT_START(`library', `libmilter-fork') + define(`bldINSTALLABLE', `true') + define(`LIBMILTER_EXTRAS', `errstring.c strl.c') + APPENDDEF(`confENVDEF', `-DNOT_SENDMAIL -Dsm_snprintf=snprintf') +-define(`bldSOURCES', `main.c engine.c listener.c handler.c comm.c smfi.c signal.c sm_gethost.c LIBMILTER_EXTRAS ') ++define(`bldSOURCES', `main.c engine.c listener.c handler.c comm.c smfi.c sm_gethost.c LIBMILTER_EXTRAS ') + define(`confBEFORE', `LIBMILTER_EXTRAS') + bldPUSH_INSTALL_TARGET(`install-mfapi') + bldPRODUCT_END +Index: libmilter/handler.c +diff -pu libmilter.orig/handler.c libmilter/handler.c +--- libmilter.orig/handler.c 2006-01-30 12:37:56.000000000 +0200 ++++ libmilter/handler.c 2006-02-08 16:28:54.000000000 +0200 +@@ -13,7 +13,6 @@ SM_RCSID("@(#)$Id: handler.c,v 8.36 2003 + + #include "libmilter.h" + +- + /* + ** HANDLE_SESSION -- Handle a connected session in its own context + ** +@@ -34,15 +33,8 @@ mi_handle_session(ctx) + return MI_FAILURE; + ctx->ctx_id = (sthread_t) sthread_get_id(); + +- /* +- ** Detach so resources are free when the thread returns. +- ** If we ever "wait" for threads, this call must be removed. +- */ +- +- if (pthread_detach(ctx->ctx_id) != 0) +- ret = MI_FAILURE; +- else +- ret = mi_engine(ctx); ++ ret = mi_engine(ctx); ++ + if (ValidSocket(ctx->ctx_sd)) + { + (void) closesocket(ctx->ctx_sd); +Index: libmilter/libmilter.h +diff -pu libmilter.orig/libmilter.h libmilter/libmilter.h +--- libmilter.orig/libmilter.h 2006-01-30 12:37:56.000000000 +0200 ++++ libmilter/libmilter.h 2006-01-30 12:43:31.000000000 +0200 +@@ -39,15 +39,7 @@ SM_IDSTR(MilterlId, "@(#)$Id: libmilter. + # define MI_SOCK_READ_FAIL(x) ((x) < 0) + # define MI_SOCK_WRITE(s, b, l) write(s, b, l) + +-# define thread_create(ptid,wr,arg) pthread_create(ptid, NULL, wr, arg) +-# define sthread_get_id() pthread_self() +- +-typedef pthread_mutex_t smutex_t; +-# define smutex_init(mp) (pthread_mutex_init(mp, NULL) == 0) +-# define smutex_destroy(mp) (pthread_mutex_destroy(mp) == 0) +-# define smutex_lock(mp) (pthread_mutex_lock(mp) == 0) +-# define smutex_unlock(mp) (pthread_mutex_unlock(mp) == 0) +-# define smutex_trylock(mp) (pthread_mutex_trylock(mp) == 0) ++# define sthread_get_id() getpid() + + #if SM_CONF_POLL + +Index: libmilter/listener.c +diff -pu libmilter.orig/listener.c libmilter/listener.c +--- libmilter.orig/listener.c 2006-01-30 12:37:56.000000000 +0200 ++++ libmilter/listener.c 2006-02-08 16:38:21.000000000 +0200 +@@ -12,7 +12,7 @@ + SM_RCSID("@(#)$Id$") + + /* +-** listener.c -- threaded network listener ++** listener.c -- a network listener + */ + + #include "libmilter.h" +@@ -26,7 +26,6 @@ SM_RCSID("@(#)$Id: listener.c,v 8.109 20 + # include <arpa/inet.h> + # endif /* NETINET || NETINET6 */ + +-static smutex_t L_Mutex; + static int L_family; + static SOCKADDR_LEN_T L_socksize; + static socket_t listenfd = INVALID_SOCKET; +@@ -68,15 +67,12 @@ mi_opensocket(conn, backlog, dbg, rmsock + "%s: Opening listen socket on conn %s", + smfi->xxfi_name, conn); + } +- (void) smutex_init(&L_Mutex); +- (void) smutex_lock(&L_Mutex); + listenfd = mi_milteropen(conn, backlog, rmsocket, smfi->xxfi_name); + if (!ValidSocket(listenfd)) + { + smi_log(SMI_LOG_FATAL, + "%s: Unable to create listening socket on conn %s", + smfi->xxfi_name, conn); +- (void) smutex_unlock(&L_Mutex); + return MI_FAILURE; + } + #if !SM_CONF_POLL +@@ -84,7 +80,6 @@ mi_opensocket(conn, backlog, dbg, rmsock + { + smi_log(SMI_LOG_ERR, "%s: fd %d is larger than FD_SETSIZE %d", + smfi->xxfi_name, listenfd, FD_SETSIZE); +- (void) smutex_unlock(&L_Mutex); + return MI_FAILURE; + } + #endif /* !SM_CONF_POLL */ +@@ -543,22 +538,6 @@ mi_milteropen(conn, backlog, rmsocket, n + L_family = addr.sa.sa_family; + return sock; + } +-/* +-** MI_THREAD_HANDLE_WRAPPER -- small wrapper to handle session +-** +-** Parameters: +-** arg -- argument to pass to mi_handle_session() +-** +-** Returns: +-** results from mi_handle_session() +-*/ +- +-void * +-mi_thread_handle_wrapper(arg) +- void *arg; +-{ +- return (void *) mi_handle_session(arg); +-} + + /* + ** MI_CLOSENER -- close listen socket +@@ -576,7 +555,6 @@ mi_thread_handle_wrapper(arg) + void + mi_closener() + { +- (void) smutex_lock(&L_Mutex); + if (ValidSocket(listenfd)) + { + #if NETUNIX +@@ -621,7 +599,6 @@ mi_closener() + } + #endif /* NETUNIX */ + } +- (void) smutex_unlock(&L_Mutex); + } + + /* +@@ -690,6 +667,22 @@ mi_closener() + #else /* BROKEN_PTHREAD_SLEEP */ + # define MI_SLEEP(s) sleep((s)) + #endif /* BROKEN_PTHREAD_SLEEP */ ++ ++int ++start_subprocess(int (*handler)(SMFICTX_PTR ctx), SMFICTX_PTR ctx) ++{ ++ pid_t pid = fork(); ++ if (pid == -1) ++ return -1; ++ if (pid != 0) ++ return 0; ++ ++ /* Child */ ++ mi_closener(); ++ reset_signals(); ++ exit(handler(ctx)); ++} ++ + + int + mi_listener(conn, dbg, smfi, timeout, backlog) +@@ -711,7 +704,6 @@ mi_listener(conn, dbg, smfi, timeout, ba + int acnt = 0; /* error count for accept() failures */ + int scnt = 0; /* error count for select() failures */ + int save_errno = 0; +- sthread_t thread_id; + _SOCK_ADDR cliaddr; + SOCKADDR_LEN_T clilen; + SMFICTX_PTR ctx; +@@ -722,17 +714,14 @@ mi_listener(conn, dbg, smfi, timeout, ba + return MI_FAILURE; + + clilen = L_socksize; +- (void) smutex_unlock(&L_Mutex); + while ((mistop = mi_stop()) == MILTER_CONT) + { +- (void) smutex_lock(&L_Mutex); + if (!ValidSocket(listenfd)) + { + ret = MI_FAILURE; + smi_log(SMI_LOG_ERR, + "%s: listenfd=%d corrupted, terminating, errno=%d", + smfi->xxfi_name, listenfd, errno); +- (void) smutex_unlock(&L_Mutex); + break; + } + +@@ -743,13 +732,11 @@ mi_listener(conn, dbg, smfi, timeout, ba + r = FD_RD_READY(listenfd, rds, excs, &chktime); + if (r == 0) /* timeout */ + { +- (void) smutex_unlock(&L_Mutex); + continue; /* just check mi_stop() */ + } + if (r < 0) + { + save_errno = errno; +- (void) smutex_unlock(&L_Mutex); + if (save_errno == EINTR) + continue; + scnt++; +@@ -769,7 +756,6 @@ mi_listener(conn, dbg, smfi, timeout, ba + { + /* some error: just stop for now... */ + ret = MI_FAILURE; +- (void) smutex_unlock(&L_Mutex); + smi_log(SMI_LOG_ERR, + "%s: %s() returned exception for socket, abort", + smfi->xxfi_name, MI_POLLSELECT); +@@ -781,7 +767,6 @@ mi_listener(conn, dbg, smfi, timeout, ba + connfd = accept(listenfd, (struct sockaddr *) &cliaddr, + &clilen); + save_errno = errno; +- (void) smutex_unlock(&L_Mutex); + + /* + ** If remote side closes before +@@ -917,18 +902,18 @@ mi_listener(conn, dbg, smfi, timeout, ba + if (smfi->xxfi_body == NULL) + ctx->ctx_pflags |= SMFIP_NOBODY; + +- if ((r = thread_create(&thread_id, +- mi_thread_handle_wrapper, +- (void *) ctx)) != 0) ++ r = start_subprocess(mi_handle_session, ctx); ++ (void) closesocket(connfd); ++ free(ctx); ++ ++ if (r != 0) + { + tcnt++; + smi_log(SMI_LOG_ERR, +- "%s: thread_create() failed: %d, %s", +- smfi->xxfi_name, r, ++ "%s: start_subprocess() failed: %d, %s", ++ smfi->xxfi_name, errno, + tcnt >= MAX_FAILS_T ? "abort" : "try again"); + MI_SLEEP(tcnt); +- (void) closesocket(connfd); +- free(ctx); + if (tcnt >= MAX_FAILS_T) + { + ret = MI_FAILURE; +@@ -947,6 +932,7 @@ mi_listener(conn, dbg, smfi, timeout, ba + smfi->xxfi_name, mistop); + mi_closener(); + } +- (void) smutex_destroy(&L_Mutex); + return ret; + } ++ ++ +Index: libmilter/main.c +diff -pu libmilter.orig/main.c libmilter/main.c +--- libmilter.orig/main.c 2006-01-30 12:37:56.000000000 +0200 ++++ libmilter/main.c 2006-02-08 16:38:18.000000000 +0200 +@@ -15,7 +15,8 @@ SM_RCSID("@(#)$Id: main.c,v 8.79 2003/10 + #include "libmilter.h" + #include <fcntl.h> + #include <sys/stat.h> +- ++#include <sys/types.h> ++#include <sys/wait.h> + + static smfiDesc_ptr smfi = NULL; + +@@ -200,6 +201,76 @@ smfi_setbacklog(obacklog) + return MI_SUCCESS; + } + ++static int MilterStop = MILTER_CONT; ++ ++int ++mi_stop() ++{ ++ return MilterStop; ++} ++ ++void ++mi_stop_milters(int v) ++{ ++ if (MilterStop < v) ++ MilterStop = v; ++ mi_closener(); ++ kill(0, SIGKILL); ++ /* FIXME: Wait for subprocesses to finish? */ ++} ++ ++static void ++sig_stop(sig) ++ int sig; ++{ ++ MilterStop = MILTER_STOP; ++} ++ ++static void ++sig_child(sig) ++ int sig; ++{ ++ pid_t pid; ++ int status; ++ ++ while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { ++ if (WIFEXITED(status)) { ++ if (WEXITSTATUS(status)) ++ smi_log(SMI_LOG_WARN, ++ "Child %lu exited with status %d", ++ (unsigned long) pid, ++ WEXITSTATUS(status)); ++ } else if (WIFSIGNALED(status)) ++ smi_log(SMI_LOG_WARN, ++ "Child %lu terminated on signal %d", ++ WTERMSIG(status)); ++ else ++ smi_log(SMI_LOG_WARN, ++ "Child %lu terminated, reason unknown", ++ WTERMSIG(status)); ++ } ++ signal (sig, sig_child); ++} ++ ++void ++setup_signals() ++{ ++ signal(SIGPIPE, SIG_IGN); ++ signal(SIGCHLD, sig_child); ++ signal(SIGHUP, sig_stop); ++ signal(SIGTERM, sig_stop); ++ signal(SIGINT, sig_stop); ++} ++ ++void ++reset_signals() ++{ ++ signal(SIGPIPE, SIG_DFL); ++ signal(SIGCHLD, SIG_DFL); ++ signal(SIGHUP, SIG_DFL); ++ signal(SIGTERM, SIG_DFL); ++ signal(SIGINT, SIG_DFL); ++} + + /* + ** SMFI_MAIN -- setup milter connnection and start listener. +@@ -216,7 +287,9 @@ smfi_main() + { + int r; + +- (void) signal(SIGPIPE, SIG_IGN); ++ setup_signals(); ++ setsid(); ++ + if (conn == NULL) + { + smi_log(SMI_LOG_FATAL, "%s: missing connection information", +@@ -224,14 +297,6 @@ smfi_main() + return MI_FAILURE; + } + +- (void) atexit(mi_clean_signals); +- if (mi_control_startup(smfi->xxfi_name) != MI_SUCCESS) +- { +- smi_log(SMI_LOG_FATAL, +- "%s: Couldn't start signal thread", +- smfi->xxfi_name); +- return MI_FAILURE; +- } + r = MI_SUCCESS; + + /* Startup the listener */ diff --git a/src/Makefile.am b/src/Makefile.am index 2aff2aaf..c4c052be 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,5 @@ # This file is part of mailfrom filter. -# Copyright (C) 2005, Sergey Poznyakoff +# Copyright (C) 2005, 2006 Sergey Poznyakoff # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -21,14 +21,16 @@ libexec_PROGRAMS = mailfromd mailfromd_SOURCES = main.c dns.c mu_dbm.c cache.c gram.y lex.l rate.c db.c noinst_HEADERS = mailfrom.h mu_dbm.h -AM_CPPFLAGS=-DMAILFROMSTATEDIR=\"$(MAILFROMSTATEDIR)\" \ +AM_CPPFLAGS=\ + -DMU_COMPAT=1 \ + -DMAILFROMSTATEDIR=\"$(MAILFROMSTATEDIR)\" \ -DDEFAULT_SOCKET=\"$(DEFAULT_SOCKET)\" \ -DDEFAULT_USER=\"$(DEFAULT_USER)\" \ -DDEFAULT_EXPIRE_INTERVAL=$(DEFAULT_EXPIRE_INTERVAL) \ -DDEFAULT_EXPIRE_RATES_INTERVAL=$(DEFAULT_EXPIRE_RATES_INTERVAL) \ -DSYSCONFDIR=\"$(sysconfdir)\" INCLUDES = $(MAILUTILS_INCLUDES) -LDADD = $(LIBOBJS) $(MAILUTILS_LIBS) -lmilter +LDADD = $(LIBOBJS) $(MAILUTILS_LIBS) $(MILTER) EXTRA_DIST = gram.h daemon.c obstack.c obstack.h snprintf.c snprintf.h strtok_r.c AM_YFLAGS=-dtv AM_LFLAGS=-dvp @@ -1,6 +1,6 @@ %{ /* This file is part of mailfrom filter. - Copyright (C) 2005, Sergey Poznyakoff + Copyright (C) 2005, 2006 Sergey Poznyakoff This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -59,7 +59,7 @@ static int regex_flags; /* Should default to REG_NOSUB ? */ %token <locus> ACT_ACCEPT ACT_REJECT ACT_TEMPFAIL ACT_CONTINUE ACT_DISCARD %token <locus> ADD REPLACE DELETE %token <locus> IF FI ELSE ELIF -%token <locus> ON HOST FOR FROM AS DO DONE POLL MATCHES FNMATCHES +%token <locus> ON HOST FOR FROM AS DO DONE POLL MATCHES FNMATCHES LISTENS %token <locus> WHEN HOSTNAME RELAYED RATE NEXT %token <string> STRING CODE XCODE %token <string> SYMBOL @@ -301,6 +301,11 @@ cond : var EQ var $$->v.rate.email = $2; $$->v.rate.limit = $3 / $4; } + | LISTENS var + { + $$ = alloc_node(node_type_listens, &$1); + $$->v.node = $2; + } ; div |