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_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 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 pr_close(struct irs_pr*); 55 static struct protoent * pr_next(struct irs_pr *); 56 static struct protoent * pr_byname(struct irs_pr *, const char *); 57 static struct protoent * pr_bynumber(struct irs_pr *, int); 58 static void pr_rewind(struct irs_pr *); 59 static void pr_minimize(struct irs_pr *); 60 static struct __res_state * pr_res_get(struct irs_pr *); 61 static void pr_res_set(struct irs_pr *, 62 struct __res_state *, 63 void (*)(void *)); 64 65 /* Public */ 66 67 struct irs_pr * 68 irs_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 100 static void 101 pr_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 108 static struct protoent * 109 pr_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 130 static struct protoent * 131 pr_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 147 static struct protoent * 148 pr_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 164 static void 165 pr_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 176 static void 177 pr_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 188 static struct __res_state * 189 pr_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 206 static void 207 pr_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