mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-22 09:57:34 +00:00
postfix-3.6-20200920
This commit is contained in:
parent
c3f7b853c3
commit
e4f3f9ea70
2
postfix/.indent.pro
vendored
2
postfix/.indent.pro
vendored
@ -1,4 +1,4 @@
|
||||
-TABOUNCE
|
||||
-TABOUNCE_STATE
|
||||
-TADDR_MATCH_LIST
|
||||
-TADDR_PATTERN
|
||||
-TALIAS_TOKEN
|
||||
|
@ -25057,6 +25057,8 @@ Apologies for any names omitted.
|
||||
mantools/man2html, mantools/readme2html, proto/*_README.html,
|
||||
proto/INSTALL.html, proto/postconf.html.prolog, html/index.html.
|
||||
|
||||
20200830
|
||||
|
||||
Refactor: moved the SASL mechanism filter code from the
|
||||
Postfix SMTP client to a library module, so that it can be
|
||||
reused in the Postfix SMTP server. Files: smtp/smtp_sasl_proto.c,
|
||||
@ -25071,3 +25073,83 @@ Apologies for any names omitted.
|
||||
wants to anounce EXTERNAL support for which Postfix support
|
||||
does not exist. Files: smtpd/smtpd.[hc], smtpd_sasl_glue.[hc],
|
||||
global/mail_params.h, proto/postconf.proto, mantools/postlink.
|
||||
|
||||
20200906
|
||||
|
||||
Cleanup: missing file. File: src/postqueue/.indent.pro.
|
||||
|
||||
Cleanup: uninitialized value in unit test code. File:
|
||||
global/haproxy_srvr.c.
|
||||
|
||||
Cleanup: duplicate 'const' in argument declaration. File:
|
||||
src/global/sasl_mech_filter.c.
|
||||
|
||||
20200906-18
|
||||
|
||||
Baseline is postfix-3.6-20200906.
|
||||
|
||||
Other debt: internal protocol identification. Each server
|
||||
sends the name of the internal protocol that it implements,
|
||||
and each client logs a warning if it receives the wrong
|
||||
protocol name. With this, a client-server mismatch results
|
||||
in a better error message. It is a good idea to "postfix
|
||||
stop" before updating, or before backing out to an earlier
|
||||
relase. To make this work consistently, a few internal
|
||||
protocols were converted from "client speaks first" to
|
||||
"server speaks first". Files: anvil/anvil.c, bounce/bounce.c,
|
||||
cleanup/cleanup.c, flush/flush.c, global/abounce.c,
|
||||
global/anvil_clnt.c, global/bounce.c, global/clnt_stream.c,
|
||||
global/clnt_stream.h, global/defer.c, global/deliver_pass.c,
|
||||
global/deliver_request.c, global/dict_proxy.c, global/flush_clnt.c,
|
||||
global/mail_command_client.c, global/mail_proto.h,
|
||||
global/mail_stream.c, global/mail_version.h, global/post_mail.c,
|
||||
global/resolve_clnt.c, global/rewrite_clnt.c, global/scache_clnt.c,
|
||||
global/trace.c, global/verify_clnt.c, local/forward.c,
|
||||
master/event_server.c, master/mail_server.h, master/multi_server.c,
|
||||
oqmgr/qmgr_deliver.c, pickup/pickup.c, postdrop/postdrop.c,
|
||||
postqueue/postqueue.c, postscreen/postscreen_starttls.c,
|
||||
proxymap/proxymap.c, qmgr/qmgr_deliver.c, scache/scache.c,
|
||||
showq/showq.c, tls/tls_mgr.c, tls/tls_proxy_clnt.c,
|
||||
tlsmgr/tlsmgr.c, tlsproxy/tlsproxy.c,
|
||||
trivial-rewrite/trivial-rewrite.c, util/attr.h, util/attr_clnt.c,
|
||||
util/attr_clnt.h, util/attr_print0.c, util/attr_print64.c,
|
||||
util/attr_print_plain.c, util/attr_scan0.c, util/attr_scan64.c,
|
||||
util/attr_scan_plain.c, util/auto_clnt.c, util/auto_clnt.h,
|
||||
verify/verify.c.
|
||||
|
||||
Debt: during the conversion of some internal protocols to
|
||||
"server speaks first", took the opportunity to improve how
|
||||
event-driven client implementations handle a server that
|
||||
is locked up. Files: global/abounce.c,
|
||||
postscreen/postscreen_starttls.c.
|
||||
|
||||
20200919
|
||||
|
||||
Cleanup: eliminated a silly optimization for lazy clients
|
||||
that read the "server speaks first" protocol announcement
|
||||
after sending a client request. Files: src/anvil/anvil.c,
|
||||
src/bounce/bounce.c, src/flush/flush.c, src/global/abounce.c,
|
||||
src/global/anvil_clnt.c, src/global/deliver_pass.c,
|
||||
src/global/deliver_request.c, src/global/dict_proxy.c,
|
||||
src/global/mail_command_client.c, src/global/mail_stream.c,
|
||||
src/global/resolve_clnt.c, src/global/rewrite_clnt.c,
|
||||
src/global/scache_clnt.c, src/global/verify_clnt.c,
|
||||
src/local/forward.c, src/oqmgr/qmgr_deliver.c, src/pickup/pickup.c,
|
||||
src/postqueue/postqueue.c, src/postscreen/postscreen_starttls.c,
|
||||
src/proxymap/proxymap.c, src/qmgr/qmgr_deliver.c,
|
||||
src/scache/scache.c, src/showq/showq.c, src/tlsmgr/tlsmgr.c,
|
||||
src/tlsproxy/tlsproxy.c, src/tls/tls_mgr.c,
|
||||
src/tls/tls_proxy_clnt.c, src/trivial-rewrite/trivial-rewrite.c,
|
||||
src/verify/verify.c.
|
||||
|
||||
Cleanup: factored out some duplicate showq client code.
|
||||
File: postqueue/postqueue.c.
|
||||
|
||||
20200920
|
||||
|
||||
Cleanup: deleted the percentm module. It was obsoleted in
|
||||
19971027 by the vbuf_print() string formatter for VSTREAM
|
||||
and VSTRING objects. Files: util/percentm.[hc].
|
||||
|
||||
Cleanup: replaced hard-coded 'private' with named constant.
|
||||
File: global/scache_clnt.c.
|
||||
|
@ -25,6 +25,22 @@ more recent Eclipse Public License 2.0. Recipients can choose to take
|
||||
the software under the license of their choice. Those who are more
|
||||
comfortable with the IPL can continue with that license.
|
||||
|
||||
Incompatible change with snapshot 20200920
|
||||
==========================================
|
||||
|
||||
Internal protocols have changed. You need to "postfix stop" before
|
||||
updating, or before backing out to an earlier release, otherwise
|
||||
long-running daemons (pickup, qmgr, verify, tlsproxy, postscreen)
|
||||
may fail to communicate with the rest of Postfix (warnings, timeouts).
|
||||
|
||||
The purpose of this change is to produce better error messages, for
|
||||
example, when someone configures the discard daemon as a bounce
|
||||
service in master.cf, or vice versa.
|
||||
|
||||
This change will break third-party code that implements a
|
||||
Postfix-internal protocol such as qpsmtpd. Programs that depend on
|
||||
Postfix internal details are not supported.
|
||||
|
||||
Incompatible change with snapshot 20200705
|
||||
==========================================
|
||||
|
||||
|
@ -1,5 +1,23 @@
|
||||
Wish list:
|
||||
|
||||
Does tlsproxy terminate to soon after 'postfix reload'?
|
||||
|
||||
The documented order of relay/recipient restrictions differs
|
||||
from the implementation. This may need a new compatibility
|
||||
parameter. For example:
|
||||
http://postfix.1071664.n5.nabble.com/Relay-attempt-questions-td103646.html
|
||||
|
||||
Hardening the half-dane behavior: some sites may rely on
|
||||
current behavior which allows original MX domain name for
|
||||
certificate matches. Requires a new (compatibility) parameter
|
||||
setting?
|
||||
|
||||
multi_server applications could be migrated to event_server;
|
||||
after accept(), they would have to set up their own read
|
||||
event callback for handling requests.
|
||||
|
||||
Maybe expand %m to "application error" when errno == 0.
|
||||
|
||||
smtp_sasl_tls_security_options = noanonymous, and make
|
||||
smtp_sasl_security_options default dependent on the
|
||||
smtp_sasl_tls_security_options default (i.e. reverse the
|
||||
|
@ -162,11 +162,12 @@ CLEANUP(8) CLEANUP(8)
|
||||
Postfix 2.6 the default protocol is 2.
|
||||
|
||||
<b><a href="postconf.5.html#milter_default_action">milter_default_action</a> (tempfail)</b>
|
||||
The default action when a Milter (mail filter) application is
|
||||
unavailable or mis-configured.
|
||||
The default action when a Milter (mail filter) response is
|
||||
unavailable (for example, bad Postfix configuration or Milter
|
||||
failure).
|
||||
|
||||
<b><a href="postconf.5.html#milter_macro_daemon_name">milter_macro_daemon_name</a> ($<a href="postconf.5.html#myhostname">myhostname</a>)</b>
|
||||
The {daemon_name} macro value for Milter (mail filter) applica-
|
||||
The {daemon_name} macro value for Milter (mail filter) applica-
|
||||
tions.
|
||||
|
||||
<b><a href="postconf.5.html#milter_macro_v">milter_macro_v</a> ($<a href="postconf.5.html#mail_name">mail_name</a> $<a href="postconf.5.html#mail_version">mail_version</a>)</b>
|
||||
@ -177,45 +178,45 @@ CLEANUP(8) CLEANUP(8)
|
||||
tion, and for negotiating protocol options.
|
||||
|
||||
<b><a href="postconf.5.html#milter_command_timeout">milter_command_timeout</a> (30s)</b>
|
||||
The time limit for sending an SMTP command to a Milter (mail
|
||||
The time limit for sending an SMTP command to a Milter (mail
|
||||
filter) application, and for receiving the response.
|
||||
|
||||
<b><a href="postconf.5.html#milter_content_timeout">milter_content_timeout</a> (300s)</b>
|
||||
The time limit for sending message content to a Milter (mail
|
||||
The time limit for sending message content to a Milter (mail
|
||||
filter) application, and for receiving the response.
|
||||
|
||||
<b><a href="postconf.5.html#milter_connect_macros">milter_connect_macros</a> (see 'postconf -d' output)</b>
|
||||
The macros that are sent to Milter (mail filter) applications
|
||||
The macros that are sent to Milter (mail filter) applications
|
||||
after completion of an SMTP connection.
|
||||
|
||||
<b><a href="postconf.5.html#milter_helo_macros">milter_helo_macros</a> (see 'postconf -d' output)</b>
|
||||
The macros that are sent to Milter (mail filter) applications
|
||||
The macros that are sent to Milter (mail filter) applications
|
||||
after the SMTP HELO or EHLO command.
|
||||
|
||||
<b><a href="postconf.5.html#milter_mail_macros">milter_mail_macros</a> (see 'postconf -d' output)</b>
|
||||
The macros that are sent to Milter (mail filter) applications
|
||||
The macros that are sent to Milter (mail filter) applications
|
||||
after the SMTP MAIL FROM command.
|
||||
|
||||
<b><a href="postconf.5.html#milter_rcpt_macros">milter_rcpt_macros</a> (see 'postconf -d' output)</b>
|
||||
The macros that are sent to Milter (mail filter) applications
|
||||
The macros that are sent to Milter (mail filter) applications
|
||||
after the SMTP RCPT TO command.
|
||||
|
||||
<b><a href="postconf.5.html#milter_data_macros">milter_data_macros</a> (see 'postconf -d' output)</b>
|
||||
The macros that are sent to version 4 or higher Milter (mail
|
||||
The macros that are sent to version 4 or higher Milter (mail
|
||||
filter) applications after the SMTP DATA command.
|
||||
|
||||
<b><a href="postconf.5.html#milter_unknown_command_macros">milter_unknown_command_macros</a> (see 'postconf -d' output)</b>
|
||||
The macros that are sent to version 3 or higher Milter (mail
|
||||
The macros that are sent to version 3 or higher Milter (mail
|
||||
filter) applications after an unknown SMTP command.
|
||||
|
||||
<b><a href="postconf.5.html#milter_end_of_data_macros">milter_end_of_data_macros</a> (see 'postconf -d' output)</b>
|
||||
The macros that are sent to Milter (mail filter) applications
|
||||
The macros that are sent to Milter (mail filter) applications
|
||||
after the message end-of-data.
|
||||
|
||||
Available in Postfix version 2.5 and later:
|
||||
|
||||
<b><a href="postconf.5.html#milter_end_of_header_macros">milter_end_of_header_macros</a> (see 'postconf -d' output)</b>
|
||||
The macros that are sent to Milter (mail filter) applications
|
||||
The macros that are sent to Milter (mail filter) applications
|
||||
after the end of the message header.
|
||||
|
||||
Available in Postfix version 2.7 and later:
|
||||
@ -227,8 +228,8 @@ CLEANUP(8) CLEANUP(8)
|
||||
Available in Postfix version 3.1 and later:
|
||||
|
||||
<b><a href="postconf.5.html#milter_macro_defaults">milter_macro_defaults</a> (empty)</b>
|
||||
Optional list of <i>name=value</i> pairs that specify default values
|
||||
for arbitrary macros that Postfix may send to Milter applica-
|
||||
Optional list of <i>name=value</i> pairs that specify default values
|
||||
for arbitrary macros that Postfix may send to Milter applica-
|
||||
tions.
|
||||
|
||||
<b>MIME PROCESSING CONTROLS</b>
|
||||
@ -254,91 +255,91 @@ CLEANUP(8) CLEANUP(8)
|
||||
ing information.
|
||||
|
||||
<b><a href="postconf.5.html#strict_mime_encoding_domain">strict_mime_encoding_domain</a> (no)</b>
|
||||
Reject mail with invalid Content-Transfer-Encoding: information
|
||||
Reject mail with invalid Content-Transfer-Encoding: information
|
||||
for the message/* or multipart/* MIME content types.
|
||||
|
||||
Available in Postfix version 2.5 and later:
|
||||
|
||||
<b><a href="postconf.5.html#detect_8bit_encoding_header">detect_8bit_encoding_header</a> (yes)</b>
|
||||
Automatically detect 8BITMIME body content by looking at Con-
|
||||
tent-Transfer-Encoding: message headers; historically, this
|
||||
Automatically detect 8BITMIME body content by looking at Con-
|
||||
tent-Transfer-Encoding: message headers; historically, this
|
||||
behavior was hard-coded to be "always on".
|
||||
|
||||
<b>AUTOMATIC BCC RECIPIENT CONTROLS</b>
|
||||
Postfix can automatically add BCC (blind carbon copy) when mail enters
|
||||
Postfix can automatically add BCC (blind carbon copy) when mail enters
|
||||
the mail system:
|
||||
|
||||
<b><a href="postconf.5.html#always_bcc">always_bcc</a> (empty)</b>
|
||||
Optional address that receives a "blind carbon copy" of each
|
||||
Optional address that receives a "blind carbon copy" of each
|
||||
message that is received by the Postfix mail system.
|
||||
|
||||
Available in Postfix version 2.1 and later:
|
||||
|
||||
<b><a href="postconf.5.html#sender_bcc_maps">sender_bcc_maps</a> (empty)</b>
|
||||
Optional BCC (blind carbon-copy) address lookup tables, indexed
|
||||
Optional BCC (blind carbon-copy) address lookup tables, indexed
|
||||
by sender address.
|
||||
|
||||
<b><a href="postconf.5.html#recipient_bcc_maps">recipient_bcc_maps</a> (empty)</b>
|
||||
Optional BCC (blind carbon-copy) address lookup tables, indexed
|
||||
Optional BCC (blind carbon-copy) address lookup tables, indexed
|
||||
by recipient address.
|
||||
|
||||
<b>ADDRESS TRANSFORMATION CONTROLS</b>
|
||||
Address rewriting is delegated to the <a href="trivial-rewrite.8.html"><b>trivial-rewrite</b>(8)</a> daemon. The
|
||||
Address rewriting is delegated to the <a href="trivial-rewrite.8.html"><b>trivial-rewrite</b>(8)</a> daemon. The
|
||||
<a href="cleanup.8.html"><b>cleanup</b>(8)</a> server implements table driven address mapping.
|
||||
|
||||
<b><a href="postconf.5.html#empty_address_recipient">empty_address_recipient</a> (MAILER-DAEMON)</b>
|
||||
The recipient of mail addressed to the null address.
|
||||
|
||||
<b><a href="postconf.5.html#canonical_maps">canonical_maps</a> (empty)</b>
|
||||
Optional address mapping lookup tables for message headers and
|
||||
Optional address mapping lookup tables for message headers and
|
||||
envelopes.
|
||||
|
||||
<b><a href="postconf.5.html#recipient_canonical_maps">recipient_canonical_maps</a> (empty)</b>
|
||||
Optional address mapping lookup tables for envelope and header
|
||||
Optional address mapping lookup tables for envelope and header
|
||||
recipient addresses.
|
||||
|
||||
<b><a href="postconf.5.html#sender_canonical_maps">sender_canonical_maps</a> (empty)</b>
|
||||
Optional address mapping lookup tables for envelope and header
|
||||
Optional address mapping lookup tables for envelope and header
|
||||
sender addresses.
|
||||
|
||||
<b><a href="postconf.5.html#masquerade_classes">masquerade_classes</a> (envelope_sender, header_sender, header_recipient)</b>
|
||||
What addresses are subject to address masquerading.
|
||||
|
||||
<b><a href="postconf.5.html#masquerade_domains">masquerade_domains</a> (empty)</b>
|
||||
Optional list of domains whose subdomain structure will be
|
||||
Optional list of domains whose subdomain structure will be
|
||||
stripped off in email addresses.
|
||||
|
||||
<b><a href="postconf.5.html#masquerade_exceptions">masquerade_exceptions</a> (empty)</b>
|
||||
Optional list of user names that are not subjected to address
|
||||
masquerading, even when their addresses match $<a href="postconf.5.html#masquerade_domains">masquer</a>-
|
||||
Optional list of user names that are not subjected to address
|
||||
masquerading, even when their addresses match $<a href="postconf.5.html#masquerade_domains">masquer</a>-
|
||||
<a href="postconf.5.html#masquerade_domains">ade_domains</a>.
|
||||
|
||||
<b><a href="postconf.5.html#propagate_unmatched_extensions">propagate_unmatched_extensions</a> (canonical, virtual)</b>
|
||||
What address lookup tables copy an address extension from the
|
||||
What address lookup tables copy an address extension from the
|
||||
lookup key to the lookup result.
|
||||
|
||||
Available before Postfix version 2.0:
|
||||
|
||||
<b><a href="postconf.5.html#virtual_maps">virtual_maps</a> (empty)</b>
|
||||
Optional lookup tables with a) names of domains for which all
|
||||
addresses are aliased to addresses in other local or remote
|
||||
Optional lookup tables with a) names of domains for which all
|
||||
addresses are aliased to addresses in other local or remote
|
||||
domains, and b) addresses that are aliased to addresses in other
|
||||
local or remote domains.
|
||||
|
||||
Available in Postfix version 2.0 and later:
|
||||
|
||||
<b><a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a> ($<a href="postconf.5.html#virtual_maps">virtual_maps</a>)</b>
|
||||
Optional lookup tables that alias specific mail addresses or
|
||||
Optional lookup tables that alias specific mail addresses or
|
||||
domains to other local or remote address.
|
||||
|
||||
Available in Postfix version 2.2 and later:
|
||||
|
||||
<b><a href="postconf.5.html#canonical_classes">canonical_classes</a> (envelope_sender, envelope_recipient, header_sender,</b>
|
||||
<b><a href="postconf.5.html#canonical_classes">canonical_classes</a> (envelope_sender, envelope_recipient, header_sender,</b>
|
||||
<b>header_recipient)</b>
|
||||
What addresses are subject to <a href="postconf.5.html#canonical_maps">canonical_maps</a> address mapping.
|
||||
|
||||
<b><a href="postconf.5.html#recipient_canonical_classes">recipient_canonical_classes</a> (envelope_recipient, header_recipient)</b>
|
||||
What addresses are subject to <a href="postconf.5.html#recipient_canonical_maps">recipient_canonical_maps</a> address
|
||||
What addresses are subject to <a href="postconf.5.html#recipient_canonical_maps">recipient_canonical_maps</a> address
|
||||
mapping.
|
||||
|
||||
<b><a href="postconf.5.html#sender_canonical_classes">sender_canonical_classes</a> (envelope_sender, header_sender)</b>
|
||||
@ -346,8 +347,8 @@ CLEANUP(8) CLEANUP(8)
|
||||
ping.
|
||||
|
||||
<b><a href="postconf.5.html#remote_header_rewrite_domain">remote_header_rewrite_domain</a> (empty)</b>
|
||||
Don't rewrite message headers from remote clients at all when
|
||||
this parameter is empty; otherwise, rewrite message headers and
|
||||
Don't rewrite message headers from remote clients at all when
|
||||
this parameter is empty; otherwise, rewrite message headers and
|
||||
append the specified domain name to incomplete addresses.
|
||||
|
||||
<b>RESOURCE AND RATE CONTROLS</b>
|
||||
@ -357,7 +358,7 @@ CLEANUP(8) CLEANUP(8)
|
||||
<a href="showq.8.html"><b>showq</b>(8)</a> queue displays.
|
||||
|
||||
<b><a href="postconf.5.html#header_size_limit">header_size_limit</a> (102400)</b>
|
||||
The maximal amount of memory in bytes for storing a message
|
||||
The maximal amount of memory in bytes for storing a message
|
||||
header.
|
||||
|
||||
<b><a href="postconf.5.html#hopcount_limit">hopcount_limit</a> (50)</b>
|
||||
@ -365,17 +366,17 @@ CLEANUP(8) CLEANUP(8)
|
||||
in the primary message headers.
|
||||
|
||||
<b><a href="postconf.5.html#in_flow_delay">in_flow_delay</a> (1s)</b>
|
||||
Time to pause before accepting a new message, when the message
|
||||
Time to pause before accepting a new message, when the message
|
||||
arrival rate exceeds the message delivery rate.
|
||||
|
||||
<b><a href="postconf.5.html#message_size_limit">message_size_limit</a> (10240000)</b>
|
||||
The maximal size in bytes of a message, including envelope
|
||||
The maximal size in bytes of a message, including envelope
|
||||
information.
|
||||
|
||||
Available in Postfix version 2.0 and later:
|
||||
|
||||
<b><a href="postconf.5.html#header_address_token_limit">header_address_token_limit</a> (10240)</b>
|
||||
The maximal number of address tokens are allowed in an address
|
||||
The maximal number of address tokens are allowed in an address
|
||||
message header.
|
||||
|
||||
<b><a href="postconf.5.html#mime_boundary_length_limit">mime_boundary_length_limit</a> (2048)</b>
|
||||
@ -391,7 +392,7 @@ CLEANUP(8) CLEANUP(8)
|
||||
Available in Postfix version 2.1 and later:
|
||||
|
||||
<b><a href="postconf.5.html#virtual_alias_expansion_limit">virtual_alias_expansion_limit</a> (1000)</b>
|
||||
The maximal number of addresses that virtual alias expansion
|
||||
The maximal number of addresses that virtual alias expansion
|
||||
produces from each original recipient.
|
||||
|
||||
<b><a href="postconf.5.html#virtual_alias_recursion_limit">virtual_alias_recursion_limit</a> (1000)</b>
|
||||
@ -400,50 +401,50 @@ CLEANUP(8) CLEANUP(8)
|
||||
Available in Postfix version 3.0 and later:
|
||||
|
||||
<b><a href="postconf.5.html#virtual_alias_address_length_limit">virtual_alias_address_length_limit</a> (1000)</b>
|
||||
The maximal length of an email address after virtual alias
|
||||
The maximal length of an email address after virtual alias
|
||||
expansion.
|
||||
|
||||
<b>SMTPUTF8 CONTROLS</b>
|
||||
Preliminary SMTPUTF8 support is introduced with Postfix 3.0.
|
||||
|
||||
<b><a href="postconf.5.html#smtputf8_enable">smtputf8_enable</a> (yes)</b>
|
||||
Enable preliminary SMTPUTF8 support for the protocols described
|
||||
Enable preliminary SMTPUTF8 support for the protocols described
|
||||
in <a href="http://tools.ietf.org/html/rfc6531">RFC 6531</a>..6533.
|
||||
|
||||
<b><a href="postconf.5.html#smtputf8_autodetect_classes">smtputf8_autodetect_classes</a> (sendmail, verify)</b>
|
||||
Detect that a message requires SMTPUTF8 support for the speci-
|
||||
Detect that a message requires SMTPUTF8 support for the speci-
|
||||
fied mail origin classes.
|
||||
|
||||
Available in Postfix version 3.2 and later:
|
||||
|
||||
<b><a href="postconf.5.html#enable_idna2003_compatibility">enable_idna2003_compatibility</a> (no)</b>
|
||||
Enable 'transitional' compatibility between IDNA2003 and
|
||||
IDNA2008, when converting UTF-8 domain names to/from the ASCII
|
||||
Enable 'transitional' compatibility between IDNA2003 and
|
||||
IDNA2008, when converting UTF-8 domain names to/from the ASCII
|
||||
form that is used for DNS lookups.
|
||||
|
||||
<b>MISCELLANEOUS CONTROLS</b>
|
||||
<b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
|
||||
The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
|
||||
The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
|
||||
figuration files.
|
||||
|
||||
<b><a href="postconf.5.html#daemon_timeout">daemon_timeout</a> (18000s)</b>
|
||||
How much time a Postfix daemon process may take to handle a
|
||||
How much time a Postfix daemon process may take to handle a
|
||||
request before it is terminated by a built-in watchdog timer.
|
||||
|
||||
<b><a href="postconf.5.html#delay_logging_resolution_limit">delay_logging_resolution_limit</a> (2)</b>
|
||||
The maximal number of digits after the decimal point when log-
|
||||
The maximal number of digits after the decimal point when log-
|
||||
ging sub-second delay values.
|
||||
|
||||
<b><a href="postconf.5.html#delay_warning_time">delay_warning_time</a> (0h)</b>
|
||||
The time after which the sender receives a copy of the message
|
||||
The time after which the sender receives a copy of the message
|
||||
headers of mail that is still queued.
|
||||
|
||||
<b><a href="postconf.5.html#ipc_timeout">ipc_timeout</a> (3600s)</b>
|
||||
The time limit for sending or receiving information over an
|
||||
The time limit for sending or receiving information over an
|
||||
internal communication channel.
|
||||
|
||||
<b><a href="postconf.5.html#max_idle">max_idle</a> (100s)</b>
|
||||
The maximum amount of time that an idle Postfix daemon process
|
||||
The maximum amount of time that an idle Postfix daemon process
|
||||
waits for an incoming connection before terminating voluntarily.
|
||||
|
||||
<b><a href="postconf.5.html#max_use">max_use</a> (100)</b>
|
||||
@ -454,7 +455,7 @@ CLEANUP(8) CLEANUP(8)
|
||||
The internet hostname of this mail system.
|
||||
|
||||
<b><a href="postconf.5.html#myorigin">myorigin</a> ($<a href="postconf.5.html#myhostname">myhostname</a>)</b>
|
||||
The domain name that locally-posted mail appears to come from,
|
||||
The domain name that locally-posted mail appears to come from,
|
||||
and that locally posted mail is delivered to.
|
||||
|
||||
<b><a href="postconf.5.html#process_id">process_id</a> (read-only)</b>
|
||||
@ -467,21 +468,21 @@ CLEANUP(8) CLEANUP(8)
|
||||
The location of the Postfix top-level queue directory.
|
||||
|
||||
<b><a href="postconf.5.html#soft_bounce">soft_bounce</a> (no)</b>
|
||||
Safety net to keep mail queued that would otherwise be returned
|
||||
Safety net to keep mail queued that would otherwise be returned
|
||||
to the sender.
|
||||
|
||||
<b><a href="postconf.5.html#syslog_facility">syslog_facility</a> (mail)</b>
|
||||
The syslog facility of Postfix logging.
|
||||
|
||||
<b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
|
||||
A prefix that is prepended to the process name in syslog
|
||||
A prefix that is prepended to the process name in syslog
|
||||
records, so that, for example, "smtpd" becomes "prefix/smtpd".
|
||||
|
||||
Available in Postfix version 2.1 and later:
|
||||
|
||||
<b><a href="postconf.5.html#enable_original_recipient">enable_original_recipient</a> (yes)</b>
|
||||
Enable support for the original recipient address after an
|
||||
address is rewritten to a different address (for example with
|
||||
Enable support for the original recipient address after an
|
||||
address is rewritten to a different address (for example with
|
||||
aliasing or with canonical mapping).
|
||||
|
||||
Available in Postfix 3.3 and later:
|
||||
@ -492,7 +493,7 @@ CLEANUP(8) CLEANUP(8)
|
||||
Available in Postfix 3.5 and later:
|
||||
|
||||
<b>info_log_address_format (external)</b>
|
||||
The email address form that will be used in non-debug logging
|
||||
The email address form that will be used in non-debug logging
|
||||
(info, warning, etc.).
|
||||
|
||||
<b>FILES</b>
|
||||
|
@ -169,8 +169,8 @@ TRIVIAL-REWRITE(8) TRIVIAL-REWRITE(8)
|
||||
explicit ".example.com" pattern.
|
||||
|
||||
<b><a href="postconf.5.html#relayhost">relayhost</a> (empty)</b>
|
||||
The next-hop destination of non-local mail; overrides non-local
|
||||
domains in recipient addresses.
|
||||
The next-hop destination(s) for non-local mail; overrides
|
||||
non-<a href="ADDRESS_CLASS_README.html#local_domain_class">local domains</a> in recipient addresses.
|
||||
|
||||
<b><a href="postconf.5.html#transport_maps">transport_maps</a> (empty)</b>
|
||||
Optional lookup tables with mappings from recipient address to
|
||||
|
@ -164,8 +164,9 @@ The mail filter protocol version and optional protocol extensions
|
||||
for communication with a Milter application; prior to Postfix 2.6
|
||||
the default protocol is 2.
|
||||
.IP "\fBmilter_default_action (tempfail)\fR"
|
||||
The default action when a Milter (mail filter) application is
|
||||
unavailable or mis\-configured.
|
||||
The default action when a Milter (mail filter) response is
|
||||
unavailable (for example, bad Postfix configuration or Milter
|
||||
failure).
|
||||
.IP "\fBmilter_macro_daemon_name ($myhostname)\fR"
|
||||
The {daemon_name} macro value for Milter (mail filter) applications.
|
||||
.IP "\fBmilter_macro_v ($mail_name $mail_version)\fR"
|
||||
|
@ -175,7 +175,7 @@ A list of Postfix features where the pattern "example.com" also
|
||||
matches subdomains of example.com,
|
||||
instead of requiring an explicit ".example.com" pattern.
|
||||
.IP "\fBrelayhost (empty)\fR"
|
||||
The next\-hop destination of non\-local mail; overrides non\-local
|
||||
The next\-hop destination(s) for non\-local mail; overrides non\-local
|
||||
domains in recipient addresses.
|
||||
.IP "\fBtransport_maps (empty)\fR"
|
||||
Optional lookup tables with mappings from recipient address to
|
||||
|
@ -1006,6 +1006,21 @@ static void post_jail_init(char *unused_name, char **unused_argv)
|
||||
|
||||
MAIL_VERSION_STAMP_DECLARE;
|
||||
|
||||
/* post_accept - announce our protocol */
|
||||
|
||||
static void post_accept(VSTREAM *stream, char *unused_name,
|
||||
char **unused_argv, HTABLE *unused_table)
|
||||
{
|
||||
|
||||
/*
|
||||
* Announce the protocol.
|
||||
*/
|
||||
attr_print_plain(stream, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_ANVIL),
|
||||
ATTR_TYPE_END);
|
||||
(void) vstream_fflush(stream);
|
||||
}
|
||||
|
||||
/* main - pass control to the multi-threaded skeleton */
|
||||
|
||||
int main(int argc, char **argv)
|
||||
@ -1024,6 +1039,7 @@ int main(int argc, char **argv)
|
||||
multi_server_main(argc, argv, anvil_service,
|
||||
CA_MAIL_SERVER_TIME_TABLE(time_table),
|
||||
CA_MAIL_SERVER_POST_INIT(post_jail_init),
|
||||
CA_MAIL_SERVER_POST_ACCEPT(post_accept),
|
||||
CA_MAIL_SERVER_SOLITARY,
|
||||
CA_MAIL_SERVER_PRE_DISCONN(anvil_service_done),
|
||||
CA_MAIL_SERVER_EXIT(anvil_status_dump),
|
||||
|
@ -527,6 +527,14 @@ static void bounce_service(VSTREAM *client, char *service_name, char **argv)
|
||||
if (mail_queue_name_ok(service_name) == 0)
|
||||
msg_fatal("malformed service name: %s", service_name);
|
||||
|
||||
/*
|
||||
* Announce the protocol.
|
||||
*/
|
||||
attr_print(client, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_BOUNCE),
|
||||
ATTR_TYPE_END);
|
||||
(void) vstream_fflush(client);
|
||||
|
||||
/*
|
||||
* Read and validate the first parameter of the client request. Let the
|
||||
* request-specific protocol routines take care of the remainder.
|
||||
|
@ -144,8 +144,9 @@
|
||||
/* for communication with a Milter application; prior to Postfix 2.6
|
||||
/* the default protocol is 2.
|
||||
/* .IP "\fBmilter_default_action (tempfail)\fR"
|
||||
/* The default action when a Milter (mail filter) application is
|
||||
/* unavailable or mis-configured.
|
||||
/* The default action when a Milter (mail filter) response is
|
||||
/* unavailable (for example, bad Postfix configuration or Milter
|
||||
/* failure).
|
||||
/* .IP "\fBmilter_macro_daemon_name ($myhostname)\fR"
|
||||
/* The {daemon_name} macro value for Milter (mail filter) applications.
|
||||
/* .IP "\fBmilter_macro_v ($mail_name $mail_version)\fR"
|
||||
@ -503,6 +504,7 @@ static void cleanup_service(VSTREAM *src, char *unused_service, char **argv)
|
||||
* about the whole operation.
|
||||
*/
|
||||
attr_print(src, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_CLEANUP),
|
||||
SEND_ATTR_STR(MAIL_ATTR_QUEUEID, state->queue_id),
|
||||
ATTR_TYPE_END);
|
||||
if (attr_scan(src, ATTR_FLAG_STRICT,
|
||||
|
@ -699,6 +699,14 @@ static int flush_request_receive(VSTREAM *client_stream, VSTRING *request)
|
||||
{
|
||||
int count;
|
||||
|
||||
/*
|
||||
* Announce the protocol.
|
||||
*/
|
||||
attr_print(client_stream, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_FLUSH),
|
||||
ATTR_TYPE_END);
|
||||
(void) vstream_fflush(client_stream);
|
||||
|
||||
/*
|
||||
* Kluge: choose the protocol depending on the request size.
|
||||
*/
|
||||
|
@ -169,6 +169,11 @@
|
||||
/* IBM T.J. Watson Research
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*
|
||||
/* Wietse Venema
|
||||
/* Google, Inc.
|
||||
/* 111 8th Avenue
|
||||
/* New York, NY 10011, USA
|
||||
/*--*/
|
||||
|
||||
/* System library. */
|
||||
@ -202,10 +207,11 @@ typedef struct {
|
||||
int command; /* bounce request type */
|
||||
int flags; /* bounce options */
|
||||
char *id; /* queue ID for logging */
|
||||
VSTRING *request; /* serialized request */
|
||||
ABOUNCE_FN callback; /* application callback */
|
||||
void *context; /* application context */
|
||||
VSTREAM *fp; /* server I/O handle */
|
||||
} ABOUNCE;
|
||||
} ABOUNCE_STATE;
|
||||
|
||||
/*
|
||||
* Encapsulate common code.
|
||||
@ -215,11 +221,6 @@ typedef struct {
|
||||
event_request_timer((callback), (context), (timeout)); \
|
||||
} while (0)
|
||||
|
||||
#define ABOUNCE_EVENT_DISABLE(fd, callback, context) do { \
|
||||
event_cancel_timer((callback), (context)); \
|
||||
event_disable_readwrite(fd); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* If we set the reply timeout too short, then we make the problem worse by
|
||||
* increasing overload. With 1000s timeout mail will keep flowing, but there
|
||||
@ -228,11 +229,30 @@ typedef struct {
|
||||
*/
|
||||
#define ABOUNCE_TIMEOUT 1000
|
||||
|
||||
/*
|
||||
* The initial buffer size for a serialized request.
|
||||
*/
|
||||
#define ABOUNCE_BUFSIZE VSTREAM_BUFSIZE
|
||||
|
||||
/*
|
||||
* We share most of the verp and non-verp code paths.
|
||||
*/
|
||||
#define ABOUNCE_NO_VERP ((char *) 0)
|
||||
|
||||
/*
|
||||
* SLMs.
|
||||
*/
|
||||
#define STR(x) vstring_str(x)
|
||||
#define LEN(x) VSTRING_LEN(x)
|
||||
|
||||
/* abounce_done - deliver status to application and clean up pseudo thread */
|
||||
|
||||
static void abounce_done(ABOUNCE *ap, int status)
|
||||
static void abounce_done(ABOUNCE_STATE *ap, int status)
|
||||
{
|
||||
(void) vstream_fclose(ap->fp);
|
||||
if (ap->fp) {
|
||||
event_disable_readwrite(vstream_fileno(ap->fp));
|
||||
(void) vstream_fclose(ap->fp);
|
||||
}
|
||||
if (status != 0 && (ap->flags & BOUNCE_FLAG_CLEAN) == 0)
|
||||
msg_info("%s: status=deferred (%s failed)", ap->id,
|
||||
ap->command == BOUNCE_CMD_FLUSH ? "bounce" :
|
||||
@ -242,65 +262,125 @@ static void abounce_done(ABOUNCE *ap, int status)
|
||||
"whatever");
|
||||
ap->callback(status, ap->context);
|
||||
myfree(ap->id);
|
||||
vstring_free(ap->request);
|
||||
myfree((void *) ap);
|
||||
}
|
||||
|
||||
/* abounce_event - resume pseudo thread after server reply event */
|
||||
/* abounce_receive - receive server reply */
|
||||
|
||||
static void abounce_event(int event, void *context)
|
||||
static void abounce_receive(int event, void *context)
|
||||
{
|
||||
ABOUNCE *ap = (ABOUNCE *) context;
|
||||
ABOUNCE_STATE *ap = (ABOUNCE_STATE *) context;
|
||||
int status;
|
||||
|
||||
ABOUNCE_EVENT_DISABLE(vstream_fileno(ap->fp), abounce_event, context);
|
||||
abounce_done(ap, (event != EVENT_TIME
|
||||
&& attr_scan(ap->fp, ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_INT(MAIL_ATTR_STATUS, &status),
|
||||
ATTR_TYPE_END) == 1) ? status : -1);
|
||||
if (event != EVENT_TIME)
|
||||
event_cancel_timer(abounce_receive, context);
|
||||
|
||||
if (event == EVENT_READ
|
||||
&& attr_scan(ap->fp, ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_INT(MAIL_ATTR_STATUS, &status),
|
||||
ATTR_TYPE_END) == 1) {
|
||||
abounce_done(ap, status);
|
||||
} else {
|
||||
abounce_done(ap, -1);
|
||||
}
|
||||
}
|
||||
|
||||
/* abounce_request_verp - suspend pseudo thread until server reply event */
|
||||
/* abounce_send - send the request and suspend until the server replies */
|
||||
|
||||
static void abounce_request_verp(const char *class, const char *service,
|
||||
int command, int flags,
|
||||
const char *queue, const char *id,
|
||||
const char *encoding,
|
||||
int smtputf8,
|
||||
const char *sender,
|
||||
const char *dsn_envid,
|
||||
int dsn_ret,
|
||||
const char *verp,
|
||||
ABOUNCE_FN callback,
|
||||
void *context)
|
||||
static void abounce_send(int event, void *context)
|
||||
{
|
||||
ABOUNCE *ap;
|
||||
ABOUNCE_STATE *ap = (ABOUNCE_STATE *) context;
|
||||
|
||||
/*
|
||||
* Save pseudo thread state. Connect to the server. Send the request and
|
||||
* suspend the pseudo thread until the server replies (or dies).
|
||||
* Receive the server's protocol name announcement. At this point the
|
||||
* server is ready to receive a request without blocking the sender. Send
|
||||
* the request and suspend until the server replies (or dies).
|
||||
*/
|
||||
ap = (ABOUNCE *) mymalloc(sizeof(*ap));
|
||||
if (event != EVENT_TIME)
|
||||
event_cancel_timer(abounce_send, context);
|
||||
|
||||
non_blocking(vstream_fileno(ap->fp), BLOCKING);
|
||||
if (event == EVENT_READ
|
||||
&& attr_scan(ap->fp, ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_STREQ(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_BOUNCE),
|
||||
ATTR_TYPE_END) == 0
|
||||
&& vstream_fwrite(ap->fp, STR(ap->request),
|
||||
LEN(ap->request)) == LEN(ap->request)
|
||||
&& vstream_fflush(ap->fp) == 0) {
|
||||
ABOUNCE_EVENT_ENABLE(vstream_fileno(ap->fp), abounce_receive,
|
||||
(void *) ap, ABOUNCE_TIMEOUT);
|
||||
} else {
|
||||
abounce_done(ap, -1);
|
||||
}
|
||||
}
|
||||
|
||||
/* abounce_connect - connect and suspend until the server replies */
|
||||
|
||||
static void abounce_connect(const char *class, const char *service,
|
||||
int command, int flags,
|
||||
const char *queue, const char *id,
|
||||
const char *encoding, int smtputf8,
|
||||
const char *sender,
|
||||
const char *dsn_envid, int dsn_ret,
|
||||
const char *verp, ABOUNCE_FN callback,
|
||||
void *context)
|
||||
{
|
||||
ABOUNCE_STATE *ap;
|
||||
|
||||
/*
|
||||
* Save pseudo thread state. Connect to the server. Prior to Postfix 3.6
|
||||
* the asynchronous bounce flush/warn client called mail_connect_wait()
|
||||
* which sleeps and retries several times before terminating with a fatal
|
||||
* error. This block-and-sleep behavior was not consistent with a) the
|
||||
* rest of the code in this module, and with b) the synchronous bounce
|
||||
* client which gives up immediately. It should be safe to give up
|
||||
* immediately because that leaves the bounce/defer/trace logs in the
|
||||
* queue. In particular, this should not increase the simultaneous number
|
||||
* of asynchronous bounce/defer/trace flush/warn requests that are in
|
||||
* flight.
|
||||
*/
|
||||
ap = (ABOUNCE_STATE *) mymalloc(sizeof(*ap));
|
||||
ap->command = command;
|
||||
ap->flags = flags;
|
||||
ap->id = mystrdup(id);
|
||||
ap->request = vstring_alloc(ABOUNCE_BUFSIZE);
|
||||
ap->callback = callback;
|
||||
ap->context = context;
|
||||
ap->fp = mail_connect_wait(class, service);
|
||||
ap->fp = mail_connect(class, service, NON_BLOCKING);
|
||||
|
||||
if (attr_print(ap->fp, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_INT(MAIL_ATTR_NREQ, command),
|
||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
|
||||
SEND_ATTR_STR(MAIL_ATTR_QUEUE, queue),
|
||||
SEND_ATTR_STR(MAIL_ATTR_QUEUEID, id),
|
||||
SEND_ATTR_STR(MAIL_ATTR_ENCODING, encoding),
|
||||
SEND_ATTR_INT(MAIL_ATTR_SMTPUTF8, smtputf8),
|
||||
SEND_ATTR_STR(MAIL_ATTR_SENDER, sender),
|
||||
SEND_ATTR_STR(MAIL_ATTR_DSN_ENVID, dsn_envid),
|
||||
SEND_ATTR_INT(MAIL_ATTR_DSN_RET, dsn_ret),
|
||||
SEND_ATTR_STR(MAIL_ATTR_VERPDL, verp),
|
||||
ATTR_TYPE_END) == 0
|
||||
&& vstream_fflush(ap->fp) == 0) {
|
||||
ABOUNCE_EVENT_ENABLE(vstream_fileno(ap->fp), abounce_event,
|
||||
/*
|
||||
* Format the request now, so that we don't have to save a lot of
|
||||
* arguments now and format the request later.
|
||||
*/
|
||||
if (ap->fp != 0) {
|
||||
/* Note: all code paths must terminate or enable I/O events. */
|
||||
VSTREAM *mp = vstream_memopen(ap->request, O_WRONLY);
|
||||
|
||||
if (attr_print(mp, ATTR_FLAG_MORE,
|
||||
SEND_ATTR_INT(MAIL_ATTR_NREQ, command),
|
||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
|
||||
SEND_ATTR_STR(MAIL_ATTR_QUEUE, queue),
|
||||
SEND_ATTR_STR(MAIL_ATTR_QUEUEID, id),
|
||||
SEND_ATTR_STR(MAIL_ATTR_ENCODING, encoding),
|
||||
SEND_ATTR_INT(MAIL_ATTR_SMTPUTF8, smtputf8),
|
||||
SEND_ATTR_STR(MAIL_ATTR_SENDER, sender),
|
||||
SEND_ATTR_STR(MAIL_ATTR_DSN_ENVID, dsn_envid),
|
||||
SEND_ATTR_INT(MAIL_ATTR_DSN_RET, dsn_ret),
|
||||
ATTR_TYPE_END) != 0
|
||||
|| (verp != 0
|
||||
&& attr_print(mp, ATTR_FLAG_MORE,
|
||||
SEND_ATTR_STR(MAIL_ATTR_VERPDL, verp),
|
||||
ATTR_TYPE_END) != 0)
|
||||
|| attr_print(mp, ATTR_FLAG_NONE,
|
||||
ATTR_TYPE_END) != 0
|
||||
|| vstream_fclose(mp) != 0)
|
||||
msg_panic("abounce_connect: write request to memory stream: %m");
|
||||
|
||||
/*
|
||||
* Suspend until the server replies (or dies).
|
||||
*/
|
||||
ABOUNCE_EVENT_ENABLE(vstream_fileno(ap->fp), abounce_send,
|
||||
(void *) ap, ABOUNCE_TIMEOUT);
|
||||
} else {
|
||||
abounce_done(ap, -1);
|
||||
@ -316,9 +396,9 @@ void abounce_flush_verp(int flags, const char *queue, const char *id,
|
||||
ABOUNCE_FN callback,
|
||||
void *context)
|
||||
{
|
||||
abounce_request_verp(MAIL_CLASS_PRIVATE, var_bounce_service,
|
||||
BOUNCE_CMD_VERP, flags, queue, id, encoding, smtputf8,
|
||||
sender, dsn_envid, dsn_ret, verp, callback, context);
|
||||
abounce_connect(MAIL_CLASS_PRIVATE, var_bounce_service,
|
||||
BOUNCE_CMD_VERP, flags, queue, id, encoding, smtputf8,
|
||||
sender, dsn_envid, dsn_ret, verp, callback, context);
|
||||
}
|
||||
|
||||
/* adefer_flush_verp - asynchronous defer flush */
|
||||
@ -330,52 +410,9 @@ void adefer_flush_verp(int flags, const char *queue, const char *id,
|
||||
ABOUNCE_FN callback, void *context)
|
||||
{
|
||||
flags |= BOUNCE_FLAG_DELRCPT;
|
||||
abounce_request_verp(MAIL_CLASS_PRIVATE, var_defer_service,
|
||||
BOUNCE_CMD_VERP, flags, queue, id, encoding, smtputf8,
|
||||
sender, dsn_envid, dsn_ret, verp, callback, context);
|
||||
}
|
||||
|
||||
/* abounce_request - suspend pseudo thread until server reply event */
|
||||
|
||||
static void abounce_request(const char *class, const char *service,
|
||||
int command, int flags,
|
||||
const char *queue, const char *id,
|
||||
const char *encoding, int smtputf8,
|
||||
const char *sender,
|
||||
const char *dsn_envid, int dsn_ret,
|
||||
ABOUNCE_FN callback, void *context)
|
||||
{
|
||||
ABOUNCE *ap;
|
||||
|
||||
/*
|
||||
* Save pseudo thread state. Connect to the server. Send the request and
|
||||
* suspend the pseudo thread until the server replies (or dies).
|
||||
*/
|
||||
ap = (ABOUNCE *) mymalloc(sizeof(*ap));
|
||||
ap->command = command;
|
||||
ap->flags = flags;
|
||||
ap->id = mystrdup(id);
|
||||
ap->callback = callback;
|
||||
ap->context = context;
|
||||
ap->fp = mail_connect_wait(class, service);
|
||||
|
||||
if (attr_print(ap->fp, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_INT(MAIL_ATTR_NREQ, command),
|
||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
|
||||
SEND_ATTR_STR(MAIL_ATTR_QUEUE, queue),
|
||||
SEND_ATTR_STR(MAIL_ATTR_QUEUEID, id),
|
||||
SEND_ATTR_STR(MAIL_ATTR_ENCODING, encoding),
|
||||
SEND_ATTR_INT(MAIL_ATTR_SMTPUTF8, smtputf8),
|
||||
SEND_ATTR_STR(MAIL_ATTR_SENDER, sender),
|
||||
SEND_ATTR_STR(MAIL_ATTR_DSN_ENVID, dsn_envid),
|
||||
SEND_ATTR_INT(MAIL_ATTR_DSN_RET, dsn_ret),
|
||||
ATTR_TYPE_END) == 0
|
||||
&& vstream_fflush(ap->fp) == 0) {
|
||||
ABOUNCE_EVENT_ENABLE(vstream_fileno(ap->fp), abounce_event,
|
||||
(void *) ap, ABOUNCE_TIMEOUT);
|
||||
} else {
|
||||
abounce_done(ap, -1);
|
||||
}
|
||||
abounce_connect(MAIL_CLASS_PRIVATE, var_defer_service,
|
||||
BOUNCE_CMD_VERP, flags, queue, id, encoding, smtputf8,
|
||||
sender, dsn_envid, dsn_ret, verp, callback, context);
|
||||
}
|
||||
|
||||
/* abounce_flush - asynchronous bounce flush */
|
||||
@ -386,9 +423,9 @@ void abounce_flush(int flags, const char *queue, const char *id,
|
||||
int dsn_ret, ABOUNCE_FN callback,
|
||||
void *context)
|
||||
{
|
||||
abounce_request(MAIL_CLASS_PRIVATE, var_bounce_service, BOUNCE_CMD_FLUSH,
|
||||
abounce_connect(MAIL_CLASS_PRIVATE, var_bounce_service, BOUNCE_CMD_FLUSH,
|
||||
flags, queue, id, encoding, smtputf8, sender, dsn_envid,
|
||||
dsn_ret, callback, context);
|
||||
dsn_ret, ABOUNCE_NO_VERP, callback, context);
|
||||
}
|
||||
|
||||
/* adefer_flush - asynchronous defer flush */
|
||||
@ -399,9 +436,9 @@ void adefer_flush(int flags, const char *queue, const char *id,
|
||||
int dsn_ret, ABOUNCE_FN callback, void *context)
|
||||
{
|
||||
flags |= BOUNCE_FLAG_DELRCPT;
|
||||
abounce_request(MAIL_CLASS_PRIVATE, var_defer_service, BOUNCE_CMD_FLUSH,
|
||||
abounce_connect(MAIL_CLASS_PRIVATE, var_defer_service, BOUNCE_CMD_FLUSH,
|
||||
flags, queue, id, encoding, smtputf8, sender, dsn_envid,
|
||||
dsn_ret, callback, context);
|
||||
dsn_ret, ABOUNCE_NO_VERP, callback, context);
|
||||
}
|
||||
|
||||
/* adefer_warn - send copy of defer log to sender as warning bounce */
|
||||
@ -411,9 +448,9 @@ void adefer_warn(int flags, const char *queue, const char *id,
|
||||
const char *sender, const char *dsn_envid,
|
||||
int dsn_ret, ABOUNCE_FN callback, void *context)
|
||||
{
|
||||
abounce_request(MAIL_CLASS_PRIVATE, var_defer_service, BOUNCE_CMD_WARN,
|
||||
abounce_connect(MAIL_CLASS_PRIVATE, var_defer_service, BOUNCE_CMD_WARN,
|
||||
flags, queue, id, encoding, smtputf8, sender, dsn_envid,
|
||||
dsn_ret, callback, context);
|
||||
dsn_ret, ABOUNCE_NO_VERP, callback, context);
|
||||
}
|
||||
|
||||
/* atrace_flush - asynchronous trace flush */
|
||||
@ -423,7 +460,7 @@ void atrace_flush(int flags, const char *queue, const char *id,
|
||||
const char *sender, const char *dsn_envid,
|
||||
int dsn_ret, ABOUNCE_FN callback, void *context)
|
||||
{
|
||||
abounce_request(MAIL_CLASS_PRIVATE, var_trace_service, BOUNCE_CMD_TRACE,
|
||||
abounce_connect(MAIL_CLASS_PRIVATE, var_trace_service, BOUNCE_CMD_TRACE,
|
||||
flags, queue, id, encoding, smtputf8, sender, dsn_envid,
|
||||
dsn_ret, callback, context);
|
||||
dsn_ret, ABOUNCE_NO_VERP, callback, context);
|
||||
}
|
||||
|
@ -170,6 +170,15 @@
|
||||
#define ANVIL_IDENT(service, addr) \
|
||||
printable(concatenate(service, ":", addr, (char *) 0), '?')
|
||||
|
||||
/* anvil_clnt_handshake - receive server protocol announcement */
|
||||
|
||||
static int anvil_clnt_handshake(VSTREAM *stream)
|
||||
{
|
||||
return (attr_scan_plain(stream, ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_STREQ(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_ANVIL),
|
||||
ATTR_TYPE_END));
|
||||
}
|
||||
|
||||
/* anvil_clnt_create - instantiate connection rate service client */
|
||||
|
||||
ANVIL_CLNT *anvil_clnt_create(void)
|
||||
@ -186,6 +195,9 @@ ANVIL_CLNT *anvil_clnt_create(void)
|
||||
#else
|
||||
anvil_clnt = attr_clnt_create(var_anvil_service, var_ipc_timeout, 0, 0);
|
||||
#endif
|
||||
attr_clnt_control(anvil_clnt,
|
||||
ATTR_CLNT_CTL_HANDSHAKE, anvil_clnt_handshake,
|
||||
ATTR_CLNT_CTL_END);
|
||||
return ((ANVIL_CLNT *) anvil_clnt);
|
||||
}
|
||||
|
||||
|
@ -186,6 +186,11 @@
|
||||
/* IBM T.J. Watson Research
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*
|
||||
/* Wietse Venema
|
||||
/* Google, Inc.
|
||||
/* 111 8th Avenue
|
||||
/* New York, NY 10011, USA
|
||||
/*--*/
|
||||
|
||||
/* System library. */
|
||||
@ -310,6 +315,7 @@ int bounce_append_intern(int flags, const char *id, MSG_STATS *stats,
|
||||
|
||||
if (mail_command_client(MAIL_CLASS_PRIVATE, var_soft_bounce ?
|
||||
var_defer_service : var_bounce_service,
|
||||
MAIL_ATTR_PROTO_BOUNCE,
|
||||
SEND_ATTR_INT(MAIL_ATTR_NREQ, BOUNCE_CMD_APPEND),
|
||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
|
||||
SEND_ATTR_STR(MAIL_ATTR_QUEUEID, id),
|
||||
@ -353,6 +359,7 @@ int bounce_flush(int flags, const char *queue, const char *id,
|
||||
if (var_soft_bounce)
|
||||
return (-1);
|
||||
if (mail_command_client(MAIL_CLASS_PRIVATE, var_bounce_service,
|
||||
MAIL_ATTR_PROTO_BOUNCE,
|
||||
SEND_ATTR_INT(MAIL_ATTR_NREQ, BOUNCE_CMD_FLUSH),
|
||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
|
||||
SEND_ATTR_STR(MAIL_ATTR_QUEUE, queue),
|
||||
@ -387,6 +394,7 @@ int bounce_flush_verp(int flags, const char *queue, const char *id,
|
||||
if (var_soft_bounce)
|
||||
return (-1);
|
||||
if (mail_command_client(MAIL_CLASS_PRIVATE, var_bounce_service,
|
||||
MAIL_ATTR_PROTO_BOUNCE,
|
||||
SEND_ATTR_INT(MAIL_ATTR_NREQ, BOUNCE_CMD_VERP),
|
||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
|
||||
SEND_ATTR_STR(MAIL_ATTR_QUEUE, queue),
|
||||
@ -494,6 +502,7 @@ int bounce_one_intern(int flags, const char *queue, const char *id,
|
||||
my_dsn.action = "failed";
|
||||
|
||||
if (mail_command_client(MAIL_CLASS_PRIVATE, var_bounce_service,
|
||||
MAIL_ATTR_PROTO_BOUNCE,
|
||||
SEND_ATTR_INT(MAIL_ATTR_NREQ, BOUNCE_CMD_ONE),
|
||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
|
||||
SEND_ATTR_STR(MAIL_ATTR_QUEUE, queue),
|
||||
|
@ -6,11 +6,15 @@
|
||||
/* SYNOPSIS
|
||||
/* #include <clnt_stream.h>
|
||||
/*
|
||||
/* CLNT_STREAM *clnt_stream_create(class, service, timeout, ttl)
|
||||
/* typedef void (*CLNT_STREAM_HANDSHAKE_FN)(VSTREAM *)
|
||||
/*
|
||||
/* CLNT_STREAM *clnt_stream_create(class, service, timeout, ttl,
|
||||
/* handshake)
|
||||
/* const char *class;
|
||||
/* const char *service;
|
||||
/* int timeout;
|
||||
/* int ttl;
|
||||
/* CLNT_STREAM_HANDSHAKE_FN *handshake;
|
||||
/*
|
||||
/* VSTREAM *clnt_stream_access(clnt_stream)
|
||||
/* CLNT_STREAM *clnt_stream;
|
||||
@ -33,6 +37,8 @@
|
||||
/*
|
||||
/* clnt_stream_access() returns an open stream to the service specified
|
||||
/* to clnt_stream_create(). The stream instance may change between calls.
|
||||
/* This function returns null when the handshake function returned an
|
||||
/* error.
|
||||
/*
|
||||
/* clnt_stream_recover() recovers from a server-initiated disconnect
|
||||
/* that happened in the middle of an I/O operation.
|
||||
@ -49,6 +55,10 @@
|
||||
/* Idle time after which the client disconnects.
|
||||
/* .IP ttl
|
||||
/* Upper bound on the time that a connection is allowed to persist.
|
||||
/* .IP handshake
|
||||
/* Null pointer, or pointer to function that will be called
|
||||
/* at the start of a new connection and that returns 0 in case
|
||||
/* of success.
|
||||
/* DIAGNOSTICS
|
||||
/* Warnings: communication failure. Fatal error: mail system is down,
|
||||
/* out of memory.
|
||||
@ -63,6 +73,11 @@
|
||||
/* IBM T.J. Watson Research
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*
|
||||
/* Wietse Venema
|
||||
/* Google, Inc.
|
||||
/* 111 8th Avenue
|
||||
/* New York, NY 10011, USA
|
||||
/*--*/
|
||||
|
||||
/* System library. */
|
||||
@ -93,6 +108,7 @@ struct CLNT_STREAM {
|
||||
VSTREAM *vstream; /* buffered I/O */
|
||||
int timeout; /* time before client disconnect */
|
||||
int ttl; /* time before client disconnect */
|
||||
CLNT_STREAM_HANDSHAKE_FN handshake;
|
||||
char *class; /* server class */
|
||||
char *service; /* server name */
|
||||
};
|
||||
@ -205,6 +221,7 @@ void clnt_stream_recover(CLNT_STREAM *clnt_stream)
|
||||
|
||||
VSTREAM *clnt_stream_access(CLNT_STREAM *clnt_stream)
|
||||
{
|
||||
CLNT_STREAM_HANDSHAKE_FN handshake;
|
||||
|
||||
/*
|
||||
* Open a stream or restart the idle timer.
|
||||
@ -213,20 +230,26 @@ VSTREAM *clnt_stream_access(CLNT_STREAM *clnt_stream)
|
||||
*/
|
||||
if (clnt_stream->vstream == 0) {
|
||||
clnt_stream_open(clnt_stream);
|
||||
handshake = clnt_stream->handshake;
|
||||
} else if (readable(vstream_fileno(clnt_stream->vstream))) {
|
||||
clnt_stream_close(clnt_stream);
|
||||
clnt_stream_open(clnt_stream);
|
||||
handshake = clnt_stream->handshake;
|
||||
} else {
|
||||
event_request_timer(clnt_stream_event, (void *) clnt_stream,
|
||||
clnt_stream->timeout);
|
||||
handshake = 0;
|
||||
}
|
||||
if (handshake != 0 && handshake(clnt_stream->vstream) != 0)
|
||||
return (0);
|
||||
return (clnt_stream->vstream);
|
||||
}
|
||||
|
||||
/* clnt_stream_create - create client stream connection */
|
||||
|
||||
CLNT_STREAM *clnt_stream_create(const char *class, const char *service,
|
||||
int timeout, int ttl)
|
||||
int timeout, int ttl,
|
||||
CLNT_STREAM_HANDSHAKE_FN handshake)
|
||||
{
|
||||
CLNT_STREAM *clnt_stream;
|
||||
|
||||
@ -237,6 +260,7 @@ CLNT_STREAM *clnt_stream_create(const char *class, const char *service,
|
||||
clnt_stream->vstream = 0;
|
||||
clnt_stream->timeout = timeout;
|
||||
clnt_stream->ttl = ttl;
|
||||
clnt_stream->handshake = handshake;
|
||||
clnt_stream->class = mystrdup(class);
|
||||
clnt_stream->service = mystrdup(service);
|
||||
return (clnt_stream);
|
||||
|
@ -20,9 +20,12 @@
|
||||
* External interface.
|
||||
*/
|
||||
typedef struct CLNT_STREAM CLNT_STREAM;
|
||||
typedef int (*CLNT_STREAM_HANDSHAKE_FN)(VSTREAM *);
|
||||
|
||||
extern CLNT_STREAM *clnt_stream_create(const char *, const char *, int, int);
|
||||
extern CLNT_STREAM *clnt_stream_create(const char *, const char *, int, int,
|
||||
CLNT_STREAM_HANDSHAKE_FN);
|
||||
extern VSTREAM *clnt_stream_access(CLNT_STREAM *);
|
||||
extern const char *clnt_stream_path(CLNT_STREAM *);
|
||||
extern void clnt_stream_recover(CLNT_STREAM *);
|
||||
extern void clnt_stream_free(CLNT_STREAM *);
|
||||
|
||||
@ -35,6 +38,11 @@ extern void clnt_stream_free(CLNT_STREAM *);
|
||||
/* IBM T.J. Watson Research
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*
|
||||
/* Wietse Venema
|
||||
/* Google, Inc.
|
||||
/* 111 8th Avenue
|
||||
/* New York, NY 10011, USA
|
||||
/*--*/
|
||||
|
||||
#endif
|
||||
|
@ -153,6 +153,11 @@
|
||||
/* IBM T.J. Watson Research
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*
|
||||
/* Wietse Venema
|
||||
/* Google, Inc.
|
||||
/* 111 8th Avenue
|
||||
/* New York, NY 10011, USA
|
||||
/*--*/
|
||||
|
||||
/* System library. */
|
||||
@ -257,6 +262,7 @@ int defer_append_intern(int flags, const char *id, MSG_STATS *stats,
|
||||
my_dsn.action = "delayed";
|
||||
|
||||
if (mail_command_client(MAIL_CLASS_PRIVATE, var_defer_service,
|
||||
MAIL_ATTR_PROTO_BOUNCE,
|
||||
SEND_ATTR_INT(MAIL_ATTR_NREQ, BOUNCE_CMD_APPEND),
|
||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
|
||||
SEND_ATTR_STR(MAIL_ATTR_QUEUEID, id),
|
||||
@ -301,6 +307,7 @@ int defer_flush(int flags, const char *queue, const char *id,
|
||||
flags |= BOUNCE_FLAG_DELRCPT;
|
||||
|
||||
if (mail_command_client(MAIL_CLASS_PRIVATE, var_defer_service,
|
||||
MAIL_ATTR_PROTO_BOUNCE,
|
||||
SEND_ATTR_INT(MAIL_ATTR_NREQ, BOUNCE_CMD_FLUSH),
|
||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
|
||||
SEND_ATTR_STR(MAIL_ATTR_QUEUE, queue),
|
||||
@ -325,6 +332,7 @@ int defer_warn(int flags, const char *queue, const char *id,
|
||||
const char *sender, const char *envid, int dsn_ret)
|
||||
{
|
||||
if (mail_command_client(MAIL_CLASS_PRIVATE, var_defer_service,
|
||||
MAIL_ATTR_PROTO_BOUNCE,
|
||||
SEND_ATTR_INT(MAIL_ATTR_NREQ, BOUNCE_CMD_WARN),
|
||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
|
||||
SEND_ATTR_STR(MAIL_ATTR_QUEUE, queue),
|
||||
|
@ -49,6 +49,11 @@
|
||||
/* IBM T.J. Watson Research
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*
|
||||
/* Wietse Venema
|
||||
/* Google, Inc.
|
||||
/* 111 8th Avenue
|
||||
/* New York, NY 10011, USA
|
||||
/*--*/
|
||||
|
||||
/* System library. */
|
||||
@ -79,15 +84,13 @@
|
||||
|
||||
static int deliver_pass_initial_reply(VSTREAM *stream)
|
||||
{
|
||||
int stat;
|
||||
|
||||
if (attr_scan(stream, ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_INT(MAIL_ATTR_STATUS, &stat),
|
||||
ATTR_TYPE_END) != 1) {
|
||||
RECV_ATTR_STREQ(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_DELIVER),
|
||||
ATTR_TYPE_END) != 0) {
|
||||
msg_warn("%s: malformed response", VSTREAM_PATH(stream));
|
||||
stat = -1;
|
||||
return (-1);
|
||||
}
|
||||
return (stat);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* deliver_pass_send_request - send delivery request to delivery process */
|
||||
|
@ -92,6 +92,11 @@
|
||||
/* IBM T.J. Watson Research
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*
|
||||
/* Wietse Venema
|
||||
/* Google, Inc.
|
||||
/* 111 8th Avenue
|
||||
/* New York, NY 10011, USA
|
||||
/*--*/
|
||||
|
||||
/* System library. */
|
||||
@ -135,13 +140,13 @@ static int deliver_request_initial(VSTREAM *stream)
|
||||
* delivery request; otherwise the queue manager could block in write().
|
||||
*/
|
||||
if (msg_verbose)
|
||||
msg_info("deliver_request_initial: send initial status");
|
||||
msg_info("deliver_request_initial: send initial response");
|
||||
attr_print(stream, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_INT(MAIL_ATTR_STATUS, 0),
|
||||
SEND_ATTR_STR(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_DELIVER),
|
||||
ATTR_TYPE_END);
|
||||
if ((err = vstream_fflush(stream)) != 0)
|
||||
if (msg_verbose)
|
||||
msg_warn("send initial status: %m");
|
||||
msg_warn("send initial response: %m");
|
||||
return (err);
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,11 @@
|
||||
/* IBM T.J. Watson Research
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*
|
||||
/* Wietse Venema
|
||||
/* Google, Inc.
|
||||
/* 111 8th Avenue
|
||||
/* New York, NY 10011, USA
|
||||
/*--*/
|
||||
|
||||
/* System library. */
|
||||
@ -89,6 +94,15 @@ typedef struct {
|
||||
static CLNT_STREAM *proxymap_stream; /* read-only maps */
|
||||
static CLNT_STREAM *proxywrite_stream; /* read-write maps */
|
||||
|
||||
/* dict_proxy_handshake - receive server protocol announcement */
|
||||
|
||||
static int dict_proxy_handshake(VSTREAM *stream)
|
||||
{
|
||||
return (attr_scan(stream, ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_STREQ(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_PROXYMAP),
|
||||
ATTR_TYPE_END));
|
||||
}
|
||||
|
||||
/* dict_proxy_sequence - find first/next entry */
|
||||
|
||||
static int dict_proxy_sequence(DICT *dict, int function,
|
||||
@ -118,12 +132,13 @@ static int dict_proxy_sequence(DICT *dict, int function,
|
||||
stream = clnt_stream_access(dict_proxy->clnt);
|
||||
errno = 0;
|
||||
count += 1;
|
||||
if (attr_print(stream, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR(MAIL_ATTR_REQ, PROXY_REQ_SEQUENCE),
|
||||
SEND_ATTR_STR(MAIL_ATTR_TABLE, dict->name),
|
||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, request_flags),
|
||||
SEND_ATTR_INT(MAIL_ATTR_FUNC, function),
|
||||
ATTR_TYPE_END) != 0
|
||||
if (stream == 0
|
||||
|| attr_print(stream, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR(MAIL_ATTR_REQ, PROXY_REQ_SEQUENCE),
|
||||
SEND_ATTR_STR(MAIL_ATTR_TABLE, dict->name),
|
||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, request_flags),
|
||||
SEND_ATTR_INT(MAIL_ATTR_FUNC, function),
|
||||
ATTR_TYPE_END) != 0
|
||||
|| vstream_fflush(stream)
|
||||
|| attr_scan(stream, ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_INT(MAIL_ATTR_STATUS, &status),
|
||||
@ -131,7 +146,7 @@ static int dict_proxy_sequence(DICT *dict, int function,
|
||||
RECV_ATTR_STR(MAIL_ATTR_VALUE, dict_proxy->result),
|
||||
ATTR_TYPE_END) != 3) {
|
||||
if (msg_verbose || count > 1 || (errno && errno != EPIPE && errno != ENOENT))
|
||||
msg_warn("%s: service %s: %m", myname, VSTREAM_PATH(stream));
|
||||
msg_warn("%s: service %s: %m", myname, dict_proxy->service);
|
||||
} else {
|
||||
if (msg_verbose)
|
||||
msg_info("%s: table=%s flags=%s func=%d -> status=%d key=%s val=%s",
|
||||
@ -196,19 +211,20 @@ static const char *dict_proxy_lookup(DICT *dict, const char *key)
|
||||
stream = clnt_stream_access(dict_proxy->clnt);
|
||||
errno = 0;
|
||||
count += 1;
|
||||
if (attr_print(stream, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR(MAIL_ATTR_REQ, PROXY_REQ_LOOKUP),
|
||||
SEND_ATTR_STR(MAIL_ATTR_TABLE, dict->name),
|
||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, request_flags),
|
||||
SEND_ATTR_STR(MAIL_ATTR_KEY, key),
|
||||
ATTR_TYPE_END) != 0
|
||||
if (stream == 0
|
||||
|| attr_print(stream, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR(MAIL_ATTR_REQ, PROXY_REQ_LOOKUP),
|
||||
SEND_ATTR_STR(MAIL_ATTR_TABLE, dict->name),
|
||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, request_flags),
|
||||
SEND_ATTR_STR(MAIL_ATTR_KEY, key),
|
||||
ATTR_TYPE_END) != 0
|
||||
|| vstream_fflush(stream)
|
||||
|| attr_scan(stream, ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_INT(MAIL_ATTR_STATUS, &status),
|
||||
RECV_ATTR_STR(MAIL_ATTR_VALUE, dict_proxy->result),
|
||||
ATTR_TYPE_END) != 2) {
|
||||
if (msg_verbose || count > 1 || (errno && errno != EPIPE && errno != ENOENT))
|
||||
msg_warn("%s: service %s: %m", myname, VSTREAM_PATH(stream));
|
||||
msg_warn("%s: service %s: %m", myname, dict_proxy->service);
|
||||
} else {
|
||||
if (msg_verbose)
|
||||
msg_info("%s: table=%s flags=%s key=%s -> status=%d result=%s",
|
||||
@ -266,19 +282,20 @@ static int dict_proxy_update(DICT *dict, const char *key, const char *value)
|
||||
stream = clnt_stream_access(dict_proxy->clnt);
|
||||
errno = 0;
|
||||
count += 1;
|
||||
if (attr_print(stream, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR(MAIL_ATTR_REQ, PROXY_REQ_UPDATE),
|
||||
SEND_ATTR_STR(MAIL_ATTR_TABLE, dict->name),
|
||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, request_flags),
|
||||
SEND_ATTR_STR(MAIL_ATTR_KEY, key),
|
||||
SEND_ATTR_STR(MAIL_ATTR_VALUE, value),
|
||||
ATTR_TYPE_END) != 0
|
||||
if (stream == 0
|
||||
|| attr_print(stream, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR(MAIL_ATTR_REQ, PROXY_REQ_UPDATE),
|
||||
SEND_ATTR_STR(MAIL_ATTR_TABLE, dict->name),
|
||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, request_flags),
|
||||
SEND_ATTR_STR(MAIL_ATTR_KEY, key),
|
||||
SEND_ATTR_STR(MAIL_ATTR_VALUE, value),
|
||||
ATTR_TYPE_END) != 0
|
||||
|| vstream_fflush(stream)
|
||||
|| attr_scan(stream, ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_INT(MAIL_ATTR_STATUS, &status),
|
||||
ATTR_TYPE_END) != 1) {
|
||||
if (msg_verbose || count > 1 || (errno && errno != EPIPE && errno != ENOENT))
|
||||
msg_warn("%s: service %s: %m", myname, VSTREAM_PATH(stream));
|
||||
msg_warn("%s: service %s: %m", myname, dict_proxy->service);
|
||||
} else {
|
||||
if (msg_verbose)
|
||||
msg_info("%s: table=%s flags=%s key=%s value=%s -> status=%d",
|
||||
@ -335,19 +352,20 @@ static int dict_proxy_delete(DICT *dict, const char *key)
|
||||
stream = clnt_stream_access(dict_proxy->clnt);
|
||||
errno = 0;
|
||||
count += 1;
|
||||
if (attr_print(stream, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR(MAIL_ATTR_REQ, PROXY_REQ_DELETE),
|
||||
SEND_ATTR_STR(MAIL_ATTR_TABLE, dict->name),
|
||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, request_flags),
|
||||
SEND_ATTR_STR(MAIL_ATTR_KEY, key),
|
||||
ATTR_TYPE_END) != 0
|
||||
if (stream == 0
|
||||
|| attr_print(stream, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR(MAIL_ATTR_REQ, PROXY_REQ_DELETE),
|
||||
SEND_ATTR_STR(MAIL_ATTR_TABLE, dict->name),
|
||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, request_flags),
|
||||
SEND_ATTR_STR(MAIL_ATTR_KEY, key),
|
||||
ATTR_TYPE_END) != 0
|
||||
|| vstream_fflush(stream)
|
||||
|| attr_scan(stream, ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_INT(MAIL_ATTR_STATUS, &status),
|
||||
ATTR_TYPE_END) != 1) {
|
||||
if (msg_verbose || count > 1 || (errno && errno != EPIPE && errno !=
|
||||
ENOENT))
|
||||
msg_warn("%s: service %s: %m", myname, VSTREAM_PATH(stream));
|
||||
msg_warn("%s: service %s: %m", myname, dict_proxy->service);
|
||||
} else {
|
||||
if (msg_verbose)
|
||||
msg_info("%s: table=%s flags=%s key=%s -> status=%d",
|
||||
@ -443,7 +461,8 @@ DICT *dict_proxy_open(const char *map, int open_flags, int dict_flags)
|
||||
prefix = kludge = concatenate(var_queue_dir, "/",
|
||||
MAIL_CLASS_PRIVATE, (char *) 0);
|
||||
*pstream = clnt_stream_create(prefix, service, var_ipc_idle_limit,
|
||||
var_ipc_ttl_limit);
|
||||
var_ipc_ttl_limit,
|
||||
dict_proxy_handshake);
|
||||
if (kludge)
|
||||
myfree(kludge);
|
||||
myfree(relative_path);
|
||||
@ -473,18 +492,19 @@ DICT *dict_proxy_open(const char *map, int open_flags, int dict_flags)
|
||||
for (;;) {
|
||||
stream = clnt_stream_access(dict_proxy->clnt);
|
||||
errno = 0;
|
||||
if (attr_print(stream, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR(MAIL_ATTR_REQ, PROXY_REQ_OPEN),
|
||||
SEND_ATTR_STR(MAIL_ATTR_TABLE, dict_proxy->dict.name),
|
||||
if (stream == 0
|
||||
|| attr_print(stream, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR(MAIL_ATTR_REQ, PROXY_REQ_OPEN),
|
||||
SEND_ATTR_STR(MAIL_ATTR_TABLE, dict_proxy->dict.name),
|
||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, dict_proxy->inst_flags),
|
||||
ATTR_TYPE_END) != 0
|
||||
ATTR_TYPE_END) != 0
|
||||
|| vstream_fflush(stream)
|
||||
|| attr_scan(stream, ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_INT(MAIL_ATTR_STATUS, &status),
|
||||
RECV_ATTR_INT(MAIL_ATTR_FLAGS, &server_flags),
|
||||
ATTR_TYPE_END) != 2) {
|
||||
if (msg_verbose || (errno != EPIPE && errno != ENOENT))
|
||||
msg_warn("%s: service %s: %m", VSTREAM_PATH(stream), myname);
|
||||
msg_warn("%s: service %s: %m", myname, dict_proxy->service);
|
||||
} else {
|
||||
if (msg_verbose)
|
||||
msg_info("%s: connect to map=%s status=%d server_flags=%s",
|
||||
|
@ -71,6 +71,11 @@
|
||||
/* IBM T.J. Watson Research
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*
|
||||
/* Wietse Venema
|
||||
/* Google, Inc.
|
||||
/* 111 8th Avenue
|
||||
/* New York, NY 10011, USA
|
||||
/*--*/
|
||||
|
||||
/* System library. */
|
||||
@ -125,6 +130,7 @@ int flush_purge(void)
|
||||
status = FLUSH_STAT_DENY;
|
||||
else
|
||||
status = mail_command_client(MAIL_CLASS_PUBLIC, var_flush_service,
|
||||
MAIL_ATTR_PROTO_FLUSH,
|
||||
SEND_ATTR_STR(MAIL_ATTR_REQ, FLUSH_REQ_PURGE),
|
||||
ATTR_TYPE_END);
|
||||
|
||||
@ -151,6 +157,7 @@ int flush_refresh(void)
|
||||
status = FLUSH_STAT_DENY;
|
||||
else
|
||||
status = mail_command_client(MAIL_CLASS_PUBLIC, var_flush_service,
|
||||
MAIL_ATTR_PROTO_FLUSH,
|
||||
SEND_ATTR_STR(MAIL_ATTR_REQ, FLUSH_REQ_REFRESH),
|
||||
ATTR_TYPE_END);
|
||||
|
||||
@ -182,6 +189,7 @@ int flush_send_site(const char *site)
|
||||
VAR_RELAY_DOMAINS "=$mydestination to flush "
|
||||
"mail for domain \"%s\"", site);
|
||||
status = mail_command_client(MAIL_CLASS_PUBLIC, var_flush_service,
|
||||
MAIL_ATTR_PROTO_FLUSH,
|
||||
SEND_ATTR_STR(MAIL_ATTR_REQ, FLUSH_REQ_SEND_SITE),
|
||||
SEND_ATTR_STR(MAIL_ATTR_SITE, site),
|
||||
ATTR_TYPE_END);
|
||||
@ -210,6 +218,7 @@ int flush_send_file(const char *queue_id)
|
||||
* Require that the service is turned on.
|
||||
*/
|
||||
status = mail_command_client(MAIL_CLASS_PUBLIC, var_flush_service,
|
||||
MAIL_ATTR_PROTO_FLUSH,
|
||||
SEND_ATTR_STR(MAIL_ATTR_REQ, FLUSH_REQ_SEND_FILE),
|
||||
SEND_ATTR_STR(MAIL_ATTR_QUEUEID, queue_id),
|
||||
ATTR_TYPE_END);
|
||||
@ -242,6 +251,7 @@ int flush_add(const char *site, const char *queue_id)
|
||||
VAR_RELAY_DOMAINS "=$mydestination to update "
|
||||
"fast-flush logfile for domain \"%s\"", site);
|
||||
status = mail_command_client(MAIL_CLASS_PUBLIC, var_flush_service,
|
||||
MAIL_ATTR_PROTO_FLUSH,
|
||||
SEND_ATTR_STR(MAIL_ATTR_REQ, FLUSH_REQ_ADD),
|
||||
SEND_ATTR_STR(MAIL_ATTR_SITE, site),
|
||||
SEND_ATTR_STR(MAIL_ATTR_QUEUEID, queue_id),
|
||||
|
@ -403,7 +403,6 @@ static const char *haproxy_srvr_parse_v2_hdr(const char *str, ssize_t *str_len,
|
||||
return ("unsupported network protocol");
|
||||
}
|
||||
/* For now, skip and ignore TLVs. */
|
||||
*non_proxy = 0;
|
||||
*str_len = PP2_HEADER_LEN + ntohs(hdr_v2->len);
|
||||
return (0);
|
||||
|
||||
@ -434,6 +433,8 @@ const char *haproxy_srvr_parse(const char *str, ssize_t *str_len,
|
||||
if (proto_info == 0)
|
||||
proto_info = inet_proto_info();
|
||||
|
||||
*non_proxy = 0;
|
||||
|
||||
/*
|
||||
* XXX We don't accept connections with the "UNKNOWN" protocol type,
|
||||
* because those would sidestep address-based access control mechanisms.
|
||||
@ -471,7 +472,6 @@ const char *haproxy_srvr_parse(const char *str, ssize_t *str_len,
|
||||
}
|
||||
myfree(saved_str);
|
||||
|
||||
*non_proxy = 0;
|
||||
return (err);
|
||||
}
|
||||
|
||||
|
@ -6,9 +6,10 @@
|
||||
/* SYNOPSIS
|
||||
/* #include <mail_proto.h>
|
||||
/*
|
||||
/* int mail_command_client(class, name, type, attr, ...)
|
||||
/* int mail_command_client(class, name, proto, type, attr, ...)
|
||||
/* const char *class;
|
||||
/* const char *name;
|
||||
/* const char *proto;
|
||||
/* int type;
|
||||
/* const char *attr;
|
||||
/* DESCRIPTION
|
||||
@ -21,6 +22,8 @@
|
||||
/* Service type: MAIL_CLASS_PUBLIC or MAIL_CLASS_PRIVATE
|
||||
/* .IP name
|
||||
/* Service name (master.cf).
|
||||
/* .IP proto
|
||||
/* The expected protocol name in the server announcement.
|
||||
/* .IP "type, attr, ..."
|
||||
/* Attribute information as defined in attr_print(3).
|
||||
/* DIAGNOSTICS
|
||||
@ -65,7 +68,8 @@
|
||||
|
||||
/* mail_command_client - single-command transaction with completion status */
|
||||
|
||||
int mail_command_client(const char *class, const char *name,...)
|
||||
int mail_command_client(const char *class, const char *name,
|
||||
const char *proto,...)
|
||||
{
|
||||
va_list ap;
|
||||
VSTREAM *stream;
|
||||
@ -82,14 +86,20 @@ int mail_command_client(const char *class, const char *name,...)
|
||||
msg_warn("connect to %s/%s: %m", class, name);
|
||||
return (-1);
|
||||
}
|
||||
va_start(ap, name);
|
||||
status = attr_vprint(stream, ATTR_FLAG_NONE, ap);
|
||||
va_end(ap);
|
||||
if (status != 0) {
|
||||
if (attr_scan(stream, ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_STREQ(MAIL_ATTR_PROTO, proto),
|
||||
ATTR_TYPE_END) != 0) {
|
||||
msg_warn("read %s: %m", VSTREAM_PATH(stream));
|
||||
status = -1;
|
||||
} else if (va_start(ap, proto),
|
||||
(status = attr_vprint(stream, ATTR_FLAG_NONE, ap)),
|
||||
va_end(ap),
|
||||
(status != 0)) {
|
||||
msg_warn("write %s: %m", VSTREAM_PATH(stream));
|
||||
status = -1;
|
||||
} else if (attr_scan(stream, ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_INT(MAIL_ATTR_STATUS, &status), 0) != 1) {
|
||||
RECV_ATTR_INT(MAIL_ATTR_STATUS, &status),
|
||||
ATTR_TYPE_END) != 1) {
|
||||
msg_warn("write/read %s: %m", VSTREAM_PATH(stream));
|
||||
status = -1;
|
||||
}
|
||||
|
@ -114,11 +114,32 @@
|
||||
*/
|
||||
extern VSTREAM *mail_connect(const char *, const char *, int);
|
||||
extern VSTREAM *mail_connect_wait(const char *, const char *);
|
||||
extern int mail_command_client(const char *, const char *,...);
|
||||
extern int mail_command_client(const char *, const char *, const char *,...);
|
||||
extern int mail_command_server(VSTREAM *,...);
|
||||
extern int mail_trigger(const char *, const char *, const char *, ssize_t);
|
||||
extern char *mail_pathname(const char *, const char *);
|
||||
|
||||
/*
|
||||
* Each Postfix internal service identifies the protocol that it intends to
|
||||
* use. On the receiver end, this information does not contribute to the
|
||||
* reported number of received attributes (it is a constant).
|
||||
*/
|
||||
#define MAIL_ATTR_PROTO "protocol"
|
||||
|
||||
#define MAIL_ATTR_PROTO_ANVIL "anvil_protocol"
|
||||
#define MAIL_ATTR_PROTO_BOUNCE "delivery_status_protocol"
|
||||
#define MAIL_ATTR_PROTO_CLEANUP "cleanup_protocol"
|
||||
#define MAIL_ATTR_PROTO_DELIVER "delivery_request_protocol"
|
||||
#define MAIL_ATTR_PROTO_FLUSH "queue_flush_protocol"
|
||||
#define MAIL_ATTR_PROTO_POSTDROP "postdrop_protocol"
|
||||
#define MAIL_ATTR_PROTO_PROXYMAP "proxymap_protocol"
|
||||
#define MAIL_ATTR_PROTO_SCACHE "connection_cache_protocol"
|
||||
#define MAIL_ATTR_PROTO_SHOWQ "mail_queue_list_protocol"
|
||||
#define MAIL_ATTR_PROTO_TLSMGR "tlsmgr_protocol"
|
||||
#define MAIL_ATTR_PROTO_TLSPROXY "tlsproxy_protocol"
|
||||
#define MAIL_ATTR_PROTO_TRIVIAL "trivial_rewrite_protocol"
|
||||
#define MAIL_ATTR_PROTO_VERIFY "address_verification_prrotocol"
|
||||
|
||||
/*
|
||||
* Attribute names.
|
||||
*/
|
||||
|
@ -105,6 +105,11 @@
|
||||
/* IBM T.J. Watson Research
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*
|
||||
/* Wietse Venema
|
||||
/* Google, Inc.
|
||||
/* 111 8th Avenue
|
||||
/* New York, NY 10011, USA
|
||||
/*--*/
|
||||
|
||||
/* System library. */
|
||||
@ -440,7 +445,8 @@ MAIL_STREAM *mail_stream_service(const char *class, const char *name)
|
||||
id_buf = vstring_alloc(10);
|
||||
|
||||
stream = mail_connect_wait(class, name);
|
||||
if (attr_scan(stream, ATTR_FLAG_MISSING,
|
||||
if (attr_scan(stream, ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_STREQ(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_CLEANUP),
|
||||
RECV_ATTR_STR(MAIL_ATTR_QUEUEID, id_buf), 0) != 1) {
|
||||
vstream_fclose(stream);
|
||||
return (0);
|
||||
@ -492,7 +498,8 @@ MAIL_STREAM *mail_stream_command(const char *command)
|
||||
CA_VSTREAM_CTL_PATH(command),
|
||||
CA_VSTREAM_CTL_END);
|
||||
|
||||
if (attr_scan(stream, ATTR_FLAG_MISSING,
|
||||
if (attr_scan(stream, ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_STREQ(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_POSTDROP),
|
||||
RECV_ATTR_STR(MAIL_ATTR_QUEUEID, id_buf), 0) != 1) {
|
||||
if ((status = vstream_pclose(stream)) != 0)
|
||||
msg_warn("command \"%s\" exited with status %d", command, status);
|
||||
|
@ -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 "20200830"
|
||||
#define MAIL_RELEASE_DATE "20200920"
|
||||
#define MAIL_VERSION_NUMBER "3.6"
|
||||
|
||||
#ifdef SNAPSHOT
|
||||
|
@ -231,8 +231,18 @@ static void post_mail_init(VSTREAM *stream, const char *sender,
|
||||
date = mail_date(now.tv_sec);
|
||||
|
||||
/*
|
||||
* XXX Don't flush buffers while sending the initial message records.
|
||||
* That would cause deadlock between verify(8) and cleanup(8) servers.
|
||||
* The comment in the next paragraph is likely obsolete. Fix 20030610
|
||||
* changed the verify server to use asynchronous submission of mail
|
||||
* probes, to avoid blocking the post_mail client for in_flow_delay
|
||||
* seconds when the cleanup service receives email messages faster than
|
||||
* they are delivered. Instead, the post_mail client waits until the
|
||||
* cleanup server announces its availability to receive input. A similar
|
||||
* change was made at the end of submission, to avoid blocking the
|
||||
* post_mail client for up to trigger_timeout seconds when the cleanup
|
||||
* server attempts to notify a queue manager that is overwhelmed.
|
||||
*
|
||||
* XXX Don't flush buffers while sending the initial message records. That
|
||||
* would cause deadlock between verify(8) and cleanup(8) servers.
|
||||
*/
|
||||
vstream_control(stream, VSTREAM_CTL_BUFSIZE, 2 * VSTREAM_BUFSIZE,
|
||||
VSTREAM_CTL_END);
|
||||
@ -241,6 +251,7 @@ static void post_mail_init(VSTREAM *stream, const char *sender,
|
||||
* Negotiate with the cleanup service. Give up if we can't agree.
|
||||
*/
|
||||
if (attr_scan(stream, ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_STREQ(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_CLEANUP),
|
||||
RECV_ATTR_STR(MAIL_ATTR_QUEUEID, id),
|
||||
ATTR_TYPE_END) != 1
|
||||
|| attr_print(stream, ATTR_FLAG_NONE,
|
||||
|
@ -152,6 +152,15 @@ void resolve_clnt_init(RESOLVE_REPLY *reply)
|
||||
reply->flags = 0;
|
||||
}
|
||||
|
||||
/* resolve_clnt_handshake - receive server protocol announcement */
|
||||
|
||||
static int resolve_clnt_handshake(VSTREAM *stream)
|
||||
{
|
||||
return (attr_scan(stream, ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_STREQ(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_TRIVIAL),
|
||||
ATTR_TYPE_END));
|
||||
}
|
||||
|
||||
/* resolve_clnt - resolve address to (transport, next hop, recipient) */
|
||||
|
||||
void resolve_clnt(const char *class, const char *sender,
|
||||
@ -219,17 +228,19 @@ void resolve_clnt(const char *class, const char *sender,
|
||||
rewrite_clnt_stream = clnt_stream_create(MAIL_CLASS_PRIVATE,
|
||||
var_rewrite_service,
|
||||
var_ipc_idle_limit,
|
||||
var_ipc_ttl_limit);
|
||||
var_ipc_ttl_limit,
|
||||
resolve_clnt_handshake);
|
||||
|
||||
for (;;) {
|
||||
stream = clnt_stream_access(rewrite_clnt_stream);
|
||||
errno = 0;
|
||||
count += 1;
|
||||
if (attr_print(stream, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR(MAIL_ATTR_REQ, class),
|
||||
SEND_ATTR_STR(MAIL_ATTR_SENDER, sender),
|
||||
SEND_ATTR_STR(MAIL_ATTR_ADDR, addr),
|
||||
ATTR_TYPE_END) != 0
|
||||
if (stream == 0
|
||||
|| attr_print(stream, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR(MAIL_ATTR_REQ, class),
|
||||
SEND_ATTR_STR(MAIL_ATTR_SENDER, sender),
|
||||
SEND_ATTR_STR(MAIL_ATTR_ADDR, addr),
|
||||
ATTR_TYPE_END) != 0
|
||||
|| vstream_fflush(stream)
|
||||
|| attr_scan(stream, ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_INT(MAIL_ATTR_FLAGS, &server_flags),
|
||||
|
@ -39,6 +39,11 @@
|
||||
/* IBM T.J. Watson Research
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*
|
||||
/* Wietse Venema
|
||||
/* Google, Inc.
|
||||
/* 111 8th Avenue
|
||||
/* New York, NY 10011, USA
|
||||
/*--*/
|
||||
|
||||
/* System library. */
|
||||
@ -77,6 +82,15 @@ static VSTRING *last_rule;
|
||||
static VSTRING *last_addr;
|
||||
static VSTRING *last_result;
|
||||
|
||||
/* rewrite_clnt_handshake - receive server protocol announcement */
|
||||
|
||||
static int rewrite_clnt_handshake(VSTREAM *stream)
|
||||
{
|
||||
return (attr_scan(stream, ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_STREQ(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_TRIVIAL),
|
||||
ATTR_TYPE_END));
|
||||
}
|
||||
|
||||
/* rewrite_clnt - rewrite address to (transport, next hop, recipient) */
|
||||
|
||||
VSTRING *rewrite_clnt(const char *rule, const char *addr, VSTRING *result)
|
||||
@ -127,17 +141,19 @@ VSTRING *rewrite_clnt(const char *rule, const char *addr, VSTRING *result)
|
||||
rewrite_clnt_stream = clnt_stream_create(MAIL_CLASS_PRIVATE,
|
||||
var_rewrite_service,
|
||||
var_ipc_idle_limit,
|
||||
var_ipc_ttl_limit);
|
||||
var_ipc_ttl_limit,
|
||||
rewrite_clnt_handshake);
|
||||
|
||||
for (;;) {
|
||||
stream = clnt_stream_access(rewrite_clnt_stream);
|
||||
errno = 0;
|
||||
count += 1;
|
||||
if (attr_print(stream, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR(MAIL_ATTR_REQ, REWRITE_ADDR),
|
||||
SEND_ATTR_STR(MAIL_ATTR_RULE, rule),
|
||||
SEND_ATTR_STR(MAIL_ATTR_ADDR, addr),
|
||||
ATTR_TYPE_END) != 0
|
||||
if (stream == 0
|
||||
|| attr_print(stream, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR(MAIL_ATTR_REQ, REWRITE_ADDR),
|
||||
SEND_ATTR_STR(MAIL_ATTR_RULE, rule),
|
||||
SEND_ATTR_STR(MAIL_ATTR_ADDR, addr),
|
||||
ATTR_TYPE_END) != 0
|
||||
|| vstream_fflush(stream)
|
||||
|| attr_scan(stream, ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_INT(MAIL_ATTR_FLAGS, &server_flags),
|
||||
|
@ -68,7 +68,7 @@
|
||||
/* sasl_mech_filter - filter a SASL mechanism list */
|
||||
|
||||
const char *sasl_mech_filter(STRING_LIST *filter,
|
||||
const const char *words)
|
||||
const char *words)
|
||||
{
|
||||
const char myname[] = "sasl_mech_filter";
|
||||
static VSTRING *buf;
|
||||
|
@ -41,6 +41,11 @@
|
||||
/* IBM T.J. Watson Research
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*
|
||||
/* Wietse Venema
|
||||
/* Google, Inc.
|
||||
/* 111 8th Avenue
|
||||
/* New York, NY 10011, USA
|
||||
/*--*/
|
||||
|
||||
/* System library. */
|
||||
@ -80,6 +85,15 @@ typedef struct {
|
||||
|
||||
#define SCACHE_MAX_TRIES 2
|
||||
|
||||
/* scache_clnt_handshake - receive server protocol announcement */
|
||||
|
||||
static int scache_clnt_handshake(VSTREAM *stream)
|
||||
{
|
||||
return (attr_scan(stream, ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_STREQ(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_SCACHE),
|
||||
ATTR_TYPE_END));
|
||||
}
|
||||
|
||||
/* scache_clnt_save_endp - save endpoint */
|
||||
|
||||
static void scache_clnt_save_endp(SCACHE *scache, int endp_ttl,
|
||||
@ -414,8 +428,11 @@ SCACHE *scache_clnt_create(const char *server, int timeout,
|
||||
sp->scache->size = scache_clnt_size;
|
||||
sp->scache->free = scache_clnt_free;
|
||||
|
||||
service = concatenate("local:private/", server, (char *) 0);
|
||||
service = concatenate("local:" MAIL_CLASS_PRIVATE "/", server, (char *) 0);
|
||||
sp->auto_clnt = auto_clnt_create(service, timeout, idle_limit, ttl_limit);
|
||||
auto_clnt_control(sp->auto_clnt,
|
||||
AUTO_CLNT_CTL_HANDSHAKE, scache_clnt_handshake,
|
||||
AUTO_CLNT_CTL_END);
|
||||
myfree(service);
|
||||
|
||||
#ifdef CANT_WRITE_BEFORE_SENDING_FD
|
||||
|
@ -79,6 +79,11 @@
|
||||
/* IBM T.J. Watson Research
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*
|
||||
/* Wietse Venema
|
||||
/* Google, Inc.
|
||||
/* 111 8th Avenue
|
||||
/* New York, NY 10011, USA
|
||||
/*--*/
|
||||
|
||||
/* System library. */
|
||||
@ -121,6 +126,7 @@ int trace_append(int flags, const char *id, MSG_STATS *stats,
|
||||
my_dsn.reason = vstring_str(why);
|
||||
|
||||
if (mail_command_client(MAIL_CLASS_PRIVATE, var_trace_service,
|
||||
MAIL_ATTR_PROTO_BOUNCE,
|
||||
SEND_ATTR_INT(MAIL_ATTR_NREQ, BOUNCE_CMD_APPEND),
|
||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
|
||||
SEND_ATTR_STR(MAIL_ATTR_QUEUEID, id),
|
||||
@ -145,6 +151,7 @@ int trace_flush(int flags, const char *queue, const char *id,
|
||||
const char *dsn_envid, int dsn_ret)
|
||||
{
|
||||
if (mail_command_client(MAIL_CLASS_PRIVATE, var_trace_service,
|
||||
MAIL_ATTR_PROTO_BOUNCE,
|
||||
SEND_ATTR_INT(MAIL_ATTR_NREQ, BOUNCE_CMD_TRACE),
|
||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
|
||||
SEND_ATTR_STR(MAIL_ATTR_QUEUE, queue),
|
||||
|
@ -56,6 +56,11 @@
|
||||
/* IBM T.J. Watson Research
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*
|
||||
/* Wietse Venema
|
||||
/* Google, Inc.
|
||||
/* 111 8th Avenue
|
||||
/* New York, NY 10011, USA
|
||||
/*--*/
|
||||
|
||||
/* System library. */
|
||||
@ -80,6 +85,15 @@
|
||||
|
||||
CLNT_STREAM *vrfy_clnt;
|
||||
|
||||
/* verify_clnt_handshake - receive server protocol announcement */
|
||||
|
||||
static int verify_clnt_handshake(VSTREAM *stream)
|
||||
{
|
||||
return (attr_scan(stream, ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_STREQ(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_VERIFY),
|
||||
ATTR_TYPE_END));
|
||||
}
|
||||
|
||||
/* verify_clnt_init - initialize */
|
||||
|
||||
static void verify_clnt_init(void)
|
||||
@ -87,7 +101,8 @@ static void verify_clnt_init(void)
|
||||
if (vrfy_clnt != 0)
|
||||
msg_panic("verify_clnt_init: multiple initialization");
|
||||
vrfy_clnt = clnt_stream_create(MAIL_CLASS_PRIVATE, var_verify_service,
|
||||
var_ipc_idle_limit, var_ipc_ttl_limit);
|
||||
var_ipc_idle_limit, var_ipc_ttl_limit,
|
||||
verify_clnt_handshake);
|
||||
}
|
||||
|
||||
/* verify_clnt_query - request address verification status */
|
||||
@ -111,10 +126,11 @@ int verify_clnt_query(const char *addr, int *addr_status, VSTRING *why)
|
||||
stream = clnt_stream_access(vrfy_clnt);
|
||||
errno = 0;
|
||||
count += 1;
|
||||
if (attr_print(stream, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR(MAIL_ATTR_REQ, VRFY_REQ_QUERY),
|
||||
SEND_ATTR_STR(MAIL_ATTR_ADDR, addr),
|
||||
ATTR_TYPE_END) != 0
|
||||
if (stream == 0
|
||||
|| attr_print(stream, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR(MAIL_ATTR_REQ, VRFY_REQ_QUERY),
|
||||
SEND_ATTR_STR(MAIL_ATTR_ADDR, addr),
|
||||
ATTR_TYPE_END) != 0
|
||||
|| vstream_fflush(stream)
|
||||
|| attr_scan(stream, ATTR_FLAG_MISSING,
|
||||
RECV_ATTR_INT(MAIL_ATTR_STATUS, &request_status),
|
||||
@ -153,12 +169,13 @@ int verify_clnt_update(const char *addr, int addr_status, const char *why)
|
||||
for (;;) {
|
||||
stream = clnt_stream_access(vrfy_clnt);
|
||||
errno = 0;
|
||||
if (attr_print(stream, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR(MAIL_ATTR_REQ, VRFY_REQ_UPDATE),
|
||||
SEND_ATTR_STR(MAIL_ATTR_ADDR, addr),
|
||||
SEND_ATTR_INT(MAIL_ATTR_ADDR_STATUS, addr_status),
|
||||
SEND_ATTR_STR(MAIL_ATTR_WHY, why),
|
||||
ATTR_TYPE_END) != 0
|
||||
if (stream == 0
|
||||
|| attr_print(stream, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR(MAIL_ATTR_REQ, VRFY_REQ_UPDATE),
|
||||
SEND_ATTR_STR(MAIL_ATTR_ADDR, addr),
|
||||
SEND_ATTR_INT(MAIL_ATTR_ADDR_STATUS, addr_status),
|
||||
SEND_ATTR_STR(MAIL_ATTR_WHY, why),
|
||||
ATTR_TYPE_END) != 0
|
||||
|| attr_scan(stream, ATTR_FLAG_MISSING,
|
||||
RECV_ATTR_INT(MAIL_ATTR_STATUS, &request_status),
|
||||
ATTR_TYPE_END) != 1) {
|
||||
|
@ -146,6 +146,7 @@ static FORWARD_INFO *forward_open(DELIVER_REQUEST *request, const char *sender)
|
||||
}
|
||||
close_on_exec(vstream_fileno(cleanup), CLOSE_ON_EXEC);
|
||||
if (attr_scan(cleanup, ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_STREQ(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_CLEANUP),
|
||||
RECV_ATTR_STR(MAIL_ATTR_QUEUEID, buffer),
|
||||
ATTR_TYPE_END) != 1) {
|
||||
vstream_fclose(cleanup);
|
||||
|
@ -273,7 +273,6 @@ static unsigned event_server_generation;
|
||||
static void (*event_server_pre_disconn) (VSTREAM *, char *, char **);
|
||||
static void (*event_server_slow_exit) (char *, char **);
|
||||
static int event_server_watchdog = 1000;
|
||||
static int event_server_saved_flags;
|
||||
|
||||
/* event_server_exit - normal termination */
|
||||
|
||||
@ -373,8 +372,7 @@ void event_server_disconnect(VSTREAM *stream)
|
||||
static void event_server_execute(int unused_event, void *context)
|
||||
{
|
||||
VSTREAM *stream = (VSTREAM *) context;
|
||||
HTABLE *attr = (vstream_flags(stream) == event_server_saved_flags ?
|
||||
(HTABLE *) vstream_context(stream) : 0);
|
||||
HTABLE *attr = (HTABLE *) vstream_context(stream);
|
||||
|
||||
if (event_server_lock != 0
|
||||
&& myflock(vstream_fileno(event_server_lock), INTERNAL_LOCK,
|
||||
@ -432,7 +430,6 @@ static void event_server_wakeup(int fd, HTABLE *attr)
|
||||
CA_VSTREAM_CTL_END);
|
||||
myfree(tmp);
|
||||
timed_ipc_setup(stream);
|
||||
event_server_saved_flags = vstream_flags(stream);
|
||||
if (event_server_in_flow_delay && mail_flow_get(1) < 0)
|
||||
event_request_timer(event_server_execute, (void *) stream,
|
||||
var_in_flow_delay);
|
||||
|
@ -12,6 +12,7 @@
|
||||
* Utility library.
|
||||
*/
|
||||
#include <vstream.h>
|
||||
#include <htable.h>
|
||||
|
||||
/*
|
||||
* Global library.
|
||||
@ -45,11 +46,13 @@
|
||||
#define MAIL_SERVER_SLOW_EXIT 21
|
||||
#define MAIL_SERVER_BOUNCE_INIT 22
|
||||
#define MAIL_SERVER_RETIRE_ME 23
|
||||
#define MAIL_SERVER_POST_ACCEPT 24
|
||||
|
||||
typedef void (*MAIL_SERVER_INIT_FN) (char *, char **);
|
||||
typedef int (*MAIL_SERVER_LOOP_FN) (char *, char **);
|
||||
typedef void (*MAIL_SERVER_EXIT_FN) (char *, char **);
|
||||
typedef void (*MAIL_SERVER_ACCEPT_FN) (char *, char **);
|
||||
typedef void (*MAIL_SERVER_POST_ACCEPT_FN) (VSTREAM *, char *, char **, HTABLE *);
|
||||
typedef void (*MAIL_SERVER_DISCONN_FN) (VSTREAM *, char *, char **);
|
||||
typedef void (*MAIL_SERVER_SLOW_EXIT_FN) (char *, char **);
|
||||
|
||||
@ -67,6 +70,7 @@ typedef void (*MAIL_SERVER_SLOW_EXIT_FN) (char *, char **);
|
||||
#define CA_MAIL_SERVER_LOOP(v) MAIL_SERVER_LOOP, CHECK_VAL(MAIL_SERVER, MAIL_SERVER_LOOP_FN, (v))
|
||||
#define CA_MAIL_SERVER_EXIT(v) MAIL_SERVER_EXIT, CHECK_VAL(MAIL_SERVER, MAIL_SERVER_EXIT_FN, (v))
|
||||
#define CA_MAIL_SERVER_PRE_ACCEPT(v) MAIL_SERVER_PRE_ACCEPT, CHECK_VAL(MAIL_SERVER, MAIL_SERVER_ACCEPT_FN, (v))
|
||||
#define CA_MAIL_SERVER_POST_ACCEPT(v) MAIL_SERVER_POST_ACCEPT, CHECK_VAL(MAIL_SERVER, MAIL_SERVER_POST_ACCEPT_FN, (v))
|
||||
#define CA_MAIL_SERVER_SOLITARY MAIL_SERVER_SOLITARY
|
||||
#define CA_MAIL_SERVER_UNLIMITED MAIL_SERVER_UNLIMITED
|
||||
#define CA_MAIL_SERVER_PRE_DISCONN(v) MAIL_SERVER_PRE_DISCONN, CHECK_VAL(MAIL_SERVER, MAIL_SERVER_DISCONN_FN, (v))
|
||||
@ -83,6 +87,7 @@ CHECK_VAL_HELPER_DCL(MAIL_SERVER, MAIL_SERVER_INIT_FN);
|
||||
CHECK_VAL_HELPER_DCL(MAIL_SERVER, MAIL_SERVER_EXIT_FN);
|
||||
CHECK_VAL_HELPER_DCL(MAIL_SERVER, MAIL_SERVER_DISCONN_FN);
|
||||
CHECK_VAL_HELPER_DCL(MAIL_SERVER, MAIL_SERVER_ACCEPT_FN);
|
||||
CHECK_VAL_HELPER_DCL(MAIL_SERVER, MAIL_SERVER_POST_ACCEPT_FN);
|
||||
CHECK_PTR_HELPER_DCL(MAIL_SERVER, int);
|
||||
CHECK_PTR_HELPER_DCL(MAIL_SERVER, char);
|
||||
CHECK_PPTR_HELPER_DCL(MAIL_SERVER, char);
|
||||
|
@ -35,9 +35,6 @@
|
||||
/* function is run after the program has optionally dropped its
|
||||
/* privileges. This function should not attempt to preserve state
|
||||
/* across calls. The stream initial state is non-blocking mode.
|
||||
/* Optional connection attributes are provided as a hash that
|
||||
/* is attached as stream context. NOTE: the attributes are
|
||||
/* destroyed after this function is called.
|
||||
/* The service name argument corresponds to the service name in the
|
||||
/* master.cf file.
|
||||
/* The argv argument specifies command-line arguments left over
|
||||
@ -114,6 +111,14 @@
|
||||
/* Function to be executed prior to accepting a new connection.
|
||||
/* .sp
|
||||
/* Only the last instance of this parameter type is remembered.
|
||||
/* .IP "CA_MAIL_SERVER_POST_ACCEPT(void *(VSTREAM *stream, char *service_name, char **argv, HTABLE *attr))"
|
||||
/* Function to be executed after accepting a new connection.
|
||||
/* The stream, service_name and argv argunents are the same
|
||||
/* as with the "service" argument. The attr argument is null
|
||||
/* or a pointer to a table with 'pass' connection attributes.
|
||||
/* The table is destroyed after the function returns.
|
||||
/* .sp
|
||||
/* Only the last instance of this parameter type is remembered.
|
||||
/* .IP "CA_MAIL_SERVER_PRE_DISCONN(VSTREAM *, char *service_name, char **argv)"
|
||||
/* A pointer to a function that is called
|
||||
/* by the multi_server_disconnect() function (see below).
|
||||
@ -250,11 +255,11 @@ static char **multi_server_argv;
|
||||
static void (*multi_server_accept) (int, void *);
|
||||
static void (*multi_server_onexit) (char *, char **);
|
||||
static void (*multi_server_pre_accept) (char *, char **);
|
||||
static void (*multi_server_post_accept) (VSTREAM *, char *, char **, HTABLE *);
|
||||
static VSTREAM *multi_server_lock;
|
||||
static int multi_server_in_flow_delay;
|
||||
static unsigned multi_server_generation;
|
||||
static void (*multi_server_pre_disconn) (VSTREAM *, char *, char **);
|
||||
static int multi_server_saved_flags;
|
||||
|
||||
/* multi_server_exit - normal termination */
|
||||
|
||||
@ -336,8 +341,6 @@ void multi_server_disconnect(VSTREAM *stream)
|
||||
static void multi_server_execute(int unused_event, void *context)
|
||||
{
|
||||
VSTREAM *stream = (VSTREAM *) context;
|
||||
HTABLE *attr = (vstream_flags(stream) == multi_server_saved_flags ?
|
||||
(HTABLE *) vstream_context(stream) : 0);
|
||||
|
||||
if (multi_server_lock != 0
|
||||
&& myflock(vstream_fileno(multi_server_lock), INTERNAL_LOCK,
|
||||
@ -358,8 +361,6 @@ static void multi_server_execute(int unused_event, void *context)
|
||||
} else {
|
||||
multi_server_disconnect(stream);
|
||||
}
|
||||
if (attr)
|
||||
htable_free(attr, myfree);
|
||||
}
|
||||
|
||||
/* multi_server_enable_read - enable read events */
|
||||
@ -404,16 +405,20 @@ static void multi_server_wakeup(int fd, HTABLE *attr)
|
||||
tmp = concatenate(multi_server_name, " socket", (char *) 0);
|
||||
vstream_control(stream,
|
||||
CA_VSTREAM_CTL_PATH(tmp),
|
||||
CA_VSTREAM_CTL_CONTEXT((void *) attr),
|
||||
CA_VSTREAM_CTL_END);
|
||||
myfree(tmp);
|
||||
timed_ipc_setup(stream);
|
||||
multi_server_saved_flags = vstream_flags(stream);
|
||||
if (multi_server_in_flow_delay && mail_flow_get(1) < 0)
|
||||
event_request_timer(multi_server_enable_read, (void *) stream,
|
||||
var_in_flow_delay);
|
||||
else
|
||||
multi_server_enable_read(0, (void *) stream);
|
||||
if (multi_server_post_accept)
|
||||
multi_server_post_accept(stream, multi_server_name, multi_server_argv, attr);
|
||||
else if (attr)
|
||||
msg_warn("service ignores 'pass' connection attributes");
|
||||
if (attr)
|
||||
htable_free(attr, myfree);
|
||||
}
|
||||
|
||||
/* multi_server_accept_local - accept client connection request */
|
||||
@ -746,6 +751,9 @@ NORETURN multi_server_main(int argc, char **argv, MULTI_SERVER_FN service,...)
|
||||
case MAIL_SERVER_PRE_ACCEPT:
|
||||
multi_server_pre_accept = va_arg(ap, MAIL_SERVER_ACCEPT_FN);
|
||||
break;
|
||||
case MAIL_SERVER_POST_ACCEPT:
|
||||
multi_server_post_accept = va_arg(ap, MAIL_SERVER_POST_ACCEPT_FN);
|
||||
break;
|
||||
case MAIL_SERVER_PRE_DISCONN:
|
||||
multi_server_pre_disconn = va_arg(ap, MAIL_SERVER_DISCONN_FN);
|
||||
break;
|
||||
|
@ -109,12 +109,12 @@ static int qmgr_deliver_initial_reply(VSTREAM *stream)
|
||||
msg_warn("%s: premature disconnect", VSTREAM_PATH(stream));
|
||||
return (DELIVER_STAT_CRASH);
|
||||
} else if (attr_scan(stream, ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_INT(MAIL_ATTR_STATUS, &stat),
|
||||
ATTR_TYPE_END) != 1) {
|
||||
RECV_ATTR_STREQ(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_DELIVER),
|
||||
ATTR_TYPE_END) != 0) {
|
||||
msg_warn("%s: malformed response", VSTREAM_PATH(stream));
|
||||
return (DELIVER_STAT_CRASH);
|
||||
return (DELIVER_STAT_DEFER);
|
||||
} else {
|
||||
return (stat ? DELIVER_STAT_DEFER : 0);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -488,6 +488,7 @@ static int pickup_file(PICKUP_INFO *info)
|
||||
|
||||
cleanup = mail_connect_wait(MAIL_CLASS_PUBLIC, var_cleanup_service);
|
||||
if (attr_scan(cleanup, ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_STREQ(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_CLEANUP),
|
||||
RECV_ATTR_STR(MAIL_ATTR_QUEUEID, buf),
|
||||
ATTR_TYPE_END) != 1
|
||||
|| attr_print(cleanup, ATTR_FLAG_NONE,
|
||||
|
@ -9,8 +9,8 @@ OBJS = postconf.o postconf_builtin.o postconf_edit.o postconf_main.o \
|
||||
postconf_lookup.o postconf_match.o postconf_print.o
|
||||
HDRS = postconf.h
|
||||
TESTSRC =
|
||||
DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
|
||||
CFLAGS = $(DEBUG) $(OPT) $(DEFS) -DLEGACY_DBMS_SUPPORT
|
||||
DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE) -DLEGACY_DBMS_SUPPORT
|
||||
CFLAGS = $(DEBUG) $(OPT) $(DEFS)
|
||||
TESTPROG=
|
||||
MAKES = bool_table.h bool_vars.h int_table.h int_vars.h str_table.h \
|
||||
str_vars.h time_table.h time_vars.h raw_table.h raw_vars.h \
|
||||
|
@ -381,6 +381,7 @@ int main(int argc, char **argv)
|
||||
dst = mail_stream_file(MAIL_QUEUE_MAILDROP, MAIL_CLASS_PUBLIC,
|
||||
var_pickup_service, 0444);
|
||||
attr_print(VSTREAM_OUT, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_POSTDROP),
|
||||
SEND_ATTR_STR(MAIL_ATTR_QUEUEID, dst->id),
|
||||
ATTR_TYPE_END);
|
||||
vstream_fflush(VSTREAM_OUT);
|
||||
|
@ -61,14 +61,19 @@ depend: $(MAKES)
|
||||
|
||||
# do not edit below this line - it is generated by 'make depend'
|
||||
postlogd.o: ../../include/check_arg.h
|
||||
postlogd.o: ../../include/htable.h
|
||||
postlogd.o: ../../include/logwriter.h
|
||||
postlogd.o: ../../include/mail_conf.h
|
||||
postlogd.o: ../../include/mail_params.h
|
||||
postlogd.o: ../../include/mail_server.h
|
||||
postlogd.o: ../../include/mail_task.h
|
||||
postlogd.o: ../../include/mail_version.h
|
||||
postlogd.o: ../../include/maillog_client.h
|
||||
postlogd.o: ../../include/msg.h
|
||||
postlogd.o: ../../include/msg_logger.h
|
||||
postlogd.o: ../../include/stringops.h
|
||||
postlogd.o: ../../include/sys_defs.h
|
||||
postlogd.o: ../../include/vbuf.h
|
||||
postlogd.o: ../../include/vstream.h
|
||||
postlogd.o: ../../include/vstring.h
|
||||
postlogd.o: postlogd.c
|
||||
|
1
postfix/src/postqueue/.indent.pro
vendored
Symbolic link
1
postfix/src/postqueue/.indent.pro
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../../.indent.pro
|
@ -341,6 +341,26 @@ static const CONFIG_STR_TABLE str_table[] = {
|
||||
0,
|
||||
};
|
||||
|
||||
/* showq_client - run the appropriate showq protocol client */
|
||||
|
||||
static void showq_client(int mode, VSTREAM *showq)
|
||||
{
|
||||
if (attr_scan(showq, ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_STREQ(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_SHOWQ),
|
||||
ATTR_TYPE_END) != 0)
|
||||
msg_fatal_status(EX_SOFTWARE, "malformed showq server response");
|
||||
switch (mode) {
|
||||
case PQ_MODE_MAILQ_LIST:
|
||||
showq_compat(showq);
|
||||
break;
|
||||
case PQ_MODE_JSON_LIST:
|
||||
showq_json(showq);
|
||||
break;
|
||||
default:
|
||||
msg_panic("show_queue: unknown mode %d", mode);
|
||||
}
|
||||
}
|
||||
|
||||
/* show_queue - show queue status */
|
||||
|
||||
static void show_queue(int mode)
|
||||
@ -361,16 +381,7 @@ static void show_queue(int mode)
|
||||
* Connect to the show queue service.
|
||||
*/
|
||||
if ((showq = mail_connect(MAIL_CLASS_PUBLIC, var_showq_service, BLOCKING)) != 0) {
|
||||
switch (mode) {
|
||||
case PQ_MODE_MAILQ_LIST:
|
||||
showq_compat(showq);
|
||||
break;
|
||||
case PQ_MODE_JSON_LIST:
|
||||
showq_json(showq);
|
||||
break;
|
||||
default:
|
||||
msg_panic("show_queue: unknown mode %d", mode);
|
||||
}
|
||||
showq_client(mode, showq);
|
||||
if (vstream_fclose(showq))
|
||||
msg_warn("close: %m");
|
||||
}
|
||||
@ -407,23 +418,14 @@ static void show_queue(int mode)
|
||||
CA_VSTREAM_POPEN_END)) == 0) {
|
||||
stat = -1;
|
||||
} else {
|
||||
switch (mode) {
|
||||
case PQ_MODE_MAILQ_LIST:
|
||||
showq_compat(showq);
|
||||
break;
|
||||
case PQ_MODE_JSON_LIST:
|
||||
showq_json(showq);
|
||||
break;
|
||||
default:
|
||||
msg_panic("show_queue: unknown mode %d", mode);
|
||||
}
|
||||
showq_client(mode, showq);
|
||||
stat = vstream_pclose(showq);
|
||||
}
|
||||
argv_free(argv);
|
||||
myfree(showq_path);
|
||||
if (stat != 0)
|
||||
msg_fatal_status(stat < 0 ? EX_OSERR : EX_SOFTWARE,
|
||||
"Error running %s", showq_path);
|
||||
myfree(showq_path);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -88,6 +88,22 @@ typedef struct {
|
||||
|
||||
static char *psc_tlsp_service = 0;
|
||||
|
||||
/* Resume the dummy SMTP engine after an event handling error */
|
||||
|
||||
#define PSC_STARTTLS_EVENT_ERR_RESUME_RETURN() do { \
|
||||
event_disable_readwrite(vstream_fileno(tlsproxy_stream)); \
|
||||
PSC_STARTTLS_EVENT_RESUME_RETURN(starttls_state); \
|
||||
} while (0);
|
||||
|
||||
/* Resume the dummy SMTP engine, possibly after swapping streams */
|
||||
|
||||
#define PSC_STARTTLS_EVENT_RESUME_RETURN(starttls_state) do { \
|
||||
vstream_fclose(tlsproxy_stream); \
|
||||
starttls_state->resume_event(event, (void *) smtp_state); \
|
||||
myfree((void *) starttls_state); \
|
||||
return; \
|
||||
} while (0)
|
||||
|
||||
/* psc_starttls_finish - complete negotiation with TLS proxy */
|
||||
|
||||
static void psc_starttls_finish(int event, void *context)
|
||||
@ -130,10 +146,11 @@ static void psc_starttls_finish(int event, void *context)
|
||||
* The TLS proxy reports that the TLS engine is not available (due to
|
||||
* configuration error, or other causes).
|
||||
*/
|
||||
event_disable_readwrite(vstream_fileno(tlsproxy_stream));
|
||||
vstream_fclose(tlsproxy_stream);
|
||||
msg_warn("%s receiving status from %s service",
|
||||
event == EVENT_TIME ? "timeout" : "problem", psc_tlsp_service);
|
||||
PSC_SEND_REPLY(smtp_state,
|
||||
"454 4.7.0 TLS not available due to local problem\r\n");
|
||||
PSC_STARTTLS_EVENT_ERR_RESUME_RETURN();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -145,13 +162,10 @@ static void psc_starttls_finish(int event, void *context)
|
||||
/*
|
||||
* Some error: drop the TLS proxy stream.
|
||||
*/
|
||||
msg_warn("%s sending file handle to %s service",
|
||||
event == EVENT_TIME ? "timeout" : "problem",
|
||||
psc_tlsp_service);
|
||||
event_disable_readwrite(vstream_fileno(tlsproxy_stream));
|
||||
vstream_fclose(tlsproxy_stream);
|
||||
msg_warn("problem sending file handle to %s service", psc_tlsp_service);
|
||||
PSC_SEND_REPLY(smtp_state,
|
||||
"454 4.7.0 TLS not available due to local problem\r\n");
|
||||
PSC_STARTTLS_EVENT_ERR_RESUME_RETURN();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -163,9 +177,10 @@ static void psc_starttls_finish(int event, void *context)
|
||||
PSC_SEND_REPLY(smtp_state, "220 2.0.0 Ready to start TLS\r\n");
|
||||
|
||||
/*
|
||||
* Replace our SMTP client stream by the TLS proxy stream. Once the
|
||||
* TLS handshake is done, the TLS proxy will deliver plaintext SMTP
|
||||
* commands to postscreen(8).
|
||||
* Swap the SMTP client stream and the TLS proxy stream, and close
|
||||
* the direct connection to the SMTP client. The TLS proxy will talk
|
||||
* directly to the SMTP client, and once the TLS handshake is
|
||||
* completed, the TLS proxy will talk plaintext to postscreen(8).
|
||||
*
|
||||
* Swap the file descriptors from under the VSTREAM so that we don't
|
||||
* have to worry about loss of user-configurable VSTREAM attributes.
|
||||
@ -174,15 +189,83 @@ static void psc_starttls_finish(int event, void *context)
|
||||
vstream_control(smtp_state->smtp_client_stream,
|
||||
CA_VSTREAM_CTL_SWAP_FD(tlsproxy_stream),
|
||||
CA_VSTREAM_CTL_END);
|
||||
vstream_fclose(tlsproxy_stream); /* direct-to-client stream! */
|
||||
smtp_state->flags |= PSC_STATE_FLAG_USING_TLS;
|
||||
PSC_STARTTLS_EVENT_RESUME_RETURN(starttls_state);
|
||||
}
|
||||
}
|
||||
|
||||
/* psc_starttls_first - start negotiation with TLS proxy */
|
||||
|
||||
static void psc_starttls_first(int event, void *context)
|
||||
{
|
||||
const char *myname = "psc_starttls_first";
|
||||
PSC_STARTTLS *starttls_state = (PSC_STARTTLS *) context;
|
||||
PSC_STATE *smtp_state = starttls_state->smtp_state;
|
||||
VSTREAM *tlsproxy_stream = starttls_state->tlsproxy_stream;
|
||||
static VSTRING *remote_endpt = 0;
|
||||
|
||||
if (msg_verbose)
|
||||
msg_info("%s: receive server protocol on proxy socket %d"
|
||||
" for smtp socket %d from [%s]:%s flags=%s",
|
||||
myname, vstream_fileno(tlsproxy_stream),
|
||||
vstream_fileno(smtp_state->smtp_client_stream),
|
||||
smtp_state->smtp_client_addr, smtp_state->smtp_client_port,
|
||||
psc_print_state_flags(smtp_state->flags, myname));
|
||||
|
||||
/*
|
||||
* We leave read-event notification enabled on the postscreen to TLS
|
||||
* proxy stream, to avoid two kqueue/epoll/etc. system calls: one here,
|
||||
* and one when resuming the dummy SMTP engine.
|
||||
*/
|
||||
if (event != EVENT_TIME)
|
||||
event_cancel_timer(psc_starttls_first, (void *) starttls_state);
|
||||
|
||||
/*
|
||||
* Receive and verify the server protocol.
|
||||
*/
|
||||
if (event != EVENT_READ
|
||||
|| attr_scan(tlsproxy_stream, ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_STREQ(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_TLSPROXY),
|
||||
ATTR_TYPE_END) != 0) {
|
||||
msg_warn("%s receiving %s attribute from %s service: %m",
|
||||
event == EVENT_TIME ? "timeout" : "problem",
|
||||
MAIL_ATTR_PROTO, psc_tlsp_service);
|
||||
PSC_SEND_REPLY(smtp_state,
|
||||
"454 4.7.0 TLS not available due to local problem\r\n");
|
||||
PSC_STARTTLS_EVENT_ERR_RESUME_RETURN();
|
||||
}
|
||||
|
||||
/*
|
||||
* Resume the postscreen(8) dummy SMTP engine and clean up.
|
||||
* Send the data attributes now, and send the client file descriptor in a
|
||||
* later transaction. We report all errors asynchronously, to avoid
|
||||
* having to maintain multiple error delivery paths.
|
||||
*
|
||||
* XXX The formatted endpoint should be a state member. Then, we can
|
||||
* simplify all the format strings throughout the program.
|
||||
*/
|
||||
starttls_state->resume_event(event, (void *) smtp_state);
|
||||
myfree((void *) starttls_state);
|
||||
if (remote_endpt == 0)
|
||||
remote_endpt = vstring_alloc(20);
|
||||
vstring_sprintf(remote_endpt, "[%s]:%s", smtp_state->smtp_client_addr,
|
||||
smtp_state->smtp_client_port);
|
||||
attr_print(tlsproxy_stream, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR(TLS_ATTR_REMOTE_ENDPT, STR(remote_endpt)),
|
||||
SEND_ATTR_INT(TLS_ATTR_FLAGS, TLS_PROXY_FLAG_ROLE_SERVER),
|
||||
SEND_ATTR_INT(TLS_ATTR_TIMEOUT, psc_normal_cmd_time_limit),
|
||||
SEND_ATTR_INT(TLS_ATTR_TIMEOUT, psc_normal_cmd_time_limit),
|
||||
SEND_ATTR_STR(TLS_ATTR_SERVERID, MAIL_SERVICE_SMTPD), /* XXX */
|
||||
ATTR_TYPE_END);
|
||||
if (vstream_fflush(tlsproxy_stream) != 0) {
|
||||
msg_warn("error sending request to %s service: %m", psc_tlsp_service);
|
||||
PSC_SEND_REPLY(smtp_state,
|
||||
"454 4.7.0 TLS not available due to local problem\r\n");
|
||||
PSC_STARTTLS_EVENT_ERR_RESUME_RETURN();
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up a read event for the next phase of the TLS proxy handshake.
|
||||
*/
|
||||
PSC_READ_EVENT_REQUEST(vstream_fileno(tlsproxy_stream), psc_starttls_finish,
|
||||
(void *) starttls_state, TLSPROXY_INIT_TIMEOUT);
|
||||
}
|
||||
|
||||
/* psc_starttls_open - open negotiations with TLS proxy */
|
||||
@ -193,12 +276,10 @@ void psc_starttls_open(PSC_STATE *smtp_state, EVENT_NOTIFY_FN resume_event)
|
||||
PSC_STARTTLS *starttls_state;
|
||||
VSTREAM *tlsproxy_stream;
|
||||
int fd;
|
||||
static VSTRING *remote_endpt = 0;
|
||||
|
||||
if (psc_tlsp_service == 0) {
|
||||
psc_tlsp_service = concatenate(MAIL_CLASS_PRIVATE "/",
|
||||
var_tlsproxy_service, (char *) 0);
|
||||
remote_endpt = vstring_alloc(20);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -213,38 +294,16 @@ void psc_starttls_open(PSC_STATE *smtp_state, EVENT_NOTIFY_FN resume_event)
|
||||
return;
|
||||
}
|
||||
if (msg_verbose)
|
||||
msg_info("%s: send client name/address on proxy socket %d"
|
||||
msg_info("%s: connecting to proxy socket %d"
|
||||
" for smtp socket %d from [%s]:%s flags=%s",
|
||||
myname, fd, vstream_fileno(smtp_state->smtp_client_stream),
|
||||
smtp_state->smtp_client_addr, smtp_state->smtp_client_port,
|
||||
psc_print_state_flags(smtp_state->flags, myname));
|
||||
|
||||
/*
|
||||
* Initial handshake. Send the data attributes now, and send the client
|
||||
* file descriptor in a later transaction. We report all errors
|
||||
* asynchronously, to avoid having to maintain multiple delivery paths.
|
||||
*
|
||||
* XXX The formatted endpoint should be a state member. Then, we can
|
||||
* simplify all the format strings throughout the program.
|
||||
*/
|
||||
tlsproxy_stream = vstream_fdopen(fd, O_RDWR);
|
||||
vstring_sprintf(remote_endpt, "[%s]:%s", smtp_state->smtp_client_addr,
|
||||
smtp_state->smtp_client_port);
|
||||
attr_print(tlsproxy_stream, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR(TLS_ATTR_REMOTE_ENDPT, STR(remote_endpt)),
|
||||
SEND_ATTR_INT(TLS_ATTR_FLAGS, TLS_PROXY_FLAG_ROLE_SERVER),
|
||||
SEND_ATTR_INT(TLS_ATTR_TIMEOUT, psc_normal_cmd_time_limit),
|
||||
SEND_ATTR_INT(TLS_ATTR_TIMEOUT, psc_normal_cmd_time_limit),
|
||||
SEND_ATTR_STR(TLS_ATTR_SERVERID, MAIL_SERVICE_SMTPD), /* XXX */
|
||||
ATTR_TYPE_END);
|
||||
if (vstream_fflush(tlsproxy_stream) != 0) {
|
||||
msg_warn("error sending request to %s service: %m", psc_tlsp_service);
|
||||
vstream_fclose(tlsproxy_stream);
|
||||
PSC_SEND_REPLY(smtp_state,
|
||||
"454 4.7.0 TLS not available due to local problem\r\n");
|
||||
event_request_timer(resume_event, (void *) smtp_state, 0);
|
||||
return;
|
||||
}
|
||||
vstream_control(tlsproxy_stream,
|
||||
VSTREAM_CTL_PATH, psc_tlsp_service,
|
||||
VSTREAM_CTL_END);
|
||||
|
||||
/*
|
||||
* Set up a read event for the next phase of the TLS proxy handshake.
|
||||
@ -253,6 +312,6 @@ void psc_starttls_open(PSC_STATE *smtp_state, EVENT_NOTIFY_FN resume_event)
|
||||
starttls_state->tlsproxy_stream = tlsproxy_stream;
|
||||
starttls_state->resume_event = resume_event;
|
||||
starttls_state->smtp_state = smtp_state;
|
||||
PSC_READ_EVENT_REQUEST(vstream_fileno(tlsproxy_stream), psc_starttls_finish,
|
||||
PSC_READ_EVENT_REQUEST(vstream_fileno(tlsproxy_stream), psc_starttls_first,
|
||||
(void *) starttls_state, TLSPROXY_INIT_TIMEOUT);
|
||||
}
|
||||
|
@ -745,6 +745,21 @@ static void pre_accept(char *unused_name, char **unused_argv)
|
||||
}
|
||||
}
|
||||
|
||||
/* post_accept - anounce our protocol name */
|
||||
|
||||
static void post_accept(VSTREAM *stream, char *unused_name, char **unused_argv,
|
||||
HTABLE *unused_attr)
|
||||
{
|
||||
|
||||
/*
|
||||
* Announce the protocol.
|
||||
*/
|
||||
attr_print(stream, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_PROXYMAP),
|
||||
ATTR_TYPE_END);
|
||||
(void) vstream_fflush(stream);
|
||||
}
|
||||
|
||||
MAIL_VERSION_STAMP_DECLARE;
|
||||
|
||||
/* main - pass control to the multi-threaded skeleton */
|
||||
@ -782,6 +797,7 @@ int main(int argc, char **argv)
|
||||
CA_MAIL_SERVER_STR_TABLE(str_table),
|
||||
CA_MAIL_SERVER_POST_INIT(post_jail_init),
|
||||
CA_MAIL_SERVER_PRE_ACCEPT(pre_accept),
|
||||
CA_MAIL_SERVER_POST_ACCEPT(post_accept),
|
||||
/* XXX CA_MAIL_SERVER_SOLITARY if proxywrite */
|
||||
0);
|
||||
}
|
||||
|
@ -108,18 +108,16 @@ int qmgr_deliver_concurrency;
|
||||
|
||||
static int qmgr_deliver_initial_reply(VSTREAM *stream)
|
||||
{
|
||||
int stat;
|
||||
|
||||
if (peekfd(vstream_fileno(stream)) < 0) {
|
||||
msg_warn("%s: premature disconnect", VSTREAM_PATH(stream));
|
||||
return (DELIVER_STAT_CRASH);
|
||||
} else if (attr_scan(stream, ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_INT(MAIL_ATTR_STATUS, &stat),
|
||||
ATTR_TYPE_END) != 1) {
|
||||
RECV_ATTR_STREQ(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_DELIVER),
|
||||
ATTR_TYPE_END) != 0) {
|
||||
msg_warn("%s: malformed response", VSTREAM_PATH(stream));
|
||||
return (DELIVER_STAT_CRASH);
|
||||
return (DELIVER_STAT_DEFER);
|
||||
} else {
|
||||
return (stat ? DELIVER_STAT_DEFER : 0);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -544,6 +544,21 @@ static void post_jail_init(char *unused_name, char **unused_argv)
|
||||
scache_start_time = event_time();
|
||||
}
|
||||
|
||||
/* scache_post_accept - announce our protocol */
|
||||
|
||||
static void scache_post_accept(VSTREAM *stream, char *unused_name,
|
||||
char **unused_argv, HTABLE *unused_table)
|
||||
{
|
||||
|
||||
/*
|
||||
* Announce the protocol.
|
||||
*/
|
||||
attr_print(stream, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_SCACHE),
|
||||
ATTR_TYPE_END);
|
||||
(void) vstream_fflush(stream);
|
||||
}
|
||||
|
||||
MAIL_VERSION_STAMP_DECLARE;
|
||||
|
||||
/* main - pass control to the multi-threaded skeleton */
|
||||
@ -564,6 +579,7 @@ int main(int argc, char **argv)
|
||||
multi_server_main(argc, argv, scache_service,
|
||||
CA_MAIL_SERVER_TIME_TABLE(time_table),
|
||||
CA_MAIL_SERVER_POST_INIT(post_jail_init),
|
||||
CA_MAIL_SERVER_POST_ACCEPT(scache_post_accept),
|
||||
CA_MAIL_SERVER_EXIT(scache_status_dump),
|
||||
CA_MAIL_SERVER_SOLITARY,
|
||||
0);
|
||||
|
@ -360,6 +360,13 @@ static void showq_service(VSTREAM *client, char *unused_service, char **argv)
|
||||
if (argv[0])
|
||||
msg_fatal("unexpected command-line argument: %s", argv[0]);
|
||||
|
||||
/*
|
||||
* Protocol identification.
|
||||
*/
|
||||
(void) attr_print(client, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_SHOWQ),
|
||||
ATTR_TYPE_END);
|
||||
|
||||
/*
|
||||
* Skip any files that have the wrong permissions. If we can't open an
|
||||
* existing file, assume the system is out of resources or that it is
|
||||
|
@ -280,7 +280,6 @@ smtpd_chat.o: ../../include/mail_params.h
|
||||
smtpd_chat.o: ../../include/mail_proto.h
|
||||
smtpd_chat.o: ../../include/mail_stream.h
|
||||
smtpd_chat.o: ../../include/maps.h
|
||||
smtpd_chat.o: ../../include/match_list.h
|
||||
smtpd_chat.o: ../../include/milter.h
|
||||
smtpd_chat.o: ../../include/msg.h
|
||||
smtpd_chat.o: ../../include/myaddrinfo.h
|
||||
@ -296,7 +295,6 @@ smtpd_chat.o: ../../include/smtp_reply_footer.h
|
||||
smtpd_chat.o: ../../include/smtp_stream.h
|
||||
smtpd_chat.o: ../../include/smtputf8.h
|
||||
smtpd_chat.o: ../../include/sock_addr.h
|
||||
smtpd_chat.o: ../../include/string_list.h
|
||||
smtpd_chat.o: ../../include/stringops.h
|
||||
smtpd_chat.o: ../../include/sys_defs.h
|
||||
smtpd_chat.o: ../../include/tls.h
|
||||
@ -400,7 +398,6 @@ smtpd_expand.o: ../../include/mac_parse.h
|
||||
smtpd_expand.o: ../../include/mail_params.h
|
||||
smtpd_expand.o: ../../include/mail_proto.h
|
||||
smtpd_expand.o: ../../include/mail_stream.h
|
||||
smtpd_expand.o: ../../include/match_list.h
|
||||
smtpd_expand.o: ../../include/milter.h
|
||||
smtpd_expand.o: ../../include/msg.h
|
||||
smtpd_expand.o: ../../include/myaddrinfo.h
|
||||
@ -409,7 +406,6 @@ smtpd_expand.o: ../../include/name_code.h
|
||||
smtpd_expand.o: ../../include/name_mask.h
|
||||
smtpd_expand.o: ../../include/nvtable.h
|
||||
smtpd_expand.o: ../../include/sock_addr.h
|
||||
smtpd_expand.o: ../../include/string_list.h
|
||||
smtpd_expand.o: ../../include/stringops.h
|
||||
smtpd_expand.o: ../../include/sys_defs.h
|
||||
smtpd_expand.o: ../../include/tls.h
|
||||
@ -428,7 +424,6 @@ smtpd_haproxy.o: ../../include/htable.h
|
||||
smtpd_haproxy.o: ../../include/iostuff.h
|
||||
smtpd_haproxy.o: ../../include/mail_params.h
|
||||
smtpd_haproxy.o: ../../include/mail_stream.h
|
||||
smtpd_haproxy.o: ../../include/match_list.h
|
||||
smtpd_haproxy.o: ../../include/milter.h
|
||||
smtpd_haproxy.o: ../../include/msg.h
|
||||
smtpd_haproxy.o: ../../include/myaddrinfo.h
|
||||
@ -438,7 +433,6 @@ smtpd_haproxy.o: ../../include/name_mask.h
|
||||
smtpd_haproxy.o: ../../include/nvtable.h
|
||||
smtpd_haproxy.o: ../../include/smtp_stream.h
|
||||
smtpd_haproxy.o: ../../include/sock_addr.h
|
||||
smtpd_haproxy.o: ../../include/string_list.h
|
||||
smtpd_haproxy.o: ../../include/stringops.h
|
||||
smtpd_haproxy.o: ../../include/sys_defs.h
|
||||
smtpd_haproxy.o: ../../include/tls.h
|
||||
@ -456,7 +450,6 @@ smtpd_milter.o: ../../include/dns.h
|
||||
smtpd_milter.o: ../../include/htable.h
|
||||
smtpd_milter.o: ../../include/mail_params.h
|
||||
smtpd_milter.o: ../../include/mail_stream.h
|
||||
smtpd_milter.o: ../../include/match_list.h
|
||||
smtpd_milter.o: ../../include/milter.h
|
||||
smtpd_milter.o: ../../include/myaddrinfo.h
|
||||
smtpd_milter.o: ../../include/mymalloc.h
|
||||
@ -468,7 +461,6 @@ smtpd_milter.o: ../../include/quote_flags.h
|
||||
smtpd_milter.o: ../../include/resolve_clnt.h
|
||||
smtpd_milter.o: ../../include/sock_addr.h
|
||||
smtpd_milter.o: ../../include/split_at.h
|
||||
smtpd_milter.o: ../../include/string_list.h
|
||||
smtpd_milter.o: ../../include/stringops.h
|
||||
smtpd_milter.o: ../../include/sys_defs.h
|
||||
smtpd_milter.o: ../../include/tls.h
|
||||
@ -491,7 +483,6 @@ smtpd_peer.o: ../../include/iostuff.h
|
||||
smtpd_peer.o: ../../include/mail_params.h
|
||||
smtpd_peer.o: ../../include/mail_proto.h
|
||||
smtpd_peer.o: ../../include/mail_stream.h
|
||||
smtpd_peer.o: ../../include/match_list.h
|
||||
smtpd_peer.o: ../../include/milter.h
|
||||
smtpd_peer.o: ../../include/msg.h
|
||||
smtpd_peer.o: ../../include/myaddrinfo.h
|
||||
@ -501,7 +492,6 @@ smtpd_peer.o: ../../include/name_mask.h
|
||||
smtpd_peer.o: ../../include/nvtable.h
|
||||
smtpd_peer.o: ../../include/sock_addr.h
|
||||
smtpd_peer.o: ../../include/split_at.h
|
||||
smtpd_peer.o: ../../include/string_list.h
|
||||
smtpd_peer.o: ../../include/stringops.h
|
||||
smtpd_peer.o: ../../include/sys_defs.h
|
||||
smtpd_peer.o: ../../include/tls.h
|
||||
@ -525,7 +515,6 @@ smtpd_proxy.o: ../../include/mail_params.h
|
||||
smtpd_proxy.o: ../../include/mail_proto.h
|
||||
smtpd_proxy.o: ../../include/mail_queue.h
|
||||
smtpd_proxy.o: ../../include/mail_stream.h
|
||||
smtpd_proxy.o: ../../include/match_list.h
|
||||
smtpd_proxy.o: ../../include/milter.h
|
||||
smtpd_proxy.o: ../../include/msg.h
|
||||
smtpd_proxy.o: ../../include/myaddrinfo.h
|
||||
@ -537,7 +526,6 @@ smtpd_proxy.o: ../../include/rec_type.h
|
||||
smtpd_proxy.o: ../../include/record.h
|
||||
smtpd_proxy.o: ../../include/smtp_stream.h
|
||||
smtpd_proxy.o: ../../include/sock_addr.h
|
||||
smtpd_proxy.o: ../../include/string_list.h
|
||||
smtpd_proxy.o: ../../include/stringops.h
|
||||
smtpd_proxy.o: ../../include/sys_defs.h
|
||||
smtpd_proxy.o: ../../include/tls.h
|
||||
@ -607,7 +595,6 @@ smtpd_sasl_proto.o: ../../include/mail_error.h
|
||||
smtpd_sasl_proto.o: ../../include/mail_params.h
|
||||
smtpd_sasl_proto.o: ../../include/mail_proto.h
|
||||
smtpd_sasl_proto.o: ../../include/mail_stream.h
|
||||
smtpd_sasl_proto.o: ../../include/match_list.h
|
||||
smtpd_sasl_proto.o: ../../include/milter.h
|
||||
smtpd_sasl_proto.o: ../../include/msg.h
|
||||
smtpd_sasl_proto.o: ../../include/myaddrinfo.h
|
||||
@ -616,7 +603,6 @@ smtpd_sasl_proto.o: ../../include/name_code.h
|
||||
smtpd_sasl_proto.o: ../../include/name_mask.h
|
||||
smtpd_sasl_proto.o: ../../include/nvtable.h
|
||||
smtpd_sasl_proto.o: ../../include/sock_addr.h
|
||||
smtpd_sasl_proto.o: ../../include/string_list.h
|
||||
smtpd_sasl_proto.o: ../../include/stringops.h
|
||||
smtpd_sasl_proto.o: ../../include/sys_defs.h
|
||||
smtpd_sasl_proto.o: ../../include/tls.h
|
||||
@ -641,7 +627,6 @@ smtpd_state.o: ../../include/mail_error.h
|
||||
smtpd_state.o: ../../include/mail_params.h
|
||||
smtpd_state.o: ../../include/mail_proto.h
|
||||
smtpd_state.o: ../../include/mail_stream.h
|
||||
smtpd_state.o: ../../include/match_list.h
|
||||
smtpd_state.o: ../../include/milter.h
|
||||
smtpd_state.o: ../../include/msg.h
|
||||
smtpd_state.o: ../../include/myaddrinfo.h
|
||||
@ -650,7 +635,6 @@ smtpd_state.o: ../../include/name_code.h
|
||||
smtpd_state.o: ../../include/name_mask.h
|
||||
smtpd_state.o: ../../include/nvtable.h
|
||||
smtpd_state.o: ../../include/sock_addr.h
|
||||
smtpd_state.o: ../../include/string_list.h
|
||||
smtpd_state.o: ../../include/sys_defs.h
|
||||
smtpd_state.o: ../../include/tls.h
|
||||
smtpd_state.o: ../../include/vbuf.h
|
||||
@ -676,7 +660,6 @@ smtpd_xforward.o: ../../include/htable.h
|
||||
smtpd_xforward.o: ../../include/iostuff.h
|
||||
smtpd_xforward.o: ../../include/mail_proto.h
|
||||
smtpd_xforward.o: ../../include/mail_stream.h
|
||||
smtpd_xforward.o: ../../include/match_list.h
|
||||
smtpd_xforward.o: ../../include/milter.h
|
||||
smtpd_xforward.o: ../../include/msg.h
|
||||
smtpd_xforward.o: ../../include/myaddrinfo.h
|
||||
@ -685,7 +668,6 @@ smtpd_xforward.o: ../../include/name_code.h
|
||||
smtpd_xforward.o: ../../include/name_mask.h
|
||||
smtpd_xforward.o: ../../include/nvtable.h
|
||||
smtpd_xforward.o: ../../include/sock_addr.h
|
||||
smtpd_xforward.o: ../../include/string_list.h
|
||||
smtpd_xforward.o: ../../include/sys_defs.h
|
||||
smtpd_xforward.o: ../../include/tls.h
|
||||
smtpd_xforward.o: ../../include/vbuf.h
|
||||
|
@ -62,6 +62,7 @@ depend: $(MAKES)
|
||||
spawn.o: ../../include/argv.h
|
||||
spawn.o: ../../include/check_arg.h
|
||||
spawn.o: ../../include/dict.h
|
||||
spawn.o: ../../include/htable.h
|
||||
spawn.o: ../../include/mail_conf.h
|
||||
spawn.o: ../../include/mail_params.h
|
||||
spawn.o: ../../include/mail_parm_split.h
|
||||
|
@ -107,6 +107,11 @@
|
||||
/* IBM T.J. Watson Research
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*
|
||||
/* Wietse Venema
|
||||
/* Google, Inc.
|
||||
/* 111 8th Avenue
|
||||
/* New York, NY 10011, USA
|
||||
/*--*/
|
||||
|
||||
/* System library. */
|
||||
@ -144,6 +149,15 @@
|
||||
|
||||
static ATTR_CLNT *tls_mgr;
|
||||
|
||||
/* tls_mgr_handshake - receive server protocol announcement */
|
||||
|
||||
static int tls_mgr_handshake(VSTREAM *stream)
|
||||
{
|
||||
return (attr_scan(stream, ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_STREQ(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_TLSMGR),
|
||||
ATTR_TYPE_END));
|
||||
}
|
||||
|
||||
/* tls_mgr_open - create client handle */
|
||||
|
||||
static void tls_mgr_open(void)
|
||||
@ -168,6 +182,7 @@ static void tls_mgr_open(void)
|
||||
|
||||
attr_clnt_control(tls_mgr,
|
||||
ATTR_CLNT_CTL_PROTO, attr_vprint, attr_vscan,
|
||||
ATTR_CLNT_CTL_HANDSHAKE, tls_mgr_handshake,
|
||||
ATTR_CLNT_CTL_END);
|
||||
}
|
||||
|
||||
|
@ -187,6 +187,14 @@ VSTREAM *tls_proxy_open(const char *service, int flags,
|
||||
* remote peer file descriptor in a later transaction.
|
||||
*/
|
||||
tlsproxy_stream = vstream_fdopen(fd, O_RDWR);
|
||||
if (attr_scan(tlsproxy_stream, ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_STREQ(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_TLSPROXY),
|
||||
ATTR_TYPE_END) != 0) {
|
||||
msg_warn("error receiving %s service initial response",
|
||||
STR(tlsproxy_service));
|
||||
vstream_fclose(tlsproxy_stream);
|
||||
return (0);
|
||||
}
|
||||
vstring_sprintf(remote_endpt, "[%s]:%s", peer_addr, peer_port);
|
||||
attr_print(tlsproxy_stream, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR(TLS_ATTR_REMOTE_ENDPT, STR(remote_endpt)),
|
||||
|
@ -1004,6 +1004,22 @@ static void tlsmgr_post_init(char *unused_name, char **unused_argv)
|
||||
tlsmgr_cache_run_event(NULL_EVENT, (void *) ent);
|
||||
}
|
||||
|
||||
/* tlsmgr_post_accept - announce our protocol */
|
||||
|
||||
static void tlsmgr_post_accept(VSTREAM *stream, char *unused_name,
|
||||
char **unused_argv, HTABLE *unused_table)
|
||||
{
|
||||
|
||||
/*
|
||||
* Announce the protocol.
|
||||
*/
|
||||
attr_print(stream, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_TLSMGR),
|
||||
ATTR_TYPE_END);
|
||||
(void) vstream_fflush(stream);
|
||||
}
|
||||
|
||||
|
||||
/* tlsmgr_before_exit - save PRNG state before exit */
|
||||
|
||||
static void tlsmgr_before_exit(char *unused_service_name, char **unused_argv)
|
||||
@ -1061,6 +1077,7 @@ int main(int argc, char **argv)
|
||||
CA_MAIL_SERVER_STR_TABLE(str_table),
|
||||
CA_MAIL_SERVER_PRE_INIT(tlsmgr_pre_init),
|
||||
CA_MAIL_SERVER_POST_INIT(tlsmgr_post_init),
|
||||
CA_MAIL_SERVER_POST_ACCEPT(tlsmgr_post_accept),
|
||||
CA_MAIL_SERVER_EXIT(tlsmgr_before_exit),
|
||||
CA_MAIL_SERVER_LOOP(tlsmgr_loop),
|
||||
CA_MAIL_SERVER_SOLITARY,
|
||||
|
@ -1481,6 +1481,12 @@ static void tlsp_service(VSTREAM *plaintext_stream,
|
||||
CA_VSTREAM_CTL_TIMEOUT(5),
|
||||
CA_VSTREAM_CTL_END);
|
||||
|
||||
(void) attr_print(plaintext_stream, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_TLSPROXY),
|
||||
ATTR_TYPE_END);
|
||||
if (vstream_fflush(plaintext_stream) != 0)
|
||||
msg_warn("write %s attribute: %m", MAIL_ATTR_PROTO);
|
||||
|
||||
/*
|
||||
* Receive postscreen's remote SMTP client address/port and socket.
|
||||
*/
|
||||
|
@ -153,7 +153,7 @@
|
||||
/* matches subdomains of example.com,
|
||||
/* instead of requiring an explicit ".example.com" pattern.
|
||||
/* .IP "\fBrelayhost (empty)\fR"
|
||||
/* The next-hop destination of non-local mail; overrides non-local
|
||||
/* The next-hop destination(s) for non-local mail; overrides non-local
|
||||
/* domains in recipient addresses.
|
||||
/* .IP "\fBtransport_maps (empty)\fR"
|
||||
/* Optional lookup tables with mappings from recipient address to
|
||||
@ -522,6 +522,21 @@ static void pre_accept(char *unused_name, char **unused_argv)
|
||||
|
||||
#endif
|
||||
|
||||
/* post_accept - anounce our protocol name */
|
||||
|
||||
static void post_accept(VSTREAM *stream, char *unused_name, char **unused_argv,
|
||||
HTABLE *unused_attr)
|
||||
{
|
||||
|
||||
/*
|
||||
* Announce the protocol.
|
||||
*/
|
||||
attr_print(stream, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_TRIVIAL),
|
||||
ATTR_TYPE_END);
|
||||
(void) vstream_fflush(stream);
|
||||
}
|
||||
|
||||
static void check_table_stats(int unused_event, void *unused_context)
|
||||
{
|
||||
const char *table;
|
||||
@ -648,5 +663,6 @@ int main(int argc, char **argv)
|
||||
#ifdef CHECK_TABLE_STATS_BEFORE_ACCEPT
|
||||
CA_MAIL_SERVER_PRE_ACCEPT(pre_accept),
|
||||
#endif
|
||||
CA_MAIL_SERVER_POST_ACCEPT(post_accept),
|
||||
0);
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ SRCS = alldig.c allprint.c argv.c argv_split.c attr_clnt.c attr_print0.c \
|
||||
msg_output.c msg_syslog.c msg_vstream.c mvect.c myaddrinfo.c myflock.c \
|
||||
mymalloc.c myrand.c mystrtok.c name_code.c name_mask.c netstring.c \
|
||||
neuter.c non_blocking.c nvtable.c open_as.c open_limit.c open_lock.c \
|
||||
peekfd.c percentm.c posix_signals.c printable.c rand_sleep.c \
|
||||
peekfd.c posix_signals.c printable.c rand_sleep.c \
|
||||
readlline.c ring.c safe_getenv.c safe_open.c \
|
||||
sane_accept.c sane_connect.c sane_link.c sane_rename.c \
|
||||
sane_socketpair.c sane_time.c scan_dir.c set_eugid.c set_ugid.c \
|
||||
@ -62,7 +62,7 @@ OBJS = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
|
||||
msg_output.o msg_syslog.o msg_vstream.o mvect.o myaddrinfo.o myflock.o \
|
||||
mymalloc.o myrand.o mystrtok.o name_code.o name_mask.o netstring.o \
|
||||
neuter.o non_blocking.o nvtable.o open_as.o open_limit.o open_lock.o \
|
||||
peekfd.o percentm.o posix_signals.o printable.o rand_sleep.o \
|
||||
peekfd.o posix_signals.o printable.o rand_sleep.o \
|
||||
readlline.o ring.o safe_getenv.o safe_open.o \
|
||||
sane_accept.o sane_connect.o sane_link.o sane_rename.o \
|
||||
sane_socketpair.o sane_time.o scan_dir.o set_eugid.o set_ugid.o \
|
||||
@ -104,7 +104,7 @@ HDRS = argv.h attr.h attr_clnt.h auto_clnt.h base64_code.h binhash.h \
|
||||
mac_parse.h make_dirs.h mask_addr.h match_list.h msg.h \
|
||||
msg_output.h msg_syslog.h msg_vstream.h mvect.h myaddrinfo.h myflock.h \
|
||||
mymalloc.h myrand.h name_code.h name_mask.h netstring.h nvtable.h \
|
||||
open_as.h open_lock.h percentm.h posix_signals.h readlline.h ring.h \
|
||||
open_as.h open_lock.h posix_signals.h readlline.h ring.h \
|
||||
safe.h safe_open.h sane_accept.h sane_connect.h sane_fsops.h \
|
||||
load_lib.h \
|
||||
sane_socketpair.h sane_time.h scan_dir.h set_eugid.h set_ugid.h \
|
||||
@ -1949,6 +1949,8 @@ load_file.o: vbuf.h
|
||||
load_file.o: vstream.h
|
||||
load_file.o: warn_stat.h
|
||||
load_lib.o: load_lib.c
|
||||
load_lib.o: load_lib.h
|
||||
load_lib.o: msg.h
|
||||
load_lib.o: sys_defs.h
|
||||
logwriter.o: check_arg.h
|
||||
logwriter.o: iostuff.h
|
||||
@ -2070,7 +2072,6 @@ msg_output.o: msg_output.c
|
||||
msg_output.o: msg_output.h
|
||||
msg_output.o: msg_vstream.h
|
||||
msg_output.o: mymalloc.h
|
||||
msg_output.o: percentm.h
|
||||
msg_output.o: stringops.h
|
||||
msg_output.o: sys_defs.h
|
||||
msg_output.o: vbuf.h
|
||||
@ -2220,12 +2221,6 @@ pass_trigger.o: trigger.h
|
||||
peekfd.o: iostuff.h
|
||||
peekfd.o: peekfd.c
|
||||
peekfd.o: sys_defs.h
|
||||
percentm.o: check_arg.h
|
||||
percentm.o: percentm.c
|
||||
percentm.o: percentm.h
|
||||
percentm.o: sys_defs.h
|
||||
percentm.o: vbuf.h
|
||||
percentm.o: vstring.h
|
||||
poll_fd.o: iostuff.h
|
||||
poll_fd.o: msg.h
|
||||
poll_fd.o: poll_fd.c
|
||||
|
@ -45,6 +45,7 @@ typedef int (*ATTR_PRINT_CUSTOM_FN) (ATTR_PRINT_COMMON_FN, VSTREAM *, int, void
|
||||
#define ATTR_TYPE_LONG 4 /* Unsigned long */
|
||||
#define ATTR_TYPE_DATA 5 /* Binary data */
|
||||
#define ATTR_TYPE_FUNC 6 /* Function pointer */
|
||||
#define ATTR_TYPE_STREQ 7 /* Requires (name, value) match */
|
||||
|
||||
/*
|
||||
* Optional sender-specified grouping for hash or nameval tables.
|
||||
@ -70,6 +71,7 @@ typedef int (*ATTR_PRINT_CUSTOM_FN) (ATTR_PRINT_COMMON_FN, VSTREAM *, int, void
|
||||
|
||||
#define RECV_ATTR_INT(name, val) ATTR_TYPE_INT, CHECK_CPTR(ATTR, char, (name)), CHECK_PTR(ATTR, int, (val))
|
||||
#define RECV_ATTR_STR(name, val) ATTR_TYPE_STR, CHECK_CPTR(ATTR, char, (name)), CHECK_PTR(ATTR, VSTRING, (val))
|
||||
#define RECV_ATTR_STREQ(name, val) ATTR_TYPE_STREQ, CHECK_CPTR(ATTR, char, (name)), CHECK_CPTR(ATTR, char, (val))
|
||||
#define RECV_ATTR_HASH(val) ATTR_TYPE_HASH, CHECK_PTR(ATTR, HTABLE, (val))
|
||||
#define RECV_ATTR_NV(val) ATTR_TYPE_NV, CHECK_PTR(ATTR, NVTABLE, (val))
|
||||
#define RECV_ATTR_LONG(name, val) ATTR_TYPE_LONG, CHECK_CPTR(ATTR, char, (name)), CHECK_PTR(ATTR, long, (val))
|
||||
|
@ -8,6 +8,7 @@
|
||||
/*
|
||||
/* typedef int (*ATTR_CLNT_PRINT_FN) (VSTREAM *, int, va_list);
|
||||
/* typedef int (*ATTR_CLNT_SCAN_FN) (VSTREAM *, int, va_list);
|
||||
/* typedef int (*ATTR_CLNT_HANDSHAKE_FN) (VSTREAM *);
|
||||
/*
|
||||
/* ATTR_CLNT *attr_clnt_create(server, timeout, max_idle, max_ttl)
|
||||
/* const char *server;
|
||||
@ -65,6 +66,9 @@
|
||||
/* .IP "ATTR_CLNT_CTL_TRY_DELAY(int)"
|
||||
/* The time in seconds between attempts to send a request
|
||||
/* (default: 1). Specify a value greater than zero.
|
||||
/* .IP "ATTR_CLNT_CTL_HANDSHAKE(VSTREAM *)"
|
||||
/* A pointer to function that will be called at the start of a
|
||||
/* new connection, and that returns 0 in case of success.
|
||||
/* DIAGNOSTICS
|
||||
/* Warnings: communication failure.
|
||||
/* SEE ALSO
|
||||
@ -80,6 +84,11 @@
|
||||
/* IBM T.J. Watson Research
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*
|
||||
/* Wietse Venema
|
||||
/* Google, Inc.
|
||||
/* 111 8th Avenue
|
||||
/* New York, NY 10011, USA
|
||||
/*--*/
|
||||
|
||||
/* System library. */
|
||||
@ -254,6 +263,12 @@ void attr_clnt_control(ATTR_CLNT *client, int name,...)
|
||||
client->print = va_arg(ap, ATTR_CLNT_PRINT_FN);
|
||||
client->scan = va_arg(ap, ATTR_CLNT_SCAN_FN);
|
||||
break;
|
||||
case ATTR_CLNT_CTL_HANDSHAKE:
|
||||
auto_clnt_control(client->auto_clnt,
|
||||
AUTO_CLNT_CTL_HANDSHAKE,
|
||||
va_arg(ap, ATTR_CLNT_HANDSHAKE_FN),
|
||||
AUTO_CLNT_CTL_END);
|
||||
break;
|
||||
case ATTR_CLNT_CTL_REQ_LIMIT:
|
||||
client->req_limit = va_arg(ap, int);
|
||||
if (client->req_limit < 0)
|
||||
|
@ -27,6 +27,7 @@
|
||||
typedef struct ATTR_CLNT ATTR_CLNT;
|
||||
typedef int (*ATTR_CLNT_PRINT_FN) (VSTREAM *, int, va_list);
|
||||
typedef int (*ATTR_CLNT_SCAN_FN) (VSTREAM *, int, va_list);
|
||||
typedef int (*ATTR_CLNT_HANDSHAKE_FN) (VSTREAM *);
|
||||
|
||||
extern ATTR_CLNT *attr_clnt_create(const char *, int, int, int);
|
||||
extern int attr_clnt_request(ATTR_CLNT *, int,...);
|
||||
@ -38,6 +39,7 @@ extern void attr_clnt_control(ATTR_CLNT *, int,...);
|
||||
#define ATTR_CLNT_CTL_REQ_LIMIT 2 /* requests per connection */
|
||||
#define ATTR_CLNT_CTL_TRY_LIMIT 3 /* attempts per request */
|
||||
#define ATTR_CLNT_CTL_TRY_DELAY 4 /* pause between requests */
|
||||
#define ATTR_CLNT_CTL_HANDSHAKE 5 /* handshake before first request */
|
||||
|
||||
/* LICENSE
|
||||
/* .ad
|
||||
@ -48,6 +50,11 @@ extern void attr_clnt_control(ATTR_CLNT *, int,...);
|
||||
/* IBM T.J. Watson Research
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*
|
||||
/* Wietse Venema
|
||||
/* Google, Inc.
|
||||
/* 111 8th Avenue
|
||||
/* New York, NY 10011, USA
|
||||
/*--*/
|
||||
|
||||
#endif
|
||||
|
@ -228,6 +228,7 @@ int main(int unused_argc, char **argv)
|
||||
htable_enter(table, "foo-name", mystrdup("foo-value"));
|
||||
htable_enter(table, "bar-name", mystrdup("bar-value"));
|
||||
attr_print0(VSTREAM_OUT, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR("protocol", "test"),
|
||||
SEND_ATTR_INT(ATTR_NAME_INT, 4711),
|
||||
SEND_ATTR_LONG(ATTR_NAME_LONG, 1234L),
|
||||
SEND_ATTR_STR(ATTR_NAME_STR, "whoopee"),
|
||||
@ -236,11 +237,15 @@ int main(int unused_argc, char **argv)
|
||||
SEND_ATTR_LONG(ATTR_NAME_LONG, 4321L),
|
||||
ATTR_TYPE_END);
|
||||
attr_print0(VSTREAM_OUT, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR("protocol", "test"),
|
||||
SEND_ATTR_INT(ATTR_NAME_INT, 4711),
|
||||
SEND_ATTR_LONG(ATTR_NAME_LONG, 1234L),
|
||||
SEND_ATTR_STR(ATTR_NAME_STR, "whoopee"),
|
||||
SEND_ATTR_DATA(ATTR_NAME_DATA, strlen("whoopee"), "whoopee"),
|
||||
ATTR_TYPE_END);
|
||||
attr_print0(VSTREAM_OUT, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR("protocol", "not-test"),
|
||||
ATTR_TYPE_END);
|
||||
if (vstream_fflush(VSTREAM_OUT) != 0)
|
||||
msg_fatal("write error: %m");
|
||||
|
||||
|
@ -269,6 +269,7 @@ int main(int unused_argc, char **argv)
|
||||
htable_enter(table, "foo-name", mystrdup("foo-value"));
|
||||
htable_enter(table, "bar-name", mystrdup("bar-value"));
|
||||
attr_print64(VSTREAM_OUT, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR("protocol", "test"),
|
||||
SEND_ATTR_INT(ATTR_NAME_INT, 4711),
|
||||
SEND_ATTR_LONG(ATTR_NAME_LONG, 1234L),
|
||||
SEND_ATTR_STR(ATTR_NAME_STR, "whoopee"),
|
||||
@ -277,11 +278,15 @@ int main(int unused_argc, char **argv)
|
||||
SEND_ATTR_LONG(ATTR_NAME_LONG, 4321L),
|
||||
ATTR_TYPE_END);
|
||||
attr_print64(VSTREAM_OUT, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR("protocol", "test"),
|
||||
SEND_ATTR_INT(ATTR_NAME_INT, 4711),
|
||||
SEND_ATTR_LONG(ATTR_NAME_LONG, 1234L),
|
||||
SEND_ATTR_STR(ATTR_NAME_STR, "whoopee"),
|
||||
SEND_ATTR_DATA(ATTR_NAME_DATA, strlen("whoopee"), "whoopee"),
|
||||
ATTR_TYPE_END);
|
||||
attr_print64(VSTREAM_OUT, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR("protocol", "not-test"),
|
||||
ATTR_TYPE_END);
|
||||
if (vstream_fflush(VSTREAM_OUT) != 0)
|
||||
msg_fatal("write error: %m");
|
||||
|
||||
|
@ -224,6 +224,7 @@ int main(int unused_argc, char **argv)
|
||||
htable_enter(table, "foo-name", mystrdup("foo-value"));
|
||||
htable_enter(table, "bar-name", mystrdup("bar-value"));
|
||||
attr_print_plain(VSTREAM_OUT, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR("protocol", "test"),
|
||||
SEND_ATTR_INT(ATTR_NAME_INT, 4711),
|
||||
SEND_ATTR_LONG(ATTR_NAME_LONG, 1234L),
|
||||
SEND_ATTR_STR(ATTR_NAME_STR, "whoopee"),
|
||||
@ -232,11 +233,15 @@ int main(int unused_argc, char **argv)
|
||||
SEND_ATTR_LONG(ATTR_NAME_LONG, 4321L),
|
||||
ATTR_TYPE_END);
|
||||
attr_print_plain(VSTREAM_OUT, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR("protocol", "test"),
|
||||
SEND_ATTR_INT(ATTR_NAME_INT, 4711),
|
||||
SEND_ATTR_LONG(ATTR_NAME_LONG, 1234L),
|
||||
SEND_ATTR_STR(ATTR_NAME_STR, "whoopee"),
|
||||
SEND_ATTR_DATA(ATTR_NAME_DATA, strlen("whoopee"), "whoopee"),
|
||||
ATTR_TYPE_END);
|
||||
attr_print_plain(VSTREAM_OUT, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR("protocol", "not-test"),
|
||||
ATTR_TYPE_END);
|
||||
if (vstream_fflush(VSTREAM_OUT) != 0)
|
||||
msg_fatal("write error: %m");
|
||||
|
||||
|
@ -100,6 +100,9 @@
|
||||
/* This argument is followed by an attribute name and a long pointer.
|
||||
/* .IP "RECV_ATTR_STR(const char *name, VSTRING *vp)"
|
||||
/* This argument is followed by an attribute name and a VSTRING pointer.
|
||||
/* .IP "RECV_ATTR_STREQ(const char *name, const char *value)"
|
||||
/* The name and value must match what the client sends.
|
||||
/* This attribute does not increment the result value.
|
||||
/* .IP "RECV_ATTR_DATA(const char *name, VSTRING *vp)"
|
||||
/* This argument is followed by an attribute name and a VSTRING pointer.
|
||||
/* .IP "RECV_ATTR_FUNC(ATTR_SCAN_CUSTOM_FN, void *data)"
|
||||
@ -278,6 +281,7 @@ int attr_vscan0(VSTREAM *fp, int flags, va_list ap)
|
||||
int conversions;
|
||||
ATTR_SCAN_CUSTOM_FN scan_fn;
|
||||
void *scan_arg;
|
||||
const char *expect_val;
|
||||
|
||||
/*
|
||||
* Sanity check.
|
||||
@ -421,6 +425,19 @@ int attr_vscan0(VSTREAM *fp, int flags, va_list ap)
|
||||
if (scan_fn(attr_scan0, fp, flags | ATTR_FLAG_MORE, scan_arg) < 0)
|
||||
return (-1);
|
||||
break;
|
||||
case ATTR_TYPE_STREQ:
|
||||
expect_val = va_arg(ap, const char *);
|
||||
if ((ch = attr_scan0_string(fp, str_buf,
|
||||
"input attribute value")) < 0)
|
||||
return (-1);
|
||||
if (strcmp(expect_val, STR(str_buf)) != 0) {
|
||||
msg_warn("unexpected %s %s from %s (expected: %s)",
|
||||
STR(name_buf), STR(str_buf), VSTREAM_PATH(fp),
|
||||
expect_val);
|
||||
return (-1);
|
||||
}
|
||||
conversions -= 1;
|
||||
break;
|
||||
case ATTR_TYPE_HASH:
|
||||
case ATTR_TYPE_CLOSE:
|
||||
if ((ch = attr_scan0_string(fp, str_buf,
|
||||
@ -513,6 +530,7 @@ int main(int unused_argc, char **used_argv)
|
||||
msg_vstream_init(used_argv[0], VSTREAM_ERR);
|
||||
if ((ret = attr_scan0(VSTREAM_IN,
|
||||
ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_STREQ("protocol", "test"),
|
||||
RECV_ATTR_INT(ATTR_NAME_INT, &int_val),
|
||||
RECV_ATTR_LONG(ATTR_NAME_LONG, &long_val),
|
||||
RECV_ATTR_STR(ATTR_NAME_STR, str_val),
|
||||
@ -534,6 +552,7 @@ int main(int unused_argc, char **used_argv)
|
||||
}
|
||||
if ((ret = attr_scan0(VSTREAM_IN,
|
||||
ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_STREQ("protocol", "test"),
|
||||
RECV_ATTR_INT(ATTR_NAME_INT, &int_val),
|
||||
RECV_ATTR_LONG(ATTR_NAME_LONG, &long_val),
|
||||
RECV_ATTR_STR(ATTR_NAME_STR, str_val),
|
||||
@ -550,6 +569,11 @@ int main(int unused_argc, char **used_argv)
|
||||
} else {
|
||||
vstream_printf("return: %d\n", ret);
|
||||
}
|
||||
if ((ret = attr_scan0(VSTREAM_IN,
|
||||
ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_STREQ("protocol", "test"),
|
||||
ATTR_TYPE_END)) != 0)
|
||||
vstream_printf("return: %d\n", ret);
|
||||
if (vstream_fflush(VSTREAM_OUT) != 0)
|
||||
msg_fatal("write error: %m");
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
./attr_print0: send attr protocol = test
|
||||
./attr_print0: send attr number = 4711
|
||||
./attr_print0: send attr long_number = 1234
|
||||
./attr_print0: send attr string = whoopee
|
||||
@ -5,10 +6,15 @@
|
||||
./attr_print0: send attr name foo-name value foo-value
|
||||
./attr_print0: send attr name bar-name value bar-value
|
||||
./attr_print0: send attr long_number = 4321
|
||||
./attr_print0: send attr protocol = test
|
||||
./attr_print0: send attr number = 4711
|
||||
./attr_print0: send attr long_number = 1234
|
||||
./attr_print0: send attr string = whoopee
|
||||
./attr_print0: send attr data = [data 7 bytes]
|
||||
./attr_print0: send attr protocol = not-test
|
||||
./attr_scan0: unknown_stream: wanted attribute: protocol
|
||||
./attr_scan0: input attribute name: protocol
|
||||
./attr_scan0: input attribute value: test
|
||||
./attr_scan0: unknown_stream: wanted attribute: number
|
||||
./attr_scan0: input attribute name: number
|
||||
./attr_scan0: input attribute value: 4711
|
||||
@ -36,6 +42,9 @@
|
||||
./attr_scan0: input attribute value: 4321
|
||||
./attr_scan0: unknown_stream: wanted attribute: (list terminator)
|
||||
./attr_scan0: input attribute name: (end)
|
||||
./attr_scan0: unknown_stream: wanted attribute: protocol
|
||||
./attr_scan0: input attribute name: protocol
|
||||
./attr_scan0: input attribute value: test
|
||||
./attr_scan0: unknown_stream: wanted attribute: number
|
||||
./attr_scan0: input attribute name: number
|
||||
./attr_scan0: input attribute value: 4711
|
||||
@ -50,6 +59,10 @@
|
||||
./attr_scan0: input attribute value: d2hvb3BlZQ==
|
||||
./attr_scan0: unknown_stream: wanted attribute: (list terminator)
|
||||
./attr_scan0: input attribute name: (end)
|
||||
./attr_scan0: unknown_stream: wanted attribute: protocol
|
||||
./attr_scan0: input attribute name: protocol
|
||||
./attr_scan0: input attribute value: not-test
|
||||
./attr_scan0: warning: unexpected protocol not-test from unknown_stream (expected: test)
|
||||
number 4711
|
||||
long_number 1234
|
||||
string whoopee
|
||||
@ -63,3 +76,4 @@ string whoopee
|
||||
data whoopee
|
||||
(hash) foo-name foo-value
|
||||
(hash) bar-name bar-value
|
||||
return: -1
|
||||
|
@ -102,6 +102,9 @@
|
||||
/* This argument is followed by an attribute name and a long pointer.
|
||||
/* .IP "RECV_ATTR_STR(const char *name, VSTRING *vp)"
|
||||
/* This argument is followed by an attribute name and a VSTRING pointer.
|
||||
/* .IP "RECV_ATTR_STREQ(const char *name, const char *value)"
|
||||
/* The name and value must match what the client sends.
|
||||
/* This attribute does not increment the result value.
|
||||
/* .IP "RECV_ATTR_DATA(const char *name, VSTRING *vp)"
|
||||
/* This argument is followed by an attribute name and a VSTRING pointer.
|
||||
/* .IP "RECV_ATTR_FUNC(ATTR_SCAN_CUSTOM_FN, void *data)"
|
||||
@ -281,6 +284,7 @@ int attr_vscan64(VSTREAM *fp, int flags, va_list ap)
|
||||
int conversions;
|
||||
ATTR_SCAN_CUSTOM_FN scan_fn;
|
||||
void *scan_arg;
|
||||
const char *expect_val;
|
||||
|
||||
/*
|
||||
* Sanity check.
|
||||
@ -470,6 +474,29 @@ int attr_vscan64(VSTREAM *fp, int flags, va_list ap)
|
||||
if (scan_fn(attr_scan64, fp, flags | ATTR_FLAG_MORE, scan_arg) < 0)
|
||||
return (-1);
|
||||
break;
|
||||
case ATTR_TYPE_STREQ:
|
||||
if (ch != ':') {
|
||||
msg_warn("missing value for string attribute %s from %s",
|
||||
STR(name_buf), VSTREAM_PATH(fp));
|
||||
return (-1);
|
||||
}
|
||||
expect_val = va_arg(ap, const char *);
|
||||
if ((ch = attr_scan64_string(fp, str_buf,
|
||||
"input attribute value")) < 0)
|
||||
return (-1);
|
||||
if (ch != '\n') {
|
||||
msg_warn("multiple values for attribute %s from %s",
|
||||
STR(name_buf), VSTREAM_PATH(fp));
|
||||
return (-1);
|
||||
}
|
||||
if (strcmp(expect_val, STR(str_buf)) != 0) {
|
||||
msg_warn("unexpected %s %s from %s (expected: %s)",
|
||||
STR(name_buf), STR(str_buf), VSTREAM_PATH(fp),
|
||||
expect_val);
|
||||
return (-1);
|
||||
}
|
||||
conversions -= 1;
|
||||
break;
|
||||
case ATTR_TYPE_HASH:
|
||||
case ATTR_TYPE_CLOSE:
|
||||
if (ch != ':') {
|
||||
@ -572,6 +599,7 @@ int main(int unused_argc, char **used_argv)
|
||||
msg_vstream_init(used_argv[0], VSTREAM_ERR);
|
||||
if ((ret = attr_scan64(VSTREAM_IN,
|
||||
ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_STREQ("protocol", "test"),
|
||||
RECV_ATTR_INT(ATTR_NAME_INT, &int_val),
|
||||
RECV_ATTR_LONG(ATTR_NAME_LONG, &long_val),
|
||||
RECV_ATTR_STR(ATTR_NAME_STR, str_val),
|
||||
@ -593,6 +621,7 @@ int main(int unused_argc, char **used_argv)
|
||||
}
|
||||
if ((ret = attr_scan64(VSTREAM_IN,
|
||||
ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_STREQ("protocol", "test"),
|
||||
RECV_ATTR_INT(ATTR_NAME_INT, &int_val),
|
||||
RECV_ATTR_LONG(ATTR_NAME_LONG, &long_val),
|
||||
RECV_ATTR_STR(ATTR_NAME_STR, str_val),
|
||||
@ -609,6 +638,11 @@ int main(int unused_argc, char **used_argv)
|
||||
} else {
|
||||
vstream_printf("return: %d\n", ret);
|
||||
}
|
||||
if ((ret = attr_scan64(VSTREAM_IN,
|
||||
ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_STREQ("protocol", "test"),
|
||||
ATTR_TYPE_END)) != 0)
|
||||
vstream_printf("return: %d\n", ret);
|
||||
if (vstream_fflush(VSTREAM_OUT) != 0)
|
||||
msg_fatal("write error: %m");
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
./attr_print64: send attr protocol = test
|
||||
./attr_print64: send attr number = 4711
|
||||
./attr_print64: send attr long_number = 1234
|
||||
./attr_print64: send attr string = whoopee
|
||||
@ -5,10 +6,15 @@
|
||||
./attr_print64: send attr name foo-name value foo-value
|
||||
./attr_print64: send attr name bar-name value bar-value
|
||||
./attr_print64: send attr long_number = 4321
|
||||
./attr_print64: send attr protocol = test
|
||||
./attr_print64: send attr number = 4711
|
||||
./attr_print64: send attr long_number = 1234
|
||||
./attr_print64: send attr string = whoopee
|
||||
./attr_print64: send attr data = [data 7 bytes]
|
||||
./attr_print64: send attr protocol = not-test
|
||||
./attr_scan64: unknown_stream: wanted attribute: protocol
|
||||
./attr_scan64: input attribute name: protocol
|
||||
./attr_scan64: input attribute value: test
|
||||
./attr_scan64: unknown_stream: wanted attribute: number
|
||||
./attr_scan64: input attribute name: number
|
||||
./attr_scan64: input attribute value: 4711
|
||||
@ -36,6 +42,9 @@
|
||||
./attr_scan64: input attribute value: 4321
|
||||
./attr_scan64: unknown_stream: wanted attribute: (list terminator)
|
||||
./attr_scan64: input attribute name: (end)
|
||||
./attr_scan64: unknown_stream: wanted attribute: protocol
|
||||
./attr_scan64: input attribute name: protocol
|
||||
./attr_scan64: input attribute value: test
|
||||
./attr_scan64: unknown_stream: wanted attribute: number
|
||||
./attr_scan64: input attribute name: number
|
||||
./attr_scan64: input attribute value: 4711
|
||||
@ -50,6 +59,10 @@
|
||||
./attr_scan64: input attribute value: whoopee
|
||||
./attr_scan64: unknown_stream: wanted attribute: (list terminator)
|
||||
./attr_scan64: input attribute name: (end)
|
||||
./attr_scan64: unknown_stream: wanted attribute: protocol
|
||||
./attr_scan64: input attribute name: protocol
|
||||
./attr_scan64: input attribute value: not-test
|
||||
./attr_scan64: warning: unexpected protocol not-test from unknown_stream (expected: test)
|
||||
number 4711
|
||||
long_number 1234
|
||||
string whoopee
|
||||
@ -63,3 +76,4 @@ string whoopee
|
||||
data whoopee
|
||||
(hash) foo-name foo-value
|
||||
(hash) bar-name bar-value
|
||||
return: -1
|
||||
|
@ -100,6 +100,9 @@
|
||||
/* This argument is followed by an attribute name and a long pointer.
|
||||
/* .IP "RECV_ATTR_STR(const char *name, VSTRING *vp)"
|
||||
/* This argument is followed by an attribute name and a VSTRING pointer.
|
||||
/* .IP "RECV_ATTR_STREQ(const char *name, const char *value)"
|
||||
/* The name and value must match what the client sends.
|
||||
/* This attribute does not increment the result value.
|
||||
/* .IP "RECV_ATTR_DATA(const char *name, VSTRING *vp)"
|
||||
/* This argument is followed by an attribute name and a VSTRING pointer.
|
||||
/* .IP "RECV_ATTR_FUNC(ATTR_SCAN_CUSTOM_FN, void *data)"
|
||||
@ -294,6 +297,7 @@ int attr_vscan_plain(VSTREAM *fp, int flags, va_list ap)
|
||||
int conversions;
|
||||
ATTR_SCAN_CUSTOM_FN scan_fn;
|
||||
void *scan_arg;
|
||||
const char *expect_val;
|
||||
|
||||
/*
|
||||
* Sanity check.
|
||||
@ -458,6 +462,24 @@ int attr_vscan_plain(VSTREAM *fp, int flags, va_list ap)
|
||||
if (scan_fn(attr_scan_plain, fp, flags | ATTR_FLAG_MORE, scan_arg) < 0)
|
||||
return (-1);
|
||||
break;
|
||||
case ATTR_TYPE_STREQ:
|
||||
if (ch != '=') {
|
||||
msg_warn("missing value for string attribute %s from %s",
|
||||
STR(name_buf), VSTREAM_PATH(fp));
|
||||
return (-1);
|
||||
}
|
||||
expect_val = va_arg(ap, const char *);
|
||||
if ((ch = attr_scan_plain_string(fp, str_buf, 0,
|
||||
"input attribute value")) < 0)
|
||||
return (-1);
|
||||
if (strcmp(expect_val, STR(str_buf)) != 0) {
|
||||
msg_warn("unexpected %s %s from %s (expected: %s)",
|
||||
STR(name_buf), STR(str_buf), VSTREAM_PATH(fp),
|
||||
expect_val);
|
||||
return (-1);
|
||||
}
|
||||
conversions -= 1;
|
||||
break;
|
||||
case ATTR_TYPE_HASH:
|
||||
case ATTR_TYPE_CLOSE:
|
||||
if (ch != '=') {
|
||||
@ -555,6 +577,7 @@ int main(int unused_argc, char **used_argv)
|
||||
msg_vstream_init(used_argv[0], VSTREAM_ERR);
|
||||
if ((ret = attr_scan_plain(VSTREAM_IN,
|
||||
ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_STREQ("protocol", "test"),
|
||||
RECV_ATTR_INT(ATTR_NAME_INT, &int_val),
|
||||
RECV_ATTR_LONG(ATTR_NAME_LONG, &long_val),
|
||||
RECV_ATTR_STR(ATTR_NAME_STR, str_val),
|
||||
@ -576,6 +599,7 @@ int main(int unused_argc, char **used_argv)
|
||||
}
|
||||
if ((ret = attr_scan_plain(VSTREAM_IN,
|
||||
ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_STREQ("protocol", "test"),
|
||||
RECV_ATTR_INT(ATTR_NAME_INT, &int_val),
|
||||
RECV_ATTR_LONG(ATTR_NAME_LONG, &long_val),
|
||||
RECV_ATTR_STR(ATTR_NAME_STR, str_val),
|
||||
@ -592,6 +616,11 @@ int main(int unused_argc, char **used_argv)
|
||||
} else {
|
||||
vstream_printf("return: %d\n", ret);
|
||||
}
|
||||
if ((ret = attr_scan_plain(VSTREAM_IN,
|
||||
ATTR_FLAG_STRICT,
|
||||
RECV_ATTR_STREQ("protocol", "test"),
|
||||
ATTR_TYPE_END)) != 0)
|
||||
vstream_printf("return: %d\n", ret);
|
||||
if (vstream_fflush(VSTREAM_OUT) != 0)
|
||||
msg_fatal("write error: %m");
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
./attr_print_plain: send attr protocol = test
|
||||
./attr_print_plain: send attr number = 4711
|
||||
./attr_print_plain: send attr long_number = 1234
|
||||
./attr_print_plain: send attr string = whoopee
|
||||
@ -5,10 +6,15 @@
|
||||
./attr_print_plain: send attr name foo-name value foo-value
|
||||
./attr_print_plain: send attr name bar-name value bar-value
|
||||
./attr_print_plain: send attr long_number = 4321
|
||||
./attr_print_plain: send attr protocol = test
|
||||
./attr_print_plain: send attr number = 4711
|
||||
./attr_print_plain: send attr long_number = 1234
|
||||
./attr_print_plain: send attr string = whoopee
|
||||
./attr_print_plain: send attr data = [data 7 bytes]
|
||||
./attr_print_plain: send attr protocol = not-test
|
||||
./attr_scan_plain: unknown_stream: wanted attribute: protocol
|
||||
./attr_scan_plain: input attribute name: protocol
|
||||
./attr_scan_plain: input attribute value: test
|
||||
./attr_scan_plain: unknown_stream: wanted attribute: number
|
||||
./attr_scan_plain: input attribute name: number
|
||||
./attr_scan_plain: input attribute value: 4711
|
||||
@ -36,6 +42,9 @@
|
||||
./attr_scan_plain: input attribute value: 4321
|
||||
./attr_scan_plain: unknown_stream: wanted attribute: (list terminator)
|
||||
./attr_scan_plain: input attribute name: (end)
|
||||
./attr_scan_plain: unknown_stream: wanted attribute: protocol
|
||||
./attr_scan_plain: input attribute name: protocol
|
||||
./attr_scan_plain: input attribute value: test
|
||||
./attr_scan_plain: unknown_stream: wanted attribute: number
|
||||
./attr_scan_plain: input attribute name: number
|
||||
./attr_scan_plain: input attribute value: 4711
|
||||
@ -50,6 +59,10 @@
|
||||
./attr_scan_plain: input attribute value: d2hvb3BlZQ==
|
||||
./attr_scan_plain: unknown_stream: wanted attribute: (list terminator)
|
||||
./attr_scan_plain: input attribute name: (end)
|
||||
./attr_scan_plain: unknown_stream: wanted attribute: protocol
|
||||
./attr_scan_plain: input attribute name: protocol
|
||||
./attr_scan_plain: input attribute value: not-test
|
||||
./attr_scan_plain: warning: unexpected protocol not-test from unknown_stream (expected: test)
|
||||
number 4711
|
||||
long_number 1234
|
||||
string whoopee
|
||||
@ -63,3 +76,4 @@ string whoopee
|
||||
data whoopee
|
||||
(hash) foo-name foo-value
|
||||
(hash) bar-name bar-value
|
||||
return: -1
|
||||
|
@ -6,6 +6,8 @@
|
||||
/* SYNOPSIS
|
||||
/* #include <auto_clnt.h>
|
||||
/*
|
||||
/* typedef void (*AUTO_CLNT_HANDSHAKE_FN)(VSTREAM *);
|
||||
/*
|
||||
/* AUTO_CLNT *auto_clnt_create(service, timeout, max_idle, max_ttl)
|
||||
/* const char *service;
|
||||
/* int timeout;
|
||||
@ -23,6 +25,10 @@
|
||||
/*
|
||||
/* void auto_clnt_free(auto_clnt)
|
||||
/* AUTO_CLNT *auto_clnt;
|
||||
/*
|
||||
/* void auto_clnt_control(auto_clnt, name, value, ... AUTO_CLNT_CTL_END)
|
||||
/* AUTO_CLNT *auto_clnt;
|
||||
/* int name;
|
||||
/* DESCRIPTION
|
||||
/* This module maintains IPC client endpoints that automatically
|
||||
/* disconnect after a being idle for a configurable amount of time,
|
||||
@ -47,6 +53,15 @@
|
||||
/*
|
||||
/* auto_clnt_free() destroys of the specified client endpoint.
|
||||
/*
|
||||
/* auto_clnt_control() allows the user to fine tune the behavior of
|
||||
/* the specified client. The arguments are a list of (name, value)
|
||||
/* terminated with AUTO_CLNT_CTL_END.
|
||||
/* The following lists the names and the types of the corresponding
|
||||
/* value arguments.
|
||||
/* .IP "AUTO_CLNT_CTL_HANDSHAKE(VSTREAM *)"
|
||||
/* A pointer to function that will be called at the start of a
|
||||
/* new connection, and that returns 0 in case of success.
|
||||
/* .PP
|
||||
/* Arguments:
|
||||
/* .IP service
|
||||
/* The service argument specifies "transport:servername" where
|
||||
@ -79,6 +94,10 @@
|
||||
/* is expected to set the stream pathname to the server endpoint name.
|
||||
/* .IP context
|
||||
/* Application context that is passed to the open_action routine.
|
||||
/* .IP handshake
|
||||
/* A null pointer, or a pointer to function that will be called
|
||||
/* at the start of a new connection and that returns 0 in case
|
||||
/* of success.
|
||||
/* DIAGNOSTICS
|
||||
/* Warnings: communication failure. Fatal error: out of memory.
|
||||
/* LICENSE
|
||||
@ -90,6 +109,11 @@
|
||||
/* IBM T.J. Watson Research
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*
|
||||
/* Wietse Venema
|
||||
/* Google, Inc.
|
||||
/* 111 8th Avenue
|
||||
/* New York, NY 10011, USA
|
||||
/*--*/
|
||||
|
||||
/* System library. */
|
||||
@ -120,6 +144,7 @@ struct AUTO_CLNT {
|
||||
int timeout; /* I/O time limit */
|
||||
int max_idle; /* time before client disconnect */
|
||||
int max_ttl; /* time before client disconnect */
|
||||
AUTO_CLNT_HANDSHAKE_FN handshake; /* new connection only */
|
||||
int (*connect) (const char *, int, int); /* unix, local, inet */
|
||||
};
|
||||
|
||||
@ -250,6 +275,7 @@ void auto_clnt_recover(AUTO_CLNT *auto_clnt)
|
||||
|
||||
VSTREAM *auto_clnt_access(AUTO_CLNT *auto_clnt)
|
||||
{
|
||||
AUTO_CLNT_HANDSHAKE_FN handshake;
|
||||
|
||||
/*
|
||||
* Open a stream or restart the idle timer.
|
||||
@ -258,11 +284,15 @@ VSTREAM *auto_clnt_access(AUTO_CLNT *auto_clnt)
|
||||
*/
|
||||
if (auto_clnt->vstream == 0) {
|
||||
auto_clnt_open(auto_clnt);
|
||||
handshake = (auto_clnt->vstream ? auto_clnt->handshake : 0);
|
||||
} else {
|
||||
if (auto_clnt->max_idle > 0)
|
||||
event_request_timer(auto_clnt_event, (void *) auto_clnt,
|
||||
auto_clnt->max_idle);
|
||||
handshake = 0;
|
||||
}
|
||||
if (handshake != 0 && handshake(auto_clnt->vstream) != 0)
|
||||
return (0);
|
||||
return (auto_clnt->vstream);
|
||||
}
|
||||
|
||||
@ -290,6 +320,7 @@ AUTO_CLNT *auto_clnt_create(const char *service, int timeout,
|
||||
auto_clnt->timeout = timeout;
|
||||
auto_clnt->max_idle = max_idle;
|
||||
auto_clnt->max_ttl = max_ttl;
|
||||
auto_clnt->handshake = 0;
|
||||
if (strcmp(transport, "inet") == 0) {
|
||||
auto_clnt->connect = inet_connect;
|
||||
} else if (strcmp(transport, "local") == 0) {
|
||||
@ -320,3 +351,22 @@ void auto_clnt_free(AUTO_CLNT *auto_clnt)
|
||||
myfree(auto_clnt->endpoint);
|
||||
myfree((void *) auto_clnt);
|
||||
}
|
||||
|
||||
/* auto_clnt_control - fine control */
|
||||
|
||||
void auto_clnt_control(AUTO_CLNT *client, int name,...)
|
||||
{
|
||||
const char *myname = "auto_clnt_control";
|
||||
va_list ap;
|
||||
|
||||
for (va_start(ap, name); name != AUTO_CLNT_CTL_END; name = va_arg(ap, int)) {
|
||||
switch (name) {
|
||||
case AUTO_CLNT_CTL_HANDSHAKE:
|
||||
client->handshake = va_arg(ap, AUTO_CLNT_HANDSHAKE_FN);
|
||||
break;
|
||||
default:
|
||||
msg_panic("%s: bad name %d", myname, name);
|
||||
}
|
||||
}
|
||||
va_end(ap);
|
||||
}
|
||||
|
@ -20,12 +20,17 @@
|
||||
* External interface.
|
||||
*/
|
||||
typedef struct AUTO_CLNT AUTO_CLNT;
|
||||
typedef int (*AUTO_CLNT_HANDSHAKE_FN) (VSTREAM *);
|
||||
|
||||
extern AUTO_CLNT *auto_clnt_create(const char *, int, int, int);
|
||||
extern VSTREAM *auto_clnt_access(AUTO_CLNT *);
|
||||
extern void auto_clnt_recover(AUTO_CLNT *);
|
||||
extern const char *auto_clnt_name(AUTO_CLNT *);
|
||||
extern void auto_clnt_free(AUTO_CLNT *);
|
||||
extern void auto_clnt_control(AUTO_CLNT *, int,...);
|
||||
|
||||
#define AUTO_CLNT_CTL_END 0
|
||||
#define AUTO_CLNT_CTL_HANDSHAKE 1 /* handshake before first request */
|
||||
|
||||
/* LICENSE
|
||||
/* .ad
|
||||
@ -36,6 +41,11 @@ extern void auto_clnt_free(AUTO_CLNT *);
|
||||
/* IBM T.J. Watson Research
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*
|
||||
/* Wietse Venema
|
||||
/* Google, Inc.
|
||||
/* 111 8th Avenue
|
||||
/* New York, NY 10011, USA
|
||||
/*--*/
|
||||
|
||||
#endif
|
||||
|
@ -95,7 +95,6 @@
|
||||
#include <vstream.h>
|
||||
#include <msg_vstream.h>
|
||||
#include <stringops.h>
|
||||
#include <percentm.h>
|
||||
#include <msg_output.h>
|
||||
|
||||
/*
|
||||
@ -165,7 +164,7 @@ void msg_vprintf(int level, const char *format, va_list ap)
|
||||
msg_vstream_init("unknown", VSTREAM_ERR);
|
||||
vp = msg_buffers[msg_vprintf_level - 1];
|
||||
/* OK if terminating signal handler hijacks control before next stmt. */
|
||||
vstring_vsprintf(vp, percentm(format, errno), ap);
|
||||
vstring_vsprintf(vp, format, ap);
|
||||
printable(vstring_str(vp), '?');
|
||||
for (i = 0; i < msg_output_fn_count; i++)
|
||||
msg_output_fn[i] (level, vstring_str(vp));
|
||||
|
@ -1,84 +0,0 @@
|
||||
/*++
|
||||
/* NAME
|
||||
/* percentm 3
|
||||
/* SUMMARY
|
||||
/* expand %m embedded in string to system error text
|
||||
/* SYNOPSIS
|
||||
/* #include <percentm.h>
|
||||
/*
|
||||
/* char *percentm(const char *src, int err)
|
||||
/* DESCRIPTION
|
||||
/* The percentm() routine makes a copy of the null-terminated string
|
||||
/* given via the \fIsrc\fR argument, with %m sequences replaced by
|
||||
/* the system error text corresponding to the \fIerr\fR argument.
|
||||
/* The result is overwritten upon each successive call.
|
||||
/*
|
||||
/* Arguments:
|
||||
/* .IP src
|
||||
/* A null-terminated input string with zero or more %m sequences.
|
||||
/* .IP err
|
||||
/* A legal \fIerrno\fR value. The text corresponding to this error
|
||||
/* value is used when expanding %m sequences.
|
||||
/* SEE ALSO
|
||||
/* syslog(3) system logger library
|
||||
/* HISTORY
|
||||
/* .ad
|
||||
/* .fi
|
||||
/* A percentm() routine appears in the TCP Wrapper software
|
||||
/* by Wietse Venema.
|
||||
/* LICENSE
|
||||
/* .ad
|
||||
/* .fi
|
||||
/* The Secure Mailer license must be distributed with this software.
|
||||
/* AUTHOR(S)
|
||||
/* Wietse Venema
|
||||
/* IBM T.J. Watson Research
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*--*/
|
||||
|
||||
/* System libraries. */
|
||||
|
||||
#include <sys_defs.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Utility library. */
|
||||
|
||||
#include "vstring.h"
|
||||
#include "percentm.h"
|
||||
|
||||
/* percentm - replace %m by error message corresponding to value in err */
|
||||
|
||||
char *percentm(const char *str, int err)
|
||||
{
|
||||
static VSTRING *vp;
|
||||
const unsigned char *ip = (const unsigned char *) str;
|
||||
|
||||
if (vp == 0)
|
||||
vp = vstring_alloc(100); /* grows on demand */
|
||||
VSTRING_RESET(vp);
|
||||
|
||||
while (*ip) {
|
||||
switch (*ip) {
|
||||
default:
|
||||
VSTRING_ADDCH(vp, *ip++);
|
||||
break;
|
||||
case '%':
|
||||
switch (ip[1]) {
|
||||
default: /* leave %<any> alone */
|
||||
VSTRING_ADDCH(vp, *ip++);
|
||||
/* FALLTHROUGH */
|
||||
case '\0': /* don't fall off end */
|
||||
VSTRING_ADDCH(vp, *ip++);
|
||||
break;
|
||||
case 'm': /* replace %m */
|
||||
vstring_strcat(vp, strerror(err));
|
||||
ip += 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
VSTRING_TERMINATE(vp);
|
||||
return (vstring_str(vp));
|
||||
}
|
||||
|
@ -1,35 +0,0 @@
|
||||
#ifndef _PERCENT_H_INCLUDED_
|
||||
#define _PERCENT_H_INCLUDED_
|
||||
|
||||
/*++
|
||||
/* NAME
|
||||
/* percentm 3h
|
||||
/* SUMMARY
|
||||
/* expand %m embedded in string to system error text
|
||||
/* SYNOPSIS
|
||||
/* #include <percentm.h>
|
||||
/* DESCRIPTION
|
||||
/* .nf
|
||||
|
||||
/*
|
||||
* External interface.
|
||||
*/
|
||||
extern char *percentm(const char *, int);
|
||||
|
||||
/* HISTORY
|
||||
/* .ad
|
||||
/* .fi
|
||||
/* A percentm() routine appears in the TCP Wrapper software
|
||||
/* by Wietse Venema.
|
||||
/* LICENSE
|
||||
/* .ad
|
||||
/* .fi
|
||||
/* The Secure Mailer license must be distributed with this software.
|
||||
/* AUTHOR(S)
|
||||
/* Wietse Venema
|
||||
/* IBM T.J. Watson Research
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*--*/
|
||||
|
||||
#endif
|
@ -526,8 +526,8 @@ static void verify_query_service(VSTREAM *client_stream)
|
||||
(addr_status != DEL_RCPT_STAT_OK && updated + var_verify_neg_try < now)
|
||||
|
||||
if (now - probed > PROBE_TTL
|
||||
&& (POSITIVE_REFRESH_NEEDED(addr_status, updated)
|
||||
|| NEGATIVE_REFRESH_NEEDED(addr_status, updated))) {
|
||||
&& (POSITIVE_REFRESH_NEEDED(addr_status, updated)
|
||||
|| NEGATIVE_REFRESH_NEEDED(addr_status, updated))) {
|
||||
if (msg_verbose)
|
||||
msg_info("PROBE %s status=%d probed=%ld updated=%ld",
|
||||
STR(addr), addr_status, now, updated);
|
||||
@ -723,6 +723,21 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
|
||||
RESTORE_SAVED_EUGID();
|
||||
}
|
||||
|
||||
/* post_accept_init - announce our protocol */
|
||||
|
||||
static void post_accept_init(VSTREAM *stream, char *unused_name,
|
||||
char **unused_argv, HTABLE *unused_table)
|
||||
{
|
||||
|
||||
/*
|
||||
* Announce the protocol.
|
||||
*/
|
||||
attr_print(stream, ATTR_FLAG_NONE,
|
||||
SEND_ATTR_STR(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_VERIFY),
|
||||
ATTR_TYPE_END);
|
||||
(void) vstream_fflush(stream);
|
||||
}
|
||||
|
||||
MAIL_VERSION_STAMP_DECLARE;
|
||||
|
||||
/* main - pass control to the multi-threaded skeleton */
|
||||
@ -754,6 +769,7 @@ int main(int argc, char **argv)
|
||||
CA_MAIL_SERVER_TIME_TABLE(time_table),
|
||||
CA_MAIL_SERVER_PRE_INIT(pre_jail_init),
|
||||
CA_MAIL_SERVER_POST_INIT(post_jail_init),
|
||||
CA_MAIL_SERVER_POST_ACCEPT(post_accept_init),
|
||||
CA_MAIL_SERVER_SOLITARY,
|
||||
CA_MAIL_SERVER_EXIT(verify_dump),
|
||||
0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user