]> git.ipfire.org Git - thirdparty/squid.git/blob - src/acl/TimeData.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / acl / TimeData.cc
1 /*
2 * Copyright (C) 1996-2014 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 /* DEBUG: section 28 Access Control */
10
11 #include "squid.h"
12 #include "acl/Checklist.h"
13 #include "acl/TimeData.h"
14 #include "cache_cf.h"
15 #include "Debug.h"
16 #include "wordlist.h"
17
18 ACLTimeData::ACLTimeData () : weekbits (0), start (0), stop (0), next (NULL) {}
19
20 ACLTimeData::ACLTimeData(ACLTimeData const &old) : weekbits(old.weekbits), start (old.start), stop (old.stop), next (NULL)
21 {
22 if (old.next)
23 next = (ACLTimeData *)old.next->clone();
24 }
25
26 ACLTimeData&
27 ACLTimeData::operator=(ACLTimeData const &old)
28 {
29 weekbits = old.weekbits;
30 start = old.start;
31 stop = old.stop;
32 next = NULL;
33
34 if (old.next)
35 next = (ACLTimeData *)old.next->clone();
36
37 return *this;
38 }
39
40 ACLTimeData::~ACLTimeData()
41 {
42 if (next)
43 delete next;
44 }
45
46 bool
47 ACLTimeData::match(time_t when)
48 {
49 static time_t last_when = 0;
50
51 static struct tm tm;
52 time_t t;
53
54 if (when != last_when) {
55 last_when = when;
56 memcpy(&tm, localtime(&when), sizeof(struct tm));
57 }
58
59 t = (time_t) (tm.tm_hour * 60 + tm.tm_min);
60 ACLTimeData *data = this;
61
62 while (data) {
63 debugs(28, 3, "aclMatchTime: checking " << t << " in " <<
64 data->start << "-" << data->stop << ", weekbits=" <<
65 std::hex << data->weekbits);
66
67 if (t >= data->start && t <= data->stop && (data->weekbits & (1 << tm.tm_wday)))
68 return 1;
69
70 data = data->next;
71 }
72
73 return 0;
74 }
75
76 SBufList
77 ACLTimeData::dump() const
78 {
79 SBufList sl;
80 const ACLTimeData *t = this;
81
82 while (t != NULL) {
83 SBuf s;
84 s.Printf("%c%c%c%c%c%c%c %02d:%02d-%02d:%02d",
85 t->weekbits & ACL_SUNDAY ? 'S' : '-',
86 t->weekbits & ACL_MONDAY ? 'M' : '-',
87 t->weekbits & ACL_TUESDAY ? 'T' : '-',
88 t->weekbits & ACL_WEDNESDAY ? 'W' : '-',
89 t->weekbits & ACL_THURSDAY ? 'H' : '-',
90 t->weekbits & ACL_FRIDAY ? 'F' : '-',
91 t->weekbits & ACL_SATURDAY ? 'A' : '-',
92 t->start / 60, t->start % 60, t->stop / 60, t->stop % 60);
93 sl.push_back(s);
94 t = t->next;
95 }
96
97 return sl;
98 }
99
100 void
101 ACLTimeData::parse()
102 {
103 ACLTimeData **Tail;
104 long parsed_weekbits = 0;
105
106 for (Tail = &next; *Tail; Tail = &((*Tail)->next));
107 ACLTimeData *q = NULL;
108
109 int h1, m1, h2, m2;
110
111 char *t = NULL;
112
113 while ((t = strtokFile())) {
114 if (*t < '0' || *t > '9') {
115 /* assume its day-of-week spec */
116
117 while (*t) {
118 switch (*t++) {
119
120 case 'S':
121 parsed_weekbits |= ACL_SUNDAY;
122 break;
123
124 case 'M':
125 parsed_weekbits |= ACL_MONDAY;
126 break;
127
128 case 'T':
129 parsed_weekbits |= ACL_TUESDAY;
130 break;
131
132 case 'W':
133 parsed_weekbits |= ACL_WEDNESDAY;
134 break;
135
136 case 'H':
137 parsed_weekbits |= ACL_THURSDAY;
138 break;
139
140 case 'F':
141 parsed_weekbits |= ACL_FRIDAY;
142 break;
143
144 case 'A':
145 parsed_weekbits |= ACL_SATURDAY;
146 break;
147
148 case 'D':
149 parsed_weekbits |= ACL_WEEKDAYS;
150 break;
151
152 case '-':
153 /* ignore placeholder */
154 break;
155
156 default:
157 debugs(28, DBG_CRITICAL, "" << cfg_filename << " line " << config_lineno <<
158 ": " << config_input_line);
159 debugs(28, DBG_CRITICAL, "aclParseTimeSpec: Bad Day '" << *t << "'" );
160 break;
161 }
162 }
163 } else {
164 /* assume its time-of-day spec */
165
166 if ((sscanf(t, "%d:%d-%d:%d", &h1, &m1, &h2, &m2) < 4) || (!((h1 >= 0 && h1 < 24) && ((h2 >= 0 && h2 < 24) || (h2 == 24 && m2 == 0)) && (m1 >= 0 && m1 < 60) && (m2 >= 0 && m2 < 60)))) {
167 debugs(28, DBG_CRITICAL, "aclParseTimeSpec: Bad time range '" << t << "'");
168 self_destruct();
169
170 if (q != this)
171 delete q;
172
173 return;
174 }
175
176 if ((parsed_weekbits == 0) && (start == 0) && (stop == 0))
177 q = this;
178 else
179 q = new ACLTimeData;
180
181 q->start = h1 * 60 + m1;
182
183 q->stop = h2 * 60 + m2;
184
185 q->weekbits = parsed_weekbits;
186
187 parsed_weekbits = 0;
188
189 if (q->start > q->stop) {
190 debugs(28, DBG_CRITICAL, "aclParseTimeSpec: Reversed time range");
191 self_destruct();
192
193 if (q != this)
194 delete q;
195
196 return;
197 }
198
199 if (q->weekbits == 0)
200 q->weekbits = ACL_ALLWEEK;
201
202 if (q != this) {
203 *(Tail) = q;
204 Tail = &q->next;
205 }
206 }
207 }
208
209 if (parsed_weekbits) {
210
211 q = new ACLTimeData;
212
213 q->start = 0 * 60 + 0;
214
215 q->stop = 24 * 60 + 0;
216
217 q->weekbits = parsed_weekbits;
218
219 *(Tail) = q;
220 Tail = &q->next;
221 }
222 }
223
224 bool
225 ACLTimeData::empty() const
226 {
227 return false;
228 }
229
230 ACLData<time_t> *
231 ACLTimeData::clone() const
232 {
233 return new ACLTimeData(*this);
234 }
235