Mercurial > wflogs-daemon
diff src/wflogs-config.cpp @ 2:400b1de6e1c6
allow multiple config contexts
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Fri, 17 May 2013 10:32:12 -0700 |
parents | 0aa1171aebd2 |
children | 37eace15ef87 |
line wrap: on
line diff
--- a/src/wflogs-config.cpp Wed May 15 13:31:12 2013 -0700 +++ b/src/wflogs-config.cpp Fri May 17 10:32:12 2013 -0700 @@ -1,6 +1,6 @@ /* -Copyright (c) 2007 Carl Byington - 510 Software Group, released under +Copyright (c) 2013 Carl Byington - 510 Software Group, released under the GPL version 3 or any later version at your choice available at http://www.gnu.org/licenses/gpl-3.0.txt @@ -34,13 +34,11 @@ //////////////////////////////////////////////// // -CONFIG::CONFIG() { - reference_count = 0; +CONTEXT::CONTEXT(const char *nam) { + name = nam; fd = -1; len = 0; fdo = -1; - generation = 0; - load_time = 0; period = 120; versions = 3; output = NULL; @@ -51,25 +49,25 @@ } -CONFIG::~CONFIG() { +CONTEXT::~CONTEXT() { + free_all(); } -void CONFIG::sleep(int duration, time_t &previous) { - ::sleep(duration); - time_t now = time(NULL); - previous = now; +void CONTEXT::dump() { + printf("context %s {\n", name); + printf(" period %d; \n", period); + printf(" versions %d; \n", versions); + printf(" output \"%s\";\n", output); + printf(" tempin \"%s\";\n", tempin); + printf(" wflogs \"%s\";\n", wflogs); + printf(" file \"%s\";\n", fn); + printf(" pattern \"%s\";\n", pattern); + printf("};\n\n"); } -void CONFIG::free_all() { - regfree(&re); - close(); - closeo(); -} - - -void CONFIG::openo(bool msg) { +void CONTEXT::openo(bool msg) { open_time = time(NULL); fdo = ::creat(tempin, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (fdo == -1) { @@ -82,7 +80,7 @@ } -void CONFIG::open(bool msg) { +void CONTEXT::open(bool msg) { fd = ::open(fn, O_RDONLY); len = 0; if (fd == -1) { @@ -103,8 +101,8 @@ snprintf(buf, sizeof(buf), "syslog file %s cannot stat after open", fn); tokp->token_error(buf); } - // specify that this fd gets closed on exec, so that selinux - // won't complain about iptables trying to read log files. + // specify that this fd gets closed on exec, so that wflogs + // won't have access to it. int oldflags = fcntl(fd, F_GETFD, 0); if (oldflags >= 0) { fcntl(fd, F_SETFD, oldflags | FD_CLOEXEC); @@ -113,7 +111,7 @@ } -bool CONFIG::write(char *p) { +bool CONTEXT::write(char *p) { // p points to \0 at end of buf, may be destroyed if (failedo()) { openo(false); @@ -124,7 +122,7 @@ } -bool CONFIG::read() { +bool CONTEXT::read() { if (failed()) { open(false); if (failed()) return false; @@ -164,13 +162,13 @@ } -void CONFIG::closeo() { +void CONTEXT::closeo() { if (fdo != -1) ::close(fdo); fdo = -1; } -void CONFIG::close() { +void CONTEXT::close() { if (debug_syslog > 1) { snprintf(buf, sizeof(buf), "syslog file %s closed", fn); my_syslog(buf); @@ -180,7 +178,7 @@ } -void CONFIG::process(char *p) { +void CONTEXT::process(char *p) { // p points to \0 at end of buf, may be destroyed if (pattern) { if (0 == regexec(&re, buf, 0, NULL, 0)) { @@ -193,7 +191,7 @@ } -void CONFIG::check_wflog() { +void CONTEXT::check_wflog() { time_t now = time(NULL); if ((fdo != -1) && (open_time + period < now)) { closeo(); @@ -216,19 +214,58 @@ } +void CONTEXT::free_all() { + regfree(&re); + close(); + closeo(); +} + + +//////////////////////////////////////////////// +// +CONFIG::CONFIG() { + reference_count = 0; + generation = 0; + load_time = 0; +} + + +CONFIG::~CONFIG() { + for (context_list::iterator i=contexts.begin(); i!=contexts.end(); i++) { + CONTEXT *c = *i; + delete c; + } +} + + void CONFIG::dump() { - int level = 0; - char indent[maxlen]; - int i = min(maxlen-1, level*4); - memset(indent, ' ', i); - indent[i] = '\0'; - printf("%s period %d; \n", indent, period); - printf("%s versions %d; \n", indent, versions); - printf("%s output \"%s\";\n", indent, output); - printf("%s tempin \"%s\";\n", indent, tempin); - printf("%s wflogs \"%s\";\n", indent, wflogs); - printf("%s file \"%s\";\n", indent, fn); - printf("%s pattern \"%s\";\n", indent, pattern); + for (context_list::iterator i=contexts.begin(); i!=contexts.end(); i++) { + CONTEXTP c = *i; + c->dump(); + } +} + + +bool CONFIG::read() { + bool rc = false; + for (context_list::iterator i=contexts.begin(); i!=contexts.end(); i++) { + CONTEXT *c = *i; + rc |= c->read(); + } +} + +void CONFIG::sleep(int duration, time_t &previous) { + ::sleep(duration); + time_t now = time(NULL); + previous = now; +} + + +void CONFIG::free_all() { + for (context_list::iterator i=contexts.begin(); i!=contexts.end(); i++) { + CONTEXT *c = *i; + c->free_all(); + } } @@ -283,67 +320,102 @@ //////////////////////////////////////////////// -// parse a config file // -bool load_conf(CONFIG &dc, const char *fn) { - TOKEN tok(fn, &dc.config_files); - dc.set_token(tok); +bool parse_context(TOKEN &tok, CONFIG &dc, CONTEXTP parent); +bool parse_context(TOKEN &tok, CONFIG &dc, CONTEXTP parent) { + const char *name = tok.next(); + if (!tsa(tok, token_lbrace)) return false; + CONTEXTP con = new CONTEXT(name); + con->set_token(tok); while (true) { const char *have = tok.next(); if (!have) break; + if (have == token_rbrace) break; // done if (have == token_period) { have = tok.next(); - dc.set_period(atoi(have)); + con->set_period(atoi(have)); if (!tsa(tok, token_semi)) return false; } else if (have == token_versions) { have = tok.next(); - dc.set_versions(atoi(have)); + con->set_versions(atoi(have)); if (!tsa(tok, token_semi)) return false; } else if (have == token_output) { - dc.set_output(tok.next()); + con->set_output(tok.next()); if (!tsa(tok, token_semi)) return false; } else if (have == token_tempin) { - dc.set_tempin(tok.next()); + con->set_tempin(tok.next()); if (!tsa(tok, token_semi)) return false; } else if (have == token_wflogs) { - dc.set_wflogs(tok.next()); + con->set_wflogs(tok.next()); if (!tsa(tok, token_semi)) return false; } else if (have == token_file) { - dc.set_file(tok.next()); + con->set_file(tok.next()); if (!tsa(tok, token_semi)) return false; } else if (have == token_pattern) { - dc.pattern = tok.next(); - int rc = regcomp(&dc.re, dc.pattern, REG_ICASE | REG_EXTENDED); + con->pattern = tok.next(); + int rc = regcomp(&con->re, con->pattern, REG_ICASE | REG_EXTENDED); if (rc) { char bu[maxlen]; - regerror(rc, &dc.re, bu, maxlen); + regerror(rc, &con->re, bu, maxlen); char buf[maxlen]; - snprintf(buf, sizeof(buf), "pattern %s not valid - %s", dc.pattern, bu); + snprintf(buf, sizeof(buf), "pattern %s not valid - %s", con->pattern, bu); tok.token_error(buf); - dc.pattern = NULL; + con->pattern = NULL; } if (!tsa(tok, token_semi)) return false; } else { - tok.token_error("statement", have); + tok.token_error("period/versions/output/tempin/wflogs/file/pattern", have); return false; } } + if (!tsa(tok, token_semi)) { + delete con; + return false; + } + dc.add_context(con); return true; } //////////////////////////////////////////////// +// parse a config file +// +bool load_conf(CONFIG &dc, const char *fn) { + int count = 0; + TOKEN tok(fn, &dc.config_files); + while (true) { + const char *have = tok.next(); + if (!have) break; + if (have == token_context) { + if (!parse_context(tok, dc, NULL)) { + tok.token_error("load_conf() failed to parse context"); + return false; + } + else count++; + } + else { + tok.token_error(token_context, have); + return false; + } + } + tok.token_error("load_conf() found %d contexts in %s", count, fn); + return (!dc.contexts.empty()); +} + + +//////////////////////////////////////////////// // init the tokens // void token_init() { + token_context = register_string("context"); token_file = register_string("file"); token_include = register_string("include"); token_lbrace = register_string("{");