Sophie

Sophie

distrib > Mandriva > cs4.0 > i586 > by-pkgid > e21f77e5abeaa9d7a2ac16f1e6817f1f > files > 13

postfix-2.2.11-1mlcs4.src.rpm

diff -urNad postfix-2.2.4.orig/conf/postfix-files postfix-2.2.4/conf/postfix-files
--- postfix-2.2.4.orig/conf/postfix-files	2005-05-04 14:18:36.000000000 -0600
+++ postfix-2.2.4/conf/postfix-files	2005-05-04 14:41:34.000000000 -0600
@@ -63,6 +63,13 @@
 $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_mysql.so:f:root:-:755
+$daemon_directory/dict_pgsql.so:f:root:-:755
+$daemon_directory/dict_tcp.so:f:root:-:755
+$daemon_directory/dict_sdbm.so:f:root:-:755
+$daemon_directory/dict_cidr.so:f:root:-:755
 $daemon_directory/cleanup:f:root:-:755
 $daemon_directory/discard:f:root:-:755
 $daemon_directory/error:f:root:-:755
@@ -85,6 +90,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
 $command_directory/postalias:f:root:-:755
 $command_directory/postcat:f:root:-:755
@@ -105,6 +115,7 @@
 $config_directory/access:f:root:-:644:p
 $config_directory/aliases:f:root:-:644:p
 $config_directory/canonical:f:root:-:644:p
+$config_directory/dynamicmaps.cf:f:root:-:644:p
 $config_directory/cidr_table:f:root:-:644:o
 $config_directory/generics:f:root:-:644:o
 $config_directory/generic:f:root:-:644:p
diff -urNad postfix-2.2.4.orig/src/dns/Makefile.in postfix-2.2.4/src/dns/Makefile.in
--- postfix-2.2.4.orig/src/dns/Makefile.in	2005-05-04 14:18:36.000000000 -0600
+++ postfix-2.2.4/src/dns/Makefile.in	2005-05-04 14:41:34.000000000 -0600
@@ -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)
 
@@ -29,12 +29,10 @@
 	dns_rr_eq_sa_test
 
 $(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); \
--- postfix-2.2.4/src/global/Makefile.in.dynamic	2005-04-29 18:08:44.000000000 -0300
+++ postfix-2.2.4/src/global/Makefile.in	2005-07-01 15:11:08.000000000 -0300
@@ -30,7 +30,7 @@
 	canon_addr.o cfg_parser.o cleanup_strerror.o cleanup_strflags.o \
 	clnt_stream.o debug_peer.o debug_process.o defer.o db_common.o \
 	deliver_completed.o deliver_flock.o deliver_pass.o deliver_request.o \
-	dict_ldap.o dict_mysql.o dict_pgsql.o dict_proxy.o domain_list.o \
+	dict_proxy.o domain_list.o \
 	dot_lockfile.o dot_lockfile_as.o ext_prop.o file_id.o flush_clnt.o \
 	header_opts.o header_token.o hold_message.o input_transp.o \
 	is_header.o log_adhoc.o mail_addr.o mail_addr_crunch.o \
@@ -50,7 +50,7 @@
 	sys_exits.o timed_ipc.o tok822_find.o tok822_node.o tok822_parse.o \
 	tok822_resolve.o tok822_rewrite.o tok822_tree.o trace.o verify.o \
 	verify_clnt.o verp_sender.o virtual8_maps.o xtext.o scache_single.o \
-	scache_clnt.o scache_multi.o user_acl.o mkmap_cdb.o mkmap_sdbm.o \
+	scache_clnt.o scache_multi.o user_acl.o mkmap_cdb.o \
 	ehlo_mask.o \
 	wildcard_inet_addr.o valid_mailhost_addr.o
 HDRS	= abounce.h anvil_clnt.h been_here.h bounce.h bounce_log.h \
@@ -92,10 +92,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
 
@@ -105,14 +108,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 $@ $? -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)
+../../libexec/$(LDAPSO): $(LDAPSO)
+	cp $(LDAPSO) ../../libexec
+
+../../libexec/$(MYSQLSO): $(MYSQLSO)
+	cp $(MYSQLSO) ../../libexec
+
+../../libexec/$(PGSQLSO): $(PGSQLSO)
+	cp $(PGSQLSO) ../../libexec
+
+update: $(LIB_DIR)/$(LIB) ../../libexec/${LDAPSO} ../../libexec/${MYSQLSO} ../../libexec/${PGSQLSO} $(HDRS)
 	-for i in $(HDRS); \
 	do \
 	  cmp -s $$i $(INC_DIR)/$$i 2>/dev/null || cp $$i $(INC_DIR); \
@@ -392,7 +411,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 -urNad postfix-2.2.4.orig/src/global/mail_conf.c postfix-2.2.4/src/global/mail_conf.c
--- postfix-2.2.4.orig/src/global/mail_conf.c	2005-05-04 14:18:36.000000000 -0600
+++ postfix-2.2.4/src/global/mail_conf.c	2005-05-04 14:41:34.000000000 -0600
@@ -175,6 +175,13 @@
     path = concatenate(var_config_dir, "/", "main.cf", (char *) 0);
     dict_load_file(CONFIG_DICT, 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_eval - expand macros in string */
diff -urNad postfix-2.2.4.orig/src/global/mail_dict.c postfix-2.2.4/src/global/mail_dict.c
--- postfix-2.2.4.orig/src/global/mail_dict.c	2005-05-04 14:18:36.000000000 -0600
+++ postfix-2.2.4/src/global/mail_dict.c	2005-05-04 14:41:34.000000000 -0600
@@ -45,6 +45,7 @@
 
 static DICT_OPEN_INFO dict_open_info[] = {
     DICT_TYPE_PROXY, dict_proxy_open,
+#ifdef NO_DYNAMIC_MAPS
 #ifdef HAS_LDAP
     DICT_TYPE_LDAP, dict_ldap_open,
 #endif
@@ -54,6 +55,7 @@
 #ifdef HAS_PGSQL
     DICT_TYPE_PGSQL, dict_pgsql_open,
 #endif
+#endif /* NO_DYNAMIC_MAPS */
     0,
 };
 
diff -urNad postfix-2.2.4.orig/src/global/mail_params.c postfix-2.2.4/src/global/mail_params.c
--- postfix-2.2.4.orig/src/global/mail_params.c	2005-05-04 14:41:34.000000000 -0600
+++ postfix-2.2.4/src/global/mail_params.c	2005-05-04 14:41:34.000000000 -0600
@@ -77,6 +77,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;
@@ -269,6 +270,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;
--- postfix-2.2.4/src/global/mkmap_open.c.dynamic	2004-12-14 22:24:22.000000000 -0200
+++ postfix-2.2.4/src/global/mkmap_open.c	2005-07-01 14:58:53.000000000 -0300
@@ -86,9 +86,11 @@
 #ifdef HAS_CDB
     DICT_TYPE_CDB, mkmap_cdb_open,
 #endif
+#ifdef NO_DYNAMIC_MAPS
 #ifdef HAS_SDBM
     DICT_TYPE_SDBM, mkmap_sdbm_open,
 #endif
+#endif
 #ifdef HAS_DBM
     DICT_TYPE_DBM, mkmap_dbm_open,
 #endif
@@ -152,7 +154,16 @@
      */
     for (mp = mkmap_types; /* void */ ; mp++) {
 	if (mp->type == 0)
+#ifndef NO_DYNAMIC_MAPS
+	{
+	    static MKMAP_OPEN_INFO oi;
+	    oi.before_open=dict_mkmap_func(type);
+	    oi.type=type;
+	    mp=&oi;
+	}
+#else
 	    msg_fatal("unsupported map type: %s", type);
+#endif
 	if (strcmp(type, mp->type) == 0)
 	    break;
     }
diff -urNad postfix-2.2.4.orig/src/master/Makefile.in postfix-2.2.4/src/master/Makefile.in
--- postfix-2.2.4.orig/src/master/Makefile.in	2005-05-04 14:18:36.000000000 -0600
+++ postfix-2.2.4/src/master/Makefile.in	2005-05-04 14:41:34.000000000 -0600
@@ -20,7 +20,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)
 
@@ -37,12 +37,10 @@
 tests:	test
 
 $(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 -urNad postfix-2.2.4.orig/src/postconf/postconf.c postfix-2.2.4/src/postconf/postconf.c
--- postfix-2.2.4.orig/src/postconf/postconf.c	2005-05-04 14:18:36.000000000 -0600
+++ postfix-2.2.4/src/postconf/postconf.c	2005-05-04 14:41:34.000000000 -0600
@@ -839,6 +839,16 @@
 {
     ARGV   *maps_argv;
     int     i;
+#ifndef NO_DYNAMIC_MAPS
+    char   *path;
+    char   *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++)
diff -urNad postfix-2.2.4.orig/src/tls/Makefile.in postfix-2.2.4/src/tls/Makefile.in
--- postfix-2.2.4.orig/src/tls/Makefile.in	2005-05-04 14:18:36.000000000 -0600
+++ postfix-2.2.4/src/tls/Makefile.in	2005-05-04 14:41:34.000000000 -0600
@@ -20,7 +20,7 @@
 INC_DIR	= ../../include
 MAKES	=
 
-.c.o:;	$(CC) $(CFLAGS) -c $*.c
+.c.o:;	$(CC) -fPIC $(CFLAGS) -c $*.c
 
 all: $(LIB)
 
@@ -32,12 +32,10 @@
 test:	$(TESTPROG)
 
 $(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); \
--- postfix-2.2.4/src/util/Makefile.in.dynamic	2005-04-29 18:12:46.000000000 -0300
+++ postfix-2.2.4/src/util/Makefile.in	2005-07-01 11:31:51.000000000 -0300
@@ -4,6 +4,7 @@
 	chroot_uid.c clean_env.c close_on_exec.c concatenate.c ctable.c \
 	dict.c dict_alloc.c dict_db.c dict_cdb.c dict_dbm.c dict_debug.c dict_env.c \
 	dict_cidr.c dict_ht.c dict_ni.c dict_nis.c \
+	load_lib.c sdbm.c \
 	dict_nisplus.c dict_open.c dict_pcre.c dict_regexp.c \
 	dict_static.c dict_tcp.c dict_unix.c dir_forest.c doze.c \
 	duplex_pipe.c environ.c events.c exec_command.c fifo_listen.c \
@@ -35,14 +36,14 @@
 	attr_scan0.o attr_scan64.o base64_code.o basename.o binhash.o \
 	chroot_uid.o clean_env.o close_on_exec.o concatenate.o ctable.o \
 	dict.o dict_alloc.o dict_db.o dict_cdb.o dict_dbm.o dict_debug.o dict_env.o \
-	dict_cidr.o dict_ht.o dict_ni.o dict_nis.o \
-	dict_nisplus.o dict_open.o dict_pcre.o dict_regexp.o \
-	dict_static.o dict_tcp.o dict_unix.o dir_forest.o doze.o \
+	dict_ht.o dict_ni.o dict_nis.o \
+	dict_nisplus.o dict_open.o dict_regexp.o \
+	dict_static.o dict_unix.o dir_forest.o doze.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_quote.o host_port.o htable.o \
 	inet_addr_host.o inet_addr_list.o inet_addr_local.o inet_connect.o \
-	inet_listen.o inet_trigger.o line_wrap.o \
+	inet_listen.o inet_trigger.o line_wrap.o load_lib.o sdbm.o \
 	lowercase.o lstat_as.o mac_expand.o mac_parse.o make_dirs.o \
 	match_list.o match_ops.o msg.o msg_output.o msg_syslog.o \
 	msg_vstream.o mvect.o myflock.o mymalloc.o myrand.o mystrtok.o \
@@ -61,12 +62,12 @@
 	write_buf.o write_wait.o auto_clnt.o attr_clnt.o attr_scan_plain.o \
 	attr_print_plain.o sane_connect.o $(STRCASE) neuter.o name_code.o \
 	uppercase.o unix_recv_fd.o stream_recv_fd.o unix_send_fd.o \
-	stream_send_fd.o dict_sdbm.o hex_code.o dummy_read.o dummy_write.o \
+	stream_send_fd.o hex_code.o dummy_read.o dummy_write.o \
 	myaddrinfo.o sock_addr.o inet_proto.o cidr_match.o mask_addr.o
 HDRS	= argv.h attr.h base64_code.h binhash.h chroot_uid.h clean_env.h \
 	connect.h ctable.h dict.h dict_db.h dict_cdb.h dict_dbm.h dict_env.h \
 	dict_cidr.h dict_ht.h dict_ni.h dict_nis.h \
-	dict_nisplus.h dict_pcre.h dict_regexp.h \
+	dict_nisplus.h dict_pcre.h dict_regexp.h sdbm.h \
 	dict_static.h dict_tcp.h dict_unix.h dir_forest.h events.h \
 	exec_command.h find_inet.h fsspace.h fullname.h get_domainname.h \
 	get_hostname.h hex_quote.h host_port.h htable.h inet_addr_host.h \
@@ -76,7 +77,7 @@
 	msg_syslog.h msg_vstream.h mvect.h myflock.h mymalloc.h myrand.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_fsops.h sane_socketpair.h sane_time.h \
+	sane_accept.h sane_fsops.h sane_socketpair.h sane_time.h load_lib.h \
 	scan_dir.h set_eugid.h set_ugid.h sigdelay.h spawn_command.h \
 	split_at.h stat_as.h stringops.h sys_defs.h timed_connect.h \
 	timed_wait.h trigger.h username.h valid_hostname.h vbuf.h \
@@ -90,6 +91,10 @@
 CFLAGS	= $(DEBUG) $(OPT) $(DEFS)
 FILES	= Makefile $(SRCS) $(HDRS)
 INCL	=
+PCRESO  = dict_pcre.so
+TCPSO   = dict_tcp.so
+SDBMSO  = dict_sdbm.so
+CIDRSO  = dict_cidr.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 \
@@ -104,10 +109,11 @@
 
 LIB_DIR	= ../../lib
 INC_DIR	= ../../include
+LIBS    = $(LIB_DIR)/$(LIB) ../../libexec/$(PCRESO) ../../libexec/$(TCPSO) ../../libexec/$(SDBMSO) ../../libexec/$(CIDRSO)
 
-.c.o:;	$(CC) $(CFLAGS) -c $*.c
+.c.o:;	$(CC) -fPIC $(CFLAGS) -c $*.c
 
-all: $(LIB)
+all: $(LIB) $(PCRESO) $(TCPSO) $(SDBMSO) $(CIDRSO)
 
 $(OBJS): ../../conf/makedefs.out
 
@@ -116,15 +122,37 @@
 
 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
+
+$(SDBMSO): dict_sdbm.o sdbm.o
+	gcc -shared -Wl,-soname,dict_sdbm.so -o $@ $? -L. -lutil
+
+$(CIDRSO): dict_cidr.o
+	gcc -shared -Wl,-soname,dict_cidr.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)
+../../libexec/$(PCRESO): $(PCRESO)
+	cp $(PCRESO) ../../libexec
+
+../../libexec/$(TCPSO): $(TCPSO)
+	cp $(TCPSO) ../../libexec
+
+../../libexec/$(SDBMSO): $(SDBMSO)
+	cp $(SDBMSO) ../../libexec
+
+../../libexec/$(CIDRSO): $(CIDRSO)
+	cp $(CIDRSO) ../../libexec
+
+update: $(LIBS) $(HDRS)
 	-for i in $(HDRS); \
 	do \
 	  cmp -s $$i $(INC_DIR)/$$i 2>/dev/null || cp $$i $(INC_DIR); \
@@ -146,7 +174,8 @@
 	lint $(SRCS)
 
 clean:
-	rm -f *.o $(LIB) *core $(TESTPROG) junk $(MAKES) *.tmp
+	rm -f *.o $(LIB) $(PCRESO) $(TCPSO) $(SDBMSO) $(CIDRSO) *core $(TESTPROG) \
+		junk $(MAKES) *.tmp
 	rm -rf printfck
 
 tidy:	clean
diff -urNad postfix-2.2.4.orig/src/util/dict.h postfix-2.2.4/src/util/dict.h
--- postfix-2.2.4.orig/src/util/dict.h	2005-05-04 14:18:36.000000000 -0600
+++ postfix-2.2.4/src/util/dict.h	2005-05-04 14:41:34.000000000 -0600
@@ -102,6 +103,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)	(dp)->lookup((dp), (key))
 #define dict_put(dp, key, val)	(dp)->update((dp), (key), (val))
diff -urNad postfix-2.2.4.orig/src/util/dict_dbm.c postfix-2.2.4/src/util/dict_dbm.c
--- postfix-2.2.4.orig/src/util/dict_dbm.c	2005-05-04 14:18:36.000000000 -0600
+++ postfix-2.2.4/src/util/dict_dbm.c	2005-05-04 14:41:34.000000000 -0600
@@ -375,6 +375,10 @@
     char   *dbm_path;
     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
     /*
      * Note: DICT_FLAG_LOCK is used only by programs that do fine-grained (in
      * the time domain) locking while accessing individual database records.
--- postfix-2.2.4/src/util/dict_open.c.dynamic	2005-03-17 13:33:02.000000000 -0300
+++ postfix-2.2.4/src/util/dict_open.c	2005-07-01 11:42:24.000000000 -0300
@@ -44,6 +44,8 @@
 /*	DICT	*(*open) (const char *, int, int);
 /*
 /*	ARGV	*dict_mapnames()
+/*
+/*	void (*)() dict_mkmap_func(const char *dict_type)
 /* DESCRIPTION
 /*	This module implements a low-level interface to multiple
 /*	physical dictionary types.
@@ -145,6 +147,9 @@
 /*
 /*	dict_mapnames() returns a sorted list with the names of all available
 /*	dictionary types.
+/*
+/*	dict_mkmap_func() returns a pointer to the mkmap setup function
+/*	for the given map type, as given in /etc/dynamicmaps.cf
 /* DIAGNOSTICS
 /*	Fatal error: open error, unsupported dictionary type, attempt to
 /*	update non-writable dictionary.
@@ -169,6 +174,9 @@
 #include <strings.h>
 #endif
 
+#include <sys/stat.h>
+#include <unistd.h>
+
 /* Utility library. */
 
 #include <argv.h>
@@ -193,6 +201,27 @@
 #include <split_at.h>
 #include <htable.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.
   */
@@ -207,12 +236,16 @@
 #endif
     DICT_TYPE_ENVIRON, dict_env_open,
     DICT_TYPE_UNIX, dict_unix_open,
+#ifdef NO_DYNAMIC_MAPS
 #ifdef SNAPSHOT
     DICT_TYPE_TCP, dict_tcp_open,
 #endif
+#endif
+#ifdef NO_DYNAMIC_MAPS
 #ifdef HAS_SDBM
     DICT_TYPE_SDBM, dict_sdbm_open,
 #endif
+#endif
 #ifdef HAS_DBM
     DICT_TYPE_DBM, dict_dbm_open,
 #endif
@@ -229,14 +262,18 @@
 #ifdef HAS_NETINFO
     DICT_TYPE_NETINFO, dict_ni_open,
 #endif
+#ifdef NO_DYNAMIC_MAPS
 #ifdef HAS_PCRE
     DICT_TYPE_PCRE, dict_pcre_open,
 #endif
+#endif /* NO_DYNAMIC_MAPS */
 #ifdef HAS_POSIX_REGEXP
     DICT_TYPE_REGEXP, dict_regexp_open,
 #endif
     DICT_TYPE_STATIC, dict_static_open,
+#ifdef NO_DYNAMIC_MAPS
     DICT_TYPE_CIDR, dict_cidr_open,
+#endif
     0,
 };
 
@@ -289,8 +326,31 @@
 		  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)
-	msg_fatal("unsupported dictionary type: %s", dict_type);
+    if ((dp = (DICT_OPEN_INFO *) htable_find(dict_open_hash, dict_type)) == 0) {
+#ifdef NO_DYNAMIC_MAPS
+	msg_fatal("%s: unsupported dictionary type: %s", myname, 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)
 	msg_fatal("opening %s:%s %m", dict_type, dict_name);
     if (msg_verbose)
@@ -298,6 +358,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,
@@ -331,6 +421,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();
@@ -339,6 +432,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);
@@ -346,6 +446,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 -urNad postfix-2.2.4.orig/src/util/load_lib.c postfix-2.2.4/src/util/load_lib.c
--- postfix-2.2.4.orig/src/util/load_lib.c	1969-12-31 17:00:00.000000000 -0700
+++ postfix-2.2.4/src/util/load_lib.c	2005-05-04 14:41:34.000000000 -0600
@@ -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 -urNad postfix-2.2.4.orig/src/util/load_lib.h postfix-2.2.4/src/util/load_lib.h
--- postfix-2.2.4.orig/src/util/load_lib.h	1969-12-31 17:00:00.000000000 -0700
+++ postfix-2.2.4/src/util/load_lib.h	2005-05-04 14:41:34.000000000 -0600
@@ -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 -urNad postfix-2.2.4.orig/src/util/sdbm.c postfix-2.2.4/src/util/sdbm.c
--- postfix-2.2.4.orig/src/util/sdbm.c	1969-12-31 17:00:00.000000000 -0700
+++ postfix-2.2.4/src/util/sdbm.c	2005-05-04 14:41:34.000000000 -0600
@@ -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 -urNad postfix-2.2.4.orig/src/util/sdbm.h postfix-2.2.4/src/util/sdbm.h
--- postfix-2.2.4.orig/src/util/sdbm.h	1969-12-31 17:00:00.000000000 -0700
+++ postfix-2.2.4/src/util/sdbm.h	2005-05-04 14:41:34.000000000 -0600
@@ -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 */
--- postfix-2.2.4/src/util/sys_defs.h.orig	2005-06-21 18:12:00.000000000 -0300
+++ postfix-2.2.4/src/util/sys_defs.h	2005-07-01 16:17:26.000000000 -0300
@@ -618,6 +618,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 DEF_DB_TYPE	"hash"
 #define ALIAS_DB_MAP	"hash:/etc/aliases"
@@ -630,6 +631,7 @@
 #define UNIX_DOMAIN_CONNECT_BLOCKS_FOR_ACCEPT
 #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"
@@ -716,6 +718,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"
@@ -751,6 +754,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"
@@ -788,6 +792,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"