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

postfix-3.8-20220507

This commit is contained in:
Wietse Venema 2022-05-07 00:00:00 -05:00 committed by Viktor Dukhovni
parent 1b1cb925cd
commit 926448aed5
60 changed files with 1194 additions and 647 deletions

View File

@ -26207,7 +26207,7 @@ Apologies for any names omitted.
Cleanup: unit tests. File: cleanup/cleanup_milter.c. Cleanup: unit tests. File: cleanup/cleanup_milter.c.
Cleamup: disable hash-table seed in unit tests. Many Cleanup: disable hash-table seed in unit tests. Many
Makefiles, some unit test 'reference' files. Makefiles, some unit test 'reference' files.
Bugfix (documented but not implemented since Postfix 2.2): Bugfix (documented but not implemented since Postfix 2.2):
@ -26234,7 +26234,7 @@ Apologies for any names omitted.
mantools/check-spell-install-proto-text. mantools/check-spell-install-proto-text.
Cleanup: for consistent parameter naming (tlsproxy_client_xxx Cleanup: for consistent parameter naming (tlsproxy_client_xxx
correspnds to smtp_tls_xxx), renamed tlsproxy_client_level corresponds to smtp_tls_xxx), renamed tlsproxy_client_level
to tlsproxy_client_security_level, and tlsproxy_client_policy to tlsproxy_client_security_level, and tlsproxy_client_policy
to tlsproxy_client_policy_maps, with backwards-compatible to tlsproxy_client_policy_maps, with backwards-compatible
defaults and updated documentation. Problem reported by defaults and updated documentation. Problem reported by
@ -26258,7 +26258,7 @@ Apologies for any names omitted.
20220128 20220128
Clenaup: standardize on FNV hash, after having verified Cleanup: standardize on FNV hash, after having verified
that collisions will change with the hash seed value, and that collisions will change with the hash seed value, and
that the collision rate is low. Files: util/htable.c, that the collision rate is low. Files: util/htable.c,
util/hash_fnv.[hc]. util/hash_fnv.[hc].
@ -26399,9 +26399,99 @@ Apologies for any names omitted.
20220421 20220421
Bugfix (introduced: Postfix 3.7): reverted an overly complex Bugfix (introduced: Postfix 3.7): reverted an overly complex
change in the postscreen SMTP engine from 20211023, that change in the postscreen SMTP engine from 20211023, and
was segfaulting on malformed input, where the Postfix 3.6 replaced it with a much simpler change. The bad change was
implementation worked properly. The purpose of the change segfaulting on some systems after receiving malformed input
was to prevent complaints about "malformed UTF8" from Postfix (for example, TLS "hello"). File: postscreen/postscreen_smtpd.c.
lookup tables. Replaced the change with a trivial guard.
File: postscreen/postscreen_smtpd.c. Under conditions described below, the postscreen program
attempted to read through an uninitialized 'const' pointer.
The pointer value depended on the compiler type and compiler
options, but crucially, it did not depend on network inputs.
The conditions were that SMTPUTF8 support was enabled (the
default), and that postscreen received non-UTF8 input, for
example, a TLS or RDP handshake request.
Depending on compiler details, the result of the read
operation could be uninteresting, a combined memory leak
and file handle leak, or a segmentation violation (signal
11).
The segmentation violation result was reported by Michael
Grimm who used a FreeBSD 13.1 early version. The result was
"uninteresting" with FreeBSD 13.0. Both FreeBSD systems use
Clang instead of GCC. The result was also "uninteresting"
on Linux-based systems that use GCC, or on a few older
systems that use GCC.
20220427
Cleanup: incorrect error message after postscreen received
a STARTTLS command with too many arguments. File:
postscreen/postscreen_smtpd.c.
20220429
Noise: shut up a useless warning. File: cleanup_map1n.c.
Documentation: IPv6 support, by Pau Amma. Files: proto/INSTALL,
proto/IPV6_README.html.
20220501
Cleanup: merged the infrastructure that "knows" which tables
are created with "postmap" or "postalias", with infrastructure
that has other information about lookup tables. The old design
pre-dated dynamically-loaded table drivers, and was difficult
to maintain.
The following files were moved from the "global" directory to
the "util" directory: src/util/mkmap.h, src/util/mkmap_cdb.c,
src/util/mkmap_db.c, src/util/mkmap_dbm.c, src/util/mkmap_fail.c,
src/util/mkmap_lmdb.c, src/util/mkmap_open.c,
src/util/mkmap_sdbm.c.
The corresponding postfix-xxx.so shared objects are now created
by util/Makefile instead of global/Makefile. There is no change
in how these files are installed or deployed.
Other files affected by this change: src/util/dict_open.c,
src/global/dynamicmaps.c, src/global/mail_version.h,
src/global/header_body_checks.h, src/global/maps.c,
src/global/dict_proxy.h, src/util/dict.c, src/util/dict_dbm.h,
src/util/dict_fail.h, src/util/dict_db.h, src/util/dict_lmdb.h,
src/util/dict_cdb.h, src/util/dict_sdbm.h, src/util/dict.h,
src/global/mail_dict.c, src/postalias/postalias.c,
src/postmap/postmap.c.
Portability: variable declaration after code. File:
global/compat_level.c.
20220504
Documentation: dymap_init() description. File:
global/dynamicmaps.c.
20220506
Added an argv_uniq() function to deduplicate same-value
adjacent array elements. Added a ton of tests to validate
the argv implementation. File: util/argv.c.
Cleanup: the dict_mapnames() function (used in "postconf
-m") now deduplicates dictionary type names. File:
util/dict_open.c.
20220507
Documentation: inverted the paragraph about "known" addresses,
in the descriptions of smtpd_reject_unlisted_sender and
smtpd_reject_unlisted_recipient. File: proto/postconf.proto.
Documentation: added the HISTORY file to the pre-release-checks.
Files: mantools/check-double-history, mantools/check-spell-history,
proto/stop.double-history, proto/stop.spell-history.
Documentation: added POSTLOG_SERVICE and POSTLOG_HOSTNAME
to the import_environment description. File: proto/postconf.proto.

View File

@ -567,7 +567,7 @@ The following is an extensive list of names and values.
|| |Do not build with IPv6 support. By default, | || |Do not build with IPv6 support. By default, |
|| |IPv6 support is compiled in on platforms that| || |IPv6 support is compiled in on platforms that|
|| |are known to have IPv6 support. Note: this | || |are known to have IPv6 support. Note: this |
||-DNO_IPV6 |directive is for debugging And testing only. | ||-DNO_IPV6 |directive is for debugging and testing only. |
|| |It is not guaranteed to work on all | || |It is not guaranteed to work on all |
|| |platforms. If you don't want IPv6 support, | || |platforms. If you don't want IPv6 support, |
|| |set "inet_protocols = ipv4" in main.cf. | || |set "inet_protocols = ipv4" in main.cf. |

View File

@ -116,7 +116,8 @@ manpages:
# Some checks require a bin/postconf executable. # Some checks require a bin/postconf executable.
pre-release-checks: typo-check missing-proxy-read-maps-check \ pre-release-checks: typo-check missing-proxy-read-maps-check \
postlink-check postfix-files-check postlink-check postfix-files-check check-spell-history \
check-double-history
postfix-files-check: postfix-files-check:
mantools/check-postfix-files | diff /dev/null - mantools/check-postfix-files | diff /dev/null -
@ -148,6 +149,12 @@ double-install-proto-text:
double-proto-html: double-proto-html:
mantools/check-double-proto-html | diff /dev/null - mantools/check-double-proto-html | diff /dev/null -
check-spell-history:
mantools/check-spell-history | diff /dev/null -
check-double-history:
mantools/check-double-history | diff /dev/null -
# The build-time shlib_directory setting must take precedence over # The build-time shlib_directory setting must take precedence over
# the installed main.cf settings, otherwise we can't update an # the installed main.cf settings, otherwise we can't update an
# installed system from dynamicmaps=yes<->dynamicmaps=no or from # installed system from dynamicmaps=yes<->dynamicmaps=no or from

View File

@ -567,7 +567,7 @@ The following is an extensive list of names and values.
|| |Do not build with IPv6 support. By default, | || |Do not build with IPv6 support. By default, |
|| |IPv6 support is compiled in on platforms that| || |IPv6 support is compiled in on platforms that|
|| |are known to have IPv6 support. Note: this | || |are known to have IPv6 support. Note: this |
||-DNO_IPV6 |directive is for debugging And testing only. | ||-DNO_IPV6 |directive is for debugging and testing only. |
|| |It is not guaranteed to work on all | || |It is not guaranteed to work on all |
|| |platforms. If you don't want IPv6 support, | || |platforms. If you don't want IPv6 support, |
|| |set "inet_protocols = ipv4" in main.cf. | || |set "inet_protocols = ipv4" in main.cf. |

View File

@ -43,7 +43,8 @@ Postfix version 2.2 supports IPv4 and IPv6 on the following platforms:
On other platforms Postfix will simply use IPv4 as it has always done. On other platforms Postfix will simply use IPv4 as it has always done.
See below for tips how to port Postfix IPv6 support to other environments. See "IPv6 Support for unsupported platforms" for tips to port Postfix IPv6
support to other environments.
CCoonnffiigguurraattiioonn CCoonnffiigguurraattiioonn
@ -83,6 +84,9 @@ configuration work with Postfix.
Note 2: on older Linux and Solaris systems, the setting "inet_protocols = Note 2: on older Linux and Solaris systems, the setting "inet_protocols =
ipv6" will not prevent Postfix from accepting IPv4 connections. ipv6" will not prevent Postfix from accepting IPv4 connections.
For an unsupported test option to build Postfix without IPv6 support, see
the NO_IPV6 option in the INSTALL document.
* The other new parameter is smtp_bind_address6. This sets the local * The other new parameter is smtp_bind_address6. This sets the local
interface address for outgoing IPv6 SMTP connections, just like the interface address for outgoing IPv6 SMTP connections, just like the
smtp_bind_address parameter does for IPv4: smtp_bind_address parameter does for IPv4:

View File

@ -24,3 +24,11 @@ historical IBM Public License 1.0, it is now also distributed with the
more recent Eclipse Public License 2.0. Recipients can choose to take more recent Eclipse Public License 2.0. Recipients can choose to take
the software under the license of their choice. Those who are more the software under the license of their choice. Those who are more
comfortable with the IPL can continue with that license. comfortable with the IPL can continue with that license.
Incompatible changes with snapshot 20220507
===========================================
Most global/mkmap*.[hc] files have moved to the util directory;
only global/mkmap_proxy.* remains. The old file organization was
designed before support for dynamically-loadable databases was
added, and the code suffered from complexity.

View File

@ -9,13 +9,18 @@ Wish list:
Scan Postfix code with github.com/googleprojectzero/weggli Scan Postfix code with github.com/googleprojectzero/weggli
(depends on "rust"). (depends on "rust").
Enforce var_line_limit in util/attr_scan*c.
Can tests use LD_PRELOAD to inject fake modules such as Can tests use LD_PRELOAD to inject fake modules such as
fake_dns(3), fake_msg(3), fake_myaddrinfo(3) and so on? fake_dns(3), fake_msg(3), fake_myaddrinfo(3) and so on?
One limitation is that functions etc. in a preloaded object One limitation is that functions etc. in a preloaded object
always take precedence, even in code that is not being always take precedence, even in code that is not being
tested. tested.
'%l' support. ef7c661c-d86a-2366-6a73-ec8d51d75012@dev.snart.me '%l' support, similar to %D in the Dovecot LDAP driver.
Subject: Feature request: '%l' expansion for ldap_table,
Date: Tue, 5 Apr 2022. Message-ID:
<ef7c661c-d86a-2366-6a73-ec8d51d75012@dev.snart.me>
WARN_IF_REJECT like prefix that disables the error counter increment. WARN_IF_REJECT like prefix that disables the error counter increment.

View File

@ -837,7 +837,7 @@ unreachable code. </td> </tr>
<tr> <td> </td> <td> -DNO_IPV6 </td> <td> Do not build with IPv6 <tr> <td> </td> <td> -DNO_IPV6 </td> <td> Do not build with IPv6
support. By default, IPv6 support is compiled in on platforms that support. By default, IPv6 support is compiled in on platforms that
are known to have IPv6 support. Note: this directive is for debugging are known to have IPv6 support. Note: this directive is for debugging
And testing only. It is not guaranteed to work on all platforms. and testing only. It is not guaranteed to work on all platforms.
If you don't want IPv6 support, set "<a href="postconf.5.html#inet_protocols">inet_protocols</a> = ipv4" in If you don't want IPv6 support, set "<a href="postconf.5.html#inet_protocols">inet_protocols</a> = ipv4" in
<a href="postconf.5.html">main.cf</a>. <a href="postconf.5.html">main.cf</a>.
</td> </tr> </td> </tr>

View File

@ -78,8 +78,8 @@ platforms: </p>
<p> On other platforms Postfix will simply use IPv4 as it has always <p> On other platforms Postfix will simply use IPv4 as it has always
done. </p> done. </p>
<p> See <a href="#porting">below</a> for tips how to port Postfix <p> See "<a href="#porting">IPv6 Support for unsupported platforms</a>"
IPv6 support to other environments. </p> for tips to port Postfix IPv6 support to other environments. </p>
<h2><a name="configuration">Configuration</a></h2> <h2><a name="configuration">Configuration</a></h2>
@ -128,6 +128,9 @@ on a software distribution with IPv6 support, "ipv4" otherwise. </p>
"<a href="postconf.5.html#inet_protocols">inet_protocols</a> = ipv6" will not prevent Postfix from "<a href="postconf.5.html#inet_protocols">inet_protocols</a> = ipv6" will not prevent Postfix from
accepting IPv4 connections. </p> accepting IPv4 connections. </p>
<p> For an unsupported test option to build Postfix without IPv6
support, see the NO_IPV6 option in the <a href="INSTALL.html">INSTALL</a> document. </p>
<li> <p> The other new parameter is <a href="postconf.5.html#smtp_bind_address6">smtp_bind_address6</a>. <li> <p> The other new parameter is <a href="postconf.5.html#smtp_bind_address6">smtp_bind_address6</a>.
This sets the local interface address for outgoing IPv6 SMTP This sets the local interface address for outgoing IPv6 SMTP
connections, just like the <a href="postconf.5.html#smtp_bind_address">smtp_bind_address</a> parameter connections, just like the <a href="postconf.5.html#smtp_bind_address">smtp_bind_address</a> parameter

View File

@ -4047,6 +4047,16 @@ environment. Examples of relevant environment variables: </p>
<dd>Needed to make "<b>postfix -c</b>" work. </dd> <dd>Needed to make "<b>postfix -c</b>" work. </dd>
<dt><b>POSTLOG_SERVICE</b></dt>
<dd>Needed to make "<b><a href="postconf.5.html#maillog_file">maillog_file</a></b>" work during daemon
process initialization. </dd>
<dt><b>POSTLOG_HOSTNAME</b></dt>
<dd>Needed to make "<b><a href="postconf.5.html#maillog_file">maillog_file</a></b>" work during daemon
process initialization. </dd>
</dl> </dl>
<p> Specify a list of names and/or name=value pairs, separated by <p> Specify a list of names and/or name=value pairs, separated by
@ -16602,8 +16612,9 @@ access restriction is specified. This prevents the Postfix queue
from filling up with undeliverable MAILER-DAEMON messages. from filling up with undeliverable MAILER-DAEMON messages.
</p> </p>
<p> An address is always considered "known" when it matches a <p> An address is considered "unknown" when it does not match a
<a href="virtual.5.html">virtual(5)</a> alias or a <a href="canonical.5.html">canonical(5)</a> mapping. <a href="virtual.5.html">virtual(5)</a> alias or a <a href="canonical.5.html">canonical(5)</a> mapping, and one of the following
conditions holds: </p>
<ul> <ul>
@ -16639,8 +16650,9 @@ sender addresses, even when no explicit <a href="postconf.5.html#reject_unlisted
access restriction is specified. This can slow down an explosion access restriction is specified. This can slow down an explosion
of forged mail from worms or viruses. </p> of forged mail from worms or viruses. </p>
<p> An address is always considered "known" when it matches a <p> An address is considered "unknown" when it does not match a
<a href="virtual.5.html">virtual(5)</a> alias or a <a href="canonical.5.html">canonical(5)</a> mapping. <a href="virtual.5.html">virtual(5)</a> alias or a <a href="canonical.5.html">canonical(5)</a> mapping, and one of the following
conditions holds: </p>
<ul> <ul>

View File

@ -2561,6 +2561,14 @@ Needed for debugging Postfix daemons with an X\-windows debugger.
.IP "\fBMAIL_CONFIG\fR" .IP "\fBMAIL_CONFIG\fR"
Needed to make "\fBpostfix \-c\fR" work. Needed to make "\fBpostfix \-c\fR" work.
.br .br
.IP "\fBPOSTLOG_SERVICE\fR"
Needed to make "\fBmaillog_file\fR" work during daemon
process initialization.
.br
.IP "\fBPOSTLOG_HOSTNAME\fR"
Needed to make "\fBmaillog_file\fR" work during daemon
process initialization.
.br
.br .br
.PP .PP
Specify a list of names and/or name=value pairs, separated by Specify a list of names and/or name=value pairs, separated by
@ -11482,8 +11490,9 @@ recipient addresses, even when no explicit reject_unlisted_recipient
access restriction is specified. This prevents the Postfix queue access restriction is specified. This prevents the Postfix queue
from filling up with undeliverable MAILER\-DAEMON messages. from filling up with undeliverable MAILER\-DAEMON messages.
.PP .PP
An address is always considered "known" when it matches a An address is considered "unknown" when it does not match a
\fBvirtual\fR(5) alias or a \fBcanonical\fR(5) mapping. \fBvirtual\fR(5) alias or a \fBcanonical\fR(5) mapping, and one of the following
conditions holds:
.IP \(bu .IP \(bu
The recipient domain matches $mydestination, $inet_interfaces The recipient domain matches $mydestination, $inet_interfaces
or $proxy_interfaces, but the recipient is not listed in or $proxy_interfaces, but the recipient is not listed in
@ -11508,8 +11517,9 @@ sender addresses, even when no explicit reject_unlisted_sender
access restriction is specified. This can slow down an explosion access restriction is specified. This can slow down an explosion
of forged mail from worms or viruses. of forged mail from worms or viruses.
.PP .PP
An address is always considered "known" when it matches a An address is considered "unknown" when it does not match a
\fBvirtual\fR(5) alias or a \fBcanonical\fR(5) mapping. \fBvirtual\fR(5) alias or a \fBcanonical\fR(5) mapping, and one of the following
conditions holds:
.IP \(bu .IP \(bu
The sender domain matches $mydestination, $inet_interfaces or The sender domain matches $mydestination, $inet_interfaces or
$proxy_interfaces, but the sender is not listed in $proxy_interfaces, but the sender is not listed in

View File

@ -0,0 +1,7 @@
#!/bin/sh
# Finds double words the HISTORY file, starting with 2022.
LANG=C; export LANG
sed '1,/^2022/d' HISTORY | mantools/find-double | fgrep -vxf proto/stop.double-history

View File

@ -0,0 +1,9 @@
#!/bin/sh
# Spellchecks text in the HISTORY file, starting with 2022.
LANG=C; export LANG
sed '1,/^2022/d' HISTORY | spell | fgrep -vxf proto/stop | \
fgrep -vxf proto/stop.spell-cc | \
fgrep -vxf proto/stop.spell-history

View File

@ -837,7 +837,7 @@ unreachable code. </td> </tr>
<tr> <td> </td> <td> -DNO_IPV6 </td> <td> Do not build with IPv6 <tr> <td> </td> <td> -DNO_IPV6 </td> <td> Do not build with IPv6
support. By default, IPv6 support is compiled in on platforms that support. By default, IPv6 support is compiled in on platforms that
are known to have IPv6 support. Note: this directive is for debugging are known to have IPv6 support. Note: this directive is for debugging
And testing only. It is not guaranteed to work on all platforms. and testing only. It is not guaranteed to work on all platforms.
If you don't want IPv6 support, set "inet_protocols = ipv4" in If you don't want IPv6 support, set "inet_protocols = ipv4" in
main.cf. main.cf.
</td> </tr> </td> </tr>

View File

@ -78,8 +78,8 @@ platforms: </p>
<p> On other platforms Postfix will simply use IPv4 as it has always <p> On other platforms Postfix will simply use IPv4 as it has always
done. </p> done. </p>
<p> See <a href="#porting">below</a> for tips how to port Postfix <p> See "<a href="#porting">IPv6 Support for unsupported platforms</a>"
IPv6 support to other environments. </p> for tips to port Postfix IPv6 support to other environments. </p>
<h2><a name="configuration">Configuration</a></h2> <h2><a name="configuration">Configuration</a></h2>
@ -128,6 +128,9 @@ inet_protocols configuration parameter. </p>
"inet_protocols = ipv6" will not prevent Postfix from "inet_protocols = ipv6" will not prevent Postfix from
accepting IPv4 connections. </p> accepting IPv4 connections. </p>
<p> For an unsupported test option to build Postfix without IPv6
support, see the NO_IPV6 option in the INSTALL document. </p>
<li> <p> The other new parameter is smtp_bind_address6. <li> <p> The other new parameter is smtp_bind_address6.
This sets the local interface address for outgoing IPv6 SMTP This sets the local interface address for outgoing IPv6 SMTP
connections, just like the smtp_bind_address parameter connections, just like the smtp_bind_address parameter

View File

@ -1957,6 +1957,16 @@ environment. Examples of relevant environment variables: </p>
<dd>Needed to make "<b>postfix -c</b>" work. </dd> <dd>Needed to make "<b>postfix -c</b>" work. </dd>
<dt><b>POSTLOG_SERVICE</b></dt>
<dd>Needed to make "<b>maillog_file</b>" work during daemon
process initialization. </dd>
<dt><b>POSTLOG_HOSTNAME</b></dt>
<dd>Needed to make "<b>maillog_file</b>" work during daemon
process initialization. </dd>
</dl> </dl>
<p> Specify a list of names and/or name=value pairs, separated by <p> Specify a list of names and/or name=value pairs, separated by
@ -8740,8 +8750,9 @@ access restriction is specified. This prevents the Postfix queue
from filling up with undeliverable MAILER-DAEMON messages. from filling up with undeliverable MAILER-DAEMON messages.
</p> </p>
<p> An address is always considered "known" when it matches a <p> An address is considered "unknown" when it does not match a
virtual(5) alias or a canonical(5) mapping. virtual(5) alias or a canonical(5) mapping, and one of the following
conditions holds: </p>
<ul> <ul>
@ -8773,8 +8784,9 @@ sender addresses, even when no explicit reject_unlisted_sender
access restriction is specified. This can slow down an explosion access restriction is specified. This can slow down an explosion
of forged mail from worms or viruses. </p> of forged mail from worms or viruses. </p>
<p> An address is always considered "known" when it matches a <p> An address is considered "unknown" when it does not match a
virtual(5) alias or a canonical(5) mapping. virtual(5) alias or a canonical(5) mapping, and one of the following
conditions holds: </p>
<ul> <ul>

View File

@ -329,3 +329,4 @@ XXX XXX
int compar DNS_RR DNS_RR int compar DNS_RR DNS_RR
USE_FNV_32BIT USE_FNV_32BIT USE_FNV_32BIT USE_FNV_32BIT
void void cleanup_milter_receive state count void void cleanup_milter_receive state count
struct DICT open const char int int dict_xx_open

View File

@ -0,0 +1,10 @@
message from the postqueue command File postqueue postqueue c
or kernel bug emits a weird error File postqueue postqueue c
Dukhovni File auxiliary collate collate pl
sanitization File showq showq c
with setgid permissions File postlogd postlogd c
cleanup server enters the chroot jail Files cleanup cleanup h
global maps c global maps h smtp smtp c
cleanup cleanup h cleanup cleanup_init c
src global mail_dict c src postalias postalias c
src postmap postmap c

View File

@ -1784,3 +1784,5 @@ stdint
Noll Noll
deinit deinit
reinit reinit
COMPAR
deduplicate

View File

@ -0,0 +1,21 @@
AppArmor
Bugfix
Degenkolb
Dybdal
Jaroslav
Kimura
Kitterman
Klanderman
Pelletier
RDP
Raf
Skarvada
Velasco
WISHLIST
Yasuhiro
deduplicates
hmtl
libs
segfaulting
srctoman
systemd

View File

@ -101,7 +101,7 @@ ARGV *cleanup_map1n_internal(CLEANUP_STATE *state, const char *addr,
* pointer. * pointer.
*/ */
#define UPDATE(ptr,new) do { \ #define UPDATE(ptr,new) do { \
if (ptr) myfree(ptr); ptr = mystrdup(new); \ if (ptr) { myfree(ptr); } ptr = mystrdup(new); \
} while (0) } while (0)
#define STR vstring_str #define STR vstring_str
#define RETURN(x) do { \ #define RETURN(x) do { \

View File

@ -16,8 +16,7 @@ SRCS = abounce.c anvil_clnt.c been_here.c bounce.c bounce_log.c \
mail_params.c mail_pathname.c mail_queue.c mail_run.c \ mail_params.c mail_pathname.c mail_queue.c mail_run.c \
mail_scan_dir.c mail_stream.c mail_task.c mail_trigger.c maps.c \ mail_scan_dir.c mail_stream.c mail_task.c mail_trigger.c maps.c \
mark_corrupt.c match_parent_style.c mbox_conf.c mbox_open.c \ mark_corrupt.c match_parent_style.c mbox_conf.c mbox_open.c \
mime_state.c mkmap_cdb.c mkmap_db.c mkmap_dbm.c mkmap_lmdb.c mkmap_open.c \ mime_state.c msg_stats_print.c msg_stats_scan.c mynetworks.c \
mkmap_sdbm.c msg_stats_print.c msg_stats_scan.c mynetworks.c \
mypwd.c namadr_list.c off_cvt.c opened.c own_inet_addr.c \ mypwd.c namadr_list.c off_cvt.c opened.c own_inet_addr.c \
pipe_command.c post_mail.c quote_821_local.c quote_822_local.c \ pipe_command.c post_mail.c quote_821_local.c quote_822_local.c \
rcpt_buf.c rcpt_print.c rec_attr_map.c rec_streamlf.c rec_type.c \ rcpt_buf.c rcpt_print.c rec_attr_map.c rec_streamlf.c rec_type.c \
@ -32,7 +31,7 @@ SRCS = abounce.c anvil_clnt.c been_here.c bounce.c bounce_log.c \
match_service.c mail_conf_nint.c addr_match_list.c mail_conf_nbool.c \ match_service.c mail_conf_nint.c addr_match_list.c mail_conf_nbool.c \
smtp_reply_footer.c safe_ultostr.c verify_sender_addr.c \ smtp_reply_footer.c safe_ultostr.c verify_sender_addr.c \
dict_memcache.c mail_version.c memcache_proto.c server_acl.c \ dict_memcache.c mail_version.c memcache_proto.c server_acl.c \
mkmap_fail.c haproxy_srvr.c dsn_filter.c dynamicmaps.c uxtext.c \ haproxy_srvr.c dsn_filter.c dynamicmaps.c uxtext.c \
smtputf8.c mail_conf_over.c mail_parm_split.c midna_adomain.c \ smtputf8.c mail_conf_over.c mail_parm_split.c midna_adomain.c \
mail_addr_form.c quote_flags.c maillog_client.c \ mail_addr_form.c quote_flags.c maillog_client.c \
normalize_mailhost_addr.c map_search.c reject_deliver_request.c \ normalize_mailhost_addr.c map_search.c reject_deliver_request.c \
@ -56,8 +55,7 @@ OBJS = abounce.o anvil_clnt.o been_here.o bounce.o bounce_log.o \
mail_params.o mail_pathname.o mail_queue.o mail_run.o \ mail_params.o mail_pathname.o mail_queue.o mail_run.o \
mail_scan_dir.o mail_stream.o mail_task.o mail_trigger.o maps.o \ mail_scan_dir.o mail_stream.o mail_task.o mail_trigger.o maps.o \
mark_corrupt.o match_parent_style.o mbox_conf.o mbox_open.o \ mark_corrupt.o match_parent_style.o mbox_conf.o mbox_open.o \
mime_state.o mkmap_db.o mkmap_dbm.o mkmap_open.o \ mime_state.o msg_stats_print.o msg_stats_scan.o mynetworks.o \
msg_stats_print.o msg_stats_scan.o mynetworks.o \
mypwd.o namadr_list.o off_cvt.o opened.o own_inet_addr.o \ mypwd.o namadr_list.o off_cvt.o opened.o own_inet_addr.o \
pipe_command.o post_mail.o quote_821_local.o quote_822_local.o \ pipe_command.o post_mail.o quote_821_local.o quote_822_local.o \
rcpt_buf.o rcpt_print.o rec_attr_map.o rec_streamlf.o rec_type.o \ rcpt_buf.o rcpt_print.o rec_attr_map.o rec_streamlf.o rec_type.o \
@ -72,7 +70,7 @@ OBJS = abounce.o anvil_clnt.o been_here.o bounce.o bounce_log.o \
match_service.o mail_conf_nint.o addr_match_list.o mail_conf_nbool.o \ match_service.o mail_conf_nint.o addr_match_list.o mail_conf_nbool.o \
smtp_reply_footer.o safe_ultostr.o verify_sender_addr.o \ smtp_reply_footer.o safe_ultostr.o verify_sender_addr.o \
dict_memcache.o mail_version.o memcache_proto.o server_acl.o \ dict_memcache.o mail_version.o memcache_proto.o server_acl.o \
mkmap_fail.o haproxy_srvr.o dsn_filter.o dynamicmaps.o uxtext.o \ haproxy_srvr.o dsn_filter.o dynamicmaps.o uxtext.o \
smtputf8.o attr_override.o mail_parm_split.o midna_adomain.o \ smtputf8.o attr_override.o mail_parm_split.o midna_adomain.o \
$(NON_PLUGIN_MAP_OBJ) mail_addr_form.o quote_flags.o maillog_client.o \ $(NON_PLUGIN_MAP_OBJ) mail_addr_form.o quote_flags.o maillog_client.o \
normalize_mailhost_addr.o map_search.o reject_deliver_request.o \ normalize_mailhost_addr.o map_search.o reject_deliver_request.o \
@ -82,8 +80,8 @@ OBJS = abounce.o anvil_clnt.o been_here.o bounce.o bounce_log.o \
# MAP_OBJ is for maps that may be dynamically loaded with dynamicmaps.cf. # MAP_OBJ is for maps that may be dynamically loaded with dynamicmaps.cf.
# When hard-linking these maps, makedefs sets NON_PLUGIN_MAP_OBJ=$(MAP_OBJ), # When hard-linking these maps, makedefs sets NON_PLUGIN_MAP_OBJ=$(MAP_OBJ),
# otherwise it sets the PLUGIN_* macros. # otherwise it sets the PLUGIN_* macros.
MAP_OBJ = dict_ldap.o dict_mysql.o dict_pgsql.o dict_sqlite.o mkmap_cdb.o \ MAP_OBJ = dict_ldap.o dict_mysql.o dict_pgsql.o dict_sqlite.o
mkmap_lmdb.o mkmap_sdbm.o
HDRS = abounce.h anvil_clnt.h been_here.h bounce.h bounce_log.h \ HDRS = abounce.h anvil_clnt.h been_here.h bounce.h bounce_log.h \
canon_addr.h cfg_parser.h cleanup_user.h clnt_stream.h config.h \ canon_addr.h cfg_parser.h cleanup_user.h clnt_stream.h config.h \
conv_time.h db_common.h debug_peer.h debug_process.h defer.h \ conv_time.h db_common.h debug_peer.h debug_process.h defer.h \
@ -98,7 +96,7 @@ HDRS = abounce.h anvil_clnt.h been_here.h bounce.h bounce_log.h \
mail_open_ok.h mail_params.h mail_proto.h mail_queue.h mail_run.h \ mail_open_ok.h mail_params.h mail_proto.h mail_queue.h mail_run.h \
mail_scan_dir.h mail_stream.h mail_task.h mail_version.h maps.h \ mail_scan_dir.h mail_stream.h mail_task.h mail_version.h maps.h \
mark_corrupt.h match_parent_style.h mbox_conf.h mbox_open.h \ mark_corrupt.h match_parent_style.h mbox_conf.h mbox_open.h \
mime_state.h mkmap.h msg_stats.h mynetworks.h mypwd.h namadr_list.h \ mime_state.h msg_stats.h mynetworks.h mypwd.h namadr_list.h \
off_cvt.h opened.h own_inet_addr.h pipe_command.h post_mail.h \ off_cvt.h opened.h own_inet_addr.h pipe_command.h post_mail.h \
qmgr_user.h qmqp_proto.h quote_821_local.h quote_822_local.h \ qmgr_user.h qmqp_proto.h quote_821_local.h quote_822_local.h \
quote_flags.h rcpt_buf.h rcpt_print.h rec_attr_map.h rec_streamlf.h \ quote_flags.h rcpt_buf.h rcpt_print.h rec_attr_map.h rec_streamlf.h \
@ -138,9 +136,7 @@ LIBS = ../../lib/lib$(LIB_PREFIX)util$(LIB_SUFFIX)
LIB_DIR = ../../lib LIB_DIR = ../../lib
INC_DIR = ../../include INC_DIR = ../../include
PLUGIN_MAP_SO = $(LIB_PREFIX)ldap$(LIB_SUFFIX) $(LIB_PREFIX)mysql$(LIB_SUFFIX) \ PLUGIN_MAP_SO = $(LIB_PREFIX)ldap$(LIB_SUFFIX) $(LIB_PREFIX)mysql$(LIB_SUFFIX) \
$(LIB_PREFIX)pgsql$(LIB_SUFFIX) $(LIB_PREFIX)sqlite$(LIB_SUFFIX) \ $(LIB_PREFIX)pgsql$(LIB_SUFFIX) $(LIB_PREFIX)sqlite$(LIB_SUFFIX)
$(LIB_PREFIX)lmdb$(LIB_SUFFIX) $(LIB_PREFIX)cdb$(LIB_SUFFIX) \
$(LIB_PREFIX)sdbm$(LIB_SUFFIX)
MAKES = MAKES =
.c.o:; $(CC) $(SHLIB_CFLAGS) $(CFLAGS) -c $*.c .c.o:; $(CC) $(SHLIB_CFLAGS) $(CFLAGS) -c $*.c
@ -177,19 +173,6 @@ $(LIB_PREFIX)pgsql$(LIB_SUFFIX): dict_pgsql.o
$(LIB_PREFIX)sqlite$(LIB_SUFFIX): dict_sqlite.o $(LIB_PREFIX)sqlite$(LIB_SUFFIX): dict_sqlite.o
$(PLUGIN_LD) $(SHLIB_RPATH) -o $@ dict_sqlite.o $(AUXLIBS_SQLITE) $(PLUGIN_LD) $(SHLIB_RPATH) -o $@ dict_sqlite.o $(AUXLIBS_SQLITE)
$(LIB_PREFIX)cdb$(LIB_SUFFIX): mkmap_cdb.o $(LIB_DIR)/dict_cdb.o
$(PLUGIN_LD) $(SHLIB_RPATH) -o $@ mkmap_cdb.o \
$(LIB_DIR)/dict_cdb.o $(AUXLIBS_CDB)
$(LIB_PREFIX)lmdb$(LIB_SUFFIX): mkmap_lmdb.o $(LIB_DIR)/dict_lmdb.o \
$(LIB_DIR)/slmdb.o
$(PLUGIN_LD) $(SHLIB_RPATH) -o $@ mkmap_lmdb.o $(LIB_DIR)/dict_lmdb.o \
$(LIB_DIR)/slmdb.o $(AUXLIBS_LMDB)
$(LIB_PREFIX)sdbm$(LIB_SUFFIX): mkmap_sdbm.o $(LIB_DIR)/dict_sdbm.o
$(PLUGIN_LD) $(SHLIB_RPATH) -o $@ mkmap_sdbm.o \
$(LIB_DIR)/dict_sdbm.o $(AUXLIBS_SDBM)
update: $(LIB_DIR)/$(LIB) $(HDRS) $(PLUGIN_MAP_SO_UPDATE) update: $(LIB_DIR)/$(LIB) $(HDRS) $(PLUGIN_MAP_SO_UPDATE)
-for i in $(HDRS); \ -for i in $(HDRS); \
do \ do \
@ -1024,6 +1007,7 @@ data_redirect.o: ../../include/dict_cdb.h
data_redirect.o: ../../include/dict_db.h data_redirect.o: ../../include/dict_db.h
data_redirect.o: ../../include/dict_dbm.h data_redirect.o: ../../include/dict_dbm.h
data_redirect.o: ../../include/dict_lmdb.h data_redirect.o: ../../include/dict_lmdb.h
data_redirect.o: ../../include/mkmap.h
data_redirect.o: ../../include/msg.h data_redirect.o: ../../include/msg.h
data_redirect.o: ../../include/myflock.h data_redirect.o: ../../include/myflock.h
data_redirect.o: ../../include/name_code.h data_redirect.o: ../../include/name_code.h
@ -1273,6 +1257,7 @@ dict_proxy.o: ../../include/check_arg.h
dict_proxy.o: ../../include/dict.h dict_proxy.o: ../../include/dict.h
dict_proxy.o: ../../include/htable.h dict_proxy.o: ../../include/htable.h
dict_proxy.o: ../../include/iostuff.h dict_proxy.o: ../../include/iostuff.h
dict_proxy.o: ../../include/mkmap.h
dict_proxy.o: ../../include/msg.h dict_proxy.o: ../../include/msg.h
dict_proxy.o: ../../include/myflock.h dict_proxy.o: ../../include/myflock.h
dict_proxy.o: ../../include/mymalloc.h dict_proxy.o: ../../include/mymalloc.h
@ -1413,6 +1398,7 @@ dynamicmaps.o: ../../include/check_arg.h
dynamicmaps.o: ../../include/dict.h dynamicmaps.o: ../../include/dict.h
dynamicmaps.o: ../../include/htable.h dynamicmaps.o: ../../include/htable.h
dynamicmaps.o: ../../include/load_lib.h dynamicmaps.o: ../../include/load_lib.h
dynamicmaps.o: ../../include/mkmap.h
dynamicmaps.o: ../../include/msg.h dynamicmaps.o: ../../include/msg.h
dynamicmaps.o: ../../include/myflock.h dynamicmaps.o: ../../include/myflock.h
dynamicmaps.o: ../../include/mymalloc.h dynamicmaps.o: ../../include/mymalloc.h
@ -1426,7 +1412,6 @@ dynamicmaps.o: ../../include/vstring.h
dynamicmaps.o: ../../include/vstring_vstream.h dynamicmaps.o: ../../include/vstring_vstream.h
dynamicmaps.o: dynamicmaps.c dynamicmaps.o: dynamicmaps.c
dynamicmaps.o: dynamicmaps.h dynamicmaps.o: dynamicmaps.h
dynamicmaps.o: mkmap.h
ehlo_mask.o: ../../include/check_arg.h ehlo_mask.o: ../../include/check_arg.h
ehlo_mask.o: ../../include/name_mask.h ehlo_mask.o: ../../include/name_mask.h
ehlo_mask.o: ../../include/sys_defs.h ehlo_mask.o: ../../include/sys_defs.h
@ -1865,6 +1850,7 @@ mail_date.o: mail_date.h
mail_dict.o: ../../include/argv.h mail_dict.o: ../../include/argv.h
mail_dict.o: ../../include/check_arg.h mail_dict.o: ../../include/check_arg.h
mail_dict.o: ../../include/dict.h mail_dict.o: ../../include/dict.h
mail_dict.o: ../../include/mkmap.h
mail_dict.o: ../../include/msg.h mail_dict.o: ../../include/msg.h
mail_dict.o: ../../include/myflock.h mail_dict.o: ../../include/myflock.h
mail_dict.o: ../../include/mymalloc.h mail_dict.o: ../../include/mymalloc.h
@ -1926,6 +1912,7 @@ mail_params.o: ../../include/inet_addr_list.h
mail_params.o: ../../include/inet_proto.h mail_params.o: ../../include/inet_proto.h
mail_params.o: ../../include/iostuff.h mail_params.o: ../../include/iostuff.h
mail_params.o: ../../include/midna_domain.h mail_params.o: ../../include/midna_domain.h
mail_params.o: ../../include/mkmap.h
mail_params.o: ../../include/msg.h mail_params.o: ../../include/msg.h
mail_params.o: ../../include/msg_syslog.h mail_params.o: ../../include/msg_syslog.h
mail_params.o: ../../include/myaddrinfo.h mail_params.o: ../../include/myaddrinfo.h
@ -1941,8 +1928,8 @@ mail_params.o: ../../include/vbuf.h
mail_params.o: ../../include/vstream.h mail_params.o: ../../include/vstream.h
mail_params.o: ../../include/vstring.h mail_params.o: ../../include/vstring.h
mail_params.o: ../../include/vstring_vstream.h mail_params.o: ../../include/vstring_vstream.h
mail_params.o: config_known_tcp_ports.h
mail_params.o: compat_level.h mail_params.o: compat_level.h
mail_params.o: config_known_tcp_ports.h
mail_params.o: mail_conf.h mail_params.o: mail_conf.h
mail_params.o: mail_params.c mail_params.o: mail_params.c
mail_params.o: mail_params.h mail_params.o: mail_params.h
@ -2212,102 +2199,10 @@ mime_state.o: mail_params.h
mime_state.o: mime_state.c mime_state.o: mime_state.c
mime_state.o: mime_state.h mime_state.o: mime_state.h
mime_state.o: rec_type.h mime_state.o: rec_type.h
mkmap_cdb.o: ../../include/argv.h
mkmap_cdb.o: ../../include/check_arg.h
mkmap_cdb.o: ../../include/dict.h
mkmap_cdb.o: ../../include/dict_cdb.h
mkmap_cdb.o: ../../include/myflock.h
mkmap_cdb.o: ../../include/mymalloc.h
mkmap_cdb.o: ../../include/sys_defs.h
mkmap_cdb.o: ../../include/vbuf.h
mkmap_cdb.o: ../../include/vstream.h
mkmap_cdb.o: ../../include/vstring.h
mkmap_cdb.o: mkmap.h
mkmap_cdb.o: mkmap_cdb.c
mkmap_db.o: ../../include/argv.h
mkmap_db.o: ../../include/check_arg.h
mkmap_db.o: ../../include/dict.h
mkmap_db.o: ../../include/dict_db.h
mkmap_db.o: ../../include/msg.h
mkmap_db.o: ../../include/myflock.h
mkmap_db.o: ../../include/mymalloc.h
mkmap_db.o: ../../include/stringops.h
mkmap_db.o: ../../include/sys_defs.h
mkmap_db.o: ../../include/vbuf.h
mkmap_db.o: ../../include/vstream.h
mkmap_db.o: ../../include/vstring.h
mkmap_db.o: ../../include/warn_stat.h
mkmap_db.o: mail_params.h
mkmap_db.o: mkmap.h
mkmap_db.o: mkmap_db.c
mkmap_dbm.o: ../../include/argv.h
mkmap_dbm.o: ../../include/check_arg.h
mkmap_dbm.o: ../../include/dict.h
mkmap_dbm.o: ../../include/dict_dbm.h
mkmap_dbm.o: ../../include/msg.h
mkmap_dbm.o: ../../include/myflock.h
mkmap_dbm.o: ../../include/mymalloc.h
mkmap_dbm.o: ../../include/stringops.h
mkmap_dbm.o: ../../include/sys_defs.h
mkmap_dbm.o: ../../include/vbuf.h
mkmap_dbm.o: ../../include/vstream.h
mkmap_dbm.o: ../../include/vstring.h
mkmap_dbm.o: mkmap.h
mkmap_dbm.o: mkmap_dbm.c
mkmap_fail.o: ../../include/argv.h
mkmap_fail.o: ../../include/check_arg.h
mkmap_fail.o: ../../include/dict.h
mkmap_fail.o: ../../include/dict_fail.h
mkmap_fail.o: ../../include/myflock.h
mkmap_fail.o: ../../include/mymalloc.h
mkmap_fail.o: ../../include/sys_defs.h
mkmap_fail.o: ../../include/vbuf.h
mkmap_fail.o: ../../include/vstream.h
mkmap_fail.o: ../../include/vstring.h
mkmap_fail.o: mkmap.h
mkmap_fail.o: mkmap_fail.c
mkmap_lmdb.o: ../../include/argv.h
mkmap_lmdb.o: ../../include/check_arg.h
mkmap_lmdb.o: ../../include/dict.h
mkmap_lmdb.o: ../../include/dict_lmdb.h
mkmap_lmdb.o: ../../include/msg.h
mkmap_lmdb.o: ../../include/myflock.h
mkmap_lmdb.o: ../../include/mymalloc.h
mkmap_lmdb.o: ../../include/stringops.h
mkmap_lmdb.o: ../../include/sys_defs.h
mkmap_lmdb.o: ../../include/vbuf.h
mkmap_lmdb.o: ../../include/vstream.h
mkmap_lmdb.o: ../../include/vstring.h
mkmap_lmdb.o: ../../include/warn_stat.h
mkmap_lmdb.o: mail_conf.h
mkmap_lmdb.o: mail_params.h
mkmap_lmdb.o: mkmap.h
mkmap_lmdb.o: mkmap_lmdb.c
mkmap_open.o: ../../include/argv.h
mkmap_open.o: ../../include/check_arg.h
mkmap_open.o: ../../include/dict.h
mkmap_open.o: ../../include/dict_cdb.h
mkmap_open.o: ../../include/dict_db.h
mkmap_open.o: ../../include/dict_dbm.h
mkmap_open.o: ../../include/dict_fail.h
mkmap_open.o: ../../include/dict_lmdb.h
mkmap_open.o: ../../include/dict_sdbm.h
mkmap_open.o: ../../include/htable.h
mkmap_open.o: ../../include/msg.h
mkmap_open.o: ../../include/myflock.h
mkmap_open.o: ../../include/mymalloc.h
mkmap_open.o: ../../include/sigdelay.h
mkmap_open.o: ../../include/stringops.h
mkmap_open.o: ../../include/sys_defs.h
mkmap_open.o: ../../include/vbuf.h
mkmap_open.o: ../../include/vstream.h
mkmap_open.o: ../../include/vstring.h
mkmap_open.o: dict_proxy.h
mkmap_open.o: mkmap.h
mkmap_open.o: mkmap_open.c
mkmap_proxy.o: ../../include/argv.h mkmap_proxy.o: ../../include/argv.h
mkmap_proxy.o: ../../include/check_arg.h mkmap_proxy.o: ../../include/check_arg.h
mkmap_proxy.o: ../../include/dict.h mkmap_proxy.o: ../../include/dict.h
mkmap_proxy.o: ../../include/mkmap.h
mkmap_proxy.o: ../../include/myflock.h mkmap_proxy.o: ../../include/myflock.h
mkmap_proxy.o: ../../include/mymalloc.h mkmap_proxy.o: ../../include/mymalloc.h
mkmap_proxy.o: ../../include/sys_defs.h mkmap_proxy.o: ../../include/sys_defs.h
@ -2315,22 +2210,7 @@ mkmap_proxy.o: ../../include/vbuf.h
mkmap_proxy.o: ../../include/vstream.h mkmap_proxy.o: ../../include/vstream.h
mkmap_proxy.o: ../../include/vstring.h mkmap_proxy.o: ../../include/vstring.h
mkmap_proxy.o: dict_proxy.h mkmap_proxy.o: dict_proxy.h
mkmap_proxy.o: mkmap.h
mkmap_proxy.o: mkmap_proxy.c mkmap_proxy.o: mkmap_proxy.c
mkmap_sdbm.o: ../../include/argv.h
mkmap_sdbm.o: ../../include/check_arg.h
mkmap_sdbm.o: ../../include/dict.h
mkmap_sdbm.o: ../../include/dict_sdbm.h
mkmap_sdbm.o: ../../include/msg.h
mkmap_sdbm.o: ../../include/myflock.h
mkmap_sdbm.o: ../../include/mymalloc.h
mkmap_sdbm.o: ../../include/stringops.h
mkmap_sdbm.o: ../../include/sys_defs.h
mkmap_sdbm.o: ../../include/vbuf.h
mkmap_sdbm.o: ../../include/vstream.h
mkmap_sdbm.o: ../../include/vstring.h
mkmap_sdbm.o: mkmap.h
mkmap_sdbm.o: mkmap_sdbm.c
msg_stats_print.o: ../../include/attr.h msg_stats_print.o: ../../include/attr.h
msg_stats_print.o: ../../include/check_arg.h msg_stats_print.o: ../../include/check_arg.h
msg_stats_print.o: ../../include/htable.h msg_stats_print.o: ../../include/htable.h

View File

@ -266,7 +266,7 @@ static MAC_EXP_OP_RES compat_relop_eval(const char *left_str, int relop,
const char *rite_str) const char *rite_str)
{ {
const char myname[] = "compat_relop_eval"; const char myname[] = "compat_relop_eval";
long left_val, rite_val; long left_val, rite_val, delta;
/* /*
* Negative result means error. * Negative result means error.
@ -279,7 +279,7 @@ static MAC_EXP_OP_RES compat_relop_eval(const char *left_str, int relop,
* Valid result. The difference between non-negative numbers will no * Valid result. The difference between non-negative numbers will no
* overflow. * overflow.
*/ */
long delta = left_val - rite_val; delta = left_val - rite_val;
switch (relop) { switch (relop) {
case MAC_EXP_OP_TOK_EQ: case MAC_EXP_OP_TOK_EQ:

View File

@ -27,8 +27,6 @@ extern const char *compat_level_to_string(long,
#define compat_level_from_major_minor(major, minor, msg_fn) \ #define compat_level_from_major_minor(major, minor, msg_fn) \
compat_level_from_numbers((major), (minor), 0, (msg_fn)) compat_level_from_numbers((major), (minor), 0, (msg_fn))
#
/* LICENSE /* LICENSE
/* .ad /* .ad
/* .fi /* .fi

View File

@ -15,6 +15,7 @@
* Utility library. * Utility library.
*/ */
#include <dict.h> #include <dict.h>
#include <mkmap.h>
/* /*
* External interface. * External interface.
@ -22,6 +23,7 @@
#define DICT_TYPE_PROXY "proxy" #define DICT_TYPE_PROXY "proxy"
extern DICT *dict_proxy_open(const char *, int, int); extern DICT *dict_proxy_open(const char *, int, int);
extern MKMAP *mkmap_proxy_open(const char *);
/* /*
* Protocol interface. * Protocol interface.
@ -48,6 +50,11 @@ extern DICT *dict_proxy_open(const char *, int, int);
/* IBM T.J. Watson Research /* IBM T.J. Watson Research
/* P.O. Box 704 /* P.O. Box 704
/* Yorktown Heights, NY 10598, USA /* Yorktown Heights, NY 10598, USA
/*
/* Wietse Venema
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*--*/ /*--*/
#endif #endif

View File

@ -8,23 +8,26 @@
/* /*
/* void dymap_init(const char *conf_path, const char *plugin_dir) /* void dymap_init(const char *conf_path, const char *plugin_dir)
/* DESCRIPTION /* DESCRIPTION
/* This module reads the dynamicmaps.cf file and performs /* This module reads the dynamicmaps.cf file and on-demand
/* run-time loading of Postfix dictionaries. Each dynamicmaps.cf /* loads Postfix dictionaries. Each dynamicmaps.cf entry
/* entry specifies the name of a dictionary type, the pathname /* specifies the name of a dictionary type, the pathname of a
/* of a shared-library object, the name of a "dict_open" /* shared-library object, the name of a "dict_open" function
/* function for access to individual dictionary entries, and /* for access to individual dictionary entries, and optionally
/* optionally the name of a "mkmap_open" function for bulk-mode /* the name of a "mkmap_open" wrapper function for bulk-mode
/* dictionary creation. Plugins may be specified with a relative /* dictionary creation. Plugins may be specified with a relative
/* pathname. /* pathname.
/* /*
/* A dictionary may be installed without editing the file /* A dictionary shared object may be installed on a system
/* dynamicmaps.cf, by placing a configuration file under the /* without editing the file dynamicmaps.cf, by placing a
/* directory dynamicmaps.cf.d, with the same format as /* configuration file under the directory dynamicmaps.cf.d,
/* dynamicmaps.cf. /* with the same format as dynamicmaps.cf.
/* /*
/* dymap_init() reads the specified configuration file which /* dymap_init() reads the specified configuration file which
/* is in dynamicmaps.cf format, and hooks itself into the /* must be in dynamicmaps.cf format, appends ".d" to the path
/* dict_open(), dict_mapnames(), and mkmap_open() functions. /* and scans the named directory for other configuration files,
/* and on the first call hooks itself into the dict_open() and
/* dict_mapnames() functions. All files are optional, but if
/* an existing file cannot be opened, that is a fatal error.
/* /*
/* dymap_init() may be called multiple times during a process /* dymap_init() may be called multiple times during a process
/* lifetime, but it will not "unload" dictionaries that have /* lifetime, but it will not "unload" dictionaries that have
@ -34,14 +37,19 @@
/* /*
/* Arguments: /* Arguments:
/* .IP conf_path /* .IP conf_path
/* Pathname for the dynamicmaps configuration file. /* Pathname for the dynamicmaps configuration file. With ".d"
/* appended, this becomes the pathname for a directory with
/* other files in dynamicmaps.cf format.
/* .IP plugin_dir /* .IP plugin_dir
/* Default directory for plugins with a relative pathname. /* Default directory for plugins with a relative pathname.
/* SEE ALSO /* SEE ALSO
/* load_lib(3) low-level run-time linker adapter /* load_lib(3) low-level run-time linker adapter.
/* DIAGNOSTICS /* DIAGNOSTICS
/* Fatal errors: memory allocation problem, dictionary or /* Warnings: unsupported dictionary type, shared object file
/* dictionary function not available. Panic: invalid use. /* does not exist, shared object permissions are not safe-for-root,
/* configuration file permissions are not safe-for-root.
/* Fatal errors: memory allocation problem, error opening an
/* existing configuration file, bad configuration file syntax.
/* LICENSE /* LICENSE
/* .ad /* .ad
/* .fi /* .fi
@ -56,6 +64,11 @@
/* IBM T.J. Watson Research /* IBM T.J. Watson Research
/* P.O. Box 704 /* P.O. Box 704
/* Yorktown Heights, NY 10598, USA /* Yorktown Heights, NY 10598, USA
/*
/* Wietse Venema
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*--*/ /*--*/
/* /*
@ -75,6 +88,7 @@
#include <htable.h> #include <htable.h>
#include <argv.h> #include <argv.h>
#include <dict.h> #include <dict.h>
#include <mkmap.h>
#include <load_lib.h> #include <load_lib.h>
#include <vstring.h> #include <vstring.h>
#include <vstream.h> #include <vstream.h>
@ -86,7 +100,6 @@
/* /*
* Global library. * Global library.
*/ */
#include <mkmap.h>
#include <dynamicmaps.h> #include <dynamicmaps.h>
#ifdef USE_DYNAMIC_MAPS #ifdef USE_DYNAMIC_MAPS
@ -103,34 +116,43 @@ typedef struct {
static HTABLE *dymap_info; static HTABLE *dymap_info;
static int dymap_hooks_done = 0; static int dymap_hooks_done = 0;
static DICT_OPEN_EXTEND_FN saved_dict_open_hook = 0; static DICT_OPEN_EXTEND_FN saved_dict_open_hook = 0;
static MKMAP_OPEN_EXTEND_FN saved_mkmap_open_hook = 0;
static DICT_MAPNAMES_EXTEND_FN saved_dict_mapnames_hook = 0; static DICT_MAPNAMES_EXTEND_FN saved_dict_mapnames_hook = 0;
#define STREQ(x, y) (strcmp((x), (y)) == 0) #define STREQ(x, y) (strcmp((x), (y)) == 0)
/* dymap_dict_lookup - look up "dict_foo_open" function */
static DICT_OPEN_FN dymap_dict_lookup(const char *dict_type) /* dymap_dict_lookup - look up DICT_OPEN_INFO */
static const DICT_OPEN_INFO *dymap_dict_lookup(const char *dict_type)
{ {
const char myname[] = "dymap_dict_lookup";
struct stat st; struct stat st;
LIB_FN fn[2]; LIB_FN fn[3];
DICT_OPEN_FN dict_open_fn;
DYMAP_INFO *dp; DYMAP_INFO *dp;
const DICT_OPEN_INFO *op;
DICT_OPEN_INFO *np;
if (msg_verbose > 1)
msg_info("%s: %s", myname, dict_type);
/* /*
* Respect the hook nesting order. * Respect the hook nesting order.
*/ */
if (saved_dict_open_hook != 0 if (saved_dict_open_hook != 0
&& (dict_open_fn = saved_dict_open_hook(dict_type)) != 0) && (op = saved_dict_open_hook(dict_type)) != 0)
return (dict_open_fn); return (op);
/* /*
* Allow for graceful degradation when a database is unavailable. This * Allow for graceful degradation when a database is unavailable. This
* allows Postfix daemon processes to continue handling email with * allows Postfix daemon processes to continue handling email with
* reduced functionality. * reduced functionality.
*/ */
if ((dp = (DYMAP_INFO *) htable_find(dymap_info, dict_type)) == 0) if ((dp = (DYMAP_INFO *) htable_find(dymap_info, dict_type)) == 0) {
msg_warn("unsupported dictionary type: %s. "
"Is the postfix-%s package installed?",
dict_type, dict_type);
return (0); return (0);
}
if (stat(dp->soname, &st) < 0) { if (stat(dp->soname, &st) < 0) {
msg_warn("unsupported dictionary type: %s (%s: %m)", msg_warn("unsupported dictionary type: %s (%s: %m)",
dict_type, dp->soname); dict_type, dp->soname);
@ -142,64 +164,15 @@ static DICT_OPEN_FN dymap_dict_lookup(const char *dict_type)
dict_type, dp->soname); dict_type, dp->soname);
return (0); return (0);
} }
fn[0].name = dp->dict_name; fn[0].name = dp->dict_name; /* not null */
fn[1].name = 0; fn[1].name = dp->mkmap_name; /* may be null */
fn[2].name = 0;
load_library_symbols(dp->soname, fn, (LIB_DP *) 0); load_library_symbols(dp->soname, fn, (LIB_DP *) 0);
return ((DICT_OPEN_FN) fn[0].fptr); np = (DICT_OPEN_INFO *) mymalloc(sizeof(*op));
} np->type = mystrdup(dict_type);
np->dict_fn = (DICT_OPEN_FN) fn[0].fptr;
/* dymap_mkmap_lookup - look up "mkmap_foo_open" function */ np->mkmap_fn = (MKMAP_OPEN_FN) (dp->mkmap_name ? fn[1].fptr : 0);
return (np);
static MKMAP_OPEN_FN dymap_mkmap_lookup(const char *dict_type)
{
struct stat st;
LIB_FN fn[2];
MKMAP_OPEN_FN mkmap_open_fn;
DYMAP_INFO *dp;
/*
* Respect the hook nesting order.
*/
if (saved_mkmap_open_hook != 0
&& (mkmap_open_fn = saved_mkmap_open_hook(dict_type)) != 0)
return (mkmap_open_fn);
/*
* All errors are fatal. If the postmap(1) or postalias(1) command can't
* create the requested database, then graceful degradation is not
* useful.
*
* Fix 20220416: if this dictionary type is registered for some non-mkmap
* purpose, then don't talk nonsense about a missing package.
*/
if ((dp = (DYMAP_INFO *) htable_find(dymap_info, dict_type)) == 0) {
ARGV *types = dict_mapnames();
char **cpp;
for (cpp = types->argv; *cpp; cpp++) {
if (strcmp(dict_type, *cpp) == 0)
msg_fatal("unsupported dictionary type: %s does not support "
"bulk-mode creation.", dict_type);
}
msg_fatal("unsupported dictionary type: %s. "
"Is the postfix-%s package installed?",
dict_type, dict_type);
}
if (!dp->mkmap_name)
msg_fatal("unsupported dictionary type: %s does not support "
"bulk-mode creation.", dict_type);
if (stat(dp->soname, &st) < 0)
msg_fatal("unsupported dictionary type: %s (%s: %m). "
"Is the postfix-%s package installed?",
dict_type, dp->soname, dict_type);
if (st.st_uid != 0 || (st.st_mode & (S_IWGRP | S_IWOTH)) != 0)
msg_fatal("unsupported dictionary type: %s "
"(%s: file is owned or writable by non-root users)",
dict_type, dp->soname);
fn[0].name = dp->mkmap_name;
fn[1].name = 0;
load_library_symbols(dp->soname, fn, (LIB_DP *) 0);
return ((MKMAP_OPEN_FN) fn[0].fptr);
} }
/* dymap_list - enumerate dynamically-linked database type names */ /* dymap_list - enumerate dynamically-linked database type names */
@ -249,6 +222,7 @@ static void dymap_entry_free(void *ptr)
static void dymap_read_conf(const char *path, const char *path_base) static void dymap_read_conf(const char *path, const char *path_base)
{ {
const char myname[] = "dymap_read_conf";
VSTREAM *fp; VSTREAM *fp;
VSTRING *buf; VSTRING *buf;
char *cp; char *cp;
@ -260,6 +234,8 @@ static void dymap_read_conf(const char *path, const char *path_base)
* Silently ignore a missing dynamicmaps.cf file, but be explicit about * Silently ignore a missing dynamicmaps.cf file, but be explicit about
* problems when the file does exist. * problems when the file does exist.
*/ */
if (msg_verbose > 1)
msg_info("%s: opening %s", myname, path);
if ((fp = vstream_fopen(path, O_RDONLY, 0)) != 0) { if ((fp = vstream_fopen(path, O_RDONLY, 0)) != 0) {
if (fstat(vstream_fileno(fp), &st) < 0) if (fstat(vstream_fileno(fp), &st) < 0)
msg_fatal("%s: fstat failed; %m", path); msg_fatal("%s: fstat failed; %m", path);
@ -270,6 +246,8 @@ static void dymap_read_conf(const char *path, const char *path_base)
buf = vstring_alloc(100); buf = vstring_alloc(100);
while (vstring_get_nonl(buf, fp) != VSTREAM_EOF) { while (vstring_get_nonl(buf, fp) != VSTREAM_EOF) {
cp = vstring_str(buf); cp = vstring_str(buf);
if (msg_verbose > 1)
msg_info("%s: read: %s", myname, cp);
linenum++; linenum++;
if (*cp == '#' || *cp == '\0') if (*cp == '#' || *cp == '\0')
continue; continue;
@ -296,13 +274,11 @@ static void dymap_read_conf(const char *path, const char *path_base)
vstring_free(buf); vstring_free(buf);
/* /*
* Once-only: hook into the dict_open(3) and mkmap_open(3) * Once-only: hook into the dict_open(3) infrastructure.
* infrastructure,
*/ */
if (dymap_hooks_done == 0) { if (dymap_hooks_done == 0) {
dymap_hooks_done = 1; dymap_hooks_done = 1;
saved_dict_open_hook = dict_open_extend(dymap_dict_lookup); saved_dict_open_hook = dict_open_extend(dymap_dict_lookup);
saved_mkmap_open_hook = mkmap_open_extend(dymap_mkmap_lookup);
saved_dict_mapnames_hook = dict_mapnames_extend(dymap_list); saved_dict_mapnames_hook = dict_mapnames_extend(dymap_list);
} }
} }
@ -322,6 +298,9 @@ void dymap_init(const char *conf_path, const char *plugin_dir)
const char *conf_name; const char *conf_name;
VSTRING *sub_conf_path; VSTRING *sub_conf_path;
if (msg_verbose > 1)
msg_info("%s: %s %s", myname, conf_path, plugin_dir);
/* /*
* Reload dynamicmaps.cf, but don't reload already-loaded plugins. * Reload dynamicmaps.cf, but don't reload already-loaded plugins.
*/ */

View File

@ -78,6 +78,11 @@ extern const char hbc_checks_unknown;
/* IBM T.J. Watson Research /* IBM T.J. Watson Research
/* P.O. Box 704 /* P.O. Box 704
/* Yorktown Heights, NY 10598, USA /* Yorktown Heights, NY 10598, USA
/*
/* Wietse Venema
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*--*/ /*--*/
#endif #endif

View File

@ -25,6 +25,11 @@
/* IBM T.J. Watson Research /* IBM T.J. Watson Research
/* P.O. Box 704 /* P.O. Box 704
/* Yorktown Heights, NY 10598, USA /* Yorktown Heights, NY 10598, USA
/*
/* Wietse Venema
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*--*/ /*--*/
/* System library. */ /* System library. */
@ -51,28 +56,23 @@
#include <mail_params.h> #include <mail_params.h>
#include <mail_dict.h> #include <mail_dict.h>
typedef struct {
char *type;
struct DICT *(*open) (const char *, int, int);
} DICT_OPEN_INFO;
static const DICT_OPEN_INFO dict_open_info[] = { static const DICT_OPEN_INFO dict_open_info[] = {
DICT_TYPE_PROXY, dict_proxy_open, DICT_TYPE_PROXY, dict_proxy_open, mkmap_proxy_open,
#ifndef USE_DYNAMIC_MAPS #ifndef USE_DYNAMIC_MAPS
#ifdef HAS_LDAP #ifdef HAS_LDAP
DICT_TYPE_LDAP, dict_ldap_open, DICT_TYPE_LDAP, dict_ldap_open, 0,
#endif #endif
#ifdef HAS_MYSQL #ifdef HAS_MYSQL
DICT_TYPE_MYSQL, dict_mysql_open, DICT_TYPE_MYSQL, dict_mysql_open, 0,
#endif #endif
#ifdef HAS_PGSQL #ifdef HAS_PGSQL
DICT_TYPE_PGSQL, dict_pgsql_open, DICT_TYPE_PGSQL, dict_pgsql_open, 0,
#endif #endif
#ifdef HAS_SQLITE #ifdef HAS_SQLITE
DICT_TYPE_SQLITE, dict_sqlite_open, DICT_TYPE_SQLITE, dict_sqlite_open, 0,
#endif #endif
#endif /* !USE_DYNAMIC_MAPS */ #endif /* !USE_DYNAMIC_MAPS */
DICT_TYPE_MEMCACHE, dict_memcache_open, DICT_TYPE_MEMCACHE, dict_memcache_open, 0,
0, 0,
}; };
@ -95,7 +95,7 @@ void mail_dict_init(void)
#endif #endif
for (dp = dict_open_info; dp->type; dp++) for (dp = dict_open_info; dp->type; dp++)
dict_open_register(dp->type, dp->open); dict_open_register(dp);
} }
#ifdef TEST #ifdef TEST

View File

@ -20,7 +20,7 @@
* Patches change both the patchlevel and the release date. Snapshots have no * Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only. * patchlevel; they change the release date only.
*/ */
#define MAIL_RELEASE_DATE "20220421" #define MAIL_RELEASE_DATE "20220507"
#define MAIL_VERSION_NUMBER "3.8" #define MAIL_VERSION_NUMBER "3.8"
#ifdef SNAPSHOT #ifdef SNAPSHOT

View File

@ -95,6 +95,11 @@
/* IBM T.J. Watson Research /* IBM T.J. Watson Research
/* P.O. Box 704 /* P.O. Box 704
/* Yorktown Heights, NY 10598, USA /* Yorktown Heights, NY 10598, USA
/*
/* Wietse Venema
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*--*/ /*--*/
/* System library. */ /* System library. */

View File

@ -1,64 +0,0 @@
#ifndef _MKMAP_H_INCLUDED_
#define _MKMAP_H_INCLUDED_
/*++
/* NAME
/* mkmap 3h
/* SUMMARY
/* create or rewrite Postfix database
/* SYNOPSIS
/* #include <mkmap.h>
/* DESCRIPTION
/* .nf
/*
* Utility library.
*/
#include <dict.h>
/*
* A database handle is an opaque structure. The user is not supposed to
* know its implementation. We try to open and lock a file before DB/DBM
* initialization. However, if the file does not exist then we may have to
* acquire the lock after the DB/DBM initialization.
*/
typedef struct MKMAP {
DICT_OPEN_FN open; /* dict_xx_open() */
struct DICT *dict; /* dict_xx_open() result */
void (*after_open) (struct MKMAP *); /* may be null */
void (*after_close) (struct MKMAP *); /* may be null */
int multi_writer; /* multi-writer safe */
} MKMAP;
extern MKMAP *mkmap_open(const char *, const char *, int, int);
extern void mkmap_append(MKMAP *, const char *, const char *);
extern void mkmap_close(MKMAP *);
#define mkmap_append(map, key, val) dict_put((map)->dict, (key), (val))
extern MKMAP *mkmap_dbm_open(const char *);
extern MKMAP *mkmap_cdb_open(const char *);
extern MKMAP *mkmap_hash_open(const char *);
extern MKMAP *mkmap_btree_open(const char *);
extern MKMAP *mkmap_lmdb_open(const char *);
extern MKMAP *mkmap_sdbm_open(const char *);
extern MKMAP *mkmap_proxy_open(const char *);
extern MKMAP *mkmap_fail_open(const char *);
typedef MKMAP *(*MKMAP_OPEN_FN) (const char *);
typedef MKMAP_OPEN_FN (*MKMAP_OPEN_EXTEND_FN) (const char *);
extern void mkmap_open_register(const char *, MKMAP_OPEN_FN);
extern MKMAP_OPEN_EXTEND_FN mkmap_open_extend(MKMAP_OPEN_EXTEND_FN);
/* 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
/*--*/
#endif

View File

@ -4,7 +4,7 @@
/* SUMMARY /* SUMMARY
/* create or proxied database /* create or proxied database
/* SYNOPSIS /* SYNOPSIS
/* #include <mkmap.h> /* #include <dict_proxy.h>
/* /*
/* MKMAP *mkmap_proxy_open(path) /* MKMAP *mkmap_proxy_open(path)
/* const char *path; /* const char *path;
@ -26,6 +26,11 @@
/* IBM T.J. Watson Research /* IBM T.J. Watson Research
/* P.O. Box 704 /* P.O. Box 704
/* Yorktown Heights, NY 10598, USA /* Yorktown Heights, NY 10598, USA
/*
/* Wietse Venema
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*--*/ /*--*/
/* System library. */ /* System library. */
@ -37,10 +42,6 @@
#include <mymalloc.h> #include <mymalloc.h>
#include <dict_proxy.h> #include <dict_proxy.h>
/* Application-specific. */
#include "mkmap.h"
/* mkmap_proxy_open - create or open database */ /* mkmap_proxy_open - create or open database */
MKMAP *mkmap_proxy_open(const char *unused_path) MKMAP *mkmap_proxy_open(const char *unused_path)

View File

@ -93,6 +93,7 @@ postalias.o: ../../include/argv.h
postalias.o: ../../include/check_arg.h postalias.o: ../../include/check_arg.h
postalias.o: ../../include/clean_env.h postalias.o: ../../include/clean_env.h
postalias.o: ../../include/dict.h postalias.o: ../../include/dict.h
postalias.o: ../../include/dict_db.h
postalias.o: ../../include/dict_proxy.h postalias.o: ../../include/dict_proxy.h
postalias.o: ../../include/mail_conf.h postalias.o: ../../include/mail_conf.h
postalias.o: ../../include/mail_dict.h postalias.o: ../../include/mail_dict.h

View File

@ -264,6 +264,7 @@
#include <set_eugid.h> #include <set_eugid.h>
#include <warn_stat.h> #include <warn_stat.h>
#include <clean_env.h> #include <clean_env.h>
#include <dict_db.h>
/* Global library. */ /* Global library. */
@ -272,7 +273,6 @@
#include <mail_dict.h> #include <mail_dict.h>
#include <mail_params.h> #include <mail_params.h>
#include <mail_version.h> #include <mail_version.h>
#include <mkmap.h>
#include <mail_task.h> #include <mail_task.h>
#include <dict_proxy.h> #include <dict_proxy.h>
#include <mail_parm_split.h> #include <mail_parm_split.h>
@ -342,6 +342,24 @@ static void postalias(char *map_type, char *path_name, int postalias_flags,
&& (st.st_uid != geteuid() || st.st_gid != getegid())) && (st.st_uid != geteuid() || st.st_gid != getegid()))
set_eugid(st.st_uid, st.st_gid); set_eugid(st.st_uid, st.st_gid);
/*
* Override the default per-table cache size for DB map (re)builds. We
* can't do this in the mkmap* functions because those don't have access
* to Postfix parameter settings.
*
* db_cache_size" is defined in util/dict_open.c and defaults to 128kB,
* which works well for the lookup code.
*
* We use a larger per-table cache when building ".db" files. For "hash"
* files performance degrades rapidly unless the memory pool is O(file
* size).
*
* For "btree" files performance is good with sorted input even for small
* memory pools, but with random input degrades rapidly unless the memory
* pool is O(file size).
*/
dict_db_cache_size = var_db_create_buf;
/* /*
* Open the database, create it when it does not exist, truncate it when * Open the database, create it when it does not exist, truncate it when
* it does exist, and lock out any spectators. * it does exist, and lock out any spectators.

View File

@ -1080,6 +1080,7 @@ postconf_dbms.o: ../../include/mac_expand.h
postconf_dbms.o: ../../include/mac_parse.h postconf_dbms.o: ../../include/mac_parse.h
postconf_dbms.o: ../../include/mail_conf.h postconf_dbms.o: ../../include/mail_conf.h
postconf_dbms.o: ../../include/mail_params.h postconf_dbms.o: ../../include/mail_params.h
postconf_dbms.o: ../../include/mkmap.h
postconf_dbms.o: ../../include/msg.h postconf_dbms.o: ../../include/msg.h
postconf_dbms.o: ../../include/myflock.h postconf_dbms.o: ../../include/myflock.h
postconf_dbms.o: ../../include/mymalloc.h postconf_dbms.o: ../../include/mymalloc.h

View File

@ -133,6 +133,7 @@ postmap.o: ../../include/argv.h
postmap.o: ../../include/check_arg.h postmap.o: ../../include/check_arg.h
postmap.o: ../../include/clean_env.h postmap.o: ../../include/clean_env.h
postmap.o: ../../include/dict.h postmap.o: ../../include/dict.h
postmap.o: ../../include/dict_db.h
postmap.o: ../../include/dict_proxy.h postmap.o: ../../include/dict_proxy.h
postmap.o: ../../include/header_opts.h postmap.o: ../../include/header_opts.h
postmap.o: ../../include/mail_conf.h postmap.o: ../../include/mail_conf.h

View File

@ -343,6 +343,7 @@
#include <set_eugid.h> #include <set_eugid.h>
#include <warn_stat.h> #include <warn_stat.h>
#include <clean_env.h> #include <clean_env.h>
#include <dict_db.h>
/* Global library. */ /* Global library. */
@ -350,7 +351,6 @@
#include <mail_dict.h> #include <mail_dict.h>
#include <mail_params.h> #include <mail_params.h>
#include <mail_version.h> #include <mail_version.h>
#include <mkmap.h>
#include <mail_task.h> #include <mail_task.h>
#include <dict_proxy.h> #include <dict_proxy.h>
#include <mime_state.h> #include <mime_state.h>
@ -435,6 +435,24 @@ static void postmap(char *map_type, char *path_name, int postmap_flags,
&& (st.st_uid != geteuid() || st.st_gid != getegid())) && (st.st_uid != geteuid() || st.st_gid != getegid()))
set_eugid(st.st_uid, st.st_gid); set_eugid(st.st_uid, st.st_gid);
/*
* Override the default per-table cache size for DB map (re)builds. We
* can't do this in the mkmap* functions because those don't have access
* to Postfix parameter settings.
*
* db_cache_size" is defined in util/dict_open.c and defaults to 128kB,
* which works well for the lookup code.
*
* We use a larger per-table cache when building ".db" files. For "hash"
* files performance degrades rapidly unless the memory pool is O(file
* size).
*
* For "btree" files performance is good with sorted input even for small
* memory pools, but with random input degrades rapidly unless the memory
* pool is O(file size).
*/
dict_db_cache_size = var_db_create_buf;
/* /*
* Open the database, optionally create it when it does not exist, * Open the database, optionally create it when it does not exist,
* optionally truncate it when it does exist, and lock out any * optionally truncate it when it does exist, and lock out any
@ -660,8 +678,8 @@ static int postmap_queries(VSTREAM *in, char **maps, const int map_count,
dicts[n] = 0; dicts[n] = 0;
/* /*
* Perform all queries. Open maps on the fly, to avoid opening unnecessary * Perform all queries. Open maps on the fly, to avoid opening
* maps. * unnecessary maps.
*/ */
if ((postmap_flags & POSTMAP_FLAG_HB_KEY) == 0) { if ((postmap_flags & POSTMAP_FLAG_HB_KEY) == 0) {
while (vstring_get_nonl(keybuf, in) != VSTREAM_EOF) { while (vstring_get_nonl(keybuf, in) != VSTREAM_EOF) {

View File

@ -435,7 +435,7 @@ static int psc_starttls_cmd(PSC_STATE *state, char *args)
* unavailable when tlsproxy(8) detects the problem too late. * unavailable when tlsproxy(8) detects the problem too late.
*/ */
if (PSC_SMTPD_NEXT_TOKEN(args) != 0) if (PSC_SMTPD_NEXT_TOKEN(args) != 0)
return (PSC_SEND_REPLY(state, "501 Syntax: EHLO hostname\r\n")); return (PSC_SEND_REPLY(state, "501 5.5.4 Syntax: STARTTLS\r\n"));
if (state->flags & PSC_STATE_FLAG_USING_TLS) if (state->flags & PSC_STATE_FLAG_USING_TLS)
return (PSC_SEND_REPLY(state, return (PSC_SEND_REPLY(state,
"554 5.5.1 Error: TLS already active\r\n")); "554 5.5.1 Error: TLS already active\r\n"));

View File

@ -73,6 +73,7 @@ proxymap.o: ../../include/mail_params.h
proxymap.o: ../../include/mail_proto.h proxymap.o: ../../include/mail_proto.h
proxymap.o: ../../include/mail_server.h proxymap.o: ../../include/mail_server.h
proxymap.o: ../../include/mail_version.h proxymap.o: ../../include/mail_version.h
proxymap.o: ../../include/mkmap.h
proxymap.o: ../../include/msg.h proxymap.o: ../../include/msg.h
proxymap.o: ../../include/myflock.h proxymap.o: ../../include/myflock.h
proxymap.o: ../../include/mymalloc.h proxymap.o: ../../include/mymalloc.h

View File

@ -567,6 +567,7 @@ smtp_sasl_auth_cache.o: ../../include/htable.h
smtp_sasl_auth_cache.o: ../../include/maps.h smtp_sasl_auth_cache.o: ../../include/maps.h
smtp_sasl_auth_cache.o: ../../include/match_list.h smtp_sasl_auth_cache.o: ../../include/match_list.h
smtp_sasl_auth_cache.o: ../../include/mime_state.h smtp_sasl_auth_cache.o: ../../include/mime_state.h
smtp_sasl_auth_cache.o: ../../include/mkmap.h
smtp_sasl_auth_cache.o: ../../include/msg.h smtp_sasl_auth_cache.o: ../../include/msg.h
smtp_sasl_auth_cache.o: ../../include/msg_stats.h smtp_sasl_auth_cache.o: ../../include/msg_stats.h
smtp_sasl_auth_cache.o: ../../include/myaddrinfo.h smtp_sasl_auth_cache.o: ../../include/myaddrinfo.h

View File

@ -43,7 +43,8 @@ SRCS = alldig.c allprint.c argv.c argv_split.c attr_clnt.c attr_print0.c \
split_qnameval.c argv_attr_print.c argv_attr_scan.c dict_file.c \ split_qnameval.c argv_attr_print.c argv_attr_scan.c dict_file.c \
msg_logger.c logwriter.c unix_dgram_connect.c unix_dgram_listen.c \ msg_logger.c logwriter.c unix_dgram_connect.c unix_dgram_listen.c \
byte_mask.c known_tcp_ports.c argv_split_at.c dict_stream.c \ byte_mask.c known_tcp_ports.c argv_split_at.c dict_stream.c \
sane_strtol.c hash_fnv.c ldseed.c sane_strtol.c hash_fnv.c ldseed.c mkmap_cdb.c mkmap_db.c mkmap_dbm.c \
mkmap_fail.c mkmap_lmdb.c mkmap_open.c mkmap_sdbm.c
OBJS = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \ OBJS = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
attr_print64.o attr_print_plain.o attr_scan0.o attr_scan64.o \ attr_print64.o attr_print_plain.o attr_scan0.o attr_scan64.o \
attr_scan_plain.o auto_clnt.o base64_code.o basename.o binhash.o \ attr_scan_plain.o auto_clnt.o base64_code.o basename.o binhash.o \
@ -88,12 +89,13 @@ OBJS = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
split_qnameval.o argv_attr_print.o argv_attr_scan.o dict_file.o \ split_qnameval.o argv_attr_print.o argv_attr_scan.o dict_file.o \
msg_logger.o logwriter.o unix_dgram_connect.o unix_dgram_listen.o \ msg_logger.o logwriter.o unix_dgram_connect.o unix_dgram_listen.o \
byte_mask.o known_tcp_ports.o argv_split_at.o dict_stream.o \ byte_mask.o known_tcp_ports.o argv_split_at.o dict_stream.o \
sane_strtol.o hash_fnv.o ldseed.o sane_strtol.o hash_fnv.o ldseed.o mkmap_db.o mkmap_dbm.o \
mkmap_fail.o mkmap_open.o
# MAP_OBJ is for maps that may be dynamically loaded with dynamicmaps.cf. # MAP_OBJ is for maps that may be dynamically loaded with dynamicmaps.cf.
# When hard-linking these, makedefs sets NON_PLUGIN_MAP_OBJ=$(MAP_OBJ), # When hard-linking these, makedefs sets NON_PLUGIN_MAP_OBJ=$(MAP_OBJ),
# otherwise it sets the PLUGIN_* macros. # otherwise it sets the PLUGIN_* macros.
MAP_OBJ = dict_pcre.o $(LIB_MAP_OBJ) MAP_OBJ = dict_pcre.o dict_cdb.o dict_lmdb.o dict_sdbm.o slmdb.o \
LIB_MAP_OBJ = dict_cdb.o dict_lmdb.o dict_sdbm.o slmdb.o mkmap_cdb.o mkmap_lmdb.o mkmap_sdbm.o
HDRS = argv.h attr.h attr_clnt.h auto_clnt.h base64_code.h binhash.h \ HDRS = argv.h attr.h attr_clnt.h auto_clnt.h base64_code.h binhash.h \
chroot_uid.h cidr_match.h clean_env.h connect.h ctable.h dict.h \ chroot_uid.h cidr_match.h clean_env.h connect.h ctable.h dict.h \
dict_cdb.h dict_cidr.h dict_db.h dict_dbm.h dict_env.h dict_ht.h \ dict_cdb.h dict_cidr.h dict_db.h dict_dbm.h dict_env.h dict_ht.h \
@ -119,7 +121,7 @@ HDRS = argv.h attr.h attr_clnt.h auto_clnt.h base64_code.h binhash.h \
slmdb.h compat_va_copy.h dict_pipe.h dict_random.h \ slmdb.h compat_va_copy.h dict_pipe.h dict_random.h \
valid_utf8_hostname.h midna_domain.h dict_union.h dict_inline.h \ valid_utf8_hostname.h midna_domain.h dict_union.h dict_inline.h \
check_arg.h argv_attr.h msg_logger.h logwriter.h byte_mask.h \ check_arg.h argv_attr.h msg_logger.h logwriter.h byte_mask.h \
known_tcp_ports.h sane_strtol.h hash_fnv.h ldseed.h known_tcp_ports.h sane_strtol.h hash_fnv.h ldseed.h mkmap.h
TESTSRC = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \ TESTSRC = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \
stream_test.c dup2_pass_on_exec.c stream_test.c dup2_pass_on_exec.c
DEFS = -I. -D$(SYSTYPE) DEFS = -I. -D$(SYSTYPE)
@ -140,8 +142,9 @@ TESTPROG= dict_open dup2_pass_on_exec events exec_command fifo_open \
valid_utf8_string ip_match base32_code msg_rate_delay netstring \ valid_utf8_string ip_match base32_code msg_rate_delay netstring \
vstream timecmp dict_cache midna_domain casefold strcasecmp_utf8 \ vstream timecmp dict_cache midna_domain casefold strcasecmp_utf8 \
vbuf_print split_qnameval vstream msg_logger byte_mask \ vbuf_print split_qnameval vstream msg_logger byte_mask \
known_tcp_ports dict_stream find_inet binhash hash_fnv known_tcp_ports dict_stream find_inet binhash hash_fnv argv
PLUGIN_MAP_SO = $(LIB_PREFIX)pcre$(LIB_SUFFIX) PLUGIN_MAP_SO = $(LIB_PREFIX)pcre$(LIB_SUFFIX) $(LIB_PREFIX)lmdb$(LIB_SUFFIX) \
$(LIB_PREFIX)cdb$(LIB_SUFFIX) $(LIB_PREFIX)sdbm$(LIB_SUFFIX)
HTABLE_FIX = NORANDOMIZE=1 HTABLE_FIX = NORANDOMIZE=1
LIB_DIR = ../../lib LIB_DIR = ../../lib
INC_DIR = ../../include INC_DIR = ../../include
@ -171,6 +174,18 @@ plugin_map_so_make: $(PLUGIN_MAP_SO)
$(LIB_PREFIX)pcre$(LIB_SUFFIX): dict_pcre.o $(LIB_PREFIX)pcre$(LIB_SUFFIX): dict_pcre.o
$(PLUGIN_LD) $(SHLIB_RPATH) -o $@ dict_pcre.o $(AUXLIBS_PCRE) $(PLUGIN_LD) $(SHLIB_RPATH) -o $@ dict_pcre.o $(AUXLIBS_PCRE)
$(LIB_PREFIX)cdb$(LIB_SUFFIX): mkmap_cdb.o dict_cdb.o
$(PLUGIN_LD) $(SHLIB_RPATH) -o $@ mkmap_cdb.o \
dict_cdb.o $(AUXLIBS_CDB)
$(LIB_PREFIX)lmdb$(LIB_SUFFIX): mkmap_lmdb.o dict_lmdb.o slmdb.o
$(PLUGIN_LD) $(SHLIB_RPATH) -o $@ mkmap_lmdb.o dict_lmdb.o \
slmdb.o $(AUXLIBS_LMDB)
$(LIB_PREFIX)sdbm$(LIB_SUFFIX): mkmap_sdbm.o dict_sdbm.o
$(PLUGIN_LD) $(SHLIB_RPATH) -o $@ mkmap_sdbm.o \
dict_sdbm.o $(AUXLIBS_SDBM)
update: $(LIB_DIR)/$(LIB) $(HDRS) $(PLUGIN_MAP_SO_UPDATE) \ update: $(LIB_DIR)/$(LIB) $(HDRS) $(PLUGIN_MAP_SO_UPDATE) \
$(PLUGIN_MAP_OBJ_UPDATE) $(PLUGIN_MAP_OBJ_UPDATE)
-for i in $(HDRS); \ -for i in $(HDRS); \
@ -576,21 +591,29 @@ dict_stream: $(LIB)
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS) $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
mv junk $@.o mv junk $@.o
argv: $(LIB)
mv $@.o junk
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
mv junk $@.o
tests: all valid_hostname_test mac_expand_test dict_test unescape_test \ tests: all valid_hostname_test mac_expand_test dict_test unescape_test \
hex_quote_test ctable_test inet_addr_list_test base64_code_test \ hex_quote_test ctable_test inet_addr_list_test base64_code_test \
attr_scan64_test attr_scan0_test dict_pcre_tests host_port_test \ attr_scan64_test attr_scan0_test host_port_test dict_tests \
dict_cidr_test attr_scan_plain_test htable_test hex_code_test \ attr_scan_plain_test htable_test hex_code_test myaddrinfo_test \
myaddrinfo_test format_tv_test ip_match_test name_mask_tests \ format_tv_test ip_match_test name_mask_tests base32_code_test \
base32_code_test dict_thash_test surrogate_test timecmp_test \ surrogate_test timecmp_test midna_domain_test casefold_test \
dict_static_test dict_inline_test midna_domain_test casefold_test \ strcasecmp_utf8_test vbuf_print_test miss_endif_cidr_test \
dict_utf8_test strcasecmp_utf8_test vbuf_print_test dict_regexp_test \
dict_union_test dict_pipe_test miss_endif_cidr_test \
miss_endif_regexp_test split_qnameval_test vstring_test \ miss_endif_regexp_test split_qnameval_test vstring_test \
vstream_test dict_regexp_file_test dict_cidr_file_test \ vstream_test byte_mask_tests mystrtok_test known_tcp_ports_test \
binhash_test argv_test
dict_tests: all dict_test \
dict_pcre_tests dict_cidr_test dict_thash_test dict_static_test \
dict_inline_test dict_utf8_test dict_regexp_test dict_union_test \
dict_pipe_test dict_regexp_file_test dict_cidr_file_test \
dict_static_file_test dict_random_test dict_random_file_test \ dict_static_file_test dict_random_test dict_random_file_test \
dict_inline_file_test byte_mask_tests mystrtok_test \ dict_inline_file_test dict_stream_test dict_inline_regexp_test \
known_tcp_ports_test dict_stream_test dict_inline_regexp_test \ dict_inline_cidr_test
dict_inline_cidr_test binhash_test
dict_pcre_tests: dict_pcre_test miss_endif_pcre_test dict_pcre_file_test \ dict_pcre_tests: dict_pcre_test miss_endif_pcre_test dict_pcre_file_test \
dict_inline_pcre_test dict_inline_pcre_test
@ -1037,10 +1060,13 @@ dict_inline_cidr_test: dict_open dict_inline_cidr.ref
rm -f dict_inline_cidr.tmp rm -f dict_inline_cidr.tmp
find_inet_test: find_inet find_inet.ref find_inet_test: find_inet find_inet.ref
$(SHLIB_ENV) ${VALGRIND} ./find_inet >find_inet.tmp 2>&1 $(SHLIB_ENV) ${VALGRIND} ./find_inet >find_inet.tmp 2>&1
diff find_inet.ref find_inet.tmp diff find_inet.ref find_inet.tmp
rm -f find_inet.tmp rm -f find_inet.tmp
argv_test: argv
$(SHLIB_ENV) ${VALGRIND} ./argv
depend: $(MAKES) depend: $(MAKES)
(sed '1,/^# do not edit/!d' Makefile.in; \ (sed '1,/^# do not edit/!d' Makefile.in; \
set -e; for i in [a-z][a-z0-9]*.c; do \ set -e; for i in [a-z][a-z0-9]*.c; do \
@ -1378,6 +1404,7 @@ dict_cdb.o: dict.h
dict_cdb.o: dict_cdb.c dict_cdb.o: dict_cdb.c
dict_cdb.o: dict_cdb.h dict_cdb.o: dict_cdb.h
dict_cdb.o: iostuff.h dict_cdb.o: iostuff.h
dict_cdb.o: mkmap.h
dict_cdb.o: msg.h dict_cdb.o: msg.h
dict_cdb.o: myflock.h dict_cdb.o: myflock.h
dict_cdb.o: mymalloc.h dict_cdb.o: mymalloc.h
@ -1411,6 +1438,7 @@ dict_db.o: dict.h
dict_db.o: dict_db.c dict_db.o: dict_db.c
dict_db.o: dict_db.h dict_db.o: dict_db.h
dict_db.o: iostuff.h dict_db.o: iostuff.h
dict_db.o: mkmap.h
dict_db.o: msg.h dict_db.o: msg.h
dict_db.o: myflock.h dict_db.o: myflock.h
dict_db.o: mymalloc.h dict_db.o: mymalloc.h
@ -1452,6 +1480,7 @@ dict_fail.o: check_arg.h
dict_fail.o: dict.h dict_fail.o: dict.h
dict_fail.o: dict_fail.c dict_fail.o: dict_fail.c
dict_fail.o: dict_fail.h dict_fail.o: dict_fail.h
dict_fail.o: mkmap.h
dict_fail.o: msg.h dict_fail.o: msg.h
dict_fail.o: myflock.h dict_fail.o: myflock.h
dict_fail.o: mymalloc.h dict_fail.o: mymalloc.h
@ -1506,6 +1535,7 @@ dict_lmdb.o: dict_lmdb.c
dict_lmdb.o: dict_lmdb.h dict_lmdb.o: dict_lmdb.h
dict_lmdb.o: htable.h dict_lmdb.o: htable.h
dict_lmdb.o: iostuff.h dict_lmdb.o: iostuff.h
dict_lmdb.o: mkmap.h
dict_lmdb.o: msg.h dict_lmdb.o: msg.h
dict_lmdb.o: myflock.h dict_lmdb.o: myflock.h
dict_lmdb.o: mymalloc.h dict_lmdb.o: mymalloc.h
@ -1572,6 +1602,7 @@ dict_open.o: dict_thash.h
dict_open.o: dict_union.h dict_open.o: dict_union.h
dict_open.o: dict_unix.h dict_open.o: dict_unix.h
dict_open.o: htable.h dict_open.o: htable.h
dict_open.o: mkmap.h
dict_open.o: msg.h dict_open.o: msg.h
dict_open.o: myflock.h dict_open.o: myflock.h
dict_open.o: mymalloc.h dict_open.o: mymalloc.h
@ -1652,6 +1683,7 @@ dict_sdbm.o: dict_sdbm.c
dict_sdbm.o: dict_sdbm.h dict_sdbm.o: dict_sdbm.h
dict_sdbm.o: htable.h dict_sdbm.o: htable.h
dict_sdbm.o: iostuff.h dict_sdbm.o: iostuff.h
dict_sdbm.o: mkmap.h
dict_sdbm.o: msg.h dict_sdbm.o: msg.h
dict_sdbm.o: myflock.h dict_sdbm.o: myflock.h
dict_sdbm.o: mymalloc.h dict_sdbm.o: mymalloc.h
@ -1738,6 +1770,7 @@ dict_test.o: dict.h
dict_test.o: dict_db.h dict_test.o: dict_db.h
dict_test.o: dict_lmdb.h dict_test.o: dict_lmdb.h
dict_test.o: dict_test.c dict_test.o: dict_test.c
dict_test.o: mkmap.h
dict_test.o: msg.h dict_test.o: msg.h
dict_test.o: msg_vstream.h dict_test.o: msg_vstream.h
dict_test.o: myflock.h dict_test.o: myflock.h
@ -2182,6 +2215,99 @@ midna_domain.o: sys_defs.h
midna_domain.o: valid_hostname.h midna_domain.o: valid_hostname.h
midna_domain.o: vbuf.h midna_domain.o: vbuf.h
midna_domain.o: vstring.h midna_domain.o: vstring.h
mkmap_cdb.o: argv.h
mkmap_cdb.o: check_arg.h
mkmap_cdb.o: dict.h
mkmap_cdb.o: dict_cdb.h
mkmap_cdb.o: mkmap.h
mkmap_cdb.o: mkmap_cdb.c
mkmap_cdb.o: myflock.h
mkmap_cdb.o: mymalloc.h
mkmap_cdb.o: sys_defs.h
mkmap_cdb.o: vbuf.h
mkmap_cdb.o: vstream.h
mkmap_cdb.o: vstring.h
mkmap_db.o: argv.h
mkmap_db.o: check_arg.h
mkmap_db.o: dict.h
mkmap_db.o: dict_db.h
mkmap_db.o: mkmap.h
mkmap_db.o: mkmap_db.c
mkmap_db.o: msg.h
mkmap_db.o: myflock.h
mkmap_db.o: mymalloc.h
mkmap_db.o: stringops.h
mkmap_db.o: sys_defs.h
mkmap_db.o: vbuf.h
mkmap_db.o: vstream.h
mkmap_db.o: vstring.h
mkmap_db.o: warn_stat.h
mkmap_dbm.o: argv.h
mkmap_dbm.o: check_arg.h
mkmap_dbm.o: dict.h
mkmap_dbm.o: dict_dbm.h
mkmap_dbm.o: mkmap.h
mkmap_dbm.o: mkmap_dbm.c
mkmap_dbm.o: msg.h
mkmap_dbm.o: myflock.h
mkmap_dbm.o: mymalloc.h
mkmap_dbm.o: stringops.h
mkmap_dbm.o: sys_defs.h
mkmap_dbm.o: vbuf.h
mkmap_dbm.o: vstream.h
mkmap_dbm.o: vstring.h
mkmap_fail.o: argv.h
mkmap_fail.o: check_arg.h
mkmap_fail.o: dict.h
mkmap_fail.o: dict_fail.h
mkmap_fail.o: mkmap.h
mkmap_fail.o: mkmap_fail.c
mkmap_fail.o: myflock.h
mkmap_fail.o: mymalloc.h
mkmap_fail.o: sys_defs.h
mkmap_fail.o: vbuf.h
mkmap_fail.o: vstream.h
mkmap_fail.o: vstring.h
mkmap_lmdb.o: argv.h
mkmap_lmdb.o: check_arg.h
mkmap_lmdb.o: dict.h
mkmap_lmdb.o: dict_lmdb.h
mkmap_lmdb.o: mkmap.h
mkmap_lmdb.o: mkmap_lmdb.c
mkmap_lmdb.o: myflock.h
mkmap_lmdb.o: mymalloc.h
mkmap_lmdb.o: sys_defs.h
mkmap_lmdb.o: vbuf.h
mkmap_lmdb.o: vstream.h
mkmap_lmdb.o: vstring.h
mkmap_open.o: argv.h
mkmap_open.o: check_arg.h
mkmap_open.o: dict.h
mkmap_open.o: mkmap.h
mkmap_open.o: mkmap_open.c
mkmap_open.o: msg.h
mkmap_open.o: myflock.h
mkmap_open.o: mymalloc.h
mkmap_open.o: sigdelay.h
mkmap_open.o: stringops.h
mkmap_open.o: sys_defs.h
mkmap_open.o: vbuf.h
mkmap_open.o: vstream.h
mkmap_open.o: vstring.h
mkmap_sdbm.o: argv.h
mkmap_sdbm.o: check_arg.h
mkmap_sdbm.o: dict.h
mkmap_sdbm.o: dict_sdbm.h
mkmap_sdbm.o: mkmap.h
mkmap_sdbm.o: mkmap_sdbm.c
mkmap_sdbm.o: msg.h
mkmap_sdbm.o: myflock.h
mkmap_sdbm.o: mymalloc.h
mkmap_sdbm.o: stringops.h
mkmap_sdbm.o: sys_defs.h
mkmap_sdbm.o: vbuf.h
mkmap_sdbm.o: vstream.h
mkmap_sdbm.o: vstring.h
msg.o: msg.c msg.o: msg.c
msg.o: msg.h msg.o: msg.h
msg.o: msg_output.h msg.o: msg_output.h

View File

@ -6,11 +6,18 @@
/* SYNOPSIS /* SYNOPSIS
/* #include <argv.h> /* #include <argv.h>
/* /*
/* typedef int (*ARGV_COMPAR_FN)(const void *, const void *);
/*
/* ARGV *argv_alloc(len) /* ARGV *argv_alloc(len)
/* ssize_t len; /* ssize_t len;
/* /*
/* ARGV *argv_sort(argvp) /* ARGV *argv_qsort(argvp, compar)
/* ARGV *argvp; /* ARGV *argvp;
/* ARGV_COMPAR_FN compar;
/*
/* void argv_uniq(argvp, compar)
/* ARGV *argvp;
/* ARGV_COMPAR_FN compar;
/* /*
/* ARGV *argv_free(argvp) /* ARGV *argv_free(argvp)
/* ARGV *argvp; /* ARGV *argvp;
@ -64,8 +71,15 @@
/* length. The result is ready for use by argv_add(). The array /* length. The result is ready for use by argv_add(). The array
/* is null terminated. /* is null terminated.
/* /*
/* argv_sort() sorts the elements of argvp in place returning /* argv_qsort() sorts the elements of argvp in place, and
/* the original array. /* returns its first argument. If the compar argument specifies
/* a null pointer, then argv_qsort() will use byte-by-byte
/* comparison.
/*
/* argv_uniq() reduces adjacent same-value elements to one
/* element, and returns its first argument. If the compar
/* argument specifies a null pointer, then argv_uniq() will
/* use byte-by-byte comparison.
/* /*
/* argv_add() copies zero or more strings and adds them to the /* argv_add() copies zero or more strings and adds them to the
/* specified string array. The array is null terminated. /* specified string array. The array is null terminated.
@ -116,6 +130,11 @@
/* IBM T.J. Watson Research /* IBM T.J. Watson Research
/* P.O. Box 704 /* P.O. Box 704
/* Yorktown Heights, NY 10598, USA /* Yorktown Heights, NY 10598, USA
/*
/* Wietse Venema
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*--*/ /*--*/
/* System libraries. */ /* System libraries. */
@ -131,6 +150,12 @@
#include "msg.h" #include "msg.h"
#include "argv.h" #include "argv.h"
#ifdef TEST
extern NORETURN PRINTFLIKE(1, 2) test_msg_panic(const char *,...);
#define msg_panic test_msg_panic
#endif
/* argv_free - destroy string array */ /* argv_free - destroy string array */
ARGV *argv_free(ARGV *argvp) ARGV *argv_free(ARGV *argvp)
@ -172,7 +197,16 @@ static int argv_cmp(const void *e1, const void *e2)
return strcmp(s1, s2); return strcmp(s1, s2);
} }
/* argv_sort - sort array in place */ /* argv_qsort - sort array in place */
ARGV *argv_qsort(ARGV *argvp, ARGV_COMPAR_FN compar)
{
qsort(argvp->argv, argvp->argc, sizeof(argvp->argv[0]),
compar ? compar : argv_cmp);
return (argvp);
}
/* argv_sort - binary compatibility */
ARGV *argv_sort(ARGV *argvp) ARGV *argv_sort(ARGV *argvp)
{ {
@ -180,6 +214,26 @@ ARGV *argv_sort(ARGV *argvp)
return (argvp); return (argvp);
} }
/* argv_uniq - deduplicate adjacent array elements */
ARGV *argv_uniq(ARGV *argvp, ARGV_COMPAR_FN compar)
{
char **cpp;
char **prev;
if (compar == 0)
compar = argv_cmp;
for (prev = 0, cpp = argvp->argv; cpp < argvp->argv + argvp->argc; cpp++) {
if (prev != 0 && compar(prev, cpp) == 0) {
argv_delete(argvp, cpp - argvp->argv, 1);
cpp = prev;
} else {
prev = cpp;
}
}
return (argvp);
}
/* argv_extend - extend array */ /* argv_extend - extend array */
static void argv_extend(ARGV *argvp) static void argv_extend(ARGV *argvp)
@ -324,3 +378,344 @@ void argv_delete(ARGV *argvp, ssize_t first, ssize_t how_many)
argvp->argv[pos] = argvp->argv[pos + how_many]; argvp->argv[pos] = argvp->argv[pos + how_many];
argvp->argc -= how_many; argvp->argc -= how_many;
} }
#ifdef TEST
/*
* System library.
*/
#include <setjmp.h>
/*
* Utility library.
*/
#include <msg_vstream.h>
#include <stringops.h>
#define ARRAY_LEN (10)
typedef struct TEST_CASE {
const char *label; /* identifies test case */
const char *inputs[ARRAY_LEN]; /* input strings */
int terminate; /* terminate result */
ARGV *(*populate_fn) (const struct TEST_CASE *, ARGV *);
const char *exp_panic_msg; /* expected panic */
int exp_argc; /* expected array length */
const char *exp_argv[ARRAY_LEN]; /* expected array content */
} TEST_CASE;
#define TERMINATE_ARRAY (1)
#define PASS (0)
#define FAIL (1)
VSTRING *test_panic_str;
jmp_buf test_panic_jbuf;
/* test_msg_panic - does not return, and does not terminate */
void test_msg_panic(const char *fmt,...)
{
va_list ap;
va_start(ap, fmt);
test_panic_str = vstring_alloc(100);
vstring_vsprintf(test_panic_str, fmt, ap);
va_end(ap);
longjmp(test_panic_jbuf, 1);
}
/* test_argv_populate - populate result, optionally terminate */
static ARGV *test_argv_populate(const TEST_CASE *tp, ARGV *argvp)
{
const char *const * cpp;
for (cpp = tp->inputs; *cpp; cpp++)
argv_add(argvp, *cpp, (char *) 0);
if (tp->terminate)
argv_terminate(argvp);
return (argvp);
}
/* test_argv_sort - populate and sort result */
static ARGV *test_argv_sort(const TEST_CASE *tp, ARGV *argvp)
{
test_argv_populate(tp, argvp);
argv_qsort(argvp, (ARGV_COMPAR_FN) 0);
return (argvp);
}
/* test_argv_sort_uniq - populate, sort, uniq result */
static ARGV *test_argv_sort_uniq(const TEST_CASE *tp, ARGV *argvp)
{
/*
* This also tests argv_delete().
*/
test_argv_sort(tp, argvp);
argv_uniq(argvp, (ARGV_COMPAR_FN) 0);
return (argvp);
}
/* test_argv_good_truncate - populate and truncate to good size */
static ARGV *test_argv_good_truncate(const TEST_CASE *tp, ARGV *argvp)
{
test_argv_populate(tp, argvp);
argv_truncate(argvp, tp->exp_argc);
return (argvp);
}
/* test_argv_bad_truncate - populate and truncate to bad size */
static ARGV *test_argv_bad_truncate(const TEST_CASE *tp, ARGV *argvp)
{
test_argv_populate(tp, argvp);
argv_truncate(argvp, -1);
return (argvp);
}
/* test_argv_good_insert - populate and insert at good position */
static ARGV *test_argv_good_insert(const TEST_CASE *tp, ARGV *argvp)
{
test_argv_populate(tp, argvp);
argv_insert_one(argvp, 1, "new");
return (argvp);
}
/* test_argv_bad_insert1 - populate and insert at bad position */
static ARGV *test_argv_bad_insert1(const TEST_CASE *tp, ARGV *argvp)
{
test_argv_populate(tp, argvp);
argv_insert_one(argvp, -1, "new");
return (argvp);
}
/* test_argv_bad_insert2 - populate and insert at bad position */
static ARGV *test_argv_bad_insert2(const TEST_CASE *tp, ARGV *argvp)
{
test_argv_populate(tp, argvp);
argv_insert_one(argvp, 100, "new");
return (argvp);
}
/* test_argv_good_replace - populate and replace at good position */
static ARGV *test_argv_good_replace(const TEST_CASE *tp, ARGV *argvp)
{
test_argv_populate(tp, argvp);
argv_replace_one(argvp, 1, "new");
return (argvp);
}
/* test_argv_bad_replace1 - populate and replace at bad position */
static ARGV *test_argv_bad_replace1(const TEST_CASE *tp, ARGV *argvp)
{
test_argv_populate(tp, argvp);
argv_replace_one(argvp, -1, "new");
return (argvp);
}
/* test_argv_bad_replace2 - populate and replace at bad position */
static ARGV *test_argv_bad_replace2(const TEST_CASE *tp, ARGV *argvp)
{
test_argv_populate(tp, argvp);
argv_replace_one(argvp, 100, "new");
return (argvp);
}
/* test_argv_bad_delete1 - populate and delete at bad position */
static ARGV *test_argv_bad_delete1(const TEST_CASE *tp, ARGV *argvp)
{
test_argv_populate(tp, argvp);
argv_delete(argvp, -1, 1);
return (argvp);
}
/* test_argv_bad_delete2 - populate and delete at bad position */
static ARGV *test_argv_bad_delete2(const TEST_CASE *tp, ARGV *argvp)
{
test_argv_populate(tp, argvp);
argv_delete(argvp, 0, -1);
return (argvp);
}
/* test_argv_bad_delete3 - populate and delete at bad position */
static ARGV *test_argv_bad_delete3(const TEST_CASE *tp, ARGV *argvp)
{
test_argv_populate(tp, argvp);
argv_delete(argvp, 100, 1);
return (argvp);
}
/* test_argv_verify - verify result */
static int test_argv_verify(const TEST_CASE *tp, ARGV *argvp)
{
int idx;
if (tp->exp_panic_msg != 0) {
if (test_panic_str == 0) {
msg_warn("test case '%s': got no panic, want: '%s'",
tp->label, tp->exp_panic_msg);
return (FAIL);
}
if (strcmp(vstring_str(test_panic_str), tp->exp_panic_msg) != 0) {
msg_warn("test case '%s': got '%s', want: '%s'",
tp->label, vstring_str(test_panic_str), tp->exp_panic_msg);
return (FAIL);
}
return (PASS);
}
if (test_panic_str != 0) {
msg_warn("test case '%s': got '%s', want: no panic",
tp->label, vstring_str(test_panic_str));
return (FAIL);
}
if (argvp->argc != tp->exp_argc) {
msg_warn("test case '%s': got argc: %ld, want: %d",
tp->label, (long) argvp->argc, tp->exp_argc);
return (FAIL);
}
if (argvp->argv[argvp->argc] != 0 && tp->terminate) {
msg_warn("test case '%s': got unterminated, want: terminated", tp->label);
return (FAIL);
}
for (idx = 0; idx < argvp->argc; idx++) {
if (strcmp(argvp->argv[idx], tp->exp_argv[idx]) != 0) {
msg_warn("test case '%s': index %d: got '%s', want: '%s'",
tp->label, idx, argvp->argv[idx], tp->exp_argv[idx]);
return (FAIL);
}
}
return (PASS);
}
/*
* The test cases. TODO: argv_addn with good and bad string length.
*/
static const TEST_CASE test_cases[] = {
{"multiple strings, unterminated array",
{"foo", "baz", "bar", 0}, 0, test_argv_populate,
0, 3, {"foo", "baz", "bar", 0}
},
{"multiple strings, terminated array",
{"foo", "baz", "bar", 0}, TERMINATE_ARRAY, test_argv_populate,
0, 3, {"foo", "baz", "bar", 0}
},
{"distinct strings, sorted array",
{"foo", "baz", "bar", 0}, 0, test_argv_sort,
0, 3, {"bar", "baz", "foo", 0}
},
{"duplicate strings, sorted array",
{"foo", "baz", "baz", "bar", 0}, 0, test_argv_sort,
0, 4, {"bar", "baz", "baz", "foo", 0}
},
{"duplicate strings, sorted, uniqued-middle elements",
{"foo", "baz", "baz", "bar", 0}, 0, test_argv_sort_uniq,
0, 3, {"bar", "baz", "foo", 0}
},
{"duplicate strings, sorted, uniqued-first elements",
{"foo", "bar", "baz", "bar", 0}, 0, test_argv_sort_uniq,
0, 3, {"bar", "baz", "foo", 0}
},
{"duplicate strings, sorted, uniqued-last elements",
{"foo", "foo", "baz", "bar", 0}, 0, test_argv_sort_uniq,
0, 3, {"bar", "baz", "foo", 0}
},
{"multiple strings, truncate array by one",
{"foo", "baz", "bar", 0}, 0, test_argv_good_truncate,
0, 2, {"foo", "baz", 0}
},
{"multiple strings, truncate whole array",
{"foo", "baz", "bar", 0}, 0, test_argv_good_truncate,
0, 0, {"foo", "baz", 0}
},
{"multiple strings, bad truncate",
{"foo", "baz", "bar", 0}, 0, test_argv_bad_truncate,
"argv_truncate: bad length -1"
},
{"multiple strings, insert one at good position",
{"foo", "baz", "bar", 0}, 0, test_argv_good_insert,
0, 4, {"foo", "new", "baz", "bar", 0}
},
{"multiple strings, insert one at bad position",
{"foo", "baz", "bar", 0}, 0, test_argv_bad_insert1,
"argv_insert_one bad position: -1"
},
{"multiple strings, insert one at bad position",
{"foo", "baz", "bar", 0}, 0, test_argv_bad_insert2,
"argv_insert_one bad position: 100"
},
{"multiple strings, replace one at good position",
{"foo", "baz", "bar", 0}, 0, test_argv_good_replace,
0, 3, {"foo", "new", "bar", 0}
},
{"multiple strings, replace one at bad position",
{"foo", "baz", "bar", 0}, 0, test_argv_bad_replace1,
"argv_replace_one bad position: -1"
},
{"multiple strings, replace one at bad position",
{"foo", "baz", "bar", 0}, 0, test_argv_bad_replace2,
"argv_replace_one bad position: 100"
},
{"multiple strings, delete one at negative position",
{"foo", "baz", "bar", 0}, 0, test_argv_bad_delete1,
"argv_delete bad range: (start=-1 count=1)"
},
{"multiple strings, delete with bad range end",
{"foo", "baz", "bar", 0}, 0, test_argv_bad_delete2,
"argv_delete bad range: (start=0 count=-1)"
},
{"multiple strings, delete at too large position",
{"foo", "baz", "bar", 0}, 0, test_argv_bad_delete3,
"argv_delete bad range: (start=100 count=1)"
},
0,
};
int main(int argc, char **argv)
{
const TEST_CASE *tp;
int pass = 0;
int fail = 0;
msg_vstream_init(sane_basename((VSTRING *) 0, argv[0]), VSTREAM_ERR);
for (tp = test_cases; tp->label != 0; tp++) {
int test_failed;
ARGV *argvp;
argvp = argv_alloc(1);
if (setjmp(test_panic_jbuf) == 0)
tp->populate_fn(tp, argvp);
test_failed = test_argv_verify(tp, argvp);
if (test_failed) {
msg_info("%s: FAIL", tp->label);
fail++;
} else {
msg_info("%s: PASS", tp->label);
pass++;
}
argv_free(argvp);
if (test_panic_str) {
vstring_free(test_panic_str);
test_panic_str = 0;
}
}
msg_info("PASS=%d FAIL=%d", pass, fail);
exit(fail != 0);
}
#endif

View File

@ -20,8 +20,12 @@ typedef struct ARGV {
char **argv; /* string array */ char **argv; /* string array */
} ARGV; } ARGV;
typedef int (*ARGV_COMPAR_FN)(const void *, const void *);
extern ARGV *argv_alloc(ssize_t); extern ARGV *argv_alloc(ssize_t);
extern ARGV *argv_sort(ARGV *); extern ARGV *argv_sort(ARGV *); /* backwards compatibility */
extern ARGV *argv_qsort(ARGV *, ARGV_COMPAR_FN);
extern ARGV *argv_uniq(ARGV *, ARGV_COMPAR_FN);
extern void argv_add(ARGV *,...); extern void argv_add(ARGV *,...);
extern void argv_addn(ARGV *,...); extern void argv_addn(ARGV *,...);
extern void argv_terminate(ARGV *); extern void argv_terminate(ARGV *);
@ -64,6 +68,11 @@ extern ARGV *argv_split_at_append(ARGV *, const char *, int);
/* IBM T.J. Watson Research /* IBM T.J. Watson Research
/* P.O. Box 704 /* P.O. Box 704
/* Yorktown Heights, NY 10598, USA /* Yorktown Heights, NY 10598, USA
/*
/* Wietse Venema
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*--*/ /*--*/
#endif #endif

View File

@ -240,6 +240,11 @@
/* IBM T.J. Watson Research /* IBM T.J. Watson Research
/* P.O. Box 704 /* P.O. Box 704
/* Yorktown Heights, NY 10598, USA /* Yorktown Heights, NY 10598, USA
/*
/* Wietse Venema
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*--*/ /*--*/
/* System libraries. */ /* System libraries. */

View File

@ -232,10 +232,16 @@ extern int dict_error(const char *);
* Low-level interface, with physical dictionary handles. * Low-level interface, with physical dictionary handles.
*/ */
typedef DICT *(*DICT_OPEN_FN) (const char *, int, int); typedef DICT *(*DICT_OPEN_FN) (const char *, int, int);
typedef DICT_OPEN_FN (*DICT_OPEN_EXTEND_FN) (const char *); typedef struct {
const char *type;
DICT_OPEN_FN dict_fn;
struct MKMAP *(*mkmap_fn) (const char *);
} DICT_OPEN_INFO;
typedef const DICT_OPEN_INFO *(*DICT_OPEN_EXTEND_FN) (const char *);
extern DICT *dict_open(const char *, int, int); extern DICT *dict_open(const char *, int, int);
extern DICT *dict_open3(const char *, const char *, int, int); extern DICT *dict_open3(const char *, const char *, int, int);
extern void dict_open_register(const char *, DICT_OPEN_FN); extern void dict_open_register(const DICT_OPEN_INFO *);
extern const DICT_OPEN_INFO *dict_open_lookup(const char *);
extern DICT_OPEN_EXTEND_FN dict_open_extend(DICT_OPEN_EXTEND_FN); extern DICT_OPEN_EXTEND_FN dict_open_extend(DICT_OPEN_EXTEND_FN);
#define dict_get(dp, key) ((const char *) (dp)->lookup((dp), (key))) #define dict_get(dp, key) ((const char *) (dp)->lookup((dp), (key)))

View File

@ -15,6 +15,7 @@
* Utility library. * Utility library.
*/ */
#include <dict.h> #include <dict.h>
#include <mkmap.h>
/* /*
* External interface. * External interface.
@ -22,6 +23,7 @@
#define DICT_TYPE_CDB "cdb" #define DICT_TYPE_CDB "cdb"
extern DICT *dict_cdb_open(const char *, int, int); extern DICT *dict_cdb_open(const char *, int, int);
extern MKMAP *mkmap_cdb_open(const char *);
/* LICENSE /* LICENSE
/* .ad /* .ad
@ -32,6 +34,11 @@ extern DICT *dict_cdb_open(const char *, int, int);
/* IBM T.J. Watson Research /* IBM T.J. Watson Research
/* P.O. Box 704 /* P.O. Box 704
/* Yorktown Heights, NY 10598, USA /* Yorktown Heights, NY 10598, USA
/*
/* Wietse Venema
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*--*/ /*--*/
#endif /* _DICT_CDB_H_INCLUDED_ */ #endif /* _DICT_CDB_H_INCLUDED_ */

View File

@ -15,6 +15,7 @@
* Utility library. * Utility library.
*/ */
#include <dict.h> #include <dict.h>
#include <mkmap.h>
/* /*
* External interface. * External interface.
@ -24,6 +25,8 @@
extern DICT *dict_hash_open(const char *, int, int); extern DICT *dict_hash_open(const char *, int, int);
extern DICT *dict_btree_open(const char *, int, int); extern DICT *dict_btree_open(const char *, int, int);
extern MKMAP *mkmap_hash_open(const char *);
extern MKMAP *mkmap_btree_open(const char *);
/* /*
* XXX Should be part of the DICT interface. * XXX Should be part of the DICT interface.

View File

@ -15,6 +15,7 @@
* Utility library. * Utility library.
*/ */
#include <dict.h> #include <dict.h>
#include <mkmap.h>
/* /*
* External interface. * External interface.
@ -22,6 +23,7 @@
#define DICT_TYPE_DBM "dbm" #define DICT_TYPE_DBM "dbm"
extern DICT *dict_dbm_open(const char *, int, int); extern DICT *dict_dbm_open(const char *, int, int);
extern MKMAP *mkmap_dbm_open(const char *);
/* LICENSE /* LICENSE
/* .ad /* .ad
@ -32,6 +34,11 @@ extern DICT *dict_dbm_open(const char *, int, int);
/* IBM T.J. Watson Research /* IBM T.J. Watson Research
/* P.O. Box 704 /* P.O. Box 704
/* Yorktown Heights, NY 10598, USA /* Yorktown Heights, NY 10598, USA
/*
/* Wietse Venema
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*--*/ /*--*/
#endif #endif

View File

@ -15,6 +15,7 @@
* Utility library. * Utility library.
*/ */
#include <dict.h> #include <dict.h>
#include <mkmap.h>
/* /*
* External interface. * External interface.
@ -22,6 +23,7 @@
#define DICT_TYPE_FAIL "fail" #define DICT_TYPE_FAIL "fail"
extern DICT *dict_fail_open(const char *, int, int); extern DICT *dict_fail_open(const char *, int, int);
extern MKMAP *mkmap_fail_open(const char *);
/* LICENSE /* LICENSE
/* .ad /* .ad
@ -30,6 +32,11 @@ extern DICT *dict_fail_open(const char *, int, int);
/* AUTHOR(S) /* AUTHOR(S)
/* jeffm /* jeffm
/* ghostgun.com /* ghostgun.com
/*
/* Wietse Venema
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*--*/ /*--*/
#endif #endif

View File

@ -15,6 +15,7 @@
* Utility library. * Utility library.
*/ */
#include <dict.h> #include <dict.h>
#include <mkmap.h>
/* /*
* External interface. * External interface.
@ -22,6 +23,7 @@
#define DICT_TYPE_LMDB "lmdb" #define DICT_TYPE_LMDB "lmdb"
extern DICT *dict_lmdb_open(const char *, int, int); extern DICT *dict_lmdb_open(const char *, int, int);
extern MKMAP *mkmap_lmdb_open(const char *);
/* /*
* XXX Should be part of the DICT interface. * XXX Should be part of the DICT interface.
@ -38,6 +40,11 @@ extern size_t dict_lmdb_map_size;
/* AUTHOR(S) /* AUTHOR(S)
/* Howard Chu /* Howard Chu
/* Symas Corporation /* Symas Corporation
/*
/* Wietse Venema
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*--*/ /*--*/
#endif #endif

View File

@ -39,13 +39,23 @@
/* void dict_close(dict) /* void dict_close(dict)
/* DICT *dict; /* DICT *dict;
/* /*
/* typedef struct {
/* .in +4
/* char *type;
/* DICT_OPEN_FN dict_fn;
/* MKMAP_OPEN_FN mkmap_fn; /* See <mkmap.h> */
/* .in -4
/* } DICT_OPEN_INFO;
/*
/* typedef DICT *(*DICT_OPEN_FN) (const char *, int, int); /* typedef DICT *(*DICT_OPEN_FN) (const char *, int, int);
/* /*
/* dict_open_register(type, open) /* void dict_open_register(open_info)
/* const char *type; /* DICT_OPEN_INFO *open_info;
/* DICT_OPEN_FN open;
/* /*
/* typedef DICT_OPEN_FN (*DICT_OPEN_EXTEND_FN)(const char *type); /* const DICT_OPEN_INFO *dict_open_lookup(dict_type)
/* const char *dict_type;
/*
/* typedef DICT_OPEN_INFO (*DICT_OPEN_EXTEND_FN)(char *);
/* /*
/* DICT_OPEN_EXTEND_FN dict_open_extend(call_back) /* DICT_OPEN_EXTEND_FN dict_open_extend(call_back)
/* DICT_OPEN_EXTEND_FN call_back; /* DICT_OPEN_EXTEND_FN call_back;
@ -238,6 +248,11 @@
/* associated data structures. /* associated data structures.
/* /*
/* dict_open_register() adds support for a new dictionary type. /* dict_open_register() adds support for a new dictionary type.
/* NOTE: this function does not copy its argument.
/*
/* dict_open_lookup() returns a pointer to the DICT_OPEN_INFO
/* for the specified dictionary type, or a null pointer if the
/* requested information is not found.
/* /*
/* dict_open_extend() registers a call-back function that looks /* dict_open_extend() registers a call-back function that looks
/* up the dictionary open() function for a type that is not /* up the dictionary open() function for a type that is not
@ -348,60 +363,56 @@
#include <split_at.h> #include <split_at.h>
#include <htable.h> #include <htable.h>
#include <myflock.h> #include <myflock.h>
#include <mkmap.h>
/* /*
* lookup table for available map types. * lookup table for available map types.
*/ */
typedef struct {
char *type;
DICT_OPEN_FN open;
} DICT_OPEN_INFO;
static const DICT_OPEN_INFO dict_open_info[] = { static const DICT_OPEN_INFO dict_open_info[] = {
DICT_TYPE_ENVIRON, dict_env_open, DICT_TYPE_ENVIRON, dict_env_open, 0,
DICT_TYPE_HT, dict_ht_open, DICT_TYPE_HT, dict_ht_open, 0,
DICT_TYPE_UNIX, dict_unix_open, DICT_TYPE_UNIX, dict_unix_open, 0,
DICT_TYPE_TCP, dict_tcp_open, DICT_TYPE_TCP, dict_tcp_open, 0,
#ifdef HAS_DBM #ifdef HAS_DBM
DICT_TYPE_DBM, dict_dbm_open, DICT_TYPE_DBM, dict_dbm_open, mkmap_dbm_open,
#endif #endif
#ifdef HAS_DB #ifdef HAS_DB
DICT_TYPE_HASH, dict_hash_open, DICT_TYPE_HASH, dict_hash_open, mkmap_hash_open,
DICT_TYPE_BTREE, dict_btree_open, DICT_TYPE_BTREE, dict_btree_open, mkmap_btree_open,
#endif #endif
#ifdef HAS_NIS #ifdef HAS_NIS
DICT_TYPE_NIS, dict_nis_open, DICT_TYPE_NIS, dict_nis_open, 0,
#endif #endif
#ifdef HAS_NISPLUS #ifdef HAS_NISPLUS
DICT_TYPE_NISPLUS, dict_nisplus_open, DICT_TYPE_NISPLUS, dict_nisplus_open, 0,
#endif #endif
#ifdef HAS_NETINFO #ifdef HAS_NETINFO
DICT_TYPE_NETINFO, dict_ni_open, DICT_TYPE_NETINFO, dict_ni_open, 0,
#endif #endif
#ifdef HAS_POSIX_REGEXP #ifdef HAS_POSIX_REGEXP
DICT_TYPE_REGEXP, dict_regexp_open, DICT_TYPE_REGEXP, dict_regexp_open, 0,
#endif #endif
DICT_TYPE_STATIC, dict_static_open, DICT_TYPE_STATIC, dict_static_open, 0,
DICT_TYPE_CIDR, dict_cidr_open, DICT_TYPE_CIDR, dict_cidr_open, 0,
DICT_TYPE_THASH, dict_thash_open, DICT_TYPE_THASH, dict_thash_open, 0,
DICT_TYPE_SOCKMAP, dict_sockmap_open, DICT_TYPE_SOCKMAP, dict_sockmap_open, 0,
DICT_TYPE_FAIL, dict_fail_open, DICT_TYPE_FAIL, dict_fail_open, mkmap_fail_open,
DICT_TYPE_PIPE, dict_pipe_open, DICT_TYPE_PIPE, dict_pipe_open, 0,
DICT_TYPE_RANDOM, dict_random_open, DICT_TYPE_RANDOM, dict_random_open, 0,
DICT_TYPE_UNION, dict_union_open, DICT_TYPE_UNION, dict_union_open, 0,
DICT_TYPE_INLINE, dict_inline_open, DICT_TYPE_INLINE, dict_inline_open, 0,
#ifndef USE_DYNAMIC_MAPS #ifndef USE_DYNAMIC_MAPS
#ifdef HAS_PCRE #ifdef HAS_PCRE
DICT_TYPE_PCRE, dict_pcre_open, DICT_TYPE_PCRE, dict_pcre_open, 0,
#endif #endif
#ifdef HAS_CDB #ifdef HAS_CDB
DICT_TYPE_CDB, dict_cdb_open, DICT_TYPE_CDB, dict_cdb_open, mkmap_cdb_open,
#endif #endif
#ifdef HAS_SDBM #ifdef HAS_SDBM
DICT_TYPE_SDBM, dict_sdbm_open, DICT_TYPE_SDBM, dict_sdbm_open, mkmap_sdbm_open,
#endif #endif
#ifdef HAS_LMDB #ifdef HAS_LMDB
DICT_TYPE_LMDB, dict_lmdb_open, DICT_TYPE_LMDB, dict_lmdb_open, mkmap_lmdb_open,
#endif #endif
#endif /* !USE_DYNAMIC_MAPS */ #endif /* !USE_DYNAMIC_MAPS */
0, 0,
@ -416,11 +427,19 @@ static DICT_OPEN_EXTEND_FN dict_open_extend_hook;
static DICT_MAPNAMES_EXTEND_FN dict_mapnames_extend_hook; static DICT_MAPNAMES_EXTEND_FN dict_mapnames_extend_hook;
/* /*
* Workaround. * Workaround: define global variables here to control database cache sizes.
* When a database driver is dynamically loaded, global control variables
* cannot simply be owned by the loadable objects because that would result
* in build-time linker errors.
*/ */
DEFINE_DICT_LMDB_MAP_SIZE; DEFINE_DICT_LMDB_MAP_SIZE;
DEFINE_DICT_DB_CACHE_SIZE; DEFINE_DICT_DB_CACHE_SIZE;
/*
* Replace obscure code with a more readable expression.
*/
#define NEED_DICT_OPEN_INIT() (dict_open_hash == 0)
/* dict_open_init - one-off initialization */ /* dict_open_init - one-off initialization */
static void dict_open_init(void) static void dict_open_init(void)
@ -428,7 +447,7 @@ static void dict_open_init(void)
const char *myname = "dict_open_init"; const char *myname = "dict_open_init";
const DICT_OPEN_INFO *dp; const DICT_OPEN_INFO *dp;
if (dict_open_hash != 0) if (!NEED_DICT_OPEN_INIT())
msg_panic("%s: multiple initialization", myname); msg_panic("%s: multiple initialization", myname);
dict_open_hash = htable_create(10); dict_open_hash = htable_create(10);
@ -453,33 +472,24 @@ DICT *dict_open(const char *dict_spec, int open_flags, int dict_flags)
return (dict); return (dict);
} }
/* dict_open3 - open dictionary */ /* dict_open3 - open dictionary */
DICT *dict_open3(const char *dict_type, const char *dict_name, DICT *dict_open3(const char *dict_type, const char *dict_name,
int open_flags, int dict_flags) int open_flags, int dict_flags)
{ {
const char *myname = "dict_open"; const char *myname = "dict_open";
DICT_OPEN_INFO *dp; const DICT_OPEN_INFO *dp;
DICT_OPEN_FN open_fn;
DICT *dict; DICT *dict;
if (*dict_type == 0 || *dict_name == 0) if (*dict_type == 0 || *dict_name == 0)
msg_fatal("open dictionary: expecting \"type:name\" form instead of \"%s:%s\"", msg_fatal("open dictionary: expecting \"type:name\" form instead of \"%s:%s\"",
dict_type, dict_name); dict_type, dict_name);
if (dict_open_hash == 0) if (NEED_DICT_OPEN_INIT())
dict_open_init(); dict_open_init();
if ((dp = (DICT_OPEN_INFO *) htable_find(dict_open_hash, dict_type)) == 0) { if ((dp = dict_open_lookup(dict_type)) == 0)
if (dict_open_extend_hook != 0 return (dict_surrogate(dict_type, dict_name, open_flags, dict_flags,
&& (open_fn = dict_open_extend_hook(dict_type)) != 0) {
dict_open_register(dict_type, open_fn);
dp = (DICT_OPEN_INFO *) htable_find(dict_open_hash, dict_type);
}
if (dp == 0)
return (dict_surrogate(dict_type, dict_name, open_flags, dict_flags,
"unsupported dictionary type: %s", dict_type)); "unsupported dictionary type: %s", dict_type));
} if ((dict = dp->dict_fn(dict_name, open_flags, dict_flags)) == 0)
if ((dict = dp->open(dict_name, open_flags, dict_flags)) == 0)
return (dict_surrogate(dict_type, dict_name, open_flags, dict_flags, return (dict_surrogate(dict_type, dict_name, open_flags, dict_flags,
"cannot open %s:%s: %m", dict_type, dict_name)); "cannot open %s:%s: %m", dict_type, dict_name));
if (msg_verbose) if (msg_verbose)
@ -508,20 +518,33 @@ DICT *dict_open3(const char *dict_type, const char *dict_name,
/* dict_open_register - register dictionary type */ /* dict_open_register - register dictionary type */
void dict_open_register(const char *type, DICT_OPEN_FN open) void dict_open_register(const DICT_OPEN_INFO *dp)
{ {
const char *myname = "dict_open_register"; const char *myname = "dict_open_register";
DICT_OPEN_INFO *dp;
HTABLE_INFO *ht;
if (dict_open_hash == 0) if (msg_verbose > 1)
msg_info("%s: %s", myname, dp->type);
if (NEED_DICT_OPEN_INIT())
dict_open_init(); dict_open_init();
if (htable_find(dict_open_hash, type)) if (htable_find(dict_open_hash, dp->type))
msg_panic("%s: dictionary type exists: %s", myname, type); msg_panic("%s: dictionary type exists: %s", myname, dp->type);
dp = (DICT_OPEN_INFO *) mymalloc(sizeof(*dp)); (void) htable_enter(dict_open_hash, dp->type, (void *) dp);
dp->open = open; }
ht = htable_enter(dict_open_hash, type, (void *) dp);
dp->type = ht->key; /* dict_open_lookup - look up DICT_OPEN_INFO for dictionary type */
const DICT_OPEN_INFO *dict_open_lookup(const char *dict_type)
{
const char myname[] = "dict_open_lookup";
const DICT_OPEN_INFO *dp;
if (msg_verbose > 1)
msg_info("%s: %s", myname, dict_type);
if ((dp = (DICT_OPEN_INFO *) htable_find(dict_open_hash, dict_type)) == 0
&& dict_open_extend_hook != 0
&& (dp = dict_open_extend_hook(dict_type)) != 0)
dict_open_register(dp);
return (dp);
} }
/* dict_open_extend - register alternate dictionary search routine */ /* dict_open_extend - register alternate dictionary search routine */
@ -535,13 +558,6 @@ DICT_OPEN_EXTEND_FN dict_open_extend(DICT_OPEN_EXTEND_FN new_cb)
return (old_cb); return (old_cb);
} }
/* dict_sort_alpha_cpp - qsort() callback */
static int dict_sort_alpha_cpp(const void *a, const void *b)
{
return (strcmp(((char **) a)[0], ((char **) b)[0]));
}
/* dict_mapnames - return an ARGV of available map_names */ /* dict_mapnames - return an ARGV of available map_names */
ARGV *dict_mapnames() ARGV *dict_mapnames()
@ -551,7 +567,7 @@ ARGV *dict_mapnames()
DICT_OPEN_INFO *dp; DICT_OPEN_INFO *dp;
ARGV *mapnames; ARGV *mapnames;
if (dict_open_hash == 0) if (NEED_DICT_OPEN_INIT())
dict_open_init(); dict_open_init();
mapnames = argv_alloc(dict_open_hash->used + 1); mapnames = argv_alloc(dict_open_hash->used + 1);
for (ht_info = ht = htable_list(dict_open_hash); *ht; ht++) { for (ht_info = ht = htable_list(dict_open_hash); *ht; ht++) {
@ -560,8 +576,9 @@ ARGV *dict_mapnames()
} }
if (dict_mapnames_extend_hook != 0) if (dict_mapnames_extend_hook != 0)
(void) dict_mapnames_extend_hook(mapnames); (void) dict_mapnames_extend_hook(mapnames);
qsort((void *) mapnames->argv, mapnames->argc, sizeof(mapnames->argv[0]), argv_qsort(mapnames, (ARGV_COMPAR_FN) 0);
dict_sort_alpha_cpp); /* In case some drivers have been loaded dynamically. */
argv_uniq(mapnames, (ARGV_COMPAR_FN) 0);
myfree((void *) ht_info); myfree((void *) ht_info);
argv_terminate(mapnames); argv_terminate(mapnames);
return mapnames; return mapnames;

View File

@ -15,6 +15,7 @@
* Utility library. * Utility library.
*/ */
#include <dict.h> #include <dict.h>
#include <mkmap.h>
/* /*
* External interface. * External interface.
@ -22,6 +23,7 @@
#define DICT_TYPE_SDBM "sdbm" #define DICT_TYPE_SDBM "sdbm"
extern DICT *dict_sdbm_open(const char *, int, int); extern DICT *dict_sdbm_open(const char *, int, int);
extern MKMAP *mkmap_sdbm_open(const char *);
/* LICENSE /* LICENSE
/* .ad /* .ad
@ -32,6 +34,11 @@ extern DICT *dict_sdbm_open(const char *, int, int);
/* IBM T.J. Watson Research /* IBM T.J. Watson Research
/* P.O. Box 704 /* P.O. Box 704
/* Yorktown Heights, NY 10598, USA /* Yorktown Heights, NY 10598, USA
/*
/* Wietse Venema
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*--*/ /*--*/
#endif #endif

50
postfix/src/util/mkmap.h Normal file
View File

@ -0,0 +1,50 @@
#ifndef _MKMAP_H_INCLUDED_
#define _MKMAP_H_INCLUDED_
/*++
/* NAME
/* mkmap 3h
/* SUMMARY
/* create or rewrite Postfix database
/* SYNOPSIS
/* #include <mkmap.h>
/* DESCRIPTION
/* .nf
/*
* We try to open and lock a file before DB/DBM initialization. However, if
* the file does not exist then we may have to acquire the lock after the
* DB/DBM initialization.
*/
typedef struct MKMAP {
struct DICT *(*open) (const char *, int, int); /* dict_xx_open() */
struct DICT *dict; /* dict_xx_open() result */
void (*after_open) (struct MKMAP *); /* may be null */
void (*after_close) (struct MKMAP *); /* may be null */
int multi_writer; /* multi-writer safe */
} MKMAP;
extern MKMAP *mkmap_open(const char *, const char *, int, int);
extern void mkmap_close(MKMAP *);
#define mkmap_append(map, key, val) dict_put((map)->dict, (key), (val))
typedef MKMAP *(*MKMAP_OPEN_FN) (const char *);
/* 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
/*
/* Wietse Venema
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*--*/
#endif

View File

@ -4,7 +4,7 @@
/* SUMMARY /* SUMMARY
/* create or open database, CDB style /* create or open database, CDB style
/* SYNOPSIS /* SYNOPSIS
/* #include <mkmap.h> /* #include <dict_cdb.h>
/* /*
/* MKMAP *mkmap_cdb_open(path) /* MKMAP *mkmap_cdb_open(path)
/* const char *path; /* const char *path;
@ -32,6 +32,11 @@
/* IBM T.J. Watson Research /* IBM T.J. Watson Research
/* P.O. Box 704 /* P.O. Box 704
/* Yorktown Heights, NY 10598, USA /* Yorktown Heights, NY 10598, USA
/*
/* Wietse Venema
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*--*/ /*--*/
/* System library. */ /* System library. */
@ -43,11 +48,6 @@
/* Utility library. */ /* Utility library. */
#include <mymalloc.h> #include <mymalloc.h>
#include <dict.h>
/* Application-specific. */
#include "mkmap.h"
#include <dict_cdb.h> #include <dict_cdb.h>
/* This is a dummy module, since CDB has all the functionality /* This is a dummy module, since CDB has all the functionality

View File

@ -4,7 +4,7 @@
/* SUMMARY /* SUMMARY
/* create or open database, DB style /* create or open database, DB style
/* SYNOPSIS /* SYNOPSIS
/* #include <mkmap.h> /* #include <dict_db.h>
/* /*
/* MKMAP *mkmap_hash_open(path) /* MKMAP *mkmap_hash_open(path)
/* const char *path; /* const char *path;
@ -30,6 +30,11 @@
/* IBM T.J. Watson Research /* IBM T.J. Watson Research
/* P.O. Box 704 /* P.O. Box 704
/* Yorktown Heights, NY 10598, USA /* Yorktown Heights, NY 10598, USA
/*
/* Wietse Venema
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*--*/ /*--*/
/* System library. */ /* System library. */
@ -44,19 +49,10 @@
#include <msg.h> #include <msg.h>
#include <mymalloc.h> #include <mymalloc.h>
#include <stringops.h> #include <stringops.h>
#include <dict.h>
#include <dict_db.h> #include <dict_db.h>
#include <myflock.h> #include <myflock.h>
#include <warn_stat.h> #include <warn_stat.h>
/* Global library. */
#include <mail_params.h>
/* Application-specific. */
#include "mkmap.h"
#ifdef HAS_DB #ifdef HAS_DB
#ifdef PATH_DB_H #ifdef PATH_DB_H
#include PATH_DB_H #include PATH_DB_H
@ -104,24 +100,9 @@ static MKMAP *mkmap_db_before_open(const char *path,
struct stat st; struct stat st;
/* /*
* Override the default per-table cache size for map (re)builds. * Assumes that dict_db_cache_size = var_db_create_buf was done in the
* * caller, because this code has no access to Postfix variables.
* db_cache_size" is defined in util/dict_db.c and defaults to 128kB, which
* works well for the lookup code.
*
* We use a larger per-table cache when building ".db" files. For "hash"
* files performance degrades rapidly unless the memory pool is O(file
* size).
*
* For "btree" files performance is good with sorted input even for small
* memory pools, but with random input degrades rapidly unless the memory
* pool is O(file size).
*
* XXX This should be specified via the DICT interface so that the buffer
* size becomes an object property, instead of being specified by poking
* a global variable so that it becomes a class property.
*/ */
dict_db_cache_size = var_db_create_buf;
/* /*
* Fill in the generic members. * Fill in the generic members.

View File

@ -4,7 +4,7 @@
/* SUMMARY /* SUMMARY
/* create or open database, DBM style /* create or open database, DBM style
/* SYNOPSIS /* SYNOPSIS
/* #include <mkmap.h> /* #include <dict_dbm.h>
/* /*
/* MKMAP *mkmap_dbm_open(path) /* MKMAP *mkmap_dbm_open(path)
/* const char *path; /* const char *path;
@ -28,6 +28,11 @@
/* IBM T.J. Watson Research /* IBM T.J. Watson Research
/* P.O. Box 704 /* P.O. Box 704
/* Yorktown Heights, NY 10598, USA /* Yorktown Heights, NY 10598, USA
/*
/* Wietse Venema
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*--*/ /*--*/
/* System library. */ /* System library. */
@ -40,14 +45,9 @@
#include <msg.h> #include <msg.h>
#include <mymalloc.h> #include <mymalloc.h>
#include <stringops.h> #include <stringops.h>
#include <dict.h>
#include <dict_dbm.h> #include <dict_dbm.h>
#include <myflock.h> #include <myflock.h>
/* Application-specific. */
#include "mkmap.h"
#ifdef HAS_DBM #ifdef HAS_DBM
#ifdef PATH_NDBM_H #ifdef PATH_NDBM_H
#include PATH_NDBM_H #include PATH_NDBM_H

View File

@ -4,7 +4,7 @@
/* SUMMARY /* SUMMARY
/* create or open database, fail: style /* create or open database, fail: style
/* SYNOPSIS /* SYNOPSIS
/* #include <mkmap.h> /* #include <dict_fail.h>
/* /*
/* MKMAP *mkmap_fail_open(path) /* MKMAP *mkmap_fail_open(path)
/* const char *path; /* const char *path;
@ -23,6 +23,11 @@
/* IBM T.J. Watson Research /* IBM T.J. Watson Research
/* P.O. Box 704 /* P.O. Box 704
/* Yorktown Heights, NY 10598, USA /* Yorktown Heights, NY 10598, USA
/*
/* Wietse Venema
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*--*/ /*--*/
/* System library. */ /* System library. */
@ -32,11 +37,6 @@
/* Utility library. */ /* Utility library. */
#include <mymalloc.h> #include <mymalloc.h>
#include <dict.h>
/* Application-specific. */
#include <mkmap.h>
#include <dict_fail.h> #include <dict_fail.h>
/* /*

View File

@ -4,7 +4,7 @@
/* SUMMARY /* SUMMARY
/* create or open database, LMDB style /* create or open database, LMDB style
/* SYNOPSIS /* SYNOPSIS
/* #include <mkmap.h> /* #include <dict_lmdb.h>
/* /*
/* MKMAP *mkmap_lmdb_open(path) /* MKMAP *mkmap_lmdb_open(path)
/* const char *path; /* const char *path;
@ -26,6 +26,11 @@
/* AUTHOR(S) /* AUTHOR(S)
/* Howard Chu /* Howard Chu
/* Symas Corporation /* Symas Corporation
/*
/* Wietse Venema
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*--*/ /*--*/
/* System library. */ /* System library. */
@ -37,13 +42,9 @@
/* Utility library. */ /* Utility library. */
#include <msg.h>
#include <mymalloc.h> #include <mymalloc.h>
#include <stringops.h>
#include <dict.h>
#include <dict_lmdb.h> #include <dict_lmdb.h>
#include <myflock.h> #include <mkmap.h>
#include <warn_stat.h>
#ifdef HAS_LMDB #ifdef HAS_LMDB
#ifdef PATH_LMDB_H #ifdef PATH_LMDB_H
@ -52,15 +53,6 @@
#include <lmdb.h> #include <lmdb.h>
#endif #endif
/* Global library. */
#include <mail_conf.h>
#include <mail_params.h>
/* Application-specific. */
#include "mkmap.h"
/* mkmap_lmdb_open */ /* mkmap_lmdb_open */
MKMAP *mkmap_lmdb_open(const char *path) MKMAP *mkmap_lmdb_open(const char *path)

View File

@ -7,8 +7,8 @@
/* #include <mkmap.h> /* #include <mkmap.h>
/* /*
/* typedef struct MKMAP { /* typedef struct MKMAP {
/* DICT_OPEN_FN open; /* dict_xx_open() */ /* struct DICT *(*open) (const char *, int, int); /* dict_xx_open() */
/* DICT *dict; /* dict_xx_open() result */ /* struct DICT *dict; /* dict_xx_open() result */
/* void (*after_open) (struct MKMAP *); /* may be null */ /* void (*after_open) (struct MKMAP *); /* may be null */
/* void (*after_close) (struct MKMAP *); /* may be null */ /* void (*after_close) (struct MKMAP *); /* may be null */
/* int multi_writer; /* multi-writer safe */ /* int multi_writer; /* multi-writer safe */
@ -28,16 +28,6 @@
/* /*
/* void mkmap_close(mkmap) /* void mkmap_close(mkmap)
/* MKMAP *mkmap; /* MKMAP *mkmap;
/*
/* typedef MKMAP *(*MKMAP_OPEN_FN) (const char *);
/* typedef MKMAP_OPEN_FN *(*MKMAP_OPEN_EXTEND_FN) (const char *);
/*
/* void mkmap_open_register(type, open_fn)
/* const char *type;
/* MKMAP_OPEN_FN open_fn;
/*
/* MKMAP_OPEN_EXTEND_FN mkmap_open_extend(call_back)
/* MKMAP_OPEN_EXTEND_FN call_back;
/* DESCRIPTION /* DESCRIPTION
/* This module implements support for creating Postfix databases. /* This module implements support for creating Postfix databases.
/* It is a dict(3) wrapper that adds global locking to dict-level /* It is a dict(3) wrapper that adds global locking to dict-level
@ -57,15 +47,6 @@
/* /*
/* mkmap_close() closes the database, releases any locks, /* mkmap_close() closes the database, releases any locks,
/* and resumes signal delivery. All errors are fatal. /* and resumes signal delivery. All errors are fatal.
/*
/* mkmap_open_register() adds support for a new database type.
/*
/* mkmap_open_extend() registers a call-back function that looks
/* up the mkmap open() function for a database type that is not
/* registered, or null in case of error. The result value is the
/* last previously-registered call-back or null. A mkmap open()
/* function is cached after it is looked up through this extension
/* mechanism.
/* SEE ALSO /* SEE ALSO
/* sigdelay(3) suspend/resume signal delivery /* sigdelay(3) suspend/resume signal delivery
/* LICENSE /* LICENSE
@ -77,6 +58,11 @@
/* IBM T.J. Watson Research /* IBM T.J. Watson Research
/* P.O. Box 704 /* P.O. Box 704
/* Yorktown Heights, NY 10598, USA /* Yorktown Heights, NY 10598, USA
/*
/* Wietse Venema
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*--*/ /*--*/
/* System library. */ /* System library. */
@ -88,117 +74,11 @@
/* Utility library. */ /* Utility library. */
#include <msg.h> #include <msg.h>
#include <htable.h>
#include <dict.h> #include <dict.h>
#include <dict_db.h>
#include <dict_cdb.h>
#include <dict_dbm.h>
#include <dict_lmdb.h>
#include <dict_sdbm.h>
#include <dict_proxy.h>
#include <dict_fail.h>
#include <sigdelay.h> #include <sigdelay.h>
#include <mymalloc.h> #include <mymalloc.h>
#include <stringops.h> #include <stringops.h>
#include <mkmap.h>
/* Global library. */
#include "mkmap.h"
/*
* Information about available database types. Here, we list only those map
* types that support "bulk create" operations.
*
* We use a different table (in dict_open.c and mail_dict.c) when querying maps
* or when making incremental updates.
*/
typedef struct {
const char *type;
MKMAP_OPEN_FN before_open;
} MKMAP_OPEN_INFO;
static const MKMAP_OPEN_INFO mkmap_open_info[] = {
#ifndef USE_DYNAMIC_MAPS
#ifdef HAS_CDB
DICT_TYPE_CDB, mkmap_cdb_open,
#endif
#ifdef HAS_SDBM
DICT_TYPE_SDBM, mkmap_sdbm_open,
#endif
#ifdef HAS_LMDB
DICT_TYPE_LMDB, mkmap_lmdb_open,
#endif
#endif /* !USE_DYNAMIC_MAPS */
#ifdef HAS_DBM
DICT_TYPE_DBM, mkmap_dbm_open,
#endif
#ifdef HAS_DB
DICT_TYPE_HASH, mkmap_hash_open,
DICT_TYPE_BTREE, mkmap_btree_open,
#endif
DICT_TYPE_FAIL, mkmap_fail_open,
0,
};
static HTABLE *mkmap_open_hash;
static MKMAP_OPEN_EXTEND_FN mkmap_open_extend_hook = 0;
/* mkmap_open_init - one-off initialization */
static void mkmap_open_init(void)
{
static const char myname[] = "mkmap_open_init";
const MKMAP_OPEN_INFO *mp;
if (mkmap_open_hash != 0)
msg_panic("%s: multiple initialization", myname);
mkmap_open_hash = htable_create(10);
for (mp = mkmap_open_info; mp->type; mp++)
htable_enter(mkmap_open_hash, mp->type, (void *) mp);
}
/* mkmap_open_register - register dictionary type */
void mkmap_open_register(const char *type, MKMAP_OPEN_FN open_fn)
{
static const char myname[] = "mkmap_open_register";
MKMAP_OPEN_INFO *mp;
HTABLE_INFO *ht;
if (mkmap_open_hash == 0)
mkmap_open_init();
if (htable_find(mkmap_open_hash, type))
msg_panic("%s: database type exists: %s", myname, type);
mp = (MKMAP_OPEN_INFO *) mymalloc(sizeof(*mp));
mp->before_open = open_fn;
ht = htable_enter(mkmap_open_hash, type, (void *) mp);
mp->type = ht->key;
}
/* mkmap_open_extend - register alternate lookup function */
MKMAP_OPEN_EXTEND_FN mkmap_open_extend(MKMAP_OPEN_EXTEND_FN new_cb)
{
MKMAP_OPEN_EXTEND_FN old_cb;
old_cb = mkmap_open_extend_hook;
mkmap_open_extend_hook = new_cb;
return (old_cb);
}
/* mkmap_append - append entry to map */
#undef mkmap_append
void mkmap_append(MKMAP *mkmap, const char *key, const char *value)
{
DICT *dict = mkmap->dict;
if (dict_put(dict, key, value) != 0 && dict->error != 0)
msg_fatal("%s:%s: update failed", dict->type, dict->name);
}
/* mkmap_close - close database */ /* mkmap_close - close database */
@ -238,23 +118,15 @@ MKMAP *mkmap_open(const char *type, const char *path,
int open_flags, int dict_flags) int open_flags, int dict_flags)
{ {
MKMAP *mkmap; MKMAP *mkmap;
const MKMAP_OPEN_INFO *mp; const DICT_OPEN_INFO *dp;
MKMAP_OPEN_FN open_fn;
/* /*
* Find out what map type to use. * Find out what map type to use.
*/ */
if (mkmap_open_hash == 0) if ((dp = dict_open_lookup(type)) == 0)
mkmap_open_init(); msg_fatal("unsupported map type: %s", type);
if ((mp = (MKMAP_OPEN_INFO *) htable_find(mkmap_open_hash, type)) == 0) { if (dp->mkmap_fn == 0)
if (mkmap_open_extend_hook != 0 && msg_fatal("no 'map create' support for this type: %s", type);
(open_fn = mkmap_open_extend_hook(type)) != 0) {
mkmap_open_register(type, open_fn);
mp = (MKMAP_OPEN_INFO *) htable_find(mkmap_open_hash, type);
}
if (mp == 0)
msg_fatal("unsupported map type for this operation: %s", type);
}
if (msg_verbose) if (msg_verbose)
msg_info("open %s %s", type, path); msg_info("open %s %s", type, path);
@ -264,7 +136,7 @@ MKMAP *mkmap_open(const char *type, const char *path,
* dict modules implement locking only for individual record operations, * dict modules implement locking only for individual record operations,
* because most Postfix applications don't need global exclusive locks. * because most Postfix applications don't need global exclusive locks.
*/ */
mkmap = mp->before_open(path); mkmap = dp->mkmap_fn(path);
/* /*
* Delay signal delivery, so that we won't leave the database in an * Delay signal delivery, so that we won't leave the database in an

View File

@ -4,7 +4,7 @@
/* SUMMARY /* SUMMARY
/* create or open database, SDBM style /* create or open database, SDBM style
/* SYNOPSIS /* SYNOPSIS
/* #include <mkmap.h> /* #include <dict_sdbm.h>
/* /*
/* MKMAP *mkmap_sdbm_open(path) /* MKMAP *mkmap_sdbm_open(path)
/* const char *path; /* const char *path;
@ -28,6 +28,11 @@
/* IBM T.J. Watson Research /* IBM T.J. Watson Research
/* P.O. Box 704 /* P.O. Box 704
/* Yorktown Heights, NY 10598, USA /* Yorktown Heights, NY 10598, USA
/*
/* Wietse Venema
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*--*/ /*--*/
/* System library. */ /* System library. */
@ -40,14 +45,9 @@
#include <msg.h> #include <msg.h>
#include <mymalloc.h> #include <mymalloc.h>
#include <stringops.h> #include <stringops.h>
#include <dict.h>
#include <dict_sdbm.h> #include <dict_sdbm.h>
#include <myflock.h> #include <myflock.h>
/* Application-specific. */
#include "mkmap.h"
#ifdef HAS_SDBM #ifdef HAS_SDBM
#include <sdbm.h> #include <sdbm.h>