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) 19static const char rcsid[] = "$Id: gen_pr.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 30#include <errno.h> 31#include <resolv.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 45struct 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 54static void pr_close(struct irs_pr*); 55static struct protoent * pr_next(struct irs_pr *); 56static struct protoent * pr_byname(struct irs_pr *, const char *); 57static struct protoent * pr_bynumber(struct irs_pr *, int); 58static void pr_rewind(struct irs_pr *); 59static void pr_minimize(struct irs_pr *); 60static struct __res_state * pr_res_get(struct irs_pr *); 61static void pr_res_set(struct irs_pr *, 62 struct __res_state *, 63 void (*)(void *)); 64 65/* Public */ 66 67struct irs_pr * 68irs_gen_pr(struct irs_acc *this) { 69 struct gen_p *accpvt = (struct gen_p *)this->private; 70 struct irs_pr *pr; 71 struct pvt *pvt; 72 73 if (!(pr = memget(sizeof *pr))) { 74 errno = ENOMEM; 75 return (NULL); 76 } 77 memset(pr, 0x5e, sizeof *pr); 78 if (!(pvt = memget(sizeof *pvt))) { 79 memput(pr, sizeof *pr); 80 errno = ENOMEM; 81 return (NULL); 82 } 83 memset(pvt, 0, sizeof *pvt); 84 pvt->rules = accpvt->map_rules[irs_pr]; 85 pvt->rule = pvt->rules; 86 pr->private = pvt; 87 pr->close = pr_close; 88 pr->next = pr_next; 89 pr->byname = pr_byname; 90 pr->bynumber = pr_bynumber; 91 pr->rewind = pr_rewind; 92 pr->minimize = pr_minimize; 93 pr->res_get = pr_res_get; 94 pr->res_set = pr_res_set; 95 return (pr); 96} 97 98/* Methods */ 99 100static void 101pr_close(struct irs_pr *this) { 102 struct pvt *pvt = (struct pvt *)this->private; 103 104 memput(pvt, sizeof *pvt); 105 memput(this, sizeof *this); 106} 107 108static struct protoent * 109pr_next(struct irs_pr *this) { 110 struct pvt *pvt = (struct pvt *)this->private; 111 struct protoent *rval; 112 struct irs_pr *pr; 113 114 while (pvt->rule) { 115 pr = pvt->rule->inst->pr; 116 rval = (*pr->next)(pr); 117 if (rval) 118 return (rval); 119 if (!(pvt->rules->flags & IRS_CONTINUE)) 120 break; 121 pvt->rule = pvt->rule->next; 122 if (pvt->rule) { 123 pr = pvt->rule->inst->pr; 124 (*pr->rewind)(pr); 125 } 126 } 127 return (NULL); 128} 129 130static struct protoent * 131pr_byname(struct irs_pr *this, const char *name) { 132 struct pvt *pvt = (struct pvt *)this->private; 133 struct irs_rule *rule; 134 struct protoent *rval; 135 struct irs_pr *pr; 136 137 rval = NULL; 138 for (rule = pvt->rules; rule; rule = rule->next) { 139 pr = rule->inst->pr; 140 rval = (*pr->byname)(pr, name); 141 if (rval || !(rule->flags & IRS_CONTINUE)) 142 break; 143 } 144 return (rval); 145} 146 147static struct protoent * 148pr_bynumber(struct irs_pr *this, int proto) { 149 struct pvt *pvt = (struct pvt *)this->private; 150 struct irs_rule *rule; 151 struct protoent *rval; 152 struct irs_pr *pr; 153 154 rval = NULL; 155 for (rule = pvt->rules; rule; rule = rule->next) { 156 pr = rule->inst->pr; 157 rval = (*pr->bynumber)(pr, proto); 158 if (rval || !(rule->flags & IRS_CONTINUE)) 159 break; 160 } 161 return (rval); 162} 163 164static void 165pr_rewind(struct irs_pr *this) { 166 struct pvt *pvt = (struct pvt *)this->private; 167 struct irs_pr *pr; 168 169 pvt->rule = pvt->rules; 170 if (pvt->rule) { 171 pr = pvt->rule->inst->pr; 172 (*pr->rewind)(pr); 173 } 174} 175 176static void 177pr_minimize(struct irs_pr *this) { 178 struct pvt *pvt = (struct pvt *)this->private; 179 struct irs_rule *rule; 180 181 for (rule = pvt->rules; rule != NULL; rule = rule->next) { 182 struct irs_pr *pr = rule->inst->pr; 183 184 (*pr->minimize)(pr); 185 } 186} 187 188static struct __res_state * 189pr_res_get(struct irs_pr *this) { 190 struct pvt *pvt = (struct pvt *)this->private; 191 192 if (!pvt->res) { 193 struct __res_state *res; 194 res = (struct __res_state *)malloc(sizeof *res); 195 if (!res) { 196 errno = ENOMEM; 197 return (NULL); 198 } 199 memset(res, 0, sizeof *res); 200 pr_res_set(this, res, free); 201 } 202 203 return (pvt->res); 204} 205 206static void 207pr_res_set(struct irs_pr *this, struct __res_state *res, 208 void (*free_res)(void *)) { 209 struct pvt *pvt = (struct pvt *)this->private; 210 struct irs_rule *rule; 211 212 if (pvt->res && pvt->free_res) { 213 res_nclose(pvt->res); 214 (*pvt->free_res)(pvt->res); 215 } 216 217 pvt->res = res; 218 pvt->free_res = free_res; 219 220 for (rule = pvt->rules; rule != NULL; rule = rule->next) { 221 struct irs_pr *pr = rule->inst->pr; 222 223 if (pr->res_set) 224 (*pr->res_set)(pr, pvt->res, NULL); 225 } 226} 227 228/*! \file */ 229