xref: /illumos-gate/usr/src/lib/libresolv2/common/irs/gen_sv.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1 /*
2  * Copyright (c) 1997-2000 by Sun Microsystems, Inc.
3  * All rights reserved.
4  */
5 
6 /*
7  * Copyright (c) 1996,1999 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(LINT) && !defined(CODECENTER)
26 static const char rcsid[] = "$Id: gen_sv.c,v 1.12 1999/10/13 16:39:30 vixie Exp $";
27 #endif
28 
29 /* Imports */
30 
31 #include "port_before.h"
32 
33 #include <sys/types.h>
34 #include <netinet/in.h>
35 #include <arpa/nameser.h>
36 #include <resolv.h>
37 
38 #include <errno.h>
39 #include <stdlib.h>
40 #include <string.h>
41 
42 #include <isc/memcluster.h>
43 #include <irs.h>
44 
45 #include "port_after.h"
46 
47 #include "irs_p.h"
48 #include "gen_p.h"
49 
50 /* Types */
51 
52 struct pvt {
53 	struct irs_rule *	rules;
54 	struct irs_rule *	rule;
55 	struct __res_state *	res;
56 	void			(*free_res)(void *);
57 };
58 
59 /* Forward */
60 
61 static void			sv_close(struct irs_sv*);
62 static struct servent *		sv_next(struct irs_sv *);
63 static struct servent *		sv_byname(struct irs_sv *, const char *,
64 					  const char *);
65 static struct servent *		sv_byport(struct irs_sv *, int, const char *);
66 static void			sv_rewind(struct irs_sv *);
67 static void			sv_minimize(struct irs_sv *);
68 static struct __res_state *	sv_res_get(struct irs_sv *);
69 static void			sv_res_set(struct irs_sv *,
70 					      struct __res_state *,
71 					      void (*)(void *));
72 
73 /* Public */
74 
75 struct irs_sv *
76 irs_gen_sv(struct irs_acc *this) {
77 	struct gen_p *accpvt = (struct gen_p *)this->private;
78 	struct irs_sv *sv;
79 	struct pvt *pvt;
80 
81 	if (!(sv = memget(sizeof *sv))) {
82 		errno = ENOMEM;
83 		return (NULL);
84 	}
85 	memset(sv, 0x5e, sizeof *sv);
86 	if (!(pvt = memget(sizeof *pvt))) {
87 		memput(sv, sizeof *sv);
88 		errno = ENOMEM;
89 		return (NULL);
90 	}
91 	memset(pvt, 0, sizeof *pvt);
92 	pvt->rules = accpvt->map_rules[irs_sv];
93 	pvt->rule = pvt->rules;
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;
101 	sv->res_get = sv_res_get;
102 	sv->res_set = sv_res_set;
103 	return (sv);
104 }
105 
106 /* Methods */
107 
108 static void
109 sv_close(struct irs_sv *this) {
110 	struct pvt *pvt = (struct pvt *)this->private;
111 
112 	memput(pvt, sizeof *pvt);
113 	memput(this, sizeof *this);
114 }
115 
116 static struct servent *
117 sv_next(struct irs_sv *this) {
118 	struct pvt *pvt = (struct pvt *)this->private;
119 	struct servent *rval;
120 	struct irs_sv *sv;
121 
122 	while (pvt->rule) {
123 		sv = pvt->rule->inst->sv;
124 		rval = (*sv->next)(sv);
125 		if (rval)
126 			return (rval);
127 		if (!(pvt->rule->flags & IRS_CONTINUE))
128 			break;
129 		pvt->rule = pvt->rule->next;
130 		if (pvt->rule) {
131 			sv = pvt->rule->inst->sv;
132 			(*sv->rewind)(sv);
133 		}
134 	}
135 	return (NULL);
136 }
137 
138 static struct servent *
139 sv_byname(struct irs_sv *this, const char *name, const char *proto) {
140 	struct pvt *pvt = (struct pvt *)this->private;
141 	struct irs_rule *rule;
142 	struct servent *rval;
143 	struct irs_sv *sv;
144 
145 	rval = NULL;
146 	for (rule = pvt->rules; rule; rule = rule->next) {
147 		sv = rule->inst->sv;
148 		rval = (*sv->byname)(sv, name, proto);
149 		if (rval || !(rule->flags & IRS_CONTINUE))
150 			break;
151 	}
152 	return (rval);
153 }
154 
155 static struct servent *
156 sv_byport(struct irs_sv *this, int port, const char *proto) {
157 	struct pvt *pvt = (struct pvt *)this->private;
158 	struct irs_rule *rule;
159 	struct servent *rval;
160 	struct irs_sv *sv;
161 
162 	rval = NULL;
163 	for (rule = pvt->rules; rule; rule = rule->next) {
164 		sv = rule->inst->sv;
165 		rval = (*sv->byport)(sv, port, proto);
166 		if (rval || !(rule->flags & IRS_CONTINUE))
167 			break;
168 	}
169 	return (rval);
170 }
171 
172 static void
173 sv_rewind(struct irs_sv *this) {
174 	struct pvt *pvt = (struct pvt *)this->private;
175 	struct irs_sv *sv;
176 
177 	pvt->rule = pvt->rules;
178 	if (pvt->rule) {
179 		sv = pvt->rule->inst->sv;
180 		(*sv->rewind)(sv);
181 	}
182 }
183 
184 static void
185 sv_minimize(struct irs_sv *this) {
186 	struct pvt *pvt = (struct pvt *)this->private;
187 	struct irs_rule *rule;
188 
189 	for (rule = pvt->rules; rule != NULL; rule = rule->next) {
190 		struct irs_sv *sv = rule->inst->sv;
191 
192 		(*sv->minimize)(sv);
193 	}
194 }
195 
196 static struct __res_state *
197 sv_res_get(struct irs_sv *this) {
198 	struct pvt *pvt = (struct pvt *)this->private;
199 
200 	if (!pvt->res) {
201 		struct __res_state *res;
202 		res = (struct __res_state *)malloc(sizeof *res);
203 		if (!res) {
204 			errno = ENOMEM;
205 			return (NULL);
206 		}
207 		memset(res, 0, sizeof *res);
208 		sv_res_set(this, res, free);
209 	}
210 
211 	return (pvt->res);
212 }
213 
214 static void
215 sv_res_set(struct irs_sv *this, struct __res_state *res,
216 		void (*free_res)(void *)) {
217 	struct pvt *pvt = (struct pvt *)this->private;
218 	struct irs_rule *rule;
219 
220 	if (pvt->res && pvt->free_res) {
221 		res_nclose(pvt->res);
222 		(*pvt->free_res)(pvt->res);
223 	}
224 
225 	pvt->res = res;
226 	pvt->free_res = free_res;
227 
228 	for (rule = pvt->rules; rule != NULL; rule = rule->next) {
229 		struct irs_sv *sv = rule->inst->sv;
230 
231 		if (sv->res_set)
232 			(*sv->res_set)(sv, pvt->res, NULL);
233 	}
234 }
235