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