]> git.ipfire.org Git - thirdparty/squid.git/blob - src/acl/InnerNode.cc
Major ACL handling update, including the following changes:
[thirdparty/squid.git] / src / acl / InnerNode.cc
1 #include "squid.h"
2 #include "acl/Acl.h"
3 #include "acl/BoolOps.h"
4 #include "acl/Checklist.h"
5 #include "acl/Gadgets.h"
6 #include "acl/InnerNode.h"
7 #include "cache_cf.h"
8 #include "ConfigParser.h"
9 #include "Debug.h"
10 #include "globals.h"
11 #include "wordlist.h"
12 #include <algorithm>
13
14
15 // "delete acl" class to use with std::for_each() in InnerNode::~InnerNode()
16 class AclDeleter {
17 public:
18 void operator()(ACL* acl) {
19 // Do not delete explicit ACLs; they are maintained by Config.aclList.
20 if (acl && !acl->registered)
21 delete acl;
22 }
23 };
24
25
26 Acl::InnerNode::~InnerNode()
27 {
28 std::for_each(nodes.begin(), nodes.end(), AclDeleter());
29 }
30
31 void
32 Acl::InnerNode::prepareForUse()
33 {
34 std::for_each(nodes.begin(), nodes.end(), std::mem_fun(&ACL::prepareForUse));
35 }
36
37 bool
38 Acl::InnerNode::empty() const
39 {
40 return nodes.empty();
41 }
42
43 void
44 Acl::InnerNode::add(ACL *node)
45 {
46 assert(node != NULL);
47 nodes.push_back(node);
48 }
49
50 // one call parses one "acl name acltype name1 name2 ..." line
51 // kids use this method to handle [multiple] parse() calls correctly
52 void
53 Acl::InnerNode::lineParse()
54 {
55 // XXX: not precise, may change when looping or parsing multiple lines
56 if (!cfgline)
57 cfgline = xstrdup(config_input_line);
58
59 // expect a list of ACL names, each possibly preceeded by '!' for negation
60
61 while (const char *t = ConfigParser::strtokFile()) {
62 const bool negated = (*t == '!');
63 if (negated)
64 ++t;
65
66 debugs(28, 3, "looking for ACL " << t);
67 ACL *a = ACL::FindByName(t);
68
69 if (a == NULL) {
70 debugs(28, DBG_CRITICAL, "ACL not found: " << t);
71 self_destruct();
72 return;
73 }
74
75 // append(negated ? new NotNode(a) : a);
76 if (negated)
77 add(new NotNode(a));
78 else
79 add(a);
80 }
81
82 return;
83 }
84
85 wordlist*
86 Acl::InnerNode::dump() const
87 {
88 wordlist *values = NULL;
89 for (Nodes::const_iterator i = nodes.begin(); i != nodes.end(); ++i)
90 wordlistAdd(&values, (*i)->name);
91 return values;
92 }
93
94 int
95 Acl::InnerNode::match(ACLChecklist *checklist)
96 {
97 return doMatch(checklist, nodes.begin());
98 }
99
100 bool
101 Acl::InnerNode::resumeMatchingAt(ACLChecklist *checklist, Nodes::const_iterator pos) const
102 {
103 debugs(28, 5, "checking " << name << " at " << (pos-nodes.begin()));
104 const int result = doMatch(checklist, pos);
105 const char *extra = checklist->asyncInProgress() ? " async" : "";
106 debugs(28, 3, "checked: " << name << " = " << result << extra);
107
108 // merges async and failures (-1) into "not matched"
109 return result == 1;
110 }