Detect FPU by checking CPUID features.
[dragonfly.git] / contrib / bind-9.5.2 / lib / lwres / getrrset.c
blobd8b6cc3fd931d8c35906275cf36af6907d3a160b
1 /*
2 * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2000-2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and/or 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.18 2007/06/19 23:47:22 tbox Exp $ */
20 /*! \file */
22 /**
23 * DESCRIPTION
25 * lwres_getrrsetbyname() gets a set of resource records associated with
26 * a hostname, class, and type. hostname is a pointer a to
27 * null-terminated string. The flags field is currently unused and must
28 * be zero.
30 * After a successful call to lwres_getrrsetbyname(), *res is a pointer
31 * to an #rrsetinfo structure, containing a list of one or more #rdatainfo
32 * structures containing resource records and potentially another list of
33 * rdatainfo structures containing SIG resource records associated with
34 * those records. The members #rri_rdclass and #rri_rdtype are copied from
35 * the parameters. #rri_ttl and #rri_name are properties of the obtained
36 * rrset. The resource records contained in #rri_rdatas and #rri_sigs are
37 * in uncompressed DNS wire format. Properties of the rdataset are
38 * represented in the #rri_flags bitfield. If the #RRSET_VALIDATED bit is
39 * set, the data has been DNSSEC validated and the signatures verified.
41 * All of the information returned by lwres_getrrsetbyname() is
42 * dynamically allocated: the rrsetinfo and rdatainfo structures, and the
43 * canonical host name strings pointed to by the rrsetinfostructure.
44 * Memory allocated for the dynamically allocated structures created by a
45 * successful call to lwres_getrrsetbyname() is released by
46 * lwres_freerrset(). rrset is a pointer to a struct rrset created by a
47 * call to lwres_getrrsetbyname().
49 * The following structures are used:
51 * \code
52 * struct rdatainfo {
53 * unsigned int rdi_length; // length of data
54 * unsigned char *rdi_data; // record data
55 * };
57 * struct rrsetinfo {
58 * unsigned int rri_flags; // RRSET_VALIDATED...
59 * unsigned int rri_rdclass; // class number
60 * unsigned int rri_rdtype; // RR type number
61 * unsigned int rri_ttl; // time to live
62 * unsigned int rri_nrdatas; // size of rdatas array
63 * unsigned int rri_nsigs; // size of sigs array
64 * char *rri_name; // canonical name
65 * struct rdatainfo *rri_rdatas; // individual records
66 * struct rdatainfo *rri_sigs; // individual signatures
67 * };
68 * \endcode
70 * \section getrrset_return Return Values
72 * lwres_getrrsetbyname() returns zero on success, and one of the
73 * following error codes if an error occurred:
75 * \li #ERRSET_NONAME: the name does not exist
77 * \li #ERRSET_NODATA:
78 * the name exists, but does not have data of the desired type
80 * \li #ERRSET_NOMEMORY:
81 * memory could not be allocated
83 * \li #ERRSET_INVAL:
84 * a parameter is invalid
86 * \li #ERRSET_FAIL:
87 * other failure
90 #include <config.h>
92 #include <string.h>
93 #include <errno.h>
94 #include <stdlib.h>
96 #include <lwres/lwres.h>
97 #include <lwres/net.h>
98 #include <lwres/netdb.h> /* XXX #include <netdb.h> */
100 #include "assert_p.h"
103 * Structure to map results
105 static unsigned int
106 lwresult_to_result(lwres_result_t lwresult) {
107 switch (lwresult) {
108 case LWRES_R_SUCCESS: return (ERRSET_SUCCESS);
109 case LWRES_R_NOMEMORY: return (ERRSET_NOMEMORY);
110 case LWRES_R_NOTFOUND: return (ERRSET_NONAME);
111 case LWRES_R_TYPENOTFOUND: return (ERRSET_NODATA);
112 default: return (ERRSET_FAIL);
116 /*@{*/
118 * malloc / calloc functions that guarantee to only
119 * return NULL if there is an error, like they used
120 * to before the ANSI C committee broke them.
123 static void *
124 sane_malloc(size_t size) {
125 if (size == 0U)
126 size = 1;
127 return (malloc(size));
130 static void *
131 sane_calloc(size_t number, size_t size) {
132 size_t len = number * size;
133 void *mem = sane_malloc(len);
134 if (mem != NULL)
135 memset(mem, 0, len);
136 return (mem);
138 /*@}*/
140 /*% Returns a set of resource records associated with a hostname, class, and type. hostname is a pointer a to null-terminated string. */
142 lwres_getrrsetbyname(const char *hostname, unsigned int rdclass,
143 unsigned int rdtype, unsigned int flags,
144 struct rrsetinfo **res)
146 lwres_context_t *lwrctx = NULL;
147 lwres_result_t lwresult;
148 lwres_grbnresponse_t *response = NULL;
149 struct rrsetinfo *rrset = NULL;
150 unsigned int i;
151 unsigned int lwflags;
152 unsigned int result;
154 if (rdclass > 0xffff || rdtype > 0xffff) {
155 result = ERRSET_INVAL;
156 goto fail;
160 * Don't allow queries of class or type ANY
162 if (rdclass == 0xff || rdtype == 0xff) {
163 result = ERRSET_INVAL;
164 goto fail;
167 lwresult = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0);
168 if (lwresult != LWRES_R_SUCCESS) {
169 result = lwresult_to_result(lwresult);
170 goto fail;
172 (void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
175 * If any input flags were defined, lwflags would be set here
176 * based on them
178 UNUSED(flags);
179 lwflags = 0;
181 lwresult = lwres_getrdatabyname(lwrctx, hostname,
182 (lwres_uint16_t)rdclass,
183 (lwres_uint16_t)rdtype,
184 lwflags, &response);
185 if (lwresult != LWRES_R_SUCCESS) {
186 result = lwresult_to_result(lwresult);
187 goto fail;
190 rrset = sane_malloc(sizeof(struct rrsetinfo));
191 if (rrset == NULL) {
192 result = ERRSET_NOMEMORY;
193 goto fail;
195 rrset->rri_name = NULL;
196 rrset->rri_rdclass = response->rdclass;
197 rrset->rri_rdtype = response->rdtype;
198 rrset->rri_ttl = response->ttl;
199 rrset->rri_flags = 0;
200 rrset->rri_nrdatas = 0;
201 rrset->rri_rdatas = NULL;
202 rrset->rri_nsigs = 0;
203 rrset->rri_sigs = NULL;
205 rrset->rri_name = sane_malloc(response->realnamelen + 1);
206 if (rrset->rri_name == NULL) {
207 result = ERRSET_NOMEMORY;
208 goto fail;
210 strncpy(rrset->rri_name, response->realname, response->realnamelen);
211 rrset->rri_name[response->realnamelen] = 0;
213 if ((response->flags & LWRDATA_VALIDATED) != 0)
214 rrset->rri_flags |= RRSET_VALIDATED;
216 rrset->rri_nrdatas = response->nrdatas;
217 rrset->rri_rdatas = sane_calloc(rrset->rri_nrdatas,
218 sizeof(struct rdatainfo));
219 if (rrset->rri_rdatas == NULL) {
220 result = ERRSET_NOMEMORY;
221 goto fail;
223 for (i = 0; i < rrset->rri_nrdatas; i++) {
224 rrset->rri_rdatas[i].rdi_length = response->rdatalen[i];
225 rrset->rri_rdatas[i].rdi_data =
226 sane_malloc(rrset->rri_rdatas[i].rdi_length);
227 if (rrset->rri_rdatas[i].rdi_data == NULL) {
228 result = ERRSET_NOMEMORY;
229 goto fail;
231 memcpy(rrset->rri_rdatas[i].rdi_data, response->rdatas[i],
232 rrset->rri_rdatas[i].rdi_length);
234 rrset->rri_nsigs = response->nsigs;
235 rrset->rri_sigs = sane_calloc(rrset->rri_nsigs,
236 sizeof(struct rdatainfo));
237 if (rrset->rri_sigs == NULL) {
238 result = ERRSET_NOMEMORY;
239 goto fail;
241 for (i = 0; i < rrset->rri_nsigs; i++) {
242 rrset->rri_sigs[i].rdi_length = response->siglen[i];
243 rrset->rri_sigs[i].rdi_data =
244 sane_malloc(rrset->rri_sigs[i].rdi_length);
245 if (rrset->rri_sigs[i].rdi_data == NULL) {
246 result = ERRSET_NOMEMORY;
247 goto fail;
249 memcpy(rrset->rri_sigs[i].rdi_data, response->sigs[i],
250 rrset->rri_sigs[i].rdi_length);
253 lwres_grbnresponse_free(lwrctx, &response);
254 lwres_conf_clear(lwrctx);
255 lwres_context_destroy(&lwrctx);
256 *res = rrset;
257 return (ERRSET_SUCCESS);
258 fail:
259 if (rrset != NULL)
260 lwres_freerrset(rrset);
261 if (response != NULL)
262 lwres_grbnresponse_free(lwrctx, &response);
263 if (lwrctx != NULL) {
264 lwres_conf_clear(lwrctx);
265 lwres_context_destroy(&lwrctx);
267 return (result);
270 /*% Releases memory allocated for the dynamically allocated structures created by a successful call to lwres_getrrsetbyname(). */
271 void
272 lwres_freerrset(struct rrsetinfo *rrset) {
273 unsigned int i;
274 for (i = 0; i < rrset->rri_nrdatas; i++) {
275 if (rrset->rri_rdatas[i].rdi_data == NULL)
276 break;
277 free(rrset->rri_rdatas[i].rdi_data);
279 free(rrset->rri_rdatas);
280 for (i = 0; i < rrset->rri_nsigs; i++) {
281 if (rrset->rri_sigs[i].rdi_data == NULL)
282 break;
283 free(rrset->rri_sigs[i].rdi_data);
285 free(rrset->rri_sigs);
286 free(rrset->rri_name);
287 free(rrset);