// --------------------------------------------------------------------
// m a s k . c p p
//
// Fido messages tracker
// Mask, BodyMask, KludgeMask, ScriptMask...
// --------------------------------------------------------------------
// Copyright (c) 1998-2001 by Fyodor Ustinov
// FIDONet 2:5020/79
//
// All rights reserved.
// --------------------------------------------------------------------
//
// Check points - 23*
//
#ifndef __GNUC__
#include <io.h>
#include <direct.h>
#else
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <errno.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <ctype.h>
#include "constant.hpp"
#include "mask.hpp"
#include "vars.hpp"
#include "log.hpp"
#include "nodelist.hpp"
#include "utils.hpp"
#include "msg.hpp"
#include "age.hpp"
#include "scandir.hpp"
#include "attach.hpp"
#include "aka.hpp"
#include "wildmat.hpp"
#include "script.hpp"
/*--------------------------------------------------------------------*/
/* Common functions */
/* CHP = 231* */
/*--------------------------------------------------------------------*/
static int SoftCmp(char *Str, char *Mask) {
// compare string with mask
int NotFlag;
int rc;
char *Str1;
char *Mask1, *m;
CHP = 23100;
NotFlag = FALSE;
if (strcmp(Mask,"*") == 0) return TRUE;
if (Str == NULL) return FALSE;
Str1 = strdup(Str);
nls_strupr(Str1);
Mask1 = strdup(Mask);
nls_strupr(Mask1);
m = Mask1;
if (*Mask1 == '!') {
NotFlag = TRUE;
Mask1++;
}
if (*Mask1 == '~') {
Mask1++;
rc = (strstr(Str1,Mask1) != NULL);
//printf("-----1>Str == '%s' Mask == '%s' rc == %d\n",Str1,Mask1,rc);
free(Str1);
free(m);
return (NotFlag != rc);
} else {
rc = (wildmat(Str1,Mask1) != 0);
// printf("-----2>Str == '%s' Mask == '%s' rc == %d\n",Str1,Mask1,rc);
free(Str1);
free(m);
return (NotFlag != rc);
}
}
static int SoftKluCmp(cMSG &m, char *StrName, char *StrBody) {
// compare message kludges with mask
IndBiList<Kludge>::ElemPtr Klu;
int rc;
int Comp;
CHP = 23101;
rc = 0;
Klu = m._Klu.GetFirst();
CHP = 23102;
while (Klu != NULL) {
CHP = 23103;
Comp = FALSE;
if (StrName == NULL) {
CHP = 23104;
if (Klu->Name() == NULL || strlen(Klu->Name()) == 0) Comp = TRUE;
} else {
CHP = 23105;
if (SoftCmp(Klu->Name(),StrName)) Comp = TRUE;
}
CHP = 23106;
if (Comp) {
CHP = 23107;
if (StrBody == NULL) {
CHP = 23108;
if (Klu->Body() == NULL || strlen(Klu->Body()) == 0) rc++;
} else {
CHP = 23109;
if (SoftCmp(Klu->Body(),StrBody)) rc++;
}
CHP = 23110;
}
CHP = 23111;
Klu++;
}
CHP = 23122;
return rc;
}
int EquFA(FA const &m, FA const &f) {
int NotFlag;
CHP = 23123;
NotFlag = FALSE;
if (m.Zone() & FA_NOTMASK) NotFlag = TRUE;
if (m.Zone() & FA_OURMASK) {
return (IsMyAka(f) != NotFlag);
}
if (m.Point() & FA_SUBMASK) {
return (Ndl.InSubHubs(f,m) != NotFlag);
}
if (m.Zone() & FA_LSTMASK) {
return ((Ndl.ExistInNodelist(f) != (unsigned int)-1) != NotFlag);
}
if (m.Zone() & FA_PVTMASK) {
return (((Ndl.GetFlags(f) & A_MASK) == A_PVT) != NotFlag);
}
if (m.Zone() & FA_HOLDMASK) {
return (((Ndl.GetFlags(f) & A_MASK) == A_HOLD) != NotFlag);
}
if (m.Zone() & FA_DOWNMASK) {
return (((Ndl.GetFlags(f) & A_MASK) == A_DOWN) != NotFlag);
}
if (m.Zone() & FA_HUBMASK) {
return (((Ndl.GetFlags(f) & A_MASK) == A_HUB) != NotFlag);
}
return(f == m);
}
/*--------------------------------------------------------------------*/
/* Classes */
/*--------------------------------------------------------------------*/
/*--------------------------------------------------------------------*/
/* Mask class */
/*--------------------------------------------------------------------*/
Mask::~Mask() {
}
void Mask::Print(void) const {
switch (_Type) {
case MASK_ADD: Log << "+" ; break;
case MASK_SKIP: Log << "*"; break;
case MASK_NORMAL: break;
case MASK_ERROR: Log << "--==(InternalError)==--"; break;
}
}
/*--------------------------------------------------------------------*/
/* BodyMask class */
/* CHP = 230* */
/*--------------------------------------------------------------------*/
BodyMask::BodyMask() {
CHP = 23000;
_Body = NULL;
_Type = MASK_ERROR;
_Lines = 0;
_Bytes = 0;
sd = NULL;
}
BodyMask::~BodyMask() {
CHP = 23001;
if (_Body != NULL) free(_Body);
_Body = NULL;
_Type = MASK_ERROR;
_Lines = 0;
_Bytes = 0;
sd = NULL;
}
void BodyMask::Print(void) const {
Mask::Print();
Log << "BodyMask: \"" << _Body << "\" ";
if (_Lines != (uint) -1) {
if ((_Lines & 0x08000000) != 0) {
Log << "!";
}
Log << (_Lines & 0x00ffffff);
} else {
Log << "*";
}
Log << " ";
if (_Bytes != (uint) -1) {
if ((_Bytes & 0x08000000) != 0) {
Log << "!";
}
Log << (_Bytes & 0x00ffffff);
} else {
Log << "*";
}
}
int BodyMask::operator == (cMSG &m) const {
CHP = 23010;
if (LogLevel >= 5) {
Log.Level(LOGD) << "Compare message with mask '";
Print();
Log.Level(LOGD) << "'" << EOL;
}
if (!SoftCmp(m.Body(),_Body)) return FALSE;
if (_Lines != (unsigned int)-1) {
if (_Lines & 0x08000000) {
if (m.Lines() >= (_Lines & 0x07ffffff)) return FALSE;
} else {
if (m.Lines() < (_Lines & 0x07ffffff)) return FALSE;
}
}
if (_Bytes != (unsigned int)-1) {
if (_Bytes & 0x08000000) {
if (m.Bytes() >= (_Bytes & 0x07ffffff)) return FALSE;
} else {
if (m.Bytes() < (_Bytes & 0x07ffffff)) return FALSE;
}
}
CHP = 23011;
Log.Level(LOGD) << "Message is equal to mask." << EOL;
return TRUE;
}
/*--------------------------------------------------------------------*/
/* KludgeMask class */
/* CHP = 232* */
/*--------------------------------------------------------------------*/
KludgeMask::KludgeMask() {
CHP = 23200;
_KludgeName = NULL;
_KludgeBody = NULL;
_Type = MASK_ERROR;
_Times = 0;
sd = NULL;
}
KludgeMask::~KludgeMask() {
CHP = 23201;
if (_KludgeName != NULL) free(_KludgeName);
_KludgeName = NULL;
if (_KludgeBody != NULL) free(_KludgeBody);
_KludgeBody = NULL;
_Type = MASK_ERROR;
_Times = 0;
sd = NULL;
}
void KludgeMask::Print(void) const {
Mask::Print();
Log << "KludgeMask: \"" << _KludgeName << "\" \"" << _KludgeBody << "\" ";
if (_Times != (uint) -1) {
if ((_Times & 0x08000000) != 0) {
Log << "!";
}
Log << (_Times & 0x00ffffff);
} else {
Log << "*";
}
}
int KludgeMask::operator == (cMSG &m) const {
uint cLoops;
CHP = 23210;
if (LogLevel >= 5) {
Log.Level(LOGD) << "Compare message with mask '";
Print();
Log.Level(LOGD) << "'" << EOL;
}
if ((cLoops = SoftKluCmp(m,_KludgeName,_KludgeBody)) == 0) return FALSE;
Log.Level(LOGD) << "Matches " << cLoops << " times." << EOL;
if (_Times != (unsigned int)-1) {
if (_Times & 0x08000000) {
if (cLoops >= (_Times & 0x07ffffff)) return FALSE;
} else {
if (cLoops < (_Times & 0x07ffffff)) return FALSE;
}
}
CHP = 23211;
Log.Level(LOGD) << "Message is equal to mask." << EOL;
return TRUE;
}
/*--------------------------------------------------------------------*/
/* NormalMask class */
/* CHP = 233* */
/*--------------------------------------------------------------------*/
NormalMask::NormalMask() {
CHP = 23300;
_FromName = NULL;
_ToName = NULL;
_Subject = NULL;
Loops = (unsigned int)-1;
fPrivate = fCrash = fReceived = fSend =
fFileAttach = fTransit = fOrphan = fKillSend = fLocal =
fHold = fFileRequest = fRRQ = fIRR = fARQ = fFURQ = fDIR =
fIMM = fCFM = fTFS = fKFS = fEmpty = fMaxAge = fLoop = fAttExists =
fEchomail = fScanned = fMaxAttach = fLok = fAS = 0;
_Type = MASK_ERROR;
sd = NULL;
}
NormalMask::~NormalMask() {
CHP = 23301;
if (_FromName != NULL) free(_FromName);
_FromName = NULL;
if (_ToName != NULL) free (_ToName);
_ToName = NULL;
if (_Subject != NULL) free (_Subject);
_Subject = NULL;
_Type = MASK_ERROR;
sd = NULL;
}
void NormalMask::Print(void) const {
Str fa1;
CHP = 23302;
Mask::Print();
Log << "Mask: \"" << _FromName << "\" " << _FromAddr
<< " \"" << _ToName << "\" " << _ToAddr
<< " \"" << _Subject << '"';
if (fMaxAge == 1) fa1 += "+g";
if (fMaxAge == 2) fa1 += "-g";
if (fAttExists == 1) fa1 += "+x";
if (fAttExists == 2) fa1 += "-x";
if (fPrivate == 1) fa1 += "+p";
if (fPrivate == 2) fa1 += "-p";
if (fCrash == 1) fa1 += "+c";
if (fCrash == 2) fa1 += "-c";
if (fReceived == 1) fa1 += "+r";
if (fReceived == 2) fa1 += "-r";
if (fSend == 1) fa1 += "+s";
if (fSend == 2) fa1 += "-s";
if (fFileAttach == 1) fa1 += "+a";
if (fFileAttach == 2) fa1 += "-a";
if (fTransit == 1) fa1 += "+i";
if (fTransit == 2) fa1 += "-i";
if (fOrphan == 1) fa1 += "+o";
if (fOrphan == 2) fa1 += "-o";
if (fKillSend == 1) fa1 += "+k";
if (fKillSend == 2) fa1 += "-k";
if (fLocal == 1) fa1 += "+l";
if (fLocal == 2) fa1 += "-l";
if (fHold == 1) fa1 += "+h";
if (fHold == 2) fa1 += "-h";
if (fFileRequest == 1) fa1 += "+f";
if (fFileRequest == 2) fa1 += "-f";
if (fRRQ == 1) fa1 += "+q";
if (fRRQ == 2) fa1 += "-q";
if (fIRR == 1) fa1 += "+y";
if (fIRR == 2) fa1 += "-y";
if (fARQ == 1) fa1 += "+b";
if (fARQ == 2) fa1 += "-b";
if (fFURQ == 1) fa1 += "+u";
if (fFURQ == 2) fa1 += "-u";
if (fDIR == 1) fa1 += "+d";
if (fDIR == 2) fa1 += "-d";
if (fIMM == 1) fa1 += "+m";
if (fIMM == 2) fa1 += "-m";
if (fEmpty == 1) fa1 += "+e";
if (fEmpty == 2) fa1 += "-e";
if (fTFS == 1) fa1 += "+t";
if (fTFS == 2) fa1 += "-t";
if (fKFS == 1) fa1 += "+j";
if (fKFS == 2) fa1 += "-j";
if (fCFM == 1) fa1 += "+n";
if (fCFM == 2) fa1 += "-n";
if (fEchomail == 1) fa1 += "+E";
if (fEchomail == 2) fa1 += "-E";
if (fMaxAttach == 1) fa1 += "+A";
if (fMaxAttach == 2) fa1 += "-A";
if (fScanned == 1) fa1 += "+v";
if (fScanned == 2) fa1 += "-v";
if (fLok == 1) fa1 += "+L";
if (fLok == 2) fa1 += "-L";
if (fAS == 1) fa1 += "+S";
if (fAS == 2) fa1 += "-S";
if (fLoop != 0) {
if (fLoop == 1) fa1 += '+';
if (fLoop == 2) fa1 += '-';
fa1 += Loops;
}
if (fa1.Length() == 0) fa1 = "*";
Log << " " << fa1;
}
int NormalMask::operator == (cMSG &m) const {
uint cMaxAge;
uint cLoops;
uint cMaxAttachSize;
char *tmt2;
CHP = 23310;
if (LogLevel >= 5) {
Log.Level(LOGD) << "Compare message with mask '";
Print();
Log.Level(LOGD) << "'" << EOL;
}
if (!EquFA(_ToAddr, m._ToAddr)) return FALSE;
if (!EquFA(_FromAddr, m._FromAddr)) return FALSE;
if (!SoftCmp(m._FromName,_FromName)) return FALSE;
if (!SoftCmp(m._ToName,_ToName)) return FALSE;
if (!SoftCmp(m._Subject,_Subject)) return FALSE;
if ((fPrivate - m.fPrivate) == 1) return FALSE;
if ((fCrash - m.fCrash) == 1) return FALSE;
if ((fReceived - m.fReceived) == 1) return FALSE;
if ((fSend - m.fSend) == 1) return FALSE;
if ((fFileAttach - m.fFileAttach) == 1) return FALSE;
if ((fTransit - m.fTransit) == 1) return FALSE;
if ((fOrphan - m.fOrphan) == 1) return FALSE;
if ((fKillSend - m.fKillSend) == 1) return FALSE;
if ((fLocal - m.fLocal) == 1) return FALSE;
if ((fHold - m.fHold) == 1) return FALSE;
if ((fFileRequest - m.fFileRequest) == 1) return FALSE;
if ((fRRQ - m.fRRQ) == 1) return FALSE;
if ((fIRR - m.fIRR) == 1) return FALSE;
if ((fARQ - m.fARQ) == 1) return FALSE;
if ((fFURQ - m.fFURQ) == 1) return FALSE;
if ((fDIR - m.fDIR) == 1) return FALSE;
if ((fIMM - m.fIMM) == 1) return FALSE;
if ((fCFM - m.fCFM) == 1) return FALSE;
if ((fTFS - m.fTFS) == 1) return FALSE;
if ((fKFS - m.fKFS) == 1) return FALSE;
if ((fEchomail - m.fEchomail) == 1) return FALSE;
if ((fScanned - m.fScanned) == 1) return FALSE;
if ((fLok - m.fLok) == 1) return FALSE;
if ((fAS - m.fAS) == 1) return FALSE;
if ((fEmpty - m.fEmpty) == 1) return FALSE;
if (fLoop != 0) {
cLoops = m.LoopCount(sd->LoopStr());
if (fLoop == 1 && (cLoops < Loops)) return FALSE;
if (fLoop == 2 && (cLoops >= Loops)) return FALSE;
}
cMaxAge = sd->MaxAge();
if (fMaxAge == 1 && !AgeIsOver(m._Time,cMaxAge)) return FALSE;
if (fMaxAge == 2 && AgeIsOver(m._Time,cMaxAge)) return FALSE;
if (fAttExists != 0 || fMaxAttach != 0) {
if (!m.fFileAttach) return FALSE;
tmt2 = FileInbound;
if (sd->_FileInbound != NULL) {
FileInbound = sd->_FileInbound;
}
if (fAttExists == 1 && !AttachExists(m)) {
FileInbound = tmt2;
return FALSE;
}
if (fAttExists == 2 && AttachExists(m)) {
FileInbound = tmt2;
return FALSE;
}
cMaxAttachSize = m.AttachSize();
FileInbound = tmt2;
if (fMaxAttach == 1 && (cMaxAttachSize <= sd->MaxAttachSize())) return FALSE;
if (fMaxAttach == 2 && (cMaxAttachSize > sd->MaxAttachSize())) return FALSE;
}
CHP = 23311;
Log.Level(LOGD) << "Message is equal to mask." << EOL;
return TRUE;
}
/*--------------------------------------------------------------------*/
/* ScriptMask class */
/* CHP = 234* */
/*--------------------------------------------------------------------*/
ScriptMask::ScriptMask() {
CHP = 23400;
_ScriptName = NULL;
_Type = MASK_ERROR;
sd = NULL;
}
ScriptMask::~ScriptMask() {
CHP = 23401;
if (_ScriptName != NULL) free(_ScriptName);
_ScriptName = NULL;
_Type = MASK_ERROR;
sd = NULL;
}
void ScriptMask::Print(void) const {
Mask::Print();
Log << "ScriptMask: \"" << _ScriptName << "\"";
}
int ScriptMask::operator == (cMSG &m) const {
m = m;
CHP = 23410;
if (LogLevel >= 5) {
Log.Level(LOGD) << "Compare message with mask '";
Print();
Log.Level(LOGD) << "'" << EOL;
}
CHP = 23411;
switch (DoSomeWordRc(_ScriptName)) {
case SS_OK: Log.Level(LOGD) << "Message is equal to mask." << EOL;
return TRUE;
case SS_NOTDEF:
case SS_FALSE:
case SS_ERROR:
default: Log.Level(LOGD) << "Message is not equal to mask." << EOL;
return FALSE;
}
}
syntax highlighted by Code2HTML, v. 0.9.1