2 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (c) 1996-1999 by Internet Software Consortium.
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.
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.
18 #if !defined(LINT) && !defined(CODECENTER)
19 static const char rcsid[] = "$Id: gen.c,v 1.3.2.2 2004/03/17 00:40:12 marka Exp $";
23 * this is the top level dispatcher
25 * The dispatcher is implemented as an accessor class; it is an
26 * accessor class that calls other accessor classes, as controlled by a
29 * A big difference between this accessor class and others is that the
30 * map class initializers are NULL, and the map classes are already
31 * filled in with method functions that will do the right thing.
36 #include "port_before.h"
38 #include <isc/assertions.h>
45 #include <sys/types.h>
46 #include <netinet/in.h>
47 #include <arpa/nameser.h>
50 #include <isc/memcluster.h>
53 #include "port_after.h"
65 static const struct nameval acc_names[irs_nacc+1] = {
73 typedef struct irs_acc *(*accinit) __P((const char *options));
75 static const accinit accs[irs_nacc+1] = {
87 static const struct nameval map_names[irs_nmap+1] = {
90 { "services", irs_sv },
91 { "protocols", irs_pr },
93 { "networks", irs_nw },
94 { "netgroup", irs_ng },
98 static const struct nameval option_names[] = {
99 { "merge", IRS_MERGE },
100 { "continue", IRS_CONTINUE },
106 static void gen_close(struct irs_acc *);
107 static struct __res_state * gen_res_get(struct irs_acc *);
108 static void gen_res_set(struct irs_acc *, struct __res_state *,
110 static int find_name(const char *, const struct nameval nv[]);
111 static void init_map_rules(struct gen_p *, const char *conf_file);
112 static struct irs_rule *release_rule(struct irs_rule *);
113 static int add_rule(struct gen_p *,
114 enum irs_map_id, enum irs_acc_id,
120 irs_gen_acc(const char *options, const char *conf_file) {
124 if (!(acc = memget(sizeof *acc))) {
128 memset(acc, 0x5e, sizeof *acc);
129 if (!(irs = memget(sizeof *irs))) {
131 memput(acc, sizeof *acc);
134 memset(irs, 0x5e, sizeof *irs);
135 irs->options = strdup(options);
137 irs->free_res = NULL;
138 memset(irs->accessors, 0, sizeof irs->accessors);
139 memset(irs->map_rules, 0, sizeof irs->map_rules);
140 init_map_rules(irs, conf_file);
143 acc->gr_map = irs_gen_gr;
148 acc->pw_map = irs_gen_pw;
152 acc->sv_map = irs_gen_sv;
153 acc->pr_map = irs_gen_pr;
154 acc->ho_map = irs_gen_ho;
155 acc->nw_map = irs_gen_nw;
156 acc->ng_map = irs_gen_ng;
157 acc->res_get = gen_res_get;
158 acc->res_set = gen_res_set;
159 acc->close = gen_close;
165 static struct __res_state *
166 gen_res_get(struct irs_acc *this) {
167 struct gen_p *irs = (struct gen_p *)this->private;
169 if (irs->res == NULL) {
170 struct __res_state *res;
171 res = (struct __res_state *)malloc(sizeof *res);
174 memset(res, 0, sizeof *res);
175 gen_res_set(this, res, free);
178 if (((irs->res->options & RES_INIT) == 0U) && res_ninit(irs->res) < 0)
185 gen_res_set(struct irs_acc *this, struct __res_state *res,
186 void (*free_res)(void *)) {
187 struct gen_p *irs = (struct gen_p *)this->private;
189 struct irs_rule *rule;
194 if (irs->res && irs->free_res) {
195 res_nclose(irs->res);
196 (*irs->free_res)(irs->res);
200 irs->free_res = free_res;
203 for (rule = irs->map_rules[irs_ho]; rule; rule = rule->next) {
206 (*ho->res_set)(ho, res, NULL);
208 for (rule = irs->map_rules[irs_nw]; rule; rule = rule->next) {
211 (*nw->res_set)(nw, res, NULL);
217 gen_close(struct irs_acc *this) {
218 struct gen_p *irs = (struct gen_p *)this->private;
222 for (n = 0; n < irs_nmap; n++)
223 while (irs->map_rules[n] != NULL)
224 irs->map_rules[n] = release_rule(irs->map_rules[n]);
226 /* Access methods. */
227 for (n = 0; n < irs_nacc; n++) {
229 if (irs->accessors[n].gr != NULL)
230 (*irs->accessors[n].gr->close)(irs->accessors[n].gr);
231 if (irs->accessors[n].pw != NULL)
232 (*irs->accessors[n].pw->close)(irs->accessors[n].pw);
233 if (irs->accessors[n].sv != NULL)
234 (*irs->accessors[n].sv->close)(irs->accessors[n].sv);
235 if (irs->accessors[n].pr != NULL)
236 (*irs->accessors[n].pr->close)(irs->accessors[n].pr);
237 if (irs->accessors[n].ho != NULL)
238 (*irs->accessors[n].ho->close)(irs->accessors[n].ho);
239 if (irs->accessors[n].nw != NULL)
240 (*irs->accessors[n].nw->close)(irs->accessors[n].nw);
241 if (irs->accessors[n].ng != NULL)
242 (*irs->accessors[n].ng->close)(irs->accessors[n].ng);
243 /* Enclosing accessor. */
244 if (irs->accessors[n].acc != NULL)
245 (*irs->accessors[n].acc->close)(irs->accessors[n].acc);
248 /* The options string was strdup'd. */
249 free((void*)irs->options);
251 if (irs->res && irs->free_res)
252 (*irs->free_res)(irs->res);
254 /* The private data container. */
255 memput(irs, sizeof *irs);
258 memput(this, sizeof *this);
264 find_name(const char *name, const struct nameval names[]) {
267 for (n = 0; names[n].name != NULL; n++)
268 if (strcmp(name, names[n].name) == 0)
269 return (names[n].val);
273 static struct irs_rule *
274 release_rule(struct irs_rule *rule) {
275 struct irs_rule *next = rule->next;
277 memput(rule, sizeof *rule);
282 add_rule(struct gen_p *irs,
283 enum irs_map_id map, enum irs_acc_id acc,
286 struct irs_rule **rules, *last, *tmp, *new;
287 struct irs_inst *inst;
303 new = memget(sizeof *new);
306 memset(new, 0x5e, sizeof *new);
309 new->inst = &irs->accessors[acc];
314 char option[50], *next;
316 next = strchr(cp, ',');
321 if ((size_t)n > sizeof option - 1)
322 n = sizeof option - 1;
323 strncpy(option, cp, n);
326 n = find_name(option, option_names);
333 rules = &irs->map_rules[map];
334 for (last = NULL, tmp = *rules;
336 last = tmp, tmp = tmp->next)
343 /* Try to instantiate map accessors for this if necessary & approp. */
344 inst = &irs->accessors[acc];
345 if (inst->acc == NULL && accs[acc] != NULL)
346 inst->acc = (*accs[acc])(irs->options);
347 if (inst->acc != NULL) {
348 if (inst->gr == NULL && inst->acc->gr_map != NULL)
349 inst->gr = (*inst->acc->gr_map)(inst->acc);
350 if (inst->pw == NULL && inst->acc->pw_map != NULL)
351 inst->pw = (*inst->acc->pw_map)(inst->acc);
352 if (inst->sv == NULL && inst->acc->sv_map != NULL)
353 inst->sv = (*inst->acc->sv_map)(inst->acc);
354 if (inst->pr == NULL && inst->acc->pr_map != NULL)
355 inst->pr = (*inst->acc->pr_map)(inst->acc);
356 if (inst->ho == NULL && inst->acc->ho_map != NULL)
357 inst->ho = (*inst->acc->ho_map)(inst->acc);
358 if (inst->nw == NULL && inst->acc->nw_map != NULL)
359 inst->nw = (*inst->acc->nw_map)(inst->acc);
360 if (inst->ng == NULL && inst->acc->ng_map != NULL)
361 inst->ng = (*inst->acc->ng_map)(inst->acc);
368 default_map_rules(struct gen_p *irs) {
369 /* Install time honoured and proved BSD style rules as default. */
370 add_rule(irs, irs_gr, irs_lcl, "");
371 add_rule(irs, irs_pw, irs_lcl, "");
372 add_rule(irs, irs_sv, irs_lcl, "");
373 add_rule(irs, irs_pr, irs_lcl, "");
374 add_rule(irs, irs_ho, irs_dns, "continue");
375 add_rule(irs, irs_ho, irs_lcl, "");
376 add_rule(irs, irs_nw, irs_dns, "continue");
377 add_rule(irs, irs_nw, irs_lcl, "");
378 add_rule(irs, irs_ng, irs_lcl, "");
382 init_map_rules(struct gen_p *irs, const char *conf_file) {
383 char line[1024], pattern[40], mapname[20], accname[20], options[100];
386 if (conf_file == NULL)
387 conf_file = _PATH_IRS_CONF ;
389 /* A conf file of "" means compiled in defaults. Irpd wants this */
390 if (conf_file[0] == '\0' || (conf = fopen(conf_file, "r")) == NULL) {
391 default_map_rules(irs);
394 (void) sprintf(pattern, "%%%ds %%%ds %%%ds\n",
395 sizeof mapname, sizeof accname, sizeof options);
396 while (fgets(line, sizeof line, conf)) {
403 isascii((unsigned char)*tmp) &&
404 isspace((unsigned char)*tmp);
407 if (*tmp == '#' || *tmp == '\n' || *tmp == '\0')
409 n = sscanf(tmp, pattern, mapname, accname, options);
415 n = find_name(mapname, map_names);
416 INSIST(n < irs_nmap);
419 map = (enum irs_map_id) n;
421 n = find_name(accname, acc_names);
422 INSIST(n < irs_nacc);
425 acc = (enum irs_acc_id) n;
427 add_rule(irs, map, acc, options);