Merge remote-tracking branch 'origin/master'
[unleashed/lotheac.git] / usr / src / lib / libresolv2 / common / irs / irp_sv.c
blob5cd3e740324585780a4701e50868cf5d96d027c6
1 /*
2 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
3 * Portions Copyright (c) 1996,1998 by Internet Software Consortium.
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.
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.
18 #include "port_before.h"
20 #include <syslog.h>
21 #include <sys/types.h>
22 #include <sys/socket.h>
24 #ifdef IRS_LCL_SV_DB
25 #include <db.h>
26 #endif
27 #include <errno.h>
28 #include <fcntl.h>
29 #include <limits.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <stdlib.h>
33 #include <syslog.h>
35 #include <irs.h>
36 #include <irp.h>
37 #include <isc/irpmarshall.h>
38 #include <isc/memcluster.h>
40 #include "irs_p.h"
41 #include "lcl_p.h"
42 #include "irp_p.h"
44 #include "port_after.h"
46 /* Types */
48 struct pvt {
49 struct irp_p *girpdata;
50 int warned;
51 struct servent service;
54 /* Forward */
56 static void sv_close(struct irs_sv*);
57 static struct servent * sv_next(struct irs_sv *);
58 static struct servent * sv_byname(struct irs_sv *, const char *,
59 const char *);
60 static struct servent * sv_byport(struct irs_sv *, int, const char *);
61 static void sv_rewind(struct irs_sv *);
62 static void sv_minimize(struct irs_sv *);
64 static void free_service(struct servent *sv);
68 /* Public */
70 /*%
71 * struct irs_sv * irs_irp_sv(struct irs_acc *this)
75 struct irs_sv *
76 irs_irp_sv(struct irs_acc *this) {
77 struct irs_sv *sv;
78 struct pvt *pvt;
80 if ((sv = memget(sizeof *sv)) == NULL) {
81 errno = ENOMEM;
82 return (NULL);
84 memset(sv, 0x0, sizeof *sv);
86 if ((pvt = memget(sizeof *pvt)) == NULL) {
87 memput(sv, sizeof *sv);
88 errno = ENOMEM;
89 return (NULL);
91 memset(pvt, 0, sizeof *pvt);
92 pvt->girpdata = this->private;
94 sv->private = pvt;
95 sv->close = sv_close;
96 sv->next = sv_next;
97 sv->byname = sv_byname;
98 sv->byport = sv_byport;
99 sv->rewind = sv_rewind;
100 sv->minimize = sv_minimize;
102 return (sv);
105 /* Methods */
108 * void sv_close(struct irs_sv *this)
112 static void
113 sv_close(struct irs_sv *this) {
114 struct pvt *pvt = (struct pvt *)this->private;
116 sv_minimize(this);
118 free_service(&pvt->service);
120 memput(pvt, sizeof *pvt);
121 memput(this, sizeof *this);
125 * Fills the cache if necessary and returns the next item from it.
129 static struct servent *
130 sv_next(struct irs_sv *this) {
131 struct pvt *pvt = (struct pvt *)this->private;
132 struct servent *sv = &pvt->service;
133 char *body;
134 size_t bodylen;
135 int code;
136 char text[256];
138 if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
139 return (NULL);
142 if (irs_irp_send_command(pvt->girpdata, "getservent") != 0) {
143 return (NULL);
146 if (irs_irp_get_full_response(pvt->girpdata, &code,
147 text, sizeof text,
148 &body, &bodylen) != 0) {
149 return (NULL);
152 if (code == IRPD_GETSERVICE_OK) {
153 free_service(sv);
154 if (irp_unmarshall_sv(sv, body) != 0) {
155 sv = NULL;
157 } else {
158 sv = NULL;
161 if (body != NULL) {
162 memput(body, bodylen);
165 return (sv);
169 * struct servent * sv_byname(struct irs_sv *this, const char *name,
170 * const char *proto)
174 static struct servent *
175 sv_byname(struct irs_sv *this, const char *name, const char *proto) {
176 struct pvt *pvt = (struct pvt *)this->private;
177 struct servent *sv = &pvt->service;
178 char *body;
179 char text[256];
180 size_t bodylen;
181 int code;
183 if (sv->s_name != NULL &&
184 strcmp(name, sv->s_name) == 0 &&
185 strcasecmp(proto, sv->s_proto) == 0) {
186 return (sv);
189 if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
190 return (NULL);
193 if (irs_irp_send_command(pvt->girpdata, "getservbyname %s %s",
194 name, proto) != 0)
195 return (NULL);
197 if (irs_irp_get_full_response(pvt->girpdata, &code,
198 text, sizeof text,
199 &body, &bodylen) != 0) {
200 return (NULL);
203 if (code == IRPD_GETSERVICE_OK) {
204 free_service(sv);
205 if (irp_unmarshall_sv(sv, body) != 0) {
206 sv = NULL;
208 } else {
209 sv = NULL;
212 if (body != NULL) {
213 memput(body, bodylen);
216 return (sv);
220 * struct servent * sv_byport(struct irs_sv *this, int port,
221 * const char *proto)
225 static struct servent *
226 sv_byport(struct irs_sv *this, int port, const char *proto) {
227 struct pvt *pvt = (struct pvt *)this->private;
228 struct servent *sv = &pvt->service;
229 char *body;
230 size_t bodylen;
231 char text[256];
232 int code;
234 if (sv->s_name != NULL &&
235 port == sv->s_port &&
236 strcasecmp(proto, sv->s_proto) == 0) {
237 return (sv);
240 if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
241 return (NULL);
244 if (irs_irp_send_command(pvt->girpdata, "getservbyport %d %s",
245 ntohs((short)port), proto) != 0) {
246 return (NULL);
249 if (irs_irp_get_full_response(pvt->girpdata, &code,
250 text, sizeof text,
251 &body, &bodylen) != 0) {
252 return (NULL);
255 if (code == IRPD_GETSERVICE_OK) {
256 free_service(sv);
257 if (irp_unmarshall_sv(sv, body) != 0) {
258 sv = NULL;
260 } else {
261 sv = NULL;
264 if (body != NULL) {
265 memput(body, bodylen);
268 return (sv);
272 * void sv_rewind(struct irs_sv *this)
276 static void
277 sv_rewind(struct irs_sv *this) {
278 struct pvt *pvt = (struct pvt *)this->private;
279 char text[256];
280 int code;
282 if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
283 return;
286 if (irs_irp_send_command(pvt->girpdata, "setservent") != 0) {
287 return;
290 code = irs_irp_read_response(pvt->girpdata, text, sizeof text);
291 if (code != IRPD_GETSERVICE_SETOK) {
292 if (irp_log_errors) {
293 syslog(LOG_WARNING, "setservent failed: %s", text);
297 return;
301 * void sv_minimize(struct irs_sv *this)
305 static void
306 sv_minimize(struct irs_sv *this) {
307 struct pvt *pvt = (struct pvt *)this->private;
309 irs_irp_disconnect(pvt->girpdata);
317 static void
318 free_service(struct servent *sv) {
319 char **p;
321 if (sv == NULL) {
322 return;
325 if (sv->s_name != NULL) {
326 free(sv->s_name);
329 for (p = sv->s_aliases ; p != NULL && *p != NULL ; p++) {
330 free(*p);
333 if (sv->s_proto != NULL) {
334 free(sv->s_proto);
340 /*! \file */