OpenPKG CVS Repository http://cvs.openpkg.org/ ____________________________________________________________________________
Server: cvs.openpkg.org Name: Ralf S. Engelschall Root: /v/openpkg/cvs Email: r...@openpkg.org Module: openpkg-src Date: 05-Jul-2009 21:25:18 Branch: HEAD Handle: 2009070520251700 Added files: openpkg-src/postfix postfix.patch.sqlite Modified files: openpkg-src/postfix postfix.spec Log: add optional SQLite support Summary: Revision Changes Path 1.1 +394 -0 openpkg-src/postfix/postfix.patch.sqlite 1.285 +19 -3 openpkg-src/postfix/postfix.spec ____________________________________________________________________________ patch -p0 <<'@@ .' Index: openpkg-src/postfix/postfix.patch.sqlite ============================================================================ $ cvs diff -u -r0 -r1.1 postfix.patch.sqlite --- /dev/null 2009-07-05 21:25:15 +0200 +++ postfix.patch.sqlite 2009-07-05 21:25:17 +0200 @@ -0,0 +1,394 @@ +Postfix SQLite Lookup Table Support +http://www.treibsand.com/postfix-sqlite/ + +Index: src/global/Makefile.in +--- src/global/Makefile.in.orig 2009-02-13 02:25:05 +0100 ++++ src/global/Makefile.in 2009-07-05 21:16:55 +0200 +@@ -4,7 +4,7 @@ + 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 \ +- dict_proxy.c domain_list.c dot_lockfile.c dot_lockfile_as.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 \ + header_token.c input_transp.c int_filt.c is_header.c log_adhoc.c \ +@@ -35,7 +35,7 @@ + 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 \ +- dict_proxy.o domain_list.o dot_lockfile.o dot_lockfile_as.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 \ + header_token.o input_transp.o int_filt.o is_header.o log_adhoc.o \ +@@ -65,7 +65,7 @@ + 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 domain_list.h \ ++ dict_ldap.h dict_mysql.h dict_pgsql.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 \ +@@ -862,6 +862,13 @@ + dict_proxy.o: dict_proxy.h + dict_proxy.o: mail_params.h + dict_proxy.o: mail_proto.h ++dict_sqlite.o: ../../include/dict.h ++dict_sqlite.o: ../../include/msg.h ++dict_sqlite.o: ../../include/sys_defs.h ++dict_sqlite.o: cfg_parser.h ++dict_sqlite.o: db_common.h ++dict_sqlite.o: dict_sqlite.c ++dict_sqlite.o: dict_sqlite.h + domain_list.o: ../../include/match_list.h + domain_list.o: ../../include/match_ops.h + domain_list.o: ../../include/sys_defs.h +@@ -1233,6 +1240,7 @@ + mail_dict.o: dict_mysql.h + mail_dict.o: dict_pgsql.h + mail_dict.o: dict_proxy.h ++mail_dict.o: dict_sqlite.h + mail_dict.o: mail_dict.c + mail_dict.o: mail_dict.h + mail_error.o: ../../include/name_mask.h +Index: src/global/dict_sqlite.c +--- /dev/null 2009-07-05 21:16:41 +0200 ++++ src/global/dict_sqlite.c 2009-07-05 21:16:55 +0200 +@@ -0,0 +1,278 @@ ++/*++ ++/* NAME ++/* dict_sqlite 3 ++/* SUMMARY ++/* dictionary manager interface to SQLite3 databases ++/* SYNOPSIS ++/* #include <dict_sqlite.h> ++/* ++/* DICT *dict_sqlite_open(name, open_flags, dict_flags) ++/* const char *name; ++/* int open_flags; ++/* int dict_flags; ++/* DESCRIPTION ++/* dict_sqlite_open() creates a dictionary of type 'sqlite'. This ++/* dictionary is an interface for the postfix key->value mappings ++/* to SQLite. 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 SQLite 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=\fBvalue\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 \fIsqlitecon\fR, the parameters would look like ++/* \fIsqlitecon_user\fR, \fIsqlitecon_table\fR, and so on. ++/* ++/* .IP open_flags ++/* Must be O_RDONLY. ++/* .IP dict_flags ++/* See dict_open(3). ++/* .PP ++/* Configuration parameters: ++/* ++/* The parameters encodes a number of pieces of information: ++/* dbpath, query, result_format and expansion_limit: ++/* .IP \fIdbpath\fR ++/* Path to SQLite database ++/* .IP \fIquery\fR ++/* Query template, before the query is actually issued, variable ++/* substitutions are performed. See sqlite_table(5) for details. ++/* .IP \fIresult_format\fR ++/* The format used to expand results from queries. Substitutions ++/* are performed as described in sqlite_table(5). Defaults to returning ++/* the lookup result unchanged. ++/* .IP expansion_limit ++/* Limit (if any) on the total number of lookup result values. Lookups which ++/* exceed the limit fail with dict_errno=DICT_ERR_RETRY. Note that each ++/* non-empty (and non-NULL) column of a multi-column result row counts as ++/* one result. ++/* ++/* SEE ALSO ++/* dict(3) generic dictionary manager ++/* AUTHOR(S) ++/* Axel Steiner ++/* a...@treibsand.com ++/*--*/ ++ ++/* System library. */ ++#include "sys_defs.h" ++ ++#ifdef HAS_SQLITE ++#include <sqlite3.h> ++ ++#if !defined(SQLITE_VERSION_NUMBER) || (SQLITE_VERSION_NUMBER < 3005004) ++#error "Your SQLite version is too old" ++#endif ++ ++/* Utility library. */ ++ ++#include "msg.h" ++#include "dict.h" ++#include "vstring.h" ++#include "stringops.h" ++#include "mymalloc.h" ++ ++/* Global library. */ ++ ++#include "cfg_parser.h" ++#include "db_common.h" ++ ++/* Application-specific. */ ++ ++#include "dict_sqlite.h" ++ ++typedef struct { ++ DICT dict; ++ CFG_PARSER *parser; ++ sqlite3 *db; ++ char *dbpath; ++ char *query; ++ char *result_format; ++ int expansion_limit; ++ void *ctx; ++} DICT_SQLITE; ++ ++typedef sqlite3_stmt *SQL; ++ ++/* internal function declarations */ ++ ++static const char *dict_sqlite_lookup(DICT *, const char *); ++DICT *dict_sqlite_open(const char *, int, int); ++static void dict_sqlite_close(DICT *); ++static void sqlite_parse_config(DICT_SQLITE *, const char *); ++ ++/* dict_sqlite_quote - escape SQL metacharacters in input string */ ++ ++static void dict_sqlite_quote(DICT *dict, const char *name, VSTRING *result) { ++ DICT_SQLITE *dict_sqlite = (DICT_SQLITE *) dict; ++ int len = strlen(name); ++ int buflen = 2*len + 1; ++ char *q; ++ ++ if (buflen < len) ++ msg_panic("dict_sqlite_quote: integer overflow in 2*%d+1", len); ++ ++ VSTRING_SPACE(result, buflen); ++ q = sqlite3_mprintf("%q",name); ++ vstring_strncat(result,q, strlen(q)); ++ sqlite3_free(q); ++ VSTRING_SKIP(result); ++} ++ ++ ++/* dict_sqlite_close - close the database */ ++ ++static void dict_sqlite_close(DICT *dict) { ++ const char *myname = "dict_sqlite_close"; ++ DICT_SQLITE *dict_sqlite = (DICT_SQLITE *) dict; ++ ++ if (msg_verbose) ++ msg_info("%s: dict_sqlite_close", myname); ++ if (sqlite3_close(dict_sqlite->db) != SQLITE_OK) ++ msg_fatal("%s: DB close failed", myname); ++ cfg_parser_free(dict_sqlite->parser); ++ myfree(dict_sqlite->dbpath); ++ myfree(dict_sqlite->query); ++ myfree(dict_sqlite->result_format); ++ if (dict_sqlite->ctx) ++ db_common_free_ctx(dict_sqlite->ctx); ++ if (dict->fold_buf) ++ vstring_free(dict->fold_buf); ++ dict_free(dict); ++} ++ ++ ++/* dict_sqlite_lookup - find database entry */ ++ ++static const char *dict_sqlite_lookup(DICT *dict, const char *name) { ++ const char *myname = "dict_sqlite_lookup"; ++ DICT_SQLITE *dict_sqlite = (DICT_SQLITE *) dict; ++ SQL sql; ++ const char *zErrMsg; ++ static VSTRING *query; ++ static VSTRING *result; ++ const char *r; ++ int expansion = 0; ++ ++ /* ++ * 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)); ++ } ++ ++ if (db_common_check_domain(dict_sqlite->ctx, name) == 0) { ++ if (msg_verbose) ++ msg_info("%s: Skipping lookup of '%s'", myname, name); ++ return (0); ++ } ++ ++#define INIT_VSTR(buf, len) do { \ ++ if (buf == 0) \ ++ buf = vstring_alloc(len); \ ++ VSTRING_RESET(buf); \ ++ VSTRING_TERMINATE(buf); \ ++ } while (0) ++ ++ INIT_VSTR(query, 10); ++ ++ if (!db_common_expand(dict_sqlite->ctx, dict_sqlite->query, ++ name, 0, query, dict_sqlite_quote)) ++ return (0); ++ ++ if (msg_verbose) ++ msg_info("%s: %s: Searching with query %s", myname, ++ dict_sqlite->parser->name, vstring_str(query)); ++ ++ if(sqlite3_prepare_v2(dict_sqlite->db,vstring_str(query),-1,&sql,&zErrMsg)!=SQLITE_OK) { ++ msg_fatal("%s: sql prepare %s\n",myname,sqlite3_errmsg(dict_sqlite->db)); ++ } ++ ++ INIT_VSTR(result, 10); ++ while (sqlite3_step(sql) == SQLITE_ROW ) { ++ if (db_common_expand(dict_sqlite->ctx, dict_sqlite->result_format, ++ sqlite3_column_text(sql, 0), name, result, 0) ++ && dict_sqlite->expansion_limit > 0 ++ && ++expansion > dict_sqlite->expansion_limit) { ++ msg_warn("%s: %s: Expansion limit exceeded for key: '%s'", ++ myname, dict_sqlite->parser->name, name); ++ dict_errno = DICT_ERR_RETRY; ++ break; ++ } ++ } ++ ++ if(sqlite3_finalize(sql)){ ++ msg_fatal("%s: sql finalize for %s; %s\n",myname,vstring_str(query),sqlite3_errmsg(dict_sqlite->db)); ++ return(0); ++ } ++ ++ ++ r = vstring_str(result); ++ return ((dict_errno == 0 && *r) ? r : 0); ++} ++ ++/* sqlite_parse_config - parse sqlite configuration file */ ++ ++static void sqlite_parse_config(DICT_SQLITE *dict_sqlite, const char *sqlitecf) { ++ CFG_PARSER *p; ++ VSTRING *buf; ++ ++ p = dict_sqlite->parser = cfg_parser_alloc(sqlitecf); ++ dict_sqlite->dbpath = cfg_get_str(p, "dbpath", "", 1, 0); ++ dict_sqlite->result_format = cfg_get_str(p, "result_format", "%s", 1, 0); ++ ++ if ((dict_sqlite->query = cfg_get_str(p, "query", NULL, 0, 0)) == 0) { ++ buf = vstring_alloc(64); ++ db_common_sql_build_query(buf, p); ++ dict_sqlite->query = vstring_export(buf); ++ } ++ dict_sqlite->expansion_limit = cfg_get_int(p,"expansion_limit", 0, 0, 0); ++ dict_sqlite->ctx = 0; ++ ++ (void) db_common_parse(&dict_sqlite->dict, &dict_sqlite->ctx, dict_sqlite->query, 1); ++ (void) db_common_parse(0, &dict_sqlite->ctx, dict_sqlite->result_format, 0); ++ ++ db_common_parse_domain(p, dict_sqlite->ctx); ++ ++ if (dict_sqlite->dict.flags & DICT_FLAG_FOLD_FIX) ++ dict_sqlite->dict.fold_buf = vstring_alloc(10); ++ ++} ++ ++/* dict_sqlite_open - open sqlite database */ ++ ++DICT *dict_sqlite_open(const char *name, int open_flags, int dict_flags) { ++ DICT_SQLITE *dict_sqlite; ++ ++ /* ++ * Sanity checks. ++ */ ++ if (open_flags != O_RDONLY) ++ msg_fatal("%s:%s map requires O_RDONLY access mode", DICT_TYPE_SQLITE, name); ++ ++ dict_sqlite = (DICT_SQLITE *) dict_alloc(DICT_TYPE_SQLITE, name, sizeof(DICT_SQLITE)); ++ dict_sqlite->dict.lookup = dict_sqlite_lookup; ++ dict_sqlite->dict.close = dict_sqlite_close; ++ dict_sqlite->dict.flags = dict_flags; ++ dict_sqlite->dict.flags |= DICT_FLAG_FIXED; ++ sqlite_parse_config(dict_sqlite, name); ++ ++ if (sqlite3_open(dict_sqlite->dbpath, &dict_sqlite->db)) { ++ msg_fatal("Can't open database: %s\n", sqlite3_errmsg(dict_sqlite->db)); ++ sqlite3_close(dict_sqlite->db); ++ } ++ ++ return (DICT_DEBUG (&dict_sqlite->dict)); ++} ++#endif +Index: src/global/dict_sqlite.h +--- /dev/null 2009-07-05 21:16:41 +0200 ++++ src/global/dict_sqlite.h 2009-07-05 21:16:55 +0200 +@@ -0,0 +1,32 @@ ++#ifndef _DICT_SQLITE_H_INCLUDED_ ++#define _DICT_SQLITE_H_INCLUDED_ ++ ++/*++ ++/* NAME ++/* dict_sqlite 3h ++/* SUMMARY ++/* dictionary manager interface to sqlite databases ++/* SYNOPSIS ++/* #include <dict_sqlite.h> ++/* DESCRIPTION ++/* .nf ++ ++ /* ++ * Utility library. ++ */ ++#include <dict.h> ++ ++ /* ++ * External interface. ++ */ ++#define DICT_TYPE_SQLITE "sqlite" ++ ++extern DICT *dict_sqlite_open(const char *, int, int); ++ ++ ++/* AUTHOR(S) ++/* Axel Steiner ++/* a...@treibsand.com ++/*--*/ ++ ++#endif +Index: src/global/mail_dict.c +--- src/global/mail_dict.c.orig 2008-01-08 22:07:47 +0100 ++++ src/global/mail_dict.c 2009-07-05 21:16:55 +0200 +@@ -36,6 +36,7 @@ + #include <dict_ldap.h> + #include <dict_mysql.h> + #include <dict_pgsql.h> ++#include <dict_sqlite.h> + #include <mail_dict.h> + + typedef struct { +@@ -54,6 +55,9 @@ + #ifdef HAS_PGSQL + DICT_TYPE_PGSQL, dict_pgsql_open, + #endif ++#ifdef HAS_SQLITE ++ DICT_TYPE_SQLITE, dict_sqlite_open, ++#endif + 0, + }; + @@ . patch -p0 <<'@@ .' Index: openpkg-src/postfix/postfix.spec ============================================================================ $ cvs diff -u -r1.284 -r1.285 postfix.spec --- openpkg-src/postfix/postfix.spec 4 Jun 2009 20:57:53 -0000 1.284 +++ openpkg-src/postfix/postfix.spec 5 Jul 2009 19:25:17 -0000 1.285 @@ -37,12 +37,13 @@ Group: Mail License: IPL Version: %{V_postfix} -Release: 20090604 +Release: 20090705 # package options %option with_fsl yes %option with_ssl no %option with_sasl no +%option with_sqlite no %option with_mysql no %option with_pgsql no %option with_ldap no @@ -57,7 +58,8 @@ Source4: rc.postfix Patch0: postfix.patch Patch1: postfix.patch.pfls -Patch2: ftp://ftp.openpkg.org/sources/CPY/postfix/postfix-%{V_whoson}-whoson.patch +Patch2: postfix.patch.sqlite +Patch3: ftp://ftp.openpkg.org/sources/CPY/postfix/postfix-%{V_whoson}-whoson.patch # build information Prefix: %{l_prefix} @@ -78,6 +80,10 @@ BuildPreReq: sasl PreReq: sasl %endif +%if "%{with_sqlite}" == "yes" +BuildPreReq: sqlite +PreReq: sqlite +%endif %if "%{with_mysql}" == "yes" BuildPreReq: mysql PreReq: mysql @@ -111,6 +117,7 @@ o PCRE matching support o Optional STARTTLS encryption support (see package options) o Optional SASL2 authentication support (see package options) + o Optional SQLite dictionary support (see package options) o Optional MySQL dictionary support (see package options) o Optional PostgreSQL dictionary support (see package options) o Optional OpenLDAP dictionary support (see package options) @@ -142,9 +149,14 @@ %patch -p0 ( cd pflogsumm-%{V_pflogsumm} && %{l_patch} -p0 -b <%{PATCH1} ) || exit $? + # apply vendor SQLite patch +%if "%{with_sqlite}" == "yes" + %patch -p0 -P 2 +%endif + # apply vendor WHOSON patch %if "%{with_whoson}" == "yes" - %patch -p0 -P 2 + %patch -p0 -P 3 %endif %build @@ -177,6 +189,10 @@ AUXLIBS="$AUXLIBS -ldb" CCARGS="$CCARGS -DHAS_PCRE" AUXLIBS="$AUXLIBS -lpcre" +%if "%{with_sqlite}" == "yes" + CCARGS="$CCARGS -DHAS_SQLITE" + AUXLIBS="$AUXLIBS -lsqlite3" +%endif %if "%{with_mysql}" == "yes" CCARGS="$CCARGS -DHAS_MYSQL %{l_cppflags mysql .}" AUXLIBS="$AUXLIBS %{l_ldflags mysql .} -lmysqlclient -lz -lm" @@ . ______________________________________________________________________ OpenPKG http://openpkg.org CVS Repository Commit List openpkg-cvs@openpkg.org