1/* 2 * Copyright (C) 2002 Nuno M. Rodrigues. 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 NUNO M. RODRIGUES 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: zone2bdb.c,v 1.3 2009/09/01 00:22:26 jinmei Exp $ */ 19 20#include <stdio.h> 21 22#include <isc/mem.h> 23#include <isc/result.h> 24#include <isc/types.h> 25#include <isc/util.h> 26 27#include <dns/db.h> 28#include <dns/dbiterator.h> 29#include <dns/fixedname.h> 30#include <dns/name.h> 31#include <dns/rdata.h> 32#include <dns/rdataset.h> 33#include <dns/rdatasetiter.h> 34#include <dns/rdatatype.h> 35#include <dns/ttl.h> 36#include <dns/types.h> 37 38#include <db.h> 39 40#define MAX_RDATATEXT 63 + 4 + 65535 + 2 /* ttl + type + rdata + sep */ 41 42/* 43 * Returns a valid 'DB' handle. 44 * 45 * Requires: 46 * 'file' is a valid non-existant path. 47 */ 48DB * 49bdb_init(const char *file) 50{ 51 DB *db; 52 53 REQUIRE(db_create(&db, NULL, 0) == 0); 54 REQUIRE(db->set_flags(db, DB_DUP) == 0); 55 REQUIRE(db->open(db, file, NULL, DB_HASH, DB_CREATE | DB_EXCL, 0) == 0); 56 57 return db; 58} 59 60/* 61 * Puts resource record data on 'db'. 62 */ 63isc_result_t 64bdb_putrdata(DB *db, dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata) 65{ 66 static DBT key, data; 67 isc_buffer_t keybuf, databuf; 68 char nametext[DNS_NAME_MAXTEXT]; 69 char rdatatext[MAX_RDATATEXT]; 70 71 isc_buffer_init(&keybuf, nametext, DNS_NAME_MAXTEXT); 72 73 dns_name_totext(name, ISC_TRUE, &keybuf); 74 75 key.data = isc_buffer_base(&keybuf); 76 key.size = isc_buffer_usedlength(&keybuf); 77 78 isc_buffer_init(&databuf, rdatatext, MAX_RDATATEXT); 79 80 dns_ttl_totext(ttl, ISC_FALSE, &databuf); 81 *(char *)isc_buffer_used(&databuf) = ' '; 82 isc_buffer_add(&databuf, 1); 83 84 dns_rdatatype_totext(rdata->type, &databuf); /* XXX private data */ 85 *(char *)isc_buffer_used(&databuf) = ' '; 86 isc_buffer_add(&databuf, 1); 87 88 dns_rdata_totext(rdata, NULL, &databuf); 89 90 data.data = isc_buffer_base(&databuf); 91 data.size = isc_buffer_usedlength(&databuf); 92 93 REQUIRE(db->put(db, NULL, &key, &data, 0) == 0); 94 95 return ISC_R_SUCCESS; 96} 97 98isc_result_t 99bdb_destroy(DB *db) 100{ 101 102 return (db->close(db, 0) == 0) ? ISC_R_SUCCESS : ISC_R_FAILURE; 103} 104 105void 106usage(const char *prog) 107{ 108 109 fprintf(stderr, "Usage: %s <origin> <zonefile> <db>\n", prog); 110 exit(1); 111} 112 113int 114main(int argc, char *argv[]) 115{ 116 isc_mem_t *mctx = NULL; 117 isc_buffer_t b; 118 int n; 119 dns_fixedname_t origin, name; 120 dns_db_t *db = NULL; 121 dns_dbiterator_t *dbiter = NULL; 122 isc_result_t res; 123 dns_dbnode_t *node = NULL; 124 dns_rdataset_t rdataset; 125 dns_rdatasetiter_t *rdatasetiter = NULL; 126 dns_rdata_t rdata; 127 DB *bdb; 128 129 if (argc != 4) usage(*argv); 130 131 REQUIRE(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); 132 133 n = strlen(argv[1]); 134 isc_buffer_init(&b, argv[1], n); 135 isc_buffer_add(&b, n); 136 137 dns_fixedname_init(&origin); 138 139 REQUIRE(dns_name_fromtext(dns_fixedname_name(&origin), &b, dns_rootname, 140 0, NULL) == ISC_R_SUCCESS); 141 REQUIRE(dns_db_create(mctx, "rbt", dns_fixedname_name(&origin), 142 dns_dbtype_zone, dns_rdataclass_in, 0, NULL, 143 &db) == ISC_R_SUCCESS); 144 145 REQUIRE(dns_db_load(db, argv[2]) == ISC_R_SUCCESS); 146 147 REQUIRE(dns_db_createiterator(db, 0, &dbiter) == ISC_R_SUCCESS); 148 149 dns_rdataset_init(&rdataset); 150 dns_rdata_init(&rdata); 151 dns_fixedname_init(&name); 152 bdb = bdb_init(argv[3]); 153 154 for (res = dns_dbiterator_first(dbiter); res == ISC_R_SUCCESS; 155 res = dns_dbiterator_next(dbiter)) { 156 dns_dbiterator_current(dbiter, &node, dns_fixedname_name(&name)); 157 REQUIRE(dns_db_allrdatasets(db, node, NULL, 0, &rdatasetiter) 158 == ISC_R_SUCCESS); 159 160 for (res = dns_rdatasetiter_first(rdatasetiter); 161 res == ISC_R_SUCCESS; 162 res = dns_rdatasetiter_next(rdatasetiter)) { 163 dns_rdatasetiter_current(rdatasetiter, &rdataset); 164 165 res = dns_rdataset_first(&rdataset); 166 while (res == ISC_R_SUCCESS) { 167 dns_rdataset_current(&rdataset, &rdata); 168 REQUIRE(bdb_putrdata(bdb, 169 dns_fixedname_name(&name), 170 rdataset.ttl, &rdata) 171 == ISC_R_SUCCESS); 172 173 dns_rdata_reset(&rdata); 174 res = dns_rdataset_next(&rdataset); 175 } 176 177 dns_rdataset_disassociate(&rdataset); 178 } 179 dns_rdatasetiter_destroy(&rdatasetiter); 180 dns_db_detachnode(db, &node); 181 } 182 dns_dbiterator_destroy(&dbiter); 183 184 REQUIRE(bdb_destroy(bdb) == ISC_R_SUCCESS); 185 186 return 0; 187} 188