]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
snapshot-20010323
authorWietse Venema <wietse@porcupine.org>
Fri, 23 Mar 2001 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:27:12 +0000 (06:27 +0000)
41 files changed:
postfix/FILTER_README
postfix/HISTORY
postfix/INSTALL
postfix/LINUX_README
postfix/conf/access
postfix/conf/main.cf
postfix/conf/postfix-script-nosgid
postfix/conf/postfix-script-sgid
postfix/conf/sample-compatibility.cf
postfix/conf/sample-misc.cf
postfix/html/access.5.html
postfix/html/faq.html
postfix/html/pipe.8.html
postfix/man/man5/access.5
postfix/man/man8/pipe.8
postfix/proto/access
postfix/src/cleanup/cleanup_extracted.c
postfix/src/flush/flush.c
postfix/src/global/Makefile.in
postfix/src/global/mail_conf.h
postfix/src/global/mail_params.c
postfix/src/global/mail_params.h
postfix/src/global/mail_task.c
postfix/src/global/mail_version.h
postfix/src/global/tok822_parse.c
postfix/src/lmtp/lmtp.c
postfix/src/lmtp/lmtp_connect.c
postfix/src/master/Makefile.in
postfix/src/master/master_listen.c
postfix/src/master/master_sig.c
postfix/src/nqmgr/qmgr_active.c
postfix/src/nqmgr/qmgr_job.c
postfix/src/pipe/pipe.c
postfix/src/postkick/postkick.c
postfix/src/qmgr/qmgr_active.c
postfix/src/util/inet_trigger.c
postfix/src/util/rand_sleep.c
postfix/src/util/sane_accept.c
postfix/src/util/stream_trigger.c
postfix/src/util/sys_defs.h
postfix/src/util/unix_trigger.c

index adb7d28fdcda68a29fb75a2484fe7bc31a4b4a13..7190790fdba4b2ee365c7987962c9ae8b11e74fd 100644 (file)
@@ -128,9 +128,9 @@ for transit mail that arrives and leaves via SMTP, provided that
 you create no temporary files. Each temporary file adds another
 factor to the performance loss.
 
-We will set up a content filtering program listening on localhost
-port 10025 that receives mail via the SMTP protocol, and that
-submits mail back into Postfix via localhost port 10026.
+We will set up a content filtering program that receives SMTP mail
+via localhost port 10025, and that submits SMTP mail back into
+Postfix via localhost port 10026.
 
       ..................................
       :            Postfix             :
@@ -162,7 +162,7 @@ transport table.  The content filtering records are added by the
 smtpd and pickup servers.
 
 When a queue file has content filtering information, the queue
-manager will deliver the mail to the specified content filtering
+manager will deliver the mail to the specified content filter
 regardless of its final destination.
 
 The content filter can be set up with the Postfix spawn service,
@@ -183,6 +183,9 @@ you want to have your filter listening on port localhost:10025
 instead of Postfix, then you must run your filter as a stand-alone
 program.
 
+Note: the localhost port 10025 SMTP server filter should announce
+itself as "220 localhost...", to silence warnings in the log.
+
 The /some/where/filter command is most likely a PERL script. PERL
 has modules that make talking SMTP easy. The command-line specifies
 that mail should be sent back into Postfix via localhost port 10026.
index d51dc47ebf8ea300138d0bbc9f5800ac5c5cee46..5e509c65c09336bff655564041380a90fe3a16a0 100644 (file)
@@ -4960,3 +4960,31 @@ Apologies for any names omitted.
        Code cleanup: some queue/transport operations need to be
        moved, after the code cleanup of the recipient/concurrency
        limit handling. Patrik Rak.  Files: *qmgr/qmgr_message.c.
+
+20010301
+
+       Feature: configurable name in syslog output (default:
+       "syslog_name = postfix") so that different Postfix instances
+       can be recognized by their logging. File: global/mail_task.c.
+
+20010313
+
+       Workaround for logic mismatch in nqmgr that was exposed
+       with the introduction of the asynchronous bounce client.
+       Patrik Rak.
+
+20010321
+
+       Workaround: LMTP connection caching never worked for
+       destinations starting with unix: or inet:. File:
+       lmtp/lmtp_connect.c.
+
+20010322
+
+       Portability: Solaris <2.6 does not have srandom() and
+       random() in libc. File: util/rand_sleep.c. It does not
+       have to be cryptographically strong.
+
+       Bugfix: the fast ETRN flush server could not handle [ipaddr]
+       or domain names with one-character hostname part. It should
+       be OK now. File: flush/flush.c.
index 20d58268c25c1507b7b6186b7c587c1acc3f1962..a12ae54513ec61a0d543e227791af964c879462e 100644 (file)
@@ -249,6 +249,8 @@ or, if you feel nostalgic, use the Postfix sendmail command:
 
 and watch your syslog file for any error messages.
 
+    % egrep '(reject|warning|error|fatal|panic):' /some/log/file
+
 When it is run for the first time, the Postfix startup shell script
 will create a bunch of subdirectories below the Postfix spool
 directory.
@@ -290,6 +292,8 @@ or, if you feel nostalgic, use the Postfix sendmail program:
 
 and watch your syslog file for any error messages. 
 
+    % egrep '(reject|warning|error|fatal|panic):' /some/log/file
+
 When it is run for the first time, the Postfix startup shell script
 will create a bunch of subdirectories below the Postfix spool
 directory.
@@ -323,6 +327,8 @@ But the good old sendmail way works just as well:
 
 and watch the syslog file for any complaints from the mail system.
 
+    % egrep '(reject|warning|error|fatal|panic):' /some/log/file
+
 When it is run for the first time, the Postfix startup shell script
 will create a bunch of subdirectories below the Postfix spool
 directory.
index 1b0c41829bc0b51d25bc111af04306b6de24a0ef..35a22a7a4266cc5df40dee714cf2409bd0b9c4d5 100644 (file)
@@ -1,3 +1,9 @@
+LINUX PORTABILITY
+=================
+
+On RedHat Linux 7.0, you must install the db3-devel RPM before you
+can compile the Postfix source code.
+
 LINUX SYSLOGD PERFORMANCE
 =========================
 
index 78f93f18859eaba3af838c6c9d7cf7e3b03182cf..59a855eb32b6ca4636df4064043b4a7cf73c7387 100644 (file)
@@ -76,7 +76,7 @@
 #               octets separated by ".".
 # 
 # ACTIONS
-#        [45]XX text
+#        [45]NN text
 #               Reject the address etc. that matches  the  pattern,
 #               and respond with the numerical code and text.
 # 
@@ -86,7 +86,7 @@
 #        OK     Accept the address etc. that matches the pattern.
 # 
 #        restriction...
-#               Apply the named UCE  restriction  (permit,  reject,
+#               Apply the named UCE restriction(s) (permit, reject,
 #               reject_unauth_destination, and so on).
 # 
 # REGULAR EXPRESSION TABLES
index ee1c90c708ab1774660fbb051cabce7b31e1d1be..fb75a55a289fa15194436a41ad301e1d3d9ff83b 100644 (file)
@@ -226,14 +226,12 @@ mail_owner = postfix
 # $inet_interfaces.  If this parameter is defined, then the SMTP server
 # will reject mail for unknown local users.
 #
-# The local_recipient_maps parameter accepts tables with bare usernames
-# such as unix:passwd.byname and alias maps.
+# If you use the default Postfix local delivery agent for local
+# delivery, uncomment the definition below.
 #
 # Beware: if the Postfix SMTP server runs chrooted, you may have to
-# copy the passwd database into the jail. This is system dependent.
-#
-# FOR THIS TO WORK, DO NOT SPECIFY VIRTUAL DOMAINS IN MYDESTINATION.
-# MYDESTINATION MUST LIST NON-VIRTUAL DOMAINS ONLY.
+# copy the passwd (not shadow) database into the jail. This is
+# system dependent.
 #
 #local_recipient_maps = $alias_maps unix:passwd.byname
 
index 2c5d43ae21c3b274e5203090b2ee30fd66c46c2b..d102a0e3bcc8fa0de6084b8c6afa2b6e4da044bb 100755 (executable)
@@ -35,7 +35,7 @@ case $daemon_directory in
     exit 1
 esac
 
-LOGGER="$command_directory/postlog -t postfix-script"
+LOGGER="$command_directory/postlog -t $MAIL_LOGTAG/postfix-script"
 INFO="$LOGGER -p info"
 WARN="$LOGGER -p warn"
 ERROR="$LOGGER -p error"
index a635ef679d787e090b01bc2c84afa5f958e30795..d436e4df33b0033ae05a99169de709d73b607475 100755 (executable)
@@ -35,7 +35,7 @@ case $daemon_directory in
     exit 1
 esac
 
-LOGGER="$command_directory/postlog -t postfix-script"
+LOGGER="$command_directory/postlog -t $MAIL_LOGTAG/postfix-script"
 INFO="$LOGGER -p info"
 WARN="$LOGGER -p warn"
 ERROR="$LOGGER -p error"
index 329ee4cf322169238b9cd699c7de1da0b135a05a..868ee5df0f9c4894c95260ab819e84574f951fc1 100644 (file)
@@ -4,6 +4,16 @@
 # This file contains example settings of Postfix configuration
 # parameters that control compatibility with broken software.
 
+# The broken_sasl_auth_clients controls inter-operability with SMTP
+# clients that do not recognize that Postfix supports RFC 2554 (AUTH
+# command).  Examples of such clients are MicroSoft Outlook Express
+# version 4 and MicroSoft Exchange version 5.0.
+# 
+# Specify broken_sasl_auth_clients=yes to have Postfix advertise 
+# AUTH support in a non-standard way.
+# 
+broken_sasl_auth_clients = no
+
 # The ignore_mx_lookup_error parameter controls what happens when a
 # name server fails to respond to an MX lookup request. By default,
 # Postfix defers delivery and tries again after some delay. Specify
index 14f9e19b2c80aa34479c98021c2a5fbd43123e4e..3e0d32d4b6ef4c2ac6addd3279a8dae6051cb614 100644 (file)
@@ -360,6 +360,18 @@ relocated_maps =
 #
 syslog_facility = mail
 
+# The syslog_name parameter specifies the mail system name that is
+# prepended to the process name in syslog records headers, so that
+# "smtpd" becomes "postfix/smtpd".
+#
+# Beware: a non-default syslog_name setting takes effect only
+# after process initialization. Some initialization errors will be
+# logged with the default name, especially errors while parsing
+# the command line and errors while accessing the Postfix main.cf
+# configuration file.
+#
+syslog_name = postfix
+
 # The trigger_timeout parameter limits the time to send a trigger to
 # a Postfix daemon. This prevents programs from getting stuck when the
 # mail system is under heavy load.
index 0818d204c6f093b3ec9030cc76b343c6a4b035d6..89db2dcb3a77b623e40013a09c2bc3bfd5ebcb14 100644 (file)
@@ -87,7 +87,7 @@ ACCESS(5)                                               ACCESS(5)
               octets separated by ".".
 
 <b>ACTIONS</b>
-       [<b>45</b>]<i>XX</i> <i>text</i>
+       [<b>45</b>]<i>NN</i> <i>text</i>
               Reject the address etc. that matches  the  pattern,
               and respond with the numerical code and text.
 
@@ -97,7 +97,7 @@ ACCESS(5)                                               ACCESS(5)
        <b>OK</b>     Accept the address etc. that matches the pattern.
 
        <i>restriction...</i>
-              Apply the named UCE  restriction  (<b>permit</b>,  reject,
+              Apply the named UCE restriction(s) (<b>permit</b>, reject,
               <b>reject</b><i>_</i><b>unauth</b><i>_</i><b>destination</b>, and so on).
 
 <b>REGULAR</b> <b>EXPRESSION</b> <b>TABLES</b>
index d48c5be2f10e30cadeb4160134e5dc8c97b541fd..d6508911367454eea920e38af4bf6d74458c7bbd 100644 (file)
@@ -24,6 +24,8 @@
 
 <li><a href="#poppers">POP or IMAP problems</a>
 
+<li><a href="#systems">Problems with specific Operating Systems</a>
+
 <li><a href="#warnings">Postfix warnings and error messages</a>
 
 <li><a href="#example_config">Example configurations</a>
 
 <li><a href="#noalias">What does "fatal: open database /etc/aliases.db" mean?</a>
 
+<li><a href="#noservice">What does "fatal: unknown service: smtp/tcp" mean?</a>
+
 <li><a href="#nosuid">sendmail has set-uid root file permissions, or is run from a set-uid root process</a>
 
+<li><a href="#whoami">sendmail: unable to find out your login name</a>
+
+
+<li><a href="#unknown_virtual_loop">Mail for unknown users in
+virtual domains fails with "mail loops back to myself"</a>
+
+<li><a href="#virtual_relay">Postfix refuses mail for virtual
+domains with "relay access denied"</a>
 </ul>
 
 <p>
@@ -186,6 +198,8 @@ domains with "relay access denied"</a>
 
 <li><a href="#skip_greeting">Postfix does not try all the MX addresses</a>
 
+<li><a href="#noservice">What does "fatal: unknown service: smtp/tcp" mean?</a>
+
 </ul>
 
 <a name="local_delivery"><h3>Local (non-virtual) delivery</h3>
@@ -311,6 +325,36 @@ mailbox</a>
 
 </ul>
 
+<p>
+
+<a name="systems"><h3>Problems with specific Operating Systems</h3>
+
+<p>
+
+<ul>
+
+<li><a href="#compaq">Problems with Compaq</a>
+
+<li><a href="#irix">Problems with IRIX</a>
+
+</ul>
+
+<a name="compaq"><h3>Problems with Compaq</h3>
+
+<ul>
+
+<li><a href="#compaq-chmod">Compaq mail blackhole problem</a>
+
+</ul>
+
+<a name="irix"><h3>Problems with IRIX</h3>
+
+<ul>
+
+<li><a href="#sgistruct">IRIX problems translating IP address to string</a>
+
+</ul>
+
 <hr>
 
 <a name="poppers"><h3>POP or IMAP problems</h3>
@@ -970,6 +1014,30 @@ PERMISSION_SECURITY="secure local"
 
 <hr>
 
+<a name="whoami"><h3>sendmail: unable to find out your login name</h3>
+
+This message is logged when submitting mail from a process with a
+userid that does not exist in the UNIX password file.  Postfix uses
+this information in order to set the envelope sender address.
+
+<p>
+
+The envelope sender address is also the default value for the From:
+header address, when none is specified in the message.
+
+<p>
+
+To fix, specify the envelope sender address on the sendmail command
+line:
+
+<blockquote>
+<pre>
+sendmail -f user@domain ...
+</pre>
+</blockquote>
+
+<hr>
+
 <a name="moby-freebsd"><h3>Running hundreds of Postfix processes on FreeBSD</h3></a>
 
 With hundreds of Postfix processes, the kernel will eventually
@@ -1112,32 +1180,41 @@ depending on the interface that it is supposed to handle.
 
 <a name="delay"><h3>Postfix responds slowly to incoming SMTP connections</h3></a>
 
-<dl>
+Question:
 
-<dt>Question:
+<blockquote> 
 
-<dd> My Postfix server is too slow. When I telnet to the SMTP port
+My Postfix server is too slow. When I telnet to the SMTP port
 (<tt>telnet hostname 25</tt>), the response comes after 40 seconds.
 On the other hand, when I telnet to the the POP port (<tt>telnet
 hostname 110</tt>) the response comes with no delay.
 
+</blockquote>
+
 <p>
 
-<dt>Answer:
+Answer:
 
-<dd>
+<blockquote>
 
-This is a DNS configuration problem. Postfix tries to resolve the
-SMTP client IP address to a hostname. Apparently, your POP server
-does not look up POP clients.
+You have a name service problem.
 
 <p>
 
-The fix is to properly configure the naming service. If you can't
-have every host in the DNS, then configure the mail server to look
-in /etc/hosts before the DNS, and specify the clients in /etc/hosts.
+Postfix calls the C library routines <b>gethostbyname()</b> and
+<b>gethostbyaddr()</b> in order to find out the SMTP client hostname.
+These library routines use several system configuration files in
+order to satisfy the request. They may in fact end up calling the
+DNS for reasons that are not under control by Postfix.
 
-</dl>
+<p>
+
+Depending on your system, these controlling files can be named
+<b>/etc/nsswitch.conf</b>, <b>/etc/svcorder</b>, <b>/etc/host.conf</b>
+or otherwise.  Those files specify whether the C library routines
+will use local <b>/etc/hosts</b> before or after DNS.
+
+</blockquote>
 
 <hr>
 
@@ -1733,6 +1810,35 @@ use the command <b>postconf mail_version</b>.
 Execute the command <b>postfix reload</b> to make the change
 effective immediately.
 
+<a name="noservice"><h3>What does "fatal: unknown service: smtp/tcp"
+mean?</h3>
+
+The Postfix <b>/etc/postfix/master.cf</b> file specifies that the
+Postfix SMTP client runs inside a <b>chroot</b> environment. However,
+the files necessary for that mode of operation are not installed
+below <b>/var/spool/postfix</b>.
+
+<p>
+
+Enabling <b>chroot</b> operation adds a non-trivial barrier for
+system penetrators.
+
+<p>
+
+Two solutions:
+
+<ul>
+
+<li> Disable the <b>chroot</b> in <b>/etc/postfix/master.cf</b>
+(and issue <b>postfix reload</b> when done).
+
+<p>
+
+<li>Install the necessary files for <b>chroot</b> operation.
+Instructions are given in the source code distribution, in the
+<b>examples/chroot-setup</b> directory.
+
+</ul>
 <hr>
 
 <a name="root"> <h3>Root's mail is delivered to nobody</h3>
@@ -2300,6 +2406,11 @@ virtual domain.
 
 <p>
 
+Sendmail-style virtual domains are not supported in Postfix versions
+released before 20001118.
+
+<p>
+
 Be sure to follow instructions in the <a href="virtual.5.html">
 virtual</a> manual page.
 
@@ -2909,6 +3020,36 @@ href="http://www.isc.org/"> http://www.isc.org/</a>.
 
 <hr>
 
+<a name="compaq-chmod"><h3>Compaq mail blackhole problem</h3>
+
+On some Compaq Tru64 UNIX configurations, Postfix will receive mail
+and then nothing happens. The mail does not even show up with the
+<b>mailq</b> command.
+
+<p>
+
+Postfix sets the execute bit on a queue file to indicate that it
+is done receiving a message. As long as a queue file does not have
+the execute bit set, Postfix will ignore it as "mail still being
+received".
+
+<p>
+
+With enhanced security enabled, Compaq Tru64 UNIX has a feature
+that disallows non-superuser attempts to set the execute bit on a
+queuefile.  Unfortunately, Postfix is never informed that such
+attempts fail, and mail seems to disappear into a black hole.
+
+<p>
+
+Postfix could be modified to use some other bit than the execute
+bit, but that might equally well fail on other systems. Another
+possibility is to allow non-superusers to set the execute bit on
+files, and to mount the Postfix queue file system with the
+<b>noexec</b> option or equivalent.
+
+<hr>
+
 <a href="index.html">Up one level</a> | Postfix FAQ
 
 </body>
index 207286715c55a5ddf188cdb5c758ab30b93b4298..4c79983a037463cdcad650970f23d03374de570a 100644 (file)
@@ -13,11 +13,9 @@ PIPE(8)                                                   PIPE(8)
 
 <b>DESCRIPTION</b>
        The  <b>pipe</b> daemon processes requests from the Postfix queue
-       manager to deliver messages  to  external  commands.  Each
-       delivery request specifies a queue file, a sender address,
-       a domain or host to deliver to, and one  or  more  recipi-
-       ents.   This  program expects to be run from the <a href="master.8.html"><b>master</b>(8)</a>
-       process manager.
+       manager to deliver messages to  external  commands.   This
+       program  expects to be run from the <a href="master.8.html"><b>master</b>(8)</a> process man-
+       ager.
 
        The <b>pipe</b> daemon updates queue files and  marks  recipients
        as finished, or it informs the queue manager that delivery
@@ -25,60 +23,74 @@ PIPE(8)                                                   PIPE(8)
        reports  are  sent  to the <a href="bounce.8.html"><b>bounce</b>(8)</a> or <a href="defer.8.html"><b>defer</b>(8)</a> daemon as
        appropriate.
 
+<b>SINGLE-RECIPIENT</b> <b>DELIVERY</b>
+       Some external commands cannot handle more than one recipi-
+       ent  per delivery request. Examples of such transports are
+       pagers, fax machines, and so on.
+
+       To prevent Postfix from sending  multiple  recipients  per
+       delivery request, specify
+
+           <i>transport_</i><b>destination</b><i>_</i><b>recipient</b><i>_</i><b>limit</b> <b>=</b> <b>1</b>
+
+       in  the  Postfix <b>main.cf</b> file, where <i>transport</i> is the name
+       in the first column of the Postfix <b>master.cf</b> entry for the
+       pipe-based delivery transport.
+
 <b>COMMAND</b> <b>ATTRIBUTE</b> <b>SYNTAX</b>
        The external command attributes are given in the <b>master.cf</b>
        file at the end of a service definition.  The syntax is as
        follows:
 
        <b>flags=BFR.</b>&gt; (optional)
-              Optional message processing flags.  By  default,  a
+              Optional  message  processing  flags. By default, a
               message is copied unchanged.
 
-              <b>B</b>      Append  a blank line at the end of each mes-
-                     sage. This is required  by  some  mail  user
-                     agents  that  recognize  "<b>From</b>  " lines only
+              <b>B</b>      Append a blank line at the end of each  mes-
+                     sage.  This  is  required  by some mail user
+                     agents that recognize  "<b>From</b>  "  lines  only
                      when preceded by a blank line.
 
-              <b>F</b>      Prepend a "<b>From</b> <i>sender</i> <i>time_stamp</i>"  envelope
-                     header  to  the  message  content.   This is
+              <b>F</b>      Prepend  a "<b>From</b> <i>sender</i> <i>time_stamp</i>" envelope
+                     header to  the  message  content.   This  is
                      expected by, for example, <b>UUCP</b> software.
 
-              <b>R</b>      Prepend a <b>Return-Path:</b> message  header  with
+              <b>R</b>      Prepend  a  <b>Return-Path:</b> message header with
                      the envelope sender address.
 
-              <b>.</b>      Prepend  <b>.</b>  to lines starting with "<b>.</b>". This
-                     is needed by, for example, <b>BSMTP</b> software.
+              <b>.</b>      Prepend <b>.</b> to lines starting with  "<b>.</b>".  This
 
-              &gt;      Prepend &gt; to lines starting  with  "<b>From</b>  ".
-                     This is expected by, for example, <b>UUCP</b> soft-
-                     ware.
 
-       <b>user</b>=<i>username</i> (required)
 
-       <b>user</b>=<i>username</i>:<i>groupname</i>
-              The external command is executed with the rights of
-              the  specified  <i>username</i>.   The software refuses to
-              execute commands with root privileges, or with  the
+                                                                1
 
 
 
-                                                                1
 
 
+PIPE(8)                                                   PIPE(8)
 
 
+                     is needed by, for example, <b>BSMTP</b> software.
 
-PIPE(8)                                                   PIPE(8)
+              &gt;      Prepend  &gt;  to  lines starting with "<b>From</b> ".
+                     This is expected by, for example, <b>UUCP</b> soft-
+                     ware.
 
+       <b>user</b>=<i>username</i> (required)
 
-              privileges  of  the mail system owner. If <i>groupname</i>
-              is specified, the corresponding group  ID  is  used
+       <b>user</b>=<i>username</i>:<i>groupname</i>
+              The external command is executed with the rights of
+              the specified <i>username</i>.  The  software  refuses  to
+              execute  commands with root privileges, or with the
+              privileges of the mail system owner.  If  <i>groupname</i>
+              is  specified,  the  corresponding group ID is used
               instead of the group ID of <i>username</i>.
 
        <b>eol=string</b> (default: <b>\n</b>)
-              The  output  record  delimiter. Typically one would
-              use either <b>\r\n</b> or <b>\n</b>. The usual C-style  backslash
-              escape  sequences are recognized: <b>\a</b> <b>\b</b> <b>\f</b> <b>\n</b> <b>\r</b> <b>\t</b>
+              The output record delimiter.  Typically  one  would
+              use  either <b>\r\n</b> or <b>\n</b>. The usual C-style backslash
+              escape sequences are recognized: <b>\a</b> <b>\b</b> <b>\f</b> <b>\n</b> <b>\r</b>  <b>\t</b>
               <b>\v</b> <b>\</b><i>octal</i> and <b>\\</b>.
 
        <b>size</b>=<i>size_limit</i> (optional)
@@ -86,45 +98,33 @@ PIPE(8)                                                   PIPE(8)
               will be bounced back to the sender.
 
        <b>argv</b>=<i>command</i>... (required)
-              The  command to be executed. This must be specified
+              The command to be executed. This must be  specified
               as the last command attribute.  The command is exe-
               cuted  directly,  i.e.  without  interpretation  of
-              shell meta characters by  a  shell  command  inter-
+              shell  meta  characters  by  a shell command inter-
               preter.
 
               In  the  command  argument  vector,  the  following
               macros are recognized and replaced with correspond-
-              ing  information  from  the  Postfix  queue manager
+              ing information  from  the  Postfix  queue  manager
               delivery request:
 
               <b>${extension</b>}
-                     This macro expands to the extension part  of
-                     a  recipient  address.  For example, with an
+                     This  macro expands to the extension part of
+                     a recipient address.  For example,  with  an
                      address  <i>user+foo@domain</i>  the  extension  is
-                     <i>foo</i>.   A command-line argument that contains
-                     <b>${extension</b>} expands into as  many  command-
+                     <i>foo</i>.
+
+                     A  command-line   argument   that   contains
+                     <b>${extension</b>}  expands  into as many command-
                      line arguments as there are recipients.
 
               <b>${mailbox</b>}
-                     This  macro  expands  to  the complete local
-                     part of a recipient address.   For  example,
-                     with  an address <i>user+foo@domain</i> the mailbox
-                     is <i>user+foo</i>.  A command-line  argument  that
-                     contains  <b>${mailbox</b>}  expands  into  as many
-                     command-line arguments as there are  recipi-
-                     ents.
+                     This macro expands  to  the  complete  local
+                     part  of  a recipient address.  For example,
+                     with an address <i>user+foo@domain</i> the  mailbox
+                     is <i>user+foo</i>.
 
-              <b>${nexthop</b>}
-                     This macro expands to the next-hop hostname.
-
-              <b>${recipient</b>}
-                     This macro expands to the complete recipient
-                     address.   A command-line argument that con-
-                     tains <b>${recipient</b>} expands into as many com-
-                     mand-line arguments as there are recipients.
-
-              <b>${sender</b>}
-                     This macro expands to  the  envelope  sender
 
 
 
@@ -137,43 +137,74 @@ PIPE(8)                                                   PIPE(8)
 PIPE(8)                                                   PIPE(8)
 
 
+                     A   command-line   argument   that  contains
+                     <b>${mailbox</b>} expands into as many command-line
+                     arguments as there are recipients.
+
+              <b>${nexthop</b>}
+                     This macro expands to the next-hop hostname.
+
+              <b>${recipient</b>}
+                     This macro expands to the complete recipient
+                     address.
+
+                     A   command-line   argument   that  contains
+                     <b>${recipient</b>} expands into as  many  command-
+                     line arguments as there are recipients.
+
+              <b>${sender</b>}
+                     This  macro  expands  to the envelope sender
                      address.
 
               <b>${size</b>}
-                     This  macro expands to Postfix's idea of the
-                     message size, which is an  approximation  of
+                     This macro expands to Postfix's idea of  the
+                     message  size,  which is an approximation of
                      the size of the message as delivered.
 
               <b>${user</b>}
                      This macro expands to the username part of a
-                     recipient address.   For  example,  with  an
+                     recipient  address.   For  example,  with an
                      address <i>user+foo@domain</i> the username part is
-                     <i>user</i>.  A command-line argument that contains
-                     <b>${user</b>}  expands  into  as many command-line
+                     <i>user</i>.
+
+                     A   command-line   argument   that  contains
+                     <b>${user</b>} expands into  as  many  command-line
                      arguments as there are recipients.
 
-       In addition to the  form  ${<i>name</i>},  the  forms  $<i>name</i>  and
-       $(<i>name</i>)  are also recognized.  Specify <b>$$</b> where a single <b>$</b>
+       In  addition  to  the  form  ${<i>name</i>},  the forms $<i>name</i> and
+       $(<i>name</i>) are also recognized.  Specify <b>$$</b> where a single  <b>$</b>
        is wanted.
 
 <b>DIAGNOSTICS</b>
-       Command exit status codes are expected to follow the  con-
+       Command  exit status codes are expected to follow the con-
        ventions defined in &lt;<b>sysexits.h</b>&gt;.
 
-       Problems  and transactions are logged to <b>syslogd</b>(8).  Cor-
-       rupted message files are marked so that the queue  manager
+       Problems and transactions are logged to <b>syslogd</b>(8).   Cor-
+       rupted  message files are marked so that the queue manager
        can move them to the <b>corrupt</b> queue for further inspection.
 
 <b>SECURITY</b>
-       This program needs a dual personality  1)  to  access  the
-       private  Postfix  queue and IPC mechanisms, and 2) to exe-
+       This  program  needs  a  dual personality 1) to access the
+       private Postfix queue and IPC mechanisms, and 2)  to  exe-
        cute external commands as the specified user. It is there-
        fore security sensitive.
 
 <b>CONFIGURATION</b> <b>PARAMETERS</b>
-       The  following  <b>main.cf</b> parameters are especially relevant
-       to this program. See the Postfix <b>main.cf</b> file  for  syntax
-       details  and  for  default  values. Use the <b>postfix</b> <b>reload</b>
+       The following <b>main.cf</b> parameters are  especially  relevant
+
+
+
+                                                                3
+
+
+
+
+
+PIPE(8)                                                   PIPE(8)
+
+
+       to  this  program. See the Postfix <b>main.cf</b> file for syntax
+       details and for default values.  Use  the  <b>postfix</b>  <b>reload</b>
        command after a configuration change.
 
 <b>Miscellaneous</b>
@@ -182,44 +213,32 @@ PIPE(8)                                                   PIPE(8)
               exported to non-Postfix processes.
 
        <b>mail</b><i>_</i><b>owner</b>
-              The  process  privileges  used while not running an
+              The process privileges used while  not  running  an
               external command.
 
 <b>Resource</b> <b>controls</b>
-       In the text below, <i>transport</i> is the first field in a  <b>mas-</b>
+       In  the text below, <i>transport</i> is the first field in a <b>mas-</b>
        <b>ter.cf</b> entry.
 
        <i>transport_</i><b>destination</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b>
               Limit the number of parallel deliveries to the same
-
-
-
-                                                                3
-
-
-
-
-
-PIPE(8)                                                   PIPE(8)
-
-
-              destination, for delivery via the named  <i>transport</i>.
-              The  default limit is taken from the <b>default</b><i>_</i><b>desti-</b>
-              <b>nation</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b> parameter.  The  limit  is
+              destination,  for delivery via the named <i>transport</i>.
+              The default limit is taken from the  <b>default</b><i>_</i><b>desti-</b>
+              <b>nation</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b>  parameter.   The limit is
               enforced by the Postfix queue manager.
 
        <i>transport_</i><b>destination</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>
-              Limit  the  number of recipients per message deliv-
-              ery, for delivery  via  the  named  <i>transport</i>.  The
-              default  limit  is  taken from the <b>default</b><i>_</i><b>destina-</b>
-              <b>tion</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>  parameter.   The   limit   is
+              Limit the number of recipients per  message  deliv-
+              ery,  for  delivery  via  the  named <i>transport</i>. The
+              default limit is taken  from  the  <b>default</b><i>_</i><b>destina-</b>
+              <b>tion</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>   parameter.    The  limit  is
               enforced by the Postfix queue manager.
 
        <i>transport_</i><b>time</b><i>_</i><b>limit</b>
-              Limit  the  time  for delivery to external command,
-              for delivery via the named <b>transport</b>.  The  default
-              limit  is taken from the <b>command</b><i>_</i><b>time</b><i>_</i><b>limit</b> parame-
-              ter.  The limit is enforced by  the  Postfix  queue
+              Limit the time for delivery  to  external  command,
+              for  delivery  via the named <b>transport</b>. The default
+              limit is taken from the <b>command</b><i>_</i><b>time</b><i>_</i><b>limit</b>  parame-
+              ter.   The  limit  is enforced by the Postfix queue
               manager.
 
 <b>SEE</b> <b>ALSO</b>
@@ -229,7 +248,7 @@ PIPE(8)                                                   PIPE(8)
        syslogd(8) system logging
 
 <b>LICENSE</b>
-       The  Secure  Mailer  license must be distributed with this
+       The Secure Mailer license must be  distributed  with  this
        software.
 
 <b>AUTHOR(S)</b>
@@ -239,25 +258,6 @@ PIPE(8)                                                   PIPE(8)
        Yorktown Heights, NY 10598, USA
 
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
 
 
                                                                 4
index 851a1390fac4f560581755796405423d99bce3d8..6488c0b7911e3eb4e7e2783ae72fa3dbd1025c10 100644 (file)
@@ -69,7 +69,7 @@ address is a sequence of one or more octets separated by ".".
 .nf
 .ad
 .fi
-.IP "[\fB45\fR]\fIXX text\fR"
+.IP "[\fB45\fR]\fINN text\fR"
 Reject the address etc. that matches the pattern, and respond with
 the numerical code and text.
 .IP \fBREJECT\fR
@@ -78,7 +78,7 @@ error response message is generated.
 .IP \fBOK\fR
 Accept the address etc. that matches the pattern.
 .IP \fIrestriction...\fR
-Apply the named UCE restriction (\fBpermit\fR, \fRreject\fR,
+Apply the named UCE restriction(s) (\fBpermit\fR, \fRreject\fR,
 \fBreject_unauth_destination\fR, and so on).
 .SH REGULAR EXPRESSION TABLES
 .na
index 7fb5787bac9427c5cda7206ca444936c964b98bf..0ab6673ef49a9e3aa9bb1f89f78c0bcab1bd5494 100644 (file)
@@ -13,9 +13,7 @@ Postfix delivery to external command
 .ad
 .fi
 The \fBpipe\fR daemon processes requests from the Postfix queue
-manager to deliver messages to external commands. Each delivery
-request specifies a queue file, a sender address, a domain or host
-to deliver to, and one or more recipients.
+manager to deliver messages to external commands.
 This program expects to be run from the \fBmaster\fR(8) process
 manager.
 
@@ -23,6 +21,24 @@ The \fBpipe\fR daemon updates queue files and marks recipients
 as finished, or it informs the queue manager that delivery should
 be tried again at a later time. Delivery problem reports are sent
 to the \fBbounce\fR(8) or \fBdefer\fR(8) daemon as appropriate.
+.SH SINGLE-RECIPIENT DELIVERY
+.na
+.nf
+.ad
+.fi
+Some external commands cannot handle more than one recipient
+per delivery request. Examples of such transports are pagers,
+fax machines, and so on.
+
+To prevent Postfix from sending multiple recipients per delivery
+request, specify
+
+.ti +4
+\fItransport\fB_destination_recipient_limit = 1\fR
+
+in the Postfix \fBmain.cf\fR file, where \fItransport\fR
+is the name in the first column of the Postfix \fBmaster.cf\fR
+entry for the pipe-based delivery transport.
 .SH COMMAND ATTRIBUTE SYNTAX
 .na
 .nf
@@ -82,18 +98,21 @@ manager delivery request:
 This macro expands to the extension part of a recipient address.
 For example, with an address \fIuser+foo@domain\fR the extension is
 \fIfoo\fR.
+.sp
 A command-line argument that contains \fB${\fBextension\fR}\fR expands
 into as many command-line arguments as there are recipients.
 .IP \fB${\fBmailbox\fR}\fR
 This macro expands to the complete local part of a recipient address.
 For example, with an address \fIuser+foo@domain\fR the mailbox is
 \fIuser+foo\fR.
+.sp
 A command-line argument that contains \fB${\fBmailbox\fR}\fR
 expands into as many command-line arguments as there are recipients.
 .IP \fB${\fBnexthop\fR}\fR
 This macro expands to the next-hop hostname.
 .IP \fB${\fBrecipient\fR}\fR
 This macro expands to the complete recipient address.
+.sp
 A command-line argument that contains \fB${\fBrecipient\fR}\fR
 expands into as many command-line arguments as there are recipients.
 .IP \fB${\fBsender\fR}\fR
@@ -105,6 +124,7 @@ is an approximation of the size of the message as delivered.
 This macro expands to the username part of a recipient address.
 For example, with an address \fIuser+foo@domain\fR the username
 part is \fIuser\fR.
+.sp
 A command-line argument that contains \fB${\fBuser\fR}\fR expands
 into as many command-line arguments as there are recipients.
 .RE
index 23b4fd96015ff9c444039c81ce14d00aa807d2b2..a319352cd567549f2e7a9e5573a7334f50ba85e4 100644 (file)
@@ -57,7 +57,7 @@
 # ACTIONS
 # .ad
 # .fi
-# .IP "[\fB45\fR]\fIXX text\fR"
+# .IP "[\fB45\fR]\fINN text\fR"
 #      Reject the address etc. that matches the pattern, and respond with
 #      the numerical code and text.
 # .IP \fBREJECT\fR
@@ -66,7 +66,7 @@
 # .IP \fBOK\fR
 #      Accept the address etc. that matches the pattern.
 # .IP \fIrestriction...\fR
-#      Apply the named UCE restriction (\fBpermit\fR, \fRreject\fR,
+#      Apply the named UCE restriction(s) (\fBpermit\fR, \fRreject\fR,
 #      \fBreject_unauth_destination\fR, and so on).
 # REGULAR EXPRESSION TABLES
 # .ad
index 1a4982fa1db2fb01ab9419bd83b191271c2bf552..243404be1c4d4b525c1c882b4780c4c506ee1ba7 100644 (file)
@@ -182,7 +182,6 @@ static void cleanup_extracted_process(CLEANUP_STATE *state, int type, char *buf,
      * straightforward.
      */
     if (vstream_fflush(state->dst)) {
-       msg_warn("%s: write queue file: %m", state->queue_id);
        if (errno == EFBIG) {
            msg_warn("%s: queue file size limit exceeded", state->queue_id);
            state->errs |= CLEANUP_STAT_SIZE;
index d35cc5813f91040a9e2bea6595824675b520b607..eb6a24dcb4d71bc5909dc8ea8f7e8b80451988fd 100644 (file)
 #include <stdlib.h>
 #include <utime.h>
 #include <errno.h>
+#include <ctype.h>
 
 /* Utility library. */
 
@@ -182,10 +183,44 @@ static DOMAIN_LIST *flush_domains;
  /*
   * Silly little macros.
   */
-
 #define STR(x)                 vstring_str(x)
 #define STREQ(x,y)             (strcmp(x,y) == 0)
 
+ /*
+  * Forward declarations for where we broke routines along their name space
+  * domain boundaries (actually, hostnames versus safe-to-use pathnames).
+  */
+static int flush_add_path(const char *, const char *);
+static int flush_send_path(const char *);
+
+/* flush_site_to_path - convert domain or [addr] to harmless string */
+
+static VSTRING *flush_site_to_path(VSTRING *path, const char *site)
+{
+    int     ch;
+
+    /*
+     * Allocate buffer on the fly; caller still needs to clean up.
+     */
+    if (path == 0)
+       path = vstring_alloc(10);
+
+    /*
+     * Convert character values to hexadecimal.
+     */
+    while ((ch = *(unsigned const char *) site++) != 0)
+       if (ISALNUM(ch))
+           VSTRING_ADDCH(path, ch);
+       else
+           VSTRING_ADDCH(path, '_');
+    VSTRING_TERMINATE(path);
+
+    if (msg_verbose)
+       msg_info("site %s to path %s", site, STR(path));
+
+    return (path);
+}
+
 /* flush_policy_ok - check logging policy */
 
 static int flush_policy_ok(const char *site)
@@ -193,12 +228,13 @@ static int flush_policy_ok(const char *site)
     return (domain_list_match(flush_domains, site));
 }
 
-/* flush_add_service - append queue ID to per-site fast flush log */
+/* flush_add_service - append queue ID to per-site fast flush logfile */
 
 static int flush_add_service(const char *site, const char *queue_id)
 {
     char   *myname = "flush_add_service";
-    VSTREAM *log;
+    VSTRING *site_path;
+    int     status;
 
     if (msg_verbose)
        msg_info("%s: site %s queue_id %s", myname, site, queue_id);
@@ -209,13 +245,29 @@ static int flush_add_service(const char *site, const char *queue_id)
     if (flush_policy_ok(site) == 0)
        return (FLUSH_STAT_OK);
 
+    /*
+     * Map site to path and update log.
+     */
+    site_path = flush_site_to_path((VSTRING *) 0, site);
+    status = flush_add_path(STR(site_path), queue_id);
+    vstring_free(site_path);
+
+    return (status);
+}
+
+/* flush_add_path - add record to log */
+
+static int flush_add_path(const char *path, const char *queue_id)
+{
+    char   *myname = "flush_add_path";
+    VSTREAM *log;
+
     /*
      * Open the logfile or bust.
      */
-    if ((log = mail_queue_open(MAIL_QUEUE_FLUSH, site,
+    if ((log = mail_queue_open(MAIL_QUEUE_FLUSH, path,
                               O_CREAT | O_APPEND | O_WRONLY, 0600)) == 0)
-       msg_fatal("%s: open fast flush log for site %s: %m",
-                 myname, site);
+       msg_fatal("%s: open fast flush logfile %s: %m", myname, path);
 
     /*
      * We must lock the logfile, so that we don't lose information due to
@@ -223,7 +275,7 @@ static int flush_add_service(const char *site, const char *queue_id)
      * will eventually take care of the problem, but it will take a while.
      */
     if (myflock(vstream_fileno(log), INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
-       msg_fatal("%s: lock fast flush log for site %s: %m", myname, site);
+       msg_fatal("%s: lock fast flush logfile %s: %m", myname, path);
 
     /*
      * Append the queue ID. With 15 bits if microsecond time, a queue ID is
@@ -237,10 +289,9 @@ static int flush_add_service(const char *site, const char *queue_id)
      * Clean up.
      */
     if (myflock(vstream_fileno(log), INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
-       msg_fatal("%s: unlock fast flush log for site %s: %m",
-                 myname, site);
+       msg_fatal("%s: unlock fast flush logfile %s: %m", myname, path);
     if (vstream_fclose(log) != 0)
-       msg_warn("write fast flush log for site %s: %m", site);
+       msg_warn("write fast flush logfile %s: %m", path);
 
     return (FLUSH_STAT_OK);
 }
@@ -250,6 +301,33 @@ static int flush_add_service(const char *site, const char *queue_id)
 static int flush_send_service(const char *site)
 {
     char   *myname = "flush_send_service";
+    VSTRING *site_path;
+    int     status;
+
+    if (msg_verbose)
+       msg_info("%s: site %s", myname, site);
+
+    /*
+     * If this site is not eligible for logging, deliver all queued mail.
+     */
+    if (flush_policy_ok(site) == 0)
+       return (mail_flush_deferred());
+
+    /*
+     * Map site name to path name and flush the log.
+     */
+    site_path = flush_site_to_path((VSTRING *) 0, site);
+    status = flush_send_path(STR(site_path));
+    vstring_free(site_path);
+
+    return (status);
+}
+
+/* flush_send_path - flush logfile file */
+
+static int flush_send_path(const char *path)
+{
+    const char *myname = "flush_send_path";
     VSTRING *queue_id;
     VSTRING *queue_file;
     VSTREAM *log;
@@ -261,22 +339,13 @@ static int flush_send_service(const char *site)
     HTABLE *dup_filter;
     int     count;
 
-    if (msg_verbose)
-       msg_info("%s: site %s", myname, site);
-
-    /*
-     * If this site is not eligible for logging, deliver all queued mail.
-     */
-    if (flush_policy_ok(site) == 0)
-       return (mail_flush_deferred());
-
     /*
      * Open the logfile. If the file does not exist, then there is no queued
      * mail for this destination.
      */
-    if ((log = mail_queue_open(MAIL_QUEUE_FLUSH, site, O_RDWR, 0600)) == 0) {
+    if ((log = mail_queue_open(MAIL_QUEUE_FLUSH, path, O_RDWR, 0600)) == 0) {
        if (errno != ENOENT)
-           msg_fatal("%s: open fast flush log for site %s: %m", myname, site);
+           msg_fatal("%s: open fast flush logfile %s: %m", myname, path);
        return (FLUSH_STAT_OK);
     }
 
@@ -287,7 +356,7 @@ static int flush_send_service(const char *site)
      * watchdog will take care of it.
      */
     if (myflock(vstream_fileno(log), INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
-       msg_fatal("%s: lock fast flush log for site %s: %m", myname, site);
+       msg_fatal("%s: lock fast flush logfile %s: %m", myname, path);
 
     /*
      * This is the part that dominates running time: schedule the listed
@@ -312,15 +381,15 @@ static int flush_send_service(const char *site)
     tbuf.actime = tbuf.modtime = event_time();
     for (count = 0; vstring_get_nonl(queue_id, log) != VSTREAM_EOF; count++) {
        if (!mail_queue_id_ok(STR(queue_id))) {
-           msg_warn("bad queue id \"%.30s...\" in fast flush log for site %s",
-                    STR(queue_id), site);
+           msg_warn("bad queue id \"%.30s...\" in fast flush logfile %s",
+                    STR(queue_id), path);
            continue;
        }
        if (dup_filter->used >= FLUSH_DUP_FILTER_SIZE
            || htable_find(dup_filter, STR(queue_id)) == 0) {
            if (msg_verbose)
-               msg_info("%s: site %s: update %s time stamps",
-                        myname, site, STR(queue_id));
+               msg_info("%s: logfile %s: update queue file %s time stamps",
+                        myname, path, STR(queue_id));
            if (dup_filter->used <= FLUSH_DUP_FILTER_SIZE)
                htable_enter(dup_filter, STR(queue_id), 0);
 
@@ -344,8 +413,8 @@ static int flush_send_service(const char *site)
            }
        } else {
            if (msg_verbose)
-               msg_info("%s: site %s: skip file %s as duplicate",
-                        myname, site, STR(queue_file));
+               msg_info("%s: logfile %s: skip queue file %s as duplicate",
+                        myname, path, STR(queue_file));
        }
     }
     htable_free(dup_filter, (void (*) (char *)) 0);
@@ -356,19 +425,18 @@ static int flush_send_service(const char *site)
      * Truncate the fast flush log.
      */
     if (count > 0 && ftruncate(vstream_fileno(log), (off_t) 0) < 0)
-       msg_fatal("%s: truncate fast flush log for site %s: %m", myname, site);
+       msg_fatal("%s: truncate fast flush logfile %s: %m", myname, path);
 
     /*
      * Request delivery and clean up.
      */
     if (myflock(vstream_fileno(log), INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
-       msg_fatal("%s: unlock fast flush log for site %s: %m",
-                 myname, site);
+       msg_fatal("%s: unlock fast flush logfile %s: %m", myname, path);
     if (vstream_fclose(log) != 0)
-       msg_warn("read fast flush log for site %s: %m", site);
+       msg_warn("%s: read fast flush logfile %s: %m", myname, path);
     if (count > 0) {
        if (msg_verbose)
-           msg_info("%s: requesting delivery for site %s", myname, site);
+           msg_info("%s: requesting delivery for logfile %s", myname, path);
        mail_trigger(MAIL_CLASS_PUBLIC, MAIL_SERVICE_QUEUE,
                     qmgr_trigger, sizeof(qmgr_trigger));
     }
@@ -381,23 +449,15 @@ static int flush_refresh_service(int max_age)
 {
     char   *myname = "flush_refresh_service";
     SCAN_DIR *scan;
-    char   *site;
+    char   *site_path;
     struct stat st;
     VSTRING *path = vstring_alloc(10);
 
     scan = scan_dir_open(MAIL_QUEUE_FLUSH);
-    while ((site = mail_scan_dir_next(scan)) != 0) {
-       if (!mail_queue_id_ok(site))
+    while ((site_path = mail_scan_dir_next(scan)) != 0) {
+       if (!mail_queue_id_ok(site_path))
            continue;                           /* XXX grumble. */
-       mail_queue_path(path, MAIL_QUEUE_FLUSH, site);
-       if (flush_policy_ok(site) == 0) {
-           if (unlink(STR(path)) < 0)
-               msg_warn("remove %s: %m", STR(path));
-           else if (msg_verbose)
-               msg_info("%s: spurious fast flush logfile name: %s",
-                        myname, site);
-           continue;
-       }
+       mail_queue_path(path, MAIL_QUEUE_FLUSH, site_path);
        if (stat(STR(path), &st) < 0) {
            if (errno != ENOENT)
                msg_warn("%s: stat %s: %m", myname, STR(path));
@@ -413,15 +473,15 @@ static int flush_refresh_service(int max_age)
                    msg_info("%s: unlink %s, empty and unchanged for %d days",
                             myname, STR(path), var_fflush_purge / 86400);
            } else if (msg_verbose)
-               msg_info("%s: skip site %s - empty log", myname, site);
+               msg_info("%s: skip logfile %s - empty log", myname, site_path);
        } else if (st.st_atime + max_age < event_time()) {
            if (msg_verbose)
-               msg_info("%s: flush site %s", myname, site);
-           flush_send_service(site);
+               msg_info("%s: flush logfile %s", myname, site_path);
+           flush_send_path(site_path);
        } else {
            if (msg_verbose)
-               msg_info("%s: skip site %s, unread for <%d hours(s) ",
-                        myname, site, max_age / 3600);
+               msg_info("%s: skip logfile %s, unread for <%d hours(s) ",
+                        myname, site_path, max_age / 3600);
        }
     }
     scan_dir_close(scan);
@@ -466,14 +526,12 @@ static void flush_service(VSTREAM *client_stream, char *unused_service,
            site = vstring_alloc(10);
            queue_id = vstring_alloc(10);
            if (mail_command_read(client_stream, "%s %s", site, queue_id) == 2
-               && valid_hostname(STR(site), DONT_GRIPE)
                && mail_queue_id_ok(STR(queue_id)))
                status = flush_add_service(lowercase(STR(site)), STR(queue_id));
            mail_print(client_stream, "%d", status);
        } else if (STREQ(STR(request), FLUSH_REQ_SEND)) {
            site = vstring_alloc(10);
-           if (mail_command_read(client_stream, "%s", site) == 1
-               && valid_hostname(STR(site), DONT_GRIPE))
+           if (mail_command_read(client_stream, "%s", site) == 1)
                status = flush_send_service(lowercase(STR(site)));
            mail_print(client_stream, "%d", status);
        } else if (STREQ(STR(request), FLUSH_REQ_REFRESH)
index 43d75aed068bd2a9273837c2e84fc1f3285cf091..c7f777ef40e3808bff461a1025ac71263c53f04a 100644 (file)
@@ -601,6 +601,7 @@ mail_params.o: ../../include/valid_hostname.h
 mail_params.o: ../../include/stringops.h
 mail_params.o: ../../include/vstring.h
 mail_params.o: ../../include/vbuf.h
+mail_params.o: ../../include/safe.h
 mail_params.o: mynetworks.h
 mail_params.o: mail_conf.h
 mail_params.o: mail_version.h
@@ -683,7 +684,9 @@ mail_task.o: mail_task.c
 mail_task.o: ../../include/sys_defs.h
 mail_task.o: ../../include/vstring.h
 mail_task.o: ../../include/vbuf.h
+mail_task.o: ../../include/safe.h
 mail_task.o: mail_params.h
+mail_task.o: mail_conf.h
 mail_task.o: mail_task.h
 mail_trigger.o: mail_trigger.c
 mail_trigger.o: ../../include/sys_defs.h
index ffa1341d7ca3ccf90eb452f6c68a434b8a742859..25406e8da14660be1fc3535857b2380c23006cfb 100644 (file)
@@ -21,7 +21,8 @@
   */
 #define CONF_ENV_PATH  "MAIL_CONFIG"   /* config database */
 #define CONF_ENV_VERB  "MAIL_VERBOSE"  /* verbose mode on */
-#define CONF_ENV_DEBUG "MAIL_DEBUG"    /* verbose mode on */
+#define CONF_ENV_DEBUG "MAIL_DEBUG"    /* live debugging */
+#define CONF_ENV_LOGTAG        "MAIL_LOGTAG"   /* instance name */
 
  /*
   * External representation for booleans.
index ed04630aad6cca6a29ea5e7eaa4b0974f5e2af5a..e0a36540b2173a23191534db1124ccd4edd89379 100644 (file)
@@ -14,6 +14,7 @@
 /*     char    *var_transit_origin;
 /*     char    *var_transit_dest;
 /*     char    *var_mail_name;
+/*     char    *var_syslog_name;
 /*     char    *var_mail_owner;
 /*     uid_t   var_owner_uid;
 /*     gid_t   var_owner_gid;
@@ -92,6 +93,7 @@
 
 #include <sys_defs.h>
 #include <unistd.h>
+#include <stdlib.h>
 #include <string.h>
 #include <pwd.h>
 #include <time.h>
 #include <get_hostname.h>
 #include <valid_hostname.h>
 #include <stringops.h>
+#include <safe.h>
 
 /* Global library. */
 
@@ -127,6 +130,7 @@ char   *var_relayhost;
 char   *var_transit_origin;
 char   *var_transit_dest;
 char   *var_mail_name;
+char   *var_syslog_name;
 char   *var_mail_owner;
 uid_t   var_owner_uid;
 gid_t   var_owner_gid;
@@ -270,6 +274,7 @@ void    mail_params_init()
     };
     static CONFIG_STR_TABLE other_str_defaults[] = {
        VAR_MAIL_NAME, DEF_MAIL_NAME, &var_mail_name, 1, 0,
+       VAR_SYSLOG_NAME, DEF_SYSLOG_NAME, &var_syslog_name, 1, 0,
        VAR_MAIL_OWNER, DEF_MAIL_OWNER, &var_mail_owner, 1, 0,
        VAR_MYDEST, DEF_MYDEST, &var_mydest, 0, 0,
        VAR_MYORIGIN, DEF_MYORIGIN, &var_myorigin, 1, 0,
@@ -326,6 +331,7 @@ void    mail_params_init()
        VAR_OWNREQ_SPECIAL, DEF_OWNREQ_SPECIAL, &var_ownreq_special,
        0,
     };
+const char *cp;
 
     /*
      * Extract syslog_facility early, so that from here on all errors are
@@ -376,6 +382,15 @@ void    mail_params_init()
      */
     time(&var_starttime);
 
+    /*
+     * Export the syslog name so children can inherit and use it before they
+     * have initialized.
+     */
+    if ((cp = safe_getenv(CONF_ENV_LOGTAG)) == 0
+       || strcmp(cp, var_syslog_name) != 0)
+       if (setenv(CONF_ENV_LOGTAG, var_syslog_name, 1) < 0)
+           msg_fatal("setenv %s %s: %m", CONF_ENV_LOGTAG, var_syslog_name);
+
     /*
      * I have seen this happen just too often.
      */
index 294fd1fc5fdce95f9ab6aeebd807e8d75788d616..dc7aee1ca5f87d5ddaa8612179eb6185e44991a6 100644 (file)
@@ -1192,7 +1192,7 @@ extern int var_fflush_refresh;
   * and what Postfix exports to the external world.
   */
 #define VAR_IMPORT_ENVIRON             "import_environment"
-#define DEF_IMPORT_ENVIRON             "MAIL_CONFIG MAIL_DEBUG TZ XAUTHORITY DISPLAY"
+#define DEF_IMPORT_ENVIRON             "MAIL_CONFIG MAIL_DEBUG MAIL_LOGTAG TZ XAUTHORITY DISPLAY"
 extern char *var_import_environ;
 
 #define VAR_EXPORT_ENVIRON             "export_environment"
@@ -1230,6 +1230,13 @@ extern int var_virt_mailbox_limit;
 #define DEF_VIRT_MAILBOX_LOCK          "fcntl"
 extern char *var_virt_mailbox_lock;
 
+ /*
+  * Distinct logging tag for multiple Postfix instances.
+  */
+#define VAR_SYSLOG_NAME                        "syslog_name"
+#define DEF_SYSLOG_NAME                        "postfix"
+extern char *var_syslog_name;
+
 /* LICENSE
 /* .ad
 /* .fi
index 0500754565cc03dc9461b9f90859dec2b6dde28b..2c06f9edaa38680fdd019cc85c0952799473650c 100644 (file)
@@ -12,7 +12,8 @@
 /*     mail_task() enforces consistent naming of mailer processes.
 /*     It strips pathname information from the process name, and
 /*     prepends the name of the mail system so that logfile entries
-/*     are easier to recognize.
+/*     are easier to recognize. The mail system name is specified
+/*     with the "syslog_name" configuration parameter.
 /*
 /*     The result is volatile.  Make a copy of the result if it is
 /*     to be used for any appreciable amount of time.
 /* Utility library. */
 
 #include <vstring.h>
+#include <safe.h>
 
 /* Global library. */
 
 #include "mail_params.h"
+#include "mail_conf.h"
 #include "mail_task.h"
 
-#define MAIL_TASK_FORMAT       "postfix/%s"
-
 /* mail_task - clean up and decorate the process name */
 
 const char *mail_task(const char *argv0)
 {
     static VSTRING *canon_name;
     const char *slash;
+    const char *tag;
 
     if (canon_name == 0)
        canon_name = vstring_alloc(10);
     if ((slash = strrchr(argv0, '/')) != 0)
        argv0 = slash + 1;
-    vstring_sprintf(canon_name, MAIL_TASK_FORMAT, argv0);
+    if ((tag = safe_getenv(CONF_ENV_LOGTAG)) == 0)
+       tag = DEF_SYSLOG_NAME;
+    vstring_sprintf(canon_name, "%s/%s", tag, argv0);
     return (vstring_str(canon_name));
 }
index f0445eecd41572b4c84be520e4bb03dd81a4d717..38259bcc5944beee437fa662aa746dff349f8db7 100644 (file)
@@ -15,7 +15,7 @@
   * Version of this program.
   */
 #define VAR_MAIL_VERSION       "mail_version"
-#define DEF_MAIL_VERSION       "Snapshot-20010228"
+#define DEF_MAIL_VERSION       "Snapshot-20010323"
 extern char *var_mail_version;
 
 /* LICENSE
index a07b75113a1486912c4351b5c99e87edb6ce6c23..09b1685fff0d213fbd7847c18d27ad028a3aec17 100644 (file)
@@ -252,7 +252,7 @@ VSTRING *tok822_externalize(VSTRING *vp, TOK822 *tree, int flags)
            VSTRING_ADDCH(vp, ')');
            break;
        case TOK822_COMMENT_TEXT:
-           tok822_copy_quoted(vp, vstring_str(tp->vstr), "()\\\r\n");
+           tok822_copy_quoted(vp, vstring_str(tp->vstr), "()\\");
            break;
        case TOK822_QSTRING:
            VSTRING_ADDCH(vp, '"');
@@ -540,7 +540,7 @@ TOK822 *tok822_scan_addr(const char *addr)
 
 #include <unistd.h>
 #include <vstream.h>
-#include <vstring_vstream.h>
+#include <readlline.h>
 
 /* tok822_print - display token */
 
@@ -577,7 +577,7 @@ int     main(int unused_argc, char **unused_argv)
     TOK822 *list;
     VSTRING *buf = vstring_alloc(100);
 
-    while (vstring_fgets_nonl(buf, VSTREAM_IN)) {
+    while (readlline(buf, VSTREAM_IN, (int *) 0, READLL_KEEPNL)) {
        if (!isatty(vstream_fileno(VSTREAM_IN)))
            vstream_printf(">>>%s<<<\n\n", vstring_str(buf));
        list = tok822_parse(vstring_str(buf));
index 09572082adef658ac1bf08aaf4925d5cc2a374be..49b89f403bd0b8770cdc5ed59e8393c1f30e22af 100644 (file)
@@ -330,6 +330,10 @@ static int deliver_message(DELIVER_REQUEST *request, char **unused_argv)
        /*
         * Disconnect if we're going to a different destination. Discard
         * transcript and status information for sending QUIT.
+        * 
+        * XXX Should transform nexthop into canonical form (unix:/path or
+        * inet:host:port) before doing connection cache lookup. See also the
+        * connection cache updating code in lmtp_connect.c.
         */
        if (strcasecmp(state->session->dest, request->nexthop) != 0) {
            lmtp_quit(state);
index d48837000aa4620c559dae5e660d73873adcde2b..cb7e24663844835358452bcb0f143a9e21a3874b 100644 (file)
@@ -116,7 +116,8 @@ static LMTP_SESSION *lmtp_connect_sock(int, struct sockaddr *, int,
 
 /* lmtp_connect_unix - connect to UNIX-domain address */
 
-static LMTP_SESSION *lmtp_connect_unix(const char *addr, VSTRING *why)
+static LMTP_SESSION *lmtp_connect_unix(const char *addr,
+                                     const char *destination, VSTRING *why)
 {
 #undef sun
     char   *myname = "lmtp_connect_unix";
@@ -156,7 +157,7 @@ static LMTP_SESSION *lmtp_connect_unix(const char *addr, VSTRING *why)
        msg_info("%s: trying: %s...", myname, addr);
 
     return (lmtp_connect_sock(sock, (struct sockaddr *) & sun, sizeof(sun),
-                             addr, addr, addr, why));
+                             addr, addr, destination, why));
 }
 
 /* lmtp_connect_addr - connect to explicit address */
@@ -358,13 +359,19 @@ LMTP_SESSION *lmtp_connect(const char *destination, VSTRING *why)
      * XXX Ad-hoc transport parsing and connection management. Some or all
      * should be moved away to a reusable library routine so that every
      * program benefits from it.
+     * 
+     * XXX Should transform destination into canonical form (unix:/path or
+     * inet:host:port before entering it into the connection cache. See also
+     * the connection cache lookup code in lmtp.c.
      */
     if (strncmp(destination, "unix:", 5) == 0)
-       return (lmtp_connect_unix(destination + 5, why));
+       return (lmtp_connect_unix(destination + 5, destination, why));
     if (strncmp(destination, "inet:", 5) == 0)
-       destination += 5;
-    dest_buf = lmtp_parse_destination(destination, def_service,
-                                     &host, &port);
+       dest_buf = lmtp_parse_destination(destination + 5, def_service,
+                                         &host, &port);
+    else
+       dest_buf = lmtp_parse_destination(destination, def_service,
+                                         &host, &port);
     if (msg_verbose)
        msg_info("%s: connecting to %s port %d", myname, host, ntohs(port));
     session = lmtp_connect_host(host, port, destination, why);
index 83d6200cc343be094328e4f7b0b48b8509a27dbf..e92df20c5a201d7b254e1a0151adf9538e2f7bfa 100644 (file)
@@ -138,6 +138,7 @@ master_listen.o: ../../include/vstring.h
 master_listen.o: ../../include/vbuf.h
 master_listen.o: ../../include/inet_addr_list.h
 master_listen.o: ../../include/set_eugid.h
+master_listen.o: ../../include/set_ugid.h
 master_listen.o: ../../include/mail_params.h
 master_listen.o: master.h
 master_proto.o: master_proto.c
index d7020ac42ab30f6791a21a6e3f60ef69c06506af..9b1d9f8a771b75f33d97a0676c108ee68ae1a44b 100644 (file)
@@ -53,6 +53,7 @@
 #include <stringops.h>
 #include <inet_addr_list.h>
 #include <set_eugid.h>
+#include <set_ugid.h>
 #include <iostuff.h>
 
 /* Global library. */
@@ -88,7 +89,7 @@ void    master_listen_init(MASTER_SERV *serv)
            LOCAL_LISTEN(serv->name, serv->max_proc > var_proc_limit ?
                         serv->max_proc : var_proc_limit, NON_BLOCKING);
        close_on_exec(serv->listen_fd[0], CLOSE_ON_EXEC);
-       set_eugid(getuid(), getgid());
+       set_ugid(getuid(), getgid());
        break;
 
        /*
@@ -98,7 +99,7 @@ void    master_listen_init(MASTER_SERV *serv)
        set_eugid(var_owner_uid, var_owner_gid);
        serv->listen_fd[0] = fifo_listen(serv->name, 0622, NON_BLOCKING);
        close_on_exec(serv->listen_fd[0], CLOSE_ON_EXEC);
-       set_eugid(getuid(), getgid());
+       set_ugid(getuid(), getgid());
        break;
 
        /*
index ca501e91873f678d7bd011844d1cb005a3cdda30..509a4a54d1ec9840baaa23d76f3b157362e42594 100644 (file)
@@ -152,7 +152,7 @@ static void master_sigchld(int sig)
 
 static void master_sigdeath(int sig)
 {
-    char   *myname = "master_sigsetup";
+    char   *myname = "master_sigdeath";
     struct sigaction action;
     pid_t   pid = getpid();
 
index ec00584bd40725bd1e7dbc53981832ecee10949e..404c4eda986d0606ea6febceafb868a7e3711ed9 100644 (file)
@@ -149,7 +149,7 @@ static void qmgr_active_defer(const char *queue_name, const char *queue_id,
 
     tbuf.actime = tbuf.modtime = event_time() + delay;
     path = mail_queue_path((VSTRING *) 0, queue_name, queue_id);
-    if (utime(path, &tbuf) < 0)
+    if (utime(path, &tbuf) < 0 && errno != ENOENT)
        msg_fatal("%s: update %s time stamps: %m", myname, path);
     if (mail_queue_rename(queue_id, queue_name, dest_queue)) {
        if (errno != ENOENT)
index 5e604cf1ae61b346a1f1887ab68570978f427d04..094838b77e2dcc8efc6f70f4bf755b66c9949e95 100644 (file)
@@ -770,8 +770,18 @@ static QMGR_PEER *qmgr_job_peer_select(QMGR_JOB *job)
      * Try reading in more recipients. Note that we do not try to read them
      * as soon as possible as that would decrease the chance of per-site
      * recipient grouping. We waited until reading more is really necessary.
-     */
-    if (message->rcpt_offset != 0 && message->rcpt_limit > message->rcpt_count) {
+     * 
+     * XXX Workaround for logic mismatch. The message->refcount test needs
+     * explanation. If the refcount is zero, it means that qmgr_active_done()
+     * is beeing completed asynchronously.  In such case, we can't read in
+     * more recipients as bad things would happen after qmgr_active_done()
+     * continues processing. Note that this results in the given job beeing
+     * stalled for some time, but fortunately this particular situation is so
+     * rare that it is not critical. Still we seek for better solution.
+     */
+    if (message->rcpt_offset != 0
+       && message->rcpt_limit > message->rcpt_count
+       && message->refcount > 0) {
        qmgr_message_realloc(message);
        if (HAS_ENTRIES(job))
            return (qmgr_peer_select(job));
index ee9154c6df6a303b0b091b87ed6c63a634c68800..cefb83716e6edee8868571a61aeb4678b8853653 100644 (file)
@@ -7,9 +7,7 @@
 /*     \fBpipe\fR [generic Postfix daemon options] command_attributes...
 /* DESCRIPTION
 /*     The \fBpipe\fR daemon processes requests from the Postfix queue
-/*     manager to deliver messages to external commands. Each delivery
-/*     request specifies a queue file, a sender address, a domain or host
-/*     to deliver to, and one or more recipients.
+/*     manager to deliver messages to external commands.
 /*     This program expects to be run from the \fBmaster\fR(8) process
 /*     manager.
 /*
 /*     as finished, or it informs the queue manager that delivery should
 /*     be tried again at a later time. Delivery problem reports are sent
 /*     to the \fBbounce\fR(8) or \fBdefer\fR(8) daemon as appropriate.
+/* SINGLE-RECIPIENT DELIVERY
+/* .ad
+/* .fi
+/*     Some external commands cannot handle more than one recipient
+/*     per delivery request. Examples of such transports are pagers,
+/*     fax machines, and so on.
+/*
+/*     To prevent Postfix from sending multiple recipients per delivery
+/*      request, specify 
+/*
+/* .ti +4
+/*     \fItransport\fB_destination_recipient_limit = 1\fR 
+/*
+/*      in the Postfix \fBmain.cf\fR file, where \fItransport\fR
+/*     is the name in the first column of the Postfix \fBmaster.cf\fR
+/*     entry for the pipe-based delivery transport.
 /* COMMAND ATTRIBUTE SYNTAX
 /* .ad
 /* .fi
 /*     This macro expands to the extension part of a recipient address.
 /*     For example, with an address \fIuser+foo@domain\fR the extension is
 /*     \fIfoo\fR.
+/* .sp
 /*     A command-line argument that contains \fB${\fBextension\fR}\fR expands
 /*     into as many command-line arguments as there are recipients.
 /* .IP \fB${\fBmailbox\fR}\fR
 /*     This macro expands to the complete local part of a recipient address.
 /*     For example, with an address \fIuser+foo@domain\fR the mailbox is
 /*     \fIuser+foo\fR.
+/* .sp
 /*     A command-line argument that contains \fB${\fBmailbox\fR}\fR
 /*     expands into as many command-line arguments as there are recipients.
 /* .IP \fB${\fBnexthop\fR}\fR
 /*     This macro expands to the next-hop hostname.
 /* .IP \fB${\fBrecipient\fR}\fR
 /*     This macro expands to the complete recipient address.
+/* .sp
 /*     A command-line argument that contains \fB${\fBrecipient\fR}\fR
 /*     expands into as many command-line arguments as there are recipients.
 /* .IP \fB${\fBsender\fR}\fR
 /*     This macro expands to the username part of a recipient address.
 /*     For example, with an address \fIuser+foo@domain\fR the username
 /*     part is \fIuser\fR.
+/* .sp
 /*     A command-line argument that contains \fB${\fBuser\fR}\fR expands
 /*     into as many command-line arguments as there are recipients.
 /* .RE
index c756c14ae4969441b75a0549d94816d182399ced..12af8b712bdd236f00c970c655c3d976965a957b 100644 (file)
@@ -80,6 +80,7 @@
 #include <vstream.h>
 #include <msg_vstream.h>
 #include <safe.h>
+#include <events.h>
 
 /* Global library. */
 
@@ -159,11 +160,12 @@ int     main(int argc, char **argv)
     /*
      * Kick the service.
      */
-    if (mail_trigger(class, service, request, strlen(request)) < 0) {
+    if (mail_trigger(class, service, request, strlen(request) + 1) < 0) {
        msg_warn("Cannot contact class %s service %s - perhaps the mail system is down",
                 class, service);
        exit(1);
     } else {
+       event_loop(-1);
        exit(0);
     }
 }
index ec00584bd40725bd1e7dbc53981832ecee10949e..404c4eda986d0606ea6febceafb868a7e3711ed9 100644 (file)
@@ -149,7 +149,7 @@ static void qmgr_active_defer(const char *queue_name, const char *queue_id,
 
     tbuf.actime = tbuf.modtime = event_time() + delay;
     path = mail_queue_path((VSTRING *) 0, queue_name, queue_id);
-    if (utime(path, &tbuf) < 0)
+    if (utime(path, &tbuf) < 0 && errno != ENOENT)
        msg_fatal("%s: update %s time stamps: %m", myname, path);
     if (mail_queue_rename(queue_id, queue_name, dest_queue)) {
        if (errno != ENOENT)
index e92c2d8dbfb82f757dd4cdb2de7f41c839389819..ace14ab0e1bd2c2912eb8ed93384d97c622c9142 100644 (file)
 /*     a brief connection to it and by writing the contents of the
 /*     named buffer.
 /*
+/*      The connection is closed by a background thread. Some kernels
+/*      cannot handle client-side disconnect before the server has
+/*      received the message.
+/*
 /*     Arguments:
 /* .IP service
 /*     Name of the communication endpoint.
@@ -45,6 +49,7 @@
 /* System library. */
 
 #include <sys_defs.h>
+#include <sys/socket.h>
 #include <unistd.h>
 #include <string.h>
 
 #include <msg.h>
 #include <connect.h>
 #include <iostuff.h>
+#include <mymalloc.h>
+#include <events.h>
 #include <trigger.h>
 
+struct inet_trigger {
+    int     fd;
+    char   *service;
+};
+
+/* inet_trigger_event - disconnect from peer */
+
+static void inet_trigger_event(int event, char *context)
+{
+    struct inet_trigger *ip = (struct inet_trigger *) context;
+    static char *myname = "inet_trigger_event";
+
+    /*
+     * Disconnect.
+     */
+    if (event == EVENT_TIME)
+       msg_warn("%s: read timeout for service %s", myname, ip->service);
+    if (close(ip->fd) < 0)
+       msg_warn("%s: close %s: %m", myname, ip->service);
+    myfree(ip->service);
+    myfree((char *) ip);
+}
+
+
 /* inet_trigger - wakeup INET-domain server */
 
 int     inet_trigger(const char *service, const char *buf, int len, int timeout)
 {
     char   *myname = "inet_trigger";
+    struct inet_trigger *ip;
     int     fd;
 
     if (msg_verbose > 1)
@@ -73,6 +105,9 @@ int     inet_trigger(const char *service, const char *buf, int len, int timeout)
            msg_warn("%s: connect to %s: %m", myname, service);
        return (-1);
     }
+    ip = (struct inet_trigger *) mymalloc(sizeof(*ip));
+    ip->fd = fd;
+    ip->service = mystrdup(service);
 
     /*
      * Write the request...
@@ -82,10 +117,10 @@ int     inet_trigger(const char *service, const char *buf, int len, int timeout)
            msg_warn("%s: write to %s: %m", myname, service);
 
     /*
-     * Disconnect.
+     * Wakeup when the peer disconnects, or when we lose patience.
      */
-    if (close(fd) < 0)
-       if (msg_verbose)
-           msg_warn("%s: close %s: %m", myname, service);
+    if (timeout > 0)
+       event_request_timer(inet_trigger_event, (char *) ip, timeout);
+    event_enable_read(fd, inet_trigger_event, (char *) ip);
     return (0);
 }
index 0173e9693f4a2e19eb9c5138b295c274eb4a291e..d119f074f578de6c7a39be39968e4a20d8d8443a 100644 (file)
@@ -67,8 +67,8 @@ void    rand_sleep(unsigned delay, unsigned variation)
      * Use the semi-crappy random number generator.
      */
     if (my_pid == 0)
-       srandom((my_pid = getpid()) ^ time((time_t *) 0));
-    usec = (delay - variation / 2) + variation * (double) random() / RAND_MAX;
+       srand((my_pid = getpid()) ^ time((time_t *) 0));
+    usec = (delay - variation / 2) + variation * (double) rand() / RAND_MAX;
     doze(usec);
 }
 
index d9d8464d0adf6fd41a6cf04799c13f338ad29f67..9ae9f6e3f49bafb9655aa44b2833d3197b61917b 100644 (file)
@@ -36,6 +36,7 @@
 
 /* Utility library. */
 
+#include "msg.h"
 #include "sane_accept.h"
 
 /* sane_accept - sanitize accept() error returns */
@@ -55,6 +56,10 @@ int     sane_accept(int sock, struct sockaddr * sa, SOCKADDR_SIZE *len)
        EWOULDBLOCK,
        0,
     };
+    static int accept_warn_errors[] = {
+       ECONNABORTED,
+       0,
+    };
     int     count;
     int     err;
     int     fd;
@@ -68,6 +73,13 @@ int     sane_accept(int sock, struct sockaddr * sa, SOCKADDR_SIZE *len)
      * XXX LINUX < 2.1 accept() wakes up before the three-way handshake is
      * complete, so it can fail with ECONNRESET and other "false alarm"
      * indications.
+     * 
+     * XXX FreeBSD 4.2-STABLE accept() returns ECONNABORTED when a UNIX-domain
+     * client has disconnected in the mean time. The data that was sent with
+     * connect() write() close() is lost, even though the write() and close()
+     * reported successful completion. This was fixed shortly before FreeBSD
+     * 4.3. However, other systems may make that same mistake again, so we're
+     * adding a special warning.
      */
     if ((fd = accept(sock, sa, len)) < 0) {
        for (count = 0; (err = accept_ok_errors[count]) != 0; count++) {
@@ -76,6 +88,13 @@ int     sane_accept(int sock, struct sockaddr * sa, SOCKADDR_SIZE *len)
                break;
            }
        }
+       for (count = 0; (err = accept_warn_errors[count]) != 0; count++) {
+           if (errno == err) {
+               msg_warn("accept: %m");
+               errno = EAGAIN;
+               break;
+           }
+       }
     }
     return (fd);
 }
index 585f392bf6eda4aaf13546a1c2d377add328f8bb..ee59b6c2859b73ce3859d4ac99a5154d32ece108 100644 (file)
 /*     stream_trigger() wakes up the named stream server by making
 /*     a brief connection to it and writing the named buffer.
 /*
+/*     The connection is closed by a background thread. Some kernels
+/*     cannot handle client-side disconnect before the server has
+/*     received the message.
+/*
 /*     Arguments:
 /* .IP service
 /*     Name of the communication endpoint.
 #include <msg.h>
 #include <connect.h>
 #include <iostuff.h>
+#include <mymalloc.h>
+#include <events.h>
 #include <trigger.h>
 
+struct stream_trigger {
+    int     fd;
+    char   *service;
+};
+
+/* stream_trigger_event - disconnect from peer */
+
+static void stream_trigger_event(int event, char *context)
+{
+    struct stream_trigger *sp = (struct stream_trigger *) context;
+    static char *myname = "stream_trigger_event";
+
+    /*
+     * Disconnect.
+     */
+    if (event == EVENT_TIME)
+       msg_warn("%s: read timeout for service %s", myname, sp->service);
+    if (close(sp->fd) < 0)
+       msg_warn("%s: close %s: %m", myname, sp->service);
+    myfree(sp->service);
+    myfree((char *) sp);
+}
+
 /* stream_trigger - wakeup stream server */
 
 int     stream_trigger(const char *service, const char *buf, int len, int timeout)
 {
     char   *myname = "stream_trigger";
+    struct stream_trigger *sp;
     int     fd;
 
     if (msg_verbose > 1)
@@ -72,6 +102,13 @@ int     stream_trigger(const char *service, const char *buf, int len, int timeou
        return (-1);
     }
 
+    /*
+     * Stash away context.
+     */
+    sp = (struct stream_trigger *) mymalloc(sizeof(*sp));
+    sp->fd = fd;
+    sp->service = mystrdup(service);
+
     /*
      * Write the request...
      */
@@ -80,10 +117,10 @@ int     stream_trigger(const char *service, const char *buf, int len, int timeou
            msg_warn("%s: write to %s: %m", myname, service);
 
     /*
-     * Disconnect.
+     * Wakeup when the peer disconnects, or when we lose patience.
      */
-    if (close(fd) < 0)
-       if (msg_verbose)
-           msg_warn("%s: close %s: %m", myname, service);
+    if (timeout > 0)
+       event_request_timer(stream_trigger_event, (char *) sp, timeout);
+    event_enable_read(fd, stream_trigger_event, (char *) sp);
     return (0);
 }
index 1b1d3df54ce75db4a71f9f3488a575157e010652..dbad4d71634544af64d2f3f2b7d5b64f3b5e2237 100644 (file)
@@ -329,10 +329,12 @@ extern int opterr;
 #define USE_STATVFS
 #define STATVFS_IN_SYS_STATVFS_H
 #define STRCASECMP_IN_STRINGS_H
+#if 0
 extern time_t time(time_t *);
 extern int seteuid(uid_t);
 extern int setegid(gid_t);
 extern int initgroups(const char *, int);
+#endif
 
 #endif
 
index d0f03d6c78fd53552ec3ec17a4bba13c704c82a1..498a6c07a0f96aa2e19916c52175cd84723eca54 100644 (file)
 /*     unix_trigger() wakes up the named UNIX-domain server by making
 /*     a brief connection to it and writing the named buffer.
 /*
+/*     The connection is closed by a background thread. Some kernels
+/*     cannot handle client-side disconnect before the server has
+/*     received the message.
+/*
 /*     Arguments:
 /* .IP service
 /*     Name of the communication endpoint.
@@ -43,6 +47,7 @@
 /* System library. */
 
 #include <sys_defs.h>
+#include <sys/socket.h>
 #include <unistd.h>
 #include <string.h>
 
 #include <msg.h>
 #include <connect.h>
 #include <iostuff.h>
+#include <mymalloc.h>
+#include <events.h>
 #include <trigger.h>
 
+struct unix_trigger {
+    int     fd;
+    char   *service;
+};
+
+/* unix_trigger_event - disconnect from peer */
+
+static void unix_trigger_event(int event, char *context)
+{
+    struct unix_trigger *up = (struct unix_trigger *) context;
+    static char *myname = "unix_trigger_event";
+
+    /*
+     * Disconnect.
+     */
+    if (event == EVENT_TIME)
+       msg_warn("%s: read timeout for service %s", myname, up->service);
+    if (close(up->fd) < 0)
+       msg_warn("%s: close %s: %m", myname, up->service);
+    myfree(up->service);
+    myfree((char *) up);
+}
+
 /* unix_trigger - wakeup UNIX-domain server */
 
 int     unix_trigger(const char *service, const char *buf, int len, int timeout)
 {
     char   *myname = "unix_trigger";
+    struct unix_trigger *up;
     int     fd;
 
     if (msg_verbose > 1)
@@ -72,6 +103,13 @@ int     unix_trigger(const char *service, const char *buf, int len, int timeout)
        return (-1);
     }
 
+    /*
+     * Stash away context.
+     */
+    up = (struct unix_trigger *) mymalloc(sizeof(*up));
+    up->fd = fd;
+    up->service = mystrdup(service);
+
     /*
      * Write the request...
      */
@@ -80,10 +118,10 @@ int     unix_trigger(const char *service, const char *buf, int len, int timeout)
            msg_warn("%s: write to %s: %m", myname, service);
 
     /*
-     * Disconnect.
+     * Wakeup when the peer disconnects, or when we lose patience.
      */
-    if (close(fd) < 0)
-       if (msg_verbose)
-           msg_warn("%s: close %s: %m", myname, service);
+    if (timeout > 0)
+       event_request_timer(unix_trigger_event, (char *) up, timeout);
+    event_enable_read(fd, unix_trigger_event, (char *) up);
     return (0);
 }