aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2007-05-04 05:37:38 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2007-05-04 05:37:38 +0000
commit5663888746b3b5e15ab795a1e2bfaae7b2cf768a (patch)
treee1ee007db83ea3832d450ae4d6e2df7010cfbed9
parent076f7df5c40dbc3c791f14e5f55568e46244c0f8 (diff)
downloadmailfromd-5663888746b3b5e15ab795a1e2bfaae7b2cf768a.tar.gz
mailfromd-5663888746b3b5e15ab795a1e2bfaae7b2cf768a.tar.bz2
SIGHUP instructs `mailfromd' to restart itself.
Remove UNIX socket after closing it. git-svn-id: file:///svnroot/mailfromd/trunk@1405 7a8a7f39-df28-0410-adc6-e0d955640f24
-rw-r--r--ChangeLog33
-rw-r--r--NEWS11
-rw-r--r--configure.ac3
-rw-r--r--doc/Makefile.am2
-rw-r--r--doc/mailfromd.texi159
-rwxr-xr-xetc/rc.in21
-rw-r--r--gacopyz/gacopyz.c16
-rw-r--r--gacopyz/gacopyz_priv.h2
-rw-r--r--gacopyz/proc.c3
-rw-r--r--src/bi_io.m48
-rw-r--r--src/engine.c72
-rw-r--r--src/mailfromd.h13
-rw-r--r--src/main.c59
-rw-r--r--src/mtasim.c2
-rw-r--r--src/mu_dbm.c9
15 files changed, 307 insertions, 106 deletions
diff --git a/ChangeLog b/ChangeLog
index 697a189c..74ac2830 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,36 @@
+2007-05-04 Sergey Poznyakoff <gray@gnu.org.ua>
+
+ * src/mu_dbm.c [WITH_BDB] (mu_dbm_open): install errcall fn if
+ debug level >= 1
+ * src/engine.c (save_cmdline,sig_restart): New function
+ (mailfromd_daemon): SIGHUP causes restart (if the program is
+ invoked using the absolute file name)
+ * src/mailfromd.h (getmaxfd): New macro from bi_io.m4
+ (script_file,mtasim_option): New globals
+ (log_setup,save_cmdline): New functions
+ * src/bi_io.m4 (getmaxfd): move to src/mailfromd.h
+ * src/main.c: New option --mtasim for mtasim interaction
+ (log_setup): New function
+ (main): Initial logging stream depends on whether stderr is closed
+ or not.
+ Save command line unless script file is not an absolute file name
+ * src/mtasim.c (start_mailfromd): Use --mtasim instead of
+ --foreground (mainly for further use.
+ * configure.ac: Check for sysconf and getdtablesize
+ * doc/mailfromd.texi: Update
+ * doc/Makefile.am (check-fixmes): The rule missed multiline fixmes
+ * etc/rc.in (mailfromd_status): remove trailing space from the
+ first grep pattern
+ (mailfromd_reload): New function
+ New option `reload'
+
+ * gacopyz/gacopyz_priv.h (struct gacopyz_conn): New members
+ cleanup and cleanup_data.
+ * gacopyz/proc.c (gacopyz_cleanup_conn): Call conn->cleanup
+ * gacopyz/gacopyz.c (do_connect): Install a cleanup handler to
+ remove the UNIX socket.
+ * NEWS: Update
+
2007-05-02 Sergey Poznyakoff <gray@gnu.org.ua>
* src/mu_dbm.c (mu_dbm_strerror): Improve error logging.
diff --git a/NEWS b/NEWS
index 0bd3c443..c88ba23c 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-Mailfromd NEWS -- history of user-visible changes. 2007-04-27
+Mailfromd NEWS -- history of user-visible changes. 2007-05-04
Copyright (C) 2005, 2006, 2007 Sergey Poznyakoff
See the end of file for copying conditions.
@@ -8,6 +8,15 @@ Please send mailfromd bug reports to <bug-mailfromd@gnu.org.ua>
Version 3.1.92, SVN
+* SIGHUP handling
+
+ SIGHUP instructs `mailfromd' to restart itself.
+
+* rc.mailfromd reload
+
+ The `reload' option given to `rc.mailfromd' instructs it to send
+SIGHUP to the running instance of the program.
+
* mtasim
The `mtasim' utility is an MTA simulator for testing and debugging
diff --git a/configure.ac b/configure.ac
index cbdf2fdf..25032d94 100644
--- a/configure.ac
+++ b/configure.ac
@@ -71,7 +71,8 @@ fi
# Checks for library functions.
AC_CHECK_FUNCS([vsyslog setegid setregid setresgid seteuid setreuid \
- res_ninit res_nclose res_nquery res_nquerydomain])
+ res_ninit res_nclose res_nquery res_nquerydomain \
+ sysconf getdtablesize])
AC_REPLACE_FUNCS(daemon)
gl_INIT
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 9ac968a8..cd62e11a 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -92,7 +92,7 @@ check-refs:
check-fixmes:
@sed -e = $(info_TEXINFOS) | \
- sed -n 'N;/@FIXME{/{s/\(^[0-9][0-9]*\).*@FIXME{\([^}]*\)}.*/$(info_TEXINFOS):\1: \2/gp}' > $@-t; \
+ sed -n 'N;/@FIXME{/{s/\(^[0-9][0-9]*\).*@FIXME{\([^}]*\).*/$(info_TEXINFOS):\1: \2/gp}' > $@-t; \
if [ -s $@-t ]; then echo "Unresolved FIXMEs:"; cat $@-t;\
fi
rm -f $@-t
diff --git a/doc/mailfromd.texi b/doc/mailfromd.texi
index 741499b1..ffd1495c 100644
--- a/doc/mailfromd.texi
+++ b/doc/mailfromd.texi
@@ -66,10 +66,10 @@ Software Foundation raise funds for GNU development.''
@page
@quotation
-Dedico aquesta obra a Lluis Llach, un home qui ha canviat la meva vida.
+@i{Dedico aquesta obra a Lluis Llach, un home qui ha canviat la meva vida.
No puc dedicar-li ni una poesia, ni una can@,c@'o, ho sento molt. Ara,
commogut pel seu concert de comiat, li dedico ho que puc: aquest programa
-senzill.
+senzill.}
@end quotation
@@ -1106,7 +1106,7 @@ The diagram below shows the control flow when processing an
@acronym{SMTP} transaction. Lines marked with @code{C:} show
@acronym{SMTP} commands issued by the remote machine (the
@dfn{client}), those marked with @samp{@result{}} show called handlers
-with their arguments. An @r{[R]} appearing at the right end of a line
+with their arguments. An @r{[R]} appearing at the start of a line
indicates that this part of the transaction can be repeated any number
of times:
@@ -1114,7 +1114,7 @@ of times:
@caption{Mailfromd Control Flow}
@smallexample
@group
-@result{} begin
+@result{} begin()
@result{} connect(@var{hostname}, @var{family}, @var{port}, @samp{IP address})
C: HELO @var{domain}
helo(@var{domain})
@@ -1123,26 +1123,26 @@ do
C: MAIL FROM @var{sender}
@result{} envfrom(@var{sender})
- C: RCPT TO @var{recipient} @r{[R]}
+@r{[R]} C: RCPT TO @var{recipient}
@result{} envrcpt(@var{recipient})
C: DATA
- C: @var{header}: @var{value} @r{[R]}
+@r{[R]} C: @var{header}: @var{value}
@result{} header(@var{header}, @var{value})
C:
- @result{} eoh
+ @result{} eoh()
- C: @var{body-line} @r{[R]}
+@r{[R]} C: @var{body-line}
@result{} /* @r{Collect lines into blocks @var{blk} of
@result{} * at most @var{len} bytes and call:}
@result{} */
@result{} body(@var{blk}, @var{len})
C: .
- @result{} eom
+ @result{} eom()
done
-@result{} end
+@result{} end()
@end group
@end smallexample
@end float
@@ -1643,48 +1643,42 @@ done
@end group
@end smallexample
-@FIXME{Proposed by Jan:
-
- Another way to avoid infinite looping caused by endless recursive
-triggering of @code{on poll}, is to accept relaying of all email originating
-from the local @acronym{IP} cluster with (trusted) clients and @acronym{SMTP} servers,
-provided that the server running mailfromd falls within this @acronym{IP} range:
+ If you feel that your Sendmail's relayed domains are not restrictive
+enough for @command{mailfromd} filters (for example you are relaying
+mails from some third-party servers), you can use a database of mail
+server addresses to decide whether the mail must be checked or not.
+If the number of such servers is small enough, a single @samp{or}
+statement can be used, e.g.:
@smallexample
-@group
-prog envfrom
-do
- if $f == ""
+ elif $@{client_addr@} = "10.10.10.1"
+ or $@{client_addr@} = "192.168.11.7"
accept
+ @dots{}
+@end smallexample
+
+@noindent
+otherwise, if the servers' @acronym{IP} addresses fall within one or
+several @acronym{CIDR}s, you can use the @code{match_cidr} function
+(@pxref{Internet address manipulation functions}), e.g.:
+
+@smallexample
elif match_cidr ($@{client_addr@}, "199.232.0.0/16")
accept
- else
- on poll $f do
- when success:
- accept
- when not_found or failure:
- reject 550 5.1.0 "Sender validity not confirmed"
- when temp_failure:
- tempfail 450 4.1.0 "Try again later"
- done
- fi
-done
-@end group
+ @dots{}
@end smallexample
-Here, triggering the @code{on poll} statement with more than 1 recursion
-is avoided for all local emails, originating from non-local @acronym{IP}s
-(outside of @acronym{CIDR} range 193.232.0.0/16) - when such an email arrives,
-handler execution falls through to @code{on poll}, which will cause
-the server to connect back to itself for local email verification, but
-this time, the @code{on poll} check will be skipped, as the server's
-own @acronym{IP} address will be caught by @code{match_cidr} statement.
-This method has particular advantage over the previous one: it
-does not rely on sendmail's relay-domains control, which can be,
-alone, too wide for sane relaying control.
+@noindent
+Finally, you can keep a @acronym{DBM} database of relayed addresses
+and use @code{dbmap} or @code{dbget} function for checking
+(@pxref{Database functions}).
-}
-
+@smallexample
+ elif dbmap(__statedir__"/relay.db", $@{client_addr@})
+ accept
+ @dots{}
+@end smallexample
+
@node HELO Domain
@section HELO Domain
@@ -1784,24 +1778,6 @@ done
@end group
@end smallexample
-@FIXME{Consider explaining this:
-
-@smallexample
-@group
-prog envfrom
-do
- if %helohost = localhost
- or (%helohost matches '^[0-9]@{1,3@}\.[0-9]@{1,3@}\.[0-9]@{1,3@}\.[0-9]@{1,3@}$'
- and hostname %helohost = %helohost)
- or resolve %helohost = "0"
- reject 570 "Please specify real host name"
- fi
-done
-
-@end group
-@end smallexample
-}
-
@node Controlling Number of Recipients
@section Controlling Number of Recipients
@@ -2936,9 +2912,8 @@ debugging, or in your @code{catch} statements.
@section Warnings about some slippery places in @acronym{MFL}
@quotation
-It seemed like a good idea at the time.
-
---- Brian Kernighan
+@i{It seemed like a good idea at the time.}@*
+Brian Kernighan
@end quotation
There are some features of @acronym{MFL} which, when used improperly,
@@ -3434,8 +3409,8 @@ scripts. @xref{tracing runtime errors}, for the detailed description.
@deffn {pragma option} user @var{string}
@xprindex{user}
- Switch to this user's privileges after startup. @FIXME{Describe
-it. Refer to --group.}
+ Switch to this user's privileges after startup.
+@FIXME{Describe it. Refer to --group.}
@end deffn
@deffn {pragma option} group @var{string}
@@ -9100,8 +9075,9 @@ the action to all available databases. @xref{compact cronjob}.
@item -D @var{string}
@itemx --domain=@var{string}
Set default @acronym{SMTP} domain. Overrides @samp{#pragma option ehlo}
-(@pxref{pragma ehlo}). @FIXME{Deprecated: use @option{-v
-ehlo_domain=@var{string}} instead. Explain why.}
+(@pxref{pragma ehlo}). This option is
+deprecated@footnote{@xref{31x-32x}, for the detailed description of
+why it is deprecated.}: use @option{-v ehlo_domain=@var{string}} instead.
@opsummary{ehlo}
@itemx --ehlo=@var{string}
@@ -9178,8 +9154,14 @@ Functions}.
@item --mailfrom=@var{email}
Set postmaster email address. Overrides @samp{#pragma option ehlo},
which you are advised to use instead (@pxref{pragma ehlo}). The
-default is null return address (@samp{""}). @FIXME{Deprecated: use
-@option{-v mailfrom_address=@var{string}} instead. Explain why.}
+default is null return address (@samp{""}). This option is
+deprecated@footnote{@xref{31x-32x}, for the detailed
+description of why it is deprecated.}: use @option{-v
+mailfrom_address=@var{string}} instead.
+
+@opsummary{mtasim}
+@item --mtasim
+This option is reserved for use by @command{mtasim} (@pxref{mtasim}).
@opsummary{optimize}
@item -O[@var{level}]
@@ -9527,15 +9509,43 @@ group}). In example above, you need to use the following directive:
option: @kbd{mailfromd --group=smmsp}).
@cindex Signals
-@cindex SIGHUP
+@cindex SIGQUIT
@cindex SIGTERM
@cindex SIGINT
To stop a running instance of @command{mailfromd} use one of the
-following signals: @code{SIGHUP}, @code{SIGTERM}, @code{SIGINT}.
+following signals: @code{SIGQUIT}, @code{SIGTERM}, @code{SIGINT}.
All three signals have the same effect: the program cancels handling any
pending requests, uninitializes the communication socket (if it is a
UNIX socket, the program unlinks it) and exits.
+@cindex SIGHUP
+ To restart the running @command{mailfromd} instance, send it
+@code{SIGHUP}. For restart to be possible, two conditions must be
+met: @command{mailfromd} must be invoked with full file name, and the
+configuration file name must be full as well. If either of them is not
+met, @command{mailfromd} displays the similar warning message:
+
+@smallexample
+@group
+warning: script file is given without full file name
+warning: restart (SIGHUP) will not work
+@end group
+@end smallexample
+
+@noindent
+or:
+
+@smallexample
+@group
+warning: mailfromd started without full file name
+warning: restart (SIGHUP) will not work
+@end group
+@end smallexample
+
+The reaction of @command{mailfromd} on @code{SIGHUP} in this case is
+the same as on the three signals described previously, i.e. cleanup
+and exit immediately.
+
@cindex pidfile
The @acronym{PID} of the master instance of @command{mailfromd} is
kept on the @dfn{pidfile}, which is named @file{mailfromd.pid} and is
@@ -9567,6 +9577,9 @@ Start the program.
@item stop
Shut down the program
+@item reload
+Reload the program, by sending it @code{SIGHUP} signal.
+
@item restart
Shut down the program and start it again.
diff --git a/etc/rc.in b/etc/rc.in
index 675dce4d..e027f70f 100755
--- a/etc/rc.in
+++ b/etc/rc.in
@@ -75,12 +75,26 @@ mailfromd_status() {
else
PID='[0-9][0-9]*'
fi
- $PS | grep "[0-9]:[0-9][0-9] $DAEMON " |
+ $PS | grep "[0-9]:[0-9][0-9] $DAEMON" |
while read pid tt stat time command
do
echo $pid $command
done |
- grep $1 "$PID $command"
+ grep $1 "$PID $DAEMON"
+}
+
+mailfromd_reload() {
+ echo "Reloading mailfromd..."
+ if mailfromd_status -q; then
+ PID=`head -n 1 $PIDFILE`
+ kill -HUP $PID 2>/dev/null
+ if [ ! -r $PIDFILE ]; then
+ sleep 1
+ test -r $PIDFILE || echo "mailfromd failed to reload" >&2
+ fi
+ else
+ echo "mailfromd is not running"
+ fi
}
mailfromd_configtest() {
@@ -147,6 +161,8 @@ mailfromd_macros() {
case $1 in
start) mailfromd_start;;
stop) mailfromd_stop;;
+reload)
+ mailfromd_reload;;
restart)
mailfromd_stop
sleep 1
@@ -164,6 +180,7 @@ usage: $0 COMMAND [OPTIONS]
COMMANDS are:
start Start the daemon.
stop Stop the running instance of the daemon.
+ reload Reload the daemon by sending SIGHUP to its running copy.
restart Restart the daemon.
status Display status of the running instance.
configtest [FILE] Check configuration file syntax. If FILE is not
diff --git a/gacopyz/gacopyz.c b/gacopyz/gacopyz.c
index a7a50177..c3aeb453 100644
--- a/gacopyz/gacopyz.c
+++ b/gacopyz/gacopyz.c
@@ -135,6 +135,17 @@ parse_connection(gacopyz_conn_t conn,
}
+static void
+cleanup_unix_socket(gacopyz_conn_t conn, void *data)
+{
+ if (unlink(data))
+ gacopyz_log(conn, SMI_LOG_ERR,
+ "%s: %s: cannot unlink: %s",
+ conn->desc.xxfi_name, (char*)data,
+ strerror(errno));
+ free(data);
+}
+
static int
do_connect(gacopyz_conn_t conn,
const char *cstr, char *proto, char *port, char *path,
@@ -174,7 +185,10 @@ do_connect(gacopyz_conn_t conn,
strcpy(addr.sun.sun_path, path);
if (stat(path, &st)) {
- if (errno != ENOENT) {
+ if (errno == ENOENT) {
+ conn->cleanup = cleanup_unix_socket;
+ conn->cleanup_data = strdup(path);
+ } else {
gacopyz_log(conn, SMI_LOG_ERR,
"%s: %s: cannot stat socket: %s",
conn->desc.xxfi_name, path,
diff --git a/gacopyz/gacopyz_priv.h b/gacopyz/gacopyz_priv.h
index 30486f42..7f5bdd69 100644
--- a/gacopyz/gacopyz_priv.h
+++ b/gacopyz/gacopyz_priv.h
@@ -61,6 +61,8 @@ struct gacopyz_conn {
struct smfiDesc desc;
pid_t *pidtab;
size_t pidcount;
+ void (*cleanup) (gacopyz_conn_t, void*);
+ void *cleanup_data;
};
#define GACOPYZ_TIMEOUT 7210
diff --git a/gacopyz/proc.c b/gacopyz/proc.c
index d388c1fa..7bce35f1 100644
--- a/gacopyz/proc.c
+++ b/gacopyz/proc.c
@@ -126,6 +126,9 @@ gacopyz_cleanup_conn(gacopyz_conn_t conn)
if (conn->pidtab[i])
kill(conn->pidtab[i], SIGTERM);
cleanup_children(conn, 1);
+
+ if (conn->cleanup)
+ conn->cleanup(conn, conn->cleanup_data);
}
static RETSIGTYPE
diff --git a/src/bi_io.m4 b/src/bi_io.m4
index d4439978..e7a2dba9 100644
--- a/src/bi_io.m4
+++ b/src/bi_io.m4
@@ -86,14 +86,6 @@ read_stream_line(struct io_stream *str)
#define REDIRECT_STDIN_P(f) ((f) & (O_WRONLY|O_RDWR))
#define REDIRECT_STDOUT_P(f) ((f) == O_RDONLY || ((f) & (O_RDONLY|O_RDWR)))
-#if defined HAVE_SYSCONF && defined _SC_OPEN_MAX
-# define getmaxfd() sysconf(_SC_OPEN_MAX)
-#elif defined (HAVE_GETDTABLESIZE)
-# define getmaxfd() getdtablesize()
-#else
-# define getmaxfd() 64
-#endif
-
static int
open_program_stream(struct io_stream *str, const char *cmdline, int flags)
{
diff --git a/src/engine.c b/src/engine.c
index ddee0a4b..34c1a49b 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -1282,7 +1282,7 @@ static void
check_local_portspec(char *p)
{
struct stat st;
-
+
if (stat(p, &st)) {
if (errno == ENOENT)
return; /* That's OK. The socket must not exist */
@@ -1290,7 +1290,7 @@ check_local_portspec(char *p)
p, mu_strerror(errno));
exit(EX_SOFTWARE);
} else if (!force_remove) {
- mu_error("File `%s' already exist. Remove it or use --remove option.", p);
+ mu_error("File `%s' already exists. Remove it or use --remove option.", p);
exit(EX_SOFTWARE);
}
@@ -1333,12 +1333,49 @@ check_portspec(char *portspec)
mu_error("Unknown port specification: %s", portspec);
}
+static int x_argc; /* A copy of argc and ... */
+static char **x_argv; /* ... argv */
+static int restart; /* Set to 1 if restart is requested */
+
+void
+save_cmdline(int argc, char **argv)
+{
+ int i;
+
+ if (argc == 0) {
+ /* Clear saved command line */
+ for (i = 0; i < x_argc; i++)
+ free(x_argv[i]);
+ free(x_argv);
+ x_argc = 0;
+ x_argv = NULL;
+ } else if (argv[0][0] != '/') {
+ /* Do not save if argv[0] is not a full file name.
+ An appropriate error message will be issued later,
+ if necessary. */
+ return;
+ }
+ x_argc = argc;
+ x_argv = xcalloc (x_argc + 1, sizeof x_argv[0]);
+ for (i = 0; i < x_argc; i++)
+ x_argv[i] = xstrdup (argv[i]);
+ x_argv[i] = NULL;
+}
+
+
static RETSIGTYPE
sig_stop(int sig)
{
smfi_stop();
}
+static RETSIGTYPE
+sig_restart(int sig)
+{
+ restart = 1;
+ smfi_stop();
+}
+
void
mailfromd_daemon()
{
@@ -1367,7 +1404,19 @@ mailfromd_daemon()
signal(SIGTERM, sig_stop);
signal(SIGQUIT, sig_stop);
- signal(SIGHUP, sig_stop);
+ if (x_argc == 0) {
+ if (!mtasim_option) {
+ if (script_file[0] != '/')
+ mu_error("warning: script file is given "
+ "without full file name");
+ else
+ mu_error("warning: mailfromd started without "
+ "full file name");
+ mu_error("warning: restart (SIGHUP) will not work");
+ }
+ signal(SIGHUP, sig_stop);
+ } else
+ signal(SIGHUP, sig_restart);
signal(SIGINT, sig_stop);
if (!foreground) {
@@ -1383,9 +1432,24 @@ mailfromd_daemon()
umask(0117);
rc = smfi_main();
}
- mu_error("mailfromd terminating");
+
if (rc)
mu_error("exit code = %d, last error status: %s",
rc, strerror (errno));
+ if (restart) {
+ char *s;
+ int i;
+
+ mu_error("mailfromd restarting");
+ mu_daemon_remove_pidfile();
+ for (i = getmaxfd(); i > 0; i--)
+ close(i);
+ execv(x_argv[0], x_argv);
+ log_setup(0);
+ mu_error("cannot restart: %s", mu_strerror(errno));
+ if (mu_argcv_string(x_argc, x_argv, &s) == 0)
+ mu_error("command line was: %s", s);
+ } else
+ mu_error("mailfromd terminating");
exit(rc);
}
diff --git a/src/mailfromd.h b/src/mailfromd.h
index 61bd3ae1..d683448a 100644
--- a/src/mailfromd.h
+++ b/src/mailfromd.h
@@ -129,6 +129,15 @@ enum smtp_state {
#define NUMERIC_BUFSIZE_BOUND INT_BUFSIZE_BOUND(long)
+#if defined HAVE_SYSCONF && defined _SC_OPEN_MAX
+# define getmaxfd() sysconf(_SC_OPEN_MAX)
+#elif defined (HAVE_GETDTABLESIZE)
+# define getmaxfd() getdtablesize()
+#else
+# define getmaxfd() 256
+#endif
+
+
mf_status dns_to_mf_status(dns_status stat);
mf_status resolve_ipstr(const char *ipstr, char **hbuf);
@@ -175,7 +184,9 @@ void disable_prog_trace(const char *modlist);
#define MAILFROMD_COMPACT 5
#define MAILFROMD_SHOW_DEFAULTS 6
+extern char *script_file;
extern int mode;
+extern int mtasim_option;
extern unsigned optimization_level;
extern enum smtp_state test_state;
extern time_t negative_expire_interval;
@@ -560,6 +571,7 @@ void free_symbols(void);
char *regex_flags_to_string(int flags, char *buf, size_t size);
+void log_setup(int want_stderr);
void builtin_setup(void);
void builtin_post_setup(void);
void print_code(void);
@@ -730,6 +742,7 @@ void trace(const char *fmt, ...);
int convert_rate(const char *arg, double *rate);
extern void priv_setup(void);
void mailfromd_daemon(void);
+void save_cmdline(int argc, char **argv);
/* DNS dictionary */
void dict_init(mu_list_t *dict);
diff --git a/src/main.c b/src/main.c
index d389ec46..a954770a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -58,6 +58,7 @@ int script_dump_macros; /* Dump used Sendmail macros */
int script_dump_xref; /* Dump cross-reference */
int do_transcript; /* Enable session transript */
int do_trace; /* Enable tracing configuration */
+int mtasim_option; /* mtasim compatibility mode */
unsigned optimization_level = 1; /* Optimization level */
int log_to_stderr; /* Use stderr for logging */
char *portspec = DEFAULT_SOCKET; /* Communication socket specification */
@@ -813,6 +814,7 @@ enum mailfromd_option {
OPTION_LOCK_RETRY_COUNT,
OPTION_LOCK_RETRY_TIMEOUT,
OPTION_MILTER_TIMEOUT,
+ OPTION_MTASIM,
OPTION_PIDFILE,
OPTION_POSTMASTER_EMAIL,
OPTION_PREDICT_NEXT,
@@ -903,6 +905,8 @@ static struct argp_option options[] = {
GRP+1 },
{ "foreground", OPTION_FOREGROUND, NULL, 0,
N_("Stay in foreground"), GRP+1 },
+ { "mtasim", OPTION_MTASIM, NULL, 0,
+ N_("Run in mtasim compatibility mode"), GRP+1 },
{ "single-process", OPTION_SINGLE_PROCESS, NULL, 0,
N_("Run in single-process mode"), GRP+1 },
{ "pidfile", OPTION_PIDFILE, N_("FILE"), 0,
@@ -1221,6 +1225,10 @@ parse_opt (int key, char *arg, struct argp_state *state)
set_option("milter-timeout", arg, 1);
break;
+ case OPTION_MTASIM:
+ mtasim_option = foreground = 1;
+ break;
+
case OPTION_PIDFILE:
set_option("pidfile", arg, 1);
break;
@@ -1643,6 +1651,34 @@ mailfromd_show_defaults()
db_format_enumerate(db_format_enumerator, NULL);
}
+void
+log_setup(int want_stderr)
+{
+ /* Set up logging */
+ if (!want_stderr) {
+#ifdef USE_SYSLOG_ASYNC
+ openlog_async(syslog_tag, LOG_PID, log_facility);
+ gacopyz_set_logger (mf_gacopyz_syslog_async_log_printer);
+#else
+ openlog(syslog_tag, LOG_PID, log_facility);
+#endif
+ mu_error_set_print(syslog_error_printer);
+ } else {
+ gacopyz_set_logger(gacopyz_stderr_log_printer);
+ mu_error_set_print(stderr_error_printer);
+ }
+}
+
+static int
+stderr_closed_p()
+{
+ int fd = dup(0);
+ if (fd < 0)
+ return 1;
+ close(fd);
+ return fd <= 2;
+}
+
int
main(int argc, char **argv)
{
@@ -1653,15 +1689,20 @@ main(int argc, char **argv)
mu_register_all_mailer_formats();
if (!program_invocation_short_name)
program_invocation_short_name = argv[0];
+
+ /* Set default logging */
log_facility = DEFAULT_LOG_FACILITY;
- mu_error_set_print(stderr_error_printer);
+ log_setup(!stderr_closed_p());
+
init_string_space();
builtin_setup();
db_format_setup();
lex_setup();
+ save_cmdline(argc, argv);
mu_argp_init (program_version, "<" PACKAGE_BUGREPORT ">");
-
mu_argp_parse (&argp, &argc, &argv, 0, capa, &index, NULL);
+
+ log_setup(log_to_stderr);
argv += index;
argc -= index;
@@ -1689,6 +1730,8 @@ main(int argc, char **argv)
argc--;
}
}
+ if (script_file[0] != '/')
+ save_cmdline(0, NULL); /* Clear saved command line */
if (parse_program(script_file, script_ydebug, script_ldebug))
exit(EX_CONFIG);
}
@@ -1708,18 +1751,6 @@ main(int argc, char **argv)
if (script_dump_xref)
print_xref();
- /* Set up default values */
- if (!log_to_stderr) {
-#ifdef USE_SYSLOG_ASYNC
- openlog_async(syslog_tag, LOG_PID, log_facility);
- gacopyz_set_logger (mf_gacopyz_syslog_async_log_printer);
-#else
- openlog(syslog_tag, LOG_PID, log_facility);
-#endif
- mu_error_set_print(syslog_error_printer);
- } else
- gacopyz_set_logger (gacopyz_stderr_log_printer);
-
if (script_dump_macros)
print_used_macros();
diff --git a/src/mtasim.c b/src/mtasim.c
index 4cc12c51..a34d5a20 100644
--- a/src/mtasim.c
+++ b/src/mtasim.c
@@ -587,7 +587,7 @@ start_mailfromd (int argc, char **argv)
xargv[0] = "mailfromd";
for (i = 1; i <= argc; i++)
xargv[i] = argv[i-1];
- xargv[i++] = "--foreground";
+ xargv[i++] = "--mtasim";
xargv[i++] = "--remove";
xargv[i++] = "--port";
xargv[i++] = milter_port;
diff --git a/src/mu_dbm.c b/src/mu_dbm.c
index f97eb02a..b98c0d94 100644
--- a/src/mu_dbm.c
+++ b/src/mu_dbm.c
@@ -17,6 +17,8 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA */
+#define MF_SOURCE_NAME MF_SOURCE_MU_DBM
+
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
@@ -475,6 +477,13 @@ mu_dbm_open (char *name, DBM_FILE *dbm, int flags, int mode, int *ro)
}
db->sync (db, 0);
+
+ __DBG(1)
+ {
+#if DB_VERSION_MAJOR > 2
+ db->set_errcall (db, mu_dbm_errcall_fcn);
+#endif
+ }
dbm->name = strdup (name);
dbm->db = db;

Return to:

Send suggestions and report system problems to the System administrator.