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/* Imports */
19
20#include "port_before.h"
21
22#include <sys/types.h>
23
24#include <netinet/in.h>
25#include <arpa/nameser.h>
26#include <resolv.h>
27
28#include <errno.h>
29#include <stdlib.h>
30#include <string.h>
31
32#include <isc/memcluster.h>
33#include <irs.h>
34
35#include "port_after.h"
36
37#include "irs_p.h"
38#include "gen_p.h"
39
40/* Types */
41
42struct pvt {
43	struct irs_rule *	rules;
44	struct irs_rule *	rule;
45	char *			curgroup;
46};
47
48/* Forward */
49
50static void		ng_close(struct irs_ng *);
51static int		ng_next(struct irs_ng *, const char **,
52				const char **, const char **);
53static int 		ng_test(struct irs_ng *, const char *,
54				const char *, const char *,
55				const char *);
56static void 		ng_rewind(struct irs_ng *, const char *);
57static void		ng_minimize(struct irs_ng *);
58
59/* Public */
60
61struct irs_ng *
62irs_gen_ng(struct irs_acc *this) {
63	struct gen_p *accpvt = (struct gen_p *)this->private;
64	struct irs_ng *ng;
65	struct pvt *pvt;
66
67	if (!(ng = memget(sizeof *ng))) {
68		errno = ENOMEM;
69		return (NULL);
70	}
71	memset(ng, 0x5e, sizeof *ng);
72	if (!(pvt = memget(sizeof *pvt))) {
73		memput(ng, sizeof *ng);
74		errno = ENOMEM;
75		return (NULL);
76	}
77	memset(pvt, 0, sizeof *pvt);
78	pvt->rules = accpvt->map_rules[irs_ng];
79	pvt->rule = pvt->rules;
80	ng->private = pvt;
81	ng->close = ng_close;
82	ng->next = ng_next;
83	ng->test = ng_test;
84	ng->rewind = ng_rewind;
85	ng->minimize = ng_minimize;
86	return (ng);
87}
88
89/* Methods */
90
91static void
92ng_close(struct irs_ng *this) {
93	struct pvt *pvt = (struct pvt *)this->private;
94
95	ng_minimize(this);
96	if (pvt->curgroup)
97		free(pvt->curgroup);
98	memput(pvt, sizeof *pvt);
99	memput(this, sizeof *this);
100}
101
102static int
103ng_next(struct irs_ng *this, const char **host, const char **user,
104	const char **domain)
105{
106	struct pvt *pvt = (struct pvt *)this->private;
107	struct irs_ng *ng;
108
109	while (pvt->rule) {
110		ng = pvt->rule->inst->ng;
111		if ((*ng->next)(ng, host, user, domain) == 1)
112			return (1);
113		if (!(pvt->rule->flags & IRS_CONTINUE))
114			break;
115		pvt->rule = pvt->rule->next;
116		if (pvt->rule) {
117			ng = pvt->rule->inst->ng;
118			(*ng->rewind)(ng, pvt->curgroup);
119		}
120	}
121	return (0);
122}
123
124static int
125ng_test(struct irs_ng *this, const char *name,
126	const char *user, const char *host, const char *domain)
127{
128	struct pvt *pvt = (struct pvt *)this->private;
129	struct irs_rule *rule;
130	struct irs_ng *ng;
131	int rval;
132
133	rval = 0;
134	for (rule = pvt->rules; rule; rule = rule->next) {
135		ng = rule->inst->ng;
136		rval = (*ng->test)(ng, name, user, host, domain);
137		if (rval || !(rule->flags & IRS_CONTINUE))
138			break;
139	}
140	return (rval);
141}
142
143static void
144ng_rewind(struct irs_ng *this, const char *group) {
145	struct pvt *pvt = (struct pvt *)this->private;
146	struct irs_ng *ng;
147
148	pvt->rule = pvt->rules;
149	if (pvt->rule) {
150		if (pvt->curgroup)
151			free(pvt->curgroup);
152		pvt->curgroup = strdup(group);
153		ng = pvt->rule->inst->ng;
154		(*ng->rewind)(ng, pvt->curgroup);
155	}
156}
157
158static void
159ng_minimize(struct irs_ng *this) {
160	struct pvt *pvt = (struct pvt *)this->private;
161	struct irs_rule *rule;
162
163	for (rule = pvt->rules; rule != NULL; rule = rule->next) {
164		struct irs_ng *ng = rule->inst->ng;
165
166		(*ng->minimize)(ng);
167	}
168}
169
170/*! \file */
171