Remove building with NOCRYPTO option
[minix.git] / external / bsd / bind / dist / contrib / sdb / tcl / tcldb.c
blobad292e938bb11e594be0f60db25571c1550414ad
1 /* $NetBSD: tcldb.c,v 1.4 2014/12/10 04:37:57 christos Exp $ */
3 /*
4 * Copyright (C) 2004, 2007, 2011, 2014 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 2000, 2001 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
20 /* Id: tcldb.c,v 1.12 2011/10/11 23:46:45 tbox Exp */
23 * A simple database driver that calls a Tcl procedure to define
24 * the contents of the DNS namespace. The procedure is loaded
25 * from the file lookup.tcl; look at the comments there for
26 * more information.
29 #include <config.h>
31 #include <string.h>
32 #include <stdlib.h>
33 #include <unistd.h>
34 #include <sys/stat.h>
36 #include <isc/mem.h>
37 #include <isc/print.h>
38 #include <isc/result.h>
39 #include <isc/util.h>
41 #include <dns/log.h>
42 #include <dns/sdb.h>
44 #include <named/globals.h>
46 #include <tcl.h>
48 #include <tcldb.h>
50 #define CHECK(op) \
51 do { result = (op); \
52 if (result != ISC_R_SUCCESS) return (result); \
53 } while (/*CONSTCOND*/0)
55 typedef struct tcldb_driver {
56 isc_mem_t *mctx;
57 Tcl_Interp *interp;
58 } tcldb_driver_t;
60 static tcldb_driver_t *the_driver = NULL;
62 static dns_sdbimplementation_t *tcldb = NULL;
64 static isc_result_t
65 tcldb_driver_create(isc_mem_t *mctx, tcldb_driver_t **driverp) {
66 int tclres;
67 isc_result_t result = ISC_R_SUCCESS;
68 tcldb_driver_t *driver = isc_mem_get(mctx, sizeof(tcldb_driver_t));
69 if (driver == NULL)
70 return (ISC_R_NOMEMORY);
71 driver->mctx = mctx;
72 driver->interp = Tcl_CreateInterp();
74 tclres = Tcl_EvalFile(driver->interp, (char *) "lookup.tcl");
75 if (tclres != TCL_OK) {
76 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
77 DNS_LOGMODULE_SDB, ISC_LOG_ERROR,
78 "initializing tcldb: "
79 "loading 'lookup.tcl' failed: %s",
80 driver->interp->result);
81 result = ISC_R_FAILURE;
82 goto cleanup;
84 *driverp = driver;
85 return (ISC_R_SUCCESS);
87 cleanup:
88 isc_mem_put(mctx, driver, sizeof(tcldb_driver_t));
89 return (result);
93 static void
94 tcldb_driver_destroy(tcldb_driver_t **driverp) {
95 tcldb_driver_t *driver = *driverp;
96 Tcl_DeleteInterp(driver->interp);
97 isc_mem_put(driver->mctx, driver, sizeof(tcldb_driver_t));
101 * Perform a lookup, by invoking the Tcl procedure "lookup".
103 #ifdef DNS_CLIENTINFO_VERSION
104 static isc_result_t
105 tcldb_lookup(const char *zone, const char *name, void *dbdata,
106 dns_sdblookup_t *lookup, dns_clientinfomethods_t *methods,
107 dns_clientinfo_t *clientinfo)
108 #else
109 static isc_result_t
110 tcldb_lookup(const char *zone, const char *name, void *dbdata,
111 dns_sdblookup_t *lookup)
112 #endif /* DNS_CLIENTINFO_VERSION */
114 isc_result_t result = ISC_R_SUCCESS;
115 int tclres;
116 int rrc; /* RR count */
117 char **rrv; /* RR vector */
118 int i;
119 char *cmdv[3];
120 char *cmd;
122 #ifdef DNS_CLIENTINFO_VERSION
123 UNUSED(methods);
124 UNUSED(clientinfo);
125 #endif /* DNS_CLIENTINFO_VERSION */
127 tcldb_driver_t *driver = (tcldb_driver_t *) dbdata;
129 cmdv[0] = "lookup";
130 cmdv[1] = zone;
131 cmdv[2] = name;
132 cmd = Tcl_Merge(3, cmdv);
133 tclres = Tcl_Eval(driver->interp, cmd);
134 Tcl_Free(cmd);
136 if (tclres != TCL_OK) {
137 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
138 DNS_LOGMODULE_SDB, ISC_LOG_ERROR,
139 "zone '%s': tcl lookup function failed: %s",
140 zone, driver->interp->result);
141 return (ISC_R_FAILURE);
144 if (strcmp(driver->interp->result, "NXDOMAIN") == 0) {
145 result = ISC_R_NOTFOUND;
146 goto fail;
149 tclres = Tcl_SplitList(driver->interp, driver->interp->result,
150 &rrc, &rrv);
151 if (tclres != TCL_OK)
152 goto malformed;
154 for (i = 0; i < rrc; i++) {
155 isc_result_t tmpres;
156 int fieldc; /* Field count */
157 char **fieldv; /* Field vector */
158 tclres = Tcl_SplitList(driver->interp, rrv[i],
159 &fieldc, &fieldv);
160 if (tclres != TCL_OK) {
161 tmpres = ISC_R_FAILURE;
162 goto failrr;
164 if (fieldc != 3)
165 goto malformed;
166 tmpres = dns_sdb_putrr(lookup, fieldv[0], atoi(fieldv[1]),
167 fieldv[2]);
168 Tcl_Free((char *) fieldv);
169 failrr:
170 if (tmpres != ISC_R_SUCCESS)
171 result = tmpres;
173 Tcl_Free((char *) rrv);
174 if (result == ISC_R_SUCCESS)
175 return (result);
177 malformed:
178 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
179 DNS_LOGMODULE_SDB, ISC_LOG_ERROR,
180 "zone '%s': "
181 "malformed return value from tcl lookup function: %s",
182 zone, driver->interp->result);
183 result = ISC_R_FAILURE;
184 fail:
185 return (result);
189 * Set up per-zone state. In our case, the database arguments of the
190 * zone are collected into a Tcl list and assigned to an element of
191 * the global array "dbargs".
193 static isc_result_t
194 tcldb_create(const char *zone, int argc, char **argv,
195 void *driverdata, void **dbdata)
197 tcldb_driver_t *driver = (tcldb_driver_t *) driverdata;
199 char *list = Tcl_Merge(argc, argv);
201 Tcl_SetVar2(driver->interp, (char *) "dbargs", (char *) zone, list, 0);
203 Tcl_Free(list);
205 *dbdata = driverdata;
207 return (ISC_R_SUCCESS);
211 * This driver does not support zone transfer, so allnodes() is NULL.
213 static dns_sdbmethods_t tcldb_methods = {
214 tcldb_lookup,
215 NULL, /* authority */
216 NULL, /* allnodes */
217 tcldb_create,
218 NULL, /* destroy */
219 NULL /* lookup2 */
223 * Initialize the tcldb driver.
225 isc_result_t
226 tcldb_init(void) {
227 isc_result_t result;
228 int flags = DNS_SDBFLAG_RELATIVEOWNER | DNS_SDBFLAG_RELATIVERDATA;
230 result = tcldb_driver_create(ns_g_mctx, &the_driver);
231 if (result != ISC_R_SUCCESS)
232 return (result);
234 return (dns_sdb_register("tcl", &tcldb_methods, the_driver, flags,
235 ns_g_mctx, &tcldb));
239 * Wrapper around dns_sdb_unregister().
241 void
242 tcldb_clear(void) {
243 if (tcldb != NULL)
244 dns_sdb_unregister(&tcldb);
245 if (the_driver != NULL)
246 tcldb_driver_destroy(&the_driver);