Bogofilter adapter for OpenSMTPD in C++
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

115 lines
3.5 KiB

#include <protocol/token.hpp>
#include <util.hpp>
using namespace std;
using namespace util;
const bool debug = false;
namespace protocol::token {
std::string compose(const list_t& tokens) {
return join(tokens, '|');
}
list_t decompose(const std::string& input, size_t max_tokens) {
return split(input, '|', max_tokens);
}
pattern_t::pattern_t() {}
pattern_t::pattern_t(list_t tokens, bool wildcard) : wildcard(wildcard) {
for(auto index = 0; index < tokens.size(); ++index) {
auto token = tokens[index];
if(!wildcard || token != "*") {
this->emplace(index, tokens[index]);
}
}
}
pattern_t::pattern_t(string input, bool wildcard) : pattern_t(split(input, '|'), wildcard) {}
list_t pattern_t::token_list() const {
list_t output;
for(auto element = begin(); element != end(); ++element) {
output.push_back(element->second);
}
return output;
}
ostream& operator<<(typeof(cout)& out, const pattern_t& pattern) {
return out << join(pattern.token_list(), '|') << "<wildcard=" << pattern.wildcard << ">";
}
bool operator<(const pattern_t& l, const pattern_t& r) {
debug && cerr << "Checking if " << l << " < " << r << endl;
if(l == r) {
debug && cerr << "Not less because left equals right" << endl;
return false;
}
if(l.size() < r.size()) {
debug && cerr << "Less because right has more elements" << endl;
return true;
}
for(auto le = l.begin(); le != l.end(); ++le) {
if(r.count(le->first) == 0) {
debug && cerr << "Not less because right is missing " << le->first << " -> " << le->second << endl;
return false;
}
if(le->second < r.at(le->first)) {
debug && cerr << "Not less because " << le->second << " < " << r.at(le->first) << endl;
return true;
}
}
return false;
}
bool operator==(const pattern_t& l, const pattern_t& r) {
debug && cerr << "Checking if " << l << " == " << r << endl;
const pattern_t *subset, *superset;
if(r.wildcard == l.wildcard) {
debug && cerr << "Left and right are both (not) wildcards" << endl;
if(l.size() != r.size()) {
debug && cerr << "Not equal because sizes are unequal" << endl;
return false;
} else {
subset = &l;
superset = &r;
}
} else if(l.wildcard) {
debug && cerr << "Left is wildcard" << endl;
subset = &l;
superset = &r;
} else {
debug && cerr << "Right is wildcard" << endl;
subset = &r;
superset = &l;
}
for(auto le : *subset) {
if(superset->count(le.first) == 0) {
debug && cerr << "Not equal because " << le.first << " -> " << le.second << " is missing in superset" << endl;
return false;
}
auto rv = superset->at(le.first);
if(rv != le.second) {
debug && cerr << "Not equal because " << le.first << " -> " << le.second << " != " << rv << " in superset" << endl;
return false;
}
debug && cerr << le.first << " -> " << le.second << " == " << rv << " in superset" << endl;
}
debug && cerr << "Patterns match" << endl;
return true;
}
}