📄 2002-12-15_ruleprocessor.cpp
字号:
/*
+-----------------------------------------------------------------------------+
| |
| ruleprocessor.cpp |
| Last change: yyyy-mm-dd |
| |
| Author: Jan Krumsiek |
| eMail: proxy@krumsiek.com |
| Web: http://www.krumsiek.com/proxy |
| |
| Copyright 2003 - Jan Krumsiek |
| This source code can freely be modified and redistributed. No liability |
| whatsoever is taken by the author for any use of this software. |
| |
| Description: |
| This file is the rule processor. It applies all rules defined in a |
| RULEFILE struct (loaded via LoadRules() in rulefile.cpp) and returns if |
| this message is spam or if it may pass |
| |
+-----------------------------------------------------------------------------+
*/
#include "proxymain.h"
#include "rulefile.h"
#include "ruleprocessor.h"
void ExtractElement(CHARPTR header, CHARPTR headerlwr, CHARPTR element, CHARPTR* start, CHARPTR* end);
int CheckString(CHARPTR string, RULE* rule);
int CheckMsg(CHARPTR msg,
RULEFILE* rulefile)
// checks a message against a set of rules and returns if the message
// is spam or may pass
{
UINT i,n;
RULE* currule;
CHARPTR headerlwr,element, tocheck;
CHARPTR sep;
// we are 'caching' all entitys that have already been extracted from the
// header so they don't need to be extracted again. this cache is a simple
// map from a string to another string (from entity name to entity contents)
STRCACHEPTR cache = new STRCACHE;
CHARPTR chkstart,chkend;
UINT result;
CHARPTR header,body;
// we need to seperate header and body
// find first occurence of double line break
sep = strstr(msg, "\x0D\x0A\x0D\x0A\0");
if (sep == 0)
// this is not even a real message, it has no header -> block
return false;
// simply put a \0 at this place to indicate end of header
sep[0] = 0;
header = msg;
// body starts 4 bytes later
body = sep + 4;
// change header to lower-case for future comparison
headerlwr = new char[strlen(header)+1];
strcpy(headerlwr,header);
strlwr(headerlwr);
// walk through rules
n = rulefile->rules->size();
for( i=0; i<n ; i++ )
{
// Get rule from vector
currule = (*(rulefile->rules))[i];
// Body or subject?
if (currule->field == F_BODY)
{
// Body
// Start = body start, end = body end
tocheck = body;
}
else
{
// Header
// Check if string is already in cache
element = (*cache)[currule->fieldname];
if (element == 0)
{
// Not in cache
// extract from header and save in cache
ExtractElement(header,headerlwr,currule->fieldname,&chkstart,&chkend);
if (chkstart != 0)
{
element = (CHARPTR)CopyAndPtr(chkstart, chkend-chkstart+1);
// Save in cache
(*cache)[currule->fieldname] = element;
}
}
tocheck = element;
}
// Now run check
result = CheckString(tocheck,currule);
// restore CR
sep[0] = 13;
// If result = 0 -> nomatch, otherwise -> match
if (result != 0)
{
// return value
if (currule->action == A_ISSPAM)
{
// SPAM
return false;
}
else if (currule->action == A_PASS)
{
// PASS
return true;
}
}
}
// if no rule matched -> PASS
return true;
}
int CheckString(CHARPTR string, RULE* rule)
// this msg checks if a single string matches a rule
{
LIST* list;
UINT i;
int result;
CHARPTR test;
// rule value points to a list or to a value?
if (rule->islist == true)
{
// List !
list = (LIST*)rule->value;
// Iterate through list
for (i=0;i<list->count;i++)
{
// call rule->compare which is the saved comparision function
result = rule->compare(string,list->items[i]);
// Negate?
if (rule->negate == true)
result = (result != 0) ? 0 : 1;
// If now result != 0 then rule does match!
if (result != 0)
{
return 1;
}
}
}
else
{
// No list, simple check
CHARPTR test= (CHARPTR)rule->value;
result = rule->compare(string,(CHARPTR)rule->value);
// Negate?
if (rule->negate == true)
result = (result != 0) ? 0 : 1;
// If now result != 0 then rule does match!
if (result != 0)
{
return 1;
}
}
return 0;
}
void ExtractElement(CHARPTR header, CHARPTR headerlwr, CHARPTR element, CHARPTR* start, CHARPTR* end)
// extracts a single entity from the header and returns the beginning and ending of
// the entity in 'start' and 'end'
{
CHARPTR temp;
CHARPTR search,search2;
UINT ilen1,ilen2;
// Put ':' at the end of element
ilen1 = strlen(element);
temp = (CHARPTR)CopyAndPtr(element,ilen1+1);
temp[ilen1] = ':';
temp[ilen1+1] = 0;
ilen2 = strlen(header);
search = headerlwr;
while (search != 0)
{
// Find occurence of that string in header
search = strstr(search,element);
// Check if beginning of line
// (last byte = line break of first byte found)
if ((search == headerlwr) || (search[-1] = 10))
{
// Is beginning of line: correct position found
// Now seek end of line
search2 = strchr(search,10);
// If no end-of-line found -> last line!
if (search2 == 0) search2 = headerlwr+ilen2;
break;
}
else
{
// No.. not beginning of a line... find next occurence
search++;
}
}
// Delete memory in temporary variable
delete temp;
// If search == 0 -> element not found
if (search == 0)
*start = 0;
else
{
*start = search + ilen1+1;
*end = search2-1;
}
// Translate positions for real 'header' and not 'headerlwr'
*start = (*start-headerlwr)+header;
*end = (*end -headerlwr)+header;
// Find first char that is no space
while (**start == 32)
(*start)++;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -