1 /*
2  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (c) 1996,1999 by Internet Software Consortium.
4  *
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.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
15  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 /* Imports */
19 
20 #include "port_before.h"
21 
22 #if !defined(__BIND_NOSTATIC)
23 
24 #include <sys/types.h>
25 
26 #include <netinet/in.h>
27 #include <arpa/nameser.h>
28 
29 #include <errno.h>
30 #include <resolv.h>
31 #include <stdio.h>
32 #include <string.h>
33 
34 #include <irs.h>
35 
36 #include "port_after.h"
37 
38 #include "irs_data.h"
39 
40 /* Forward */
41 
42 static struct net_data *init(void);
43 
44 /* Public */
45 
46 struct protoent *
getprotoent()47 getprotoent() {
48 	struct net_data *net_data = init();
49 
50 	return (getprotoent_p(net_data));
51 }
52 
53 struct protoent *
getprotobyname(const char * name)54 getprotobyname(const char *name) {
55 	struct net_data *net_data = init();
56 
57 	return (getprotobyname_p(name, net_data));
58 }
59 
60 struct protoent *
getprotobynumber(int proto)61 getprotobynumber(int proto) {
62 	struct net_data *net_data = init();
63 
64 	return (getprotobynumber_p(proto, net_data));
65 }
66 
67 void
setprotoent(int stayopen)68 setprotoent(int stayopen) {
69 	struct net_data *net_data = init();
70 
71 	setprotoent_p(stayopen, net_data);
72 }
73 
74 void
endprotoent()75 endprotoent() {
76 	struct net_data *net_data = init();
77 
78 	endprotoent_p(net_data);
79 }
80 
81 /* Shared private. */
82 
83 struct protoent *
getprotoent_p(struct net_data * net_data)84 getprotoent_p(struct net_data *net_data) {
85 	struct irs_pr *pr;
86 
87 	if (!net_data || !(pr = net_data->pr))
88 		return (NULL);
89 	net_data->pr_last = (*pr->next)(pr);
90 	return (net_data->pr_last);
91 }
92 
93 struct protoent *
getprotobyname_p(const char * name,struct net_data * net_data)94 getprotobyname_p(const char *name, struct net_data *net_data) {
95 	struct irs_pr *pr;
96 	char **pap;
97 
98 	if (!net_data || !(pr = net_data->pr))
99 		return (NULL);
100 	if (net_data->pr_stayopen && net_data->pr_last) {
101 		if (!strcmp(net_data->pr_last->p_name, name))
102 			return (net_data->pr_last);
103 		for (pap = net_data->pr_last->p_aliases; pap && *pap; pap++)
104 			if (!strcmp(name, *pap))
105 				return (net_data->pr_last);
106 	}
107 	net_data->pr_last = (*pr->byname)(pr, name);
108 	if (!net_data->pr_stayopen)
109 		endprotoent();
110 	return (net_data->pr_last);
111 }
112 
113 struct protoent *
getprotobynumber_p(int proto,struct net_data * net_data)114 getprotobynumber_p(int proto, struct net_data *net_data) {
115 	struct irs_pr *pr;
116 
117 	if (!net_data || !(pr = net_data->pr))
118 		return (NULL);
119 	if (net_data->pr_stayopen && net_data->pr_last)
120 		if (net_data->pr_last->p_proto == proto)
121 			return (net_data->pr_last);
122 	net_data->pr_last = (*pr->bynumber)(pr, proto);
123 	if (!net_data->pr_stayopen)
124 		endprotoent();
125 	return (net_data->pr_last);
126 }
127 
128 void
setprotoent_p(int stayopen,struct net_data * net_data)129 setprotoent_p(int stayopen, struct net_data *net_data) {
130 	struct irs_pr *pr;
131 
132 	if (!net_data || !(pr = net_data->pr))
133 		return;
134 	(*pr->rewind)(pr);
135 	net_data->pr_stayopen = (stayopen != 0);
136 	if (stayopen == 0)
137 		net_data_minimize(net_data);
138 }
139 
140 void
endprotoent_p(struct net_data * net_data)141 endprotoent_p(struct net_data *net_data) {
142 	struct irs_pr *pr;
143 
144 	if ((net_data != NULL) && ((pr = net_data->pr) != NULL))
145 		(*pr->minimize)(pr);
146 }
147 
148 /* Private */
149 
150 static struct net_data *
init()151 init() {
152 	struct net_data *net_data;
153 
154 	if (!(net_data = net_data_init(NULL)))
155 		goto error;
156 	if (!net_data->pr) {
157 		net_data->pr = (*net_data->irs->pr_map)(net_data->irs);
158 
159 		if (!net_data->pr || !net_data->res) {
160  error:
161 			errno = EIO;
162 			return (NULL);
163 		}
164 		(*net_data->pr->res_set)(net_data->pr, net_data->res, NULL);
165 	}
166 
167 	return (net_data);
168 }
169 
170 #endif /*__BIND_NOSTATIC*/
171 
172 /*! \file */
173