mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-29 13:18:12 +00:00
snapshot-20010323
This commit is contained in:
parent
f9eee68f7a
commit
c70c1482d6
@ -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
|
you create no temporary files. Each temporary file adds another
|
||||||
factor to the performance loss.
|
factor to the performance loss.
|
||||||
|
|
||||||
We will set up a content filtering program listening on localhost
|
We will set up a content filtering program that receives SMTP mail
|
||||||
port 10025 that receives mail via the SMTP protocol, and that
|
via localhost port 10025, and that submits SMTP mail back into
|
||||||
submits mail back into Postfix via localhost port 10026.
|
Postfix via localhost port 10026.
|
||||||
|
|
||||||
..................................
|
..................................
|
||||||
: Postfix :
|
: Postfix :
|
||||||
@ -162,7 +162,7 @@ transport table. The content filtering records are added by the
|
|||||||
smtpd and pickup servers.
|
smtpd and pickup servers.
|
||||||
|
|
||||||
When a queue file has content filtering information, the queue
|
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.
|
regardless of its final destination.
|
||||||
|
|
||||||
The content filter can be set up with the Postfix spawn service,
|
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
|
instead of Postfix, then you must run your filter as a stand-alone
|
||||||
program.
|
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
|
The /some/where/filter command is most likely a PERL script. PERL
|
||||||
has modules that make talking SMTP easy. The command-line specifies
|
has modules that make talking SMTP easy. The command-line specifies
|
||||||
that mail should be sent back into Postfix via localhost port 10026.
|
that mail should be sent back into Postfix via localhost port 10026.
|
||||||
|
@ -4960,3 +4960,31 @@ Apologies for any names omitted.
|
|||||||
Code cleanup: some queue/transport operations need to be
|
Code cleanup: some queue/transport operations need to be
|
||||||
moved, after the code cleanup of the recipient/concurrency
|
moved, after the code cleanup of the recipient/concurrency
|
||||||
limit handling. Patrik Rak. Files: *qmgr/qmgr_message.c.
|
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.
|
||||||
|
@ -249,6 +249,8 @@ or, if you feel nostalgic, use the Postfix sendmail command:
|
|||||||
|
|
||||||
and watch your syslog file for any error messages.
|
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
|
When it is run for the first time, the Postfix startup shell script
|
||||||
will create a bunch of subdirectories below the Postfix spool
|
will create a bunch of subdirectories below the Postfix spool
|
||||||
directory.
|
directory.
|
||||||
@ -290,6 +292,8 @@ or, if you feel nostalgic, use the Postfix sendmail program:
|
|||||||
|
|
||||||
and watch your syslog file for any error messages.
|
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
|
When it is run for the first time, the Postfix startup shell script
|
||||||
will create a bunch of subdirectories below the Postfix spool
|
will create a bunch of subdirectories below the Postfix spool
|
||||||
directory.
|
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.
|
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
|
When it is run for the first time, the Postfix startup shell script
|
||||||
will create a bunch of subdirectories below the Postfix spool
|
will create a bunch of subdirectories below the Postfix spool
|
||||||
directory.
|
directory.
|
||||||
|
@ -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
|
LINUX SYSLOGD PERFORMANCE
|
||||||
=========================
|
=========================
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@
|
|||||||
# octets separated by ".".
|
# octets separated by ".".
|
||||||
#
|
#
|
||||||
# ACTIONS
|
# ACTIONS
|
||||||
# [45]XX text
|
# [45]NN text
|
||||||
# Reject the address etc. that matches the pattern,
|
# Reject the address etc. that matches the pattern,
|
||||||
# and respond with the numerical code and text.
|
# and respond with the numerical code and text.
|
||||||
#
|
#
|
||||||
@ -86,7 +86,7 @@
|
|||||||
# OK Accept the address etc. that matches the pattern.
|
# OK Accept the address etc. that matches the pattern.
|
||||||
#
|
#
|
||||||
# restriction...
|
# restriction...
|
||||||
# Apply the named UCE restriction (permit, reject,
|
# Apply the named UCE restriction(s) (permit, reject,
|
||||||
# reject_unauth_destination, and so on).
|
# reject_unauth_destination, and so on).
|
||||||
#
|
#
|
||||||
# REGULAR EXPRESSION TABLES
|
# REGULAR EXPRESSION TABLES
|
||||||
|
@ -226,14 +226,12 @@ mail_owner = postfix
|
|||||||
# $inet_interfaces. If this parameter is defined, then the SMTP server
|
# $inet_interfaces. If this parameter is defined, then the SMTP server
|
||||||
# will reject mail for unknown local users.
|
# will reject mail for unknown local users.
|
||||||
#
|
#
|
||||||
# The local_recipient_maps parameter accepts tables with bare usernames
|
# If you use the default Postfix local delivery agent for local
|
||||||
# such as unix:passwd.byname and alias maps.
|
# delivery, uncomment the definition below.
|
||||||
#
|
#
|
||||||
# Beware: if the Postfix SMTP server runs chrooted, you may have to
|
# Beware: if the Postfix SMTP server runs chrooted, you may have to
|
||||||
# copy the passwd database into the jail. This is system dependent.
|
# copy the passwd (not shadow) 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.
|
|
||||||
#
|
#
|
||||||
#local_recipient_maps = $alias_maps unix:passwd.byname
|
#local_recipient_maps = $alias_maps unix:passwd.byname
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ case $daemon_directory in
|
|||||||
exit 1
|
exit 1
|
||||||
esac
|
esac
|
||||||
|
|
||||||
LOGGER="$command_directory/postlog -t postfix-script"
|
LOGGER="$command_directory/postlog -t $MAIL_LOGTAG/postfix-script"
|
||||||
INFO="$LOGGER -p info"
|
INFO="$LOGGER -p info"
|
||||||
WARN="$LOGGER -p warn"
|
WARN="$LOGGER -p warn"
|
||||||
ERROR="$LOGGER -p error"
|
ERROR="$LOGGER -p error"
|
||||||
|
@ -35,7 +35,7 @@ case $daemon_directory in
|
|||||||
exit 1
|
exit 1
|
||||||
esac
|
esac
|
||||||
|
|
||||||
LOGGER="$command_directory/postlog -t postfix-script"
|
LOGGER="$command_directory/postlog -t $MAIL_LOGTAG/postfix-script"
|
||||||
INFO="$LOGGER -p info"
|
INFO="$LOGGER -p info"
|
||||||
WARN="$LOGGER -p warn"
|
WARN="$LOGGER -p warn"
|
||||||
ERROR="$LOGGER -p error"
|
ERROR="$LOGGER -p error"
|
||||||
|
@ -4,6 +4,16 @@
|
|||||||
# This file contains example settings of Postfix configuration
|
# This file contains example settings of Postfix configuration
|
||||||
# parameters that control compatibility with broken software.
|
# 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
|
# The ignore_mx_lookup_error parameter controls what happens when a
|
||||||
# name server fails to respond to an MX lookup request. By default,
|
# name server fails to respond to an MX lookup request. By default,
|
||||||
# Postfix defers delivery and tries again after some delay. Specify
|
# Postfix defers delivery and tries again after some delay. Specify
|
||||||
|
@ -360,6 +360,18 @@ relocated_maps =
|
|||||||
#
|
#
|
||||||
syslog_facility = mail
|
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
|
# The trigger_timeout parameter limits the time to send a trigger to
|
||||||
# a Postfix daemon. This prevents programs from getting stuck when the
|
# a Postfix daemon. This prevents programs from getting stuck when the
|
||||||
# mail system is under heavy load.
|
# mail system is under heavy load.
|
||||||
|
@ -87,7 +87,7 @@ ACCESS(5) ACCESS(5)
|
|||||||
octets separated by ".".
|
octets separated by ".".
|
||||||
|
|
||||||
<b>ACTIONS</b>
|
<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,
|
Reject the address etc. that matches the pattern,
|
||||||
and respond with the numerical code and text.
|
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.
|
<b>OK</b> Accept the address etc. that matches the pattern.
|
||||||
|
|
||||||
<i>restriction...</i>
|
<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>reject</b><i>_</i><b>unauth</b><i>_</i><b>destination</b>, and so on).
|
||||||
|
|
||||||
<b>REGULAR</b> <b>EXPRESSION</b> <b>TABLES</b>
|
<b>REGULAR</b> <b>EXPRESSION</b> <b>TABLES</b>
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
|
|
||||||
<li><a href="#poppers">POP or IMAP problems</a>
|
<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="#warnings">Postfix warnings and error messages</a>
|
||||||
|
|
||||||
<li><a href="#example_config">Example configurations</a>
|
<li><a href="#example_config">Example configurations</a>
|
||||||
@ -74,8 +76,18 @@
|
|||||||
|
|
||||||
<li><a href="#noalias">What does "fatal: open database /etc/aliases.db" mean?</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="#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>
|
</ul>
|
||||||
|
|
||||||
<p>
|
<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="#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>
|
</ul>
|
||||||
|
|
||||||
<a name="local_delivery"><h3>Local (non-virtual) delivery</h3>
|
<a name="local_delivery"><h3>Local (non-virtual) delivery</h3>
|
||||||
@ -311,6 +325,36 @@ mailbox</a>
|
|||||||
|
|
||||||
</ul>
|
</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>
|
<hr>
|
||||||
|
|
||||||
<a name="poppers"><h3>POP or IMAP problems</h3>
|
<a name="poppers"><h3>POP or IMAP problems</h3>
|
||||||
@ -970,6 +1014,30 @@ PERMISSION_SECURITY="secure local"
|
|||||||
|
|
||||||
<hr>
|
<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>
|
<a name="moby-freebsd"><h3>Running hundreds of Postfix processes on FreeBSD</h3></a>
|
||||||
|
|
||||||
With hundreds of Postfix processes, the kernel will eventually
|
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>
|
<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.
|
(<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
|
On the other hand, when I telnet to the the POP port (<tt>telnet
|
||||||
hostname 110</tt>) the response comes with no delay.
|
hostname 110</tt>) the response comes with no delay.
|
||||||
|
|
||||||
<p>
|
</blockquote>
|
||||||
|
|
||||||
<dt>Answer:
|
|
||||||
|
|
||||||
<dd>
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
||||||
The fix is to properly configure the naming service. If you can't
|
Answer:
|
||||||
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.
|
|
||||||
|
|
||||||
</dl>
|
<blockquote>
|
||||||
|
|
||||||
|
You have a name service problem.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
<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>
|
<hr>
|
||||||
|
|
||||||
@ -1733,6 +1810,35 @@ use the command <b>postconf mail_version</b>.
|
|||||||
Execute the command <b>postfix reload</b> to make the change
|
Execute the command <b>postfix reload</b> to make the change
|
||||||
effective immediately.
|
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>
|
<hr>
|
||||||
|
|
||||||
<a name="root"> <h3>Root's mail is delivered to nobody</h3>
|
<a name="root"> <h3>Root's mail is delivered to nobody</h3>
|
||||||
@ -2300,6 +2406,11 @@ virtual domain.
|
|||||||
|
|
||||||
<p>
|
<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">
|
Be sure to follow instructions in the <a href="virtual.5.html">
|
||||||
virtual</a> manual page.
|
virtual</a> manual page.
|
||||||
|
|
||||||
@ -2909,6 +3020,36 @@ href="http://www.isc.org/"> http://www.isc.org/</a>.
|
|||||||
|
|
||||||
<hr>
|
<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
|
<a href="index.html">Up one level</a> | Postfix FAQ
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
@ -13,11 +13,9 @@ PIPE(8) PIPE(8)
|
|||||||
|
|
||||||
<b>DESCRIPTION</b>
|
<b>DESCRIPTION</b>
|
||||||
The <b>pipe</b> daemon processes requests from the Postfix queue
|
The <b>pipe</b> daemon processes requests from the Postfix queue
|
||||||
manager to deliver messages to external commands. Each
|
manager to deliver messages to external commands. This
|
||||||
delivery request specifies a queue file, a sender address,
|
program expects to be run from the <a href="master.8.html"><b>master</b>(8)</a> process man-
|
||||||
a domain or host to deliver to, and one or more recipi-
|
ager.
|
||||||
ents. This program expects to be run from the <a href="master.8.html"><b>master</b>(8)</a>
|
|
||||||
process manager.
|
|
||||||
|
|
||||||
The <b>pipe</b> daemon updates queue files and marks recipients
|
The <b>pipe</b> daemon updates queue files and marks recipients
|
||||||
as finished, or it informs the queue manager that delivery
|
as finished, or it informs the queue manager that delivery
|
||||||
@ -25,6 +23,20 @@ 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
|
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.
|
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>
|
<b>COMMAND</b> <b>ATTRIBUTE</b> <b>SYNTAX</b>
|
||||||
The external command attributes are given in the <b>master.cf</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
|
file at the end of a service definition. The syntax is as
|
||||||
@ -47,18 +59,6 @@ PIPE(8) PIPE(8)
|
|||||||
the envelope sender address.
|
the envelope sender address.
|
||||||
|
|
||||||
<b>.</b> Prepend <b>.</b> to lines starting with "<b>.</b>". This
|
<b>.</b> Prepend <b>.</b> to lines starting with "<b>.</b>". This
|
||||||
is needed by, for example, <b>BSMTP</b> software.
|
|
||||||
|
|
||||||
> 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
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -71,6 +71,18 @@ PIPE(8) PIPE(8)
|
|||||||
PIPE(8) PIPE(8)
|
PIPE(8) PIPE(8)
|
||||||
|
|
||||||
|
|
||||||
|
is needed by, for example, <b>BSMTP</b> software.
|
||||||
|
|
||||||
|
> 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
|
||||||
privileges of the mail system owner. If <i>groupname</i>
|
privileges of the mail system owner. If <i>groupname</i>
|
||||||
is specified, the corresponding group ID is used
|
is specified, the corresponding group ID is used
|
||||||
instead of the group ID of <i>username</i>.
|
instead of the group ID of <i>username</i>.
|
||||||
@ -101,7 +113,9 @@ PIPE(8) PIPE(8)
|
|||||||
This macro expands to the extension part of
|
This macro expands to the extension part of
|
||||||
a recipient address. For example, with an
|
a recipient address. For example, with an
|
||||||
address <i>user+foo@domain</i> the extension is
|
address <i>user+foo@domain</i> the extension is
|
||||||
<i>foo</i>. A command-line argument that contains
|
<i>foo</i>.
|
||||||
|
|
||||||
|
A command-line argument that contains
|
||||||
<b>${extension</b>} expands into as many command-
|
<b>${extension</b>} expands into as many command-
|
||||||
line arguments as there are recipients.
|
line arguments as there are recipients.
|
||||||
|
|
||||||
@ -109,22 +123,8 @@ PIPE(8) PIPE(8)
|
|||||||
This macro expands to the complete local
|
This macro expands to the complete local
|
||||||
part of a recipient address. For example,
|
part of a recipient address. For example,
|
||||||
with an address <i>user+foo@domain</i> the mailbox
|
with an address <i>user+foo@domain</i> the mailbox
|
||||||
is <i>user+foo</i>. A command-line argument that
|
is <i>user+foo</i>.
|
||||||
contains <b>${mailbox</b>} expands into as many
|
|
||||||
command-line arguments as there are recipi-
|
|
||||||
ents.
|
|
||||||
|
|
||||||
<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,6 +137,23 @@ PIPE(8) PIPE(8)
|
|||||||
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.
|
address.
|
||||||
|
|
||||||
<b>${size</b>}
|
<b>${size</b>}
|
||||||
@ -148,7 +165,9 @@ PIPE(8) PIPE(8)
|
|||||||
This macro expands to the username part of a
|
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
|
address <i>user+foo@domain</i> the username part is
|
||||||
<i>user</i>. A command-line argument that contains
|
<i>user</i>.
|
||||||
|
|
||||||
|
A command-line argument that contains
|
||||||
<b>${user</b>} expands into as many command-line
|
<b>${user</b>} expands into as many command-line
|
||||||
arguments as there are recipients.
|
arguments as there are recipients.
|
||||||
|
|
||||||
@ -172,6 +191,18 @@ PIPE(8) PIPE(8)
|
|||||||
|
|
||||||
<b>CONFIGURATION</b> <b>PARAMETERS</b>
|
<b>CONFIGURATION</b> <b>PARAMETERS</b>
|
||||||
The following <b>main.cf</b> parameters are especially relevant
|
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
|
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>
|
details and for default values. Use the <b>postfix</b> <b>reload</b>
|
||||||
command after a configuration change.
|
command after a configuration change.
|
||||||
@ -191,18 +222,6 @@ PIPE(8) PIPE(8)
|
|||||||
|
|
||||||
<i>transport_</i><b>destination</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b>
|
<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
|
Limit the number of parallel deliveries to the same
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
3
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PIPE(8) PIPE(8)
|
|
||||||
|
|
||||||
|
|
||||||
destination, for delivery via the named <i>transport</i>.
|
destination, for delivery via the named <i>transport</i>.
|
||||||
The default limit is taken from the <b>default</b><i>_</i><b>desti-</b>
|
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
|
<b>nation</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b> parameter. The limit is
|
||||||
@ -239,25 +258,6 @@ PIPE(8) PIPE(8)
|
|||||||
Yorktown Heights, NY 10598, USA
|
Yorktown Heights, NY 10598, USA
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
4
|
4
|
||||||
|
@ -69,7 +69,7 @@ address is a sequence of one or more octets separated by ".".
|
|||||||
.nf
|
.nf
|
||||||
.ad
|
.ad
|
||||||
.fi
|
.fi
|
||||||
.IP "[\fB45\fR]\fIXX text\fR"
|
.IP "[\fB45\fR]\fINN text\fR"
|
||||||
Reject the address etc. that matches the pattern, and respond with
|
Reject the address etc. that matches the pattern, and respond with
|
||||||
the numerical code and text.
|
the numerical code and text.
|
||||||
.IP \fBREJECT\fR
|
.IP \fBREJECT\fR
|
||||||
@ -78,7 +78,7 @@ error response message is generated.
|
|||||||
.IP \fBOK\fR
|
.IP \fBOK\fR
|
||||||
Accept the address etc. that matches the pattern.
|
Accept the address etc. that matches the pattern.
|
||||||
.IP \fIrestriction...\fR
|
.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).
|
\fBreject_unauth_destination\fR, and so on).
|
||||||
.SH REGULAR EXPRESSION TABLES
|
.SH REGULAR EXPRESSION TABLES
|
||||||
.na
|
.na
|
||||||
|
@ -13,9 +13,7 @@ Postfix delivery to external command
|
|||||||
.ad
|
.ad
|
||||||
.fi
|
.fi
|
||||||
The \fBpipe\fR daemon processes requests from the Postfix queue
|
The \fBpipe\fR daemon processes requests from the Postfix queue
|
||||||
manager to deliver messages to external commands. Each delivery
|
manager to deliver messages to external commands.
|
||||||
request specifies a queue file, a sender address, a domain or host
|
|
||||||
to deliver to, and one or more recipients.
|
|
||||||
This program expects to be run from the \fBmaster\fR(8) process
|
This program expects to be run from the \fBmaster\fR(8) process
|
||||||
manager.
|
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
|
as finished, or it informs the queue manager that delivery should
|
||||||
be tried again at a later time. Delivery problem reports are sent
|
be tried again at a later time. Delivery problem reports are sent
|
||||||
to the \fBbounce\fR(8) or \fBdefer\fR(8) daemon as appropriate.
|
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
|
.SH COMMAND ATTRIBUTE SYNTAX
|
||||||
.na
|
.na
|
||||||
.nf
|
.nf
|
||||||
@ -82,18 +98,21 @@ manager delivery request:
|
|||||||
This macro expands to the extension part of a recipient address.
|
This macro expands to the extension part of a recipient address.
|
||||||
For example, with an address \fIuser+foo@domain\fR the extension is
|
For example, with an address \fIuser+foo@domain\fR the extension is
|
||||||
\fIfoo\fR.
|
\fIfoo\fR.
|
||||||
|
.sp
|
||||||
A command-line argument that contains \fB${\fBextension\fR}\fR expands
|
A command-line argument that contains \fB${\fBextension\fR}\fR expands
|
||||||
into as many command-line arguments as there are recipients.
|
into as many command-line arguments as there are recipients.
|
||||||
.IP \fB${\fBmailbox\fR}\fR
|
.IP \fB${\fBmailbox\fR}\fR
|
||||||
This macro expands to the complete local part of a recipient address.
|
This macro expands to the complete local part of a recipient address.
|
||||||
For example, with an address \fIuser+foo@domain\fR the mailbox is
|
For example, with an address \fIuser+foo@domain\fR the mailbox is
|
||||||
\fIuser+foo\fR.
|
\fIuser+foo\fR.
|
||||||
|
.sp
|
||||||
A command-line argument that contains \fB${\fBmailbox\fR}\fR
|
A command-line argument that contains \fB${\fBmailbox\fR}\fR
|
||||||
expands into as many command-line arguments as there are recipients.
|
expands into as many command-line arguments as there are recipients.
|
||||||
.IP \fB${\fBnexthop\fR}\fR
|
.IP \fB${\fBnexthop\fR}\fR
|
||||||
This macro expands to the next-hop hostname.
|
This macro expands to the next-hop hostname.
|
||||||
.IP \fB${\fBrecipient\fR}\fR
|
.IP \fB${\fBrecipient\fR}\fR
|
||||||
This macro expands to the complete recipient address.
|
This macro expands to the complete recipient address.
|
||||||
|
.sp
|
||||||
A command-line argument that contains \fB${\fBrecipient\fR}\fR
|
A command-line argument that contains \fB${\fBrecipient\fR}\fR
|
||||||
expands into as many command-line arguments as there are recipients.
|
expands into as many command-line arguments as there are recipients.
|
||||||
.IP \fB${\fBsender\fR}\fR
|
.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.
|
This macro expands to the username part of a recipient address.
|
||||||
For example, with an address \fIuser+foo@domain\fR the username
|
For example, with an address \fIuser+foo@domain\fR the username
|
||||||
part is \fIuser\fR.
|
part is \fIuser\fR.
|
||||||
|
.sp
|
||||||
A command-line argument that contains \fB${\fBuser\fR}\fR expands
|
A command-line argument that contains \fB${\fBuser\fR}\fR expands
|
||||||
into as many command-line arguments as there are recipients.
|
into as many command-line arguments as there are recipients.
|
||||||
.RE
|
.RE
|
||||||
|
@ -57,7 +57,7 @@
|
|||||||
# ACTIONS
|
# ACTIONS
|
||||||
# .ad
|
# .ad
|
||||||
# .fi
|
# .fi
|
||||||
# .IP "[\fB45\fR]\fIXX text\fR"
|
# .IP "[\fB45\fR]\fINN text\fR"
|
||||||
# Reject the address etc. that matches the pattern, and respond with
|
# Reject the address etc. that matches the pattern, and respond with
|
||||||
# the numerical code and text.
|
# the numerical code and text.
|
||||||
# .IP \fBREJECT\fR
|
# .IP \fBREJECT\fR
|
||||||
@ -66,7 +66,7 @@
|
|||||||
# .IP \fBOK\fR
|
# .IP \fBOK\fR
|
||||||
# Accept the address etc. that matches the pattern.
|
# Accept the address etc. that matches the pattern.
|
||||||
# .IP \fIrestriction...\fR
|
# .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).
|
# \fBreject_unauth_destination\fR, and so on).
|
||||||
# REGULAR EXPRESSION TABLES
|
# REGULAR EXPRESSION TABLES
|
||||||
# .ad
|
# .ad
|
||||||
|
@ -182,7 +182,6 @@ static void cleanup_extracted_process(CLEANUP_STATE *state, int type, char *buf,
|
|||||||
* straightforward.
|
* straightforward.
|
||||||
*/
|
*/
|
||||||
if (vstream_fflush(state->dst)) {
|
if (vstream_fflush(state->dst)) {
|
||||||
msg_warn("%s: write queue file: %m", state->queue_id);
|
|
||||||
if (errno == EFBIG) {
|
if (errno == EFBIG) {
|
||||||
msg_warn("%s: queue file size limit exceeded", state->queue_id);
|
msg_warn("%s: queue file size limit exceeded", state->queue_id);
|
||||||
state->errs |= CLEANUP_STAT_SIZE;
|
state->errs |= CLEANUP_STAT_SIZE;
|
||||||
|
@ -129,6 +129,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <utime.h>
|
#include <utime.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
/* Utility library. */
|
/* Utility library. */
|
||||||
|
|
||||||
@ -182,10 +183,44 @@ static DOMAIN_LIST *flush_domains;
|
|||||||
/*
|
/*
|
||||||
* Silly little macros.
|
* Silly little macros.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define STR(x) vstring_str(x)
|
#define STR(x) vstring_str(x)
|
||||||
#define STREQ(x,y) (strcmp(x,y) == 0)
|
#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 */
|
/* flush_policy_ok - check logging policy */
|
||||||
|
|
||||||
static int flush_policy_ok(const char *site)
|
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));
|
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)
|
static int flush_add_service(const char *site, const char *queue_id)
|
||||||
{
|
{
|
||||||
char *myname = "flush_add_service";
|
char *myname = "flush_add_service";
|
||||||
VSTREAM *log;
|
VSTRING *site_path;
|
||||||
|
int status;
|
||||||
|
|
||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
msg_info("%s: site %s queue_id %s", myname, site, queue_id);
|
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)
|
if (flush_policy_ok(site) == 0)
|
||||||
return (FLUSH_STAT_OK);
|
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.
|
* 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)
|
O_CREAT | O_APPEND | O_WRONLY, 0600)) == 0)
|
||||||
msg_fatal("%s: open fast flush log for site %s: %m",
|
msg_fatal("%s: open fast flush logfile %s: %m", myname, path);
|
||||||
myname, site);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We must lock the logfile, so that we don't lose information due to
|
* 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.
|
* will eventually take care of the problem, but it will take a while.
|
||||||
*/
|
*/
|
||||||
if (myflock(vstream_fileno(log), INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
|
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 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.
|
* Clean up.
|
||||||
*/
|
*/
|
||||||
if (myflock(vstream_fileno(log), INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
|
if (myflock(vstream_fileno(log), INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
|
||||||
msg_fatal("%s: unlock fast flush log for site %s: %m",
|
msg_fatal("%s: unlock fast flush logfile %s: %m", myname, path);
|
||||||
myname, site);
|
|
||||||
if (vstream_fclose(log) != 0)
|
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);
|
return (FLUSH_STAT_OK);
|
||||||
}
|
}
|
||||||
@ -250,16 +301,8 @@ static int flush_add_service(const char *site, const char *queue_id)
|
|||||||
static int flush_send_service(const char *site)
|
static int flush_send_service(const char *site)
|
||||||
{
|
{
|
||||||
char *myname = "flush_send_service";
|
char *myname = "flush_send_service";
|
||||||
VSTRING *queue_id;
|
VSTRING *site_path;
|
||||||
VSTRING *queue_file;
|
int status;
|
||||||
VSTREAM *log;
|
|
||||||
struct utimbuf tbuf;
|
|
||||||
static char qmgr_trigger[] = {
|
|
||||||
QMGR_REQ_SCAN_INCOMING, /* scan incoming queue */
|
|
||||||
QMGR_REQ_FLUSH_DEAD, /* flush dead site/transport cache */
|
|
||||||
};
|
|
||||||
HTABLE *dup_filter;
|
|
||||||
int count;
|
|
||||||
|
|
||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
msg_info("%s: site %s", myname, site);
|
msg_info("%s: site %s", myname, site);
|
||||||
@ -270,13 +313,39 @@ static int flush_send_service(const char *site)
|
|||||||
if (flush_policy_ok(site) == 0)
|
if (flush_policy_ok(site) == 0)
|
||||||
return (mail_flush_deferred());
|
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;
|
||||||
|
struct utimbuf tbuf;
|
||||||
|
static char qmgr_trigger[] = {
|
||||||
|
QMGR_REQ_SCAN_INCOMING, /* scan incoming queue */
|
||||||
|
QMGR_REQ_FLUSH_DEAD, /* flush dead site/transport cache */
|
||||||
|
};
|
||||||
|
HTABLE *dup_filter;
|
||||||
|
int count;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Open the logfile. If the file does not exist, then there is no queued
|
* Open the logfile. If the file does not exist, then there is no queued
|
||||||
* mail for this destination.
|
* 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)
|
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);
|
return (FLUSH_STAT_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,7 +356,7 @@ static int flush_send_service(const char *site)
|
|||||||
* watchdog will take care of it.
|
* watchdog will take care of it.
|
||||||
*/
|
*/
|
||||||
if (myflock(vstream_fileno(log), INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
|
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
|
* 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();
|
tbuf.actime = tbuf.modtime = event_time();
|
||||||
for (count = 0; vstring_get_nonl(queue_id, log) != VSTREAM_EOF; count++) {
|
for (count = 0; vstring_get_nonl(queue_id, log) != VSTREAM_EOF; count++) {
|
||||||
if (!mail_queue_id_ok(STR(queue_id))) {
|
if (!mail_queue_id_ok(STR(queue_id))) {
|
||||||
msg_warn("bad queue id \"%.30s...\" in fast flush log for site %s",
|
msg_warn("bad queue id \"%.30s...\" in fast flush logfile %s",
|
||||||
STR(queue_id), site);
|
STR(queue_id), path);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (dup_filter->used >= FLUSH_DUP_FILTER_SIZE
|
if (dup_filter->used >= FLUSH_DUP_FILTER_SIZE
|
||||||
|| htable_find(dup_filter, STR(queue_id)) == 0) {
|
|| htable_find(dup_filter, STR(queue_id)) == 0) {
|
||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
msg_info("%s: site %s: update %s time stamps",
|
msg_info("%s: logfile %s: update queue file %s time stamps",
|
||||||
myname, site, STR(queue_id));
|
myname, path, STR(queue_id));
|
||||||
if (dup_filter->used <= FLUSH_DUP_FILTER_SIZE)
|
if (dup_filter->used <= FLUSH_DUP_FILTER_SIZE)
|
||||||
htable_enter(dup_filter, STR(queue_id), 0);
|
htable_enter(dup_filter, STR(queue_id), 0);
|
||||||
|
|
||||||
@ -344,8 +413,8 @@ static int flush_send_service(const char *site)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
msg_info("%s: site %s: skip file %s as duplicate",
|
msg_info("%s: logfile %s: skip queue file %s as duplicate",
|
||||||
myname, site, STR(queue_file));
|
myname, path, STR(queue_file));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
htable_free(dup_filter, (void (*) (char *)) 0);
|
htable_free(dup_filter, (void (*) (char *)) 0);
|
||||||
@ -356,19 +425,18 @@ static int flush_send_service(const char *site)
|
|||||||
* Truncate the fast flush log.
|
* Truncate the fast flush log.
|
||||||
*/
|
*/
|
||||||
if (count > 0 && ftruncate(vstream_fileno(log), (off_t) 0) < 0)
|
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.
|
* Request delivery and clean up.
|
||||||
*/
|
*/
|
||||||
if (myflock(vstream_fileno(log), INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
|
if (myflock(vstream_fileno(log), INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
|
||||||
msg_fatal("%s: unlock fast flush log for site %s: %m",
|
msg_fatal("%s: unlock fast flush logfile %s: %m", myname, path);
|
||||||
myname, site);
|
|
||||||
if (vstream_fclose(log) != 0)
|
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 (count > 0) {
|
||||||
if (msg_verbose)
|
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,
|
mail_trigger(MAIL_CLASS_PUBLIC, MAIL_SERVICE_QUEUE,
|
||||||
qmgr_trigger, sizeof(qmgr_trigger));
|
qmgr_trigger, sizeof(qmgr_trigger));
|
||||||
}
|
}
|
||||||
@ -381,23 +449,15 @@ static int flush_refresh_service(int max_age)
|
|||||||
{
|
{
|
||||||
char *myname = "flush_refresh_service";
|
char *myname = "flush_refresh_service";
|
||||||
SCAN_DIR *scan;
|
SCAN_DIR *scan;
|
||||||
char *site;
|
char *site_path;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
VSTRING *path = vstring_alloc(10);
|
VSTRING *path = vstring_alloc(10);
|
||||||
|
|
||||||
scan = scan_dir_open(MAIL_QUEUE_FLUSH);
|
scan = scan_dir_open(MAIL_QUEUE_FLUSH);
|
||||||
while ((site = mail_scan_dir_next(scan)) != 0) {
|
while ((site_path = mail_scan_dir_next(scan)) != 0) {
|
||||||
if (!mail_queue_id_ok(site))
|
if (!mail_queue_id_ok(site_path))
|
||||||
continue; /* XXX grumble. */
|
continue; /* XXX grumble. */
|
||||||
mail_queue_path(path, MAIL_QUEUE_FLUSH, site);
|
mail_queue_path(path, MAIL_QUEUE_FLUSH, site_path);
|
||||||
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;
|
|
||||||
}
|
|
||||||
if (stat(STR(path), &st) < 0) {
|
if (stat(STR(path), &st) < 0) {
|
||||||
if (errno != ENOENT)
|
if (errno != ENOENT)
|
||||||
msg_warn("%s: stat %s: %m", myname, STR(path));
|
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",
|
msg_info("%s: unlink %s, empty and unchanged for %d days",
|
||||||
myname, STR(path), var_fflush_purge / 86400);
|
myname, STR(path), var_fflush_purge / 86400);
|
||||||
} else if (msg_verbose)
|
} 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()) {
|
} else if (st.st_atime + max_age < event_time()) {
|
||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
msg_info("%s: flush site %s", myname, site);
|
msg_info("%s: flush logfile %s", myname, site_path);
|
||||||
flush_send_service(site);
|
flush_send_path(site_path);
|
||||||
} else {
|
} else {
|
||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
msg_info("%s: skip site %s, unread for <%d hours(s) ",
|
msg_info("%s: skip logfile %s, unread for <%d hours(s) ",
|
||||||
myname, site, max_age / 3600);
|
myname, site_path, max_age / 3600);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scan_dir_close(scan);
|
scan_dir_close(scan);
|
||||||
@ -466,14 +526,12 @@ static void flush_service(VSTREAM *client_stream, char *unused_service,
|
|||||||
site = vstring_alloc(10);
|
site = vstring_alloc(10);
|
||||||
queue_id = vstring_alloc(10);
|
queue_id = vstring_alloc(10);
|
||||||
if (mail_command_read(client_stream, "%s %s", site, queue_id) == 2
|
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)))
|
&& mail_queue_id_ok(STR(queue_id)))
|
||||||
status = flush_add_service(lowercase(STR(site)), STR(queue_id));
|
status = flush_add_service(lowercase(STR(site)), STR(queue_id));
|
||||||
mail_print(client_stream, "%d", status);
|
mail_print(client_stream, "%d", status);
|
||||||
} else if (STREQ(STR(request), FLUSH_REQ_SEND)) {
|
} else if (STREQ(STR(request), FLUSH_REQ_SEND)) {
|
||||||
site = vstring_alloc(10);
|
site = vstring_alloc(10);
|
||||||
if (mail_command_read(client_stream, "%s", site) == 1
|
if (mail_command_read(client_stream, "%s", site) == 1)
|
||||||
&& valid_hostname(STR(site), DONT_GRIPE))
|
|
||||||
status = flush_send_service(lowercase(STR(site)));
|
status = flush_send_service(lowercase(STR(site)));
|
||||||
mail_print(client_stream, "%d", status);
|
mail_print(client_stream, "%d", status);
|
||||||
} else if (STREQ(STR(request), FLUSH_REQ_REFRESH)
|
} else if (STREQ(STR(request), FLUSH_REQ_REFRESH)
|
||||||
|
@ -601,6 +601,7 @@ mail_params.o: ../../include/valid_hostname.h
|
|||||||
mail_params.o: ../../include/stringops.h
|
mail_params.o: ../../include/stringops.h
|
||||||
mail_params.o: ../../include/vstring.h
|
mail_params.o: ../../include/vstring.h
|
||||||
mail_params.o: ../../include/vbuf.h
|
mail_params.o: ../../include/vbuf.h
|
||||||
|
mail_params.o: ../../include/safe.h
|
||||||
mail_params.o: mynetworks.h
|
mail_params.o: mynetworks.h
|
||||||
mail_params.o: mail_conf.h
|
mail_params.o: mail_conf.h
|
||||||
mail_params.o: mail_version.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/sys_defs.h
|
||||||
mail_task.o: ../../include/vstring.h
|
mail_task.o: ../../include/vstring.h
|
||||||
mail_task.o: ../../include/vbuf.h
|
mail_task.o: ../../include/vbuf.h
|
||||||
|
mail_task.o: ../../include/safe.h
|
||||||
mail_task.o: mail_params.h
|
mail_task.o: mail_params.h
|
||||||
|
mail_task.o: mail_conf.h
|
||||||
mail_task.o: mail_task.h
|
mail_task.o: mail_task.h
|
||||||
mail_trigger.o: mail_trigger.c
|
mail_trigger.o: mail_trigger.c
|
||||||
mail_trigger.o: ../../include/sys_defs.h
|
mail_trigger.o: ../../include/sys_defs.h
|
||||||
|
@ -21,7 +21,8 @@
|
|||||||
*/
|
*/
|
||||||
#define CONF_ENV_PATH "MAIL_CONFIG" /* config database */
|
#define CONF_ENV_PATH "MAIL_CONFIG" /* config database */
|
||||||
#define CONF_ENV_VERB "MAIL_VERBOSE" /* verbose mode on */
|
#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.
|
* External representation for booleans.
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
/* char *var_transit_origin;
|
/* char *var_transit_origin;
|
||||||
/* char *var_transit_dest;
|
/* char *var_transit_dest;
|
||||||
/* char *var_mail_name;
|
/* char *var_mail_name;
|
||||||
|
/* char *var_syslog_name;
|
||||||
/* char *var_mail_owner;
|
/* char *var_mail_owner;
|
||||||
/* uid_t var_owner_uid;
|
/* uid_t var_owner_uid;
|
||||||
/* gid_t var_owner_gid;
|
/* gid_t var_owner_gid;
|
||||||
@ -92,6 +93,7 @@
|
|||||||
|
|
||||||
#include <sys_defs.h>
|
#include <sys_defs.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@ -107,6 +109,7 @@
|
|||||||
#include <get_hostname.h>
|
#include <get_hostname.h>
|
||||||
#include <valid_hostname.h>
|
#include <valid_hostname.h>
|
||||||
#include <stringops.h>
|
#include <stringops.h>
|
||||||
|
#include <safe.h>
|
||||||
|
|
||||||
/* Global library. */
|
/* Global library. */
|
||||||
|
|
||||||
@ -127,6 +130,7 @@ char *var_relayhost;
|
|||||||
char *var_transit_origin;
|
char *var_transit_origin;
|
||||||
char *var_transit_dest;
|
char *var_transit_dest;
|
||||||
char *var_mail_name;
|
char *var_mail_name;
|
||||||
|
char *var_syslog_name;
|
||||||
char *var_mail_owner;
|
char *var_mail_owner;
|
||||||
uid_t var_owner_uid;
|
uid_t var_owner_uid;
|
||||||
gid_t var_owner_gid;
|
gid_t var_owner_gid;
|
||||||
@ -270,6 +274,7 @@ void mail_params_init()
|
|||||||
};
|
};
|
||||||
static CONFIG_STR_TABLE other_str_defaults[] = {
|
static CONFIG_STR_TABLE other_str_defaults[] = {
|
||||||
VAR_MAIL_NAME, DEF_MAIL_NAME, &var_mail_name, 1, 0,
|
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_MAIL_OWNER, DEF_MAIL_OWNER, &var_mail_owner, 1, 0,
|
||||||
VAR_MYDEST, DEF_MYDEST, &var_mydest, 0, 0,
|
VAR_MYDEST, DEF_MYDEST, &var_mydest, 0, 0,
|
||||||
VAR_MYORIGIN, DEF_MYORIGIN, &var_myorigin, 1, 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,
|
VAR_OWNREQ_SPECIAL, DEF_OWNREQ_SPECIAL, &var_ownreq_special,
|
||||||
0,
|
0,
|
||||||
};
|
};
|
||||||
|
const char *cp;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Extract syslog_facility early, so that from here on all errors are
|
* Extract syslog_facility early, so that from here on all errors are
|
||||||
@ -376,6 +382,15 @@ void mail_params_init()
|
|||||||
*/
|
*/
|
||||||
time(&var_starttime);
|
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.
|
* I have seen this happen just too often.
|
||||||
*/
|
*/
|
||||||
|
@ -1192,7 +1192,7 @@ extern int var_fflush_refresh;
|
|||||||
* and what Postfix exports to the external world.
|
* and what Postfix exports to the external world.
|
||||||
*/
|
*/
|
||||||
#define VAR_IMPORT_ENVIRON "import_environment"
|
#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;
|
extern char *var_import_environ;
|
||||||
|
|
||||||
#define VAR_EXPORT_ENVIRON "export_environment"
|
#define VAR_EXPORT_ENVIRON "export_environment"
|
||||||
@ -1230,6 +1230,13 @@ extern int var_virt_mailbox_limit;
|
|||||||
#define DEF_VIRT_MAILBOX_LOCK "fcntl"
|
#define DEF_VIRT_MAILBOX_LOCK "fcntl"
|
||||||
extern char *var_virt_mailbox_lock;
|
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
|
/* LICENSE
|
||||||
/* .ad
|
/* .ad
|
||||||
/* .fi
|
/* .fi
|
||||||
|
@ -12,7 +12,8 @@
|
|||||||
/* mail_task() enforces consistent naming of mailer processes.
|
/* mail_task() enforces consistent naming of mailer processes.
|
||||||
/* It strips pathname information from the process name, and
|
/* It strips pathname information from the process name, and
|
||||||
/* prepends the name of the mail system so that logfile entries
|
/* 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
|
/* The result is volatile. Make a copy of the result if it is
|
||||||
/* to be used for any appreciable amount of time.
|
/* to be used for any appreciable amount of time.
|
||||||
@ -35,25 +36,28 @@
|
|||||||
/* Utility library. */
|
/* Utility library. */
|
||||||
|
|
||||||
#include <vstring.h>
|
#include <vstring.h>
|
||||||
|
#include <safe.h>
|
||||||
|
|
||||||
/* Global library. */
|
/* Global library. */
|
||||||
|
|
||||||
#include "mail_params.h"
|
#include "mail_params.h"
|
||||||
|
#include "mail_conf.h"
|
||||||
#include "mail_task.h"
|
#include "mail_task.h"
|
||||||
|
|
||||||
#define MAIL_TASK_FORMAT "postfix/%s"
|
|
||||||
|
|
||||||
/* mail_task - clean up and decorate the process name */
|
/* mail_task - clean up and decorate the process name */
|
||||||
|
|
||||||
const char *mail_task(const char *argv0)
|
const char *mail_task(const char *argv0)
|
||||||
{
|
{
|
||||||
static VSTRING *canon_name;
|
static VSTRING *canon_name;
|
||||||
const char *slash;
|
const char *slash;
|
||||||
|
const char *tag;
|
||||||
|
|
||||||
if (canon_name == 0)
|
if (canon_name == 0)
|
||||||
canon_name = vstring_alloc(10);
|
canon_name = vstring_alloc(10);
|
||||||
if ((slash = strrchr(argv0, '/')) != 0)
|
if ((slash = strrchr(argv0, '/')) != 0)
|
||||||
argv0 = slash + 1;
|
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));
|
return (vstring_str(canon_name));
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* Version of this program.
|
* Version of this program.
|
||||||
*/
|
*/
|
||||||
#define VAR_MAIL_VERSION "mail_version"
|
#define VAR_MAIL_VERSION "mail_version"
|
||||||
#define DEF_MAIL_VERSION "Snapshot-20010228"
|
#define DEF_MAIL_VERSION "Snapshot-20010323"
|
||||||
extern char *var_mail_version;
|
extern char *var_mail_version;
|
||||||
|
|
||||||
/* LICENSE
|
/* LICENSE
|
||||||
|
@ -252,7 +252,7 @@ VSTRING *tok822_externalize(VSTRING *vp, TOK822 *tree, int flags)
|
|||||||
VSTRING_ADDCH(vp, ')');
|
VSTRING_ADDCH(vp, ')');
|
||||||
break;
|
break;
|
||||||
case TOK822_COMMENT_TEXT:
|
case TOK822_COMMENT_TEXT:
|
||||||
tok822_copy_quoted(vp, vstring_str(tp->vstr), "()\\\r\n");
|
tok822_copy_quoted(vp, vstring_str(tp->vstr), "()\\");
|
||||||
break;
|
break;
|
||||||
case TOK822_QSTRING:
|
case TOK822_QSTRING:
|
||||||
VSTRING_ADDCH(vp, '"');
|
VSTRING_ADDCH(vp, '"');
|
||||||
@ -540,7 +540,7 @@ TOK822 *tok822_scan_addr(const char *addr)
|
|||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <vstream.h>
|
#include <vstream.h>
|
||||||
#include <vstring_vstream.h>
|
#include <readlline.h>
|
||||||
|
|
||||||
/* tok822_print - display token */
|
/* tok822_print - display token */
|
||||||
|
|
||||||
@ -577,7 +577,7 @@ int main(int unused_argc, char **unused_argv)
|
|||||||
TOK822 *list;
|
TOK822 *list;
|
||||||
VSTRING *buf = vstring_alloc(100);
|
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)))
|
if (!isatty(vstream_fileno(VSTREAM_IN)))
|
||||||
vstream_printf(">>>%s<<<\n\n", vstring_str(buf));
|
vstream_printf(">>>%s<<<\n\n", vstring_str(buf));
|
||||||
list = tok822_parse(vstring_str(buf));
|
list = tok822_parse(vstring_str(buf));
|
||||||
|
@ -330,6 +330,10 @@ static int deliver_message(DELIVER_REQUEST *request, char **unused_argv)
|
|||||||
/*
|
/*
|
||||||
* Disconnect if we're going to a different destination. Discard
|
* Disconnect if we're going to a different destination. Discard
|
||||||
* transcript and status information for sending QUIT.
|
* 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) {
|
if (strcasecmp(state->session->dest, request->nexthop) != 0) {
|
||||||
lmtp_quit(state);
|
lmtp_quit(state);
|
||||||
|
@ -116,7 +116,8 @@ static LMTP_SESSION *lmtp_connect_sock(int, struct sockaddr *, int,
|
|||||||
|
|
||||||
/* lmtp_connect_unix - connect to UNIX-domain address */
|
/* 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
|
#undef sun
|
||||||
char *myname = "lmtp_connect_unix";
|
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);
|
msg_info("%s: trying: %s...", myname, addr);
|
||||||
|
|
||||||
return (lmtp_connect_sock(sock, (struct sockaddr *) & sun, sizeof(sun),
|
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 */
|
/* lmtp_connect_addr - connect to explicit address */
|
||||||
@ -358,11 +359,17 @@ LMTP_SESSION *lmtp_connect(const char *destination, VSTRING *why)
|
|||||||
* XXX Ad-hoc transport parsing and connection management. Some or all
|
* XXX Ad-hoc transport parsing and connection management. Some or all
|
||||||
* should be moved away to a reusable library routine so that every
|
* should be moved away to a reusable library routine so that every
|
||||||
* program benefits from it.
|
* 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)
|
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)
|
if (strncmp(destination, "inet:", 5) == 0)
|
||||||
destination += 5;
|
dest_buf = lmtp_parse_destination(destination + 5, def_service,
|
||||||
|
&host, &port);
|
||||||
|
else
|
||||||
dest_buf = lmtp_parse_destination(destination, def_service,
|
dest_buf = lmtp_parse_destination(destination, def_service,
|
||||||
&host, &port);
|
&host, &port);
|
||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
|
@ -138,6 +138,7 @@ master_listen.o: ../../include/vstring.h
|
|||||||
master_listen.o: ../../include/vbuf.h
|
master_listen.o: ../../include/vbuf.h
|
||||||
master_listen.o: ../../include/inet_addr_list.h
|
master_listen.o: ../../include/inet_addr_list.h
|
||||||
master_listen.o: ../../include/set_eugid.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: ../../include/mail_params.h
|
||||||
master_listen.o: master.h
|
master_listen.o: master.h
|
||||||
master_proto.o: master_proto.c
|
master_proto.o: master_proto.c
|
||||||
|
@ -53,6 +53,7 @@
|
|||||||
#include <stringops.h>
|
#include <stringops.h>
|
||||||
#include <inet_addr_list.h>
|
#include <inet_addr_list.h>
|
||||||
#include <set_eugid.h>
|
#include <set_eugid.h>
|
||||||
|
#include <set_ugid.h>
|
||||||
#include <iostuff.h>
|
#include <iostuff.h>
|
||||||
|
|
||||||
/* Global library. */
|
/* Global library. */
|
||||||
@ -88,7 +89,7 @@ void master_listen_init(MASTER_SERV *serv)
|
|||||||
LOCAL_LISTEN(serv->name, serv->max_proc > var_proc_limit ?
|
LOCAL_LISTEN(serv->name, serv->max_proc > var_proc_limit ?
|
||||||
serv->max_proc : var_proc_limit, NON_BLOCKING);
|
serv->max_proc : var_proc_limit, NON_BLOCKING);
|
||||||
close_on_exec(serv->listen_fd[0], CLOSE_ON_EXEC);
|
close_on_exec(serv->listen_fd[0], CLOSE_ON_EXEC);
|
||||||
set_eugid(getuid(), getgid());
|
set_ugid(getuid(), getgid());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -98,7 +99,7 @@ void master_listen_init(MASTER_SERV *serv)
|
|||||||
set_eugid(var_owner_uid, var_owner_gid);
|
set_eugid(var_owner_uid, var_owner_gid);
|
||||||
serv->listen_fd[0] = fifo_listen(serv->name, 0622, NON_BLOCKING);
|
serv->listen_fd[0] = fifo_listen(serv->name, 0622, NON_BLOCKING);
|
||||||
close_on_exec(serv->listen_fd[0], CLOSE_ON_EXEC);
|
close_on_exec(serv->listen_fd[0], CLOSE_ON_EXEC);
|
||||||
set_eugid(getuid(), getgid());
|
set_ugid(getuid(), getgid());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -152,7 +152,7 @@ static void master_sigchld(int sig)
|
|||||||
|
|
||||||
static void master_sigdeath(int sig)
|
static void master_sigdeath(int sig)
|
||||||
{
|
{
|
||||||
char *myname = "master_sigsetup";
|
char *myname = "master_sigdeath";
|
||||||
struct sigaction action;
|
struct sigaction action;
|
||||||
pid_t pid = getpid();
|
pid_t pid = getpid();
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@ static void qmgr_active_defer(const char *queue_name, const char *queue_id,
|
|||||||
|
|
||||||
tbuf.actime = tbuf.modtime = event_time() + delay;
|
tbuf.actime = tbuf.modtime = event_time() + delay;
|
||||||
path = mail_queue_path((VSTRING *) 0, queue_name, queue_id);
|
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);
|
msg_fatal("%s: update %s time stamps: %m", myname, path);
|
||||||
if (mail_queue_rename(queue_id, queue_name, dest_queue)) {
|
if (mail_queue_rename(queue_id, queue_name, dest_queue)) {
|
||||||
if (errno != ENOENT)
|
if (errno != ENOENT)
|
||||||
|
@ -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
|
* 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
|
* as soon as possible as that would decrease the chance of per-site
|
||||||
* recipient grouping. We waited until reading more is really necessary.
|
* recipient grouping. We waited until reading more is really necessary.
|
||||||
|
*
|
||||||
|
* 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) {
|
if (message->rcpt_offset != 0
|
||||||
|
&& message->rcpt_limit > message->rcpt_count
|
||||||
|
&& message->refcount > 0) {
|
||||||
qmgr_message_realloc(message);
|
qmgr_message_realloc(message);
|
||||||
if (HAS_ENTRIES(job))
|
if (HAS_ENTRIES(job))
|
||||||
return (qmgr_peer_select(job));
|
return (qmgr_peer_select(job));
|
||||||
|
@ -7,9 +7,7 @@
|
|||||||
/* \fBpipe\fR [generic Postfix daemon options] command_attributes...
|
/* \fBpipe\fR [generic Postfix daemon options] command_attributes...
|
||||||
/* DESCRIPTION
|
/* DESCRIPTION
|
||||||
/* The \fBpipe\fR daemon processes requests from the Postfix queue
|
/* The \fBpipe\fR daemon processes requests from the Postfix queue
|
||||||
/* manager to deliver messages to external commands. Each delivery
|
/* manager to deliver messages to external commands.
|
||||||
/* request specifies a queue file, a sender address, a domain or host
|
|
||||||
/* to deliver to, and one or more recipients.
|
|
||||||
/* This program expects to be run from the \fBmaster\fR(8) process
|
/* This program expects to be run from the \fBmaster\fR(8) process
|
||||||
/* manager.
|
/* manager.
|
||||||
/*
|
/*
|
||||||
@ -17,6 +15,22 @@
|
|||||||
/* as finished, or it informs the queue manager that delivery should
|
/* as finished, or it informs the queue manager that delivery should
|
||||||
/* be tried again at a later time. Delivery problem reports are sent
|
/* be tried again at a later time. Delivery problem reports are sent
|
||||||
/* to the \fBbounce\fR(8) or \fBdefer\fR(8) daemon as appropriate.
|
/* 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
|
/* COMMAND ATTRIBUTE SYNTAX
|
||||||
/* .ad
|
/* .ad
|
||||||
/* .fi
|
/* .fi
|
||||||
@ -74,18 +88,21 @@
|
|||||||
/* This macro expands to the extension part of a recipient address.
|
/* This macro expands to the extension part of a recipient address.
|
||||||
/* For example, with an address \fIuser+foo@domain\fR the extension is
|
/* For example, with an address \fIuser+foo@domain\fR the extension is
|
||||||
/* \fIfoo\fR.
|
/* \fIfoo\fR.
|
||||||
|
/* .sp
|
||||||
/* A command-line argument that contains \fB${\fBextension\fR}\fR expands
|
/* A command-line argument that contains \fB${\fBextension\fR}\fR expands
|
||||||
/* into as many command-line arguments as there are recipients.
|
/* into as many command-line arguments as there are recipients.
|
||||||
/* .IP \fB${\fBmailbox\fR}\fR
|
/* .IP \fB${\fBmailbox\fR}\fR
|
||||||
/* This macro expands to the complete local part of a recipient address.
|
/* This macro expands to the complete local part of a recipient address.
|
||||||
/* For example, with an address \fIuser+foo@domain\fR the mailbox is
|
/* For example, with an address \fIuser+foo@domain\fR the mailbox is
|
||||||
/* \fIuser+foo\fR.
|
/* \fIuser+foo\fR.
|
||||||
|
/* .sp
|
||||||
/* A command-line argument that contains \fB${\fBmailbox\fR}\fR
|
/* A command-line argument that contains \fB${\fBmailbox\fR}\fR
|
||||||
/* expands into as many command-line arguments as there are recipients.
|
/* expands into as many command-line arguments as there are recipients.
|
||||||
/* .IP \fB${\fBnexthop\fR}\fR
|
/* .IP \fB${\fBnexthop\fR}\fR
|
||||||
/* This macro expands to the next-hop hostname.
|
/* This macro expands to the next-hop hostname.
|
||||||
/* .IP \fB${\fBrecipient\fR}\fR
|
/* .IP \fB${\fBrecipient\fR}\fR
|
||||||
/* This macro expands to the complete recipient address.
|
/* This macro expands to the complete recipient address.
|
||||||
|
/* .sp
|
||||||
/* A command-line argument that contains \fB${\fBrecipient\fR}\fR
|
/* A command-line argument that contains \fB${\fBrecipient\fR}\fR
|
||||||
/* expands into as many command-line arguments as there are recipients.
|
/* expands into as many command-line arguments as there are recipients.
|
||||||
/* .IP \fB${\fBsender\fR}\fR
|
/* .IP \fB${\fBsender\fR}\fR
|
||||||
@ -97,6 +114,7 @@
|
|||||||
/* This macro expands to the username part of a recipient address.
|
/* This macro expands to the username part of a recipient address.
|
||||||
/* For example, with an address \fIuser+foo@domain\fR the username
|
/* For example, with an address \fIuser+foo@domain\fR the username
|
||||||
/* part is \fIuser\fR.
|
/* part is \fIuser\fR.
|
||||||
|
/* .sp
|
||||||
/* A command-line argument that contains \fB${\fBuser\fR}\fR expands
|
/* A command-line argument that contains \fB${\fBuser\fR}\fR expands
|
||||||
/* into as many command-line arguments as there are recipients.
|
/* into as many command-line arguments as there are recipients.
|
||||||
/* .RE
|
/* .RE
|
||||||
|
@ -80,6 +80,7 @@
|
|||||||
#include <vstream.h>
|
#include <vstream.h>
|
||||||
#include <msg_vstream.h>
|
#include <msg_vstream.h>
|
||||||
#include <safe.h>
|
#include <safe.h>
|
||||||
|
#include <events.h>
|
||||||
|
|
||||||
/* Global library. */
|
/* Global library. */
|
||||||
|
|
||||||
@ -159,11 +160,12 @@ int main(int argc, char **argv)
|
|||||||
/*
|
/*
|
||||||
* Kick the service.
|
* 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",
|
msg_warn("Cannot contact class %s service %s - perhaps the mail system is down",
|
||||||
class, service);
|
class, service);
|
||||||
exit(1);
|
exit(1);
|
||||||
} else {
|
} else {
|
||||||
|
event_loop(-1);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -149,7 +149,7 @@ static void qmgr_active_defer(const char *queue_name, const char *queue_id,
|
|||||||
|
|
||||||
tbuf.actime = tbuf.modtime = event_time() + delay;
|
tbuf.actime = tbuf.modtime = event_time() + delay;
|
||||||
path = mail_queue_path((VSTRING *) 0, queue_name, queue_id);
|
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);
|
msg_fatal("%s: update %s time stamps: %m", myname, path);
|
||||||
if (mail_queue_rename(queue_id, queue_name, dest_queue)) {
|
if (mail_queue_rename(queue_id, queue_name, dest_queue)) {
|
||||||
if (errno != ENOENT)
|
if (errno != ENOENT)
|
||||||
|
@ -16,6 +16,10 @@
|
|||||||
/* a brief connection to it and by writing the contents of the
|
/* a brief connection to it and by writing the contents of the
|
||||||
/* named buffer.
|
/* 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:
|
/* Arguments:
|
||||||
/* .IP service
|
/* .IP service
|
||||||
/* Name of the communication endpoint.
|
/* Name of the communication endpoint.
|
||||||
@ -45,6 +49,7 @@
|
|||||||
/* System library. */
|
/* System library. */
|
||||||
|
|
||||||
#include <sys_defs.h>
|
#include <sys_defs.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -53,13 +58,40 @@
|
|||||||
#include <msg.h>
|
#include <msg.h>
|
||||||
#include <connect.h>
|
#include <connect.h>
|
||||||
#include <iostuff.h>
|
#include <iostuff.h>
|
||||||
|
#include <mymalloc.h>
|
||||||
|
#include <events.h>
|
||||||
#include <trigger.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 */
|
/* inet_trigger - wakeup INET-domain server */
|
||||||
|
|
||||||
int inet_trigger(const char *service, const char *buf, int len, int timeout)
|
int inet_trigger(const char *service, const char *buf, int len, int timeout)
|
||||||
{
|
{
|
||||||
char *myname = "inet_trigger";
|
char *myname = "inet_trigger";
|
||||||
|
struct inet_trigger *ip;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
if (msg_verbose > 1)
|
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);
|
msg_warn("%s: connect to %s: %m", myname, service);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
ip = (struct inet_trigger *) mymalloc(sizeof(*ip));
|
||||||
|
ip->fd = fd;
|
||||||
|
ip->service = mystrdup(service);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write the request...
|
* 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);
|
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 (timeout > 0)
|
||||||
if (msg_verbose)
|
event_request_timer(inet_trigger_event, (char *) ip, timeout);
|
||||||
msg_warn("%s: close %s: %m", myname, service);
|
event_enable_read(fd, inet_trigger_event, (char *) ip);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
@ -67,8 +67,8 @@ void rand_sleep(unsigned delay, unsigned variation)
|
|||||||
* Use the semi-crappy random number generator.
|
* Use the semi-crappy random number generator.
|
||||||
*/
|
*/
|
||||||
if (my_pid == 0)
|
if (my_pid == 0)
|
||||||
srandom((my_pid = getpid()) ^ time((time_t *) 0));
|
srand((my_pid = getpid()) ^ time((time_t *) 0));
|
||||||
usec = (delay - variation / 2) + variation * (double) random() / RAND_MAX;
|
usec = (delay - variation / 2) + variation * (double) rand() / RAND_MAX;
|
||||||
doze(usec);
|
doze(usec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
|
|
||||||
/* Utility library. */
|
/* Utility library. */
|
||||||
|
|
||||||
|
#include "msg.h"
|
||||||
#include "sane_accept.h"
|
#include "sane_accept.h"
|
||||||
|
|
||||||
/* sane_accept - sanitize accept() error returns */
|
/* sane_accept - sanitize accept() error returns */
|
||||||
@ -55,6 +56,10 @@ int sane_accept(int sock, struct sockaddr * sa, SOCKADDR_SIZE *len)
|
|||||||
EWOULDBLOCK,
|
EWOULDBLOCK,
|
||||||
0,
|
0,
|
||||||
};
|
};
|
||||||
|
static int accept_warn_errors[] = {
|
||||||
|
ECONNABORTED,
|
||||||
|
0,
|
||||||
|
};
|
||||||
int count;
|
int count;
|
||||||
int err;
|
int err;
|
||||||
int fd;
|
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
|
* XXX LINUX < 2.1 accept() wakes up before the three-way handshake is
|
||||||
* complete, so it can fail with ECONNRESET and other "false alarm"
|
* complete, so it can fail with ECONNRESET and other "false alarm"
|
||||||
* indications.
|
* 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) {
|
if ((fd = accept(sock, sa, len)) < 0) {
|
||||||
for (count = 0; (err = accept_ok_errors[count]) != 0; count++) {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (count = 0; (err = accept_warn_errors[count]) != 0; count++) {
|
||||||
|
if (errno == err) {
|
||||||
|
msg_warn("accept: %m");
|
||||||
|
errno = EAGAIN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return (fd);
|
return (fd);
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,10 @@
|
|||||||
/* stream_trigger() wakes up the named stream server by making
|
/* stream_trigger() wakes up the named stream server by making
|
||||||
/* a brief connection to it and writing the named buffer.
|
/* 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:
|
/* Arguments:
|
||||||
/* .IP service
|
/* .IP service
|
||||||
/* Name of the communication endpoint.
|
/* Name of the communication endpoint.
|
||||||
@ -51,13 +55,39 @@
|
|||||||
#include <msg.h>
|
#include <msg.h>
|
||||||
#include <connect.h>
|
#include <connect.h>
|
||||||
#include <iostuff.h>
|
#include <iostuff.h>
|
||||||
|
#include <mymalloc.h>
|
||||||
|
#include <events.h>
|
||||||
#include <trigger.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 */
|
/* stream_trigger - wakeup stream server */
|
||||||
|
|
||||||
int stream_trigger(const char *service, const char *buf, int len, int timeout)
|
int stream_trigger(const char *service, const char *buf, int len, int timeout)
|
||||||
{
|
{
|
||||||
char *myname = "stream_trigger";
|
char *myname = "stream_trigger";
|
||||||
|
struct stream_trigger *sp;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
if (msg_verbose > 1)
|
if (msg_verbose > 1)
|
||||||
@ -72,6 +102,13 @@ int stream_trigger(const char *service, const char *buf, int len, int timeou
|
|||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Stash away context.
|
||||||
|
*/
|
||||||
|
sp = (struct stream_trigger *) mymalloc(sizeof(*sp));
|
||||||
|
sp->fd = fd;
|
||||||
|
sp->service = mystrdup(service);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write the request...
|
* 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);
|
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 (timeout > 0)
|
||||||
if (msg_verbose)
|
event_request_timer(stream_trigger_event, (char *) sp, timeout);
|
||||||
msg_warn("%s: close %s: %m", myname, service);
|
event_enable_read(fd, stream_trigger_event, (char *) sp);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
@ -329,10 +329,12 @@ extern int opterr;
|
|||||||
#define USE_STATVFS
|
#define USE_STATVFS
|
||||||
#define STATVFS_IN_SYS_STATVFS_H
|
#define STATVFS_IN_SYS_STATVFS_H
|
||||||
#define STRCASECMP_IN_STRINGS_H
|
#define STRCASECMP_IN_STRINGS_H
|
||||||
|
#if 0
|
||||||
extern time_t time(time_t *);
|
extern time_t time(time_t *);
|
||||||
extern int seteuid(uid_t);
|
extern int seteuid(uid_t);
|
||||||
extern int setegid(gid_t);
|
extern int setegid(gid_t);
|
||||||
extern int initgroups(const char *, int);
|
extern int initgroups(const char *, int);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -15,6 +15,10 @@
|
|||||||
/* unix_trigger() wakes up the named UNIX-domain server by making
|
/* unix_trigger() wakes up the named UNIX-domain server by making
|
||||||
/* a brief connection to it and writing the named buffer.
|
/* 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:
|
/* Arguments:
|
||||||
/* .IP service
|
/* .IP service
|
||||||
/* Name of the communication endpoint.
|
/* Name of the communication endpoint.
|
||||||
@ -43,6 +47,7 @@
|
|||||||
/* System library. */
|
/* System library. */
|
||||||
|
|
||||||
#include <sys_defs.h>
|
#include <sys_defs.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -51,13 +56,39 @@
|
|||||||
#include <msg.h>
|
#include <msg.h>
|
||||||
#include <connect.h>
|
#include <connect.h>
|
||||||
#include <iostuff.h>
|
#include <iostuff.h>
|
||||||
|
#include <mymalloc.h>
|
||||||
|
#include <events.h>
|
||||||
#include <trigger.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 */
|
/* unix_trigger - wakeup UNIX-domain server */
|
||||||
|
|
||||||
int unix_trigger(const char *service, const char *buf, int len, int timeout)
|
int unix_trigger(const char *service, const char *buf, int len, int timeout)
|
||||||
{
|
{
|
||||||
char *myname = "unix_trigger";
|
char *myname = "unix_trigger";
|
||||||
|
struct unix_trigger *up;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
if (msg_verbose > 1)
|
if (msg_verbose > 1)
|
||||||
@ -72,6 +103,13 @@ int unix_trigger(const char *service, const char *buf, int len, int timeout)
|
|||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Stash away context.
|
||||||
|
*/
|
||||||
|
up = (struct unix_trigger *) mymalloc(sizeof(*up));
|
||||||
|
up->fd = fd;
|
||||||
|
up->service = mystrdup(service);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write the request...
|
* 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);
|
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 (timeout > 0)
|
||||||
if (msg_verbose)
|
event_request_timer(unix_trigger_event, (char *) up, timeout);
|
||||||
msg_warn("%s: close %s: %m", myname, service);
|
event_enable_read(fd, unix_trigger_event, (char *) up);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user