2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-22 09:57:34 +00:00

postfix-2.11-20131119

This commit is contained in:
Wietse Venema 2013-11-19 00:00:00 -05:00 committed by Viktor Dukhovni
parent 9de1f6a1d7
commit f5ad0386b9
38 changed files with 182 additions and 77 deletions

View 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.

View 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

View 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>

View 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>

View 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>

View 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).

View 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>

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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).

View 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

View 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

View 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

View 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.

View 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

View 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

View 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

View 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.

View 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

View 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

View 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

View 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

View 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

View 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.

View File

@ -31,6 +31,37 @@
/* 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().
@ -161,11 +198,12 @@
* 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)

View 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);

View 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.

View 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

View 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);

View 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 */

View 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;

View 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.

View File

@ -90,10 +90,15 @@
/* .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)