diff options
author | Philip Hazel <ph10@hermes.cam.ac.uk> | 2007-08-23 10:16:51 +0000 |
---|---|---|
committer | Philip Hazel <ph10@hermes.cam.ac.uk> | 2007-08-23 10:16:51 +0000 |
commit | b7670459b9549ad6dcca2398580165e54b09b92d (patch) | |
tree | a697ce1627742155665310463145ff9f0bda9edb /src | |
parent | 48ed62d9a68c4e44c9fbaa6e300f88401bb32d65 (diff) |
Add "server=" feature to MySQL and PostgreSQL lookups.
Diffstat (limited to 'src')
-rwxr-xr-x | src/scripts/MakeLinks | 3 | ||||
-rw-r--r-- | src/src/lookups/Makefile | 5 | ||||
-rw-r--r-- | src/src/lookups/lf_functions.h | 5 | ||||
-rw-r--r-- | src/src/lookups/lf_sqlperform.c | 139 | ||||
-rw-r--r-- | src/src/lookups/mysql.c | 28 | ||||
-rw-r--r-- | src/src/lookups/pgsql.c | 29 |
6 files changed, 160 insertions, 49 deletions
diff --git a/src/scripts/MakeLinks b/src/scripts/MakeLinks index ce125a8dd..c016e50c7 100755 --- a/src/scripts/MakeLinks +++ b/src/scripts/MakeLinks @@ -1,5 +1,5 @@ #!/bin/sh -# $Cambridge: exim/src/scripts/MakeLinks,v 1.11 2007/06/26 11:16:54 ph10 Exp $ +# $Cambridge: exim/src/scripts/MakeLinks,v 1.12 2007/08/23 10:16:51 ph10 Exp $ # Script to build links for all the exim source files from the system- # specific build directory. It should be run from within that directory. @@ -95,6 +95,7 @@ ln -s ../../src/lookups/whoson.c whoson.c ln -s ../../src/lookups/lf_functions.h lf_functions.h ln -s ../../src/lookups/lf_check_file.c lf_check_file.c ln -s ../../src/lookups/lf_quote.c lf_quote.c +ln -s ../../src/lookups/lf_sqlperform.c lf_sqlperform.c cd .. diff --git a/src/src/lookups/Makefile b/src/src/lookups/Makefile index 59237263c..fce944589 100644 --- a/src/src/lookups/Makefile +++ b/src/src/lookups/Makefile @@ -1,4 +1,4 @@ -# $Cambridge: exim/src/src/lookups/Makefile,v 1.5 2005/09/12 13:50:03 ph10 Exp $ +# $Cambridge: exim/src/src/lookups/Makefile,v 1.6 2007/08/23 10:16:51 ph10 Exp $ # Make file for building a library containing all the available lookups and # calling it lookups.a. This is called from the main make file, after cd'ing @@ -7,7 +7,7 @@ OBJ = cdb.o dbmdb.o dnsdb.o dsearch.o ibase.o ldap.o lsearch.o mysql.o nis.o \ nisplus.o oracle.o passwd.o pgsql.o spf.o sqlite.o testdb.o whoson.o \ - lf_check_file.o lf_quote.o + lf_check_file.o lf_quote.o lf_sqlperform.o lookups.a: $(OBJ) @$(RM_COMMAND) -f lookups.a @@ -22,6 +22,7 @@ lookups.a: $(OBJ) lf_check_file.o: $(HDRS) lf_check_file.c lf_functions.h lf_quote.o: $(HDRS) lf_quote.c lf_functions.h +lf_sqlperform.o: $(HDRS) lf_sqlperform.c lf_functions.h cdb.o: $(HDRS) cdb.c cdb.h dbmdb.o: $(HDRS) dbmdb.c dbmdb.h diff --git a/src/src/lookups/lf_functions.h b/src/src/lookups/lf_functions.h index 0cf06a2d7..7e9dec1dd 100644 --- a/src/src/lookups/lf_functions.h +++ b/src/src/lookups/lf_functions.h @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/lookups/lf_functions.h,v 1.4 2007/01/08 10:50:19 ph10 Exp $ */ +/* $Cambridge: exim/src/src/lookups/lf_functions.h,v 1.5 2007/08/23 10:16:51 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -12,5 +12,8 @@ extern int lf_check_file(int, uschar *, int, int, uid_t *, gid_t *, char *, uschar **); extern uschar *lf_quote(uschar *, uschar *, int, uschar *, int *, int *); +extern int lf_sqlperform(uschar *, uschar *, uschar *, uschar *, uschar **, + uschar **, BOOL *, int(*)(uschar *, uschar *, uschar **, + uschar **, BOOL *, BOOL *)); /* End of lf_functions.h */ diff --git a/src/src/lookups/lf_sqlperform.c b/src/src/lookups/lf_sqlperform.c new file mode 100644 index 000000000..2d50f70a0 --- /dev/null +++ b/src/src/lookups/lf_sqlperform.c @@ -0,0 +1,139 @@ +/* $Cambridge: exim/src/src/lookups/lf_sqlperform.c,v 1.1 2007/08/23 10:16:51 ph10 Exp $ */ + +/************************************************* +* Exim - an Internet mail transport agent * +*************************************************/ + +/* Copyright (c) University of Cambridge 1995 - 2007 */ +/* See the file NOTICE for conditions of use and distribution. */ + + +#include "../exim.h" +#include "lf_functions.h" + + + +/************************************************* +* Call SQL server(s) to run an actual query * +*************************************************/ + +/* All the SQL lookups are of the same form, with a list of servers to try +until one can be accessed. It is now also possible to provide the server data +as part of the query. This function manages server selection and looping; each +lookup has its own function for actually performing the lookup. + +Arguments: + name the lookup name, e.g. "MySQL" + optionname the name of the servers option, e.g. "mysql_servers" + optserverlist the value of the servers option + query the query + result where to pass back the result + errmsg where to pass back an error message + do_cache to be set FALSE if data is changed + func the lookup function to call + +Returns: the return from the lookup function, or DEFER +*/ + +int +lf_sqlperform(uschar *name, uschar *optionname, uschar *optserverlist, + uschar *query, uschar **result, uschar **errmsg, BOOL *do_cache, + int(*fn)(uschar *, uschar *, uschar **, uschar **, BOOL *, BOOL *)) +{ +int sep, rc; +uschar *server; +uschar *serverlist; +uschar buffer[512]; +BOOL defer_break = FALSE; + +DEBUG(D_lookup) debug_printf("%s query: %s\n", name, query); + +/* Handle queries that do not have server information at the start. */ + +if (Ustrncmp(query, "servers", 7) != 0) + { + sep = 0; + serverlist = optserverlist; + while ((server = string_nextinlist(&serverlist, &sep, buffer, + sizeof(buffer))) != NULL) + { + rc = (*fn)(query, server, result, errmsg, &defer_break, do_cache); + if (rc != DEFER || defer_break) return rc; + } + if (optserverlist == NULL) + *errmsg = string_sprintf("no %s servers defined (%s option)", name, + optionname); + } + +/* Handle queries that do have server information at the start. */ + +else + { + int qsep; + uschar *s, *ss; + uschar *qserverlist; + uschar *qserver; + uschar qbuffer[512]; + + s = query + 7; + while (isspace(*s)) s++; + if (*s++ != '=') + { + *errmsg = string_sprintf("missing = after \"servers\" in %s lookup", name); + return DEFER; + } + while (isspace(*s)) s++; + + ss = Ustrchr(s, ';'); + if (ss == NULL) + { + *errmsg = string_sprintf("missing ; after \"servers=\" in %s lookup", + name); + return DEFER; + } + + if (ss == s) + { + *errmsg = string_sprintf("\"servers=\" defines no servers in \"%s\"", + query); + return DEFER; + } + + qserverlist = string_sprintf("%.*s", ss - s, s); + qsep = 0; + + while ((qserver = string_nextinlist(&qserverlist, &qsep, qbuffer, + sizeof(qbuffer))) != NULL) + { + if (Ustrchr(qserver, '/') != NULL) + server = qserver; + else + { + int len = Ustrlen(qserver); + + sep = 0; + serverlist = optserverlist; + while ((server = string_nextinlist(&serverlist, &sep, buffer, + sizeof(buffer))) != NULL) + { + if (Ustrncmp(server, qserver, len) == 0 && server[len] == '/') + break; + } + + if (server == NULL) + { + *errmsg = string_sprintf("%s server \"%s\" not found in %s", name, + qserver, optionname); + return DEFER; + } + } + + rc = (*fn)(ss+1, server, result, errmsg, &defer_break, do_cache); + if (rc != DEFER || defer_break) return rc; + } + } + +return DEFER; +} + +/* End of lf_sqlperform.c */ diff --git a/src/src/lookups/mysql.c b/src/src/lookups/mysql.c index 56da5f95d..781b09575 100644 --- a/src/src/lookups/mysql.c +++ b/src/src/lookups/mysql.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/lookups/mysql.c,v 1.4 2007/01/08 10:50:19 ph10 Exp $ */ +/* $Cambridge: exim/src/src/lookups/mysql.c,v 1.5 2007/08/23 10:16:51 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -338,32 +338,16 @@ else *************************************************/ /* See local README for interface description. The handle and filename -arguments are not used. Loop through a list of servers while the query is -deferred with a retryable error. */ +arguments are not used. The code to loop through a list of servers while the +query is deferred with a retryable error is now in a separate function that is +shared with other SQL lookups. */ int mysql_find(void *handle, uschar *filename, uschar *query, int length, uschar **result, uschar **errmsg, BOOL *do_cache) { -int sep = 0; -uschar *server; -uschar *list = mysql_servers; -uschar buffer[512]; - -DEBUG(D_lookup) debug_printf("MYSQL query: %s\n", query); - -while ((server = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL) - { - BOOL defer_break = FALSE; - int rc = perform_mysql_search(query, server, result, errmsg, &defer_break, - do_cache); - if (rc != DEFER || defer_break) return rc; - } - -if (mysql_servers == NULL) - *errmsg = US"no MYSQL servers defined (mysql_servers option)"; - -return DEFER; +return lf_sqlperform(US"MySQL", US"mysql_servers", mysql_servers, query, + result, errmsg, do_cache, perform_mysql_search); } diff --git a/src/src/lookups/pgsql.c b/src/src/lookups/pgsql.c index e6e8f70ba..eace0840d 100644 --- a/src/src/lookups/pgsql.c +++ b/src/src/lookups/pgsql.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/lookups/pgsql.c,v 1.9 2007/01/08 10:50:19 ph10 Exp $ */ +/* $Cambridge: exim/src/src/lookups/pgsql.c,v 1.10 2007/08/23 10:16:51 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -410,33 +410,16 @@ else *************************************************/ /* See local README for interface description. The handle and filename -arguments are not used. Loop through a list of servers while the query is -deferred with a retryable error. */ +arguments are not used. The code to loop through a list of servers while the +query is deferred with a retryable error is now in a separate function that is +shared with other SQL lookups. */ int pgsql_find(void *handle, uschar *filename, uschar *query, int length, uschar **result, uschar **errmsg, BOOL *do_cache) { -int sep = 0; -uschar *server; -uschar *list = pgsql_servers; -uschar buffer[512]; - -DEBUG(D_lookup) debug_printf("PGSQL query: %s\n", query); - -while ((server = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) - != NULL) - { - BOOL defer_break = FALSE; - int rc = perform_pgsql_search(query, server, result, errmsg, &defer_break, - do_cache); - if (rc != DEFER || defer_break) return rc; - } - -if (pgsql_servers == NULL) - *errmsg = US"no PGSQL servers defined (pgsql_servers option)"; - -return DEFER; +return lf_sqlperform(US"PostgreSQL", US"pgsql_servers", pgsql_servers, query, + result, errmsg, do_cache, perform_pgsql_search); } |