with unread data according to ioctl FIONREAD. Incredible.
Diagnosis by Max Pashkov. File: smtp/smtp-sink.c.
- Weirdstuff: sender-based routing. This will become more
+ Weird feature: sender-based routing. This will become more
useful once per-address transport map entries are done.
- File: src/qmgr/qmgr_message.c.
+ File: src/*qmgr/qmgr_message.c.
20020605
addresses in message headers. The limit is expressed as a
number of tokens. File: global/tok822_parse.c
+20020608
+
+ Feature: user@domain transport map lookup, based on code
+ by Scott Cotton, from several years ago. Adding this code
+ now was much less painful than it was in the past. Files:
+ global/strip_addr.c, trivial-rewrite/transport.c.
+
+20020610
+
+ Cleanup: making user@domain transport map lookups work with
+ sender-based routing was a bit tricky, because the null
+ address must be handled sensibly. Files: global/resolve_clnt.c,
+ trivial-rewrite/resolve.c. It ain't perfect yet, but close.
+
Open problems:
Medium: old maildrop files are no longer readable by the
done;
rm -f Makefile; (set -e; $(SHELL) makedefs && cat Makefile.in) >Makefile
-update printfck:
+update printfck tests:
set -e; for i in $(DIRS); do \
(set -e; echo "[$$i]"; cd $$i; $(MAKE) $(OPTS) $@ MAKELEVEL=) || exit 1; \
done
date. Snapshots change only the release date, unless they include
the same bugfixes as a patch release.
+Incompatible changes with Postfix snapshot 1.1.11-20020610
+==========================================================
+
+Regexp-based transport maps now see the entire recipient address
+instead of only the destination domain name.
+
+Major changes with Postfix snapshot 1.1.11-20020610
+===================================================
+
+A bizarre feature, sender-based routing, that could be useful in
+combination with user@domain address lookups in the transport map.
+
+An actually useful feature, user@domain address lookups in the
+transport map. This feature also understands address extensions.
+Transport maps still support lookup keys in the form of domain
+names, but only with non-regexp tables. Specify <> in order to
+match the null address. More in the transport(5) manual page.
+
+Together with sender-based routing, and a dual Postfix setup.
+user@domain transport map lookups could fulfill people's wishes to
+have multiple SMTP personalities for sending and receiving mail,
+including bounce processing. Details will have to be hammered out
+by users, as Wietse is now completely tied up by other business
+for the next three weeks.
+
Incompatible changes with Postfix snapshot 1.1.11-20020528
==========================================================
#
header_size_limit = 102400
-# The header_address_token_limit limits the amount of memory and CPU
-# that Postfix will spend while rewriting addresses in message headers.
-# The limit is expressed as a token count. Tokens beyond the limit are
-# discarded.
+# The header_address_token_limit limits the amount of memory that
+# Postfix will spend while rewriting addresses in message headers.
+# The limit is expressed as a token count. Tokens beyond the limit
+# are discarded.
#
header_address_token_limit = 10240
#
# DESCRIPTION
# The optional transport table specifies a mapping from
-# domain hierarchies to message delivery transports and/or
+# email addresses to message delivery transports and/or
# relay hosts. The mapping is used by the trivial-rewrite(8)
# daemon.
#
# Alternatively, the table can be provided as a regular-
# expression map where patterns are given as regular expres-
# sions. In that case, the lookups are done in a slightly
-# different way as described below.
+# different way as described in the section titled "REGULAR
+# EXPRESSION TABLES".
#
# TABLE FORMAT
# The format of the transport table is as follows:
#
# pattern result
-# When pattern matches the domain, use the corre-
+# When pattern matches the domain, use the corre-
# sponding result.
#
# blank lines and comments
-# Empty lines and whitespace-only lines are ignored,
-# as are lines whose first non-whitespace character
+# Empty lines and whitespace-only lines are ignored,
+# as are lines whose first non-whitespace character
# is a `#'.
#
# multi-line text
-# A logical line starts with non-whitespace text. A
-# line that starts with whitespace continues a logi-
+# A logical line starts with non-whitespace text. A
+# line that starts with whitespace continues a logi-
# cal line.
#
# In an indexed file, a pattern of `*' matches everything.
#
-# The result is of the form transport:nexthop. The trans-
-# port field specifies a mail delivery transport such as
-# smtp or local. The nexthop field specifies where and how
-# to deliver mail. A null transport or nexthop field means
-# "do not change": use the delivery transport and nexthop
+# The result is of the form transport:nexthop. The trans-
+# port field specifies a mail delivery transport such as
+# smtp or local. The nexthop field specifies where and how
+# to deliver mail. A null transport or nexthop field means
+# "do not change": use the delivery transport and nexthop
# information that would be used if no match were found.
#
-# The interpretation of the nexthop field is transport
+# The interpretation of the nexthop field is transport
# dependent. In the case of SMTP, specify host:service for a
-# non-default server port, and use [host] or [host]:port in
-# order to disable MX (mail exchanger) DNS lookups. The []
-# form can also be used with IP addresses instead of host-
+# non-default server port, and use [host] or [host]:port in
+# order to disable MX (mail exchanger) DNS lookups. The []
+# form can also be used with IP addresses instead of host-
# names.
#
# With lookups from indexed files such as DB or DBM, or from
-# networked tables such as NIS, LDAP or SQL, patterns are
+# networked tables such as NIS, LDAP or SQL, patterns are
# tried in the order as listed below:
#
+# user+extension@domain transport:nexthop
+# Mail for user+extension@domain is delivered through
+# transport to nexthop.
+#
+# user@domain transport:nexthop
+# Mail for user@domain is delivered through transport
+# to nexthop.
+#
# domain transport:nexthop
-# Mail for domain is delivered through transport to
+# Mail for domain is delivered through transport to
# nexthop.
#
# .domain transport:nexthop
-# Mail for any subdomain of domain is delivered
-# through transport to nexthop. This applies only
+# Mail for any subdomain of domain is delivered
+# through transport to nexthop. This applies only
# when the string transport_maps is not listed in the
# parent_domain_matches_subdomains configuration set-
-# ting. Otherwise, a domain name matches itself and
+# ting. Otherwise, a domain name matches itself and
# its subdomains.
#
+# NOTE
+# The special pattern <> represents the null address, and
+# the special pattern * represents any address (i.e. it
+# functions as the wild-card pattern).
+#
# EXAMPLES
-# In order to deliver internal mail directly, while using a
-# mail relay for all other mail, specify a null entry for
-# internal destinations (do not change the delivery trans-
-# port or the nexthop information) and specify a wildcard
-# for all other destinations. Note that for this trick to
-# work you should not specify a relayhost in the main.cf
+# In order to deliver internal mail directly, while using a
+# mail relay for all other mail, specify a null entry for
+# internal destinations (do not change the delivery trans-
+# port or the nexthop information) and specify a wildcard
+# for all other destinations. Note that for this trick to
+# work you should not specify a relayhost in the main.cf
# file.
#
# my.domain :
# .my.domain :
# * smtp:outbound-relay.my.domain
#
-# In order to send mail for foo.org and its subdomains via
+# In order to send mail for foo.org and its subdomains via
# the uucp transport to the UUCP host named foo:
#
# foo.org uucp:foo
# .foo.org uucp:foo
#
-# When no nexthop host name is specified, the destination
-# domain name is used instead. For example, the following
-# directs mail for user@foo.org via the slow transport to a
-# mail exchanger for foo.org. The slow transport could be
-# something that runs at most one delivery process at a
+# When no nexthop host name is specified, the destination
+# domain name is used instead. For example, the following
+# directs mail for user@foo.org via the slow transport to a
+# mail exchanger for foo.org. The slow transport could be
+# something that runs at most one delivery process at a
# time:
#
# foo.org slow:
#
# When no transport is specified, Postfix uses either
-# $local_transport or $default_transport, depending on
-# whether the destination matches $mydestination. The fol-
-# lowing sends all mail for foo.org and its subdomains to
+# $local_transport or $default_transport, depending on
+# whether the destination matches $mydestination. The fol-
+# lowing sends all mail for foo.org and its subdomains to
# host gateway.foo.org:
#
# foo.org :[gateway.foo.org]
# .foo.org :[gateway.foo.org]
#
-# In the above example, the [] are used to suppress MX
-# lookups. The result would likely point to your local
+# In the above example, the [] are used to suppress MX
+# lookups. The result would likely point to your local
# machine.
#
-# In the case of delivery via SMTP, one may specify host-
+# In the case of delivery via SMTP, one may specify host-
# name:service instead of just a host:
#
# foo.org smtp:bar.org:2025
#
-# This directs mail for user@foo.org to host bar.org port
-# 2025. Instead of a numerical port a symbolic name may be
-# used. Specify [] around the hostname in order to disable
+# This directs mail for user@foo.org to host bar.org port
+# 2025. Instead of a numerical port a symbolic name may be
+# used. Specify [] around the hostname in order to disable
# MX lookups.
#
# The error mailer can be used to bounce mail:
#
-# .foo.org error:mail for *.foo.org is not deliv-
+# .foo.org error:mail for *.foo.org is not deliv-
# erable
#
-# This causes all mail for user@anything.foo.org to be
+# This causes all mail for user@anything.foo.org to be
# bounced.
#
# REGULAR EXPRESSION TABLES
-# This section describes how the table lookups change when
+# This section describes how the table lookups change when
# the table is given in the form of regular expressions. For
-# a description of regular expression lookup table syntax,
+# a description of regular expression lookup table syntax,
# see regexp_table(5) or pcre_table(5).
#
-# Each pattern is a regular expression that is applied to
+# Each pattern is a regular expression that is applied to
# the entire domain being looked up. Thus, some.domain.hier-
# archy is not broken up into parent domains.
#
-# Patterns are applied in the order as specified in the
-# table, until a pattern is found that matches the search
+# Patterns are applied in the order as specified in the
+# table, until a pattern is found that matches the search
# string.
#
-# Results are the same as with indexed file lookups, with
-# the additional feature that parenthesized substrings from
+# Results are the same as with indexed file lookups, with
+# the additional feature that parenthesized substrings from
# the pattern can be interpolated as $1, $2 and so on.
#
# CONFIGURATION PARAMETERS
-# The following main.cf parameters are especially relevant
-# to this topic. See the Postfix main.cf file for syntax
-# details and for default values. Use the postfix reload
+# The following main.cf parameters are especially relevant
+# to this topic. See the Postfix main.cf file for syntax
+# details and for default values. Use the postfix reload
# command after a configuration change.
#
# parent_domain_matches_subdomains
-# List of Postfix features that use domain.tld pat-
-# terns to match sub.domain.tld (as opposed to
+# List of Postfix features that use domain.tld pat-
+# terns to match sub.domain.tld (as opposed to
# requiring .domain.tld patterns).
#
# transport_maps
# Other parameters of interest:
#
# local_transport
-# The mail delivery transport to use when no trans-
-# port is explicitly specified, and the destination
+# The mail delivery transport to use when no trans-
+# port is explicitly specified, and the destination
# matches $mydestination.
#
# default_transport
-# The mail delivery transport to use when no trans-
-# port is explicitly specified, and the destination
+# The mail delivery transport to use when no trans-
+# port is explicitly specified, and the destination
# does not match $mydestination.
#
# mydestination
# regexp_table(5) format of POSIX regular expression tables
#
# LICENSE
-# The Secure Mailer license must be distributed with this
+# The Secure Mailer license must be distributed with this
# software.
#
# AUTHOR(S)
You can specify zero or more domain names, <i>/file/name</i> patterns
and/or <i>type:name</i> lookup tables, separated by whitespace
and/or commas. A <i>/file/name</i> is replaced by its contents;
-<i>type:name</i> requests that a table lookup is done, typically
-from a <a href="rewrite.html#virtual">virtual</a> database.
+<i>type:name</i> requests that a table lookup is done.
<p>
<b>DESCRIPTION</b>
The optional <b>transport</b> table specifies a mapping from
- domain hierarchies to message delivery transports and/or
+ email addresses to message delivery transports and/or
relay hosts. The mapping is used by the <a href="trivial-rewrite.8.html"><b>trivial-rewrite</b>(8)</a>
daemon.
Alternatively, the table can be provided as a regular-
expression map where patterns are given as regular expres-
sions. In that case, the lookups are done in a slightly
- different way as described below.
+ different way as described in the section titled "REGULAR
+ EXPRESSION TABLES".
<b>TABLE</b> <b>FORMAT</b>
The format of the transport table is as follows:
<i>pattern</i> <i>result</i>
- When <i>pattern</i> matches the domain, use the corre-
+ When <i>pattern</i> matches the domain, use the corre-
sponding <i>result</i>.
blank lines and comments
- Empty lines and whitespace-only lines are ignored,
- as are lines whose first non-whitespace character
+ Empty lines and whitespace-only lines are ignored,
+ as are lines whose first non-whitespace character
is a `#'.
multi-line text
- A logical line starts with non-whitespace text. A
- line that starts with whitespace continues a logi-
+ A logical line starts with non-whitespace text. A
+ line that starts with whitespace continues a logi-
cal line.
In an indexed file, a pattern of `<b>*</b>' matches everything.
- The <i>result</i> is of the form <i>transport</i><b>:</b><i>nexthop</i>. The <i>trans-</i>
- <i>port</i> field specifies a mail delivery transport such as
- <b>smtp</b> or <b>local</b>. The <i>nexthop</i> field specifies where and how
- to deliver mail. A null <i>transport</i> or <i>nexthop</i> field means
- "do not change": use the delivery transport and nexthop
+ The <i>result</i> is of the form <i>transport</i><b>:</b><i>nexthop</i>. The <i>trans-</i>
+ <i>port</i> field specifies a mail delivery transport such as
+ <b>smtp</b> or <b>local</b>. The <i>nexthop</i> field specifies where and how
+ to deliver mail. A null <i>transport</i> or <i>nexthop</i> field means
+ "do not change": use the delivery transport and nexthop
information that would be used if no match were found.
- The interpretation of the <i>nexthop</i> field is transport
+ The interpretation of the <i>nexthop</i> field is transport
dependent. In the case of SMTP, specify <i>host</i>:<i>service</i> for a
- non-default server port, and use [<i>host</i>] or [<i>host</i>]:<i>port</i> in
- order to disable MX (mail exchanger) DNS lookups. The []
- form can also be used with IP addresses instead of host-
+ non-default server port, and use [<i>host</i>] or [<i>host</i>]:<i>port</i> in
+ order to disable MX (mail exchanger) DNS lookups. The []
+ form can also be used with IP addresses instead of host-
names.
With lookups from indexed files such as DB or DBM, or from
- networked tables such as NIS, LDAP or SQL, patterns are
+ networked tables such as NIS, LDAP or SQL, patterns are
tried in the order as listed below:
+ <i>user+extension@domain</i> <i>transport</i>:<i>nexthop</i>
+ Mail for <i>user+extension@domain</i> is delivered through
+ <i>transport</i> to <i>nexthop</i>.
+
+ <i>user@domain</i> <i>transport</i>:<i>nexthop</i>
+ Mail for <i>user@domain</i> is delivered through <i>transport</i>
+ to <i>nexthop</i>.
+
<i>domain</i> <i>transport</i>:<i>nexthop</i>
- Mail for <i>domain</i> is delivered through <i>transport</i> to
+ Mail for <i>domain</i> is delivered through <i>transport</i> to
<i>nexthop</i>.
<i>.domain</i> <i>transport</i>:<i>nexthop</i>
- Mail for any subdomain of <i>domain</i> is delivered
- through <i>transport</i> to <i>nexthop</i>. This applies only
+ Mail for any subdomain of <i>domain</i> is delivered
+ through <i>transport</i> to <i>nexthop</i>. This applies only
when the string <b>transport</b><i>_</i><b>maps</b> is not listed in the
<b>parent</b><i>_</i><b>domain</b><i>_</i><b>matches</b><i>_</i><b>subdomains</b> configuration set-
- ting. Otherwise, a domain name matches itself and
+ ting. Otherwise, a domain name matches itself and
its subdomains.
+<b>NOTE</b>
+ The special pattern <> represents the null address, and
+ the special pattern <b>*</b> represents any address (i.e. it
+ functions as the wild-card pattern).
+
<b>EXAMPLES</b>
- In order to deliver internal mail directly, while using a
- mail relay for all other mail, specify a null entry for
- internal destinations (do not change the delivery trans-
- port or the nexthop information) and specify a wildcard
- for all other destinations. Note that for this trick to
- work you should not specify a <b>relayhost</b> in the <b>main.cf</b>
+ In order to deliver internal mail directly, while using a
+ mail relay for all other mail, specify a null entry for
+ internal destinations (do not change the delivery trans-
+ port or the nexthop information) and specify a wildcard
+ for all other destinations. Note that for this trick to
+ work you should not specify a <b>relayhost</b> in the <b>main.cf</b>
file.
<b>my.domain</b> <b>:</b>
<b>.my.domain</b> <b>:</b>
<b>*</b> <b>smtp:outbound-relay.my.domain</b>
- In order to send mail for <b>foo.org</b> and its subdomains via
+ In order to send mail for <b>foo.org</b> and its subdomains via
the <b>uucp</b> transport to the UUCP host named <b>foo</b>:
<b>foo.org</b> <b>uucp:foo</b>
<b>.foo.org</b> <b>uucp:foo</b>
- When no <i>nexthop</i> host name is specified, the destination
- domain name is used instead. For example, the following
- directs mail for <i>user</i>@<b>foo.org</b> via the <b>slow</b> transport to a
- mail exchanger for <b>foo.org</b>. The <b>slow</b> transport could be
- something that runs at most one delivery process at a
+ When no <i>nexthop</i> host name is specified, the destination
+ domain name is used instead. For example, the following
+ directs mail for <i>user</i>@<b>foo.org</b> via the <b>slow</b> transport to a
+ mail exchanger for <b>foo.org</b>. The <b>slow</b> transport could be
+ something that runs at most one delivery process at a
time:
<b>foo.org</b> <b>slow:</b>
When no <i>transport</i> is specified, Postfix uses either
- <b>$local</b><i>_</i><b>transport</b> or <b>$default</b><i>_</i><b>transport</b>, depending on
- whether the destination matches <b>$mydestination</b>. The fol-
- lowing sends all mail for <b>foo.org</b> and its subdomains to
+ <b>$local</b><i>_</i><b>transport</b> or <b>$default</b><i>_</i><b>transport</b>, depending on
+ whether the destination matches <b>$mydestination</b>. The fol-
+ lowing sends all mail for <b>foo.org</b> and its subdomains to
host <b>gateway.foo.org</b>:
<b>foo.org</b> <b>:[gateway.foo.org]</b>
<b>.foo.org</b> <b>:[gateway.foo.org]</b>
- In the above example, the [] are used to suppress MX
- lookups. The result would likely point to your local
+ In the above example, the [] are used to suppress MX
+ lookups. The result would likely point to your local
machine.
- In the case of delivery via SMTP, one may specify <i>host-</i>
+ In the case of delivery via SMTP, one may specify <i>host-</i>
<i>name</i>:<i>service</i> instead of just a host:
<b>foo.org</b> <b>smtp:bar.org:2025</b>
- This directs mail for <i>user</i>@<b>foo.org</b> to host <b>bar.org</b> port
- <b>2025</b>. Instead of a numerical port a symbolic name may be
- used. Specify [] around the hostname in order to disable
+ This directs mail for <i>user</i>@<b>foo.org</b> to host <b>bar.org</b> port
+ <b>2025</b>. Instead of a numerical port a symbolic name may be
+ used. Specify [] around the hostname in order to disable
MX lookups.
The error mailer can be used to bounce mail:
- <b>.foo.org</b> <b>error:mail</b> <b>for</b> <b>*.foo.org</b> <b>is</b> <b>not</b> <b>deliv-</b>
+ <b>.foo.org</b> <b>error:mail</b> <b>for</b> <b>*.foo.org</b> <b>is</b> <b>not</b> <b>deliv-</b>
<b>erable</b>
- This causes all mail for <i>user</i>@<i>anything</i><b>.foo.org</b> to be
+ This causes all mail for <i>user</i>@<i>anything</i><b>.foo.org</b> to be
bounced.
<b>REGULAR</b> <b>EXPRESSION</b> <b>TABLES</b>
- This section describes how the table lookups change when
+ This section describes how the table lookups change when
the table is given in the form of regular expressions. For
- a description of regular expression lookup table syntax,
+ a description of regular expression lookup table syntax,
see <a href="regexp_table.5.html"><b>regexp</b><i>_</i><b>table</b>(5)</a> or <a href="pcre_table.5.html"><b>pcre</b><i>_</i><b>table</b>(5)</a>.
- Each pattern is a regular expression that is applied to
+ Each pattern is a regular expression that is applied to
the entire domain being looked up. Thus, <i>some.domain.hier-</i>
<i>archy</i> is not broken up into parent domains.
- Patterns are applied in the order as specified in the
- table, until a pattern is found that matches the search
+ Patterns are applied in the order as specified in the
+ table, until a pattern is found that matches the search
string.
- Results are the same as with indexed file lookups, with
- the additional feature that parenthesized substrings from
+ Results are the same as with indexed file lookups, with
+ the additional feature that parenthesized substrings from
the pattern can be interpolated as <b>$1</b>, <b>$2</b> and so on.
<b>CONFIGURATION</b> <b>PARAMETERS</b>
- The following <b>main.cf</b> parameters are especially relevant
- to this topic. See the Postfix <b>main.cf</b> file for syntax
- details and for default values. Use the <b>postfix</b> <b>reload</b>
+ The following <b>main.cf</b> parameters are especially relevant
+ to this topic. See the Postfix <b>main.cf</b> file for syntax
+ details and for default values. Use the <b>postfix</b> <b>reload</b>
command after a configuration change.
<b>parent</b><i>_</i><b>domain</b><i>_</i><b>matches</b><i>_</i><b>subdomains</b>
- List of Postfix features that use <i>domain.tld</i> pat-
- terns to match <i>sub.domain.tld</i> (as opposed to
+ List of Postfix features that use <i>domain.tld</i> pat-
+ terns to match <i>sub.domain.tld</i> (as opposed to
requiring <i>.domain.tld</i> patterns).
<b>transport</b><i>_</i><b>maps</b>
Other parameters of interest:
<b>local</b><i>_</i><b>transport</b>
- The mail delivery transport to use when no trans-
- port is explicitly specified, and the destination
+ The mail delivery transport to use when no trans-
+ port is explicitly specified, and the destination
matches <b>$mydestination</b>.
<b>default</b><i>_</i><b>transport</b>
- The mail delivery transport to use when no trans-
- port is explicitly specified, and the destination
+ The mail delivery transport to use when no trans-
+ port is explicitly specified, and the destination
does not match <b>$mydestination</b>.
<b>mydestination</b>
<a href="regexp_table.5.html">regexp_table(5)</a> format of POSIX regular expression tables
<b>LICENSE</b>
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
<b>AUTHOR(S)</b>
List of tables with <i>domain</i> to (<i>transport,</i> <i>nexthop</i>)
mappings.
+ <b>transport</b><i>_</i><b>null</b><i>_</i><b>address</b><i>_</i><b>lookup</b><i>_</i><b>key</b>
+ Lookup key to be used for the null address.
+
<b>SEE</b> <b>ALSO</b>
<a href="master.8.html">master(8)</a> process manager
syslogd(8) system logging
.SH DESCRIPTION
.ad
.fi
-The optional \fBtransport\fR table specifies a mapping from domain
-hierarchies to message delivery transports and/or relay hosts. The
+The optional \fBtransport\fR table specifies a mapping from email
+addresses to message delivery transports and/or relay hosts. The
mapping is used by the \fBtrivial-rewrite\fR(8) daemon.
Normally, the \fBtransport\fR table is specified as a text file
Alternatively, the table can be provided as a regular-expression
map where patterns are given as regular expressions. In that case,
-the lookups are done in a slightly different way as described below.
+the lookups are done in a slightly different way as described
+in the section titled "REGULAR EXPRESSION TABLES".
.SH TABLE FORMAT
.na
.nf
With lookups from indexed files such as DB or DBM, or from networked
tables such as NIS, LDAP or SQL, patterns are tried in the order as
listed below:
+.IP "\fIuser+extension@domain transport\fR:\fInexthop\fR"
+Mail for \fIuser+extension@domain\fR is delivered through
+\fItransport\fR to
+\fInexthop\fR.
+.IP "\fIuser@domain transport\fR:\fInexthop\fR"
+Mail for \fIuser@domain\fR is delivered through \fItransport\fR to
+\fInexthop\fR.
.IP "\fIdomain transport\fR:\fInexthop\fR"
Mail for \fIdomain\fR is delivered through \fItransport\fR to
\fInexthop\fR.
string \fBtransport_maps\fR is not listed in the
\fBparent_domain_matches_subdomains\fR configuration setting.
Otherwise, a domain name matches itself and its subdomains.
+.PP
+.SH NOTE
+.na
+.nf
+.ad
+.fi
+The special pattern \fB<>\fR represents the null address, and the
+special pattern \fB*\fR represents any address (i.e. it functions
+as the wild-card pattern).
.SH EXAMPLES
.na
.nf
.IP \fBtransport_maps\fR
List of tables with \fIdomain\fR to (\fItransport, nexthop\fR)
mappings.
+.IP \fBtransport_null_address_lookup_key\fR
+Lookup key to be used for the null address.
.SH SEE ALSO
.na
.nf
# SYNOPSIS
# \fBpostmap /etc/postfix/transport\fR
# DESCRIPTION
-# The optional \fBtransport\fR table specifies a mapping from domain
-# hierarchies to message delivery transports and/or relay hosts. The
+# The optional \fBtransport\fR table specifies a mapping from email
+# addresses to message delivery transports and/or relay hosts. The
# mapping is used by the \fBtrivial-rewrite\fR(8) daemon.
#
# Normally, the \fBtransport\fR table is specified as a text file
#
# Alternatively, the table can be provided as a regular-expression
# map where patterns are given as regular expressions. In that case,
-# the lookups are done in a slightly different way as described below.
+# the lookups are done in a slightly different way as described
+# in the section titled "REGULAR EXPRESSION TABLES".
# TABLE FORMAT
# .ad
# .fi
# With lookups from indexed files such as DB or DBM, or from networked
# tables such as NIS, LDAP or SQL, patterns are tried in the order as
# listed below:
+# .IP "\fIuser+extension@domain transport\fR:\fInexthop\fR"
+# Mail for \fIuser+extension@domain\fR is delivered through
+# \fItransport\fR to
+# \fInexthop\fR.
+# .IP "\fIuser@domain transport\fR:\fInexthop\fR"
+# Mail for \fIuser@domain\fR is delivered through \fItransport\fR to
+# \fInexthop\fR.
# .IP "\fIdomain transport\fR:\fInexthop\fR"
# Mail for \fIdomain\fR is delivered through \fItransport\fR to
# \fInexthop\fR.
# string \fBtransport_maps\fR is not listed in the
# \fBparent_domain_matches_subdomains\fR configuration setting.
# Otherwise, a domain name matches itself and its subdomains.
+# .PP
+# NOTE
+# .ad
+# .fi
+# The special pattern \fB<>\fR represents the null address, and the
+# special pattern \fB*\fR represents any address (i.e. it functions
+# as the wild-card pattern).
# EXAMPLES
# .ad
# .fi
test: $(TESTPROG)
+tests: test
+
update: ../../libexec/$(PROG)
../../libexec/$(PROG): $(PROG)
test: $(TESTPROG)
+tests: test
+
update: ../../libexec/$(PROG)
../../libexec/$(PROG): $(PROG)
* checking in one place, instead of having error handling code all over
* the place.
*/
-#define NO_TOKEN_LIMIT 0
-
tok822_externalize(temp, tree->head, TOK822_STR_DEFL);
cleanup_map11_external(state, temp, maps, propagate);
tok822_free_tree(tree->head);
- tree->head = tok822_scan(STR(temp), &tree->tail, NO_TOKEN_LIMIT);
+ tree->head = tok822_scan(STR(temp), &tree->tail);
vstring_free(temp);
}
{
VSTRING *temp = vstring_alloc(100);
-#define NO_TOKEN_LIMIT 0
-
tok822_externalize(temp, tree->head, TOK822_STR_DEFL);
cleanup_masquerade_external(temp, masq_domains);
tok822_free_tree(tree->head);
- tree->head = tok822_scan(STR(temp), &tree->tail, NO_TOKEN_LIMIT);
+ tree->head = tok822_scan(STR(temp), &tree->tail);
vstring_free(temp);
}
* sender addresses, and regenerate the header line. Finally, pipe the
* result through the header line folding routine.
*/
- tree = tok822_parse(vstring_str(header_buf) + strlen(hdr_opts->name) + 1,
- var_token_limit);
+ tree = tok822_parse_limit(vstring_str(header_buf)
+ + strlen(hdr_opts->name) + 1,
+ var_token_limit);
addr_list = tok822_grep(tree, TOK822_ADDR);
for (tpp = addr_list; *tpp; tpp++) {
cleanup_rewrite_tree(*tpp);
* recipient addresses, and regenerate the header line. Finally, pipe the
* result through the header line folding routine.
*/
- tree = tok822_parse(vstring_str(header_buf) + strlen(hdr_opts->name) + 1,
- var_token_limit);
+ tree = tok822_parse_limit(vstring_str(header_buf)
+ + strlen(hdr_opts->name) + 1,
+ var_token_limit);
addr_list = tok822_grep(tree, TOK822_ADDR);
for (tpp = addr_list; *tpp; tpp++) {
cleanup_rewrite_tree(*tpp);
/*
* Add a missing (Resent-)From: header.
*/
-#define NO_TOKEN_LIMIT 0
-
if ((state->headers_seen & (1 << (state->resent[0] ?
HDR_RESENT_FROM : HDR_FROM))) == 0) {
quote_822_local(state->temp1, *state->sender ?
state->resent, vstring_str(state->temp1));
if (*state->sender && state->fullname && *state->fullname) {
vstring_sprintf(state->temp1, "(%s)", state->fullname);
- token = tok822_parse(vstring_str(state->temp1), NO_TOKEN_LIMIT);
+ token = tok822_parse(vstring_str(state->temp1));
vstring_strcat(state->temp2, " ");
tok822_externalize(state->temp2, token, TOK822_STR_NONE);
tok822_free_tree(token);
VSTRING *dst = vstring_alloc(100);
VSTRING *src = vstring_alloc(100);
-#define NO_TOKEN_LIMIT 0
-
tok822_externalize(src, tree->head, TOK822_STR_DEFL);
cleanup_rewrite_external(dst, STR(src));
tok822_free_tree(tree->head);
- tree->head = tok822_scan(STR(dst), &tree->tail, NO_TOKEN_LIMIT);
+ tree->head = tok822_scan(STR(dst), &tree->tail);
vstring_free(dst);
vstring_free(src);
}
test: $(TESTPROG)
+tests: test
+
$(LIB): $(OBJS)
$(AR) $(ARFL) $(LIB) $?
$(RANLIB) $(LIB)
-Wunused
DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
CFLAGS = $(DEBUG) $(OPT) $(DEFS)
-TESTPROG= quote_821_local error_unalias
+TESTPROG=
PROG = error
INC_DIR = ../../include
LIBS = ../../lib/libmaster.a ../../lib/libglobal.a ../../lib/libutil.a
test: $(TESTPROG)
+tests: test
+
update: ../../libexec/$(PROG)
../../libexec/$(PROG): $(PROG)
test: $(TESTPROG)
+tests: test
+
update: ../../libexec/$(PROG)
../../libexec/$(PROG): $(PROG)
timed_ipc.c tok822_find.c tok822_node.c tok822_parse.c \
tok822_resolve.c tok822_rewrite.c tok822_tree.c xtext.c bounce_log.c \
flush_clnt.c mail_conf_time.c mbox_conf.c mbox_open.c abounce.c \
- verp_sender.c match_parent_style.c mime_state.c header_token.c
+ verp_sender.c match_parent_style.c mime_state.c header_token.c \
+ strip_addr.c
OBJS = been_here.o bounce.o canon_addr.o cleanup_strerror.o clnt_stream.o \
debug_peer.o debug_process.o defer.o deliver_completed.o \
deliver_flock.o deliver_pass.o deliver_request.o domain_list.o \
timed_ipc.o tok822_find.o tok822_node.o tok822_parse.o \
tok822_resolve.o tok822_rewrite.o tok822_tree.o xtext.o bounce_log.o \
flush_clnt.o mail_conf_time.o mbox_conf.o mbox_open.o abounce.o \
- verp_sender.o match_parent_style.o mime_state.o header_token.o
+ verp_sender.o match_parent_style.o mime_state.o header_token.o \
+ strip_addr.o
HDRS = been_here.h bounce.h canon_addr.h cleanup_user.h clnt_stream.h \
config.h debug_peer.h debug_process.h defer.h deliver_completed.h \
deliver_flock.h deliver_pass.h deliver_request.h domain_list.h \
sys_exits.h timed_ipc.h tok822.h xtext.h bounce_log.h flush_clnt.h \
mbox_conf.h mbox_open.h abounce.h qmqp_proto.h verp_sender.h \
match_parent_style.h quote_flags.h mime_state.h header_token.h \
- lex_822.h
+ lex_822.h strip_addr.h
TESTSRC = rec2stream.c stream2rec.c recdump.c
WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \
-Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \
mail_addr_map mail_date maps mynetworks mypwd namadr_list \
off_cvt quote_822_local rec2stream recdump resolve_clnt \
resolve_local rewrite_clnt stream2rec string_list tok822_parse \
- quote_821_local mail_conf_time mime_state
+ quote_821_local mail_conf_time mime_state strip_addr
LIBS = ../../lib/libutil.a
LIB_DIR = ../../lib
$(CC) -DTEST $(CFLAGS) -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
mv junk $@.o
-tests: tok822_test mime_test mime_nest mime_8bit mime_dom mime_trunc
+strip_addr: $(LIB) $(LIBS)
+ mv $@.o junk
+ $(CC) -DTEST $(CFLAGS) -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
+ mv junk $@.o
+
+tests: tok822_test mime_test mime_nest mime_8bit mime_dom mime_trunc \
+ strip_addr_test tok822_limit_test
tok822_test: tok822_parse tok822_parse.in tok822_parse.ref
./tok822_parse <tok822_parse.in >tok822_parse.tmp
diff mime_trunc.ref mime_trunc.tmp
rm -f mime_trunc.tmp
+tok822_limit_test: tok822_parse tok822_limit.in tok822_limit.ref
+ ./tok822_parse <tok822_limit.in >tok822_limit.tmp
+ diff tok822_limit.ref tok822_limit.tmp
+ rm -f tok822_limit.tmp
+
printfck: $(OBJS) $(PROG)
rm -rf printfck
mkdir printfck
set -e; for i in *.c; do printfck -f .printfck $$i >printfck/$$i; done
cd printfck; make "INC_DIR=../../../include" `cd ..; ls *.o`
+strip_addr_test: strip_addr strip_addr.ref
+ ./strip_addr 2>strip_addr.tmp
+ diff strip_addr.ref strip_addr.tmp
+ rm -f strip_addr.tmp
lint:
lint $(DEFS) $(SRCS) $(LINTFIX)
mail_addr_find.o: ../../include/vstring.h
mail_addr_find.o: ../../include/mymalloc.h
mail_addr_find.o: mail_params.h
-mail_addr_find.o: split_addr.h
+mail_addr_find.o: strip_addr.h
mail_addr_find.o: mail_addr_find.h
mail_addr_find.o: maps.h
mail_addr_find.o: resolve_local.h
string_list.o: ../../include/match_list.h
string_list.o: string_list.h
string_list.o: ../../include/match_ops.h
+strip_addr.o: strip_addr.c
+strip_addr.o: ../../include/sys_defs.h
+strip_addr.o: ../../include/mymalloc.h
+strip_addr.o: split_addr.h
+strip_addr.o: strip_addr.h
sys_exits.o: sys_exits.c
sys_exits.o: ../../include/sys_defs.h
sys_exits.o: ../../include/msg.h
* the result to external (quoted) form. Optionally apply the extension
* to each address found.
*/
-#define NO_TOKEN_LIMIT 0
-
- tree = tok822_parse(string, NO_TOKEN_LIMIT);
+ tree = tok822_parse(string);
addr_list = tok822_grep(tree, TOK822_ADDR);
for (tpp = addr_list; *tpp; tpp++) {
tok822_externalize(extern_addr, tpp[0]->head, TOK822_STR_DEFL);
/* Global library. */
#include <mail_params.h>
-#include <split_addr.h>
+#include <strip_addr.h>
#include <mail_addr_find.h>
#include <resolve_local.h>
const char *result;
char *ratsign = 0;
char *full_key;
- char *extent;
char *bare_key;
char *saved_ext;
if (*var_rcpt_delim == 0) {
bare_key = saved_ext = 0;
} else {
- bare_key = mystrdup(full_key);
- if ((ratsign = strrchr(bare_key, '@')) != 0)
- *ratsign = 0;
- if ((extent = split_addr(bare_key, *var_rcpt_delim)) != 0) {
- extent -= 1;
- *extent = *var_rcpt_delim; /* XXX this is unclean */
- saved_ext = mystrdup(extent); /* XXX maybe omit delimiter ? */
- if (ratsign != 0) {
- *ratsign = '@';
- memmove(extent, ratsign, strlen(ratsign) + 1);
- }
- } else {
- myfree(bare_key);
- bare_key = saved_ext = 0;
- }
+ bare_key = strip_addr(full_key, &saved_ext, *var_rcpt_delim);
}
/*
#define DEF_SENDER_ROUTING 0
extern bool var_sender_routing;
+#define VAR_XPORT_NULL_KEY "transport_null_address_lookup_key"
+#define DEF_XPORT_NULL_KEY "<>"
+extern char *var_xport_null_key;
+
/* LICENSE
/* .ad
/* .fi
* Patches change the patchlevel and the release date. Snapshots change the
* release date only, unless they include the same bugfix as a patch release.
*/
-#define MAIL_RELEASE_DATE "20020605"
+#define MAIL_RELEASE_DATE "20020610"
#define VAR_MAIL_VERSION "mail_version"
#define DEF_MAIL_VERSION "1.1.11-" MAIL_RELEASE_DATE
/*
* Peek at the cache.
*/
- if (strcmp(addr, STR(last_addr)) == 0) {
+ if (*addr && strcmp(addr, STR(last_addr)) == 0) {
vstring_strcpy(reply->transport, STR(last_reply.transport));
vstring_strcpy(reply->nexthop, STR(last_reply.nexthop));
vstring_strcpy(reply->recipient, STR(last_reply.recipient));
STR(reply->nexthop), STR(reply->recipient));
if (STR(reply->transport)[0] == 0)
msg_warn("%s: null transport result for: <%s>", myname, addr);
- else if (STR(reply->recipient)[0] == 0)
+ else if (STR(reply->recipient)[0] == 0 && *addr != 0)
msg_warn("%s: null recipient result for: <%s>", myname, addr);
else
break;
--- /dev/null
+/*++
+/* NAME
+/* strip_addr 3
+/* SUMMARY
+/* strip extension from full or localpart-only address
+/* SYNOPSIS
+/* #include <strip_addr.h>
+/*
+/* char *strip_addr(address, extension, delimiter)
+/* const char *address;
+/* char **extension;
+/* int delimiter;
+/* DESCRIPTION
+/* strip_addr() takes an address and either returns a null
+/* pointer when the address contains no address extension,
+/* or returns a copy of the address without address extension.
+/* The caller is expected to pass the copy to myfree().
+/*
+/* Arguments:
+/* .IP address
+/* Address localpart or user@domain form.
+/* .IP extension
+/* A null pointer, or the address of a pointer that is set to
+/* the address of a dynamic memory copy of the address extension
+/* that had to be chopped off.
+/* The copy includes the recipient address delimiter.
+/* The caller is expected to pass the copy to myfree().
+/* .IP delimiter
+/* Recipient address delimiter.
+/* SEE ALSO
+/* split_addr(3) strip extension from localpart
+/* 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 library. */
+
+#include <sys_defs.h>
+#include <string.h>
+
+/* Utility library. */
+
+#include <mymalloc.h>
+
+/* Global library. */
+
+#include <split_addr.h>
+#include <strip_addr.h>
+
+/* strip_addr - strip extension from address */
+
+char *strip_addr(const char *full, char **extension, int delimiter)
+{
+ char *ratsign;
+ char *extent;
+ char *saved_ext;
+ char *stripped;
+
+ /*
+ * A quick test to eliminate inputs without delimiter anywhere.
+ */
+ if (delimiter == 0 || strchr(full, delimiter) == 0) {
+ stripped = saved_ext = 0;
+ } else {
+ stripped = mystrdup(full);
+ if ((ratsign = strrchr(stripped, '@')) != 0)
+ *ratsign = 0;
+ if ((extent = split_addr(stripped, delimiter)) != 0) {
+ extent -= 1;
+ if (extension) {
+ *extent = delimiter;
+ saved_ext = mystrdup(extent);
+ *extent = 0;
+ } else
+ saved_ext = 0;
+ if (ratsign != 0) {
+ *ratsign = '@';
+ memmove(extent, ratsign, strlen(ratsign) + 1);
+ }
+ } else {
+ myfree(stripped);
+ stripped = saved_ext = 0;
+ }
+ }
+ if (extension)
+ *extension = saved_ext;
+ return (stripped);
+}
+
+#ifdef TEST
+
+#include <msg.h>
+#include <mail_params.h>
+
+char *var_double_bounce_sender = DEF_DOUBLE_BOUNCE;
+
+int main(int unused_argc, char **unused_argv)
+{
+ char *extension;
+ char *stripped;
+ int delim = '-';
+
+ /*
+ * Incredible. This function takes only three arguments, and the tests
+ * already take more lines of code than the code being tested.
+ */
+ stripped = strip_addr("foo", (char **) 0, 0);
+ if (stripped != 0)
+ msg_panic("strip_addr botch 1");
+
+ stripped = strip_addr("foo", &extension, 0);
+ if (stripped != 0)
+ msg_panic("strip_addr botch 2");
+ if (extension != 0)
+ msg_panic("strip_addr botch 3");
+
+ stripped = strip_addr("foo", (char **) 0, delim);
+ if (stripped != 0)
+ msg_panic("strip_addr botch 4");
+
+ stripped = strip_addr("foo", &extension, delim);
+ if (stripped != 0)
+ msg_panic("strip_addr botch 5");
+ if (extension != 0)
+ msg_panic("strip_addr botch 6");
+
+ stripped = strip_addr("foo@bar", (char **) 0, 0);
+ if (stripped != 0)
+ msg_panic("strip_addr botch 7");
+
+ stripped = strip_addr("foo@bar", &extension, 0);
+ if (stripped != 0)
+ msg_panic("strip_addr botch 8");
+ if (extension != 0)
+ msg_panic("strip_addr botch 9");
+
+ stripped = strip_addr("foo@bar", (char **) 0, delim);
+ if (stripped != 0)
+ msg_panic("strip_addr botch 10");
+
+ stripped = strip_addr("foo@bar", &extension, delim);
+ if (stripped != 0)
+ msg_panic("strip_addr botch 11");
+ if (extension != 0)
+ msg_panic("strip_addr botch 12");
+
+ stripped = strip_addr("foo-ext", (char **) 0, 0);
+ if (stripped != 0)
+ msg_panic("strip_addr botch 13");
+
+ stripped = strip_addr("foo-ext", &extension, 0);
+ if (stripped != 0)
+ msg_panic("strip_addr botch 14");
+ if (extension != 0)
+ msg_panic("strip_addr botch 15");
+
+ stripped = strip_addr("foo-ext", (char **) 0, delim);
+ if (stripped == 0)
+ msg_panic("strip_addr botch 16");
+ msg_info("wanted: foo-ext -> %s", "foo");
+ msg_info("strip_addr foo-ext -> %s", stripped);
+ myfree(stripped);
+
+ stripped = strip_addr("foo-ext", &extension, delim);
+ if (stripped == 0)
+ msg_panic("strip_addr botch 17");
+ if (extension == 0)
+ msg_panic("strip_addr botch 18");
+ msg_info("wanted: foo-ext -> %s %s", "foo", "-ext");
+ msg_info("strip_addr foo-ext -> %s %s", stripped, extension);
+ myfree(stripped);
+ myfree(extension);
+
+ stripped = strip_addr("foo-ext@bar", (char **) 0, 0);
+ if (stripped != 0)
+ msg_panic("strip_addr botch 19");
+
+ stripped = strip_addr("foo-ext@bar", &extension, 0);
+ if (stripped != 0)
+ msg_panic("strip_addr botch 20");
+ if (extension != 0)
+ msg_panic("strip_addr botch 21");
+
+ stripped = strip_addr("foo-ext@bar", (char **) 0, delim);
+ if (stripped == 0)
+ msg_panic("strip_addr botch 22");
+ msg_info("wanted: foo-ext@bar -> %s", "foo@bar");
+ msg_info("strip_addr foo-ext@bar -> %s", stripped);
+ myfree(stripped);
+
+ stripped = strip_addr("foo-ext@bar", &extension, delim);
+ if (stripped == 0)
+ msg_panic("strip_addr botch 23");
+ if (extension == 0)
+ msg_panic("strip_addr botch 24");
+ msg_info("wanted: foo-ext@bar -> %s %s", "foo@bar", "-ext");
+ msg_info("strip_addr foo-ext@bar -> %s %s", stripped, extension);
+ myfree(stripped);
+ myfree(extension);
+
+ return (0);
+}
+
+#endif
--- /dev/null
+#ifndef _STRIP_ADDR_H_INCLUDED_
+#define _STRIP_ADDR_H_INCLUDED_
+
+/*++
+/* NAME
+/* strip_addr 3h
+/* SUMMARY
+/* strip extension from full address
+/* SYNOPSIS
+/* #include <strip_addr.h>
+/* DESCRIPTION
+/* .nf
+
+ /* External interface. */
+
+extern char *strip_addr(const char *, char **, int);
+
+/* 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
--- /dev/null
+unknown: wanted: foo-ext -> foo
+unknown: strip_addr foo-ext -> foo
+unknown: wanted: foo-ext -> foo -ext
+unknown: strip_addr foo-ext -> foo -ext
+unknown: wanted: foo-ext@bar -> foo@bar
+unknown: strip_addr foo-ext@bar -> foo@bar
+unknown: wanted: foo-ext@bar -> foo@bar -ext
+unknown: strip_addr foo-ext@bar -> foo@bar -ext
/*
* tok822_parse.c
*/
-extern TOK822 *tok822_scan(const char *, TOK822 **, int);
+extern TOK822 *tok822_scan_limit(const char *, TOK822 **, int);
extern TOK822 *tok822_scan_addr(const char *);
-extern TOK822 *tok822_parse(const char *, int);
+extern TOK822 *tok822_parse_limit(const char *, int);
extern VSTRING *tok822_externalize(VSTRING *, TOK822 *, int);
extern VSTRING *tok822_internalize(VSTRING *, TOK822 *, int);
+#define tok822_scan(cp, ptr) tok822_scan_limit((cp), (ptr), 0)
+#define tok822_parse(cp) tok822_parse_limit((cp), 0)
+
#define TOK822_STR_NONE (0)
#define TOK822_STR_WIPE (1<<0)
#define TOK822_STR_TERM (1<<1)
--- /dev/null
+1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
--- /dev/null
+>>>1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22<<<
+
+Parse tree:
+ address
+ atom "1"
+ OP ","
+ address
+ atom "2"
+ OP ","
+ address
+ atom "3"
+ OP ","
+ address
+ atom "4"
+ OP ","
+ address
+ atom "5"
+ OP ","
+ address
+ atom "6"
+ OP ","
+ address
+ atom "7"
+ OP ","
+ address
+ atom "8"
+ OP ","
+ address
+ atom "9"
+ OP ","
+ address
+ atom "10"
+ OP ","
+ address
+ atom "11"
+ OP ","
+ address
+ atom "12"
+ OP ","
+ address
+ atom "13"
+ OP ","
+ address
+ atom "14"
+ OP ","
+ address
+ atom "15"
+ OP ","
+ address
+ atom "16"
+ OP ","
+ address
+ atom "17"
+ OP ","
+ address
+ atom "18"
+ OP ","
+ address
+ atom "19"
+ OP ","
+ address
+ atom "20"
+
+Internalized:
+1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
+
+Externalized, no newlines inserted:
+1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
+
+Externalized, newlines inserted:
+1,
+2,
+3,
+4,
+5,
+6,
+7,
+8,
+9,
+10,
+11,
+12,
+13,
+14,
+15,
+16,
+17,
+18,
+19,
+20
+
/* SYNOPSIS
/* #include <tok822.h>
/*
-/* TOK822 *tok822_scan(str, tailp, limit)
+/* TOK822 *tok822_scan_limit(str, tailp, limit)
/* const char *str;
/* TOK822 **tailp;
/* int limit;
/*
-/* TOK822 *tok822_parse(str, limit)
+/* TOK822 *tok822_scan(str, tailp)
+/* const char *str;
+/* TOK822 **tailp;
+/*
+/* TOK822 *tok822_parse_limit(str, limit)
/* const char *str;
/* int limit;
/*
+/* TOK822 *tok822_parse(str)
+/* const char *str;
+/*
/* TOK822 *tok822_scan_addr(str)
/* const char *str;
/*
/* tok822_scan() converts the external-form string in \fIstr\fR
/* to a linear token list. The \fItailp\fR argument is a null pointer
/* or receives the pointer value of the last result list element.
+/*
+/* tok822_scan_limit() implements tok822_scan(), which is a macro.
/* The \fIlimit\fR argument is either zero or an upper bound on the
/* number of tokens produced.
/*
/* \fIstr\fR to the corresponding token tree. The parser is permissive
/* and will not throw away information that it does not understand.
/* The parser adds missing commas between addresses.
+/*
+/* tok822_parse_limit() implements tok822_parse(), which is a macro.
/* The \fIlimit\fR argument is either zero or an upper bound on the
/* number of tokens produced.
/*
return (NON_OPERATOR(tp) && NON_OPERATOR(next));
}
-/* tok822_scan - tokenize string */
+/* tok822_scan_limit - tokenize string */
-TOK822 *tok822_scan(const char *str, TOK822 **tailp, int tok_count_limit)
+TOK822 *tok822_scan_limit(const char *str, TOK822 **tailp, int tok_count_limit)
{
TOK822 *head = 0;
TOK822 *tail = 0;
return (head);
}
-/* tok822_parse - translate external string to token tree */
+/* tok822_parse_limit - translate external string to token tree */
-TOK822 *tok822_parse(const char *str, int tok_count_limit)
+TOK822 *tok822_parse_limit(const char *str, int tok_count_limit)
{
TOK822 *head;
TOK822 *tail;
* token list that contains all tokens, we can always convert back to
* string form.
*/
- if ((first_token = tok822_scan(str, &last_token, tok_count_limit)) == 0)
+ if ((first_token = tok822_scan_limit(str, &last_token, tok_count_limit)) == 0)
return (0);
/*
{
TOK822 *tree = tok822_alloc(TOK822_ADDR, (char *) 0);
- tree->head = tok822_scan(addr, &tree->tail, 0);
+ tree->head = tok822_scan(addr, &tree->tail);
return (tree);
}
}
if (!isatty(vstream_fileno(VSTREAM_IN)))
vstream_printf(">>>%s<<<\n\n", vstring_str(buf));
- list = tok822_parse(vstring_str(buf), TEST_TOKEN_LIMIT);
+ list = tok822_parse_limit(vstring_str(buf), TEST_TOKEN_LIMIT);
vstream_printf("Parse tree:\n");
tok822_print(list, 0);
vstream_printf("\n");
* the result. Shipping external form is much simpler than shipping parse
* trees.
*/
-#define NO_TOKEN_LIMIT 0
-
tok822_externalize(input_ext_form, addr->head, TOK822_STR_DEFL);
if (msg_verbose)
msg_info("tok822_rewrite: input: %s", vstring_str(input_ext_form));
if (msg_verbose)
msg_info("tok822_rewrite: result: %s", vstring_str(canon_ext_form));
tok822_free_tree(addr->head);
- addr->head = tok822_scan(vstring_str(canon_ext_form), &addr->tail,
- NO_TOKEN_LIMIT);
+ addr->head = tok822_scan(vstring_str(canon_ext_form), &addr->tail);
vstring_free(input_ext_form);
vstring_free(canon_ext_form);
-Wunused
DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
CFLAGS = $(DEBUG) $(OPT) $(DEFS)
-TESTPROG= quote_821_local
+TESTPROG=
PROG = lmtp
INC_DIR = ../../include
LIBS = ../../lib/libmaster.a ../../lib/libglobal.a ../../lib/libdns.a ../../lib/libutil.a
test: $(TESTPROG)
+tests: test
+
update: ../../libexec/$(PROG)
../../libexec/$(PROG): $(PROG)
tidy: clean
-quote_821_local: quote_821_local.c $(LIBS)
- $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIBS) $(SYSLIBS)
-
depend: $(MAKES)
(sed '1,/^# do not edit/!d' Makefile.in; \
set -e; for i in [a-z][a-z0-9]*.c; do \
test: $(TESTPROG)
+tests: test
+
update: ../../libexec/$(PROG)
../../libexec/$(PROG): $(PROG)
if (msg_verbose)
msg_info("deliver_token_string: %s", string);
-#define NO_TOKEN_LIMIT 0
-
- tree = tok822_parse(string, NO_TOKEN_LIMIT);
+ tree = tok822_parse(string);
for (addr = tree; addr != 0; addr = addr->next) {
if (addr->type == TOK822_ADDR) {
if (addr_count)
test: $(TESTPROG)
+tests: test
+
$(LIB): $(LIB_OBJ)
$(AR) $(ARFL) $(LIB) $?
$(RANLIB) $(LIB)
test: $(TESTPROG)
+tests: test
+
update: ../../libexec/n$(PROG)
../../libexec/n$(PROG): $(PROG)
if (!STREQ(recipient->address, STR(reply.recipient)))
UPDATE(recipient->address, STR(reply.recipient));
}
+ if (recipient->address[0] == 0) {
+ qmgr_bounce_recipient(message, recipient,
+ "null recipient address");
+ continue;
+ }
/*
* XXX The nexthop destination is also used as lookup key for the
test: $(TESTPROG)
+tests: test
+
update: ../../libexec/$(PROG)
../../libexec/$(PROG): $(PROG)
-Wunused
DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
CFLAGS = $(DEBUG) $(OPT) $(DEFS)
-TESTPROG= quote_821_local pipe_unalias
+TESTPROG=
PROG = pipe
INC_DIR = ../../include
LIBS = ../../lib/libmaster.a ../../lib/libglobal.a ../../lib/libutil.a
test: $(TESTPROG)
+tests: test
+
update: ../../libexec/$(PROG)
../../libexec/$(PROG): $(PROG)
update: ../../bin/$(PROG)
-test: test1 test2
+tests: test1 test2
test1: $(PROG) map.in map-abc1.ref map-ghi1.ref map-ABC1.ref
./$(PROG) map.in
* Tokenize the input, so that we do the right thing when a quoted
* localpart contains special characters such as "@", ":" and so on.
*/
-#define NO_TOKEN_LIMIT 0
-
- if ((tok_list = tok822_scan(STR(line_buffer), (TOK822 **) 0,
- NO_TOKEN_LIMIT)) == 0)
+ if ((tok_list = tok822_scan(STR(line_buffer), (TOK822 **) 0)) == 0)
continue;
/*
test: $(TESTPROG)
+tests: test
+
update: ../../bin/$(PROG)
../../bin/$(PROG): $(PROG)
test: $(TESTPROG)
+tests: test
+
update: ../../bin/$(PROG) $(SAMPLES)
../../bin/$(PROG): $(PROG)
test: $(TESTPROG)
+tests: test
+
update: ../../bin/$(PROG)
../../bin/$(PROG): $(PROG)
test: $(TESTPROG)
+tests: test
+
update: ../../bin/$(PROG)
../../bin/$(PROG): $(PROG)
test: $(TESTPROG)
+tests: test
+
update: ../../bin/$(PROG)
../../bin/$(PROG): $(PROG)
test: $(TESTPROG)
+tests: test
+
update: ../../bin/$(PROG)
../../bin/$(PROG): $(PROG)
test: $(TESTPROG)
+tests: test
+
update: ../../bin/$(PROG)
../../bin/$(PROG): $(PROG)
../../bin/$(PROG): $(PROG)
cp $(PROG) ../../bin
-test: test1 test2
+tests: test1 test2
test1: $(PROG) map.in map-abc1.ref map-ghi1.ref map-ABC1.ref
./$(PROG) map.in
test: $(TESTPROG)
+tests: test
+
update: ../../bin/$(PROG)
../../bin/$(PROG): $(PROG)
test: $(TESTPROG)
+tests: test
+
update: ../../bin/$(PROG)
../../bin/$(PROG): $(PROG)
test: $(TESTPROG)
+tests: test
+
update: ../../libexec/$(PROG)
../../libexec/$(PROG): $(PROG)
if (!STREQ(recipient->address, STR(reply.recipient)))
UPDATE(recipient->address, STR(reply.recipient));
}
+ if (recipient->address[0] == 0) {
+ qmgr_bounce_recipient(message, recipient,
+ "null recipient address");
+ continue;
+ }
/*
* XXX The nexthop destination is also used as lookup key for the
-Wunused
DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
CFLAGS = $(DEBUG) $(OPT) $(DEFS)
-TESTPROG= qmqpd_token qmqpd_check
+TESTPROG=
PROG = qmqpd
INC_DIR = ../../include
LIBS = ../../lib/libmaster.a ../../lib/libglobal.a ../../lib/libdns.a ../../lib/libutil.a
test: $(TESTPROG)
+tests: test
+
update: ../../libexec/$(PROG)
../../libexec/$(PROG): $(PROG)
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
@$(EXPORT) make -f Makefile.in Makefile 1>&2
-tests:
-
# do not edit below this line - it is generated by 'make depend'
qmqpd.o: qmqpd.c
qmqpd.o: ../../include/sys_defs.h
test: $(TESTPROG)
+tests: test
+
update: ../../bin/$(PROG)
../../bin/$(PROG): $(PROG)
* pickup would not be able to run chrooted, and it may not be desirable
* to use login names at all.
*/
-#define NO_TOKEN_LIMIT 0
-
if (sender != 0) {
- tree = tok822_parse(sender, NO_TOKEN_LIMIT);
+ tree = tok822_parse(sender);
for (naddr = 0, tp = tree; tp != 0; tp = tp->next)
if (tp->type == TOK822_ADDR)
naddr++, tok822_internalize(buf, tp->head, TOK822_STR_DEFL);
rec_fputs(dst, REC_TYPE_VERP, verp_delims);
if (recipients) {
for (cpp = recipients; *cpp != 0; cpp++) {
- tree = tok822_parse(*cpp, NO_TOKEN_LIMIT);
+ tree = tok822_parse(*cpp);
for (tp = tree; tp != 0; tp = tp->next) {
if (tp->type == TOK822_ADDR) {
tok822_internalize(buf, tp->head, TOK822_STR_DEFL);
test: $(TESTPROG)
+tests: test
+
update: ../../libexec/$(PROG)
../../libexec/$(PROG): $(PROG)
test: $(TESTPROG)
+tests: test
+
update: ../../libexec/$(PROG)
../../libexec/$(PROG): $(PROG)
smtpd_check.o: ../../include/maps.h
smtpd_check.o: ../../include/mail_addr_find.h
smtpd_check.o: ../../include/match_parent_style.h
-smtpd_check.o: ../../include/split_addr.h
+smtpd_check.o: ../../include/strip_addr.h
smtpd_check.o: smtpd.h
smtpd_check.o: ../../include/mail_stream.h
smtpd_check.o: smtpd_sasl_glue.h
* XXX We have only one address parser, written according to the rules of
* RFC 822. That standard differs subtly from RFC 821.
*/
-#define NO_TOKEN_LIMIT 0
-
if (msg_verbose)
msg_info("%s: input: %s", myname, STR(arg->vstrval));
if (STR(arg->vstrval)[0] == '<'
&& STR(arg->vstrval)[LEN(arg->vstrval) - 1] == '>') {
junk = mystrndup(STR(arg->vstrval) + 1, LEN(arg->vstrval) - 2);
- tree = tok822_parse(junk, NO_TOKEN_LIMIT);
+ tree = tok822_parse(junk);
myfree(junk);
} else
- tree = tok822_parse(STR(arg->vstrval), NO_TOKEN_LIMIT);
+ tree = tok822_parse(STR(arg->vstrval));
/*
* Find trouble.
recipient_restrictions hash:./smtpd_check_access
# Expect: REJECT
rcpt reject@dunno.domain
+# Expect: REJECT
+recipient_delimiter +
+rcpt reject+ext@dunno.domain
+recipient_delimiter |
# Expect: OK
rcpt ok@dunno.domain
# Expect: OK
+recipient_delimiter +
+rcpt ok+ext@dunno.domain
+recipient_delimiter |
+# Expect: OK
rcpt anyone@dunno.domain
# Expect: OK
rcpt bad-sender@dunno.domain
>>> rcpt reject@dunno.domain
./smtpd_check: reject: RCPT from bar.duno.com[44.33.44.33]: 554 <reject@dunno.domain>: Recipient address rejected: Access denied; from=<bad-sender@ok.domain> to=<reject@dunno.domain>
554 <reject@dunno.domain>: Recipient address rejected: Access denied
+>>> # Expect: REJECT
+>>> recipient_delimiter +
+OK
+>>> rcpt reject+ext@dunno.domain
+./smtpd_check: reject: RCPT from bar.duno.com[44.33.44.33]: 554 <reject+ext@dunno.domain>: Recipient address rejected: Access denied; from=<bad-sender@ok.domain> to=<reject+ext@dunno.domain>
+554 <reject+ext@dunno.domain>: Recipient address rejected: Access denied
+>>> recipient_delimiter |
+OK
>>> # Expect: OK
>>> rcpt ok@dunno.domain
OK
>>> # Expect: OK
+>>> recipient_delimiter +
+OK
+>>> rcpt ok+ext@dunno.domain
+OK
+>>> recipient_delimiter |
+OK
+>>> # Expect: OK
>>> rcpt anyone@dunno.domain
OK
>>> # Expect: OK
#include <maps.h>
#include <mail_addr_find.h>
#include <match_parent_style.h>
-#include <split_addr.h>
+#include <strip_addr.h>
/* Application-specific. */
int status;
char *local_at;
char *bare_addr;
- char *bare_ext;
char *bare_at;
if (msg_verbose)
if (*var_rcpt_delim == 0) {
bare_addr = 0;
} else {
- bare_addr = mystrdup(addr);
- if ((bare_at = strrchr(bare_addr, '@')) != 0)
- *bare_at = 0;
- if ((bare_ext = split_addr(bare_addr, *var_rcpt_delim)) != 0) {
- if (bare_at != 0) {
- *bare_at = '@';
- memmove(bare_ext - 1, bare_at, strlen(bare_at) + 1);
- bare_at = bare_ext - 1;
- }
- } else {
- myfree(bare_addr);
- bare_addr = 0;
- }
+ bare_addr = strip_addr(addr, (char **) 0, *var_rcpt_delim);
}
#define CHECK_MAIL_ACCESS_RETURN(x) \
* Look up user@ if the address has an extension. XXX Same problem here.
*/
if (bare_addr) {
+ bare_at = strrchr(bare_addr, '@');
local_at = (bare_at ? mystrndup(bare_addr, bare_at + 1 - bare_addr) :
mystrdup(bare_addr));
status = check_access(state, table, local_at, PARTIAL, found,
char *var_par_dom_match;
char *var_smtpd_null_key;
char *var_smtpd_snd_auth_maps;
+char *var_double_bounce_sender;
typedef struct {
char *name;
VAR_PAR_DOM_MATCH, DEF_PAR_DOM_MATCH, &var_par_dom_match,
VAR_SMTPD_SND_AUTH_MAPS, DEF_SMTPD_SND_AUTH_MAPS, &var_smtpd_snd_auth_maps,
VAR_SMTPD_NULL_KEY, DEF_SMTPD_NULL_KEY, &var_smtpd_null_key,
+ VAR_DOUBLE_BOUNCE, DEF_DOUBLE_BOUNCE, &var_double_bounce_sender,
0,
};
vstring_free(reply->recipient);
}
-#ifdef USE_SASL_AUTH
-
bool var_smtpd_sasl_enable = 0;
+#ifdef USE_SASL_AUTH
+
/* smtpd_sasl_connect - stub */
void smtpd_sasl_connect(SMTPD_STATE *state)
test: $(TESTPROG)
+tests: test
+
update: ../../bin/smtp-source ../../bin/smtp-sink ../../bin/qmqp-source
../../bin/smtp-source: smtp-source
test: $(TESTPROG)
+tests: test
+
update: ../../libexec/$(PROG)
../../libexec/$(PROG): $(PROG)
test: $(TESTPROG)
+tests: test
+
$(BIN_DIR)/$(PROG): $(PROG)
cp $(PROG) $@
transport.o: ../../include/dict.h
transport.o: ../../include/vstream.h
transport.o: ../../include/argv.h
+transport.o: ../../include/strip_addr.h
transport.o: ../../include/mail_params.h
transport.o: ../../include/maps.h
transport.o: ../../include/match_parent_style.h
/*
* A lone empty string becomes the postmaster.
*/
-#define NO_TOKEN_LIMIT 0
-
if (tree->head == tree->tail && tree->head->type == TOK822_QSTRING
&& VSTRING_LEN(tree->head->vstr) == 0) {
tok822_free(tree->head);
- tree->head = tok822_scan(MAIL_ADDR_POSTMASTER, &tree->tail,
- NO_TOKEN_LIMIT);
+ tree->head = tok822_scan(MAIL_ADDR_POSTMASTER, &tree->tail);
rewrite_tree(REWRITE_CANON, tree);
}
if (saved_domain) {
tok822_sub_append(tree, saved_domain);
saved_domain = 0;
- } else {
+ } else if (tree->head) {
tok822_sub_append(tree, tok822_alloc('@', (char *) 0));
- tok822_sub_append(tree, tok822_scan(var_myhostname, (TOK822 **) 0,
- NO_TOKEN_LIMIT));
+ tok822_sub_append(tree, tok822_scan(var_myhostname, (TOK822 **) 0));
}
}
tok822_internalize(nextrcpt, tree, TOK822_STR_DEFL);
* transport maps cannot return zero-length hostnames.
*/
if (*var_transport_maps)
- transport_lookup(strrchr(STR(nextrcpt), '@') + 1, channel, nexthop);
+ transport_lookup(STR(nextrcpt), channel, nexthop);
/*
* Clean up.
/*
* Append missing @origin
*/
-#define NO_TOKEN_LIMIT 0
-
else if (var_append_at_myorigin != 0) {
domain = tok822_sub_append(tree, tok822_alloc('@', (char *) 0));
- tok822_sub_append(tree, tok822_scan(var_myorigin, (TOK822 **) 0,
- NO_TOKEN_LIMIT));
+ tok822_sub_append(tree, tok822_scan(var_myorigin, (TOK822 **) 0));
}
}
&& tok822_find_type(domain, TOK822_DOMLIT) == 0
&& tok822_find_type(domain, '.') == 0) {
tok822_sub_append(tree, tok822_alloc('.', (char *) 0));
- tok822_sub_append(tree, tok822_scan(var_mydomain, (TOK822 **) 0,
- NO_TOKEN_LIMIT));
+ tok822_sub_append(tree, tok822_scan(var_mydomain, (TOK822 **) 0));
}
/*
/*
/* void transport_init()
/*
-/* int transport_lookup(domain, channel, nexthop)
-/* const char *domain;
+/* int transport_lookup(address, channel, nexthop)
+/* const char *address;
/* VSTRING *channel;
/* VSTRING *nexthop;
/* DESCRIPTION
/* This module implements access to the table that maps transport
-/* domains to (channel, nexthop) tuples.
+/* user@domain addresses to (channel, nexthop) tuples.
/*
/* transport_init() performs initializations that should be
/* done before the process enters the chroot jail, and
/* should be tried again.
/* SEE ALSO
/* maps(3), multi-dictionary search
+/* strip_addr(3), strip extension from address
/* transport(5), format of transport map
/* FILES
/* /etc/postfix/transport*
/* Global library. */
+#include <strip_addr.h>
#include <mail_params.h>
#include <maps.h>
#include <match_parent_style.h>
}
}
+/* check_maps_find - map lookup with extreme prejudice */
+
+static const char *check_maps_find(MAPS *maps, const char *key, int flags)
+{
+ const char *value;
+
+ if ((value = maps_find(maps, key, flags)) == 0 && dict_errno != 0)
+ msg_fatal("transport table lookup problem.");
+ return (value);
+}
+
/* transport_lookup - map a transport domain */
-int transport_lookup(const char *domain, VSTRING *channel, VSTRING *nexthop)
+int transport_lookup(const char *addr, VSTRING *channel, VSTRING *nexthop)
{
- char *low_domain = lowercase(mystrdup(domain));
+ char *full_addr = lowercase(mystrdup(*addr ? addr : var_xport_null_key));
+ char *stripped_addr = 0;
+ char *ratsign = 0;
const char *name;
const char *next;
const char *value;
#define FULL 0
#define PARTIAL DICT_FLAG_FIXED
-
- int maps_flag = FULL;
+#define STRNE strcmp
+#define DISCARD_EXTENSION ((char **) 0)
if (transport_path == 0)
msg_panic("transport_lookup: missing initialization");
+ if (STRNE(full_addr, var_xport_null_key) && STRNE(full_addr, "*"))
+ if ((ratsign = strrchr(full_addr, '@')) == 0)
+ msg_panic("transport_lookup: bad address: \"%s\"", full_addr);
+
+ /*
+ * Look up the full address with the FULL flag to include regexp maps in
+ * the query.
+ */
+ if ((value = check_maps_find(transport_path, full_addr, FULL)) != 0) {
+ found = 1;
+ }
+
+ /*
+ * If this is a special address such as <> or *, not user@domain, then we
+ * are done now.
+ */
+ else if (ratsign == 0) {
+ found = 0;
+ }
+
+ /*
+ * If the full address did not match, and there is an address extension,
+ * look up the stripped address with the PARTIAL flag to avoid matching
+ * partial lookup keys with regular expressions.
+ */
+ else if ((stripped_addr = strip_addr(full_addr, DISCARD_EXTENSION,
+ *var_rcpt_delim)) != 0
+ && (value = check_maps_find(transport_path, stripped_addr,
+ PARTIAL)) != 0) {
+ found = 1;
+ }
+
/*
+ * If the full and stripped address lookup fails, try domain name lookup.
+ *
* Keep stripping domain components until nothing is left or until a
* matching entry is found.
*
- * If the entry specifies no nexthop host and/or delivery channel, do not
- * change caller-provided information.
- *
- * If we find no match, then return the wildcard entry, if any.
- *
- * After checking the full name, check for .upper.domain, to distinguish
- * between the upper domain and it's decendants, ala sendmail and tcp
- * wrappers.
+ * After checking the full domain name, check for .upper.domain, to
+ * distinguish between the parent domain and it's decendants, a la
+ * sendmail and tcp wrappers.
*
* Before changing the DB lookup result, make a copy first, in order to
* avoid DB cache corruption.
*
- * Specify if a key is partial or full, to avoid matching partial keys with
- * regular expressions.
+ * Specify that the lookup key is partial, to avoid matching partial keys
+ * with regular expressions.
+ */
+ else if (found == 0) {
+ for (name = ratsign + 1; /* void */ ; name = next) {
+ if ((value = maps_find(transport_path, name, PARTIAL)) != 0) {
+ found = 1;
+ break;
+ }
+ if ((next = strchr(name + 1, '.')) == 0)
+ break;
+ if (transport_match_parent_style == MATCH_FLAG_PARENT)
+ next++;
+ }
+ }
+
+ /*
+ * XXX user+ext@ and user@ lookups for domains that resolve locally?
*/
- for (name = low_domain; /* void */ ; name = next) {
- if ((value = maps_find(transport_path, name, maps_flag)) != 0) {
- saved_value = mystrdup(value);
- if ((host = split_at(saved_value, ':')) != 0 && *host != 0)
+
+ /*
+ * We found an answer in the transport table. Use the results to
+ * override transport and/or next-hop information.
+ */
+ if (found == 1) {
+ saved_value = mystrdup(value);
+ if ((host = split_at(saved_value, ':')) != 0 && *host != 0) {
+#if 0
+ if (strchr(host, '@'))
+ vstring_strcpy(recipient, host);
+ else
+#endif
vstring_strcpy(nexthop, host);
- if (*(transport = saved_value) != 0)
- vstring_strcpy(channel, transport);
- myfree(saved_value);
- found = 1;
- break;
- } else if (dict_errno != 0) {
- msg_fatal("transport table lookup problem");
}
- if ((next = strchr(name + 1, '.')) == 0)
- break;
- if (transport_match_parent_style == MATCH_FLAG_PARENT)
- next++;
- maps_flag = PARTIAL;
+ if (*(transport = saved_value) != 0)
+ vstring_strcpy(channel, transport);
+ myfree(saved_value);
}
- myfree(low_domain);
+
+ /*
+ * Clean up.
+ */
+ myfree(full_addr);
+ if (stripped_addr)
+ myfree(stripped_addr);
/*
* Fall back to the wild-card entry.
/* .IP \fBtransport_maps\fR
/* List of tables with \fIdomain\fR to (\fItransport, nexthop\fR)
/* mappings.
+/* .IP \fBtransport_null_address_lookup_key\fR
+/* Lookup key to be used for the null address.
/* SEE ALSO
/* master(8) process manager
/* syslogd(8) system logging
bool var_percent_hack;
char *var_local_transport;
int var_resolve_dequoted;
+char *var_xport_null_key;
/* rewrite_service - read request and send reply */
static CONFIG_STR_TABLE str_table[] = {
VAR_TRANSPORT_MAPS, DEF_TRANSPORT_MAPS, &var_transport_maps, 0, 0,
VAR_LOCAL_TRANSPORT, DEF_LOCAL_TRANSPORT, &var_local_transport, 0, 0,
+ VAR_XPORT_NULL_KEY, DEF_XPORT_NULL_KEY, &var_xport_null_key, 1, 0,
0,
};
static CONFIG_BOOL_TABLE bool_table[] = {
test: $(TESTPROG)
+tests: test
+
update: ../../libexec/$(PROG)
../../libexec/$(PROG): $(PROG)