As of 20050525, DSN support does not involve new queue file
record types, so you can switch back to older Postfix
versions. Older non-production releases did introduce queue
- file incompatibilty.
+ file incompatibility.
DSN support is selected via the SMTP port by extra parameters
to the MAIL FROM and RCPT TO commands, and with the Postfix
MTA" with "preferred MTA". The SMTP client was changed years
ago to try alternate MXes after a 4XX SMTP server response.
File: proto/ADDRES_VERIFY_README.html.
+
+20141001
+
+ Safety: backwards-compatibility safety net that forces Postfix
+ to run with backwards-compatible default settings after an
+ upgrade to a newer Postfix version. Postfix logs all uses
+ of those backwards-compatible default settings so that the
+ system administator can determine whether or not some
+ backwards-compatible default settings need to be made
+ permanent in main.cf or master.cf. All this is controlled
+ with a new compatibility_level parameter, default value 0.
+ Files: global/mail_params.[hc], trivial-rewrite/rewrite.c,
+ master/master_ent.c, smtpd/smtpd.c, postfix/postfix.c.
+
+ New defaults for master.cf chroot (n), append_dot_mydomain
+ (no) and smtputf8_enable (yes). File: global/mail_params.h,
+ global/mail_params.c, smtp/smtp.c (manpage), smtpd/smtpd.c
+ (manpage), trivial-rewrite/trivial-rewrite.c.
+
+ Simple relational expression evaluator so that main.cf
+ defaults can be made dependent on comparisons with the
+ compatibility_level parameter value. File: util/mac_expand.c.
+
+ Bugfix: do not reset the mail transaction after receiving
+ a non-ASCII recipient. File: smtpd/smtpd.c.
Inside the list, syntax is similar to what we already know from main.cf: items
separated by space or comma. There is one difference: y\byo\bou\bu m\bmu\bus\bst\bt e\ben\bnc\bcl\blo\bos\bse\be a\ba
-s\bse\bet\btt\bti\bin\bng\bg i\bin\bn p\bpa\bar\bre\ben\bnt\bth\bhe\bes\bse\bes\bs,\b, a\bas\bs i\bin\bn "\b"{\b{ n\bna\bam\bme\be =\b= v\bva\bal\blu\bue\be }\b}"\b",\b, i\bif\bf y\byo\bou\bu w\bwa\ban\bnt\bt t\bto\bo h\bha\bav\bve\be s\bsp\bpa\bac\bce\be
-w\bwi\bit\bth\bhi\bin\bn a\ba v\bva\bal\blu\bue\be o\bor\br a\bar\bro\bou\bun\bnd\bd "\b"=\b="\b".
+s\bse\bet\btt\bti\bin\bng\bg i\bin\bn p\bpa\bar\bre\ben\bnt\bth\bhe\bes\bse\bes\bs,\b, a\bas\bs i\bin\bn "\b"{\b{ n\bna\bam\bme\be =\b= v\bva\bal\blu\bue\be }\b}"\b",\b, i\bif\bf y\byo\bou\bu w\bwa\ban\bnt\bt t\bto\bo h\bha\bav\bve\be s\bsp\bpa\bac\bce\be o\bor\br
+c\bco\bom\bmm\bma\ba w\bwi\bit\bth\bhi\bin\bn a\ba v\bva\bal\blu\bue\be o\bor\br a\bar\bro\bou\bun\bnd\bd "\b"=\b="\b".
S\bSe\ben\bnd\bdm\bma\bai\bil\bl m\bma\bac\bcr\bro\bo e\bem\bmu\bul\bla\bat\bti\bio\bon\bn
smtpd_end_of_data_restrictions = check_policy_service unix:private/policy
Each restriction list is evaluated from left to right until some restriction
-produces a result of PERMIT, REJECT or DEFER (try again later). The end of the
+produces a result of PERMIT, REJECT or DEFER (try again later). The end of each
list is equivalent to a PERMIT result. By placing a PERMIT restriction before a
REJECT restriction you can make exceptions for specific clients or users. This
is called whitelisting; the fourth example above allows mail from local
Inside the list, syntax is similar to what we already know from main.cf: items
separated by space or comma. There is one difference: y\byo\bou\bu m\bmu\bus\bst\bt e\ben\bnc\bcl\blo\bos\bse\be a\ba
-s\bse\bet\btt\bti\bin\bng\bg i\bin\bn p\bpa\bar\bre\ben\bnt\bth\bhe\bes\bse\bes\bs,\b, a\bas\bs i\bin\bn "\b"{\b{ n\bna\bam\bme\be =\b= v\bva\bal\blu\bue\be }\b}"\b",\b, i\bif\bf y\byo\bou\bu w\bwa\ban\bnt\bt t\bto\bo h\bha\bav\bve\be s\bsp\bpa\bac\bce\be
-w\bwi\bit\bth\bhi\bin\bn a\ba v\bva\bal\blu\bue\be o\bor\br a\bar\bro\bou\bun\bnd\bd "\b"=\b="\b". This comes in handy when different policy servers
-require different default actions with different SMTP status codes or text:
+s\bse\bet\btt\bti\bin\bng\bg i\bin\bn p\bpa\bar\bre\ben\bnt\bth\bhe\bes\bse\bes\bs,\b, a\bas\bs i\bin\bn "\b"{\b{ n\bna\bam\bme\be =\b= v\bva\bal\blu\bue\be }\b}"\b",\b, i\bif\bf y\byo\bou\bu w\bwa\ban\bnt\bt t\bto\bo h\bha\bav\bve\be s\bsp\bpa\bac\bce\be o\bor\br
+c\bco\bom\bmm\bma\ba w\bwi\bit\bth\bhi\bin\bn a\ba v\bva\bal\blu\bue\be o\bor\br a\bar\bro\bou\bun\bnd\bd "\b"=\b="\b". This comes in handy when different policy
+servers require different default actions with different SMTP status codes or
+text:
1 /etc/postfix/main.cf:
2 smtpd_recipient_restrictions =
E\bEn\bna\bab\bbl\bli\bin\bng\bg P\bPo\bos\bst\btf\bfi\bix\bx S\bSM\bMT\bTP\bPU\bUT\bTF\bF8\b8 s\bsu\bup\bpp\bpo\bor\brt\bt
-Before turning on SMTPUTF8 support in Postfix, you need to verify that the rest
-of your email infrastructure can handle UTF-8 email addresses and message
-header values, including SMTPUTF8 protocol support in SMTP-based content
-filters (Amavisd), LMTP servers (Dovecot), and down-stream SMTP servers.
+There is more to SMTPUTF8 than just Postfix itself. The rest of your email
+infrastructure also needs to be able to handle UTF-8 email addresses and
+message header values. This includes SMTPUTF8 protocol support in SMTP-based
+content filters (Amavisd), LMTP servers (Dovecot), and down-stream SMTP
+servers.
+
+Postfix SMTPUTF8 support is enabled by default, but it may be disabled as part
+of a backwards-compatibility safety net (see the Postfix 2.12 RELEASE_NOTES
+file).
SMTPUTF8 support is enabled by setting the smtputf8_enable parameter in
main.cf:
# p\bpo\bos\bst\btc\bco\bon\bnf\bf "\b"s\bsm\bmt\btp\bpu\but\btf\bf8\b8_\b_e\ben\bna\bab\bbl\ble\be =\b= y\bye\bes\bs"\b"
# p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd
-With SMTPUTF8 support enabled, Postfix changes behavior as follows:
+With SMTPUTF8 support enabled, Postfix changes behavior with respect to earlier
+Postfix releases:
* UTF-8 is permitted in the myorigin parameter value. However, the myhostname
and mydomain parameters must specify ASCII-only domain names. This
Notes for distribution maintainers
----------------------------------
+* New backwards-compatibility safety net.
+
+Several Postfix default settings have changed with Postfix 2.12.
+To avoid massive breakage, Postfix comes with a safety net that
+forces Postfix to keep running with backwards-compatible main.cf
+and master.cf default settings.
+
+With NEW Postfix installs, you should install a main.cf file with
+the setting "compatibility_level = 1". See the stock main.cf file
+in the conf subdirectory.
+
+With existing Postfix UPGRADES, the main.cf compatibility_level
+setting (if any) MUST be left alone, to enable the backwards-compatibility
+safety net as discussed below.
+
+* New Postfix build system.
+
The Postfix build/install procedure has changed to support Postfix
shared libraries and database plugins.
(mantools/srctoman - makedefs | nroff -man | less) with information
about build options that are not described in the INSTALL instructions.
+Major changes with snapshot 20141001
+====================================
+
+A new backwards-compatibility safety net forces Postfix to keep
+running with backwards-compatible main.cf and master.cf default
+settings after an upgrade to a newer Postfix version.
+
+The following presents the messages that the backwards-compatibility
+safety net will log, what the messages mean, and what action the
+system adminstrator is expected to take.
+
+1) postfix/master[27664]: /etc/postfix/master.cf: line 72: using
+ legacy default setting chroot=y
+
+ chroot=n is the new default, but that may not always be disirable.
+ Postfix continues to use the backwards-compatible default,
+ chroot=y, until the system administrator has determined whether
+ or not the backwards-compatible chroot=y setting needs to be
+ made permanent in master.cf.
+
+2) postfix/trivial-rewrite[25835]: using legacy default setting
+ append_dot_mydomain=yes to rewrite "foo" to "foo.example.com"
+
+ append_dot_mydomain=no is the new default, but that change may
+ affect email from ancient clients that cannot be updated. Postfix
+ continues to use the backwards-compatible default,
+ append_dot_mydomain=yes, until the system administrator has
+ determined whether or not the backwards-compatible
+ append_dot_mydomain=yes setting needs to be made permanent in
+ main.cf.
+
+3) postfix/smtpd[27560]: using legacy default setting smtputf8_enable=no
+ to accept non-ASCII sender address "??@example.org" from
+ localhost[127.0.0.1]
+
+4) postfix/smtpd[27560]: using legacy default setting smtputf8_enable=no
+ to accept non-ASCII recipient address "??@example.com" from
+ localhost[127.0.0.1]
+
+ smtputf8_enable=yes is the new default, but that would break
+ existing email streams with non-ASCII localparts. Postfix continues
+ to use the backwards-compatible default, smtputf8_enable=no,
+ until the system administrator has determined whether or not the
+ backwards-compatible smtputf8_enable=no setting needs to be made
+ permanent in main.cf.
+
+It may take several weeks until all dependencies on backwards-compatible
+default settings are identified. After the review is complete, and
+no more backwards-compatible settings need to be made permanent.
+the administrator should accept the remaining Postfix built-in
+default settings by updating the compatibility_level setting in
+main.cf.
+
+For the changes discussed above, the administrator should set:
+
+/etc/postfix/main.cf:
+ compatibility_level = 1
+
+This will stop all the warning messages shown above.
+
+Future incompatible changes will require setting "compatibility_level
+= 2", and so on.
+
Major changes with snapshot 20140928
====================================
Here is an example that uses both old and new syntax:
smtpd_milters = { inet:127.0.0.1:port1, default_action=accept, ... },
- inet:127.0.0.1:port2, ...
+ inet:127.0.0.1:port2, ...
The per-milter settings are specified as attribute=value pairs
separated by comma or space; specify { name = value } to allow
verbose logging or network sniffer.
Normal session, no TLS:
- disconnect from name[addr] ehlo=1 mail=1 rcpt=1 data=1 quit=1
+ disconnect from name[addr] ehlo=1 mail=1 rcpt=1 data=1 quit=1
Normal session. with TLS:
- disconnect from name[addr] ehlo=2 starttls=1 mail=1 rcpt=1 data=1 quit=1
+ disconnect from name[addr] ehlo=2 starttls=1 mail=1 rcpt=1 data=1 quit=1
All recipients rejected, no ESMTP command pipelining:
- disconnect from name[addr] ehlo=1 mail=1 rcpt=0/1 quit=1
+ disconnect from name[addr] ehlo=1 mail=1 rcpt=0/1 quit=1
All recipients rejected, with ESMTP command pipelining:
- disconnect from name[addr] ehlo=1 mail=1 rcpt=0/1 data=0/1 rset=1 quit=1
+ disconnect from name[addr] ehlo=1 mail=1 rcpt=0/1 data=0/1 rset=1 quit=1
Password guessing bot, hangs up without QUIT:
- disconnect from name[addr] ehlo=1 auth=0/1
+ disconnect from name[addr] ehlo=1 auth=0/1
Mis-configured client trying to use TLS wrappermode on port 587:
- disconnect from name[addr] unknown=0/1
+ disconnect from name[addr] unknown=0/1
Logfile analyzers can trigger on the presence of "/". It indicates
that Postfix rejected at least one command.
/etc/postfix/main.cf:
transport_maps =
- # Deliver my own domain as usual.
- hash:/etc/postfix/transport
- # Deliver other domains via randomly-selected relayhosts
- randmap:!smtp:smtp0.example.com!smtp:smtp1.example.com
+ # Deliver my own domain as usual.
+ hash:/etc/postfix/transport
+ # Deliver other domains via randomly-selected relayhosts
+ randmap:!smtp:smtp0.example.com!smtp:smtp1.example.com
A variant of this can randomly select SMTP clients with different
smtp_bind_address settings.
to system accounts that have "nologin" as their login shell:
/etc/postfix/main.cf:
- local_recipient_maps =
- pipemap:!unix:passwd.byname!pcre:/etc/postfix/no-nologin.pcre
- alias_maps
+ local_recipient_maps =
+ pipemap:!unix:passwd.byname!pcre:/etc/postfix/no-nologin.pcre
+ alias_maps
/etc/postfix/no-nologin.pcre:
- !/nologin/ whatever
+ !/nologin/ whatever
The first ASCII character after "pipemap:" will be used as the
separator between the lookup tables that follow (do not use space,
Remove this file from the stable release.
+ Consolidate import_env and export_env parsing code and
+ add support for { name = value with whitespace }.
+
Things to do after the stable release:
+ use "static const char myname[] ..."
+
+ Add milter_mumble_macros to the list of per-macro features.
+
The pickup daemon logs warnings only when the cleanup daemon
dit not provide a "reason" attribute. Is this logic right?
# For best results, change no more than 2-3 parameters at a time,
# and test if Postfix still works after every change.
+# COMPATIBILITY
+#
+# The compatibility_level determines what default settings Postfix
+# will use for main.cf and master.cf settings. These defaults will
+# change over time.
+#
+# To avoid breaking things, Postfix will use backwards-compatible
+# default settings and log where it uses those old backwards-compatible
+# default settings, until the system administrator has determined
+# if any backwards-compatible default settings need to be made
+# permanent in main.cf or master.cf.
+#
+# When this review is complete, update the compatibility_level setting
+# below as recommended in the RELEASE_NOTES file.
+#
+# The level below is what should be used with new (not upgrade) installs.
+#
+compatibility_level = 1
+
# SOFT BOUNCE
#
# The soft_bounce parameter provides a limited safety net for
#
# ==========================================================================
# service type private unpriv chroot wakeup maxproc command + args
-# (yes) (yes) (yes) (never) (100)
+# (yes) (yes) (no) (never) (100)
# ==========================================================================
smtp inet n - n - - smtpd
#smtp inet n - n - 1 postscreen
<p> Inside the list, syntax is similar to what we already know from
<a href="postconf.5.html">main.cf</a>: items separated by space or comma. There is one difference:
<b>you must enclose a setting in parentheses, as in "{ name = value
-}", if you want to have space within a value or around "="</b>.
-</p>
+}", if you want to have space or comma within a value or around
+"="</b>. </p>
<h3><a name="macros">Sendmail macro emulation</a></h3>
<p> Each restriction list is evaluated from left to right until
some restriction produces a result of PERMIT, REJECT or DEFER (try
-again later). The end of the list is equivalent to a PERMIT result.
+again later). The end of each list is equivalent to a PERMIT result.
By placing a PERMIT restriction before a REJECT restriction you
can make exceptions for specific clients or users. This is called
whitelisting; the fourth example above allows mail from local
<p> Inside the list, syntax is similar to what we already know from
<a href="postconf.5.html">main.cf</a>: items separated by space or comma. There is one difference:
<b>you must enclose a setting in parentheses, as in "{ name = value
-}", if you want to have space within a value or around "="</b>.
-This comes in handy when different policy servers require different
-default actions with different SMTP status codes or text: </p>
+}", if you want to have space or comma within a value or around
+"="</b>. This comes in handy when different policy servers require
+different default actions with different SMTP status codes or text:
+</p>
<blockquote>
<pre>
<h2> <a name="enabling">Enabling Postfix SMTPUTF8 support</a> </h2>
-<p> Before turning on SMTPUTF8 support in Postfix, you need to
-verify that the rest of your email infrastructure can handle UTF-8
-email addresses and message header values, including SMTPUTF8
+<p> There is more to SMTPUTF8 than just Postfix itself. The rest
+of your email infrastructure also needs to be able to handle UTF-8
+email addresses and message header values. This includes SMTPUTF8
protocol support in SMTP-based content filters (Amavisd), LMTP
servers (Dovecot), and down-stream SMTP servers. </p>
+<p> Postfix SMTPUTF8 support is enabled by default, but it may be
+disabled as part of a backwards-compatibility safety net (see the
+Postfix 2.12 RELEASE_NOTES file). </p>
+
<p> SMTPUTF8 support is enabled by setting the <a href="postconf.5.html#smtputf8_enable">smtputf8_enable</a>
parameter in <a href="postconf.5.html">main.cf</a>:</p>
</pre>
</blockquote>
-<p> With SMTPUTF8 support enabled, Postfix changes behavior as follows: </p>
+<p> With SMTPUTF8 support enabled, Postfix changes behavior with
+respect to earlier Postfix releases: </p>
<ul>
<b>SMTPUTF8 CONTROLS</b>
Preliminary SMTPUTF8 support is introduced with Postfix 2.12.
- <b><a href="postconf.5.html#smtputf8_enable">smtputf8_enable</a> (no)</b>
+ <b><a href="postconf.5.html#smtputf8_enable">smtputf8_enable</a> (yes)</b>
Enable experimental SMTPUTF8 support for the protocols described
in <a href="http://tools.ietf.org/html/rfc6531">RFC 6531</a>..6533.
The <a href="local.8.html"><b>local</b>(8)</a>, <a href="pipe.8.html"><b>pipe</b>(8)</a>, <a href="spawn.8.html"><b>spawn</b>(8)</a>, and <a href="virtual.8.html"><b>virtual</b>(8)</a> daemons require
privileges.
- <b>Chroot (default: y)</b>
+ <b>Chroot (default: Postfix</b> ><b>= 2.12: y, Postfix</b> <<b>2.12: n)</b>
Whether or not the service runs chrooted to the mail queue
directory (pathname is controlled by the <b><a href="postconf.5.html#queue_directory">queue_directory</a></b> config-
uration variable in the <a href="postconf.5.html">main.cf</a> file).
</DD>
<DT><b><a name="append_dot_mydomain">append_dot_mydomain</a>
-(default: yes)</b></DT><DD>
+(default: Postfix ≥ 2.12: no, Postfix < 2.12: yes)</b></DT><DD>
<p>
With locally submitted mail, append the string ".$<a href="postconf.5.html#mydomain">mydomain</a>" to
</p>
+</DD>
+
+<DT><b><a name="compatibility_level">compatibility_level</a>
+(default: 0)</b></DT><DD>
+
+<p> A safety net that forces Postfix to keep running with
+backwards-compatible <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> default settings after
+an upgrade to a newer but incompatible Postfix version. </p>
+
+<p> Depending on the <a href="postconf.5.html#compatibility_level">compatibility_level</a> parameter setting, Postfix
+continues to use backwards-compatible default settings, and logs
+the use of those backwards-compatible default settings with messages
+that contain the string "using legacy default setting". Based on
+this logging the system administrator can determine that a new
+default setting breaks nothing or that a backwards-compatible
+default setting needs to be made permanent in <a href="postconf.5.html">main.cf</a> or <a href="master.5.html">master.cf</a>.
+</p>
+
+<p> After this review is complete, and no more backwards-compatible
+settings need to be made permanent, the administrator should accept
+the remaining Postfix built-in default settings by updating the
+<a href="postconf.5.html#compatibility_level">compatibility_level</a> setting in <a href="postconf.5.html">main.cf</a> as recommended in the Postfix
+RELEASE_NOTES. </p>
+
+<p> This feature is available in Postfix 2.12 and later. </p>
+
+
</DD>
<DT><b><a name="config_directory">config_directory</a>
</DD>
<DT><b><a name="smtputf8_enable">smtputf8_enable</a>
-(default: no)</b></DT><DD>
+(default: yes)</b></DT><DD>
<p> Enable experimental SMTPUTF8 support for the protocols described
in <a href="http://tools.ietf.org/html/rfc6531">RFC 6531</a>..6533. This requires that Postfix is built to support
<b>SMTPUTF8 CONTROLS</b>
Preliminary SMTPUTF8 support is introduced with Postfix 2.12.
- <b><a href="postconf.5.html#smtputf8_enable">smtputf8_enable</a> (no)</b>
+ <b><a href="postconf.5.html#smtputf8_enable">smtputf8_enable</a> (yes)</b>
Enable experimental SMTPUTF8 support for the protocols described
in <a href="http://tools.ietf.org/html/rfc6531">RFC 6531</a>..6533.
<b>SMTPUTF8 CONTROLS</b>
Preliminary SMTPUTF8 support is introduced with Postfix 2.12.
- <b><a href="postconf.5.html#smtputf8_enable">smtputf8_enable</a> (no)</b>
+ <b><a href="postconf.5.html#smtputf8_enable">smtputf8_enable</a> (yes)</b>
Enable experimental SMTPUTF8 support for the protocols described
in <a href="http://tools.ietf.org/html/rfc6531">RFC 6531</a>..6533.
With locally submitted mail, append the string "@$<a href="postconf.5.html#myorigin">myorigin</a>" to
mail addresses without domain information.
- <b><a href="postconf.5.html#append_dot_mydomain">append_dot_mydomain</a> (yes)</b>
+ <b><a href="postconf.5.html#append_dot_mydomain">append_dot_mydomain</a> (Postfix</b> &<b>ge; 2.12: no, Postfix</b> < <b>2.12: yes)</b>
With locally submitted mail, append the string ".$<a href="postconf.5.html#mydomain">mydomain</a>" to
addresses that have no ".domain" information.
.sp
The \fBlocal\fR(8), \fBpipe\fR(8), \fBspawn\fR(8), and
\fBvirtual\fR(8) daemons require privileges.
-.IP "\fBChroot (default: y)\fR"
+.IP "\fBChroot (default: Postfix >= 2.12: y, Postfix <2.12: n)\fR"
Whether or not the service runs chrooted to the mail queue
directory (pathname is controlled by the \fBqueue_directory\fR
configuration variable in the main.cf file).
.PP
To get the behavior before Postfix version 2.2, specify
"local_header_rewrite_clients = static:all".
-.SH append_dot_mydomain (default: yes)
+.SH append_dot_mydomain (default: Postfix >= 2.12: no, Postfix < 2.12: yes)
With locally submitted mail, append the string ".$mydomain" to
addresses that have no ".domain" information. With remotely submitted
mail, append the string ".$remote_header_rewrite_domain"
.PP
Note: if you set this time limit to a large value you must update the
global ipc_timeout parameter as well.
+.SH compatibility_level (default: 0)
+A safety net that forces Postfix to keep running with
+backwards-compatible main.cf and master.cf default settings after
+an upgrade to a newer but incompatible Postfix version.
+.PP
+Depending on the compatibility_level parameter setting, Postfix
+continues to use backwards-compatible default settings, and logs
+the use of those backwards-compatible default settings with messages
+that contain the string "using legacy default setting". Based on
+this logging the system administrator can determine that a new
+default setting breaks nothing or that a backwards-compatible
+default setting needs to be made permanent in main.cf or master.cf.
+.PP
+After this review is complete, and no more backwards-compatible
+settings need to be made permanent, the administrator should accept
+the remaining Postfix built-in default settings by updating the
+compatibility_level setting in main.cf as recommended in the Postfix
+RELEASE_NOTES.
+.PP
+This feature is available in Postfix 2.12 and later.
.SH config_directory (default: see "postconf -d" output)
The default location of the Postfix main.cf and master.cf
configuration files. This can be overruled via the following
.br
.PP
This feature is available in Postfix 2.12 and later.
-.SH smtputf8_enable (default: no)
+.SH smtputf8_enable (default: yes)
Enable experimental SMTPUTF8 support for the protocols described
in RFC 6531..6533. This requires that Postfix is built to support
these protocols.
.ad
.fi
Preliminary SMTPUTF8 support is introduced with Postfix 2.12.
-.IP "\fBsmtputf8_enable (no)\fR"
+.IP "\fBsmtputf8_enable (yes)\fR"
Enable experimental SMTPUTF8 support for the protocols described
in RFC 6531..6533.
.IP "\fBsmtputf8_autodetect_classes (sendmail, verify)\fR"
.ad
.fi
Preliminary SMTPUTF8 support is introduced with Postfix 2.12.
-.IP "\fBsmtputf8_enable (no)\fR"
+.IP "\fBsmtputf8_enable (yes)\fR"
Enable experimental SMTPUTF8 support for the protocols described
in RFC 6531..6533.
.IP "\fBstrict_smtputf8 (no)\fR"
.IP "\fBappend_at_myorigin (yes)\fR"
With locally submitted mail, append the string "@$myorigin" to mail
addresses without domain information.
-.IP "\fBappend_dot_mydomain (yes)\fR"
+.IP "\fBappend_dot_mydomain (Postfix ≥ 2.12: no, Postfix < 2.12: yes)\fR"
With locally submitted mail, append the string ".$mydomain" to
addresses that have no ".domain" information.
.IP "\fBrecipient_delimiter (empty)\fR"
s;\bpolicy_time_limit\b;<a href="postconf.5.html#transport_time_limit">$&</a>;g;
s;\bgreylist_time_limit\b;<a href="postconf.5.html#transport_time_limit">$&</a>;g;
+ # Compatibility and migration
+
+ s;\bcompatibility_level\b;<a href="postconf.5.html#compatibility_level">$&</a>;g;
+
# Hyperlink URLs and RFC documents
s/(http:\/\/[^ ,"\(\)]*[^ ,"\(\):;!?.])/<a href="$1">$1<\/a>/;
<p> Inside the list, syntax is similar to what we already know from
main.cf: items separated by space or comma. There is one difference:
<b>you must enclose a setting in parentheses, as in "{ name = value
-}", if you want to have space within a value or around "="</b>.
-</p>
+}", if you want to have space or comma within a value or around
+"="</b>. </p>
<h3><a name="macros">Sendmail macro emulation</a></h3>
<p> Each restriction list is evaluated from left to right until
some restriction produces a result of PERMIT, REJECT or DEFER (try
-again later). The end of the list is equivalent to a PERMIT result.
+again later). The end of each list is equivalent to a PERMIT result.
By placing a PERMIT restriction before a REJECT restriction you
can make exceptions for specific clients or users. This is called
whitelisting; the fourth example above allows mail from local
<p> Inside the list, syntax is similar to what we already know from
main.cf: items separated by space or comma. There is one difference:
<b>you must enclose a setting in parentheses, as in "{ name = value
-}", if you want to have space within a value or around "="</b>.
-This comes in handy when different policy servers require different
-default actions with different SMTP status codes or text: </p>
+}", if you want to have space or comma within a value or around
+"="</b>. This comes in handy when different policy servers require
+different default actions with different SMTP status codes or text:
+</p>
<blockquote>
<pre>
<h2> <a name="enabling">Enabling Postfix SMTPUTF8 support</a> </h2>
-<p> Before turning on SMTPUTF8 support in Postfix, you need to
-verify that the rest of your email infrastructure can handle UTF-8
-email addresses and message header values, including SMTPUTF8
+<p> There is more to SMTPUTF8 than just Postfix itself. The rest
+of your email infrastructure also needs to be able to handle UTF-8
+email addresses and message header values. This includes SMTPUTF8
protocol support in SMTP-based content filters (Amavisd), LMTP
servers (Dovecot), and down-stream SMTP servers. </p>
+<p> Postfix SMTPUTF8 support is enabled by default, but it may be
+disabled as part of a backwards-compatibility safety net (see the
+Postfix 2.12 RELEASE_NOTES file). </p>
+
<p> SMTPUTF8 support is enabled by setting the smtputf8_enable
parameter in main.cf:</p>
</pre>
</blockquote>
-<p> With SMTPUTF8 support enabled, Postfix changes behavior as follows: </p>
+<p> With SMTPUTF8 support enabled, Postfix changes behavior with
+respect to earlier Postfix releases: </p>
<ul>
# .sp
# The \fBlocal\fR(8), \fBpipe\fR(8), \fBspawn\fR(8), and
# \fBvirtual\fR(8) daemons require privileges.
-# .IP "\fBChroot (default: y)\fR"
+# .IP "\fBChroot (default: Postfix >= 2.12: y, Postfix <2.12: n)\fR"
# Whether or not the service runs chrooted to the mail queue
# directory (pathname is controlled by the \fBqueue_directory\fR
# configuration variable in the main.cf file).
<p> To get the behavior before Postfix version 2.2, specify
"local_header_rewrite_clients = static:all". </p>
-%PARAM append_dot_mydomain yes
+%PARAM append_dot_mydomain Postfix ≥ 2.12: no, Postfix < 2.12: yes
<p>
With locally submitted mail, append the string ".$mydomain" to
<p> This feature is available in Postfix 2.12 and later. </p>
-%PARAM smtputf8_enable no
+%PARAM smtputf8_enable yes
<p> Enable experimental SMTPUTF8 support for the protocols described
in RFC 6531..6533. This requires that Postfix is built to support
</dl>
<p> This feature is available in Postfix 2.12 and later. </p>
+
+%PARAM compatibility_level 0
+
+<p> A safety net that forces Postfix to keep running with
+backwards-compatible main.cf and master.cf default settings after
+an upgrade to a newer but incompatible Postfix version. </p>
+
+<p> Depending on the compatibility_level parameter setting, Postfix
+continues to use backwards-compatible default settings, and logs
+the use of those backwards-compatible default settings with messages
+that contain the string "using legacy default setting". Based on
+this logging the system administrator can determine that a new
+default setting breaks nothing or that a backwards-compatible
+default setting needs to be made permanent in main.cf or master.cf.
+</p>
+
+<p> After this review is complete, and no more backwards-compatible
+settings need to be made permanent, the administrator should accept
+the remaining Postfix built-in default settings by updating the
+compatibility_level setting in main.cf as recommended in the Postfix
+RELEASE_NOTES. </p>
+
+<p> This feature is available in Postfix 2.12 and later. </p>
/* int var_smtputf8_enable
/* int var_strict_smtputf8;
/* char *var_smtputf8_autoclass;
+/* int var_compat_level;
/*
/* void mail_params_init()
/*
/* const char null_format_string[1];
+/*
+/* int warn_compat_break_app_dot_mydomain;
+/* int warn_compat_break_smtputf8_enable;
+/* int warn_compat_break_chroot;
/* DESCRIPTION
/* This module (actually the associated include file) define the names
/* and defaults of all mail configuration parameters.
/*
/* null_format_string is a workaround for gcc compilers that complain
/* about empty or null format strings.
+/*
+/* The warn_compat_XXX variables enable warnings for the use
+/* of legacy default settings after an incompatible change.
/* DIAGNOSTICS
/* Fatal errors: out of memory; null system or domain name.
/* LICENSE
int var_smtputf8_enable;
int var_strict_smtputf8;
char *var_smtputf8_autoclass;
+int var_compat_level;
const char null_format_string[1] = "";
+int warn_compat_break_app_dot_mydomain;
+int warn_compat_break_smtputf8_enable;
+int warn_compat_break_chroot;
+
/* check_myhostname - lookup hostname and validate */
static const char *check_myhostname(void)
#endif
+/* check_legacy_defaults - flag parameters that require safety-net logging */
+
+static void check_legacy_defaults(void)
+{
+
+ /*
+ * Basic idea: when an existing parameter default is changed, or a new
+ * parameter is introduced with incompatible default behavior, force
+ * Postfix to run with backwards-compatible default settings and log a
+ * warning when the backwards-compatible behavior is used.
+ *
+ * Based on a review of Postfix logging the system administrator can decide
+ * whether or not to make backwards-compatible default settings permanent
+ * in main.cf or master.cf.
+ *
+ * To turn off further warnings and deploy the new default settings, the
+ * system administrator should update the compatibility_level setting as
+ * recommended in the RELASE_NOTES file.
+ *
+ * Each incompatible change has its own flag variable, instead of bit in a
+ * shared variable. We don't want to rip up code when we need more flag
+ * bits.
+ */
+
+ /*
+ * Look for specific parameters that were left behind at legacy defaults
+ * when the compatibility level changed for the first time, from 0 to 1.
+ */
+ if (var_compat_level < 1) {
+ /* Should inet_protocols also be listed here? */
+ if (mail_conf_lookup(VAR_APP_DOT_MYDOMAIN) == 0)
+ warn_compat_break_app_dot_mydomain = 1;
+ if (mail_conf_lookup(VAR_SMTPUTF8_ENABLE) == 0)
+ warn_compat_break_smtputf8_enable = 1;
+ warn_compat_break_chroot = 1;
+ }
+}
+
/* mail_params_init - configure built-in parameters */
void mail_params_init()
{
+ static const CONFIG_INT_TABLE first_int_defaults[] = {
+ VAR_COMPAT_LEVEL, DEF_COMPAT_LEVEL, &var_compat_level, 0, 0,
+ 0,
+ };
static const CONFIG_STR_TABLE first_str_defaults[] = {
/* $mail_version may appear in other parameters. */
VAR_MAIL_VERSION, DEF_MAIL_VERSION, &var_mail_version, 1, 0,
VAR_CYRUS_SASL_AUTHZID, DEF_CYRUS_SASL_AUTHZID, &var_cyrus_sasl_authzid,
VAR_MULTI_ENABLE, DEF_MULTI_ENABLE, &var_multi_enable,
VAR_LONG_QUEUE_IDS, DEF_LONG_QUEUE_IDS, &var_long_queue_ids,
- VAR_SMTPUTF8_ENABLE, DEF_SMTPUTF8_ENABLE, &var_smtputf8_enable,
VAR_STRICT_SMTPUTF8, DEF_STRICT_SMTPUTF8, &var_strict_smtputf8,
0,
};
+ static const CONFIG_NBOOL_TABLE nbool_defaults[] = {
+ VAR_SMTPUTF8_ENABLE, DEF_SMTPUTF8_ENABLE, &var_smtputf8_enable,
+ 0,
+ };
const char *cp;
INET_PROTO_INFO *proto_info;
+ /*
+ * Extract compatibility level first, so that we can determine what
+ * parameters of interest are left at their legacy defaults.
+ */
+ get_mail_conf_int_table(first_int_defaults);
+ check_legacy_defaults();
+
/*
* Extract syslog_facility early, so that from here on all errors are
* logged with the proper facility.
get_mail_conf_int_table(other_int_defaults);
get_mail_conf_long_table(long_defaults);
get_mail_conf_bool_table(bool_defaults);
+ get_mail_conf_nbool_table(nbool_defaults);
get_mail_conf_time_table(time_defaults);
check_default_privs();
check_mail_owner();
#define DEF_SHOW_UNK_RCPT_TABLE 1
extern bool var_show_unk_rcpt_table;
+ /*
+ * Compatibility level and migration support.
+ */
+#define VAR_COMPAT_LEVEL "compatibility_level"
+#define DEF_COMPAT_LEVEL 0
+#define CUR_COMPAT_LEVEL 1
+extern int var_compat_level;
+
+extern int warn_compat_break_app_dot_mydomain;
+extern int warn_compat_break_smtputf8_enable;
+extern int warn_compat_break_chroot;
+
/*
* What problem classes should be reported to the postmaster via email.
* Default is bad problems only. See mail_error(3). Even when mail notices
extern bool var_append_at_myorigin;
#define VAR_APP_DOT_MYDOMAIN "append_dot_mydomain"
-#define DEF_APP_DOT_MYDOMAIN 1
+#define DEF_APP_DOT_MYDOMAIN "${{$compatibility_level} < {1} ? {yes} : {no}}"
extern bool var_append_dot_mydomain;
#define VAR_PERCENT_HACK "allow_percent_hack"
* SMTPUTF8 support.
*/
#define VAR_SMTPUTF8_ENABLE "smtputf8_enable"
-#define DEF_SMTPUTF8_ENABLE 0
+#define DEF_SMTPUTF8_ENABLE "${{$compatibility_level} < {1} ? {no} : {yes}}"
extern int var_smtputf8_enable;
#define VAR_STRICT_SMTPUTF8 "strict_smtputf8"
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20140929"
+#define MAIL_RELEASE_DATE "20141001"
#define MAIL_VERSION_NUMBER "2.12"
#ifdef SNAPSHOT
if (strcmp(value, "-") == 0) {
if (def_val == 0)
fatal_with_context("field \"%s\" has no default value", name);
+ if (warn_compat_break_chroot && strcmp(name, "chroot") == 0)
+ msg_info("%s: line %d: using legacy default setting %s=%s ("
+ VAR_COMPAT_LEVEL "<1)", master_path, master_line,
+ name, def_val);
return (def_val);
} else {
return (value);
* XXX Chroot cannot imply unprivileged service (for example, the pickup
* service runs chrooted but needs privileges to open files as the user).
*/
- chroot = get_bool_ent(&bufp, "chroot", "y");
+ chroot = get_bool_ent(&bufp, "chroot", var_compat_level < 1 ? "y" : "n");
/*
* Wakeup timer. XXX should we require that var_proc_limit == 1? Right
mail_conf_read();
get_mail_conf_str_table(str_table);
+ /*
+ * Alert the sysadmin that the backwards-compatible settings are still
+ * in effect.
+ */
+ if (var_compat_level < CUR_COMPAT_LEVEL) {
+ msg_warn("Postfix is running with backwards-compatible default "
+ "settings");
+ msg_warn("See http://www.postfix.org/postconf.5.html#"
+ VAR_COMPAT_LEVEL " for details");
+ msg_warn("Use \"postconf " VAR_COMPAT_LEVEL "=%d\" to disable "
+ "the backwards-compatible default settings",
+ CUR_COMPAT_LEVEL);
+ }
+
/*
* Environment import filter, to enforce consistent behavior whether this
* command is started by hand, or at system boot time. This is necessary
/* .ad
/* .fi
/* Preliminary SMTPUTF8 support is introduced with Postfix 2.12.
-/* .IP "\fBsmtputf8_enable (no)\fR"
+/* .IP "\fBsmtputf8_enable (yes)\fR"
/* Enable experimental SMTPUTF8 support for the protocols described
/* in RFC 6531..6533.
/* .IP "\fBsmtputf8_autodetect_classes (sendmail, verify)\fR"
/* .ad
/* .fi
/* Preliminary SMTPUTF8 support is introduced with Postfix 2.12.
-/* .IP "\fBsmtputf8_enable (no)\fR"
+/* .IP "\fBsmtputf8_enable (yes)\fR"
/* Enable experimental SMTPUTF8 support for the protocols described
/* in RFC 6531..6533.
/* .IP "\fBstrict_smtputf8 (no)\fR"
* Changing this would be a compatibility break. That can't happen in the
* forseeable future.
*/
- if (var_strict_smtputf8 && (state->flags & SMTPD_FLAG_SMTPUTF8) == 0) {
- if (*STR(state->addr_buf) && !allascii(STR(state->addr_buf))) {
- mail_reset(state);
- smtpd_chat_reply(state, "553 5.6.7 Must declare SMTPUTF8 to send unicode address");
+ if ((var_strict_smtputf8 || warn_compat_break_smtputf8_enable)
+ && (state->flags & SMTPD_FLAG_SMTPUTF8) == 0
+ && *STR(state->addr_buf) && !allascii(STR(state->addr_buf))) {
+ if (var_strict_smtputf8) {
+ smtpd_chat_reply(state, "553 5.6.7 Must declare SMTPUTF8 to "
+ "send unicode address");
return (-1);
}
+ if (warn_compat_break_smtputf8_enable)
+ msg_info("using legacy default setting " VAR_SMTPUTF8_ENABLE
+ "=no to accept non-ASCII sender address \"%s\" from "
+ "%s (" VAR_COMPAT_LEVEL "<1)", STR(state->addr_buf),
+ state->namaddr);
}
/*
* Changing this would be a compatibility break. That can't happen in the
* forseeable future.
*/
- if (var_strict_smtputf8 && (state->flags & SMTPD_FLAG_SMTPUTF8) == 0) {
- if (*STR(state->addr_buf) && !allascii(STR(state->addr_buf))) {
- mail_reset(state);
- smtpd_chat_reply(state, "553 5.6.7 Must declare SMTPUTF8 to send unicode address");
+ if ((var_strict_smtputf8 || warn_compat_break_smtputf8_enable)
+ && (state->flags & SMTPD_FLAG_SMTPUTF8) == 0
+ && *STR(state->addr_buf) && !allascii(STR(state->addr_buf))) {
+ if (var_strict_smtputf8) {
+ smtpd_chat_reply(state, "553 5.6.7 Must declare SMTPUTF8 to "
+ "send unicode address");
return (-1);
}
+ if (warn_compat_break_smtputf8_enable)
+ msg_info("using legacy default setting " VAR_SMTPUTF8_ENABLE
+ "=no to accept non-ASCII recipient address \"%s\" from"
+ " %s (" VAR_COMPAT_LEVEL "<1)", STR(state->addr_buf),
+ state->namaddr);
}
if (SMTPD_STAND_ALONE(state) == 0) {
const char *verify_sender;
TOK822 *domain;
TOK822 *bang;
TOK822 *local;
+ VSTRING *vstringval;
/*
* XXX If you change this module, quote_822_local.c, or tok822_parse.c,
&& domain != tree->tail
&& tok822_find_type(domain, TOK822_DOMLIT) == 0
&& tok822_find_type(domain, '.') == 0) {
+ if (warn_compat_break_app_dot_mydomain
+ && (vstringval = domain->next->vstr) != 0)
+ msg_info("using legacy default setting " VAR_APP_DOT_MYDOMAIN
+ "=yes to rewrite \"%s\" to \"%s.%s\" (" VAR_COMPAT_LEVEL
+ " < 1)", vstring_str(vstringval),
+ vstring_str(vstringval), var_mydomain);
tok822_sub_append(tree, tok822_alloc('.', (char *) 0));
tok822_sub_append(tree, tok822_scan(REW_PARAM_VALUE(context->domain),
(TOK822 **) 0));
/* .IP "\fBappend_at_myorigin (yes)\fR"
/* With locally submitted mail, append the string "@$myorigin" to mail
/* addresses without domain information.
-/* .IP "\fBappend_dot_mydomain (yes)\fR"
+/* .IP "\fBappend_dot_mydomain (Postfix ≥ 2.12: no, Postfix < 2.12: yes)\fR"
/* With locally submitted mail, append the string ".$mydomain" to
/* addresses that have no ".domain" information.
/* .IP "\fBrecipient_delimiter (empty)\fR"
};
static const CONFIG_BOOL_TABLE bool_table[] = {
VAR_SWAP_BANGPATH, DEF_SWAP_BANGPATH, &var_swap_bangpath,
- VAR_APP_DOT_MYDOMAIN, DEF_APP_DOT_MYDOMAIN, &var_append_dot_mydomain,
VAR_APP_AT_MYORIGIN, DEF_APP_AT_MYORIGIN, &var_append_at_myorigin,
VAR_PERCENT_HACK, DEF_PERCENT_HACK, &var_percent_hack,
VAR_RESOLVE_DEQUOTED, DEF_RESOLVE_DEQUOTED, &var_resolve_dequoted,
VAR_ALLOW_MIN_USER, DEF_ALLOW_MIN_USER, &var_allow_min_user,
0,
};
+ static const CONFIG_NBOOL_TABLE nbool_table[] = {
+ VAR_APP_DOT_MYDOMAIN, DEF_APP_DOT_MYDOMAIN, &var_append_dot_mydomain,
+ 0,
+ };
/*
* Fingerprint executables and core dumps.
multi_server_main(argc, argv, rewrite_service,
MAIL_SERVER_STR_TABLE, str_table,
MAIL_SERVER_BOOL_TABLE, bool_table,
+ MAIL_SERVER_NBOOL_TABLE, nbool_table,
MAIL_SERVER_PRE_INIT, pre_jail_init,
MAIL_SERVER_POST_INIT, post_jail_init,
#ifdef CHECK_TABLE_STATS_BEFORE_ACCEPT
/*
* Split the table name into its constituent parts.
*/
- saved_name = mystrdup(name + 1); /* XXX ASCII delimiter */
if ((len = balpar(name, "{}")) == 0 || name[len] != 0
|| *(saved_name = mystrndup(name + 1, len - 2)) == 0)
DICT_UNION_RETURN(dict_surrogate(DICT_TYPE_UNION, name,
#include <sys_defs.h>
#include <ctype.h>
#include <string.h>
+#include <stdlib.h>
/* Utility library. */
*/
#define MAC_EXP_OP_STR_EQ "=="
#define MAC_EXP_OP_STR_NE "!="
+#define MAC_EXP_OP_STR_LT "<"
+#define MAC_EXP_OP_STR_LE "<="
+#define MAC_EXP_OP_STR_GE ">="
+#define MAC_EXP_OP_STR_GT ">"
#define MAC_EXP_OP_STR_ANY "\"" MAC_EXP_OP_STR_EQ \
- "\" or \"" MAC_EXP_OP_STR_NE "\""
+ "\" or \"" MAC_EXP_OP_STR_NE "\"" \
+ "\" or \"" MAC_EXP_OP_STR_LT "\"" \
+ "\" or \"" MAC_EXP_OP_STR_LE "\"" \
+ "\" or \"" MAC_EXP_OP_STR_GE "\"" \
+ "\" or \"" MAC_EXP_OP_STR_GT "\""
#define MAC_EXP_OP_TOK_NONE 0
#define MAC_EXP_OP_TOK_EQ 1
#define MAC_EXP_OP_TOK_NE 2
+#define MAC_EXP_OP_TOK_LT 3
+#define MAC_EXP_OP_TOK_LE 4
+#define MAC_EXP_OP_TOK_GE 5
+#define MAC_EXP_OP_TOK_GT 6
static const NAME_CODE mac_exp_op_table[] =
{
MAC_EXP_OP_STR_EQ, MAC_EXP_OP_TOK_EQ,
MAC_EXP_OP_STR_NE, MAC_EXP_OP_TOK_NE,
+ MAC_EXP_OP_STR_LT, MAC_EXP_OP_TOK_LT,
+ MAC_EXP_OP_STR_LE, MAC_EXP_OP_TOK_LE,
+ MAC_EXP_OP_STR_GE, MAC_EXP_OP_TOK_GE,
+ MAC_EXP_OP_STR_GT, MAC_EXP_OP_TOK_GT,
0, MAC_EXP_OP_TOK_NONE,
};
*/
#define MAC_EXP_WHITESPACE " \t\r\n"
+/* mac_exp_eval - evaluate binary expression */
+
+static int mac_exp_eval(const char *left, int tok_val,
+ const char *rite)
+{
+ static const char myname[] = "mac_exp_eval";
+ long delta;
+
+ /*
+ * Numerical or string comparison.
+ */
+ if (alldig(left) && alldig(rite)) {
+ delta = atol(left) - atol(rite);
+ } else {
+ delta = strcmp(left, rite);
+ }
+ switch (tok_val) {
+ case MAC_EXP_OP_TOK_EQ:
+ return (delta == 0);
+ case MAC_EXP_OP_TOK_NE:
+ return (delta != 0);
+ case MAC_EXP_OP_TOK_LT:
+ return (delta < 0);
+ case MAC_EXP_OP_TOK_LE:
+ return (delta <= 0);
+ case MAC_EXP_OP_TOK_GE:
+ return (delta >= 0);
+ case MAC_EXP_OP_TOK_GT:
+ return (delta > 0);
+ default:
+ msg_panic("%s: unknown operator: %d",
+ myname, tok_val);
+ }
+}
+
/* mac_exp_parse_error - report parse error, set error flag, return status */
static int PRINTFLIKE(2, 3) mac_exp_parse_error(MAC_EXP_CONTEXT *mc,
static int mac_exp_parse_logical(MAC_EXP_CONTEXT *mc, const char **lookup,
char **bp)
{
- const char myname[] = "mac_exp_parse_logical";
char *cp = *bp;
VSTRING *left_op_buf;
VSTRING *rite_op_buf;
mc->status |=
mac_expand(rite_op_buf = vstring_alloc(100), rite_op_strval,
mc->flags, mc->filter, mc->lookup, mc->context);
- op_result =
- strcmp(vstring_str(left_op_buf), vstring_str(rite_op_buf));
+ op_result = mac_exp_eval(vstring_str(left_op_buf), op_tokval,
+ vstring_str(rite_op_buf));
vstring_free(left_op_buf);
vstring_free(rite_op_buf);
if (mc->status & MAC_PARSE_ERROR)
* for compatibility with the historical code that looks named parameter
* values.
*/
- switch (op_tokval) {
- case MAC_EXP_OP_TOK_EQ:
- *lookup = op_result == 0 ?
- MAC_EXP_BVAL_TRUE : MAC_EXP_BVAL_FALSE;
- break;
- case MAC_EXP_OP_TOK_NE:
- *lookup = op_result != 0 ?
- MAC_EXP_BVAL_TRUE : MAC_EXP_BVAL_FALSE;
- break;
- default:
- msg_panic("%s: unknown macro operator code %d",
- myname, op_tokval);
- }
+ *lookup = (op_result ? MAC_EXP_BVAL_TRUE : MAC_EXP_BVAL_FALSE);
*bp = cp;
return (0);
}
${{$name2} != {} ? {name 2 defined, |$name1|$name2|} : name 2 undefined, |$name1|$name2|}
${{$name2} != {}}
${{$name2} == {}}
+
+
+${{1} == {1}}
+${{1} < {1}}
+${{1} <= {1}}
+${{1} >= {1}}
+${{1} > {1}}
+${{1} == {2}}
+${{1} < {2}}
+${{1} <= {2}}
+${{1} >= {2}}
+${{1} > {2}}
+${{a} == {a}}
+${{a} < {a}}
+${{a} <= {a}}
+${{a} >= {a}}
+${{a} > {a}}
+${{a} == {b}}
+${{a} < {b}}
+${{a} <= {b}}
+${{a} >= {b}}
+${{a} > {b}}
unknown: warning: attribute name syntax error at: "...>>> ${name1} ?name 1 de"
stat=1 result=
<< ${{$name1} ? {name 1 defined, |$name1|$name2|} : {name 1 undefined, |$name1|$name2|} }
-unknown: warning: "==" or "!=" expected at: "...$name1}>>>? {name 1 defined, |"
+unknown: warning: "==" or "!="" or "<"" or "<="" or ">="" or ">" expected at: "...$name1}>>>? {name 1 defined, |"
stat=1 result=
<< ${x{$name1} != {}?{name 1 defined, |$name1|$name2|}}
unknown: warning: attribute name syntax error at: "...x>>>{$name1} != {}?{name"
stat=1 result=
<< ${{$name1}x?{name 1 defined, |$name1|$name2|}}
-unknown: warning: "==" or "!=" expected at: "...$name1}>>>x?{name 1 defined, |"
+unknown: warning: "==" or "!="" or "<"" or "<="" or ">="" or ">" expected at: "...$name1}>>>x?{name 1 defined, |"
stat=1 result=
<< ${{$name1} != {}x{name 1 defined, |$name1|$name2|}}
unknown: warning: "?" or ":" expected at: "...}>>>x{name 1 defined, |$"
<< ${{$name2} != {}?{name 2 defined, |$name1|$name2|}:x{name 2 undefined, |$name1|$name2|}}
stat=2 result=x{name 2 undefined, |name1-value||}
<< ${{text}}
-unknown: warning: "==" or "!=" expected at: "...text}>>>"
+unknown: warning: "==" or "!="" or "<"" or "<="" or ">="" or ">" expected at: "...text}>>>"
stat=1 result=
<< ${{text}?{non-empty}:{empty}}
-unknown: warning: "==" or "!=" expected at: "...text}>>>?{non-empty}:{empty}"
+unknown: warning: "==" or "!="" or "<"" or "<="" or ">="" or ">" expected at: "...text}>>>?{non-empty}:{empty}"
stat=1 result=
<< ${{text} = {}}
-unknown: warning: "==" or "!=" expected at: "...text}>>>= {}"
+unknown: warning: "==" or "!="" or "<"" or "<="" or ">="" or ">" expected at: "...text}>>>= {}"
stat=1 result=
<< ${{${ name1}} == {}}
unknown: warning: attribute name syntax error at: "...>>> name1"
stat=2 result=
<< ${{$name2} == {}}
stat=2 result=true
+<<
+
+<<
+<< ${{1} == {1}}
+stat=0 result=true
+<< ${{1} < {1}}
+stat=0 result=
+<< ${{1} <= {1}}
+stat=0 result=true
+<< ${{1} >= {1}}
+stat=0 result=true
+<< ${{1} > {1}}
+stat=0 result=
+<< ${{1} == {2}}
+stat=0 result=
+<< ${{1} < {2}}
+stat=0 result=true
+<< ${{1} <= {2}}
+stat=0 result=true
+<< ${{1} >= {2}}
+stat=0 result=
+<< ${{1} > {2}}
+stat=0 result=
+<< ${{a} == {a}}
+stat=0 result=true
+<< ${{a} < {a}}
+stat=0 result=
+<< ${{a} <= {a}}
+stat=0 result=true
+<< ${{a} >= {a}}
+stat=0 result=true
+<< ${{a} > {a}}
+stat=0 result=
+<< ${{a} == {b}}
+stat=0 result=
+<< ${{a} < {b}}
+stat=0 result=true
+<< ${{a} <= {b}}
+stat=0 result=true
+<< ${{a} >= {b}}
+stat=0 result=
+<< ${{a} > {b}}
+stat=0 result=