4 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (c) 1996-1999 by Internet Software Consortium.
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
17 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 #if !defined(LINT) && !defined(CODECENTER)
21 static const char rcsid
[] = "Id: gen.c,v 1.7 2005/04/27 04:56:23 sra Exp";
26 * this is the top level dispatcher
28 * The dispatcher is implemented as an accessor class; it is an
29 * accessor class that calls other accessor classes, as controlled by a
32 * A big difference between this accessor class and others is that the
33 * map class initializers are NULL, and the map classes are already
34 * filled in with method functions that will do the right thing.
39 #include "port_before.h"
41 #include <isc/assertions.h>
48 #include <sys/types.h>
49 #include <netinet/in.h>
50 #include <arpa/nameser.h>
53 #include <isc/memcluster.h>
56 #include "port_after.h"
68 static const struct nameval acc_names
[irs_nacc
+1] = {
76 typedef struct irs_acc
*(*accinit
) __P((const char *options
));
78 static const accinit accs
[irs_nacc
+1] = {
90 static const struct nameval map_names
[irs_nmap
+1] = {
93 { "services", irs_sv
},
94 { "protocols", irs_pr
},
96 { "networks", irs_nw
},
97 { "netgroup", irs_ng
},
101 static const struct nameval option_names
[] = {
102 { "merge", IRS_MERGE
},
103 { "continue", IRS_CONTINUE
},
109 static void gen_close(struct irs_acc
*);
110 static struct __res_state
* gen_res_get(struct irs_acc
*);
111 static void gen_res_set(struct irs_acc
*, struct __res_state
*,
113 static int find_name(const char *, const struct nameval nv
[]);
114 static void init_map_rules(struct gen_p
*, const char *conf_file
);
115 static struct irs_rule
*release_rule(struct irs_rule
*);
116 static int add_rule(struct gen_p
*,
117 enum irs_map_id
, enum irs_acc_id
,
123 irs_gen_acc(const char *options
, const char *conf_file
) {
127 if (!(acc
= memget(sizeof *acc
))) {
131 memset(acc
, 0x5e, sizeof *acc
);
132 if (!(irs
= memget(sizeof *irs
))) {
134 memput(acc
, sizeof *acc
);
137 memset(irs
, 0x5e, sizeof *irs
);
138 irs
->options
= strdup(options
);
140 irs
->free_res
= NULL
;
141 memset(irs
->accessors
, 0, sizeof irs
->accessors
);
142 memset(irs
->map_rules
, 0, sizeof irs
->map_rules
);
143 init_map_rules(irs
, conf_file
);
146 acc
->gr_map
= irs_gen_gr
;
151 acc
->pw_map
= irs_gen_pw
;
155 acc
->sv_map
= irs_gen_sv
;
156 acc
->pr_map
= irs_gen_pr
;
157 acc
->ho_map
= irs_gen_ho
;
158 acc
->nw_map
= irs_gen_nw
;
159 acc
->ng_map
= irs_gen_ng
;
160 acc
->res_get
= gen_res_get
;
161 acc
->res_set
= gen_res_set
;
162 acc
->close
= gen_close
;
168 static struct __res_state
*
169 gen_res_get(struct irs_acc
*this) {
170 struct gen_p
*irs
= (struct gen_p
*)this->private;
172 if (irs
->res
== NULL
) {
173 struct __res_state
*res
;
174 res
= (struct __res_state
*)malloc(sizeof *res
);
177 memset(res
, 0, sizeof *res
);
178 gen_res_set(this, res
, free
);
181 if (((irs
->res
->options
& RES_INIT
) == 0U) && res_ninit(irs
->res
) < 0)
188 gen_res_set(struct irs_acc
*this, struct __res_state
*res
,
189 void (*free_res
)(void *)) {
190 struct gen_p
*irs
= (struct gen_p
*)this->private;
192 struct irs_rule
*rule
;
197 if (irs
->res
&& irs
->free_res
) {
198 res_nclose(irs
->res
);
199 (*irs
->free_res
)(irs
->res
);
203 irs
->free_res
= free_res
;
206 for (rule
= irs
->map_rules
[irs_ho
]; rule
; rule
= rule
->next
) {
209 (*ho
->res_set
)(ho
, res
, NULL
);
211 for (rule
= irs
->map_rules
[irs_nw
]; rule
; rule
= rule
->next
) {
214 (*nw
->res_set
)(nw
, res
, NULL
);
220 gen_close(struct irs_acc
*this) {
221 struct gen_p
*irs
= (struct gen_p
*)this->private;
225 for (n
= 0; n
< irs_nmap
; n
++)
226 while (irs
->map_rules
[n
] != NULL
)
227 irs
->map_rules
[n
] = release_rule(irs
->map_rules
[n
]);
229 /* Access methods. */
230 for (n
= 0; n
< irs_nacc
; n
++) {
232 if (irs
->accessors
[n
].gr
!= NULL
)
233 (*irs
->accessors
[n
].gr
->close
)(irs
->accessors
[n
].gr
);
234 if (irs
->accessors
[n
].pw
!= NULL
)
235 (*irs
->accessors
[n
].pw
->close
)(irs
->accessors
[n
].pw
);
236 if (irs
->accessors
[n
].sv
!= NULL
)
237 (*irs
->accessors
[n
].sv
->close
)(irs
->accessors
[n
].sv
);
238 if (irs
->accessors
[n
].pr
!= NULL
)
239 (*irs
->accessors
[n
].pr
->close
)(irs
->accessors
[n
].pr
);
240 if (irs
->accessors
[n
].ho
!= NULL
)
241 (*irs
->accessors
[n
].ho
->close
)(irs
->accessors
[n
].ho
);
242 if (irs
->accessors
[n
].nw
!= NULL
)
243 (*irs
->accessors
[n
].nw
->close
)(irs
->accessors
[n
].nw
);
244 if (irs
->accessors
[n
].ng
!= NULL
)
245 (*irs
->accessors
[n
].ng
->close
)(irs
->accessors
[n
].ng
);
246 /* Enclosing accessor. */
247 if (irs
->accessors
[n
].acc
!= NULL
)
248 (*irs
->accessors
[n
].acc
->close
)(irs
->accessors
[n
].acc
);
251 /* The options string was strdup'd. */
252 free((void*)irs
->options
);
254 if (irs
->res
&& irs
->free_res
)
255 (*irs
->free_res
)(irs
->res
);
257 /* The private data container. */
258 memput(irs
, sizeof *irs
);
261 memput(this, sizeof *this);
267 find_name(const char *name
, const struct nameval names
[]) {
270 for (n
= 0; names
[n
].name
!= NULL
; n
++)
271 if (strcmp(name
, names
[n
].name
) == 0)
272 return (names
[n
].val
);
276 static struct irs_rule
*
277 release_rule(struct irs_rule
*rule
) {
278 struct irs_rule
*next
= rule
->next
;
280 memput(rule
, sizeof *rule
);
285 add_rule(struct gen_p
*irs
,
286 enum irs_map_id map
, enum irs_acc_id acc
,
289 struct irs_rule
**rules
, *last
, *tmp
, *new;
290 struct irs_inst
*inst
;
306 new = memget(sizeof *new);
309 memset(new, 0x5e, sizeof *new);
312 new->inst
= &irs
->accessors
[acc
];
317 char option
[50], *next
;
319 next
= strchr(cp
, ',');
324 if ((size_t)n
> sizeof option
- 1)
325 n
= sizeof option
- 1;
326 strncpy(option
, cp
, n
);
329 n
= find_name(option
, option_names
);
336 rules
= &irs
->map_rules
[map
];
337 for (last
= NULL
, tmp
= *rules
;
339 last
= tmp
, tmp
= tmp
->next
)
346 /* Try to instantiate map accessors for this if necessary & approp. */
347 inst
= &irs
->accessors
[acc
];
348 if (inst
->acc
== NULL
&& accs
[acc
] != NULL
)
349 inst
->acc
= (*accs
[acc
])(irs
->options
);
350 if (inst
->acc
!= NULL
) {
351 if (inst
->gr
== NULL
&& inst
->acc
->gr_map
!= NULL
)
352 inst
->gr
= (*inst
->acc
->gr_map
)(inst
->acc
);
353 if (inst
->pw
== NULL
&& inst
->acc
->pw_map
!= NULL
)
354 inst
->pw
= (*inst
->acc
->pw_map
)(inst
->acc
);
355 if (inst
->sv
== NULL
&& inst
->acc
->sv_map
!= NULL
)
356 inst
->sv
= (*inst
->acc
->sv_map
)(inst
->acc
);
357 if (inst
->pr
== NULL
&& inst
->acc
->pr_map
!= NULL
)
358 inst
->pr
= (*inst
->acc
->pr_map
)(inst
->acc
);
359 if (inst
->ho
== NULL
&& inst
->acc
->ho_map
!= NULL
)
360 inst
->ho
= (*inst
->acc
->ho_map
)(inst
->acc
);
361 if (inst
->nw
== NULL
&& inst
->acc
->nw_map
!= NULL
)
362 inst
->nw
= (*inst
->acc
->nw_map
)(inst
->acc
);
363 if (inst
->ng
== NULL
&& inst
->acc
->ng_map
!= NULL
)
364 inst
->ng
= (*inst
->acc
->ng_map
)(inst
->acc
);
371 default_map_rules(struct gen_p
*irs
) {
372 /* Install time honoured and proved BSD style rules as default. */
373 add_rule(irs
, irs_gr
, irs_lcl
, "");
374 add_rule(irs
, irs_pw
, irs_lcl
, "");
375 add_rule(irs
, irs_sv
, irs_lcl
, "");
376 add_rule(irs
, irs_pr
, irs_lcl
, "");
377 add_rule(irs
, irs_ho
, irs_dns
, "continue");
378 add_rule(irs
, irs_ho
, irs_lcl
, "");
379 add_rule(irs
, irs_nw
, irs_dns
, "continue");
380 add_rule(irs
, irs_nw
, irs_lcl
, "");
381 add_rule(irs
, irs_ng
, irs_lcl
, "");
385 init_map_rules(struct gen_p
*irs
, const char *conf_file
) {
386 char line
[1024], pattern
[40], mapname
[20], accname
[20], options
[100];
389 if (conf_file
== NULL
)
390 conf_file
= _PATH_IRS_CONF
;
392 /* A conf file of "" means compiled in defaults. Irpd wants this */
393 if (conf_file
[0] == '\0' || (conf
= fopen(conf_file
, "r")) == NULL
) {
394 default_map_rules(irs
);
397 (void) sprintf(pattern
, "%%%lus %%%lus %%%lus\n",
398 (unsigned long)sizeof mapname
,
399 (unsigned long)sizeof accname
,
400 (unsigned long)sizeof options
);
401 while (fgets(line
, sizeof line
, conf
)) {
408 isascii((unsigned char)*tmp
) &&
409 isspace((unsigned char)*tmp
);
412 if (*tmp
== '#' || *tmp
== '\n' || *tmp
== '\0')
414 n
= sscanf(tmp
, pattern
, mapname
, accname
, options
);
420 n
= find_name(mapname
, map_names
);
421 INSIST(n
< irs_nmap
);
424 map
= (enum irs_map_id
) n
;
426 n
= find_name(accname
, acc_names
);
427 INSIST(n
< irs_nacc
);
430 acc
= (enum irs_acc_id
) n
;
432 add_rule(irs
, map
, acc
, options
);