Add BIND 9.2.4rc7.
[dragonfly.git] / contrib / bind-9.2.4rc7 / lib / lwres / getrrset.c
blobfe3dd855a76b05033eb3ca14c4d38ab9fe2be20f
1 /*
2 * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2000-2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
18 /* $Id: getrrset.c,v 1.11.2.5 2004/03/09 06:12:33 marka Exp $ */
20 #include <config.h>
22 #include <string.h>
23 #include <errno.h>
24 #include <stdlib.h>
26 #include <lwres/lwres.h>
27 #include <lwres/net.h>
28 #include <lwres/netdb.h> /* XXX #include <netdb.h> */
30 #include "assert_p.h"
32 static unsigned int
33 lwresult_to_result(lwres_result_t lwresult) {
34 switch (lwresult) {
35 case LWRES_R_SUCCESS: return (ERRSET_SUCCESS);
36 case LWRES_R_NOMEMORY: return (ERRSET_NOMEMORY);
37 case LWRES_R_NOTFOUND: return (ERRSET_NONAME);
38 case LWRES_R_TYPENOTFOUND: return (ERRSET_NODATA);
39 default: return (ERRSET_FAIL);
44 * malloc / calloc functions that guarantee to only
45 * return NULL if there is an error, like they used
46 * to before the ANSI C committee broke them.
49 static void *
50 sane_malloc(size_t size) {
51 if (size == 0U)
52 size = 1;
53 return (malloc(size));
56 static void *
57 sane_calloc(size_t number, size_t size) {
58 size_t len = number * size;
59 void *mem = sane_malloc(len);
60 if (mem != NULL)
61 memset(mem, 0, len);
62 return (mem);
65 int
66 lwres_getrrsetbyname(const char *hostname, unsigned int rdclass,
67 unsigned int rdtype, unsigned int flags,
68 struct rrsetinfo **res)
70 lwres_context_t *lwrctx = NULL;
71 lwres_result_t lwresult;
72 lwres_grbnresponse_t *response = NULL;
73 struct rrsetinfo *rrset = NULL;
74 unsigned int i;
75 unsigned int lwflags;
76 unsigned int result;
78 if (rdclass > 0xffff || rdtype > 0xffff) {
79 result = ERRSET_INVAL;
80 goto fail;
84 * Don't allow queries of class or type ANY
86 if (rdclass == 0xff || rdtype == 0xff) {
87 result = ERRSET_INVAL;
88 goto fail;
91 lwresult = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0);
92 if (lwresult != LWRES_R_SUCCESS) {
93 result = lwresult_to_result(lwresult);
94 goto fail;
96 (void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
99 * If any input flags were defined, lwflags would be set here
100 * based on them
102 UNUSED(flags);
103 lwflags = 0;
105 lwresult = lwres_getrdatabyname(lwrctx, hostname,
106 (lwres_uint16_t)rdclass,
107 (lwres_uint16_t)rdtype,
108 lwflags, &response);
109 if (lwresult != LWRES_R_SUCCESS) {
110 result = lwresult_to_result(lwresult);
111 goto fail;
114 rrset = sane_malloc(sizeof(struct rrsetinfo));
115 if (rrset == NULL) {
116 result = ERRSET_NOMEMORY;
117 goto fail;
119 rrset->rri_name = NULL;
120 rrset->rri_rdclass = response->rdclass;
121 rrset->rri_rdtype = response->rdtype;
122 rrset->rri_ttl = response->ttl;
123 rrset->rri_flags = 0;
124 rrset->rri_nrdatas = 0;
125 rrset->rri_rdatas = NULL;
126 rrset->rri_nsigs = 0;
127 rrset->rri_sigs = NULL;
129 rrset->rri_name = sane_malloc(response->realnamelen + 1);
130 if (rrset->rri_name == NULL) {
131 result = ERRSET_NOMEMORY;
132 goto fail;
134 strncpy(rrset->rri_name, response->realname, response->realnamelen);
135 rrset->rri_name[response->realnamelen] = 0;
137 if ((response->flags & LWRDATA_VALIDATED) != 0)
138 rrset->rri_flags |= RRSET_VALIDATED;
140 rrset->rri_nrdatas = response->nrdatas;
141 rrset->rri_rdatas = sane_calloc(rrset->rri_nrdatas,
142 sizeof(struct rdatainfo));
143 if (rrset->rri_rdatas == NULL) {
144 result = ERRSET_NOMEMORY;
145 goto fail;
147 for (i = 0; i < rrset->rri_nrdatas; i++) {
148 rrset->rri_rdatas[i].rdi_length = response->rdatalen[i];
149 rrset->rri_rdatas[i].rdi_data =
150 sane_malloc(rrset->rri_rdatas[i].rdi_length);
151 if (rrset->rri_rdatas[i].rdi_data == NULL) {
152 result = ERRSET_NOMEMORY;
153 goto fail;
155 memcpy(rrset->rri_rdatas[i].rdi_data, response->rdatas[i],
156 rrset->rri_rdatas[i].rdi_length);
158 rrset->rri_nsigs = response->nsigs;
159 rrset->rri_sigs = sane_calloc(rrset->rri_nsigs,
160 sizeof(struct rdatainfo));
161 if (rrset->rri_sigs == NULL) {
162 result = ERRSET_NOMEMORY;
163 goto fail;
165 for (i = 0; i < rrset->rri_nsigs; i++) {
166 rrset->rri_sigs[i].rdi_length = response->siglen[i];
167 rrset->rri_sigs[i].rdi_data =
168 sane_malloc(rrset->rri_sigs[i].rdi_length);
169 if (rrset->rri_sigs[i].rdi_data == NULL) {
170 result = ERRSET_NOMEMORY;
171 goto fail;
173 memcpy(rrset->rri_sigs[i].rdi_data, response->sigs[i],
174 rrset->rri_sigs[i].rdi_length);
177 lwres_grbnresponse_free(lwrctx, &response);
178 lwres_conf_clear(lwrctx);
179 lwres_context_destroy(&lwrctx);
180 *res = rrset;
181 return (ERRSET_SUCCESS);
182 fail:
183 if (rrset != NULL)
184 lwres_freerrset(rrset);
185 if (response != NULL)
186 lwres_grbnresponse_free(lwrctx, &response);
187 if (lwrctx != NULL) {
188 lwres_conf_clear(lwrctx);
189 lwres_context_destroy(&lwrctx);
191 return (result);
194 void
195 lwres_freerrset(struct rrsetinfo *rrset) {
196 unsigned int i;
197 for (i = 0; i < rrset->rri_nrdatas; i++) {
198 if (rrset->rri_rdatas[i].rdi_data == NULL)
199 break;
200 free(rrset->rri_rdatas[i].rdi_data);
202 free(rrset->rri_rdatas);
203 for (i = 0; i < rrset->rri_nsigs; i++) {
204 if (rrset->rri_sigs[i].rdi_data == NULL)
205 break;
206 free(rrset->rri_sigs[i].rdi_data);
208 free(rrset->rri_sigs);
209 free(rrset->rri_name);
210 free(rrset);