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