]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-1.1.11-20020610
authorWietse Venema <wietse@porcupine.org>
Mon, 10 Jun 2002 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:28:03 +0000 (06:28 +0000)
74 files changed:
postfix/HISTORY
postfix/Makefile.in
postfix/RELEASE_NOTES
postfix/conf/sample-resource.cf
postfix/conf/transport
postfix/html/basic.html
postfix/html/transport.5.html
postfix/html/trivial-rewrite.8.html
postfix/man/man5/transport.5
postfix/man/man8/trivial-rewrite.8
postfix/proto/transport
postfix/src/bounce/Makefile.in
postfix/src/cleanup/Makefile.in
postfix/src/cleanup/cleanup_map11.c
postfix/src/cleanup/cleanup_masquerade.c
postfix/src/cleanup/cleanup_message.c
postfix/src/cleanup/cleanup_rewrite.c
postfix/src/dns/Makefile.in
postfix/src/error/Makefile.in
postfix/src/flush/Makefile.in
postfix/src/global/Makefile.in
postfix/src/global/mail_addr_crunch.c
postfix/src/global/mail_addr_find.c
postfix/src/global/mail_params.h
postfix/src/global/mail_version.h
postfix/src/global/resolve_clnt.c
postfix/src/global/strip_addr.c [new file with mode: 0644]
postfix/src/global/strip_addr.h [new file with mode: 0644]
postfix/src/global/strip_addr.ref [new file with mode: 0644]
postfix/src/global/tok822.h
postfix/src/global/tok822_limit.in [new file with mode: 0644]
postfix/src/global/tok822_limit.ref [new file with mode: 0644]
postfix/src/global/tok822_parse.c
postfix/src/global/tok822_rewrite.c
postfix/src/lmtp/Makefile.in
postfix/src/local/Makefile.in
postfix/src/local/token.c
postfix/src/master/Makefile.in
postfix/src/nqmgr/Makefile.in
postfix/src/nqmgr/qmgr_message.c
postfix/src/pickup/Makefile.in
postfix/src/pipe/Makefile.in
postfix/src/postalias/Makefile.in
postfix/src/postalias/postalias.c
postfix/src/postcat/Makefile.in
postfix/src/postconf/Makefile.in
postfix/src/postdrop/Makefile.in
postfix/src/postfix/Makefile.in
postfix/src/postkick/Makefile.in
postfix/src/postlock/Makefile.in
postfix/src/postlog/Makefile.in
postfix/src/postmap/Makefile.in
postfix/src/postqueue/Makefile.in
postfix/src/postsuper/Makefile.in
postfix/src/qmgr/Makefile.in
postfix/src/qmgr/qmgr_message.c
postfix/src/qmqpd/Makefile.in
postfix/src/sendmail/Makefile.in
postfix/src/sendmail/sendmail.c
postfix/src/showq/Makefile.in
postfix/src/smtp/Makefile.in
postfix/src/smtpd/Makefile.in
postfix/src/smtpd/smtpd.c
postfix/src/smtpd/smtpd_acl.in
postfix/src/smtpd/smtpd_acl.ref
postfix/src/smtpd/smtpd_check.c
postfix/src/smtpstone/Makefile.in
postfix/src/spawn/Makefile.in
postfix/src/trivial-rewrite/Makefile.in
postfix/src/trivial-rewrite/resolve.c
postfix/src/trivial-rewrite/rewrite.c
postfix/src/trivial-rewrite/transport.c
postfix/src/trivial-rewrite/trivial-rewrite.c
postfix/src/virtual/Makefile.in

index 9d8a06eba049e82f948e397a47b6427f2bf704f9..d319941eb7b84a766162cc7fc4bd9d6827676075 100644 (file)
@@ -6598,9 +6598,9 @@ Apologies for any names omitted.
        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
 
@@ -6609,6 +6609,20 @@ Apologies for any names omitted.
        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
index 70bb65c824715bc2cd6ebe92a241e0f2715aee3e..7395b3a253b2b0e05e27a7327bcc61e5bd0c89e5 100644 (file)
@@ -18,7 +18,7 @@ makefiles Makefiles:
        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
index 4610c389d21bebe0b4f6f36f668cc5fd46d4e433..bf097f5ebdcde80b527509386262f13e6e5c9759 100644 (file)
@@ -12,6 +12,31 @@ snapshot release).  Patches change the patchlevel and the release
 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
 ==========================================================
 
index c6cdbc32f8ca51d08f7e84d30c578e37a8db0fe7..7e24abd621e5c9d6848736520ea59cd22ba038c7 100644 (file)
@@ -66,10 +66,10 @@ fork_delay = 1s
 #
 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
 
index 3e5aece89461f94ef7694d6e4f7c532700737534..52b9a87eeec8a22d6416aa7c12ea4cc9be1b7d2e 100644 (file)
@@ -8,7 +8,7 @@
 # 
 # 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)
index 26db800a86150d1480de3baa0a36673e4f4d4c34..8116e1f62de04f22edc7e763d67e75b34f4a7a51 100644 (file)
@@ -118,8 +118,7 @@ machine. The default is to receive mail for the machine itself.
 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>
 
index 096c8f4195798557bcc33a7b4ac1d0eed85c199c..28b826f853d02e179aac92669b50c7825fc82089 100644 (file)
@@ -9,7 +9,7 @@ TRANSPORT(5)                                         TRANSPORT(5)
 
 <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.
 
@@ -27,143 +27,157 @@ TRANSPORT(5)                                         TRANSPORT(5)
        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 &lt;&gt; 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>
@@ -172,13 +186,13 @@ TRANSPORT(5)                                         TRANSPORT(5)
        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>
@@ -196,7 +210,7 @@ TRANSPORT(5)                                         TRANSPORT(5)
        <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>
index 60284d1040fde6d29ec6e0ec5f4b972426dbe9ae..008a7debf2206fabda1314dae41170e8a48b13e3 100644 (file)
@@ -133,6 +133,9 @@ TRIVIAL-REWRITE(8)                             TRIVIAL-REWRITE(8)
               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
index a2bc8783c26e76e2bf478f1a274cfc23e2048dd8..48f350a599b9cf03b5670a17b7be00707a593081 100644 (file)
@@ -12,8 +12,8 @@ format of Postfix transport table
 .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
@@ -28,7 +28,8 @@ or SQL, the same lookups are done as for ordinary indexed files.
 
 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
@@ -64,6 +65,13 @@ can also be used with IP addresses instead of hostnames.
 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.
@@ -73,6 +81,15 @@ Mail for any subdomain of \fIdomain\fR is delivered through
 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
index eee387c6694aa0575c314b9c26dfa0551b20c9e4..1737acfdb736c78488ad26043928ff4df42f9c57 100644 (file)
@@ -127,6 +127,8 @@ to the destination's mail exchanger.
 .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
index a6d71c16cefb4be959b01b0039d17e25ca3c7957..0ac28451b0f5ef2efc62f805f9d63930a0727a94 100644 (file)
@@ -6,8 +6,8 @@
 # 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
@@ -22,7 +22,8 @@
 #
 #      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
index 4c578391cd15053374a0fc0b13f3fede6af0b62a..2769ab7b5d8ae8c656a5eb41c191e48fa0a34d3b 100644 (file)
@@ -25,6 +25,8 @@ Makefile: Makefile.in
 
 test:  $(TESTPROG)
 
+tests: test
+
 update: ../../libexec/$(PROG)
 
 ../../libexec/$(PROG): $(PROG)
index 4e216c2baa59ccb9a4e763b6965e775e25dd57ff..dee5642128b765705776602627e20d5237d8e7c9 100644 (file)
@@ -29,6 +29,8 @@ Makefile: Makefile.in
 
 test:  $(TESTPROG)
 
+tests: test
+
 update: ../../libexec/$(PROG)
 
 ../../libexec/$(PROG): $(PROG)
index 4d656f7c686f5d23b6f258852eb8fdb2f49cf3bd..6d699d3483b1da4371df653d2f28fa8f91846dcb 100644 (file)
@@ -142,12 +142,10 @@ void    cleanup_map11_tree(CLEANUP_STATE *state, TOK822 *tree,
      * 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);
 }
 
index 665bbe14a68cb8e663906a3dc009ba3bdb45d1a4..b742e25ca9152def9d1ad710bc14aea7df245432 100644 (file)
@@ -151,12 +151,10 @@ void    cleanup_masquerade_tree(TOK822 *tree, ARGV *masq_domains)
 {
     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);
 }
index 026e6e827f2d8fb52d117a6446380a22f60bb5f6..752e8479e1b1df899444ef46d7235fa5fa793b34 100644 (file)
@@ -170,8 +170,9 @@ static void cleanup_rewrite_sender(CLEANUP_STATE *state, HEADER_OPTS *hdr_opts,
      * 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);
@@ -222,8 +223,9 @@ static void cleanup_rewrite_recip(CLEANUP_STATE *state, HEADER_OPTS *hdr_opts,
      * 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);
@@ -501,8 +503,6 @@ static void cleanup_header_done_callback(void *context)
     /*
      * 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 ?
@@ -511,7 +511,7 @@ static void cleanup_header_done_callback(void *context)
                        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);
index 51fb370aaeff03179cd9e1971eb8869be9ce42ff..1ae6871d8bf9f9ef42fa1580d2494384a809acd0 100644 (file)
@@ -80,12 +80,10 @@ void    cleanup_rewrite_tree(TOK822 *tree)
     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);
 }
index 812c3fbc8e809bdf54d62facc7dd85c15aaff3ae..9948582e7124d2c5b4d8846f71f77a2989c51470 100644 (file)
@@ -24,6 +24,8 @@ Makefile: Makefile.in
 
 test:  $(TESTPROG)
 
+tests: test
+
 $(LIB):        $(OBJS)
        $(AR) $(ARFL) $(LIB) $?
        $(RANLIB) $(LIB)
index 2398dea06302af6c5994944c905e7ad98a97ac05..4ba674db5f107a6ebf0a60a0da2a09a210acd332 100644 (file)
@@ -8,7 +8,7 @@ WARN    = -W -Wformat -Wimplicit -Wmissing-prototypes \
        -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
@@ -23,6 +23,8 @@ Makefile: Makefile.in
 
 test:  $(TESTPROG)
 
+tests: test
+
 update: ../../libexec/$(PROG)
 
 ../../libexec/$(PROG): $(PROG)
index 835aea3787e67ed236f3c85950ea6683ca05ef5e..266254d9103e2693d4a2df69490eb858d13ef157 100644 (file)
@@ -23,6 +23,8 @@ Makefile: Makefile.in
 
 test:  $(TESTPROG)
 
+tests: test
+
 update: ../../libexec/$(PROG)
 
 ../../libexec/$(PROG): $(PROG)
index 9b89e45791b33fa035cc83632a0ddf7ce94d9ee8..bd0134e92ab56b8916fb1ef9825aa0986124d32c 100644 (file)
@@ -19,7 +19,8 @@ SRCS  = been_here.c bounce.c canon_addr.c cleanup_strerror.c clnt_stream.c \
        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 \
@@ -40,7 +41,8 @@ OBJS  = been_here.o bounce.o canon_addr.o cleanup_strerror.o clnt_stream.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 \
@@ -58,7 +60,7 @@ HDRS  = been_here.h bounce.h canon_addr.h cleanup_user.h clnt_stream.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 \
@@ -71,7 +73,7 @@ TESTPROG= domain_list dot_lockfile mail_addr_crunch mail_addr_find \
        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
@@ -219,7 +221,13 @@ mime_state: $(LIB) $(LIBS)
        $(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
@@ -251,6 +259,11 @@ mime_trunc: mime_state mime_trunc.in mime_trunc.ref
        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
@@ -259,6 +272,10 @@ printfck: $(OBJS) $(PROG)
        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)
 
@@ -512,7 +529,7 @@ mail_addr_find.o: ../../include/stringops.h
 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
@@ -1070,6 +1087,11 @@ string_list.o: ../../include/sys_defs.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
index 9bf8cc9531a4acff317908ced47c609b3fa7de98..23383e0410cd6b4fb322359bf12c9358c5e6f736 100644 (file)
@@ -78,9 +78,7 @@ ARGV   *mail_addr_crunch(const char *string, const char *extension)
      * 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);
index e5ee6bd2bfb717c41385b3fa80ea5d2ba34f8f38..a6c5024f254a65dfef8aae8aff8da16cbaba2dda 100644 (file)
@@ -81,7 +81,7 @@
 /* Global library. */
 
 #include <mail_params.h>
-#include <split_addr.h>
+#include <strip_addr.h>
 #include <mail_addr_find.h>
 #include <resolve_local.h>
 
@@ -97,7 +97,6 @@ const char *mail_addr_find(MAPS *path, const char *address, char **extp)
     const char *result;
     char   *ratsign = 0;
     char   *full_key;
-    char   *extent;
     char   *bare_key;
     char   *saved_ext;
 
@@ -108,21 +107,7 @@ const char *mail_addr_find(MAPS *path, const char *address, char **extp)
     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);
     }
 
     /*
index 6f45aa4e485e9580f3be8e6c858c2ad1ac44a408..9fd905ac6ed4cc641f4463318ed2028778a79438 100644 (file)
@@ -1558,6 +1558,10 @@ extern bool var_strict_encoding;
 #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
index b700c5b4af69a8f624d3add394a72d2656011b33..93cf88a40712e48edca2537d0f3a31559ee4994b 100644 (file)
@@ -20,7 +20,7 @@
   * 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
index c506f4939a71966d4c460e767df20eab8382d345..7f1ccbbca125f941b24622f5d022cac876ee91cc 100644 (file)
@@ -133,7 +133,7 @@ void    resolve_clnt_query(const char *addr, RESOLVE_REPLY *reply)
     /*
      * 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));
@@ -179,7 +179,7 @@ void    resolve_clnt_query(const char *addr, RESOLVE_REPLY *reply)
                         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;
diff --git a/postfix/src/global/strip_addr.c b/postfix/src/global/strip_addr.c
new file mode 100644 (file)
index 0000000..803db87
--- /dev/null
@@ -0,0 +1,211 @@
+/*++
+/* 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
diff --git a/postfix/src/global/strip_addr.h b/postfix/src/global/strip_addr.h
new file mode 100644 (file)
index 0000000..e99c6fd
--- /dev/null
@@ -0,0 +1,29 @@
+#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
diff --git a/postfix/src/global/strip_addr.ref b/postfix/src/global/strip_addr.ref
new file mode 100644 (file)
index 0000000..3068918
--- /dev/null
@@ -0,0 +1,8 @@
+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
index 3ec6cf7946c38ab13498e66e16fd2abb1ce42721..9a2b236e94dd61d334fa089cdf558e55f3ca6aec 100644 (file)
@@ -74,12 +74,15 @@ extern TOK822 **tok822_grep(TOK822 *, int);
  /*
   * 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)
diff --git a/postfix/src/global/tok822_limit.in b/postfix/src/global/tok822_limit.in
new file mode 100644 (file)
index 0000000..02b5c9d
--- /dev/null
@@ -0,0 +1 @@
+1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
diff --git a/postfix/src/global/tok822_limit.ref b/postfix/src/global/tok822_limit.ref
new file mode 100644 (file)
index 0000000..9f56d04
--- /dev/null
@@ -0,0 +1,91 @@
+>>>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
+
index eb33e50d31f6cf0012450c33cbdb5edbf7513fdc..a483bdc7d772455bfd6c79aba01a4970fb0dc269 100644 (file)
@@ -6,15 +6,22 @@
 /* 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;
 /*
@@ -38,6 +45,8 @@
 /*     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.
 /*
@@ -45,6 +54,8 @@
 /*     \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.
 /*
@@ -320,9 +331,9 @@ static int tok822_append_space(TOK822 *tp)
     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;
@@ -372,9 +383,9 @@ TOK822 *tok822_scan(const char *str, TOK822 **tailp, int tok_count_limit)
     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;
@@ -390,7 +401,7 @@ TOK822 *tok822_parse(const char *str, int tok_count_limit)
      * 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);
 
     /*
@@ -547,7 +558,7 @@ TOK822 *tok822_scan_addr(const char *addr)
 {
     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);
 }
 
@@ -598,7 +609,7 @@ int     main(int unused_argc, char **unused_argv)
        }
        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");
index c6091e9f5a51519952e35ab4b03f43ecebdd988a..fd52abbf32668e7f32290bbffa987908b401fafb 100644 (file)
@@ -53,8 +53,6 @@ TOK822 *tok822_rewrite(TOK822 *addr, const char *how)
      * 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));
@@ -62,8 +60,7 @@ TOK822 *tok822_rewrite(TOK822 *addr, const char *how)
     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);
index 2422e352fdb22095c8a9bd43493a7887862589fe..ba92b2f78621e7ab2997695ee2aea46d9cd04612 100644 (file)
@@ -12,7 +12,7 @@ WARN  = -W -Wformat -Wimplicit -Wmissing-prototypes \
        -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
@@ -27,6 +27,8 @@ Makefile: Makefile.in
 
 test:  $(TESTPROG)
 
+tests: test
+
 update: ../../libexec/$(PROG)
 
 ../../libexec/$(PROG): $(PROG)
@@ -49,9 +51,6 @@ clean:
 
 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 \
index e04a3a51107bcbd413f54c3d6ad425925cbc18aa..b07e17fb8c07dd3f5526bc5a41e0b7a986a77d41 100644 (file)
@@ -29,6 +29,8 @@ Makefile: Makefile.in
 
 test:  $(TESTPROG)
 
+tests: test
+
 update: ../../libexec/$(PROG)
 
 ../../libexec/$(PROG): $(PROG)
index da86c06e41af5116d6665fab83735d5cca321288..c427eb7042c4b24e1985822fe12722cda427804e 100644 (file)
@@ -177,9 +177,7 @@ int     deliver_token_string(LOCAL_STATE state, USER_ATTR usr_attr,
     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)
index cbb2894bf3fc74b90f946dd2216037cb5920579e..811d264e366dc950f6c81d9632652f8fd20bebb6 100644 (file)
@@ -35,6 +35,8 @@ $(PROG): $(OBJS) $(LIBS)
 
 test:  $(TESTPROG)
 
+tests: test
+
 $(LIB):        $(LIB_OBJ)
        $(AR) $(ARFL) $(LIB) $?
        $(RANLIB) $(LIB)
index cb465cfa8e3619e8bc45d22bca680c7a5e58e312..739cb3f422248e940820c2b9c02762235f7e6753 100644 (file)
@@ -29,6 +29,8 @@ Makefile: Makefile.in
 
 test:  $(TESTPROG)
 
+tests: test
+
 update: ../../libexec/n$(PROG)
 
 ../../libexec/n$(PROG): $(PROG)
index 882b1e8b8c8f8b85f4fd6d592c7a5a4dd2e142e6..63c6326dd1e641905ef56ff548b23409e59567df 100644 (file)
@@ -654,6 +654,11 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message)
            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
index 373a9e91f058597698a981849253097d14529070..9a078de4ff0c10fc0370761501d15d33a43176c7 100644 (file)
@@ -23,6 +23,8 @@ Makefile: Makefile.in
 
 test:  $(TESTPROG)
 
+tests: test
+
 update: ../../libexec/$(PROG)
 
 ../../libexec/$(PROG): $(PROG)
index afc0bc722e11a587be9067608f31ba4fc7603981..7f0c13f38e2d4b487269ed6448069d813aa45643 100644 (file)
@@ -8,7 +8,7 @@ WARN    = -W -Wformat -Wimplicit -Wmissing-prototypes \
        -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
@@ -23,6 +23,8 @@ Makefile: Makefile.in
 
 test:  $(TESTPROG)
 
+tests: test
+
 update: ../../libexec/$(PROG)
 
 ../../libexec/$(PROG): $(PROG)
index 20f602bfe1aaba8c8f4d900447344511d8f44ce9..5fd24274493e390d65338882fa83d3b1fc4a9570 100644 (file)
@@ -23,7 +23,7 @@ Makefile: Makefile.in
 
 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
index 750be2bc106ea219f540b4ce1b319719a0f4310a..fdde2aafbe5b3d04a85d6cf68e84df267c627343 100644 (file)
@@ -249,10 +249,7 @@ static void postalias(char *map_type, char *path_name, int postalias_flags,
         * 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;
 
        /*
index c753f9aeaeba381f97d44c24a256e9476a977a3d..65cf7576f3a32630f0ad782408823dc8078e27a4 100644 (file)
@@ -23,6 +23,8 @@ Makefile: Makefile.in
 
 test:  $(TESTPROG)
 
+tests: test
+
 update: ../../bin/$(PROG)
 
 ../../bin/$(PROG): $(PROG)
index 35434d4b7512961943426ce49452a1b6173cfe13..7732636b8967d609fba76e813fa725eca93b401b 100644 (file)
@@ -33,6 +33,8 @@ Makefile: Makefile.in
 
 test:  $(TESTPROG)
 
+tests: test
+
 update: ../../bin/$(PROG) $(SAMPLES)
 
 ../../bin/$(PROG): $(PROG)
index a58a1b581ce93eba27406c5b1240bb7acb748cb3..01cbe2893cf22b9ed0faf159dbeef09cff0718b9 100644 (file)
@@ -23,6 +23,8 @@ Makefile: Makefile.in
 
 test:  $(TESTPROG)
 
+tests: test
+
 update: ../../bin/$(PROG)
 
 ../../bin/$(PROG): $(PROG)
index 45e05f7f978cfdfc929f87ec16105a62d19bb0a1..bd1e8f5e30d5aba190f9121547a0ae71687d3985 100644 (file)
@@ -24,6 +24,8 @@ Makefile: Makefile.in
 
 test:  $(TESTPROG)
 
+tests: test
+
 update: ../../bin/$(PROG)
 
 ../../bin/$(PROG): $(PROG)
index d4cf100f460ca00d06027953c970807e90d309e1..ce8b4a4858526b5735f72d03a3f9b9332bbfdda5 100644 (file)
@@ -23,6 +23,8 @@ Makefile: Makefile.in
 
 test:  $(TESTPROG)
 
+tests: test
+
 update: ../../bin/$(PROG)
 
 ../../bin/$(PROG): $(PROG)
index 7e17af81592b607870332811a2915d1c3916b950..3e95260c39cfea2cb5594272083dc2f851dfa4c1 100644 (file)
@@ -23,6 +23,8 @@ Makefile: Makefile.in
 
 test:  $(TESTPROG)
 
+tests: test
+
 update: ../../bin/$(PROG)
 
 ../../bin/$(PROG): $(PROG)
index c1c5948dd97ba166692c46e179707a3d5d6f8d1d..5feba3056cde5a95ec98dca5d6991008759ec1fc 100644 (file)
@@ -24,6 +24,8 @@ Makefile: Makefile.in
 
 test:  $(TESTPROG)
 
+tests: test
+
 update: ../../bin/$(PROG)
 
 ../../bin/$(PROG): $(PROG)
index 9725268cbc4e0f1db53ac1a958b3dc7c2ab4d9be..66ebf9f744bccf73b26c28235a0b1bc37045aa41 100644 (file)
@@ -26,7 +26,7 @@ update: ../../bin/$(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
index f9470cc9a477d163aec885a1cd3722204217dcb5..29ba1bff45b6a2f2a68abba2632564f09a24dd8a 100644 (file)
@@ -23,6 +23,8 @@ Makefile: Makefile.in
 
 test:  $(TESTPROG)
 
+tests: test
+
 update: ../../bin/$(PROG)
 
 ../../bin/$(PROG): $(PROG)
index 4afa39a5434adc3a27fb097e4f17767a155ff760..aacc1841a1b0c7c601ace6ea59f2d14cc1b17969 100644 (file)
@@ -23,6 +23,8 @@ Makefile: Makefile.in
 
 test:  $(TESTPROG)
 
+tests: test
+
 update: ../../bin/$(PROG)
 
 ../../bin/$(PROG): $(PROG)
index 92ef4a93fee8d7ecffd9a1d6208c24a897e9479d..4f364f5b9d64b34c4f12d18ea0b4795a14c7423c 100644 (file)
@@ -27,6 +27,8 @@ Makefile: Makefile.in
 
 test:  $(TESTPROG)
 
+tests: test
+
 update: ../../libexec/$(PROG)
 
 ../../libexec/$(PROG): $(PROG)
index 85f08a9e5eff4aa2adf733f9a4e251100eb2846c..9bbac697573c37fe31ae9757b5a5789cd3d2d2b7 100644 (file)
@@ -534,6 +534,11 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message)
            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
index 77fb1bf1482e89b696d4789306c37ce524c8dca7..cc878e4fc384096bd62488ffa8486dffb1ad1642 100644 (file)
@@ -8,7 +8,7 @@ WARN    = -W -Wformat -Wimplicit -Wmissing-prototypes \
        -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
@@ -23,6 +23,8 @@ Makefile: Makefile.in
 
 test:  $(TESTPROG)
 
+tests: test
+
 update: ../../libexec/$(PROG)
 
 ../../libexec/$(PROG): $(PROG)
@@ -64,8 +66,6 @@ depend: $(MAKES)
        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
index e037edf1fd362ff9ada721fb77812794eca47a22..e6e96aa0f16dcb83681e89918bfa38e3f9096eb0 100644 (file)
@@ -23,6 +23,8 @@ Makefile: Makefile.in
 
 test:  $(TESTPROG)
 
+tests: test
+
 update: ../../bin/$(PROG)
 
 ../../bin/$(PROG): $(PROG)
index 9f60742de52ea4a9be115b980670becc2c339dd6..138f38be16a9e989f7c46500a68181e8522bbecc 100644 (file)
@@ -379,10 +379,8 @@ static void enqueue(const int flags, const char *encoding, const char *sender,
      * 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);
@@ -435,7 +433,7 @@ static void enqueue(const int flags, const char *encoding, const char *sender,
        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);
index 7b7b5cd366c7ef37767c86ec920a0851707641f3..2001e4df340b951ab4036cb77f45f12cd156e64e 100644 (file)
@@ -23,6 +23,8 @@ Makefile: Makefile.in
 
 test:  $(TESTPROG)
 
+tests: test
+
 update: ../../libexec/$(PROG)
 
 ../../libexec/$(PROG): $(PROG)
index 40011cf33ab8bba7c3d3163074ab2c2e52b00f46..fcf2e243b5999ff18e7fafacae7036137e65f94d 100644 (file)
@@ -27,6 +27,8 @@ Makefile: Makefile.in
 
 test:  $(TESTPROG)
 
+tests: test
+
 update: ../../libexec/$(PROG)
 
 ../../libexec/$(PROG): $(PROG)
index e881b28f45d677aafef58d83dd6e05efa22b97df..bb8cc718969a5aa0731e36025f32419ab0377547 100644 (file)
@@ -196,7 +196,7 @@ smtpd_check.o: ../../include/mail_conf.h
 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
index 2163dde943827d4a07ce910f184a08a7ae7b5af0..cf2adfb46ddea5052388aaea58562f0dec0e8247 100644 (file)
@@ -591,17 +591,15 @@ static char *extract_addr(SMTPD_STATE *state, SMTPD_TOKEN *arg,
      * 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.
index 99955409f7356a15c0c91f1b3cbd5f42406c0898..45d1d4fa5f0833a0802100d5c38304fc38a8a304 100644 (file)
@@ -78,9 +78,17 @@ mail bad-sender@ok.domain
 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
index 294891fd0c49a9e81fc8c9490cc642c34d4ff551..08ca5591642609e1db635f30ad0f3deaf68ed431 100644 (file)
@@ -121,10 +121,25 @@ OK
 >>> 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
index cd0b46b1138e78942f060f78658acdce758b0b1b..cf704592b89c26584b0c9cb3929bfc22026ac763 100644 (file)
 #include <maps.h>
 #include <mail_addr_find.h>
 #include <match_parent_style.h>
-#include <split_addr.h>
+#include <strip_addr.h>
 
 /* Application-specific. */
 
@@ -1717,7 +1717,6 @@ static int check_mail_access(SMTPD_STATE *state, const char *table,
     int     status;
     char   *local_at;
     char   *bare_addr;
-    char   *bare_ext;
     char   *bare_at;
 
     if (msg_verbose)
@@ -1745,19 +1744,7 @@ static int check_mail_access(SMTPD_STATE *state, const char *table,
     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) \
@@ -1824,6 +1811,7 @@ static int check_mail_access(SMTPD_STATE *state, const char *table,
      * 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,
@@ -2623,6 +2611,7 @@ char   *var_perm_mx_networks;
 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;
@@ -2648,6 +2637,7 @@ static STRING_TABLE string_table[] = {
     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,
 };
 
@@ -2812,10 +2802,10 @@ void    resolve_clnt_free(RESOLVE_REPLY *reply)
     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)
index 454a44c134319f415a418ce03fd4f56af7e3948c..fb9cacbdc429e4d3058dc8d33da9d0675a6f308e 100644 (file)
@@ -34,6 +34,8 @@ qmqp-source: qmqp-source.o $(LIBS)
 
 test:  $(TESTPROG)
 
+tests: test
+
 update: ../../bin/smtp-source ../../bin/smtp-sink ../../bin/qmqp-source
 
 ../../bin/smtp-source: smtp-source
index 1269837e172169a3dce7ac3469384e42eae0a655..95fcb3e31251fae012846fe249cfd4a8a6aed9af 100644 (file)
@@ -23,6 +23,8 @@ Makefile: Makefile.in
 
 test:  $(TESTPROG)
 
+tests: test
+
 update: ../../libexec/$(PROG)
 
 ../../libexec/$(PROG): $(PROG)
index 1ee66fde9a656636e6baea4290ad4e3d8bc83c2e..01e2166c8af233d495f7b4c8d6a87b6372338f91 100644 (file)
@@ -28,6 +28,8 @@ Makefile: Makefile.in
 
 test:  $(TESTPROG)
 
+tests: test
+
 $(BIN_DIR)/$(PROG): $(PROG)
        cp $(PROG) $@
 
@@ -109,6 +111,7 @@ transport.o: ../../include/split_at.h
 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
index 00cdccc56c1340d3cc80c4016d0a47003b4155d7..88b79c971fa75d0b83d518bab8ea0c8fe5180c76 100644 (file)
@@ -134,13 +134,10 @@ void    resolve_addr(char *addr, VSTRING *channel, VSTRING *nexthop,
        /*
         * 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);
        }
 
@@ -196,10 +193,9 @@ void    resolve_addr(char *addr, VSTRING *channel, VSTRING *nexthop,
        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);
@@ -247,7 +243,7 @@ void    resolve_addr(char *addr, VSTRING *channel, VSTRING *nexthop,
      * 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.
index 22a3e2f721652195b54bfd1b8497bbf914e1cef9..9ff6a12f092a6b9e41c0d3e0f0f73927b87069d3 100644 (file)
@@ -151,12 +151,9 @@ void    rewrite_tree(char *unused_ruleset, TOK822 *tree)
        /*
         * 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));
        }
     }
 
@@ -168,8 +165,7 @@ void    rewrite_tree(char *unused_ruleset, TOK822 *tree)
        && 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));
     }
 
     /*
index 00ec9d734ba2babb8f18e47c3cd256a02cedbf7d..f329b95311c82d4a96bd6674be97f6b86961f460 100644 (file)
@@ -8,13 +8,13 @@
 /*
 /*     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
@@ -28,6 +28,7 @@
 /*     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*
@@ -60,6 +61,7 @@
 
 /* Global library. */
 
+#include <strip_addr.h>
 #include <mail_params.h>
 #include <maps.h>
 #include <match_parent_style.h>
@@ -104,11 +106,24 @@ void    transport_wildcard_init(void)
     }
 }
 
+/* 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;
@@ -119,51 +134,102 @@ int     transport_lookup(const char *domain, VSTRING *channel, VSTRING *nexthop)
 
 #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.
index ae18f612ba8f4609494f5b26e110640965311990..92106dce4a2386b51c2eb7583dcf2212079f5d14 100644 (file)
 /* .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
@@ -174,6 +176,7 @@ bool    var_append_at_myorigin;
 bool    var_percent_hack;
 char   *var_local_transport;
 int     var_resolve_dequoted;
+char   *var_xport_null_key;
 
 /* rewrite_service - read request and send reply */
 
@@ -239,6 +242,7 @@ int     main(int argc, char **argv)
     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[] = {
index c2fc33c39a64e08db881568e46fce7e10d2dbe59..415e21d8705497e733eb7e0201b1c59770a0b637 100644 (file)
@@ -23,6 +23,8 @@ Makefile: Makefile.in
 
 test:  $(TESTPROG)
 
+tests: test
+
 update: ../../libexec/$(PROG)
 
 ../../libexec/$(PROG): $(PROG)