#include #include #include #include #include "rule.h" #include "parser.h" RulesetParser::RulesetParser(const QString &filename) : _is_valid(false) { int ret; QFile file(filename); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) return; _buffer = ""; _raw_buffer = ""; QTextStream in(&file); QString line = in.readLine(); while (!line.isNull()) { ret = process_line(line); if (ret == 1) { //qDebug("**************************************") //qDebug("buffer: %s", (const char*)_buffer.toAscii() ); //qDebug("**************************************") Rule * rule = process_rule(_buffer,_raw_buffer); if (rule != NULL) _rules_list.append(rule); // XXX memory leak //qDebug(""); _buffer = ""; _raw_buffer = ""; } line = in.readLine(); } _is_valid = true; } int RulesetParser::process_line(QString &input) { QString line = input.simplified(); if (line.length() == 0) return 0; if (line[0] == '#') { if (line.mid(0,5) == "#LOG:") { /* log sample */ _buffer.append(line); _buffer.append("\n"); _raw_buffer.append(line).append("\n"); return 0; } /* line is a comment, ignore it */ return 0; } if (line[line.length()-1] == '\\') { /* continue appending to buffer */ _buffer.append(line.mid(0,line.length()-1)); _raw_buffer.append(line).append("\n"); return 0; } else { _buffer.append(line); _raw_buffer.append(line).append("\n"); return 1; } return -1; } Rule * RulesetParser::process_rule(QString &buffer, const QString &raw_buffer) { Rule * rule = new Rule(buffer,raw_buffer); int has_regex = 0; int index = 0; QStringList lines = buffer.split("\n", QString::SkipEmptyParts); for (int i=0; iaddLogSample(line.mid(5,line.length()-5)); } else if (line.mid(0,6) == "regex=") { line.remove(0,6); has_regex++; if (has_regex > 1) { qWarning("ERROR: more than one 'regex=' in definition"); free(rule); return NULL; } /* read regex */ index = line.indexOf(';'); if (index < 0) { qWarning("ERROR: incomplete regex, missing semicolon ';'"); qWarning("Complete regex: \n****\n%s\n****\n", (const char*)line.toAscii() ); free(rule); return NULL; } //qDebug("Found Regex: %s", (const char*)line.mid(0,index).toAscii() ); rule->setRegex(line.mid(0,index)); /* parse options */ line.remove(0,index+1); while (line.length()) { index = line.indexOf(';'); if (index < 0) { qWarning("WARNING: missing semicolon ';' after sequence '%s', trying to continue anyway",(const char*)line.toAscii()); index = line.length(); } QString _t = line.mid(0,index).simplified(); if (_t.contains("=")) { QStringList keyval = _t.split("=", QString::SkipEmptyParts); if (keyval.size() != 2) { qWarning("ERROR: invalid key = value sequence: %s", (const char*)_t.toAscii() ); free(rule); return NULL; } if ( rule_is_option(keyval.at(0)) ) { rule->setRuleOption(keyval.at(0),keyval.at(1)); } else { rule->addOption(keyval.at(0),keyval.at(1)); } } else if ( rule_is_option(_t) ) { rule->setRuleOption(_t,"1"); } else { qDebug("INFO: unhandled sequence: %s", (const char*)_t.toAscii() ); rule->addOption(_t,""); } line.remove(0,index+1); } } else { qWarning("ERROR: Invalid line: %s", (const char*)line.toAscii() ); free(rule); return NULL; } } return rule; } const Rule * RulesetParser::operator[](int index) { if (index < 0 || index >= _rules_list.size()) return NULL; return _rules_list.at(index); }