]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.11-20131119
authorWietse Venema <wietse@porcupine.org>
Tue, 19 Nov 2013 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <postfix-users@dukhovni.org>
Wed, 20 Nov 2013 02:25:56 +0000 (21:25 -0500)
38 files changed:
postfix/HISTORY
postfix/html/ldap_table.5.html
postfix/html/memcache_table.5.html
postfix/html/mysql_table.5.html
postfix/html/pgsql_table.5.html
postfix/html/postconf.5.html
postfix/html/sqlite_table.5.html
postfix/man/man5/cidr_table.5
postfix/man/man5/ldap_table.5
postfix/man/man5/memcache_table.5
postfix/man/man5/mysql_table.5
postfix/man/man5/nisplus_table.5
postfix/man/man5/pcre_table.5
postfix/man/man5/pgsql_table.5
postfix/man/man5/postconf.5
postfix/man/man5/regexp_table.5
postfix/man/man5/sqlite_table.5
postfix/man/man5/tcp_table.5
postfix/proto/cidr_table
postfix/proto/ldap_table
postfix/proto/memcache_table
postfix/proto/mysql_table
postfix/proto/nisplus_table
postfix/proto/pcre_table
postfix/proto/pgsql_table
postfix/proto/regexp_table
postfix/proto/sqlite_table
postfix/proto/tcp_table
postfix/src/dns/dns.h
postfix/src/dns/dns_lookup.c
postfix/src/dns/test_dns_lookup.c
postfix/src/global/dict_memcache.c
postfix/src/global/mail_version.h
postfix/src/smtpstone/smtp-source.c
postfix/src/util/dict.h
postfix/src/util/dict_alloc.c
postfix/src/util/dict_lmdb.c
postfix/src/util/dict_open.c

index ca5a6f902b22206bcf9efb9d4c87246ab1420dd6..cda458ed70f120b55b049435c983c70ef87e8e4a 100644 (file)
@@ -19165,3 +19165,21 @@ Apologies for any names omitted.
 
        Cleanup: removed redundant sort operation. Viktor Dukhovni.
        File: tls/tls_dane.c.
+
+20131119
+
+       Bugfix (introduced: 20111211): the Postfix memcache client
+       did not propagate a persistent "open()" lock to the optional
+       backup database.  File: global/dict_memcache.c.
+
+       Feature: a Postfix LMDB database can now be used as shared
+       cache. Until now only the Postfix memcache database could
+       be used in this manner. This is implemented by allowing a
+       database to downgrade the permanent DICT_FLAG_OPEN_LOCK
+       method to the temporary DICT_FLAG_LOCK method. Files:
+       util/dict.h, util/dict_alloc.c, util/dict_open.c,
+       util/dict_lmdb.c.
+
+       Internal: DNS client support to report reply RCODE information,
+       in addition to the simplified DNS_NOTFOUND, DNS_RETRY etc.
+       Files: dns/dns.h. dns/dns_lookup.c, dns/test_dns_lookup.c.
index dcb3a9ee7d4fdeb6c621e8a03c8cf7b330793af9..423b4fa457cc7e90ff40f63520a772f96b785443 100644 (file)
@@ -10,9 +10,9 @@ LDAP_TABLE(5)                                                    LDAP_TABLE(5)
        ldap_table - Postfix LDAP client configuration
 
 <b>SYNOPSIS</b>
-       <b>postmap -q "<i></b>string</i><b>" <a href="ldap_table.5.html">ldap</a>:/etc/postfix/filename</b>
+       <b>postmap -q "</b><i>string</i><b>" <a href="ldap_table.5.html">ldap</a>:/etc/postfix/</b><i>filename</i>
 
-       <b>postmap -q - <a href="ldap_table.5.html">ldap</a>:/etc/postfix/<i></b>filename</i> &lt;<i>inputfile</i>
+       <b>postmap -q - <a href="ldap_table.5.html">ldap</a>:/etc/postfix/</b><i>filename</i> &lt;<i>inputfile</i>
 
 <b>DESCRIPTION</b>
        The  Postfix  mail system uses optional tables for address
index ef3ac47bff798b755b132d645437c9049a20f35a..e8b3536f39d6ba56675feb992764a08c2c71b006 100644 (file)
@@ -10,7 +10,7 @@ MEMCACHE_TABLE(5)                                            MEMCACHE_TABLE(5)
        memcache_table - Postfix memcache client configuration
 
 <b>SYNOPSIS</b>
-       <b>postmap -q "</b><i>string</i><b>" <a href="memcache_table.5.html">memcache</a>:/etc/postfix/filename</b>
+       <b>postmap -q "</b><i>string</i><b>" <a href="memcache_table.5.html">memcache</a>:/etc/postfix/</b><i>filename</i>
 
        <b>postmap -q - <a href="memcache_table.5.html">memcache</a>:/etc/postfix/</b><i>filename</i> &lt;<i>inputfile</i>
 
index c40b1723c1d5cbcd21ab52386ac13cb5231cfb16..a5989351458bfe818647d5b69035bdf13922b5c1 100644 (file)
@@ -10,7 +10,7 @@ MYSQL_TABLE(5)                                                  MYSQL_TABLE(5)
        mysql_table - Postfix MySQL client configuration
 
 <b>SYNOPSIS</b>
-       <b>postmap -q "</b><i>string</i><b>" <a href="mysql_table.5.html">mysql</a>:/etc/postfix/filename</b>
+       <b>postmap -q "</b><i>string</i><b>" <a href="mysql_table.5.html">mysql</a>:/etc/postfix/</b><i>filename</i>
 
        <b>postmap -q - <a href="mysql_table.5.html">mysql</a>:/etc/postfix/</b><i>filename</i> &lt;<i>inputfile</i>
 
index 14c337a0d790864506695585c140d4f0abb46cbc..a378ef7ed7d47bf58ecee2908fe467ec0b9ff6d2 100644 (file)
@@ -10,7 +10,7 @@ PGSQL_TABLE(5)                                                  PGSQL_TABLE(5)
        pgsql_table - Postfix PostgreSQL client configuration
 
 <b>SYNOPSIS</b>
-       <b>postmap -q "</b><i>string</i><b>" <a href="pgsql_table.5.html">pgsql</a>:/etc/postfix/filename</b>
+       <b>postmap -q "</b><i>string</i><b>" <a href="pgsql_table.5.html">pgsql</a>:/etc/postfix/</b><i>filename</i>
 
        <b>postmap -q - <a href="pgsql_table.5.html">pgsql</a>:/etc/postfix/</b><i>filename</i> &lt;<i>inputfile</i>
 
index c1523c001538b62e46e1febde2e62d0eeae747c5..7f646f1de429a54d6e36f47cb80f294530cc95a7 100644 (file)
@@ -8571,7 +8571,8 @@ address, and one address extension per email address.  </p>
 extension by the first character that matches the <a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a>
 set. </p>
 
-<p> When used in <a href="postconf.5.html#forward_path">forward_path</a>, ${<a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a>} is replaced
+<p> When used in <a href="postconf.5.html#command_execution_directory">command_execution_directory</a>, <a href="postconf.5.html#forward_path">forward_path</a>, or
+<a href="postconf.5.html#luser_relay">luser_relay</a>, ${<a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a>} is replaced
 with the recipient delimiter that was found in the recipient email
 address (Postfix 2.11 and later), or it is replaced with the <a href="postconf.5.html">main.cf</a>
 <a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> parameter value (Postfix 2.10 and earlier).
index acf9f90a4a8c80e7eddf5aa4b224ffcfd2c40c57..80302fdae11d9e3657762d6264c170fed20bc2d0 100644 (file)
@@ -10,7 +10,7 @@ SQLITE_TABLE(5)                                                SQLITE_TABLE(5)
        sqlite_table - Postfix SQLite configuration
 
 <b>SYNOPSIS</b>
-       <b>postmap -q "</b><i>string</i><b>" <a href="sqlite_table.5.html">sqlite</a>:/etc/postfix/filename</b>
+       <b>postmap -q "</b><i>string</i><b>" <a href="sqlite_table.5.html">sqlite</a>:/etc/postfix/</b><i>filename</i>
 
        <b>postmap -q - <a href="sqlite_table.5.html">sqlite</a>:/etc/postfix/</b><i>filename</i> &lt;<i>inputfile</i>
 
index 5619b2b09da71132d47f13217ebefbd3de57bed1..1c436fdf1cb5317ed1134eec800ca40dbd7fa497 100644 (file)
@@ -10,7 +10,7 @@ format of Postfix CIDR tables
 .nf
 \fBpostmap -q "\fIstring\fB" cidr:/etc/postfix/\fIfilename\fR
 
-\fBpostmap -q - cidr:/etc/postfix/\fIfilename\fR <\fIinputfile\fR
+\fBpostmap -q - cidr:/etc/postfix/\fIfilename\fB <\fIinputfile\fR
 .SH DESCRIPTION
 .ad
 .fi
index 67fa8244ee4ebf01c2529f117747f1a314a05320..9a68f7501daf4c352c0319b74cd0769c6f54e34b 100644 (file)
@@ -8,9 +8,9 @@ Postfix LDAP client configuration
 .SH "SYNOPSIS"
 .na
 .nf
-\fBpostmap -q "\fIstring\fB" ldap:/etc/postfix/filename\fR
+\fBpostmap -q "\fIstring\fB" ldap:/etc/postfix/\fIfilename\fR
 
-\fBpostmap -q - ldap:/etc/postfix/\fIfilename\fR <\fIinputfile\fR
+\fBpostmap -q - ldap:/etc/postfix/\fIfilename\fB <\fIinputfile\fR
 .SH DESCRIPTION
 .ad
 .fi
index a672cedf064d67633fedd546e62d9c8f5465fac8..5b355c306358fa8f751eb6a9a07837ee89cdafcc 100644 (file)
@@ -8,9 +8,9 @@ Postfix memcache client configuration
 .SH "SYNOPSIS"
 .na
 .nf
-\fBpostmap -q "\fIstring\fB" memcache:/etc/postfix/filename\fR
+\fBpostmap -q "\fIstring\fB" memcache:/etc/postfix/\fIfilename\fR
 
-\fBpostmap -q - memcache:/etc/postfix/\fIfilename\fR <\fIinputfile\fR
+\fBpostmap -q - memcache:/etc/postfix/\fIfilename\fB <\fIinputfile\fR
 .SH DESCRIPTION
 .ad
 .fi
index dd3ec9b4c107a5de52292dfcc97ac004e257dfb4..0b332e48681cd9c37155d938b83625d652773daf 100644 (file)
@@ -8,9 +8,9 @@ Postfix MySQL client configuration
 .SH "SYNOPSIS"
 .na
 .nf
-\fBpostmap -q "\fIstring\fB" mysql:/etc/postfix/filename\fR
+\fBpostmap -q "\fIstring\fB" mysql:/etc/postfix/\fIfilename\fR
 
-\fBpostmap -q - mysql:/etc/postfix/\fIfilename\fR <\fIinputfile\fR
+\fBpostmap -q - mysql:/etc/postfix/\fIfilename\fB <\fIinputfile\fR
 .SH DESCRIPTION
 .ad
 .fi
index d4dd670a1971426919924032ce7001a2481974bc..65ae659b2a794621e9bc605f53d0b6f7d7c2bd5b 100644 (file)
@@ -10,7 +10,7 @@ Postfix NIS+ client
 .nf
 \fBpostmap -q "\fIstring\fB" "nisplus:[\fIname\fB=%s];\fIname.name.\fB"\fR
 
-\fBpostmap -q - "nisplus:[\fIname\fB=%s];\fIname.name.\fB"\fR <\fIinputfile\fR
+\fBpostmap -q - "nisplus:[\fIname\fB=%s];\fIname.name.\fB" <\fIinputfile\fR
 .SH DESCRIPTION
 .ad
 .fi
index 37a65dd797ace9c7ef181ab7809329b4a3948c4d..2a4333059fbb260b1a3f8e5f97c41ad742ee0b8d 100644 (file)
@@ -10,7 +10,7 @@ format of Postfix PCRE tables
 .nf
 \fBpostmap -q "\fIstring\fB" pcre:/etc/postfix/\fIfilename\fR
 
-\fBpostmap -q - pcre:/etc/postfix/\fIfilename\fR <\fIinputfile\fR
+\fBpostmap -q - pcre:/etc/postfix/\fIfilename\fB <\fIinputfile\fR
 .SH DESCRIPTION
 .ad
 .fi
index ce072f2fc651745c751af0da1247e9d39c12e372..5aac0691249ffacdcf8f3fdaf47dce5fb5f4047f 100644 (file)
@@ -8,9 +8,9 @@ Postfix PostgreSQL client configuration
 .SH "SYNOPSIS"
 .na
 .nf
-\fBpostmap -q "\fIstring\fB" pgsql:/etc/postfix/filename\fR
+\fBpostmap -q "\fIstring\fB" pgsql:/etc/postfix/\fIfilename\fR
 
-\fBpostmap -q - pgsql:/etc/postfix/\fIfilename\fR <\fIinputfile\fR
+\fBpostmap -q - pgsql:/etc/postfix/\fIfilename\fB <\fIinputfile\fR
 .SH DESCRIPTION
 .ad
 .fi
index 4f9068d199e7cf7f9d0033dd69cd18a6f8e2ad05..8058abb27c73a2cc430d138c6fe45a51271de359 100644 (file)
@@ -5144,7 +5144,8 @@ When the recipient_delimiter set contains multiple characters
 extension by the first character that matches the recipient_delimiter
 set.
 .PP
-When used in forward_path, ${recipient_delimiter} is replaced
+When used in command_execution_directory, forward_path, or
+luser_relay, ${recipient_delimiter} is replaced
 with the recipient delimiter that was found in the recipient email
 address (Postfix 2.11 and later), or it is replaced with the main.cf
 recipient_delimiter parameter value (Postfix 2.10 and earlier).
index cc8979c70afa764cf606fc92d7dc1e4f3236baf1..ba7fe3f5ec288c235d3bcbee9fee1157f8c0623e 100644 (file)
@@ -10,7 +10,7 @@ format of Postfix regular expression tables
 .nf
 \fBpostmap -q "\fIstring\fB" regexp:/etc/postfix/\fIfilename\fR
 
-\fBpostmap -q - regexp:/etc/postfix/\fIfilename\fR <\fIinputfile\fR
+\fBpostmap -q - regexp:/etc/postfix/\fIfilename\fB <\fIinputfile\fR
 .SH DESCRIPTION
 .ad
 .fi
index 7da05239021c6d82e1f1dbe9527c408bc3d0ccb7..40495546ca2a7aff649b21332c49b4c31ad381f1 100644 (file)
@@ -8,9 +8,9 @@ Postfix SQLite configuration
 .SH "SYNOPSIS"
 .na
 .nf
-\fBpostmap -q "\fIstring\fB" sqlite:/etc/postfix/filename\fR
+\fBpostmap -q "\fIstring\fB" sqlite:/etc/postfix/\fIfilename\fR
 
-\fBpostmap -q - sqlite:/etc/postfix/\fIfilename\fR <\fIinputfile\fR
+\fBpostmap -q - sqlite:/etc/postfix/\fIfilename\fB <\fIinputfile\fR
 .SH DESCRIPTION
 .ad
 .fi
index 6eb90fedde0cbeda05f530b1ae2e8c11f573eb74..d5d195c443e15438c6ab99be26652c3291d69bb3 100644 (file)
@@ -10,7 +10,7 @@ Postfix client/server table lookup protocol
 .nf
 \fBpostmap -q "\fIstring\fB" tcp:\fIhost:port\fR
 
-\fBpostmap -q - tcp:\fIhost:port\fR <\fIinputfile\fR
+\fBpostmap -q - tcp:\fIhost:port\fB <\fIinputfile\fR
 .SH DESCRIPTION
 .ad
 .fi
index 0f1706ad11da3de0ba8c3873d20d3fd04533f3db..2658ad9413e09be03696525ff60828143316260a 100644 (file)
@@ -6,7 +6,7 @@
 # SYNOPSIS
 #      \fBpostmap -q "\fIstring\fB" cidr:/etc/postfix/\fIfilename\fR
 #
-#      \fBpostmap -q - cidr:/etc/postfix/\fIfilename\fR <\fIinputfile\fR
+#      \fBpostmap -q - cidr:/etc/postfix/\fIfilename\fB <\fIinputfile\fR
 # DESCRIPTION
 #      The Postfix mail system uses optional lookup tables.
 #      These tables are usually in \fBdbm\fR or \fBdb\fR format.
index 7b0e564f17ad9143a9e0619d227da93f9d3e30f5..32204b8f195784b089d231779f7dfc94f2253e27 100644 (file)
@@ -4,9 +4,9 @@
 # SUMMARY
 #      Postfix LDAP client configuration
 # SYNOPSIS
-#      \fBpostmap -q "\fIstring\fB" ldap:/etc/postfix/filename\fR
+#      \fBpostmap -q "\fIstring\fB" ldap:/etc/postfix/\fIfilename\fR
 #
-#      \fBpostmap -q - ldap:/etc/postfix/\fIfilename\fR <\fIinputfile\fR
+#      \fBpostmap -q - ldap:/etc/postfix/\fIfilename\fB <\fIinputfile\fR
 # DESCRIPTION
 #      The Postfix mail system uses optional tables for address
 #      rewriting or mail routing. These tables are usually in
index 3a99b5eb25811daf80909a817f42c1b3f648e40b..726de6131f5ea70e20fdbe333a4557ce8f53274a 100644 (file)
@@ -4,9 +4,9 @@
 # SUMMARY
 #      Postfix memcache client configuration
 # SYNOPSIS
-#      \fBpostmap -q "\fIstring\fB" memcache:/etc/postfix/filename\fR
+#      \fBpostmap -q "\fIstring\fB" memcache:/etc/postfix/\fIfilename\fR
 #
-#      \fBpostmap -q - memcache:/etc/postfix/\fIfilename\fR <\fIinputfile\fR
+#      \fBpostmap -q - memcache:/etc/postfix/\fIfilename\fB <\fIinputfile\fR
 # DESCRIPTION
 #      The Postfix mail system uses optional tables for address
 #      rewriting or mail routing. These tables are usually in
index d422e7d4632466f3cb22936827226948ec0955db..9300a15ddf3395ac08ebb529cd51acbcf903a70c 100644 (file)
@@ -4,9 +4,9 @@
 # SUMMARY
 #      Postfix MySQL client configuration
 # SYNOPSIS
-#      \fBpostmap -q "\fIstring\fB" mysql:/etc/postfix/filename\fR
+#      \fBpostmap -q "\fIstring\fB" mysql:/etc/postfix/\fIfilename\fR
 #
-#      \fBpostmap -q - mysql:/etc/postfix/\fIfilename\fR <\fIinputfile\fR
+#      \fBpostmap -q - mysql:/etc/postfix/\fIfilename\fB <\fIinputfile\fR
 # DESCRIPTION
 #      The Postfix mail system uses optional tables for address
 #      rewriting or mail routing. These tables are usually in
index f7ace421aec0030814f5f351d1e0e5f17879b0ed..40da70cee046933aa5fe55c021eb9f7b1b938a73 100644 (file)
@@ -6,7 +6,7 @@
 # SYNOPSIS
 #      \fBpostmap -q "\fIstring\fB" "nisplus:[\fIname\fB=%s];\fIname.name.\fB"\fR
 #
-#      \fBpostmap -q - "nisplus:[\fIname\fB=%s];\fIname.name.\fB"\fR <\fIinputfile\fR
+#      \fBpostmap -q - "nisplus:[\fIname\fB=%s];\fIname.name.\fB" <\fIinputfile\fR
 # DESCRIPTION
 #      The Postfix mail system uses optional lookup tables.
 #      These tables are usually in \fBdbm\fR or \fBdb\fR format.
index 7cf6ea4e7dcbe7e789a23e91df17591ea41de2bf..56ddcb94b6ec0df3dc424a79b077755bb79d376f 100644 (file)
@@ -6,7 +6,7 @@
 # SYNOPSIS
 #      \fBpostmap -q "\fIstring\fB" pcre:/etc/postfix/\fIfilename\fR
 #
-#      \fBpostmap -q - pcre:/etc/postfix/\fIfilename\fR <\fIinputfile\fR
+#      \fBpostmap -q - pcre:/etc/postfix/\fIfilename\fB <\fIinputfile\fR
 # DESCRIPTION
 #      The Postfix mail system uses optional tables for address
 #      rewriting, mail routing, or access control. These tables
index fcb86ab15b27239100b7d5cc1b84d66375b2d1ab..a086dd83104410c061ec9a3775c3813f9ed9df22 100644 (file)
@@ -4,9 +4,9 @@
 # SUMMARY
 #      Postfix PostgreSQL client configuration
 # SYNOPSIS
-#      \fBpostmap -q "\fIstring\fB" pgsql:/etc/postfix/filename\fR
+#      \fBpostmap -q "\fIstring\fB" pgsql:/etc/postfix/\fIfilename\fR
 #
-#      \fBpostmap -q - pgsql:/etc/postfix/\fIfilename\fR <\fIinputfile\fR
+#      \fBpostmap -q - pgsql:/etc/postfix/\fIfilename\fB <\fIinputfile\fR
 # DESCRIPTION
 #      The Postfix mail system uses optional tables for address
 #      rewriting or mail routing. These tables are usually in
index 1f1de40a14c526b207d336eb437ca50860afa3fb..49b3d50ece8734a3c1ce5fb43643c4def4d44ba0 100644 (file)
@@ -6,7 +6,7 @@
 # SYNOPSIS
 #      \fBpostmap -q "\fIstring\fB" regexp:/etc/postfix/\fIfilename\fR
 #
-#      \fBpostmap -q - regexp:/etc/postfix/\fIfilename\fR <\fIinputfile\fR
+#      \fBpostmap -q - regexp:/etc/postfix/\fIfilename\fB <\fIinputfile\fR
 # DESCRIPTION
 #      The Postfix mail system uses optional tables for address
 #      rewriting, mail routing, or access control. These tables
index b981134e2026ea0973a8cfd9c6a4b014c44c21c5..9103f7f2b2281a40a9542392127cbec75913e8a8 100644 (file)
@@ -4,9 +4,9 @@
 # SUMMARY
 #      Postfix SQLite configuration
 # SYNOPSIS
-#      \fBpostmap -q "\fIstring\fB" sqlite:/etc/postfix/filename\fR
+#      \fBpostmap -q "\fIstring\fB" sqlite:/etc/postfix/\fIfilename\fR
 #
-#      \fBpostmap -q - sqlite:/etc/postfix/\fIfilename\fR <\fIinputfile\fR
+#      \fBpostmap -q - sqlite:/etc/postfix/\fIfilename\fB <\fIinputfile\fR
 # DESCRIPTION
 #      The Postfix mail system uses optional tables for address
 #      rewriting or mail routing. These tables are usually in
index 9b91db600681b053ac26a644a1a0d686708013cf..e8de8a2666993661fb7af4d17027978a642f57d3 100644 (file)
@@ -6,7 +6,7 @@
 # SYNOPSIS
 #      \fBpostmap -q "\fIstring\fB" tcp:\fIhost:port\fR
 #
-#      \fBpostmap -q - tcp:\fIhost:port\fR <\fIinputfile\fR
+#      \fBpostmap -q - tcp:\fIhost:port\fB <\fIinputfile\fR
 # DESCRIPTION
 #       The Postfix mail system uses optional tables for address
 #       rewriting or mail routing. These tables are usually in
index 7a5d20c86fe0f0f342da2701ef775518fa5aa777..999f71528e05899baaa2bca201ac33484b2a3070 100644 (file)
@@ -207,12 +207,20 @@ extern int dns_rr_eq_sa(DNS_RR *, struct sockaddr *);
  /*
   * dns_lookup.c
   */
-extern int dns_lookup(const char *, unsigned, unsigned, DNS_RR **,
-                             VSTRING *, VSTRING *);
-extern int dns_lookup_l(const char *, unsigned, DNS_RR **, VSTRING *,
-                               VSTRING *, int,...);
-extern int dns_lookup_v(const char *, unsigned, DNS_RR **, VSTRING *,
-                               VSTRING *, int, unsigned *);
+extern int dns_lookup_r(const char *, unsigned, unsigned, DNS_RR **,
+                             VSTRING *, VSTRING *, int *);
+extern int dns_lookup_rl(const char *, unsigned, DNS_RR **, VSTRING *,
+                               VSTRING *, int *, int,...);
+extern int dns_lookup_rv(const char *, unsigned, DNS_RR **, VSTRING *,
+                               VSTRING *, int *, int, unsigned *);
+#define dns_lookup(name, type, rflags, list, fqdn, why) \
+    dns_lookup_r((name), (type), (rflags), (list), (fqdn), (why), (int *) 0)
+#define dns_lookup_l(name, rflags, list, fqdn, why, lflags, ...) \
+    dns_lookup_rl((name), (rflags), (list), (fqdn), (why), (int *) 0, \
+       (lflags), __VA_ARGS__)
+#define dns_lookup_v(name, rflags, list, fqdn, why, lflags, ltype) \
+    dns_lookup_rv((name), (rflags), (list), (fqdn), (why), (int *) 0, \
+       (lflags), (ltype))
 
  /*
   * Request flags.
index b751fc7a827e61124fc844f659400ba1a8d87400..4fe4b2ef3b96a5d9f21f9a2455cd78944e72e405 100644 (file)
 /*     VSTRING *why;
 /*     int     lflags;
 /*     unsigned *ltype;
+/* AUXILIARY FUNCTIONS
+/*     int     dns_lookup_r(name, type, rflags, list, fqdn, why, rcode)
+/*     const char *name;
+/*     unsigned type;
+/*     unsigned rflags;
+/*     DNS_RR  **list;
+/*     VSTRING *fqdn;
+/*     VSTRING *why;
+/*     int     *rcode;
+/*
+/*     int     dns_lookup_rl(name, rflags, list, fqdn, why, rcode, lflags,
+/*                             ltype, ...)
+/*     const char *name;
+/*     unsigned rflags;
+/*     DNS_RR  **list;
+/*     VSTRING *fqdn;
+/*     VSTRING *why;
+/*     int     *rcode;
+/*     int     lflags;
+/*     unsigned ltype;
+/*
+/*     int     dns_lookup_rv(name, rflags, list, fqdn, why, rcode, lflags,
+/*                             ltype)
+/*     const char *name;
+/*     unsigned rflags;
+/*     DNS_RR  **list;
+/*     VSTRING *fqdn;
+/*     VSTRING *why;
+/*     int     *rcode;
+/*     int     lflags;
+/*     unsigned *ltype;
 /* DESCRIPTION
 /*     dns_lookup() looks up DNS resource records. When requested to
 /*     look up data other than type CNAME, it will follow a limited
@@ -42,6 +73,9 @@
 /*
 /*     dns_lookup_l() and dns_lookup_v() allow the user to specify
 /*     a list of resource types.
+/*
+/*     dns_lookup_r(), dns_lookup_rl() and dns_lookup_rv() provide
+/*     additional information.
 /* INPUTS
 /* .ad
 /* .fi
@@ -64,6 +98,9 @@
 /*     Request DNSSEC validation. This flag is silently ignored
 /*     when the system stub resolver API, resolver(3), does not
 /*     implement DNSSEC.
+/* .IP
+/*     Pointer to storage for the reply RCODE value. This gives
+/*     more detailed information than DNS_FAIL, DNS_RETRY, etc.
 /* .RE
 /* .IP lflags
 /*     Multi-type request control for dns_lookup_l() and dns_lookup_v().
   * Structure to keep track of things while decoding a name server reply.
   */
 #define DEF_DNS_REPLY_SIZE     4096    /* in case we're using TCP */
-#define MAX_DNS_REPLY_SIZE     32768   /* in case we're using TCP */
+#define MAX_DNS_REPLY_SIZE     65536   /* in case we're using TCP */
 
 typedef struct DNS_REPLY {
     unsigned char *buf;                        /* raw reply data */
     size_t  buf_len;                   /* reply buffer length */
+    int     rcode;                     /* unfiltered reply code */
     int     dnssec_valid;              /* DNSSEC AD bit */
     int     query_count;               /* number of queries */
     int     answer_count;              /* number of answers */
@@ -238,6 +276,8 @@ static int dns_query(const char *name, int type, int flags,
        len = res_search((char *) name, C_IN, type, reply->buf, reply->buf_len);
        _res.options &= ~flags;
        _res.options |= saved_options;
+       reply_header = (HEADER *) reply->buf;
+       reply->rcode = reply_header->rcode;
        if (len < 0) {
            if (why)
                vstring_sprintf(why, "Host or domain name not found. "
@@ -259,7 +299,6 @@ static int dns_query(const char *name, int type, int flags,
        if (msg_verbose)
            msg_info("dns_query: %s (%s): OK", name, dns_strtype(type));
 
-       reply_header = (HEADER *) reply->buf;
        if (reply_header->tc == 0 || reply->buf_len >= MAX_DNS_REPLY_SIZE)
            break;
        reply->buf = (unsigned char *)
@@ -602,10 +641,11 @@ static int dns_get_answer(const char *orig_name, DNS_REPLY *reply, int type,
     return (not_found_status);
 }
 
-/* dns_lookup - DNS lookup user interface */
+/* dns_lookup_r - DNS lookup user interface */
 
-int     dns_lookup(const char *name, unsigned type, unsigned flags,
-                          DNS_RR **rrlist, VSTRING *fqdn, VSTRING *why)
+int     dns_lookup_r(const char *name, unsigned type, unsigned flags,
+                            DNS_RR **rrlist, VSTRING *fqdn, VSTRING *why,
+                            int *rcode)
 {
     char    cname[DNS_NAME_LEN];
     int     c_len = sizeof(cname);
@@ -648,7 +688,10 @@ int     dns_lookup(const char *name, unsigned type, unsigned flags,
        /*
         * Perform the DNS lookup, and pre-parse the name server reply.
         */
-       if ((status = dns_query(name, type, flags, &reply, why)) != DNS_OK)
+       status = dns_query(name, type, flags, &reply, why);
+       if (rcode)
+           *rcode = reply.rcode;
+       if (status != DNS_OK)
            return (status);
 
        /*
@@ -680,10 +723,11 @@ int     dns_lookup(const char *name, unsigned type, unsigned flags,
     return (DNS_NOTFOUND);
 }
 
-/* dns_lookup_l - DNS lookup interface with types list */
+/* dns_lookup_rl - DNS lookup interface with types list */
 
-int     dns_lookup_l(const char *name, unsigned flags, DNS_RR **rrlist,
-                            VSTRING *fqdn, VSTRING *why, int lflags,...)
+int     dns_lookup_rl(const char *name, unsigned flags, DNS_RR **rrlist,
+                             VSTRING *fqdn, VSTRING *why, int *rcode,
+                             int lflags,...)
 {
     va_list ap;
     unsigned type;
@@ -699,8 +743,8 @@ int     dns_lookup_l(const char *name, unsigned flags, DNS_RR **rrlist,
        if (msg_verbose)
            msg_info("lookup %s type %s flags %d",
                     name, dns_strtype(type), flags);
-       status = dns_lookup(name, type, flags, rrlist ? &rr : (DNS_RR **) 0,
-                           fqdn, why);
+       status = dns_lookup_r(name, type, flags, rrlist ? &rr : (DNS_RR **) 0,
+                             fqdn, why, rcode);
        if (status == DNS_OK) {
            non_err = 1;
            if (rrlist)
@@ -719,11 +763,11 @@ int     dns_lookup_l(const char *name, unsigned flags, DNS_RR **rrlist,
     return (non_err ? DNS_OK : soft_err ? DNS_RETRY : status);
 }
 
-/* dns_lookup_v - DNS lookup interface with types vector */
+/* dns_lookup_rv - DNS lookup interface with types vector */
 
-int     dns_lookup_v(const char *name, unsigned flags, DNS_RR **rrlist,
-                            VSTRING *fqdn, VSTRING *why, int lflags,
-                            unsigned *types)
+int     dns_lookup_rv(const char *name, unsigned flags, DNS_RR **rrlist,
+                             VSTRING *fqdn, VSTRING *why, int *rcode,
+                             int lflags, unsigned *types)
 {
     unsigned type;
     int     status = DNS_NOTFOUND;
@@ -737,8 +781,8 @@ int     dns_lookup_v(const char *name, unsigned flags, DNS_RR **rrlist,
        if (msg_verbose)
            msg_info("lookup %s type %s flags %d",
                     name, dns_strtype(type), flags);
-       status = dns_lookup(name, type, flags, rrlist ? &rr : (DNS_RR **) 0,
-                           fqdn, why);
+       status = dns_lookup_r(name, type, flags, rrlist ? &rr : (DNS_RR **) 0,
+                             fqdn, why, rcode);
        if (status == DNS_OK) {
            non_err = 1;
            if (rrlist)
index 109bb883212a45fcb803bf0cea27f2669209b13e..4c6c781b12cef0d4b78c036803fbce33dc440862 100644 (file)
@@ -102,6 +102,7 @@ int     main(int argc, char **argv)
     char   *name;
     VSTRING *fqdn = vstring_alloc(100);
     VSTRING *why = vstring_alloc(100);
+    int     rcode;
     DNS_RR *rr;
     int     i;
 
@@ -117,10 +118,10 @@ int     main(int argc, char **argv)
     argv_free(types_argv);
     name = argv[2];
     msg_verbose = 1;
-    switch (dns_lookup_v(name, RES_DEBUG | RES_USE_DNSSEC, &rr, fqdn, why,
-                        DNS_REQ_FLAG_NONE, types)) {
+    switch (dns_lookup_rv(name, RES_DEBUG | RES_USE_DNSSEC, &rr, fqdn, why,
+                         &rcode, DNS_REQ_FLAG_NONE, types)) {
     default:
-       msg_fatal("%s", vstring_str(why));
+       msg_fatal("%s (rcode=%d)", vstring_str(why), rcode);
     case DNS_OK:
        printf("%s: fqdn: %s\n", name, vstring_str(fqdn));
        print_rr(rr);
index e3ce925381cc72643af1303554a72f646b435f32..34c0a7383f595941e5c332b23c00f8424d17d838 100644 (file)
@@ -574,10 +574,29 @@ DICT   *dict_memcache_open(const char *name, int open_flags, int dict_flags)
                         (char *) 0, 0, 0);
     if (backup) {
        dict_mc->backup = dict_open(backup, open_flags, dict_flags);
+       /* Expose backup lock and status to caller. */
+       dict_mc->dict.lock = dict_mc->backup->lock;
+       dict_mc->dict.lock_type = dict_mc->backup->lock_type;
+       dict_mc->dict.lock_fd = dict_mc->backup->lock_fd;
+       dict_mc->dict.stat_fd = dict_mc->backup->stat_fd;
        myfree(backup);
     } else
        dict_mc->backup = 0;
 
+    /*
+     * Memcached is write-share safe. If the backup database is also
+     * write-share safe, e.g. it has downgraded its persistent lock to
+     * temporary, then expose that downgraded lock to the caller.
+     */
+    if ((dict_flags & DICT_FLAG_OPEN_LOCK) != 0
+       && (dict_mc->backup == 0
+           || dict_mc->backup->lock_fd < 0
+           || ((dict_mc->backup->flags & DICT_FLAG_OPEN_LOCK) == 0
+               && (dict_mc->backup->flags & DICT_FLAG_LOCK) != 0))) {
+       dict_mc->dict.flags &= ~DICT_FLAG_OPEN_LOCK;
+       dict_mc->dict.flags |= DICT_FLAG_LOCK;
+    }
+
     /*
      * Parse templates and common database parameters. Maps that use
      * substring keys should only be used with the full input key.
index b6e7770d3baf52292803dc56e5c58df7ba9ce7ed..3799c7bbf29dc26de5c3916b391a3c8df240ec0f 100644 (file)
@@ -20,7 +20,7 @@
   * Patches change both the patchlevel and the release date. Snapshots have no
   * patchlevel; they change the release date only.
   */
-#define MAIL_RELEASE_DATE      "20131118"
+#define MAIL_RELEASE_DATE      "20131119"
 #define MAIL_VERSION_NUMBER    "2.11"
 
 #ifdef SNAPSHOT
index 592b9b0bceb15d529885e07eae1eece01d48e889..491f3d7c0df818be72e7890fe620c3b868f8c11c 100644 (file)
@@ -244,9 +244,7 @@ static int random_interval(int interval)
 
 static void command(VSTREAM *stream, char *fmt,...)
 {
-    VSTRING *buf;
     va_list ap;
-    va_list ap2;
 
     va_start(ap, fmt);
 
@@ -255,12 +253,11 @@ static void command(VSTREAM *stream, char *fmt,...)
      * what the program is trying to do.
      */
     if (msg_verbose) {
-       buf = vstring_alloc(100);
+       va_list ap2;
+
        VA_COPY(ap2, ap);
-       vstring_vsprintf(buf, fmt, ap2);
+       vmsg_info(fmt, ap2);
        va_end(ap2);
-       msg_info("%s", vstring_str(buf));
-       vstring_free(buf);
     }
     smtp_vprintf(stream, fmt, ap);
     va_end(ap);
index c8564f6bd8a311f2cec4de37369a09293d23b044..2efb1f5b4af4677544fbae8ae0af79a69dd5e7de 100644 (file)
@@ -57,7 +57,8 @@ typedef struct DICT {
     int     (*sequence) (struct DICT *, int, const char **, const char **);
     int     (*lock) (struct DICT *, int);
     void    (*close) (struct DICT *);
-    int     lock_fd;                   /* for dict_update() lock */
+    int     lock_type;                 /* for read/write lock */
+    int     lock_fd;                   /* for read/write lock */
     int     stat_fd;                   /* change detection */
     time_t  mtime;                     /* mod time at open */
     VSTRING *fold_buf;                 /* key folding buffer */
index fc35dc0a8e8d378662af478f83608b767cd2b16a..eb2b40c9a3a2a96b11bf9f381a8dac59e10af8b9 100644 (file)
@@ -28,7 +28,8 @@
 /*
 /*     One exception is the default lock function.  When the
 /*     dictionary provides a file handle for locking, the default
-/*     lock function returns the result from myflock(), otherwise
+/*     lock function returns the result from myflock with the
+/*     locking method specified in the lock_type member, otherwise
 /*     it returns 0. Presently, the lock function is used only to
 /*     implement the DICT_FLAG_OPEN_LOCK feature (lock the database
 /*     exclusively after it is opened) for databases that are not
@@ -115,7 +116,7 @@ static int dict_default_sequence(DICT *dict, int unused_function,
 static int dict_default_lock(DICT *dict, int operation)
 {
     if (dict->lock_fd >= 0) {
-       return (myflock(dict->lock_fd, INTERNAL_LOCK, operation));
+       return (myflock(dict->lock_fd, dict->lock_type, operation));
     } else {
        return (0);
     }
@@ -144,6 +145,7 @@ DICT   *dict_alloc(const char *dict_type, const char *dict_name, ssize_t size)
     dict->sequence = dict_default_sequence;
     dict->close = dict_default_close;
     dict->lock = dict_default_lock;
+    dict->lock_type = INTERNAL_LOCK;
     dict->lock_fd = -1;
     dict->stat_fd = -1;
     dict->mtime = 0;
index 2dd36f6ea3ae3098c207165b048b91ff5ad967a2..5b079e374c0d8a12cce26514804b899a95f35276 100644 (file)
@@ -646,6 +646,7 @@ DICT   *dict_lmdb_open(const char *path, int open_flags, int dict_flags)
     if (fstat(db_fd, &st) < 0)
        msg_fatal("dict_lmdb_open: fstat: %m");
     dict_lmdb->dict.lock_fd = dict_lmdb->dict.stat_fd = db_fd;
+    dict_lmdb->dict.lock_type = MYFLOCK_STYLE_FCNTL;
     dict_lmdb->dict.mtime = st.st_mtime;
     dict_lmdb->dict.owner.uid = st.st_uid;
     dict_lmdb->dict.owner.status = (st.st_uid != 0);
@@ -672,6 +673,12 @@ DICT   *dict_lmdb_open(const char *path, int open_flags, int dict_flags)
     if (dict_flags & DICT_FLAG_BULK_UPDATE)
        dict_jmp_alloc(&dict_lmdb->dict);
 
+    /* LMDB is write-share safe; downgrade a persistent lock to temporary. */
+    if (dict_flags & DICT_FLAG_OPEN_LOCK) {
+       dict_lmdb->dict.flags &= ~DICT_FLAG_OPEN_LOCK;
+       dict_lmdb->dict.flags |= DICT_FLAG_LOCK;
+    }
+
     /*
      * The following requests return an error result only if we have serious
      * memory corruption problem.
index a8b5a0a7243bc7ac887b3274452cf871e1f84d42..d0a9bacff2b80f34a6b25ed3a13ac6a6b75787e4 100644 (file)
 /* .IP DICT_FLAG_LOCK
 /*     With maps where this is appropriate, acquire an exclusive lock
 /*     before writing, and acquire a shared lock before reading.
+/*     Release the lock when the operation completes.
 /* .IP DICT_FLAG_OPEN_LOCK
 /*     With databases that are not multi-writer safe, request that
 /*     dict_open() acquires an exclusive lock, or that it terminates
 /*     with a fatal run-time error.
+/*
+/*     With databases that are multi-writer safe, downgrade from
+/*     DICT_FLAG_OPEN_LOCK (persistent lock) to DICT_FLAG_LOCK
+/*     (temporary lock).
 /* .IP DICT_FLAG_FOLD_FIX
 /*     With databases whose lookup fields are fixed-case strings,
 /*     fold the search string to lower case before accessing the
@@ -384,9 +389,10 @@ DICT   *dict_open3(const char *dict_type, const char *dict_name,
                            "cannot open %s:%s: %m", dict_type, dict_name));
     if (msg_verbose)
        msg_info("%s: %s:%s", myname, dict_type, dict_name);
-    /* XXX the choice between wait-for-lock or no-wait is hard-coded. */
-    if (dict_flags & DICT_FLAG_OPEN_LOCK) {
-       if (dict_flags & DICT_FLAG_LOCK)
+    /* Write-share safe maps may downgrade a persistent lock to temporary. */
+    /* XXX The choice between wait-for-lock or no-wait is hard-coded. */
+    if (dict->flags & DICT_FLAG_OPEN_LOCK) {
+       if (dict->flags & DICT_FLAG_LOCK)
            msg_panic("%s: attempt to open %s:%s with both \"open\" lock and \"access\" lock",
                      myname, dict_type, dict_name);
        if (dict->lock(dict, MYFLOCK_OP_EXCLUSIVE | MYFLOCK_OP_NOWAIT) < 0)