mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-25 11:27:48 +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_MATCH_LIST
|
||||||
-TADDR_PATTERN
|
-TADDR_PATTERN
|
||||||
-TALIAS_TOKEN
|
-TALIAS_TOKEN
|
||||||
|
@ -25057,6 +25057,8 @@ Apologies for any names omitted.
|
|||||||
mantools/man2html, mantools/readme2html, proto/*_README.html,
|
mantools/man2html, mantools/readme2html, proto/*_README.html,
|
||||||
proto/INSTALL.html, proto/postconf.html.prolog, html/index.html.
|
proto/INSTALL.html, proto/postconf.html.prolog, html/index.html.
|
||||||
|
|
||||||
|
20200830
|
||||||
|
|
||||||
Refactor: moved the SASL mechanism filter code from the
|
Refactor: moved the SASL mechanism filter code from the
|
||||||
Postfix SMTP client to a library module, so that it can be
|
Postfix SMTP client to a library module, so that it can be
|
||||||
reused in the Postfix SMTP server. Files: smtp/smtp_sasl_proto.c,
|
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
|
wants to anounce EXTERNAL support for which Postfix support
|
||||||
does not exist. Files: smtpd/smtpd.[hc], smtpd_sasl_glue.[hc],
|
does not exist. Files: smtpd/smtpd.[hc], smtpd_sasl_glue.[hc],
|
||||||
global/mail_params.h, proto/postconf.proto, mantools/postlink.
|
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
|
the software under the license of their choice. Those who are more
|
||||||
comfortable with the IPL can continue with that license.
|
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
|
Incompatible change with snapshot 20200705
|
||||||
==========================================
|
==========================================
|
||||||
|
|
||||||
|
@ -1,5 +1,23 @@
|
|||||||
Wish list:
|
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_tls_security_options = noanonymous, and make
|
||||||
smtp_sasl_security_options default dependent on the
|
smtp_sasl_security_options default dependent on the
|
||||||
smtp_sasl_tls_security_options default (i.e. reverse 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.
|
Postfix 2.6 the default protocol is 2.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#milter_default_action">milter_default_action</a> (tempfail)</b>
|
<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
|
The default action when a Milter (mail filter) response is
|
||||||
unavailable or mis-configured.
|
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>
|
<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.
|
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>
|
<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.
|
tion, and for negotiating protocol options.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#milter_command_timeout">milter_command_timeout</a> (30s)</b>
|
<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.
|
filter) application, and for receiving the response.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#milter_content_timeout">milter_content_timeout</a> (300s)</b>
|
<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.
|
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>
|
<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.
|
after completion of an SMTP connection.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#milter_helo_macros">milter_helo_macros</a> (see 'postconf -d' output)</b>
|
<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.
|
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>
|
<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.
|
after the SMTP MAIL FROM command.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#milter_rcpt_macros">milter_rcpt_macros</a> (see 'postconf -d' output)</b>
|
<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.
|
after the SMTP RCPT TO command.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#milter_data_macros">milter_data_macros</a> (see 'postconf -d' output)</b>
|
<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.
|
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>
|
<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.
|
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>
|
<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.
|
after the message end-of-data.
|
||||||
|
|
||||||
Available in Postfix version 2.5 and later:
|
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>
|
<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.
|
after the end of the message header.
|
||||||
|
|
||||||
Available in Postfix version 2.7 and later:
|
Available in Postfix version 2.7 and later:
|
||||||
@ -227,8 +228,8 @@ CLEANUP(8) CLEANUP(8)
|
|||||||
Available in Postfix version 3.1 and later:
|
Available in Postfix version 3.1 and later:
|
||||||
|
|
||||||
<b><a href="postconf.5.html#milter_macro_defaults">milter_macro_defaults</a> (empty)</b>
|
<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
|
Optional list of <i>name=value</i> pairs that specify default values
|
||||||
for arbitrary macros that Postfix may send to Milter applica-
|
for arbitrary macros that Postfix may send to Milter applica-
|
||||||
tions.
|
tions.
|
||||||
|
|
||||||
<b>MIME PROCESSING CONTROLS</b>
|
<b>MIME PROCESSING CONTROLS</b>
|
||||||
@ -254,91 +255,91 @@ CLEANUP(8) CLEANUP(8)
|
|||||||
ing information.
|
ing information.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#strict_mime_encoding_domain">strict_mime_encoding_domain</a> (no)</b>
|
<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.
|
for the message/* or multipart/* MIME content types.
|
||||||
|
|
||||||
Available in Postfix version 2.5 and later:
|
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>
|
<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-
|
Automatically detect 8BITMIME body content by looking at Con-
|
||||||
tent-Transfer-Encoding: message headers; historically, this
|
tent-Transfer-Encoding: message headers; historically, this
|
||||||
behavior was hard-coded to be "always on".
|
behavior was hard-coded to be "always on".
|
||||||
|
|
||||||
<b>AUTOMATIC BCC RECIPIENT CONTROLS</b>
|
<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:
|
the mail system:
|
||||||
|
|
||||||
<b><a href="postconf.5.html#always_bcc">always_bcc</a> (empty)</b>
|
<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.
|
message that is received by the Postfix mail system.
|
||||||
|
|
||||||
Available in Postfix version 2.1 and later:
|
Available in Postfix version 2.1 and later:
|
||||||
|
|
||||||
<b><a href="postconf.5.html#sender_bcc_maps">sender_bcc_maps</a> (empty)</b>
|
<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.
|
by sender address.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#recipient_bcc_maps">recipient_bcc_maps</a> (empty)</b>
|
<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.
|
by recipient address.
|
||||||
|
|
||||||
<b>ADDRESS TRANSFORMATION CONTROLS</b>
|
<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.
|
<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>
|
<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.
|
The recipient of mail addressed to the null address.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#canonical_maps">canonical_maps</a> (empty)</b>
|
<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.
|
envelopes.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#recipient_canonical_maps">recipient_canonical_maps</a> (empty)</b>
|
<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.
|
recipient addresses.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#sender_canonical_maps">sender_canonical_maps</a> (empty)</b>
|
<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.
|
sender addresses.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#masquerade_classes">masquerade_classes</a> (envelope_sender, header_sender, header_recipient)</b>
|
<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.
|
What addresses are subject to address masquerading.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#masquerade_domains">masquerade_domains</a> (empty)</b>
|
<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.
|
stripped off in email addresses.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#masquerade_exceptions">masquerade_exceptions</a> (empty)</b>
|
<b><a href="postconf.5.html#masquerade_exceptions">masquerade_exceptions</a> (empty)</b>
|
||||||
Optional list of user names that are not subjected to address
|
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>-
|
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>.
|
<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>
|
<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.
|
lookup key to the lookup result.
|
||||||
|
|
||||||
Available before Postfix version 2.0:
|
Available before Postfix version 2.0:
|
||||||
|
|
||||||
<b><a href="postconf.5.html#virtual_maps">virtual_maps</a> (empty)</b>
|
<b><a href="postconf.5.html#virtual_maps">virtual_maps</a> (empty)</b>
|
||||||
Optional lookup tables with a) names of domains for which all
|
Optional lookup tables with a) names of domains for which all
|
||||||
addresses are aliased to addresses in other local or remote
|
addresses are aliased to addresses in other local or remote
|
||||||
domains, and b) addresses that are aliased to addresses in other
|
domains, and b) addresses that are aliased to addresses in other
|
||||||
local or remote domains.
|
local or remote domains.
|
||||||
|
|
||||||
Available in Postfix version 2.0 and later:
|
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>
|
<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.
|
domains to other local or remote address.
|
||||||
|
|
||||||
Available in Postfix version 2.2 and later:
|
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>
|
<b>header_recipient)</b>
|
||||||
What addresses are subject to <a href="postconf.5.html#canonical_maps">canonical_maps</a> address mapping.
|
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>
|
<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.
|
mapping.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#sender_canonical_classes">sender_canonical_classes</a> (envelope_sender, header_sender)</b>
|
<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.
|
ping.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#remote_header_rewrite_domain">remote_header_rewrite_domain</a> (empty)</b>
|
<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
|
Don't rewrite message headers from remote clients at all when
|
||||||
this parameter is empty; otherwise, rewrite message headers and
|
this parameter is empty; otherwise, rewrite message headers and
|
||||||
append the specified domain name to incomplete addresses.
|
append the specified domain name to incomplete addresses.
|
||||||
|
|
||||||
<b>RESOURCE AND RATE CONTROLS</b>
|
<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.
|
<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>
|
<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.
|
header.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#hopcount_limit">hopcount_limit</a> (50)</b>
|
<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.
|
in the primary message headers.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#in_flow_delay">in_flow_delay</a> (1s)</b>
|
<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.
|
arrival rate exceeds the message delivery rate.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#message_size_limit">message_size_limit</a> (10240000)</b>
|
<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.
|
information.
|
||||||
|
|
||||||
Available in Postfix version 2.0 and later:
|
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>
|
<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.
|
message header.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#mime_boundary_length_limit">mime_boundary_length_limit</a> (2048)</b>
|
<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:
|
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>
|
<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.
|
produces from each original recipient.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#virtual_alias_recursion_limit">virtual_alias_recursion_limit</a> (1000)</b>
|
<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:
|
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>
|
<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.
|
expansion.
|
||||||
|
|
||||||
<b>SMTPUTF8 CONTROLS</b>
|
<b>SMTPUTF8 CONTROLS</b>
|
||||||
Preliminary SMTPUTF8 support is introduced with Postfix 3.0.
|
Preliminary SMTPUTF8 support is introduced with Postfix 3.0.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#smtputf8_enable">smtputf8_enable</a> (yes)</b>
|
<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.
|
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>
|
<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.
|
fied mail origin classes.
|
||||||
|
|
||||||
Available in Postfix version 3.2 and later:
|
Available in Postfix version 3.2 and later:
|
||||||
|
|
||||||
<b><a href="postconf.5.html#enable_idna2003_compatibility">enable_idna2003_compatibility</a> (no)</b>
|
<b><a href="postconf.5.html#enable_idna2003_compatibility">enable_idna2003_compatibility</a> (no)</b>
|
||||||
Enable 'transitional' compatibility between IDNA2003 and
|
Enable 'transitional' compatibility between IDNA2003 and
|
||||||
IDNA2008, when converting UTF-8 domain names to/from the ASCII
|
IDNA2008, when converting UTF-8 domain names to/from the ASCII
|
||||||
form that is used for DNS lookups.
|
form that is used for DNS lookups.
|
||||||
|
|
||||||
<b>MISCELLANEOUS CONTROLS</b>
|
<b>MISCELLANEOUS CONTROLS</b>
|
||||||
<b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</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.
|
figuration files.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#daemon_timeout">daemon_timeout</a> (18000s)</b>
|
<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.
|
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>
|
<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.
|
ging sub-second delay values.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#delay_warning_time">delay_warning_time</a> (0h)</b>
|
<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.
|
headers of mail that is still queued.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#ipc_timeout">ipc_timeout</a> (3600s)</b>
|
<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.
|
internal communication channel.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#max_idle">max_idle</a> (100s)</b>
|
<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.
|
waits for an incoming connection before terminating voluntarily.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#max_use">max_use</a> (100)</b>
|
<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.
|
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>
|
<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.
|
and that locally posted mail is delivered to.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#process_id">process_id</a> (read-only)</b>
|
<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.
|
The location of the Postfix top-level queue directory.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#soft_bounce">soft_bounce</a> (no)</b>
|
<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.
|
to the sender.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#syslog_facility">syslog_facility</a> (mail)</b>
|
<b><a href="postconf.5.html#syslog_facility">syslog_facility</a> (mail)</b>
|
||||||
The syslog facility of Postfix logging.
|
The syslog facility of Postfix logging.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
|
<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".
|
records, so that, for example, "smtpd" becomes "prefix/smtpd".
|
||||||
|
|
||||||
Available in Postfix version 2.1 and later:
|
Available in Postfix version 2.1 and later:
|
||||||
|
|
||||||
<b><a href="postconf.5.html#enable_original_recipient">enable_original_recipient</a> (yes)</b>
|
<b><a href="postconf.5.html#enable_original_recipient">enable_original_recipient</a> (yes)</b>
|
||||||
Enable support for the original recipient address after an
|
Enable support for the original recipient address after an
|
||||||
address is rewritten to a different address (for example with
|
address is rewritten to a different address (for example with
|
||||||
aliasing or with canonical mapping).
|
aliasing or with canonical mapping).
|
||||||
|
|
||||||
Available in Postfix 3.3 and later:
|
Available in Postfix 3.3 and later:
|
||||||
@ -492,7 +493,7 @@ CLEANUP(8) CLEANUP(8)
|
|||||||
Available in Postfix 3.5 and later:
|
Available in Postfix 3.5 and later:
|
||||||
|
|
||||||
<b>info_log_address_format (external)</b>
|
<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.).
|
(info, warning, etc.).
|
||||||
|
|
||||||
<b>FILES</b>
|
<b>FILES</b>
|
||||||
|
@ -169,8 +169,8 @@ TRIVIAL-REWRITE(8) TRIVIAL-REWRITE(8)
|
|||||||
explicit ".example.com" pattern.
|
explicit ".example.com" pattern.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#relayhost">relayhost</a> (empty)</b>
|
<b><a href="postconf.5.html#relayhost">relayhost</a> (empty)</b>
|
||||||
The next-hop destination of non-local mail; overrides non-local
|
The next-hop destination(s) for non-local mail; overrides
|
||||||
domains in recipient addresses.
|
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>
|
<b><a href="postconf.5.html#transport_maps">transport_maps</a> (empty)</b>
|
||||||
Optional lookup tables with mappings from recipient address to
|
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
|
for communication with a Milter application; prior to Postfix 2.6
|
||||||
the default protocol is 2.
|
the default protocol is 2.
|
||||||
.IP "\fBmilter_default_action (tempfail)\fR"
|
.IP "\fBmilter_default_action (tempfail)\fR"
|
||||||
The default action when a Milter (mail filter) application is
|
The default action when a Milter (mail filter) response is
|
||||||
unavailable or mis\-configured.
|
unavailable (for example, bad Postfix configuration or Milter
|
||||||
|
failure).
|
||||||
.IP "\fBmilter_macro_daemon_name ($myhostname)\fR"
|
.IP "\fBmilter_macro_daemon_name ($myhostname)\fR"
|
||||||
The {daemon_name} macro value for Milter (mail filter) applications.
|
The {daemon_name} macro value for Milter (mail filter) applications.
|
||||||
.IP "\fBmilter_macro_v ($mail_name $mail_version)\fR"
|
.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,
|
matches subdomains of example.com,
|
||||||
instead of requiring an explicit ".example.com" pattern.
|
instead of requiring an explicit ".example.com" pattern.
|
||||||
.IP "\fBrelayhost (empty)\fR"
|
.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.
|
domains in recipient addresses.
|
||||||
.IP "\fBtransport_maps (empty)\fR"
|
.IP "\fBtransport_maps (empty)\fR"
|
||||||
Optional lookup tables with mappings from recipient address to
|
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;
|
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 */
|
/* main - pass control to the multi-threaded skeleton */
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
@ -1024,6 +1039,7 @@ int main(int argc, char **argv)
|
|||||||
multi_server_main(argc, argv, anvil_service,
|
multi_server_main(argc, argv, anvil_service,
|
||||||
CA_MAIL_SERVER_TIME_TABLE(time_table),
|
CA_MAIL_SERVER_TIME_TABLE(time_table),
|
||||||
CA_MAIL_SERVER_POST_INIT(post_jail_init),
|
CA_MAIL_SERVER_POST_INIT(post_jail_init),
|
||||||
|
CA_MAIL_SERVER_POST_ACCEPT(post_accept),
|
||||||
CA_MAIL_SERVER_SOLITARY,
|
CA_MAIL_SERVER_SOLITARY,
|
||||||
CA_MAIL_SERVER_PRE_DISCONN(anvil_service_done),
|
CA_MAIL_SERVER_PRE_DISCONN(anvil_service_done),
|
||||||
CA_MAIL_SERVER_EXIT(anvil_status_dump),
|
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)
|
if (mail_queue_name_ok(service_name) == 0)
|
||||||
msg_fatal("malformed service name: %s", service_name);
|
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
|
* Read and validate the first parameter of the client request. Let the
|
||||||
* request-specific protocol routines take care of the remainder.
|
* request-specific protocol routines take care of the remainder.
|
||||||
|
@ -144,8 +144,9 @@
|
|||||||
/* for communication with a Milter application; prior to Postfix 2.6
|
/* for communication with a Milter application; prior to Postfix 2.6
|
||||||
/* the default protocol is 2.
|
/* the default protocol is 2.
|
||||||
/* .IP "\fBmilter_default_action (tempfail)\fR"
|
/* .IP "\fBmilter_default_action (tempfail)\fR"
|
||||||
/* The default action when a Milter (mail filter) application is
|
/* The default action when a Milter (mail filter) response is
|
||||||
/* unavailable or mis-configured.
|
/* unavailable (for example, bad Postfix configuration or Milter
|
||||||
|
/* failure).
|
||||||
/* .IP "\fBmilter_macro_daemon_name ($myhostname)\fR"
|
/* .IP "\fBmilter_macro_daemon_name ($myhostname)\fR"
|
||||||
/* The {daemon_name} macro value for Milter (mail filter) applications.
|
/* The {daemon_name} macro value for Milter (mail filter) applications.
|
||||||
/* .IP "\fBmilter_macro_v ($mail_name $mail_version)\fR"
|
/* .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.
|
* about the whole operation.
|
||||||
*/
|
*/
|
||||||
attr_print(src, ATTR_FLAG_NONE,
|
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),
|
SEND_ATTR_STR(MAIL_ATTR_QUEUEID, state->queue_id),
|
||||||
ATTR_TYPE_END);
|
ATTR_TYPE_END);
|
||||||
if (attr_scan(src, ATTR_FLAG_STRICT,
|
if (attr_scan(src, ATTR_FLAG_STRICT,
|
||||||
|
@ -699,6 +699,14 @@ static int flush_request_receive(VSTREAM *client_stream, VSTRING *request)
|
|||||||
{
|
{
|
||||||
int count;
|
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.
|
* Kluge: choose the protocol depending on the request size.
|
||||||
*/
|
*/
|
||||||
|
@ -169,6 +169,11 @@
|
|||||||
/* IBM T.J. Watson Research
|
/* IBM T.J. Watson Research
|
||||||
/* P.O. Box 704
|
/* P.O. Box 704
|
||||||
/* Yorktown Heights, NY 10598, USA
|
/* Yorktown Heights, NY 10598, USA
|
||||||
|
/*
|
||||||
|
/* Wietse Venema
|
||||||
|
/* Google, Inc.
|
||||||
|
/* 111 8th Avenue
|
||||||
|
/* New York, NY 10011, USA
|
||||||
/*--*/
|
/*--*/
|
||||||
|
|
||||||
/* System library. */
|
/* System library. */
|
||||||
@ -202,10 +207,11 @@ typedef struct {
|
|||||||
int command; /* bounce request type */
|
int command; /* bounce request type */
|
||||||
int flags; /* bounce options */
|
int flags; /* bounce options */
|
||||||
char *id; /* queue ID for logging */
|
char *id; /* queue ID for logging */
|
||||||
|
VSTRING *request; /* serialized request */
|
||||||
ABOUNCE_FN callback; /* application callback */
|
ABOUNCE_FN callback; /* application callback */
|
||||||
void *context; /* application context */
|
void *context; /* application context */
|
||||||
VSTREAM *fp; /* server I/O handle */
|
VSTREAM *fp; /* server I/O handle */
|
||||||
} ABOUNCE;
|
} ABOUNCE_STATE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Encapsulate common code.
|
* Encapsulate common code.
|
||||||
@ -215,11 +221,6 @@ typedef struct {
|
|||||||
event_request_timer((callback), (context), (timeout)); \
|
event_request_timer((callback), (context), (timeout)); \
|
||||||
} while (0)
|
} 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
|
* 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
|
* increasing overload. With 1000s timeout mail will keep flowing, but there
|
||||||
@ -228,11 +229,30 @@ typedef struct {
|
|||||||
*/
|
*/
|
||||||
#define ABOUNCE_TIMEOUT 1000
|
#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 */
|
/* 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)
|
if (status != 0 && (ap->flags & BOUNCE_FLAG_CLEAN) == 0)
|
||||||
msg_info("%s: status=deferred (%s failed)", ap->id,
|
msg_info("%s: status=deferred (%s failed)", ap->id,
|
||||||
ap->command == BOUNCE_CMD_FLUSH ? "bounce" :
|
ap->command == BOUNCE_CMD_FLUSH ? "bounce" :
|
||||||
@ -242,65 +262,125 @@ static void abounce_done(ABOUNCE *ap, int status)
|
|||||||
"whatever");
|
"whatever");
|
||||||
ap->callback(status, ap->context);
|
ap->callback(status, ap->context);
|
||||||
myfree(ap->id);
|
myfree(ap->id);
|
||||||
|
vstring_free(ap->request);
|
||||||
myfree((void *) ap);
|
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;
|
int status;
|
||||||
|
|
||||||
ABOUNCE_EVENT_DISABLE(vstream_fileno(ap->fp), abounce_event, context);
|
if (event != EVENT_TIME)
|
||||||
abounce_done(ap, (event != EVENT_TIME
|
event_cancel_timer(abounce_receive, context);
|
||||||
&& attr_scan(ap->fp, ATTR_FLAG_STRICT,
|
|
||||||
RECV_ATTR_INT(MAIL_ATTR_STATUS, &status),
|
if (event == EVENT_READ
|
||||||
ATTR_TYPE_END) == 1) ? status : -1);
|
&& 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,
|
static void abounce_send(int event, void *context)
|
||||||
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 *ap;
|
ABOUNCE_STATE *ap = (ABOUNCE_STATE *) context;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Save pseudo thread state. Connect to the server. Send the request and
|
* Receive the server's protocol name announcement. At this point the
|
||||||
* suspend the pseudo thread until the server replies (or dies).
|
* 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->command = command;
|
||||||
ap->flags = flags;
|
ap->flags = flags;
|
||||||
ap->id = mystrdup(id);
|
ap->id = mystrdup(id);
|
||||||
|
ap->request = vstring_alloc(ABOUNCE_BUFSIZE);
|
||||||
ap->callback = callback;
|
ap->callback = callback;
|
||||||
ap->context = context;
|
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),
|
* Format the request now, so that we don't have to save a lot of
|
||||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
|
* arguments now and format the request later.
|
||||||
SEND_ATTR_STR(MAIL_ATTR_QUEUE, queue),
|
*/
|
||||||
SEND_ATTR_STR(MAIL_ATTR_QUEUEID, id),
|
if (ap->fp != 0) {
|
||||||
SEND_ATTR_STR(MAIL_ATTR_ENCODING, encoding),
|
/* Note: all code paths must terminate or enable I/O events. */
|
||||||
SEND_ATTR_INT(MAIL_ATTR_SMTPUTF8, smtputf8),
|
VSTREAM *mp = vstream_memopen(ap->request, O_WRONLY);
|
||||||
SEND_ATTR_STR(MAIL_ATTR_SENDER, sender),
|
|
||||||
SEND_ATTR_STR(MAIL_ATTR_DSN_ENVID, dsn_envid),
|
if (attr_print(mp, ATTR_FLAG_MORE,
|
||||||
SEND_ATTR_INT(MAIL_ATTR_DSN_RET, dsn_ret),
|
SEND_ATTR_INT(MAIL_ATTR_NREQ, command),
|
||||||
SEND_ATTR_STR(MAIL_ATTR_VERPDL, verp),
|
SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
|
||||||
ATTR_TYPE_END) == 0
|
SEND_ATTR_STR(MAIL_ATTR_QUEUE, queue),
|
||||||
&& vstream_fflush(ap->fp) == 0) {
|
SEND_ATTR_STR(MAIL_ATTR_QUEUEID, id),
|
||||||
ABOUNCE_EVENT_ENABLE(vstream_fileno(ap->fp), abounce_event,
|
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);
|
(void *) ap, ABOUNCE_TIMEOUT);
|
||||||
} else {
|
} else {
|
||||||
abounce_done(ap, -1);
|
abounce_done(ap, -1);
|
||||||
@ -316,9 +396,9 @@ void abounce_flush_verp(int flags, const char *queue, const char *id,
|
|||||||
ABOUNCE_FN callback,
|
ABOUNCE_FN callback,
|
||||||
void *context)
|
void *context)
|
||||||
{
|
{
|
||||||
abounce_request_verp(MAIL_CLASS_PRIVATE, var_bounce_service,
|
abounce_connect(MAIL_CLASS_PRIVATE, var_bounce_service,
|
||||||
BOUNCE_CMD_VERP, flags, queue, id, encoding, smtputf8,
|
BOUNCE_CMD_VERP, flags, queue, id, encoding, smtputf8,
|
||||||
sender, dsn_envid, dsn_ret, verp, callback, context);
|
sender, dsn_envid, dsn_ret, verp, callback, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* adefer_flush_verp - asynchronous defer flush */
|
/* 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)
|
ABOUNCE_FN callback, void *context)
|
||||||
{
|
{
|
||||||
flags |= BOUNCE_FLAG_DELRCPT;
|
flags |= BOUNCE_FLAG_DELRCPT;
|
||||||
abounce_request_verp(MAIL_CLASS_PRIVATE, var_defer_service,
|
abounce_connect(MAIL_CLASS_PRIVATE, var_defer_service,
|
||||||
BOUNCE_CMD_VERP, flags, queue, id, encoding, smtputf8,
|
BOUNCE_CMD_VERP, flags, queue, id, encoding, smtputf8,
|
||||||
sender, dsn_envid, dsn_ret, verp, callback, context);
|
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_flush - asynchronous bounce flush */
|
/* 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,
|
int dsn_ret, ABOUNCE_FN callback,
|
||||||
void *context)
|
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,
|
flags, queue, id, encoding, smtputf8, sender, dsn_envid,
|
||||||
dsn_ret, callback, context);
|
dsn_ret, ABOUNCE_NO_VERP, callback, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* adefer_flush - asynchronous defer flush */
|
/* 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)
|
int dsn_ret, ABOUNCE_FN callback, void *context)
|
||||||
{
|
{
|
||||||
flags |= BOUNCE_FLAG_DELRCPT;
|
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,
|
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 */
|
/* 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,
|
const char *sender, const char *dsn_envid,
|
||||||
int dsn_ret, ABOUNCE_FN callback, void *context)
|
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,
|
flags, queue, id, encoding, smtputf8, sender, dsn_envid,
|
||||||
dsn_ret, callback, context);
|
dsn_ret, ABOUNCE_NO_VERP, callback, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* atrace_flush - asynchronous trace flush */
|
/* 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,
|
const char *sender, const char *dsn_envid,
|
||||||
int dsn_ret, ABOUNCE_FN callback, void *context)
|
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,
|
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) \
|
#define ANVIL_IDENT(service, addr) \
|
||||||
printable(concatenate(service, ":", addr, (char *) 0), '?')
|
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_create - instantiate connection rate service client */
|
||||||
|
|
||||||
ANVIL_CLNT *anvil_clnt_create(void)
|
ANVIL_CLNT *anvil_clnt_create(void)
|
||||||
@ -186,6 +195,9 @@ ANVIL_CLNT *anvil_clnt_create(void)
|
|||||||
#else
|
#else
|
||||||
anvil_clnt = attr_clnt_create(var_anvil_service, var_ipc_timeout, 0, 0);
|
anvil_clnt = attr_clnt_create(var_anvil_service, var_ipc_timeout, 0, 0);
|
||||||
#endif
|
#endif
|
||||||
|
attr_clnt_control(anvil_clnt,
|
||||||
|
ATTR_CLNT_CTL_HANDSHAKE, anvil_clnt_handshake,
|
||||||
|
ATTR_CLNT_CTL_END);
|
||||||
return ((ANVIL_CLNT *) anvil_clnt);
|
return ((ANVIL_CLNT *) anvil_clnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,6 +186,11 @@
|
|||||||
/* IBM T.J. Watson Research
|
/* IBM T.J. Watson Research
|
||||||
/* P.O. Box 704
|
/* P.O. Box 704
|
||||||
/* Yorktown Heights, NY 10598, USA
|
/* Yorktown Heights, NY 10598, USA
|
||||||
|
/*
|
||||||
|
/* Wietse Venema
|
||||||
|
/* Google, Inc.
|
||||||
|
/* 111 8th Avenue
|
||||||
|
/* New York, NY 10011, USA
|
||||||
/*--*/
|
/*--*/
|
||||||
|
|
||||||
/* System library. */
|
/* 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 ?
|
if (mail_command_client(MAIL_CLASS_PRIVATE, var_soft_bounce ?
|
||||||
var_defer_service : var_bounce_service,
|
var_defer_service : var_bounce_service,
|
||||||
|
MAIL_ATTR_PROTO_BOUNCE,
|
||||||
SEND_ATTR_INT(MAIL_ATTR_NREQ, BOUNCE_CMD_APPEND),
|
SEND_ATTR_INT(MAIL_ATTR_NREQ, BOUNCE_CMD_APPEND),
|
||||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
|
SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
|
||||||
SEND_ATTR_STR(MAIL_ATTR_QUEUEID, id),
|
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)
|
if (var_soft_bounce)
|
||||||
return (-1);
|
return (-1);
|
||||||
if (mail_command_client(MAIL_CLASS_PRIVATE, var_bounce_service,
|
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_NREQ, BOUNCE_CMD_FLUSH),
|
||||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
|
SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
|
||||||
SEND_ATTR_STR(MAIL_ATTR_QUEUE, queue),
|
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)
|
if (var_soft_bounce)
|
||||||
return (-1);
|
return (-1);
|
||||||
if (mail_command_client(MAIL_CLASS_PRIVATE, var_bounce_service,
|
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_NREQ, BOUNCE_CMD_VERP),
|
||||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
|
SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
|
||||||
SEND_ATTR_STR(MAIL_ATTR_QUEUE, queue),
|
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";
|
my_dsn.action = "failed";
|
||||||
|
|
||||||
if (mail_command_client(MAIL_CLASS_PRIVATE, var_bounce_service,
|
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_NREQ, BOUNCE_CMD_ONE),
|
||||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
|
SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
|
||||||
SEND_ATTR_STR(MAIL_ATTR_QUEUE, queue),
|
SEND_ATTR_STR(MAIL_ATTR_QUEUE, queue),
|
||||||
|
@ -6,11 +6,15 @@
|
|||||||
/* SYNOPSIS
|
/* SYNOPSIS
|
||||||
/* #include <clnt_stream.h>
|
/* #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 *class;
|
||||||
/* const char *service;
|
/* const char *service;
|
||||||
/* int timeout;
|
/* int timeout;
|
||||||
/* int ttl;
|
/* int ttl;
|
||||||
|
/* CLNT_STREAM_HANDSHAKE_FN *handshake;
|
||||||
/*
|
/*
|
||||||
/* VSTREAM *clnt_stream_access(clnt_stream)
|
/* VSTREAM *clnt_stream_access(clnt_stream)
|
||||||
/* CLNT_STREAM *clnt_stream;
|
/* CLNT_STREAM *clnt_stream;
|
||||||
@ -33,6 +37,8 @@
|
|||||||
/*
|
/*
|
||||||
/* clnt_stream_access() returns an open stream to the service specified
|
/* clnt_stream_access() returns an open stream to the service specified
|
||||||
/* to clnt_stream_create(). The stream instance may change between calls.
|
/* 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
|
/* clnt_stream_recover() recovers from a server-initiated disconnect
|
||||||
/* that happened in the middle of an I/O operation.
|
/* that happened in the middle of an I/O operation.
|
||||||
@ -49,6 +55,10 @@
|
|||||||
/* Idle time after which the client disconnects.
|
/* Idle time after which the client disconnects.
|
||||||
/* .IP ttl
|
/* .IP ttl
|
||||||
/* Upper bound on the time that a connection is allowed to persist.
|
/* 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
|
/* DIAGNOSTICS
|
||||||
/* Warnings: communication failure. Fatal error: mail system is down,
|
/* Warnings: communication failure. Fatal error: mail system is down,
|
||||||
/* out of memory.
|
/* out of memory.
|
||||||
@ -63,6 +73,11 @@
|
|||||||
/* IBM T.J. Watson Research
|
/* IBM T.J. Watson Research
|
||||||
/* P.O. Box 704
|
/* P.O. Box 704
|
||||||
/* Yorktown Heights, NY 10598, USA
|
/* Yorktown Heights, NY 10598, USA
|
||||||
|
/*
|
||||||
|
/* Wietse Venema
|
||||||
|
/* Google, Inc.
|
||||||
|
/* 111 8th Avenue
|
||||||
|
/* New York, NY 10011, USA
|
||||||
/*--*/
|
/*--*/
|
||||||
|
|
||||||
/* System library. */
|
/* System library. */
|
||||||
@ -93,6 +108,7 @@ struct CLNT_STREAM {
|
|||||||
VSTREAM *vstream; /* buffered I/O */
|
VSTREAM *vstream; /* buffered I/O */
|
||||||
int timeout; /* time before client disconnect */
|
int timeout; /* time before client disconnect */
|
||||||
int ttl; /* time before client disconnect */
|
int ttl; /* time before client disconnect */
|
||||||
|
CLNT_STREAM_HANDSHAKE_FN handshake;
|
||||||
char *class; /* server class */
|
char *class; /* server class */
|
||||||
char *service; /* server name */
|
char *service; /* server name */
|
||||||
};
|
};
|
||||||
@ -205,6 +221,7 @@ void clnt_stream_recover(CLNT_STREAM *clnt_stream)
|
|||||||
|
|
||||||
VSTREAM *clnt_stream_access(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.
|
* 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) {
|
if (clnt_stream->vstream == 0) {
|
||||||
clnt_stream_open(clnt_stream);
|
clnt_stream_open(clnt_stream);
|
||||||
|
handshake = clnt_stream->handshake;
|
||||||
} else if (readable(vstream_fileno(clnt_stream->vstream))) {
|
} else if (readable(vstream_fileno(clnt_stream->vstream))) {
|
||||||
clnt_stream_close(clnt_stream);
|
clnt_stream_close(clnt_stream);
|
||||||
clnt_stream_open(clnt_stream);
|
clnt_stream_open(clnt_stream);
|
||||||
|
handshake = clnt_stream->handshake;
|
||||||
} else {
|
} else {
|
||||||
event_request_timer(clnt_stream_event, (void *) clnt_stream,
|
event_request_timer(clnt_stream_event, (void *) clnt_stream,
|
||||||
clnt_stream->timeout);
|
clnt_stream->timeout);
|
||||||
|
handshake = 0;
|
||||||
}
|
}
|
||||||
|
if (handshake != 0 && handshake(clnt_stream->vstream) != 0)
|
||||||
|
return (0);
|
||||||
return (clnt_stream->vstream);
|
return (clnt_stream->vstream);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clnt_stream_create - create client stream connection */
|
/* clnt_stream_create - create client stream connection */
|
||||||
|
|
||||||
CLNT_STREAM *clnt_stream_create(const char *class, const char *service,
|
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;
|
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->vstream = 0;
|
||||||
clnt_stream->timeout = timeout;
|
clnt_stream->timeout = timeout;
|
||||||
clnt_stream->ttl = ttl;
|
clnt_stream->ttl = ttl;
|
||||||
|
clnt_stream->handshake = handshake;
|
||||||
clnt_stream->class = mystrdup(class);
|
clnt_stream->class = mystrdup(class);
|
||||||
clnt_stream->service = mystrdup(service);
|
clnt_stream->service = mystrdup(service);
|
||||||
return (clnt_stream);
|
return (clnt_stream);
|
||||||
|
@ -20,9 +20,12 @@
|
|||||||
* External interface.
|
* External interface.
|
||||||
*/
|
*/
|
||||||
typedef struct CLNT_STREAM CLNT_STREAM;
|
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 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_recover(CLNT_STREAM *);
|
||||||
extern void clnt_stream_free(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
|
/* IBM T.J. Watson Research
|
||||||
/* P.O. Box 704
|
/* P.O. Box 704
|
||||||
/* Yorktown Heights, NY 10598, USA
|
/* Yorktown Heights, NY 10598, USA
|
||||||
|
/*
|
||||||
|
/* Wietse Venema
|
||||||
|
/* Google, Inc.
|
||||||
|
/* 111 8th Avenue
|
||||||
|
/* New York, NY 10011, USA
|
||||||
/*--*/
|
/*--*/
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -153,6 +153,11 @@
|
|||||||
/* IBM T.J. Watson Research
|
/* IBM T.J. Watson Research
|
||||||
/* P.O. Box 704
|
/* P.O. Box 704
|
||||||
/* Yorktown Heights, NY 10598, USA
|
/* Yorktown Heights, NY 10598, USA
|
||||||
|
/*
|
||||||
|
/* Wietse Venema
|
||||||
|
/* Google, Inc.
|
||||||
|
/* 111 8th Avenue
|
||||||
|
/* New York, NY 10011, USA
|
||||||
/*--*/
|
/*--*/
|
||||||
|
|
||||||
/* System library. */
|
/* System library. */
|
||||||
@ -257,6 +262,7 @@ int defer_append_intern(int flags, const char *id, MSG_STATS *stats,
|
|||||||
my_dsn.action = "delayed";
|
my_dsn.action = "delayed";
|
||||||
|
|
||||||
if (mail_command_client(MAIL_CLASS_PRIVATE, var_defer_service,
|
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_NREQ, BOUNCE_CMD_APPEND),
|
||||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
|
SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
|
||||||
SEND_ATTR_STR(MAIL_ATTR_QUEUEID, id),
|
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;
|
flags |= BOUNCE_FLAG_DELRCPT;
|
||||||
|
|
||||||
if (mail_command_client(MAIL_CLASS_PRIVATE, var_defer_service,
|
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_NREQ, BOUNCE_CMD_FLUSH),
|
||||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
|
SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
|
||||||
SEND_ATTR_STR(MAIL_ATTR_QUEUE, queue),
|
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)
|
const char *sender, const char *envid, int dsn_ret)
|
||||||
{
|
{
|
||||||
if (mail_command_client(MAIL_CLASS_PRIVATE, var_defer_service,
|
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_NREQ, BOUNCE_CMD_WARN),
|
||||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
|
SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
|
||||||
SEND_ATTR_STR(MAIL_ATTR_QUEUE, queue),
|
SEND_ATTR_STR(MAIL_ATTR_QUEUE, queue),
|
||||||
|
@ -49,6 +49,11 @@
|
|||||||
/* IBM T.J. Watson Research
|
/* IBM T.J. Watson Research
|
||||||
/* P.O. Box 704
|
/* P.O. Box 704
|
||||||
/* Yorktown Heights, NY 10598, USA
|
/* Yorktown Heights, NY 10598, USA
|
||||||
|
/*
|
||||||
|
/* Wietse Venema
|
||||||
|
/* Google, Inc.
|
||||||
|
/* 111 8th Avenue
|
||||||
|
/* New York, NY 10011, USA
|
||||||
/*--*/
|
/*--*/
|
||||||
|
|
||||||
/* System library. */
|
/* System library. */
|
||||||
@ -79,15 +84,13 @@
|
|||||||
|
|
||||||
static int deliver_pass_initial_reply(VSTREAM *stream)
|
static int deliver_pass_initial_reply(VSTREAM *stream)
|
||||||
{
|
{
|
||||||
int stat;
|
|
||||||
|
|
||||||
if (attr_scan(stream, ATTR_FLAG_STRICT,
|
if (attr_scan(stream, ATTR_FLAG_STRICT,
|
||||||
RECV_ATTR_INT(MAIL_ATTR_STATUS, &stat),
|
RECV_ATTR_STREQ(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_DELIVER),
|
||||||
ATTR_TYPE_END) != 1) {
|
ATTR_TYPE_END) != 0) {
|
||||||
msg_warn("%s: malformed response", VSTREAM_PATH(stream));
|
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 */
|
/* deliver_pass_send_request - send delivery request to delivery process */
|
||||||
|
@ -92,6 +92,11 @@
|
|||||||
/* IBM T.J. Watson Research
|
/* IBM T.J. Watson Research
|
||||||
/* P.O. Box 704
|
/* P.O. Box 704
|
||||||
/* Yorktown Heights, NY 10598, USA
|
/* Yorktown Heights, NY 10598, USA
|
||||||
|
/*
|
||||||
|
/* Wietse Venema
|
||||||
|
/* Google, Inc.
|
||||||
|
/* 111 8th Avenue
|
||||||
|
/* New York, NY 10011, USA
|
||||||
/*--*/
|
/*--*/
|
||||||
|
|
||||||
/* System library. */
|
/* System library. */
|
||||||
@ -135,13 +140,13 @@ static int deliver_request_initial(VSTREAM *stream)
|
|||||||
* delivery request; otherwise the queue manager could block in write().
|
* delivery request; otherwise the queue manager could block in write().
|
||||||
*/
|
*/
|
||||||
if (msg_verbose)
|
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,
|
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);
|
ATTR_TYPE_END);
|
||||||
if ((err = vstream_fflush(stream)) != 0)
|
if ((err = vstream_fflush(stream)) != 0)
|
||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
msg_warn("send initial status: %m");
|
msg_warn("send initial response: %m");
|
||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +41,11 @@
|
|||||||
/* IBM T.J. Watson Research
|
/* IBM T.J. Watson Research
|
||||||
/* P.O. Box 704
|
/* P.O. Box 704
|
||||||
/* Yorktown Heights, NY 10598, USA
|
/* Yorktown Heights, NY 10598, USA
|
||||||
|
/*
|
||||||
|
/* Wietse Venema
|
||||||
|
/* Google, Inc.
|
||||||
|
/* 111 8th Avenue
|
||||||
|
/* New York, NY 10011, USA
|
||||||
/*--*/
|
/*--*/
|
||||||
|
|
||||||
/* System library. */
|
/* System library. */
|
||||||
@ -89,6 +94,15 @@ typedef struct {
|
|||||||
static CLNT_STREAM *proxymap_stream; /* read-only maps */
|
static CLNT_STREAM *proxymap_stream; /* read-only maps */
|
||||||
static CLNT_STREAM *proxywrite_stream; /* read-write 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 */
|
/* dict_proxy_sequence - find first/next entry */
|
||||||
|
|
||||||
static int dict_proxy_sequence(DICT *dict, int function,
|
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);
|
stream = clnt_stream_access(dict_proxy->clnt);
|
||||||
errno = 0;
|
errno = 0;
|
||||||
count += 1;
|
count += 1;
|
||||||
if (attr_print(stream, ATTR_FLAG_NONE,
|
if (stream == 0
|
||||||
SEND_ATTR_STR(MAIL_ATTR_REQ, PROXY_REQ_SEQUENCE),
|
|| attr_print(stream, ATTR_FLAG_NONE,
|
||||||
SEND_ATTR_STR(MAIL_ATTR_TABLE, dict->name),
|
SEND_ATTR_STR(MAIL_ATTR_REQ, PROXY_REQ_SEQUENCE),
|
||||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, request_flags),
|
SEND_ATTR_STR(MAIL_ATTR_TABLE, dict->name),
|
||||||
SEND_ATTR_INT(MAIL_ATTR_FUNC, function),
|
SEND_ATTR_INT(MAIL_ATTR_FLAGS, request_flags),
|
||||||
ATTR_TYPE_END) != 0
|
SEND_ATTR_INT(MAIL_ATTR_FUNC, function),
|
||||||
|
ATTR_TYPE_END) != 0
|
||||||
|| vstream_fflush(stream)
|
|| vstream_fflush(stream)
|
||||||
|| attr_scan(stream, ATTR_FLAG_STRICT,
|
|| attr_scan(stream, ATTR_FLAG_STRICT,
|
||||||
RECV_ATTR_INT(MAIL_ATTR_STATUS, &status),
|
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),
|
RECV_ATTR_STR(MAIL_ATTR_VALUE, dict_proxy->result),
|
||||||
ATTR_TYPE_END) != 3) {
|
ATTR_TYPE_END) != 3) {
|
||||||
if (msg_verbose || count > 1 || (errno && errno != EPIPE && errno != ENOENT))
|
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 {
|
} else {
|
||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
msg_info("%s: table=%s flags=%s func=%d -> status=%d key=%s val=%s",
|
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);
|
stream = clnt_stream_access(dict_proxy->clnt);
|
||||||
errno = 0;
|
errno = 0;
|
||||||
count += 1;
|
count += 1;
|
||||||
if (attr_print(stream, ATTR_FLAG_NONE,
|
if (stream == 0
|
||||||
SEND_ATTR_STR(MAIL_ATTR_REQ, PROXY_REQ_LOOKUP),
|
|| attr_print(stream, ATTR_FLAG_NONE,
|
||||||
SEND_ATTR_STR(MAIL_ATTR_TABLE, dict->name),
|
SEND_ATTR_STR(MAIL_ATTR_REQ, PROXY_REQ_LOOKUP),
|
||||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, request_flags),
|
SEND_ATTR_STR(MAIL_ATTR_TABLE, dict->name),
|
||||||
SEND_ATTR_STR(MAIL_ATTR_KEY, key),
|
SEND_ATTR_INT(MAIL_ATTR_FLAGS, request_flags),
|
||||||
ATTR_TYPE_END) != 0
|
SEND_ATTR_STR(MAIL_ATTR_KEY, key),
|
||||||
|
ATTR_TYPE_END) != 0
|
||||||
|| vstream_fflush(stream)
|
|| vstream_fflush(stream)
|
||||||
|| attr_scan(stream, ATTR_FLAG_STRICT,
|
|| attr_scan(stream, ATTR_FLAG_STRICT,
|
||||||
RECV_ATTR_INT(MAIL_ATTR_STATUS, &status),
|
RECV_ATTR_INT(MAIL_ATTR_STATUS, &status),
|
||||||
RECV_ATTR_STR(MAIL_ATTR_VALUE, dict_proxy->result),
|
RECV_ATTR_STR(MAIL_ATTR_VALUE, dict_proxy->result),
|
||||||
ATTR_TYPE_END) != 2) {
|
ATTR_TYPE_END) != 2) {
|
||||||
if (msg_verbose || count > 1 || (errno && errno != EPIPE && errno != ENOENT))
|
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 {
|
} else {
|
||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
msg_info("%s: table=%s flags=%s key=%s -> status=%d result=%s",
|
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);
|
stream = clnt_stream_access(dict_proxy->clnt);
|
||||||
errno = 0;
|
errno = 0;
|
||||||
count += 1;
|
count += 1;
|
||||||
if (attr_print(stream, ATTR_FLAG_NONE,
|
if (stream == 0
|
||||||
SEND_ATTR_STR(MAIL_ATTR_REQ, PROXY_REQ_UPDATE),
|
|| attr_print(stream, ATTR_FLAG_NONE,
|
||||||
SEND_ATTR_STR(MAIL_ATTR_TABLE, dict->name),
|
SEND_ATTR_STR(MAIL_ATTR_REQ, PROXY_REQ_UPDATE),
|
||||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, request_flags),
|
SEND_ATTR_STR(MAIL_ATTR_TABLE, dict->name),
|
||||||
SEND_ATTR_STR(MAIL_ATTR_KEY, key),
|
SEND_ATTR_INT(MAIL_ATTR_FLAGS, request_flags),
|
||||||
SEND_ATTR_STR(MAIL_ATTR_VALUE, value),
|
SEND_ATTR_STR(MAIL_ATTR_KEY, key),
|
||||||
ATTR_TYPE_END) != 0
|
SEND_ATTR_STR(MAIL_ATTR_VALUE, value),
|
||||||
|
ATTR_TYPE_END) != 0
|
||||||
|| vstream_fflush(stream)
|
|| vstream_fflush(stream)
|
||||||
|| attr_scan(stream, ATTR_FLAG_STRICT,
|
|| attr_scan(stream, ATTR_FLAG_STRICT,
|
||||||
RECV_ATTR_INT(MAIL_ATTR_STATUS, &status),
|
RECV_ATTR_INT(MAIL_ATTR_STATUS, &status),
|
||||||
ATTR_TYPE_END) != 1) {
|
ATTR_TYPE_END) != 1) {
|
||||||
if (msg_verbose || count > 1 || (errno && errno != EPIPE && errno != ENOENT))
|
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 {
|
} else {
|
||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
msg_info("%s: table=%s flags=%s key=%s value=%s -> status=%d",
|
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);
|
stream = clnt_stream_access(dict_proxy->clnt);
|
||||||
errno = 0;
|
errno = 0;
|
||||||
count += 1;
|
count += 1;
|
||||||
if (attr_print(stream, ATTR_FLAG_NONE,
|
if (stream == 0
|
||||||
SEND_ATTR_STR(MAIL_ATTR_REQ, PROXY_REQ_DELETE),
|
|| attr_print(stream, ATTR_FLAG_NONE,
|
||||||
SEND_ATTR_STR(MAIL_ATTR_TABLE, dict->name),
|
SEND_ATTR_STR(MAIL_ATTR_REQ, PROXY_REQ_DELETE),
|
||||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, request_flags),
|
SEND_ATTR_STR(MAIL_ATTR_TABLE, dict->name),
|
||||||
SEND_ATTR_STR(MAIL_ATTR_KEY, key),
|
SEND_ATTR_INT(MAIL_ATTR_FLAGS, request_flags),
|
||||||
ATTR_TYPE_END) != 0
|
SEND_ATTR_STR(MAIL_ATTR_KEY, key),
|
||||||
|
ATTR_TYPE_END) != 0
|
||||||
|| vstream_fflush(stream)
|
|| vstream_fflush(stream)
|
||||||
|| attr_scan(stream, ATTR_FLAG_STRICT,
|
|| attr_scan(stream, ATTR_FLAG_STRICT,
|
||||||
RECV_ATTR_INT(MAIL_ATTR_STATUS, &status),
|
RECV_ATTR_INT(MAIL_ATTR_STATUS, &status),
|
||||||
ATTR_TYPE_END) != 1) {
|
ATTR_TYPE_END) != 1) {
|
||||||
if (msg_verbose || count > 1 || (errno && errno != EPIPE && errno !=
|
if (msg_verbose || count > 1 || (errno && errno != EPIPE && errno !=
|
||||||
ENOENT))
|
ENOENT))
|
||||||
msg_warn("%s: service %s: %m", myname, VSTREAM_PATH(stream));
|
msg_warn("%s: service %s: %m", myname, dict_proxy->service);
|
||||||
} else {
|
} else {
|
||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
msg_info("%s: table=%s flags=%s key=%s -> status=%d",
|
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, "/",
|
prefix = kludge = concatenate(var_queue_dir, "/",
|
||||||
MAIL_CLASS_PRIVATE, (char *) 0);
|
MAIL_CLASS_PRIVATE, (char *) 0);
|
||||||
*pstream = clnt_stream_create(prefix, service, var_ipc_idle_limit,
|
*pstream = clnt_stream_create(prefix, service, var_ipc_idle_limit,
|
||||||
var_ipc_ttl_limit);
|
var_ipc_ttl_limit,
|
||||||
|
dict_proxy_handshake);
|
||||||
if (kludge)
|
if (kludge)
|
||||||
myfree(kludge);
|
myfree(kludge);
|
||||||
myfree(relative_path);
|
myfree(relative_path);
|
||||||
@ -473,18 +492,19 @@ DICT *dict_proxy_open(const char *map, int open_flags, int dict_flags)
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
stream = clnt_stream_access(dict_proxy->clnt);
|
stream = clnt_stream_access(dict_proxy->clnt);
|
||||||
errno = 0;
|
errno = 0;
|
||||||
if (attr_print(stream, ATTR_FLAG_NONE,
|
if (stream == 0
|
||||||
SEND_ATTR_STR(MAIL_ATTR_REQ, PROXY_REQ_OPEN),
|
|| attr_print(stream, ATTR_FLAG_NONE,
|
||||||
SEND_ATTR_STR(MAIL_ATTR_TABLE, dict_proxy->dict.name),
|
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),
|
SEND_ATTR_INT(MAIL_ATTR_FLAGS, dict_proxy->inst_flags),
|
||||||
ATTR_TYPE_END) != 0
|
ATTR_TYPE_END) != 0
|
||||||
|| vstream_fflush(stream)
|
|| vstream_fflush(stream)
|
||||||
|| attr_scan(stream, ATTR_FLAG_STRICT,
|
|| attr_scan(stream, ATTR_FLAG_STRICT,
|
||||||
RECV_ATTR_INT(MAIL_ATTR_STATUS, &status),
|
RECV_ATTR_INT(MAIL_ATTR_STATUS, &status),
|
||||||
RECV_ATTR_INT(MAIL_ATTR_FLAGS, &server_flags),
|
RECV_ATTR_INT(MAIL_ATTR_FLAGS, &server_flags),
|
||||||
ATTR_TYPE_END) != 2) {
|
ATTR_TYPE_END) != 2) {
|
||||||
if (msg_verbose || (errno != EPIPE && errno != ENOENT))
|
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 {
|
} else {
|
||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
msg_info("%s: connect to map=%s status=%d server_flags=%s",
|
msg_info("%s: connect to map=%s status=%d server_flags=%s",
|
||||||
|
@ -71,6 +71,11 @@
|
|||||||
/* IBM T.J. Watson Research
|
/* IBM T.J. Watson Research
|
||||||
/* P.O. Box 704
|
/* P.O. Box 704
|
||||||
/* Yorktown Heights, NY 10598, USA
|
/* Yorktown Heights, NY 10598, USA
|
||||||
|
/*
|
||||||
|
/* Wietse Venema
|
||||||
|
/* Google, Inc.
|
||||||
|
/* 111 8th Avenue
|
||||||
|
/* New York, NY 10011, USA
|
||||||
/*--*/
|
/*--*/
|
||||||
|
|
||||||
/* System library. */
|
/* System library. */
|
||||||
@ -125,6 +130,7 @@ int flush_purge(void)
|
|||||||
status = FLUSH_STAT_DENY;
|
status = FLUSH_STAT_DENY;
|
||||||
else
|
else
|
||||||
status = mail_command_client(MAIL_CLASS_PUBLIC, var_flush_service,
|
status = mail_command_client(MAIL_CLASS_PUBLIC, var_flush_service,
|
||||||
|
MAIL_ATTR_PROTO_FLUSH,
|
||||||
SEND_ATTR_STR(MAIL_ATTR_REQ, FLUSH_REQ_PURGE),
|
SEND_ATTR_STR(MAIL_ATTR_REQ, FLUSH_REQ_PURGE),
|
||||||
ATTR_TYPE_END);
|
ATTR_TYPE_END);
|
||||||
|
|
||||||
@ -151,6 +157,7 @@ int flush_refresh(void)
|
|||||||
status = FLUSH_STAT_DENY;
|
status = FLUSH_STAT_DENY;
|
||||||
else
|
else
|
||||||
status = mail_command_client(MAIL_CLASS_PUBLIC, var_flush_service,
|
status = mail_command_client(MAIL_CLASS_PUBLIC, var_flush_service,
|
||||||
|
MAIL_ATTR_PROTO_FLUSH,
|
||||||
SEND_ATTR_STR(MAIL_ATTR_REQ, FLUSH_REQ_REFRESH),
|
SEND_ATTR_STR(MAIL_ATTR_REQ, FLUSH_REQ_REFRESH),
|
||||||
ATTR_TYPE_END);
|
ATTR_TYPE_END);
|
||||||
|
|
||||||
@ -182,6 +189,7 @@ int flush_send_site(const char *site)
|
|||||||
VAR_RELAY_DOMAINS "=$mydestination to flush "
|
VAR_RELAY_DOMAINS "=$mydestination to flush "
|
||||||
"mail for domain \"%s\"", site);
|
"mail for domain \"%s\"", site);
|
||||||
status = mail_command_client(MAIL_CLASS_PUBLIC, var_flush_service,
|
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_REQ, FLUSH_REQ_SEND_SITE),
|
||||||
SEND_ATTR_STR(MAIL_ATTR_SITE, site),
|
SEND_ATTR_STR(MAIL_ATTR_SITE, site),
|
||||||
ATTR_TYPE_END);
|
ATTR_TYPE_END);
|
||||||
@ -210,6 +218,7 @@ int flush_send_file(const char *queue_id)
|
|||||||
* Require that the service is turned on.
|
* Require that the service is turned on.
|
||||||
*/
|
*/
|
||||||
status = mail_command_client(MAIL_CLASS_PUBLIC, var_flush_service,
|
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_REQ, FLUSH_REQ_SEND_FILE),
|
||||||
SEND_ATTR_STR(MAIL_ATTR_QUEUEID, queue_id),
|
SEND_ATTR_STR(MAIL_ATTR_QUEUEID, queue_id),
|
||||||
ATTR_TYPE_END);
|
ATTR_TYPE_END);
|
||||||
@ -242,6 +251,7 @@ int flush_add(const char *site, const char *queue_id)
|
|||||||
VAR_RELAY_DOMAINS "=$mydestination to update "
|
VAR_RELAY_DOMAINS "=$mydestination to update "
|
||||||
"fast-flush logfile for domain \"%s\"", site);
|
"fast-flush logfile for domain \"%s\"", site);
|
||||||
status = mail_command_client(MAIL_CLASS_PUBLIC, var_flush_service,
|
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_REQ, FLUSH_REQ_ADD),
|
||||||
SEND_ATTR_STR(MAIL_ATTR_SITE, site),
|
SEND_ATTR_STR(MAIL_ATTR_SITE, site),
|
||||||
SEND_ATTR_STR(MAIL_ATTR_QUEUEID, queue_id),
|
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");
|
return ("unsupported network protocol");
|
||||||
}
|
}
|
||||||
/* For now, skip and ignore TLVs. */
|
/* For now, skip and ignore TLVs. */
|
||||||
*non_proxy = 0;
|
|
||||||
*str_len = PP2_HEADER_LEN + ntohs(hdr_v2->len);
|
*str_len = PP2_HEADER_LEN + ntohs(hdr_v2->len);
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
@ -434,6 +433,8 @@ const char *haproxy_srvr_parse(const char *str, ssize_t *str_len,
|
|||||||
if (proto_info == 0)
|
if (proto_info == 0)
|
||||||
proto_info = inet_proto_info();
|
proto_info = inet_proto_info();
|
||||||
|
|
||||||
|
*non_proxy = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX We don't accept connections with the "UNKNOWN" protocol type,
|
* XXX We don't accept connections with the "UNKNOWN" protocol type,
|
||||||
* because those would sidestep address-based access control mechanisms.
|
* 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);
|
myfree(saved_str);
|
||||||
|
|
||||||
*non_proxy = 0;
|
|
||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,9 +6,10 @@
|
|||||||
/* SYNOPSIS
|
/* SYNOPSIS
|
||||||
/* #include <mail_proto.h>
|
/* #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 *class;
|
||||||
/* const char *name;
|
/* const char *name;
|
||||||
|
/* const char *proto;
|
||||||
/* int type;
|
/* int type;
|
||||||
/* const char *attr;
|
/* const char *attr;
|
||||||
/* DESCRIPTION
|
/* DESCRIPTION
|
||||||
@ -21,6 +22,8 @@
|
|||||||
/* Service type: MAIL_CLASS_PUBLIC or MAIL_CLASS_PRIVATE
|
/* Service type: MAIL_CLASS_PUBLIC or MAIL_CLASS_PRIVATE
|
||||||
/* .IP name
|
/* .IP name
|
||||||
/* Service name (master.cf).
|
/* Service name (master.cf).
|
||||||
|
/* .IP proto
|
||||||
|
/* The expected protocol name in the server announcement.
|
||||||
/* .IP "type, attr, ..."
|
/* .IP "type, attr, ..."
|
||||||
/* Attribute information as defined in attr_print(3).
|
/* Attribute information as defined in attr_print(3).
|
||||||
/* DIAGNOSTICS
|
/* DIAGNOSTICS
|
||||||
@ -65,7 +68,8 @@
|
|||||||
|
|
||||||
/* mail_command_client - single-command transaction with completion status */
|
/* 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;
|
va_list ap;
|
||||||
VSTREAM *stream;
|
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);
|
msg_warn("connect to %s/%s: %m", class, name);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
va_start(ap, name);
|
if (attr_scan(stream, ATTR_FLAG_STRICT,
|
||||||
status = attr_vprint(stream, ATTR_FLAG_NONE, ap);
|
RECV_ATTR_STREQ(MAIL_ATTR_PROTO, proto),
|
||||||
va_end(ap);
|
ATTR_TYPE_END) != 0) {
|
||||||
if (status != 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));
|
msg_warn("write %s: %m", VSTREAM_PATH(stream));
|
||||||
status = -1;
|
status = -1;
|
||||||
} else if (attr_scan(stream, ATTR_FLAG_STRICT,
|
} 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));
|
msg_warn("write/read %s: %m", VSTREAM_PATH(stream));
|
||||||
status = -1;
|
status = -1;
|
||||||
}
|
}
|
||||||
|
@ -114,11 +114,32 @@
|
|||||||
*/
|
*/
|
||||||
extern VSTREAM *mail_connect(const char *, const char *, int);
|
extern VSTREAM *mail_connect(const char *, const char *, int);
|
||||||
extern VSTREAM *mail_connect_wait(const char *, const char *);
|
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_command_server(VSTREAM *,...);
|
||||||
extern int mail_trigger(const char *, const char *, const char *, ssize_t);
|
extern int mail_trigger(const char *, const char *, const char *, ssize_t);
|
||||||
extern char *mail_pathname(const char *, const char *);
|
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.
|
* Attribute names.
|
||||||
*/
|
*/
|
||||||
|
@ -105,6 +105,11 @@
|
|||||||
/* IBM T.J. Watson Research
|
/* IBM T.J. Watson Research
|
||||||
/* P.O. Box 704
|
/* P.O. Box 704
|
||||||
/* Yorktown Heights, NY 10598, USA
|
/* Yorktown Heights, NY 10598, USA
|
||||||
|
/*
|
||||||
|
/* Wietse Venema
|
||||||
|
/* Google, Inc.
|
||||||
|
/* 111 8th Avenue
|
||||||
|
/* New York, NY 10011, USA
|
||||||
/*--*/
|
/*--*/
|
||||||
|
|
||||||
/* System library. */
|
/* System library. */
|
||||||
@ -440,7 +445,8 @@ MAIL_STREAM *mail_stream_service(const char *class, const char *name)
|
|||||||
id_buf = vstring_alloc(10);
|
id_buf = vstring_alloc(10);
|
||||||
|
|
||||||
stream = mail_connect_wait(class, name);
|
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) {
|
RECV_ATTR_STR(MAIL_ATTR_QUEUEID, id_buf), 0) != 1) {
|
||||||
vstream_fclose(stream);
|
vstream_fclose(stream);
|
||||||
return (0);
|
return (0);
|
||||||
@ -492,7 +498,8 @@ MAIL_STREAM *mail_stream_command(const char *command)
|
|||||||
CA_VSTREAM_CTL_PATH(command),
|
CA_VSTREAM_CTL_PATH(command),
|
||||||
CA_VSTREAM_CTL_END);
|
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) {
|
RECV_ATTR_STR(MAIL_ATTR_QUEUEID, id_buf), 0) != 1) {
|
||||||
if ((status = vstream_pclose(stream)) != 0)
|
if ((status = vstream_pclose(stream)) != 0)
|
||||||
msg_warn("command \"%s\" exited with status %d", command, status);
|
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
|
* Patches change both the patchlevel and the release date. Snapshots have no
|
||||||
* patchlevel; they change the release date only.
|
* patchlevel; they change the release date only.
|
||||||
*/
|
*/
|
||||||
#define MAIL_RELEASE_DATE "20200830"
|
#define MAIL_RELEASE_DATE "20200920"
|
||||||
#define MAIL_VERSION_NUMBER "3.6"
|
#define MAIL_VERSION_NUMBER "3.6"
|
||||||
|
|
||||||
#ifdef SNAPSHOT
|
#ifdef SNAPSHOT
|
||||||
|
@ -231,8 +231,18 @@ static void post_mail_init(VSTREAM *stream, const char *sender,
|
|||||||
date = mail_date(now.tv_sec);
|
date = mail_date(now.tv_sec);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX Don't flush buffers while sending the initial message records.
|
* The comment in the next paragraph is likely obsolete. Fix 20030610
|
||||||
* That would cause deadlock between verify(8) and cleanup(8) servers.
|
* 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_control(stream, VSTREAM_CTL_BUFSIZE, 2 * VSTREAM_BUFSIZE,
|
||||||
VSTREAM_CTL_END);
|
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.
|
* Negotiate with the cleanup service. Give up if we can't agree.
|
||||||
*/
|
*/
|
||||||
if (attr_scan(stream, ATTR_FLAG_STRICT,
|
if (attr_scan(stream, ATTR_FLAG_STRICT,
|
||||||
|
RECV_ATTR_STREQ(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_CLEANUP),
|
||||||
RECV_ATTR_STR(MAIL_ATTR_QUEUEID, id),
|
RECV_ATTR_STR(MAIL_ATTR_QUEUEID, id),
|
||||||
ATTR_TYPE_END) != 1
|
ATTR_TYPE_END) != 1
|
||||||
|| attr_print(stream, ATTR_FLAG_NONE,
|
|| attr_print(stream, ATTR_FLAG_NONE,
|
||||||
|
@ -152,6 +152,15 @@ void resolve_clnt_init(RESOLVE_REPLY *reply)
|
|||||||
reply->flags = 0;
|
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) */
|
/* resolve_clnt - resolve address to (transport, next hop, recipient) */
|
||||||
|
|
||||||
void resolve_clnt(const char *class, const char *sender,
|
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,
|
rewrite_clnt_stream = clnt_stream_create(MAIL_CLASS_PRIVATE,
|
||||||
var_rewrite_service,
|
var_rewrite_service,
|
||||||
var_ipc_idle_limit,
|
var_ipc_idle_limit,
|
||||||
var_ipc_ttl_limit);
|
var_ipc_ttl_limit,
|
||||||
|
resolve_clnt_handshake);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
stream = clnt_stream_access(rewrite_clnt_stream);
|
stream = clnt_stream_access(rewrite_clnt_stream);
|
||||||
errno = 0;
|
errno = 0;
|
||||||
count += 1;
|
count += 1;
|
||||||
if (attr_print(stream, ATTR_FLAG_NONE,
|
if (stream == 0
|
||||||
SEND_ATTR_STR(MAIL_ATTR_REQ, class),
|
|| attr_print(stream, ATTR_FLAG_NONE,
|
||||||
SEND_ATTR_STR(MAIL_ATTR_SENDER, sender),
|
SEND_ATTR_STR(MAIL_ATTR_REQ, class),
|
||||||
SEND_ATTR_STR(MAIL_ATTR_ADDR, addr),
|
SEND_ATTR_STR(MAIL_ATTR_SENDER, sender),
|
||||||
ATTR_TYPE_END) != 0
|
SEND_ATTR_STR(MAIL_ATTR_ADDR, addr),
|
||||||
|
ATTR_TYPE_END) != 0
|
||||||
|| vstream_fflush(stream)
|
|| vstream_fflush(stream)
|
||||||
|| attr_scan(stream, ATTR_FLAG_STRICT,
|
|| attr_scan(stream, ATTR_FLAG_STRICT,
|
||||||
RECV_ATTR_INT(MAIL_ATTR_FLAGS, &server_flags),
|
RECV_ATTR_INT(MAIL_ATTR_FLAGS, &server_flags),
|
||||||
|
@ -39,6 +39,11 @@
|
|||||||
/* IBM T.J. Watson Research
|
/* IBM T.J. Watson Research
|
||||||
/* P.O. Box 704
|
/* P.O. Box 704
|
||||||
/* Yorktown Heights, NY 10598, USA
|
/* Yorktown Heights, NY 10598, USA
|
||||||
|
/*
|
||||||
|
/* Wietse Venema
|
||||||
|
/* Google, Inc.
|
||||||
|
/* 111 8th Avenue
|
||||||
|
/* New York, NY 10011, USA
|
||||||
/*--*/
|
/*--*/
|
||||||
|
|
||||||
/* System library. */
|
/* System library. */
|
||||||
@ -77,6 +82,15 @@ static VSTRING *last_rule;
|
|||||||
static VSTRING *last_addr;
|
static VSTRING *last_addr;
|
||||||
static VSTRING *last_result;
|
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) */
|
/* rewrite_clnt - rewrite address to (transport, next hop, recipient) */
|
||||||
|
|
||||||
VSTRING *rewrite_clnt(const char *rule, const char *addr, VSTRING *result)
|
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,
|
rewrite_clnt_stream = clnt_stream_create(MAIL_CLASS_PRIVATE,
|
||||||
var_rewrite_service,
|
var_rewrite_service,
|
||||||
var_ipc_idle_limit,
|
var_ipc_idle_limit,
|
||||||
var_ipc_ttl_limit);
|
var_ipc_ttl_limit,
|
||||||
|
rewrite_clnt_handshake);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
stream = clnt_stream_access(rewrite_clnt_stream);
|
stream = clnt_stream_access(rewrite_clnt_stream);
|
||||||
errno = 0;
|
errno = 0;
|
||||||
count += 1;
|
count += 1;
|
||||||
if (attr_print(stream, ATTR_FLAG_NONE,
|
if (stream == 0
|
||||||
SEND_ATTR_STR(MAIL_ATTR_REQ, REWRITE_ADDR),
|
|| attr_print(stream, ATTR_FLAG_NONE,
|
||||||
SEND_ATTR_STR(MAIL_ATTR_RULE, rule),
|
SEND_ATTR_STR(MAIL_ATTR_REQ, REWRITE_ADDR),
|
||||||
SEND_ATTR_STR(MAIL_ATTR_ADDR, addr),
|
SEND_ATTR_STR(MAIL_ATTR_RULE, rule),
|
||||||
ATTR_TYPE_END) != 0
|
SEND_ATTR_STR(MAIL_ATTR_ADDR, addr),
|
||||||
|
ATTR_TYPE_END) != 0
|
||||||
|| vstream_fflush(stream)
|
|| vstream_fflush(stream)
|
||||||
|| attr_scan(stream, ATTR_FLAG_STRICT,
|
|| attr_scan(stream, ATTR_FLAG_STRICT,
|
||||||
RECV_ATTR_INT(MAIL_ATTR_FLAGS, &server_flags),
|
RECV_ATTR_INT(MAIL_ATTR_FLAGS, &server_flags),
|
||||||
|
@ -68,7 +68,7 @@
|
|||||||
/* sasl_mech_filter - filter a SASL mechanism list */
|
/* sasl_mech_filter - filter a SASL mechanism list */
|
||||||
|
|
||||||
const char *sasl_mech_filter(STRING_LIST *filter,
|
const char *sasl_mech_filter(STRING_LIST *filter,
|
||||||
const const char *words)
|
const char *words)
|
||||||
{
|
{
|
||||||
const char myname[] = "sasl_mech_filter";
|
const char myname[] = "sasl_mech_filter";
|
||||||
static VSTRING *buf;
|
static VSTRING *buf;
|
||||||
|
@ -41,6 +41,11 @@
|
|||||||
/* IBM T.J. Watson Research
|
/* IBM T.J. Watson Research
|
||||||
/* P.O. Box 704
|
/* P.O. Box 704
|
||||||
/* Yorktown Heights, NY 10598, USA
|
/* Yorktown Heights, NY 10598, USA
|
||||||
|
/*
|
||||||
|
/* Wietse Venema
|
||||||
|
/* Google, Inc.
|
||||||
|
/* 111 8th Avenue
|
||||||
|
/* New York, NY 10011, USA
|
||||||
/*--*/
|
/*--*/
|
||||||
|
|
||||||
/* System library. */
|
/* System library. */
|
||||||
@ -80,6 +85,15 @@ typedef struct {
|
|||||||
|
|
||||||
#define SCACHE_MAX_TRIES 2
|
#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 */
|
/* scache_clnt_save_endp - save endpoint */
|
||||||
|
|
||||||
static void scache_clnt_save_endp(SCACHE *scache, int endp_ttl,
|
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->size = scache_clnt_size;
|
||||||
sp->scache->free = scache_clnt_free;
|
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);
|
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);
|
myfree(service);
|
||||||
|
|
||||||
#ifdef CANT_WRITE_BEFORE_SENDING_FD
|
#ifdef CANT_WRITE_BEFORE_SENDING_FD
|
||||||
|
@ -79,6 +79,11 @@
|
|||||||
/* IBM T.J. Watson Research
|
/* IBM T.J. Watson Research
|
||||||
/* P.O. Box 704
|
/* P.O. Box 704
|
||||||
/* Yorktown Heights, NY 10598, USA
|
/* Yorktown Heights, NY 10598, USA
|
||||||
|
/*
|
||||||
|
/* Wietse Venema
|
||||||
|
/* Google, Inc.
|
||||||
|
/* 111 8th Avenue
|
||||||
|
/* New York, NY 10011, USA
|
||||||
/*--*/
|
/*--*/
|
||||||
|
|
||||||
/* System library. */
|
/* System library. */
|
||||||
@ -121,6 +126,7 @@ int trace_append(int flags, const char *id, MSG_STATS *stats,
|
|||||||
my_dsn.reason = vstring_str(why);
|
my_dsn.reason = vstring_str(why);
|
||||||
|
|
||||||
if (mail_command_client(MAIL_CLASS_PRIVATE, var_trace_service,
|
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_NREQ, BOUNCE_CMD_APPEND),
|
||||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
|
SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
|
||||||
SEND_ATTR_STR(MAIL_ATTR_QUEUEID, id),
|
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)
|
const char *dsn_envid, int dsn_ret)
|
||||||
{
|
{
|
||||||
if (mail_command_client(MAIL_CLASS_PRIVATE, var_trace_service,
|
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_NREQ, BOUNCE_CMD_TRACE),
|
||||||
SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
|
SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
|
||||||
SEND_ATTR_STR(MAIL_ATTR_QUEUE, queue),
|
SEND_ATTR_STR(MAIL_ATTR_QUEUE, queue),
|
||||||
|
@ -56,6 +56,11 @@
|
|||||||
/* IBM T.J. Watson Research
|
/* IBM T.J. Watson Research
|
||||||
/* P.O. Box 704
|
/* P.O. Box 704
|
||||||
/* Yorktown Heights, NY 10598, USA
|
/* Yorktown Heights, NY 10598, USA
|
||||||
|
/*
|
||||||
|
/* Wietse Venema
|
||||||
|
/* Google, Inc.
|
||||||
|
/* 111 8th Avenue
|
||||||
|
/* New York, NY 10011, USA
|
||||||
/*--*/
|
/*--*/
|
||||||
|
|
||||||
/* System library. */
|
/* System library. */
|
||||||
@ -80,6 +85,15 @@
|
|||||||
|
|
||||||
CLNT_STREAM *vrfy_clnt;
|
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 */
|
/* verify_clnt_init - initialize */
|
||||||
|
|
||||||
static void verify_clnt_init(void)
|
static void verify_clnt_init(void)
|
||||||
@ -87,7 +101,8 @@ static void verify_clnt_init(void)
|
|||||||
if (vrfy_clnt != 0)
|
if (vrfy_clnt != 0)
|
||||||
msg_panic("verify_clnt_init: multiple initialization");
|
msg_panic("verify_clnt_init: multiple initialization");
|
||||||
vrfy_clnt = clnt_stream_create(MAIL_CLASS_PRIVATE, var_verify_service,
|
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 */
|
/* 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);
|
stream = clnt_stream_access(vrfy_clnt);
|
||||||
errno = 0;
|
errno = 0;
|
||||||
count += 1;
|
count += 1;
|
||||||
if (attr_print(stream, ATTR_FLAG_NONE,
|
if (stream == 0
|
||||||
SEND_ATTR_STR(MAIL_ATTR_REQ, VRFY_REQ_QUERY),
|
|| attr_print(stream, ATTR_FLAG_NONE,
|
||||||
SEND_ATTR_STR(MAIL_ATTR_ADDR, addr),
|
SEND_ATTR_STR(MAIL_ATTR_REQ, VRFY_REQ_QUERY),
|
||||||
ATTR_TYPE_END) != 0
|
SEND_ATTR_STR(MAIL_ATTR_ADDR, addr),
|
||||||
|
ATTR_TYPE_END) != 0
|
||||||
|| vstream_fflush(stream)
|
|| vstream_fflush(stream)
|
||||||
|| attr_scan(stream, ATTR_FLAG_MISSING,
|
|| attr_scan(stream, ATTR_FLAG_MISSING,
|
||||||
RECV_ATTR_INT(MAIL_ATTR_STATUS, &request_status),
|
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 (;;) {
|
for (;;) {
|
||||||
stream = clnt_stream_access(vrfy_clnt);
|
stream = clnt_stream_access(vrfy_clnt);
|
||||||
errno = 0;
|
errno = 0;
|
||||||
if (attr_print(stream, ATTR_FLAG_NONE,
|
if (stream == 0
|
||||||
SEND_ATTR_STR(MAIL_ATTR_REQ, VRFY_REQ_UPDATE),
|
|| attr_print(stream, ATTR_FLAG_NONE,
|
||||||
SEND_ATTR_STR(MAIL_ATTR_ADDR, addr),
|
SEND_ATTR_STR(MAIL_ATTR_REQ, VRFY_REQ_UPDATE),
|
||||||
SEND_ATTR_INT(MAIL_ATTR_ADDR_STATUS, addr_status),
|
SEND_ATTR_STR(MAIL_ATTR_ADDR, addr),
|
||||||
SEND_ATTR_STR(MAIL_ATTR_WHY, why),
|
SEND_ATTR_INT(MAIL_ATTR_ADDR_STATUS, addr_status),
|
||||||
ATTR_TYPE_END) != 0
|
SEND_ATTR_STR(MAIL_ATTR_WHY, why),
|
||||||
|
ATTR_TYPE_END) != 0
|
||||||
|| attr_scan(stream, ATTR_FLAG_MISSING,
|
|| attr_scan(stream, ATTR_FLAG_MISSING,
|
||||||
RECV_ATTR_INT(MAIL_ATTR_STATUS, &request_status),
|
RECV_ATTR_INT(MAIL_ATTR_STATUS, &request_status),
|
||||||
ATTR_TYPE_END) != 1) {
|
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);
|
close_on_exec(vstream_fileno(cleanup), CLOSE_ON_EXEC);
|
||||||
if (attr_scan(cleanup, ATTR_FLAG_STRICT,
|
if (attr_scan(cleanup, ATTR_FLAG_STRICT,
|
||||||
|
RECV_ATTR_STREQ(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_CLEANUP),
|
||||||
RECV_ATTR_STR(MAIL_ATTR_QUEUEID, buffer),
|
RECV_ATTR_STR(MAIL_ATTR_QUEUEID, buffer),
|
||||||
ATTR_TYPE_END) != 1) {
|
ATTR_TYPE_END) != 1) {
|
||||||
vstream_fclose(cleanup);
|
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_pre_disconn) (VSTREAM *, char *, char **);
|
||||||
static void (*event_server_slow_exit) (char *, char **);
|
static void (*event_server_slow_exit) (char *, char **);
|
||||||
static int event_server_watchdog = 1000;
|
static int event_server_watchdog = 1000;
|
||||||
static int event_server_saved_flags;
|
|
||||||
|
|
||||||
/* event_server_exit - normal termination */
|
/* 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)
|
static void event_server_execute(int unused_event, void *context)
|
||||||
{
|
{
|
||||||
VSTREAM *stream = (VSTREAM *) context;
|
VSTREAM *stream = (VSTREAM *) context;
|
||||||
HTABLE *attr = (vstream_flags(stream) == event_server_saved_flags ?
|
HTABLE *attr = (HTABLE *) vstream_context(stream);
|
||||||
(HTABLE *) vstream_context(stream) : 0);
|
|
||||||
|
|
||||||
if (event_server_lock != 0
|
if (event_server_lock != 0
|
||||||
&& myflock(vstream_fileno(event_server_lock), INTERNAL_LOCK,
|
&& 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);
|
CA_VSTREAM_CTL_END);
|
||||||
myfree(tmp);
|
myfree(tmp);
|
||||||
timed_ipc_setup(stream);
|
timed_ipc_setup(stream);
|
||||||
event_server_saved_flags = vstream_flags(stream);
|
|
||||||
if (event_server_in_flow_delay && mail_flow_get(1) < 0)
|
if (event_server_in_flow_delay && mail_flow_get(1) < 0)
|
||||||
event_request_timer(event_server_execute, (void *) stream,
|
event_request_timer(event_server_execute, (void *) stream,
|
||||||
var_in_flow_delay);
|
var_in_flow_delay);
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
* Utility library.
|
* Utility library.
|
||||||
*/
|
*/
|
||||||
#include <vstream.h>
|
#include <vstream.h>
|
||||||
|
#include <htable.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Global library.
|
* Global library.
|
||||||
@ -45,11 +46,13 @@
|
|||||||
#define MAIL_SERVER_SLOW_EXIT 21
|
#define MAIL_SERVER_SLOW_EXIT 21
|
||||||
#define MAIL_SERVER_BOUNCE_INIT 22
|
#define MAIL_SERVER_BOUNCE_INIT 22
|
||||||
#define MAIL_SERVER_RETIRE_ME 23
|
#define MAIL_SERVER_RETIRE_ME 23
|
||||||
|
#define MAIL_SERVER_POST_ACCEPT 24
|
||||||
|
|
||||||
typedef void (*MAIL_SERVER_INIT_FN) (char *, char **);
|
typedef void (*MAIL_SERVER_INIT_FN) (char *, char **);
|
||||||
typedef int (*MAIL_SERVER_LOOP_FN) (char *, char **);
|
typedef int (*MAIL_SERVER_LOOP_FN) (char *, char **);
|
||||||
typedef void (*MAIL_SERVER_EXIT_FN) (char *, char **);
|
typedef void (*MAIL_SERVER_EXIT_FN) (char *, char **);
|
||||||
typedef void (*MAIL_SERVER_ACCEPT_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_DISCONN_FN) (VSTREAM *, char *, char **);
|
||||||
typedef void (*MAIL_SERVER_SLOW_EXIT_FN) (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_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_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_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_SOLITARY MAIL_SERVER_SOLITARY
|
||||||
#define CA_MAIL_SERVER_UNLIMITED MAIL_SERVER_UNLIMITED
|
#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))
|
#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_EXIT_FN);
|
||||||
CHECK_VAL_HELPER_DCL(MAIL_SERVER, MAIL_SERVER_DISCONN_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_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, int);
|
||||||
CHECK_PTR_HELPER_DCL(MAIL_SERVER, char);
|
CHECK_PTR_HELPER_DCL(MAIL_SERVER, char);
|
||||||
CHECK_PPTR_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
|
/* function is run after the program has optionally dropped its
|
||||||
/* privileges. This function should not attempt to preserve state
|
/* privileges. This function should not attempt to preserve state
|
||||||
/* across calls. The stream initial state is non-blocking mode.
|
/* 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
|
/* The service name argument corresponds to the service name in the
|
||||||
/* master.cf file.
|
/* master.cf file.
|
||||||
/* The argv argument specifies command-line arguments left over
|
/* The argv argument specifies command-line arguments left over
|
||||||
@ -114,6 +111,14 @@
|
|||||||
/* Function to be executed prior to accepting a new connection.
|
/* Function to be executed prior to accepting a new connection.
|
||||||
/* .sp
|
/* .sp
|
||||||
/* Only the last instance of this parameter type is remembered.
|
/* 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)"
|
/* .IP "CA_MAIL_SERVER_PRE_DISCONN(VSTREAM *, char *service_name, char **argv)"
|
||||||
/* A pointer to a function that is called
|
/* A pointer to a function that is called
|
||||||
/* by the multi_server_disconnect() function (see below).
|
/* 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_accept) (int, void *);
|
||||||
static void (*multi_server_onexit) (char *, char **);
|
static void (*multi_server_onexit) (char *, char **);
|
||||||
static void (*multi_server_pre_accept) (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 VSTREAM *multi_server_lock;
|
||||||
static int multi_server_in_flow_delay;
|
static int multi_server_in_flow_delay;
|
||||||
static unsigned multi_server_generation;
|
static unsigned multi_server_generation;
|
||||||
static void (*multi_server_pre_disconn) (VSTREAM *, char *, char **);
|
static void (*multi_server_pre_disconn) (VSTREAM *, char *, char **);
|
||||||
static int multi_server_saved_flags;
|
|
||||||
|
|
||||||
/* multi_server_exit - normal termination */
|
/* 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)
|
static void multi_server_execute(int unused_event, void *context)
|
||||||
{
|
{
|
||||||
VSTREAM *stream = (VSTREAM *) context;
|
VSTREAM *stream = (VSTREAM *) context;
|
||||||
HTABLE *attr = (vstream_flags(stream) == multi_server_saved_flags ?
|
|
||||||
(HTABLE *) vstream_context(stream) : 0);
|
|
||||||
|
|
||||||
if (multi_server_lock != 0
|
if (multi_server_lock != 0
|
||||||
&& myflock(vstream_fileno(multi_server_lock), INTERNAL_LOCK,
|
&& myflock(vstream_fileno(multi_server_lock), INTERNAL_LOCK,
|
||||||
@ -358,8 +361,6 @@ static void multi_server_execute(int unused_event, void *context)
|
|||||||
} else {
|
} else {
|
||||||
multi_server_disconnect(stream);
|
multi_server_disconnect(stream);
|
||||||
}
|
}
|
||||||
if (attr)
|
|
||||||
htable_free(attr, myfree);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* multi_server_enable_read - enable read events */
|
/* 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);
|
tmp = concatenate(multi_server_name, " socket", (char *) 0);
|
||||||
vstream_control(stream,
|
vstream_control(stream,
|
||||||
CA_VSTREAM_CTL_PATH(tmp),
|
CA_VSTREAM_CTL_PATH(tmp),
|
||||||
CA_VSTREAM_CTL_CONTEXT((void *) attr),
|
|
||||||
CA_VSTREAM_CTL_END);
|
CA_VSTREAM_CTL_END);
|
||||||
myfree(tmp);
|
myfree(tmp);
|
||||||
timed_ipc_setup(stream);
|
timed_ipc_setup(stream);
|
||||||
multi_server_saved_flags = vstream_flags(stream);
|
|
||||||
if (multi_server_in_flow_delay && mail_flow_get(1) < 0)
|
if (multi_server_in_flow_delay && mail_flow_get(1) < 0)
|
||||||
event_request_timer(multi_server_enable_read, (void *) stream,
|
event_request_timer(multi_server_enable_read, (void *) stream,
|
||||||
var_in_flow_delay);
|
var_in_flow_delay);
|
||||||
else
|
else
|
||||||
multi_server_enable_read(0, (void *) stream);
|
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 */
|
/* 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:
|
case MAIL_SERVER_PRE_ACCEPT:
|
||||||
multi_server_pre_accept = va_arg(ap, MAIL_SERVER_ACCEPT_FN);
|
multi_server_pre_accept = va_arg(ap, MAIL_SERVER_ACCEPT_FN);
|
||||||
break;
|
break;
|
||||||
|
case MAIL_SERVER_POST_ACCEPT:
|
||||||
|
multi_server_post_accept = va_arg(ap, MAIL_SERVER_POST_ACCEPT_FN);
|
||||||
|
break;
|
||||||
case MAIL_SERVER_PRE_DISCONN:
|
case MAIL_SERVER_PRE_DISCONN:
|
||||||
multi_server_pre_disconn = va_arg(ap, MAIL_SERVER_DISCONN_FN);
|
multi_server_pre_disconn = va_arg(ap, MAIL_SERVER_DISCONN_FN);
|
||||||
break;
|
break;
|
||||||
|
@ -109,12 +109,12 @@ static int qmgr_deliver_initial_reply(VSTREAM *stream)
|
|||||||
msg_warn("%s: premature disconnect", VSTREAM_PATH(stream));
|
msg_warn("%s: premature disconnect", VSTREAM_PATH(stream));
|
||||||
return (DELIVER_STAT_CRASH);
|
return (DELIVER_STAT_CRASH);
|
||||||
} else if (attr_scan(stream, ATTR_FLAG_STRICT,
|
} else if (attr_scan(stream, ATTR_FLAG_STRICT,
|
||||||
RECV_ATTR_INT(MAIL_ATTR_STATUS, &stat),
|
RECV_ATTR_STREQ(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_DELIVER),
|
||||||
ATTR_TYPE_END) != 1) {
|
ATTR_TYPE_END) != 0) {
|
||||||
msg_warn("%s: malformed response", VSTREAM_PATH(stream));
|
msg_warn("%s: malformed response", VSTREAM_PATH(stream));
|
||||||
return (DELIVER_STAT_CRASH);
|
return (DELIVER_STAT_DEFER);
|
||||||
} else {
|
} 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);
|
cleanup = mail_connect_wait(MAIL_CLASS_PUBLIC, var_cleanup_service);
|
||||||
if (attr_scan(cleanup, ATTR_FLAG_STRICT,
|
if (attr_scan(cleanup, ATTR_FLAG_STRICT,
|
||||||
|
RECV_ATTR_STREQ(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_CLEANUP),
|
||||||
RECV_ATTR_STR(MAIL_ATTR_QUEUEID, buf),
|
RECV_ATTR_STR(MAIL_ATTR_QUEUEID, buf),
|
||||||
ATTR_TYPE_END) != 1
|
ATTR_TYPE_END) != 1
|
||||||
|| attr_print(cleanup, ATTR_FLAG_NONE,
|
|| 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
|
postconf_lookup.o postconf_match.o postconf_print.o
|
||||||
HDRS = postconf.h
|
HDRS = postconf.h
|
||||||
TESTSRC =
|
TESTSRC =
|
||||||
DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
|
DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE) -DLEGACY_DBMS_SUPPORT
|
||||||
CFLAGS = $(DEBUG) $(OPT) $(DEFS) -DLEGACY_DBMS_SUPPORT
|
CFLAGS = $(DEBUG) $(OPT) $(DEFS)
|
||||||
TESTPROG=
|
TESTPROG=
|
||||||
MAKES = bool_table.h bool_vars.h int_table.h int_vars.h str_table.h \
|
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 \
|
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,
|
dst = mail_stream_file(MAIL_QUEUE_MAILDROP, MAIL_CLASS_PUBLIC,
|
||||||
var_pickup_service, 0444);
|
var_pickup_service, 0444);
|
||||||
attr_print(VSTREAM_OUT, ATTR_FLAG_NONE,
|
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),
|
SEND_ATTR_STR(MAIL_ATTR_QUEUEID, dst->id),
|
||||||
ATTR_TYPE_END);
|
ATTR_TYPE_END);
|
||||||
vstream_fflush(VSTREAM_OUT);
|
vstream_fflush(VSTREAM_OUT);
|
||||||
|
@ -61,14 +61,19 @@ depend: $(MAKES)
|
|||||||
|
|
||||||
# do not edit below this line - it is generated by 'make depend'
|
# do not edit below this line - it is generated by 'make depend'
|
||||||
postlogd.o: ../../include/check_arg.h
|
postlogd.o: ../../include/check_arg.h
|
||||||
|
postlogd.o: ../../include/htable.h
|
||||||
postlogd.o: ../../include/logwriter.h
|
postlogd.o: ../../include/logwriter.h
|
||||||
postlogd.o: ../../include/mail_conf.h
|
postlogd.o: ../../include/mail_conf.h
|
||||||
postlogd.o: ../../include/mail_params.h
|
postlogd.o: ../../include/mail_params.h
|
||||||
postlogd.o: ../../include/mail_server.h
|
postlogd.o: ../../include/mail_server.h
|
||||||
|
postlogd.o: ../../include/mail_task.h
|
||||||
postlogd.o: ../../include/mail_version.h
|
postlogd.o: ../../include/mail_version.h
|
||||||
|
postlogd.o: ../../include/maillog_client.h
|
||||||
postlogd.o: ../../include/msg.h
|
postlogd.o: ../../include/msg.h
|
||||||
postlogd.o: ../../include/msg_logger.h
|
postlogd.o: ../../include/msg_logger.h
|
||||||
|
postlogd.o: ../../include/stringops.h
|
||||||
postlogd.o: ../../include/sys_defs.h
|
postlogd.o: ../../include/sys_defs.h
|
||||||
postlogd.o: ../../include/vbuf.h
|
postlogd.o: ../../include/vbuf.h
|
||||||
postlogd.o: ../../include/vstream.h
|
postlogd.o: ../../include/vstream.h
|
||||||
|
postlogd.o: ../../include/vstring.h
|
||||||
postlogd.o: postlogd.c
|
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,
|
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 */
|
/* show_queue - show queue status */
|
||||||
|
|
||||||
static void show_queue(int mode)
|
static void show_queue(int mode)
|
||||||
@ -361,16 +381,7 @@ static void show_queue(int mode)
|
|||||||
* Connect to the show queue service.
|
* Connect to the show queue service.
|
||||||
*/
|
*/
|
||||||
if ((showq = mail_connect(MAIL_CLASS_PUBLIC, var_showq_service, BLOCKING)) != 0) {
|
if ((showq = mail_connect(MAIL_CLASS_PUBLIC, var_showq_service, BLOCKING)) != 0) {
|
||||||
switch (mode) {
|
showq_client(mode, showq);
|
||||||
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);
|
|
||||||
}
|
|
||||||
if (vstream_fclose(showq))
|
if (vstream_fclose(showq))
|
||||||
msg_warn("close: %m");
|
msg_warn("close: %m");
|
||||||
}
|
}
|
||||||
@ -407,23 +418,14 @@ static void show_queue(int mode)
|
|||||||
CA_VSTREAM_POPEN_END)) == 0) {
|
CA_VSTREAM_POPEN_END)) == 0) {
|
||||||
stat = -1;
|
stat = -1;
|
||||||
} else {
|
} else {
|
||||||
switch (mode) {
|
showq_client(mode, showq);
|
||||||
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);
|
|
||||||
}
|
|
||||||
stat = vstream_pclose(showq);
|
stat = vstream_pclose(showq);
|
||||||
}
|
}
|
||||||
argv_free(argv);
|
argv_free(argv);
|
||||||
|
myfree(showq_path);
|
||||||
if (stat != 0)
|
if (stat != 0)
|
||||||
msg_fatal_status(stat < 0 ? EX_OSERR : EX_SOFTWARE,
|
msg_fatal_status(stat < 0 ? EX_OSERR : EX_SOFTWARE,
|
||||||
"Error running %s", showq_path);
|
"Error running %s", showq_path);
|
||||||
myfree(showq_path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -88,6 +88,22 @@ typedef struct {
|
|||||||
|
|
||||||
static char *psc_tlsp_service = 0;
|
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 */
|
/* psc_starttls_finish - complete negotiation with TLS proxy */
|
||||||
|
|
||||||
static void psc_starttls_finish(int event, void *context)
|
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
|
* The TLS proxy reports that the TLS engine is not available (due to
|
||||||
* configuration error, or other causes).
|
* configuration error, or other causes).
|
||||||
*/
|
*/
|
||||||
event_disable_readwrite(vstream_fileno(tlsproxy_stream));
|
msg_warn("%s receiving status from %s service",
|
||||||
vstream_fclose(tlsproxy_stream);
|
event == EVENT_TIME ? "timeout" : "problem", psc_tlsp_service);
|
||||||
PSC_SEND_REPLY(smtp_state,
|
PSC_SEND_REPLY(smtp_state,
|
||||||
"454 4.7.0 TLS not available due to local problem\r\n");
|
"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.
|
* Some error: drop the TLS proxy stream.
|
||||||
*/
|
*/
|
||||||
msg_warn("%s sending file handle to %s service",
|
msg_warn("problem sending file handle to %s service", psc_tlsp_service);
|
||||||
event == EVENT_TIME ? "timeout" : "problem",
|
|
||||||
psc_tlsp_service);
|
|
||||||
event_disable_readwrite(vstream_fileno(tlsproxy_stream));
|
|
||||||
vstream_fclose(tlsproxy_stream);
|
|
||||||
PSC_SEND_REPLY(smtp_state,
|
PSC_SEND_REPLY(smtp_state,
|
||||||
"454 4.7.0 TLS not available due to local problem\r\n");
|
"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");
|
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
|
* Swap the SMTP client stream and the TLS proxy stream, and close
|
||||||
* TLS handshake is done, the TLS proxy will deliver plaintext SMTP
|
* the direct connection to the SMTP client. The TLS proxy will talk
|
||||||
* commands to postscreen(8).
|
* 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
|
* Swap the file descriptors from under the VSTREAM so that we don't
|
||||||
* have to worry about loss of user-configurable VSTREAM attributes.
|
* 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,
|
vstream_control(smtp_state->smtp_client_stream,
|
||||||
CA_VSTREAM_CTL_SWAP_FD(tlsproxy_stream),
|
CA_VSTREAM_CTL_SWAP_FD(tlsproxy_stream),
|
||||||
CA_VSTREAM_CTL_END);
|
CA_VSTREAM_CTL_END);
|
||||||
vstream_fclose(tlsproxy_stream); /* direct-to-client stream! */
|
|
||||||
smtp_state->flags |= PSC_STATE_FLAG_USING_TLS;
|
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);
|
if (remote_endpt == 0)
|
||||||
myfree((void *) starttls_state);
|
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 */
|
/* 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;
|
PSC_STARTTLS *starttls_state;
|
||||||
VSTREAM *tlsproxy_stream;
|
VSTREAM *tlsproxy_stream;
|
||||||
int fd;
|
int fd;
|
||||||
static VSTRING *remote_endpt = 0;
|
|
||||||
|
|
||||||
if (psc_tlsp_service == 0) {
|
if (psc_tlsp_service == 0) {
|
||||||
psc_tlsp_service = concatenate(MAIL_CLASS_PRIVATE "/",
|
psc_tlsp_service = concatenate(MAIL_CLASS_PRIVATE "/",
|
||||||
var_tlsproxy_service, (char *) 0);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
if (msg_verbose)
|
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",
|
" for smtp socket %d from [%s]:%s flags=%s",
|
||||||
myname, fd, vstream_fileno(smtp_state->smtp_client_stream),
|
myname, fd, vstream_fileno(smtp_state->smtp_client_stream),
|
||||||
smtp_state->smtp_client_addr, smtp_state->smtp_client_port,
|
smtp_state->smtp_client_addr, smtp_state->smtp_client_port,
|
||||||
psc_print_state_flags(smtp_state->flags, myname));
|
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);
|
tlsproxy_stream = vstream_fdopen(fd, O_RDWR);
|
||||||
vstring_sprintf(remote_endpt, "[%s]:%s", smtp_state->smtp_client_addr,
|
vstream_control(tlsproxy_stream,
|
||||||
smtp_state->smtp_client_port);
|
VSTREAM_CTL_PATH, psc_tlsp_service,
|
||||||
attr_print(tlsproxy_stream, ATTR_FLAG_NONE,
|
VSTREAM_CTL_END);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up a read event for the next phase of the TLS proxy handshake.
|
* 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->tlsproxy_stream = tlsproxy_stream;
|
||||||
starttls_state->resume_event = resume_event;
|
starttls_state->resume_event = resume_event;
|
||||||
starttls_state->smtp_state = smtp_state;
|
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);
|
(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;
|
MAIL_VERSION_STAMP_DECLARE;
|
||||||
|
|
||||||
/* main - pass control to the multi-threaded skeleton */
|
/* 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_STR_TABLE(str_table),
|
||||||
CA_MAIL_SERVER_POST_INIT(post_jail_init),
|
CA_MAIL_SERVER_POST_INIT(post_jail_init),
|
||||||
CA_MAIL_SERVER_PRE_ACCEPT(pre_accept),
|
CA_MAIL_SERVER_PRE_ACCEPT(pre_accept),
|
||||||
|
CA_MAIL_SERVER_POST_ACCEPT(post_accept),
|
||||||
/* XXX CA_MAIL_SERVER_SOLITARY if proxywrite */
|
/* XXX CA_MAIL_SERVER_SOLITARY if proxywrite */
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
|
@ -108,18 +108,16 @@ int qmgr_deliver_concurrency;
|
|||||||
|
|
||||||
static int qmgr_deliver_initial_reply(VSTREAM *stream)
|
static int qmgr_deliver_initial_reply(VSTREAM *stream)
|
||||||
{
|
{
|
||||||
int stat;
|
|
||||||
|
|
||||||
if (peekfd(vstream_fileno(stream)) < 0) {
|
if (peekfd(vstream_fileno(stream)) < 0) {
|
||||||
msg_warn("%s: premature disconnect", VSTREAM_PATH(stream));
|
msg_warn("%s: premature disconnect", VSTREAM_PATH(stream));
|
||||||
return (DELIVER_STAT_CRASH);
|
return (DELIVER_STAT_CRASH);
|
||||||
} else if (attr_scan(stream, ATTR_FLAG_STRICT,
|
} else if (attr_scan(stream, ATTR_FLAG_STRICT,
|
||||||
RECV_ATTR_INT(MAIL_ATTR_STATUS, &stat),
|
RECV_ATTR_STREQ(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_DELIVER),
|
||||||
ATTR_TYPE_END) != 1) {
|
ATTR_TYPE_END) != 0) {
|
||||||
msg_warn("%s: malformed response", VSTREAM_PATH(stream));
|
msg_warn("%s: malformed response", VSTREAM_PATH(stream));
|
||||||
return (DELIVER_STAT_CRASH);
|
return (DELIVER_STAT_DEFER);
|
||||||
} else {
|
} 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_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;
|
MAIL_VERSION_STAMP_DECLARE;
|
||||||
|
|
||||||
/* main - pass control to the multi-threaded skeleton */
|
/* 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,
|
multi_server_main(argc, argv, scache_service,
|
||||||
CA_MAIL_SERVER_TIME_TABLE(time_table),
|
CA_MAIL_SERVER_TIME_TABLE(time_table),
|
||||||
CA_MAIL_SERVER_POST_INIT(post_jail_init),
|
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_EXIT(scache_status_dump),
|
||||||
CA_MAIL_SERVER_SOLITARY,
|
CA_MAIL_SERVER_SOLITARY,
|
||||||
0);
|
0);
|
||||||
|
@ -360,6 +360,13 @@ static void showq_service(VSTREAM *client, char *unused_service, char **argv)
|
|||||||
if (argv[0])
|
if (argv[0])
|
||||||
msg_fatal("unexpected command-line argument: %s", 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
|
* 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
|
* 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_proto.h
|
||||||
smtpd_chat.o: ../../include/mail_stream.h
|
smtpd_chat.o: ../../include/mail_stream.h
|
||||||
smtpd_chat.o: ../../include/maps.h
|
smtpd_chat.o: ../../include/maps.h
|
||||||
smtpd_chat.o: ../../include/match_list.h
|
|
||||||
smtpd_chat.o: ../../include/milter.h
|
smtpd_chat.o: ../../include/milter.h
|
||||||
smtpd_chat.o: ../../include/msg.h
|
smtpd_chat.o: ../../include/msg.h
|
||||||
smtpd_chat.o: ../../include/myaddrinfo.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/smtp_stream.h
|
||||||
smtpd_chat.o: ../../include/smtputf8.h
|
smtpd_chat.o: ../../include/smtputf8.h
|
||||||
smtpd_chat.o: ../../include/sock_addr.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/stringops.h
|
||||||
smtpd_chat.o: ../../include/sys_defs.h
|
smtpd_chat.o: ../../include/sys_defs.h
|
||||||
smtpd_chat.o: ../../include/tls.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_params.h
|
||||||
smtpd_expand.o: ../../include/mail_proto.h
|
smtpd_expand.o: ../../include/mail_proto.h
|
||||||
smtpd_expand.o: ../../include/mail_stream.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/milter.h
|
||||||
smtpd_expand.o: ../../include/msg.h
|
smtpd_expand.o: ../../include/msg.h
|
||||||
smtpd_expand.o: ../../include/myaddrinfo.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/name_mask.h
|
||||||
smtpd_expand.o: ../../include/nvtable.h
|
smtpd_expand.o: ../../include/nvtable.h
|
||||||
smtpd_expand.o: ../../include/sock_addr.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/stringops.h
|
||||||
smtpd_expand.o: ../../include/sys_defs.h
|
smtpd_expand.o: ../../include/sys_defs.h
|
||||||
smtpd_expand.o: ../../include/tls.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/iostuff.h
|
||||||
smtpd_haproxy.o: ../../include/mail_params.h
|
smtpd_haproxy.o: ../../include/mail_params.h
|
||||||
smtpd_haproxy.o: ../../include/mail_stream.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/milter.h
|
||||||
smtpd_haproxy.o: ../../include/msg.h
|
smtpd_haproxy.o: ../../include/msg.h
|
||||||
smtpd_haproxy.o: ../../include/myaddrinfo.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/nvtable.h
|
||||||
smtpd_haproxy.o: ../../include/smtp_stream.h
|
smtpd_haproxy.o: ../../include/smtp_stream.h
|
||||||
smtpd_haproxy.o: ../../include/sock_addr.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/stringops.h
|
||||||
smtpd_haproxy.o: ../../include/sys_defs.h
|
smtpd_haproxy.o: ../../include/sys_defs.h
|
||||||
smtpd_haproxy.o: ../../include/tls.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/htable.h
|
||||||
smtpd_milter.o: ../../include/mail_params.h
|
smtpd_milter.o: ../../include/mail_params.h
|
||||||
smtpd_milter.o: ../../include/mail_stream.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/milter.h
|
||||||
smtpd_milter.o: ../../include/myaddrinfo.h
|
smtpd_milter.o: ../../include/myaddrinfo.h
|
||||||
smtpd_milter.o: ../../include/mymalloc.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/resolve_clnt.h
|
||||||
smtpd_milter.o: ../../include/sock_addr.h
|
smtpd_milter.o: ../../include/sock_addr.h
|
||||||
smtpd_milter.o: ../../include/split_at.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/stringops.h
|
||||||
smtpd_milter.o: ../../include/sys_defs.h
|
smtpd_milter.o: ../../include/sys_defs.h
|
||||||
smtpd_milter.o: ../../include/tls.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_params.h
|
||||||
smtpd_peer.o: ../../include/mail_proto.h
|
smtpd_peer.o: ../../include/mail_proto.h
|
||||||
smtpd_peer.o: ../../include/mail_stream.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/milter.h
|
||||||
smtpd_peer.o: ../../include/msg.h
|
smtpd_peer.o: ../../include/msg.h
|
||||||
smtpd_peer.o: ../../include/myaddrinfo.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/nvtable.h
|
||||||
smtpd_peer.o: ../../include/sock_addr.h
|
smtpd_peer.o: ../../include/sock_addr.h
|
||||||
smtpd_peer.o: ../../include/split_at.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/stringops.h
|
||||||
smtpd_peer.o: ../../include/sys_defs.h
|
smtpd_peer.o: ../../include/sys_defs.h
|
||||||
smtpd_peer.o: ../../include/tls.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_proto.h
|
||||||
smtpd_proxy.o: ../../include/mail_queue.h
|
smtpd_proxy.o: ../../include/mail_queue.h
|
||||||
smtpd_proxy.o: ../../include/mail_stream.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/milter.h
|
||||||
smtpd_proxy.o: ../../include/msg.h
|
smtpd_proxy.o: ../../include/msg.h
|
||||||
smtpd_proxy.o: ../../include/myaddrinfo.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/record.h
|
||||||
smtpd_proxy.o: ../../include/smtp_stream.h
|
smtpd_proxy.o: ../../include/smtp_stream.h
|
||||||
smtpd_proxy.o: ../../include/sock_addr.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/stringops.h
|
||||||
smtpd_proxy.o: ../../include/sys_defs.h
|
smtpd_proxy.o: ../../include/sys_defs.h
|
||||||
smtpd_proxy.o: ../../include/tls.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_params.h
|
||||||
smtpd_sasl_proto.o: ../../include/mail_proto.h
|
smtpd_sasl_proto.o: ../../include/mail_proto.h
|
||||||
smtpd_sasl_proto.o: ../../include/mail_stream.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/milter.h
|
||||||
smtpd_sasl_proto.o: ../../include/msg.h
|
smtpd_sasl_proto.o: ../../include/msg.h
|
||||||
smtpd_sasl_proto.o: ../../include/myaddrinfo.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/name_mask.h
|
||||||
smtpd_sasl_proto.o: ../../include/nvtable.h
|
smtpd_sasl_proto.o: ../../include/nvtable.h
|
||||||
smtpd_sasl_proto.o: ../../include/sock_addr.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/stringops.h
|
||||||
smtpd_sasl_proto.o: ../../include/sys_defs.h
|
smtpd_sasl_proto.o: ../../include/sys_defs.h
|
||||||
smtpd_sasl_proto.o: ../../include/tls.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_params.h
|
||||||
smtpd_state.o: ../../include/mail_proto.h
|
smtpd_state.o: ../../include/mail_proto.h
|
||||||
smtpd_state.o: ../../include/mail_stream.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/milter.h
|
||||||
smtpd_state.o: ../../include/msg.h
|
smtpd_state.o: ../../include/msg.h
|
||||||
smtpd_state.o: ../../include/myaddrinfo.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/name_mask.h
|
||||||
smtpd_state.o: ../../include/nvtable.h
|
smtpd_state.o: ../../include/nvtable.h
|
||||||
smtpd_state.o: ../../include/sock_addr.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/sys_defs.h
|
||||||
smtpd_state.o: ../../include/tls.h
|
smtpd_state.o: ../../include/tls.h
|
||||||
smtpd_state.o: ../../include/vbuf.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/iostuff.h
|
||||||
smtpd_xforward.o: ../../include/mail_proto.h
|
smtpd_xforward.o: ../../include/mail_proto.h
|
||||||
smtpd_xforward.o: ../../include/mail_stream.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/milter.h
|
||||||
smtpd_xforward.o: ../../include/msg.h
|
smtpd_xforward.o: ../../include/msg.h
|
||||||
smtpd_xforward.o: ../../include/myaddrinfo.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/name_mask.h
|
||||||
smtpd_xforward.o: ../../include/nvtable.h
|
smtpd_xforward.o: ../../include/nvtable.h
|
||||||
smtpd_xforward.o: ../../include/sock_addr.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/sys_defs.h
|
||||||
smtpd_xforward.o: ../../include/tls.h
|
smtpd_xforward.o: ../../include/tls.h
|
||||||
smtpd_xforward.o: ../../include/vbuf.h
|
smtpd_xforward.o: ../../include/vbuf.h
|
||||||
|
@ -62,6 +62,7 @@ depend: $(MAKES)
|
|||||||
spawn.o: ../../include/argv.h
|
spawn.o: ../../include/argv.h
|
||||||
spawn.o: ../../include/check_arg.h
|
spawn.o: ../../include/check_arg.h
|
||||||
spawn.o: ../../include/dict.h
|
spawn.o: ../../include/dict.h
|
||||||
|
spawn.o: ../../include/htable.h
|
||||||
spawn.o: ../../include/mail_conf.h
|
spawn.o: ../../include/mail_conf.h
|
||||||
spawn.o: ../../include/mail_params.h
|
spawn.o: ../../include/mail_params.h
|
||||||
spawn.o: ../../include/mail_parm_split.h
|
spawn.o: ../../include/mail_parm_split.h
|
||||||
|
@ -107,6 +107,11 @@
|
|||||||
/* IBM T.J. Watson Research
|
/* IBM T.J. Watson Research
|
||||||
/* P.O. Box 704
|
/* P.O. Box 704
|
||||||
/* Yorktown Heights, NY 10598, USA
|
/* Yorktown Heights, NY 10598, USA
|
||||||
|
/*
|
||||||
|
/* Wietse Venema
|
||||||
|
/* Google, Inc.
|
||||||
|
/* 111 8th Avenue
|
||||||
|
/* New York, NY 10011, USA
|
||||||
/*--*/
|
/*--*/
|
||||||
|
|
||||||
/* System library. */
|
/* System library. */
|
||||||
@ -144,6 +149,15 @@
|
|||||||
|
|
||||||
static ATTR_CLNT *tls_mgr;
|
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 */
|
/* tls_mgr_open - create client handle */
|
||||||
|
|
||||||
static void tls_mgr_open(void)
|
static void tls_mgr_open(void)
|
||||||
@ -168,6 +182,7 @@ static void tls_mgr_open(void)
|
|||||||
|
|
||||||
attr_clnt_control(tls_mgr,
|
attr_clnt_control(tls_mgr,
|
||||||
ATTR_CLNT_CTL_PROTO, attr_vprint, attr_vscan,
|
ATTR_CLNT_CTL_PROTO, attr_vprint, attr_vscan,
|
||||||
|
ATTR_CLNT_CTL_HANDSHAKE, tls_mgr_handshake,
|
||||||
ATTR_CLNT_CTL_END);
|
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.
|
* remote peer file descriptor in a later transaction.
|
||||||
*/
|
*/
|
||||||
tlsproxy_stream = vstream_fdopen(fd, O_RDWR);
|
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);
|
vstring_sprintf(remote_endpt, "[%s]:%s", peer_addr, peer_port);
|
||||||
attr_print(tlsproxy_stream, ATTR_FLAG_NONE,
|
attr_print(tlsproxy_stream, ATTR_FLAG_NONE,
|
||||||
SEND_ATTR_STR(TLS_ATTR_REMOTE_ENDPT, STR(remote_endpt)),
|
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_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 */
|
/* tlsmgr_before_exit - save PRNG state before exit */
|
||||||
|
|
||||||
static void tlsmgr_before_exit(char *unused_service_name, char **unused_argv)
|
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_STR_TABLE(str_table),
|
||||||
CA_MAIL_SERVER_PRE_INIT(tlsmgr_pre_init),
|
CA_MAIL_SERVER_PRE_INIT(tlsmgr_pre_init),
|
||||||
CA_MAIL_SERVER_POST_INIT(tlsmgr_post_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_EXIT(tlsmgr_before_exit),
|
||||||
CA_MAIL_SERVER_LOOP(tlsmgr_loop),
|
CA_MAIL_SERVER_LOOP(tlsmgr_loop),
|
||||||
CA_MAIL_SERVER_SOLITARY,
|
CA_MAIL_SERVER_SOLITARY,
|
||||||
|
@ -1481,6 +1481,12 @@ static void tlsp_service(VSTREAM *plaintext_stream,
|
|||||||
CA_VSTREAM_CTL_TIMEOUT(5),
|
CA_VSTREAM_CTL_TIMEOUT(5),
|
||||||
CA_VSTREAM_CTL_END);
|
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.
|
* Receive postscreen's remote SMTP client address/port and socket.
|
||||||
*/
|
*/
|
||||||
|
@ -153,7 +153,7 @@
|
|||||||
/* matches subdomains of example.com,
|
/* matches subdomains of example.com,
|
||||||
/* instead of requiring an explicit ".example.com" pattern.
|
/* instead of requiring an explicit ".example.com" pattern.
|
||||||
/* .IP "\fBrelayhost (empty)\fR"
|
/* .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.
|
/* domains in recipient addresses.
|
||||||
/* .IP "\fBtransport_maps (empty)\fR"
|
/* .IP "\fBtransport_maps (empty)\fR"
|
||||||
/* Optional lookup tables with mappings from recipient address to
|
/* Optional lookup tables with mappings from recipient address to
|
||||||
@ -522,6 +522,21 @@ static void pre_accept(char *unused_name, char **unused_argv)
|
|||||||
|
|
||||||
#endif
|
#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)
|
static void check_table_stats(int unused_event, void *unused_context)
|
||||||
{
|
{
|
||||||
const char *table;
|
const char *table;
|
||||||
@ -648,5 +663,6 @@ int main(int argc, char **argv)
|
|||||||
#ifdef CHECK_TABLE_STATS_BEFORE_ACCEPT
|
#ifdef CHECK_TABLE_STATS_BEFORE_ACCEPT
|
||||||
CA_MAIL_SERVER_PRE_ACCEPT(pre_accept),
|
CA_MAIL_SERVER_PRE_ACCEPT(pre_accept),
|
||||||
#endif
|
#endif
|
||||||
|
CA_MAIL_SERVER_POST_ACCEPT(post_accept),
|
||||||
0);
|
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 \
|
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 \
|
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 \
|
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 \
|
readlline.c ring.c safe_getenv.c safe_open.c \
|
||||||
sane_accept.c sane_connect.c sane_link.c sane_rename.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 \
|
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 \
|
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 \
|
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 \
|
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 \
|
readlline.o ring.o safe_getenv.o safe_open.o \
|
||||||
sane_accept.o sane_connect.o sane_link.o sane_rename.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 \
|
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 \
|
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 \
|
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 \
|
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 \
|
safe.h safe_open.h sane_accept.h sane_connect.h sane_fsops.h \
|
||||||
load_lib.h \
|
load_lib.h \
|
||||||
sane_socketpair.h sane_time.h scan_dir.h set_eugid.h set_ugid.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: vstream.h
|
||||||
load_file.o: warn_stat.h
|
load_file.o: warn_stat.h
|
||||||
load_lib.o: load_lib.c
|
load_lib.o: load_lib.c
|
||||||
|
load_lib.o: load_lib.h
|
||||||
|
load_lib.o: msg.h
|
||||||
load_lib.o: sys_defs.h
|
load_lib.o: sys_defs.h
|
||||||
logwriter.o: check_arg.h
|
logwriter.o: check_arg.h
|
||||||
logwriter.o: iostuff.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_output.h
|
||||||
msg_output.o: msg_vstream.h
|
msg_output.o: msg_vstream.h
|
||||||
msg_output.o: mymalloc.h
|
msg_output.o: mymalloc.h
|
||||||
msg_output.o: percentm.h
|
|
||||||
msg_output.o: stringops.h
|
msg_output.o: stringops.h
|
||||||
msg_output.o: sys_defs.h
|
msg_output.o: sys_defs.h
|
||||||
msg_output.o: vbuf.h
|
msg_output.o: vbuf.h
|
||||||
@ -2220,12 +2221,6 @@ pass_trigger.o: trigger.h
|
|||||||
peekfd.o: iostuff.h
|
peekfd.o: iostuff.h
|
||||||
peekfd.o: peekfd.c
|
peekfd.o: peekfd.c
|
||||||
peekfd.o: sys_defs.h
|
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: iostuff.h
|
||||||
poll_fd.o: msg.h
|
poll_fd.o: msg.h
|
||||||
poll_fd.o: poll_fd.c
|
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_LONG 4 /* Unsigned long */
|
||||||
#define ATTR_TYPE_DATA 5 /* Binary data */
|
#define ATTR_TYPE_DATA 5 /* Binary data */
|
||||||
#define ATTR_TYPE_FUNC 6 /* Function pointer */
|
#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.
|
* 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_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_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_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_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))
|
#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_PRINT_FN) (VSTREAM *, int, va_list);
|
||||||
/* typedef int (*ATTR_CLNT_SCAN_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)
|
/* ATTR_CLNT *attr_clnt_create(server, timeout, max_idle, max_ttl)
|
||||||
/* const char *server;
|
/* const char *server;
|
||||||
@ -65,6 +66,9 @@
|
|||||||
/* .IP "ATTR_CLNT_CTL_TRY_DELAY(int)"
|
/* .IP "ATTR_CLNT_CTL_TRY_DELAY(int)"
|
||||||
/* The time in seconds between attempts to send a request
|
/* The time in seconds between attempts to send a request
|
||||||
/* (default: 1). Specify a value greater than zero.
|
/* (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
|
/* DIAGNOSTICS
|
||||||
/* Warnings: communication failure.
|
/* Warnings: communication failure.
|
||||||
/* SEE ALSO
|
/* SEE ALSO
|
||||||
@ -80,6 +84,11 @@
|
|||||||
/* IBM T.J. Watson Research
|
/* IBM T.J. Watson Research
|
||||||
/* P.O. Box 704
|
/* P.O. Box 704
|
||||||
/* Yorktown Heights, NY 10598, USA
|
/* Yorktown Heights, NY 10598, USA
|
||||||
|
/*
|
||||||
|
/* Wietse Venema
|
||||||
|
/* Google, Inc.
|
||||||
|
/* 111 8th Avenue
|
||||||
|
/* New York, NY 10011, USA
|
||||||
/*--*/
|
/*--*/
|
||||||
|
|
||||||
/* System library. */
|
/* 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->print = va_arg(ap, ATTR_CLNT_PRINT_FN);
|
||||||
client->scan = va_arg(ap, ATTR_CLNT_SCAN_FN);
|
client->scan = va_arg(ap, ATTR_CLNT_SCAN_FN);
|
||||||
break;
|
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:
|
case ATTR_CLNT_CTL_REQ_LIMIT:
|
||||||
client->req_limit = va_arg(ap, int);
|
client->req_limit = va_arg(ap, int);
|
||||||
if (client->req_limit < 0)
|
if (client->req_limit < 0)
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
typedef struct ATTR_CLNT ATTR_CLNT;
|
typedef struct ATTR_CLNT ATTR_CLNT;
|
||||||
typedef int (*ATTR_CLNT_PRINT_FN) (VSTREAM *, int, va_list);
|
typedef int (*ATTR_CLNT_PRINT_FN) (VSTREAM *, int, va_list);
|
||||||
typedef int (*ATTR_CLNT_SCAN_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 ATTR_CLNT *attr_clnt_create(const char *, int, int, int);
|
||||||
extern int attr_clnt_request(ATTR_CLNT *, 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_REQ_LIMIT 2 /* requests per connection */
|
||||||
#define ATTR_CLNT_CTL_TRY_LIMIT 3 /* attempts per request */
|
#define ATTR_CLNT_CTL_TRY_LIMIT 3 /* attempts per request */
|
||||||
#define ATTR_CLNT_CTL_TRY_DELAY 4 /* pause between requests */
|
#define ATTR_CLNT_CTL_TRY_DELAY 4 /* pause between requests */
|
||||||
|
#define ATTR_CLNT_CTL_HANDSHAKE 5 /* handshake before first request */
|
||||||
|
|
||||||
/* LICENSE
|
/* LICENSE
|
||||||
/* .ad
|
/* .ad
|
||||||
@ -48,6 +50,11 @@ extern void attr_clnt_control(ATTR_CLNT *, int,...);
|
|||||||
/* IBM T.J. Watson Research
|
/* IBM T.J. Watson Research
|
||||||
/* P.O. Box 704
|
/* P.O. Box 704
|
||||||
/* Yorktown Heights, NY 10598, USA
|
/* Yorktown Heights, NY 10598, USA
|
||||||
|
/*
|
||||||
|
/* Wietse Venema
|
||||||
|
/* Google, Inc.
|
||||||
|
/* 111 8th Avenue
|
||||||
|
/* New York, NY 10011, USA
|
||||||
/*--*/
|
/*--*/
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -228,6 +228,7 @@ int main(int unused_argc, char **argv)
|
|||||||
htable_enter(table, "foo-name", mystrdup("foo-value"));
|
htable_enter(table, "foo-name", mystrdup("foo-value"));
|
||||||
htable_enter(table, "bar-name", mystrdup("bar-value"));
|
htable_enter(table, "bar-name", mystrdup("bar-value"));
|
||||||
attr_print0(VSTREAM_OUT, ATTR_FLAG_NONE,
|
attr_print0(VSTREAM_OUT, ATTR_FLAG_NONE,
|
||||||
|
SEND_ATTR_STR("protocol", "test"),
|
||||||
SEND_ATTR_INT(ATTR_NAME_INT, 4711),
|
SEND_ATTR_INT(ATTR_NAME_INT, 4711),
|
||||||
SEND_ATTR_LONG(ATTR_NAME_LONG, 1234L),
|
SEND_ATTR_LONG(ATTR_NAME_LONG, 1234L),
|
||||||
SEND_ATTR_STR(ATTR_NAME_STR, "whoopee"),
|
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),
|
SEND_ATTR_LONG(ATTR_NAME_LONG, 4321L),
|
||||||
ATTR_TYPE_END);
|
ATTR_TYPE_END);
|
||||||
attr_print0(VSTREAM_OUT, ATTR_FLAG_NONE,
|
attr_print0(VSTREAM_OUT, ATTR_FLAG_NONE,
|
||||||
|
SEND_ATTR_STR("protocol", "test"),
|
||||||
SEND_ATTR_INT(ATTR_NAME_INT, 4711),
|
SEND_ATTR_INT(ATTR_NAME_INT, 4711),
|
||||||
SEND_ATTR_LONG(ATTR_NAME_LONG, 1234L),
|
SEND_ATTR_LONG(ATTR_NAME_LONG, 1234L),
|
||||||
SEND_ATTR_STR(ATTR_NAME_STR, "whoopee"),
|
SEND_ATTR_STR(ATTR_NAME_STR, "whoopee"),
|
||||||
SEND_ATTR_DATA(ATTR_NAME_DATA, strlen("whoopee"), "whoopee"),
|
SEND_ATTR_DATA(ATTR_NAME_DATA, strlen("whoopee"), "whoopee"),
|
||||||
ATTR_TYPE_END);
|
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)
|
if (vstream_fflush(VSTREAM_OUT) != 0)
|
||||||
msg_fatal("write error: %m");
|
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, "foo-name", mystrdup("foo-value"));
|
||||||
htable_enter(table, "bar-name", mystrdup("bar-value"));
|
htable_enter(table, "bar-name", mystrdup("bar-value"));
|
||||||
attr_print64(VSTREAM_OUT, ATTR_FLAG_NONE,
|
attr_print64(VSTREAM_OUT, ATTR_FLAG_NONE,
|
||||||
|
SEND_ATTR_STR("protocol", "test"),
|
||||||
SEND_ATTR_INT(ATTR_NAME_INT, 4711),
|
SEND_ATTR_INT(ATTR_NAME_INT, 4711),
|
||||||
SEND_ATTR_LONG(ATTR_NAME_LONG, 1234L),
|
SEND_ATTR_LONG(ATTR_NAME_LONG, 1234L),
|
||||||
SEND_ATTR_STR(ATTR_NAME_STR, "whoopee"),
|
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),
|
SEND_ATTR_LONG(ATTR_NAME_LONG, 4321L),
|
||||||
ATTR_TYPE_END);
|
ATTR_TYPE_END);
|
||||||
attr_print64(VSTREAM_OUT, ATTR_FLAG_NONE,
|
attr_print64(VSTREAM_OUT, ATTR_FLAG_NONE,
|
||||||
|
SEND_ATTR_STR("protocol", "test"),
|
||||||
SEND_ATTR_INT(ATTR_NAME_INT, 4711),
|
SEND_ATTR_INT(ATTR_NAME_INT, 4711),
|
||||||
SEND_ATTR_LONG(ATTR_NAME_LONG, 1234L),
|
SEND_ATTR_LONG(ATTR_NAME_LONG, 1234L),
|
||||||
SEND_ATTR_STR(ATTR_NAME_STR, "whoopee"),
|
SEND_ATTR_STR(ATTR_NAME_STR, "whoopee"),
|
||||||
SEND_ATTR_DATA(ATTR_NAME_DATA, strlen("whoopee"), "whoopee"),
|
SEND_ATTR_DATA(ATTR_NAME_DATA, strlen("whoopee"), "whoopee"),
|
||||||
ATTR_TYPE_END);
|
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)
|
if (vstream_fflush(VSTREAM_OUT) != 0)
|
||||||
msg_fatal("write error: %m");
|
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, "foo-name", mystrdup("foo-value"));
|
||||||
htable_enter(table, "bar-name", mystrdup("bar-value"));
|
htable_enter(table, "bar-name", mystrdup("bar-value"));
|
||||||
attr_print_plain(VSTREAM_OUT, ATTR_FLAG_NONE,
|
attr_print_plain(VSTREAM_OUT, ATTR_FLAG_NONE,
|
||||||
|
SEND_ATTR_STR("protocol", "test"),
|
||||||
SEND_ATTR_INT(ATTR_NAME_INT, 4711),
|
SEND_ATTR_INT(ATTR_NAME_INT, 4711),
|
||||||
SEND_ATTR_LONG(ATTR_NAME_LONG, 1234L),
|
SEND_ATTR_LONG(ATTR_NAME_LONG, 1234L),
|
||||||
SEND_ATTR_STR(ATTR_NAME_STR, "whoopee"),
|
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),
|
SEND_ATTR_LONG(ATTR_NAME_LONG, 4321L),
|
||||||
ATTR_TYPE_END);
|
ATTR_TYPE_END);
|
||||||
attr_print_plain(VSTREAM_OUT, ATTR_FLAG_NONE,
|
attr_print_plain(VSTREAM_OUT, ATTR_FLAG_NONE,
|
||||||
|
SEND_ATTR_STR("protocol", "test"),
|
||||||
SEND_ATTR_INT(ATTR_NAME_INT, 4711),
|
SEND_ATTR_INT(ATTR_NAME_INT, 4711),
|
||||||
SEND_ATTR_LONG(ATTR_NAME_LONG, 1234L),
|
SEND_ATTR_LONG(ATTR_NAME_LONG, 1234L),
|
||||||
SEND_ATTR_STR(ATTR_NAME_STR, "whoopee"),
|
SEND_ATTR_STR(ATTR_NAME_STR, "whoopee"),
|
||||||
SEND_ATTR_DATA(ATTR_NAME_DATA, strlen("whoopee"), "whoopee"),
|
SEND_ATTR_DATA(ATTR_NAME_DATA, strlen("whoopee"), "whoopee"),
|
||||||
ATTR_TYPE_END);
|
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)
|
if (vstream_fflush(VSTREAM_OUT) != 0)
|
||||||
msg_fatal("write error: %m");
|
msg_fatal("write error: %m");
|
||||||
|
|
||||||
|
@ -100,6 +100,9 @@
|
|||||||
/* This argument is followed by an attribute name and a long pointer.
|
/* This argument is followed by an attribute name and a long pointer.
|
||||||
/* .IP "RECV_ATTR_STR(const char *name, VSTRING *vp)"
|
/* .IP "RECV_ATTR_STR(const char *name, VSTRING *vp)"
|
||||||
/* This argument is followed by an attribute name and a VSTRING pointer.
|
/* 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)"
|
/* .IP "RECV_ATTR_DATA(const char *name, VSTRING *vp)"
|
||||||
/* This argument is followed by an attribute name and a VSTRING pointer.
|
/* This argument is followed by an attribute name and a VSTRING pointer.
|
||||||
/* .IP "RECV_ATTR_FUNC(ATTR_SCAN_CUSTOM_FN, void *data)"
|
/* .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;
|
int conversions;
|
||||||
ATTR_SCAN_CUSTOM_FN scan_fn;
|
ATTR_SCAN_CUSTOM_FN scan_fn;
|
||||||
void *scan_arg;
|
void *scan_arg;
|
||||||
|
const char *expect_val;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sanity check.
|
* 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)
|
if (scan_fn(attr_scan0, fp, flags | ATTR_FLAG_MORE, scan_arg) < 0)
|
||||||
return (-1);
|
return (-1);
|
||||||
break;
|
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_HASH:
|
||||||
case ATTR_TYPE_CLOSE:
|
case ATTR_TYPE_CLOSE:
|
||||||
if ((ch = attr_scan0_string(fp, str_buf,
|
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);
|
msg_vstream_init(used_argv[0], VSTREAM_ERR);
|
||||||
if ((ret = attr_scan0(VSTREAM_IN,
|
if ((ret = attr_scan0(VSTREAM_IN,
|
||||||
ATTR_FLAG_STRICT,
|
ATTR_FLAG_STRICT,
|
||||||
|
RECV_ATTR_STREQ("protocol", "test"),
|
||||||
RECV_ATTR_INT(ATTR_NAME_INT, &int_val),
|
RECV_ATTR_INT(ATTR_NAME_INT, &int_val),
|
||||||
RECV_ATTR_LONG(ATTR_NAME_LONG, &long_val),
|
RECV_ATTR_LONG(ATTR_NAME_LONG, &long_val),
|
||||||
RECV_ATTR_STR(ATTR_NAME_STR, str_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,
|
if ((ret = attr_scan0(VSTREAM_IN,
|
||||||
ATTR_FLAG_STRICT,
|
ATTR_FLAG_STRICT,
|
||||||
|
RECV_ATTR_STREQ("protocol", "test"),
|
||||||
RECV_ATTR_INT(ATTR_NAME_INT, &int_val),
|
RECV_ATTR_INT(ATTR_NAME_INT, &int_val),
|
||||||
RECV_ATTR_LONG(ATTR_NAME_LONG, &long_val),
|
RECV_ATTR_LONG(ATTR_NAME_LONG, &long_val),
|
||||||
RECV_ATTR_STR(ATTR_NAME_STR, str_val),
|
RECV_ATTR_STR(ATTR_NAME_STR, str_val),
|
||||||
@ -550,6 +569,11 @@ int main(int unused_argc, char **used_argv)
|
|||||||
} else {
|
} else {
|
||||||
vstream_printf("return: %d\n", ret);
|
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)
|
if (vstream_fflush(VSTREAM_OUT) != 0)
|
||||||
msg_fatal("write error: %m");
|
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 number = 4711
|
||||||
./attr_print0: send attr long_number = 1234
|
./attr_print0: send attr long_number = 1234
|
||||||
./attr_print0: send attr string = whoopee
|
./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 foo-name value foo-value
|
||||||
./attr_print0: send attr name bar-name value bar-value
|
./attr_print0: send attr name bar-name value bar-value
|
||||||
./attr_print0: send attr long_number = 4321
|
./attr_print0: send attr long_number = 4321
|
||||||
|
./attr_print0: send attr protocol = test
|
||||||
./attr_print0: send attr number = 4711
|
./attr_print0: send attr number = 4711
|
||||||
./attr_print0: send attr long_number = 1234
|
./attr_print0: send attr long_number = 1234
|
||||||
./attr_print0: send attr string = whoopee
|
./attr_print0: send attr string = whoopee
|
||||||
./attr_print0: send attr data = [data 7 bytes]
|
./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: unknown_stream: wanted attribute: number
|
||||||
./attr_scan0: input attribute name: number
|
./attr_scan0: input attribute name: number
|
||||||
./attr_scan0: input attribute value: 4711
|
./attr_scan0: input attribute value: 4711
|
||||||
@ -36,6 +42,9 @@
|
|||||||
./attr_scan0: input attribute value: 4321
|
./attr_scan0: input attribute value: 4321
|
||||||
./attr_scan0: unknown_stream: wanted attribute: (list terminator)
|
./attr_scan0: unknown_stream: wanted attribute: (list terminator)
|
||||||
./attr_scan0: input attribute name: (end)
|
./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: unknown_stream: wanted attribute: number
|
||||||
./attr_scan0: input attribute name: number
|
./attr_scan0: input attribute name: number
|
||||||
./attr_scan0: input attribute value: 4711
|
./attr_scan0: input attribute value: 4711
|
||||||
@ -50,6 +59,10 @@
|
|||||||
./attr_scan0: input attribute value: d2hvb3BlZQ==
|
./attr_scan0: input attribute value: d2hvb3BlZQ==
|
||||||
./attr_scan0: unknown_stream: wanted attribute: (list terminator)
|
./attr_scan0: unknown_stream: wanted attribute: (list terminator)
|
||||||
./attr_scan0: input attribute name: (end)
|
./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
|
number 4711
|
||||||
long_number 1234
|
long_number 1234
|
||||||
string whoopee
|
string whoopee
|
||||||
@ -63,3 +76,4 @@ string whoopee
|
|||||||
data whoopee
|
data whoopee
|
||||||
(hash) foo-name foo-value
|
(hash) foo-name foo-value
|
||||||
(hash) bar-name bar-value
|
(hash) bar-name bar-value
|
||||||
|
return: -1
|
||||||
|
@ -102,6 +102,9 @@
|
|||||||
/* This argument is followed by an attribute name and a long pointer.
|
/* This argument is followed by an attribute name and a long pointer.
|
||||||
/* .IP "RECV_ATTR_STR(const char *name, VSTRING *vp)"
|
/* .IP "RECV_ATTR_STR(const char *name, VSTRING *vp)"
|
||||||
/* This argument is followed by an attribute name and a VSTRING pointer.
|
/* 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)"
|
/* .IP "RECV_ATTR_DATA(const char *name, VSTRING *vp)"
|
||||||
/* This argument is followed by an attribute name and a VSTRING pointer.
|
/* This argument is followed by an attribute name and a VSTRING pointer.
|
||||||
/* .IP "RECV_ATTR_FUNC(ATTR_SCAN_CUSTOM_FN, void *data)"
|
/* .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;
|
int conversions;
|
||||||
ATTR_SCAN_CUSTOM_FN scan_fn;
|
ATTR_SCAN_CUSTOM_FN scan_fn;
|
||||||
void *scan_arg;
|
void *scan_arg;
|
||||||
|
const char *expect_val;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sanity check.
|
* 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)
|
if (scan_fn(attr_scan64, fp, flags | ATTR_FLAG_MORE, scan_arg) < 0)
|
||||||
return (-1);
|
return (-1);
|
||||||
break;
|
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_HASH:
|
||||||
case ATTR_TYPE_CLOSE:
|
case ATTR_TYPE_CLOSE:
|
||||||
if (ch != ':') {
|
if (ch != ':') {
|
||||||
@ -572,6 +599,7 @@ int main(int unused_argc, char **used_argv)
|
|||||||
msg_vstream_init(used_argv[0], VSTREAM_ERR);
|
msg_vstream_init(used_argv[0], VSTREAM_ERR);
|
||||||
if ((ret = attr_scan64(VSTREAM_IN,
|
if ((ret = attr_scan64(VSTREAM_IN,
|
||||||
ATTR_FLAG_STRICT,
|
ATTR_FLAG_STRICT,
|
||||||
|
RECV_ATTR_STREQ("protocol", "test"),
|
||||||
RECV_ATTR_INT(ATTR_NAME_INT, &int_val),
|
RECV_ATTR_INT(ATTR_NAME_INT, &int_val),
|
||||||
RECV_ATTR_LONG(ATTR_NAME_LONG, &long_val),
|
RECV_ATTR_LONG(ATTR_NAME_LONG, &long_val),
|
||||||
RECV_ATTR_STR(ATTR_NAME_STR, str_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,
|
if ((ret = attr_scan64(VSTREAM_IN,
|
||||||
ATTR_FLAG_STRICT,
|
ATTR_FLAG_STRICT,
|
||||||
|
RECV_ATTR_STREQ("protocol", "test"),
|
||||||
RECV_ATTR_INT(ATTR_NAME_INT, &int_val),
|
RECV_ATTR_INT(ATTR_NAME_INT, &int_val),
|
||||||
RECV_ATTR_LONG(ATTR_NAME_LONG, &long_val),
|
RECV_ATTR_LONG(ATTR_NAME_LONG, &long_val),
|
||||||
RECV_ATTR_STR(ATTR_NAME_STR, str_val),
|
RECV_ATTR_STR(ATTR_NAME_STR, str_val),
|
||||||
@ -609,6 +638,11 @@ int main(int unused_argc, char **used_argv)
|
|||||||
} else {
|
} else {
|
||||||
vstream_printf("return: %d\n", ret);
|
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)
|
if (vstream_fflush(VSTREAM_OUT) != 0)
|
||||||
msg_fatal("write error: %m");
|
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 number = 4711
|
||||||
./attr_print64: send attr long_number = 1234
|
./attr_print64: send attr long_number = 1234
|
||||||
./attr_print64: send attr string = whoopee
|
./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 foo-name value foo-value
|
||||||
./attr_print64: send attr name bar-name value bar-value
|
./attr_print64: send attr name bar-name value bar-value
|
||||||
./attr_print64: send attr long_number = 4321
|
./attr_print64: send attr long_number = 4321
|
||||||
|
./attr_print64: send attr protocol = test
|
||||||
./attr_print64: send attr number = 4711
|
./attr_print64: send attr number = 4711
|
||||||
./attr_print64: send attr long_number = 1234
|
./attr_print64: send attr long_number = 1234
|
||||||
./attr_print64: send attr string = whoopee
|
./attr_print64: send attr string = whoopee
|
||||||
./attr_print64: send attr data = [data 7 bytes]
|
./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: unknown_stream: wanted attribute: number
|
||||||
./attr_scan64: input attribute name: number
|
./attr_scan64: input attribute name: number
|
||||||
./attr_scan64: input attribute value: 4711
|
./attr_scan64: input attribute value: 4711
|
||||||
@ -36,6 +42,9 @@
|
|||||||
./attr_scan64: input attribute value: 4321
|
./attr_scan64: input attribute value: 4321
|
||||||
./attr_scan64: unknown_stream: wanted attribute: (list terminator)
|
./attr_scan64: unknown_stream: wanted attribute: (list terminator)
|
||||||
./attr_scan64: input attribute name: (end)
|
./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: unknown_stream: wanted attribute: number
|
||||||
./attr_scan64: input attribute name: number
|
./attr_scan64: input attribute name: number
|
||||||
./attr_scan64: input attribute value: 4711
|
./attr_scan64: input attribute value: 4711
|
||||||
@ -50,6 +59,10 @@
|
|||||||
./attr_scan64: input attribute value: whoopee
|
./attr_scan64: input attribute value: whoopee
|
||||||
./attr_scan64: unknown_stream: wanted attribute: (list terminator)
|
./attr_scan64: unknown_stream: wanted attribute: (list terminator)
|
||||||
./attr_scan64: input attribute name: (end)
|
./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
|
number 4711
|
||||||
long_number 1234
|
long_number 1234
|
||||||
string whoopee
|
string whoopee
|
||||||
@ -63,3 +76,4 @@ string whoopee
|
|||||||
data whoopee
|
data whoopee
|
||||||
(hash) foo-name foo-value
|
(hash) foo-name foo-value
|
||||||
(hash) bar-name bar-value
|
(hash) bar-name bar-value
|
||||||
|
return: -1
|
||||||
|
@ -100,6 +100,9 @@
|
|||||||
/* This argument is followed by an attribute name and a long pointer.
|
/* This argument is followed by an attribute name and a long pointer.
|
||||||
/* .IP "RECV_ATTR_STR(const char *name, VSTRING *vp)"
|
/* .IP "RECV_ATTR_STR(const char *name, VSTRING *vp)"
|
||||||
/* This argument is followed by an attribute name and a VSTRING pointer.
|
/* 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)"
|
/* .IP "RECV_ATTR_DATA(const char *name, VSTRING *vp)"
|
||||||
/* This argument is followed by an attribute name and a VSTRING pointer.
|
/* This argument is followed by an attribute name and a VSTRING pointer.
|
||||||
/* .IP "RECV_ATTR_FUNC(ATTR_SCAN_CUSTOM_FN, void *data)"
|
/* .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;
|
int conversions;
|
||||||
ATTR_SCAN_CUSTOM_FN scan_fn;
|
ATTR_SCAN_CUSTOM_FN scan_fn;
|
||||||
void *scan_arg;
|
void *scan_arg;
|
||||||
|
const char *expect_val;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sanity check.
|
* 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)
|
if (scan_fn(attr_scan_plain, fp, flags | ATTR_FLAG_MORE, scan_arg) < 0)
|
||||||
return (-1);
|
return (-1);
|
||||||
break;
|
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_HASH:
|
||||||
case ATTR_TYPE_CLOSE:
|
case ATTR_TYPE_CLOSE:
|
||||||
if (ch != '=') {
|
if (ch != '=') {
|
||||||
@ -555,6 +577,7 @@ int main(int unused_argc, char **used_argv)
|
|||||||
msg_vstream_init(used_argv[0], VSTREAM_ERR);
|
msg_vstream_init(used_argv[0], VSTREAM_ERR);
|
||||||
if ((ret = attr_scan_plain(VSTREAM_IN,
|
if ((ret = attr_scan_plain(VSTREAM_IN,
|
||||||
ATTR_FLAG_STRICT,
|
ATTR_FLAG_STRICT,
|
||||||
|
RECV_ATTR_STREQ("protocol", "test"),
|
||||||
RECV_ATTR_INT(ATTR_NAME_INT, &int_val),
|
RECV_ATTR_INT(ATTR_NAME_INT, &int_val),
|
||||||
RECV_ATTR_LONG(ATTR_NAME_LONG, &long_val),
|
RECV_ATTR_LONG(ATTR_NAME_LONG, &long_val),
|
||||||
RECV_ATTR_STR(ATTR_NAME_STR, str_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,
|
if ((ret = attr_scan_plain(VSTREAM_IN,
|
||||||
ATTR_FLAG_STRICT,
|
ATTR_FLAG_STRICT,
|
||||||
|
RECV_ATTR_STREQ("protocol", "test"),
|
||||||
RECV_ATTR_INT(ATTR_NAME_INT, &int_val),
|
RECV_ATTR_INT(ATTR_NAME_INT, &int_val),
|
||||||
RECV_ATTR_LONG(ATTR_NAME_LONG, &long_val),
|
RECV_ATTR_LONG(ATTR_NAME_LONG, &long_val),
|
||||||
RECV_ATTR_STR(ATTR_NAME_STR, str_val),
|
RECV_ATTR_STR(ATTR_NAME_STR, str_val),
|
||||||
@ -592,6 +616,11 @@ int main(int unused_argc, char **used_argv)
|
|||||||
} else {
|
} else {
|
||||||
vstream_printf("return: %d\n", ret);
|
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)
|
if (vstream_fflush(VSTREAM_OUT) != 0)
|
||||||
msg_fatal("write error: %m");
|
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 number = 4711
|
||||||
./attr_print_plain: send attr long_number = 1234
|
./attr_print_plain: send attr long_number = 1234
|
||||||
./attr_print_plain: send attr string = whoopee
|
./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 foo-name value foo-value
|
||||||
./attr_print_plain: send attr name bar-name value bar-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 long_number = 4321
|
||||||
|
./attr_print_plain: send attr protocol = test
|
||||||
./attr_print_plain: send attr number = 4711
|
./attr_print_plain: send attr number = 4711
|
||||||
./attr_print_plain: send attr long_number = 1234
|
./attr_print_plain: send attr long_number = 1234
|
||||||
./attr_print_plain: send attr string = whoopee
|
./attr_print_plain: send attr string = whoopee
|
||||||
./attr_print_plain: send attr data = [data 7 bytes]
|
./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: unknown_stream: wanted attribute: number
|
||||||
./attr_scan_plain: input attribute name: number
|
./attr_scan_plain: input attribute name: number
|
||||||
./attr_scan_plain: input attribute value: 4711
|
./attr_scan_plain: input attribute value: 4711
|
||||||
@ -36,6 +42,9 @@
|
|||||||
./attr_scan_plain: input attribute value: 4321
|
./attr_scan_plain: input attribute value: 4321
|
||||||
./attr_scan_plain: unknown_stream: wanted attribute: (list terminator)
|
./attr_scan_plain: unknown_stream: wanted attribute: (list terminator)
|
||||||
./attr_scan_plain: input attribute name: (end)
|
./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: unknown_stream: wanted attribute: number
|
||||||
./attr_scan_plain: input attribute name: number
|
./attr_scan_plain: input attribute name: number
|
||||||
./attr_scan_plain: input attribute value: 4711
|
./attr_scan_plain: input attribute value: 4711
|
||||||
@ -50,6 +59,10 @@
|
|||||||
./attr_scan_plain: input attribute value: d2hvb3BlZQ==
|
./attr_scan_plain: input attribute value: d2hvb3BlZQ==
|
||||||
./attr_scan_plain: unknown_stream: wanted attribute: (list terminator)
|
./attr_scan_plain: unknown_stream: wanted attribute: (list terminator)
|
||||||
./attr_scan_plain: input attribute name: (end)
|
./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
|
number 4711
|
||||||
long_number 1234
|
long_number 1234
|
||||||
string whoopee
|
string whoopee
|
||||||
@ -63,3 +76,4 @@ string whoopee
|
|||||||
data whoopee
|
data whoopee
|
||||||
(hash) foo-name foo-value
|
(hash) foo-name foo-value
|
||||||
(hash) bar-name bar-value
|
(hash) bar-name bar-value
|
||||||
|
return: -1
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
/* SYNOPSIS
|
/* SYNOPSIS
|
||||||
/* #include <auto_clnt.h>
|
/* #include <auto_clnt.h>
|
||||||
/*
|
/*
|
||||||
|
/* typedef void (*AUTO_CLNT_HANDSHAKE_FN)(VSTREAM *);
|
||||||
|
/*
|
||||||
/* AUTO_CLNT *auto_clnt_create(service, timeout, max_idle, max_ttl)
|
/* AUTO_CLNT *auto_clnt_create(service, timeout, max_idle, max_ttl)
|
||||||
/* const char *service;
|
/* const char *service;
|
||||||
/* int timeout;
|
/* int timeout;
|
||||||
@ -23,6 +25,10 @@
|
|||||||
/*
|
/*
|
||||||
/* void auto_clnt_free(auto_clnt)
|
/* void auto_clnt_free(auto_clnt)
|
||||||
/* AUTO_CLNT *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
|
/* DESCRIPTION
|
||||||
/* This module maintains IPC client endpoints that automatically
|
/* This module maintains IPC client endpoints that automatically
|
||||||
/* disconnect after a being idle for a configurable amount of time,
|
/* 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_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:
|
/* Arguments:
|
||||||
/* .IP service
|
/* .IP service
|
||||||
/* The service argument specifies "transport:servername" where
|
/* The service argument specifies "transport:servername" where
|
||||||
@ -79,6 +94,10 @@
|
|||||||
/* is expected to set the stream pathname to the server endpoint name.
|
/* is expected to set the stream pathname to the server endpoint name.
|
||||||
/* .IP context
|
/* .IP context
|
||||||
/* Application context that is passed to the open_action routine.
|
/* 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
|
/* DIAGNOSTICS
|
||||||
/* Warnings: communication failure. Fatal error: out of memory.
|
/* Warnings: communication failure. Fatal error: out of memory.
|
||||||
/* LICENSE
|
/* LICENSE
|
||||||
@ -90,6 +109,11 @@
|
|||||||
/* IBM T.J. Watson Research
|
/* IBM T.J. Watson Research
|
||||||
/* P.O. Box 704
|
/* P.O. Box 704
|
||||||
/* Yorktown Heights, NY 10598, USA
|
/* Yorktown Heights, NY 10598, USA
|
||||||
|
/*
|
||||||
|
/* Wietse Venema
|
||||||
|
/* Google, Inc.
|
||||||
|
/* 111 8th Avenue
|
||||||
|
/* New York, NY 10011, USA
|
||||||
/*--*/
|
/*--*/
|
||||||
|
|
||||||
/* System library. */
|
/* System library. */
|
||||||
@ -120,6 +144,7 @@ struct AUTO_CLNT {
|
|||||||
int timeout; /* I/O time limit */
|
int timeout; /* I/O time limit */
|
||||||
int max_idle; /* time before client disconnect */
|
int max_idle; /* time before client disconnect */
|
||||||
int max_ttl; /* 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 */
|
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)
|
VSTREAM *auto_clnt_access(AUTO_CLNT *auto_clnt)
|
||||||
{
|
{
|
||||||
|
AUTO_CLNT_HANDSHAKE_FN handshake;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Open a stream or restart the idle timer.
|
* 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) {
|
if (auto_clnt->vstream == 0) {
|
||||||
auto_clnt_open(auto_clnt);
|
auto_clnt_open(auto_clnt);
|
||||||
|
handshake = (auto_clnt->vstream ? auto_clnt->handshake : 0);
|
||||||
} else {
|
} else {
|
||||||
if (auto_clnt->max_idle > 0)
|
if (auto_clnt->max_idle > 0)
|
||||||
event_request_timer(auto_clnt_event, (void *) auto_clnt,
|
event_request_timer(auto_clnt_event, (void *) auto_clnt,
|
||||||
auto_clnt->max_idle);
|
auto_clnt->max_idle);
|
||||||
|
handshake = 0;
|
||||||
}
|
}
|
||||||
|
if (handshake != 0 && handshake(auto_clnt->vstream) != 0)
|
||||||
|
return (0);
|
||||||
return (auto_clnt->vstream);
|
return (auto_clnt->vstream);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -290,6 +320,7 @@ AUTO_CLNT *auto_clnt_create(const char *service, int timeout,
|
|||||||
auto_clnt->timeout = timeout;
|
auto_clnt->timeout = timeout;
|
||||||
auto_clnt->max_idle = max_idle;
|
auto_clnt->max_idle = max_idle;
|
||||||
auto_clnt->max_ttl = max_ttl;
|
auto_clnt->max_ttl = max_ttl;
|
||||||
|
auto_clnt->handshake = 0;
|
||||||
if (strcmp(transport, "inet") == 0) {
|
if (strcmp(transport, "inet") == 0) {
|
||||||
auto_clnt->connect = inet_connect;
|
auto_clnt->connect = inet_connect;
|
||||||
} else if (strcmp(transport, "local") == 0) {
|
} else if (strcmp(transport, "local") == 0) {
|
||||||
@ -320,3 +351,22 @@ void auto_clnt_free(AUTO_CLNT *auto_clnt)
|
|||||||
myfree(auto_clnt->endpoint);
|
myfree(auto_clnt->endpoint);
|
||||||
myfree((void *) auto_clnt);
|
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.
|
* External interface.
|
||||||
*/
|
*/
|
||||||
typedef struct AUTO_CLNT AUTO_CLNT;
|
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 AUTO_CLNT *auto_clnt_create(const char *, int, int, int);
|
||||||
extern VSTREAM *auto_clnt_access(AUTO_CLNT *);
|
extern VSTREAM *auto_clnt_access(AUTO_CLNT *);
|
||||||
extern void auto_clnt_recover(AUTO_CLNT *);
|
extern void auto_clnt_recover(AUTO_CLNT *);
|
||||||
extern const char *auto_clnt_name(AUTO_CLNT *);
|
extern const char *auto_clnt_name(AUTO_CLNT *);
|
||||||
extern void auto_clnt_free(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
|
/* LICENSE
|
||||||
/* .ad
|
/* .ad
|
||||||
@ -36,6 +41,11 @@ extern void auto_clnt_free(AUTO_CLNT *);
|
|||||||
/* IBM T.J. Watson Research
|
/* IBM T.J. Watson Research
|
||||||
/* P.O. Box 704
|
/* P.O. Box 704
|
||||||
/* Yorktown Heights, NY 10598, USA
|
/* Yorktown Heights, NY 10598, USA
|
||||||
|
/*
|
||||||
|
/* Wietse Venema
|
||||||
|
/* Google, Inc.
|
||||||
|
/* 111 8th Avenue
|
||||||
|
/* New York, NY 10011, USA
|
||||||
/*--*/
|
/*--*/
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -95,7 +95,6 @@
|
|||||||
#include <vstream.h>
|
#include <vstream.h>
|
||||||
#include <msg_vstream.h>
|
#include <msg_vstream.h>
|
||||||
#include <stringops.h>
|
#include <stringops.h>
|
||||||
#include <percentm.h>
|
|
||||||
#include <msg_output.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);
|
msg_vstream_init("unknown", VSTREAM_ERR);
|
||||||
vp = msg_buffers[msg_vprintf_level - 1];
|
vp = msg_buffers[msg_vprintf_level - 1];
|
||||||
/* OK if terminating signal handler hijacks control before next stmt. */
|
/* 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), '?');
|
printable(vstring_str(vp), '?');
|
||||||
for (i = 0; i < msg_output_fn_count; i++)
|
for (i = 0; i < msg_output_fn_count; i++)
|
||||||
msg_output_fn[i] (level, vstring_str(vp));
|
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)
|
(addr_status != DEL_RCPT_STAT_OK && updated + var_verify_neg_try < now)
|
||||||
|
|
||||||
if (now - probed > PROBE_TTL
|
if (now - probed > PROBE_TTL
|
||||||
&& (POSITIVE_REFRESH_NEEDED(addr_status, updated)
|
&& (POSITIVE_REFRESH_NEEDED(addr_status, updated)
|
||||||
|| NEGATIVE_REFRESH_NEEDED(addr_status, updated))) {
|
|| NEGATIVE_REFRESH_NEEDED(addr_status, updated))) {
|
||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
msg_info("PROBE %s status=%d probed=%ld updated=%ld",
|
msg_info("PROBE %s status=%d probed=%ld updated=%ld",
|
||||||
STR(addr), addr_status, now, updated);
|
STR(addr), addr_status, now, updated);
|
||||||
@ -723,6 +723,21 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
|
|||||||
RESTORE_SAVED_EUGID();
|
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;
|
MAIL_VERSION_STAMP_DECLARE;
|
||||||
|
|
||||||
/* main - pass control to the multi-threaded skeleton */
|
/* 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_TIME_TABLE(time_table),
|
||||||
CA_MAIL_SERVER_PRE_INIT(pre_jail_init),
|
CA_MAIL_SERVER_PRE_INIT(pre_jail_init),
|
||||||
CA_MAIL_SERVER_POST_INIT(post_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_SOLITARY,
|
||||||
CA_MAIL_SERVER_EXIT(verify_dump),
|
CA_MAIL_SERVER_EXIT(verify_dump),
|
||||||
0);
|
0);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user