326 lines
7.1 KiB
ObjectPascal
326 lines
7.1 KiB
ObjectPascal
|
Unit MUTIL_EchoCore;
|
||
|
|
||
|
{$I M_OPS.PAS}
|
||
|
|
||
|
Interface
|
||
|
|
||
|
Uses
|
||
|
m_CRC,
|
||
|
m_FileIO,
|
||
|
m_Strings,
|
||
|
m_DateTime,
|
||
|
MPL_FileIO,
|
||
|
BBS_Common,
|
||
|
mUtil_Common;
|
||
|
|
||
|
Const
|
||
|
MaxDupeChecks = 40000;
|
||
|
|
||
|
Const
|
||
|
pktPrivate = $0001;
|
||
|
pktCrash = $0002;
|
||
|
pktReceived = $0004;
|
||
|
pktSent = $0008;
|
||
|
pktFileAttach = $0010;
|
||
|
pktInTransit = $0020;
|
||
|
pktOrphan = $0040;
|
||
|
pktKillSent = $0080;
|
||
|
pktLocal = $0100;
|
||
|
pktHold = $0200;
|
||
|
pktUnused = $0400;
|
||
|
pktFileReq = $0800;
|
||
|
pktReturnReq = $1000;
|
||
|
pktIsReceipt = $2000;
|
||
|
pktAuditReq = $4000;
|
||
|
pktFileUpdate = $8000;
|
||
|
|
||
|
Type
|
||
|
RecPKTMessageHdr = Record
|
||
|
MsgType,
|
||
|
OrigNode : System.Word;
|
||
|
DestNode : System.Word;
|
||
|
OrigNet : System.Word;
|
||
|
DestNet : System.Word;
|
||
|
Attribute : System.Word;
|
||
|
Cost : System.Word;
|
||
|
DateTime : String[19];
|
||
|
End;
|
||
|
|
||
|
RecPKTHeader = Record
|
||
|
OrigNode : System.Word;
|
||
|
DestNode : System.Word;
|
||
|
Year : System.Word;
|
||
|
Month : System.Word;
|
||
|
Day : System.Word;
|
||
|
Hour : System.Word;
|
||
|
Minute : System.Word;
|
||
|
Second : System.Word;
|
||
|
Baud : System.Word;
|
||
|
PKTType : System.Word;
|
||
|
OrigNet : System.Word;
|
||
|
DestNet : System.Word;
|
||
|
ProdCode : System.Word;
|
||
|
Password : Array[1..8] of Char;
|
||
|
OrigZone : System.Word;
|
||
|
DestZone : System.Word;
|
||
|
Filler : Array[1..20] of Char;
|
||
|
End;
|
||
|
|
||
|
RecMsgDupe = Record
|
||
|
Header : Cardinal;
|
||
|
Text : Cardinal;
|
||
|
End;
|
||
|
|
||
|
RecMsgLine = String[79];
|
||
|
|
||
|
TPKTReader = Class
|
||
|
PKTHeader : RecPKTHeader;
|
||
|
Orig : RecEchoMailAddr;
|
||
|
Dest : RecEchoMailAddr;
|
||
|
MsgHdr : RecPKTMessageHdr;
|
||
|
MsgFile : PCharFile;
|
||
|
DupeFile : PCharFile;
|
||
|
MsgTo : String[50];
|
||
|
MsgFrom : String[50];
|
||
|
MsgSubj : String[80];
|
||
|
MsgDate : String[20];
|
||
|
MsgTime : String[5];
|
||
|
MsgText : Array[1..mysMaxMsgLines] of ^RecMsgLine;
|
||
|
MsgSize : LongInt;
|
||
|
MsgLines : LongInt;
|
||
|
MsgArea : String;
|
||
|
MsgCRC : RecMsgDupe;
|
||
|
Opened : Boolean;
|
||
|
|
||
|
Constructor Create;
|
||
|
Destructor Destroy; Override;
|
||
|
Procedure DisposeText;
|
||
|
|
||
|
Function Open (FN: String) : Boolean;
|
||
|
Function GetMessage (NetMail: Boolean) : Boolean;
|
||
|
Function IsDuplicate : Boolean;
|
||
|
Procedure AddDuplicate;
|
||
|
End;
|
||
|
|
||
|
Implementation
|
||
|
|
||
|
Constructor TPKTReader.Create;
|
||
|
Begin
|
||
|
Opened := False;
|
||
|
MsgLines := 0;
|
||
|
MsgFile := New (PCharFile, Init(1024 * 4));
|
||
|
DupeFile := New (PCharFile, Init(1024 * 8));
|
||
|
End;
|
||
|
|
||
|
Destructor TPKTReader.Destroy;
|
||
|
Begin
|
||
|
DisposeText;
|
||
|
|
||
|
If MsgFile.Opened Then MsgFile.Close;
|
||
|
If DupeFile.Opened Then DupeFile.Close;
|
||
|
|
||
|
Dispose (MsgFile, Done);
|
||
|
Dispose (DupeFile, Done);
|
||
|
|
||
|
// TRIM DUPLICATE FILE HERE
|
||
|
|
||
|
Inherited Destroy;
|
||
|
End;
|
||
|
|
||
|
Procedure TPKTReader.DisposeText;
|
||
|
Var
|
||
|
Count : LongInt;
|
||
|
Begin
|
||
|
For Count := MsgLines DownTo 1 Do
|
||
|
Dispose (MsgText[Count]);
|
||
|
|
||
|
MsgLines := 0;
|
||
|
End;
|
||
|
|
||
|
Function TPKTReader.Open (FN: String) : Boolean;
|
||
|
Var
|
||
|
Res : LongInt;
|
||
|
Begin
|
||
|
Result := False;
|
||
|
|
||
|
If Not MsgFile.Open(FN) Then Exit;
|
||
|
|
||
|
MsgFile.BlockRead (PKTHeader, SizeOf(PKTHeader), Res);
|
||
|
|
||
|
If (Res <> SizeOf(PKTHeader)) or (PKTHeader.PKTType <> $0002) Then Begin
|
||
|
MsgFile.Close;
|
||
|
Opened := False;
|
||
|
End Else Begin
|
||
|
Orig.Zone := PKTHeader.OrigZone;
|
||
|
Orig.Net := PKTHeader.OrigNet;
|
||
|
Orig.Node := PKTHeader.OrigNode;
|
||
|
Dest.Zone := PKTHeader.DestZone;
|
||
|
Dest.Net := PKTHeader.DestNet;
|
||
|
Dest.Node := PKTHeader.DestNode;
|
||
|
Result := True;
|
||
|
Opened := True;
|
||
|
End;
|
||
|
End;
|
||
|
|
||
|
Function TPKTReader.GetMessage (NetMail: Boolean) : Boolean;
|
||
|
Var
|
||
|
Res : LongInt;
|
||
|
Ch : Char;
|
||
|
|
||
|
Function GetStr (TermChar: Char) : String;
|
||
|
Begin
|
||
|
Result := '';
|
||
|
|
||
|
While Not MsgFile.Eof Do Begin
|
||
|
Ch := MsgFile.Read;
|
||
|
|
||
|
If Ch = TermChar Then Break;
|
||
|
|
||
|
Result := Result + Ch;
|
||
|
End;
|
||
|
End;
|
||
|
|
||
|
Var
|
||
|
Tmp : String[3];
|
||
|
Begin
|
||
|
Result := False;
|
||
|
|
||
|
If Not Opened Then Exit;
|
||
|
|
||
|
MsgFile.BlockRead (MsgHdr, SizeOf(MsgHdr), Res);
|
||
|
|
||
|
If Res <> SizeOf(MsgHdr) Then Exit;
|
||
|
|
||
|
MsgDate := strWide2Str (MsgHdr.DateTime, 20);
|
||
|
MsgTo := GetStr (#0);
|
||
|
MsgFrom := GetStr (#0);
|
||
|
MsgSubj := GetStr (#0);
|
||
|
MsgTime := Copy(MsgDate, 12, 5);
|
||
|
|
||
|
If Not NetMail Then Begin
|
||
|
MsgArea := GetStr (#13);
|
||
|
|
||
|
Delete (MsgArea, Pos('AREA:', MsgArea), 5);
|
||
|
End;
|
||
|
|
||
|
Tmp := strUpper(Copy(MsgDate, 4, 3));
|
||
|
|
||
|
For Res := 1 to 12 Do
|
||
|
If strUpper(MonthString[Res]) = Tmp Then Begin
|
||
|
Tmp := strZero(Res);
|
||
|
Break;
|
||
|
End;
|
||
|
|
||
|
MsgDate := Tmp + '/' + Copy(MsgDate, 1, 2) + '/' + Copy(MsgDate, 8, 2);
|
||
|
|
||
|
DisposeText;
|
||
|
|
||
|
MsgSize := 0;
|
||
|
Result := True;
|
||
|
MsgLines := 1;
|
||
|
MsgCRC.Header := StringCRC32(MsgDate + MsgTime + MsgArea + MsgFrom + MsgTo + MsgSubj);
|
||
|
MsgCRC.Text := $FFFFFFFF;
|
||
|
|
||
|
New (MsgText[MsgLines]);
|
||
|
|
||
|
MsgText[MsgLines]^ := '';
|
||
|
|
||
|
Repeat
|
||
|
Ch := MsgFile.Read;
|
||
|
|
||
|
Case Ch of
|
||
|
#000 : Break;
|
||
|
#010 : ;
|
||
|
#013 : Begin
|
||
|
If MsgLines = mysMaxMsgLines Then Begin
|
||
|
Repeat
|
||
|
Ch := MsgFile.Read;
|
||
|
Until (Ch = #0) or (MsgFile.EOF);
|
||
|
|
||
|
Break;
|
||
|
End;
|
||
|
|
||
|
Inc (MsgSize, Length(MsgText[MsgLines]^));
|
||
|
Inc (MsgLines);
|
||
|
|
||
|
New (MsgText[MsgLines]);
|
||
|
|
||
|
MsgText[MsgLines]^ := '';
|
||
|
End;
|
||
|
#141 : ;
|
||
|
Else
|
||
|
If Length(MsgText[MsgLines]^) = 79 Then Begin
|
||
|
If (Ch <> ' ') and (Pos(' ', MsgText[MsgLines]^) > 0) and (MsgLines < mysMaxMsgLines) Then Begin
|
||
|
For Res := Length(MsgText[MsgLines]^) DownTo 1 Do
|
||
|
If MsgText[MsgLines]^[Res] = ' ' Then Begin
|
||
|
Inc (MsgLines);
|
||
|
|
||
|
New (MsgText[MsgLines]);
|
||
|
|
||
|
MsgText[MsgLines]^ := Copy(MsgText[MsgLines - 1]^, Res + 1, 255);
|
||
|
|
||
|
Delete (MsgText[MsgLines - 1]^, Res, 255);
|
||
|
|
||
|
Break;
|
||
|
End;
|
||
|
End Else Begin
|
||
|
If MsgLines = mysMaxMsgLines Then Begin
|
||
|
Repeat
|
||
|
Ch := MsgFile.Read;
|
||
|
Until (Ch = #0) or (MsgFile.EOF);
|
||
|
|
||
|
Break;
|
||
|
End;
|
||
|
|
||
|
Inc (MsgLines);
|
||
|
|
||
|
New (MsgText[MsgLines]);
|
||
|
|
||
|
MsgText[MsgLines]^ := '';
|
||
|
End;
|
||
|
End;
|
||
|
|
||
|
MsgText[MsgLines]^ := MsgText[MsgLines]^ + Ch;
|
||
|
MsgCRC.Text := Crc32(Byte(Ch), MsgCRC.Text);
|
||
|
End;
|
||
|
Until False;
|
||
|
End;
|
||
|
|
||
|
Procedure TPKTReader.AddDuplicate;
|
||
|
Var
|
||
|
F: File;
|
||
|
Begin
|
||
|
Assign (F, bbsConfig.DataPath + 'echodupes.dat');
|
||
|
|
||
|
If Not ioReset (F, 1, fmRWDN) Then
|
||
|
ioReWrite (F, 1, fmRWDN);
|
||
|
|
||
|
Seek (F, FileSize(F));
|
||
|
BlockWrite (F, MsgCRC, SizeOf(RecMsgDupe));
|
||
|
Close (F);
|
||
|
End;
|
||
|
|
||
|
Function TPKTReader.IsDuplicate : Boolean;
|
||
|
Var
|
||
|
Dupe : RecMsgDupe;
|
||
|
Res : LongInt;
|
||
|
Begin
|
||
|
Result := False;
|
||
|
|
||
|
If Not DupeFile.Open (bbsConfig.DataPath + 'echodupes.dat') Then Exit;
|
||
|
|
||
|
While Not DupeFile.EOF Do Begin
|
||
|
DupeFile.BlockRead (Dupe, SizeOf(RecMsgDupe), Res);
|
||
|
|
||
|
If (Dupe.Text = MsgCRC.Text) and (Dupe.Header = MsgCRC.Header) Then Begin
|
||
|
Result := True;
|
||
|
|
||
|
Break;
|
||
|
End;
|
||
|
End;
|
||
|
|
||
|
DupeFile.Close;
|
||
|
End;
|
||
|
|
||
|
End.
|