1 /* $NetBSD: lwsearch.c,v 1.4 2014/12/10 04:37:51 christos Exp $ */
4 * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 2000, 2001 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
20 /* Id: lwsearch.c,v 1.13 2007/06/19 23:46:59 tbox Exp */
26 #include <isc/magic.h>
28 #include <isc/mutex.h>
29 #include <isc/result.h>
30 #include <isc/types.h>
34 #include <dns/types.h>
36 #include <named/lwsearch.h>
37 #include <named/types.h>
39 #define LWSEARCHLIST_MAGIC ISC_MAGIC('L', 'W', 'S', 'L')
40 #define VALID_LWSEARCHLIST(l) ISC_MAGIC_VALID(l, LWSEARCHLIST_MAGIC)
43 ns_lwsearchlist_create(isc_mem_t
*mctx
, ns_lwsearchlist_t
**listp
) {
44 ns_lwsearchlist_t
*list
;
47 REQUIRE(mctx
!= NULL
);
48 REQUIRE(listp
!= NULL
&& *listp
== NULL
);
50 list
= isc_mem_get(mctx
, sizeof(ns_lwsearchlist_t
));
52 return (ISC_R_NOMEMORY
);
54 result
= isc_mutex_init(&list
->lock
);
55 if (result
!= ISC_R_SUCCESS
) {
56 isc_mem_put(mctx
, list
, sizeof(ns_lwsearchlist_t
));
60 isc_mem_attach(mctx
, &list
->mctx
);
62 ISC_LIST_INIT(list
->names
);
63 list
->magic
= LWSEARCHLIST_MAGIC
;
66 return (ISC_R_SUCCESS
);
70 ns_lwsearchlist_attach(ns_lwsearchlist_t
*source
, ns_lwsearchlist_t
**target
) {
71 REQUIRE(VALID_LWSEARCHLIST(source
));
72 REQUIRE(target
!= NULL
&& *target
== NULL
);
75 INSIST(source
->refs
> 0);
77 INSIST(source
->refs
!= 0);
78 UNLOCK(&source
->lock
);
84 ns_lwsearchlist_detach(ns_lwsearchlist_t
**listp
) {
85 ns_lwsearchlist_t
*list
;
88 REQUIRE(listp
!= NULL
);
90 REQUIRE(VALID_LWSEARCHLIST(list
));
93 INSIST(list
->refs
> 0);
102 while (!ISC_LIST_EMPTY(list
->names
)) {
103 dns_name_t
*name
= ISC_LIST_HEAD(list
->names
);
104 ISC_LIST_UNLINK(list
->names
, name
, link
);
105 dns_name_free(name
, list
->mctx
);
106 isc_mem_put(list
->mctx
, name
, sizeof(dns_name_t
));
109 isc_mem_put(mctx
, list
, sizeof(ns_lwsearchlist_t
));
110 isc_mem_detach(&mctx
);
114 ns_lwsearchlist_append(ns_lwsearchlist_t
*list
, dns_name_t
*name
) {
118 REQUIRE(VALID_LWSEARCHLIST(list
));
119 REQUIRE(name
!= NULL
);
121 newname
= isc_mem_get(list
->mctx
, sizeof(dns_name_t
));
123 return (ISC_R_NOMEMORY
);
124 dns_name_init(newname
, NULL
);
125 result
= dns_name_dup(name
, list
->mctx
, newname
);
126 if (result
!= ISC_R_SUCCESS
) {
127 isc_mem_put(list
->mctx
, newname
, sizeof(dns_name_t
));
130 ISC_LINK_INIT(newname
, link
);
131 ISC_LIST_APPEND(list
->names
, newname
, link
);
132 return (ISC_R_SUCCESS
);
136 ns_lwsearchctx_init(ns_lwsearchctx_t
*sctx
, ns_lwsearchlist_t
*list
,
137 dns_name_t
*name
, unsigned int ndots
)
139 INSIST(sctx
!= NULL
);
140 sctx
->relname
= name
;
141 sctx
->searchname
= NULL
;
142 sctx
->doneexact
= ISC_FALSE
;
143 sctx
->exactfirst
= ISC_FALSE
;
145 if (dns_name_isabsolute(name
) || list
== NULL
) {
150 sctx
->searchname
= ISC_LIST_HEAD(sctx
->list
->names
);
151 if (dns_name_countlabels(name
) > ndots
)
152 sctx
->exactfirst
= ISC_TRUE
;
156 ns_lwsearchctx_first(ns_lwsearchctx_t
*sctx
) {
157 REQUIRE(sctx
!= NULL
);
162 ns_lwsearchctx_next(ns_lwsearchctx_t
*sctx
) {
163 REQUIRE(sctx
!= NULL
);
165 if (sctx
->list
== NULL
)
166 return (ISC_R_NOMORE
);
168 if (sctx
->searchname
== NULL
) {
169 INSIST (!sctx
->exactfirst
|| sctx
->doneexact
);
170 if (sctx
->exactfirst
|| sctx
->doneexact
)
171 return (ISC_R_NOMORE
);
172 sctx
->doneexact
= ISC_TRUE
;
174 if (sctx
->exactfirst
&& !sctx
->doneexact
)
175 sctx
->doneexact
= ISC_TRUE
;
177 sctx
->searchname
= ISC_LIST_NEXT(sctx
->searchname
,
179 if (sctx
->searchname
== NULL
&& sctx
->doneexact
)
180 return (ISC_R_NOMORE
);
184 return (ISC_R_SUCCESS
);
188 ns_lwsearchctx_current(ns_lwsearchctx_t
*sctx
, dns_name_t
*absname
) {
190 isc_boolean_t useexact
= ISC_FALSE
;
192 REQUIRE(sctx
!= NULL
);
194 if (sctx
->list
== NULL
||
195 sctx
->searchname
== NULL
||
196 (sctx
->exactfirst
&& !sctx
->doneexact
))
200 if (dns_name_isabsolute(sctx
->relname
))
203 tname
= dns_rootname
;
205 tname
= sctx
->searchname
;
207 return (dns_name_concatenate(sctx
->relname
, tname
, absname
, NULL
));