From: Wietse Venema Date: Thu, 18 Jan 2007 05:00:00 +0000 (-0500) Subject: postfix-2.4-20070118 X-Git-Tag: v2.4.0-RC1~19 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3b08d6f9a98717b5176081a61603713cfa98df02;p=thirdparty%2Fpostfix.git postfix-2.4-20070118 --- diff --git a/postfix/.indent.pro b/postfix/.indent.pro index c45e2f9ce..e759f3ea7 100644 --- a/postfix/.indent.pro +++ b/postfix/.indent.pro @@ -28,7 +28,7 @@ -TBOUNCE_TIME_PARAMETER -TCFG_PARSER -TCIDR_MATCH --TCLEANUP_BODY_REGION +-TCLEANUP_REGION -TCLEANUP_STATE -TCLEANUP_STAT_DETAIL -TCLIENT_LIST diff --git a/postfix/HISTORY b/postfix/HISTORY index 0e6d4be2a..324df9365 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -13116,8 +13116,28 @@ Apologies for any names omitted. as it was before the body was replaced. Files: milter/milter8.c, cleanup/cleanup_milter.c, cleanup/cleanup_body_region.c. +20070117 + + Cleanup: reusable infrastructure for body replacement. + Files: cleanup/cleanup_body_edit.c, cleanup/cleanup_region.c. + +20070118 + + Bugfix: match lists didn't implement !maptype:mapname. + Problem reported by Paulo Pacheco. File: util/match_list.c. + + Cleanup: revised the matchlist "!" support, added support + for !/file/name, and updated the documentation. File: + util/match_list.c. + Wish list: + Need scache size limit. + + Don't transform bare username into user@localdomain.localdomain + when no domain is specified via main.cf or via the machine + hostname. + Update BACKSCATTER_README to use PCRE because that's what I am using now. diff --git a/postfix/conf/postfix-files b/postfix/conf/postfix-files index b04779dc0..0f1a23b1b 100644 --- a/postfix/conf/postfix-files +++ b/postfix/conf/postfix-files @@ -263,6 +263,7 @@ $readme_directory/SMTPD_ACCESS_README:f:root:-:644 $readme_directory/SMTPD_POLICY_README:f:root:-:644 $readme_directory/SMTPD_PROXY_README:f:root:-:644 $readme_directory/STANDARD_CONFIGURATION_README:f:root:-:644 +$readme_directory/TLS_LEGACY_README:f:root:-:644 $readme_directory/TLS_README:f:root:-:644 $readme_directory/TUNING_README:f:root:-:644 $readme_directory/ULTRIX_README:f:root:-:644 diff --git a/postfix/html/postconf.5.html b/postfix/html/postconf.5.html index 03fbe53db..e2dd877d8 100644 --- a/postfix/html/postconf.5.html +++ b/postfix/html/postconf.5.html @@ -823,11 +823,13 @@ password file.

Specify a list of user names, "/file/name" or "type:table" patterns, separated by commas and/or whitespace. The list is matched left to -right, and the search stops on the first match. Specify "!name" to -exclude a name from the list. A "/file/name" pattern is replaced +right, and the search stops on the first match. A "/file/name" +pattern is replaced by its contents; a "type:table" lookup table is matched when a name matches a lookup key (the lookup result is ignored). Continue long -lines by starting the next line with whitespace.

+lines by starting the next line with whitespace. Specify "!pattern" +to exclude a name from the list. The form "!/file/name" is supported +only in Postfix version 2.4 and later.

This feature is available in Postfix 2.2 and later. @@ -855,11 +857,13 @@ password file.

Specify a list of user names, "/file/name" or "type:table" patterns, separated by commas and/or whitespace. The list is matched left to -right, and the search stops on the first match. Specify "!name" to -exclude a name from the list. A "/file/name" pattern is replaced +right, and the search stops on the first match. A "/file/name" +pattern is replaced by its contents; a "type:table" lookup table is matched when a name matches a lookup key (the lookup result is ignored). Continue long -lines by starting the next line with whitespace.

+lines by starting the next line with whitespace. Specify "!pattern" +to exclude a user name from the list. The form "!/file/name" is +supported only in Postfix version 2.4 and later.

This feature is available in Postfix 2.2 and later. @@ -887,11 +891,13 @@ submission access to all users specify an empty list.

Specify a list of user names, "/file/name" or "type:table" patterns, separated by commas and/or whitespace. The list is matched left to right, -and the search stops on the first match. Specify "!name" to exclude a -name from the list. A "/file/name" pattern is replaced by its contents; +and the search stops on the first match. A "/file/name" pattern is +replaced by its contents; a "type:table" lookup table is matched when a name matches a lookup key (the lookup result is ignored). Continue long lines by starting the -next line with whitespace.

+next line with whitespace. Specify "!pattern" to exclude a user +name from the list. The form "!/file/name" is supported only in +Postfix version 2.4 and later.

Example: @@ -930,7 +936,9 @@ below it), "/file/name" or "type:table" patt pattern is replaced by its contents; a "type:table" lookup table is matched when a table entry matches a lookup string (the lookup result is ignored). Continue long lines by starting the next line -with whitespace.

+with whitespace. Specify "!pattern" to exclude an address or network +block from the list. The form "!/file/name" is supported only in +Postfix version 2.4 and later.

Note: IP version 6 address information must be specified inside [] in the authorized_verp_clients value, and in files @@ -4841,11 +4849,13 @@ By default, address masquerading makes no exceptions.

Specify a list of user names, "/file/name" or "type:table" patterns, separated by commas and/or whitespace. The list is matched left to -right, and the search stops on the first match. Specify "!name" to -exclude a name from the list. A "/file/name" pattern is replaced +right, and the search stops on the first match. A "/file/name" +pattern is replaced by its contents; a "type:table" lookup table is matched when a name matches a lookup key (the lookup result is ignored). Continue long -lines by starting the next line with whitespace.

+lines by starting the next line with whitespace. Specify "!pattern" +to exclude a name from the list. The form "!/file/name" is supported +only in Postfix version 2.4 and later.

Examples: @@ -5421,7 +5431,8 @@ lookup string (the lookup result is ignored).

The list is matched left to right, and the search stops on the first match. Specify "!pattern" to exclude an address or network -block from the list.

+block from the list. The form "!/file/name" is supported only +in Postfix version 2.4 and later.

Note: IP version 6 address information must be specified inside [] in the mynetworks value, and in files specified with @@ -5937,8 +5948,9 @@ table lookup is used instead.

Patterns are separated by whitespace and/or commas. In order to -reverse the result, precede a non-file name pattern with an -exclamation point (!). +reverse the result, precede a pattern with an +exclamation point (!). The form "!/file/name" is supported only +in Postfix version 2.4 and later.

@@ -6387,7 +6399,9 @@ or "type:table" lookup tables, separated by c Continue long lines by starting the next line with whitespace. A "/file/name" pattern is replaced by its contents; a "type:table" lookup table is matched when a (parent) domain appears as lookup -key.

+key. Specify "!pattern" to exclude a domain from the list. The form +"!/file/name" is supported only in Postfix version 2.4 and later. +

@@ -7690,7 +7704,9 @@ mechanisms the client will take into consideration.

Specify mechanism names, "/file/name" patterns or "type:table" lookup tables. The right-hand side result from "type:table" lookups -is ignored.

+is ignored. Specify "!pattern" to exclude a mechanism name from the +list. The form "!/file/name" is supported only in Postfix version +2.4 and later.

This feature is available in Postfix 2.2 and later.

@@ -8839,7 +8855,9 @@ below it), "/file/name" or "type:table" patt pattern is replaced by its contents; a "type:table" lookup table is matched when a table entry matches a lookup string (the lookup result is ignored). Continue long lines by starting the next line -with whitespace.

+with whitespace. Specify "!pattern" to exclude an address or network +block from the list. The form "!/file/name" is supported only in +Postfix version 2.4 and later.

Note: IP version 6 address information must be specified inside [] in the smtpd_authorized_verp_clients value, and in @@ -8878,7 +8896,9 @@ below it), "/file/name" or "type:table" patt pattern is replaced by its contents; a "type:table" lookup table is matched when a table entry matches a lookup string (the lookup result is ignored). Continue long lines by starting the next line -with whitespace.

+with whitespace. Specify "!pattern" to exclude an address or network +block from the list. The form "!/file/name" is supported only in +Postfix version 2.4 and later.

Note: IP version 6 address information must be specified inside [] in the smtpd_authorized_xclient_hosts value, and in @@ -8916,7 +8936,9 @@ below it), "/file/name" or "type:table" patt pattern is replaced by its contents; a "type:table" lookup table is matched when a table entry matches a lookup string (the lookup result is ignored). Continue long lines by starting the next line -with whitespace.

+with whitespace. Specify "!pattern" to exclude an address or network +block from the list. The form "!/file/name" is supported only in +Postfix version 2.4 and later.

Note: IP version 6 address information must be specified inside [] in the smtpd_authorized_xforward_hosts value, and in @@ -10409,7 +10431,10 @@ network part of a host address. You can also "/file/name" or "type:table" patterns. A "/file/name" pattern is replaced by its contents; a "type:table" lookup table is matched when a table entry matches a lookup string (the lookup result is ignored). Continue -long lines by starting the next line with whitespace.

+long lines by starting the next line with whitespace. Specify +"!pattern" to exclude an address or network block from the list. +The form "!/file/name" is supported only in Postfix version 2.4 and +later.

Note: IP version 6 address information must be specified inside [] in the smtpd_sasl_exceptions_networks value, and in @@ -12136,7 +12161,9 @@ domain names). "/file/name" pattern is replaced by its contents; a "type:table" lookup table is matched when a table entry matches a lookup string (the lookup result is ignored). Continue long lines by starting -the next line with whitespace.

+the next line with whitespace. Specify "!pattern" to exclude a host +or domain name from the list. The form "!/file/name" is supported +only in Postfix version 2.4 and later.

See also the VIRTUAL_README and ADDRESS_CLASS_README documents diff --git a/postfix/man/man5/postconf.5 b/postfix/man/man5/postconf.5 index 64c3e303c..197513cdd 100644 --- a/postfix/man/man5/postconf.5 +++ b/postfix/man/man5/postconf.5 @@ -450,11 +450,13 @@ password file. .PP Specify a list of user names, "/file/name" or "type:table" patterns, separated by commas and/or whitespace. The list is matched left to -right, and the search stops on the first match. Specify "!name" to -exclude a name from the list. A "/file/name" pattern is replaced +right, and the search stops on the first match. A "/file/name" +pattern is replaced by its contents; a "type:table" lookup table is matched when a name matches a lookup key (the lookup result is ignored). Continue long -lines by starting the next line with whitespace. +lines by starting the next line with whitespace. Specify "!pattern" +to exclude a name from the list. The form "!/file/name" is supported +only in Postfix version 2.4 and later. .PP This feature is available in Postfix 2.2 and later. .SH authorized_mailq_users (default: static:anyone) @@ -470,11 +472,13 @@ password file. .PP Specify a list of user names, "/file/name" or "type:table" patterns, separated by commas and/or whitespace. The list is matched left to -right, and the search stops on the first match. Specify "!name" to -exclude a name from the list. A "/file/name" pattern is replaced +right, and the search stops on the first match. A "/file/name" +pattern is replaced by its contents; a "type:table" lookup table is matched when a name matches a lookup key (the lookup result is ignored). Continue long -lines by starting the next line with whitespace. +lines by starting the next line with whitespace. Specify "!pattern" +to exclude a user name from the list. The form "!/file/name" is +supported only in Postfix version 2.4 and later. .PP This feature is available in Postfix 2.2 and later. .SH authorized_submit_users (default: static:anyone) @@ -490,11 +494,13 @@ submission access to all users specify an empty list. .PP Specify a list of user names, "/file/name" or "type:table" patterns, separated by commas and/or whitespace. The list is matched left to right, -and the search stops on the first match. Specify "!name" to exclude a -name from the list. A "/file/name" pattern is replaced by its contents; +and the search stops on the first match. A "/file/name" pattern is +replaced by its contents; a "type:table" lookup table is matched when a name matches a lookup key (the lookup result is ignored). Continue long lines by starting the -next line with whitespace. +next line with whitespace. Specify "!pattern" to exclude a user +name from the list. The form "!/file/name" is supported only in +Postfix version 2.4 and later. .PP Example: .PP @@ -526,7 +532,9 @@ below it), "/file/name" or "type:table" patterns. A "/file/name" pattern is replaced by its contents; a "type:table" lookup table is matched when a table entry matches a lookup string (the lookup result is ignored). Continue long lines by starting the next line -with whitespace. +with whitespace. Specify "!pattern" to exclude an address or network +block from the list. The form "!/file/name" is supported only in +Postfix version 2.4 and later. .PP Note: IP version 6 address information must be specified inside [] in the authorized_verp_clients value, and in files @@ -2620,11 +2628,13 @@ By default, address masquerading makes no exceptions. .PP Specify a list of user names, "/file/name" or "type:table" patterns, separated by commas and/or whitespace. The list is matched left to -right, and the search stops on the first match. Specify "!name" to -exclude a name from the list. A "/file/name" pattern is replaced +right, and the search stops on the first match. A "/file/name" +pattern is replaced by its contents; a "type:table" lookup table is matched when a name matches a lookup key (the lookup result is ignored). Continue long -lines by starting the next line with whitespace. +lines by starting the next line with whitespace. Specify "!pattern" +to exclude a name from the list. The form "!/file/name" is supported +only in Postfix version 2.4 and later. .PP Examples: .PP @@ -2958,7 +2968,8 @@ lookup string (the lookup result is ignored). .PP The list is matched left to right, and the search stops on the first match. Specify "!pattern" to exclude an address or network -block from the list. +block from the list. The form "!/file/name" is supported only +in Postfix version 2.4 and later. .PP Note: IP version 6 address information must be specified inside [] in the mynetworks value, and in files specified with @@ -3240,8 +3251,9 @@ for the file name; when a pattern is a "type:table" table specification, table lookup is used instead. .PP Patterns are separated by whitespace and/or commas. In order to -reverse the result, precede a non-file name pattern with an -exclamation point (!). +reverse the result, precede a pattern with an +exclamation point (!). The form "!/file/name" is supported only +in Postfix version 2.4 and later. .PP Example: .PP @@ -3513,7 +3525,8 @@ or "type:table" lookup tables, separated by commas and/or whitespace. Continue long lines by starting the next line with whitespace. A "/file/name" pattern is replaced by its contents; a "type:table" lookup table is matched when a (parent) domain appears as lookup -key. +key. Specify "!pattern" to exclude a domain from the list. The form +"!/file/name" is supported only in Postfix version 2.4 and later. .SH relay_domains_reject_code (default: 554) The numerical Postfix SMTP server response code when a client request is rejected by the reject_unauth_destination recipient @@ -4275,7 +4288,9 @@ mechanisms the client will take into consideration. .PP Specify mechanism names, "/file/name" patterns or "type:table" lookup tables. The right-hand side result from "type:table" lookups -is ignored. +is ignored. Specify "!pattern" to exclude a mechanism name from the +list. The form "!/file/name" is supported only in Postfix version +2.4 and later. .PP This feature is available in Postfix 2.2 and later. .PP @@ -5191,7 +5206,9 @@ below it), "/file/name" or "type:table" patterns. A "/file/name" pattern is replaced by its contents; a "type:table" lookup table is matched when a table entry matches a lookup string (the lookup result is ignored). Continue long lines by starting the next line -with whitespace. +with whitespace. Specify "!pattern" to exclude an address or network +block from the list. The form "!/file/name" is supported only in +Postfix version 2.4 and later. .PP Note: IP version 6 address information must be specified inside [] in the smtpd_authorized_verp_clients value, and in @@ -5217,7 +5234,9 @@ below it), "/file/name" or "type:table" patterns. A "/file/name" pattern is replaced by its contents; a "type:table" lookup table is matched when a table entry matches a lookup string (the lookup result is ignored). Continue long lines by starting the next line -with whitespace. +with whitespace. Specify "!pattern" to exclude an address or network +block from the list. The form "!/file/name" is supported only in +Postfix version 2.4 and later. .PP Note: IP version 6 address information must be specified inside [] in the smtpd_authorized_xclient_hosts value, and in @@ -5242,7 +5261,9 @@ below it), "/file/name" or "type:table" patterns. A "/file/name" pattern is replaced by its contents; a "type:table" lookup table is matched when a table entry matches a lookup string (the lookup result is ignored). Continue long lines by starting the next line -with whitespace. +with whitespace. Specify "!pattern" to exclude an address or network +block from the list. The form "!/file/name" is supported only in +Postfix version 2.4 and later. .PP Note: IP version 6 address information must be specified inside [] in the smtpd_authorized_xforward_hosts value, and in @@ -6199,7 +6220,10 @@ network part of a host address. You can also "/file/name" or "type:table" patterns. A "/file/name" pattern is replaced by its contents; a "type:table" lookup table is matched when a table entry matches a lookup string (the lookup result is ignored). Continue -long lines by starting the next line with whitespace. +long lines by starting the next line with whitespace. Specify +"!pattern" to exclude an address or network block from the list. +The form "!/file/name" is supported only in Postfix version 2.4 and +later. .PP Note: IP version 6 address information must be specified inside [] in the smtpd_sasl_exceptions_networks value, and in @@ -7322,7 +7346,9 @@ Specify a list of host or domain names, "/file/name" or "/file/name" pattern is replaced by its contents; a "type:table" lookup table is matched when a table entry matches a lookup string (the lookup result is ignored). Continue long lines by starting -the next line with whitespace. +the next line with whitespace. Specify "!pattern" to exclude a host +or domain name from the list. The form "!/file/name" is supported +only in Postfix version 2.4 and later. .PP See also the VIRTUAL_README and ADDRESS_CLASS_README documents for further information. diff --git a/postfix/proto/postconf.proto b/postfix/proto/postconf.proto index abbd8714b..0df64f8f3 100644 --- a/postfix/proto/postconf.proto +++ b/postfix/proto/postconf.proto @@ -2543,11 +2543,13 @@ By default, address masquerading makes no exceptions.

Specify a list of user names, "/file/name" or "type:table" patterns, separated by commas and/or whitespace. The list is matched left to -right, and the search stops on the first match. Specify "!name" to -exclude a name from the list. A "/file/name" pattern is replaced +right, and the search stops on the first match. A "/file/name" +pattern is replaced by its contents; a "type:table" lookup table is matched when a name matches a lookup key (the lookup result is ignored). Continue long -lines by starting the next line with whitespace.

+lines by starting the next line with whitespace. Specify "!pattern" +to exclude a name from the list. The form "!/file/name" is supported +only in Postfix version 2.4 and later.

Examples: @@ -2777,7 +2779,8 @@ lookup string (the lookup result is ignored).

The list is matched left to right, and the search stops on the first match. Specify "!pattern" to exclude an address or network -block from the list.

+block from the list. The form "!/file/name" is supported only +in Postfix version 2.4 and later.

Note: IP version 6 address information must be specified inside [] in the mynetworks value, and in files specified with @@ -3007,8 +3010,9 @@ table lookup is used instead.

Patterns are separated by whitespace and/or commas. In order to -reverse the result, precede a non-file name pattern with an -exclamation point (!). +reverse the result, precede a pattern with an +exclamation point (!). The form "!/file/name" is supported only +in Postfix version 2.4 and later.

@@ -3284,7 +3288,9 @@ or "type:table" lookup tables, separated by commas and/or whitespace. Continue long lines by starting the next line with whitespace. A "/file/name" pattern is replaced by its contents; a "type:table" lookup table is matched when a (parent) domain appears as lookup -key.

+key. Specify "!pattern" to exclude a domain from the list. The form +"!/file/name" is supported only in Postfix version 2.4 and later. +

%PARAM relay_domains_reject_code 554 @@ -4134,7 +4140,9 @@ mechanisms the client will take into consideration.

Specify mechanism names, "/file/name" patterns or "type:table" lookup tables. The right-hand side result from "type:table" lookups -is ignored.

+is ignored. Specify "!pattern" to exclude a mechanism name from the +list. The form "!/file/name" is supported only in Postfix version +2.4 and later.

This feature is available in Postfix 2.2 and later.

@@ -4239,7 +4247,9 @@ below it), "/file/name" or "type:table" patterns. A "/file/name" pattern is replaced by its contents; a "type:table" lookup table is matched when a table entry matches a lookup string (the lookup result is ignored). Continue long lines by starting the next line -with whitespace.

+with whitespace. Specify "!pattern" to exclude an address or network +block from the list. The form "!/file/name" is supported only in +Postfix version 2.4 and later.

Note: IP version 6 address information must be specified inside [] in the authorized_verp_clients value, and in files @@ -4266,7 +4276,9 @@ below it), "/file/name" or "type:table" patterns. A "/file/name" pattern is replaced by its contents; a "type:table" lookup table is matched when a table entry matches a lookup string (the lookup result is ignored). Continue long lines by starting the next line -with whitespace.

+with whitespace. Specify "!pattern" to exclude an address or network +block from the list. The form "!/file/name" is supported only in +Postfix version 2.4 and later.

Note: IP version 6 address information must be specified inside [] in the smtpd_authorized_verp_clients value, and in @@ -4301,7 +4313,9 @@ below it), "/file/name" or "type:table" patterns. A "/file/name" pattern is replaced by its contents; a "type:table" lookup table is matched when a table entry matches a lookup string (the lookup result is ignored). Continue long lines by starting the next line -with whitespace.

+with whitespace. Specify "!pattern" to exclude an address or network +block from the list. The form "!/file/name" is supported only in +Postfix version 2.4 and later.

Note: IP version 6 address information must be specified inside [] in the smtpd_authorized_xclient_hosts value, and in @@ -4335,7 +4349,9 @@ below it), "/file/name" or "type:table" patterns. A "/file/name" pattern is replaced by its contents; a "type:table" lookup table is matched when a table entry matches a lookup string (the lookup result is ignored). Continue long lines by starting the next line -with whitespace.

+with whitespace. Specify "!pattern" to exclude an address or network +block from the list. The form "!/file/name" is supported only in +Postfix version 2.4 and later.

Note: IP version 6 address information must be specified inside [] in the smtpd_authorized_xforward_hosts value, and in @@ -5450,7 +5466,10 @@ network part of a host address. You can also "/file/name" or "type:table" patterns. A "/file/name" pattern is replaced by its contents; a "type:table" lookup table is matched when a table entry matches a lookup string (the lookup result is ignored). Continue -long lines by starting the next line with whitespace.

+long lines by starting the next line with whitespace. Specify +"!pattern" to exclude an address or network block from the list. +The form "!/file/name" is supported only in Postfix version 2.4 and +later.

Note: IP version 6 address information must be specified inside [] in the smtpd_sasl_exceptions_networks value, and in @@ -6049,7 +6068,9 @@ domain names). "/file/name" pattern is replaced by its contents; a "type:table" lookup table is matched when a table entry matches a lookup string (the lookup result is ignored). Continue long lines by starting -the next line with whitespace.

+the next line with whitespace. Specify "!pattern" to exclude a host +or domain name from the list. The form "!/file/name" is supported +only in Postfix version 2.4 and later.

See also the VIRTUAL_README and ADDRESS_CLASS_README documents @@ -6275,11 +6296,13 @@ password file.

Specify a list of user names, "/file/name" or "type:table" patterns, separated by commas and/or whitespace. The list is matched left to -right, and the search stops on the first match. Specify "!name" to -exclude a name from the list. A "/file/name" pattern is replaced +right, and the search stops on the first match. A "/file/name" +pattern is replaced by its contents; a "type:table" lookup table is matched when a name matches a lookup key (the lookup result is ignored). Continue long -lines by starting the next line with whitespace.

+lines by starting the next line with whitespace. Specify "!pattern" +to exclude a name from the list. The form "!/file/name" is supported +only in Postfix version 2.4 and later.

This feature is available in Postfix 2.2 and later. @@ -6303,11 +6326,13 @@ password file.

Specify a list of user names, "/file/name" or "type:table" patterns, separated by commas and/or whitespace. The list is matched left to -right, and the search stops on the first match. Specify "!name" to -exclude a name from the list. A "/file/name" pattern is replaced +right, and the search stops on the first match. A "/file/name" +pattern is replaced by its contents; a "type:table" lookup table is matched when a name matches a lookup key (the lookup result is ignored). Continue long -lines by starting the next line with whitespace.

+lines by starting the next line with whitespace. Specify "!pattern" +to exclude a user name from the list. The form "!/file/name" is +supported only in Postfix version 2.4 and later.

This feature is available in Postfix 2.2 and later. @@ -6331,11 +6356,13 @@ submission access to all users specify an empty list.

Specify a list of user names, "/file/name" or "type:table" patterns, separated by commas and/or whitespace. The list is matched left to right, -and the search stops on the first match. Specify "!name" to exclude a -name from the list. A "/file/name" pattern is replaced by its contents; +and the search stops on the first match. A "/file/name" pattern is +replaced by its contents; a "type:table" lookup table is matched when a name matches a lookup key (the lookup result is ignored). Continue long lines by starting the -next line with whitespace.

+next line with whitespace. Specify "!pattern" to exclude a user +name from the list. The form "!/file/name" is supported only in +Postfix version 2.4 and later.

Example: diff --git a/postfix/src/cleanup/Makefile.in b/postfix/src/cleanup/Makefile.in index 563023324..cbf1e44fe 100644 --- a/postfix/src/cleanup/Makefile.in +++ b/postfix/src/cleanup/Makefile.in @@ -4,13 +4,13 @@ SRCS = cleanup.c cleanup_out.c cleanup_envelope.c cleanup_message.c \ cleanup_map11.c cleanup_map1n.c cleanup_masquerade.c \ cleanup_out_recipient.c cleanup_init.c cleanup_api.c \ cleanup_addr.c cleanup_bounce.c cleanup_milter.c \ - cleanup_body_region.c + cleanup_body_edit.c cleanup_region.c OBJS = cleanup.o cleanup_out.o cleanup_envelope.o cleanup_message.o \ cleanup_extracted.o cleanup_state.o cleanup_rewrite.o \ cleanup_map11.o cleanup_map1n.o cleanup_masquerade.o \ cleanup_out_recipient.o cleanup_init.o cleanup_api.o \ cleanup_addr.o cleanup_bounce.o cleanup_milter.o \ - cleanup_body_region.o + cleanup_body_edit.o cleanup_region.o HDRS = TESTSRC = DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE) @@ -61,7 +61,7 @@ cleanup_masquerade: cleanup_masquerade.o mv junk cleanup_masquerade.o CLEANUP_MILTER_OBJS = cleanup_state.o cleanup_out.o cleanup_addr.o \ - cleanup_out_recipient.o cleanup_body_region.o + cleanup_out_recipient.o cleanup_body_edit.o cleanup_region.o cleanup_milter: cleanup_milter.o $(CLEANUP_MILTER_OBJS) $(LIBS) mv cleanup_milter.o junk $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(CLEANUP_MILTER_OBJS) $(LIBS) $(SYSLIBS) @@ -74,7 +74,7 @@ milter_tests: cleanup_milter_test bug_tests \ cleanup_milter_test5 cleanup_milter_test6 cleanup_milter_test7 \ cleanup_milter_test8 cleanup_milter_test9 cleanup_milter_test10a \ cleanup_milter_test10b cleanup_milter_test10c cleanup_milter_test10d \ - cleanup_milter_test10e + cleanup_milter_test10e cleanup_milter_test11 root_tests: @@ -93,6 +93,9 @@ cleanup_masquerade_test: cleanup_masquerade cleanup_masq.ref bug_tests: bug1_test bug2_test +../postcat/postcat: + cd ../postcat; make + bug1_test: cleanup_milter bug1.file bug1.in bug1.ref bug1.text.ref \ ../postcat/postcat cp bug1.file bug1.file.tmp @@ -118,7 +121,7 @@ bug2_test: cleanup_milter bug2.file bug2.in bug2.ref bug2.text.ref \ # Test queue file editing routines. cleanup_milter_test: cleanup_milter test-queue-file cleanup_milter.in1 \ - cleanup_milter.ref1 test-queue-file ../postcat/postcat + cleanup_milter.ref1 ../postcat/postcat cp test-queue-file test-queue-file.tmp chmod u+w test-queue-file.tmp ./cleanup_milter /dev/null >cleanup_milter.tmp + diff cleanup_milter.ref11 cleanup_milter.tmp + rm -f test-queue-file11.tmp cleanup_milter.tmp + depend: $(MAKES) (sed '1,/^# do not edit/!d' Makefile.in; \ set -e; for i in [a-z][a-z0-9]*.c; do \ @@ -391,33 +403,33 @@ cleanup_api.o: ../../include/vstream.h cleanup_api.o: ../../include/vstring.h cleanup_api.o: cleanup.h cleanup_api.o: cleanup_api.c -cleanup_body_region.o: ../../include/argv.h -cleanup_body_region.o: ../../include/been_here.h -cleanup_body_region.o: ../../include/cleanup_user.h -cleanup_body_region.o: ../../include/dict.h -cleanup_body_region.o: ../../include/header_opts.h -cleanup_body_region.o: ../../include/htable.h -cleanup_body_region.o: ../../include/mail_conf.h -cleanup_body_region.o: ../../include/mail_stream.h -cleanup_body_region.o: ../../include/maps.h -cleanup_body_region.o: ../../include/match_list.h -cleanup_body_region.o: ../../include/match_ops.h -cleanup_body_region.o: ../../include/milter.h -cleanup_body_region.o: ../../include/mime_state.h -cleanup_body_region.o: ../../include/msg.h -cleanup_body_region.o: ../../include/mymalloc.h -cleanup_body_region.o: ../../include/nvtable.h -cleanup_body_region.o: ../../include/rec_type.h -cleanup_body_region.o: ../../include/record.h -cleanup_body_region.o: ../../include/resolve_clnt.h -cleanup_body_region.o: ../../include/string_list.h -cleanup_body_region.o: ../../include/sys_defs.h -cleanup_body_region.o: ../../include/tok822.h -cleanup_body_region.o: ../../include/vbuf.h -cleanup_body_region.o: ../../include/vstream.h -cleanup_body_region.o: ../../include/vstring.h -cleanup_body_region.o: cleanup.h -cleanup_body_region.o: cleanup_body_region.c +cleanup_body_edit.o: ../../include/argv.h +cleanup_body_edit.o: ../../include/been_here.h +cleanup_body_edit.o: ../../include/cleanup_user.h +cleanup_body_edit.o: ../../include/dict.h +cleanup_body_edit.o: ../../include/header_opts.h +cleanup_body_edit.o: ../../include/htable.h +cleanup_body_edit.o: ../../include/mail_conf.h +cleanup_body_edit.o: ../../include/mail_stream.h +cleanup_body_edit.o: ../../include/maps.h +cleanup_body_edit.o: ../../include/match_list.h +cleanup_body_edit.o: ../../include/match_ops.h +cleanup_body_edit.o: ../../include/milter.h +cleanup_body_edit.o: ../../include/mime_state.h +cleanup_body_edit.o: ../../include/msg.h +cleanup_body_edit.o: ../../include/mymalloc.h +cleanup_body_edit.o: ../../include/nvtable.h +cleanup_body_edit.o: ../../include/rec_type.h +cleanup_body_edit.o: ../../include/record.h +cleanup_body_edit.o: ../../include/resolve_clnt.h +cleanup_body_edit.o: ../../include/string_list.h +cleanup_body_edit.o: ../../include/sys_defs.h +cleanup_body_edit.o: ../../include/tok822.h +cleanup_body_edit.o: ../../include/vbuf.h +cleanup_body_edit.o: ../../include/vstream.h +cleanup_body_edit.o: ../../include/vstring.h +cleanup_body_edit.o: cleanup.h +cleanup_body_edit.o: cleanup_body_edit.c cleanup_bounce.o: ../../include/argv.h cleanup_bounce.o: ../../include/attr.h cleanup_bounce.o: ../../include/been_here.h @@ -801,6 +813,31 @@ cleanup_out_recipient.o: ../../include/vstream.h cleanup_out_recipient.o: ../../include/vstring.h cleanup_out_recipient.o: cleanup.h cleanup_out_recipient.o: cleanup_out_recipient.c +cleanup_region.o: ../../include/argv.h +cleanup_region.o: ../../include/been_here.h +cleanup_region.o: ../../include/cleanup_user.h +cleanup_region.o: ../../include/dict.h +cleanup_region.o: ../../include/header_opts.h +cleanup_region.o: ../../include/htable.h +cleanup_region.o: ../../include/mail_conf.h +cleanup_region.o: ../../include/mail_stream.h +cleanup_region.o: ../../include/maps.h +cleanup_region.o: ../../include/match_list.h +cleanup_region.o: ../../include/match_ops.h +cleanup_region.o: ../../include/milter.h +cleanup_region.o: ../../include/mime_state.h +cleanup_region.o: ../../include/msg.h +cleanup_region.o: ../../include/mymalloc.h +cleanup_region.o: ../../include/nvtable.h +cleanup_region.o: ../../include/resolve_clnt.h +cleanup_region.o: ../../include/string_list.h +cleanup_region.o: ../../include/sys_defs.h +cleanup_region.o: ../../include/tok822.h +cleanup_region.o: ../../include/vbuf.h +cleanup_region.o: ../../include/vstream.h +cleanup_region.o: ../../include/vstring.h +cleanup_region.o: cleanup.h +cleanup_region.o: cleanup_region.c cleanup_rewrite.o: ../../include/argv.h cleanup_rewrite.o: ../../include/attr.h cleanup_rewrite.o: ../../include/been_here.h diff --git a/postfix/src/cleanup/cleanup.h b/postfix/src/cleanup/cleanup.h index e31301f37..c419f2472 100644 --- a/postfix/src/cleanup/cleanup.h +++ b/postfix/src/cleanup/cleanup.h @@ -69,6 +69,7 @@ typedef struct CLEANUP_STATE { BH_TABLE *dups; /* recipient dup filter */ void (*action) (struct CLEANUP_STATE *, int, const char *, ssize_t); off_t data_offset; /* start of message content */ + off_t body_offset; /* start of body content */ off_t xtra_offset; /* start of extra segment */ off_t cont_length; /* length including Milter edits */ off_t append_rcpt_pt_offset; /* append recipient here */ @@ -107,9 +108,9 @@ typedef struct CLEANUP_STATE { /* * Support for Milter body replacement requests. */ - struct CLEANUP_BODY_REGION *body_regions; - struct CLEANUP_BODY_REGION *curr_body_region; - off_t body_write_offs; /* body write position */ + struct CLEANUP_REGION *free_regions;/* unused regions */ + struct CLEANUP_REGION *body_regions;/* regions with body content */ + struct CLEANUP_REGION *curr_body_region; } CLEANUP_STATE; /* @@ -295,18 +296,25 @@ extern void cleanup_milter_emul_data(CLEANUP_STATE *, MILTERS *); && (s)->errs == 0 && ((s)->flags & CLEANUP_FLAG_DISCARD) == 0) /* - * cleanup_body_region.c + * cleanup_body_edit.c */ -typedef struct CLEANUP_BODY_REGION { +typedef struct CLEANUP_REGION { off_t start; /* start of region */ off_t len; /* length or zero (open-ended) */ - struct CLEANUP_BODY_REGION *next; -} CLEANUP_BODY_REGION; - -extern int cleanup_body_region_start(CLEANUP_STATE *); -extern int cleanup_body_region_write(CLEANUP_STATE *, int, VSTRING *); -extern int cleanup_body_region_finish(CLEANUP_STATE *); -extern void cleanup_body_region_free(CLEANUP_STATE *); + off_t write_offs; /* write offset */ + struct CLEANUP_REGION *next; /* linkage */ +} CLEANUP_REGION; + +extern void cleanup_region_init(CLEANUP_STATE *); +extern CLEANUP_REGION *cleanup_region_open(CLEANUP_STATE *, ssize_t); +extern void cleanup_region_close(CLEANUP_STATE *, CLEANUP_REGION *); +extern CLEANUP_REGION *cleanup_region_return(CLEANUP_STATE *, CLEANUP_REGION *); +extern void cleanup_region_done(CLEANUP_STATE *); + +extern int cleanup_body_edit_start(CLEANUP_STATE *); +extern int cleanup_body_edit_write(CLEANUP_STATE *, int, VSTRING *); +extern int cleanup_body_edit_finish(CLEANUP_STATE *); +extern void cleanup_body_edit_free(CLEANUP_STATE *); /* LICENSE /* .ad diff --git a/postfix/src/cleanup/cleanup_body_edit.c b/postfix/src/cleanup/cleanup_body_edit.c new file mode 100644 index 000000000..5219dcc98 --- /dev/null +++ b/postfix/src/cleanup/cleanup_body_edit.c @@ -0,0 +1,231 @@ +/*++ +/* NAME +/* cleanup_body_edit 3 +/* SUMMARY +/* edit body content +/* SYNOPSIS +/* #include "cleanup.h" +/* +/* int cleanup_body_edit_start(state) +/* CLEANUP_STATE *state; +/* +/* int cleanup_body_edit_write(state, type, buf) +/* CLEANUP_STATE *state; +/* int type; +/* VSTRING *buf; +/* +/* int cleanup_body_edit_finish(state) +/* CLEANUP_STATE *state; +/* +/* void cleanup_body_edit_free(state) +/* CLEANUP_STATE *state; +/* DESCRIPTION +/* This module maintains queue file regions with body content. +/* Regions are created on the fly, and can be reused multiple +/* times. This module must not be called until the queue file +/* is complete, and there must be no other read/write access +/* to the queue file between the cleanup_body_edit_start() and +/* cleanup_body_edit_finish() calls. +/* +/* cleanup_body_edit_start() performs initialization and sets +/* the queue file write pointer to the start of the first body +/* region. +/* +/* cleanup_body_edit_write() adds a queue file record to the +/* queue file. When the current body region fills up, some +/* unused region is reused, or a new region is created. +/* +/* cleanup_body_edit_finish() makes some final adjustments +/* after the last body content record is written. +/* +/* cleanup_body_edit_free() frees up memory that was allocated +/* by cleanup_body_edit_start() and cleanup_body_edit_write(). +/* +/* Arguments: +/* .IP state +/* Queue file and message processing state. This state is updated +/* as records are processed and as errors happen. +/* .IP type +/* Record type. +/* .IP buf +/* Record content. +/* LICENSE +/* .ad +/* .fi +/* The Secure Mailer license must be distributed with this software. +/* AUTHOR(S) +/* Wietse Venema +/* IBM T.J. Watson Research +/* P.O. Box 704 +/* Yorktown Heights, NY 10598, USA +/*--*/ + +/* System library. */ + +#include + +/* Utility library. */ + +#include +#include +#include +#include + +/* Global library. */ + +#include +#include + +/* Application-specific. */ + +#include + +#define LEN(s) VSTRING_LEN(s) + +static int cleanup_body_edit_ptr_rec_len; + +/* cleanup_body_edit_start - rewrite body region pool */ + +int cleanup_body_edit_start(CLEANUP_STATE *state) +{ + const char *myname = "cleanup_body_edit_start"; + CLEANUP_REGION *curr_rp; + + /* + * Calculate the payload size sans body. + */ + state->cont_length = state->body_offset - state->data_offset; + + /* + * One-time initialization. + */ + if (state->body_regions == 0) { + REC_SPACE_NEED(REC_TYPE_PTR_PAYL_SIZE, cleanup_body_edit_ptr_rec_len); + cleanup_region_init(state); + } + + /* + * Return all body regions to the free pool. + */ + cleanup_region_return(state, state->body_regions); + + /* + * Select the first region. XXX This will usally be the original body + * segment, but we must not count on that. Region assignments may change + * when header editing also uses queue file regions. XXX We don't really + * know if the first region will be large enough to hold the first body + * text record, but this problem is so rare that we will not complicate + * the code for it. If the first region is too small then we will simply + * waste it. + */ + curr_rp = state->curr_body_region = state->body_regions = + cleanup_region_open(state, cleanup_body_edit_ptr_rec_len); + + /* + * Link the first body region to the last message header. + */ + if (vstream_fseek(state->dst, state->append_hdr_pt_offset, SEEK_SET) < 0) { + msg_warn("%s: seek file %s: %m", myname, cleanup_path); + return (-1); + } + state->append_hdr_pt_target = curr_rp->start; + rec_fprintf(state->dst, REC_TYPE_PTR, REC_TYPE_PTR_FORMAT, + (long) state->append_hdr_pt_target); + + /* + * Move the file write pointer to the start of the current region. + */ + if (vstream_ftell(state->dst) != curr_rp->start + && vstream_fseek(state->dst, curr_rp->start, SEEK_SET) < 0) { + msg_warn("%s: seek file %s: %m", myname, cleanup_path); + return (-1); + } + return (0); +} + +/* cleanup_body_edit_write - add record to body region pool */ + +int cleanup_body_edit_write(CLEANUP_STATE *state, int rec_type, + VSTRING *buf) +{ + const char *myname = "cleanup_body_edit_write"; + CLEANUP_REGION *curr_rp = state->curr_body_region; + CLEANUP_REGION *next_rp; + off_t space_used; + ssize_t space_needed; + ssize_t rec_len; + + if (msg_verbose) + msg_info("%s: where %ld, buflen %ld region start %ld len %ld", + myname, (long) curr_rp->write_offs, (long) LEN(buf), + (long) curr_rp->start, (long) curr_rp->len); + + /* + * Switch to the next body region if we filled up the current one (we + * always append to an open-ended region). Besides space to write the + * specified record, we need to leave space for a final pointer record + * that will link this body region to the next region or to the content + * terminator record. + */ + if (curr_rp->len > 0) { + space_used = curr_rp->write_offs - curr_rp->start; + REC_SPACE_NEED(LEN(buf), rec_len); + space_needed = rec_len + cleanup_body_edit_ptr_rec_len; + if (space_needed > curr_rp->len - space_used) { + + /* + * Update the payload size. Connect the filled up body region to + * its successor. + */ + state->cont_length += space_used; + next_rp = cleanup_region_open(state, space_needed); + if (msg_verbose) + msg_info("%s: link %ld -> %ld", myname, + (long) curr_rp->write_offs, (long) next_rp->start); + rec_fprintf(state->dst, REC_TYPE_PTR, REC_TYPE_PTR_FORMAT, + (long) next_rp->start); + curr_rp->write_offs = vstream_ftell(state->dst); + cleanup_region_close(state, curr_rp); + curr_rp->next = next_rp; + + /* + * Select the new body region. + */ + state->curr_body_region = curr_rp = next_rp; + if (vstream_fseek(state->dst, curr_rp->start, SEEK_SET) < 0) { + msg_warn("%s: seek file %s: %m", myname, cleanup_path); + return (-1); + } + } + } + + /* + * Finally, output the queue file record. + */ + CLEANUP_OUT_BUF(state, REC_TYPE_NORM, buf); + curr_rp->write_offs = vstream_ftell(state->dst); + + return (0); +} + +/* cleanup_body_edit_finish - wrap up body region pool */ + +int cleanup_body_edit_finish(CLEANUP_STATE *state) +{ + CLEANUP_REGION *curr_rp = state->curr_body_region; + + /* + * Update the payload size. + */ + state->cont_length += curr_rp->write_offs - curr_rp->start; + + /* + * Link the last body region to the content terminator record. + */ + rec_fprintf(state->dst, REC_TYPE_PTR, REC_TYPE_PTR_FORMAT, + (long) state->xtra_offset); + curr_rp->write_offs = vstream_ftell(state->dst); + cleanup_region_close(state, curr_rp); + + return (CLEANUP_OUT_OK(state) ? 0 : -1); +} diff --git a/postfix/src/cleanup/cleanup_body_region.c b/postfix/src/cleanup/cleanup_body_region.c deleted file mode 100644 index 5c04d89f9..000000000 --- a/postfix/src/cleanup/cleanup_body_region.c +++ /dev/null @@ -1,266 +0,0 @@ -/*++ -/* NAME -/* cleanup_body_region 3 -/* SUMMARY -/* manage body content regions -/* SYNOPSIS -/* #include "cleanup.h" -/* -/* int cleanup_body_region_start(state) -/* CLEANUP_STATE *state; -/* -/* int cleanup_body_region_write(state, type, buf) -/* CLEANUP_STATE *state; -/* int type; -/* VSTRING *buf; -/* -/* int cleanup_body_region_finish(state) -/* CLEANUP_STATE *state; -/* -/* void cleanup_body_region_free(state) -/* CLEANUP_STATE *state; -/* DESCRIPTION -/* This module maintains queue file regions with body content. -/* Regions are created on the fly, and can be reused multiple -/* times. This module must not be called until the queue file -/* is complete. -/* -/* cleanup_body_region_start() performs initialization and -/* sets the queue file write pointer to the start of the -/* first body content segment. -/* -/* cleanup_body_region_write() adds a queue file record to the -/* current queue file. When the current queue file region fills -/* up, some other region is reused or a new one is created. -/* -/* cleanup_body_region_finish() makes some final adjustments -/* after the last body content record is written. -/* -/* cleanup_body_region_free() frees up memory that was allocated -/* by cleanup_body_region_start() and cleanup_body_region_write(). -/* -/* Arguments: -/* .IP state -/* Queue file and message processing state. This state is updated -/* as records are processed and as errors happen. -/* .IP type -/* Record type. -/* .IP buf -/* Record content. -/* BUGS -/* Currently, queue file region management is intertwined with -/* body content management. Eventually the two should be -/* decoupled, so that space freed up after body editing may -/* be reused for header updates and vice versa. -/* LICENSE -/* .ad -/* .fi -/* The Secure Mailer license must be distributed with this software. -/* AUTHOR(S) -/* Wietse Venema -/* IBM T.J. Watson Research -/* P.O. Box 704 -/* Yorktown Heights, NY 10598, USA -/*--*/ - -/* System library. */ - -#include - -/* Utility library. */ - -#include -#include -#include -#include - -/* Global library. */ - -#include -#include - -/* Application-specific. */ - -#include - -#define LEN(s) VSTRING_LEN(s) - -/* cleanup_body_region_alloc - create body content region */ - -static CLEANUP_BODY_REGION *cleanup_body_region_alloc(off_t start, off_t len) -{ - CLEANUP_BODY_REGION *rp; - - rp = (CLEANUP_BODY_REGION *) mymalloc(sizeof(*rp)); - rp->start = start; - rp->len = len; - rp->next = 0; - - return (rp); -} - -/* cleanup_body_region_free - destroy all body content regions */ - -void cleanup_body_region_free(CLEANUP_STATE *state) -{ - CLEANUP_BODY_REGION *rp; - CLEANUP_BODY_REGION *next; - - for (rp = state->body_regions; rp != 0; rp = next) { - next = rp->next; - myfree((char *) rp); - } -} - -/* cleanup_body_region_start - rewrite body buffer pool */ - -int cleanup_body_region_start(CLEANUP_STATE *state) -{ - const char *myname = "cleanup_body_region_write"; - - /* - * Calculate the payload size sans body. - */ - state->cont_length = state->append_hdr_pt_target - state->data_offset; - - /* - * Craft the first body region on the fly, from circumstantial evidence. - */ - if (state->body_regions == 0) - state->body_regions = - cleanup_body_region_alloc(state->append_hdr_pt_target, - state->xtra_offset - state->append_hdr_pt_target); - - /* - * Select the first region and initialize the write position. - */ - state->curr_body_region = state->body_regions; - state->body_write_offs = state->curr_body_region->start; - - /* - * Move the file write pointer to the start of the current region. - */ - if (vstream_fseek(state->dst, state->body_write_offs, SEEK_SET) < 0) { - msg_warn("%s: seek file %s: %m", myname, cleanup_path); - return (-1); - } - return (0); -} - -/* cleanup_body_region_write - add record to body buffer pool */ - -int cleanup_body_region_write(CLEANUP_STATE *state, int rec_type, - VSTRING *buf) -{ - const char *myname = "cleanup_body_region_write"; - CLEANUP_BODY_REGION *rp = state->curr_body_region; - off_t used; - ssize_t rec_len; - off_t start; - - if (msg_verbose) - msg_info("%s: where %ld, buflen %ld region start %ld len %ld", - myname, (long) state->body_write_offs, (long) LEN(buf), - (long) rp->start, (long) rp->len); - - /* - * Switch to the next body region if we filled up the current one (we - * always append to an open-ended region). Besides space to write the - * specified record, we need to leave space for a final pointer record - * that will link this body region to the next region or to the content - * terminator record. - */ - REC_SPACE_NEED(LEN(buf), rec_len); - while (rp->len > 0 && (used = state->body_write_offs - rp->start, - rec_len + REC_TYPE_PTR_SIZE > rp->len - used)) { - - /* - * Allocate a new body region if we filled up the last one. A newly - * allocated region sits at the end of the queue file, and therefore - * it starts as open ended. We freeze the region size later. - * - * Don't use fstat() to figure out where the queue file ends, in case - * file sizes have magic in them. Instead we seek to the end and then - * back to where we were. We're not switching body regions often, so - * this is not performance critical. - */ - if (rp->next == 0) { - if ((start = vstream_fseek(state->dst, (off_t) 0, SEEK_END)) < 0) { - msg_warn("%s: seek file %s: %m", myname, cleanup_path); - return (-1); - } - if (vstream_fseek(state->dst, state->body_write_offs, SEEK_SET) < 0) { - msg_warn("%s: seek file %s: %m", myname, cleanup_path); - return (-1); - } - rp->next = cleanup_body_region_alloc(start, 0); - } - - /* - * Update the payload size and select the new body region. - */ - state->cont_length += state->body_write_offs - rp->start; - state->curr_body_region = rp = rp->next; - - /* - * Connect the filled up body region to its successor. By design a - * region has always space for a final pointer record. - */ - if (msg_verbose) - msg_info("%s: link %ld -> %ld", myname, - (long) state->body_write_offs, (long) rp->start); - rec_fprintf(state->dst, REC_TYPE_PTR, REC_TYPE_PTR_FORMAT, - (long) rp->start); - if (vstream_fseek(state->dst, rp->start, SEEK_SET) < 0) { - msg_warn("%s: seek file %s: %m", myname, cleanup_path); - return (-1); - } - } - - /* - * Finally, output the queue file record. - */ - CLEANUP_OUT_BUF(state, REC_TYPE_NORM, buf); - state->body_write_offs = vstream_ftell(state->dst); - - return (0); -} - -/* cleanup_body_region_finish - wrap up body buffer pool */ - -int cleanup_body_region_finish(CLEANUP_STATE *state) -{ - const char *myname = "cleanup_body_region_finish"; - CLEANUP_BODY_REGION *rp; - - /* - * Link the last body region to the content terminator record. - */ - rec_fprintf(state->dst, REC_TYPE_PTR, REC_TYPE_PTR_FORMAT, - (long) state->xtra_offset); - state->body_write_offs = vstream_ftell(state->dst); - - /* - * Update the payload size. - */ - rp = state->curr_body_region; - state->cont_length += state->body_write_offs - rp->start; - - /* - * Freeze the size of the last region if it is still open ended. The next - * Milter application may append more header records, therefore we must - * not assume that this region can grow further. Nor can we truncate the - * queue file to the end of this region, as this region may be followed - * by headers that were appended by an earlier Milter application. - * - * XXX Eventually, split a partially-used region so that the remainder can - * be returned to a free pool and reused for header updates. - */ - if (rp->len == 0) - rp->len = state->body_write_offs - rp->start; - if (msg_verbose) - msg_info("%s: freeze start %ld len %ld", - myname, (long) rp->start, (long) rp->len); - - return (CLEANUP_OUT_OK(state) ? 0 : -1); -} diff --git a/postfix/src/cleanup/cleanup_extracted.c b/postfix/src/cleanup/cleanup_extracted.c index 5f02e2585..e3bf7e0ba 100644 --- a/postfix/src/cleanup/cleanup_extracted.c +++ b/postfix/src/cleanup/cleanup_extracted.c @@ -287,7 +287,6 @@ void cleanup_extracted_process(CLEANUP_STATE *state, int type, void cleanup_extracted_finish(CLEANUP_STATE *state) { - const char myname[] = "cleanup_extracted_finish"; /* * On the way out, add the optional automatic BCC recipient. diff --git a/postfix/src/cleanup/cleanup_message.c b/postfix/src/cleanup/cleanup_message.c index e777f455a..be6b2ed1c 100644 --- a/postfix/src/cleanup/cleanup_message.c +++ b/postfix/src/cleanup/cleanup_message.c @@ -705,6 +705,7 @@ static void cleanup_header_done_callback(void *context) cleanup_out_format(state, REC_TYPE_PTR, REC_TYPE_PTR_FORMAT, 0L); if ((state->append_hdr_pt_target = vstream_ftell(state->dst)) < 0) msg_fatal("%s: vstream_ftell %s: %m", myname, cleanup_path); + state->body_offset = state->append_hdr_pt_target; } } diff --git a/postfix/src/cleanup/cleanup_milter.c b/postfix/src/cleanup/cleanup_milter.c index 348b3b790..d3a9cb07a 100644 --- a/postfix/src/cleanup/cleanup_milter.c +++ b/postfix/src/cleanup/cleanup_milter.c @@ -603,7 +603,7 @@ static const char *cleanup_patch_header(CLEANUP_STATE *state, * pointer record. Requirement: the message headers (and body) always end * in a pointer record. */ - while (rec_type != REC_TYPE_PTR && avail_space < REC_TYPE_PTR_SIZE) { + while (rec_type != REC_TYPE_PTR && avail_space < REC_TYPE_PTR_PAYL_SIZE) { /* Read existing text or pointer record. */ if (vstream_fseek(state->dst, read_offset, SEEK_SET) < 0) { msg_warn("%s: seek file %s: %m", myname, cleanup_path); @@ -1266,17 +1266,17 @@ static const char *cleanup_repl_body(void *context, int cmd, VSTRING *buf) */ switch (cmd) { case MILTER_BODY_LINE: - if (cleanup_body_region_write(state, REC_TYPE_NORM, buf) < 0) + if (cleanup_body_edit_write(state, REC_TYPE_NORM, buf) < 0) return (cleanup_milter_error(state, errno)); break; case MILTER_BODY_START: VSTRING_RESET(&empty); - if (cleanup_body_region_start(state) < 0 - || cleanup_body_region_write(state, REC_TYPE_NORM, &empty) < 0) + if (cleanup_body_edit_start(state) < 0 + || cleanup_body_edit_write(state, REC_TYPE_NORM, &empty) < 0) return (cleanup_milter_error(state, errno)); break; case MILTER_BODY_END: - if (cleanup_body_region_finish(state) < 0) + if (cleanup_body_edit_finish(state) < 0) return (cleanup_milter_error(state, errno)); break; default: diff --git a/postfix/src/cleanup/cleanup_milter.in11 b/postfix/src/cleanup/cleanup_milter.in11 new file mode 100644 index 000000000..8e69f7157 --- /dev/null +++ b/postfix/src/cleanup/cleanup_milter.in11 @@ -0,0 +1,10 @@ +# +# Replace a non-existent body by a non-empty one. +# +#verbose on +open test-queue-file11.tmp + +replbody loremipsum +replbody loremipsum + +close diff --git a/postfix/src/cleanup/cleanup_milter.ref10a b/postfix/src/cleanup/cleanup_milter.ref10a index 38c5c84fb..e7b4c1ea6 100644 --- a/postfix/src/cleanup/cleanup_milter.ref10a +++ b/postfix/src/cleanup/cleanup_milter.ref10a @@ -14,7 +14,7 @@ 346 regular_text: Message-Id: <20060725192735.5EC2D29013F@hades.porcupine.org> 408 regular_text: Date: Tue, 25 Jul 2006 15:27:19 -0400 (EDT) 453 regular_text: Subject: hey! - 468 pointer_record: 0 + 468 pointer_record: 485 485 regular_text: 487 pointer_record: 552 552 regular_text: Sed ut perspiciatis unde omnis iste natus error sit voluptatem diff --git a/postfix/src/cleanup/cleanup_milter.ref10b b/postfix/src/cleanup/cleanup_milter.ref10b index 38c5c84fb..e7b4c1ea6 100644 --- a/postfix/src/cleanup/cleanup_milter.ref10b +++ b/postfix/src/cleanup/cleanup_milter.ref10b @@ -14,7 +14,7 @@ 346 regular_text: Message-Id: <20060725192735.5EC2D29013F@hades.porcupine.org> 408 regular_text: Date: Tue, 25 Jul 2006 15:27:19 -0400 (EDT) 453 regular_text: Subject: hey! - 468 pointer_record: 0 + 468 pointer_record: 485 485 regular_text: 487 pointer_record: 552 552 regular_text: Sed ut perspiciatis unde omnis iste natus error sit voluptatem diff --git a/postfix/src/cleanup/cleanup_milter.ref10c b/postfix/src/cleanup/cleanup_milter.ref10c index 78704f2fc..4b4ce6659 100644 --- a/postfix/src/cleanup/cleanup_milter.ref10c +++ b/postfix/src/cleanup/cleanup_milter.ref10c @@ -14,7 +14,7 @@ 346 regular_text: Message-Id: <20060725192735.5EC2D29013F@hades.porcupine.org> 408 regular_text: Date: Tue, 25 Jul 2006 15:27:19 -0400 (EDT) 453 regular_text: Subject: hey! - 468 pointer_record: 0 + 468 pointer_record: 485 485 regular_text: 487 pointer_record: 552 552 regular_text: Sed ut perspiciatis unde omnis iste natus error sit voluptatem diff --git a/postfix/src/cleanup/cleanup_milter.ref10d b/postfix/src/cleanup/cleanup_milter.ref10d index 38c5c84fb..e7b4c1ea6 100644 --- a/postfix/src/cleanup/cleanup_milter.ref10d +++ b/postfix/src/cleanup/cleanup_milter.ref10d @@ -14,7 +14,7 @@ 346 regular_text: Message-Id: <20060725192735.5EC2D29013F@hades.porcupine.org> 408 regular_text: Date: Tue, 25 Jul 2006 15:27:19 -0400 (EDT) 453 regular_text: Subject: hey! - 468 pointer_record: 0 + 468 pointer_record: 485 485 regular_text: 487 pointer_record: 552 552 regular_text: Sed ut perspiciatis unde omnis iste natus error sit voluptatem diff --git a/postfix/src/cleanup/cleanup_milter.ref11 b/postfix/src/cleanup/cleanup_milter.ref11 new file mode 100644 index 000000000..7eba2f3ce --- /dev/null +++ b/postfix/src/cleanup/cleanup_milter.ref11 @@ -0,0 +1,60 @@ +*** ENVELOPE RECORDS test-queue-file11.tmp *** + 0 message_size: 358 480 1 0 358 + 81 message_arrival_time: Thu Jan 18 15:15:42 2007 + 100 create_time: Thu Jan 18 15:15:48 2007 + 124 named_attribute: rewrite_context=local + 147 sender: + 149 named_attribute: log_client_name=localhost + 176 named_attribute: log_client_address=127.0.0.1 + 206 named_attribute: log_message_origin=localhost[127.0.0.1] + 247 named_attribute: log_protocol_name=SMTP + 271 named_attribute: client_name=localhost + 294 named_attribute: reverse_client_name=localhost + 325 named_attribute: client_address=127.0.0.1 + 351 named_attribute: client_address_type=2 + 374 named_attribute: dsn_orig_rcpt=rfc822;wietse@localhost + 413 original_recipient: wietse@localhost + 431 recipient: wietse@localhost.example.com + 461 pointer_record: 0 + 478 *** MESSAGE CONTENTS test-queue-file11.tmp *** + 480 regular_text: Received: from localhost (localhost [127.0.0.1]) + 530 regular_text: by foo.example.com (Postfix) with SMTP id 2ADF9290403 + 586 regular_text: for ; Thu, 18 Jan 2007 15:15:42 -0500 (EST) + 650 regular_text: Message-Id: <20070118201548.2ADF9290403@foo.example.com> + 708 regular_text: Date: Thu, 18 Jan 2007 15:15:42 -0500 (EST) + 753 regular_text: From: MAILER-DAEMON + 774 regular_text: To: undisclosed-recipients:; + 804 pointer_record: 821 + 821 pointer_record: 842 + 842 regular_text: + 844 regular_text: Sed ut perspiciatis unde omnis iste natus error sit voluptatem + 909 regular_text: accusantium doloremque laudantium, totam rem aperiam, eaque ipsa + 976 regular_text: quae ab illo inventore veritatis et quasi architecto beatae vitae + 1044 regular_text: dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit + 1113 regular_text: aspernatur aut odit aut fugit, sed quia consequuntur magni dolores + 1182 regular_text: eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam + 1248 regular_text: est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci + 1316 regular_text: velit, sed quia non numquam eius modi tempora incidunt ut labore + 1383 regular_text: et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima + 1448 regular_text: veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, + 1522 regular_text: nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure + 1591 regular_text: reprehenderit qui in ea voluptate velit esse quam nihil molestiae + 1659 regular_text: consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla + 1726 regular_text: pariatur? + 1738 regular_text: + 1741 regular_text: At vero eos et accusamus et iusto odio dignissimos ducimus qui + 1806 regular_text: blanditiis praesentium voluptatum deleniti atque corrupti quos + 1871 regular_text: dolores et quas molestias excepturi sint occaecati cupiditate non + 1939 regular_text: provident, similique sunt in culpa qui officia deserunt mollitia + 2006 regular_text: animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis + 2077 regular_text: est et expedita distinctio. Nam libero tempore, cum soluta nobis + 2144 regular_text: est eligendi optio cumque nihil impedit quo minus id quod maxime + 2211 regular_text: placeat facere possimus, omnis voluptas assumenda est, omnis dolor + 2280 regular_text: repellendus. Temporibus autem quibusdam et aut officiis debitis aut + 2350 regular_text: rerum necessitatibus saepe eveniet ut et voluptates repudiandae + 2416 regular_text: sint et molestiae non recusandae. Itaque earum rerum hic tenetur a + 2485 regular_text: sapiente delectus, ut aut reiciendis voluptatibus maiores alias + 2551 regular_text: consequatur aut perferendis doloribus asperiores repellat. + 2612 pointer_record: 838 + 838 *** HEADER EXTRACTED test-queue-file11.tmp *** + 840 *** MESSAGE FILE END test-queue-file11.tmp *** diff --git a/postfix/src/cleanup/cleanup_region.c b/postfix/src/cleanup/cleanup_region.c new file mode 100644 index 000000000..78479d47b --- /dev/null +++ b/postfix/src/cleanup/cleanup_region.c @@ -0,0 +1,231 @@ +/*++ +/* NAME +/* cleanup_region 3 +/* SUMMARY +/* queue file region manager +/* SYNOPSIS +/* #include "cleanup.h" +/* +/* void cleanup_region_init(state) +/* CLEANUP_STATE *state; +/* +/* CLEANUP_REGION *cleanup_region_open(state, space_needed) +/* CLEANUP_STATE *state; +/* ssize_t space_needed; +/* +/* int cleanup_region_close(state, rp) +/* CLEANUP_STATE *state; +/* CLEANUP_REGION *rp; +/* +/* CLEANUP_REGION *cleanup_region_return(state, rp) +/* CLEANUP_STATE *state; +/* CLEANUP_REGION *rp; +/* +/* void cleanup_region_done(state) +/* CLEANUP_STATE *state; +/* DESCRIPTION +/* This module maintains queue file regions. Regions are created +/* on-the-fly and can be reused multiple times. Each region +/* structure consists of a file offset, a length (0 for an +/* open-ended region at the end of the file), a write offset +/* (maintained by the caller), and list linkage. Region +/* boundaries are not enforced by this module. It is up to the +/* caller to ensure that they stay within bounds. +/* +/* cleanup_region_init() performs mandatory initialization and +/* overlays an initial region structure over an already existing +/* queue file. This function must not be called before the +/* queue file is complete. +/* +/* cleanup_region_open() opens an existing region or creates +/* a new region that can accomodate at least the specified +/* amount of space. A new region is an open-ended region at +/* the end of the file; it must be closed (see next) before +/* unrelated data can be appended to the same file. +/* +/* cleanup_region_close() indicates that a region will not be +/* updated further. With an open-ended region, the region's +/* end is frozen just before the caller-maintained write offset. +/* With a close-ended region, unused space (beginning at the +/* caller-maintained write offset) may be returned to the free +/* pool. +/* +/* cleanup_region_return() returns a list of regions to the +/* free pool, and returns a null pointer. To avoid fragmentation, +/* adjacent free regions may be coalesced together. +/* +/* cleanup_region_done() destroys all in-memory information +/* that was allocated for administering queue file regions. +/* +/* Arguments: +/* .IP state +/* Queue file and message processing state. This state is +/* updated as records are processed and as errors happen. +/* .IP space_needed +/* The minimum region size needed. +/* LICENSE +/* .ad +/* .fi +/* The Secure Mailer license must be distributed with this software. +/* AUTHOR(S) +/* Wietse Venema +/* IBM T.J. Watson Research +/* P.O. Box 704 +/* Yorktown Heights, NY 10598, USA +/*--*/ + +/* System library. */ + +#include +#include + +/* Utility library. */ + +#include +#include + +/* Application-specific. */ + +#include + +/* cleanup_region_alloc - create queue file region */ + +static CLEANUP_REGION *cleanup_region_alloc(off_t start, off_t len) +{ + CLEANUP_REGION *rp; + + rp = (CLEANUP_REGION *) mymalloc(sizeof(*rp)); + rp->write_offs = rp->start = start; + rp->len = len; + rp->next = 0; + + return (rp); +} + +/* cleanup_region_free - destroy region list */ + +static CLEANUP_REGION *cleanup_region_free(CLEANUP_REGION *regions) +{ + CLEANUP_REGION *rp; + CLEANUP_REGION *next; + + for (rp = regions; rp != 0; rp = next) { + next = rp->next; + myfree((char *) rp); + } + return (0); +} + +/* cleanup_region_init - create initial region overlay */ + +void cleanup_region_init(CLEANUP_STATE *state) +{ + const char *myname = "cleanup_region_init"; + + /* + * Sanity check. + */ + if (state->free_regions != 0 || state->body_regions != 0) + msg_panic("%s: repeated call", myname); + + /* + * Craft the first regions on the fly, from circumstantial evidence. + */ + state->body_regions = + cleanup_region_alloc(state->append_hdr_pt_target, + state->xtra_offset - state->append_hdr_pt_target); + if (msg_verbose) + msg_info("%s: body start %ld len %ld", + myname, (long) state->body_regions->start, (long) state->body_regions->len); +} + +/* cleanup_region_open - open existing region or create new region */ + +CLEANUP_REGION *cleanup_region_open(CLEANUP_STATE *state, ssize_t len) +{ + const char *myname = "cleanup_region_open"; + CLEANUP_REGION **rpp; + CLEANUP_REGION *rp; + struct stat st; + + /* + * Find the first region that is large enough, or create a new region. + */ + for (rpp = &state->free_regions; /* see below */ ; rpp = &(rp->next)) { + + /* + * Create an open-ended region at the end of the queue file. We + * freeze the region size after we stop writing to it. XXX Assume + * that fstat() returns a file size that is never less than the file + * append offset. It is not a problem if fstat() returns a larger + * result; we would just waste some space. + */ + if ((rp = *rpp) == 0) { + if (fstat(vstream_fileno(state->dst), &st) < 0) + msg_fatal("%s: fstat file %s: %m", myname, cleanup_path); + rp = cleanup_region_alloc(st.st_size, 0); + break; + } + + /* + * Reuse an existing region. + */ + if (rp->len >= len) { + (*rpp) = rp->next; + rp->next = 0; + rp->write_offs = rp->start; + break; + } + + /* + * Skip a too small region. + */ + if (msg_verbose) + msg_info("%s: skip start %ld len %ld < %ld", + myname, (long) rp->start, (long) rp->len, (long) len); + } + if (msg_verbose) + msg_info("%s: done start %ld len %ld", + myname, (long) rp->start, (long) rp->len); + return (rp); +} + +/* cleanup_region_close - freeze queue file region size */ + +void cleanup_region_close(CLEANUP_STATE *unused_state, CLEANUP_REGION *rp) +{ + const char *myname = "cleanup_region_close"; + + /* + * If this region is still open ended, freeze the size. If this region is + * closed, some future version of this routine may shrink the size and + * return the unused portion to the free pool. + */ + if (rp->len == 0) + rp->len = rp->write_offs - rp->start; + if (msg_verbose) + msg_info("%s: freeze start %ld len %ld", + myname, (long) rp->start, (long) rp->len); +} + +/* cleanup_region_return - return region list to free pool */ + +CLEANUP_REGION *cleanup_region_return(CLEANUP_STATE *state, CLEANUP_REGION *rp) +{ + CLEANUP_REGION **rpp; + + for (rpp = &state->free_regions; (*rpp) != 0; rpp = &(*rpp)->next) + /* void */ ; + *rpp = rp; + return (0); +} + +/* cleanup_region_done - destroy region metadata */ + +void cleanup_region_done(CLEANUP_STATE *state) +{ + if (state->free_regions != 0) + state->free_regions = cleanup_region_free(state->free_regions); + if (state->body_regions != 0) + state->body_regions = cleanup_region_free(state->body_regions); +} diff --git a/postfix/src/cleanup/cleanup_state.c b/postfix/src/cleanup/cleanup_state.c index e07bd2ace..a69f9f7aa 100644 --- a/postfix/src/cleanup/cleanup_state.c +++ b/postfix/src/cleanup/cleanup_state.c @@ -88,6 +88,7 @@ CLEANUP_STATE *cleanup_state_alloc(VSTREAM *src) state->dups = been_here_init(var_dup_filter_limit, BH_FLAG_FOLD); state->action = cleanup_envelope; state->data_offset = -1; + state->body_offset = -1; state->xtra_offset = -1; state->cont_length = 0; state->append_rcpt_pt_offset = -1; @@ -116,7 +117,7 @@ CLEANUP_STATE *cleanup_state_alloc(VSTREAM *src) state->client_port = 0; state->milter_ext_from = 0; state->milter_ext_rcpt = 0; - state->body_regions = state->curr_body_region = 0; + state->free_regions = state->body_regions = state->curr_body_region = 0; return (state); } @@ -167,7 +168,6 @@ void cleanup_state_free(CLEANUP_STATE *state) vstring_free(state->milter_ext_from); if (state->milter_ext_rcpt) vstring_free(state->milter_ext_rcpt); - if (state->body_regions) - cleanup_body_region_free(state); + cleanup_region_done(state); myfree((char *) state); } diff --git a/postfix/src/cleanup/test-queue-file11 b/postfix/src/cleanup/test-queue-file11 new file mode 100644 index 000000000..440f31640 Binary files /dev/null and b/postfix/src/cleanup/test-queue-file11 differ diff --git a/postfix/src/global/domain_list.c b/postfix/src/global/domain_list.c index b5617a7aa..9535ac223 100644 --- a/postfix/src/global/domain_list.c +++ b/postfix/src/global/domain_list.c @@ -30,8 +30,8 @@ /* A host name matches a domain list when its name appears in the /* list of domain patterns, or when any of its parent domains appears /* in the list of domain patterns. The matching process is case -/* insensitive. In order to reverse the result, precede a non-file -/* name pattern with an exclamation point (!). +/* insensitive. In order to reverse the result, precede a +/* pattern with an exclamation point (!). /* /* domain_list_init() performs initializations. The first argument /* is the bit-wise OR of zero or more of the following: diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index acd961db0..1505cc4d9 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -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 "20070117" +#define MAIL_RELEASE_DATE "20070118" #define MAIL_VERSION_NUMBER "2.4" #ifdef SNAPSHOT diff --git a/postfix/src/global/namadr_list.c b/postfix/src/global/namadr_list.c index f74b8337a..883b64a8f 100644 --- a/postfix/src/global/namadr_list.c +++ b/postfix/src/global/namadr_list.c @@ -31,8 +31,8 @@ /* type:name table specification, table lookup is used /* instead. /* Patterns are separated by whitespace and/or commas. In -/* order to reverse the result, precede a non-file name -/* pattern with an exclamation point (!). +/* order to reverse the result, precede a pattern with an +/* exclamation point (!). /* /* A host matches a list when its name or address matches /* a pattern, or when any of its parent domains matches a diff --git a/postfix/src/global/namadr_list.in b/postfix/src/global/namadr_list.in index a19a45263..39103638a 100644 --- a/postfix/src/global/namadr_list.in +++ b/postfix/src/global/namadr_list.in @@ -15,3 +15,14 @@ ./namadr_list 168.100.189.2 dummy 168.100.189.3 ./namadr_list '[168.100.189.2]' dummy 168.100.189.2 ./namadr_list '[168.100.189.2]' dummy 168.100.189.3 +echo foo !bar baz >junk +./namadr_list !`pwd`/junk dummy 168.100.189.3 +./namadr_list !`pwd`/junk foo 168.100.189.3 +./namadr_list !`pwd`/junk bar 168.100.189.3 +rm -f junk +env foo=x ./namadr_list environ:junk foo 168.100.189.3 +env foo=x ./namadr_list environ:junk bar 168.100.189.3 +env foo=x ./namadr_list !environ:junk foo 168.100.189.3 +env foo=x ./namadr_list !environ:junk bar 168.100.189.3 +env foo=x ./namadr_list !!environ:junk foo 168.100.189.3 +env foo=x ./namadr_list !!environ:junk bar 168.100.189.3 diff --git a/postfix/src/global/namadr_list.ref b/postfix/src/global/namadr_list.ref index fd6d70233..5db5ce3d8 100644 --- a/postfix/src/global/namadr_list.ref +++ b/postfix/src/global/namadr_list.ref @@ -15,3 +15,12 @@ dummy/168.100.189.2: YES dummy/168.100.189.3: NO dummy/168.100.189.2: YES dummy/168.100.189.3: NO +dummy/168.100.189.3: NO +foo/168.100.189.3: NO +bar/168.100.189.3: YES +foo/168.100.189.3: YES +bar/168.100.189.3: NO +foo/168.100.189.3: NO +bar/168.100.189.3: NO +foo/168.100.189.3: YES +bar/168.100.189.3: NO diff --git a/postfix/src/global/rec_type.h b/postfix/src/global/rec_type.h index cd0873f9e..60aa64cc1 100644 --- a/postfix/src/global/rec_type.h +++ b/postfix/src/global/rec_type.h @@ -173,7 +173,7 @@ * See also: REC_TYPE_SIZE_FORMAT above. */ #define REC_TYPE_PTR_FORMAT "%15ld" -#define REC_TYPE_PTR_SIZE 15 +#define REC_TYPE_PTR_PAYL_SIZE 15 /* Payload only, excludes record header. */ /* * Programmatic interface. diff --git a/postfix/src/global/record.h b/postfix/src/global/record.h index a5e8b8ced..fdbddf453 100644 --- a/postfix/src/global/record.h +++ b/postfix/src/global/record.h @@ -54,7 +54,7 @@ extern int rec_goto(VSTREAM *, const char *); #define REC_SPACE_NEED(buflen, reclen) do { \ ssize_t _c, _l; \ - for (_c = 1, _l = (buflen); _l != 0; _l >>= 7U, _c++) \ + for (_c = 1, _l = (buflen); (_l >>= 7U) != 0; _c++) \ ; \ (reclen) = 1 + _c + (buflen); \ } while (0) diff --git a/postfix/src/global/string_list.c b/postfix/src/global/string_list.c index 42cbec009..bdb6fc4fb 100644 --- a/postfix/src/global/string_list.c +++ b/postfix/src/global/string_list.c @@ -28,8 +28,8 @@ /* /* A string matches a string list when it appears in the list of /* string patterns. The matching process is case insensitive. -/* In order to reverse the result, precede a non-file name pattern -/* with an exclamation point (!). +/* In order to reverse the result, precede a pattern with an +/* exclamation point (!). /* /* string_list_init() performs initializations. The flags argument /* is ignored; pattern_list specifies a list of string patterns. diff --git a/postfix/src/util/match_list.c b/postfix/src/util/match_list.c index efeebd939..0aee3cf2d 100644 --- a/postfix/src/util/match_list.c +++ b/postfix/src/util/match_list.c @@ -26,8 +26,7 @@ /* is either a string, a file name (in which case the contents /* of the file are substituted for the file name) or a type:name /* lookup table specification. In order to reverse the result of -/* a pattern match, precede a non-file name pattern with an -/* exclamation point (!). +/* a pattern match, precede a pattern with an exclamation point (!). /* /* match_list_init() performs initializations. The flags argument /* specifies the bit-wise OR of zero or more of the following: @@ -100,55 +99,51 @@ struct MATCH_LIST { /* match_list_parse - parse buffer, destroy buffer */ -static ARGV *match_list_parse(ARGV *list, char *string) +static ARGV *match_list_parse(ARGV *list, char *string, int match) { const char *myname = "match_list_parse"; - VSTRING *buf = 0; + VSTRING *buf = vstring_alloc(10); VSTREAM *fp; const char *delim = " ,\t\r\n"; char *bp = string; - char *pattern; - char *map_type_name; + char *start; + char *item; char *map_type_name_flags; /* - * XXX We do not support ! before /filename, because the file contents - * are expanded in-line. Fixing this requires separating the operator (!) - * from its operands (file content) so that the operator can apply to a - * group of operands. + * /filename contents are expanded in-line. To support !/filename we + * prepend the negation operator to each item from the file. */ - while ((pattern = mystrtok(&bp, delim)) != 0) { - if (*pattern == '/') { /* /file/name */ - if (buf == 0) - buf = vstring_alloc(10); - if ((fp = vstream_fopen(pattern, O_RDONLY, 0)) == 0) - msg_fatal("%s: open file %s: %m", myname, pattern); + while ((start = mystrtok(&bp, delim)) != 0) { + for (item = start; *item == '!'; item++) + match = !match; + if (*item == 0) + msg_fatal("%s: no pattern after '!'", myname); + if (*item == '/') { /* /file/name */ + if ((fp = vstream_fopen(item, O_RDONLY, 0)) == 0) + msg_fatal("%s: open file %s: %m", myname, item); while (vstring_fgets(buf, fp)) if (vstring_str(buf)[0] != '#') - list = match_list_parse(list, vstring_str(buf)); + list = match_list_parse(list, vstring_str(buf), match); if (vstream_fclose(fp)) - msg_fatal("%s: read file %s: %m", myname, pattern); - } else if (MATCH_DICTIONARY(pattern)) { /* type:table */ - if (buf == 0) - buf = vstring_alloc(10); + msg_fatal("%s: read file %s: %m", myname, item); + } else if (MATCH_DICTIONARY(item)) { /* type:table */ #define OPEN_FLAGS O_RDONLY #define DICT_FLAGS (DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX) #define STR(x) vstring_str(x) - for (map_type_name = pattern; *map_type_name == '!'; map_type_name++) - /* void */ ; - vstring_sprintf(buf, "%s(%o,%s)", pattern, OPEN_FLAGS, - dict_flags_str(DICT_FLAGS)); - map_type_name_flags = STR(buf) + (map_type_name - pattern); + vstring_sprintf(buf, "%s%s(%o,%s)", match ? "" : "!", + item, OPEN_FLAGS, dict_flags_str(DICT_FLAGS)); + map_type_name_flags = STR(buf) + (match == 0); if (dict_handle(map_type_name_flags) == 0) dict_register(map_type_name_flags, - dict_open(map_type_name, OPEN_FLAGS, DICT_FLAGS)); + dict_open(item, OPEN_FLAGS, DICT_FLAGS)); argv_add(list, STR(buf), (char *) 0); } else { /* other pattern */ - argv_add(list, pattern, (char *) 0); + argv_add(list, match ? item : + STR(vstring_sprintf(buf, "!%s", item)), (char *) 0); } } - if (buf) - vstring_free(buf); + vstring_free(buf); return (list); } @@ -176,8 +171,10 @@ MATCH_LIST *match_list_init(int flags, const char *patterns, int match_count,... list->match_func[i] = va_arg(ap, MATCH_LIST_FN); va_end(ap); +#define DO_MATCH 1 + saved_patterns = mystrdup(patterns); - list->patterns = match_list_parse(argv_alloc(1), saved_patterns); + list->patterns = match_list_parse(argv_alloc(1), saved_patterns, DO_MATCH); argv_terminate(list->patterns); myfree(saved_patterns); return (list);