]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.12-20141019
authorWietse Venema <wietse@porcupine.org>
Sun, 19 Oct 2014 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <postfix-users@dukhovni.org>
Mon, 20 Oct 2014 00:13:12 +0000 (20:13 -0400)
69 files changed:
postfix/HISTORY
postfix/README_FILES/TLS_README
postfix/html/TLS_README.html
postfix/html/lmtp.8.html
postfix/html/postconf.5.html
postfix/html/smtp.8.html
postfix/man/man5/postconf.5
postfix/man/man8/smtp.8
postfix/proto/TLS_README.html
postfix/proto/postconf.proto
postfix/src/cleanup/cleanup.h
postfix/src/cleanup/cleanup_init.c
postfix/src/cleanup/cleanup_masquerade.c
postfix/src/cleanup/cleanup_message.c
postfix/src/cleanup/cleanup_milter.c
postfix/src/cleanup/cleanup_state.c
postfix/src/dns/test_dns_lookup.c
postfix/src/global/attr_override.c
postfix/src/global/dict_ldap.c
postfix/src/global/dict_mysql.c
postfix/src/global/dict_pgsql.c
postfix/src/global/mail_conf.c
postfix/src/global/mail_params.c
postfix/src/global/mail_queue.c
postfix/src/global/mail_version.h
postfix/src/global/maps.c
postfix/src/global/match_service.c
postfix/src/global/pipe_command.c
postfix/src/global/scache.c
postfix/src/global/server_acl.c
postfix/src/global/verify_clnt.c
postfix/src/local/dotforward.c
postfix/src/master/master_ent.c
postfix/src/milter/milter.c
postfix/src/milter/milter.h
postfix/src/milter/milter8.c
postfix/src/oqmgr/qmgr_message.c
postfix/src/postconf/postconf_dbms.c
postfix/src/postconf/postconf_edit.c
postfix/src/postconf/postconf_master.c
postfix/src/postconf/postconf_user.c
postfix/src/postfix/postfix.c
postfix/src/postmap/postmap.c
postfix/src/postmulti/postmulti.c
postfix/src/postscreen/postscreen_dnsbl.c
postfix/src/postsuper/postsuper.c
postfix/src/proxymap/proxymap.c
postfix/src/qmgr/qmgr_message.c
postfix/src/sendmail/sendmail.c
postfix/src/smtp/smtp_connect.c
postfix/src/smtp/smtp_sasl_auth_cache.c
postfix/src/smtp/smtp_tls_policy.c
postfix/src/smtpd/smtpd.c
postfix/src/smtpd/smtpd_check.c
postfix/src/smtpstone/smtp-sink.c
postfix/src/tls/tls_dane.c
postfix/src/tls/tls_mgr.c
postfix/src/tls/tls_misc.c
postfix/src/util/dict_pipe.c
postfix/src/util/dict_random.c
postfix/src/util/dict_thash.c
postfix/src/util/dict_union.c
postfix/src/util/mac_expand.c
postfix/src/util/match_list.c
postfix/src/util/mystrtok.c
postfix/src/util/spawn_command.c
postfix/src/util/stringops.h
postfix/src/util/sys_defs.h
postfix/src/util/vstream_popen.c

index 080399cdc99c81070b5f2f0c123183698a04a6ea..8a0e2084ab19b530bfd711350ab0a2b9dffeaadc 100644 (file)
@@ -20666,3 +20666,22 @@ Apologies for any names omitted.
        with similar code elsewhere. File: master/master_ent.c.
 
        Backed out SMTP client TLS fallback due to multiple problems.
+
+20141018
+
+       Bugfix (introduced: Postfix 2.3): when a Milter inserted a
+       header ABOVE Postfix's own Received: header, Postfix would
+       expose its own Received: header to Milters (violating
+       protocol) and hide the Milter-inserted header from Milters
+       (wtf).  Files: cleanup/cleanup.h, cleanup/cleanup_message.c,
+       cleanup/cleanup_state.c, milter/milter.[hc], milter/milter8.c.
+
+       Cleanup: revert the workaround that places headers inserted
+       with PREPEND actions or policy requests BELOW Postfix's own
+       Received: message header. File: smtpd/smtpd.c.
+
+20141019
+
+       Cleanup: replace dozens and dozens of ad-hoc string constants
+       with CHARS_SPACE, CHARS_COMMA_SP, and CHARS_BRACE. Files:
+       52, too many files to mention here.
index 67a2e3f8c7559eb05db64f450b1f2ba4b5ac4b5a..adca4c825557f59f130dfdbc9fd4debe82423a4d 100644 (file)
@@ -1027,11 +1027,8 @@ default. This is the recommended configuration for early adopters.
   * The "example.com" destination uses DANE, but if TLSA records are not
     present or are unusable, mail is deferred.
 
-  * The "example.org" destination uses DANE if possible, but uses opportunistic
-    TLS if no TLSA records are found. The "fallback" attribute (Postfix >=
-    2.12) overrides the global main.cf smtp_tls_fallback_level parameter to
-    employ unauthenticated mandatory encryption if DANE authentication fails,
-    after logging a warning.
+  * The "example.org" destination uses DANE if possible, but if no TLSA records
+    are found opportunistic TLS is used.
 
     main.cf:
         indexed = ${default_database_type}:${config_directory}/
@@ -1055,8 +1052,6 @@ default. This is the recommended configuration for early adopters.
 
     tls_policy:
         example.com dane-only
-        # Postfix >= 2.12, per-destination smtp_tls_fallback_level override
-        example.org dane fallback=encrypt
 
     master.cf:
         dane       unix  -       -       n       -       -       smtp
@@ -1637,9 +1632,7 @@ d\bda\ban\bne\be
     obtained for the remote SMTP server, SSLv2 is automatically disabled (see
     smtp_tls_mandatory_protocols), and the server certificate must match the
     TLSA records. RFC 6698 (DANE) TLS authentication and DNSSEC support is
-    available with Postfix 2.11 and later. The optional "fallback" attribute
-    provides a per-site override of the main.cf smtp_tls_fallback_level
-    parameter (Postfix >= 2.12).
+    available with Postfix 2.11 and later.
 d\bda\ban\bne\be-\b-o\bon\bnl\bly\by
     Mandatory DANE TLS. The TLS policy for the destination is obtained via TLSA
     records in DNSSEC. If no TLSA records are found, or none are usable, no
@@ -1647,9 +1640,7 @@ d\bda\ban\bne\be-\b-o\bon\bnl\bly\by
     the remote SMTP server, SSLv2 is automatically disabled (see
     smtp_tls_mandatory_protocols), and the server certificate must match the
     TLSA records. RFC 6698 (DANE) TLS authentication and DNSSEC support is
-    available with Postfix 2.11 and later. The optional "fallback" attribute
-    provides a per-site override of the main.cf smtp_tls_fallback_level
-    parameter (Postfix >= 2.12).
+    available with Postfix 2.11 and later.
 f\bfi\bin\bng\bge\ber\brp\bpr\bri\bin\bnt\bt
     Certificate fingerprint verification. Available with Postfix 2.5 and later.
     At this security level, there are no trusted certificate authorities. The
@@ -1662,8 +1653,7 @@ f\bfi\bin\bng\bge\ber\brp\bpr\bri\bin\bnt\bt
     combined with a "|" delimiter in a single match attribute, or multiple
     match attributes can be employed. The ":" character is not used as a
     delimiter as it occurs between each pair of fingerprint (hexadecimal)
-    digits. The optional "fallback" attribute provides a per-site override of
-    the main.cf smtp_tls_fallback_level parameter (Postfix >= 2.12).
+    digits.
 v\bve\ber\bri\bif\bfy\by
     Mandatory server certificate verification. Mail is delivered only if the
     TLS handshake succeeds, if the remote SMTP server certificate can be
@@ -1674,8 +1664,7 @@ v\bve\ber\bri\bif\bfy\by
     "tafile" attribute optionally modifies trust chain verification in the same
     manner as the "smtp_tls_trust_anchor_file" parameter. The "tafile"
     attribute may be specified multiple times to load multiple trust-anchor
-    files. The optional "fallback" attribute provides a per-site override of
-    the main.cf smtp_tls_fallback_level parameter (Postfix >= 2.12).
+    files.
 s\bse\bec\bcu\bur\bre\be
     Secure certificate verification. Mail is delivered only if the TLS
     handshake succeeds, if the remote SMTP server certificate can be validated
@@ -1685,9 +1674,7 @@ s\bse\bec\bcu\bur\bre\be
     "match" attribute is specified). With Postfix >= 2.11 the "tafile"
     attribute optionally modifies trust chain verification in the same manner
     as the "smtp_tls_trust_anchor_file" parameter. The "tafile" attribute may
-    be specified multiple times to load multiple trust-anchor files. The
-    optional "fallback" attribute provides a per-site override of the main.cf
-    smtp_tls_fallback_level parameter (Postfix >= 2.12).
+    be specified multiple times to load multiple trust-anchor files.
 Notes:
 
   * The "match" attribute is especially useful to verify TLS certificates for
@@ -1721,7 +1708,6 @@ Example:
         smtp_tls_policy_maps = hash:/etc/postfix/tls_policy
         # Postfix 2.5 and later
         smtp_tls_fingerprint_digest = md5
-
     /etc/postfix/tls_policy:
         example.edu             none
         example.mil             may
@@ -1737,8 +1723,6 @@ Example:
         # Postfix 2.6 and later
         example.info            may protocols=!SSLv2 ciphers=medium
     exclude=3DES
-        # Postfix 2.12 and later override of smtp_tls_fallback_level
-        fallback.example        secure fallback=encrypt
 
 N\bNo\bot\bte\be:\b: The "hostname" strategy if listed in a non-default setting of
 smtp_tls_secure_cert_match or in the "match" attribute in the policy table can
index 286bf394ca447ab48b6006efe9aa1052ed4bc80a..2548b9f5761584241e216f36b255abe65d66ebc0 100644 (file)
@@ -1373,12 +1373,8 @@ for early adopters. <p>
 <li> <p> The "example.com" destination uses DANE, but if TLSA records
 are not present or are unusable, mail is deferred. </p>
 
-<li> <p> The "example.org" destination uses DANE if possible, but
-uses opportunistic TLS if no TLSA records are found.  The
-"fallback" attribute (Postfix &ge; 2.12) overrides the global
-<a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_fallback_level">smtp_tls_fallback_level</a> parameter to employ unauthenticated
-mandatory encryption if DANE authentication fails, after logging a
-warning.  </p>
+<li> <p> The "example.org" destination uses DANE if possible, but if no TLSA
+records are found opportunistic TLS is used. </p>
 </ul>
 
 <blockquote>
@@ -1398,16 +1394,26 @@ warning.  </p>
     # <a href="postconf.5.html#default_transport">default_transport</a> = smtp, but some destinations are special:
     #
     <a href="postconf.5.html#transport_maps">transport_maps</a> = ${indexed}transport
+</pre>
+</blockquote>
 
+<blockquote>
+<pre>
 transport:
     example.com dane
     example.org dane
+</pre>
+</blockquote>
 
+<blockquote>
+<pre>
 tls_policy:
     example.com dane-only
-    # Postfix &ge; 2.12, per-destination <a href="postconf.5.html#smtp_tls_fallback_level">smtp_tls_fallback_level</a> override
-    example.org dane fallback=encrypt
+</pre>
+</blockquote>
 
+<blockquote>
+<pre>
 <a href="master.5.html">master.cf</a>:
     dane       unix  -       -       n       -       -       smtp
       -o <a href="postconf.5.html#smtp_dns_support_level">smtp_dns_support_level</a>=dnssec
@@ -2140,10 +2146,7 @@ href="#client_tls_encrypt">encrypt</a>.  When usable TLSA records
 are obtained for the remote SMTP server, SSLv2 is automatically
 disabled (see <a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a>), and the server certificate
 must match the TLSA records.  <a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a> (DANE) TLS authentication
-and DNSSEC support is available with Postfix 2.11 and later.  
-The optional "fallback" attribute provides a per-site override of
-the <a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_fallback_level">smtp_tls_fallback_level</a> parameter (Postfix &ge; 2.12).
-</dd>
+and DNSSEC support is available with Postfix 2.11 and later.  </dd>
 
 <dt><b>dane-only</b></dt> <dd><a href="#client_tls_dane">Mandatory DANE TLS</a>.
 The TLS policy for the destination is obtained via TLSA records in
@@ -2152,10 +2155,7 @@ connection is made to the server.  When usable TLSA records are
 obtained for the remote SMTP server, SSLv2 is automatically disabled
 (see <a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a>), and the server certificate must
 match the TLSA records.  <a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a> (DANE) TLS authentication and
-DNSSEC support is available with Postfix 2.11 and later.  
-The optional "fallback" attribute provides a per-site override of
-the <a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_fallback_level">smtp_tls_fallback_level</a> parameter (Postfix &ge; 2.12).
-</dd>
+DNSSEC support is available with Postfix 2.11 and later.  </dd>
 
 <dt><b>fingerprint</b></dt> <dd><a href="#client_tls_fprint">Certificate
 fingerprint verification.</a> Available with Postfix 2.5 and
@@ -2164,15 +2164,13 @@ authorities. The certificate trust chain, expiration date, ... are
 not checked. Instead, the optional <b>match</b> attribute, or else
 the <a href="postconf.5.html">main.cf</a> <b><a href="postconf.5.html#smtp_tls_fingerprint_cert_match">smtp_tls_fingerprint_cert_match</a></b> parameter, lists
 the server certificate fingerprints or public key fingerprints
-(Postfix 2.9 and later).  The digest algorithm used to calculate
-fingerprints is selected by the <b><a href="postconf.5.html#smtp_tls_fingerprint_digest">smtp_tls_fingerprint_digest</a></b>
-parameter. Multiple fingerprints can be combined with a "|" delimiter
-in a single match attribute, or multiple match attributes can be
-employed. The ":" character is not used as a delimiter as it occurs
-between each pair of fingerprint (hexadecimal) digits.
-The optional "fallback" attribute provides a per-site override of
-the <a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_fallback_level">smtp_tls_fallback_level</a> parameter (Postfix &ge; 2.12).
-</dd>
+(Postfix 2.9 and later).  The
+digest algorithm used to calculate fingerprints is selected by the
+<b><a href="postconf.5.html#smtp_tls_fingerprint_digest">smtp_tls_fingerprint_digest</a></b> parameter. Multiple fingerprints can
+be combined with a "|" delimiter in a single match attribute, or multiple
+match attributes can be employed. The ":" character is not used as a
+delimiter as it occurs between each pair of fingerprint (hexadecimal)
+digits. </dd>
 
 <dt><b>verify</b></dt> <dd><a href="#client_tls_verify">Mandatory
 server certificate verification</a>.  Mail is delivered only if the
@@ -2183,11 +2181,9 @@ the optional "match" attribute (or the <a href="postconf.5.html">main.cf</a> <a
 parameter value when no optional "match" attribute is specified).
 With Postfix &ge; 2.11 the "tafile" attribute optionally modifies
 trust chain verification in the same manner as the
-"<a href="postconf.5.html#smtp_tls_trust_anchor_file">smtp_tls_trust_anchor_file</a>" parameter.  The "tafile" attribute may
-be specified multiple times to load multiple trust-anchor files.
-The optional "fallback" attribute provides a per-site override of
-the <a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_fallback_level">smtp_tls_fallback_level</a> parameter (Postfix &ge; 2.12).
-</dd>
+"<a href="postconf.5.html#smtp_tls_trust_anchor_file">smtp_tls_trust_anchor_file</a>" parameter.  The "tafile" attribute
+may be specified multiple times to load multiple trust-anchor
+files.  </dd>
 
 <dt><b>secure</b></dt> <dd><a href="#client_tls_secure">Secure certificate
 verification.</a> Mail is delivered only if the TLS handshake succeeds,
@@ -2199,10 +2195,7 @@ server certificate name matches the optional "match" attribute (or the
 attribute optionally modifies trust chain verification in the same manner
 as the "<a href="postconf.5.html#smtp_tls_trust_anchor_file">smtp_tls_trust_anchor_file</a>" parameter.  The "tafile" attribute
 may be specified multiple times to load multiple trust-anchor
-files.  
-The optional "fallback" attribute provides a per-site override of
-the <a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_fallback_level">smtp_tls_fallback_level</a> parameter (Postfix &ge; 2.12).
-</dd>
+files.  </dd>
 
 </dl>
 
@@ -2249,7 +2242,6 @@ Example:
     <a href="postconf.5.html#smtp_tls_policy_maps">smtp_tls_policy_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/tls_policy
     # Postfix 2.5 and later
     <a href="postconf.5.html#smtp_tls_fingerprint_digest">smtp_tls_fingerprint_digest</a> = md5
-
 /etc/postfix/tls_policy:
     example.edu             none
     example.mil             may
@@ -2264,8 +2256,6 @@ Example:
         match=3D:95:34:51:24:66:33:B9:D2:40:99:C0:C1:17:0B:D1
     # Postfix 2.6 and later
     example.info            may protocols=!SSLv2 ciphers=medium exclude=3DES
-    # Postfix 2.12 and later override of <a href="postconf.5.html#smtp_tls_fallback_level">smtp_tls_fallback_level</a>
-    fallback.example        secure fallback=encrypt
 </pre>
 </blockquote>
 
index 2299c5cc506157e89178fd82f7a46b0a4a92efc1..f07bc31f16c112485da0aca4733ae6e4f798cb45 100644 (file)
@@ -552,11 +552,6 @@ SMTP(8)                                                                SMTP(8)
        <b><a href="postconf.5.html#tlsmgr_service_name">tlsmgr_service_name</a> (tlsmgr)</b>
               The name of the <a href="tlsmgr.8.html"><b>tlsmgr</b>(8)</a> service entry in <a href="master.5.html">master.cf</a>.
 
-       Available in Postfix version 2.12 and later:
-
-       <b><a href="postconf.5.html#smtp_tls_fallback_level">smtp_tls_fallback_level</a> (empty)</b>
-              Optional fallback levels for authenticated TLS levels.
-
 <b>OBSOLETE STARTTLS CONTROLS</b>
        The  following  configuration  parameters  exist for compatibility with
        Postfix versions before 2.3. Support for these will  be  removed  in  a
index c40fe6f61751480f0494f76a0a124f84317bbcf8..e4e47d80dd6d898f478237bb36023c04b781c1c7 100644 (file)
@@ -5027,17 +5027,6 @@ configuration parameter.  See there for details. </p>
 <p> This feature is available in Postfix 2.3 and later. </p>
 
 
-</DD>
-
-<DT><b><a name="lmtp_tls_fallback_level">lmtp_tls_fallback_level</a>
-(default: empty)</b></DT><DD>
-
-<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_tls_fallback_level">smtp_tls_fallback_level</a>
-configuration parameter.  See there for details. </p>
-
-<p> This feature is available in Postfix 2.12 and later. </p>
-
-
 </DD>
 
 <DT><b><a name="lmtp_tls_fingerprint_cert_match">lmtp_tls_fingerprint_cert_match</a>
@@ -11648,61 +11637,6 @@ key exchange with RSA authentication. </p>
 <p> This feature is available in Postfix 2.3 and later. </p>
 
 
-</DD>
-
-<DT><b><a name="smtp_tls_fallback_level">smtp_tls_fallback_level</a>
-(default: empty)</b></DT><DD>
-
-<p> Optional fallback levels for authenticated TLS levels.  Specify
-a white-space or comma-separated list of
-<b>policy_level</b>=<b>fallback_level</b> pairs.  The <b>policy_level</b>
-must require authentication (one of dane, dane-only, fingerprint,
-verify, secure).  The <b>fallback_level</b> must be "encrypt" or
-"may".  When an authenticated connection at some desired policy
-level cannot be established, delivery will proceed at the correponding
-fallback level if possible.  A warning will be logged
-indicating the fallback reason. </p>
-
-<p> The TLS <a href="TLS_README.html#client_tls_policy">policy</a> table
-can be used to specify a destination-specific fallback strategy via the
-"fallback" policy attribute.  The value of the "fallback" attribute, if
-specified, must be "may", "encrypt" or "none".  If not "none", this
-specifies the fallback level for the destination in question.  If the
-attribute value is "none", fallback is suppressed for the destination
-even if enabled via a global setting of <a href="postconf.5.html#smtp_tls_fallback_level">smtp_tls_fallback_level</a>.  </p>
-
-<p> Example: </p>
-
-<blockquote>
-<pre>
-/etc/postfix/<a href="postconf.5.html">main.cf</a>:
-    # When authentication fails, log a warning and deliver anyway
-    # over an unauthenticated TLS connection.
-    #
-    <a href="postconf.5.html#smtp_tls_fallback_level">smtp_tls_fallback_level</a> =
-        dane=encrypt,
-        dane-only=encrypt,
-        fingerprint=encrypt,
-        verify=encrypt,
-        secure=encrypt
-    indexed = ${<a href="postconf.5.html#default_database_type">default_database_type</a>}:${<a href="postconf.5.html#config_directory">config_directory</a>}/
-    <a href="postconf.5.html#smtp_tls_policy_maps">smtp_tls_policy_maps</a> = ${indexed}tls-policy
-</pre>
-</blockquote>
-
-<blockquote>
-<pre>
-/etc/postfix/tls-policy:
-    # No fallback for example.com
-    example.com secure fallback=none
-    # For example.net tolerate cleartext fallback
-    example.net dane fallback=may
-</pre>
-</blockquote>
-
-<p> This feature is available in Postfix 2.12 and later. </p>
-
-
 </DD>
 
 <DT><b><a name="smtp_tls_fingerprint_cert_match">smtp_tls_fingerprint_cert_match</a>
index 2299c5cc506157e89178fd82f7a46b0a4a92efc1..f07bc31f16c112485da0aca4733ae6e4f798cb45 100644 (file)
@@ -552,11 +552,6 @@ SMTP(8)                                                                SMTP(8)
        <b><a href="postconf.5.html#tlsmgr_service_name">tlsmgr_service_name</a> (tlsmgr)</b>
               The name of the <a href="tlsmgr.8.html"><b>tlsmgr</b>(8)</a> service entry in <a href="master.5.html">master.cf</a>.
 
-       Available in Postfix version 2.12 and later:
-
-       <b><a href="postconf.5.html#smtp_tls_fallback_level">smtp_tls_fallback_level</a> (empty)</b>
-              Optional fallback levels for authenticated TLS levels.
-
 <b>OBSOLETE STARTTLS CONTROLS</b>
        The  following  configuration  parameters  exist for compatibility with
        Postfix versions before 2.3. Support for these will  be  removed  in  a
index c8b16dfe017ae13a3cbd999b48a40bac4e64728f..daeebcb9c361cfcc1dbec7d967cb55895f9e98ed 100644 (file)
@@ -2970,11 +2970,6 @@ The LMTP-specific version of the smtp_tls_exclude_ciphers
 configuration parameter.  See there for details.
 .PP
 This feature is available in Postfix 2.3 and later.
-.SH lmtp_tls_fallback_level (default: empty)
-The LMTP-specific version of the smtp_tls_fallback_level
-configuration parameter.  See there for details.
-.PP
-This feature is available in Postfix 2.12 and later.
 .SH lmtp_tls_fingerprint_cert_match (default: empty)
 The LMTP-specific version of the smtp_tls_fingerprint_cert_match
 configuration parameter.  See there for details.
@@ -7309,63 +7304,6 @@ and "DES-CBC3-MD5". The last setting disables ciphers that use "EDH"
 key exchange with RSA authentication.
 .PP
 This feature is available in Postfix 2.3 and later.
-.SH smtp_tls_fallback_level (default: empty)
-Optional fallback levels for authenticated TLS levels.  Specify
-a white-space or comma-separated list of
-\fBpolicy_level\fR=\fBfallback_level\fR pairs.  The \fBpolicy_level\fR
-must require authentication (one of dane, dane-only, fingerprint,
-verify, secure).  The \fBfallback_level\fR must be "encrypt" or
-"may".  When an authenticated connection at some desired policy
-level cannot be established, delivery will proceed at the correponding
-fallback level if possible.  A warning will be logged
-indicating the fallback reason.
-.PP
-The TLS policy table
-can be used to specify a destination-specific fallback strategy via the
-"fallback" policy attribute.  The value of the "fallback" attribute, if
-specified, must be "may", "encrypt" or "none".  If not "none", this
-specifies the fallback level for the destination in question.  If the
-attribute value is "none", fallback is suppressed for the destination
-even if enabled via a global setting of smtp_tls_fallback_level.
-.PP
-Example:
-.sp
-.in +4
-.nf
-.na
-.ft C
-/etc/postfix/main.cf:
-    # When authentication fails, log a warning and deliver anyway
-    # over an unauthenticated TLS connection.
-    #
-    smtp_tls_fallback_level =
-        dane=encrypt,
-        dane-only=encrypt,
-        fingerprint=encrypt,
-        verify=encrypt,
-        secure=encrypt
-    indexed = ${default_database_type}:${config_directory}/
-    smtp_tls_policy_maps = ${indexed}tls-policy
-.fi
-.ad
-.ft R
-.in -4
-.sp
-.in +4
-.nf
-.na
-.ft C
-/etc/postfix/tls-policy:
-    # No fallback for example.com
-    example.com secure fallback=none
-    # For example.net tolerate cleartext fallback
-    example.net dane fallback=may
-.fi
-.ad
-.ft R
-.in -4
-.PP
-This feature is available in Postfix 2.12 and later.
 .SH smtp_tls_fingerprint_cert_match (default: empty)
 List of acceptable remote SMTP server certificate fingerprints for
 the "fingerprint" TLS security level (\fBsmtp_tls_security_level\fR =
index 05ff23f2b2d907ac6ac0740b441c8d6f26e279b2..c0c3ed2bc72fd809f6b7597950828afdb85057d5 100644 (file)
@@ -492,10 +492,6 @@ not an alias and its address records lie in an unsigned zone.
 RFC 6698 trust-anchor digest support in the Postfix TLS library.
 .IP "\fBtlsmgr_service_name (tlsmgr)\fR"
 The name of the \fBtlsmgr\fR(8) service entry in master.cf.
-.PP
-Available in Postfix version 2.12 and later:
-.IP "\fBsmtp_tls_fallback_level (empty)\fR"
-Optional fallback levels for authenticated TLS levels.
 .SH "OBSOLETE STARTTLS CONTROLS"
 .na
 .nf
index c63ab9e5ed4f60f4b74d41a23a2bf382d047a50d..bc492ebd506d2fd8e7dcdbc82aaec3db558af460 100644 (file)
@@ -1373,12 +1373,8 @@ for early adopters. <p>
 <li> <p> The "example.com" destination uses DANE, but if TLSA records
 are not present or are unusable, mail is deferred. </p>
 
-<li> <p> The "example.org" destination uses DANE if possible, but
-uses opportunistic TLS if no TLSA records are found.  The
-"fallback" attribute (Postfix &ge; 2.12) overrides the global
-main.cf smtp_tls_fallback_level parameter to employ unauthenticated
-mandatory encryption if DANE authentication fails, after logging a
-warning.  </p>
+<li> <p> The "example.org" destination uses DANE if possible, but if no TLSA
+records are found opportunistic TLS is used. </p>
 </ul>
 
 <blockquote>
@@ -1398,16 +1394,26 @@ main.cf:
     # default_transport = smtp, but some destinations are special:
     #
     transport_maps = ${indexed}transport
+</pre>
+</blockquote>
 
+<blockquote>
+<pre>
 transport:
     example.com dane
     example.org dane
+</pre>
+</blockquote>
 
+<blockquote>
+<pre>
 tls_policy:
     example.com dane-only
-    # Postfix &ge; 2.12, per-destination smtp_tls_fallback_level override
-    example.org dane fallback=encrypt
+</pre>
+</blockquote>
 
+<blockquote>
+<pre>
 master.cf:
     dane       unix  -       -       n       -       -       smtp
       -o smtp_dns_support_level=dnssec
@@ -2140,10 +2146,7 @@ href="#client_tls_encrypt">encrypt</a>.  When usable TLSA records
 are obtained for the remote SMTP server, SSLv2 is automatically
 disabled (see smtp_tls_mandatory_protocols), and the server certificate
 must match the TLSA records.  RFC 6698 (DANE) TLS authentication
-and DNSSEC support is available with Postfix 2.11 and later.  
-The optional "fallback" attribute provides a per-site override of
-the main.cf smtp_tls_fallback_level parameter (Postfix &ge; 2.12).
-</dd>
+and DNSSEC support is available with Postfix 2.11 and later.  </dd>
 
 <dt><b>dane-only</b></dt> <dd><a href="#client_tls_dane">Mandatory DANE TLS</a>.
 The TLS policy for the destination is obtained via TLSA records in
@@ -2152,10 +2155,7 @@ connection is made to the server.  When usable TLSA records are
 obtained for the remote SMTP server, SSLv2 is automatically disabled
 (see smtp_tls_mandatory_protocols), and the server certificate must
 match the TLSA records.  RFC 6698 (DANE) TLS authentication and
-DNSSEC support is available with Postfix 2.11 and later.  
-The optional "fallback" attribute provides a per-site override of
-the main.cf smtp_tls_fallback_level parameter (Postfix &ge; 2.12).
-</dd>
+DNSSEC support is available with Postfix 2.11 and later.  </dd>
 
 <dt><b>fingerprint</b></dt> <dd><a href="#client_tls_fprint">Certificate
 fingerprint verification.</a> Available with Postfix 2.5 and
@@ -2164,15 +2164,13 @@ authorities. The certificate trust chain, expiration date, ... are
 not checked. Instead, the optional <b>match</b> attribute, or else
 the main.cf <b>smtp_tls_fingerprint_cert_match</b> parameter, lists
 the server certificate fingerprints or public key fingerprints
-(Postfix 2.9 and later).  The digest algorithm used to calculate
-fingerprints is selected by the <b>smtp_tls_fingerprint_digest</b>
-parameter. Multiple fingerprints can be combined with a "|" delimiter
-in a single match attribute, or multiple match attributes can be
-employed. The ":" character is not used as a delimiter as it occurs
-between each pair of fingerprint (hexadecimal) digits.
-The optional "fallback" attribute provides a per-site override of
-the main.cf smtp_tls_fallback_level parameter (Postfix &ge; 2.12).
-</dd>
+(Postfix 2.9 and later).  The
+digest algorithm used to calculate fingerprints is selected by the
+<b>smtp_tls_fingerprint_digest</b> parameter. Multiple fingerprints can
+be combined with a "|" delimiter in a single match attribute, or multiple
+match attributes can be employed. The ":" character is not used as a
+delimiter as it occurs between each pair of fingerprint (hexadecimal)
+digits. </dd>
 
 <dt><b>verify</b></dt> <dd><a href="#client_tls_verify">Mandatory
 server certificate verification</a>.  Mail is delivered only if the
@@ -2183,11 +2181,9 @@ the optional "match" attribute (or the main.cf smtp_tls_verify_cert_match
 parameter value when no optional "match" attribute is specified).
 With Postfix &ge; 2.11 the "tafile" attribute optionally modifies
 trust chain verification in the same manner as the
-"smtp_tls_trust_anchor_file" parameter.  The "tafile" attribute may
-be specified multiple times to load multiple trust-anchor files.
-The optional "fallback" attribute provides a per-site override of
-the main.cf smtp_tls_fallback_level parameter (Postfix &ge; 2.12).
-</dd>
+"smtp_tls_trust_anchor_file" parameter.  The "tafile" attribute
+may be specified multiple times to load multiple trust-anchor
+files.  </dd>
 
 <dt><b>secure</b></dt> <dd><a href="#client_tls_secure">Secure certificate
 verification.</a> Mail is delivered only if the TLS handshake succeeds,
@@ -2199,10 +2195,7 @@ main.cf smtp_tls_secure_cert_match parameter value when no optional
 attribute optionally modifies trust chain verification in the same manner
 as the "smtp_tls_trust_anchor_file" parameter.  The "tafile" attribute
 may be specified multiple times to load multiple trust-anchor
-files.  
-The optional "fallback" attribute provides a per-site override of
-the main.cf smtp_tls_fallback_level parameter (Postfix &ge; 2.12).
-</dd>
+files.  </dd>
 
 </dl>
 
@@ -2249,7 +2242,6 @@ Example:
     smtp_tls_policy_maps = hash:/etc/postfix/tls_policy
     # Postfix 2.5 and later
     smtp_tls_fingerprint_digest = md5
-
 /etc/postfix/tls_policy:
     example.edu             none
     example.mil             may
@@ -2264,8 +2256,6 @@ Example:
        match=3D:95:34:51:24:66:33:B9:D2:40:99:C0:C1:17:0B:D1
     # Postfix 2.6 and later
     example.info            may protocols=!SSLv2 ciphers=medium exclude=3DES
-    # Postfix 2.12 and later override of smtp_tls_fallback_level
-    fallback.example        secure fallback=encrypt
 </pre>
 </blockquote>
 
index 3d016e68becfd6612f5dda74ac706f51687e0ec3..d481280656ff14d4fb0bb2e305a916949a1b30b7 100644 (file)
@@ -16205,64 +16205,6 @@ mail. </dd>
 
 <p> This feature is available in Postfix 2.12 and later. </p>
 
-%PARAM smtp_tls_fallback_level
-
-<p> Optional fallback levels for authenticated TLS levels.  Specify
-a white-space or comma-separated list of
-<b>policy_level</b>=<b>fallback_level</b> pairs.  The <b>policy_level</b>
-must require authentication (one of dane, dane-only, fingerprint,
-verify, secure).  The <b>fallback_level</b> must be "encrypt" or
-"may".  When an authenticated connection at some desired policy
-level cannot be established, delivery will proceed at the correponding
-fallback level if possible.  A warning will be logged
-indicating the fallback reason. </p>
-
-<p> The TLS <a href="TLS_README.html#client_tls_policy">policy</a> table
-can be used to specify a destination-specific fallback strategy via the
-"fallback" policy attribute.  The value of the "fallback" attribute, if
-specified, must be "may", "encrypt" or "none".  If not "none", this
-specifies the fallback level for the destination in question.  If the
-attribute value is "none", fallback is suppressed for the destination
-even if enabled via a global setting of smtp_tls_fallback_level.  </p>
-
-<p> Example: </p>
-
-<blockquote>
-<pre>
-/etc/postfix/main.cf:
-    # When authentication fails, log a warning and deliver anyway
-    # over an unauthenticated TLS connection.
-    #
-    smtp_tls_fallback_level =
-       dane=encrypt,
-       dane-only=encrypt,
-       fingerprint=encrypt,
-       verify=encrypt,
-       secure=encrypt
-    indexed = ${default_database_type}:${config_directory}/
-    smtp_tls_policy_maps = ${indexed}tls-policy
-</pre>
-</blockquote>
-
-<blockquote>
-<pre>
-/etc/postfix/tls-policy:
-    # No fallback for example.com
-    example.com secure fallback=none
-    # For example.net tolerate cleartext fallback
-    example.net dane fallback=may
-</pre>
-</blockquote>
-
-<p> This feature is available in Postfix 2.12 and later. </p>
-
-%PARAM lmtp_tls_fallback_level
-
-<p> The LMTP-specific version of the smtp_tls_fallback_level
-configuration parameter.  See there for details. </p>
-
-<p> This feature is available in Postfix 2.12 and later. </p>
-
 %PARAM compatibility_level 0
 
 <p> A safety net that causes Postfix to run with backwards-compatible
index 1891c082d3e9c5564faade7e80d4a085a04a7630..a18c3cdaaa2e5e7b48c734d6533f4ee5c1638e34 100644 (file)
@@ -61,6 +61,7 @@ typedef struct CLEANUP_STATE {
     char   *orig_rcpt;                 /* original recipient address */
     char   *return_receipt;            /* return-receipt address */
     char   *errors_to;                 /* errors-to address */
+    ARGV   *auto_hdrs;                 /* MTA's own header(s) */
     int     flags;                     /* processing options, status flags */
     int     qmgr_opts;                 /* qmgr processing options */
     int     errs;                      /* any badness experienced */
index 66d33026e697d3b7233527a28f840c078a703056..a117500d2f846056b2408aacc6c06324c5b7df1f 100644 (file)
@@ -360,7 +360,7 @@ void    cleanup_pre_jail(char *unused_name, char **unused_argv)
            name_mask(VAR_CANON_CLASSES, rcpt_canon_class_table,
                      var_rcpt_canon_classes);
     if (*var_masq_domains)
-       cleanup_masq_domains = argv_split(var_masq_domains, " ,\t\r\n");
+       cleanup_masq_domains = argv_split(var_masq_domains, CHARS_COMMA_SP);
     if (*var_header_checks)
        cleanup_header_checks =
            maps_create(VAR_HEADER_CHECKS, var_header_checks, DICT_FLAG_LOCK);
index 9bf9761bf01f6a163cdda271b355e5311d5de124..e81bc188c74618b5da809d526c18d102525cea42 100644 (file)
@@ -207,7 +207,7 @@ int     main(int argc, char **argv)
     var_masq_exceptions = argv[1];
     cleanup_masq_exceptions =
        string_list_init(MATCH_FLAG_RETURN, var_masq_exceptions);
-    masq_domains = argv_split(argv[2], " ,\t\r\n");
+    masq_domains = argv_split(argv[2], CHARS_COMMA_SP);
     addr = vstring_alloc(1);
     if (strchr(argv[3], '@') == 0)
        msg_fatal("address must be in user@domain form");
index 7860df213b006a994f4ffd1129d9e6d54c0b9592..a233b0220fbdac1402ef07e8cbda3183c8b91d10 100644 (file)
@@ -479,6 +479,10 @@ static void cleanup_header_callback(void *context, int header_class,
     if (hdr_opts && (hdr_opts->flags & HDR_OPT_MIME))
        header_class = MIME_HDR_MULTIPART;
 
+    /* Update the Received: header count before maybe dropping headers below. */
+    if (hdr_opts && hdr_opts->type == HDR_RECEIVED)
+       state->hop_count += 1;
+
     if ((state->flags & CLEANUP_FLAG_FILTER)
        && (CHECK(MIME_HDR_PRIMARY, cleanup_header_checks, VAR_HEADER_CHECKS)
     || CHECK(MIME_HDR_MULTIPART, cleanup_mimehdr_checks, VAR_MIMEHDR_CHECKS)
@@ -579,12 +583,16 @@ static void cleanup_header_callback(void *context, int header_class,
            msg_info("%s: message-id=%s", state->queue_id, hdrval);
        if (hdr_opts->type == HDR_RESENT_MESSAGE_ID)
            msg_info("%s: resent-message-id=%s", state->queue_id, hdrval);
-       if (hdr_opts->type == HDR_RECEIVED)
-           if (++state->hop_count >= var_hopcount_limit) {
+       if (hdr_opts->type == HDR_RECEIVED) {
+           if (state->hop_count >= var_hopcount_limit) {
                msg_warn("%s: message rejected: hopcount exceeded",
                         state->queue_id);
                state->errs |= CLEANUP_STAT_HOPS;
            }
+           /* Save our Received: header after maybe updating headers above. */
+           if (state->hop_count == 1)
+               argv_add(state->auto_hdrs, vstring_str(header_buf), ARGV_END);
+       }
        if (CLEANUP_OUT_OK(state)) {
            if (hdr_opts->flags & HDR_OPT_RR)
                state->resent = "Resent-";
@@ -622,6 +630,19 @@ static void cleanup_header_done_callback(void *context)
     if (CLEANUP_OUT_OK(state) == 0)
        return;
 
+    /*
+     * Future proofing: the Milter client's header suppression algorithm
+     * assumes that the MTA prepends its own Received: header. This
+     * assupmtion may be violated after some source-code update. The
+     * following check ensures consistency, at least for local submission.
+     */
+    if (state->hop_count < 1) {
+       msg_warn("%s: message rejected: no Received: header",
+                state->queue_id);
+       state->errs |= CLEANUP_STAT_BAD;
+       return;
+    }
+
     /*
      * Add a missing (Resent-)Message-Id: header. The message ID gives the
      * time in GMT units, plus the local queue ID.
index db38c911f10dc06d731f4a03e7d7ac839b2f4129..2894fa011ff29ba095238098ff6e1bedd0755fc2 100644 (file)
@@ -2020,7 +2020,7 @@ void    cleanup_milter_inspect(CLEANUP_STATE *state, MILTERS *milters)
      * filter library.
      */
     if ((resp = milter_message(milters, state->handle->stream,
-                              state->data_offset)) != 0)
+                              state->data_offset, state->auto_hdrs)) != 0)
        cleanup_milter_apply(state, "END-OF-MESSAGE", resp);
 
     /*
index 340d32d6274681483b8fc627763bee212365b021..e061921ff9993e890021e194cb4ac556df812f75 100644 (file)
@@ -78,6 +78,7 @@ CLEANUP_STATE *cleanup_state_alloc(VSTREAM *src)
     state->orig_rcpt = 0;
     state->return_receipt = 0;
     state->errors_to = 0;
+    state->auto_hdrs = argv_alloc(1);
     state->flags = 0;
     state->qmgr_opts = 0;
     state->errs = 0;
@@ -152,6 +153,7 @@ void    cleanup_state_free(CLEANUP_STATE *state)
        myfree(state->return_receipt);
     if (state->errors_to)
        myfree(state->errors_to);
+    argv_free(state->auto_hdrs);
     if (state->queue_name)
        myfree(state->queue_name);
     if (state->queue_id)
index 572f4e37a228b81caa6a608327b77d15cb2b4885..8da9033bae8ad55abae58a6b11665eae1b32c84a 100644 (file)
@@ -109,7 +109,7 @@ int     main(int argc, char **argv)
     msg_vstream_init(argv[0], VSTREAM_ERR);
     if (argc != 3)
        msg_fatal("usage: %s types name", argv[0]);
-    types_argv = argv_split(argv[1], ", \t\r\n");
+    types_argv = argv_split(argv[1], CHARS_COMMA_SP);
     types = (unsigned *) mymalloc(sizeof(*types) * (types_argv->argc + 1));
     for (i = 0; i < types_argv->argc; i++)
        if ((types[i] = dns_type(types_argv->argv[i])) == 0)
index b3454335f3c824ea4f065f24d0e9b347b042f017..c5bd616d8f0005ccc1e4f9a97183ce48b0e78aff 100644 (file)
@@ -26,7 +26,7 @@
 /*     Pointer to input string. The input is modified.
 /* .IP "delimiters, parens"
 /*     See mystrtok(3) for description. Typical values are
-/*     ", \\t\\r\\n" and "{}", respectively.
+/*     CHARS_COMMA_SP and CHARS_BRACE, respectively.
 /* .PP
 /*     The parens argument is followed by a list of (key, value)
 /*     argument pairs. Each key may appear only once.  The list
index 0b7bf80277a116ecf1d18d7ea7d997bd2af26040..0c1182d7b526da998447b4cfec0341dde2ce5de8 100644 (file)
@@ -1683,7 +1683,7 @@ DICT   *dict_ldap_open(const char *ldapsource, int open_flags, int dict_flags)
 
     url_list = vstring_alloc(32);
     s = server_host;
-    while ((h = mystrtok(&s, " \t\n\r,")) != NULL) {
+    while ((h = mystrtok(&s, CHARS_COMMA_SP)) != NULL) {
 #if defined(LDAP_API_FEATURE_X_OPENLDAP)
 
        /*
@@ -1815,14 +1815,14 @@ DICT   *dict_ldap_open(const char *ldapsource, int open_flags, int dict_flags)
 
     /* Order matters, first the terminal attributes: */
     attr = cfg_get_str(dict_ldap->parser, "terminal_result_attribute", "", 0, 0);
-    dict_ldap->result_attributes = argv_split(attr, " ,\t\r\n");
+    dict_ldap->result_attributes = argv_split(attr, CHARS_COMMA_SP);
     dict_ldap->num_terminal = dict_ldap->result_attributes->argc;
     myfree(attr);
 
     /* Order matters, next the leaf-only attributes: */
     attr = cfg_get_str(dict_ldap->parser, "leaf_result_attribute", "", 0, 0);
     if (*attr)
-       argv_split_append(dict_ldap->result_attributes, attr, " ,\t\r\n");
+       argv_split_append(dict_ldap->result_attributes, attr, CHARS_COMMA_SP);
     dict_ldap->num_leaf =
        dict_ldap->result_attributes->argc - dict_ldap->num_terminal;
     myfree(attr);
@@ -1830,14 +1830,14 @@ DICT   *dict_ldap_open(const char *ldapsource, int open_flags, int dict_flags)
     /* Order matters, next the regular attributes: */
     attr = cfg_get_str(dict_ldap->parser, "result_attribute", "maildrop", 0, 0);
     if (*attr)
-       argv_split_append(dict_ldap->result_attributes, attr, " ,\t\r\n");
+       argv_split_append(dict_ldap->result_attributes, attr, CHARS_COMMA_SP);
     dict_ldap->num_attributes = dict_ldap->result_attributes->argc;
     myfree(attr);
 
     /* Order matters, finally the special attributes: */
     attr = cfg_get_str(dict_ldap->parser, "special_result_attribute", "", 0, 0);
     if (*attr)
-       argv_split_append(dict_ldap->result_attributes, attr, " ,\t\r\n");
+       argv_split_append(dict_ldap->result_attributes, attr, CHARS_COMMA_SP);
     myfree(attr);
 
     /*
index 268f51d33b8eef21b3f6b064fd2db6bcb38b5b91..d5a6254c8b748a04eae9cc063eab6784bab472dd 100644 (file)
@@ -683,7 +683,7 @@ static void mysql_parse_config(DICT_MYSQL *dict_mysql, const char *mysqlcf)
 
     hosts = cfg_get_str(p, "hosts", "", 0, 0);
 
-    dict_mysql->hosts = argv_split(hosts, " ,\t\r\n");
+    dict_mysql->hosts = argv_split(hosts, CHARS_COMMA_SP);
     if (dict_mysql->hosts->argc == 0) {
        argv_add(dict_mysql->hosts, "localhost", ARGV_END);
        argv_terminate(dict_mysql->hosts);
index b96a81fe3a50ff452b6bf5edca086b7d1017dd9c..efe4957e6e34cbada6a589077ade70d463efc086 100644 (file)
@@ -735,7 +735,7 @@ static void pgsql_parse_config(DICT_PGSQL *dict_pgsql, const char *pgsqlcf)
 
     hosts = cfg_get_str(p, "hosts", "", 0, 0);
 
-    dict_pgsql->hosts = argv_split(hosts, " ,\t\r\n");
+    dict_pgsql->hosts = argv_split(hosts, CHARS_COMMA_SP);
     if (dict_pgsql->hosts->argc == 0) {
        argv_add(dict_pgsql->hosts, "localhost", ARGV_END);
        argv_terminate(dict_pgsql->hosts);
index 9ad465e2c01f7a2e7b05707a167690923864496c..40626bbb7fe4a68ff8e12ffc6532272b8740afed 100644 (file)
@@ -133,7 +133,7 @@ static void mail_conf_checkdir(const char *config_dir)
        if (split_nameval(vstring_str(buf), &name, &value) == 0
            && (strcmp(name, VAR_CONFIG_DIRS) == 0
                || strcmp(name, VAR_MULTI_CONF_DIRS) == 0)) {
-           while (found == 0 && (cp = mystrtok(&value, ", \t\r\n")) != 0)
+           while (found == 0 && (cp = mystrtok(&value, CHARS_COMMA_SP)) != 0)
                if (strcmp(cp, config_dir) == 0)
                    found = 1;
        }
index 415387dd9a2399d72ddb0fd3bb6fd196a4926f7c..18e84abd9e5d31092adf70f4cd5b3b8fc437c9c0 100644 (file)
@@ -898,11 +898,11 @@ void    mail_params_init()
     /*
      * XXX These should be caught by a proper parameter parsing algorithm.
      */
-    if (var_myorigin[strcspn(var_myorigin, ", \t\r\n")])
+    if (var_myorigin[strcspn(var_myorigin, CHARS_COMMA_SP)])
        msg_fatal("%s parameter setting must not contain multiple values: %s",
                  VAR_MYORIGIN, var_myorigin);
 
-    if (var_relayhost[strcspn(var_relayhost, ", \t\r\n")])
+    if (var_relayhost[strcspn(var_relayhost, CHARS_COMMA_SP)])
        msg_fatal("%s parameter setting must not contain multiple values: %s",
                  VAR_RELAYHOST, var_relayhost);
 
index 95f80490b51658a19ca6e90e806307d4c8b35b00..6cdfa24822c7f7dfe7a12b5f2e1f9cc582c78b82 100644 (file)
@@ -171,7 +171,7 @@ const char *mail_queue_dir(VSTRING *buf, const char *queue_name,
     }
     if (hash_buf == 0) {
        hash_buf = vstring_alloc(100);
-       hash_queue_names = argv_split(var_hash_queue_names, " \t\r\n,");
+       hash_queue_names = argv_split(var_hash_queue_names, CHARS_COMMA_SP);
     }
 
     /*
index ed2e3069ca057845af66a49a81844629119f584e..1cf37dafca02b581c9944f33d841c8b73ebb9c18 100644 (file)
@@ -20,7 +20,7 @@
   * Patches change both the patchlevel and the release date. Snapshots have no
   * patchlevel; they change the release date only.
   */
-#define MAIL_RELEASE_DATE      "20141015"
+#define MAIL_RELEASE_DATE      "20141019"
 #define MAIL_VERSION_NUMBER    "2.12"
 
 #ifdef SNAPSHOT
index b0e0b9b5b73d3e56f352d3545dd73ef5a2a95f0d..2a46f7c905d0d91028f202d1e3626e7af064b151 100644 (file)
@@ -114,8 +114,8 @@ MAPS   *maps_create(const char *title, const char *map_names, int dict_flags)
     const char *myname = "maps_create";
     char   *temp;
     char   *bufp;
-    static char sep[] = " \t,\r\n";
-    static char parens[] = "{}";
+    static char sep[] = CHARS_COMMA_SP;
+    static char parens[] = CHARS_BRACE;
     MAPS   *maps;
     char   *map_type_name;
     VSTRING *map_type_name_flags;
index ad029892c58da4a4e54edccedce39f6c7119d911..856355eddbb6809b32159482325079f59f9c222f 100644 (file)
@@ -98,7 +98,7 @@ static void match_service_compat(ARGV *argv)
 
 ARGV   *match_service_init(const char *patterns)
 {
-    const char *delim = " ,\t\r\n";
+    const char *delim = CHARS_COMMA_SP;
     ARGV   *list = argv_alloc(1);
     char   *saved_patterns = mystrdup(patterns);
     char   *bp = saved_patterns;
index aac532c532fde4d07cd07bfb9f948708b7545e37..32a32b010a40a8b811a009c2f6981f902f1ced66 100644 (file)
@@ -547,7 +547,7 @@ int     pipe_command(VSTREAM *src, DSN_BUF *why,...)
            execvp(args.argv[0], args.argv);
            msg_fatal("%s: execvp %s: %m", myname, args.argv[0]);
        } else if (args.shell && *args.shell) {
-           argv = argv_split(args.shell, " \t\r\n");
+           argv = argv_split(args.shell, CHARS_SPACE);
            argv_add(argv, args.command, (char *) 0);
            argv_terminate(argv);
            execvp(argv->argv[0], argv->argv);
index 2a242ae0e4dffdc06c7d2091c483b63f41fccd7b..802f62f1cd36bf83edf258c19abe0a7ccacd3266 100644 (file)
@@ -379,7 +379,7 @@ int     main(int unused_argc, char **unused_argv)
     vstream_fileno(VSTREAM_ERR) = 1;
 
     while (get_buffer(buf, VSTREAM_IN, interactive) != VSTREAM_EOF) {
-       argv = argv_split(STR(buf), " \t\r\n");
+       argv = argv_split(STR(buf), CHARS_SPACE);
        if (argv->argc > 0 && argv->argv[0][0] != '#') {
            msg_verbose = verbose_level;
            for (ap = actions; ap->command != 0; ap++) {
index d05128dd703f30abd6116570dbb8d5a7bab3807b..7605e5f5976fdbd31c0f208c22ab77fa6d3ec649 100644 (file)
@@ -87,8 +87,6 @@
 
 /* Application-specific. */
 
-#define SERVER_ACL_SEPARATORS  ", \t\r\n"
-
 static ADDR_MATCH_LIST *server_acl_mynetworks;
 static ADDR_MATCH_LIST *server_acl_mynetworks_host;
 
@@ -129,7 +127,7 @@ SERVER_ACL *server_acl_parse(const char *extern_acl, const char *origin)
      * chroot jail, while access lists are evaluated after entering the
      * chroot jail.
      */
-    while ((acl = mystrtokq(&bp, SERVER_ACL_SEPARATORS, "{}")) != 0) {
+    while ((acl = mystrtokq(&bp, CHARS_COMMA_SP, CHARS_BRACE)) != 0) {
        if (strchr(acl, ':') != 0) {
            if (strchr(origin, ':') != 0) {
                msg_warn("table %s: lookup result \"%s\" is not allowed"
@@ -196,7 +194,7 @@ int     server_acl_eval(const char *client_addr, SERVER_ACL * intern_acl,
                msg_panic("%s: unexpected dictionary: %s", myname, acl);
            if ((dict_val = dict_get(dict, client_addr)) != 0) {
                /* Fake up an ARGV to avoid lots of mallocs and frees. */
-               if (dict_val[strcspn(dict_val, ":" SERVER_ACL_SEPARATORS)] == 0) {
+               if (dict_val[strcspn(dict_val, ":" CHARS_COMMA_SP)] == 0) {
                    ARGV_FAKE_BEGIN(fake_argv, dict_val);
                    ret = server_acl_eval(client_addr, &fake_argv, acl);
                    ARGV_FAKE_END;
index 7468c1f0c6a12b6d0d40e9dd72fc28ac8b3552b4..e6de59bccb1f344bbf2a876d5b310f167288973e 100644 (file)
@@ -221,8 +221,8 @@ static void update(char *query)
     char   *status_text;
     char   *cp = query;
 
-    if ((addr = mystrtok(&cp, " \t\r\n")) == 0
-       || (status_text = mystrtok(&cp, " \t\r\n")) == 0) {
+    if ((addr = mystrtok(&cp, CHARS_SPACE)) == 0
+       || (status_text = mystrtok(&cp, CHARS_SPACE)) == 0) {
        msg_warn("bad request format");
        return;
     }
@@ -276,7 +276,7 @@ int     main(int argc, char **argv)
 
     while (vstring_fgets_nonl(buffer, VSTREAM_IN)) {
        cp = STR(buffer);
-       if ((command = mystrtok(&cp, " \t\r\n")) == 0)
+       if ((command = mystrtok(&cp, CHARS_SPACE)) == 0)
            continue;
        if (strcmp(command, "query") == 0)
            query(cp, buffer);
index 7b7309e40d24e38732cb95699ceff8b0d0ec623b..3ce2cfca90565c5422d76af8601151de1860c980 100644 (file)
@@ -194,7 +194,7 @@ int     deliver_dotforward(LOCAL_STATE state, USER_ATTR usr_attr, int *statusp)
     next = saved_forward_path;
     lookup_status = -1;
 
-    while ((lhs = mystrtok(&next, ", \t\r\n")) != 0) {
+    while ((lhs = mystrtok(&next, CHARS_COMMA_SP)) != 0) {
        expand_status = local_expand(path, lhs, &state, &usr_attr,
                                     var_fwd_exp_filter);
        if ((expand_status & (MAC_PARSE_ERROR | MAC_PARSE_UNDEF)) == 0) {
index 739cd044eb9a7c3163e93932806685935bf1a9cc..69cff9f51fe58acef2d1eb438d75cf33beb80b05 100644 (file)
@@ -109,7 +109,7 @@ static int master_line_last;                /* config file line number */
 static int master_line;                        /* config file line number */
 static ARGV *master_disable;           /* disabled service patterns */
 
-static char master_blanks[] = " \t\r\n";/* field delimiters */
+static char master_blanks[] = CHARS_SPACE;/* field delimiters */
 
 /* fset_master_ent - specify configuration file pathname */
 
@@ -561,8 +561,9 @@ MASTER_SERV *get_master_ent()
        argv_add(serv->args, "-s",
            vstring_str(vstring_sprintf(junk, "%d", serv->listen_fd_count)),
                 (char *) 0);
-    while ((cp = mystrtokq(&bufp, master_blanks, "{}")) != 0) {
-       if (*cp == '{' && (err = extpar(&cp, "{}", EXTPAR_FLAG_STRIP)) != 0)
+    while ((cp = mystrtokq(&bufp, master_blanks, CHARS_BRACE)) != 0) {
+       if (*cp == CHARS_BRACE[0]
+           && (err = extpar(&cp, CHARS_BRACE, EXTPAR_FLAG_STRIP)) != 0)
            fatal_with_context("%s", err);
        argv_add(serv->args, cp, (char *) 0);
     }
index 87dad812aafe4588d254ccf1c6ac62dcbbac0b99..ab63c68fc907799f3925a058e0fc741381657e9d 100644 (file)
 /*     const char *milter_other_event(milters)
 /*     MILTERS *milters;
 /*
-/*     const char *milter_message(milters, qfile, data_offset)
+/*     const char *milter_message(milters, qfile, data_offset, auto_hdrs)
 /*     MILTERS *milters;
 /*     VSTREAM *qfile;
 /*     off_t   data_offset;
+/*     ARGV    *auto_hdrs;
 /*
 /*     const char *milter_abort(milters)
 /*     MILTERS *milters;
@@ -269,7 +270,7 @@ static ARGV *milter_macro_lookup(MILTERS *milters, const char *macro_names)
     const char *value;
     const char *name;
 
-    while ((name = mystrtok(&cp, ", \t\r\n")) != 0) {
+    while ((name = mystrtok(&cp, CHARS_COMMA_SP)) != 0) {
        if (msg_verbose)
            msg_info("%s: \"%s\"", myname, name);
        if ((value = milters->mac_lookup(name, milters->mac_context)) != 0) {
@@ -483,7 +484,8 @@ const char *milter_other_event(MILTERS *milters)
 
 /* milter_message - inspect message content */
 
-const char *milter_message(MILTERS *milters, VSTREAM *fp, off_t data_offset)
+const char *milter_message(MILTERS *milters, VSTREAM *fp, off_t data_offset,
+                                  ARGV *auto_hdrs)
 {
     const char *resp;
     MILTER *m;
@@ -497,7 +499,8 @@ const char *milter_message(MILTERS *milters, VSTREAM *fp, off_t data_offset)
     for (resp = 0, m = milters->milter_list; resp == 0 && m != 0; m = m->next) {
        any_eoh_macros = MILTER_MACRO_EVAL(global_eoh_macros, m, milters, eoh_macros);
        any_eod_macros = MILTER_MACRO_EVAL(global_eod_macros, m, milters, eod_macros);
-       resp = m->message(m, fp, data_offset, any_eoh_macros, any_eod_macros);
+       resp = m->message(m, fp, data_offset, any_eoh_macros, any_eod_macros,
+                         auto_hdrs);
        if (any_eoh_macros != global_eoh_macros)
            argv_free(any_eoh_macros);
        if (any_eod_macros != global_eod_macros)
@@ -576,8 +579,8 @@ MILTERS *milter_new(const char *names,
     MILTER *tail = 0;
     char   *name;
     MILTER *milter;
-    const char *sep = ", \t\r\n";
-    const char *parens = "{}";
+    const char *sep = CHARS_COMMA_SP;
+    const char *parens = CHARS_BRACE;
     int     my_conn_timeout;
     int     my_cmd_timeout;
     int     my_msg_timeout;
@@ -612,7 +615,7 @@ MILTERS *milter_new(const char *names,
            my_msg_timeout = msg_timeout;
            my_protocol = protocol;
            my_def_action = def_action;
-           if (name[0] == '{') {               /* } */
+           if (name[0] == parens[0]) {
                op = name;
                if ((err = extpar(&op, parens, EXTPAR_FLAG_NONE)) != 0)
                    msg_fatal("milter service syntax error: %s", err);
index 17d163dc42a3d0c42bea40736e5c087b6b0d56d5..bf25fccc040ef9b08832f9be6c98a5c02e1926cd 100644 (file)
@@ -40,7 +40,7 @@ typedef struct MILTER {
     const char *(*mail_event) (struct MILTER *, const char **, ARGV *);
     const char *(*rcpt_event) (struct MILTER *, const char **, ARGV *);
     const char *(*data_event) (struct MILTER *, ARGV *);
-    const char *(*message) (struct MILTER *, VSTREAM *, off_t, ARGV *, ARGV *);
+    const char *(*message) (struct MILTER *, VSTREAM *, off_t, ARGV *, ARGV *, ARGV *);
     const char *(*unknown_event) (struct MILTER *, const char *, ARGV *);
     const char *(*other_event) (struct MILTER *);
     void    (*abort) (struct MILTER *);
@@ -136,7 +136,7 @@ extern const char *milter_helo_event(MILTERS *, const char *, int);
 extern const char *milter_mail_event(MILTERS *, const char **);
 extern const char *milter_rcpt_event(MILTERS *, int, const char **);
 extern const char *milter_data_event(MILTERS *);
-extern const char *milter_message(MILTERS *, VSTREAM *, off_t);
+extern const char *milter_message(MILTERS *, VSTREAM *, off_t, ARGV *);
 extern const char *milter_unknown_event(MILTERS *, const char *);
 extern const char *milter_other_event(MILTERS *);
 extern void milter_abort(MILTERS *);
index 74a50e8739f464bcc4ad62afba8219d70ae1881f..b065f235f1e7389e8240eaeda0940c9d1e48daf8 100644 (file)
@@ -1648,7 +1648,7 @@ static void milter8_connect(MILTER8 *milter)
      * don't want to take the risk that a future version will be more picky.
      */
     cp = saved_version = mystrdup(milter->protocol);
-    while ((name = mystrtok(&cp, " ,\t\r\n")) != 0) {
+    while ((name = mystrtok(&cp, CHARS_COMMA_SP)) != 0) {
        int     mask;
        int     vers;
 
@@ -2285,6 +2285,8 @@ typedef struct {
     MILTER8 *milter;                   /* milter client */
     ARGV   *eoh_macros;                        /* end-of-header macros */
     ARGV   *eod_macros;                        /* end-of-body macros */
+    ARGV   *auto_hdrs;                 /* auto-generated headers */
+    int     auto_done;                 /* good enough for now */
     int     first_header;              /* first header */
     int     first_body;                        /* first body line */
     const char *resp;                  /* milter application response */
@@ -2301,6 +2303,8 @@ static void milter8_header(void *ptr, int unused_header_class,
     MILTER8 *milter = msg_ctx->milter;
     char   *cp;
     int     skip_reply;
+    char  **cpp;
+    unsigned done;
 
     /*
      * XXX Workaround: mime_state_update() may invoke multiple call-backs
@@ -2329,10 +2333,11 @@ static void milter8_header(void *ptr, int unused_header_class,
      * XXX Sendmail compatibility. It eats the first space (not tab) after the
      * header label and ":".
      */
-    if (msg_ctx->first_header) {
-       msg_ctx->first_header = 0;
-       return;
-    }
+    for (cpp = msg_ctx->auto_hdrs->argv, done = 1; *cpp; cpp++, done <<= 1)
+       if ((msg_ctx->auto_done & done) == 0 && strcmp(*cpp, STR(buf)) == 0) {
+           msg_ctx->auto_done |= done;
+           return;
+       }
 
     /*
      * Sendmail 8 sends multi-line headers as text separated by newline.
@@ -2507,7 +2512,8 @@ static void milter8_eob(void *ptr)
 static const char *milter8_message(MILTER *m, VSTREAM *qfile,
                                           off_t data_offset,
                                           ARGV *eoh_macros,
-                                          ARGV *eod_macros)
+                                          ARGV *eod_macros,
+                                          ARGV *auto_hdrs)
 {
     const char *myname = "milter8_message";
     MILTER8 *milter = (MILTER8 *) m;
@@ -2541,6 +2547,8 @@ static const char *milter8_message(MILTER *m, VSTREAM *qfile,
        msg_ctx.milter = milter;
        msg_ctx.eoh_macros = eoh_macros;
        msg_ctx.eod_macros = eod_macros;
+       msg_ctx.auto_hdrs = auto_hdrs;
+       msg_ctx.auto_done = 0;
        msg_ctx.first_header = 1;
        msg_ctx.first_body = 1;
        msg_ctx.resp = 0;
index 33cfad725817c06a23874480e28db4acc2047a1b..6112e0585f1cd3ab92c9ca7021cbefdaef04767e 100644 (file)
@@ -1101,7 +1101,7 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message)
         */
        if (*var_defer_xports && (message->qflags & QMGR_FLUSH_DFXP) == 0) {
            if (defer_xport_argv == 0)
-               defer_xport_argv = argv_split(var_defer_xports, " \t\r\n,");
+               defer_xport_argv = argv_split(var_defer_xports, CHARS_COMMA_SP);
            for (cpp = defer_xport_argv->argv; *cpp; cpp++)
                if (strcmp(*cpp, STR(reply.transport)) == 0)
                    break;
index 97405194e4d31c6716a02bf49e88b81194ca0569..2d1ab5c76259e2c08148251bca138d9511981999 100644 (file)
@@ -162,7 +162,7 @@ static void pcf_register_dbms_helper(char *str_value,
      * Naive parsing. We don't really know if this substring specifies a
      * database or some other text.
      */
-    while ((db_type = mystrtokq(&str_value, " ,\t\r\n", "{}")) != 0) {
+    while ((db_type = mystrtokq(&str_value, CHARS_COMMA_SP, CHARS_BRACE)) != 0) {
 
        /*
         * Skip over "proxy:" maptypes, to emulate the proxymap(8) server's
@@ -180,8 +180,8 @@ static void pcf_register_dbms_helper(char *str_value,
         * local or global namespace.
         */
        if (prefix != 0 && *prefix != '/' && *prefix != '.') {
-           if (*prefix == '{') {               /* } */
-               if ((err = extpar(&prefix, "{}", EXTPAR_FLAG_NONE)) != 0) {
+           if (*prefix == CHARS_BRACE[0]) {
+               if ((err = extpar(&prefix, CHARS_BRACE, EXTPAR_FLAG_NONE)) != 0) {
                    /* XXX Encapsulate this in pcf_warn() function. */
                    if (local_scope)
                        msg_warn("%s:%s: %s",
index 4781c46f457a85d80bf17f3fd84a3222930d6d81..7a92087339f10904421745e3cd3d82d8a1ba1d7f 100644 (file)
@@ -234,7 +234,7 @@ void    pcf_edit_main(int mode, int argc, char **argv)
        }
        /* Copy or replace start of logical line. */
        else {
-           vstring_strncpy(key, cp, strcspn(cp, " \t\r\n="));
+           vstring_strncpy(key, cp, strcspn(cp, CHARS_SPACE "="));
            cvalue = (struct cvalue *) htable_find(table, STR(key));
            if ((interesting = !!cvalue) != 0) {
                if (cvalue->found++ == 1)
index a745df20cb675a8f8abe8adcd47671738fc7c7ca..7f9a5c1b519b23ad722b3e484eda3ec41f442378 100644 (file)
@@ -261,16 +261,16 @@ static void pcf_normalize_daemon_args(ARGV *argv)
            argv_insert_one(argv, field + 1, arg + 2);
            arg[2] = 0;                         /* XXX argv_replace_one() */
            field += 1;
-           extract_field = (argv->argv[field][0] == '{');
+           extract_field = (argv->argv[field][0] == CHARS_BRACE[0]);
        } else if (argv->argv[field + 1] != 0) {
            /* Already in "-o" "name=value" form. */
            field += 1;
-           extract_field = (argv->argv[field][0] == '{');
+           extract_field = (argv->argv[field][0] == CHARS_BRACE[0]);
        } else
            extract_field = 0;
        /* Extract text inside {}, optionally convert to name=value. */
        if (extract_field) {
-           pcf_extract_field(argv, field, "{}");
+           pcf_extract_field(argv, field, CHARS_BRACE);
            if (argv->argv[field - 1][1] == 'o')
                pcf_normalize_nameval(argv, field);
        }
@@ -278,8 +278,8 @@ static void pcf_normalize_daemon_args(ARGV *argv)
     /* Normalize non-option arguments. */
     for ( /* void */ ; argv->argv[field] != 0; field++)
        /* Extract text inside {}. */
-       if (argv->argv[field][0] == '{')        /* } */
-           pcf_extract_field(argv, field, "{}");
+       if (argv->argv[field][0] == CHARS_BRACE[0])
+           pcf_extract_field(argv, field, CHARS_BRACE);
 }
 
 /* pcf_fix_fatal - fix multiline text before release */
@@ -370,7 +370,7 @@ const char *pcf_parse_master_entry(PCF_MASTER_ENT *masterp, const char *buf)
      * 
      * XXX Do per-field sanity checks.
      */
-    argv = argv_splitq(buf, PCF_MASTER_BLANKS, "{}");
+    argv = argv_splitq(buf, PCF_MASTER_BLANKS, CHARS_BRACE);
     if (argv->argc < PCF_MASTER_MIN_FIELDS) {
        argv_free(argv);                        /* Coverity 201311 */
        return ("bad field count");
@@ -829,7 +829,7 @@ void    pcf_edit_master_field(PCF_MASTER_ENT *masterp, int field,
      */
     if (field == PCF_MASTER_FLD_CMD) {
        argv_truncate(masterp->argv, PCF_MASTER_FLD_CMD);
-       argv_splitq_append(masterp->argv, new_value, PCF_MASTER_BLANKS, "{}");
+       argv_splitq_append(masterp->argv, new_value, PCF_MASTER_BLANKS, CHARS_BRACE);
        pcf_normalize_daemon_args(masterp->argv);
     }
 
index 639f2efd364842d3491a918d9a8a47763cdb963a..a55074fc0848663d6761633bd387aedf2b4d09f7 100644 (file)
@@ -237,7 +237,7 @@ static void pcf_scan_user_parameter_namespace(const char *dict_name,
      */
     if ((class_list = pcf_lookup_eval(dict_name, VAR_REST_CLASSES)) != 0) {
        cp = saved_class_list = mystrdup(class_list);
-       while ((param_name = mystrtok(&cp, ", \t\r\n")) != 0) {
+       while ((param_name = mystrtok(&cp, CHARS_COMMA_SP)) != 0) {
            if (local_scope == 0
                && htable_locate(pcf_rest_class_table, param_name) == 0)
                htable_enter(pcf_rest_class_table, param_name, "");
index 6f676d5aa786bc198b97a117403d2a940a782426..2d8a1abe155b129aa16df3d1e2a8e3475774e834 100644 (file)
@@ -559,7 +559,7 @@ int     main(int argc, char **argv)
      * Run the management script.
      */
     if (force_single_instance
-       || argv_split(var_multi_conf_dirs, "\t\r\n, ")->argc == 0) {
+       || argv_split(var_multi_conf_dirs, CHARS_COMMA_SP)->argc == 0) {
        script = concatenate(var_daemon_dir, "/postfix-script", (char *) 0);
        if (optind < 1)
            msg_panic("bad optind value");
@@ -575,7 +575,7 @@ int     main(int argc, char **argv)
        if (*var_multi_wrapper == 0)
            msg_fatal("multi-instance support is requested, but %s is empty",
                      VAR_MULTI_WRAPPER);
-       my_argv = argv_split(var_multi_wrapper, " \t\r\n");
+       my_argv = argv_split(var_multi_wrapper, CHARS_SPACE);
        do {
            argv_add(my_argv, argv[optind], (char *) 0);
        } while (argv[optind++] != 0);
index 85301cc7f6dd67f0918bc13d1406d2f3d3a509ea..adcae32071d7b6848be0346a700596736a189ace 100644 (file)
@@ -406,7 +406,7 @@ static void postmap(char *map_type, char *path_name, int postmap_flags,
             * trailing whitespace from key and value.
             */
            key = STR(line_buffer);
-           value = key + strcspn(key, " \t\r\n");
+           value = key + strcspn(key, CHARS_SPACE);
            if (*value)
                *value++ = 0;
            while (ISSPACE(*value))
index 3c24d33c0b6c65383bf4875c3f3e3835c5e6e67d..6c80314c9e0aebd315651167b8721dede20a41fb 100644 (file)
@@ -863,7 +863,7 @@ static void load_all_instances(void)
      * only comma characters. Count the actual number of elements, before we
      * decide that the list is empty.
      */
-    secondary_names = argv_split(var_multi_conf_dirs, "\t\n\r, ");
+    secondary_names = argv_split(var_multi_conf_dirs, CHARS_COMMA_SP);
 
     /*
      * First, the primary instance.  This is synthesized out of thin air.
@@ -1469,7 +1469,7 @@ static int word_in_list(char *cmdlist, const char *cmd)
     char   *elem;
 
     cp = saved = mystrdup(cmdlist);
-    while ((elem = mystrtok(&cp, "\t\n\r, ")) != 0 && strcmp(elem, cmd) != 0)
+    while ((elem = mystrtok(&cp, CHARS_COMMA_SP)) != 0 && strcmp(elem, cmd) != 0)
         /* void */ ;
     myfree(saved);
     return (elem != 0);
index 9d379e7408c2b8d40b7efb2f4acb7cc1ac3cbc5e..3e3b9eb097d5f89d039144b509c3d64ef816c10f 100644 (file)
@@ -531,7 +531,7 @@ int     psc_dnsbl_request(const char *client_addr,
 void    psc_dnsbl_init(void)
 {
     const char *myname = "psc_dnsbl_init";
-    ARGV   *dnsbl_site = argv_split(var_psc_dnsbl_sites, ", \t\r\n");
+    ARGV   *dnsbl_site = argv_split(var_psc_dnsbl_sites, CHARS_COMMA_SP);
     char  **cpp;
 
     /*
index 9dabb5dc4c92b36308bbd76a24bd7e73a7730da0..0e821367d767123960d110788d930caa87ac9c0b 100644 (file)
@@ -726,7 +726,7 @@ static int fix_queue_id(const char *actual_path, const char *actual_queue,
 
 static void super(const char **queues, int action)
 {
-    ARGV   *hash_queue_names = argv_split(var_hash_queue_names, " \t\r\n,");
+    ARGV   *hash_queue_names = argv_split(var_hash_queue_names, CHARS_COMMA_SP);
     VSTRING *actual_path = vstring_alloc(10);
     VSTRING *wanted_path = vstring_alloc(10);
     struct stat st;
index ec745e0942110c1c80f0f319fe1e02f3d9b93504..6f792481d7163947e4a8490e2ab54891f1365d70 100644 (file)
@@ -650,8 +650,8 @@ DICT   *dict_proxy_open(const char *map, int open_flags, int dict_flags)
 
 static void post_jail_init(char *service_name, char **unused_argv)
 {
-    const char *sep = ", \t\r\n";
-    const char *parens = "{}";
+    const char *sep = CHARS_COMMA_SP;
+    const char *parens = CHARS_BRACE;
     char   *saved_filter;
     char   *bp;
     char   *type_name;
index f2c69a699bdd39949cc26975434a431440333c63..54af411df453905a216f25abd6a3d8045fbb2b9f 100644 (file)
@@ -1160,7 +1160,7 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message)
         */
        if (*var_defer_xports && (message->qflags & QMGR_FLUSH_DFXP) == 0) {
            if (defer_xport_argv == 0)
-               defer_xport_argv = argv_split(var_defer_xports, " \t\r\n,");
+               defer_xport_argv = argv_split(var_defer_xports, CHARS_COMMA_SP);
            for (cpp = defer_xport_argv->argv; *cpp; cpp++)
                if (strcmp(*cpp, STR(reply.transport)) == 0)
                    break;
index d68a294d1be7f4f6b15dc9f5e0043f02fe38b6ca..b510513de104617df49420a1a988f45ac8a4d65b 100644 (file)
@@ -1395,7 +1395,7 @@ int     main(int argc, char **argv)
        argv_add(ext_argv, "postalias", (char *) 0);
        for (n = 0; n < msg_verbose; n++)
            argv_add(ext_argv, "-v", (char *) 0);
-       argv_split_append(ext_argv, var_alias_db_map, ", \t\r\n");
+       argv_split_append(ext_argv, var_alias_db_map, CHARS_COMMA_SP);
        argv_terminate(ext_argv);
        mail_run_replace(var_command_dir, ext_argv->argv);
        /* NOTREACHED */
index 1d4a6bbf402e82a184422f887ebcea0553021512..8522205c755f9a4e7e5893cde46a29cb08955f1a 100644 (file)
@@ -781,7 +781,7 @@ static void smtp_connect_inet(SMTP_STATE *state, const char *nexthop,
     non_fallback_sites = sites->argc;
     /* When we are lmtp(8) var_fallback_relay is null */
     if (smtp_mode)
-       argv_split_append(sites, var_fallback_relay, ", \t\r\n");
+       argv_split_append(sites, var_fallback_relay, CHARS_COMMA_SP);
 
     /*
      * Don't give up after a hard host lookup error until we have tried the
index 520f8b6e5f61c5e2bfaddcee0da9a58dc14dd53f..29ad938cb8c6a01f279f564f0176e040ed916c5e 100644 (file)
@@ -114,7 +114,7 @@ SMTP_SASL_AUTH_CACHE *smtp_sasl_auth_cache_init(const char *map, int ttl)
     /*
      * Sanity checks.
      */
-#define HAS_MULTIPLE_VALUES(s) ((s)[strcspn((s),  ", \t\r\n")] != 0)
+#define HAS_MULTIPLE_VALUES(s) ((s)[strcspn((s),  CHARS_COMMA_SP)] != 0)
 
     if (*map == 0)
        msg_panic("%s: empty SASL authentication cache name", myname);
index f58113e573c3bad22bc674a40064b5fe98d93625..6ae7ade9ed825b422a29c65ba811c381ccd01b0d 100644 (file)
@@ -242,7 +242,7 @@ static void tls_policy_lookup_one(SMTP_TLS_POLICY *tls, int *site_level,
     }
     saved_policy = policy = mystrdup(lookup);
 
-    if ((tok = mystrtok(&policy, "\t\n\r ,")) == 0) {
+    if ((tok = mystrtok(&policy, CHARS_COMMA_SP)) == 0) {
        msg_warn("%s: invalid empty policy", WHERE);
        INVALID_RETURN(tls->why, site_level);
     }
@@ -257,7 +257,7 @@ static void tls_policy_lookup_one(SMTP_TLS_POLICY *tls, int *site_level,
      * Warn about ignored attributes when TLS is disabled.
      */
     if (*site_level < TLS_LEV_MAY) {
-       while ((tok = mystrtok(&policy, "\t\n\r ,")) != 0)
+       while ((tok = mystrtok(&policy, CHARS_COMMA_SP)) != 0)
            msg_warn("%s: ignoring attribute \"%s\" with TLS disabled",
                     WHERE, tok);
        FREE_RETURN;
@@ -267,7 +267,7 @@ static void tls_policy_lookup_one(SMTP_TLS_POLICY *tls, int *site_level,
      * Errors in attributes may have security consequences, don't ignore
      * errors that can degrade security.
      */
-    while ((tok = mystrtok(&policy, "\t\n\r ,")) != 0) {
+    while ((tok = mystrtok(&policy, CHARS_COMMA_SP)) != 0) {
        if ((err = split_nameval(tok, &name, &val)) != 0) {
            msg_warn("%s: malformed attribute/value pair \"%s\": %s",
                     WHERE, tok, err);
@@ -397,7 +397,7 @@ static int load_tas(TLS_DANE *dane, const char *files)
     char   *file;
 
     do {
-       if ((file = mystrtok(&buf, "\t\n\r ,")) != 0)
+       if ((file = mystrtok(&buf, CHARS_COMMA_SP)) != 0)
            ret = tls_dane_load_trustfile(dane, file);
     } while (file && ret);
 
@@ -565,7 +565,7 @@ static void *policy_create(const char *unused_key, void *context)
            tls->dane = tls_dane_alloc();
        if (!TLS_DANE_HASEE(tls->dane)) {
            tls_dane_add_ee_digests(tls->dane, var_smtp_tls_fpt_dgst,
-                                   var_smtp_tls_fpt_cmatch, "\t\n\r, ");
+                                   var_smtp_tls_fpt_cmatch, CHARS_COMMA_SP);
            if (!TLS_DANE_HASEE(tls->dane)) {
                msg_warn("nexthop domain %s: configured at fingerprint "
                       "security level, but with no fingerprints to match.",
@@ -581,7 +581,7 @@ static void *policy_create(const char *unused_key, void *context)
            tls->matchargv =
                argv_split(tls->level == TLS_LEV_VERIFY ?
                           var_smtp_tls_vfy_cmatch : var_smtp_tls_sec_cmatch,
-                          "\t\n\r, :");
+                          CHARS_COMMA_SP ":");
        if (*var_smtp_tls_tafile) {
            if (tls->dane == 0)
                tls->dane = tls_dane_alloc();
index 6932d499708bc850a473bade641a8557bf1d58e8..b2ce8da140397bcc128f27a1d4433254e8c75c2b 100644 (file)
@@ -3114,6 +3114,13 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
        rec_fputs(state->cleanup, REC_TYPE_MESG, "");
     }
 
+    /*
+     * PREPEND message headers above our own Received: header.
+     */
+    if (state->prepend)
+       for (cpp = state->prepend->argv; *cpp; cpp++)
+           out_fprintf(out_stream, REC_TYPE_NORM, "%s", *cpp);
+
     /*
      * Suppress our own Received: header in the unlikely case that we are an
      * intermediate proxy.
@@ -3204,17 +3211,6 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
 #endif
     }
 
-    /*
-     * PREPEND message headers below our own Received: header. According
-     * https://www.milter.org/developers/api/smfi_insheader, Milters see only
-     * headers that have been sent by the SMTP client and those header
-     * modifications by earlier filters. Based on this we allow Milters to
-     * see headers added by access map or by policy service.
-     */
-    if (state->prepend)
-       for (cpp = state->prepend->argv; *cpp; cpp++)
-           out_fprintf(out_stream, REC_TYPE_NORM, "%s", *cpp);
-
     smtpd_chat_reply(state, "354 End data with <CR><LF>.<CR><LF>");
     state->where = SMTPD_AFTER_DATA;
 
index 41db103270f50c784efaf1cd0b0428613783aa24..cfe6d014bf869a8967730ce012ae5d25b14cbef2 100644 (file)
 #include "smtpd_resolve.h"
 #include "smtpd_expand.h"
 
-#define RESTRICTION_SEPARATORS ", \t\r\n"
-
  /*
   * Eject seat in case of parsing problems.
   */
@@ -510,8 +508,8 @@ static void policy_client_register(const char *name)
     char   *saved_name = 0;
     const char *policy_name = 0;
     char   *cp;
-    const char *sep = ", \t\r\n";
-    const char *parens = "{}";
+    const char *sep = CHARS_COMMA_SP;
+    const char *parens = CHARS_BRACE;
     char   *err;
 
     if (policy_clnt_table == 0)
@@ -538,7 +536,7 @@ static void policy_client_register(const char *name)
        link_override_table_to_variable(int_table, smtpd_policy_try_limit);
        link_override_table_to_variable(str_table, smtpd_policy_def_action);
 
-       if (*name == '{') {                     /* } */
+       if (*name == parens[0]) {
            cp = saved_name = mystrdup(name);
            if ((err = extpar(&cp, parens, EXTPAR_FLAG_NONE)) != 0)
                msg_fatal("policy service syntax error: %s", cp);
@@ -601,7 +599,7 @@ static ARGV *smtpd_check_parse(int flags, const char *checks)
 #define SMTPD_CHECK_PARSE_MAPS         (1<<1)
 #define SMTPD_CHECK_PARSE_ALL          (~0)
 
-    while ((name = mystrtokq(&bp, RESTRICTION_SEPARATORS, "{}")) != 0) {
+    while ((name = mystrtokq(&bp, CHARS_COMMA_SP, CHARS_BRACE)) != 0) {
        argv_add(argv, name, (char *) 0);
        if ((flags & SMTPD_CHECK_PARSE_POLICY)
            && last && strcasecmp(last, CHECK_POLICY_SERVICE) == 0)
@@ -807,7 +805,7 @@ void    smtpd_check_init(void)
     smtpd_rest_classes = htable_create(1);
     if (*var_rest_classes) {
        cp = saved_classes = mystrdup(var_rest_classes);
-       while ((name = mystrtok(&cp, RESTRICTION_SEPARATORS)) != 0) {
+       while ((name = mystrtok(&cp, CHARS_COMMA_SP)) != 0) {
            if ((value = mail_conf_lookup_eval(name)) == 0 || *value == 0)
                msg_fatal("restriction class `%s' needs a definition", name);
            /* XXX This store operation should not be case-sensitive. */
@@ -2590,7 +2588,7 @@ static int check_table_result(SMTPD_STATE *state, const char *table,
      */
 #define ADDROF(x) ((char *) &(x))
 
-    restrictions = argv_splitq(value, RESTRICTION_SEPARATORS, "{}");
+    restrictions = argv_splitq(value, CHARS_COMMA_SP, CHARS_BRACE);
     memcpy(ADDROF(savebuf), ADDROF(smtpd_check_buf), sizeof(savebuf));
     status = setjmp(smtpd_check_buf);
     if (status != 0) {
@@ -3699,7 +3697,7 @@ static int reject_maps_rbl(SMTPD_STATE *state)
                 "use \"%s domain-name\" instead",
                 REJECT_MAPS_RBL, var_mail_name, REJECT_RBL_CLIENT);
     }
-    while ((rbl_domain = mystrtok(&bp, RESTRICTION_SEPARATORS)) != 0) {
+    while ((rbl_domain = mystrtok(&bp, CHARS_COMMA_SP)) != 0) {
        result = reject_rbl_addr(state, rbl_domain, state->addr,
                                 SMTPD_NAME_CLIENT);
        if (result != SMTPD_CHECK_DUNNO)
@@ -3740,7 +3738,7 @@ static int reject_auth_sender_login_mismatch(SMTPD_STATE *state, const char *sen
        if ((owners = check_mail_addr_find(state, sender, smtpd_sender_login_maps,
                                STR(reply->recipient), (char **) 0)) != 0) {
            cp = saved_owners = mystrdup(owners);
-           while ((name = mystrtok(&cp, RESTRICTION_SEPARATORS)) != 0) {
+           while ((name = mystrtok(&cp, CHARS_COMMA_SP)) != 0) {
                if (strcasecmp(state->sasl_username, name) == 0) {
                    found = 1;
                    break;
@@ -5653,7 +5651,7 @@ static void rest_class(char *class)
     if (smtpd_rest_classes == 0)
        smtpd_rest_classes = htable_create(1);
 
-    if ((name = mystrtok(&cp, RESTRICTION_SEPARATORS)) == 0)
+    if ((name = mystrtok(&cp, CHARS_COMMA_SP)) == 0)
        msg_panic("rest_class: null class name");
     if ((entry = htable_locate(smtpd_rest_classes, name)) != 0)
        argv_free((ARGV *) entry->value);
@@ -5843,7 +5841,7 @@ int     main(int argc, char **argv)
            vstream_printf("exit %d\n", system(bp + 1));
            continue;
        }
-       args = argv_split(bp, " \t\r\n");
+       args = argv_split(bp, CHARS_SPACE);
 
        /*
         * Recognize the command.
index 120cef10a809e305994fbdf45feb51dbd94da0fb..68dd840394b7a436517bf1e9ce4139e96537760a 100644 (file)
@@ -1005,7 +1005,7 @@ static void set_cmds_flags(const char *cmds, int flags)
     char   *cmd;
 
     saved_cmds = cp = mystrdup(cmds);
-    while ((cmd = mystrtok(&cp, " \t\r\n,")) != 0)
+    while ((cmd = mystrtok(&cp, CHARS_COMMA_SP)) != 0)
        set_cmd_flags(cmd, flags);
     myfree(saved_cmds);
 }
index 9013bc50ff99a7954af9f5af353fa842378927fe..6195e04bd4dbc67126d6797530ff47d1b82827cf 100644 (file)
@@ -473,7 +473,7 @@ static void dane_init(void)
                 VAR_TLS_DANE_AGILITY, var_tls_dane_agility);
     } else if (add_digest(fullmtype, 0)) {
        save = cp = mystrdup(var_tls_dane_digests);
-       while ((tok = mystrtok(&cp, "\t\n\r ,")) != 0) {
+       while ((tok = mystrtok(&cp, CHARS_COMMA_SP)) != 0) {
            if ((d = add_digest(tok, ++digest_pref)) == 0) {
                signalg = 0;
                signmd = 0;
index 702aeee7c1aa94f97a35897b37d939ba0f280932..1ac9b50b9366b0243763f174e0c54f03244ff18a 100644 (file)
@@ -411,7 +411,7 @@ int     main(int unused_ac, char **av)
        msg_fatal("chdir %s: %m", var_queue_dir);
 
     while (vstring_fgets_nonl(inbuf, VSTREAM_IN)) {
-       argv = argv_split(STR(inbuf), " \t\r\n");
+       argv = argv_split(STR(inbuf), CHARS_SPACE);
        if (argv->argc == 0) {
            argv_free(argv);
            continue;
index 1791dce2253ca4fb68483e1f4b39eb7b39ac7150..b6d5f4fdd013741688b3a64f1106a1e59ae36523 100644 (file)
@@ -580,7 +580,7 @@ int     tls_protocol_mask(const char *plist)
     } while (0)
 
     save = cp = mystrdup(plist);
-    while ((tok = mystrtok(&cp, "\t\n\r ,:")) != 0) {
+    while ((tok = mystrtok(&cp, CHARS_COMMA_SP ":")) != 0) {
        if (*tok == '!')
            exclude |= code =
                name_code(protocol_table, NAME_CODE_FLAG_NONE, ++tok);
@@ -718,7 +718,7 @@ const char *tls_set_ciphers(TLS_APPL_STATE *app_ctx, const char *context,
     /*
      * Apply locally-specified exclusions.
      */
-#define CIPHER_SEP "\t\n\r ,:"
+#define CIPHER_SEP CHARS_COMMA_SP ":"
     if (exclusions != 0) {
        cp = save = mystrdup(exclusions);
        while ((tok = mystrtok(&cp, CIPHER_SEP)) != 0) {
index 135c66d50813d0822b0ec9576926d0c8654b6c47..e15ff5e0174b56235e4e5996297ef3925152b83e 100644 (file)
@@ -138,7 +138,7 @@ DICT   *dict_pipe_open(const char *name, int open_flags, int dict_flags)
     /*
      * Split the table name into its constituent parts.
      */
-    if ((len = balpar(name, "{}")) == 0 || name[len] != 0
+    if ((len = balpar(name, CHARS_BRACE)) == 0 || name[len] != 0
        || *(saved_name = mystrndup(name + 1, len - 2)) == 0)
        DICT_PIPE_RETURN(dict_surrogate(DICT_TYPE_PIPE, name,
                                        open_flags, dict_flags,
@@ -152,7 +152,7 @@ DICT   *dict_pipe_open(const char *name, int open_flags, int dict_flags)
      * level. The first table determines the pattern-matching flags.
      */
     DICT_OWNER_AGGREGATE_INIT(aggr_owner);
-    argv = argv_splitq(saved_name, ", \t\r\n", "{}");
+    argv = argv_splitq(saved_name, CHARS_COMMA_SP, CHARS_BRACE);
     for (cpp = argv->argv; (dict_type_name = *cpp) != 0; cpp++) {
        if (msg_verbose)
            msg_info("%s: %s", myname, dict_type_name);
index 0ee4a83653306150125ee9bdcef35c6a7c246806..4497fe1c3de59e35ff07d51458e574d5bb99fbdc 100644 (file)
@@ -104,7 +104,7 @@ DICT   *dict_random_open(const char *name, int open_flags, int dict_flags)
     /*
      * Split the name name into its constituent parts.
      */
-    if ((len = balpar(name, "{}")) == 0 || name[len] != 0
+    if ((len = balpar(name, CHARS_BRACE)) == 0 || name[len] != 0
        || *(saved_name = mystrndup(name + 1, len - 2)) == 0)
        DICT_RANDOM_RETURN(dict_surrogate(DICT_TYPE_RANDOM, name,
                                          open_flags, dict_flags,
@@ -121,7 +121,7 @@ DICT   *dict_random_open(const char *name, int open_flags, int dict_flags)
     dict_random->dict.lookup = dict_random_lookup;
     dict_random->dict.close = dict_random_close;
     dict_random->dict.flags = dict_flags | DICT_FLAG_PATTERN;
-    dict_random->replies = argv_splitq(saved_name, ", \t\r\n", "{}");
+    dict_random->replies = argv_splitq(saved_name, CHARS_COMMA_SP, CHARS_BRACE);
     dict_random->dict.owner.status = DICT_OWNER_TRUSTED;
     dict_random->dict.owner.uid = 0;
 
index 1bee77d30b1ac3cd02cd24346ac9ffb6427b0924..93a4f447274ac3effb9244c8bb46c355869dbd1b 100644 (file)
@@ -199,7 +199,7 @@ DICT   *dict_thash_open(const char *path, int open_flags, int dict_flags)
             * trailing whitespace from key and value.
             */
            key = STR(line_buffer);
-           value = key + strcspn(key, " \t\r\n");
+           value = key + strcspn(key, CHARS_SPACE);
            if (*value)
                *value++ = 0;
            while (ISSPACE(*value))
index ef709ed43dd092302df230f819bae88778b4c3ee..b2a5feec861e9e71b24573eb4084970ffec4ed57 100644 (file)
@@ -145,7 +145,7 @@ DICT   *dict_union_open(const char *name, int open_flags, int dict_flags)
     /*
      * Split the table name into its constituent parts.
      */
-    if ((len = balpar(name, "{}")) == 0 || name[len] != 0
+    if ((len = balpar(name, CHARS_BRACE)) == 0 || name[len] != 0
        || *(saved_name = mystrndup(name + 1, len - 2)) == 0)
        DICT_UNION_RETURN(dict_surrogate(DICT_TYPE_UNION, name,
                                         open_flags, dict_flags,
@@ -159,7 +159,7 @@ DICT   *dict_union_open(const char *name, int open_flags, int dict_flags)
      * level. The first table determines the pattern-matching flags.
      */
     DICT_OWNER_AGGREGATE_INIT(aggr_owner);
-    argv = argv_splitq(saved_name, ", \t\r\n", "{}");
+    argv = argv_splitq(saved_name, CHARS_COMMA_SP, CHARS_BRACE);
     for (cpp = argv->argv; (dict_type_name = *cpp) != 0; cpp++) {
        if (msg_verbose)
            msg_info("%s: %s", myname, dict_type_name);
index d7e6c1101d06969214b200d6a4a00d71490f62cc..2b081b8105b4ff1e07b871e79043acae1cce1182 100644 (file)
@@ -208,7 +208,7 @@ static const NAME_CODE mac_exp_op_table[] =
  /*
   * The whitespace separator set.
   */
-#define MAC_EXP_WHITESPACE     " \t\r\n"
+#define MAC_EXP_WHITESPACE     CHARS_SPACE
 
 /* mac_exp_eval - evaluate binary expression */
 
@@ -628,8 +628,8 @@ int     main(int unused_argc, char **unused_argv)
            if (VSTRING_LEN(buf) == 0)
                break;
            cp = vstring_str(buf);
-           name = mystrtok(&cp, " \t\r\n=");
-           value = mystrtok(&cp, " \t\r\n=");
+           name = mystrtok(&cp, CHARS_SPACE "=");
+           value = mystrtok(&cp, CHARS_SPACE "=");
            htable_enter(table, name, value ? mystrdup(value) : 0);
        }
 
index cfd93e655bf79e5da697c1fab0e25aa3ab96c1f7..306a5ed9cc5ccf6d54f6c6649f51ab462eee4ec8 100644 (file)
@@ -99,7 +99,7 @@ static ARGV *match_list_parse(ARGV *list, char *string, int init_match)
     const char *myname = "match_list_parse";
     VSTRING *buf = vstring_alloc(10);
     VSTREAM *fp;
-    const char *delim = " ,\t\r\n";
+    const char *delim = CHARS_COMMA_SP;
     char   *bp = string;
     char   *start;
     char   *item;
@@ -114,7 +114,7 @@ static ARGV *match_list_parse(ARGV *list, char *string, int init_match)
      * /filename contents are expanded in-line. To support !/filename we
      * prepend the negation operator to each item from the file.
      */
-    while ((start = mystrtokq(&bp, delim, "{}")) != 0) {
+    while ((start = mystrtokq(&bp, delim, CHARS_BRACE)) != 0) {
        if (*start == '#') {
            msg_warn("%s: comment at end of line is not supported: %s %s",
                     myname, start, bp);
index 0056f836ab9b3ef4b806c46827fffb6f1947e166..91e3c472e0f059ef31d7e21ba2a8ff303eb5ab68 100644 (file)
@@ -127,11 +127,11 @@ int     main(void)
 
     while (vstring_fgets(vp, VSTREAM_IN) && VSTRING_LEN(vp) > 0) {
        start = vstring_str(vp);
-       if (strchr(start, '{') == 0) {
-           while ((str = mystrtok(&start, " \t\r\n")) != 0)
+       if (strchr(start, CHARS_BRACE[0]) == 0) {
+           while ((str = mystrtok(&start, CHARS_SPACE)) != 0)
                vstream_printf(">%s<\n", str);
        } else {
-           while ((str = mystrtokq(&start, " \t\r\n", "{}")) != 0)
+           while ((str = mystrtokq(&start, CHARS_SPACE, CHARS_BRACE)) != 0)
                vstream_printf(">%s<\n", str);
        }
        vstream_fflush(VSTREAM_OUT);
index a452582245441912650186925fa036c446dda0c6..2cfb3b27297a260eafb19fc88ffa1ac3432db753 100644 (file)
@@ -276,7 +276,7 @@ WAIT_STATUS_T spawn_command(int key,...)
            execvp(args.argv[0], args.argv);
            msg_fatal("%s: execvp %s: %m", myname, args.argv[0]);
        } else if (args.shell && *args.shell) {
-           argv = argv_split(args.shell, " \t\r\n");
+           argv = argv_split(args.shell, CHARS_SPACE);
            argv_add(argv, args.command, (char *) 0);
            argv_terminate(argv);
            execvp(argv->argv[0], argv->argv);
index 43b97fcb5ffbf20b8d2d348a34164a604f93d660..3d9b60fa66c6a6a6ab8b987d5719fe370ff4dda4 100644 (file)
@@ -51,13 +51,6 @@ extern char *extpar(char **, const char *, int);
 #define EXTPAR_FLAG_STRIP      (1<<0)  /* "{ text }" -> "text" */
 #define EXTPAR_FLAG_EXTRACT    (1<<1)  /* hint from caller's caller */
 
- /*
-  * Character sets for parsing.
-  */
-#define CHARS_COMMA_SP ", \t\r\n"      /* list separator */
-#define CHARS_SPACE    " \t\r\n"       /* word separator */
-#define CHARS_BRACE    "{}"            /* grouping */
-
 /* LICENSE
 /* .ad
 /* .fi
index 5c37ac3fda209971c3caff75c0e06bd21beba5a3..bfd6f054934c368fa0d12611200a43239c067a96 100644 (file)
@@ -1717,6 +1717,13 @@ typedef int pid_t;
 #define TOLOWER(c)     (ISUPPER(c) ? tolower((unsigned char)(c)) : (c))
 #define TOUPPER(c)     (ISLOWER(c) ? toupper((unsigned char)(c)) : (c))
 
+ /*
+  * Character sets for parsing.
+  */
+#define CHARS_COMMA_SP ", \t\r\n"      /* list separator */
+#define CHARS_SPACE    " \t\r\n"       /* word separator */
+#define CHARS_BRACE    "{}"            /* grouping */
+
  /*
   * Scaffolding. I don't want to lose messages while the program is under
   * development.
index aace6c82cdcc1fe7c30d453b3fd922d85fc40f01..7c54ec14a659a66bf070d20cd3b74547edc93b56 100644 (file)
@@ -255,7 +255,7 @@ VSTREAM *vstream_popen(int flags,...)
            execvp(args.argv[0], args.argv);
            msg_fatal("%s: execvp %s: %m", myname, args.argv[0]);
        } else if (args.shell && *args.shell) {
-           argv = argv_split(args.shell, " \t\r\n");
+           argv = argv_split(args.shell, CHARS_SPACE);
            argv_add(argv, args.command, (char *) 0);
            argv_terminate(argv);
            execvp(argv->argv[0], argv->argv);