// --------------------------------------------------------------------
// S c d _ d o . c p p
//
// Fido messages tracker
// ScanDir.cpp portion.
// --------------------------------------------------------------------
// Copyright (c) 1998-2000 by Fyodor Ustinov
// FIDONet 2:5020/79
//
// All rights reserved.
// --------------------------------------------------------------------
#ifndef __SCD_DP_CPP__
#define __SCD_DP_CPP__
FA &MakeFromAddr(cMSG &m, FA &s) {
static FA t;
CHP = 2;
t = s;
if (s.Zone() & FA_ANYMASK) {
t.Zone(m._FromAddr.Zone());
} else {
t.Zone(s.Zone());
}
if (s.Net() & FA_ANYMASK) {
t.Net(m._FromAddr.Net());
} else {
t.Net(s.Net());
}
if (s.Node() & FA_ANYMASK) {
t.Node(m._FromAddr.Node());
} else {
t.Node(s.Node());
}
if (s.Point() & FA_ANYMASK) {
t.Point(m._FromAddr.Point());
} else {
t.Point(s.Point());
}
if (s.Zone() & FA_TOMASK) {
t = m._ToAddr;
}
if (s.Zone() & FA_FROMMASK) {
t = m._FromAddr;
}
if (s.Zone() & FA_OURMASK) {
t = GetMyAka(m._ToAddr);
}
return t;
}
FA &MakeToAddr(cMSG &m, FA &s) {
static FA t;
CHP = 3;
t = s;
if (s.Zone() & FA_ANYMASK) {
t.Zone(m._ToAddr.Zone());
} else {
t.Zone(s.Zone());
}
if (s.Net() & FA_ANYMASK) {
t.Net(m._ToAddr.Net());
} else {
t.Net(s.Net());
}
if (s.Node() & FA_ANYMASK) {
t.Node(m._ToAddr.Node());
} else {
t.Node(s.Node());
}
if (s.Point() & FA_ANYMASK) {
t.Point(m._ToAddr.Point());
} else {
t.Point(s.Point());
}
if (s.Zone() & FA_FROMMASK) {
t = m._FromAddr;
}
if (s.Zone() & FA_TOMASK) {
t = m._ToAddr;
}
if (s.Zone() & FA_OURMASK) {
t = GetMyAka(m._FromAddr);
}
return t;
}
void MakeToName(cMSG &m, char *s, char *t) {
CHP = 4;
if (s != NULL && strcmp(s,"*") == 0) {
strncpy(t,m._ToName,36);
return;
}
if (s != NULL && strcmp(s,FROMMASK_CHAR) == 0) {
strncpy(t,m._FromName,36);
return;
}
if (s != NULL && strcmp(s,TOMASK_CHAR) == 0) {
strncpy(t,m._ToName,36);
return;
}
if (s != NULL) {
strncpy(t,s,36);
return;
}
}
void MakeFromName(cMSG &m, char *s, char *t) {
CHP = 5;
if (s != NULL && strcmp(s,"*") == 0) {
strncpy(t,m._FromName,36);
return;
}
if (s != NULL && strcmp(s,FROMMASK_CHAR) == 0) {
strncpy(t,m._FromName,36);
return;
}
if (s != NULL && strcmp(s,TOMASK_CHAR) == 0) {
strncpy(t,m._ToName,36);
return;
}
if (s != NULL) {
strncpy(t,s,36);
return;
}
}
void PrepareMsg(cMSG &s, cMSG &d, NormalMask *_Mask) {
FA tf;
FA tt;
char sf[36];
char st[36];
char *tmt;
CHP = 6;
MakeFromName(s,_Mask->_FromName,sf);
MakeToName(s,_Mask->_ToName,st);
strncpy(d._FromName,sf,36);
strncpy(d._ToName,st,36);
strncpy(d._Subject,s._Subject,72);
tf = MakeFromAddr(s,_Mask->_FromAddr);
tt = MakeToAddr(s,_Mask->_ToAddr);
if (s._FromAddr != tf) { // If we change source address
d.fChanged = 1; // we need change MSGID.
}
d._FromAddr = tf;
d._ToAddr = tt;
if (&s == &d) {
d.fPrivate = (_Mask->fPrivate != 0) ? _Mask->fPrivate : s.fPrivate;
d.fCrash = (_Mask->fCrash != 0) ? _Mask->fCrash : s.fCrash;
d.fReceived = (_Mask->fReceived != 0) ? _Mask->fReceived : s.fReceived;
d.fSend = (_Mask->fSend != 0) ? _Mask->fSend : s.fSend;
d.fFileAttach = (_Mask->fFileAttach != 0) ? _Mask->fFileAttach : s.fFileAttach;
d.fTransit = (_Mask->fTransit != 0) ? _Mask->fTransit : s.fTransit;
d.fOrphan = (_Mask->fOrphan != 0) ? _Mask->fOrphan : s.fOrphan;
d.fKillSend = (_Mask->fKillSend != 0) ? _Mask->fKillSend : s.fKillSend;
d.fLocal = (_Mask->fLocal != 0) ? _Mask->fLocal : s.fLocal;
d.fHold = (_Mask->fHold != 0) ? _Mask->fHold : s.fHold;
d.fFileRequest = (_Mask->fFileRequest != 0) ? _Mask->fFileRequest : s.fFileRequest;
d.fRRQ = (_Mask->fRRQ != 0) ? _Mask->fRRQ : s.fRRQ;
d.fIRR = (_Mask->fIRR != 0) ? _Mask->fIRR : s.fIRR;
d.fARQ = (_Mask->fARQ != 0) ? _Mask->fARQ : s.fARQ;
d.fFURQ = (_Mask->fFURQ != 0) ? _Mask->fFURQ : s.fFURQ;
d.fDIR = (_Mask->fDIR != 0) ? _Mask->fDIR : s.fDIR;
d.fIMM = (_Mask->fIMM != 0) ? _Mask->fIMM : s.fIMM;
d.fCFM = (_Mask->fCFM != 0) ? _Mask->fCFM : s.fCFM;
d.fTFS = (_Mask->fTFS != 0) ? _Mask->fTFS : s.fTFS;
d.fKFS = (_Mask->fKFS != 0) ? _Mask->fKFS : s.fKFS;
d.fScanned = (_Mask->fScanned != 0) ? _Mask->fScanned : s.fScanned;
d.fLok = (_Mask->fLok != 0) ? _Mask->fLok : s.fLok;
d.fAS = (_Mask->fAS != 0) ? _Mask->fAS : s.fAS;
} else {
d.fPrivate = (_Mask->fPrivate != 0) ? _Mask->fPrivate : 0;
d.fCrash = (_Mask->fCrash != 0) ? _Mask->fCrash : 0;
d.fReceived = (_Mask->fReceived != 0) ? _Mask->fReceived : 0;
d.fSend = (_Mask->fSend != 0) ? _Mask->fSend : 0;
d.fFileAttach = (_Mask->fFileAttach != 0) ? _Mask->fFileAttach : 0;
d.fTransit = (_Mask->fTransit != 0) ? _Mask->fTransit : 0;
d.fOrphan = (_Mask->fOrphan != 0) ? _Mask->fOrphan : 0;
d.fKillSend = (_Mask->fKillSend != 0) ? _Mask->fKillSend : 0;
d.fLocal = (_Mask->fLocal != 0) ? _Mask->fLocal : 0;
d.fHold = (_Mask->fHold != 0) ? _Mask->fHold : 0;
d.fFileRequest = (_Mask->fFileRequest != 0) ? _Mask->fFileRequest : 0;
d.fRRQ = (_Mask->fRRQ != 0) ? _Mask->fRRQ : 0;
d.fIRR = (_Mask->fIRR != 0) ? _Mask->fIRR : 0;
d.fARQ = (_Mask->fARQ != 0) ? _Mask->fARQ : 0;
d.fFURQ = (_Mask->fFURQ != 0) ? _Mask->fFURQ : 0;
d.fDIR = (_Mask->fDIR != 0) ? _Mask->fDIR : 0;
d.fIMM = (_Mask->fIMM != 0) ? _Mask->fIMM : 0;
d.fCFM = (_Mask->fCFM != 0) ? _Mask->fCFM : 0;
d.fTFS = (_Mask->fTFS != 0) ? _Mask->fTFS : 0;
d.fKFS = (_Mask->fKFS != 0) ? _Mask->fKFS : 0;
d.fScanned = (_Mask->fScanned != 0) ? _Mask->fScanned : 0;
d.fLok = (_Mask->fLok != 0) ? _Mask->fLok : 0;
d.fAS = (_Mask->fAS != 0) ? _Mask->fAS : 0;
}
if (_Mask->_Subject != NULL && strcmp(_Mask->_Subject,"*") != 0) {
tmt = StrAsTpl(d,_Mask->_Subject);
strncpy(d._Subject,tmt,72);
free(tmt);
}
if (LogLevel >= 5) {
Log.Level(LOGD) << "----------------------- Destin message -----------------" << EOL;
d.Print();
Log.Level(LOGD) << "----------------------- Source message -----------------" << EOL;
s.Print();
}
}
int Action::Do(MSGBASE &b, cMSG &m) {
char *tmt;
char *tmt2;
cMSG *d;
FILE *fh;
PKT p;
FA f;
PKTrc rc;
int rcc;
CHP = 7;
switch(_Act) {
case ACT_IGNORE:
CHP = 8;
if (LogIgnore) {
Log.Level(LOGI) << "Ignore msg " << b.MessageName() << EOL;
}
break;
case ACT_DELETE:
CHP = 9;
tmt = b.MessageName();
Log.Level(LOGI) << "Delete msg " << tmt << EOL;
if (!b.DeleteMsg()) {
Log.Level(LOGE) << "Error deleting message " << tmt << EOL;
return FALSE;
}
break;
case ACT_FLAG:
CHP = 10;
Log.Level(LOGI) << "Create file " << _OutDir << EOL;
fh = fcopen(_OutDir,"wb");
if (fh == NULL) {
Log.Level(LOGE) << "Error creating file " << _OutDir << EOL;
return FALSE;
}
fclose(fh);
break;
case ACT_DELFILE:
CHP = 10;
Log.Level(LOGI) << "Delete file " << _OutDir << EOL;
unlink(_OutDir);
break;
case ACT_DELETEATTACH:
CHP = 11;
if (m.fFileAttach) {
m.Normalise();
tmt = b.MessageName();
Log.Level(LOGI) << "Delete files attached to " << tmt << EOL;
tmt2 = FileInbound;
if (sd->_FileInbound != NULL) {
FileInbound = sd->_FileInbound;
}
if (!DeleteAttach(m)) {
FileInbound = tmt2;
return FALSE;
}
FileInbound = tmt2;
}
break;
case ACT_CHANGEPATH:
CHP = 12;
if (m.fFileAttach) {
m.Normalise();
tmt = b.MessageName();
if (strlen(_OutDir) == 0) {
Log.Level(LOGI) << "Strip path to attached files in " << tmt << EOL;
} else {
Log.Level(LOGI) << "Change path to attached files in " << tmt << " to " << _OutDir << EOL;
}
tmt2 = FileInbound;
if (sd->_FileInbound != NULL) {
FileInbound = sd->_FileInbound;
}
if (!ChangePath(m,_OutDir)) {
FileInbound = tmt2;
return FALSE;
}
FileInbound = tmt2;
// m.fChanged = 1;
if (SetViaAlways == TRUE) {
m.AddOurVia();
}
if (!b.WriteMsg(m)) {
Log.Level(LOGE) << "Error writing message with new subject " << tmt << EOL;
return FALSE;
}
}
break;
case ACT_MOVEATTACH:
CHP = 13;
if (m.fFileAttach) {
m.Normalise();
tmt = b.MessageName();
Log.Level(LOGI) << "Move attached files in " << tmt << " to " << _OutDir << EOL;
tmt2 = FileInbound;
if (sd->_FileInbound != NULL) {
FileInbound = sd->_FileInbound;
}
if (!MoveAttach(m,_OutDir)) {
FileInbound = tmt2;
return FALSE;
}
FileInbound = tmt2;
// m.fChanged = 1;
if (SetViaAlways == TRUE) {
m.AddOurVia();
}
if (!b.WriteMsg(m)) {
Log.Level(LOGE) << "Error writing message with new subject " << tmt << EOL;
return FALSE;
}
}
break;
case ACT_COPYATTACH:
CHP = 13;
if (m.fFileAttach) {
m.Normalise();
tmt = b.MessageName();
Log.Level(LOGI) << "Copy attached files in " << tmt << " to " << _OutDir << EOL;
tmt2 = FileInbound;
if (sd->_FileInbound != NULL) {
FileInbound = sd->_FileInbound;
}
if (!CopyAttach(m,_OutDir)) {
FileInbound = tmt2;
return FALSE;
}
FileInbound = tmt2;
}
break;
case ACT_COPY:
CHP = 14;
m.Normalise();
if (SetViaAlways == TRUE) {
m.AddOurVia();
}
CHP = 1401;
tmt = b.MessageName();
CHP = 1402;
Log.Level(LOGI) << "Copy msg " << tmt << " to " << _Base->BaseName() << EOL;
if (_Base->Open() != TRUE) {
Log.Level(LOGE) << "Error opening base '" << _Base->BaseName() << "'" << EOL;
return FALSE;
}
CHP = 1403;
if (!_Base->WriteNewMsg(m)) {
CHP = 1404;
Log.Level(LOGE) << "Error writing message " << tmt <<
" to " << _Base->BaseName() << EOL;
_Base->Close();
return FALSE;
}
CHP = 1405;
_Base->Close();
CHP = 1406;
break;
case ACT_MOVE:
CHP = 15;
m.Normalise();
CHP = 1501;
if (SetViaAlways == TRUE) {
m.AddOurVia();
}
tmt = b.MessageName();
CHP = 1502;
Log.Level(LOGI) << "Move msg " << tmt << " to " << _Base->BaseName() << EOL;
if (_Base->Open() != TRUE) {
Log.Level(LOGE) << "Error opening base '" << _Base->BaseName() << "'" << EOL;
return FALSE;
}
CHP = 1503;
if (!_Base->WriteNewMsg(m)) {
CHP = 1504;
Log.Level(LOGE) << "Error writing message " << tmt <<
" to " << _Base->BaseName() << EOL;
_Base->Close();
return FALSE;
}
CHP = 1505;
if (!b.DeleteMsg()) {
CHP = 1506;
Log.Level(LOGE) << "Error deleting message " << tmt << EOL;
_Base->Close();
return FALSE;
}
CHP = 1506;
_Base->Close();
CHP = 1507;
break;
case ACT_WRITEFILE:
CHP = 16;
m.Normalise();
_Tpl->Clean();
_Tpl->SetMsg(m);
Log.Level(LOGI) << "Create file " << _OutDir << EOL;
if (!_Tpl->Parse()) {
return FALSE;
}
if (!_Tpl->Save(_OutDir,1)) {
return FALSE;
}
_Tpl->Clean();
break;
case ACT_ADDFILE:
CHP = 16001;
m.Normalise();
_Tpl->Clean();
_Tpl->SetMsg(m);
Log.Level(LOGI) << "Append to file " << _OutDir << EOL;
if (!_Tpl->Parse()) {
return FALSE;
}
if (!_Tpl->Save(_OutDir,2)) {
return FALSE;
}
_Tpl->Clean();
break;
case ACT_ADDNOTE:
CHP = 16100;
m.Normalise();
if (SetViaAlways == TRUE) {
m.AddOurVia();
}
_Tpl->Clean();
_Tpl->SetMsg(m);
tmt = b.MessageName();
Log.Level(LOGI) << "Add note " << _OutDir << " to msg " << tmt << EOL;
if (!_Tpl->Parse()) {
return FALSE;
}
CHP = 16101;
while ((tmt = strchr((char *) _Tpl->Body,'\n')) != NULL) *tmt = '\r';
tmt = m._Body;
CHP = 16102;
m._Body = (char *) malloc(((tmt != NULL) ? strlen(tmt) : 0) + strlen(_Tpl->Body) + 1);
m.fEmpty = 0;
CheckMem(m._Body);
CHP = 16103;
strcpy(m._Body,_Tpl->Body);
CHP = 16104;
if (tmt != NULL) {
strcat(m._Body,tmt);
free(tmt);
}
CHP = 16105;
_Tpl->Clean();
// m.fChanged = 1;
CHP = 16106;
if (!b.WriteMsg(m)) {
tmt = b.MessageName();
Log.Level(LOGE) << "Error rewriting message " << tmt << EOL;
return FALSE;
}
CHP = 16107;
break;
case ACT_CALL:
m.Normalise();
tmt = StrAsTpl(m,_TplName);
Log.Level(LOGI) << "Execute programm " << tmt << EOL;
if (_Tpl != NULL) {
_Tpl->Clean();
_Tpl->SetMsg(m);
if (!_Tpl->Parse()) {
free(tmt);
return FALSE;
}
if (!_Tpl->Save(_OutDir,1)) {
free(tmt);
return FALSE;
}
_Tpl->Clean();
}
rcc = ExecP(tmt);
unlink(_OutDir);
if (rcc < 0) {
Log.Level(LOGE) << "Error execution " << tmt << EOL;
} else {
Log.Level(LOGI) << "Done execution. Error code == " << rcc << EOL;
}
free(tmt);
break;
case ACT_ROUTE:
CHP = 17;
tmt2 = FileInbound;
if (sd->_FileInbound != NULL) {
FileInbound = sd->_FileInbound;
}
m.Normalise();
if (_f.Zone() & FA_TOMASK) {
f = m._ToAddr;
if (!(_f.Point() & FA_TOMASK)) {
f.Point(0);
}
} else {
f = _f;
}
Log.Level(LOGI) << "Route message from " << m._FromAddr;
Log.Level(LOGI) << " to " << m._ToAddr;
Log.Level(LOGI) << " via " << f << EOL;
strncpy(m._RoutedVia,(char *)(Str)f,127);
if (Before != NULL) {
Log.Level(LOGI) << " Execute 'BeforeRoute' ScanDir." << EOL;
Before->DoWithRoute(*sd->_Base,m);
m._RoutedVia[0] = '\0';
}
p.Set(f);
tmt = (char *)(Str)f;
m.AddOurVia();
rc = p.AddMsg(m,_Flav);
switch (rc) {
case BSY:
Log.Level(LOGW) << f << " is Busy now." << EOL;
p.Clean();
FileInbound = tmt2;
return TRUE;
case NULLPKT:
Log.Level(LOGW) << "?UT file for address " << f
<< " is null size. Message " << b.MessageName()
<< " skipped." << EOL;
p.Clean();
FileInbound = tmt2;
return TRUE;
case PKTERROR:
Log.Level(LOGE) << "Error routing message "<< b.MessageName()
<< " to " << f << EOL;
p.Clean();
FileInbound = tmt2;
return FALSE;
case ATTERROR:
Log.Level(LOGE) << "Error routing files attached to message "<< b.MessageName()
<< " to " << f << EOL;
p.Clean();
FileInbound = tmt2;
return FALSE;
case BADPKT:
Log.Level(LOGE) << "?LO file for address " << f
<< " is invalid. Message " << b.MessageName()
<< " skipped." << EOL;
p.Clean();
FileInbound = tmt2;
return TRUE;
default: break;
}
p.Clean();
LogTraffic(m,f);
tmt = b.MessageName();
if (KillMode == KILL_ALWAYS || (KillMode == KILL_FLAG && m.fKillSend)) {
if (!b.DeleteMsg()) {
Log.Level(LOGE) << "Error deleting message " << tmt << EOL;
FileInbound = tmt2;
return FALSE;
}
}
if (After != NULL) {
Log.Level(LOGI) << " Execute 'AfterRoute' ScanDir." << EOL;
strncpy(m._RoutedVia,(char *)(Str)f,127);
After->DoWithRoute(*sd->_Base,m);
m._RoutedVia[0] = '\0';
}
FileInbound = tmt2;
break;
case ACT_POLL:
CHP = -17;
if (_f.Zone() & FA_TOMASK) {
f = m._ToAddr;
if (!(_f.Point() & FA_TOMASK)) {
f.Point(0);
}
} else {
f = _f;
}
Log.Level(LOGI) << "Poll " << f << EOL;
p.Set(f);
rc = p.Poll(_Flav);
switch (rc) {
case BSY:
Log.Level(LOGW) << f << " is Busy now." << EOL;
p.Clean();
return TRUE;
case PKTERROR:
Log.Level(LOGE) << "Error generating poll to " << f << EOL;
p.Clean();
return FALSE;
default: break;
}
p.Clean();
break;
case ACT_NEWMSG:
CHP = 18;
d = new cMSG();
CHP = 1801;
_Tpl->Clean();
_Tpl->SetMsg(m,*d);
CHP = 1802;
d->_Time = time(NULL);
Log.Level(LOGI) << "Create new msg in " << _Base->BaseName() << EOL;
if (_Base->Open() != TRUE) {
Log.Level(LOGE) << "Error opening base '" << _Base->BaseName() << "'" << EOL;
return FALSE;
}
CHP = 1803;
PrepareMsg(m,*d,(NormalMask*)_Mask);
CHP = 1804;
m.Normalise();
CHP = 1805;
d->fChanged = 1;
if (!_Tpl->Parse()) {
CHP = 1806;
delete d;
_Base->Close();
return FALSE;
}
CHP = 1807;
CHP = 1808;
if (!_Tpl->Save(*d)) {
delete d;
_Base->Close();
CHP = 1809;
return FALSE;
}
CHP = 1810;
if (SetViaAlways == TRUE) {
d->AddOurVia();
}
if (!_Base->WriteNewMsg(*d)) {
Log.Level(LOGE) << "Error writing new message " << _Base->MessageName() << EOL;
delete d;
_Base->Close();
return FALSE;
}
CHP = 1811;
_Tpl->Clean();
CHP = 1812;
delete d;
_Base->Close();
break;
case ACT_REWRITE:
CHP = 19;
tmt = b.MessageName();
Log.Level(LOGI) << "Rewrite msg " << tmt << EOL;
PrepareMsg(m,m,(NormalMask*)_Mask);
m.Normalise();
if (SetViaAlways == TRUE) {
m.AddOurVia();
}
// m.fChanged = 1;
if (!b.WriteMsg(m)) {
Log.Level(LOGE) << "Error rewriting message " << tmt << EOL;
return FALSE;
}
break;
case ACT_RECODE:
CHP = 1901;
tmt = b.MessageName();
Log.Level(LOGI) << "Recode msg " << tmt << EOL;
m.Normalise();
m.Recode(_TplName);
if (!b.WriteMsg(m)) {
Log.Level(LOGE) << "Error recoding message " << tmt << EOL;
return FALSE;
}
break;
case ACT_DISPLAY:
CHP = 20;
tmt = StrAsTpl(m,_TplName);
Log.Level(LOGE) << tmt << EOL;
free(tmt);
break;
case ACT_SCRIPT:
CHP = 2001;
if (DoThisWord(_TplName) != TRUE) {
return FALSE;
}
break;
case ACT_SPLIT:{
int Parts;
int Lns;
int CurPart;
char *sBeg = NULL;
char *tmt2;
char *stmt = NULL;
m.Normalise();
if (SetViaAlways == TRUE) {
m.AddOurVia();
}
tmt = b.MessageName();
Lns = m.Lines();
if (Lns > _Lines) {
Log.Level(LOGI) << "Split message " << tmt << EOL;
Parts = Lns / _Lines;
if ((Lns % _Lines) != 0) Parts++;
CurPart = 1;
sBeg = m.Body();
tmt2 = sBeg;
tmt = (char *)malloc(m.Bytes()+200);
stmt = tmt;
CheckMem(tmt);
while (*tmt2 != '\0') {
tmt = stmt;
sprintf(tmt,"\1SPLITTED: By FTrack. Part %d of %d\r",CurPart, Parts);
tmt += strlen(tmt);
for(Lns = 0; Lns < _Lines && *tmt2 != '\0'; tmt2++,tmt++) {
if (*tmt2 == '\r') Lns++;
*tmt = *tmt2;
}
*tmt = '\0';
m.Body(stmt);
m.fChanged = TRUE;
if (!b.WriteNewMsg(m)) {
Log.Level(LOGE) << " Error writing splitted message." << EOL;
free(stmt);
m.Body(sBeg);
return FALSE;
}
CurPart++;
}
m.Body(sBeg);
free(stmt);
Log.Level(LOGI) << " Message splitted to " << Parts << " Parts" << EOL;
if (!b.DeleteMsg()) {
Log.Level(LOGE) << " Error deleting splitted message." << EOL;
return FALSE;
}
}
};
break;
default: break;
}
CHP = 21;
return TRUE;
}
#endif
syntax highlighted by Code2HTML, v. 0.9.1