1 /*
2  * Copyright 1997-2002 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 /*
7  * Copyright (c) 1996,1999 by Internet Software Consortium.
8  *
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.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
14  * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
15  * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
16  * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
17  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
18  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
19  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
20  * SOFTWARE.
21  */
22 
23 #pragma ident	"%Z%%M%	%I%	%E% SMI"
24 
25 #if !defined(LINT) && !defined(CODECENTER)
26 static const char rcsid[] = "$Id: getservent.c,v 1.17 2001/11/01 07:33:16 marka Exp $";
27 #endif
28 
29 /* Imports */
30 
31 #include "port_before.h"
32 
33 #if !defined(__BIND_NOSTATIC)
34 
35 #include <sys/types.h>
36 
37 #include <netinet/in.h>
38 #include <arpa/nameser.h>
39 
40 #include <errno.h>
41 #include <resolv.h>
42 #include <stdio.h>
43 #include <string.h>
44 
45 #include <irs.h>
46 
47 #include "port_after.h"
48 
49 #include "irs_data.h"
50 
51 /* Forward */
52 
53 static struct net_data *init(void);
54 
55 /* Public */
56 
57 struct servent *
58 getservent(void) {
59 	struct net_data *net_data = init();
60 
61 	return (getservent_p(net_data));
62 }
63 
64 struct servent *
65 getservbyname(const char *name, const char *proto) {
66 	struct net_data *net_data = init();
67 
68 	return (getservbyname_p(name, proto, net_data));
69 }
70 
71 struct servent *
72 getservbyport(int port, const char *proto) {
73 	struct net_data *net_data = init();
74 
75 	return (getservbyport_p(port, proto, net_data));
76 }
77 
78 #ifdef	ORIGINAL_ISC_CODE
79 void
80 #else
81 int
82 #endif
83 setservent(int stayopen) {
84 	struct net_data *net_data = init();
85 
86 	setservent_p(stayopen, net_data);
87 #ifdef	ORIGINAL_ISC_CODE
88 #else
89 	return (0);
90 #endif
91 }
92 
93 #ifdef	ORIGINAL_ISC_CODE
94 void
95 #else
96 int
97 #endif
98 endservent() {
99 	struct net_data *net_data = init();
100 
101 	endservent_p(net_data);
102 #ifdef	ORIGINAL_ISC_CODE
103 #else
104 	return (0);
105 #endif
106 }
107 
108 /* Shared private. */
109 
110 struct servent *
111 getservent_p(struct net_data *net_data) {
112 	struct irs_sv *sv;
113 
114 	if (!net_data || !(sv = net_data->sv))
115 		return (NULL);
116 	net_data->sv_last = (*sv->next)(sv);
117 	return (net_data->sv_last);
118 }
119 
120 struct servent *
121 getservbyname_p(const char *name, const char *proto,
122 		struct net_data *net_data) {
123 	struct irs_sv *sv;
124 	char **sap;
125 
126 	if (!net_data || !(sv = net_data->sv))
127 		return (NULL);
128 	if (net_data->sv_stayopen && net_data->sv_last)
129 		if (!proto || !strcmp(net_data->sv_last->s_proto, proto)) {
130 			if (!strcmp(net_data->sv_last->s_name, name))
131 				return (net_data->sv_last);
132 			for (sap = net_data->sv_last->s_aliases;
133 			     sap && *sap; sap++)
134 				if (!strcmp(name, *sap))
135 					return (net_data->sv_last);
136 		}
137 	net_data->sv_last = (*sv->byname)(sv, name, proto);
138 	if (!net_data->sv_stayopen)
139 		endservent();
140 	return (net_data->sv_last);
141 }
142 
143 struct servent *
144 getservbyport_p(int port, const char *proto, struct net_data *net_data) {
145 	struct irs_sv *sv;
146 
147 	if (!net_data || !(sv = net_data->sv))
148 		return (NULL);
149 	if (net_data->sv_stayopen && net_data->sv_last)
150 		if (port == net_data->sv_last->s_port &&
151 		    ( !proto ||
152 		     !strcmp(net_data->sv_last->s_proto, proto)))
153 			return (net_data->sv_last);
154 	net_data->sv_last = (*sv->byport)(sv, port, proto);
155 	return (net_data->sv_last);
156 }
157 
158 void
159 setservent_p(int stayopen, struct net_data *net_data) {
160 	struct irs_sv *sv;
161 
162 	if (!net_data || !(sv = net_data->sv))
163 		return;
164 	(*sv->rewind)(sv);
165 	net_data->sv_stayopen = (stayopen != 0);
166 	if (stayopen == 0)
167 		net_data_minimize(net_data);
168 }
169 
170 void
171 endservent_p(struct net_data *net_data) {
172 	struct irs_sv *sv;
173 
174 	if ((net_data != NULL) && ((sv = net_data->sv) != NULL))
175 		(*sv->minimize)(sv);
176 }
177 
178 /* Private */
179 
180 static struct net_data *
181 init() {
182 	struct net_data *net_data;
183 
184 	if (!(net_data = net_data_init(NULL)))
185 		goto error;
186 	if (!net_data->sv) {
187 		net_data->sv = (*net_data->irs->sv_map)(net_data->irs);
188 
189 		if (!net_data->sv || !net_data->res) {
190  error:
191 			errno = EIO;
192 			return (NULL);
193 		}
194 		(*net_data->sv->res_set)(net_data->sv, net_data->res, NULL);
195 	}
196 
197 	return (net_data);
198 }
199 
200 #endif /*__BIND_NOSTATIC*/
201