ph10 2005/01/27 15:00:39 GMT
Modified files:
exim-doc/doc-src spec.src
exim-doc/doc-txt ChangeLog
exim-src/src daemon.c perl.c
exim-test-orig/AutoTest/aux 904.pl
exim-test-orig/AutoTest/confs 904
exim-test-orig/AutoTest/scripts 904
exim-test-orig/AutoTest/stderr 904
exim-test-orig/AutoTest/stdout 904
Added files:
exim-test-orig/AutoTest/log 904
Log:
Arrange for output from Perl's "warn" to go to the mainlog by default.
Revision Changes Path
1.6 +19 -11 exim/exim-doc/doc-src/spec.src
1.76 +10 -0 exim/exim-doc/doc-txt/ChangeLog
1.6 +21 -12 exim/exim-src/src/daemon.c
1.3 +15 -0 exim/exim-src/src/perl.c
1.3 +4 -0 exim/exim-test-orig/AutoTest/aux/904.pl
1.2 +11 -0 exim/exim-test-orig/AutoTest/confs/904
1.1 +3 -0 exim/exim-test-orig/AutoTest/log/904 (new)
1.3 +42 -0 exim/exim-test-orig/AutoTest/scripts/904
1.3 +24 -0 exim/exim-test-orig/AutoTest/stderr/904
1.3 +41 -0 exim/exim-test-orig/AutoTest/stdout/904
Index: spec.src
===================================================================
RCS file: /home/cvs/exim/exim-doc/doc-src/spec.src,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- spec.src 27 Jan 2005 10:25:35 -0000 1.5
+++ spec.src 27 Jan 2005 15:00:38 -0000 1.6
@@ -1,4 +1,4 @@
-. $Cambridge: exim/exim-doc/doc-src/spec.src,v 1.5 2005/01/27 10:25:35 ph10 Exp $
+. $Cambridge: exim/exim-doc/doc-src/spec.src,v 1.6 2005/01/27 15:00:38 ph10 Exp $
.
.set version "4.50"
.set previousversion "4.40"
@@ -10673,21 +10673,29 @@
.em
.section Use of standard output and error by Perl
+.index Perl||standard output and error
You should not write to the standard error or output streams from within your
-Perl code, as it is not defined how these are set up. In versions of Exim up to
-at least 4.50, it is possible for the standard output or error to refer to the
-SMTP connection during message reception. Writing to this stream is likely to
-cause chaos. Something may be done about this in later releases.
-
-Unfortunately, the Perl \warn\ statment writes to the standard error stream,
-and this may be embedded in Perl modules that you use, but over which you have
-no control. One way round this is to ensure that the following Perl magic is
-obeyed before \warn\ is used:
-.display asis
-$SIG{__WARN__} = sub { Exim::log_write($_[0]) };
-.endd
-This causes the output of the \warn\ statement to be written to Exim's log
-file.
+Perl code, as it is not defined how these are set up. In versions of Exim
+before 4.50, it is possible for the standard output or error to refer to the
+SMTP connection during message reception via the daemon. Writing to this stream
+is certain to cause chaos. From Exim 4.50 onwards, the standard output and
+error streams are connected to \(/dev/null)\ in the daemon. The chaos is
+avoided, but the output is lost.
+
+.index Perl||\warn\, use of
+The Perl \warn\ statement writes to the standard error stream by default. Calls
+to \warn\ may be embedded in Perl modules that you use, but over which you have
+no control. When Exim starts up the Perl interpreter, it arranges for output
+from the \warn\ statement to be written to the Exim main log. You can change
+this by including appropriate Perl magic somewhere in your Perl code. For
+example, to discard \warn\ output completely, you need this:
+.display asis
+$SIG{__WARN__} = sub { };
+.endd
+Whenever a \warn\ is obeyed, the anonymous subroutine is called. In this
+example, the code for the subroutine is empty, so it does nothing, but you can
+include any Perl code that you like. The text of the \warn\ message is passed
+as the first subroutine argument.
.nem
Index: ChangeLog
===================================================================
RCS file: /home/cvs/exim/exim-doc/doc-txt/ChangeLog,v
retrieving revision 1.75
retrieving revision 1.76
diff -u -r1.75 -r1.76
--- ChangeLog 27 Jan 2005 10:26:14 -0000 1.75
+++ ChangeLog 27 Jan 2005 15:00:39 -0000 1.76
@@ -1,4 +1,4 @@
-$Cambridge: exim/exim-doc/doc-txt/ChangeLog,v 1.75 2005/01/27 10:26:14 ph10 Exp $
+$Cambridge: exim/exim-doc/doc-txt/ChangeLog,v 1.76 2005/01/27 15:00:39 ph10 Exp $
Change log file for Exim from version 4.21
-------------------------------------------
@@ -350,6 +350,16 @@
when verifying addresses in header lines, that is, for this case:
verify = header_sender/callout=defer_ok
+
+75. A backgrounded daemon closed stdin/stdout/stderr on entry; this meant that
+ those file descriptors could be used for SMTP connections. If anything
+ wrote to stderr (the example that came up was "warn" in embedded Perl), it
+ could be sent to the SMTP client, causing chaos. The daemon now opens
+ stdin, stdout, and stderr to /dev/null when it puts itself into the
+ background.
+
+76. Arrange for output from Perl's "warn" command to be written to Exim's main
+ log by default. The user can override this with suitable Perl magic.
----------------------------------------------------
Index: daemon.c
===================================================================
RCS file: /home/cvs/exim/exim-src/src/daemon.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- daemon.c 4 Jan 2005 10:37:55 -0000 1.5
+++ daemon.c 27 Jan 2005 15:00:39 -0000 1.6
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/exim-src/src/daemon.c,v 1.5 2005/01/04 10:37:55 ph10 Exp $ */
+/* $Cambridge: exim/exim-src/src/daemon.c,v 1.6 2005/01/27 15:00:39 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -1124,26 +1124,35 @@
}
}
-/* We now close all open file descriptors that we know about, and disconnect
-from the controlling terminal, unless background_daemon is unset. This is
-always unset when debugging, but can also be forced. Most modern Unixes seem to
-have setsid() for getting rid of the controlling terminal. For any OS that
-doesn't, setsid() can be #defined as a no-op, or as something else. */
+/* The variable background_daemon is always false when debugging, but
+can also be forced false in order to keep a non-debugging daemon in the
+foreground. If background_daemon is true, close all open file descriptors that
+we know about, but then re-open stdin, stdout, and stderr to /dev/null.
+
+This is protection against any called functions (in libraries, or in
+Perl, or whatever) that think they can write to stderr (or stdout). Before this
+was added, it was quite likely that an SMTP connection would use one of these
+file descriptors, in which case writing random stuff to it caused chaos.
+
+Then disconnect from the controlling terminal, Most modern Unixes seem to have
+setsid() for getting rid of the controlling terminal. For any OS that doesn't,
+setsid() can be #defined as a no-op, or as something else. */
if (background_daemon)
{
- log_close_all(); /* Just in case anything was logged earlier */
- search_tidyup(); /* Just in case any were used in reading the config. */
- close(0); /* Get rid of stdin/stdout/stderr */
+ log_close_all(); /* Just in case anything was logged earlier */
+ search_tidyup(); /* Just in case any were used in reading the config. */
+ close(0); /* Get rid of stdin/stdout/stderr */
close(1);
close(2);
+ exim_nullstd(); /* Connect stdin/stdout/stderr to /dev/null */
log_stderr = NULL; /* So no attempt to copy paniclog output */
/* If the parent process of this one has pid == 1, we are re-initializing the
- daemon as the result of a SIGHUP. In this case, there is no need to do any
- forking, because the controlling terminal has long gone. Otherwise, fork,
- in case current process is a process group leader (see 'man setsid' for an
- explanation). */
+ daemon as the result of a SIGHUP. In this case, there is no need to do
+ anything, because the controlling terminal has long gone. Otherwise, fork, in
+ case current process is a process group leader (see 'man setsid' for an
+ explanation) before calling setsid(). */
if (getppid() != 1)
{
Index: perl.c
===================================================================
RCS file: /home/cvs/exim/exim-src/src/perl.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- perl.c 20 Dec 2004 11:46:21 -0000 1.2
+++ perl.c 27 Jan 2005 15:00:39 -0000 1.3
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/exim-src/src/perl.c,v 1.2 2004/12/20 11:46:21 ph10 Exp $ */
+/* $Cambridge: exim/exim-src/src/perl.c,v 1.3 2005/01/27 15:00:39 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -109,6 +109,21 @@
perl_run(interp_perl);
{
dSP;
+
+ /*********************************************************************/
+ /* These lines by PH added to make "warn" output go to the Exim log; I
+ hope this doesn't break anything. */
+
+ sv = newSVpv(
+ "$SIG{__WARN__} = sub { my($s) = $_[0];"
+ "$s =~ s/\\n$//;"
+ "Exim::log_write($s) };", 0);
+ PUSHMARK(SP);
+ perl_eval_sv(sv, G_SCALAR|G_DISCARD|G_KEEPERR);
+ SvREFCNT_dec(sv);
+ if (SvTRUE(ERRSV)) return US SvPV(ERRSV, len);
+ /*********************************************************************/
+
sv = newSVpv(CS startup_code, 0);
PUSHMARK(SP);
perl_eval_sv(sv, G_SCALAR|G_DISCARD|G_KEEPERR);
Index: 904.pl
===================================================================
RCS file: /home/cvs/exim/exim-test-orig/AutoTest/aux/904.pl,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- 904.pl 20 Dec 2004 11:46:21 -0000 1.2
+++ 904.pl 27 Jan 2005 15:00:39 -0000 1.3
@@ -21,3 +21,7 @@
sub log_write { Exim::log_write("$_[0]"); "Wrote log"; }
sub change_locale { setlocale(LC_TIME, "fr_FR"); "Changed locale"; }
+
+sub foo_warn { warn "this is a warning"; "Wrote warning"; }
+
+sub no_warn { $SIG{__WARN__} = sub { }; "Discarded warnings"; }
Index: 904
===================================================================
RCS file: /home/cvs/exim/exim-test-orig/AutoTest/confs/904,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- 904 8 Oct 2004 14:49:16 -0000 1.1
+++ 904 27 Jan 2005 15:00:39 -0000 1.2
@@ -11,6 +11,17 @@
# ----- Main settings -----
+acl_smtp_rcpt = check_rcpt
perl_startup = do 'DIR/aux/904.pl'
+queue_only = true
+
+
+# ----- ACLs -----
+
+begin acl
+
+check_rcpt:
+ accept condition = ${if !eq {${perl{foo_warn}}}{}}
+
# End of Exim 4 configuration
Index: 904
====================================================================
1999-03-02 09:44:33 this is a warning at /source/exim4/AutoTest/aux/904.pl line 25.
1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225 (IPv6 and IPv4)
1999-03-02 09:44:33 this is a warning at /source/exim4/AutoTest/aux/904.pl line 25.
Index: 904
===================================================================
RCS file: /home/cvs/exim/exim-test-orig/AutoTest/scripts/904,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- 904 20 Dec 2004 11:46:22 -0000 1.2
+++ 904 27 Jan 2005 15:00:39 -0000 1.3
@@ -4,6 +4,7 @@
${perl{foo}{arg1}}
${perl{foo_undef}}
${perl{foo_die}}
+${perl{foo_warn}}
${perl{unknown}}
${perl{readvar}{primary_hostname}}
${perl{readvar}{notexists}}
@@ -26,3 +27,44 @@
${perl{debug_write}{debug from Perl\n}}
${perl{log_write}{log from Perl}}
****
+0
+exim -v -bs
+ehlo x.y.z
+mail from:<>
+rcpt to:<abc@???>
+quit
+****
+0
+exim -bh 10.0.0.1
+ehlo x.y.z
+mail from:<>
+rcpt to:<abc@???>
+quit
+****
+0
+exim -DSERVER=server -bd -oX 1225
+****
+0
+sleep 1
+****
+0
+client 127.0.0.1 1225
+??? 220
+helo x.y.z
+??? 250
+mail from:<>
+??? 250
+rcpt to:<abc@???>
+??? 250
+quit
+??? 221
+****
+0
+killdaemon
+****
+0
+exim -be
+${perl{no_warn}}
+${perl{foo_warn}}
+****
+no_msglog_check
Index: 904
===================================================================
RCS file: /home/cvs/exim/exim-test-orig/AutoTest/stderr/904,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- 904 20 Dec 2004 11:46:22 -0000 1.2
+++ 904 27 Jan 2005 15:00:39 -0000 1.3
@@ -1,3 +1,4 @@
+1999-03-02 09:44:33 this is a warning at /source/exim4/AutoTest/aux/904.pl line 25.
Exim version x.yz uid=1169 gid=1169 pid=pppp D=100
Lookups: lsearch wildlsearch nwildlsearch iplsearch cdb dbm dbmnz dnsdb dsearch ldap ldapdn ldapm mysql passwd pgsql testdb
Fixed never_users: 0
@@ -33,3 +34,26 @@
expanding: ${perl{log_write}{log from Perl}}
result: Wrote log
>>>>>>>>>>>>>>>> Exim pid=pppp terminating with rc=0 >>>>>>>>>>>>>>>>
+LOG: smtp_connection MAIN
+ SMTP connection from ph10
+LOG: MAIN
+ this is a warning at /source/exim4/AutoTest/aux/904.pl line 25.
+LOG: smtp_connection MAIN
+ SMTP connection from ph10 closed by QUIT
+>>> host in hosts_connection_nolog? no (option unset)
+>>> host in host_lookup? no (option unset)
+>>> host in host_reject_connection? no (option unset)
+>>> host in sender_unqualified_hosts? no (option unset)
+>>> host in recipient_unqualified_hosts? no (option unset)
+>>> host in helo_verify_hosts? no (option unset)
+>>> host in helo_try_verify_hosts? no (option unset)
+>>> host in helo_accept_junk_hosts? no (option unset)
+>>> x.y.z in helo_lookup_domains? no (end of list)
+>>> host in pipelining_advertise_hosts? yes (matched "*")
+>>> host in tls_advertise_hosts? no (option unset)
+>>> using ACL "check_rcpt"
+>>> processing "accept"
+LOG: this is a warning at /source/exim4/AutoTest/aux/904.pl line 25.
+>>> check condition = ${if !eq {${perl{foo_warn}}}{}}
+>>> = true
+>>> accept: condition test succeeded
Index: 904
===================================================================
RCS file: /home/cvs/exim/exim-test-orig/AutoTest/stdout/904,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- 904 20 Dec 2004 11:46:22 -0000 1.2
+++ 904 27 Jan 2005 15:00:39 -0000 1.3
@@ -3,6 +3,7 @@
> Failed: Perl subroutine "foo_undef" returned undef to force failure
> Failed: expiring... at /source/exim4/AutoTest/aux/904.pl line 7.
+> Wrote warning
> Failed: Undefined subroutine &main::unknown called.
> myhost.test.ex
@@ -24,4 +25,44 @@
> Failed: Perl subroutine "foo_undef" returned undef to force failure
> Wrote debug
> Wrote log
+>
+220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
+250-myhost.test.ex Hello ph10 at x.y.z
+250-SIZE 52428800
+250-PIPELINING
+250 HELP
+250 OK
+250 Accepted
+221 myhost.test.ex closing connection
+
+**** SMTP testing session as if from host 10.0.0.1
+**** but without any ident (RFC 1413) callback.
+**** This is not for real!
+
+220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
+250-myhost.test.ex Hello x.y.z [10.0.0.1]
+250-SIZE 52428800
+250-PIPELINING
+250 HELP
+250 OK
+250 Accepted
+221 myhost.test.ex closing connection
+Connecting to 127.0.0.1 port 1225 ... connected
+??? 220
+<<< 220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
+>>> helo x.y.z
+??? 250
+<<< 250 myhost.test.ex Hello ph10 at x.y.z [127.0.0.1]
+>>> mail from:<>
+??? 250
+<<< 250 OK
+>>> rcpt to:<abc@???>
+??? 250
+<<< 250 Accepted
+>>> quit
+??? 221
+<<< 221 myhost.test.ex closing connection
+End of script
+> Discarded warnings
+> Wrote warning
>