Mercurial > syslog2iptables
comparison src/syslogconfig.cpp @ 51:206448c00b55 stable-1-0-12
Allow multiple contexts with independent add/remove commands.
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Sat, 24 Jan 2009 15:52:20 -0800 |
parents | ba0259c9e411 |
children | b45dddebe8fc |
comparison
equal
deleted
inserted
replaced
50:75361069c6ef | 51:206448c00b55 |
---|---|
14 #include <netdb.h> | 14 #include <netdb.h> |
15 #include <limits.h> | 15 #include <limits.h> |
16 | 16 |
17 const char *token_add; | 17 const char *token_add; |
18 const char *token_bucket; | 18 const char *token_bucket; |
19 const char *token_context; | |
19 const char *token_file; | 20 const char *token_file; |
20 const char *token_ignore; | 21 const char *token_ignore; |
21 const char *token_include; | 22 const char *token_include; |
22 const char *token_index; | 23 const char *token_index; |
23 const char *token_lbrace; | 24 const char *token_lbrace; |
26 const char *token_rbrace; | 27 const char *token_rbrace; |
27 const char *token_remove; | 28 const char *token_remove; |
28 const char *token_semi; | 29 const char *token_semi; |
29 const char *token_slash; | 30 const char *token_slash; |
30 const char *token_threshold; | 31 const char *token_threshold; |
31 | 32 string_set all_strings;// owns all the strings, only modified by the config loader thread |
32 struct ltint | 33 recorder_map recorders; // all the recorders are named |
33 { | |
34 bool operator()(const int s1, const int s2) const | |
35 { | |
36 return (unsigned)s1 < (unsigned)s2; | |
37 } | |
38 }; | |
39 | |
40 struct bucket { | |
41 int count; | |
42 bool latch; // true iff ever count>threshold | |
43 }; | |
44 | |
45 string_set all_strings; // owns all the strings, only modified by the config loader thread | |
46 const int maxlen = 1000; // used for snprintf buffers | 34 const int maxlen = 1000; // used for snprintf buffers |
47 typedef map<int, bucket, ltint> ip_buckets; | 35 |
48 | 36 |
49 class IPR { | 37 //////////////////////////////////////////////// |
50 ip_buckets violations; | 38 // |
51 public: | 39 |
52 void add(int ip, int amount, CONFIG &con, const char *file_name, int pattern_index, const char *message); | 40 IPR::IPR() { |
53 void leak(int amount, CONFIG &con); | 41 reference_count = 0; |
54 void free_all(CONFIG &con); | 42 } |
55 void update(int ip, bool added, const char *file_name, int pattern_index, const char *message); | 43 |
56 void changed(CONFIG &con, int ip, bool added); | 44 IPR* IPR::find(const char* name) { |
57 }; | 45 recorder_map::iterator m = recorders.find(name); |
58 | 46 if (m == recorders.end()) recorders[name] = new IPR; |
59 IPR recorder; | 47 recorders[name]->reference(1); |
60 | 48 return recorders[name]; |
61 | 49 } |
62 //////////////////////////////////////////////// | 50 |
63 // | 51 |
64 void IPR::add(int ip, int amount, CONFIG &con, const char *file_name, int pattern_index, const char *message) { | 52 void IPR::release(const char* name) { |
53 recorder_map::iterator m = recorders.find(name); | |
54 IPR* i = (*m).second; | |
55 int r = i->reference(-1); | |
56 if (r == 0) { | |
57 delete i; | |
58 recorders.erase(m); | |
59 } | |
60 } | |
61 | |
62 | |
63 void IPR::add(int ip, int amount, CONTEXT &con, const char *file_name, int pattern_index, const char *message) { | |
65 if (con.looking(ip)) { | 64 if (con.looking(ip)) { |
66 ip_buckets::iterator i = violations.find(ip); | 65 ip_buckets::iterator i = violations.find(ip); |
67 if (i == violations.end()) { | 66 if (i == violations.end()) { |
68 bucket b; | 67 bucket b; |
69 b.count = amount; | 68 b.count = amount; |
89 } | 88 } |
90 } | 89 } |
91 } | 90 } |
92 | 91 |
93 | 92 |
94 void IPR::leak(int amount, CONFIG &con) { | 93 void IPR::leak(int amount, CONTEXT &con) { |
95 for (ip_buckets::iterator i=violations.begin(); i!=violations.end(); ) { | 94 for (ip_buckets::iterator i=violations.begin(); i!=violations.end(); ) { |
96 int ip = (*i).first; | 95 int ip = (*i).first; |
97 bucket &b = (*i).second; | 96 bucket &b = (*i).second; |
98 if (b.count <= amount) { | 97 if (b.count <= amount) { |
99 if (b.latch) { | 98 if (b.latch) { |
108 } | 107 } |
109 } | 108 } |
110 } | 109 } |
111 | 110 |
112 | 111 |
113 void IPR::free_all(CONFIG &con) { | 112 void IPR::free_all(CONTEXT &con) { |
114 if (debug_syslog > 2) { | 113 if (debug_syslog > 2) { |
115 my_syslog("syslog2iptables shutting down"); | 114 my_syslog("syslog2iptables shutting down"); |
116 } | 115 } |
117 for (ip_buckets::iterator i=violations.begin(); i!=violations.end(); i++) { | 116 for (ip_buckets::iterator i=violations.begin(); i!=violations.end(); i++) { |
118 int ip = (*i).first; | 117 int ip = (*i).first; |
139 my_syslog(buf); | 138 my_syslog(buf); |
140 } | 139 } |
141 } | 140 } |
142 | 141 |
143 | 142 |
144 void IPR::changed(CONFIG &con, int ip, bool added) { | 143 void IPR::changed(CONTEXT &con, int ip, bool added) { |
145 int t = con.get_threshold(); | 144 int t = con.get_threshold(); |
146 char buf[maxlen]; | 145 char buf[maxlen]; |
147 if (added) { | 146 if (added) { |
148 bucket &b = violations[ip]; | 147 bucket &b = violations[ip]; |
149 if (con.looking(ip) && (b.count > t)) { | 148 if (con.looking(ip) && (b.count > t)) { |
201 PATTERN::~PATTERN() { | 200 PATTERN::~PATTERN() { |
202 regfree(&re); | 201 regfree(&re); |
203 } | 202 } |
204 | 203 |
205 | 204 |
206 bool PATTERN::process(char *buf, CONFIG &con, const char *file_name, int pattern_index) { | 205 bool PATTERN::process(char *buf, CONTEXT &con, const char *file_name, int pattern_index) { |
207 if (pattern) { | 206 if (pattern) { |
208 const int nmatch = index+1; | 207 const int nmatch = index+1; |
209 regmatch_t match[nmatch]; | 208 regmatch_t match[nmatch]; |
210 if (0 == regexec(&re, buf, nmatch, match, 0)) { | 209 if (0 == regexec(&re, buf, nmatch, match, 0)) { |
211 int s = match[index].rm_so; | 210 int s = match[index].rm_so; |
215 my_syslog(buf); // show lines with matches | 214 my_syslog(buf); // show lines with matches |
216 } | 215 } |
217 buf[e] = '\0'; | 216 buf[e] = '\0'; |
218 int ip = ip_address(buf+s); | 217 int ip = ip_address(buf+s); |
219 if (ip) { | 218 if (ip) { |
220 recorder.add(ip, amount, con, file_name, pattern_index, message); | 219 con.recorder->add(ip, amount, con, file_name, pattern_index, message); |
221 } | 220 } |
222 return true; | 221 return true; |
223 } | 222 } |
224 } | 223 } |
225 } | 224 } |
240 } | 239 } |
241 | 240 |
242 | 241 |
243 //////////////////////////////////////////////// | 242 //////////////////////////////////////////////// |
244 // | 243 // |
245 CONFIG::CONFIG() { | 244 CONTEXT::CONTEXT(const char *nam) { |
246 reference_count = 0; | 245 name = nam; |
247 generation = 0; | |
248 load_time = 0; | |
249 threshold = 500; | 246 threshold = 500; |
250 add_command = "/sbin/iptables -I INPUT --src %s --jump DROP"; | 247 add_command = "/sbin/iptables -I INPUT --src %s --jump DROP"; |
251 remove_command = "/sbin/iptables -D INPUT --src %s --jump DROP"; | 248 remove_command = "/sbin/iptables -D INPUT --src %s --jump DROP"; |
252 } | 249 recorder = IPR::find(name); |
253 | 250 } |
254 | 251 |
255 CONFIG::~CONFIG() { | 252 |
253 //////////////////////////////////////////////// | |
254 // | |
255 CONTEXT::~CONTEXT() { | |
256 ignore.clear(); | |
256 for (syslogconfig_list::iterator i=syslogconfigs.begin(); i!=syslogconfigs.end(); i++) { | 257 for (syslogconfig_list::iterator i=syslogconfigs.begin(); i!=syslogconfigs.end(); i++) { |
257 SYSLOGCONFIG *c = *i; | 258 SYSLOGCONFIG *c = *i; |
258 delete c; | 259 delete c; |
259 } | 260 } |
260 ignore.clear(); | 261 IPR::release(name); |
261 } | 262 } |
262 | 263 |
263 | 264 |
264 void CONFIG::add_syslogconfig(SYSLOGCONFIGP con) { | 265 void CONTEXT::add_syslogconfig(SYSLOGCONFIGP con) { |
265 syslogconfigs.push_back(con); | 266 syslogconfigs.push_back(con); |
266 } | 267 } |
267 | 268 |
268 | 269 |
269 void CONFIG::add_pair(IPPAIR pair) { | 270 void CONTEXT::add_pair(IPPAIR pair) { |
270 ignore.push_back(pair); | 271 ignore.push_back(pair); |
271 } | 272 } |
272 | 273 |
273 | 274 |
274 void CONFIG::dump() { | 275 void CONTEXT::dump() { |
275 printf(" threshold %d; \n\n", threshold); | 276 string indents(" "); |
276 | 277 const char *indent = indents.c_str(); |
277 printf(" add_command \"%s\"; \n", add_command); | 278 |
278 printf(" remove_command \"%s\"; \n\n", remove_command); | 279 printf("context %s {\n", name); |
279 | 280 printf("%s threshold %d; \n\n", indent, threshold); |
280 printf(" ignore { \n"); | 281 |
282 printf("%s add_command \"%s\"; \n", indent, add_command); | |
283 printf("%s remove_command \"%s\"; \n\n", indent, remove_command); | |
284 | |
285 printf("%s ignore { \n", indent); | |
281 for (ippair_list::iterator i=ignore.begin(); i!=ignore.end(); i++) { | 286 for (ippair_list::iterator i=ignore.begin(); i!=ignore.end(); i++) { |
282 IPPAIR &p = *i; | 287 IPPAIR &p = *i; |
283 in_addr ip; | 288 in_addr ip; |
284 ip.s_addr = htonl(p.first); | 289 ip.s_addr = htonl(p.first); |
285 printf(" %s/%d; \n", inet_ntoa(ip), p.cidr); | 290 printf("%s %s/%d; \n", indent, inet_ntoa(ip), p.cidr); |
286 } | 291 } |
287 printf(" }; \n\n"); | 292 printf("%s }; \n\n", indent); |
288 | 293 |
289 for (syslogconfig_list::iterator i=syslogconfigs.begin(); i!=syslogconfigs.end(); i++) { | 294 for (syslogconfig_list::iterator i=syslogconfigs.begin(); i!=syslogconfigs.end(); i++) { |
290 SYSLOGCONFIGP c = *i; | 295 SYSLOGCONFIGP c = *i; |
291 c->dump(0); | 296 c->dump(1); |
292 } | 297 } |
293 } | 298 printf("}; \n\n"); |
294 | 299 } |
295 | 300 |
296 void CONFIG::read() { | 301 |
302 void CONTEXT::read(CONFIG &con) { | |
297 while (true) { | 303 while (true) { |
298 bool have = false; | 304 bool have = false; |
299 for (syslogconfig_list::iterator i=syslogconfigs.begin(); i!=syslogconfigs.end(); i++) { | 305 for (syslogconfig_list::iterator i=syslogconfigs.begin(); i!=syslogconfigs.end(); i++) { |
300 SYSLOGCONFIGP c = *i; | 306 SYSLOGCONFIGP c = *i; |
301 have |= c->read(*this); | 307 have |= c->read(*this); |
303 if (!have) break; | 309 if (!have) break; |
304 } | 310 } |
305 } | 311 } |
306 | 312 |
307 | 313 |
314 void CONTEXT::free_all() { | |
315 recorder->free_all(*this); | |
316 } | |
317 | |
318 | |
319 void CONTEXT::leak(int delta) { | |
320 recorder->leak(delta, *this); | |
321 | |
322 } | |
323 | |
324 | |
325 bool CONTEXT::looking(int ip) { | |
326 for (ippair_list::iterator i=ignore.begin(); i!=ignore.end(); i++) { | |
327 IPPAIR &p = *i; | |
328 if ((p.first <= ip) && (ip <= p.last)) return false; | |
329 } | |
330 return true; | |
331 } | |
332 | |
333 //////////////////////////////////////////////// | |
334 // | |
335 CONFIG::CONFIG() { | |
336 reference_count = 0; | |
337 generation = 0; | |
338 load_time = 0; | |
339 } | |
340 | |
341 | |
342 CONFIG::~CONFIG() { | |
343 for (context_list::iterator i=contexts.begin(); i!=contexts.end(); i++) { | |
344 CONTEXT *c = *i; | |
345 delete c; | |
346 } | |
347 } | |
348 | |
349 | |
350 void CONFIG::dump() { | |
351 for (context_list::iterator i=contexts.begin(); i!=contexts.end(); i++) { | |
352 CONTEXTP c = *i; | |
353 c->dump(); | |
354 } | |
355 } | |
356 | |
357 | |
358 void CONFIG::read() { | |
359 for (context_list::iterator i=contexts.begin(); i!=contexts.end(); i++) { | |
360 CONTEXT *c = *i; | |
361 c->read(*this); | |
362 } | |
363 } | |
364 | |
365 | |
308 void CONFIG::sleep(int duration, time_t &previous) { | 366 void CONFIG::sleep(int duration, time_t &previous) { |
309 ::sleep(duration); | 367 ::sleep(duration); |
310 time_t now = time(NULL); | 368 time_t now = time(NULL); |
311 recorder.leak(now-previous, *this); | 369 for (context_list::iterator i=contexts.begin(); i!=contexts.end(); i++) { |
370 CONTEXT *c = *i; | |
371 c->leak(now-previous); | |
372 } | |
312 previous = now; | 373 previous = now; |
313 } | 374 } |
314 | 375 |
315 | 376 |
316 void CONFIG::free_all() { | 377 void CONFIG::free_all() { |
317 recorder.free_all(*this); | 378 for (context_list::iterator i=contexts.begin(); i!=contexts.end(); i++) { |
318 } | 379 CONTEXT *c = *i; |
319 | 380 c->free_all(); |
320 bool CONFIG::looking(int ip) { | 381 } |
321 for (ippair_list::iterator i=ignore.begin(); i!=ignore.end(); i++) { | 382 } |
322 IPPAIR &p = *i; | 383 |
323 if ((p.first <= ip) && (ip <= p.last)) return false; | |
324 } | |
325 return true; | |
326 } | |
327 | 384 |
328 //////////////////////////////////////////////// | 385 //////////////////////////////////////////////// |
329 // | 386 // |
330 SYSLOGCONFIG::SYSLOGCONFIG(TOKEN &tok, const char *file_name_) { | 387 SYSLOGCONFIG::SYSLOGCONFIG(TOKEN &tok, const char *file_name_) { |
331 tokp = &tok; | 388 tokp = &tok; |
372 } | 429 } |
373 } | 430 } |
374 } | 431 } |
375 | 432 |
376 | 433 |
377 bool SYSLOGCONFIG::read(CONFIG &con) { | 434 bool SYSLOGCONFIG::read(CONTEXT &con) { |
378 if (failed()) { | 435 if (failed()) { |
379 open(false); | 436 open(false); |
380 if (failed()) return false; | 437 if (failed()) return false; |
381 } | 438 } |
382 int n = ::read(fd, buf+len, buflen-len); | 439 int n = ::read(fd, buf+len, buflen-len); |
426 void SYSLOGCONFIG::add_pattern(PATTERNP pat) { | 483 void SYSLOGCONFIG::add_pattern(PATTERNP pat) { |
427 patterns.push_back(pat); | 484 patterns.push_back(pat); |
428 } | 485 } |
429 | 486 |
430 | 487 |
431 void SYSLOGCONFIG::process(CONFIG &con) { | 488 void SYSLOGCONFIG::process(CONTEXT &con) { |
432 int pi=0; | 489 int pi=0; |
433 for (pattern_list::iterator i=patterns.begin(); i!=patterns.end(); i++) { | 490 for (pattern_list::iterator i=patterns.begin(); i!=patterns.end(); i++) { |
434 PATTERN *p = *i; | 491 PATTERN *p = *i; |
435 if (p->process(buf, con, file_name, pi)) break; | 492 if (p->process(buf, con, file_name, pi)) break; |
436 pi++; | 493 pi++; |
502 } | 559 } |
503 | 560 |
504 | 561 |
505 //////////////////////////////////////////////// | 562 //////////////////////////////////////////////// |
506 // | 563 // |
507 bool parse_pattern(TOKEN &tok, SYSLOGCONFIG &con); | 564 bool parse_pattern(TOKEN &tok, SYSLOGCONFIG &con, CONTEXT &me); |
508 bool parse_pattern(TOKEN &tok, SYSLOGCONFIG &con) { | 565 bool parse_pattern(TOKEN &tok, SYSLOGCONFIG &con, CONTEXT &me) { |
509 const char *pat = tok.next(); | 566 const char *pat = tok.next(); |
510 int ind = 0; | 567 int ind = 0; |
511 int buc = 0; | 568 int buc = 0; |
512 const char *msg = NULL; | 569 const char *msg = NULL; |
513 if (!tsa(tok, token_lbrace)) return false; | 570 if (!tsa(tok, token_lbrace)) return false; |
541 } | 598 } |
542 | 599 |
543 | 600 |
544 //////////////////////////////////////////////// | 601 //////////////////////////////////////////////// |
545 // | 602 // |
546 bool parse_ignore(TOKEN &tok, CONFIG &dc); | 603 bool parse_ignore(TOKEN &tok, CONFIG &dc, CONTEXT &me); |
547 bool parse_ignore(TOKEN &tok, CONFIG &dc) { | 604 bool parse_ignore(TOKEN &tok, CONFIG &dc, CONTEXT &me) { |
548 if (!tsa(tok, token_lbrace)) return false; | 605 if (!tsa(tok, token_lbrace)) return false; |
549 while (true) { | 606 while (true) { |
550 const char *have = tok.next(); | 607 const char *have = tok.next(); |
551 if (!have) break; | 608 if (!have) break; |
552 if (have == token_rbrace) break; | 609 if (have == token_rbrace) break; |
598 0x00000001, // 31 | 655 0x00000001, // 31 |
599 0x00000000}; // 32 | 656 0x00000000}; // 32 |
600 pair.first = ipaddr; | 657 pair.first = ipaddr; |
601 pair.last = ipaddr | masks[mask]; | 658 pair.last = ipaddr | masks[mask]; |
602 pair.cidr = mask; | 659 pair.cidr = mask; |
603 dc.add_pair(pair); | 660 me.add_pair(pair); |
604 } | 661 } |
605 if (!tsa(tok, token_semi)) return false; | 662 if (!tsa(tok, token_semi)) return false; |
606 return true; | 663 return true; |
607 } | 664 } |
608 | 665 |
609 | 666 |
610 //////////////////////////////////////////////// | 667 //////////////////////////////////////////////// |
611 // | 668 // |
612 bool parse_syslogconfig(TOKEN &tok, CONFIG &dc); | 669 bool parse_syslogconfig(TOKEN &tok, CONFIG &dc, CONTEXT &me); |
613 bool parse_syslogconfig(TOKEN &tok, CONFIG &dc) { | 670 bool parse_syslogconfig(TOKEN &tok, CONFIG &dc, CONTEXT &me) { |
614 const char *name = tok.next(); | 671 const char *name = tok.next(); |
615 if (!tsa(tok, token_lbrace)) return false; | 672 if (!tsa(tok, token_lbrace)) return false; |
616 SYSLOGCONFIGP con = new SYSLOGCONFIG(tok, name); | 673 SYSLOGCONFIGP con = new SYSLOGCONFIG(tok, name); |
617 if (con->failed()) { | 674 if (con->failed()) { |
618 delete con; | 675 delete con; |
619 return false; | 676 return false; |
620 } | 677 } |
621 dc.add_syslogconfig(con); | 678 me.add_syslogconfig(con); |
622 while (true) { | 679 while (true) { |
623 const char *have = tok.next(); | 680 const char *have = tok.next(); |
624 if (!have) break; | 681 if (!have) break; |
625 if (have == token_rbrace) break; | 682 if (have == token_rbrace) break; |
626 if (have == token_pattern) { | 683 if (have == token_pattern) { |
627 if (!parse_pattern(tok, *con)) return false; | 684 if (!parse_pattern(tok, *con, me)) return false; |
628 } | 685 } |
629 else { | 686 else { |
630 tok.token_error("pattern", have); | 687 tok.token_error("pattern", have); |
631 return false; | 688 return false; |
632 } | 689 } |
633 } | 690 } |
634 if (!tsa(tok, token_semi)) return false; | 691 if (!tsa(tok, token_semi)) return false; |
692 return true; | |
693 } | |
694 | |
695 | |
696 //////////////////////////////////////////////// | |
697 // | |
698 bool parse_context(TOKEN &tok, CONFIG &dc, CONTEXTP parent); | |
699 bool parse_context(TOKEN &tok, CONFIG &dc, CONTEXTP parent) { | |
700 const char *name = tok.next(); | |
701 if (!tsa(tok, token_lbrace)) return false; | |
702 CONTEXTP con = new CONTEXT(name); | |
703 | |
704 while (true) { | |
705 const char *have = tok.next(); | |
706 if (!have) break; | |
707 if (have == token_rbrace) break; // done | |
708 if (have == token_threshold) { | |
709 have = tok.next(); | |
710 con->set_threshold(atoi(have)); | |
711 if (!tsa(tok, token_semi)) return false; | |
712 } | |
713 else if (have == token_ignore) { | |
714 if (!parse_ignore(tok, dc, *con)) return false; | |
715 } | |
716 else if (have == token_add) { | |
717 have = tok.next(); | |
718 con->set_add(have); | |
719 if (!tsa(tok, token_semi)) return false; | |
720 } | |
721 else if (have == token_remove) { | |
722 have = tok.next(); | |
723 con->set_remove(have); | |
724 if (!tsa(tok, token_semi)) return false; | |
725 } | |
726 else if (have == token_file) { | |
727 if (!parse_syslogconfig(tok, dc, *con)) return false; | |
728 } | |
729 else { | |
730 tok.token_error("threshold/ignore/add_command/remove_command/file", have); | |
731 return false; | |
732 } | |
733 } | |
734 if (!tsa(tok, token_semi)) { | |
735 delete con; | |
736 return false; | |
737 } | |
738 dc.add_context(con); | |
635 return true; | 739 return true; |
636 } | 740 } |
637 | 741 |
638 | 742 |
639 //////////////////////////////////////////////// | 743 //////////////////////////////////////////////// |
643 int count = 0; | 747 int count = 0; |
644 TOKEN tok(fn, &dc.config_files); | 748 TOKEN tok(fn, &dc.config_files); |
645 while (true) { | 749 while (true) { |
646 const char *have = tok.next(); | 750 const char *have = tok.next(); |
647 if (!have) break; | 751 if (!have) break; |
648 if (have == token_threshold) { | 752 if (have == token_context) { |
649 have = tok.next(); | 753 if (!parse_context(tok, dc, NULL)) { |
650 dc.set_threshold(atoi(have)); | 754 tok.token_error("load_conf() failed to parse context"); |
651 if (!tsa(tok, token_semi)) return false; | 755 return false; |
652 } | 756 } |
653 else if (have == token_ignore) { | 757 else count++; |
654 if (!parse_ignore(tok, dc)) return false; | |
655 } | |
656 else if (have == token_add) { | |
657 have = tok.next(); | |
658 dc.set_add(have); | |
659 if (!tsa(tok, token_semi)) return false; | |
660 } | |
661 else if (have == token_remove) { | |
662 have = tok.next(); | |
663 dc.set_remove(have); | |
664 if (!tsa(tok, token_semi)) return false; | |
665 } | |
666 else if (have == token_file) { | |
667 if (!parse_syslogconfig(tok, dc)) return false; | |
668 count++; | |
669 } | 758 } |
670 else { | 759 else { |
671 tok.token_error("threshold/ignore/add_command/remove_command/file", have); | 760 tok.token_error(token_context, have); |
672 return false; | 761 return false; |
673 } | 762 } |
674 } | 763 } |
675 tok.token_error("load_conf() found %d syslog files in %s", count, fn); | 764 tok.token_error("load_conf() found %d contexts in %s", count, fn); |
676 return (!dc.syslogconfigs.empty()); | 765 return (!dc.contexts.empty()); |
677 } | 766 } |
678 | 767 |
679 | 768 |
680 //////////////////////////////////////////////// | 769 //////////////////////////////////////////////// |
681 // init the tokens | 770 // init the tokens |
682 // | 771 // |
683 void token_init() { | 772 void token_init() { |
684 token_add = register_string("add_command"); | 773 token_add = register_string("add_command"); |
685 token_bucket = register_string("bucket"); | 774 token_bucket = register_string("bucket"); |
775 token_context = register_string("context"); | |
686 token_file = register_string("file"); | 776 token_file = register_string("file"); |
687 token_ignore = register_string("ignore"); | 777 token_ignore = register_string("ignore"); |
688 token_include = register_string("include"); | 778 token_include = register_string("include"); |
689 token_index = register_string("index"); | 779 token_index = register_string("index"); |
690 token_lbrace = register_string("{"); | 780 token_lbrace = register_string("{"); |