mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-29 13:18:12 +00:00
postfix-2.5-20071004
This commit is contained in:
parent
b357c48245
commit
7c07e99edd
@ -13712,3 +13712,47 @@ Apologies for any names omitted.
|
||||
unparsable canonical name caused the SMTPD policy client
|
||||
to allocate zero-length memory, triggering an assertion
|
||||
that it shouldn't do such things. File: smtpd/smtpd_check.c.
|
||||
|
||||
20070912
|
||||
|
||||
Bugfix (introduced Postfix 2.4) missing initialization of
|
||||
event mask in the event_mask_drain() routine (used by the
|
||||
obsolete postkick(1) command). Found by Coverity. File:
|
||||
util/events.c.
|
||||
|
||||
20070917
|
||||
|
||||
Workaround: the flush daemon forces an access time update
|
||||
for the per-destination logfile, to prevent an excessive
|
||||
rate of delivery attempts when the queue file system is
|
||||
mounted with "noatime". File: flush/flush.c.
|
||||
|
||||
20070923
|
||||
|
||||
Cleanup: don't complain when a "corrupt" queue file is
|
||||
deleted before it can be saved to the "corrupt" queue.
|
||||
Files: *qmgr/qmgr_active.c.
|
||||
|
||||
20071003
|
||||
|
||||
Logging: the Postfix SMTP server now logs the number of
|
||||
bytes received after the DATA command when a connection
|
||||
breaks before mail delivery completes. This may help finding
|
||||
the cause of the problem: packet loss, MTU, or other. File:
|
||||
smtpd/smtpd.c.
|
||||
|
||||
20071004
|
||||
|
||||
Logging: all daemons now log the TCP port number of remote
|
||||
SMTP or QMQP clients. The information is overruled with
|
||||
the SMTP XCLIENT command, is propagated through SMTP-based
|
||||
content filters with XFORWARD, and is sent to Milter
|
||||
applications. Files: smtpd/smtpd_peer.c, smtpd/smtpd.c,
|
||||
smtpd/smtpd_proxy.c, smtpd/smtpd_milter.c, qmqpd/qmqpd_peer.c,
|
||||
cleanup/cleanup_milter.c, *qmgr/qmgr_message.c,
|
||||
*qmgr/qmgr_deliver.c, smtp/smtp_proto.c, pipe/pipe.c,
|
||||
global/deliver_request.c, global/deliver_pass.c,
|
||||
proto/XFORWARD_README, proto/XCLIENT_README.
|
||||
|
||||
Feature: per-command delays in smtp-sink. File:
|
||||
smtpstone/smtp-sink.c. Victor Duchovni.
|
||||
|
@ -7,14 +7,15 @@ IInnttrroodduuccttiioonn
|
||||
Postfix version 2.3 introduces support for the Sendmail version 8 Milter (mail
|
||||
filter) protocol. This protocol is used by applications that run outside the
|
||||
MTA to inspect SMTP events (CONNECT, DISCONNECT), SMTP commands (HELO, MAIL
|
||||
FROM, etc.) as well as mail content. All this happens before mail is queued.
|
||||
FROM, etc.) as well as mail content (headers and body). All this happens before
|
||||
mail is queued.
|
||||
|
||||
The reason for adding Milter support to Postfix is that there exists a large
|
||||
collection of applications, not only to block unwanted mail, but also to verify
|
||||
authenticity (examples: Domain keys identified mail, SenderID+SPF and Domain
|
||||
keys) or to digitally sign mail (examples: Domain keys identified mail, Domain
|
||||
keys). Having yet another Postfix-specific version of all that software is a
|
||||
poor use of human and system resources.
|
||||
authenticity (examples: DomainKeys Identified Mail (DKIM), SenderID+SPF and
|
||||
DomainKeys) or to digitally sign mail (examples: DomainKeys Identified Mail
|
||||
(DKIM), DomainKeys). Having yet another Postfix-specific version of all that
|
||||
software is a poor use of human and system resources.
|
||||
|
||||
Postfix version 2.4 implements all the requests of Sendmail version 8 Milter
|
||||
protocols up to version 4, including message body replacement (body replacement
|
||||
@ -336,6 +337,9 @@ workarounds section below for solutions.
|
||||
|{client_name} |Always |when lookup or |
|
||||
| | |verification fails |
|
||||
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
|{client_port} |Always |Client TCP port |
|
||||
| |(Postfix >=2.5) | |
|
||||
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
||||
| | |Client name from reverse |
|
||||
|{client_ptr} |CONNECT, HELO, MAIL, DATA|lookup, "unknown" when |
|
||||
| | |lookup fails |
|
||||
|
@ -48,7 +48,7 @@ are in fact case insensitive.
|
||||
|
||||
xclient-command = XCLIENT 1*( SP attribute-name"="attribute-value )
|
||||
|
||||
attribute-name = ( NAME | ADDR | PROTO | HELO )
|
||||
attribute-name = ( NAME | ADDR | PORT | PROTO | HELO )
|
||||
|
||||
attribute-value = xtext
|
||||
|
||||
@ -63,6 +63,9 @@ are in fact case insensitive.
|
||||
an IPv6 address prefixed with IPV6:, or [UNAVAILABLE] when the address
|
||||
information is unavailable. Address information is not enclosed with [].
|
||||
|
||||
* The PORT attribute specifies the SMTP client TCP port number as a decimal
|
||||
number, or [UNAVAILABLE] when the information is unavailable.
|
||||
|
||||
* The PROTO attribute specifies either SMTP or ESMTP.
|
||||
|
||||
* The HELO attribute specifies an SMTP HELO parameter value, or the value
|
||||
@ -81,6 +84,9 @@ Note 3: Postfix implementations prior to version 2.3 do not xtext encode
|
||||
attribute values. Servers that wish to interoperate with these older
|
||||
implementations should be prepared to receive unencoded information.
|
||||
|
||||
Note 4: Postfix implementations prior to version 2.5 do not implement the PORT
|
||||
attribute.
|
||||
|
||||
XXCCLLIIEENNTT SSeerrvveerr rreessppoonnssee
|
||||
|
||||
Upon receipt of a correctly formatted XCLIENT command, the server resets state
|
||||
|
@ -41,7 +41,7 @@ are in fact case insensitive.
|
||||
|
||||
xforward-command = XFORWARD 1*( SP attribute-name"="attribute-value )
|
||||
|
||||
attribute-name = ( NAME | ADDR | PROTO | HELO | SOURCE )
|
||||
attribute-name = ( NAME | ADDR | PORT | PROTO | HELO | SOURCE )
|
||||
|
||||
attribute-value = xtext
|
||||
|
||||
@ -54,6 +54,9 @@ are in fact case insensitive.
|
||||
[UNAVAILABLE] when the information is unavailable. Address information is
|
||||
not enclosed with []. The address may be a non-IP address.
|
||||
|
||||
* The PORT attribute specifies an up-stream client TCP port number in
|
||||
decimal, or [UNAVAILABLE] when the information is unavailable.
|
||||
|
||||
* The PROTO attribute specifies the mail protocol for receiving mail from the
|
||||
up-stream host. This may be an SMTP or non-SMTP protocol name of up to 64
|
||||
characters, or [UNAVAILABLE] when the information is unavailable.
|
||||
|
@ -1,5 +1,12 @@
|
||||
Wish list:
|
||||
|
||||
Combine smtpd_peer.c and qmqpd_peer.c into a single function
|
||||
that produces a client context object, and provide attribute
|
||||
print/scan routines that pass these client context objects
|
||||
around. With this, we no longer have to update a multiple
|
||||
pieces of code when a client attribute is added. Ditto for
|
||||
SASL and TLS context.
|
||||
|
||||
Make TLS_BIO_BUFSIZE run-time adjustable, to future-proof
|
||||
Postfix for remote connections with MSS > 8 kbytes.
|
||||
|
||||
|
@ -22,20 +22,20 @@
|
||||
<p> Postfix version 2.3 introduces support for the Sendmail version
|
||||
8 Milter (mail filter) protocol. This protocol is used by applications
|
||||
that run outside the MTA to inspect SMTP events (CONNECT, DISCONNECT),
|
||||
SMTP commands (HELO, MAIL FROM, etc.) as well as mail content. All
|
||||
this happens before mail is queued. </p>
|
||||
SMTP commands (HELO, MAIL FROM, etc.) as well as mail content (headers
|
||||
and body). All this happens before mail is queued. </p>
|
||||
|
||||
<p> The reason for adding Milter support to Postfix is that there
|
||||
exists a large collection of applications, not only to block unwanted
|
||||
mail, but also to verify authenticity (examples: <a
|
||||
href="http://sourceforge.net/projects/dkim-milter/">Domain keys
|
||||
identified mail</a>, <a
|
||||
href="http://sourceforge.net/projects/dkim-milter/">DomainKeys
|
||||
Identified Mail (DKIM)</a>, <a
|
||||
href="http://sourceforge.net/projects/sid-milter/">SenderID+SPF</a> and
|
||||
<a href="http://sourceforge.net/projects/dk-milter/">Domain keys</a>)
|
||||
<a href="http://sourceforge.net/projects/dk-milter/">DomainKeys</a>)
|
||||
or to digitally sign mail (examples: <a
|
||||
href="http://sourceforge.net/projects/dkim-milter/">Domain keys
|
||||
identified mail</a>, <a
|
||||
href="http://sourceforge.net/projects/dk-milter/">Domain keys</a>).
|
||||
href="http://sourceforge.net/projects/dkim-milter/">DomainKeys
|
||||
Identified Mail (DKIM)</a>, <a
|
||||
href="http://sourceforge.net/projects/dk-milter/">DomainKeys</a>).
|
||||
Having yet another Postfix-specific version of all that software
|
||||
is a poor use of human and system resources. </p>
|
||||
|
||||
@ -548,6 +548,9 @@ Connection concurrency for this client </td> </tr>
|
||||
<tr> <td> {client_name} </td> <td> Always </td> <td> Client hostname,
|
||||
"unknown" when lookup or verification fails </td> </tr>
|
||||
|
||||
<tr> <td> {client_port} </td> <td> Always <br> (Postfix ≥2.5) </td>
|
||||
<td> Client TCP port </td> </tr>
|
||||
|
||||
<tr> <td> {client_ptr} </td> <td> CONNECT, HELO, MAIL, DATA </td>
|
||||
<td> Client name from reverse lookup, "unknown" when lookup fails
|
||||
</td> </tr>
|
||||
|
@ -77,7 +77,7 @@ names are shown in upper case, they are in fact case insensitive.
|
||||
xclient-command = XCLIENT 1*( SP attribute-name"="attribute-value )
|
||||
</p>
|
||||
<p>
|
||||
attribute-name = ( NAME | ADDR | PROTO | HELO )
|
||||
attribute-name = ( NAME | ADDR | PORT | PROTO | HELO )
|
||||
</p>
|
||||
<p>
|
||||
attribute-value = xtext
|
||||
@ -86,7 +86,7 @@ names are shown in upper case, they are in fact case insensitive.
|
||||
|
||||
<ul>
|
||||
|
||||
<li> <p> Attribute values are xtext encoded as per <a href="http://www.faqs.org/rfcs/rfc1891.html">RFC 1891</a>.
|
||||
<li> <p> Attribute values are xtext encoded as per <a href="http://tools.ietf.org/html/rfc1891">RFC 1891</a>.
|
||||
</p>
|
||||
|
||||
<li> <p> The NAME attribute specifies an SMTP client hostname
|
||||
@ -99,6 +99,10 @@ names are shown in upper case, they are in fact case insensitive.
|
||||
[UNAVAILABLE] when the address information is unavailable.
|
||||
Address information is not enclosed with []. </p>
|
||||
|
||||
<li> <p> The PORT attribute specifies the SMTP client TCP port
|
||||
number as a decimal number, or [UNAVAILABLE] when the information
|
||||
is unavailable. </p>
|
||||
|
||||
<li> <p> The PROTO attribute specifies either SMTP or ESMTP.
|
||||
</p>
|
||||
|
||||
@ -123,6 +127,9 @@ xtext encode attribute values. Servers that wish to interoperate
|
||||
with these older implementations should be prepared to receive
|
||||
unencoded information. </p>
|
||||
|
||||
<p> Note 4: Postfix implementations prior to version 2.5 do not
|
||||
implement the PORT attribute. </p>
|
||||
|
||||
<h2>XCLIENT Server response</h2>
|
||||
|
||||
<p> Upon receipt of a correctly formatted XCLIENT command, the
|
||||
@ -236,7 +243,7 @@ before each MAIL FROM command. </p>
|
||||
<h2> References </h2>
|
||||
|
||||
<p> Moore, K, "SMTP Service Extension for Delivery Status Notifications",
|
||||
<a href="http://www.faqs.org/rfcs/rfc1891.html">RFC 1891</a>, January 1996. </p>
|
||||
<a href="http://tools.ietf.org/html/rfc1891">RFC 1891</a>, January 1996. </p>
|
||||
|
||||
</body>
|
||||
|
||||
|
@ -68,7 +68,7 @@ names are shown in upper case, they are in fact case insensitive.
|
||||
xforward-command = XFORWARD 1*( SP attribute-name"="attribute-value )
|
||||
</p>
|
||||
<p>
|
||||
attribute-name = ( NAME | ADDR | PROTO | HELO | SOURCE )
|
||||
attribute-name = ( NAME | ADDR | PORT | PROTO | HELO | SOURCE )
|
||||
</p>
|
||||
<p>
|
||||
attribute-value = xtext
|
||||
@ -77,7 +77,7 @@ names are shown in upper case, they are in fact case insensitive.
|
||||
|
||||
<ul>
|
||||
|
||||
<li> <p> Attribute values are xtext encoded as per <a href="http://www.faqs.org/rfcs/rfc1891.html">RFC 1891</a>.
|
||||
<li> <p> Attribute values are xtext encoded as per <a href="http://tools.ietf.org/html/rfc1891">RFC 1891</a>.
|
||||
</p>
|
||||
|
||||
<li> <p> The NAME attribute specifies the up-stream hostname,
|
||||
@ -89,6 +89,10 @@ names are shown in upper case, they are in fact case insensitive.
|
||||
Address information is not enclosed with []. The address may
|
||||
be a non-IP address. </p>
|
||||
|
||||
<li> <p> The PORT attribute specifies an up-stream client TCP
|
||||
port number in decimal, or [UNAVAILABLE] when the information
|
||||
is unavailable. </p>
|
||||
|
||||
<li> <p> The PROTO attribute specifies the mail protocol for
|
||||
receiving mail from the up-stream host. This may be an SMTP or
|
||||
non-SMTP protocol name of up to 64 characters, or [UNAVAILABLE]
|
||||
@ -211,7 +215,7 @@ so there is no risk of information leakage. </p>
|
||||
<h2> References </h2>
|
||||
|
||||
<p> Moore, K, "SMTP Service Extension for Delivery Status Notifications",
|
||||
<a href="http://www.faqs.org/rfcs/rfc1891.html">RFC 1891</a>, January 1996. </p>
|
||||
<a href="http://tools.ietf.org/html/rfc1891">RFC 1891</a>, January 1996. </p>
|
||||
|
||||
</body>
|
||||
|
||||
|
@ -239,6 +239,12 @@ PIPE(8) PIPE(8)
|
||||
|
||||
This is available in Postfix 2.2 and later.
|
||||
|
||||
<b>${client_port</b>}
|
||||
This macro expands to the remote client TCP
|
||||
port number.
|
||||
|
||||
This is available in Postfix 2.5 and later.
|
||||
|
||||
<b>${client_protocol</b>}
|
||||
This macro expands to the remote client pro-
|
||||
tocol.
|
||||
|
@ -99,11 +99,6 @@ REGEXP_TABLE(5) REGEXP_TABLE(5)
|
||||
Toggles the case sensitivity flag. By default,
|
||||
matching is case insensitive.
|
||||
|
||||
<b>x</b> (default: on)
|
||||
Toggles the extended expression syntax flag. By
|
||||
default, support for extended expression syntax is
|
||||
enabled.
|
||||
|
||||
<b>m</b> (default: off)
|
||||
Toggle the multi-line mode flag. When this flag is
|
||||
on, the <b>^</b> and <b>$</b> metacharacters match immediately
|
||||
@ -111,6 +106,11 @@ REGEXP_TABLE(5) REGEXP_TABLE(5)
|
||||
respectively, in addition to matching at the start
|
||||
and end of the input string.
|
||||
|
||||
<b>x</b> (default: on)
|
||||
Toggles the extended expression syntax flag. By
|
||||
default, support for extended expression syntax is
|
||||
enabled.
|
||||
|
||||
<b>TABLE SEARCH ORDER</b>
|
||||
Patterns are applied in the order as specified in the ta-
|
||||
ble, until a pattern is found that matches the input
|
||||
|
@ -185,6 +185,15 @@ SMTP-SINK(1) SMTP-SINK(1)
|
||||
Wait <i>delay</i> seconds before responding to a DATA com-
|
||||
mand.
|
||||
|
||||
<b>-W</b> <i>command:delay[:odds]</i>
|
||||
Wait <i>delay</i> seconds before responding to <i>command</i>.
|
||||
If <i>odds</i> is also specified (a number between 1-99
|
||||
inclusive), wait for a random multiple of <i>delay</i>.
|
||||
The random multiplier is equal to the number of
|
||||
times the program needs to roll a dice with a range
|
||||
of 0..99 inclusive, before the dice produces a
|
||||
result greater than or equal to <i>odds</i>.
|
||||
|
||||
[<b>inet:</b>][<i>host</i>]:<i>port</i>
|
||||
Listen on network interface <i>host</i> (default: any
|
||||
interface) TCP port <i>port</i>. Both <i>host</i> and <i>port</i> may be
|
||||
|
@ -156,6 +156,13 @@ with super-user privileges. See also the \fB-R\fR option.
|
||||
Show the SMTP conversations.
|
||||
.IP "\fB-w \fIdelay\fR"
|
||||
Wait \fIdelay\fR seconds before responding to a DATA command.
|
||||
.IP "\fB-W \fIcommand:delay[:odds]\fR"
|
||||
Wait \fIdelay\fR seconds before responding to \fIcommand\fR.
|
||||
If \fIodds\fR is also specified (a number between 1-99
|
||||
inclusive), wait for a random multiple of \fIdelay\fR. The
|
||||
random multiplier is equal to the number of times the program
|
||||
needs to roll a dice with a range of 0..99 inclusive, before
|
||||
the dice produces a result greater than or equal to \fIodds\fR.
|
||||
.IP [\fBinet:\fR][\fIhost\fR]:\fIport\fR
|
||||
Listen on network interface \fIhost\fR (default: any interface)
|
||||
TCP port \fIport\fR. Both \fIhost\fR and \fIport\fR may be
|
||||
|
@ -91,14 +91,14 @@ characters after the pattern:
|
||||
.IP "\fBi\fR (default: on)"
|
||||
Toggles the case sensitivity flag. By default, matching is case
|
||||
insensitive.
|
||||
.IP "\fBx\fR (default: on)"
|
||||
Toggles the extended expression syntax flag. By default, support
|
||||
for extended expression syntax is enabled.
|
||||
.IP "\fBm\fR (default: off)"
|
||||
Toggle the multi-line mode flag. When this flag is on, the \fB^\fR
|
||||
and \fB$\fR metacharacters match immediately after and immediately
|
||||
before a newline character, respectively, in addition to
|
||||
matching at the start and end of the input string.
|
||||
.IP "\fBx\fR (default: on)"
|
||||
Toggles the extended expression syntax flag. By default, support
|
||||
for extended expression syntax is enabled.
|
||||
.SH "TABLE SEARCH ORDER"
|
||||
.na
|
||||
.nf
|
||||
|
@ -216,6 +216,10 @@ This is available in Postfix 2.2 and later.
|
||||
This macro expands to the remote client hostname.
|
||||
.sp
|
||||
This is available in Postfix 2.2 and later.
|
||||
.IP \fB${\fBclient_port\fR}\fR
|
||||
This macro expands to the remote client TCP port number.
|
||||
.sp
|
||||
This is available in Postfix 2.5 and later.
|
||||
.IP \fB${\fBclient_protocol\fR}\fR
|
||||
This macro expands to the remote client protocol.
|
||||
.sp
|
||||
|
@ -22,20 +22,20 @@
|
||||
<p> Postfix version 2.3 introduces support for the Sendmail version
|
||||
8 Milter (mail filter) protocol. This protocol is used by applications
|
||||
that run outside the MTA to inspect SMTP events (CONNECT, DISCONNECT),
|
||||
SMTP commands (HELO, MAIL FROM, etc.) as well as mail content. All
|
||||
this happens before mail is queued. </p>
|
||||
SMTP commands (HELO, MAIL FROM, etc.) as well as mail content (headers
|
||||
and body). All this happens before mail is queued. </p>
|
||||
|
||||
<p> The reason for adding Milter support to Postfix is that there
|
||||
exists a large collection of applications, not only to block unwanted
|
||||
mail, but also to verify authenticity (examples: <a
|
||||
href="http://sourceforge.net/projects/dkim-milter/">Domain keys
|
||||
identified mail</a>, <a
|
||||
href="http://sourceforge.net/projects/dkim-milter/">DomainKeys
|
||||
Identified Mail (DKIM)</a>, <a
|
||||
href="http://sourceforge.net/projects/sid-milter/">SenderID+SPF</a> and
|
||||
<a href="http://sourceforge.net/projects/dk-milter/">Domain keys</a>)
|
||||
<a href="http://sourceforge.net/projects/dk-milter/">DomainKeys</a>)
|
||||
or to digitally sign mail (examples: <a
|
||||
href="http://sourceforge.net/projects/dkim-milter/">Domain keys
|
||||
identified mail</a>, <a
|
||||
href="http://sourceforge.net/projects/dk-milter/">Domain keys</a>).
|
||||
href="http://sourceforge.net/projects/dkim-milter/">DomainKeys
|
||||
Identified Mail (DKIM)</a>, <a
|
||||
href="http://sourceforge.net/projects/dk-milter/">DomainKeys</a>).
|
||||
Having yet another Postfix-specific version of all that software
|
||||
is a poor use of human and system resources. </p>
|
||||
|
||||
@ -548,6 +548,9 @@ Connection concurrency for this client </td> </tr>
|
||||
<tr> <td> {client_name} </td> <td> Always </td> <td> Client hostname,
|
||||
"unknown" when lookup or verification fails </td> </tr>
|
||||
|
||||
<tr> <td> {client_port} </td> <td> Always <br> (Postfix ≥2.5) </td>
|
||||
<td> Client TCP port </td> </tr>
|
||||
|
||||
<tr> <td> {client_ptr} </td> <td> CONNECT, HELO, MAIL, DATA </td>
|
||||
<td> Client name from reverse lookup, "unknown" when lookup fails
|
||||
</td> </tr>
|
||||
|
@ -77,7 +77,7 @@ names are shown in upper case, they are in fact case insensitive.
|
||||
xclient-command = XCLIENT 1*( SP attribute-name"="attribute-value )
|
||||
</p>
|
||||
<p>
|
||||
attribute-name = ( NAME | ADDR | PROTO | HELO )
|
||||
attribute-name = ( NAME | ADDR | PORT | PROTO | HELO )
|
||||
</p>
|
||||
<p>
|
||||
attribute-value = xtext
|
||||
@ -99,6 +99,10 @@ names are shown in upper case, they are in fact case insensitive.
|
||||
[UNAVAILABLE] when the address information is unavailable.
|
||||
Address information is not enclosed with []. </p>
|
||||
|
||||
<li> <p> The PORT attribute specifies the SMTP client TCP port
|
||||
number as a decimal number, or [UNAVAILABLE] when the information
|
||||
is unavailable. </p>
|
||||
|
||||
<li> <p> The PROTO attribute specifies either SMTP or ESMTP.
|
||||
</p>
|
||||
|
||||
@ -123,6 +127,9 @@ xtext encode attribute values. Servers that wish to interoperate
|
||||
with these older implementations should be prepared to receive
|
||||
unencoded information. </p>
|
||||
|
||||
<p> Note 4: Postfix implementations prior to version 2.5 do not
|
||||
implement the PORT attribute. </p>
|
||||
|
||||
<h2>XCLIENT Server response</h2>
|
||||
|
||||
<p> Upon receipt of a correctly formatted XCLIENT command, the
|
||||
|
@ -68,7 +68,7 @@ names are shown in upper case, they are in fact case insensitive.
|
||||
xforward-command = XFORWARD 1*( SP attribute-name"="attribute-value )
|
||||
</p>
|
||||
<p>
|
||||
attribute-name = ( NAME | ADDR | PROTO | HELO | SOURCE )
|
||||
attribute-name = ( NAME | ADDR | PORT | PROTO | HELO | SOURCE )
|
||||
</p>
|
||||
<p>
|
||||
attribute-value = xtext
|
||||
@ -89,6 +89,10 @@ names are shown in upper case, they are in fact case insensitive.
|
||||
Address information is not enclosed with []. The address may
|
||||
be a non-IP address. </p>
|
||||
|
||||
<li> <p> The PORT attribute specifies an up-stream client TCP
|
||||
port number in decimal, or [UNAVAILABLE] when the information
|
||||
is unavailable. </p>
|
||||
|
||||
<li> <p> The PROTO attribute specifies the mail protocol for
|
||||
receiving mail from the up-stream host. This may be an SMTP or
|
||||
non-SMTP protocol name of up to 64 characters, or [UNAVAILABLE]
|
||||
|
@ -81,14 +81,14 @@
|
||||
# .IP "\fBi\fR (default: on)"
|
||||
# Toggles the case sensitivity flag. By default, matching is case
|
||||
# insensitive.
|
||||
# .IP "\fBx\fR (default: on)"
|
||||
# Toggles the extended expression syntax flag. By default, support
|
||||
# for extended expression syntax is enabled.
|
||||
# .IP "\fBm\fR (default: off)"
|
||||
# Toggle the multi-line mode flag. When this flag is on, the \fB^\fR
|
||||
# and \fB$\fR metacharacters match immediately after and immediately
|
||||
# before a newline character, respectively, in addition to
|
||||
# matching at the start and end of the input string.
|
||||
# .IP "\fBx\fR (default: on)"
|
||||
# Toggles the extended expression syntax flag. By default, support
|
||||
# for extended expression syntax is enabled.
|
||||
# TABLE SEARCH ORDER
|
||||
# .ad
|
||||
# .fi
|
||||
|
@ -1283,6 +1283,8 @@ static const char *cleanup_milter_eval(const char *name, void *ptr)
|
||||
return (state->client_addr);
|
||||
if (strcmp(name, S8_MAC_CLIENT_NAME) == 0)
|
||||
return (state->client_name);
|
||||
if (strcmp(name, S8_MAC_CLIENT_PORT) == 0)
|
||||
return (state->client_port);
|
||||
if (strcmp(name, S8_MAC_CLIENT_PTR) == 0)
|
||||
return (state->reverse_name);
|
||||
|
||||
@ -1450,6 +1452,7 @@ static void cleanup_milter_client_init(CLEANUP_STATE *state)
|
||||
state->client_af = atoi(proto_attr);
|
||||
if (state->reverse_name == 0)
|
||||
state->reverse_name = state->client_name;
|
||||
/* Compatibility with pre-2.5 queue files. */
|
||||
if (state->client_port == 0)
|
||||
state->client_port = NO_CLIENT_PORT;
|
||||
}
|
||||
|
@ -149,6 +149,7 @@
|
||||
|
||||
#include <sys_defs.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <utime.h>
|
||||
@ -576,6 +577,11 @@ static int flush_send_path(const char *path, int how)
|
||||
if (count > 0 && ftruncate(vstream_fileno(log), (off_t) 0) < 0)
|
||||
msg_fatal("%s: truncate fast flush logfile %s: %m", myname, path);
|
||||
|
||||
/*
|
||||
* Workaround for noatime mounts. Use futimes() if available.
|
||||
*/
|
||||
(void) utimes(VSTREAM_PATH(log), (struct timeval *) 0);
|
||||
|
||||
/*
|
||||
* Request delivery and clean up.
|
||||
*/
|
||||
|
@ -109,13 +109,17 @@ static int deliver_pass_send_request(VSTREAM *stream, DELIVER_REQUEST *request,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_DSN_ENVID, request->dsn_envid,
|
||||
ATTR_TYPE_INT, MAIL_ATTR_DSN_RET, request->dsn_ret,
|
||||
ATTR_TYPE_FUNC, msg_stats_print, (void *) &request->msg_stats,
|
||||
/* XXX Should be encapsulated with ATTR_TYPE_FUNC. */
|
||||
ATTR_TYPE_STR, MAIL_ATTR_LOG_CLIENT_NAME, request->client_name,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_LOG_CLIENT_ADDR, request->client_addr,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_LOG_CLIENT_PORT, request->client_port,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_LOG_PROTO_NAME, request->client_proto,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_LOG_HELO_NAME, request->client_helo,
|
||||
/* XXX Should be encapsulated with ATTR_TYPE_FUNC. */
|
||||
ATTR_TYPE_STR, MAIL_ATTR_SASL_METHOD, request->sasl_method,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_SASL_USERNAME, request->sasl_username,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_SASL_SENDER, request->sasl_sender,
|
||||
/* XXX Ditto if we want to pass TLS certificate info. */
|
||||
ATTR_TYPE_STR, MAIL_ATTR_RWR_CONTEXT, request->rewrite_context,
|
||||
ATTR_TYPE_INT, MAIL_ATTR_RCPT_COUNT, 1,
|
||||
ATTR_TYPE_END);
|
||||
|
@ -22,6 +22,7 @@
|
||||
/* DSN *hop_status;
|
||||
/* char *client_name;
|
||||
/* char *client_addr;
|
||||
/* char *client_port;
|
||||
/* char *client_proto;
|
||||
/* char *client_helo;
|
||||
/* char *sasl_method;
|
||||
@ -195,6 +196,7 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request)
|
||||
static VSTRING *address;
|
||||
static VSTRING *client_name;
|
||||
static VSTRING *client_addr;
|
||||
static VSTRING *client_port;
|
||||
static VSTRING *client_proto;
|
||||
static VSTRING *client_helo;
|
||||
static VSTRING *sasl_method;
|
||||
@ -219,6 +221,7 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request)
|
||||
address = vstring_alloc(10);
|
||||
client_name = vstring_alloc(10);
|
||||
client_addr = vstring_alloc(10);
|
||||
client_port = vstring_alloc(10);
|
||||
client_proto = vstring_alloc(10);
|
||||
client_helo = vstring_alloc(10);
|
||||
sasl_method = vstring_alloc(10);
|
||||
@ -245,16 +248,20 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request)
|
||||
ATTR_TYPE_STR, MAIL_ATTR_DSN_ENVID, dsn_envid,
|
||||
ATTR_TYPE_INT, MAIL_ATTR_DSN_RET, &dsn_ret,
|
||||
ATTR_TYPE_FUNC, msg_stats_scan, (void *) &request->msg_stats,
|
||||
/* XXX Should be encapsulated with ATTR_TYPE_FUNC. */
|
||||
ATTR_TYPE_STR, MAIL_ATTR_LOG_CLIENT_NAME, client_name,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_LOG_CLIENT_ADDR, client_addr,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_LOG_CLIENT_PORT, client_port,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_LOG_PROTO_NAME, client_proto,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_LOG_HELO_NAME, client_helo,
|
||||
/* XXX Should be encapsulated with ATTR_TYPE_FUNC. */
|
||||
ATTR_TYPE_STR, MAIL_ATTR_SASL_METHOD, sasl_method,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_SASL_USERNAME, sasl_username,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_SASL_SENDER, sasl_sender,
|
||||
/* XXX Ditto if we want to pass TLS certificate info. */
|
||||
ATTR_TYPE_STR, MAIL_ATTR_RWR_CONTEXT, rewrite_context,
|
||||
ATTR_TYPE_INT, MAIL_ATTR_RCPT_COUNT, &rcpt_count,
|
||||
ATTR_TYPE_END) != 20) {
|
||||
ATTR_TYPE_END) != 21) {
|
||||
msg_warn("%s: error receiving common attributes", myname);
|
||||
return (-1);
|
||||
}
|
||||
@ -273,6 +280,7 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request)
|
||||
request->sender = mystrdup(vstring_str(address));
|
||||
request->client_name = mystrdup(vstring_str(client_name));
|
||||
request->client_addr = mystrdup(vstring_str(client_addr));
|
||||
request->client_port = mystrdup(vstring_str(client_port));
|
||||
request->client_proto = mystrdup(vstring_str(client_proto));
|
||||
request->client_helo = mystrdup(vstring_str(client_helo));
|
||||
request->sasl_method = mystrdup(vstring_str(sasl_method));
|
||||
@ -353,6 +361,7 @@ static DELIVER_REQUEST *deliver_request_alloc(void)
|
||||
request->hop_status = 0;
|
||||
request->client_name = 0;
|
||||
request->client_addr = 0;
|
||||
request->client_port = 0;
|
||||
request->client_proto = 0;
|
||||
request->client_helo = 0;
|
||||
request->sasl_method = 0;
|
||||
@ -386,6 +395,8 @@ static void deliver_request_free(DELIVER_REQUEST *request)
|
||||
myfree(request->client_name);
|
||||
if (request->client_addr)
|
||||
myfree(request->client_addr);
|
||||
if (request->client_port)
|
||||
myfree(request->client_port);
|
||||
if (request->client_proto)
|
||||
myfree(request->client_proto);
|
||||
if (request->client_helo)
|
||||
|
@ -42,6 +42,7 @@ typedef struct DELIVER_REQUEST {
|
||||
DSN *hop_status; /* DSN status */
|
||||
char *client_name; /* client hostname */
|
||||
char *client_addr; /* client address */
|
||||
char *client_port; /* client port */
|
||||
char *client_proto; /* client protocol */
|
||||
char *client_helo; /* helo parameter */
|
||||
char *sasl_method; /* SASL method */
|
||||
|
@ -5,7 +5,7 @@
|
||||
/* NAME
|
||||
/* mail_proto 3h
|
||||
/* SUMMARY
|
||||
/* mail internal IPC support
|
||||
/* mail internal and external protocol support
|
||||
/* SYNOPSIS
|
||||
/* #include <mail_proto.h>
|
||||
/* DESCRIPTION
|
||||
@ -169,9 +169,10 @@ extern char *mail_pathname(const char *, const char *);
|
||||
|
||||
#define MAIL_ATTR_LOG_CLIENT_NAME "log_client_name" /* client hostname */
|
||||
#define MAIL_ATTR_LOG_CLIENT_ADDR "log_client_address" /* client address */
|
||||
#define MAIL_ATTR_LOG_CLIENT_PORT "log_client_port" /* client port */
|
||||
#define MAIL_ATTR_LOG_HELO_NAME "log_helo_name" /* SMTP helo name */
|
||||
#define MAIL_ATTR_LOG_PROTO_NAME "log_protocol_name" /* SMTP/ESMTP/QMQP */
|
||||
#define MAIL_ATTR_LOG_ORIGIN "log_message_origin" /* hostname[address] */
|
||||
#define MAIL_ATTR_LOG_ORIGIN "log_message_origin" /* name[addr]:port */
|
||||
|
||||
#define MAIL_ATTR_ACT_CLIENT "client"/* client name addr */
|
||||
#define MAIL_ATTR_ACT_CLIENT_NAME "client_name" /* client name */
|
||||
@ -197,6 +198,7 @@ extern char *mail_pathname(const char *, const char *);
|
||||
#define XCLIENT_FORWARD_NAME "FORWARD_NAME" /* forward client name */
|
||||
#endif
|
||||
#define XCLIENT_ADDR "ADDR" /* client address */
|
||||
#define XCLIENT_PORT "PORT" /* client port */
|
||||
#define XCLIENT_PROTO "PROTO" /* client protocol */
|
||||
#define XCLIENT_HELO "HELO" /* client helo */
|
||||
|
||||
@ -206,6 +208,7 @@ extern char *mail_pathname(const char *, const char *);
|
||||
#define XFORWARD_CMD "XFORWARD" /* XFORWARD command */
|
||||
#define XFORWARD_NAME "NAME" /* client name */
|
||||
#define XFORWARD_ADDR "ADDR" /* client address */
|
||||
#define XFORWARD_PORT "PORT" /* client port */
|
||||
#define XFORWARD_PROTO "PROTO" /* client protocol */
|
||||
#define XFORWARD_HELO "HELO" /* client helo */
|
||||
#define XFORWARD_IDENT "IDENT" /* message identifier */
|
||||
|
@ -20,7 +20,7 @@
|
||||
* Patches change both the patchlevel and the release date. Snapshots have no
|
||||
* patchlevel; they change the release date only.
|
||||
*/
|
||||
#define MAIL_RELEASE_DATE "20070911"
|
||||
#define MAIL_RELEASE_DATE "20071004"
|
||||
#define MAIL_VERSION_NUMBER "2.5"
|
||||
|
||||
#ifdef SNAPSHOT
|
||||
|
@ -125,6 +125,7 @@ extern void milter_free(MILTERS *);
|
||||
#define S8_MAC_CLIENT_ADDR "{client_addr}"
|
||||
#define S8_MAC_CLIENT_CONN "{client_connections}"
|
||||
#define S8_MAC_CLIENT_NAME "{client_name}"
|
||||
#define S8_MAC_CLIENT_PORT "{client_port}"
|
||||
#define S8_MAC_CLIENT_PTR "{client_ptr}"
|
||||
#define S8_MAC_CLIENT_RES "{client_resolve}"
|
||||
|
||||
|
@ -162,7 +162,7 @@ static sfsistat test_connect(SMFICTX *ctx, char *name, struct sockaddr * sa)
|
||||
print_addr = inet_ntop(AF_INET, &sin->sin_addr, buf, sizeof(buf));
|
||||
if (print_addr == 0)
|
||||
print_addr = strerror(errno);
|
||||
printf("AF_INET (%s)\n", print_addr);
|
||||
printf("AF_INET (%s:%d)\n", print_addr, ntohs(sin->sin_port));
|
||||
}
|
||||
break;
|
||||
#ifdef HAS_IPV6
|
||||
@ -173,7 +173,7 @@ static sfsistat test_connect(SMFICTX *ctx, char *name, struct sockaddr * sa)
|
||||
print_addr = inet_ntop(AF_INET, &sin6->sin6_addr, buf, sizeof(buf));
|
||||
if (print_addr == 0)
|
||||
print_addr = strerror(errno);
|
||||
printf("AF_INET6 (%s)\n", print_addr);
|
||||
printf("AF_INET6 (%s:%d)\n", print_addr, ntohs(sin6->sin6_port));
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
@ -235,6 +235,7 @@ struct QMGR_MESSAGE {
|
||||
long rcpt_offset; /* more recipients here */
|
||||
char *client_name; /* client hostname */
|
||||
char *client_addr; /* client address */
|
||||
char *client_port; /* client port */
|
||||
char *client_proto; /* client protocol */
|
||||
char *client_helo; /* helo parameter */
|
||||
char *sasl_method; /* SASL method */
|
||||
|
@ -130,8 +130,6 @@ static void qmgr_active_corrupt(const char *queue_id)
|
||||
if (errno != ENOENT)
|
||||
msg_fatal("%s: save corrupt file queue %s id %s: %m",
|
||||
myname, MAIL_QUEUE_ACTIVE, queue_id);
|
||||
msg_warn("%s: save corrupt file queue %s id %s: %m",
|
||||
myname, MAIL_QUEUE_ACTIVE, queue_id);
|
||||
} else {
|
||||
msg_warn("saving corrupt file \"%s\" from queue \"%s\" to queue \"%s\"",
|
||||
queue_id, MAIL_QUEUE_ACTIVE, MAIL_QUEUE_CORRUPT);
|
||||
|
@ -165,13 +165,17 @@ static int qmgr_deliver_send_request(QMGR_ENTRY *entry, VSTREAM *stream)
|
||||
ATTR_TYPE_STR, MAIL_ATTR_DSN_ENVID, message->dsn_envid,
|
||||
ATTR_TYPE_INT, MAIL_ATTR_DSN_RET, message->dsn_ret,
|
||||
ATTR_TYPE_FUNC, msg_stats_print, (void *) &stats,
|
||||
/* XXX Should be encapsulated with ATTR_TYPE_FUNC. */
|
||||
ATTR_TYPE_STR, MAIL_ATTR_LOG_CLIENT_NAME, message->client_name,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_LOG_CLIENT_ADDR, message->client_addr,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_LOG_CLIENT_PORT, message->client_port,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_LOG_PROTO_NAME, message->client_proto,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_LOG_HELO_NAME, message->client_helo,
|
||||
/* XXX Should be encapsulated with ATTR_TYPE_FUNC. */
|
||||
ATTR_TYPE_STR, MAIL_ATTR_SASL_METHOD, message->sasl_method,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_SASL_USERNAME, message->sasl_username,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_SASL_SENDER, message->sasl_sender,
|
||||
/* XXX Ditto if we want to pass TLS certificate info. */
|
||||
ATTR_TYPE_STR, MAIL_ATTR_RWR_CONTEXT, message->rewrite_context,
|
||||
ATTR_TYPE_INT, MAIL_ATTR_RCPT_COUNT, list.len,
|
||||
ATTR_TYPE_END);
|
||||
|
@ -179,6 +179,7 @@ static QMGR_MESSAGE *qmgr_message_create(const char *queue_name,
|
||||
message->verp_delims = 0;
|
||||
message->client_name = 0;
|
||||
message->client_addr = 0;
|
||||
message->client_port = 0;
|
||||
message->client_proto = 0;
|
||||
message->client_helo = 0;
|
||||
message->sasl_method = 0;
|
||||
@ -634,6 +635,10 @@ static int qmgr_message_read(QMGR_MESSAGE *message)
|
||||
if (message->client_addr != 0)
|
||||
myfree(message->client_addr);
|
||||
message->client_addr = mystrdup(value);
|
||||
} else if (strcmp(name, MAIL_ATTR_LOG_CLIENT_PORT) == 0) {
|
||||
if (message->client_port != 0)
|
||||
myfree(message->client_port);
|
||||
message->client_port = mystrdup(value);
|
||||
} else if (strcmp(name, MAIL_ATTR_LOG_PROTO_NAME) == 0) {
|
||||
if (message->client_proto != 0)
|
||||
myfree(message->client_proto);
|
||||
@ -735,6 +740,8 @@ static int qmgr_message_read(QMGR_MESSAGE *message)
|
||||
message->client_name = mystrdup("");
|
||||
if (message->client_addr == 0)
|
||||
message->client_addr = mystrdup("");
|
||||
if (message->client_port == 0)
|
||||
message->client_port = mystrdup("");
|
||||
if (message->client_proto == 0)
|
||||
message->client_proto = mystrdup("");
|
||||
if (message->client_helo == 0)
|
||||
@ -1253,6 +1260,8 @@ void qmgr_message_free(QMGR_MESSAGE *message)
|
||||
myfree(message->client_name);
|
||||
if (message->client_addr)
|
||||
myfree(message->client_addr);
|
||||
if (message->client_port)
|
||||
myfree(message->client_port);
|
||||
if (message->client_proto)
|
||||
myfree(message->client_proto);
|
||||
if (message->client_helo)
|
||||
|
@ -206,6 +206,10 @@
|
||||
/* This macro expands to the remote client hostname.
|
||||
/* .sp
|
||||
/* This is available in Postfix 2.2 and later.
|
||||
/* .IP \fB${\fBclient_port\fR}\fR
|
||||
/* This macro expands to the remote client TCP port number.
|
||||
/* .sp
|
||||
/* This is available in Postfix 2.5 and later.
|
||||
/* .IP \fB${\fBclient_protocol\fR}\fR
|
||||
/* This macro expands to the remote client protocol.
|
||||
/* .sp
|
||||
@ -474,6 +478,7 @@
|
||||
#define PIPE_DICT_SIZE "size" /* key */
|
||||
#define PIPE_DICT_CLIENT_ADDR "client_address" /* key */
|
||||
#define PIPE_DICT_CLIENT_NAME "client_hostname" /* key */
|
||||
#define PIPE_DICT_CLIENT_PORT "client_port" /* key */
|
||||
#define PIPE_DICT_CLIENT_PROTO "client_protocol" /* key */
|
||||
#define PIPE_DICT_CLIENT_HELO "client_helo" /* key */
|
||||
#define PIPE_DICT_SASL_METHOD "sasl_method" /* key */
|
||||
@ -570,6 +575,7 @@ static int parse_callback(int type, VSTRING *buf, char *context)
|
||||
PIPE_DICT_SIZE, 0,
|
||||
PIPE_DICT_CLIENT_ADDR, 0,
|
||||
PIPE_DICT_CLIENT_NAME, 0,
|
||||
PIPE_DICT_CLIENT_PORT, 0,
|
||||
PIPE_DICT_CLIENT_PROTO, 0,
|
||||
PIPE_DICT_CLIENT_HELO, 0,
|
||||
PIPE_DICT_SASL_METHOD, 0,
|
||||
@ -1177,6 +1183,8 @@ static int deliver_message(DELIVER_REQUEST *request, char *service, char **argv)
|
||||
request->client_helo);
|
||||
dict_update(PIPE_DICT_TABLE, PIPE_DICT_CLIENT_NAME,
|
||||
request->client_name);
|
||||
dict_update(PIPE_DICT_TABLE, PIPE_DICT_CLIENT_PORT,
|
||||
request->client_port);
|
||||
dict_update(PIPE_DICT_TABLE, PIPE_DICT_CLIENT_PROTO,
|
||||
request->client_proto);
|
||||
dict_update(PIPE_DICT_TABLE, PIPE_DICT_SASL_METHOD,
|
||||
|
@ -280,6 +280,7 @@ struct QMGR_MESSAGE {
|
||||
long rcpt_offset; /* more recipients here */
|
||||
char *client_name; /* client hostname */
|
||||
char *client_addr; /* client address */
|
||||
char *client_port; /* client port */
|
||||
char *client_proto; /* client protocol */
|
||||
char *client_helo; /* helo parameter */
|
||||
char *sasl_method; /* SASL method */
|
||||
|
@ -130,8 +130,6 @@ static void qmgr_active_corrupt(const char *queue_id)
|
||||
if (errno != ENOENT)
|
||||
msg_fatal("%s: save corrupt file queue %s id %s: %m",
|
||||
myname, MAIL_QUEUE_ACTIVE, queue_id);
|
||||
msg_warn("%s: save corrupt file queue %s id %s: %m",
|
||||
myname, MAIL_QUEUE_ACTIVE, queue_id);
|
||||
} else {
|
||||
msg_warn("saving corrupt file \"%s\" from queue \"%s\" to queue \"%s\"",
|
||||
queue_id, MAIL_QUEUE_ACTIVE, MAIL_QUEUE_CORRUPT);
|
||||
|
@ -170,13 +170,17 @@ static int qmgr_deliver_send_request(QMGR_ENTRY *entry, VSTREAM *stream)
|
||||
ATTR_TYPE_STR, MAIL_ATTR_DSN_ENVID, message->dsn_envid,
|
||||
ATTR_TYPE_INT, MAIL_ATTR_DSN_RET, message->dsn_ret,
|
||||
ATTR_TYPE_FUNC, msg_stats_print, (void *) &stats,
|
||||
/* XXX Should be encapsulated with ATTR_TYPE_FUNC. */
|
||||
ATTR_TYPE_STR, MAIL_ATTR_LOG_CLIENT_NAME, message->client_name,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_LOG_CLIENT_ADDR, message->client_addr,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_LOG_CLIENT_PORT, message->client_port,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_LOG_PROTO_NAME, message->client_proto,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_LOG_HELO_NAME, message->client_helo,
|
||||
/* XXX Should be encapsulated with ATTR_TYPE_FUNC. */
|
||||
ATTR_TYPE_STR, MAIL_ATTR_SASL_METHOD, message->sasl_method,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_SASL_USERNAME, message->sasl_username,
|
||||
ATTR_TYPE_STR, MAIL_ATTR_SASL_SENDER, message->sasl_sender,
|
||||
/* XXX Ditto if we want to pass TLS certificate info. */
|
||||
ATTR_TYPE_STR, MAIL_ATTR_RWR_CONTEXT, message->rewrite_context,
|
||||
ATTR_TYPE_INT, MAIL_ATTR_RCPT_COUNT, list.len,
|
||||
ATTR_TYPE_END);
|
||||
|
@ -190,6 +190,7 @@ static QMGR_MESSAGE *qmgr_message_create(const char *queue_name,
|
||||
message->verp_delims = 0;
|
||||
message->client_name = 0;
|
||||
message->client_addr = 0;
|
||||
message->client_port = 0;
|
||||
message->client_proto = 0;
|
||||
message->client_helo = 0;
|
||||
message->sasl_method = 0;
|
||||
@ -675,6 +676,10 @@ static int qmgr_message_read(QMGR_MESSAGE *message)
|
||||
if (message->client_addr != 0)
|
||||
myfree(message->client_addr);
|
||||
message->client_addr = mystrdup(value);
|
||||
} else if (strcmp(name, MAIL_ATTR_LOG_CLIENT_PORT) == 0) {
|
||||
if (message->client_port != 0)
|
||||
myfree(message->client_port);
|
||||
message->client_port = mystrdup(value);
|
||||
} else if (strcmp(name, MAIL_ATTR_LOG_PROTO_NAME) == 0) {
|
||||
if (message->client_proto != 0)
|
||||
myfree(message->client_proto);
|
||||
@ -783,6 +788,8 @@ static int qmgr_message_read(QMGR_MESSAGE *message)
|
||||
message->client_name = mystrdup("");
|
||||
if (message->client_addr == 0)
|
||||
message->client_addr = mystrdup("");
|
||||
if (message->client_port == 0)
|
||||
message->client_port = mystrdup("");
|
||||
if (message->client_proto == 0)
|
||||
message->client_proto = mystrdup("");
|
||||
if (message->client_helo == 0)
|
||||
@ -1374,6 +1381,8 @@ void qmgr_message_free(QMGR_MESSAGE *message)
|
||||
myfree(message->client_name);
|
||||
if (message->client_addr)
|
||||
myfree(message->client_addr);
|
||||
if (message->client_port)
|
||||
myfree(message->client_port);
|
||||
if (message->client_proto)
|
||||
myfree(message->client_proto);
|
||||
if (message->client_helo)
|
||||
|
@ -322,6 +322,9 @@ static void qmqpd_write_attributes(QMQPD_STATE *state)
|
||||
if (IS_AVAIL_CLIENT_ADDR(state->addr))
|
||||
rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s",
|
||||
MAIL_ATTR_LOG_CLIENT_ADDR, state->rfc_addr);
|
||||
if (IS_AVAIL_CLIENT_PORT(state->port))
|
||||
rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s",
|
||||
MAIL_ATTR_LOG_CLIENT_PORT, state->port);
|
||||
if (IS_AVAIL_CLIENT_NAMADDR(state->namaddr))
|
||||
rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s",
|
||||
MAIL_ATTR_LOG_ORIGIN, state->namaddr);
|
||||
@ -335,6 +338,8 @@ static void qmqpd_write_attributes(QMQPD_STATE *state)
|
||||
MAIL_ATTR_ACT_CLIENT_NAME, state->name);
|
||||
rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s",
|
||||
MAIL_ATTR_ACT_CLIENT_ADDR, state->rfc_addr);
|
||||
rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s",
|
||||
MAIL_ATTR_ACT_CLIENT_PORT, state->port);
|
||||
rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%u",
|
||||
MAIL_ATTR_ACT_CLIENT_AF, state->addr_family);
|
||||
}
|
||||
|
@ -35,7 +35,8 @@ typedef struct {
|
||||
struct timeval arrival_time; /* start of session */
|
||||
char *name; /* client name */
|
||||
char *addr; /* client IP address */
|
||||
char *namaddr; /* name[addr] */
|
||||
char *port; /* client TCP port */
|
||||
char *namaddr; /* name[addr]:port */
|
||||
char *rfc_addr; /* RFC 2821 client IP address */
|
||||
int addr_family; /* address family */
|
||||
char *queue_id; /* queue file ID */
|
||||
@ -60,12 +61,14 @@ typedef struct {
|
||||
|
||||
#define CLIENT_NAME_UNKNOWN CLIENT_ATTR_UNKNOWN
|
||||
#define CLIENT_ADDR_UNKNOWN CLIENT_ATTR_UNKNOWN
|
||||
#define CLIENT_PORT_UNKNOWN CLIENT_ATTR_UNKNOWN
|
||||
#define CLIENT_NAMADDR_UNKNOWN CLIENT_ATTR_UNKNOWN
|
||||
|
||||
#define IS_AVAIL_CLIENT_ATTR(v) ((v) && strcmp((v), CLIENT_ATTR_UNKNOWN))
|
||||
|
||||
#define IS_AVAIL_CLIENT_NAME(v) IS_AVAIL_CLIENT_ATTR(v)
|
||||
#define IS_AVAIL_CLIENT_ADDR(v) IS_AVAIL_CLIENT_ATTR(v)
|
||||
#define IS_AVAIL_CLIENT_PORT(v) IS_AVAIL_CLIENT_ATTR(v)
|
||||
#define IS_AVAIL_CLIENT_NAMADDR(v) IS_AVAIL_CLIENT_ATTR(v)
|
||||
|
||||
/*
|
||||
|
@ -24,7 +24,7 @@
|
||||
/* .IP addr
|
||||
/* Printable representation of the client address.
|
||||
/* .IP namaddr
|
||||
/* String of the form: "name[addr]".
|
||||
/* String of the form: "name[addr]:port".
|
||||
/* .PP
|
||||
/* qmqpd_peer_reset() releases memory allocated by qmqpd_peer_init().
|
||||
/* LICENSE
|
||||
@ -96,6 +96,7 @@ void qmqpd_peer_init(QMQPD_STATE *state)
|
||||
state->addr = mystrdup(CLIENT_ADDR_UNKNOWN);
|
||||
state->rfc_addr = mystrdup(CLIENT_ADDR_UNKNOWN);
|
||||
state->addr_family = AF_UNSPEC;
|
||||
state->port = mystrdup(CLIENT_PORT_UNKNOWN);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -114,6 +115,7 @@ void qmqpd_peer_init(QMQPD_STATE *state)
|
||||
)) {
|
||||
MAI_HOSTNAME_STR client_name;
|
||||
MAI_HOSTADDR_STR client_addr;
|
||||
MAI_SERVPORT_STR client_port;
|
||||
int aierr;
|
||||
char *colonp;
|
||||
|
||||
@ -143,9 +145,10 @@ void qmqpd_peer_init(QMQPD_STATE *state)
|
||||
* Convert the client address to printable form.
|
||||
*/
|
||||
if ((aierr = sockaddr_to_hostaddr(sa, sa_length, &client_addr,
|
||||
(MAI_SERVPORT_STR *) 0, 0)) != 0)
|
||||
msg_fatal("%s: cannot convert client address to string: %s",
|
||||
&client_port, 0)) != 0)
|
||||
msg_fatal("%s: cannot convert client address/port to string: %s",
|
||||
myname, MAI_STRERROR(aierr));
|
||||
state->port = mystrdup(client_port.buf);
|
||||
|
||||
/*
|
||||
* We convert IPv4-in-IPv6 address to 'true' IPv4 address early on,
|
||||
@ -266,13 +269,15 @@ void qmqpd_peer_init(QMQPD_STATE *state)
|
||||
state->addr = mystrdup("127.0.0.1"); /* XXX bogus. */
|
||||
state->rfc_addr = mystrdup("127.0.0.1");/* XXX bogus. */
|
||||
state->addr_family = AF_UNSPEC;
|
||||
state->port = mystrdup("0"); /* XXX bogus. */
|
||||
}
|
||||
|
||||
/*
|
||||
* Do the name[addr] formatting for pretty reports.
|
||||
* Do the name[addr]:port formatting for pretty reports.
|
||||
*/
|
||||
state->namaddr =
|
||||
concatenate(state->name, "[", state->addr, "]", (char *) 0);
|
||||
concatenate(state->name, "[", state->addr,
|
||||
"]:", state->port, (char *) 0);
|
||||
}
|
||||
|
||||
/* qmqpd_peer_reset - destroy peer information */
|
||||
@ -283,4 +288,5 @@ void qmqpd_peer_reset(QMQPD_STATE *state)
|
||||
myfree(state->addr);
|
||||
myfree(state->namaddr);
|
||||
myfree(state->rfc_addr);
|
||||
myfree(state->port);
|
||||
}
|
||||
|
@ -117,6 +117,7 @@ typedef struct SMTP_STATE {
|
||||
#define SMTP_FEATURE_DSN (1<<15) /* DSN supported */
|
||||
#define SMTP_FEATURE_PIX_NO_ESMTP (1<<16) /* PIX smtp fixup mode */
|
||||
#define SMTP_FEATURE_PIX_DELAY_DOTCRLF (1<<17) /* PIX smtp fixup mode */
|
||||
#define SMTP_FEATURE_XFORWARD_PORT (1<<18)
|
||||
|
||||
/*
|
||||
* Features that passivate under the endpoint.
|
||||
|
@ -255,6 +255,7 @@ int smtp_helo(SMTP_STATE *state)
|
||||
static NAME_CODE xforward_features[] = {
|
||||
XFORWARD_NAME, SMTP_FEATURE_XFORWARD_NAME,
|
||||
XFORWARD_ADDR, SMTP_FEATURE_XFORWARD_ADDR,
|
||||
XFORWARD_PORT, SMTP_FEATURE_XFORWARD_PORT,
|
||||
XFORWARD_PROTO, SMTP_FEATURE_XFORWARD_PROTO,
|
||||
XFORWARD_HELO, SMTP_FEATURE_XFORWARD_HELO,
|
||||
XFORWARD_DOMAIN, SMTP_FEATURE_XFORWARD_DOMAIN,
|
||||
@ -1167,6 +1168,12 @@ static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state,
|
||||
DEL_REQ_ATTR_AVAIL(request->client_addr) ?
|
||||
request->client_addr : XFORWARD_UNAVAILABLE, "");
|
||||
}
|
||||
if (session->features & SMTP_FEATURE_XFORWARD_PORT) {
|
||||
vstring_strcat(next_command, " " XFORWARD_PORT "=");
|
||||
xtext_quote_append(next_command,
|
||||
DEL_REQ_ATTR_AVAIL(request->client_port) ?
|
||||
request->client_port : XFORWARD_UNAVAILABLE, "");
|
||||
}
|
||||
if (session->send_proto_helo)
|
||||
next_state = SMTP_STATE_XFORWARD_PROTO_HELO;
|
||||
else
|
||||
|
@ -1533,13 +1533,13 @@ static int ehlo_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
|
||||
ENQUEUE_FIX_REPLY(state, reply_buf, XCLIENT_CMD
|
||||
" " XCLIENT_NAME " " XCLIENT_ADDR
|
||||
" " XCLIENT_PROTO " " XCLIENT_HELO
|
||||
" " XCLIENT_REVERSE_NAME);
|
||||
" " XCLIENT_REVERSE_NAME " " XCLIENT_PORT);
|
||||
if ((discard_mask & EHLO_MASK_XFORWARD) == 0)
|
||||
if (xforward_allowed)
|
||||
ENQUEUE_FIX_REPLY(state, reply_buf, XFORWARD_CMD
|
||||
" " XFORWARD_NAME " " XFORWARD_ADDR
|
||||
" " XFORWARD_PROTO " " XFORWARD_HELO
|
||||
" " XFORWARD_DOMAIN);
|
||||
" " XFORWARD_DOMAIN " " XFORWARD_PORT);
|
||||
if ((discard_mask & EHLO_MASK_ENHANCEDSTATUSCODES) == 0)
|
||||
ENQUEUE_FIX_REPLY(state, reply_buf, "ENHANCEDSTATUSCODES");
|
||||
if ((discard_mask & EHLO_MASK_8BITMIME) == 0)
|
||||
@ -1716,6 +1716,9 @@ static int mail_open_stream(SMTPD_STATE *state)
|
||||
if (IS_AVAIL_CLIENT_ADDR(FORWARD_ADDR(state)))
|
||||
rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s",
|
||||
MAIL_ATTR_LOG_CLIENT_ADDR, FORWARD_ADDR(state));
|
||||
if (IS_AVAIL_CLIENT_PORT(FORWARD_PORT(state)))
|
||||
rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s",
|
||||
MAIL_ATTR_LOG_CLIENT_PORT, FORWARD_PORT(state));
|
||||
if (IS_AVAIL_CLIENT_NAMADDR(FORWARD_NAMADDR(state)))
|
||||
rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s",
|
||||
MAIL_ATTR_LOG_ORIGIN, FORWARD_NAMADDR(state));
|
||||
@ -1736,6 +1739,8 @@ static int mail_open_stream(SMTPD_STATE *state)
|
||||
MAIL_ATTR_ACT_REVERSE_CLIENT_NAME, state->reverse_name);
|
||||
rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s",
|
||||
MAIL_ATTR_ACT_CLIENT_ADDR, state->addr);
|
||||
rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s",
|
||||
MAIL_ATTR_ACT_CLIENT_PORT, state->port);
|
||||
if (state->helo_name)
|
||||
rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s",
|
||||
MAIL_ATTR_ACT_HELO_NAME, state->helo_name);
|
||||
@ -3294,6 +3299,25 @@ static int xclient_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
|
||||
update_namaddr = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* PORT=substitute SMTP client port number.
|
||||
*/
|
||||
else if (STREQ(attr_name, XCLIENT_PORT)) {
|
||||
if (STREQ(attr_value, XCLIENT_UNAVAILABLE)) {
|
||||
attr_value = CLIENT_PORT_UNKNOWN;
|
||||
} else {
|
||||
if (!alldig(attr_value)
|
||||
|| strlen(attr_value) > sizeof("65535") - 1) {
|
||||
state->error_mask |= MAIL_ERROR_PROTOCOL;
|
||||
smtpd_chat_reply(state, "501 5.5.4 Bad %s syntax: %s",
|
||||
XCLIENT_PORT, attr_value);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
UPDATE_STR(state->port, attr_value);
|
||||
update_namaddr = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* HELO=substitute SMTP client HELO parameter. Censor special
|
||||
* characters that could mess up message headers.
|
||||
@ -3346,7 +3370,8 @@ static int xclient_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
|
||||
if (state->namaddr)
|
||||
myfree(state->namaddr);
|
||||
state->namaddr =
|
||||
concatenate(state->name, "[", state->addr, "]", (char *) 0);
|
||||
concatenate(state->name, "[", state->addr, "]:",
|
||||
state->port, (char *) 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3401,6 +3426,7 @@ static int xforward_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
|
||||
static NAME_CODE xforward_flags[] = {
|
||||
XFORWARD_NAME, SMTPD_STATE_XFORWARD_NAME,
|
||||
XFORWARD_ADDR, SMTPD_STATE_XFORWARD_ADDR,
|
||||
XFORWARD_PORT, SMTPD_STATE_XFORWARD_PORT,
|
||||
XFORWARD_PROTO, SMTPD_STATE_XFORWARD_PROTO,
|
||||
XFORWARD_HELO, SMTPD_STATE_XFORWARD_HELO,
|
||||
XFORWARD_DOMAIN, SMTPD_STATE_XFORWARD_DOMAIN,
|
||||
@ -3520,6 +3546,24 @@ static int xforward_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
|
||||
UPDATE_STR(state->xforward.rfc_addr, attr_value);
|
||||
break;
|
||||
|
||||
/*
|
||||
* PORT=up-stream port number.
|
||||
*/
|
||||
case SMTPD_STATE_XFORWARD_PORT:
|
||||
if (STREQ(attr_value, XFORWARD_UNAVAILABLE)) {
|
||||
attr_value = CLIENT_PORT_UNKNOWN;
|
||||
} else {
|
||||
if (!alldig(attr_value)
|
||||
|| strlen(attr_value) > sizeof("65535") - 1) {
|
||||
state->error_mask |= MAIL_ERROR_PROTOCOL;
|
||||
smtpd_chat_reply(state, "501 5.5.4 Bad %s syntax: %s",
|
||||
XFORWARD_PORT, attr_value);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
UPDATE_STR(state->xforward.port, attr_value);
|
||||
break;
|
||||
|
||||
/*
|
||||
* HELO=hostname that the up-stream MTA introduced itself with
|
||||
* (not necessarily SMTP HELO). Censor special characters that
|
||||
@ -3593,7 +3637,8 @@ static int xforward_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
|
||||
state->xforward.namaddr =
|
||||
IS_AVAIL_CLIENT_ADDR(state->xforward.addr) ?
|
||||
concatenate(state->xforward.name, "[",
|
||||
state->xforward.addr, "]",
|
||||
state->xforward.addr, "]:",
|
||||
state->xforward.port,
|
||||
(char *) 0) : mystrdup(state->xforward.name);
|
||||
}
|
||||
smtpd_chat_reply(state, "250 2.0.0 Ok");
|
||||
@ -4004,14 +4049,13 @@ static void smtpd_proto(SMTPD_STATE *state)
|
||||
* HELO or EHLO, but we do change the feature list that is announced
|
||||
* in the EHLO response.
|
||||
*/
|
||||
#define XXX_NO_PORT "0"
|
||||
else {
|
||||
err = 0;
|
||||
if (smtpd_milters != 0 && SMTPD_STAND_ALONE(state) == 0) {
|
||||
milter_macro_callback(smtpd_milters, smtpd_milter_eval,
|
||||
(void *) state);
|
||||
if ((err = milter_conn_event(smtpd_milters, state->name,
|
||||
state->addr, XXX_NO_PORT,
|
||||
state->addr, state->port,
|
||||
state->addr_family)) != 0)
|
||||
err = check_milter_reply(state, err);
|
||||
}
|
||||
@ -4142,13 +4186,20 @@ static void smtpd_proto(SMTPD_STATE *state)
|
||||
* Log abnormal session termination, in case postmaster notification has
|
||||
* been turned off. In the log, indicate the last recognized state before
|
||||
* things went wrong. Don't complain about clients that go away without
|
||||
* sending QUIT.
|
||||
* sending QUIT. Log the byte count after DATA to help diagnose MTU
|
||||
* troubles.
|
||||
*/
|
||||
if (state->reason && state->where
|
||||
&& (strcmp(state->where, SMTPD_AFTER_DOT)
|
||||
|| strcmp(state->reason, REASON_LOST_CONNECTION)))
|
||||
if (state->reason && state->where) {
|
||||
if (strcmp(state->where, SMTPD_CMD_DATA) == 0) {
|
||||
msg_info("%s after %s (%lu bytes) from %s[%s]",
|
||||
state->reason, state->where, (long) state->act_size,
|
||||
state->name, state->addr);
|
||||
} else if (strcmp(state->where, SMTPD_AFTER_DOT)
|
||||
|| strcmp(state->reason, REASON_LOST_CONNECTION)) {
|
||||
msg_info("%s after %s from %s[%s]",
|
||||
state->reason, state->where, state->name, state->addr);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Cleanup whatever information the client gave us during the SMTP
|
||||
@ -4193,7 +4244,7 @@ static void smtpd_service(VSTREAM *stream, char *service, char **argv)
|
||||
* machines.
|
||||
*/
|
||||
smtpd_state_init(&state, stream, service);
|
||||
msg_info("connect from %s[%s]", state.name, state.addr);
|
||||
msg_info("connect from %s", state.namaddr);
|
||||
|
||||
/*
|
||||
* With TLS wrapper mode, we run on a dedicated port and turn on TLS
|
||||
@ -4243,7 +4294,7 @@ static void smtpd_service(VSTREAM *stream, char *service, char **argv)
|
||||
* After the client has gone away, clean up whatever we have set up at
|
||||
* connection time.
|
||||
*/
|
||||
msg_info("disconnect from %s[%s]", state.name, state.addr);
|
||||
msg_info("disconnect from %s", state.namaddr);
|
||||
smtpd_state_reset(&state);
|
||||
debug_peer_restore();
|
||||
}
|
||||
|
@ -55,7 +55,8 @@ typedef struct {
|
||||
int flags; /* XFORWARD server state */
|
||||
char *name; /* name for access control */
|
||||
char *addr; /* address for access control */
|
||||
char *namaddr; /* name[address] */
|
||||
char *port; /* port for logging */
|
||||
char *namaddr; /* name[address]:port */
|
||||
char *rfc_addr; /* address for RFC 2821 */
|
||||
char *protocol; /* email protocol */
|
||||
char *helo_name; /* helo/ehlo parameter */
|
||||
@ -74,7 +75,8 @@ typedef struct SMTPD_STATE {
|
||||
char *name; /* verified client hostname */
|
||||
char *reverse_name; /* unverified client hostname */
|
||||
char *addr; /* client host address string */
|
||||
char *namaddr; /* combined name and address */
|
||||
char *port; /* port for logging */
|
||||
char *namaddr; /* name[address]:port */
|
||||
char *rfc_addr; /* address for RFC 2821 */
|
||||
int addr_family; /* address family */
|
||||
struct sockaddr_storage sockaddr; /* binary client endpoint */
|
||||
@ -187,10 +189,12 @@ typedef struct SMTPD_STATE {
|
||||
#define SMTPD_STATE_XFORWARD_HELO (1<<4) /* client helo received */
|
||||
#define SMTPD_STATE_XFORWARD_IDENT (1<<5) /* message identifier */
|
||||
#define SMTPD_STATE_XFORWARD_DOMAIN (1<<6) /* message identifier */
|
||||
#define SMTPD_STATE_XFORWARD_PORT (1<<7) /* client port received */
|
||||
|
||||
#define SMTPD_STATE_XFORWARD_CLIENT_MASK \
|
||||
(SMTPD_STATE_XFORWARD_NAME | SMTPD_STATE_XFORWARD_ADDR \
|
||||
| SMTPD_STATE_XFORWARD_PROTO | SMTPD_STATE_XFORWARD_HELO)
|
||||
| SMTPD_STATE_XFORWARD_PROTO | SMTPD_STATE_XFORWARD_HELO \
|
||||
| SMTPD_STATE_XFORWARD_PORT)
|
||||
|
||||
extern void smtpd_state_init(SMTPD_STATE *, VSTREAM *, const char *);
|
||||
extern void smtpd_state_reset(SMTPD_STATE *);
|
||||
@ -232,6 +236,7 @@ extern void smtpd_state_reset(SMTPD_STATE *);
|
||||
|
||||
#define CLIENT_NAME_UNKNOWN CLIENT_ATTR_UNKNOWN
|
||||
#define CLIENT_ADDR_UNKNOWN CLIENT_ATTR_UNKNOWN
|
||||
#define CLIENT_PORT_UNKNOWN CLIENT_ATTR_UNKNOWN
|
||||
#define CLIENT_NAMADDR_UNKNOWN CLIENT_ATTR_UNKNOWN
|
||||
#define CLIENT_HELO_UNKNOWN 0
|
||||
#define CLIENT_PROTO_UNKNOWN CLIENT_ATTR_UNKNOWN
|
||||
@ -242,6 +247,7 @@ extern void smtpd_state_reset(SMTPD_STATE *);
|
||||
|
||||
#define IS_AVAIL_CLIENT_NAME(v) IS_AVAIL_CLIENT_ATTR(v)
|
||||
#define IS_AVAIL_CLIENT_ADDR(v) IS_AVAIL_CLIENT_ATTR(v)
|
||||
#define IS_AVAIL_CLIENT_PORT(v) IS_AVAIL_CLIENT_ATTR(v)
|
||||
#define IS_AVAIL_CLIENT_NAMADDR(v) IS_AVAIL_CLIENT_ATTR(v)
|
||||
#define IS_AVAIL_CLIENT_HELO(v) ((v) != 0)
|
||||
#define IS_AVAIL_CLIENT_PROTO(v) IS_AVAIL_CLIENT_ATTR(v)
|
||||
@ -299,6 +305,7 @@ extern void smtpd_peer_reset(SMTPD_STATE *state);
|
||||
#define FORWARD_NAMADDR(s) FORWARD_CLIENT_ATTR((s), namaddr)
|
||||
#define FORWARD_PROTO(s) FORWARD_CLIENT_ATTR((s), protocol)
|
||||
#define FORWARD_HELO(s) FORWARD_CLIENT_ATTR((s), helo_name)
|
||||
#define FORWARD_PORT(s) FORWARD_CLIENT_ATTR((s), port)
|
||||
|
||||
#define FORWARD_IDENT(s) \
|
||||
(((s)->xforward.flags & SMTPD_STATE_XFORWARD_IDENT) ? \
|
||||
|
@ -92,6 +92,8 @@ const char *smtpd_milter_eval(const char *name, void *ptr)
|
||||
return (var_myhostname);
|
||||
if (strcmp(name, S8_MAC_CLIENT_ADDR) == 0)
|
||||
return (state->rfc_addr);
|
||||
if (strcmp(name, S8_MAC_CLIENT_PORT) == 0)
|
||||
return (state->port);
|
||||
if (strcmp(name, S8_MAC_CLIENT_CONN) == 0) {
|
||||
if (state->expand_buf == 0)
|
||||
state->expand_buf = vstring_alloc(10);
|
||||
|
@ -41,7 +41,7 @@
|
||||
/* .IP addr
|
||||
/* Printable representation of the client address.
|
||||
/* .IP namaddr
|
||||
/* String of the form: "name[addr]".
|
||||
/* String of the form: "name[addr]:port".
|
||||
/* .IP rfc_addr
|
||||
/* String of the form "ipv4addr" or "ipv6:ipv6addr" for use
|
||||
/* in Received: message headers.
|
||||
@ -170,6 +170,7 @@ void smtpd_peer_init(SMTPD_STATE *state)
|
||||
state->addr_family = AF_UNSPEC;
|
||||
state->name_status = SMTPD_PEER_CODE_PERM;
|
||||
state->reverse_name_status = SMTPD_PEER_CODE_PERM;
|
||||
state->port = mystrdup(CLIENT_PORT_UNKNOWN);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -188,6 +189,7 @@ void smtpd_peer_init(SMTPD_STATE *state)
|
||||
)) {
|
||||
MAI_HOSTNAME_STR client_name;
|
||||
MAI_HOSTADDR_STR client_addr;
|
||||
MAI_SERVPORT_STR client_port;
|
||||
int aierr;
|
||||
char *colonp;
|
||||
|
||||
@ -217,9 +219,10 @@ void smtpd_peer_init(SMTPD_STATE *state)
|
||||
* Convert the client address to printable form.
|
||||
*/
|
||||
if ((aierr = sockaddr_to_hostaddr(sa, sa_length, &client_addr,
|
||||
(MAI_SERVPORT_STR *) 0, 0)) != 0)
|
||||
msg_fatal("%s: cannot convert client address to string: %s",
|
||||
&client_port, 0)) != 0)
|
||||
msg_fatal("%s: cannot convert client address/port to string: %s",
|
||||
myname, MAI_STRERROR(aierr));
|
||||
state->port = mystrdup(client_port.buf);
|
||||
|
||||
/*
|
||||
* We convert IPv4-in-IPv6 address to 'true' IPv4 address early on,
|
||||
@ -364,13 +367,15 @@ void smtpd_peer_init(SMTPD_STATE *state)
|
||||
state->addr_family = AF_UNSPEC;
|
||||
state->name_status = SMTPD_PEER_CODE_OK;
|
||||
state->reverse_name_status = SMTPD_PEER_CODE_OK;
|
||||
state->port = mystrdup("0"); /* XXX bogus. */
|
||||
}
|
||||
|
||||
/*
|
||||
* Do the name[addr] formatting for pretty reports.
|
||||
* Do the name[addr]:port formatting for pretty reports.
|
||||
*/
|
||||
state->namaddr =
|
||||
concatenate(state->name, "[", state->addr, "]", (char *) 0);
|
||||
concatenate(state->name, "[", state->addr,
|
||||
"]:", state->port, (char *) 0);
|
||||
}
|
||||
|
||||
/* smtpd_peer_reset - destroy peer information */
|
||||
@ -382,4 +387,5 @@ void smtpd_peer_reset(SMTPD_STATE *state)
|
||||
myfree(state->addr);
|
||||
myfree(state->namaddr);
|
||||
myfree(state->rfc_addr);
|
||||
myfree(state->port);
|
||||
}
|
||||
|
@ -178,6 +178,7 @@
|
||||
#define SMTPD_PROXY_XFORWARD_HELO (1<<3) /* client helo */
|
||||
#define SMTPD_PROXY_XFORWARD_IDENT (1<<4) /* message identifier */
|
||||
#define SMTPD_PROXY_XFORWARD_DOMAIN (1<<5) /* origin type */
|
||||
#define SMTPD_PROXY_XFORWARD_PORT (1<<6) /* client port */
|
||||
|
||||
/*
|
||||
* SLMs.
|
||||
@ -257,6 +258,7 @@ int smtpd_proxy_open(SMTPD_STATE *state, const char *service,
|
||||
static NAME_CODE xforward_features[] = {
|
||||
XFORWARD_NAME, SMTPD_PROXY_XFORWARD_NAME,
|
||||
XFORWARD_ADDR, SMTPD_PROXY_XFORWARD_ADDR,
|
||||
XFORWARD_PORT, SMTPD_PROXY_XFORWARD_PORT,
|
||||
XFORWARD_PROTO, SMTPD_PROXY_XFORWARD_PROTO,
|
||||
XFORWARD_HELO, SMTPD_PROXY_XFORWARD_HELO,
|
||||
XFORWARD_DOMAIN, SMTPD_PROXY_XFORWARD_DOMAIN,
|
||||
@ -367,6 +369,11 @@ int smtpd_proxy_open(SMTPD_STATE *state, const char *service,
|
||||
bad = smtpd_xforward(state, buf, XFORWARD_ADDR,
|
||||
IS_AVAIL_CLIENT_ADDR(FORWARD_ADDR(state)),
|
||||
FORWARD_ADDR(state));
|
||||
if (bad == 0
|
||||
&& (state->proxy_xforward_features & SMTPD_PROXY_XFORWARD_PORT))
|
||||
bad = smtpd_xforward(state, buf, XFORWARD_PORT,
|
||||
IS_AVAIL_CLIENT_PORT(FORWARD_PORT(state)),
|
||||
FORWARD_PORT(state));
|
||||
if (bad == 0
|
||||
&& (state->proxy_xforward_features & SMTPD_PROXY_XFORWARD_HELO))
|
||||
bad = smtpd_xforward(state, buf, XFORWARD_HELO,
|
||||
|
@ -55,6 +55,7 @@ void smtpd_xforward_init(SMTPD_STATE *state)
|
||||
state->xforward.flags = 0;
|
||||
state->xforward.name = 0;
|
||||
state->xforward.addr = 0;
|
||||
state->xforward.port = 0;
|
||||
state->xforward.namaddr = 0;
|
||||
state->xforward.protocol = 0;
|
||||
state->xforward.helo_name = 0;
|
||||
@ -82,6 +83,7 @@ void smtpd_xforward_preset(SMTPD_STATE *state)
|
||||
state->xforward.flags = SMTPD_STATE_XFORWARD_INIT;
|
||||
state->xforward.name = mystrdup(CLIENT_NAME_UNKNOWN);
|
||||
state->xforward.addr = mystrdup(CLIENT_ADDR_UNKNOWN);
|
||||
state->xforward.port = mystrdup(CLIENT_PORT_UNKNOWN);
|
||||
state->xforward.namaddr = mystrdup(CLIENT_NAMADDR_UNKNOWN);
|
||||
state->xforward.rfc_addr = mystrdup(CLIENT_ADDR_UNKNOWN);
|
||||
/* Leave helo at zero. */
|
||||
@ -99,6 +101,7 @@ void smtpd_xforward_reset(SMTPD_STATE *state)
|
||||
state->xforward.flags = 0;
|
||||
FREE_AND_WIPE(state->xforward.name);
|
||||
FREE_AND_WIPE(state->xforward.addr);
|
||||
FREE_AND_WIPE(state->xforward.port);
|
||||
FREE_AND_WIPE(state->xforward.namaddr);
|
||||
FREE_AND_WIPE(state->xforward.rfc_addr);
|
||||
FREE_AND_WIPE(state->xforward.protocol);
|
||||
|
@ -150,6 +150,13 @@
|
||||
/* Show the SMTP conversations.
|
||||
/* .IP "\fB-w \fIdelay\fR"
|
||||
/* Wait \fIdelay\fR seconds before responding to a DATA command.
|
||||
/* .IP "\fB-W \fIcommand:delay[:odds]\fR"
|
||||
/* Wait \fIdelay\fR seconds before responding to \fIcommand\fR.
|
||||
/* If \fIodds\fR is also specified (a number between 1-99
|
||||
/* inclusive), wait for a random multiple of \fIdelay\fR. The
|
||||
/* random multiplier is equal to the number of times the program
|
||||
/* needs to roll a dice with a range of 0..99 inclusive, before
|
||||
/* the dice produces a result greater than or equal to \fIodds\fR.
|
||||
/* .IP [\fBinet:\fR][\fIhost\fR]:\fIport\fR
|
||||
/* Listen on network interface \fIhost\fR (default: any interface)
|
||||
/* TCP port \fIport\fR. Both \fIhost\fR and \fIport\fR may be
|
||||
@ -286,6 +293,8 @@ typedef struct SINK_STATE {
|
||||
time_t start_time; /* MAIL command time */
|
||||
int id; /* pseudo-random */
|
||||
VSTREAM *dump_file; /* dump file or null */
|
||||
void (*delayed_response) (struct SINK_STATE *state, const char *);
|
||||
char *delayed_args;
|
||||
} SINK_STATE;
|
||||
|
||||
#define ST_ANY 0
|
||||
@ -318,7 +327,6 @@ static int mesg_count;
|
||||
static int max_quit_count;
|
||||
static int disable_pipelining;
|
||||
static int disable_8bitmime;
|
||||
static int fixed_delay;
|
||||
static int disable_esmtp;
|
||||
static int enable_lmtp;
|
||||
static int pretend_pix;
|
||||
@ -708,18 +716,6 @@ static void data_response(SINK_STATE *state, const char *unused_args)
|
||||
mail_file_finish_header(state);
|
||||
}
|
||||
|
||||
/* data_event - delayed response to DATA command */
|
||||
|
||||
static void data_event(int unused_event, char *context)
|
||||
{
|
||||
SINK_STATE *state = (SINK_STATE *) context;
|
||||
|
||||
data_response(state, "");
|
||||
/* Resume input event handling after the delayed DATA response. */
|
||||
event_enable_read(vstream_fileno(state->stream), read_event, (char *) state);
|
||||
event_request_timer(read_timeout, (char *) state, var_tmout);
|
||||
}
|
||||
|
||||
/* dot_resp_hard - hard error response to . command */
|
||||
|
||||
static void dot_resp_hard(SINK_STATE *state)
|
||||
@ -782,6 +778,25 @@ static void conn_response(SINK_STATE *state, const char *unused_args)
|
||||
smtp_flush(state->stream);
|
||||
}
|
||||
|
||||
/* delay_event - delayed command response */
|
||||
|
||||
static void delay_event(int unused_event, char *context)
|
||||
{
|
||||
SINK_STATE *state = (SINK_STATE *) context;
|
||||
|
||||
state->delayed_response(state, state->delayed_args);
|
||||
myfree(state->delayed_args);
|
||||
state->delayed_args = 0;
|
||||
|
||||
if (state->delayed_response == quit_response) {
|
||||
disconnect(state);
|
||||
return;
|
||||
}
|
||||
/* Resume input event handling after the delayed response. */
|
||||
event_enable_read(vstream_fileno(state->stream), read_event, (char *) state);
|
||||
event_request_timer(read_timeout, (char *) state, var_tmout);
|
||||
}
|
||||
|
||||
/* data_read - read data from socket */
|
||||
|
||||
static int data_read(SINK_STATE *state)
|
||||
@ -863,6 +878,8 @@ typedef struct SINK_COMMAND {
|
||||
void (*hard_response) (SINK_STATE *);
|
||||
void (*soft_response) (SINK_STATE *);
|
||||
int flags;
|
||||
int delay;
|
||||
int delay_odds;
|
||||
} SINK_COMMAND;
|
||||
|
||||
#define FLAG_ENABLE (1<<0) /* command is enabled */
|
||||
@ -872,21 +889,21 @@ typedef struct SINK_COMMAND {
|
||||
#define FLAG_DISCONNECT (1<<4) /* disconnect */
|
||||
|
||||
static SINK_COMMAND command_table[] = {
|
||||
"connect", conn_response, hard_err_resp, soft_err_resp, 0,
|
||||
"helo", helo_response, hard_err_resp, soft_err_resp, 0,
|
||||
"ehlo", ehlo_response, hard_err_resp, soft_err_resp, 0,
|
||||
"lhlo", ehlo_response, hard_err_resp, soft_err_resp, 0,
|
||||
"xclient", ok_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
|
||||
"xforward", ok_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
|
||||
"auth", ok_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
|
||||
"mail", mail_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
|
||||
"rcpt", rcpt_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
|
||||
"data", data_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
|
||||
".", dot_response, dot_resp_hard, dot_resp_soft, FLAG_ENABLE,
|
||||
"rset", rset_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
|
||||
"noop", ok_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
|
||||
"vrfy", ok_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
|
||||
"quit", quit_response, hard_err_resp, soft_err_resp, FLAG_ENABLE,
|
||||
"connect", conn_response, hard_err_resp, soft_err_resp, 0, 0, 0,
|
||||
"helo", helo_response, hard_err_resp, soft_err_resp, 0, 0, 0,
|
||||
"ehlo", ehlo_response, hard_err_resp, soft_err_resp, 0, 0, 0,
|
||||
"lhlo", ehlo_response, hard_err_resp, soft_err_resp, 0, 0, 0,
|
||||
"xclient", ok_response, hard_err_resp, soft_err_resp, FLAG_ENABLE, 0, 0,
|
||||
"xforward", ok_response, hard_err_resp, soft_err_resp, FLAG_ENABLE, 0, 0,
|
||||
"auth", ok_response, hard_err_resp, soft_err_resp, FLAG_ENABLE, 0, 0,
|
||||
"mail", mail_response, hard_err_resp, soft_err_resp, FLAG_ENABLE, 0, 0,
|
||||
"rcpt", rcpt_response, hard_err_resp, soft_err_resp, FLAG_ENABLE, 0, 0,
|
||||
"data", data_response, hard_err_resp, soft_err_resp, FLAG_ENABLE, 0, 0,
|
||||
".", dot_response, dot_resp_hard, dot_resp_soft, FLAG_ENABLE, 0, 0,
|
||||
"rset", rset_response, hard_err_resp, soft_err_resp, FLAG_ENABLE, 0, 0,
|
||||
"noop", ok_response, hard_err_resp, soft_err_resp, FLAG_ENABLE, 0, 0,
|
||||
"vrfy", ok_response, hard_err_resp, soft_err_resp, FLAG_ENABLE, 0, 0,
|
||||
"quit", quit_response, hard_err_resp, soft_err_resp, FLAG_ENABLE, 0, 0,
|
||||
0,
|
||||
};
|
||||
|
||||
@ -932,6 +949,47 @@ static void set_cmds_flags(const char *cmds, int flags)
|
||||
myfree(saved_cmds);
|
||||
}
|
||||
|
||||
/* set_cmd_delay - set per-command delay */
|
||||
|
||||
static void set_cmd_delay(const char *cmd, int delay, int odds)
|
||||
{
|
||||
SINK_COMMAND *cmdp;
|
||||
|
||||
for (cmdp = command_table; cmdp->name != 0; cmdp++)
|
||||
if (strcasecmp(cmd, cmdp->name) == 0)
|
||||
break;
|
||||
if (cmdp->name == 0)
|
||||
msg_fatal("unknown command: %s", cmd);
|
||||
|
||||
if (delay <= 0)
|
||||
msg_fatal("non-positive '%s' delay", cmd);
|
||||
if (odds < 0 || odds > 99)
|
||||
msg_fatal("delay odds for '%s' out of range", cmd);
|
||||
|
||||
cmdp->delay = delay;
|
||||
cmdp->delay_odds = odds;
|
||||
}
|
||||
|
||||
/* set_cmd_delay_arg - set per-command delay from option argument */
|
||||
|
||||
static void set_cmd_delay_arg(char *arg)
|
||||
{
|
||||
char *cp;
|
||||
char *saved_arg;
|
||||
char *cmd;
|
||||
char *delay;
|
||||
char *odds;
|
||||
|
||||
saved_arg = cp = mystrdup(arg);
|
||||
cmd = mystrtok(&cp, ":");
|
||||
delay = mystrtok(&cp, ":");
|
||||
if (cmd == 0 || delay == 0)
|
||||
msg_fatal("invalid command delay argument: %s", arg);
|
||||
odds = mystrtok(&cp, "");
|
||||
set_cmd_delay(cmd, atoi(delay), odds ? atoi(odds) : 0);
|
||||
myfree(saved_arg);
|
||||
}
|
||||
|
||||
/* command_resp - respond to command */
|
||||
|
||||
static int command_resp(SINK_STATE *state, SINK_COMMAND *cmdp,
|
||||
@ -950,11 +1008,20 @@ static int command_resp(SINK_STATE *state, SINK_COMMAND *cmdp,
|
||||
cmdp->soft_response(state);
|
||||
return (0);
|
||||
}
|
||||
if (cmdp->response == data_response && fixed_delay > 0) {
|
||||
/* Suspend input event handling while delaying the DATA response. */
|
||||
if (cmdp->delay > 0) {
|
||||
int delay = cmdp->delay;
|
||||
|
||||
if (cmdp->delay_odds > 0)
|
||||
for (delay = 0;
|
||||
((int) (100.0 * rand() / (RAND_MAX + 1.0))) < cmdp->delay_odds;
|
||||
delay += cmdp->delay)
|
||||
/* NOP */ ;
|
||||
/* Suspend input event handling while delaying the command response. */
|
||||
event_disable_readwrite(vstream_fileno(state->stream));
|
||||
event_cancel_timer(read_timeout, (char *) state);
|
||||
event_request_timer(data_event, (char *) state, fixed_delay);
|
||||
event_request_timer(delay_event, (char *) state, delay);
|
||||
state->delayed_response = cmdp->response;
|
||||
state->delayed_args = mystrdup(args);
|
||||
} else {
|
||||
cmdp->response(state, args);
|
||||
if (cmdp->response == quit_response)
|
||||
@ -1153,6 +1220,8 @@ static void disconnect(SINK_STATE *state)
|
||||
myfree(state->helo_args);
|
||||
/* Delete incomplete mail transaction. */
|
||||
mail_cmd_reset(state);
|
||||
if (state->delayed_args)
|
||||
myfree(state->delayed_args);
|
||||
myfree((char *) state);
|
||||
if (max_quit_count > 0 && quit_count >= max_quit_count)
|
||||
exit(0);
|
||||
@ -1201,6 +1270,8 @@ static void connect_event(int unused_event, char *unused_context)
|
||||
smtp_timeout_setup(state->stream, var_tmout);
|
||||
state->in_mail = 0;
|
||||
state->rcpts = 0;
|
||||
state->delayed_response = 0;
|
||||
state->delayed_args = 0;
|
||||
/* Initialize file capture attributes. */
|
||||
#ifdef AF_INET6
|
||||
if (sa.sa_family == AF_INET6)
|
||||
@ -1261,6 +1332,7 @@ int main(int argc, char **argv)
|
||||
{
|
||||
int backlog;
|
||||
int ch;
|
||||
int delay;
|
||||
const char *protocols = INET_PROTO_NAME_ALL;
|
||||
const char *root_dir = 0;
|
||||
const char *user_privs = 0;
|
||||
@ -1283,7 +1355,7 @@ int main(int argc, char **argv)
|
||||
/*
|
||||
* Parse JCL.
|
||||
*/
|
||||
while ((ch = GETOPT(argc, argv, "468aA:cCd:D:eEf:Fh:Ln:m:pPq:r:R:s:S:t:u:vw:")) > 0) {
|
||||
while ((ch = GETOPT(argc, argv, "468aA:cCd:D:eEf:Fh:Ln:m:pPq:r:R:s:S:t:u:vw:W:")) > 0) {
|
||||
switch (ch) {
|
||||
case '4':
|
||||
protocols = INET_PROTO_NAME_IPV4;
|
||||
@ -1378,8 +1450,12 @@ int main(int argc, char **argv)
|
||||
msg_verbose++;
|
||||
break;
|
||||
case 'w':
|
||||
if ((fixed_delay = atoi(optarg)) <= 0)
|
||||
if ((delay = atoi(optarg)) <= 0)
|
||||
usage(argv[0]);
|
||||
set_cmd_delay("data", delay, 0);
|
||||
break;
|
||||
case 'W':
|
||||
set_cmd_delay_arg(optarg);
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
|
@ -346,8 +346,8 @@ int attr_vscan0(VSTREAM *fp, int flags, va_list ap)
|
||||
&& strcmp(wanted_name, STR(name_buf)) == 0))
|
||||
break;
|
||||
if ((flags & ATTR_FLAG_EXTRA) != 0) {
|
||||
msg_warn("unexpected attribute %s in input from %s",
|
||||
STR(name_buf), VSTREAM_PATH(fp));
|
||||
msg_warn("unexpected attribute %s from %s (expecting: %s)",
|
||||
STR(name_buf), VSTREAM_PATH(fp), wanted_name);
|
||||
return (conversions);
|
||||
}
|
||||
|
||||
|
@ -349,8 +349,8 @@ int attr_vscan64(VSTREAM *fp, int flags, va_list ap)
|
||||
&& strcmp(wanted_name, STR(name_buf)) == 0))
|
||||
break;
|
||||
if ((flags & ATTR_FLAG_EXTRA) != 0) {
|
||||
msg_warn("unexpected attribute %s in input from %s",
|
||||
STR(name_buf), VSTREAM_PATH(fp));
|
||||
msg_warn("unexpected attribute %s from %s (expecting: %s)",
|
||||
STR(name_buf), VSTREAM_PATH(fp), wanted_name);
|
||||
return (conversions);
|
||||
}
|
||||
|
||||
|
@ -362,8 +362,8 @@ int attr_vscan_plain(VSTREAM *fp, int flags, va_list ap)
|
||||
&& strcmp(wanted_name, STR(name_buf)) == 0))
|
||||
break;
|
||||
if ((flags & ATTR_FLAG_EXTRA) != 0) {
|
||||
msg_warn("unexpected attribute %s in input from %s",
|
||||
STR(name_buf), VSTREAM_PATH(fp));
|
||||
msg_warn("unexpected attribute %s from %s (expecting: %s)",
|
||||
STR(name_buf), VSTREAM_PATH(fp), wanted_name);
|
||||
return (conversions);
|
||||
}
|
||||
|
||||
|
@ -622,7 +622,11 @@ void event_drain(int time_limit)
|
||||
if (EVENT_INIT_NEEDED())
|
||||
return;
|
||||
|
||||
#if (EVENTS_STYLE == EVENTS_STYLE_SELECT)
|
||||
EVENT_MASK_ZERO(&zero_mask);
|
||||
#else
|
||||
EVENT_MASK_ALLOC(&zero_mask, event_fdslots);
|
||||
#endif
|
||||
(void) time(&event_present);
|
||||
max_time = event_present + time_limit;
|
||||
while (event_present < max_time
|
||||
@ -630,6 +634,9 @@ void event_drain(int time_limit)
|
||||
|| memcmp(&zero_mask, &event_xmask,
|
||||
EVENT_MASK_BYTE_COUNT(&zero_mask)) != 0))
|
||||
event_loop(1);
|
||||
#if (EVENTS_STYLE != EVENTS_STYLE_SELECT)
|
||||
EVENT_MASK_FREE(&zero_mask);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* event_enable_read - enable read events */
|
||||
|
Loading…
x
Reference in New Issue
Block a user