1 /* $NetBSD: zone2sqlite.c,v 1.5 2014/12/10 04:37:57 christos Exp $ */
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: zone2sqlite.c,v 1.4 2010/08/16 05:32:44 marka Exp */
25 #include <isc/buffer.h>
27 #include <isc/print.h>
28 #include <isc/result.h>
31 #include <dns/dbiterator.h>
32 #include <isc/entropy.h>
33 #include <dns/fixedname.h>
36 #include <dns/rdata.h>
37 #include <dns/rdataset.h>
38 #include <dns/rdatasetiter.h>
39 #include <dns/rdatatype.h>
40 #include <dns/result.h>
45 #define UNUSED(x) (void)&(x)
49 * Generate an SQLite table from a zone.
52 typedef struct _dbinfo
{
58 dbinfo_t dbi
= { NULL
, NULL
, NULL
};
62 closeandexit(int status
)
65 sqlite3_close(dbi
.db
);
72 check_result(isc_result_t result
, const char *message
)
74 if (result
!= ISC_R_SUCCESS
) {
75 fprintf(stderr
, "%s: %s\n", message
,
76 isc_result_totext(result
));
82 db_connect(dbinfo_t
*dbi
)
84 if (sqlite3_open(dbi
->filename
, &dbi
->db
) == SQLITE_OK
) {
85 return (ISC_R_SUCCESS
);
87 /* a connection is returned even if the open fails */
88 sqlite3_close(dbi
->db
);
90 return (ISC_R_FAILURE
);
95 add_rdata_cb(void *parm
, int cc
, char **cv
, char **cn
)
107 addrdata(dns_name_t
*name
, dns_ttl_t ttl
, dns_rdata_t
*rdata
)
109 unsigned char namearray
[DNS_NAME_MAXTEXT
+ 1];
110 unsigned char typearray
[20];
111 unsigned char dataarray
[2048];
118 isc_buffer_init(&b
, namearray
, sizeof(namearray
) - 1);
119 result
= dns_name_totext(name
, ISC_TRUE
, &b
);
120 check_result(result
, "dns_name_totext");
121 namearray
[isc_buffer_usedlength(&b
)] = 0;
123 isc_buffer_init(&b
, typearray
, sizeof(typearray
) - 1);
124 result
= dns_rdatatype_totext(rdata
->type
, &b
);
125 check_result(result
, "dns_rdatatype_totext");
126 typearray
[isc_buffer_usedlength(&b
)] = 0;
128 isc_buffer_init(&b
, dataarray
, sizeof(dataarray
) - 1);
129 result
= dns_rdata_totext(rdata
, NULL
, &b
);
130 check_result(result
, "dns_rdata_totext");
131 dataarray
[isc_buffer_usedlength(&b
)] = 0;
133 sql
= sqlite3_mprintf(
134 "INSERT INTO %Q (NAME, TTL, RDTYPE, RDATA)"
135 " VALUES ('%q', %d, '%q', '%q') ",
137 namearray
, ttl
, typearray
, dataarray
);
139 res
= sqlite3_exec(dbi
.db
, sql
, add_rdata_cb
, NULL
, &errmsg
);
142 if (res
!= SQLITE_OK
) {
143 fprintf(stderr
, "INSERT failed: %s\n", errmsg
);
149 main(int argc
, char *argv
[])
154 char *porigin
, *zonefile
;
155 dns_fixedname_t forigin
, fname
;
156 dns_name_t
*origin
, *name
;
158 dns_dbiterator_t
*dbiter
;
160 dns_rdatasetiter_t
*rdsiter
;
161 dns_rdataset_t rdataset
;
162 dns_rdata_t rdata
= DNS_RDATA_INIT
;
163 isc_mem_t
*mctx
= NULL
;
164 isc_entropy_t
*ectx
= NULL
;
169 printf("usage: %s <zone> <zonefile> <dbfile> <dbtable>\n", argv
[0]);
176 dbi
.filename
= argv
[3];
179 dns_result_register();
181 result
= isc_mem_create(0, 0, &mctx
);
182 check_result(result
, "isc_mem_create");
183 result
= isc_entropy_create(mctx
, &ectx
);
184 check_result(result
, "isc_entropy_create");
185 result
= isc_hash_create(mctx
, ectx
, DNS_NAME_MAXWIRE
);
186 check_result(result
, "isc_hash_create");
188 isc_buffer_init(&b
, porigin
, strlen(porigin
));
189 isc_buffer_add(&b
, strlen(porigin
));
190 dns_fixedname_init(&forigin
);
191 origin
= dns_fixedname_name(&forigin
);
192 result
= dns_name_fromtext(origin
, &b
, dns_rootname
, 0, NULL
);
193 check_result(result
, "dns_name_fromtext");
196 result
= dns_db_create(mctx
, "rbt", origin
, dns_dbtype_zone
,
197 dns_rdataclass_in
, 0, NULL
, &db
);
198 check_result(result
, "dns_db_create");
200 result
= dns_db_load(db
, zonefile
);
201 if (result
== DNS_R_SEENINCLUDE
)
202 result
= ISC_R_SUCCESS
;
203 check_result(result
, "dns_db_load");
205 printf("Connecting to '%s'\n", dbi
.filename
);
207 if ((result
= db_connect(&dbi
)) != ISC_R_SUCCESS
) {
208 fprintf(stderr
, "Connection to database '%s' failed\n",
213 sql
= sqlite3_mprintf("DROP TABLE %Q ", dbi
.table
);
215 res
= sqlite3_exec(dbi
.db
, sql
, NULL
, NULL
, &errmsg
);
218 if (res
!= SQLITE_OK
) {
219 fprintf(stderr
, "DROP TABLE %s failed: %s\n",
225 sql
= sqlite3_mprintf(sql
, "BEGIN TRANSACTION");
227 res
= sqlite3_exec(dbi
.db
, sql
, NULL
, NULL
, &errmsg
);
229 if (res
!= SQLITE_OK
) {
230 fprintf(stderr
, "BEGIN TRANSACTION failed: %s\n", errmsg
);
235 sql
= sqlite3_mprintf(
237 "(NAME TEXT, TTL INTEGER, RDTYPE TEXT, RDATA TEXT) ",
240 res
= sqlite3_exec(dbi
.db
, sql
, NULL
, NULL
, &errmsg
);
242 if (res
!= SQLITE_OK
) {
243 fprintf(stderr
, "CREATE TABLE %s failed: %s\n",
249 result
= dns_db_createiterator(db
, 0, &dbiter
);
250 check_result(result
, "dns_db_createiterator()");
252 result
= dns_dbiterator_first(dbiter
);
253 check_result(result
, "dns_dbiterator_first");
255 dns_fixedname_init(&fname
);
256 name
= dns_fixedname_name(&fname
);
257 dns_rdataset_init(&rdataset
);
258 dns_rdata_init(&rdata
);
260 while (result
== ISC_R_SUCCESS
) {
262 result
= dns_dbiterator_current(dbiter
, &node
, name
);
263 if (result
== ISC_R_NOMORE
)
265 check_result(result
, "dns_dbiterator_current");
268 result
= dns_db_allrdatasets(db
, node
, NULL
, 0, &rdsiter
);
269 check_result(result
, "dns_db_allrdatasets");
271 result
= dns_rdatasetiter_first(rdsiter
);
273 while (result
== ISC_R_SUCCESS
) {
274 dns_rdatasetiter_current(rdsiter
, &rdataset
);
275 result
= dns_rdataset_first(&rdataset
);
276 check_result(result
, "dns_rdataset_first");
277 while (result
== ISC_R_SUCCESS
) {
278 dns_rdataset_current(&rdataset
, &rdata
);
279 addrdata(name
, rdataset
.ttl
, &rdata
);
280 dns_rdata_reset(&rdata
);
281 result
= dns_rdataset_next(&rdataset
);
283 dns_rdataset_disassociate(&rdataset
);
284 result
= dns_rdatasetiter_next(rdsiter
);
286 dns_rdatasetiter_destroy(&rdsiter
);
287 dns_db_detachnode(db
, &node
);
288 result
= dns_dbiterator_next(dbiter
);
292 sql
= sqlite3_mprintf(sql
, "COMMIT TRANSACTION ");
294 res
= sqlite3_exec(dbi
.db
, sql
, NULL
, NULL
, &errmsg
);
296 if (res
!= SQLITE_OK
) {
297 fprintf(stderr
, "COMMIT TRANSACTION failed: %s\n", errmsg
);
302 dns_dbiterator_destroy(&dbiter
);
305 isc_entropy_detach(&ectx
);
306 isc_mem_destroy(&mctx
);