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 :
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,
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.
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.
+
+20010313
+
+ Bugfix: the RFC 822 untokenizer quoted newlines inside
+ comments. File: global/tok822_parse.c.
+
+20010316
+
+ Cleanup: removed an extraneous warning when a queue file
+ write error happened.
+
+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. This
+ fix changes the destination to logfile name mapping, so
+ that you need to populate the new files with "sendmail -q".
+ The old files go away automatically. File: flush/flush.c.
+
+20010327
+
+ Speed up mailq (sendmail -bp) display by flushing output
+ after each file. File: showq/showq.c.
+
+ Portability: missing string.h includes, %p wants (void *),
+ Lamont Jones, HP.
+
+20010328
+
+ Bugfix: swapped logic caused cleanup to stall when the
+ queue file size exceeded the file size limit by less than
+ one the VSTREAM buffer size, so that the "file too big"
+ was detected after flushing the last queue file record.
+ File: cleanup/cleanup.c.
+
+20010329
+
+ Portability: workaround for missing prototype problem in
+ dict_ldap.c. This module should move to the global directory,
+ because it depends on Postfix main.cf parameter information.
and watch your syslog file for any error messages.
+ % egrep '(reject|warning|error|fatal|panic):' /some/log/file
+
+Typical logfile names are: /var/log/maillog or /var/log/syslog.
+See /etc/syslog.conf for actual logfile names.
+
When it is run for the first time, the Postfix startup shell script
will create a bunch of subdirectories below the Postfix spool
directory.
and watch your syslog file for any error messages.
+ % egrep '(reject|warning|error|fatal|panic):' /some/log/file
+
+Typical logfile names are: /var/log/maillog or /var/log/syslog.
+See /etc/syslog.conf for actual logfile names.
+
When it is run for the first time, the Postfix startup shell script
will create a bunch of subdirectories below the Postfix spool
directory.
and watch the syslog file for any complaints from the mail system.
+ % egrep '(reject|warning|error|fatal|panic):' /some/log/file
+
+Typical logfile names are: /var/log/maillog or /var/log/syslog.
+See /etc/syslog.conf for actual logfile names.
+
When it is run for the first time, the Postfix startup shell script
will create a bunch of subdirectories below the Postfix spool
directory.
# postfix check
# egrep '(reject|warning|error|fatal|panic):' /some/log/file
+Typical logfile names are: /var/log/maillog or /var/log/syslog.
+See /etc/syslog.conf for actual logfile names.
+
+The first line (postfix check) causes Postfix to report file
+permission/ownership discrepancies.
+
The second line looks for problem reports from the mail software,
and reports how effective the anti-relay and anti-UCE blocks are.
We've written code to add a mysql map type. It utilizes the mysql
client library, which can be obtained from:
- http://www.tcx.se/download.html
+ http://www.mysql.com/downloads/
+ http://sourceforge.net/projects/mysql/
In order to build postfix with mysql map support, you will need to add
-DHAS_MYSQL and -I for the directory containing the mysql headers, and
-This is the first official Postfix release that is not called BETA.
-May it help the people who cannot get BETA software past their
-management.
-
-Release 20010228 differs from snapshot 20010228 in that the virtual
-delivery agent and nqmgr queue manager are left out. That software
-will become part of the official release when it has not changed
-in a while.
+Release 20010228 is the first official Postfix release that is not
+called BETA. May it help the people who cannot get BETA software
+past their management.
In the text below, incompatible changes are labeled with the Postfix
version that introduced the change. If you upgrade from a later
Postfix version, then you do not have to worry about that particular
incompatibility.
+Major incompatible changes with release-20010228 Patch 01
+=========================================================
+
+This release changes the names of the "fast ETRN" logfiles with
+delayed mail per destination. These files are maintained by the
+Postfix "fast flush" daemon. The old scheme failed with addresses
+of the form user@[ip.address] and user@a.domain.name. In order to
+populate the new "fast ETRN" logfiles, execute the command "sendmail
+-q". The old "fast ETRN" logfiles go away by themselves (default:
+after 7 days).
+
Major incompatible changes with release-20010228
================================================
permit_mynetworks permit_sasl_authenticated ...
In /usr/local/lib/sasl/smtpd.conf you need to specify how the server
-should validate client passwords. For example:
+should validate client passwords.
+
+In order to authenticate against the UNIX password database, try:
+
+ /usr/local/lib/sasl/smtpd.conf:
+ pwcheck_method: pwcheck
+
+The pwcheck daemon is contained in the cyrus-sasl source tarball.
+
+In order to authenticate against SASL's own password database:
/usr/local/lib/sasl/smtpd.conf:
pwcheck_method: sasldb
EXAMPLE: saslpasswd -c -u `postconf -h myhostname` exampleuser
-Instead of the SASL-specific password file you can configure the
-Postfix SMTP server to validate client passwords against the UNIX
-shadow password file:
-
- /usr/local/lib/sasl/smtpd.conf:
- pwcheck_method: shadow
-
-However this requires that Postfix has read access to the UNIX shadow
-password file, which is normally readable only by root. Shadow
-password support has been found to work for Solaris 2.7 and RedHat
-6.1 but not with FreeBSD 3.4.
+To run software chrooted with SASL support is an interesting
+exercise. It probably is not worth the trouble.
-To run software chrooted with SASL support is an interesting exercise.
-This is one of the many problems with the present SASL support.
+Testing SASL authentication in the Postfix SMTP server
+======================================================
To test the whole mess, connect to the SMTP server, and you should
be able to have a conversation like this:
# 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.
#
# 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
# $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
# 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
mkdir etc
cp /etc/services etc
+mkdir -p usr/lib
+cp /usr/lib/tztab usr/lib
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.
<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>
<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>
<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>
</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>
<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
<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>
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>
<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.
<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>
<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
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>> (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
- > Prepend > 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)
+ > Prepend > 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)
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
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 <<b>sysexits.h</b>>.
- 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>
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>
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>
Yorktown Heights, NY 10598, USA
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
4
<dt>Syntax:
<dd>Specify a list of zero or more lookup tables. Whenever a header
-matches a table, a REJECT result means reject the message, and a
-SKIP result means delete the header from the message.
+matches a table, a REJECT result means reject the message, and an
+IGNORE result means delete the header from the message.
<p>
.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
.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
.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.
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
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
# 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
# .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
if (CLEANUP_OUT_OK(state) == 0 && type > 0) {
if ((state->errs & CLEANUP_STAT_CONT) == 0)
msg_warn("%s: skipping further client input", state->queue_id);
- while ((type = rec_get(src, buf, 0)) > 0
- && type != REC_TYPE_END)
+ while (type != REC_TYPE_END
+ && (type = rec_get(src, buf, 0)) > 0)
/* void */ ;
}
* 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;
flush.o: ../../include/vstring.h
flush.o: ../../include/vstring_vstream.h
flush.o: ../../include/myflock.h
-flush.o: ../../include/valid_hostname.h
flush.o: ../../include/htable.h
flush.o: ../../include/dict.h
flush.o: ../../include/argv.h
#include <stdlib.h>
#include <utime.h>
#include <errno.h>
+#include <ctype.h>
+#include <string.h>
/* Utility library. */
#include <vstring.h>
#include <vstring_vstream.h>
#include <myflock.h>
-#include <valid_hostname.h>
#include <htable.h>
#include <dict.h>
#include <scan_dir.h>
/* Application-specific. */
/*
- * Tunable parameters.
+ * Tunable parameters. The fast_flush_domains parameter is not defined here,
+ * because it is also used by the global library, and therefore is owned by
+ * the library.
*/
int var_fflush_refresh;
int var_fflush_purge;
/*
* Some hard-wired policy: how many queue IDs we remember while we're
- * flushing a logfile.
+ * flushing a logfile (duplicate elimination). Sites with 1000+ emails
+ * queued should arrange for permanent connectivity.
*/
#define FLUSH_DUP_FILTER_SIZE 10000 /* graceful degradation */
/*
* Silly little macros.
*/
-
#define STR(x) vstring_str(x)
#define STREQ(x,y) (strcmp(x,y) == 0)
+ /*
+ * Forward declarations resulting from breaking up routines according to
+ * name space: domain names 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);
+
+ /*
+ * Mask characters that could upset the name-to-queue-file mapping code.
+ */
+ 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)
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);
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;
+
+ /*
+ * Sanity check.
+ */
+ if (!mail_queue_id_ok(path))
+ return (FLUSH_STAT_BAD);
+
/*
* 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
* 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
+ * Append the queue ID. With 15 bits of microsecond time, a queue ID is
* not recycled often enough for false hits to be a problem. If it does,
* then we could add other signature information, such as the file size
* in bytes.
*/
vstream_fprintf(log, "%s\n", queue_id);
+ if (vstream_fflush(log))
+ msg_warn("write fast flush logfile %s: %m", path);
/*
* 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);
}
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;
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.
+ * Sanity check.
*/
- if (flush_policy_ok(site) == 0)
- return (mail_flush_deferred());
+ if (!mail_queue_id_ok(path))
+ return (FLUSH_STAT_BAD);
/*
* 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);
}
* 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
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);
}
} 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);
* 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));
}
{
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));
if (st.st_size == 0) {
if (st.st_mtime + var_fflush_purge < event_time()) {
if (unlink(STR(path)) < 0)
- msg_warn("remove %s: %m", STR(path));
+ msg_warn("remove logfile %s: %m", STR(path));
else if (msg_verbose)
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);
* This routine runs whenever a client connects to the UNIX-domain socket
* dedicated to the fast flush service. What we see below is a little
* protocol to (1) read a request from the client (the name of the site)
- * and (2) acknowledge that we have received the request. Since the site
- * name maps onto the file system, make sure the site name is a valid
- * SMTP hostname.
+ * and (2) acknowledge that we have received the request.
*
* All connection-management stuff is handled by the common code in
* single_server.c.
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)
* Version of this program.
*/
#define VAR_MAIL_VERSION "mail_version"
-#define DEF_MAIL_VERSION "Release-20010228"
+#define DEF_MAIL_VERSION "Postfix-20010228-pl01"
extern char *var_mail_version;
/* LICENSE
#include <sys_defs.h>
#include <unistd.h>
#include <errno.h>
+#include <string.h>
/* Utility library. */
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, '"');
#include <unistd.h>
#include <vstream.h>
-#include <vstring_vstream.h>
+#include <readlline.h>
/* tok822_print - display token */
TOK822 *list;
VSTRING *buf = vstring_alloc(100);
- while (vstring_fgets_nonl(buf, VSTREAM_IN)) {
+ while (readlline(buf, VSTREAM_IN, (int *) 0, READLL_KEEPNL)) {
+ while (VSTRING_LEN(buf) > 0 && vstring_end(buf)[-1] == '\n') {
+ vstring_end(buf)[-1] = 0;
+ vstring_truncate(buf, VSTRING_LEN(buf) - 1);
+ }
if (!isatty(vstream_fileno(VSTREAM_IN)))
vstream_printf(">>>%s<<<\n\n", vstring_str(buf));
list = tok822_parse(vstring_str(buf));
wietse@[stuff
wietse@["stuff]
named group: foo@bar, baz@barf;
+wietse@foo (wietse
+ venema)
named group: foo@bar,
baz@barf;
+>>>wietse@foo (wietse
+ venema)<<<
+
+Parse tree:
+ address
+ atom "wietse"
+ OP "@"
+ atom "foo"
+ comment
+ text "wietse
+ venema"
+
+Internalized:
+wietse@foo (wietse
+ venema)
+
+Externalized, no newlines inserted:
+wietse@foo (wietse
+ venema)
+
+Externalized, newlines inserted:
+wietse@foo (wietse
+ venema)
+
/*
* 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);
/* 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";
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 */
* 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);
#include <sys_defs.h>
#include <unistd.h>
+#include <string.h>
/* Utility library. */
static void master_sigdeath(int sig)
{
- char *myname = "master_sigsetup";
+ char *myname = "master_sigdeath";
struct sigaction action;
pid_t pid = getpid();
}
if (proc->serv != serv)
msg_panic("%s: pointer corruption: %p != %p",
- myname, (char *) proc->serv, (char *) serv);
+ myname, (void *) proc->serv, (void *) serv);
/*
* Update our idea of the child process status. Allow redundant status
/* \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
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)
} else if (errno != ENOENT)
msg_fatal("open %s %s: %m", *queue, id);
file_count++;
+ vstream_fflush(client);
}
vstream_fflush(client);
}
#include "dict.h"
#include "dict_ldap.h"
+/* AAARGH!! */
+
+#include "../global/mail_conf.h"
+
/*
* Structure containing all the configuration parameters for a given
* LDAP source, plus its connection handle.
#include <stdarg.h>
#include <errno.h>
#include <syslog.h>
+#include <string.h>
/* Application-specific. */
* 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);
}
#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
#if defined(IRIX5)
#define MISSING_USLEEP
+#endif
+
+#if defined(IRIX6)
+#define HAS_POSIX_REGEXP
#endif
/*
if ((wp = watchdog_curr) == 0)
msg_panic("%s: no instance", myname);
if (msg_verbose)
- msg_info("%s: %p %d", myname, (char *) wp, wp->trip_run);
+ msg_info("%s: %p %d", myname, (void *) wp, wp->trip_run);
if (++(wp->trip_run) < WATCHDOG_STEPS) {
alarm(wp->timeout);
} else {
if (sigaction(SIGALRM, &sig_action, &wp->saved_action) < 0)
msg_fatal("%s: sigaction(SIGALRM): %m", myname);
if (msg_verbose)
- msg_info("%s: %p %d", myname, (char *) wp, timeout);
+ msg_info("%s: %p %d", myname, (void *) wp, timeout);
return (watchdog_curr = wp);
}
alarm(wp->saved_time);
myfree((char *) wp);
if (msg_verbose)
- msg_info("%s: %p", myname, (char *) wp);
+ msg_info("%s: %p", myname, (void *) wp);
}
/* watchdog_start - enable watchdog timer */
wp->trip_run = 0;
alarm(wp->timeout);
if (msg_verbose)
- msg_info("%s: %p", myname, (char *) wp);
+ msg_info("%s: %p", myname, (void *) wp);
}
/* watchdog_stop - disable watchdog timer */
msg_panic("%s: wrong watchdog instance", myname);
alarm(0);
if (msg_verbose)
- msg_info("%s: %p", myname, (char *) wp);
+ msg_info("%s: %p", myname, (void *) wp);
}
/* watchdog_pat - pat the dog so it stays quiet */
if (watchdog_curr)
watchdog_curr->trip_run = 0;
if (msg_verbose)
- msg_info("%s: %p", myname, (char *) watchdog_curr);
+ msg_info("%s: %p", myname, (void *) watchdog_curr);
}
#ifdef TEST