]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.8-20100618
authorWietse Venema <wietse@porcupine.org>
Fri, 18 Jun 2010 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:36:20 +0000 (06:36 +0000)
postfix/HISTORY
postfix/html/SQLITE_README.html
postfix/html/sqlite_table.5.html
postfix/man/man5/sqlite_table.5
postfix/mantools/postlink
postfix/proto/sqlite_table
postfix/src/global/dict_mysql.c
postfix/src/global/dict_pgsql.c
postfix/src/global/dict_sqlite.c
postfix/src/global/mail_version.h

index 4d6f411a0b0c66394770081db391d925ae2bc9ce..747e4440ac22d6e29913e24b63e287552dbbf59d 100644 (file)
@@ -15846,8 +15846,12 @@ Apologies for any names omitted.
        Feature: read-only sqlite support based on code by Axel
        Steiner and documentation by Jesus Garcia Crespo. Files:
        conf/postfix-files, mantools/postlink, proto/DATABASE_README.html,
-       proto/Makefile.in, proto/INSTALL.html, proto/SASL_README.html,
-       proto/mysql_table, proto/pgsql_table, proto/sqlite_table,
-       proto/SQLITE_README.html, global/Makefile.in, global/mail_dict.c,
-       global/dict_sqlite.c, global/dict_sqlite.h, postconf/postconf.c,
-       postfix/postfix.c.
+       proto/Makefile.in, proto/INSTALL.html, proto/mysql_table,
+       proto/pgsql_table, proto/sqlite_table, proto/SQLITE_README.html,
+       global/Makefile.in, global/mail_dict.c, global/dict_sqlite.c,
+       global/dict_sqlite.h, postconf/postconf.c, postfix/postfix.c.
+
+20100618
+
+       Cleanup: SQLite read-only driver and documentation.  Files:
+       global/dict_sqlite.c, proto/mysql_table, proto/SQLITE_README.html.
index c9147cef0f5c7ab53b7602a4ad1587bbc28dd3de..7b78f7465c661fe323469dec001965138c816de9 100644 (file)
@@ -54,7 +54,7 @@ map type in <a href="postconf.5.html">main.cf</a> like this: </p>
 
 <blockquote>
 <pre>
-<a href="postconf.5.html#alias_maps">alias_maps</a> = sqlite:/etc/postfix/sqlite-aliases.cf
+<a href="postconf.5.html#alias_maps">alias_maps</a> = <a href="mysql_table.5.html">sqlite</a>:/etc/postfix/sqlite-aliases.cf
 </pre>
 </blockquote>
 
index dc92a21aaf8d694d3d1e99031202920ea58e8733..c385d77ccf9644a33813d470e5f4bfc62f564db8 100644 (file)
@@ -10,9 +10,9 @@ SQLITE_TABLE(5)                                                SQLITE_TABLE(5)
        sqlite_table - Postfix SQLite configuration
 
 <b>SYNOPSIS</b>
-       <b>postmap -q "</b><i>string</i><b>" sqlite:/etc/postfix/filename</b>
+       <b>postmap -q "</b><i>string</i><b>" <a href="mysql_table.5.html">sqlite</a>:/etc/postfix/filename</b>
 
-       <b>postmap -q - sqlite:/etc/postfix/</b><i>filename</i> &lt;<i>inputfile</i>
+       <b>postmap -q - <a href="mysql_table.5.html">sqlite</a>:/etc/postfix/</b><i>filename</i> &lt;<i>inputfile</i>
 
 <b>DESCRIPTION</b>
        The  Postfix  mail system uses optional tables for address
@@ -20,9 +20,9 @@ SQLITE_TABLE(5)                                                SQLITE_TABLE(5)
        or <b>db</b> format.
 
        Alternatively,  lookup  tables  can be specified as SQLite
-       databases.  In order  to  use  SQLite  lookups,  define  a
+       databases.  In order to  use  SQLite  lookups,  define  an
        SQLite source as a lookup table in <a href="postconf.5.html">main.cf</a>, for example:
-           <a href="postconf.5.html#alias_maps">alias_maps</a> = sqlite:/etc/sqlite-aliases.cf
+           <a href="postconf.5.html#alias_maps">alias_maps</a> = <a href="mysql_table.5.html">sqlite</a>:/etc/sqlite-aliases.cf
 
        The  file /etc/postfix/sqlite-aliases.cf has the same for-
        mat as the Postfix  <a href="postconf.5.html">main.cf</a>  file,  and  can  specify  the
@@ -35,7 +35,7 @@ SQLITE_TABLE(5)                                                SQLITE_TABLE(5)
        with a slash or a dot.  The SQLite parameters will then be
        accessible as the name you've given the source in its def-
        inition, an underscore, and the  name  of  the  parameter.
-       For  example,  if  the map is specified as "sqlite:<i>sqlite-</i>
+       For  example,  if  the map is specified as "<a href="mysql_table.5.html">sqlite</a>:<i>sqlite-</i>
        <i>name</i>", the parameter "query" below  would  be  defined  in
        <a href="postconf.5.html">main.cf</a> as "<i>sqlitename</i>_query".
 
@@ -269,7 +269,7 @@ SQLITE_TABLE(5)                                                SQLITE_TABLE(5)
 
 <b>README FILES</b>
        <a href="DATABASE_README.html">DATABASE_README</a>, Postfix lookup table overview
-       <a href="SQLITE_README.html">SQLITE_README</a>, Postfix SQLITE driver
+       <a href="SQLITE_README.html">SQLITE_README</a>, Postfix SQLITE howto
 
 <b>LICENSE</b>
        The  Secure  Mailer  license must be distributed with this
index 8133f6d51942bef7bb0226c24b2f121371b4f009..7da05239021c6d82e1f1dbe9527c408bc3d0ccb7 100644 (file)
@@ -19,7 +19,7 @@ rewriting or mail routing. These tables are usually in
 \fBdbm\fR or \fBdb\fR format.
 
 Alternatively, lookup tables can be specified as SQLite databases.
-In order to use SQLite lookups, define a SQLite source as a lookup
+In order to use SQLite lookups, define an SQLite source as a lookup
 table in main.cf, for example:
 .nf
     alias_maps = sqlite:/etc/sqlite-aliases.cf
@@ -286,7 +286,7 @@ Use "\fBpostconf readme_directory\fR" or
 .na
 .nf
 DATABASE_README, Postfix lookup table overview
-SQLITE_README, Postfix SQLITE driver
+SQLITE_README, Postfix SQLITE howto
 .SH "LICENSE"
 .na
 .nf
index 587af90e6a2eede21870e835b80671b9be4314c0..cca42d88215a13a20c90d9a455bcf1d1bfdb87c0 100755 (executable)
@@ -979,6 +979,7 @@ while (<>) {
     s/\b(nisplus):/<a href="nisplus_table.5.html">$1<\/a>:/g;
     s/\b(ldap):/<a href="ldap_table.5.html">$1<\/a>:/g;
     s/\b(regexp):/<a href="regexp_table.5.html">$1<\/a>:/g;
+    s/\b(sqlite):/<a href="mysql_table.5.html">$1<\/a>:/g;
     s/\b(tcp):/<a href="tcp_table.5.html">$1<\/a>:/g;
 
     # Do nice links for smtp:host:port etc.
index f9934d2077683dbf884c0d895a9a9d01b5c0f130..b981134e2026ea0973a8cfd9c6a4b014c44c21c5 100644 (file)
@@ -13,7 +13,7 @@
 #      \fBdbm\fR or \fBdb\fR format.
 #
 #      Alternatively, lookup tables can be specified as SQLite databases.
-#      In order to use SQLite lookups, define a SQLite source as a lookup
+#      In order to use SQLite lookups, define an SQLite source as a lookup
 #      table in main.cf, for example:
 # .nf
 #          alias_maps = sqlite:/etc/sqlite-aliases.cf
 # .na
 # .nf
 #      DATABASE_README, Postfix lookup table overview
-#      SQLITE_README, Postfix SQLITE driver
+#      SQLITE_README, Postfix SQLITE howto
 # LICENSE
 # .ad
 # .fi
index 5bbc1c31b21dc48073b8cd232a1a009f3da2ecaf..27663ad1e6e857e752caaa4178399a5f9bcc7203 100644 (file)
 /*     "vmailer" and password "passwd" then the configuration file
 /*     should read:
 /* .PP
-/*     \fIuser\fR = \fBvmailer\fR
+/*     user = vmailer
 /* .br
-/*     \fIpassword\fR = \fBpasswd\fR
+/*     password = passwd
 /* .br
-/*     \fIdbname\fR = \fBvmailer_info\fR
+/*     dbname = vmailer_info
 /* .br
-/*     \fItable\fR = \fBaliases\fR
+/*     table = aliases
 /* .br
-/*     \fIselect_field\fR = \fBforw_addr\fR
+/*     select_field = forw_addr
 /* .br
-/*     \fIwhere_field\fR = \fBalias\fR
+/*     where_field = alias
 /* .br
-/*     \fIhosts\fR = \fBhost1.some.domain\fR \fBhost2.some.domain\fR
+/*     hosts = host1.some.domain\fR \fBhost2.some.domain
 /* .IP additional_conditions
 /*      Backward compatibility when \fIquery\fR is not set, additional
 /*     conditions to the WHERE clause.
 /*     "vmailer" and password "passwd" then the configuration file
 /*     should read:
 /* .PP
-/*     \fIuser\fR = \fBvmailer\fR
+/*     user = vmailer
 /* .br
-/*     \fIpassword\fR = \fBpasswd\fR
+/*     password = passwd
 /* .br
-/*     \fIdbname\fR = \fBvmailer_info\fR
+/*     dbname = vmailer_info
 /* .br
-/*     \fItable\fR = \fBaliases\fR
+/*     table = aliases
 /* .br
-/*     \fIselect_field\fR = \fBforw_addr\fR
+/*     select_field = forw_addr
 /* .br
-/*     \fIwhere_field\fR = \fBalias\fR
+/*     where_field = alias
 /* .br
-/*     \fIhosts\fR = \fBhost1.some.domain\fR \fBhost2.some.domain\fR
+/*     hosts = host1.some.domain\fR \fBhost2.some.domain
 /* .PP
 /* SEE ALSO
 /*     dict(3) generic dictionary manager
index c01c01097fd0dc6e49f3165cf57a356805f37556..9899cf4fce7ca24c83d031d5dd75e769ab2b6cbe 100644 (file)
 /*     "postfix" and password "passwd" then the configuration file
 /*     should read:
 /* .PP
-/*     \fIuser\fR = \fBpostfix\fR
+/*     user = postfix
 /* .br
-/*     \fIpassword\fR = \fBpasswd\fR
+/*     password = passwd
 /* .br
-/*     \fIdbname\fR = \fBpostfix_info\fR
+/*     dbname = postfix_info
 /* .br
-/*     \fItable\fR = \fBaliases\fR
+/*     table = aliases
 /* .br
-/*     \fIselect_field\fR = \fBforw_addr\fR
+/*     select_field = forw_addr
 /* .br
-/*     \fIwhere_field\fR = \fBalias\fR
+/*     where_field = alias
 /* .br
-/*     \fIhosts\fR = \fBhost1.some.domain\fR \fBhost2.some.domain\fR
+/*     hosts = host1.some.domain\fR \fBhost2.some.domain
 /* .PP
 /* SEE ALSO
 /*     dict(3) generic dictionary manager
index 1314107c1c5ca68f225e3beec60fcded7c9a4e17..5d6659ab8ea40b6423315846cbb342dedee00bd7 100644 (file)
@@ -14,7 +14,7 @@
 /*     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.
+/*     dictionary.
 /* .PP
 /*     Arguments:
 /* .IP name
@@ -39,7 +39,7 @@
 /* .IP dbpath
 /*     Path to SQLite database
 /* .IP query
-/*     Query template, before the query is actually issued, variable
+/*     Query template. Before the query is actually issued, variable
 /*     substitutions are performed. See sqlite_table(5) for details.
 /* .IP result_format
 /*     The format used to expand results from queries.  Substitutions
@@ -101,16 +101,16 @@ typedef struct {
 
 /* dict_sqlite_quote - escape SQL metacharacters in input string */
 
-static void dict_sqlite_quote(DICT *dict, const char *name, VSTRING *result)
+static void dict_sqlite_quote(DICT *dict, const char *raw_text, VSTRING *result)
 {
-    char   *q;
+    char   *quoted_text;
 
-    q = sqlite3_mprintf("%q", name);
+    quoted_text = sqlite3_mprintf("%q", raw_text);
     /* Fix 20100616 */
-    if (q == 0)
+    if (quoted_text == 0)
        msg_fatal("dict_sqlite_quote: out of memory");
-    vstring_strcat(result, q);
-    sqlite3_free(q);
+    vstring_strcat(result, raw_text);
+    sqlite3_free(quoted_text);
 }
 
 /* dict_sqlite_close - close the database */
@@ -142,11 +142,11 @@ static const char *dict_sqlite_lookup(DICT *dict, const char *name)
 {
     const char *myname = "dict_sqlite_lookup";
     DICT_SQLITE *dict_sqlite = (DICT_SQLITE *) dict;
-    sqlite3_stmt *sql;
-    const char *zErrMsg;
+    sqlite3_stmt *sql_stmt;
+    const char *query_remainder;
     static VSTRING *query;
     static VSTRING *result;
-    const char *r;
+    const char *retval;
     int     expansion = 0;
     int     status;
 
@@ -161,17 +161,17 @@ static const char *dict_sqlite_lookup(DICT *dict, const char *name)
     }
 
     /*
-     * Optionally fold the key.
+     * Optionally fold the key. Folding may be enabled on on-the-fly.
      */
     if (dict->flags & DICT_FLAG_FOLD_FIX) {
        if (dict->fold_buf == 0)
-           dict->fold_buf = vstring_alloc(10);
+           dict->fold_buf = vstring_alloc(100);
        vstring_strcpy(dict->fold_buf, name);
        name = lowercase(vstring_str(dict->fold_buf));
     }
 
     /*
-     * Domain filter for email address lookups.
+     * Apply the optional domain filter for email address lookups.
      */
     if (db_common_check_domain(dict_sqlite->ctx, name) == 0) {
        if (msg_verbose)
@@ -201,75 +201,95 @@ static const char *dict_sqlite_lookup(DICT *dict, const char *name)
                 myname, dict_sqlite->parser->name, vstring_str(query));
 
     if (sqlite3_prepare_v2(dict_sqlite->db, vstring_str(query), -1,
-                          &sql, &zErrMsg) != SQLITE_OK) {
+                          &sql_stmt, &query_remainder) != SQLITE_OK)
        msg_fatal("%s: %s: SQL prepare failed: %s\n",
                  myname, dict_sqlite->parser->name,
                  sqlite3_errmsg(dict_sqlite->db));
-    }
+
+    if (*query_remainder && msg_verbose)
+       msg_info("%s: %s: Ignoring text at end of query: %s",
+                myname, dict_sqlite->parser->name, query_remainder);
 
     /*
      * Retrieve and expand the result(s).
      */
     INIT_VSTR(result, 10);
-    while ((status = sqlite3_step(sql)) == SQLITE_ROW) {
-       if (db_common_expand(dict_sqlite->ctx, dict_sqlite->result_format,
-                            (char *) 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);
+    while ((status = sqlite3_step(sql_stmt)) != SQLITE_DONE) {
+       if (status == SQLITE_ROW) {
+           if (db_common_expand(dict_sqlite->ctx, dict_sqlite->result_format,
+                                (char *) sqlite3_column_text(sql_stmt, 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;
+           }
+       }
+       /* Fix 20100616 */
+       else {
+           msg_warn("%s: %s: SQL step failed for query '%s': %s\n",
+                    myname, dict_sqlite->parser->name,
+                    vstring_str(query), sqlite3_errmsg(dict_sqlite->db));
            dict_errno = DICT_ERR_RETRY;
            break;
        }
     }
 
-    /* Fix 20100616 */
-    if (status != SQLITE_ROW && status != SQLITE_DONE) {
-       msg_warn("%s: %s: sql step for %s; %s\n",
-                myname, dict_sqlite->parser->name,
-                vstring_str(query), sqlite3_errmsg(dict_sqlite->db));
-       dict_errno = DICT_ERR_RETRY;
-    }
-
     /*
      * Clean up.
      */
-    if (sqlite3_finalize(sql))
-       msg_fatal("%s: %s: SQL finalize for %s; %s\n",
+    if (sqlite3_finalize(sql_stmt))
+       msg_fatal("%s: %s: SQL finalize failed for query '%s': %s\n",
                  myname, dict_sqlite->parser->name,
                  vstring_str(query), sqlite3_errmsg(dict_sqlite->db));
 
-    r = vstring_str(result);
-    return ((dict_errno == 0 && *r) ? r : 0);
+    return ((dict_errno == 0 && *(retval = vstring_str(result)) != 0) ?
+           retval : 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);
+    /*
+     * Parse the primary configuration parameters, and emulate the legacy
+     * query interface if necessary. This simplifies migration from one SQL
+     * database type to another.
+     */
+    dict_sqlite->parser = cfg_parser_alloc(sqlitecf);
+    dict_sqlite->dbpath = cfg_get_str(dict_sqlite->parser, "dbpath", "", 1, 0);
+    dict_sqlite->query = cfg_get_str(dict_sqlite->parser, "query", NULL, 0, 0);
+    if (dict_sqlite->query == 0) {
+       buf = vstring_alloc(100);
+       db_common_sql_build_query(buf, dict_sqlite->parser);
        dict_sqlite->query = vstring_export(buf);
     }
-    dict_sqlite->expansion_limit = cfg_get_int(p, "expansion_limit", 0, 0, 0);
-    dict_sqlite->ctx = 0;
+    dict_sqlite->result_format =
+       cfg_get_str(dict_sqlite->parser, "result_format", "%s", 1, 0);
+    dict_sqlite->expansion_limit =
+       cfg_get_int(dict_sqlite->parser, "expansion_limit", 0, 0, 0);
 
-    (void) db_common_parse(&dict_sqlite->dict, &dict_sqlite->ctx, dict_sqlite->query, 1);
+    /*
+     * Parse the query / result templates and the optional domain filter.
+     */
+    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(dict_sqlite->parser, dict_sqlite->ctx);
 
-    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);
+    /*
+     * Maps that use substring keys should only be used with the full input
+     * key.
+     */
+    if (db_common_dict_partial(dict_sqlite->ctx))
+       dict_sqlite->dict.flags |= DICT_FLAG_PATTERN;
+    else
+       dict_sqlite->dict.flags |= DICT_FLAG_FIXED;
 }
 
 /* dict_sqlite_open - open sqlite database */
@@ -290,13 +310,13 @@ DICT   *dict_sqlite_open(const char *name, int open_flags, int dict_flags)
     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);
-    }
+    if (sqlite3_open(dict_sqlite->dbpath, &dict_sqlite->db))
+       msg_fatal("%s:%s: Can't open database: %s\n",
+                 DICT_TYPE_SQLITE, name, sqlite3_errmsg(dict_sqlite->db));
+
     return (DICT_DEBUG (&dict_sqlite->dict));
 }
 
index 157cbcea654f34c45905e63e3532db6b6270de90..f7703cd423c781057e3decdb902f3951cbee57df 100644 (file)
@@ -20,7 +20,7 @@
   * Patches change both the patchlevel and the release date. Snapshots have no
   * patchlevel; they change the release date only.
   */
-#define MAIL_RELEASE_DATE      "20100617"
+#define MAIL_RELEASE_DATE      "20100618"
 #define MAIL_VERSION_NUMBER    "2.8"
 
 #ifdef SNAPSHOT