Update all copyright messages to cover 1995 - 2009. Remove tab from exim_checkaccess.src
[exim.git] / src / src / lookups / lf_sqlperform.c
CommitLineData
0a49a7a4 1/* $Cambridge: exim/src/src/lookups/lf_sqlperform.c,v 1.2 2009/11/16 19:50:38 nm4 Exp $ */
b7670459
PH
2
3/*************************************************
4* Exim - an Internet mail transport agent *
5*************************************************/
6
0a49a7a4 7/* Copyright (c) University of Cambridge 1995 - 2009 */
b7670459
PH
8/* See the file NOTICE for conditions of use and distribution. */
9
10
11#include "../exim.h"
12#include "lf_functions.h"
13
14
15
16/*************************************************
17* Call SQL server(s) to run an actual query *
18*************************************************/
19
20/* All the SQL lookups are of the same form, with a list of servers to try
21until one can be accessed. It is now also possible to provide the server data
22as part of the query. This function manages server selection and looping; each
23lookup has its own function for actually performing the lookup.
24
25Arguments:
26 name the lookup name, e.g. "MySQL"
27 optionname the name of the servers option, e.g. "mysql_servers"
28 optserverlist the value of the servers option
29 query the query
30 result where to pass back the result
31 errmsg where to pass back an error message
32 do_cache to be set FALSE if data is changed
33 func the lookup function to call
34
35Returns: the return from the lookup function, or DEFER
36*/
37
38int
39lf_sqlperform(uschar *name, uschar *optionname, uschar *optserverlist,
40 uschar *query, uschar **result, uschar **errmsg, BOOL *do_cache,
41 int(*fn)(uschar *, uschar *, uschar **, uschar **, BOOL *, BOOL *))
42{
43int sep, rc;
44uschar *server;
45uschar *serverlist;
46uschar buffer[512];
47BOOL defer_break = FALSE;
48
49DEBUG(D_lookup) debug_printf("%s query: %s\n", name, query);
50
51/* Handle queries that do not have server information at the start. */
52
53if (Ustrncmp(query, "servers", 7) != 0)
54 {
55 sep = 0;
56 serverlist = optserverlist;
57 while ((server = string_nextinlist(&serverlist, &sep, buffer,
58 sizeof(buffer))) != NULL)
59 {
60 rc = (*fn)(query, server, result, errmsg, &defer_break, do_cache);
61 if (rc != DEFER || defer_break) return rc;
62 }
63 if (optserverlist == NULL)
64 *errmsg = string_sprintf("no %s servers defined (%s option)", name,
65 optionname);
66 }
67
68/* Handle queries that do have server information at the start. */
69
70else
71 {
72 int qsep;
73 uschar *s, *ss;
74 uschar *qserverlist;
75 uschar *qserver;
76 uschar qbuffer[512];
77
78 s = query + 7;
79 while (isspace(*s)) s++;
80 if (*s++ != '=')
81 {
82 *errmsg = string_sprintf("missing = after \"servers\" in %s lookup", name);
83 return DEFER;
84 }
85 while (isspace(*s)) s++;
86
87 ss = Ustrchr(s, ';');
88 if (ss == NULL)
89 {
90 *errmsg = string_sprintf("missing ; after \"servers=\" in %s lookup",
91 name);
92 return DEFER;
93 }
94
95 if (ss == s)
96 {
97 *errmsg = string_sprintf("\"servers=\" defines no servers in \"%s\"",
98 query);
99 return DEFER;
100 }
101
102 qserverlist = string_sprintf("%.*s", ss - s, s);
103 qsep = 0;
104
105 while ((qserver = string_nextinlist(&qserverlist, &qsep, qbuffer,
106 sizeof(qbuffer))) != NULL)
107 {
108 if (Ustrchr(qserver, '/') != NULL)
109 server = qserver;
110 else
111 {
112 int len = Ustrlen(qserver);
113
114 sep = 0;
115 serverlist = optserverlist;
116 while ((server = string_nextinlist(&serverlist, &sep, buffer,
117 sizeof(buffer))) != NULL)
118 {
119 if (Ustrncmp(server, qserver, len) == 0 && server[len] == '/')
120 break;
121 }
122
123 if (server == NULL)
124 {
125 *errmsg = string_sprintf("%s server \"%s\" not found in %s", name,
126 qserver, optionname);
127 return DEFER;
128 }
129 }
130
131 rc = (*fn)(ss+1, server, result, errmsg, &defer_break, do_cache);
132 if (rc != DEFER || defer_break) return rc;
133 }
134 }
135
136return DEFER;
137}
138
139/* End of lf_sqlperform.c */