Mercurial > syslog2iptables
view src/syslogconfig.cpp @ 2:6e88da080f08
initial coding
author | carl |
---|---|
date | Thu, 24 Nov 2005 10:31:09 -0800 |
parents | 551433a01cab |
children | 8fe310e5cd44 |
line wrap: on
line source
/*************************************************************************** * Copyright (C) 2005 by 510 Software Group * * * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "includes.h" #include <fcntl.h> static char* syslogconfig_version="$Id$"; char *token_cisco; char *token_file; char *token_include; char *token_lbrace; char *token_parser; char *token_rbrace; char *token_semi; char *token_ssh; string_set all_strings; // owns all the strings, only modified by the config loader thread const int maxlen = 1000; // used for snprintf buffers CONFIG::CONFIG() { reference_count = 0; generation = 0; load_time = 0; } CONFIG::~CONFIG() { for (syslogconfig_list::iterator i=syslogconfigs.begin(); i!=syslogconfigs.end(); i++) { SYSLOGCONFIG *c = *i; delete c; } } void CONFIG::add_syslogconfig(SYSLOGCONFIGP con) { syslogconfigs.push_back(con); } void CONFIG::dump() { for (syslogconfig_list::iterator i=syslogconfigs.begin(); i!=syslogconfigs.end(); i++) { SYSLOGCONFIGP c = *i; c->dump(0); } } void CONFIG::read() { for (syslogconfig_list::iterator i=syslogconfigs.begin(); i!=syslogconfigs.end(); i++) { SYSLOGCONFIGP c = *i; c->read(); } } SYSLOGCONFIG::SYSLOGCONFIG(TOKEN &tok, char *file_name_, parser_style parser_) { file_name = file_name_; parser = parser_; fd = open(file_name, O_RDONLY); len = 0; if (fd == -1) { char buf[maxlen]; snprintf(buf, sizeof(buf), "syslog file %s not readable", file_name); tok.token_error(buf); } else { lseek(fd, 0, SEEK_END); } } SYSLOGCONFIG::~SYSLOGCONFIG() { if (fd != -1) close(fd); fd = -1; } void SYSLOGCONFIG::read() { if (failed()) return; int n = ::read(fd, buf, buflen-len); if (n > 0) { len += n; while (true) { char *p = (char*)memchr(buf, '\n', len); if (!p) break; n = p-buf; *p = '\0'; process(); // process null terminated string len -= n+1; memmove(buf, p+1, len); } // no <lf> in a full buffer if (len == buflen) len = 0; } } void SYSLOGCONFIG::process() { my_syslog(buf); } void SYSLOGCONFIG::dump(int level) { char indent[maxlen]; int i = min(maxlen-1, level*4); memset(indent, ' ', i); indent[i] = '\0'; char buf[maxlen]; printf("%s file \"%s\" {\n", indent, file_name); switch (parser) { case cisco: printf("%s parser cisco; \n", indent); break; case ssh: printf("%s parser ssh; \n", indent); break; } printf("%s }; \n", indent); } //////////////////////////////////////////////// // helper to discard the strings held by a string_set // void discard(string_set &s) { for (string_set::iterator i=s.begin(); i!=s.end(); i++) { free(*i); } s.clear(); } //////////////////////////////////////////////// // helper to register a string in a string set // char* register_string(string_set &s, char *name) { string_set::iterator i = s.find(name); if (i != s.end()) return *i; char *x = strdup(name); s.insert(x); return x; } //////////////////////////////////////////////// // register a global string // char* register_string(char *name) { return register_string(all_strings, name); } //////////////////////////////////////////////// // bool tsa(TOKEN &tok, char *token); bool tsa(TOKEN &tok, char *token) { char *have = tok.next(); if (have == token) return true; tok.token_error(token, have); return false; } //////////////////////////////////////////////// // bool parse_syslogconfig(TOKEN &tok, CONFIG &dc); bool parse_syslogconfig(TOKEN &tok, CONFIG &dc) { char *name = tok.next(); parser_style parser; if (!tsa(tok, token_lbrace)) return false; while (true) { char *have = tok.next(); if (have == token_parser) { have = tok.next(); if (have == token_cisco) parser = cisco; else if (have == token_ssh) parser = ssh; else { tok.token_error("cisco/ssh", have); return false; } if (!tsa(tok, token_semi)) return false; } else if (have == token_rbrace) { break; // done } else { tok.token_error("file keyword", have); return false; } } if (!tsa(tok, token_semi)) return false; SYSLOGCONFIGP con = new SYSLOGCONFIG(tok, name, parser); if (con->failed()) { delete con; return false; } dc.add_syslogconfig(con); return true; } //////////////////////////////////////////////// // parse a config file // bool load_conf(CONFIG &dc, char *fn) { int count = 0; TOKEN tok(fn, &dc.config_files); while (true) { char *have = tok.next(); if (!have) break; if (have == token_file) { if (!parse_syslogconfig(tok, dc)) { tok.token_error("load_conf() failed to parse syslogconfig"); return false; } else count++; } else { tok.token_error(token_file, have); return false; } } tok.token_error("load_conf() found %d syslog files in %s", count, fn); return (!dc.syslogconfigs.empty()); } //////////////////////////////////////////////// // init the tokens // void token_init() { token_cisco = register_string("cisco"); token_file = register_string("file"); token_include = register_string("include"); token_lbrace = register_string("{"); token_parser = register_string("parser"); token_rbrace = register_string("}"); token_semi = register_string(";"); token_ssh = register_string("ssh"); }