PageRenderTime 82ms CodeModel.GetById 69ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 0ms

/contrib/bind9/lib/dns/rriterator.c

https://bitbucket.org/freebsd/freebsd-head/
C | 204 lines | 145 code | 23 blank | 36 comment | 55 complexity | 605c49797c3f21a8d88156a8507503cb MD5 | raw file
  1/*
  2 * Copyright (C) 2009, 2011, 2012  Internet Systems Consortium, Inc. ("ISC")
  3 *
  4 * Permission to use, copy, modify, and/or 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 ISC DISCLAIMS ALL WARRANTIES WITH
  9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 10 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
 11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
 13 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 14 * PERFORMANCE OF THIS SOFTWARE.
 15 */
 16
 17/* $Id$ */
 18
 19/*! \file */
 20
 21/***
 22 *** Imports
 23 ***/
 24
 25#include <config.h>
 26
 27#include <isc/string.h>
 28#include <isc/util.h>
 29
 30#include <dns/db.h>
 31#include <dns/dbiterator.h>
 32#include <dns/rdata.h>
 33#include <dns/rdataset.h>
 34#include <dns/rdatasetiter.h>
 35#include <dns/result.h>
 36#include <dns/rriterator.h>
 37
 38/***
 39 *** RRiterator methods
 40 ***/
 41
 42isc_result_t
 43dns_rriterator_init(dns_rriterator_t *it, dns_db_t *db, dns_dbversion_t *ver,
 44		    isc_stdtime_t now)
 45{
 46	isc_result_t result;
 47	it->magic = RRITERATOR_MAGIC;
 48	it->db = db;
 49	it->dbit = NULL;
 50	it->ver = ver;
 51	it->now = now;
 52	it->node = NULL;
 53	result = dns_db_createiterator(it->db, 0, &it->dbit);
 54	if (result != ISC_R_SUCCESS)
 55		return (result);
 56	it->rdatasetit = NULL;
 57	dns_rdata_init(&it->rdata);
 58	dns_rdataset_init(&it->rdataset);
 59	dns_fixedname_init(&it->fixedname);
 60	INSIST(! dns_rdataset_isassociated(&it->rdataset));
 61	it->result = ISC_R_SUCCESS;
 62	return (it->result);
 63}
 64
 65isc_result_t
 66dns_rriterator_first(dns_rriterator_t *it) {
 67	REQUIRE(VALID_RRITERATOR(it));
 68	/* Reset state */
 69	if (dns_rdataset_isassociated(&it->rdataset))
 70		dns_rdataset_disassociate(&it->rdataset);
 71	if (it->rdatasetit != NULL)
 72		dns_rdatasetiter_destroy(&it->rdatasetit);
 73	if (it->node != NULL)
 74		dns_db_detachnode(it->db, &it->node);
 75	it->result = dns_dbiterator_first(it->dbit);
 76
 77	/*
 78	 * The top node may be empty when out of zone glue exists.
 79	 * Walk the tree to find the first node with data.
 80	 */
 81	while (it->result == ISC_R_SUCCESS) {
 82		it->result = dns_dbiterator_current(it->dbit, &it->node,
 83					   dns_fixedname_name(&it->fixedname));
 84		if (it->result != ISC_R_SUCCESS)
 85			return (it->result);
 86
 87		it->result = dns_db_allrdatasets(it->db, it->node, it->ver,
 88						 it->now, &it->rdatasetit);
 89		if (it->result != ISC_R_SUCCESS)
 90			return (it->result);
 91
 92		it->result = dns_rdatasetiter_first(it->rdatasetit);
 93		if (it->result != ISC_R_SUCCESS) {
 94			/*
 95			 * This node is empty. Try next node.
 96			 */
 97			dns_rdatasetiter_destroy(&it->rdatasetit);
 98			dns_db_detachnode(it->db, &it->node);
 99			it->result = dns_dbiterator_next(it->dbit);
100			continue;
101		}
102		dns_rdatasetiter_current(it->rdatasetit, &it->rdataset);
103		it->rdataset.attributes |= DNS_RDATASETATTR_LOADORDER;
104		it->result = dns_rdataset_first(&it->rdataset);
105		return (it->result);
106	}
107	return (it->result);
108}
109
110isc_result_t
111dns_rriterator_nextrrset(dns_rriterator_t *it) {
112	REQUIRE(VALID_RRITERATOR(it));
113	if (dns_rdataset_isassociated(&it->rdataset))
114		dns_rdataset_disassociate(&it->rdataset);
115	it->result = dns_rdatasetiter_next(it->rdatasetit);
116	/*
117	 * The while loop body is executed more than once
118	 * only when an empty dbnode needs to be skipped.
119	 */
120	while (it->result == ISC_R_NOMORE) {
121		dns_rdatasetiter_destroy(&it->rdatasetit);
122		dns_db_detachnode(it->db, &it->node);
123		it->result = dns_dbiterator_next(it->dbit);
124		if (it->result == ISC_R_NOMORE) {
125			/* We are at the end of the entire database. */
126			return (it->result);
127		}
128		if (it->result != ISC_R_SUCCESS)
129			return (it->result);
130		it->result = dns_dbiterator_current(it->dbit, &it->node,
131					   dns_fixedname_name(&it->fixedname));
132		if (it->result != ISC_R_SUCCESS)
133			return (it->result);
134		it->result = dns_db_allrdatasets(it->db, it->node, it->ver,
135						 it->now, &it->rdatasetit);
136		if (it->result != ISC_R_SUCCESS)
137			return (it->result);
138		it->result = dns_rdatasetiter_first(it->rdatasetit);
139	}
140	if (it->result != ISC_R_SUCCESS)
141		return (it->result);
142	dns_rdatasetiter_current(it->rdatasetit, &it->rdataset);
143	it->rdataset.attributes |= DNS_RDATASETATTR_LOADORDER;
144	it->result = dns_rdataset_first(&it->rdataset);
145	return (it->result);
146}
147
148isc_result_t
149dns_rriterator_next(dns_rriterator_t *it) {
150	REQUIRE(VALID_RRITERATOR(it));
151	if (it->result != ISC_R_SUCCESS)
152		return (it->result);
153
154	INSIST(it->dbit != NULL);
155	INSIST(it->node != NULL);
156	INSIST(it->rdatasetit != NULL);
157
158	it->result = dns_rdataset_next(&it->rdataset);
159	if (it->result == ISC_R_NOMORE)
160		return (dns_rriterator_nextrrset(it));
161	return (it->result);
162}
163
164void
165dns_rriterator_pause(dns_rriterator_t *it) {
166	REQUIRE(VALID_RRITERATOR(it));
167	RUNTIME_CHECK(dns_dbiterator_pause(it->dbit) == ISC_R_SUCCESS);
168}
169
170void
171dns_rriterator_destroy(dns_rriterator_t *it) {
172	REQUIRE(VALID_RRITERATOR(it));
173	if (dns_rdataset_isassociated(&it->rdataset))
174		dns_rdataset_disassociate(&it->rdataset);
175	if (it->rdatasetit != NULL)
176		dns_rdatasetiter_destroy(&it->rdatasetit);
177	if (it->node != NULL)
178		dns_db_detachnode(it->db, &it->node);
179	dns_dbiterator_destroy(&it->dbit);
180}
181
182void
183dns_rriterator_current(dns_rriterator_t *it, dns_name_t **name,
184		       isc_uint32_t *ttl, dns_rdataset_t **rdataset,
185		       dns_rdata_t **rdata)
186{
187	REQUIRE(name != NULL && *name == NULL);
188	REQUIRE(VALID_RRITERATOR(it));
189	REQUIRE(it->result == ISC_R_SUCCESS);
190	REQUIRE(rdataset == NULL || *rdataset == NULL);
191	REQUIRE(rdata == NULL || *rdata == NULL);
192
193	*name = dns_fixedname_name(&it->fixedname);
194	*ttl = it->rdataset.ttl;
195
196	dns_rdata_reset(&it->rdata);
197	dns_rdataset_current(&it->rdataset, &it->rdata);
198
199	if (rdataset != NULL)
200		*rdataset = &it->rdataset;
201
202	if (rdata != NULL)
203		*rdata = &it->rdata;
204}