1/* 2 * Copyright (C) 2007 Internet Software Consortium. 3 * 4 * Permission to use, copy, modify, and distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM 9 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL 10 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL 11 * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, 12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING 13 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 14 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 15 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18/* $Id: zone2sqlite.c,v 1.4 2010/08/16 05:32:44 marka Exp $ */ 19 20#include <stdlib.h> 21#include <string.h> 22 23#include <isc/buffer.h> 24#include <isc/mem.h> 25#include <isc/print.h> 26#include <isc/result.h> 27 28#include <dns/db.h> 29#include <dns/dbiterator.h> 30#include <isc/entropy.h> 31#include <dns/fixedname.h> 32#include <isc/hash.h> 33#include <dns/name.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> 39 40#include <sqlite3.h> 41 42#ifndef UNUSED 43#define UNUSED(x) (x) = (x) 44#endif 45 46/* 47 * Generate an SQLite table from a zone. 48 */ 49 50typedef struct _dbinfo { 51 sqlite3 *db; 52 char *filename; 53 char *table; 54} dbinfo_t; 55 56dbinfo_t dbi = { NULL, NULL, NULL }; 57 58 59static void 60closeandexit(int status) 61{ 62 if (dbi.db) { 63 sqlite3_close(dbi.db); 64 dbi.db = NULL; 65 } 66 exit(status); 67} 68 69static void 70check_result(isc_result_t result, const char *message) 71{ 72 if (result != ISC_R_SUCCESS) { 73 fprintf(stderr, "%s: %s\n", message, 74 isc_result_totext(result)); 75 closeandexit(1); 76 } 77} 78 79static isc_result_t 80db_connect(dbinfo_t *dbi) 81{ 82 if (sqlite3_open(dbi->filename, &dbi->db) == SQLITE_OK) { 83 return (ISC_R_SUCCESS); 84 } else { 85 /* a connection is returned even if the open fails */ 86 sqlite3_close(dbi->db); 87 dbi->db = NULL; 88 return (ISC_R_FAILURE); 89 } 90} 91 92static int 93add_rdata_cb(void *parm, int cc, char **cv, char **cn) 94{ 95 UNUSED(parm); 96 UNUSED(cc); 97 UNUSED(cv); 98 UNUSED(cn); 99 100 return 0; 101} 102 103 104static void 105addrdata(dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata) 106{ 107 unsigned char namearray[DNS_NAME_MAXTEXT + 1]; 108 unsigned char typearray[20]; 109 unsigned char dataarray[2048]; 110 isc_buffer_t b; 111 isc_result_t result; 112 char *sql; 113 char *errmsg = NULL; 114 int res; 115 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; 120 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; 125 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; 130 131 sql = sqlite3_mprintf( 132 "INSERT INTO %q (NAME, TTL, RDTYPE, RDATA)" 133 " VALUES ('%q', %d, '%q', '%q') ", 134 dbi.table, 135 namearray, ttl, typearray, dataarray); 136 printf("%s\n", sql); 137 res = sqlite3_exec(dbi.db, sql, add_rdata_cb, NULL, &errmsg); 138 sqlite3_free(sql); 139 140 if (result != SQLITE_OK) { 141 fprintf(stderr, "INSERT failed: %s\n", errmsg); 142 closeandexit(1); 143 } 144} 145 146int 147main(int argc, char *argv[]) 148{ 149 char *sql; 150 int res; 151 char *errmsg = NULL; 152 char *porigin, *zonefile; 153 dns_fixedname_t forigin, fname; 154 dns_name_t *origin, *name; 155 dns_db_t *db = NULL; 156 dns_dbiterator_t *dbiter; 157 dns_dbnode_t *node; 158 dns_rdatasetiter_t *rdsiter; 159 dns_rdataset_t rdataset; 160 dns_rdata_t rdata = DNS_RDATA_INIT; 161 isc_mem_t *mctx = NULL; 162 isc_entropy_t *ectx = NULL; 163 isc_buffer_t b; 164 isc_result_t result; 165 166 if (argc != 5) { 167 printf("usage: %s <zone> <zonefile> <dbfile> <dbtable>\n", argv[0]); 168 exit(1); 169 } 170 171 porigin = argv[1]; 172 zonefile = argv[2]; 173 174 dbi.filename = argv[3]; 175 dbi.table = argv[4]; 176 177 dns_result_register(); 178 179 result = isc_mem_create(0, 0, &mctx); 180 check_result(result, "isc_mem_create"); 181 result = isc_entropy_create(mctx, &ectx); 182 check_result(result, "isc_entropy_create"); 183 result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); 184 check_result(result, "isc_hash_create"); 185 186 isc_buffer_init(&b, porigin, strlen(porigin)); 187 isc_buffer_add(&b, strlen(porigin)); 188 dns_fixedname_init(&forigin); 189 origin = dns_fixedname_name(&forigin); 190 result = dns_name_fromtext(origin, &b, dns_rootname, 0, NULL); 191 check_result(result, "dns_name_fromtext"); 192 193 db = NULL; 194 result = dns_db_create(mctx, "rbt", origin, dns_dbtype_zone, 195 dns_rdataclass_in, 0, NULL, &db); 196 check_result(result, "dns_db_create"); 197 198 result = dns_db_load(db, zonefile); 199 if (result == DNS_R_SEENINCLUDE) 200 result = ISC_R_SUCCESS; 201 check_result(result, "dns_db_load"); 202 203 printf("Connecting to '%s'\n", dbi.filename); 204 205 if ((result = db_connect(&dbi)) != ISC_R_SUCCESS) { 206 fprintf(stderr, "Connection to database '%s' failed\n", 207 dbi.filename); 208 closeandexit(1); 209 } 210 211 sql = sqlite3_mprintf("DROP TABLE %q ", dbi.table); 212 printf("%s\n", sql); 213 res = sqlite3_exec(dbi.db, sql, NULL, NULL, &errmsg); 214 sqlite3_free(sql); 215#if 0 216 if (res != SQLITE_OK) { 217 fprintf(stderr, "DROP TABLE %s failed: %s\n", 218 dbi.table, errmsg); 219 } 220#endif 221 222#if 0 223 sql = sqlite3_mprintf(sql, "BEGIN TRANSACTION"); 224 printf("%s\n", sql); 225 res = sqlite3_exec(dbi.db, sql, NULL, NULL, &errmsg); 226 sqlite3_free(sql); 227 if (res != SQLITE_OK) { 228 fprintf(stderr, "BEGIN TRANSACTION failed: %s\n", errmsg); 229 closeandexit(1); 230 } 231#endif 232 233 sql = sqlite3_mprintf( 234 "CREATE TABLE %q " 235 "(NAME TEXT, TTL INTEGER, RDTYPE TEXT, RDATA TEXT) ", 236 dbi.table); 237 printf("%s\n", sql); 238 res = sqlite3_exec(dbi.db, sql, NULL, NULL, &errmsg); 239 sqlite3_free(sql); 240 if (res != SQLITE_OK) { 241 fprintf(stderr, "CREATE TABLE %s failed: %s\n", 242 dbi.table, errmsg); 243 closeandexit(1); 244 } 245 246 dbiter = NULL; 247 result = dns_db_createiterator(db, 0, &dbiter); 248 check_result(result, "dns_db_createiterator()"); 249 250 result = dns_dbiterator_first(dbiter); 251 check_result(result, "dns_dbiterator_first"); 252 253 dns_fixedname_init(&fname); 254 name = dns_fixedname_name(&fname); 255 dns_rdataset_init(&rdataset); 256 dns_rdata_init(&rdata); 257 258 while (result == ISC_R_SUCCESS) { 259 node = NULL; 260 result = dns_dbiterator_current(dbiter, &node, name); 261 if (result == ISC_R_NOMORE) 262 break; 263 check_result(result, "dns_dbiterator_current"); 264 265 rdsiter = NULL; 266 result = dns_db_allrdatasets(db, node, NULL, 0, &rdsiter); 267 check_result(result, "dns_db_allrdatasets"); 268 269 result = dns_rdatasetiter_first(rdsiter); 270 271 while (result == ISC_R_SUCCESS) { 272 dns_rdatasetiter_current(rdsiter, &rdataset); 273 result = dns_rdataset_first(&rdataset); 274 check_result(result, "dns_rdataset_first"); 275 while (result == ISC_R_SUCCESS) { 276 dns_rdataset_current(&rdataset, &rdata); 277 addrdata(name, rdataset.ttl, &rdata); 278 dns_rdata_reset(&rdata); 279 result = dns_rdataset_next(&rdataset); 280 } 281 dns_rdataset_disassociate(&rdataset); 282 result = dns_rdatasetiter_next(rdsiter); 283 } 284 dns_rdatasetiter_destroy(&rdsiter); 285 dns_db_detachnode(db, &node); 286 result = dns_dbiterator_next(dbiter); 287 } 288 289#if 0 290 sql = sqlite3_mprintf(sql, "COMMIT TRANSACTION "); 291 printf("%s\n", sql); 292 res = sqlite3_exec(dbi.db, sql, NULL, NULL, &errmsg); 293 sqlite3_free(sql); 294 if (res != SQLITE_OK) { 295 fprintf(stderr, "COMMIT TRANSACTION failed: %s\n", errmsg); 296 closeandexit(1); 297 } 298#endif 299 300 dns_dbiterator_destroy(&dbiter); 301 dns_db_detach(&db); 302 isc_hash_destroy(); 303 isc_entropy_detach(&ectx); 304 isc_mem_destroy(&mctx); 305 306 closeandexit(0); 307 308 exit(0); 309} 310