xref: /netbsd-src/external/bsd/libbind/dist/irs/irp_pr.c (revision 5bbd2a12505d72a8177929a37b5cee489d0a1cfd)
1 /*	$NetBSD: irp_pr.c,v 1.1.1.2 2012/09/09 16:07:56 christos Exp $	*/
2 
3 /*
4  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
5  * Portions Copyright (c) 1996 by Internet Software Consortium.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
17  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #if defined(LIBC_SCCS) && !defined(lint)
21 static const char rcsid[] = "Id: irp_pr.c,v 1.3 2005/04/27 04:56:29 sra Exp ";
22 #endif /* LIBC_SCCS and not lint */
23 
24 /* extern */
25 
26 #include "port_before.h"
27 
28 #include <syslog.h>
29 #include <sys/types.h>
30 
31 #include <errno.h>
32 #include <fcntl.h>
33 #include <string.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <netdb.h>
37 #include <syslog.h>
38 
39 #include <irs.h>
40 #include <irp.h>
41 #include <isc/memcluster.h>
42 #include <isc/irpmarshall.h>
43 
44 #include "irs_p.h"
45 #include "lcl_p.h"
46 #include "irp_p.h"
47 
48 #include "port_after.h"
49 
50 
51 #define MAXALIASES	35
52 
53 /* Types */
54 
55 struct pvt {
56 	struct irp_p	       *girpdata;
57 	int			warned;
58 	struct protoent		proto;
59 };
60 
61 /* Forward */
62 
63 static void			pr_close(struct irs_pr *);
64 static struct protoent *	pr_next(struct irs_pr *);
65 static struct protoent *	pr_byname(struct irs_pr *, const char *);
66 static struct protoent *	pr_bynumber(struct irs_pr *, int);
67 static void			pr_rewind(struct irs_pr *);
68 static void			pr_minimize(struct irs_pr *);
69 
70 static void			free_proto(struct protoent *pr);
71 
72 /* Public */
73 
74 /*%
75  * struct irs_pr * irs_irp_pr(struct irs_acc *this)
76  *
77  */
78 
79 struct irs_pr *
irs_irp_pr(struct irs_acc * this)80 irs_irp_pr(struct irs_acc *this) {
81 	struct irs_pr *pr;
82 	struct pvt *pvt;
83 
84 	if (!(pr = memget(sizeof *pr))) {
85 		errno = ENOMEM;
86 		return (NULL);
87 	}
88 	memset(pr, 0x0, sizeof *pr);
89 
90 	if (!(pvt = memget(sizeof *pvt))) {
91 		memput(pr, sizeof *pr);
92 		errno = ENOMEM;
93 		return (NULL);
94 	}
95 	memset(pvt, 0, sizeof *pvt);
96 	pvt->girpdata = this->private;
97 
98 	pr->private = pvt;
99 	pr->close = pr_close;
100 	pr->byname = pr_byname;
101 	pr->bynumber = pr_bynumber;
102 	pr->next = pr_next;
103 	pr->rewind = pr_rewind;
104 	pr->minimize = pr_minimize;
105 	return (pr);
106 }
107 
108 /* Methods */
109 
110 /*%
111  * void pr_close(struct irs_pr *this)
112  *
113  */
114 
115 static void
pr_close(struct irs_pr * this)116 pr_close(struct irs_pr *this) {
117 	struct pvt *pvt = (struct pvt *)this->private;
118 
119 	pr_minimize(this);
120 
121 	free_proto(&pvt->proto);
122 
123 	memput(pvt, sizeof *pvt);
124 	memput(this, sizeof *this);
125 }
126 
127 /*%
128  * struct protoent * pr_byname(struct irs_pr *this, const char *name)
129  *
130  */
131 
132 static struct protoent *
pr_byname(struct irs_pr * this,const char * name)133 pr_byname(struct irs_pr *this, const char *name) {
134 	struct pvt *pvt = (struct pvt *)this->private;
135 	struct protoent *pr = &pvt->proto;
136 	char *body = NULL;
137 	size_t bodylen;
138 	int code;
139 	int i;
140 	char text[256];
141 
142 	if (pr->p_name != NULL && strcmp(name, pr->p_name) == 0) {
143 		return (pr);
144 	}
145 
146 	if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
147 		return (NULL);
148 	}
149 
150 	i = irs_irp_send_command(pvt->girpdata, "getprotobyname %s", name);
151 	if (i != 0)
152 		return (NULL);
153 
154 	if (irs_irp_get_full_response(pvt->girpdata, &code,
155 				      text, sizeof text,
156 				      &body, &bodylen) != 0) {
157 		return (NULL);
158 	}
159 
160 	if (code == IRPD_GETPROTO_OK) {
161 		free_proto(pr);
162 		if (irp_unmarshall_pr(pr, body) != 0) {
163 			pr = NULL;
164 		}
165 	} else {
166 		pr = NULL;
167 	}
168 
169 	if (body != NULL) {
170 		memput(body, bodylen);
171 	}
172 
173 	return (pr);
174 }
175 
176 /*%
177  * struct protoent * pr_bynumber(struct irs_pr *this, int proto)
178  *
179  */
180 
181 static struct protoent *
pr_bynumber(struct irs_pr * this,int proto)182 pr_bynumber(struct irs_pr *this, int proto) {
183 	struct pvt *pvt = (struct pvt *)this->private;
184 	struct protoent *pr = &pvt->proto;
185 	char *body = NULL;
186 	size_t bodylen;
187 	int code;
188 	int i;
189 	char text[256];
190 
191 	if (pr->p_name != NULL && proto == pr->p_proto) {
192 		return (pr);
193 	}
194 
195 	if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
196 		return (NULL);
197 	}
198 
199 	i = irs_irp_send_command(pvt->girpdata, "getprotobynumber %d", proto);
200 	if (i != 0)
201 		return (NULL);
202 
203 	if (irs_irp_get_full_response(pvt->girpdata, &code,
204 				      text, sizeof text,
205 				      &body, &bodylen) != 0) {
206 		return (NULL);
207 	}
208 
209 	if (code == IRPD_GETPROTO_OK) {
210 		free_proto(pr);
211 		if (irp_unmarshall_pr(pr, body) != 0) {
212 			pr = NULL;
213 		}
214 	} else {
215 		pr = NULL;
216 	}
217 
218 	if (body != NULL) {
219 		memput(body, bodylen);
220 	}
221 
222 	return (pr);
223 }
224 
225 /*%
226  * void pr_rewind(struct irs_pr *this)
227  *
228  */
229 
230 static void
pr_rewind(struct irs_pr * this)231 pr_rewind(struct irs_pr *this) {
232 	struct pvt *pvt = (struct pvt *)this->private;
233 	char text[256];
234 	int code;
235 
236 	if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
237 		return;
238 	}
239 
240 	if (irs_irp_send_command(pvt->girpdata, "setprotoent") != 0) {
241 		return;
242 	}
243 
244 	code = irs_irp_read_response(pvt->girpdata, text, sizeof text);
245 	if (code != IRPD_GETPROTO_SETOK) {
246 		if (irp_log_errors) {
247 			syslog(LOG_WARNING, "setprotoent failed: %s", text);
248 		}
249 	}
250 
251 	return;
252 }
253 
254 /*%
255  *	Prepares the cache if necessary and returns the next item in it.
256  *
257  */
258 
259 static struct protoent *
pr_next(struct irs_pr * this)260 pr_next(struct irs_pr *this) {
261 	struct pvt *pvt = (struct pvt *)this->private;
262 	struct protoent *pr = &pvt->proto;
263 	char *body;
264 	size_t bodylen;
265 	int code;
266 	char text[256];
267 
268 	if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
269 		return (NULL);
270 	}
271 
272 	if (irs_irp_send_command(pvt->girpdata, "getprotoent") != 0) {
273 		return (NULL);
274 	}
275 
276 	if (irs_irp_get_full_response(pvt->girpdata, &code,
277 				      text, sizeof text,
278 				      &body, &bodylen) != 0) {
279 		return (NULL);
280 	}
281 
282 	if (code == IRPD_GETPROTO_OK) {
283 		free_proto(pr);
284 		if (irp_unmarshall_pr(pr, body) != 0) {
285 			pr = NULL;
286 		}
287 	} else {
288 		pr = NULL;
289 	}
290 
291 	if (body != NULL) {
292 		memput(body, bodylen);
293 	}
294 
295 	return (pr);
296 }
297 
298 /*%
299  * void pr_minimize(struct irs_pr *this)
300  *
301  */
302 
303 static void
pr_minimize(struct irs_pr * this)304 pr_minimize(struct irs_pr *this) {
305 	struct pvt *pvt = (struct pvt *)this->private;
306 
307 	irs_irp_disconnect(pvt->girpdata);
308 }
309 
310 /*%
311  *	Deallocate all the memory irp_unmarshall_pr allocated.
312  *
313  */
314 
315 static void
free_proto(struct protoent * pr)316 free_proto(struct protoent *pr) {
317 	char **p;
318 
319 	if (pr == NULL)
320 		return;
321 
322 	if (pr->p_name != NULL)
323 		free(pr->p_name);
324 
325 	for (p = pr->p_aliases ; p != NULL && *p != NULL ; p++)
326 		free(*p);
327 }
328 
329 /*! \file */
330