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.7 2005/04/27 04:56:23 sra Exp $";
24 * this is the top level dispatcher
26 * The dispatcher is implemented as an accessor class; it is an
27 * accessor class that calls other accessor classes, as controlled by a
30 * A big difference between this accessor class and others is that the
31 * map class initializers are NULL, and the map classes are already
32 * filled in with method functions that will do the right thing.
37 #include "port_before.h"
39 #include <isc/assertions.h>
46 #include <sys/types.h>
47 #include <netinet/in.h>
48 #include <arpa/nameser.h>
51 #include <isc/memcluster.h>
54 #include "port_after.h"
66 static const struct nameval acc_names
[irs_nacc
+1] = {
74 typedef struct irs_acc
*(*accinit
) __P((const char *options
));
76 static const accinit accs
[irs_nacc
+1] = {
88 static const struct nameval map_names
[irs_nmap
+1] = {
91 { "services", irs_sv
},
92 { "protocols", irs_pr
},
94 { "networks", irs_nw
},
95 { "netgroup", irs_ng
},
99 static const struct nameval option_names
[] = {
100 { "merge", IRS_MERGE
},
101 { "continue", IRS_CONTINUE
},
107 static void gen_close(struct irs_acc
*);
108 static struct __res_state
* gen_res_get(struct irs_acc
*);
109 static void gen_res_set(struct irs_acc
*, struct __res_state
*,
111 static int find_name(const char *, const struct nameval nv
[]);
112 static void init_map_rules(struct gen_p
*, const char *conf_file
);
113 static struct irs_rule
*release_rule(struct irs_rule
*);
114 static int add_rule(struct gen_p
*,
115 enum irs_map_id
, enum irs_acc_id
,
121 irs_gen_acc(const char *options
, const char *conf_file
) {
125 if (!(acc
= memget(sizeof *acc
))) {
129 memset(acc
, 0x5e, sizeof *acc
);
130 if (!(irs
= memget(sizeof *irs
))) {
132 memput(acc
, sizeof *acc
);
135 memset(irs
, 0x5e, sizeof *irs
);
136 irs
->options
= strdup(options
);
138 irs
->free_res
= NULL
;
139 memset(irs
->accessors
, 0, sizeof irs
->accessors
);
140 memset(irs
->map_rules
, 0, sizeof irs
->map_rules
);
141 init_map_rules(irs
, conf_file
);
144 acc
->gr_map
= irs_gen_gr
;
149 acc
->pw_map
= irs_gen_pw
;
153 acc
->sv_map
= irs_gen_sv
;
154 acc
->pr_map
= irs_gen_pr
;
155 acc
->ho_map
= irs_gen_ho
;
156 acc
->nw_map
= irs_gen_nw
;
157 acc
->ng_map
= irs_gen_ng
;
158 acc
->res_get
= gen_res_get
;
159 acc
->res_set
= gen_res_set
;
160 acc
->close
= gen_close
;
166 static struct __res_state
*
167 gen_res_get(struct irs_acc
*this) {
168 struct gen_p
*irs
= (struct gen_p
*)this->private;
170 if (irs
->res
== NULL
) {
171 struct __res_state
*res
;
172 res
= (struct __res_state
*)malloc(sizeof *res
);
175 memset(res
, 0, sizeof *res
);
176 gen_res_set(this, res
, free
);
179 if (((irs
->res
->options
& RES_INIT
) == 0U) && res_ninit(irs
->res
) < 0)
186 gen_res_set(struct irs_acc
*this, struct __res_state
*res
,
187 void (*free_res
)(void *)) {
188 struct gen_p
*irs
= (struct gen_p
*)this->private;
190 struct irs_rule
*rule
;
195 if (irs
->res
&& irs
->free_res
) {
196 res_nclose(irs
->res
);
197 (*irs
->free_res
)(irs
->res
);
201 irs
->free_res
= free_res
;
204 for (rule
= irs
->map_rules
[irs_ho
]; rule
; rule
= rule
->next
) {
207 (*ho
->res_set
)(ho
, res
, NULL
);
209 for (rule
= irs
->map_rules
[irs_nw
]; rule
; rule
= rule
->next
) {
212 (*nw
->res_set
)(nw
, res
, NULL
);
218 gen_close(struct irs_acc
*this) {
219 struct gen_p
*irs
= (struct gen_p
*)this->private;
223 for (n
= 0; n
< irs_nmap
; n
++)
224 while (irs
->map_rules
[n
] != NULL
)
225 irs
->map_rules
[n
] = release_rule(irs
->map_rules
[n
]);
227 /* Access methods. */
228 for (n
= 0; n
< irs_nacc
; n
++) {
230 if (irs
->accessors
[n
].gr
!= NULL
)
231 (*irs
->accessors
[n
].gr
->close
)(irs
->accessors
[n
].gr
);
232 if (irs
->accessors
[n
].pw
!= NULL
)
233 (*irs
->accessors
[n
].pw
->close
)(irs
->accessors
[n
].pw
);
234 if (irs
->accessors
[n
].sv
!= NULL
)
235 (*irs
->accessors
[n
].sv
->close
)(irs
->accessors
[n
].sv
);
236 if (irs
->accessors
[n
].pr
!= NULL
)
237 (*irs
->accessors
[n
].pr
->close
)(irs
->accessors
[n
].pr
);
238 if (irs
->accessors
[n
].ho
!= NULL
)
239 (*irs
->accessors
[n
].ho
->close
)(irs
->accessors
[n
].ho
);
240 if (irs
->accessors
[n
].nw
!= NULL
)
241 (*irs
->accessors
[n
].nw
->close
)(irs
->accessors
[n
].nw
);
242 if (irs
->accessors
[n
].ng
!= NULL
)
243 (*irs
->accessors
[n
].ng
->close
)(irs
->accessors
[n
].ng
);
244 /* Enclosing accessor. */
245 if (irs
->accessors
[n
].acc
!= NULL
)
246 (*irs
->accessors
[n
].acc
->close
)(irs
->accessors
[n
].acc
);
249 /* The options string was strdup'd. */
250 free((void*)irs
->options
);
252 if (irs
->res
&& irs
->free_res
)
253 (*irs
->free_res
)(irs
->res
);
255 /* The private data container. */
256 memput(irs
, sizeof *irs
);
259 memput(this, sizeof *this);
265 find_name(const char *name
, const struct nameval names
[]) {
268 for (n
= 0; names
[n
].name
!= NULL
; n
++)
269 if (strcmp(name
, names
[n
].name
) == 0)
270 return (names
[n
].val
);
274 static struct irs_rule
*
275 release_rule(struct irs_rule
*rule
) {
276 struct irs_rule
*next
= rule
->next
;
278 memput(rule
, sizeof *rule
);
283 add_rule(struct gen_p
*irs
,
284 enum irs_map_id map
, enum irs_acc_id acc
,
287 struct irs_rule
**rules
, *last
, *tmp
, *new;
288 struct irs_inst
*inst
;
304 new = memget(sizeof *new);
307 memset(new, 0x5e, sizeof *new);
310 new->inst
= &irs
->accessors
[acc
];
315 char option
[50], *next
;
317 next
= strchr(cp
, ',');
322 if ((size_t)n
> sizeof option
- 1)
323 n
= sizeof option
- 1;
324 strncpy(option
, cp
, n
);
327 n
= find_name(option
, option_names
);
334 rules
= &irs
->map_rules
[map
];
335 for (last
= NULL
, tmp
= *rules
;
337 last
= tmp
, tmp
= tmp
->next
)
344 /* Try to instantiate map accessors for this if necessary & approp. */
345 inst
= &irs
->accessors
[acc
];
346 if (inst
->acc
== NULL
&& accs
[acc
] != NULL
)
347 inst
->acc
= (*accs
[acc
])(irs
->options
);
348 if (inst
->acc
!= NULL
) {
349 if (inst
->gr
== NULL
&& inst
->acc
->gr_map
!= NULL
)
350 inst
->gr
= (*inst
->acc
->gr_map
)(inst
->acc
);
351 if (inst
->pw
== NULL
&& inst
->acc
->pw_map
!= NULL
)
352 inst
->pw
= (*inst
->acc
->pw_map
)(inst
->acc
);
353 if (inst
->sv
== NULL
&& inst
->acc
->sv_map
!= NULL
)
354 inst
->sv
= (*inst
->acc
->sv_map
)(inst
->acc
);
355 if (inst
->pr
== NULL
&& inst
->acc
->pr_map
!= NULL
)
356 inst
->pr
= (*inst
->acc
->pr_map
)(inst
->acc
);
357 if (inst
->ho
== NULL
&& inst
->acc
->ho_map
!= NULL
)
358 inst
->ho
= (*inst
->acc
->ho_map
)(inst
->acc
);
359 if (inst
->nw
== NULL
&& inst
->acc
->nw_map
!= NULL
)
360 inst
->nw
= (*inst
->acc
->nw_map
)(inst
->acc
);
361 if (inst
->ng
== NULL
&& inst
->acc
->ng_map
!= NULL
)
362 inst
->ng
= (*inst
->acc
->ng_map
)(inst
->acc
);
369 default_map_rules(struct gen_p
*irs
) {
370 /* Install time honoured and proved BSD style rules as default. */
371 add_rule(irs
, irs_gr
, irs_lcl
, "");
372 add_rule(irs
, irs_pw
, irs_lcl
, "");
373 add_rule(irs
, irs_sv
, irs_lcl
, "");
374 add_rule(irs
, irs_pr
, irs_lcl
, "");
375 add_rule(irs
, irs_ho
, irs_dns
, "continue");
376 add_rule(irs
, irs_ho
, irs_lcl
, "");
377 add_rule(irs
, irs_nw
, irs_dns
, "continue");
378 add_rule(irs
, irs_nw
, irs_lcl
, "");
379 add_rule(irs
, irs_ng
, irs_lcl
, "");
383 init_map_rules(struct gen_p
*irs
, const char *conf_file
) {
384 char line
[1024], pattern
[40], mapname
[20], accname
[20], options
[100];
387 if (conf_file
== NULL
)
388 conf_file
= _PATH_IRS_CONF
;
390 /* A conf file of "" means compiled in defaults. Irpd wants this */
391 if (conf_file
[0] == '\0' || (conf
= fopen(conf_file
, "r")) == NULL
) {
392 default_map_rules(irs
);
395 (void) sprintf(pattern
, "%%%lus %%%lus %%%lus\n",
396 (unsigned long)sizeof mapname
,
397 (unsigned long)sizeof accname
,
398 (unsigned long)sizeof options
);
399 while (fgets(line
, sizeof line
, conf
)) {
406 isascii((unsigned char)*tmp
) &&
407 isspace((unsigned char)*tmp
);
410 if (*tmp
== '#' || *tmp
== '\n' || *tmp
== '\0')
412 n
= sscanf(tmp
, pattern
, mapname
, accname
, options
);
418 n
= find_name(mapname
, map_names
);
419 INSIST(n
< irs_nmap
);
422 map
= (enum irs_map_id
) n
;
424 n
= find_name(accname
, acc_names
);
425 INSIST(n
< irs_nacc
);
428 acc
= (enum irs_acc_id
) n
;
430 add_rule(irs
, map
, acc
, options
);