]> git.ipfire.org Git - thirdparty/squid.git/blob - src/acl/BoolOps.cc
Support for --long-acl-options
[thirdparty/squid.git] / src / acl / BoolOps.cc
1 /*
2 * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9 #include "squid.h"
10 #include "acl/BoolOps.h"
11 #include "acl/Checklist.h"
12 #include "Debug.h"
13 #include "sbuf/SBuf.h"
14
15 /* Acl::NotNode */
16
17 Acl::NotNode::NotNode(ACL *acl)
18 {
19 assert(acl);
20 name[0] = '!';
21 name[1] = '\0';
22 strncat(&name[1], acl->name, sizeof(name)-1-1);
23 add(acl);
24 }
25
26 void
27 Acl::NotNode::parse()
28 {
29 // Not implemented: by the time an upper level parser discovers
30 // an '!' operator, there is nothing left for us to parse.
31 assert(false);
32 }
33
34 int
35 Acl::NotNode::doMatch(ACLChecklist *checklist, Nodes::const_iterator start) const
36 {
37 assert(start == nodes.begin()); // we only have one node
38
39 if (checklist->matchChild(this, start, *start))
40 return 0; // converting match into mismatch
41
42 if (!checklist->keepMatching())
43 return -1; // suspend on async calls and stop on failures
44
45 return 1; // converting mismatch into match
46 }
47
48 char const *
49 Acl::NotNode::typeString() const
50 {
51 return "!";
52 }
53
54 ACL *
55 Acl::NotNode::clone() const
56 {
57 // Not implemented: we are not a named ACL type in squid.conf so nobody
58 // should try to create a NotNode instance by ACL type name (which is
59 // what clone() API is for -- it does not really clone anything).
60 assert(false);
61 return NULL;
62 }
63
64 SBufList
65 Acl::NotNode::dump() const
66 {
67 SBufList text;
68 text.push_back(SBuf(name));
69 return text;
70 }
71
72 /* Acl::AndNode */
73
74 char const *
75 Acl::AndNode::typeString() const
76 {
77 return "and";
78 }
79
80 ACL *
81 Acl::AndNode::clone() const
82 {
83 return new AndNode;
84 }
85
86 int
87 Acl::AndNode::doMatch(ACLChecklist *checklist, Nodes::const_iterator start) const
88 {
89 // find the first node that does not match
90 for (Nodes::const_iterator i = start; i != nodes.end(); ++i) {
91 if (!checklist->matchChild(this, i, *i))
92 return checklist->keepMatching() ? 0 : -1;
93 }
94
95 // one and not zero on empty because in math empty product equals identity
96 return 1; // no mismatches found (i.e., all kids matched)
97 }
98
99 void
100 Acl::AndNode::parse()
101 {
102 // Not implemented: AndNode cannot be configured directly. See Acl::AllOf.
103 assert(false);
104 }
105
106 /* Acl::OrNode */
107
108 char const *
109 Acl::OrNode::typeString() const
110 {
111 return "any-of";
112 }
113
114 ACL *
115 Acl::OrNode::clone() const
116 {
117 return new OrNode;
118 }
119
120 bool
121 Acl::OrNode::bannedAction(ACLChecklist *, Nodes::const_iterator) const
122 {
123 return false;
124 }
125
126 int
127 Acl::OrNode::doMatch(ACLChecklist *checklist, Nodes::const_iterator start) const
128 {
129 lastMatch_ = nodes.end();
130
131 // find the first node that matches, but stop if things go wrong
132 for (Nodes::const_iterator i = start; i != nodes.end(); ++i) {
133 if (bannedAction(checklist, i))
134 continue;
135 if (checklist->matchChild(this, i, *i)) {
136 lastMatch_ = i;
137 return 1;
138 }
139
140 if (!checklist->keepMatching())
141 return -1; // suspend on async calls and stop on failures
142 }
143
144 // zero and not one on empty because in math empty sum equals zero
145 return 0; // all nodes mismatched
146 }
147
148 void
149 Acl::OrNode::parse()
150 {
151 // Not implemented: OrNode cannot be configured directly. See Acl::AnyOf.
152 assert(false);
153 }
154