Merge from vendor branch LIBARCHIVE:
[dragonfly.git] / contrib / bind-9.3 / lib / bind / irs / irp_pr.c
1 /*
2  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
3  * Portions Copyright (c) 1996 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 #if defined(LIBC_SCCS) && !defined(lint)
19 static const char rcsid[] = "$Id: irp_pr.c,v 1.1.206.1 2004/03/09 08:33:37 marka Exp $";
20 #endif /* LIBC_SCCS and not lint */
21
22 /* extern */
23
24 #include "port_before.h"
25
26 #include <syslog.h>
27 #include <sys/types.h>
28
29 #include <errno.h>
30 #include <fcntl.h>
31 #include <string.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <netdb.h>
35 #include <syslog.h>
36
37 #include <irs.h>
38 #include <irp.h>
39 #include <isc/memcluster.h>
40 #include <isc/irpmarshall.h>
41
42 #include "irs_p.h"
43 #include "lcl_p.h"
44 #include "irp_p.h"
45
46 #include "port_after.h"
47
48
49 #define MAXALIASES      35
50
51 /* Types */
52
53 struct pvt {
54         struct irp_p           *girpdata;
55         int                     warned;
56         struct protoent         proto;
57 };
58
59 /* Forward */
60
61 static void                     pr_close(struct irs_pr *);
62 static struct protoent *        pr_next(struct irs_pr *);
63 static struct protoent *        pr_byname(struct irs_pr *, const char *);
64 static struct protoent *        pr_bynumber(struct irs_pr *, int);
65 static void                     pr_rewind(struct irs_pr *);
66 static void                     pr_minimize(struct irs_pr *);
67
68 static void                     free_proto(struct protoent *pr);
69
70 /* Public */
71
72
73
74 /*
75  * struct irs_pr * irs_irp_pr(struct irs_acc *this)
76  *
77  */
78
79 struct irs_pr *
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
112 /*
113  * void pr_close(struct irs_pr *this)
114  *
115  */
116
117 static void
118 pr_close(struct irs_pr *this) {
119         struct pvt *pvt = (struct pvt *)this->private;
120
121         pr_minimize(this);
122
123         free_proto(&pvt->proto);
124
125         memput(pvt, sizeof *pvt);
126         memput(this, sizeof *this);
127 }
128
129
130
131 /*
132  * struct protoent * pr_byname(struct irs_pr *this, const char *name)
133  *
134  */
135
136 static struct protoent *
137 pr_byname(struct irs_pr *this, const char *name) {
138         struct pvt *pvt = (struct pvt *)this->private;
139         struct protoent *pr = &pvt->proto;
140         char *body = NULL;
141         size_t bodylen;
142         int code;
143         int i;
144         char text[256];
145
146         if (pr->p_name != NULL && strcmp(name, pr->p_name) == 0) {
147                 return (pr);
148         }
149
150         if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
151                 return (NULL);
152         }
153
154         i = irs_irp_send_command(pvt->girpdata, "getprotobyname %s", name);
155         if (i != 0)
156                 return (NULL);
157
158         if (irs_irp_get_full_response(pvt->girpdata, &code,
159                                       text, sizeof text,
160                                       &body, &bodylen) != 0) {
161                 return (NULL);
162         }
163
164         if (code == IRPD_GETPROTO_OK) {
165                 free_proto(pr);
166                 if (irp_unmarshall_pr(pr, body) != 0) {
167                         pr = NULL;
168                 }
169         } else {
170                 pr = NULL;
171         }
172
173         if (body != NULL) {
174                 memput(body, bodylen);
175         }
176
177         return (pr);
178 }
179
180
181
182 /*
183  * struct protoent * pr_bynumber(struct irs_pr *this, int proto)
184  *
185  */
186
187 static struct protoent *
188 pr_bynumber(struct irs_pr *this, int proto) {
189         struct pvt *pvt = (struct pvt *)this->private;
190         struct protoent *pr = &pvt->proto;
191         char *body = NULL;
192         size_t bodylen;
193         int code;
194         int i;
195         char text[256];
196
197         if (pr->p_name != NULL && proto == pr->p_proto) {
198                 return (pr);
199         }
200
201         if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
202                 return (NULL);
203         }
204
205         i = irs_irp_send_command(pvt->girpdata, "getprotobynumber %d", proto);
206         if (i != 0)
207                 return (NULL);
208
209         if (irs_irp_get_full_response(pvt->girpdata, &code,
210                                       text, sizeof text,
211                                       &body, &bodylen) != 0) {
212                 return (NULL);
213         }
214
215         if (code == IRPD_GETPROTO_OK) {
216                 free_proto(pr);
217                 if (irp_unmarshall_pr(pr, body) != 0) {
218                         pr = NULL;
219                 }
220         } else {
221                 pr = NULL;
222         }
223
224         if (body != NULL) {
225                 memput(body, bodylen);
226         }
227
228         return (pr);
229 }
230
231
232
233
234 /*
235  * void pr_rewind(struct irs_pr *this)
236  *
237  */
238
239 static void
240 pr_rewind(struct irs_pr *this) {
241         struct pvt *pvt = (struct pvt *)this->private;
242         char text[256];
243         int code;
244
245         if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
246                 return;
247         }
248
249         if (irs_irp_send_command(pvt->girpdata, "setprotoent") != 0) {
250                 return;
251         }
252
253         code = irs_irp_read_response(pvt->girpdata, text, sizeof text);
254         if (code != IRPD_GETPROTO_SETOK) {
255                 if (irp_log_errors) {
256                         syslog(LOG_WARNING, "setprotoent failed: %s", text);
257                 }
258         }
259
260         return;
261 }
262
263
264
265
266 /*
267  * struct protoent * pr_next(struct irs_pr *this)
268  *
269  * Notes:
270  *
271  *      Prepares the cache if necessary and returns the next item in it.
272  *
273  */
274
275 static struct protoent *
276 pr_next(struct irs_pr *this) {
277         struct pvt *pvt = (struct pvt *)this->private;
278         struct protoent *pr = &pvt->proto;
279         char *body;
280         size_t bodylen;
281         int code;
282         char text[256];
283
284         if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
285                 return (NULL);
286         }
287
288         if (irs_irp_send_command(pvt->girpdata, "getprotoent") != 0) {
289                 return (NULL);
290         }
291
292         if (irs_irp_get_full_response(pvt->girpdata, &code,
293                                       text, sizeof text,
294                                       &body, &bodylen) != 0) {
295                 return (NULL);
296         }
297
298         if (code == IRPD_GETPROTO_OK) {
299                 free_proto(pr);
300                 if (irp_unmarshall_pr(pr, body) != 0) {
301                         pr = NULL;
302                 }
303         } else {
304                 pr = NULL;
305         }
306
307         if (body != NULL) {
308                 memput(body, bodylen);
309         }
310
311         return (pr);
312 }
313
314
315
316
317 /*
318  * void pr_minimize(struct irs_pr *this)
319  *
320  */
321
322 static void
323 pr_minimize(struct irs_pr *this) {
324         struct pvt *pvt = (struct pvt *)this->private;
325
326         irs_irp_disconnect(pvt->girpdata);
327 }
328
329
330
331
332
333
334 /*
335  * static void free_proto(struct protoent *pw);
336  *
337  *      Deallocate all the memory irp_unmarshall_pr allocated.
338  *
339  */
340
341 static void
342 free_proto(struct protoent *pr) {
343         char **p;
344
345         if (pr == NULL)
346                 return;
347
348         if (pr->p_name != NULL)
349                 free(pr->p_name);
350
351         for (p = pr->p_aliases ; p != NULL && *p != NULL ; p++)
352                 free(*p);
353 }