2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
6 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
7 * Copyright (c) 1996,1999 by Internet Software Consortium.
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
13 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 #include "port_before.h"
24 #ifndef __BIND_NOSTATIC
26 #include <sys/types.h>
28 #include <netinet/in.h>
29 #include <arpa/nameser.h>
34 #include <isc/memcluster.h>
43 #include "port_after.h"
47 #if !(__GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)
52 extern struct __res_state _res
;
55 static pthread_key_t key
;
58 static struct net_data
*net_data
;
65 net_data_destroy(net_data
);
71 net_data_destroy(void *p
) {
72 struct net_data
*net_data
= p
;
74 res_ndestroy(net_data
->res
);
75 if (net_data
->gr
!= NULL
) {
76 (*net_data
->gr
->close
)(net_data
->gr
);
79 if (net_data
->pw
!= NULL
) {
80 (*net_data
->pw
->close
)(net_data
->pw
);
83 if (net_data
->sv
!= NULL
) {
84 (*net_data
->sv
->close
)(net_data
->sv
);
87 if (net_data
->pr
!= NULL
) {
88 (*net_data
->pr
->close
)(net_data
->pr
);
91 if (net_data
->ho
!= NULL
) {
92 (*net_data
->ho
->close
)(net_data
->ho
);
95 if (net_data
->nw
!= NULL
) {
96 (*net_data
->nw
->close
)(net_data
->nw
);
99 if (net_data
->ng
!= NULL
) {
100 (*net_data
->ng
->close
)(net_data
->ng
);
103 if (net_data
->ho_data
!= NULL
) {
104 free(net_data
->ho_data
);
105 net_data
->ho_data
= NULL
;
107 if (net_data
->nw_data
!= NULL
) {
108 free(net_data
->nw_data
);
109 net_data
->nw_data
= NULL
;
112 (*net_data
->irs
->close
)(net_data
->irs
);
113 memput(net_data
, sizeof *net_data
);
117 * applications that need a specific config file other than
118 * _PATH_IRS_CONF should call net_data_init directly rather than letting
119 * the various wrapper functions make the first call. - brister
123 net_data_init(const char *conf_file
) {
125 #ifndef LIBBIND_MUTEX_INITIALIZER
126 #define LIBBIND_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
128 static pthread_mutex_t keylock
= LIBBIND_MUTEX_INITIALIZER
;
129 struct net_data
*net_data
;
132 if (pthread_mutex_lock(&keylock
) != 0)
135 if (pthread_key_create(&key
, net_data_destroy
) != 0) {
136 (void)pthread_mutex_unlock(&keylock
);
141 if (pthread_mutex_unlock(&keylock
) != 0)
144 net_data
= pthread_getspecific(key
);
147 if (net_data
== NULL
) {
148 net_data
= net_data_create(conf_file
);
149 if (net_data
== NULL
)
152 if (pthread_setspecific(key
, net_data
) != 0) {
153 net_data_destroy(net_data
);
163 net_data_create(const char *conf_file
) {
164 struct net_data
*net_data
;
166 net_data
= memget(sizeof (struct net_data
));
167 if (net_data
== NULL
)
169 memset(net_data
, 0, sizeof (struct net_data
));
171 if ((net_data
->irs
= irs_gen_acc("", conf_file
)) == NULL
) {
172 memput(net_data
, sizeof (struct net_data
));
176 (*net_data
->irs
->res_set
)(net_data
->irs
, &_res
, NULL
);
179 net_data
->res
= (*net_data
->irs
->res_get
)(net_data
->irs
);
180 if (net_data
->res
== NULL
) {
181 (*net_data
->irs
->close
)(net_data
->irs
);
182 memput(net_data
, sizeof (struct net_data
));
186 if ((net_data
->res
->options
& RES_INIT
) == 0U &&
187 res_ninit(net_data
->res
) == -1) {
188 (*net_data
->irs
->close
)(net_data
->irs
);
189 memput(net_data
, sizeof (struct net_data
));
197 net_data_minimize(struct net_data
*net_data
) {
198 res_nclose(net_data
->res
);
203 /* NULL param here means use the default config file. */
204 struct net_data
*net_data
= net_data_init(NULL
);
205 if (net_data
&& net_data
->res
)
206 return (net_data
->res
);
213 /* NULL param here means use the default config file. */
214 struct net_data
*net_data
= net_data_init(NULL
);
215 if (net_data
&& net_data
->res
)
216 return (&net_data
->res
->res_h_errno
);
217 #ifdef ORIGINAL_ISC_CODE
218 #if !(__GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)
219 return(&_res
.res_h_errno
);
225 #endif /* ORIGINAL_ISC_CODE */
229 __h_errno_set(struct __res_state
*res
, int err
) {
232 #if (__GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)
233 res
->res_h_errno
= err
;
235 h_errno
= res
->res_h_errno
= err
;
239 #endif /*__BIND_NOSTATIC*/