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