Wietse Venema:
> Dunk:
> > Thanks, I have tested in on a low volume email server.
>
> Wietse Venema:
> > The code is pretty clean, so I expect no surprises. I noticed that
>
> I have cleaned up the docs and code a little, and discovered that
> the query interface does not support the query formatting and domain
> matching features of the ldap, *sql* and memcache clients.
>
> This could (should) be similar to the memcache client implementation,
> including the key_format feature.
>
> I can do that but it will take some time, and it is unlikley to be
> part of the upcoming Postfix 3.6 release.
Attached is an updated patch, with some TODOs. I can implement
those, that but it will take some time.
Wietse
diff '--exclude=man' '--exclude=html' '--exclude=README_FILES'
'--exclude=INSTALL' '--exclude=.indent.pro' -r -ur --new-file
/var/tmp/postfix-3.6-20210224/conf/dynamicmaps.cf ./conf/dynamicmaps.cf
--- /var/tmp/postfix-3.6-20210224/conf/dynamicmaps.cf 2014-05-30
07:38:33.000000000 -0400
+++ ./conf/dynamicmaps.cf 2021-03-11 18:07:16.529195712 -0500
@@ -5,5 +5,6 @@
mysql ${LIB_PREFIX}mysql${LIB_SUFFIX} dict_mysql_open
pcre ${LIB_PREFIX}pcre${LIB_SUFFIX} dict_pcre_open
pgsql ${LIB_PREFIX}pgsql${LIB_SUFFIX} dict_pgsql_open
+redis ${LIB_PREFIX}redis${LIB_SUFFIX} dict_redis_open
sdbm ${LIB_PREFIX}sdbm${LIB_SUFFIX} dict_sdbm_open mkmap_sdbm_open
sqlite ${LIB_PREFIX}sqlite${LIB_SUFFIX} dict_sqlite_open
diff '--exclude=man' '--exclude=html' '--exclude=README_FILES'
'--exclude=INSTALL' '--exclude=.indent.pro' -r -ur --new-file
/var/tmp/postfix-3.6-20210224/conf/postfix-files ./conf/postfix-files
--- /var/tmp/postfix-3.6-20210224/conf/postfix-files 2019-01-29
17:24:42.000000000 -0500
+++ ./conf/postfix-files 2021-03-11 18:07:16.530195726 -0500
@@ -78,6 +78,7 @@
$shlib_directory/${LIB_PREFIX}mysql${LIB_SUFFIX}:f:root:-:755
$shlib_directory/${LIB_PREFIX}pcre${LIB_SUFFIX}:f:root:-:755
$shlib_directory/${LIB_PREFIX}pgsql${LIB_SUFFIX}:f:root:-:755
+$shlib_directory/${LIB_PREFIX}redis${LIB_SUFFIX}:f:root:-:755
$shlib_directory/${LIB_PREFIX}sdbm${LIB_SUFFIX}:f:root:-:755
$shlib_directory/${LIB_PREFIX}sqlite${LIB_SUFFIX}:f:root:-:755
$meta_directory/dynamicmaps.cf.d:d:root:-:755
@@ -200,6 +201,7 @@
$manpage_directory/man5/nisplus_table.5:f:root:-:644
$manpage_directory/man5/pcre_table.5:f:root:-:644
$manpage_directory/man5/pgsql_table.5:f:root:-:644
+$manpage_directory/man5/redis_table.5:f:root:-:644
$manpage_directory/man5/postconf.5:f:root:-:644
$manpage_directory/man5/postfix-wrapper.5:f:root:-:644
$manpage_directory/man5/regexp_table.5:f:root:-:644
@@ -307,6 +309,7 @@
$readme_directory/PACKAGE_README:f:root:-:644
$readme_directory/PCRE_README:f:root:-:644
$readme_directory/PGSQL_README:f:root:-:644
+$readme_directory/REDIS_README:f:root:-:644
$readme_directory/POSTSCREEN_README:f:root:-:644
$readme_directory/QMQP_README:f:root:-:644:o
$readme_directory/QSHAPE_README:f:root:-:644
@@ -363,6 +366,7 @@
$html_directory/PACKAGE_README.html:f:root:-:644
$html_directory/PCRE_README.html:f:root:-:644
$html_directory/PGSQL_README.html:f:root:-:644
+$html_directory/REDIS_README.html:f:root:-:644
$html_directory/POSTSCREEN_README.html:f:root:-:644
$html_directory/QMQP_README.html:f:root:-:644:o
$html_directory/QSHAPE_README.html:f:root:-:644
@@ -414,6 +418,7 @@
$html_directory/oqmgr.8.html:f:root:-:644
$html_directory/pcre_table.5.html:f:root:-:644
$html_directory/pgsql_table.5.html:f:root:-:644
+$html_directory/redis_table.5.html:f:root:-:644
$html_directory/pickup.8.html:f:root:-:644
$html_directory/pipe.8.html:f:root:-:644
$html_directory/postalias.1.html:f:root:-:644
diff '--exclude=man' '--exclude=html' '--exclude=README_FILES'
'--exclude=INSTALL' '--exclude=.indent.pro' -r -ur --new-file
/var/tmp/postfix-3.6-20210224/makedefs ./makedefs
--- /var/tmp/postfix-3.6-20210224/makedefs 2020-09-30 17:22:49.000000000
-0400
+++ ./makedefs 2021-03-11 18:07:16.531195739 -0500
@@ -1165,7 +1165,7 @@
# Propagate AUXLIBS_FOO or merge them into global AUXLIBS (i.e. SYSLIBS).
-PLUGGABLE_MAPS="CDB LDAP LMDB MYSQL PCRE PGSQL SDBM SQLITE"
+PLUGGABLE_MAPS="CDB LDAP LMDB MYSQL PCRE PGSQL REDIS SDBM SQLITE"
case "$dynamicmaps" in
yes) for name in $PLUGGABLE_MAPS
diff '--exclude=man' '--exclude=html' '--exclude=README_FILES'
'--exclude=INSTALL' '--exclude=.indent.pro' -r -ur --new-file
/var/tmp/postfix-3.6-20210224/proto/DATABASE_README.html
./proto/DATABASE_README.html
--- /var/tmp/postfix-3.6-20210224/proto/DATABASE_README.html 2020-08-29
13:51:42.000000000 -0400
+++ ./proto/DATABASE_README.html 2021-03-13 17:14:36.642652892 -0500
@@ -421,6 +421,11 @@
as used in "sdbm:table" is the database file name without the ".dir"
or ".pag" suffix. </dd>
+<dt> <b>redis</b> (read-only) </dt>
+
+<dd> Redis database. Configuration details are given in redis_table(5).
+</dd>
+
<dt> <b>socketmap</b> (read-only) </dt>
<dd> Sendmail-style socketmap client. The name of the table is
diff '--exclude=man' '--exclude=html' '--exclude=README_FILES'
'--exclude=INSTALL' '--exclude=.indent.pro' -r -ur --new-file
/var/tmp/postfix-3.6-20210224/proto/redis_table ./proto/redis_table
--- /var/tmp/postfix-3.6-20210224/proto/redis_table 1969-12-31
19:00:00.000000000 -0500
+++ ./proto/redis_table 2021-03-13 17:01:09.830335391 -0500
@@ -0,0 +1,81 @@
+#++
+# NAME
+# redis_table 5
+# SUMMARY
+# Postfix Redis client configuration
+# SYNOPSIS
+# \fBpostmap -q "\fIprefix:string\fB" redis:/etc/postfix/\fIfilename\fR
+#
+# \fBpostmap -q - redis:/etc/postfix/\fIfilename\fB <\fIinputfile\fR
+# DESCRIPTION
+# The Postfix mail system uses optional tables for address
+# rewriting or mail routing. These tables are usually in
+# \fBdbm\fR or \fBdb\fR format.
+#
+# Alternatively, lookup tables can be specified as Redis
+# databases. In order to use Redis lookups, define a Redis
+# source as a lookup table in main.cf, for example:
+# .nf
+# virtual_alias_maps = redis:/etc/postfix/redis-valias-maps.cf
+# .fi
+#
+# The file /etc/postfix/redis-valias-maps.cf has the same
+# format as the Postfix main.cf file, and can specify the
+# parameters described below.
+# .IP "\fBhost\fR"
+# The IP address of the host that Postfix will try to connect
+# to and query from.
+# .sp
+# Example:
+# .nf
+# host = 127.0.0.1
+# .fi
+# .IP "\fBport\fR"
+# The TCP port that Postfix will connect to and query from.
+# If not specified the default of \fB6379\fR will be used.
+# .sp
+# Example:
+# .nf
+# port = 6379
+# .fi
+# .IP "\fBprefix\fR"
+# This is the prefix that is added to the query from Postfix
+# before it is passed to Redis for a lookup, allowing postfix
+# to use simple key:value lookups from Redis.
+# .sp
+# Examples:
+# .nf
+# prefix = VALI
+# prefix = LOCAL
+# prefix = REV
+# prefix = HELO
+# .fi
+# SEE ALSO
+# .na
+# .nf
+# postmap(1), Postfix lookup table manager
+# postconf(5), configuration parameters
+# ldap_table(5), LDAP lookup tables
+# mysql_table(5), MySQL lookup tables
+# sqlite_table(5), SQLite lookup tables
+# README FILES
+# .ad
+# .fi
+# Use "\fBpostconf readme_directory\fR" or
+# "\fBpostconf html_directory\fR" to locate this information.
+# .na
+# .nf
+# DATABASE_README, Postfix lookup table overview
+# REDIS_README, Postfix Redis client support
+# LICENSE
+# The Secure Mailer license must be distributed with this software.
+# HISTORY
+# Redis support was introduced with Postfix version 3.7.
+# AUTHOR(S)
+# Titus Jose
+# [email protected]
+#
+# Updated by:
+# Duncan Bellamy
+# [email protected]
+#--
diff '--exclude=man' '--exclude=html' '--exclude=README_FILES'
'--exclude=INSTALL' '--exclude=.indent.pro' -r -ur --new-file
/var/tmp/postfix-3.6-20210224/src/global/dict_redis.c ./src/global/dict_redis.c
--- /var/tmp/postfix-3.6-20210224/src/global/dict_redis.c 1969-12-31
19:00:00.000000000 -0500
+++ ./src/global/dict_redis.c 2021-03-13 17:29:03.371773960 -0500
@@ -0,0 +1,250 @@
+/*++
+/* NAME
+/* dict_redis 3
+/* SUMMARY
+/* dictionary manager interface to Redis databases
+/* SYNOPSIS
+/* #include <dict_redis.h>
+/*
+/* DICT *dict_redis_open(name, open_flags, dict_flags)
+/* const char *name;
+/* int open_flags;
+/* int dict_flags;
+/* DESCRIPTION
+/* dict_redis_open() creates a dictionary of type 'redis'. This
+/* dictionary is an interface for the postfix key->value mappings
+/* to redis. The result is a pointer to the installed dictionary,
+/* or a null pointer in case of problems.
+/* .PP
+/* Arguments:
+/* .IP name
+/* Either the path to the Redis configuration file (if it
+/* starts with '/' or '.'), or the prefix which will be used to
+/* obtain main.cf configuration parameters for this search.
+/*
+/* In the first case, the configuration parameters below are
+/* specified in the file as \fIname\fR=\fIvalue\fR pairs.
+/*
+/* In the second case, the configuration parameters are
+/* prefixed with the value of \fIname\fR and an underscore,
+/* and they are specified in main.cf. For example, if this
+/* value is \fIredisDB\fR, the parameters would look like
+/* \fIredisDB_host\fR, \fIpredisDB_prefix\fR, and so on.
+/* .IP other_name
+/* reference for outside use.
+/* .IP open_flags
+/* unused.
+/* .IP dict_flags
+/* See dict_open(3).
+/*
+/* .PP
+/* Configuration parameters:
+/* .IP host
+/* IP address of the redis server hosting the database.
+/* .IP port
+/* Port number to connect to the above.
+/* .IP prefix
+/* Prefix to add to the key when looking it up.
+/* .PP
+/* For example, if you want the map to reference databases on
+/* redis host "127.0.0.1" and prefix the query with VDOM:
+/* Then the configuration file
+/* should read:
+/* .PP
+/* host = 127.0.0.1
+/* .br
+/* port = 6379
+/* .br
+/* prefix = VDOM:
+/* .PP
+/* SEE ALSO
+/* dict(3) generic dictionary manager
+/* HISTORY
+/* .ad
+/* .fi
+/* This feature was introduced with Postfix 3.7.
+/* AUTHOR(S)
+/* Titus Jose
+/* [email protected]
+/*
+/* Updated by:
+/* Duncan Bellamy
+/* [email protected]
+/*--*/
+
+#include <sys_defs.h>
+
+#ifdef HAS_REDIS
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <dict.h>
+#include <mymalloc.h>
+#include <vstring.h>
+#include <stringops.h>
+
+/* Global library. */
+
+#include <cfg_parser.h>
+
+/* Application-specific. */
+
+#include <dict_redis.h>
+#include <hiredis.h>
+
+typedef struct {
+ DICT dict;
+ CFG_PARSER *parser;
+ redisContext *c;
+ char *host;
+ int port;
+ char *prefix;
+ VSTRING *result;
+} DICT_REDIS;
+
+/* internal function declarations */
+static const char *dict_redis_lookup(DICT *, const char *);
+DICT *dict_redis_open(const char *, int, int);
+static void dict_redis_close(DICT *);
+static void redis_parse_config(DICT_REDIS *, const char *);
+
+
+static const char *dict_redis_lookup(DICT *dict, const char *name)
+{
+ const char *myname = "dict_redis_lookup";
+ DICT_REDIS *dict_redis = (DICT_REDIS *) dict;
+ redisReply *reply;
+ const char *r;
+ int error;
+
+ dict->error = 0;
+
+ if (msg_verbose)
+ msg_info("%s: Requesting key %s%s", dict_redis->host,
dict_redis->prefix, name);
+
+ /*
+ * Optionally fold the key.
+ */
+ if (dict->flags & DICT_FLAG_FOLD_FIX) {
+ if (dict->fold_buf == 0)
+ dict->fold_buf = vstring_alloc(10);
+ vstring_strcpy(dict->fold_buf, name);
+ name = lowercase(vstring_str(dict->fold_buf));
+ }
+
+ /*
+ * TODO(wietse) domain match, substring query, and key format support as in
+ * memcache_table.
+ */
+ reply = redisCommand(dict_redis->c, "GET %s%s", dict_redis->prefix, name);
+ error = dict->error;
+ if (reply->str) {
+ vstring_strcpy(dict_redis->result, reply->str);
+ r = vstring_str(dict_redis->result);
+ } else {
+ error = 1;
+ }
+ freeReplyObject(reply);
+ return ((error == 0 && *r) ? r : 0);
+}
+
+/* redis_parse_config - parse redis configuration file */
+
+static void redis_parse_config(DICT_REDIS *dict_redis, const char *rediscf)
+{
+ const char *myname = "redis_parse_config";
+ CFG_PARSER *p = dict_redis->parser;
+
+#if 0
+
+ /*
+ * TODO(wietse) substring query and key format support as in
+ * memcache_table.
+ */
+ dict_redis->key_format = cfg_get_str(p, "key_format", "%s", 0, 0);
+#endif
+ dict_redis->port = cfg_get_int(p, "port", 6379, 0, 0);
+ dict_redis->host = cfg_get_str(p, "host", "127.0.0.1", 1, 0);
+ dict_redis->prefix = cfg_get_str(p, "prefix", "", 0, 0);
+ dict_redis->result = vstring_alloc(10);
+}
+
+/* dict_redis_open - open redis data base */
+
+DICT *dict_redis_open(const char *name, int open_flags, int dict_flags)
+{
+ DICT_REDIS *dict_redis;
+ CFG_PARSER *parser;
+
+ /*
+ * Sanity check.
+ */
+ if (open_flags != O_RDONLY)
+ return (dict_surrogate(DICT_TYPE_REDIS, name, open_flags, dict_flags,
+ "%s:%s map requires O_RDONLY access mode",
+ DICT_TYPE_REDIS, name));
+
+ /*
+ * Open the configuration file.
+ */
+ if ((parser = cfg_parser_alloc(name)) == 0)
+ return (dict_surrogate(DICT_TYPE_REDIS, name, open_flags, dict_flags,
+ "open %s: %m", name));
+
+ dict_redis = (DICT_REDIS *) dict_alloc(DICT_TYPE_REDIS, name,
+ sizeof(DICT_REDIS));
+ dict_redis->dict.lookup = dict_redis_lookup;
+ dict_redis->dict.close = dict_redis_close;
+ dict_redis->dict.flags = dict_flags;
+ dict_redis->parser = parser;
+ redis_parse_config(dict_redis, name);
+ dict_redis->dict.owner = cfg_get_owner(dict_redis->parser);
+ dict_redis->c = redisConnect(dict_redis->host, dict_redis->port);
+ if (dict_redis->c == 0 || dict_redis->c->err) {
+ msg_warn("%s:%s: Cannot connect to Redis server %s",
+ DICT_TYPE_REDIS, name, dict_redis->host);
+ dict_redis->dict.close((DICT *) dict_redis);
+ return (dict_surrogate(DICT_TYPE_REDIS, name, open_flags, dict_flags,
+ "open %s: %m", name));
+ }
+#if 0
+
+ /*
+ * TODO(wietse) domain match, substring query, and key format support as in
+ * memcache_table.
+ */
+ dict_redis->dbc_ctxt = 0;
+ db_common_parse(&dict_redis->dict, &dict_redis->dbc_ctxt,
+ dict_redis->key_format, 1);
+ db_common_parse_domain(dict_redis->parser, dict_redis->dbc_ctxt);
+ if (db_common_dict_partial(dict_redis->dbc_ctxt))
+ /* Breaks recipient delimiters */
+ dict_redis->dict.flags |= DICT_FLAG_PATTERN;
+ else
+ dict_redis->dict.flags |= DICT_FLAG_FIXED;
+#endif
+ return (DICT_DEBUG (&dict_redis->dict));
+}
+
+/* dict_redis_close - close redis database */
+
+static void dict_redis_close(DICT *dict)
+{
+ DICT_REDIS *dict_redis = (DICT_REDIS *) dict;
+
+ if (dict_redis->c)
+ redisFree(dict_redis->c);
+ cfg_parser_free(dict_redis->parser);
+ myfree(dict_redis->host);
+ myfree(dict_redis->prefix);
+ vstring_free(dict_redis->result);
+ if (dict->fold_buf)
+ vstring_free(dict->fold_buf);
+ dict_free(dict);
+}
+
+#endif
diff '--exclude=man' '--exclude=html' '--exclude=README_FILES'
'--exclude=INSTALL' '--exclude=.indent.pro' -r -ur --new-file
/var/tmp/postfix-3.6-20210224/src/global/dict_redis.h ./src/global/dict_redis.h
--- /var/tmp/postfix-3.6-20210224/src/global/dict_redis.h 1969-12-31
19:00:00.000000000 -0500
+++ ./src/global/dict_redis.h 2021-03-13 16:47:47.025084145 -0500
@@ -0,0 +1,40 @@
+#ifndef _DICT_REDIS_H_INCLUDED_
+#define _DICT_REDIS_H_INCLUDED_
+
+/*++
+/* NAME
+/* dict_redis 3h
+/* SUMMARY
+/* dictionary manager interface to redis databases
+/* SYNOPSIS
+/* #include <dict_redis.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+ * Utility library.
+ */
+#include <dict.h>
+
+ /*
+ * External interface.
+ */
+#define DICT_TYPE_REDIS "redis"
+#endif /*SNAPSHOT */
+
+extern DICT *dict_redis_open(const char *, int, int);
+
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Titus Jose
+/* [email protected]
+/*
+/* Updated by:
+/* Duncan Bellamy
+/* [email protected]
+/*--*/
+
+#endif
diff '--exclude=man' '--exclude=html' '--exclude=README_FILES'
'--exclude=INSTALL' '--exclude=.indent.pro' -r -ur --new-file
/var/tmp/postfix-3.6-20210224/src/global/mail_dict.c ./src/global/mail_dict.c
--- /var/tmp/postfix-3.6-20210224/src/global/mail_dict.c 2014-06-21
20:42:55.000000000 -0400
+++ ./src/global/mail_dict.c 2021-03-11 18:07:16.532195753 -0500
@@ -45,6 +45,7 @@
#include <dict_ldap.h>
#include <dict_mysql.h>
#include <dict_pgsql.h>
+#include <dict_redis.h>
#include <dict_sqlite.h>
#include <dict_memcache.h>
#include <mail_dict.h>
@@ -68,6 +69,9 @@
#ifdef HAS_PGSQL
DICT_TYPE_PGSQL, dict_pgsql_open,
#endif
+#ifdef HAS_REDIS
+ DICT_TYPE_REDIS, dict_redis_open,
+#endif
#ifdef HAS_SQLITE
DICT_TYPE_SQLITE, dict_sqlite_open,
#endif
diff '--exclude=man' '--exclude=html' '--exclude=README_FILES'
'--exclude=INSTALL' '--exclude=.indent.pro' -r -ur --new-file
/var/tmp/postfix-3.6-20210224/src/global/Makefile.in ./src/global/Makefile.in
--- /var/tmp/postfix-3.6-20210224/src/global/Makefile.in 2021-01-09
16:24:11.000000000 -0500
+++ ./src/global/Makefile.in 2021-03-11 18:07:16.535195793 -0500
@@ -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_ldap.c dict_mysql.c dict_pgsql.c dict_redis.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 \
@@ -80,13 +80,13 @@
# MAP_OBJ is for maps that may be dynamically loaded with dynamicmaps.cf.
# When hard-linking these maps, makedefs sets NON_PLUGIN_MAP_OBJ=$(MAP_OBJ),
# otherwise it sets the PLUGIN_* macros.
-MAP_OBJ = dict_ldap.o dict_mysql.o dict_pgsql.o dict_sqlite.o mkmap_cdb.o \
+MAP_OBJ = dict_ldap.o dict_mysql.o dict_pgsql.o dict_redis.o dict_sqlite.o
mkmap_cdb.o \
mkmap_lmdb.o mkmap_sdbm.o
HDRS = abounce.h anvil_clnt.h been_here.h bounce.h bounce_log.h \
canon_addr.h cfg_parser.h cleanup_user.h clnt_stream.h config.h \
conv_time.h db_common.h debug_peer.h debug_process.h defer.h \
deliver_completed.h deliver_flock.h deliver_pass.h deliver_request.h \
- dict_ldap.h dict_mysql.h dict_pgsql.h dict_proxy.h dict_sqlite.h
domain_list.h \
+ dict_ldap.h dict_mysql.h dict_pgsql.h dict_redis.h dict_proxy.h
dict_sqlite.h domain_list.h \
dot_lockfile.h dot_lockfile_as.h dsb_scan.h dsn.h dsn_buf.h \
dsn_mask.h dsn_print.h dsn_util.h ehlo_mask.h ext_prop.h \
file_id.h flush_clnt.h header_opts.h header_token.h input_transp.h \
@@ -135,7 +135,7 @@
LIB_DIR = ../../lib
INC_DIR = ../../include
PLUGIN_MAP_SO = $(LIB_PREFIX)ldap$(LIB_SUFFIX) $(LIB_PREFIX)mysql$(LIB_SUFFIX)
\
- $(LIB_PREFIX)pgsql$(LIB_SUFFIX) $(LIB_PREFIX)sqlite$(LIB_SUFFIX) \
+ $(LIB_PREFIX)pgsql$(LIB_SUFFIX) $(LIB_PREFIX)redis$(LIB_SUFFIX)
$(LIB_PREFIX)sqlite$(LIB_SUFFIX) \
$(LIB_PREFIX)lmdb$(LIB_SUFFIX) $(LIB_PREFIX)cdb$(LIB_SUFFIX) \
$(LIB_PREFIX)sdbm$(LIB_SUFFIX)
MAKES =
@@ -171,6 +171,9 @@
$(LIB_PREFIX)pgsql$(LIB_SUFFIX): dict_pgsql.o
$(PLUGIN_LD) $(SHLIB_RPATH) -o $@ dict_pgsql.o $(AUXLIBS_PGSQL)
+$(LIB_PREFIX)redis$(LIB_SUFFIX): dict_redis.o
+ $(PLUGIN_LD) $(SHLIB_RPATH) -o $@ dict_redis.o $(AUXLIBS_REDIS)
+
$(LIB_PREFIX)sqlite$(LIB_SUFFIX): dict_sqlite.o
$(PLUGIN_LD) $(SHLIB_RPATH) -o $@ dict_sqlite.o $(AUXLIBS_SQLITE)
@@ -535,6 +538,8 @@
echo get foo| $(SHLIB_ENV) $(VALGRIND) ./mail_dict mysql:/xx read
>>surrogate.tmp 2>&1
echo get foo| $(SHLIB_ENV) $(VALGRIND) ./mail_dict pgsql:/xx write
>>surrogate.tmp 2>&1
echo get foo| $(SHLIB_ENV) $(VALGRIND) ./mail_dict pgsql:/xx read
>>surrogate.tmp 2>&1
+ echo get foo| $(SHLIB_ENV) $(VALGRIND) ./mail_dict redis:/xx write
>>surrogate.tmp 2>&1
+ echo get foo| $(SHLIB_ENV) $(VALGRIND) ./mail_dict redis:/xx read
>>surrogate.tmp 2>&1
echo get foo| $(SHLIB_ENV) $(VALGRIND) ./mail_dict sqlite:/xx write
>>surrogate.tmp 2>&1
echo get foo| $(SHLIB_ENV) $(VALGRIND) ./mail_dict sqlite:/xx read
>>surrogate.tmp 2>&1
echo get foo| $(SHLIB_ENV) $(VALGRIND) ./mail_dict memcache:/xx read
>>surrogate.tmp 2>&1
@@ -1231,6 +1236,17 @@
dict_pgsql.o: dict_pgsql.c
dict_pgsql.o: dict_pgsql.h
dict_pgsql.o: string_list.h
+dict_redis.o: ../../include/dict.h
+dict_redis.o: ../../include/msg.h
+dict_redis.o: ../../include/mymalloc.h
+dict_redis.o: ../../include/vbuf.h
+dict_redis.o: ../../include/vstream.h
+dict_redis.o: ../../include/vstring.h
+dict_redis.o: ../../include/stringops.h
+dict_redis.o: ../../include/sys_defs.h
+dict_redis.o: cfg_parser.h
+dict_redis.o: dict_redis.c
+dict_redis.o: dict_redis.h
dict_proxy.o: ../../include/argv.h
dict_proxy.o: ../../include/attr.h
dict_proxy.o: ../../include/check_arg.h
@@ -1835,6 +1851,7 @@
mail_dict.o: dict_memcache.h
mail_dict.o: dict_mysql.h
mail_dict.o: dict_pgsql.h
+mail_dict.o: dict_redis.h
mail_dict.o: dict_proxy.h
mail_dict.o: dict_sqlite.h
mail_dict.o: dynamicmaps.h
diff '--exclude=man' '--exclude=html' '--exclude=README_FILES'
'--exclude=INSTALL' '--exclude=.indent.pro' -r -ur --new-file
/var/tmp/postfix-3.6-20210224/src/postconf/postconf.c ./src/postconf/postconf.c
--- /var/tmp/postfix-3.6-20210224/src/postconf/postconf.c 2021-01-03
12:08:51.000000000 -0500
+++ ./src/postconf/postconf.c 2021-03-13 16:50:27.846333680 -0500
@@ -339,6 +339,10 @@
/* with support for SDBM databases.
/*
/* This feature is available with Postfix 2.2 and later.
+/* .IP "\fBredis\fR (read-only)"
+/* Redis database. This is described in \fBredis_table\fR(5).
+/*
+/* This feature is available with Postfix 3.7 and later.
/* .IP "\fBsocketmap\fR (read-only)"
/* Sendmail-style socketmap client. The table name is
/* \fBinet\fR:\fIhost\fR:\fIport\fR:\fIname\fR for a TCP/IP