aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog53
-rw-r--r--NEWS30
-rw-r--r--README84
-rw-r--r--THANKS2
-rw-r--r--configure.ac28
-rw-r--r--doc/mailfromd.texi106
-rw-r--r--etc/Makefile.am4
-rw-r--r--etc/sendmail-8.13.1.diff384
-rw-r--r--src/Makefile.am8
-rw-r--r--src/gram.y30
-rw-r--r--src/lex.l5
-rw-r--r--src/mailfrom.h11
-rw-r--r--src/main.c122
13 files changed, 797 insertions, 70 deletions
diff --git a/ChangeLog b/ChangeLog
index 33e79990..a86ca84c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/NEWS b/NEWS
index ff83eb66..c8329fd8 100644
--- a/NEWS
+++ b/NEWS
@@ -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.
diff --git a/README b/README
index cf660ef4..ec5820ca 100644
--- a/README
+++ b/README
@@ -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
diff --git a/THANKS b/THANKS
index 44c3ec39..6de9d1be 100644
--- a/THANKS
+++ b/THANKS
@@ -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
diff --git a/src/gram.y b/src/gram.y
index 25a6a74c..498c346d 100644
--- a/src/gram.y
+++ b/src/gram.y
@@ -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