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.3 2009/09/01 00:22:26 jinmei Exp */
25 #include <isc/buffer.h>
27 #include <isc/print.h>
28 #include <isc/result.h>
31 #include <dns/dbiterator.h>
32 #include <dns/fixedname.h>
34 #include <dns/rdata.h>
35 #include <dns/rdataset.h>
36 #include <dns/rdatasetiter.h>
37 #include <dns/rdatatype.h>
38 #include <dns/result.h>
43 #define UNUSED(x) (x) = (x)
47 * Generate an SQLite table from a zone.
50 typedef struct _dbinfo
{
56 dbinfo_t dbi
= { NULL
, NULL
, NULL
};
60 closeandexit(int status
)
63 sqlite3_close(dbi
.db
);
70 check_result(isc_result_t result
, const char *message
)
72 if (result
!= ISC_R_SUCCESS
) {
73 fprintf(stderr
, "%s: %s\n", message
,
74 isc_result_totext(result
));
80 db_connect(dbinfo_t
*dbi
)
82 if (sqlite3_open(dbi
->filename
, &dbi
->db
) == SQLITE_OK
) {
83 return (ISC_R_SUCCESS
);
85 /* a connection is returned even if the open fails */
86 sqlite3_close(dbi
->db
);
88 return (ISC_R_FAILURE
);
93 add_rdata_cb(void *parm
, int cc
, char **cv
, char **cn
)
105 addrdata(dns_name_t
*name
, dns_ttl_t ttl
, dns_rdata_t
*rdata
)
107 unsigned char namearray
[DNS_NAME_MAXTEXT
+ 1];
108 unsigned char typearray
[20];
109 unsigned char dataarray
[2048];
116 isc_buffer_init(&b
, namearray
, sizeof(namearray
) - 1);
117 result
= dns_name_totext(name
, ISC_TRUE
, &b
);
118 check_result(result
, "dns_name_totext");
119 namearray
[isc_buffer_usedlength(&b
)] = 0;
121 isc_buffer_init(&b
, typearray
, sizeof(typearray
) - 1);
122 result
= dns_rdatatype_totext(rdata
->type
, &b
);
123 check_result(result
, "dns_rdatatype_totext");
124 typearray
[isc_buffer_usedlength(&b
)] = 0;
126 isc_buffer_init(&b
, dataarray
, sizeof(dataarray
) - 1);
127 result
= dns_rdata_totext(rdata
, NULL
, &b
);
128 check_result(result
, "dns_rdata_totext");
129 dataarray
[isc_buffer_usedlength(&b
)] = 0;
131 sql
= sqlite3_mprintf(
132 "INSERT INTO %q (NAME, TTL, RDTYPE, RDATA)"
133 " VALUES ('%q', %d, '%q', '%q') ",
135 namearray
, ttl
, typearray
, dataarray
);
137 res
= sqlite3_exec(dbi
.db
, sql
, add_rdata_cb
, NULL
, &errmsg
);
140 if (result
!= SQLITE_OK
) {
141 fprintf(stderr
, "INSERT failed: %s\n", errmsg
);
147 main(int argc
, char *argv
[])
152 char *porigin
, *zonefile
;
153 dns_fixedname_t forigin
, fname
;
154 dns_name_t
*origin
, *name
;
156 dns_dbiterator_t
*dbiter
;
158 dns_rdatasetiter_t
*rdsiter
;
159 dns_rdataset_t rdataset
;
160 dns_rdata_t rdata
= DNS_RDATA_INIT
;
161 isc_mem_t
*mctx
= NULL
;
166 printf("usage: %s <zone> <zonefile> <dbfile> <dbtable>\n", argv
[0]);
173 dbi
.filename
= argv
[3];
176 dns_result_register();
179 result
= isc_mem_create(0, 0, &mctx
);
180 check_result(result
, "isc_mem_create");
182 isc_buffer_init(&b
, porigin
, strlen(porigin
));
183 isc_buffer_add(&b
, strlen(porigin
));
184 dns_fixedname_init(&forigin
);
185 origin
= dns_fixedname_name(&forigin
);
186 result
= dns_name_fromtext(origin
, &b
, dns_rootname
, 0, NULL
);
187 check_result(result
, "dns_name_fromtext");
190 result
= dns_db_create(mctx
, "rbt", origin
, dns_dbtype_zone
,
191 dns_rdataclass_in
, 0, NULL
, &db
);
192 check_result(result
, "dns_db_create");
194 result
= dns_db_load(db
, zonefile
);
195 if (result
== DNS_R_SEENINCLUDE
)
196 result
= ISC_R_SUCCESS
;
197 check_result(result
, "dns_db_load");
199 printf("Connecting to '%s'\n", dbi
.filename
);
201 if ((result
= db_connect(&dbi
)) != ISC_R_SUCCESS
) {
202 fprintf(stderr
, "Connection to database '%s' failed\n",
207 sql
= sqlite3_mprintf("DROP TABLE %q ", dbi
.table
);
209 res
= sqlite3_exec(dbi
.db
, sql
, NULL
, NULL
, &errmsg
);
212 if (res
!= SQLITE_OK
) {
213 fprintf(stderr
, "DROP TABLE %s failed: %s\n",
219 sql
= sqlite3_mprintf(sql
, "BEGIN TRANSACTION");
221 res
= sqlite3_exec(dbi
.db
, sql
, NULL
, NULL
, &errmsg
);
223 if (res
!= SQLITE_OK
) {
224 fprintf(stderr
, "BEGIN TRANSACTION failed: %s\n", errmsg
);
229 sql
= sqlite3_mprintf(
231 "(NAME TEXT, TTL INTEGER, RDTYPE TEXT, RDATA TEXT) ",
234 res
= sqlite3_exec(dbi
.db
, sql
, NULL
, NULL
, &errmsg
);
236 if (res
!= SQLITE_OK
) {
237 fprintf(stderr
, "CREATE TABLE %s failed: %s\n",
243 result
= dns_db_createiterator(db
, 0, &dbiter
);
244 check_result(result
, "dns_db_createiterator()");
246 result
= dns_dbiterator_first(dbiter
);
247 check_result(result
, "dns_dbiterator_first");
249 dns_fixedname_init(&fname
);
250 name
= dns_fixedname_name(&fname
);
251 dns_rdataset_init(&rdataset
);
252 dns_rdata_init(&rdata
);
254 while (result
== ISC_R_SUCCESS
) {
256 result
= dns_dbiterator_current(dbiter
, &node
, name
);
257 if (result
== ISC_R_NOMORE
)
259 check_result(result
, "dns_dbiterator_current");
262 result
= dns_db_allrdatasets(db
, node
, NULL
, 0, &rdsiter
);
263 check_result(result
, "dns_db_allrdatasets");
265 result
= dns_rdatasetiter_first(rdsiter
);
267 while (result
== ISC_R_SUCCESS
) {
268 dns_rdatasetiter_current(rdsiter
, &rdataset
);
269 result
= dns_rdataset_first(&rdataset
);
270 check_result(result
, "dns_rdataset_first");
271 while (result
== ISC_R_SUCCESS
) {
272 dns_rdataset_current(&rdataset
, &rdata
);
273 addrdata(name
, rdataset
.ttl
, &rdata
);
274 dns_rdata_reset(&rdata
);
275 result
= dns_rdataset_next(&rdataset
);
277 dns_rdataset_disassociate(&rdataset
);
278 result
= dns_rdatasetiter_next(rdsiter
);
280 dns_rdatasetiter_destroy(&rdsiter
);
281 dns_db_detachnode(db
, &node
);
282 result
= dns_dbiterator_next(dbiter
);
286 sql
= sqlite3_mprintf(sql
, "COMMIT TRANSACTION ");
288 res
= sqlite3_exec(dbi
.db
, sql
, NULL
, NULL
, &errmsg
);
290 if (res
!= SQLITE_OK
) {
291 fprintf(stderr
, "COMMIT TRANSACTION failed: %s\n", errmsg
);
296 dns_dbiterator_destroy(&dbiter
);
298 isc_mem_destroy(&mctx
);