Remove building with NOCRYPTO option
[minix.git] / external / bsd / bind / dist / contrib / sdb / sqlite / sqlitedb.c
blob90747b144c350bfeefb276c82d51c9b28be4e3a4
1 /* $NetBSD: sqlitedb.c,v 1.4 2014/12/10 04:37:57 christos Exp $ */
3 /*
4 * Copyright (C) 2007 Internet Software Consortium.
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
11 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
12 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
13 * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
15 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
16 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
17 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 /* Id: sqlitedb.c,v 1.2 2011/10/11 00:09:02 each Exp */
22 #include <config.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <unistd.h>
29 #include <sqlite3.h>
31 #include <isc/mem.h>
32 #include <isc/print.h>
33 #include <isc/result.h>
34 #include <isc/util.h>
36 #include <dns/sdb.h>
37 #include <dns/result.h>
39 #include <named/globals.h>
41 #include "sqlitedb.h"
44 * A simple database driver that interfaces to a SQLite database.
46 * The table must contain the fields "name", "rdtype", and "rdata", and
47 * is expected to contain a properly constructed zone. The program "zonetodb"
48 * creates such a table.
51 static dns_sdbimplementation_t *sqlitedb = NULL;
53 typedef struct _dbinfo {
54 sqlite3 *db;
55 char *filename;
56 char *table;
57 } dbinfo_t;
60 static isc_result_t
61 db_connect(dbinfo_t *dbi)
63 if (sqlite3_open(dbi->filename, &dbi->db) == SQLITE_OK) {
64 return (ISC_R_SUCCESS);
65 } else {
66 /* a connection is returned even if the open fails */
67 sqlite3_close(dbi->db);
68 dbi->db = NULL;
69 return (ISC_R_FAILURE);
74 typedef struct _lookup_parm_t {
75 int i;
76 dns_sdblookup_t *lookup;
77 isc_result_t result;
78 } lookup_parm_t;
81 static int
82 sqlitedb_lookup_cb(void *p, int cc, char **cv, char **cn)
84 lookup_parm_t *parm = p;
85 dns_ttl_t ttl;
86 char *endp;
88 /* FIXME - check these(num/names); I'm assuming a mapping for now */
89 char *ttlstr = cv[0];
90 char *type = cv[1];
91 char *data = cv[2];
93 UNUSED(cc);
94 UNUSED(cn);
96 ttl = strtol(ttlstr, &endp, 10);
97 if (*endp) {
98 parm->result = DNS_R_BADTTL;
99 return 1;
102 parm->result = dns_sdb_putrr(parm->lookup, type, ttl, data);
104 if (parm->result != ISC_R_SUCCESS)
105 return 1;
107 (parm->i)++;
109 return 0;
113 #ifdef DNS_CLIENTINFO_VERSION
114 static isc_result_t
115 sqlitedb_lookup(const char *zone, const char *name, void *dbdata,
116 dns_sdblookup_t *lookup, dns_clientinfomethods_t *methods,
117 dns_clientinfo_t *clientinfo)
118 #else
119 static isc_result_t
120 sqlitedb_lookup(const char *zone, const char *name, void *dbdata,
121 dns_sdblookup_t *lookup)
122 #endif /* DNS_CLIENTINFO_VERSION */
124 * synchronous absolute name lookup
127 dbinfo_t *dbi = (dbinfo_t *) dbdata;
128 char *sql;
129 lookup_parm_t parm = { 0, lookup, ISC_R_SUCCESS };
130 char *errmsg = NULL;
131 int result;
133 UNUSED(zone);
134 #ifdef DNS_CLIENTINFO_VERSION
135 UNUSED(methods);
136 UNUSED(clientinfo);
137 #endif /* DNS_CLIENTINFO_VERSION */
139 sql = sqlite3_mprintf(
140 "SELECT TTL,RDTYPE,RDATA FROM \"%q\" WHERE "
141 "lower(NAME) = lower('%q')",
142 dbi->table, name);
144 result = sqlite3_exec(dbi->db, sql,
145 &sqlitedb_lookup_cb, &parm,
146 &errmsg);
147 sqlite3_free(sql);
149 if (result != SQLITE_OK)
150 return (ISC_R_FAILURE);
151 if (parm.i == 0)
152 return (ISC_R_NOTFOUND);
154 return (ISC_R_SUCCESS);
158 typedef struct _allnodes_parm_t {
159 int i;
160 dns_sdballnodes_t *allnodes;
161 isc_result_t result;
162 } allnodes_parm_t;
165 static int
166 sqlitedb_allnodes_cb(void *p, int cc, char **cv, char **cn)
168 allnodes_parm_t *parm = p;
169 dns_ttl_t ttl;
170 char *endp;
172 /* FIXME - check these(num/names); I'm assuming a mapping for now */
173 char *ttlstr = cv[0];
174 char *name = cv[1];
175 char *type = cv[2];
176 char *data = cv[3];
178 UNUSED(cc);
179 UNUSED(cn);
181 ttl = strtol(ttlstr, &endp, 10);
182 if (*endp) {
183 parm->result = DNS_R_BADTTL;
184 return 1;
187 parm->result = dns_sdb_putnamedrr(parm->allnodes, name, type, ttl, data);
189 if (parm->result != ISC_R_SUCCESS)
190 return 1;
192 (parm->i)++;
194 return 0;
198 static isc_result_t
199 sqlitedb_allnodes(const char *zone,
200 void *dbdata,
201 dns_sdballnodes_t *allnodes)
203 dbinfo_t *dbi = (dbinfo_t *) dbdata;
204 char *sql;
205 allnodes_parm_t parm = { 0, allnodes, ISC_R_SUCCESS };
206 char *errmsg = NULL;
207 int result;
209 UNUSED(zone);
211 sql = sqlite3_mprintf(
212 "SELECT TTL,NAME,RDTYPE,RDATA FROM \"%q\" ORDER BY NAME",
213 dbi->table);
215 result = sqlite3_exec(dbi->db, sql,
216 &sqlitedb_allnodes_cb, &parm,
217 &errmsg);
218 sqlite3_free(sql);
220 if (result != SQLITE_OK)
221 return (ISC_R_FAILURE);
222 if (parm.i == 0)
223 return (ISC_R_NOTFOUND);
225 return (ISC_R_SUCCESS);
229 static void
230 sqlitedb_destroy(const char *zone, void *driverdata, void **dbdata)
232 dbinfo_t *dbi = *dbdata;
234 UNUSED(zone);
235 UNUSED(driverdata);
237 if (dbi->db != NULL)
238 sqlite3_close(dbi->db);
239 if (dbi->table != NULL)
240 isc_mem_free(ns_g_mctx, dbi->table);
241 if (dbi->filename != NULL)
242 isc_mem_free(ns_g_mctx, dbi->filename);
244 isc_mem_put(ns_g_mctx, dbi, sizeof(dbinfo_t));
248 #define STRDUP_OR_FAIL(target, source) \
249 do { \
250 target = isc_mem_strdup(ns_g_mctx, source); \
251 if (target == NULL) { \
252 result = ISC_R_NOMEMORY; \
253 goto cleanup; \
255 } while (/*CONSTCOND*/0);
258 * Create a connection to the database and save any necessary information
259 * in dbdata.
261 * argv[0] is the name of the database file
262 * argv[1] is the name of the table
264 static isc_result_t
265 sqlitedb_create(const char *zone,
266 int argc, char **argv,
267 void *driverdata, void **dbdata)
269 dbinfo_t *dbi;
270 isc_result_t result;
272 UNUSED(zone);
273 UNUSED(driverdata);
275 if (argc < 2)
276 return (ISC_R_FAILURE);
278 dbi = isc_mem_get(ns_g_mctx, sizeof(dbinfo_t));
279 if (dbi == NULL)
280 return (ISC_R_NOMEMORY);
281 dbi->db = NULL;
282 dbi->filename = NULL;
283 dbi->table = NULL;
285 STRDUP_OR_FAIL(dbi->filename, argv[0]);
286 STRDUP_OR_FAIL(dbi->table, argv[1]);
288 result = db_connect(dbi);
289 if (result != ISC_R_SUCCESS)
290 goto cleanup;
292 *dbdata = dbi;
293 return (ISC_R_SUCCESS);
295 cleanup:
296 sqlitedb_destroy(zone, driverdata, (void **)&dbi);
297 return (result);
302 * Since the SQL database corresponds to a zone, the authority data should
303 * be returned by the lookup() function. Therefore the authority() function
304 * is NULL.
306 static dns_sdbmethods_t sqlitedb_methods = {
307 sqlitedb_lookup,
308 NULL, /* authority */
309 sqlitedb_allnodes,
310 sqlitedb_create,
311 sqlitedb_destroy,
312 NULL /* lookup2 */
317 * Wrapper around dns_sdb_register().
319 isc_result_t
320 sqlitedb_init(void)
322 unsigned int flags;
323 flags = 0;
324 return (dns_sdb_register("sqlite", &sqlitedb_methods, NULL, flags,
325 ns_g_mctx, &sqlitedb));
330 * Wrapper around dns_sdb_unregister().
332 void
333 sqlitedb_clear(void)
335 if (sqlitedb != NULL)
336 dns_sdb_unregister(&sqlitedb);