// -------------------------------------------------------------------- // 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 #include #else #include #include #include #include #include #endif #include #include #include #include #include #include #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::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; } }