xref: /illumos-gate/usr/src/lib/libresolv2/common/irs/irp_sv.c (revision bdb9230ac765cb7af3fc1f4119caf2c5720dceb3)
1 /*
2  * Copyright (c) 1999 by Sun Microsystems, Inc.
3  * All rights reserved.
4  */
5 
6 /*
7  * Portions Copyright (c) 1996,1998 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(LIBC_SCCS) && !defined(lint)
26 static const char rcsid[] = "$Id: irp_sv.c,v 8.1 1999/01/18 07:46:54 vixie Exp $";
27 #endif /* LIBC_SCCS and not lint */
28 
29 /* extern */
30 
31 #include "port_before.h"
32 
33 #include <syslog.h>
34 #include <sys/types.h>
35 #include <sys/socket.h>
36 
37 #ifdef IRS_LCL_SV_DB
38 #include <db.h>
39 #endif
40 #include <errno.h>
41 #include <fcntl.h>
42 #include <limits.h>
43 #include <stdio.h>
44 #include <string.h>
45 #include <stdlib.h>
46 #include <syslog.h>
47 
48 #include <irs.h>
49 #include <irp.h>
50 #include <isc/irpmarshall.h>
51 #include <isc/memcluster.h>
52 
53 #include "irs_p.h"
54 #include "lcl_p.h"
55 #include "irp_p.h"
56 
57 #include "port_after.h"
58 
59 /* Types */
60 
61 struct pvt {
62 	struct irp_p	       *girpdata;
63 	int			warned;
64 	struct servent		service;
65 };
66 
67 /* Forward */
68 
69 static void			sv_close(struct irs_sv*);
70 static struct servent *		sv_next(struct irs_sv *);
71 static struct servent *		sv_byname(struct irs_sv *, const char *,
72 					  const char *);
73 static struct servent *		sv_byport(struct irs_sv *, int, const char *);
74 static void			sv_rewind(struct irs_sv *);
75 static void			sv_minimize(struct irs_sv *);
76 
77 static void			free_service(struct servent *sv);
78 
79 
80 
81 /* Public */
82 
83 
84 
85 /*
86  * struct irs_sv * irs_irp_sv(struct irs_acc *this)
87  *
88  */
89 
90 struct irs_sv *
91 irs_irp_sv(struct irs_acc *this) {
92 	struct irs_sv *sv;
93 	struct pvt *pvt;
94 
95 	if ((sv = memget(sizeof *sv)) == NULL) {
96 		errno = ENOMEM;
97 		return (NULL);
98 	}
99 	memset(sv, 0x0, sizeof *sv);
100 
101 	if ((pvt = memget(sizeof *pvt)) == NULL) {
102 		memput(sv, sizeof *sv);
103 		errno = ENOMEM;
104 		return (NULL);
105 	}
106 	memset(pvt, 0, sizeof *pvt);
107 	pvt->girpdata = this->private;
108 
109 	sv->private = pvt;
110 	sv->close = sv_close;
111 	sv->next = sv_next;
112 	sv->byname = sv_byname;
113 	sv->byport = sv_byport;
114 	sv->rewind = sv_rewind;
115 	sv->minimize = sv_minimize;
116 
117 	return (sv);
118 }
119 
120 /* Methods */
121 
122 
123 
124 /*
125  * void sv_close(struct irs_sv *this)
126  *
127  */
128 
129 static void
130 sv_close(struct irs_sv *this) {
131 	struct pvt *pvt = (struct pvt *)this->private;
132 
133 	sv_minimize(this);
134 
135 	free_service(&pvt->service);
136 
137 	memput(pvt, sizeof *pvt);
138 	memput(this, sizeof *this);
139 }
140 
141 
142 
143 
144 /*
145  * struct servent * sv_next(struct irs_sv *this)
146  *
147  * Notes:
148  *
149  *	Fills the cache if necessary and returns the next item from it.
150  *
151  */
152 
153 static struct servent *
154 sv_next(struct irs_sv *this) {
155 	struct pvt *pvt = (struct pvt *)this->private;
156 	struct servent *sv = &pvt->service;
157 	char *body;
158 	size_t bodylen;
159 	int code;
160 	char text[256];
161 
162 	if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
163 		return (NULL);
164 	}
165 
166 	if (irs_irp_send_command(pvt->girpdata, "getservent") != 0) {
167 		return (NULL);
168 	}
169 
170 	if (irs_irp_get_full_response(pvt->girpdata, &code,
171 				      text, sizeof text,
172 				      &body, &bodylen) != 0) {
173 		return (NULL);
174 	}
175 
176 	if (code == IRPD_GETSERVICE_OK) {
177 		free_service(sv);
178 		if (irp_unmarshall_sv(sv, body) != 0) {
179 			sv = NULL;
180 		}
181 	} else {
182 		sv = NULL;
183 	}
184 
185 	if (body != NULL) {
186 		memput(body, bodylen);
187 	}
188 
189 	return (sv);
190 }
191 
192 
193 
194 
195 /*
196  * struct servent * sv_byname(struct irs_sv *this, const char *name,
197  *				const char *proto)
198  *
199  */
200 
201 static struct servent *
202 sv_byname(struct irs_sv *this, const char *name, const char *proto) {
203 	struct pvt *pvt = (struct pvt *)this->private;
204 	struct servent *sv = &pvt->service;
205 	char *body;
206 	char text[256];
207 	size_t bodylen;
208 	int code;
209 
210 	if (sv->s_name != NULL &&
211 	    strcmp(name, sv->s_name) == 0 &&
212 	    strcasecmp(proto, sv->s_proto) == 0) {
213 		return (sv);
214 	}
215 
216 	if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
217 		return (NULL);
218 	}
219 
220 	if (irs_irp_send_command(pvt->girpdata, "getservbyname %s %s",
221 				 name, proto) != 0)
222 		return (NULL);
223 
224 	if (irs_irp_get_full_response(pvt->girpdata, &code,
225 				      text, sizeof text,
226 				      &body, &bodylen) != 0) {
227 		return (NULL);
228 	}
229 
230 	if (code == IRPD_GETSERVICE_OK) {
231 		free_service(sv);
232 		if (irp_unmarshall_sv(sv, body) != 0) {
233 			sv = NULL;
234 		}
235 	} else {
236 		sv = NULL;
237 	}
238 
239 	if (body != NULL) {
240 		memput(body, bodylen);
241 	}
242 
243 	return (sv);
244 }
245 
246 
247 
248 
249 /*
250  * struct servent * sv_byport(struct irs_sv *this, int port,
251  *				const char *proto)
252  *
253  */
254 
255 static struct servent *
256 sv_byport(struct irs_sv *this, int port, const char *proto) {
257 	struct pvt *pvt = (struct pvt *)this->private;
258 	struct servent *sv = &pvt->service;
259 	char *body;
260 	size_t bodylen;
261 	char text[256];
262 	int code;
263 
264 	if (sv->s_name != NULL &&
265 	    port == sv->s_port &&
266 	    strcasecmp(proto, sv->s_proto) == 0) {
267 		return (sv);
268 	}
269 
270 	if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
271 		return (NULL);
272 	}
273 
274 	if (irs_irp_send_command(pvt->girpdata, "getservbyport %d %s",
275 				 ntohs((short)port), proto) != 0) {
276 		return (NULL);
277 	}
278 
279 	if (irs_irp_get_full_response(pvt->girpdata, &code,
280 				      text, sizeof text,
281 				      &body, &bodylen) != 0) {
282 		return (NULL);
283 	}
284 
285 	if (code == IRPD_GETSERVICE_OK) {
286 		free_service(sv);
287 		if (irp_unmarshall_sv(sv, body) != 0) {
288 			sv = NULL;
289 		}
290 	} else {
291 		sv = NULL;
292 	}
293 
294 	if (body != NULL) {
295 		memput(body, bodylen);
296 	}
297 
298 	return (sv);
299 }
300 
301 
302 
303 
304 
305 /*
306  * void sv_rewind(struct irs_sv *this)
307  *
308  */
309 
310 static void
311 sv_rewind(struct irs_sv *this) {
312 	struct pvt *pvt = (struct pvt *)this->private;
313 	char text[256];
314 	int code;
315 
316 	if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
317 		return;
318 	}
319 
320 	if (irs_irp_send_command(pvt->girpdata, "setservent") != 0) {
321 		return;
322 	}
323 
324 	code = irs_irp_read_response(pvt->girpdata, text, sizeof text);
325 	if (code != IRPD_GETSERVICE_SETOK) {
326 		if (irp_log_errors) {
327 			syslog(LOG_WARNING, "setservent failed: %s", text);
328 		}
329 	}
330 
331 	return;
332 }
333 
334 
335 
336 
337 
338 /*
339  * void sv_minimize(struct irs_sv *this)
340  *
341  */
342 
343 static void
344 sv_minimize(struct irs_sv *this) {
345 	struct pvt *pvt = (struct pvt *)this->private;
346 
347 	irs_irp_disconnect(pvt->girpdata);
348 }
349 
350 
351 
352 
353 
354 
355 static void
356 free_service(struct servent *sv) {
357 	char **p;
358 
359 	if (sv == NULL) {
360 		return;
361 	}
362 
363 	if (sv->s_name != NULL) {
364 		free(sv->s_name);
365 	}
366 
367 	for (p = sv->s_aliases ; p != NULL && *p != NULL ; p++) {
368 		free(*p);
369 	}
370 
371 	if (sv->s_proto != NULL) {
372 		free(sv->s_proto);
373 	}
374 }
375 
376 
377