1/*	$NetBSD: gen_pr.c,v 1.1.1.1 2009/04/12 15:33:40 christos Exp $	*/
2
3/*
4 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (c) 1996,1999 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(LINT) && !defined(CODECENTER)
21static const char rcsid[] = "Id: gen_pr.c,v 1.3 2005/04/27 04:56:24 sra Exp";
22#endif
23
24/* Imports */
25
26#include "port_before.h"
27
28#include <sys/types.h>
29#include <netinet/in.h>
30#include <arpa/nameser.h>
31
32#include <errno.h>
33#include <resolv.h>
34#include <stdlib.h>
35#include <string.h>
36
37#include <isc/memcluster.h>
38#include <irs.h>
39
40#include "port_after.h"
41
42#include "irs_p.h"
43#include "gen_p.h"
44
45/* Types */
46
47struct pvt {
48	struct irs_rule *	rules;
49	struct irs_rule *	rule;
50	struct __res_state *	res;
51	void			(*free_res)(void *);
52};
53
54/* Forward */
55
56static void			pr_close(struct irs_pr*);
57static struct protoent *	pr_next(struct irs_pr *);
58static struct protoent *	pr_byname(struct irs_pr *, const char *);
59static struct protoent * 	pr_bynumber(struct irs_pr *, int);
60static void 			pr_rewind(struct irs_pr *);
61static void			pr_minimize(struct irs_pr *);
62static struct __res_state *	pr_res_get(struct irs_pr *);
63static void			pr_res_set(struct irs_pr *,
64					   struct __res_state *,
65					   void (*)(void *));
66
67/* Public */
68
69struct irs_pr *
70irs_gen_pr(struct irs_acc *this) {
71	struct gen_p *accpvt = (struct gen_p *)this->private;
72	struct irs_pr *pr;
73	struct pvt *pvt;
74
75	if (!(pr = memget(sizeof *pr))) {
76		errno = ENOMEM;
77		return (NULL);
78	}
79	memset(pr, 0x5e, sizeof *pr);
80	if (!(pvt = memget(sizeof *pvt))) {
81		memput(pr, sizeof *pr);
82		errno = ENOMEM;
83		return (NULL);
84	}
85	memset(pvt, 0, sizeof *pvt);
86	pvt->rules = accpvt->map_rules[irs_pr];
87	pvt->rule = pvt->rules;
88	pr->private = pvt;
89	pr->close = pr_close;
90	pr->next = pr_next;
91	pr->byname = pr_byname;
92	pr->bynumber = pr_bynumber;
93	pr->rewind = pr_rewind;
94	pr->minimize = pr_minimize;
95	pr->res_get = pr_res_get;
96	pr->res_set = pr_res_set;
97	return (pr);
98}
99
100/* Methods */
101
102static void
103pr_close(struct irs_pr *this) {
104	struct pvt *pvt = (struct pvt *)this->private;
105
106	memput(pvt, sizeof *pvt);
107	memput(this, sizeof *this);
108}
109
110static struct protoent *
111pr_next(struct irs_pr *this) {
112	struct pvt *pvt = (struct pvt *)this->private;
113	struct protoent *rval;
114	struct irs_pr *pr;
115
116	while (pvt->rule) {
117		pr = pvt->rule->inst->pr;
118		rval = (*pr->next)(pr);
119		if (rval)
120			return (rval);
121		if (!(pvt->rules->flags & IRS_CONTINUE))
122			break;
123		pvt->rule = pvt->rule->next;
124		if (pvt->rule) {
125			pr = pvt->rule->inst->pr;
126			(*pr->rewind)(pr);
127		}
128	}
129	return (NULL);
130}
131
132static struct protoent *
133pr_byname(struct irs_pr *this, const char *name) {
134	struct pvt *pvt = (struct pvt *)this->private;
135	struct irs_rule *rule;
136	struct protoent *rval;
137	struct irs_pr *pr;
138
139	rval = NULL;
140	for (rule = pvt->rules; rule; rule = rule->next) {
141		pr = rule->inst->pr;
142		rval = (*pr->byname)(pr, name);
143		if (rval || !(rule->flags & IRS_CONTINUE))
144			break;
145	}
146	return (rval);
147}
148
149static struct protoent *
150pr_bynumber(struct irs_pr *this, int proto) {
151	struct pvt *pvt = (struct pvt *)this->private;
152	struct irs_rule *rule;
153	struct protoent *rval;
154	struct irs_pr *pr;
155
156	rval = NULL;
157	for (rule = pvt->rules; rule; rule = rule->next) {
158		pr = rule->inst->pr;
159		rval = (*pr->bynumber)(pr, proto);
160		if (rval || !(rule->flags & IRS_CONTINUE))
161			break;
162	}
163	return (rval);
164}
165
166static void
167pr_rewind(struct irs_pr *this) {
168	struct pvt *pvt = (struct pvt *)this->private;
169	struct irs_pr *pr;
170
171	pvt->rule = pvt->rules;
172	if (pvt->rule) {
173		pr = pvt->rule->inst->pr;
174		(*pr->rewind)(pr);
175	}
176}
177
178static void
179pr_minimize(struct irs_pr *this) {
180	struct pvt *pvt = (struct pvt *)this->private;
181	struct irs_rule *rule;
182
183	for (rule = pvt->rules; rule != NULL; rule = rule->next) {
184		struct irs_pr *pr = rule->inst->pr;
185
186		(*pr->minimize)(pr);
187	}
188}
189
190static struct __res_state *
191pr_res_get(struct irs_pr *this) {
192	struct pvt *pvt = (struct pvt *)this->private;
193
194	if (!pvt->res) {
195		struct __res_state *res;
196		res = (struct __res_state *)malloc(sizeof *res);
197		if (!res) {
198			errno = ENOMEM;
199			return (NULL);
200		}
201		memset(res, 0, sizeof *res);
202		pr_res_set(this, res, free);
203	}
204
205	return (pvt->res);
206}
207
208static void
209pr_res_set(struct irs_pr *this, struct __res_state *res,
210		void (*free_res)(void *)) {
211	struct pvt *pvt = (struct pvt *)this->private;
212	struct irs_rule *rule;
213
214	if (pvt->res && pvt->free_res) {
215		res_nclose(pvt->res);
216		(*pvt->free_res)(pvt->res);
217	}
218
219	pvt->res = res;
220	pvt->free_res = free_res;
221
222	for (rule = pvt->rules; rule != NULL; rule = rule->next) {
223		struct irs_pr *pr = rule->inst->pr;
224
225		if (pr->res_set)
226			(*pr->res_set)(pr, pvt->res, NULL);
227	}
228}
229
230/*! \file */
231