080ea46ad2
* TLS o Support for PKI-less TLS server certificate verification, where the CA public key or the server certificate is identified via DNSSEC lookup * LMDB database support * master o The master_service_disable parameter value syntax has changed: use "service/type" instead of "service.type". * postconf: o Support for advanced master.cf query and update operations. This was implemented primarily to support automated system management tools. o The postconf command produces more warnings * relay safety New smtpd_relay_restrictions parameter built-in default settings: smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination * postscreen whitelisting Allow a remote SMTP client to skip postscreen(8) tests based on its postscreen_dnsbl_sites score. OBS-URL: https://build.opensuse.org/package/show/server:mail/postfix?expand=0&rev=180
2261 lines
63 KiB
Diff
2261 lines
63 KiB
Diff
diff -rNu postfix-2.11.0/conf/dynamicmaps.cf postfix-2.11.0-patched/conf/dynamicmaps.cf
|
|
--- postfix-2.11.0/conf/dynamicmaps.cf 1970-01-01 01:00:00.000000000 +0100
|
|
+++ postfix-2.11.0-patched/conf/dynamicmaps.cf 2014-02-12 12:37:46.922115761 +0100
|
|
@@ -0,0 +1,7 @@
|
|
+# Postfix dynamic maps configuration file.
|
|
+#
|
|
+# The first match found is the one that is used.
|
|
+# Wildcards are not supported.
|
|
+#
|
|
+#type location of .so file open function (mkmap func)
|
|
+#==== ================================ ============= ============
|
|
diff -rNu postfix-2.11.0/conf/postfix-files postfix-2.11.0-patched/conf/postfix-files
|
|
--- postfix-2.11.0/conf/postfix-files 2013-12-18 16:11:44.000000000 +0100
|
|
+++ postfix-2.11.0-patched/conf/postfix-files 2014-02-12 12:37:46.923115768 +0100
|
|
@@ -65,6 +65,11 @@
|
|
$queue_directory/trace:d:$mail_owner:-:700:ucr
|
|
$daemon_directory/anvil:f:root:-:755
|
|
$daemon_directory/bounce:f:root:-:755
|
|
+$daemon_directory/dict_ldap.so:f:root:-:755
|
|
+$daemon_directory/dict_pcre.so:f:root:-:755
|
|
+$daemon_directory/dict_tcp.so:f:root:-:755
|
|
+$daemon_directory/dict_mysql.so:f:root:-:755
|
|
+$daemon_directory/dict_pgsql.so:f:root:-:755
|
|
$daemon_directory/cleanup:f:root:-:755
|
|
$daemon_directory/discard:f:root:-:755
|
|
$daemon_directory/dnsblog:f:root:-:755
|
|
@@ -97,6 +102,11 @@
|
|
$daemon_directory/trivial-rewrite:f:root:-:755
|
|
$daemon_directory/verify:f:root:-:755
|
|
$daemon_directory/virtual:f:root:-:755
|
|
+/usr/lib/libpostfix-dns.so.1:f:root:-:755
|
|
+/usr/lib/libpostfix-global.so.1:f:root:-:755
|
|
+/usr/lib/libpostfix-tls.so.1:f:root:-:755
|
|
+/usr/lib/libpostfix-master.so.1:f:root:-:755
|
|
+/usr/lib/libpostfix-util.so.1:f:root:-:755
|
|
$daemon_directory/nqmgr:h:$daemon_directory/qmgr
|
|
$daemon_directory/lmtp:h:$daemon_directory/smtp
|
|
$command_directory/postalias:f:root:-:755
|
|
@@ -120,6 +130,7 @@
|
|
$config_directory/aliases:f:root:-:644:p1
|
|
$config_directory/bounce.cf.default:f:root:-:644:1
|
|
$config_directory/canonical:f:root:-:644:p1
|
|
+$config_directory/dynamicmaps.cf:f:root:-:644:p
|
|
$config_directory/cidr_table:f:root:-:644:o
|
|
$config_directory/generic:f:root:-:644:p1
|
|
$config_directory/generics:f:root:-:644:o
|
|
diff -rNu postfix-2.11.0/src/dns/Makefile.in postfix-2.11.0-patched/src/dns/Makefile.in
|
|
--- postfix-2.11.0/src/dns/Makefile.in 2013-11-18 16:50:13.000000000 +0100
|
|
+++ postfix-2.11.0-patched/src/dns/Makefile.in 2014-02-12 12:37:46.923115768 +0100
|
|
@@ -14,7 +14,7 @@
|
|
LIB_DIR = ../../lib
|
|
INC_DIR = ../../include
|
|
|
|
-.c.o:; $(CC) $(CFLAGS) -c $*.c
|
|
+.c.o:; $(CC) -fPIC $(CFLAGS) -c $*.c
|
|
|
|
all: $(LIB)
|
|
|
|
@@ -31,12 +31,10 @@
|
|
root_tests:
|
|
|
|
$(LIB): $(OBJS)
|
|
- $(AR) $(ARFL) $(LIB) $?
|
|
- $(RANLIB) $(LIB)
|
|
+ gcc -shared -Wl,-soname,libpostfix-dns.so.1 -o $(LIB) $(OBJS) $(LIBS) $(SYSLIBS)
|
|
|
|
$(LIB_DIR)/$(LIB): $(LIB)
|
|
cp $(LIB) $(LIB_DIR)
|
|
- $(RANLIB) $(LIB_DIR)/$(LIB)
|
|
|
|
update: $(LIB_DIR)/$(LIB) $(HDRS)
|
|
-for i in $(HDRS); \
|
|
diff -rNu postfix-2.11.0/src/global/Makefile.in postfix-2.11.0-patched/src/global/Makefile.in
|
|
--- postfix-2.11.0/src/global/Makefile.in 2013-12-09 21:13:50.000000000 +0100
|
|
+++ postfix-2.11.0-patched/src/global/Makefile.in 2014-02-12 12:37:46.924115776 +0100
|
|
@@ -3,7 +3,7 @@
|
|
canon_addr.c cfg_parser.c cleanup_strerror.c cleanup_strflags.c \
|
|
clnt_stream.c conv_time.c db_common.c debug_peer.c debug_process.c \
|
|
defer.c deliver_completed.c deliver_flock.c deliver_pass.c \
|
|
- deliver_request.c dict_ldap.c dict_mysql.c dict_pgsql.c \
|
|
+ deliver_request.c \
|
|
dict_proxy.c dict_sqlite.c domain_list.c dot_lockfile.c dot_lockfile_as.c \
|
|
dsb_scan.c dsn.c dsn_buf.c dsn_mask.c dsn_print.c dsn_util.c \
|
|
ehlo_mask.c ext_prop.c file_id.c flush_clnt.c header_opts.c \
|
|
@@ -37,7 +37,7 @@
|
|
canon_addr.o cfg_parser.o cleanup_strerror.o cleanup_strflags.o \
|
|
clnt_stream.o conv_time.o db_common.o debug_peer.o debug_process.o \
|
|
defer.o deliver_completed.o deliver_flock.o deliver_pass.o \
|
|
- deliver_request.o dict_ldap.o dict_mysql.o dict_pgsql.o \
|
|
+ deliver_request.o \
|
|
dict_proxy.o dict_sqlite.o domain_list.o dot_lockfile.o dot_lockfile_as.o \
|
|
dsb_scan.o dsn.o dsn_buf.o dsn_mask.o dsn_print.o dsn_util.o \
|
|
ehlo_mask.o ext_prop.o file_id.o flush_clnt.o header_opts.o \
|
|
@@ -113,10 +113,13 @@
|
|
LIB_DIR = ../../lib
|
|
INC_DIR = ../../include
|
|
MAKES =
|
|
+LDAPSO = dict_ldap.so
|
|
+MYSQLSO = dict_mysql.so
|
|
+PGSQLSO = dict_pgsql.so
|
|
|
|
-.c.o:; $(CC) $(CFLAGS) -c $*.c
|
|
+.c.o:; $(CC) -fPIC $(CFLAGS) -c $*.c
|
|
|
|
-all: $(LIB)
|
|
+all: $(LIB) $(LDAPSO) $(MYSQLSO) $(PGSQLSO)
|
|
|
|
$(OBJS): ../../conf/makedefs.out
|
|
|
|
@@ -126,14 +129,30 @@
|
|
test: $(TESTPROG)
|
|
|
|
$(LIB): $(OBJS)
|
|
- $(AR) $(ARFL) $(LIB) $?
|
|
- $(RANLIB) $(LIB)
|
|
+ gcc -shared -Wl,-soname,libpostfix-global.so.1 -o $(LIB) $(OBJS) $(LIBS) $(SYSLIBS)
|
|
+
|
|
+$(LDAPSO): dict_ldap.o
|
|
+ gcc -shared -Wl,-soname,dict_ldap.so -o $@ $? -lldap -llber -L../../lib -lutil -L. -lglobal
|
|
+
|
|
+$(MYSQLSO): dict_mysql.o
|
|
+ gcc -shared -Wl,-soname,dict_mysql.so -o $@ $? -L/usr/lib/mysql -lmysqlclient -L. -lutil -lglobal
|
|
+
|
|
+$(PGSQLSO): dict_pgsql.o
|
|
+ gcc -shared -Wl,-soname,dict_pgsql.so -o $@ $? -lpq -L. -lutil -lglobal
|
|
|
|
$(LIB_DIR)/$(LIB): $(LIB)
|
|
cp $(LIB) $(LIB_DIR)
|
|
- $(RANLIB) $(LIB_DIR)/$(LIB)
|
|
|
|
-update: $(LIB_DIR)/$(LIB) $(HDRS)
|
|
+$(LIB_DIR)/$(LDAPSO): $(LDAPSO)
|
|
+ cp $(LDAPSO) $(LIB_DIR)
|
|
+
|
|
+$(LIB_DIR)/$(MYSQLSO): $(MYSQLSO)
|
|
+ cp $(MYSQLSO) $(LIB_DIR)
|
|
+
|
|
+$(LIB_DIR)/$(PGSQLSO): $(PGSQLSO)
|
|
+ cp $(PGSQLSO) $(LIB_DIR)
|
|
+
|
|
+update: $(LIB_DIR)/$(LIB) $(LIB_DIR)/${LDAPSO} $(LIB_DIR)/${MYSQLSO} $(LIB_DIR)/${PGSQLSO} $(HDRS)
|
|
-for i in $(HDRS); \
|
|
do \
|
|
cmp -s $$i $(INC_DIR)/$$i 2>/dev/null || cp $$i $(INC_DIR); \
|
|
@@ -584,7 +603,7 @@
|
|
lint $(DEFS) $(SRCS) $(LINTFIX)
|
|
|
|
clean:
|
|
- rm -f *.o $(LIB) *core $(TESTPROG) junk
|
|
+ rm -f *.o $(LIB) $(LDAPSO) $(MYSQLSO) $(PGSQLSO) *core $(TESTPROG) junk
|
|
rm -rf printfck
|
|
|
|
tidy: clean
|
|
diff -rNu postfix-2.11.0/src/global/mail_conf.c postfix-2.11.0-patched/src/global/mail_conf.c
|
|
--- postfix-2.11.0/src/global/mail_conf.c 2012-01-13 23:21:46.000000000 +0100
|
|
+++ postfix-2.11.0-patched/src/global/mail_conf.c 2014-02-12 12:37:46.924115776 +0100
|
|
@@ -190,6 +190,13 @@
|
|
if (dict_load_file_xt(CONFIG_DICT, path) == 0)
|
|
msg_fatal("open %s: %m", path);
|
|
myfree(path);
|
|
+
|
|
+#ifndef NO_DYNAMIC_MAPS
|
|
+ path = concatenate(var_config_dir, "/", "dynamicmaps.cf", (char *) 0);
|
|
+ dict_open_dlinfo(path);
|
|
+ myfree(path);
|
|
+#endif
|
|
+
|
|
}
|
|
|
|
/* mail_conf_flush - discard configuration dictionary */
|
|
diff -rNu postfix-2.11.0/src/global/mail_dict.c postfix-2.11.0-patched/src/global/mail_dict.c
|
|
--- postfix-2.11.0/src/global/mail_dict.c 2011-12-19 20:55:38.000000000 +0100
|
|
+++ postfix-2.11.0-patched/src/global/mail_dict.c 2014-02-12 12:37:46.924115776 +0100
|
|
@@ -47,6 +47,7 @@
|
|
|
|
static const DICT_OPEN_INFO dict_open_info[] = {
|
|
DICT_TYPE_PROXY, dict_proxy_open,
|
|
+#ifndef MAX_DYNAMIC_MAPS
|
|
#ifdef HAS_LDAP
|
|
DICT_TYPE_LDAP, dict_ldap_open,
|
|
#endif
|
|
@@ -60,6 +61,7 @@
|
|
DICT_TYPE_SQLITE, dict_sqlite_open,
|
|
#endif
|
|
DICT_TYPE_MEMCACHE, dict_memcache_open,
|
|
+#endif /* MAX_DYNAMIC_MAPS */
|
|
0,
|
|
};
|
|
|
|
diff -rNu postfix-2.11.0/src/global/mail_params.c postfix-2.11.0-patched/src/global/mail_params.c
|
|
--- postfix-2.11.0/src/global/mail_params.c 2014-01-08 02:19:18.000000000 +0100
|
|
+++ postfix-2.11.0-patched/src/global/mail_params.c 2014-02-12 12:37:46.925115784 +0100
|
|
@@ -79,6 +79,7 @@
|
|
/* char *var_export_environ;
|
|
/* char *var_debug_peer_list;
|
|
/* int var_debug_peer_level;
|
|
+/* int var_command_maxtime;
|
|
/* int var_in_flow_delay;
|
|
/* int var_fault_inj_code;
|
|
/* char *var_bounce_service;
|
|
@@ -273,6 +274,7 @@
|
|
char *var_export_environ;
|
|
char *var_debug_peer_list;
|
|
int var_debug_peer_level;
|
|
+int var_command_maxtime;
|
|
int var_fault_inj_code;
|
|
char *var_bounce_service;
|
|
char *var_cleanup_service;
|
|
@@ -284,6 +286,7 @@
|
|
char *var_error_service;
|
|
char *var_flush_service;
|
|
char *var_verify_service;
|
|
+char *var_scache_service;
|
|
char *var_trace_service;
|
|
char *var_proxymap_service;
|
|
char *var_proxywrite_service;
|
|
diff -rNu postfix-2.11.0/src/global/mkmap_open.c postfix-2.11.0-patched/src/global/mkmap_open.c
|
|
--- postfix-2.11.0/src/global/mkmap_open.c 2014-01-08 02:19:18.000000000 +0100
|
|
+++ postfix-2.11.0-patched/src/global/mkmap_open.c 2014-02-12 13:02:20.390317089 +0100
|
|
@@ -83,7 +83,7 @@
|
|
* We use a different table (in dict_open.c) when querying maps.
|
|
*/
|
|
typedef struct {
|
|
- char *type;
|
|
+ const char *type;
|
|
MKMAP *(*before_open) (const char *);
|
|
} MKMAP_OPEN_INFO;
|
|
|
|
@@ -166,7 +166,16 @@
|
|
*/
|
|
for (mp = mkmap_types; /* void */ ; mp++) {
|
|
if (mp->type == 0)
|
|
+#ifndef NO_DYNAMIC_MAPS
|
|
+ {
|
|
+ static MKMAP_OPEN_INFO oi;
|
|
+ oi.before_open=(MKMAP*(*)(const char*))dict_mkmap_func(type);
|
|
+ oi.type=type;
|
|
+ mp=&oi;
|
|
+ }
|
|
+#else
|
|
msg_fatal("unsupported map type for this operation: %s", type);
|
|
+#endif
|
|
if (strcmp(type, mp->type) == 0)
|
|
break;
|
|
}
|
|
diff -rNu postfix-2.11.0/src/master/Makefile.in postfix-2.11.0-patched/src/master/Makefile.in
|
|
--- postfix-2.11.0/src/master/Makefile.in 2013-11-18 16:50:14.000000000 +0100
|
|
+++ postfix-2.11.0-patched/src/master/Makefile.in 2014-02-12 12:37:46.926115791 +0100
|
|
@@ -22,7 +22,7 @@
|
|
INC_DIR = ../../include
|
|
BIN_DIR = ../../libexec
|
|
|
|
-.c.o:; $(CC) $(CFLAGS) -c $*.c
|
|
+.c.o:; $(CC) `for i in $(LIB_OBJ); do [ $$i = $@ ] && echo -fPIC; done` $(CFLAGS) -c $*.c
|
|
|
|
all: $(PROG) $(LIB)
|
|
|
|
@@ -41,12 +41,10 @@
|
|
root_tests:
|
|
|
|
$(LIB): $(LIB_OBJ)
|
|
- $(AR) $(ARFL) $(LIB) $?
|
|
- $(RANLIB) $(LIB)
|
|
+ gcc -shared -Wl,-soname,libpostfix-master.so.1 -o $(LIB) $(LIB_OBJ) $(LIBS) $(SYSLIBS)
|
|
|
|
$(LIB_DIR)/$(LIB): $(LIB)
|
|
cp $(LIB) $(LIB_DIR)/$(LIB)
|
|
- $(RANLIB) $(LIB_DIR)/$(LIB)
|
|
|
|
$(BIN_DIR)/$(PROG): $(PROG)
|
|
cp $(PROG) $(BIN_DIR)
|
|
diff -rNu postfix-2.11.0/src/milter/Makefile.in postfix-2.11.0-patched/src/milter/Makefile.in
|
|
--- postfix-2.11.0/src/milter/Makefile.in 2013-11-18 16:50:14.000000000 +0100
|
|
+++ postfix-2.11.0-patched/src/milter/Makefile.in 2014-02-12 12:37:46.926115791 +0100
|
|
@@ -14,7 +14,7 @@
|
|
INC_DIR = ../../include
|
|
MAKES =
|
|
|
|
-.c.o:; $(CC) $(CFLAGS) -c $*.c
|
|
+.c.o:; $(CC) -fPIC $(CFLAGS) -c $*.c
|
|
|
|
all: $(LIB)
|
|
|
|
@@ -30,12 +30,10 @@
|
|
root_tests:
|
|
|
|
$(LIB): $(OBJS)
|
|
- $(AR) $(ARFL) $(LIB) $?
|
|
- $(RANLIB) $(LIB)
|
|
+ gcc -shared -Wl,-soname,libpostfix-milter.so.1 -o $(LIB) $(OBJS) $(LIBS) $(SYSLIBS)
|
|
|
|
$(LIB_DIR)/$(LIB): $(LIB)
|
|
cp $(LIB) $(LIB_DIR)
|
|
- $(RANLIB) $(LIB_DIR)/$(LIB)
|
|
|
|
update: $(LIB_DIR)/$(LIB) $(HDRS)
|
|
-for i in $(HDRS); \
|
|
diff -rNu postfix-2.11.0/src/postconf/Makefile.in postfix-2.11.0-patched/src/postconf/Makefile.in
|
|
--- postfix-2.11.0/src/postconf/Makefile.in 2013-11-27 21:16:56.000000000 +0100
|
|
+++ postfix-2.11.0-patched/src/postconf/Makefile.in 2014-02-12 13:04:12.559089946 +0100
|
|
@@ -938,6 +938,7 @@
|
|
postconf_other.o: ../../include/argv.h
|
|
postconf_other.o: ../../include/dict.h
|
|
postconf_other.o: ../../include/htable.h
|
|
+postconf_other.o: ../../include/mail_params.h
|
|
postconf_other.o: ../../include/mbox_conf.h
|
|
postconf_other.o: ../../include/myflock.h
|
|
postconf_other.o: ../../include/name_code.h
|
|
diff -rNu postfix-2.11.0/src/postconf/postconf_other.c postfix-2.11.0-patched/src/postconf/postconf_other.c
|
|
--- postfix-2.11.0/src/postconf/postconf_other.c 2013-12-19 23:40:30.000000000 +0100
|
|
+++ postfix-2.11.0-patched/src/postconf/postconf_other.c 2014-02-12 12:37:46.927115797 +0100
|
|
@@ -47,10 +47,15 @@
|
|
#include <vstream.h>
|
|
#include <argv.h>
|
|
#include <dict.h>
|
|
+#include <mymalloc.h>
|
|
+#include <safe.h>
|
|
+#include <stringops.h>
|
|
|
|
/* Global library. */
|
|
|
|
#include <mbox_conf.h>
|
|
+#include <mail_params.h>
|
|
+#include <mail_conf.h>
|
|
|
|
/* XSASL library. */
|
|
|
|
@@ -67,6 +72,19 @@
|
|
ARGV *maps_argv;
|
|
int i;
|
|
|
|
+#ifndef NO_DYNAMIC_MAPS
|
|
+ char *path;
|
|
+ char *config_dir;
|
|
+
|
|
+ if (var_config_dir)
|
|
+ myfree(var_config_dir);
|
|
+ var_config_dir = mystrdup((config_dir = safe_getenv(CONF_ENV_PATH)) != 0 ?
|
|
+ config_dir : DEF_CONFIG_DIR); /* XXX */
|
|
+ path = concatenate(var_config_dir, "/", "dynamicmaps.cf", (char *) 0);
|
|
+ dict_open_dlinfo(path);
|
|
+ myfree(path);
|
|
+#endif
|
|
+
|
|
maps_argv = dict_mapnames();
|
|
for (i = 0; i < maps_argv->argc; i++)
|
|
vstream_printf("%s\n", maps_argv->argv[i]);
|
|
diff -rNu postfix-2.11.0/src/postmap/postmap.c postfix-2.11.0-patched/src/postmap/postmap.c
|
|
--- postfix-2.11.0/src/postmap/postmap.c 2013-11-20 16:14:32.000000000 +0100
|
|
+++ postfix-2.11.0-patched/src/postmap/postmap.c 2014-02-12 12:37:46.927115797 +0100
|
|
@@ -5,7 +5,7 @@
|
|
/* Postfix lookup table management
|
|
/* SYNOPSIS
|
|
/* .fi
|
|
-/* \fBpostmap\fR [\fB-Nbfhimnoprsvw\fR] [\fB-c \fIconfig_dir\fR]
|
|
+/* \fBpostmap\fR [\fB-Nbfhimnoprsuvw\fR] [\fB-c \fIconfig_dir\fR]
|
|
/* [\fB-d \fIkey\fR] [\fB-q \fIkey\fR]
|
|
/* [\fIfile_type\fR:]\fIfile_name\fR ...
|
|
/* DESCRIPTION
|
|
@@ -151,6 +151,8 @@
|
|
/* .sp
|
|
/* This feature is available in Postfix version 2.2 and later,
|
|
/* and is not available for all database types.
|
|
+/* .IP \fB-u\fR
|
|
+/* Upgrade the database to the current version.
|
|
/* .IP \fB-v\fR
|
|
/* Enable verbose logging for debugging purposes. Multiple \fB-v\fR
|
|
/* options make the software increasingly verbose.
|
|
@@ -764,6 +766,18 @@
|
|
dict_close(dict);
|
|
}
|
|
|
|
+/* postmap_upgrade - upgrade a map */
|
|
+
|
|
+static int postmap_upgrade(const char *map_type, const char *map_name)
|
|
+{
|
|
+ DICT *dict;
|
|
+
|
|
+ dict = dict_open3(map_type, map_name, O_RDWR,
|
|
+ DICT_FLAG_LOCK|DICT_FLAG_UPGRADE);
|
|
+ dict_close(dict);
|
|
+ return (dict != 0);
|
|
+}
|
|
+
|
|
/* usage - explain */
|
|
|
|
static NORETURN usage(char *myname)
|
|
@@ -784,6 +798,7 @@
|
|
int postmap_flags = POSTMAP_FLAG_AS_OWNER | POSTMAP_FLAG_SAVE_PERM;
|
|
int open_flags = O_RDWR | O_CREAT | O_TRUNC;
|
|
int dict_flags = DICT_FLAG_DUP_WARN | DICT_FLAG_FOLD_FIX;
|
|
+ int upgrade = 0;
|
|
char *query = 0;
|
|
char *delkey = 0;
|
|
int sequence = 0;
|
|
@@ -833,7 +848,7 @@
|
|
/*
|
|
* Parse JCL.
|
|
*/
|
|
- while ((ch = GETOPT(argc, argv, "Nbc:d:fhimnopq:rsvw")) > 0) {
|
|
+ while ((ch = GETOPT(argc, argv, "Nbc:d:fhimnopq:rsuvw")) > 0) {
|
|
switch (ch) {
|
|
default:
|
|
usage(argv[0]);
|
|
@@ -850,8 +865,8 @@
|
|
msg_fatal("out of memory");
|
|
break;
|
|
case 'd':
|
|
- if (sequence || query || delkey)
|
|
- msg_fatal("specify only one of -s -q or -d");
|
|
+ if (sequence || query || delkey || upgrade)
|
|
+ msg_fatal("specify only one of -s -q -u or -d");
|
|
delkey = optarg;
|
|
break;
|
|
case 'f':
|
|
@@ -877,8 +892,8 @@
|
|
postmap_flags &= ~POSTMAP_FLAG_SAVE_PERM;
|
|
break;
|
|
case 'q':
|
|
- if (sequence || query || delkey)
|
|
- msg_fatal("specify only one of -s -q or -d");
|
|
+ if (sequence || query || delkey || upgrade)
|
|
+ msg_fatal("specify only one of -s -q -u or -d");
|
|
query = optarg;
|
|
break;
|
|
case 'r':
|
|
@@ -886,10 +901,15 @@
|
|
dict_flags |= DICT_FLAG_DUP_REPLACE;
|
|
break;
|
|
case 's':
|
|
- if (query || delkey)
|
|
- msg_fatal("specify only one of -s or -q or -d");
|
|
+ if (query || delkey || upgrade)
|
|
+ msg_fatal("specify only one of -s or -q -u or -d");
|
|
sequence = 1;
|
|
break;
|
|
+ case 'u':
|
|
+ if (sequence || query || delkey || upgrade)
|
|
+ msg_fatal("specify only one of -s -q -u or -d");
|
|
+ upgrade=1;
|
|
+ break;
|
|
case 'v':
|
|
msg_verbose++;
|
|
break;
|
|
@@ -964,6 +984,21 @@
|
|
exit(0);
|
|
}
|
|
exit(1);
|
|
+ } else if (upgrade) { /* Upgrade the map(s) */
|
|
+ int success = 1;
|
|
+ if (optind + 1 > argc)
|
|
+ usage(argv[0]);
|
|
+ while (optind < argc) {
|
|
+ if ((path_name = split_at(argv[optind], ':')) != 0) {
|
|
+ success &= postmap_upgrade(argv[optind], path_name);
|
|
+ } else {
|
|
+ success &= postmap_upgrade(var_db_type, path_name);
|
|
+ }
|
|
+ if (!success)
|
|
+ exit(1);
|
|
+ optind++;
|
|
+ }
|
|
+ exit(0);
|
|
} else { /* create/update map(s) */
|
|
if (optind + 1 > argc)
|
|
usage(argv[0]);
|
|
diff -rNu postfix-2.11.0/src/tls/Makefile.in postfix-2.11.0-patched/src/tls/Makefile.in
|
|
--- postfix-2.11.0/src/tls/Makefile.in 2013-12-31 17:26:05.000000000 +0100
|
|
+++ postfix-2.11.0-patched/src/tls/Makefile.in 2014-02-12 12:37:46.927115797 +0100
|
|
@@ -24,7 +24,7 @@
|
|
INC_DIR = ../../include
|
|
MAKES =
|
|
|
|
-.c.o:; $(CC) $(CFLAGS) -c $*.c
|
|
+.c.o:; $(CC) -fPIC $(CFLAGS) -c $*.c
|
|
|
|
all: $(LIB)
|
|
|
|
@@ -40,12 +40,10 @@
|
|
root_tests:
|
|
|
|
$(LIB): $(OBJS)
|
|
- $(AR) $(ARFL) $(LIB) $?
|
|
- $(RANLIB) $(LIB)
|
|
+ gcc -shared -Wl,-soname,libpostfix-tls.so.1 -o $(LIB) $(OBJS) $(LIBS) $(SYSLIBS)
|
|
|
|
$(LIB_DIR)/$(LIB): $(LIB)
|
|
cp $(LIB) $(LIB_DIR)
|
|
- $(RANLIB) $(LIB_DIR)/$(LIB)
|
|
|
|
update: $(LIB_DIR)/$(LIB) $(HDRS)
|
|
-for i in $(HDRS); \
|
|
diff -rNu postfix-2.11.0/src/tls/tls_client.c postfix-2.11.0-patched/src/tls/tls_client.c
|
|
--- postfix-2.11.0/src/tls/tls_client.c 2013-12-15 14:35:52.000000000 +0100
|
|
+++ postfix-2.11.0-patched/src/tls/tls_client.c 2014-02-12 12:37:46.927115797 +0100
|
|
@@ -156,6 +156,8 @@
|
|
#define STR vstring_str
|
|
#define LEN VSTRING_LEN
|
|
|
|
+int var_tls_daemon_rand_bytes;
|
|
+
|
|
/* load_clnt_session - load session from client cache (non-callback) */
|
|
|
|
static SSL_SESSION *load_clnt_session(TLS_SESS_STATE *TLScontext)
|
|
diff -rNu postfix-2.11.0/src/tls/tls_server.c postfix-2.11.0-patched/src/tls/tls_server.c
|
|
--- postfix-2.11.0/src/tls/tls_server.c 2013-12-15 14:35:52.000000000 +0100
|
|
+++ postfix-2.11.0-patched/src/tls/tls_server.c 2014-02-12 12:37:46.927115797 +0100
|
|
@@ -155,6 +155,8 @@
|
|
#define STR(x) vstring_str(x)
|
|
#define LEN(x) VSTRING_LEN(x)
|
|
|
|
+int var_tls_daemon_rand_bytes;
|
|
+
|
|
/* Application-specific. */
|
|
|
|
/*
|
|
diff -rNu postfix-2.11.0/src/util/Makefile.in postfix-2.11.0-patched/src/util/Makefile.in
|
|
--- postfix-2.11.0/src/util/Makefile.in 2013-12-26 16:28:55.000000000 +0100
|
|
+++ postfix-2.11.0-patched/src/util/Makefile.in 2014-02-12 13:08:35.151917586 +0100
|
|
@@ -36,15 +36,15 @@
|
|
ip_match.c nbbio.c base32_code.c dict_test.c \
|
|
dict_fail.c msg_rate_delay.c dict_surrogate.c warn_stat.c \
|
|
dict_sockmap.c line_number.c recv_pass_attr.c pass_accept.c \
|
|
- poll_fd.c timecmp.c slmdb.c
|
|
+ poll_fd.c timecmp.c slmdb.c load_lib.c sdbm.c
|
|
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_scan_plain.o auto_clnt.o base64_code.o basename.o binhash.o \
|
|
chroot_uid.o cidr_match.o clean_env.o close_on_exec.o concatenate.o \
|
|
ctable.o dict.o dict_alloc.o dict_cdb.o dict_cidr.o dict_db.o \
|
|
dict_dbm.o dict_debug.o dict_env.o dict_ht.o dict_lmdb.o dict_ni.o dict_nis.o \
|
|
- dict_nisplus.o dict_open.o dict_pcre.o dict_regexp.o dict_sdbm.o \
|
|
- dict_static.o dict_tcp.o dict_unix.o dir_forest.o doze.o dummy_read.o \
|
|
+ dict_nisplus.o dict_open.o dict_regexp.o dict_sdbm.o \
|
|
+ dict_static.o dict_unix.o dir_forest.o doze.o dummy_read.o \
|
|
dummy_write.o duplex_pipe.o environ.o events.o exec_command.o \
|
|
fifo_listen.o fifo_trigger.o file_limit.o find_inet.o fsspace.o \
|
|
fullname.o get_domainname.o get_hostname.o hex_code.o hex_quote.o \
|
|
@@ -74,7 +74,7 @@
|
|
ip_match.o nbbio.o base32_code.o dict_test.o \
|
|
dict_fail.o msg_rate_delay.o dict_surrogate.o warn_stat.o \
|
|
dict_sockmap.o line_number.o recv_pass_attr.o pass_accept.o \
|
|
- poll_fd.o timecmp.o slmdb.o
|
|
+ poll_fd.o timecmp.o slmdb.o load_lib.o sdbm.o
|
|
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 \
|
|
dict_cdb.h dict_cidr.h dict_db.h dict_dbm.h dict_env.h dict_ht.h \
|
|
@@ -88,7 +88,7 @@
|
|
msg_output.h msg_syslog.h msg_vstream.h mvect.h myaddrinfo.h myflock.h \
|
|
mymalloc.h myrand.h name_code.h name_mask.h netstring.h nvtable.h \
|
|
open_as.h open_lock.h percentm.h posix_signals.h readlline.h ring.h \
|
|
- safe.h safe_open.h sane_accept.h sane_connect.h sane_fsops.h \
|
|
+ safe.h safe_open.h sane_accept.h sane_connect.h sane_fsops.h sdbm.h load_lib.h \
|
|
sane_socketpair.h sane_time.h scan_dir.h set_eugid.h set_ugid.h \
|
|
sigdelay.h sock_addr.h spawn_command.h split_at.h stat_as.h \
|
|
stringops.h sys_defs.h timed_connect.h timed_wait.h trigger.h \
|
|
@@ -103,6 +103,8 @@
|
|
CFLAGS = $(DEBUG) $(OPT) $(DEFS)
|
|
FILES = Makefile $(SRCS) $(HDRS)
|
|
INCL =
|
|
+PCRESO = dict_pcre.so
|
|
+TCPSO = dict_tcp.so
|
|
LIB = libutil.a
|
|
TESTPROG= dict_open dup2_pass_on_exec events exec_command fifo_open \
|
|
fifo_rdonly_bug fifo_rdwr_bug fifo_trigger fsspace fullname \
|
|
@@ -119,10 +121,11 @@
|
|
|
|
LIB_DIR = ../../lib
|
|
INC_DIR = ../../include
|
|
+LIBS = $(LIB_DIR)/$(LIB) $(LIB_DIR)/$(PCRESO) $(LIB_DIR)/$(TCPSO)
|
|
|
|
-.c.o:; $(CC) $(CFLAGS) -c $*.c
|
|
+.c.o:; $(CC) -fPIC $(CFLAGS) -c $*.c
|
|
|
|
-all: $(LIB)
|
|
+all: $(LIB) $(PCRESO) $(TCPSO)
|
|
|
|
$(OBJS): ../../conf/makedefs.out
|
|
|
|
@@ -131,15 +134,25 @@
|
|
|
|
test: $(TESTPROG)
|
|
|
|
+$(PCRESO): dict_pcre.o
|
|
+ gcc -shared -Wl,-soname,dict_pcre.so -o $@ $? -lpcre -L. -lutil
|
|
+
|
|
+$(TCPSO): dict_tcp.o
|
|
+ gcc -shared -Wl,-soname,dict_tcp.so -o $@ $? -L. -lutil
|
|
+
|
|
$(LIB): $(OBJS)
|
|
- $(AR) $(ARFL) $(LIB) $?
|
|
- $(RANLIB) $(LIB)
|
|
+ gcc -shared -Wl,-soname,libpostfix-util.so.1 -o $(LIB) $(OBJS) -ldl $(SYSLIBS)
|
|
|
|
$(LIB_DIR)/$(LIB): $(LIB)
|
|
cp $(LIB) $(LIB_DIR)
|
|
- $(RANLIB) $(LIB_DIR)/$(LIB)
|
|
|
|
-update: $(LIB_DIR)/$(LIB) $(HDRS)
|
|
+$(LIB_DIR)/$(PCRESO): $(PCRESO)
|
|
+ cp $(PCRESO) $(LIB_DIR)
|
|
+
|
|
+$(LIB_DIR)/$(TCPSO): $(TCPSO)
|
|
+ cp $(TCPSO) $(LIB_DIR)
|
|
+
|
|
+update: $(LIBS) $(HDRS)
|
|
-for i in $(HDRS); \
|
|
do \
|
|
cmp -s $$i $(INC_DIR)/$$i 2>/dev/null || cp $$i $(INC_DIR); \
|
|
@@ -161,7 +174,8 @@
|
|
lint $(DEFS) $(SRCS) $(LINTFIX)
|
|
|
|
clean:
|
|
- rm -f *.o $(LIB) *core $(TESTPROG) junk $(MAKES) *.tmp
|
|
+ rm -f *.o $(LIB) $(PCRESO) $(TCPSO) *core $(TESTPROG) \
|
|
+ junk $(MAKES) *.tmp
|
|
rm -rf printfck
|
|
|
|
tidy: clean
|
|
diff -rNu postfix-2.11.0/src/util/dict.h postfix-2.11.0-patched/src/util/dict.h
|
|
--- postfix-2.11.0/src/util/dict.h 2013-11-20 16:31:49.000000000 +0100
|
|
+++ postfix-2.11.0-patched/src/util/dict.h 2014-02-12 13:10:21.671699162 +0100
|
|
@@ -98,6 +98,7 @@
|
|
#define DICT_FLAG_OPEN_LOCK (1<<16) /* perm lock if not multi-writer safe */
|
|
#define DICT_FLAG_BULK_UPDATE (1<<17) /* optimize for bulk updates */
|
|
#define DICT_FLAG_MULTI_WRITER (1<<18) /* multi-writer safe map */
|
|
+#define DICT_FLAG_UPGRADE (1<<30) /* Upgrade the db */
|
|
|
|
/* IMPORTANT: Update the dict_mask[] table when the above changes */
|
|
|
|
@@ -187,6 +188,11 @@
|
|
extern DICT *dict_open(const char *, int, int);
|
|
extern DICT *dict_open3(const char *, const char *, int, int);
|
|
extern void dict_open_register(const char *, DICT *(*) (const char *, int, int));
|
|
+#ifndef NO_DYNAMIC_MAPS
|
|
+extern void dict_open_dlinfo(const char *path);
|
|
+typedef void* (*dict_mkmap_func_t)(const char *);
|
|
+dict_mkmap_func_t dict_mkmap_func(const char *dict_type);
|
|
+#endif
|
|
|
|
#define dict_get(dp, key) ((const char *) (dp)->lookup((dp), (key)))
|
|
#define dict_put(dp, key, val) (dp)->update((dp), (key), (val))
|
|
diff -rNu postfix-2.11.0/src/util/dict_db.c postfix-2.11.0-patched/src/util/dict_db.c
|
|
--- postfix-2.11.0/src/util/dict_db.c 2012-01-25 01:41:08.000000000 +0100
|
|
+++ postfix-2.11.0-patched/src/util/dict_db.c 2014-02-12 12:37:46.928115804 +0100
|
|
@@ -693,6 +693,12 @@
|
|
msg_fatal("set DB cache size %d: %m", dict_db_cache_size);
|
|
if (type == DB_HASH && db->set_h_nelem(db, DICT_DB_NELM) != 0)
|
|
msg_fatal("set DB hash element count %d: %m", DICT_DB_NELM);
|
|
+ if (dict_flags & DICT_FLAG_UPGRADE) {
|
|
+ if (msg_verbose)
|
|
+ msg_info("upgrading database %s",db_path);
|
|
+ if ((errno = db->upgrade(db,db_path,0)) != 0)
|
|
+ msg_fatal("upgrade of database %s: %m",db_path);
|
|
+ }
|
|
#if DB_VERSION_MAJOR == 5 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR > 0)
|
|
if ((errno = db->open(db, 0, db_path, 0, type, db_flags, 0644)) != 0)
|
|
FREE_RETURN(dict_surrogate(class, path, open_flags, dict_flags,
|
|
diff -rNu postfix-2.11.0/src/util/dict_dbm.c postfix-2.11.0-patched/src/util/dict_dbm.c
|
|
--- postfix-2.11.0/src/util/dict_dbm.c 2013-11-14 19:28:03.000000000 +0100
|
|
+++ postfix-2.11.0-patched/src/util/dict_dbm.c 2014-02-12 13:13:01.431869325 +0100
|
|
@@ -417,6 +417,10 @@
|
|
char *dbm_path = 0;
|
|
int lock_fd;
|
|
|
|
+#ifdef HAVE_GDBM
|
|
+ msg_fatal("%s: gdbm maps use locking that is incompatible with postfix. Use a hash map instead.",
|
|
+ path);
|
|
+#endif
|
|
/*
|
|
* Let the optimizer worry about eliminating redundant code.
|
|
*/
|
|
diff -rNu postfix-2.11.0/src/util/dict_open.c postfix-2.11.0-patched/src/util/dict_open.c
|
|
--- postfix-2.11.0/src/util/dict_open.c 2014-01-08 02:19:18.000000000 +0100
|
|
+++ postfix-2.11.0-patched/src/util/dict_open.c 2014-02-12 14:40:45.018379461 +0100
|
|
@@ -54,6 +54,9 @@
|
|
/* int dict_longjmp(dict, val)
|
|
/* DICT *dict;
|
|
/* int val;
|
|
+/*
|
|
+/* void (*)() dict_mkmap_func(const char *dict_type)
|
|
+/*
|
|
/* DESCRIPTION
|
|
/* This module implements a low-level interface to multiple
|
|
/* physical dictionary types.
|
|
@@ -201,6 +204,9 @@
|
|
/* returns non-zero when dict_setjmp() and dict_longjmp()
|
|
/* are enabled for a given dictionary.
|
|
/*
|
|
+/* dict_mkmap_func() returns a pointer to the mkmap setup function
|
|
+/* for the given map type, as given in /etc/dynamicmaps.cf
|
|
+/*
|
|
/* NB: non-local jumps such as dict_longjmp() are not safe for
|
|
/* jumping out of any routine that manipulates DICT data.
|
|
/* longjmp() like calls are best avoided in signal handlers.
|
|
@@ -251,6 +257,9 @@
|
|
#include <strings.h>
|
|
#endif
|
|
|
|
+#include <sys/stat.h>
|
|
+#include <unistd.h>
|
|
+
|
|
/* Utility library. */
|
|
|
|
#include <argv.h>
|
|
@@ -281,6 +290,27 @@
|
|
#include <htable.h>
|
|
#include <myflock.h>
|
|
|
|
+#ifndef NO_DYNAMIC_MAPS
|
|
+#include <load_lib.h>
|
|
+#include <vstring.h>
|
|
+#include <vstream.h>
|
|
+#include <vstring_vstream.h>
|
|
+#include <mvect.h>
|
|
+
|
|
+ /*
|
|
+ * Interface for dynamic map loading.
|
|
+ */
|
|
+typedef struct {
|
|
+ const char *pattern;
|
|
+ const char *soname;
|
|
+ const char *openfunc;
|
|
+ const char *mkmapfunc;
|
|
+} DLINFO;
|
|
+
|
|
+static DLINFO *dict_dlinfo;
|
|
+static DLINFO *dict_open_dlfind(const char *type);
|
|
+#endif
|
|
+
|
|
/*
|
|
* lookup table for available map types.
|
|
*/
|
|
@@ -296,7 +326,9 @@
|
|
DICT_TYPE_ENVIRON, dict_env_open,
|
|
DICT_TYPE_HT, dict_ht_open,
|
|
DICT_TYPE_UNIX, dict_unix_open,
|
|
+#ifndef MAX_DYNAMIC_MAPS
|
|
DICT_TYPE_TCP, dict_tcp_open,
|
|
+#endif
|
|
#ifdef HAS_SDBM
|
|
DICT_TYPE_SDBM, dict_sdbm_open,
|
|
#endif
|
|
@@ -319,9 +351,11 @@
|
|
#ifdef HAS_NETINFO
|
|
DICT_TYPE_NETINFO, dict_ni_open,
|
|
#endif
|
|
+#ifndef MAX_DYNAMIC_MAPS
|
|
#ifdef HAS_PCRE
|
|
DICT_TYPE_PCRE, dict_pcre_open,
|
|
#endif
|
|
+#endif /* MAX_DYNAMIC_MAPS */
|
|
#ifdef HAS_POSIX_REGEXP
|
|
DICT_TYPE_REGEXP, dict_regexp_open,
|
|
#endif
|
|
@@ -382,9 +416,32 @@
|
|
dict_type, dict_name);
|
|
if (dict_open_hash == 0)
|
|
dict_open_init();
|
|
- if ((dp = (DICT_OPEN_INFO *) htable_find(dict_open_hash, dict_type)) == 0)
|
|
+ if ((dp = (DICT_OPEN_INFO *) htable_find(dict_open_hash, dict_type)) == 0) {
|
|
+#ifdef NO_DYNAMIC_MAPS
|
|
return (dict_surrogate(dict_type, dict_name, open_flags, dict_flags,
|
|
"unsupported dictionary type: %s", dict_type));
|
|
+#else
|
|
+ struct stat st;
|
|
+ LIB_FN fn[2];
|
|
+ DICT *(*open) (const char *, int, int);
|
|
+ DLINFO *dl=dict_open_dlfind(dict_type);
|
|
+ if (!dl)
|
|
+ msg_fatal("%s: unsupported dictionary type: %s: Is the postfix-%s package installed?", myname, dict_type, dict_type);
|
|
+ if (stat(dl->soname,&st) < 0) {
|
|
+ msg_fatal("%s: unsupported dictionary type: %s (%s not found. Is the postfix-%s package installed?)",
|
|
+ myname, dict_type, dl->soname, dict_type);
|
|
+ }
|
|
+ fn[0].name = dl->openfunc;
|
|
+ fn[0].ptr = (void**)&open;
|
|
+ fn[1].name = NULL;
|
|
+ load_library_symbols(dl->soname, fn, NULL);
|
|
+ dict_open_register(dict_type, open);
|
|
+ dp = (DICT_OPEN_INFO *) htable_find(dict_open_hash, dict_type);
|
|
+#endif
|
|
+ }
|
|
+ if (msg_verbose>1) {
|
|
+ msg_info("%s: calling %s open routine",myname,dict_type);
|
|
+ }
|
|
if ((dict = dp->open(dict_name, open_flags, dict_flags)) == 0)
|
|
return (dict_surrogate(dict_type, dict_name, open_flags, dict_flags,
|
|
"cannot open %s:%s: %m", dict_type, dict_name));
|
|
@@ -408,6 +465,36 @@
|
|
return (dict);
|
|
}
|
|
|
|
+dict_mkmap_func_t dict_mkmap_func(const char *dict_type)
|
|
+{
|
|
+ char *myname="dict_mkmap_func";
|
|
+ struct stat st;
|
|
+ LIB_FN fn[2];
|
|
+ dict_mkmap_func_t mkmap;
|
|
+ DLINFO *dl;
|
|
+#ifndef NO_DYNAMIC_MAPS
|
|
+ if (!dict_dlinfo)
|
|
+ msg_fatal("dlinfo==NULL");
|
|
+ dl=dict_open_dlfind(dict_type);
|
|
+ if (!dl)
|
|
+ msg_fatal("%s: unsupported dictionary type: %s: Is the postfix-%s package installed?", myname, dict_type, dict_type);
|
|
+ if (stat(dl->soname,&st) < 0) {
|
|
+ msg_fatal("%s: unsupported dictionary type: %s (%s not found. Is the postfix-%s package installed?)",
|
|
+ myname, dict_type, dl->soname, dict_type);
|
|
+ }
|
|
+ if (!dl->mkmapfunc)
|
|
+ msg_fatal("%s: unsupported dictionary type: %s does not allow map creation.", myname, dict_type);
|
|
+
|
|
+ fn[0].name = dl->mkmapfunc;
|
|
+ fn[0].ptr = (void**)&mkmap;
|
|
+ fn[1].name = NULL;
|
|
+ load_library_symbols(dl->soname, fn, NULL);
|
|
+ return mkmap;
|
|
+#else
|
|
+ return (void(*)())NULL;
|
|
+#endif
|
|
+}
|
|
+
|
|
/* dict_open_register - register dictionary type */
|
|
|
|
void dict_open_register(const char *type,
|
|
@@ -441,6 +528,9 @@
|
|
HTABLE_INFO **ht;
|
|
DICT_OPEN_INFO *dp;
|
|
ARGV *mapnames;
|
|
+#ifndef NO_DYNAMIC_MAPS
|
|
+ DLINFO *dlp;
|
|
+#endif
|
|
|
|
if (dict_open_hash == 0)
|
|
dict_open_init();
|
|
@@ -449,6 +539,13 @@
|
|
dp = (DICT_OPEN_INFO *) ht[0]->value;
|
|
argv_add(mapnames, dp->type, ARGV_END);
|
|
}
|
|
+#ifndef NO_DYNAMIC_MAPS
|
|
+ if (!dict_dlinfo)
|
|
+ msg_fatal("dlinfo==NULL");
|
|
+ for (dlp=dict_dlinfo; dlp->pattern; dlp++) {
|
|
+ argv_add(mapnames, dlp->pattern, ARGV_END);
|
|
+ }
|
|
+#endif
|
|
qsort((void *) mapnames->argv, mapnames->argc, sizeof(mapnames->argv[0]),
|
|
dict_sort_alpha_cpp);
|
|
myfree((char *) ht_info);
|
|
@@ -456,6 +553,87 @@
|
|
return mapnames;
|
|
}
|
|
|
|
+#ifndef NO_DYNAMIC_MAPS
|
|
+#define STREQ(x,y) (x == y || (x[0] == y[0] && strcmp(x,y) == 0))
|
|
+
|
|
+void dict_open_dlinfo(const char *path)
|
|
+{
|
|
+ char *myname="dict_open_dlinfo";
|
|
+ VSTREAM *conf_fp=vstream_fopen(path,O_RDONLY,0);
|
|
+ VSTRING *buf = vstring_alloc(100);
|
|
+ char *cp;
|
|
+ ARGV *argv;
|
|
+ MVECT vector;
|
|
+ int nelm=0;
|
|
+ int linenum=0;
|
|
+
|
|
+ dict_dlinfo=(DLINFO*)mvect_alloc(&vector,sizeof(DLINFO),3,NULL,NULL);
|
|
+
|
|
+ if (!conf_fp) {
|
|
+ msg_warn("%s: cannot open %s. No dynamic maps will be allowed.",
|
|
+ myname, path);
|
|
+ } else {
|
|
+ while (vstring_get_nonl(buf,conf_fp) != VSTREAM_EOF) {
|
|
+ cp = vstring_str(buf);
|
|
+ linenum++;
|
|
+ if (*cp == '#' || *cp == '\0')
|
|
+ continue;
|
|
+ argv = argv_split(cp, " \t");
|
|
+ if (argv->argc != 3 && argv->argc != 4) {
|
|
+ msg_fatal("%s: Expected \"pattern .so-name open-function [mkmap-function]\" at line %d",
|
|
+ myname, linenum);
|
|
+ }
|
|
+ if (STREQ(argv->argv[0],"*")) {
|
|
+ msg_warn("%s: wildcard dynamic map entry no longer supported.",
|
|
+ myname);
|
|
+ continue;
|
|
+ }
|
|
+ if (argv->argv[1][0] != '/') {
|
|
+ msg_fatal("%s: .so name must begin with a \"/\" at line %d",
|
|
+ myname, linenum);
|
|
+ }
|
|
+ if (nelm >= vector.nelm) {
|
|
+ dict_dlinfo=(DLINFO*)mvect_realloc(&vector,vector.nelm+3);
|
|
+ }
|
|
+ dict_dlinfo[nelm].pattern = mystrdup(argv->argv[0]);
|
|
+ dict_dlinfo[nelm].soname = mystrdup(argv->argv[1]);
|
|
+ dict_dlinfo[nelm].openfunc = mystrdup(argv->argv[2]);
|
|
+ if (argv->argc==4)
|
|
+ dict_dlinfo[nelm].mkmapfunc = mystrdup(argv->argv[3]);
|
|
+ else
|
|
+ dict_dlinfo[nelm].mkmapfunc = NULL;
|
|
+ nelm++;
|
|
+ argv_free(argv);
|
|
+ }
|
|
+ }
|
|
+ if (nelm >= vector.nelm) {
|
|
+ dict_dlinfo=(DLINFO*)mvect_realloc(&vector,vector.nelm+1);
|
|
+ }
|
|
+ dict_dlinfo[nelm].pattern = NULL;
|
|
+ dict_dlinfo[nelm].soname = NULL;
|
|
+ dict_dlinfo[nelm].openfunc = NULL;
|
|
+ dict_dlinfo[nelm].mkmapfunc = NULL;
|
|
+ if (conf_fp)
|
|
+ vstream_fclose(conf_fp);
|
|
+ vstring_free(buf);
|
|
+}
|
|
+
|
|
+static DLINFO *dict_open_dlfind(const char *type)
|
|
+{
|
|
+ DLINFO *dp;
|
|
+
|
|
+ if (!dict_dlinfo)
|
|
+ return NULL;
|
|
+
|
|
+ for (dp=dict_dlinfo; dp->pattern; dp++) {
|
|
+ if (STREQ(dp->pattern,type))
|
|
+ return dp;
|
|
+ }
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
+#endif /* !NO_DYNAMIC_MAPS */
|
|
+
|
|
#ifdef TEST
|
|
|
|
/*
|
|
diff -rNu postfix-2.11.0/src/util/load_lib.c postfix-2.11.0-patched/src/util/load_lib.c
|
|
--- postfix-2.11.0/src/util/load_lib.c 1970-01-01 01:00:00.000000000 +0100
|
|
+++ postfix-2.11.0-patched/src/util/load_lib.c 2014-02-12 12:37:46.929115810 +0100
|
|
@@ -0,0 +1,135 @@
|
|
+/*++
|
|
+/* NAME
|
|
+/* load_lib 3
|
|
+/* SUMMARY
|
|
+/* library loading wrappers
|
|
+/* SYNOPSIS
|
|
+/* #include <load_lib.h>
|
|
+/*
|
|
+/* extern int load_library_symbols(const char *, LIB_FN *, LIB_FN *);
|
|
+/* const char *libname;
|
|
+/* LIB_FN *libfuncs;
|
|
+/* LIB_FN *libdata;
|
|
+/*
|
|
+/* DESCRIPTION
|
|
+/* This module loads functions from libraries, returnine pointers
|
|
+/* to the named functions.
|
|
+/*
|
|
+/* load_library_symbols() loads all of the desired functions, and
|
|
+/* returns zero for success, or exits via msg_fatal().
|
|
+/*
|
|
+/* SEE ALSO
|
|
+/* msg(3) diagnostics interface
|
|
+/* DIAGNOSTICS
|
|
+/* Problems are reported via the msg(3) diagnostics routines:
|
|
+/* library not found, symbols not found, other fatal errors.
|
|
+/* LICENSE
|
|
+/* .ad
|
|
+/* .fi
|
|
+/* The Secure Mailer license must be distributed with this software.
|
|
+/* AUTHOR(S)
|
|
+/* LaMont Jones
|
|
+/* Hewlett-Packard Company
|
|
+/* 3404 Harmony Road
|
|
+/* Fort Collins, CO 80528, USA
|
|
+/*
|
|
+/* Wietse Venema
|
|
+/* IBM T.J. Watson Research
|
|
+/* P.O. Box 704
|
|
+/* Yorktown Heights, NY 10598, USA
|
|
+/*--*/
|
|
+
|
|
+/* System libraries. */
|
|
+
|
|
+#include "sys_defs.h"
|
|
+#include <stdlib.h>
|
|
+#include <stddef.h>
|
|
+#include <string.h>
|
|
+#if defined(HAS_DLOPEN)
|
|
+#include <dlfcn.h>
|
|
+#elif defined(HAS_SHL_LOAD)
|
|
+#include <dl.h>
|
|
+#endif
|
|
+
|
|
+/* Application-specific. */
|
|
+
|
|
+#include "msg.h"
|
|
+#include "load_lib.h"
|
|
+
|
|
+extern int load_library_symbols(const char * libname, LIB_FN * libfuncs, LIB_FN * libdata)
|
|
+{
|
|
+ char *myname = "load_library_symbols";
|
|
+ LIB_FN *fn;
|
|
+
|
|
+#if defined(HAS_DLOPEN)
|
|
+ void *handle;
|
|
+ char *emsg;
|
|
+
|
|
+ handle=dlopen(libname,RTLD_NOW);
|
|
+ emsg=dlerror();
|
|
+ if (emsg) {
|
|
+ msg_fatal("%s: dlopen failure loading %s: %s", myname, libname, emsg);
|
|
+ }
|
|
+
|
|
+ if (libfuncs) {
|
|
+ for (fn=libfuncs; fn->name; fn++) {
|
|
+ *(fn->ptr) = dlsym(handle,fn->name);
|
|
+ emsg=dlerror();
|
|
+ if (emsg) {
|
|
+ msg_fatal("%s: dlsym failure looking up %s in %s: %s", myname,
|
|
+ fn->name, libname, emsg);
|
|
+ }
|
|
+ if (msg_verbose>1) {
|
|
+ msg_info("loaded %s = %lx",fn->name, *((long*)(fn->ptr)));
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (libdata) {
|
|
+ for (fn=libdata; fn->name; fn++) {
|
|
+ *(fn->ptr) = dlsym(handle,fn->name);
|
|
+ emsg=dlerror();
|
|
+ if (emsg) {
|
|
+ msg_fatal("%s: dlsym failure looking up %s in %s: %s", myname,
|
|
+ fn->name, libname, emsg);
|
|
+ }
|
|
+ if (msg_verbose>1) {
|
|
+ msg_info("loaded %s = %lx",fn->name, *((long*)(fn->ptr)));
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+#elif defined(HAS_SHL_LOAD)
|
|
+ shl_t handle;
|
|
+
|
|
+ handle = shl_load(libname,BIND_IMMEDIATE,0);
|
|
+
|
|
+ if (libfuncs) {
|
|
+ for (fn=libfuncs; fn->name; fn++) {
|
|
+ if (shl_findsym(&handle,fn->name,TYPE_PROCEDURE,fn->ptr) != 0) {
|
|
+ msg_fatal("%s: shl_findsym failure looking up %s in %s: %m",
|
|
+ myname, fn->name, libname);
|
|
+ }
|
|
+ if (msg_verbose>1) {
|
|
+ msg_info("loaded %s = %x",fn->name, *((long*)(fn->ptr)));
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (libdata) {
|
|
+ for (fn=libdata; fn->name; fn++) {
|
|
+ if (shl_findsym(&handle,fn->name,TYPE_DATA,fn->ptr) != 0) {
|
|
+ msg_fatal("%s: shl_findsym failure looking up %s in %s: %m",
|
|
+ myname, fn->name, libname);
|
|
+ }
|
|
+ if (msg_verbose>1) {
|
|
+ msg_info("loaded %s = %x",fn->name, *((long*)(fn->ptr)));
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+#else
|
|
+ msg_fatal("%s: need dlopen or shl_load support for dynamic libraries",
|
|
+ myname);
|
|
+#endif
|
|
+ return 0;
|
|
+}
|
|
diff -rNu postfix-2.11.0/src/util/load_lib.h postfix-2.11.0-patched/src/util/load_lib.h
|
|
--- postfix-2.11.0/src/util/load_lib.h 1970-01-01 01:00:00.000000000 +0100
|
|
+++ postfix-2.11.0-patched/src/util/load_lib.h 2014-02-12 12:37:46.929115810 +0100
|
|
@@ -0,0 +1,41 @@
|
|
+#ifndef _LOAD_LIB_H_INCLUDED_
|
|
+#define _LOAD_LIB_H_INCLUDED_
|
|
+
|
|
+/*++
|
|
+/* NAME
|
|
+/* load_lib 3h
|
|
+/* SUMMARY
|
|
+/* library loading wrappers
|
|
+/* SYNOPSIS
|
|
+/* #include "load_lib.h"
|
|
+/* DESCRIPTION
|
|
+/* .nf
|
|
+
|
|
+ /*
|
|
+ * External interface.
|
|
+ */
|
|
+/* NULL name terminates list */
|
|
+typedef struct LIB_FN {
|
|
+ const char *name;
|
|
+ void **ptr;
|
|
+} LIB_FN;
|
|
+
|
|
+extern int load_library_symbols(const char *, LIB_FN *, LIB_FN *);
|
|
+
|
|
+/* LICENSE
|
|
+/* .ad
|
|
+/* .fi
|
|
+/* The Secure Mailer license must be distributed with this software.
|
|
+/* AUTHOR(S)
|
|
+/* LaMont Jones
|
|
+/* Hewlett-Packard Company
|
|
+/* 3404 Harmony Road
|
|
+/* Fort Collins, CO 80528, USA
|
|
+/*
|
|
+/* Wietse Venema
|
|
+/* IBM T.J. Watson Research
|
|
+/* P.O. Box 704
|
|
+/* Yorktown Heights, NY 10598, USA
|
|
+/*--*/
|
|
+
|
|
+#endif
|
|
diff -rNu postfix-2.11.0/src/util/sdbm.c postfix-2.11.0-patched/src/util/sdbm.c
|
|
--- postfix-2.11.0/src/util/sdbm.c 1970-01-01 01:00:00.000000000 +0100
|
|
+++ postfix-2.11.0-patched/src/util/sdbm.c 2014-02-12 12:37:46.929115810 +0100
|
|
@@ -0,0 +1,972 @@
|
|
+/*++
|
|
+/* NAME
|
|
+/* sdbm 3h
|
|
+/* SUMMARY
|
|
+/* SDBM Simple DBM: ndbm work-alike hashed database library
|
|
+/* SYNOPSIS
|
|
+/* include "sdbm.h"
|
|
+/* DESCRIPTION
|
|
+/* This file includes the public domain SDBM (ndbm work-alike hashed
|
|
+/* database library), based on Per-Aake Larson's Dynamic Hashing
|
|
+/* algorithms. BIT 18 (1978).
|
|
+/* author: oz@nexus.yorku.ca
|
|
+/* status: public domain
|
|
+/* The file has been patched following the advice of Uwe Ohse
|
|
+/* <uwe@ohse.de>:
|
|
+/* --------------------------------------------------------------
|
|
+/* this patch fixes a problem with sdbms .dir file, which arrises when
|
|
+/* a second .dir block is needed for the first time. read() returns 0
|
|
+/* in that case, and the library forgot to initialize that new block.
|
|
+/*
|
|
+/* A related problem is that the calculation of db->maxbno is wrong.
|
|
+/* It just appends 4096*BYTESIZ bits, which is not enough except for
|
|
+/* small databases (.dir basically doubles everytime it's too small).
|
|
+/* --------------------------------------------------------------
|
|
+/* According to Uwe Ohse, the patch has also been submitted to the
|
|
+/* author of SDBM. (The 4096*BYTESIZ bits comment may apply with a
|
|
+/* different size for Postfix/TLS, as the patch was sent against the
|
|
+/* original SDBM distributiona and for Postfix/TLS I have changed the
|
|
+/* default sizes.
|
|
+/* .nf
|
|
+/*--*/
|
|
+
|
|
+/*
|
|
+ * sdbm - ndbm work-alike hashed database library
|
|
+ * based on Per-Aake Larson's Dynamic Hashing algorithms. BIT 18 (1978).
|
|
+ * author: oz@nexus.yorku.ca
|
|
+ * status: public domain.
|
|
+ *
|
|
+ * core routines
|
|
+ */
|
|
+
|
|
+#include <stdio.h>
|
|
+#include <stdlib.h>
|
|
+#ifdef WIN32
|
|
+#include <io.h>
|
|
+#include <errno.h>
|
|
+#else
|
|
+#include <unistd.h>
|
|
+#endif
|
|
+#include <sys/types.h>
|
|
+#include <sys/stat.h>
|
|
+#include <fcntl.h>
|
|
+#include <errno.h>
|
|
+#include <string.h>
|
|
+#ifdef __STDC__
|
|
+#include <stddef.h>
|
|
+#endif
|
|
+#include <mymalloc.h>
|
|
+
|
|
+#include <sdbm.h>
|
|
+
|
|
+/*
|
|
+ * useful macros
|
|
+ */
|
|
+#define bad(x) ((x).dptr == NULL || (x).dsize <= 0)
|
|
+#define exhash(item) sdbm_hash((item).dptr, (item).dsize)
|
|
+#define ioerr(db) ((db)->flags |= DBM_IOERR)
|
|
+
|
|
+#define OFF_PAG(off) (long) (off) * PBLKSIZ
|
|
+#define OFF_DIR(off) (long) (off) * DBLKSIZ
|
|
+
|
|
+static long masks[] =
|
|
+{
|
|
+ 000000000000, 000000000001, 000000000003, 000000000007,
|
|
+ 000000000017, 000000000037, 000000000077, 000000000177,
|
|
+ 000000000377, 000000000777, 000000001777, 000000003777,
|
|
+ 000000007777, 000000017777, 000000037777, 000000077777,
|
|
+ 000000177777, 000000377777, 000000777777, 000001777777,
|
|
+ 000003777777, 000007777777, 000017777777, 000037777777,
|
|
+ 000077777777, 000177777777, 000377777777, 000777777777,
|
|
+ 001777777777, 003777777777, 007777777777, 017777777777
|
|
+};
|
|
+
|
|
+datum nullitem =
|
|
+{NULL, 0};
|
|
+
|
|
+typedef struct
|
|
+{
|
|
+ int dirf; /* directory file descriptor */
|
|
+ int pagf; /* page file descriptor */
|
|
+ int flags; /* status/error flags, see below */
|
|
+ long maxbno; /* size of dirfile in bits */
|
|
+ long curbit; /* current bit number */
|
|
+ long hmask; /* current hash mask */
|
|
+ long blkptr; /* current block for nextkey */
|
|
+ int keyptr; /* current key for nextkey */
|
|
+ long blkno; /* current page to read/write */
|
|
+ long pagbno; /* current page in pagbuf */
|
|
+ char *pagbuf; /* page file block buffer */
|
|
+ long dirbno; /* current block in dirbuf */
|
|
+ char *dirbuf; /* directory file block buffer */
|
|
+} DBM;
|
|
+
|
|
+
|
|
+/* ************************* */
|
|
+
|
|
+/*
|
|
+ * sdbm - ndbm work-alike hashed database library
|
|
+ * based on Per-Aake Larson's Dynamic Hashing algorithms. BIT 18 (1978).
|
|
+ * author: oz@nexus.yorku.ca
|
|
+ * status: public domain. keep it that way.
|
|
+ *
|
|
+ * hashing routine
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * polynomial conversion ignoring overflows
|
|
+ * [this seems to work remarkably well, in fact better
|
|
+ * then the ndbm hash function. Replace at your own risk]
|
|
+ * use: 65599 nice.
|
|
+ * 65587 even better.
|
|
+ */
|
|
+static long sdbm_hash (char *str, int len)
|
|
+{
|
|
+ unsigned long n = 0;
|
|
+
|
|
+#ifdef DUFF
|
|
+#define HASHC n = *str++ + 65599 * n
|
|
+ if (len > 0)
|
|
+ {
|
|
+ int loop = (len + 8 - 1) >> 3;
|
|
+
|
|
+ switch (len & (8 - 1))
|
|
+ {
|
|
+ case 0:
|
|
+ do
|
|
+ {
|
|
+ HASHC;
|
|
+ case 7:
|
|
+ HASHC;
|
|
+ case 6:
|
|
+ HASHC;
|
|
+ case 5:
|
|
+ HASHC;
|
|
+ case 4:
|
|
+ HASHC;
|
|
+ case 3:
|
|
+ HASHC;
|
|
+ case 2:
|
|
+ HASHC;
|
|
+ case 1:
|
|
+ HASHC;
|
|
+ }
|
|
+ while (--loop);
|
|
+ }
|
|
+
|
|
+ }
|
|
+#else
|
|
+ while (len--)
|
|
+ n = *str++ + 65599 * n;
|
|
+#endif
|
|
+ return n;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * check page sanity:
|
|
+ * number of entries should be something
|
|
+ * reasonable, and all offsets in the index should be in order.
|
|
+ * this could be made more rigorous.
|
|
+ */
|
|
+static int chkpage (char *pag)
|
|
+{
|
|
+ int n;
|
|
+ int off;
|
|
+ short *ino = (short *) pag;
|
|
+
|
|
+ if ((n = ino[0]) < 0 || n > PBLKSIZ / sizeof (short))
|
|
+ return 0;
|
|
+
|
|
+ if (n > 0)
|
|
+ {
|
|
+ off = PBLKSIZ;
|
|
+ for (ino++; n > 0; ino += 2)
|
|
+ {
|
|
+ if (ino[0] > off || ino[1] > off ||
|
|
+ ino[1] > ino[0])
|
|
+ return 0;
|
|
+ off = ino[1];
|
|
+ n -= 2;
|
|
+ }
|
|
+ }
|
|
+ return 1;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * search for the key in the page.
|
|
+ * return offset index in the range 0 < i < n.
|
|
+ * return 0 if not found.
|
|
+ */
|
|
+static int seepair (char *pag, int n, char *key, int siz)
|
|
+{
|
|
+ int i;
|
|
+ int off = PBLKSIZ;
|
|
+ short *ino = (short *) pag;
|
|
+
|
|
+ for (i = 1; i < n; i += 2)
|
|
+ {
|
|
+ if (siz == off - ino[i] &&
|
|
+ memcmp (key, pag + ino[i], siz) == 0)
|
|
+ return i;
|
|
+ off = ino[i + 1];
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+#ifdef SEEDUPS
|
|
+static int duppair (char *pag, datum key)
|
|
+{
|
|
+ short *ino = (short *) pag;
|
|
+
|
|
+ return ino[0] > 0 && seepair (pag, ino[0], key.dptr, key.dsize) > 0;
|
|
+}
|
|
+
|
|
+#endif
|
|
+
|
|
+/* ************************* */
|
|
+
|
|
+/*
|
|
+ * sdbm - ndbm work-alike hashed database library
|
|
+ * based on Per-Aake Larson's Dynamic Hashing algorithms. BIT 18 (1978).
|
|
+ * author: oz@nexus.yorku.ca
|
|
+ * status: public domain.
|
|
+ *
|
|
+ * page-level routines
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * page format:
|
|
+ * +------------------------------+
|
|
+ * ino | n | keyoff | datoff | keyoff |
|
|
+ * +------------+--------+--------+
|
|
+ * | datoff | - - - ----> |
|
|
+ * +--------+---------------------+
|
|
+ * | F R E E A R E A |
|
|
+ * +--------------+---------------+
|
|
+ * | <---- - - - | data |
|
|
+ * +--------+-----+----+----------+
|
|
+ * | key | data | key |
|
|
+ * +--------+----------+----------+
|
|
+ *
|
|
+ * calculating the offsets for free area: if the number
|
|
+ * of entries (ino[0]) is zero, the offset to the END of
|
|
+ * the free area is the block size. Otherwise, it is the
|
|
+ * nth (ino[ino[0]]) entry's offset.
|
|
+ */
|
|
+
|
|
+static int fitpair (char *pag, int need)
|
|
+{
|
|
+ int n;
|
|
+ int off;
|
|
+ int avail;
|
|
+ short *ino = (short *) pag;
|
|
+
|
|
+ off = ((n = ino[0]) > 0) ? ino[n] : PBLKSIZ;
|
|
+ avail = off - (n + 1) * sizeof (short);
|
|
+ need += 2 * sizeof (short);
|
|
+
|
|
+ return need <= avail;
|
|
+}
|
|
+
|
|
+static void putpair (char *pag, datum key, datum val)
|
|
+{
|
|
+ int n;
|
|
+ int off;
|
|
+ short *ino = (short *) pag;
|
|
+
|
|
+ off = ((n = ino[0]) > 0) ? ino[n] : PBLKSIZ;
|
|
+/*
|
|
+ * enter the key first
|
|
+ */
|
|
+ off -= key.dsize;
|
|
+ (void) memcpy (pag + off, key.dptr, key.dsize);
|
|
+ ino[n + 1] = off;
|
|
+/*
|
|
+ * now the data
|
|
+ */
|
|
+ off -= val.dsize;
|
|
+ (void) memcpy (pag + off, val.dptr, val.dsize);
|
|
+ ino[n + 2] = off;
|
|
+/*
|
|
+ * adjust item count
|
|
+ */
|
|
+ ino[0] += 2;
|
|
+}
|
|
+
|
|
+static datum getpair (char *pag, datum key)
|
|
+{
|
|
+ int i;
|
|
+ int n;
|
|
+ datum val;
|
|
+ short *ino = (short *) pag;
|
|
+
|
|
+ if ((n = ino[0]) == 0)
|
|
+ return nullitem;
|
|
+
|
|
+ if ((i = seepair (pag, n, key.dptr, key.dsize)) == 0)
|
|
+ return nullitem;
|
|
+
|
|
+ val.dptr = pag + ino[i + 1];
|
|
+ val.dsize = ino[i] - ino[i + 1];
|
|
+ return val;
|
|
+}
|
|
+
|
|
+static datum getnkey (char *pag, int num)
|
|
+{
|
|
+ datum key;
|
|
+ int off;
|
|
+ short *ino = (short *) pag;
|
|
+
|
|
+ num = num * 2 - 1;
|
|
+ if (ino[0] == 0 || num > ino[0])
|
|
+ return nullitem;
|
|
+
|
|
+ off = (num > 1) ? ino[num - 1] : PBLKSIZ;
|
|
+
|
|
+ key.dptr = pag + ino[num];
|
|
+ key.dsize = off - ino[num];
|
|
+
|
|
+ return key;
|
|
+}
|
|
+
|
|
+static int delpair (char *pag, datum key)
|
|
+{
|
|
+ int n;
|
|
+ int i;
|
|
+ short *ino = (short *) pag;
|
|
+
|
|
+ if ((n = ino[0]) == 0)
|
|
+ return 0;
|
|
+
|
|
+ if ((i = seepair (pag, n, key.dptr, key.dsize)) == 0)
|
|
+ return 0;
|
|
+/*
|
|
+ * found the key. if it is the last entry
|
|
+ * [i.e. i == n - 1] we just adjust the entry count.
|
|
+ * hard case: move all data down onto the deleted pair,
|
|
+ * shift offsets onto deleted offsets, and adjust them.
|
|
+ * [note: 0 < i < n]
|
|
+ */
|
|
+ if (i < n - 1)
|
|
+ {
|
|
+ int m;
|
|
+ char *dst = pag + (i == 1 ? PBLKSIZ : ino[i - 1]);
|
|
+ char *src = pag + ino[i + 1];
|
|
+ int zoo = dst - src;
|
|
+
|
|
+/*
|
|
+ * shift data/keys down
|
|
+ */
|
|
+ m = ino[i + 1] - ino[n];
|
|
+#ifdef DUFF
|
|
+#define MOVB *--dst = *--src
|
|
+ if (m > 0)
|
|
+ {
|
|
+ int loop = (m + 8 - 1) >> 3;
|
|
+
|
|
+ switch (m & (8 - 1))
|
|
+ {
|
|
+ case 0:
|
|
+ do
|
|
+ {
|
|
+ MOVB;
|
|
+ case 7:
|
|
+ MOVB;
|
|
+ case 6:
|
|
+ MOVB;
|
|
+ case 5:
|
|
+ MOVB;
|
|
+ case 4:
|
|
+ MOVB;
|
|
+ case 3:
|
|
+ MOVB;
|
|
+ case 2:
|
|
+ MOVB;
|
|
+ case 1:
|
|
+ MOVB;
|
|
+ }
|
|
+ while (--loop);
|
|
+ }
|
|
+ }
|
|
+#else
|
|
+ dst -= m;
|
|
+ src -= m;
|
|
+ memmove (dst, src, m);
|
|
+#endif
|
|
+/*
|
|
+ * adjust offset index up
|
|
+ */
|
|
+ while (i < n - 1)
|
|
+ {
|
|
+ ino[i] = ino[i + 2] + zoo;
|
|
+ i++;
|
|
+ }
|
|
+ }
|
|
+ ino[0] -= 2;
|
|
+ return 1;
|
|
+}
|
|
+
|
|
+static void splpage (char *pag, char *new, long sbit)
|
|
+{
|
|
+ datum key;
|
|
+ datum val;
|
|
+
|
|
+ int n;
|
|
+ int off = PBLKSIZ;
|
|
+ char cur[PBLKSIZ];
|
|
+ short *ino = (short *) cur;
|
|
+
|
|
+ (void) memcpy (cur, pag, PBLKSIZ);
|
|
+ (void) memset (pag, 0, PBLKSIZ);
|
|
+ (void) memset (new, 0, PBLKSIZ);
|
|
+
|
|
+ n = ino[0];
|
|
+ for (ino++; n > 0; ino += 2)
|
|
+ {
|
|
+ key.dptr = cur + ino[0];
|
|
+ key.dsize = off - ino[0];
|
|
+ val.dptr = cur + ino[1];
|
|
+ val.dsize = ino[0] - ino[1];
|
|
+/*
|
|
+ * select the page pointer (by looking at sbit) and insert
|
|
+ */
|
|
+ (void) putpair ((exhash (key) & sbit) ? new : pag, key, val);
|
|
+
|
|
+ off = ino[1];
|
|
+ n -= 2;
|
|
+ }
|
|
+}
|
|
+
|
|
+static int getdbit (DBM * db, long dbit)
|
|
+{
|
|
+ long c;
|
|
+ long dirb;
|
|
+
|
|
+ c = dbit / BYTESIZ;
|
|
+ dirb = c / DBLKSIZ;
|
|
+
|
|
+ if (dirb != db->dirbno)
|
|
+ {
|
|
+ int got;
|
|
+ if (lseek (db->dirf, OFF_DIR (dirb), SEEK_SET) < 0
|
|
+ || (got = read(db->dirf, db->dirbuf, DBLKSIZ)) < 0)
|
|
+ return 0;
|
|
+ if (got==0)
|
|
+ memset(db->dirbuf,0,DBLKSIZ);
|
|
+ db->dirbno = dirb;
|
|
+ }
|
|
+
|
|
+ return db->dirbuf[c % DBLKSIZ] & (1 << dbit % BYTESIZ);
|
|
+}
|
|
+
|
|
+static int setdbit (DBM * db, long dbit)
|
|
+{
|
|
+ long c;
|
|
+ long dirb;
|
|
+
|
|
+ c = dbit / BYTESIZ;
|
|
+ dirb = c / DBLKSIZ;
|
|
+
|
|
+ if (dirb != db->dirbno)
|
|
+ {
|
|
+ int got;
|
|
+ if (lseek (db->dirf, OFF_DIR (dirb), SEEK_SET) < 0
|
|
+ || (got = read(db->dirf, db->dirbuf, DBLKSIZ)) < 0)
|
|
+ return 0;
|
|
+ if (got==0)
|
|
+ memset(db->dirbuf,0,DBLKSIZ);
|
|
+ db->dirbno = dirb;
|
|
+ }
|
|
+
|
|
+ db->dirbuf[c % DBLKSIZ] |= (1 << dbit % BYTESIZ);
|
|
+
|
|
+#if 0
|
|
+ if (dbit >= db->maxbno)
|
|
+ db->maxbno += DBLKSIZ * BYTESIZ;
|
|
+#else
|
|
+ if (OFF_DIR((dirb+1))*BYTESIZ > db->maxbno)
|
|
+ db->maxbno=OFF_DIR((dirb+1))*BYTESIZ;
|
|
+#endif
|
|
+
|
|
+ if (lseek (db->dirf, OFF_DIR (dirb), SEEK_SET) < 0
|
|
+ || write (db->dirf, db->dirbuf, DBLKSIZ) < 0)
|
|
+ return 0;
|
|
+
|
|
+ return 1;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * getnext - get the next key in the page, and if done with
|
|
+ * the page, try the next page in sequence
|
|
+ */
|
|
+static datum getnext (DBM * db)
|
|
+{
|
|
+ datum key;
|
|
+
|
|
+ for (;;)
|
|
+ {
|
|
+ db->keyptr++;
|
|
+ key = getnkey (db->pagbuf, db->keyptr);
|
|
+ if (key.dptr != NULL)
|
|
+ return key;
|
|
+/*
|
|
+ * we either run out, or there is nothing on this page..
|
|
+ * try the next one... If we lost our position on the
|
|
+ * file, we will have to seek.
|
|
+ */
|
|
+ db->keyptr = 0;
|
|
+ if (db->pagbno != db->blkptr++)
|
|
+ if (lseek (db->pagf, OFF_PAG (db->blkptr), SEEK_SET) < 0)
|
|
+ break;
|
|
+ db->pagbno = db->blkptr;
|
|
+ if (read (db->pagf, db->pagbuf, PBLKSIZ) <= 0)
|
|
+ break;
|
|
+ if (!chkpage (db->pagbuf))
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ return ioerr (db), nullitem;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * all important binary trie traversal
|
|
+ */
|
|
+static int getpage (DBM * db, long hash)
|
|
+{
|
|
+ int hbit;
|
|
+ long dbit;
|
|
+ long pagb;
|
|
+
|
|
+ dbit = 0;
|
|
+ hbit = 0;
|
|
+ while (dbit < db->maxbno && getdbit (db, dbit))
|
|
+ dbit = 2 * dbit + ((hash & (1 << hbit++)) ? 2 : 1);
|
|
+
|
|
+ db->curbit = dbit;
|
|
+ db->hmask = masks[hbit];
|
|
+
|
|
+ pagb = hash & db->hmask;
|
|
+/*
|
|
+ * see if the block we need is already in memory.
|
|
+ * note: this lookaside cache has about 10% hit rate.
|
|
+ */
|
|
+ if (pagb != db->pagbno)
|
|
+ {
|
|
+/*
|
|
+ * note: here, we assume a "hole" is read as 0s.
|
|
+ * if not, must zero pagbuf first.
|
|
+ */
|
|
+ if (lseek (db->pagf, OFF_PAG (pagb), SEEK_SET) < 0
|
|
+ || read (db->pagf, db->pagbuf, PBLKSIZ) < 0)
|
|
+ return 0;
|
|
+ if (!chkpage (db->pagbuf))
|
|
+ return 0;
|
|
+ db->pagbno = pagb;
|
|
+ }
|
|
+ return 1;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * makroom - make room by splitting the overfull page
|
|
+ * this routine will attempt to make room for SPLTMAX times before
|
|
+ * giving up.
|
|
+ */
|
|
+static int makroom (DBM * db, long hash, int need)
|
|
+{
|
|
+ long newp;
|
|
+ char twin[PBLKSIZ];
|
|
+ char *pag = db->pagbuf;
|
|
+ char *new = twin;
|
|
+ int smax = SPLTMAX;
|
|
+
|
|
+ do
|
|
+ {
|
|
+/*
|
|
+ * split the current page
|
|
+ */
|
|
+ (void) splpage (pag, new, db->hmask + 1);
|
|
+/*
|
|
+ * address of the new page
|
|
+ */
|
|
+ newp = (hash & db->hmask) | (db->hmask + 1);
|
|
+
|
|
+/*
|
|
+ * write delay, read avoidence/cache shuffle:
|
|
+ * select the page for incoming pair: if key is to go to the new page,
|
|
+ * write out the previous one, and copy the new one over, thus making
|
|
+ * it the current page. If not, simply write the new page, and we are
|
|
+ * still looking at the page of interest. current page is not updated
|
|
+ * here, as sdbm_store will do so, after it inserts the incoming pair.
|
|
+ */
|
|
+ if (hash & (db->hmask + 1))
|
|
+ {
|
|
+ if (lseek (db->pagf, OFF_PAG (db->pagbno), SEEK_SET) < 0
|
|
+ || write (db->pagf, db->pagbuf, PBLKSIZ) < 0)
|
|
+ return 0;
|
|
+ db->pagbno = newp;
|
|
+ (void) memcpy (pag, new, PBLKSIZ);
|
|
+ }
|
|
+ else if (lseek (db->pagf, OFF_PAG (newp), SEEK_SET) < 0
|
|
+ || write (db->pagf, new, PBLKSIZ) < 0)
|
|
+ return 0;
|
|
+
|
|
+ if (!setdbit (db, db->curbit))
|
|
+ return 0;
|
|
+/*
|
|
+ * see if we have enough room now
|
|
+ */
|
|
+ if (fitpair (pag, need))
|
|
+ return 1;
|
|
+/*
|
|
+ * try again... update curbit and hmask as getpage would have
|
|
+ * done. because of our update of the current page, we do not
|
|
+ * need to read in anything. BUT we have to write the current
|
|
+ * [deferred] page out, as the window of failure is too great.
|
|
+ */
|
|
+ db->curbit = 2 * db->curbit +
|
|
+ ((hash & (db->hmask + 1)) ? 2 : 1);
|
|
+ db->hmask |= db->hmask + 1;
|
|
+
|
|
+ if (lseek (db->pagf, OFF_PAG (db->pagbno), SEEK_SET) < 0
|
|
+ || write (db->pagf, db->pagbuf, PBLKSIZ) < 0)
|
|
+ return 0;
|
|
+
|
|
+ }
|
|
+ while (--smax);
|
|
+/*
|
|
+ * if we are here, this is real bad news. After SPLTMAX splits,
|
|
+ * we still cannot fit the key. say goodnight.
|
|
+ */
|
|
+#ifdef BADMESS
|
|
+ (void) write (2, "sdbm: cannot insert after SPLTMAX attempts.\n", 44);
|
|
+#endif
|
|
+ return 0;
|
|
+
|
|
+}
|
|
+
|
|
+static SDBM *sdbm_prep (char *dirname, char *pagname, int flags, int mode)
|
|
+{
|
|
+ SDBM *db;
|
|
+ struct stat dstat;
|
|
+
|
|
+ if ((db = (SDBM *) mymalloc (sizeof (SDBM))) == NULL)
|
|
+ return errno = ENOMEM, (SDBM *) NULL;
|
|
+
|
|
+ db->flags = 0;
|
|
+ db->blkptr = 0;
|
|
+ db->keyptr = 0;
|
|
+/*
|
|
+ * adjust user flags so that WRONLY becomes RDWR,
|
|
+ * as required by this package. Also set our internal
|
|
+ * flag for RDONLY if needed.
|
|
+ */
|
|
+ if (flags & O_WRONLY)
|
|
+ flags = (flags & ~O_WRONLY) | O_RDWR;
|
|
+ else if ((flags & 03) == O_RDONLY)
|
|
+ db->flags = DBM_RDONLY;
|
|
+#if defined(OS2) || defined(MSDOS) || defined(WIN32)
|
|
+ flags |= O_BINARY;
|
|
+#endif
|
|
+
|
|
+/*
|
|
+ * Make sure to ignore the O_EXCL option, as the file might exist due
|
|
+ * to the locking.
|
|
+ */
|
|
+ flags &= ~O_EXCL;
|
|
+
|
|
+/*
|
|
+ * open the files in sequence, and stat the dirfile.
|
|
+ * If we fail anywhere, undo everything, return NULL.
|
|
+ */
|
|
+
|
|
+ if ((db->pagf = open (pagname, flags, mode)) > -1)
|
|
+ {
|
|
+ if ((db->dirf = open (dirname, flags, mode)) > -1)
|
|
+ {
|
|
+/*
|
|
+ * need the dirfile size to establish max bit number.
|
|
+ */
|
|
+ if (fstat (db->dirf, &dstat) == 0)
|
|
+ {
|
|
+ /*
|
|
+ * success
|
|
+ */
|
|
+ return db;
|
|
+ }
|
|
+ msg_info ("closing dirf");
|
|
+ (void) close (db->dirf);
|
|
+ }
|
|
+ msg_info ("closing pagf");
|
|
+ (void) close (db->pagf);
|
|
+ }
|
|
+ myfree ((char *) db);
|
|
+ return (SDBM *) NULL;
|
|
+}
|
|
+
|
|
+static DBM *sdbm_internal_open (SDBM * sdbm)
|
|
+{
|
|
+ DBM *db;
|
|
+ struct stat dstat;
|
|
+
|
|
+ if ((db = (DBM *) mymalloc (sizeof (DBM))) == NULL)
|
|
+ return errno = ENOMEM, (DBM *) NULL;
|
|
+
|
|
+ db->flags = sdbm->flags;
|
|
+ db->hmask = 0;
|
|
+ db->blkptr = sdbm->blkptr;
|
|
+ db->keyptr = sdbm->keyptr;
|
|
+ db->pagf = sdbm->pagf;
|
|
+ db->dirf = sdbm->dirf;
|
|
+ db->pagbuf = sdbm->pagbuf;
|
|
+ db->dirbuf = sdbm->dirbuf;
|
|
+
|
|
+/*
|
|
+ * need the dirfile size to establish max bit number.
|
|
+ */
|
|
+ if (fstat (db->dirf, &dstat) == 0)
|
|
+ {
|
|
+/*
|
|
+ * zero size: either a fresh database, or one with a single,
|
|
+ * unsplit data page: dirpage is all zeros.
|
|
+ */
|
|
+ db->dirbno = (!dstat.st_size) ? 0 : -1;
|
|
+ db->pagbno = -1;
|
|
+ db->maxbno = dstat.st_size * BYTESIZ;
|
|
+
|
|
+ (void) memset (db->pagbuf, 0, PBLKSIZ);
|
|
+ (void) memset (db->dirbuf, 0, DBLKSIZ);
|
|
+ return db;
|
|
+ }
|
|
+ myfree ((char *) db);
|
|
+ return (DBM *) NULL;
|
|
+}
|
|
+
|
|
+static void sdbm_internal_close (DBM * db)
|
|
+{
|
|
+ if (db == NULL)
|
|
+ errno = EINVAL;
|
|
+ else
|
|
+ {
|
|
+ myfree ((char *) db);
|
|
+ }
|
|
+}
|
|
+
|
|
+datum sdbm_fetch (SDBM * sdb, datum key)
|
|
+{
|
|
+ datum retval;
|
|
+ DBM *db;
|
|
+
|
|
+ if (sdb == NULL || bad (key))
|
|
+ return errno = EINVAL, nullitem;
|
|
+
|
|
+ if (!(db = sdbm_internal_open (sdb)))
|
|
+ return errno = EINVAL, nullitem;
|
|
+
|
|
+ if (getpage (db, exhash (key)))
|
|
+ {
|
|
+ retval = getpair (db->pagbuf, key);
|
|
+ sdbm_internal_close (db);
|
|
+ return retval;
|
|
+ }
|
|
+
|
|
+ sdbm_internal_close (db);
|
|
+
|
|
+ return ioerr (sdb), nullitem;
|
|
+}
|
|
+
|
|
+int sdbm_delete (SDBM * sdb, datum key)
|
|
+{
|
|
+ int retval;
|
|
+ DBM *db;
|
|
+
|
|
+ if (sdb == NULL || bad (key))
|
|
+ return errno = EINVAL, -1;
|
|
+ if (sdbm_rdonly (sdb))
|
|
+ return errno = EPERM, -1;
|
|
+
|
|
+ if (!(db = sdbm_internal_open (sdb)))
|
|
+ return errno = EINVAL, -1;
|
|
+
|
|
+ if (getpage (db, exhash (key)))
|
|
+ {
|
|
+ if (!delpair (db->pagbuf, key))
|
|
+ retval = -1;
|
|
+/*
|
|
+ * update the page file
|
|
+ */
|
|
+ else if (lseek (db->pagf, OFF_PAG (db->pagbno), SEEK_SET) < 0
|
|
+ || write (db->pagf, db->pagbuf, PBLKSIZ) < 0)
|
|
+ retval = ioerr (sdb), -1;
|
|
+ else
|
|
+ retval = 0;
|
|
+ }
|
|
+ else
|
|
+ retval = ioerr (sdb), -1;
|
|
+
|
|
+ sdbm_internal_close (db);
|
|
+
|
|
+ return retval;
|
|
+}
|
|
+
|
|
+int sdbm_store (SDBM * sdb, datum key, datum val, int flags)
|
|
+{
|
|
+ int need;
|
|
+ int retval;
|
|
+ long hash;
|
|
+ DBM *db;
|
|
+
|
|
+ if (sdb == NULL || bad (key))
|
|
+ return errno = EINVAL, -1;
|
|
+ if (sdbm_rdonly (sdb))
|
|
+ return errno = EPERM, -1;
|
|
+
|
|
+ need = key.dsize + val.dsize;
|
|
+/*
|
|
+ * is the pair too big (or too small) for this database ??
|
|
+ */
|
|
+ if (need < 0 || need > PAIRMAX)
|
|
+ return errno = EINVAL, -1;
|
|
+
|
|
+ if (!(db = sdbm_internal_open (sdb)))
|
|
+ return errno = EINVAL, -1;
|
|
+
|
|
+ if (getpage (db, (hash = exhash (key))))
|
|
+ {
|
|
+/*
|
|
+ * if we need to replace, delete the key/data pair
|
|
+ * first. If it is not there, ignore.
|
|
+ */
|
|
+ if (flags == DBM_REPLACE)
|
|
+ (void) delpair (db->pagbuf, key);
|
|
+#ifdef SEEDUPS
|
|
+ else if (duppair (db->pagbuf, key))
|
|
+ {
|
|
+ sdbm_internal_close (db);
|
|
+ return 1;
|
|
+ }
|
|
+#endif
|
|
+/*
|
|
+ * if we do not have enough room, we have to split.
|
|
+ */
|
|
+ if (!fitpair (db->pagbuf, need))
|
|
+ if (!makroom (db, hash, need))
|
|
+ {
|
|
+ sdbm_internal_close (db);
|
|
+ return ioerr (db), -1;
|
|
+ }
|
|
+/*
|
|
+ * we have enough room or split is successful. insert the key,
|
|
+ * and update the page file.
|
|
+ */
|
|
+ (void) putpair (db->pagbuf, key, val);
|
|
+
|
|
+ if (lseek (db->pagf, OFF_PAG (db->pagbno), SEEK_SET) < 0
|
|
+ || write (db->pagf, db->pagbuf, PBLKSIZ) < 0)
|
|
+ {
|
|
+ sdbm_internal_close (db);
|
|
+ return ioerr (db), -1;
|
|
+ }
|
|
+ /*
|
|
+ * success
|
|
+ */
|
|
+ sdbm_internal_close (db);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ sdbm_internal_close (db);
|
|
+ return ioerr (sdb), -1;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * the following two routines will break if
|
|
+ * deletions aren't taken into account. (ndbm bug)
|
|
+ */
|
|
+datum sdbm_firstkey (SDBM * sdb)
|
|
+{
|
|
+ datum retval;
|
|
+ DBM *db;
|
|
+
|
|
+ if (sdb == NULL)
|
|
+ return errno = EINVAL, nullitem;
|
|
+
|
|
+ if (!(db = sdbm_internal_open (sdb)))
|
|
+ return errno = EINVAL, nullitem;
|
|
+
|
|
+/*
|
|
+ * start at page 0
|
|
+ */
|
|
+ if (lseek (db->pagf, OFF_PAG (0), SEEK_SET) < 0
|
|
+ || read (db->pagf, db->pagbuf, PBLKSIZ) < 0)
|
|
+ {
|
|
+ sdbm_internal_close (db);
|
|
+ return ioerr (sdb), nullitem;
|
|
+ }
|
|
+ db->pagbno = 0;
|
|
+ db->blkptr = 0;
|
|
+ db->keyptr = 0;
|
|
+
|
|
+ retval = getnext (db);
|
|
+ sdb->blkptr = db->blkptr;
|
|
+ sdb->keyptr = db->keyptr;
|
|
+ sdbm_internal_close (db);
|
|
+ return retval;
|
|
+}
|
|
+
|
|
+datum sdbm_nextkey (SDBM * sdb)
|
|
+{
|
|
+ datum retval;
|
|
+ DBM *db;
|
|
+
|
|
+ if (sdb == NULL)
|
|
+ return errno = EINVAL, nullitem;
|
|
+
|
|
+ if (!(db = sdbm_internal_open (sdb)))
|
|
+ return errno = EINVAL, nullitem;
|
|
+
|
|
+ retval = getnext (db);
|
|
+ sdb->blkptr = db->blkptr;
|
|
+ sdb->keyptr = db->keyptr;
|
|
+ sdbm_internal_close (db);
|
|
+ return retval;
|
|
+}
|
|
+
|
|
+void sdbm_close (SDBM * db)
|
|
+{
|
|
+ if (db == NULL)
|
|
+ errno = EINVAL;
|
|
+ else
|
|
+ {
|
|
+ (void) close (db->dirf);
|
|
+ (void) close (db->pagf);
|
|
+ myfree ((char *) db);
|
|
+ }
|
|
+}
|
|
+
|
|
+SDBM *sdbm_open (char *file, int flags, int mode)
|
|
+{
|
|
+ SDBM *db;
|
|
+ char *dirname;
|
|
+ char *pagname;
|
|
+ int n;
|
|
+
|
|
+ if (file == NULL || !*file)
|
|
+ return errno = EINVAL, (SDBM *) NULL;
|
|
+/*
|
|
+ * need space for two seperate filenames
|
|
+ */
|
|
+ n = strlen (file) * 2 + strlen (DIRFEXT) + strlen (PAGFEXT) + 2;
|
|
+
|
|
+ if ((dirname = (char *) mymalloc ((unsigned) n)) == NULL)
|
|
+ return errno = ENOMEM, (SDBM *) NULL;
|
|
+/*
|
|
+ * build the file names
|
|
+ */
|
|
+ dirname = strcat (strcpy (dirname, file), DIRFEXT);
|
|
+ pagname = strcpy (dirname + strlen (dirname) + 1, file);
|
|
+ pagname = strcat (pagname, PAGFEXT);
|
|
+
|
|
+ db = sdbm_prep (dirname, pagname, flags, mode);
|
|
+ myfree ((char *) dirname);
|
|
+ return db;
|
|
+}
|
|
+
|
|
diff -rNu postfix-2.11.0/src/util/sdbm.h postfix-2.11.0-patched/src/util/sdbm.h
|
|
--- postfix-2.11.0/src/util/sdbm.h 1970-01-01 01:00:00.000000000 +0100
|
|
+++ postfix-2.11.0-patched/src/util/sdbm.h 2014-02-12 12:37:46.930115817 +0100
|
|
@@ -0,0 +1,97 @@
|
|
+/*++
|
|
+/* NAME
|
|
+/* sdbm 3h
|
|
+/* SUMMARY
|
|
+/* SDBM Simple DBM: ndbm work-alike hashed database library
|
|
+/* SYNOPSIS
|
|
+/* include "sdbm.h"
|
|
+/* DESCRIPTION
|
|
+/* .nf
|
|
+/*--*/
|
|
+
|
|
+#ifndef UTIL_SDBM_H
|
|
+#define UTIL_SDBM_H
|
|
+
|
|
+/*
|
|
+ * sdbm - ndbm work-alike hashed database library
|
|
+ * based on Per-Ake Larson's Dynamic Hashing algorithms. BIT 18 (1978).
|
|
+ * author: oz@nexus.yorku.ca
|
|
+ * status: public domain.
|
|
+ */
|
|
+
|
|
+#define DUFF /* go ahead and use the loop-unrolled version */
|
|
+
|
|
+#include <stdio.h>
|
|
+
|
|
+#define DBLKSIZ 16384 /* SSL cert chains require more */
|
|
+#define PBLKSIZ 8192 /* SSL cert chains require more */
|
|
+#define PAIRMAX 8008 /* arbitrary on PBLKSIZ-N */
|
|
+#define SPLTMAX 10 /* maximum allowed splits */
|
|
+ /* for a single insertion */
|
|
+#define DIRFEXT ".dir"
|
|
+#define PAGFEXT ".pag"
|
|
+
|
|
+typedef struct {
|
|
+ int dirf; /* directory file descriptor */
|
|
+ int pagf; /* page file descriptor */
|
|
+ int flags; /* status/error flags, see below */
|
|
+ long blkptr; /* current block for nextkey */
|
|
+ int keyptr; /* current key for nextkey */
|
|
+ char pagbuf[PBLKSIZ]; /* page file block buffer */
|
|
+ char dirbuf[DBLKSIZ]; /* directory file block buffer */
|
|
+} SDBM;
|
|
+
|
|
+#define DBM_RDONLY 0x1 /* data base open read-only */
|
|
+#define DBM_IOERR 0x2 /* data base I/O error */
|
|
+
|
|
+/*
|
|
+ * utility macros
|
|
+ */
|
|
+#define sdbm_rdonly(db) ((db)->flags & DBM_RDONLY)
|
|
+#define sdbm_error(db) ((db)->flags & DBM_IOERR)
|
|
+
|
|
+#define sdbm_clearerr(db) ((db)->flags &= ~DBM_IOERR) /* ouch */
|
|
+
|
|
+#define sdbm_dirfno(db) ((db)->dirf)
|
|
+#define sdbm_pagfno(db) ((db)->pagf)
|
|
+
|
|
+typedef struct {
|
|
+ char *dptr;
|
|
+ int dsize;
|
|
+} datum;
|
|
+
|
|
+extern datum nullitem;
|
|
+
|
|
+/*
|
|
+ * flags to sdbm_store
|
|
+ */
|
|
+#define DBM_INSERT 0
|
|
+#define DBM_REPLACE 1
|
|
+
|
|
+/*
|
|
+ * ndbm interface
|
|
+ */
|
|
+extern SDBM *sdbm_open(char *, int, int);
|
|
+extern void sdbm_close(SDBM *);
|
|
+extern datum sdbm_fetch(SDBM *, datum);
|
|
+extern int sdbm_delete(SDBM *, datum);
|
|
+extern int sdbm_store(SDBM *, datum, datum, int);
|
|
+extern datum sdbm_firstkey(SDBM *);
|
|
+extern datum sdbm_nextkey(SDBM *);
|
|
+
|
|
+/*
|
|
+ * sdbm - ndbm work-alike hashed database library
|
|
+ * tuning and portability constructs [not nearly enough]
|
|
+ * author: oz@nexus.yorku.ca
|
|
+ */
|
|
+
|
|
+#define BYTESIZ 8
|
|
+
|
|
+/*
|
|
+ * important tuning parms (hah)
|
|
+ */
|
|
+
|
|
+#define SEEDUPS /* always detect duplicates */
|
|
+#define BADMESS /* generate a message for worst case:
|
|
+ cannot make room after SPLTMAX splits */
|
|
+#endif /* UTIL_SDBM_H */
|
|
diff -rNu postfix-2.11.0/src/util/sys_defs.h postfix-2.11.0-patched/src/util/sys_defs.h
|
|
--- postfix-2.11.0/src/util/sys_defs.h 2013-09-29 22:51:55.000000000 +0200
|
|
+++ postfix-2.11.0-patched/src/util/sys_defs.h 2014-02-12 14:44:07.594868198 +0100
|
|
@@ -767,6 +767,7 @@
|
|
#define INTERNAL_LOCK MYFLOCK_STYLE_FLOCK
|
|
#define DEF_MAILBOX_LOCK "fcntl, dotlock" /* RedHat >= 4.x */
|
|
#define HAS_FSYNC
|
|
+#define HAS_SDBM
|
|
#define HAS_DB
|
|
#define NATIVE_DB_TYPE "hash"
|
|
#define ALIAS_DB_MAP DEF_DB_TYPE ":/etc/aliases"
|
|
@@ -780,11 +781,25 @@
|
|
#define STATFS_IN_SYS_VFS_H
|
|
#define PREPEND_PLUS_TO_OPTSTRING
|
|
#define HAS_POSIX_REGEXP
|
|
+#define HAS_DLOPEN
|
|
#define NATIVE_SENDMAIL_PATH "/usr/sbin/sendmail"
|
|
#define NATIVE_MAILQ_PATH "/usr/bin/mailq"
|
|
#define NATIVE_NEWALIAS_PATH "/usr/bin/newaliases"
|
|
#define NATIVE_COMMAND_DIR "/usr/sbin"
|
|
+#ifdef DEBIAN
|
|
+#define NATIVE_DAEMON_DIR "/usr/lib/postfix"
|
|
+#ifndef DEF_MANPAGE_DIR
|
|
+#define DEF_MANPAGE_DIR "/usr/share/man"
|
|
+#endif
|
|
+#ifndef DEF_SAMPLE_DIR
|
|
+#define DEF_SAMPLE_DIR "/usr/share/doc/postfix/examples"
|
|
+#endif
|
|
+#ifndef DEF_README_DIR
|
|
+#define DEF_README_DIR "/usr/share/doc/postfix"
|
|
+#endif
|
|
+#else
|
|
#define NATIVE_DAEMON_DIR "/usr/libexec/postfix"
|
|
+#endif
|
|
#ifdef __GLIBC_PREREQ
|
|
# define HAVE_GLIBC_API_VERSION_SUPPORT(maj, min) __GLIBC_PREREQ(maj, min)
|
|
#else
|
|
@@ -966,6 +981,7 @@
|
|
#define USE_STATFS
|
|
#define STATFS_IN_SYS_VFS_H
|
|
#define HAS_POSIX_REGEXP
|
|
+#define HAS_DLOPEN
|
|
#define NATIVE_SENDMAIL_PATH "/usr/sbin/sendmail"
|
|
#define NATIVE_MAILQ_PATH "/usr/bin/mailq"
|
|
#define NATIVE_NEWALIAS_PATH "/usr/bin/newaliases"
|
|
@@ -1005,6 +1021,7 @@
|
|
#define USE_STATFS
|
|
#define STATFS_IN_SYS_VFS_H
|
|
#define HAS_POSIX_REGEXP
|
|
+#define HAS_SHL_LOAD
|
|
#define NATIVE_SENDMAIL_PATH "/usr/sbin/sendmail"
|
|
#define NATIVE_MAILQ_PATH "/usr/bin/mailq"
|
|
#define NATIVE_NEWALIAS_PATH "/usr/bin/newaliases"
|
|
@@ -1046,6 +1063,7 @@
|
|
#define USE_STATFS
|
|
#define STATFS_IN_SYS_VFS_H
|
|
#define HAS_POSIX_REGEXP
|
|
+#define HAS_SHL_LOAD
|
|
#define NATIVE_SENDMAIL_PATH "/usr/bin/sendmail"
|
|
#define NATIVE_MAILQ_PATH "/usr/bin/mailq"
|
|
#define NATIVE_NEWALIAS_PATH "/usr/bin/newaliases"
|