Initial import
This commit is contained in:
parent
c84487672e
commit
44908433fb
|
@ -0,0 +1,979 @@
|
||||||
|
Unit bbs_MsgBase_QWK;
|
||||||
|
|
||||||
|
// networking notes:
|
||||||
|
// no control files
|
||||||
|
// no file list
|
||||||
|
// no index files
|
||||||
|
// extended = selectable by user's setting
|
||||||
|
// archive = selectable by user's setting
|
||||||
|
|
||||||
|
{$I M_OPS.PAS}
|
||||||
|
|
||||||
|
Interface
|
||||||
|
|
||||||
|
Uses
|
||||||
|
m_FileIO,
|
||||||
|
bbs_DataBase;
|
||||||
|
|
||||||
|
Const
|
||||||
|
QWK_EOL = #13#10;
|
||||||
|
|
||||||
|
Type
|
||||||
|
BSingle = Array [0..3] of Byte;
|
||||||
|
|
||||||
|
QwkNdxHdr = Record
|
||||||
|
MsgPos : BSingle;
|
||||||
|
Junk : Byte;
|
||||||
|
End;
|
||||||
|
|
||||||
|
QwkDATHdr = Record {128 bytes}
|
||||||
|
Status : Char;
|
||||||
|
MSGNum : Array [1..7] of Char;
|
||||||
|
Date : Array [1..8] of Char;
|
||||||
|
Time : Array [1..5] of Char;
|
||||||
|
UpTO : Array [1..25] of Char;
|
||||||
|
UpFROM : Array [1..25] of Char;
|
||||||
|
Subject : Array [1..25] of Char;
|
||||||
|
PassWord : Array [1..12] of Char;
|
||||||
|
ReferNum : Array [1..8] of Char;
|
||||||
|
NumChunk : Array [1..6] of Char;
|
||||||
|
Active : Char; {225 active, 226 killed}
|
||||||
|
ConfNum : Word;
|
||||||
|
Junk : Word;
|
||||||
|
NetTag : Char;
|
||||||
|
End;
|
||||||
|
|
||||||
|
QwkLRRec = Record
|
||||||
|
Base : Word;
|
||||||
|
Pos : LongInt;
|
||||||
|
End;
|
||||||
|
|
||||||
|
TQWKEngine_HasAccess = Function (AcsStr: String) : Boolean;
|
||||||
|
|
||||||
|
TQWKEngine = Class
|
||||||
|
IsExtended : Boolean;
|
||||||
|
IsNetworked : Boolean;
|
||||||
|
WorkPath : String;
|
||||||
|
PacketID : String;
|
||||||
|
UserRecord : RecUser;
|
||||||
|
UserNumber : Cardinal;
|
||||||
|
HasAccess : TQWKEngine_HasAccess;
|
||||||
|
TotalMessages : Cardinal;
|
||||||
|
TotalBases : Cardinal;
|
||||||
|
RepOK : LongInt;
|
||||||
|
RepFailed : LongInt;
|
||||||
|
RepBaseAdd : LongInt;
|
||||||
|
RepBaseDel : LongInt;
|
||||||
|
DataFile : TFileBuffer;
|
||||||
|
|
||||||
|
Constructor Create (QwkPath, QwkID: String; UN: Cardinal; UR: RecUser);
|
||||||
|
Procedure LONG2MSB (Index : LongInt; Var MS : BSingle);
|
||||||
|
Procedure WriteDOORID;
|
||||||
|
Procedure WriteTOREADEREXT;
|
||||||
|
Procedure WriteCONTROLDAT;
|
||||||
|
Function WriteMSGDAT : LongInt;
|
||||||
|
Procedure CreatePacket;
|
||||||
|
Function ProcessReply : Boolean;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Implementation
|
||||||
|
|
||||||
|
Uses
|
||||||
|
m_Strings,
|
||||||
|
m_DateTime;
|
||||||
|
|
||||||
|
Constructor TQWKEngine.Create (QwkPath, QwkID: String; UN: Cardinal; UR: RecUser);
|
||||||
|
Begin
|
||||||
|
Inherited Create;
|
||||||
|
|
||||||
|
WorkPath := QwkPath;
|
||||||
|
PacketID := QwkID;
|
||||||
|
UserNumber := UN;
|
||||||
|
UserRecord := UR;
|
||||||
|
IsExtended := False;
|
||||||
|
IsNetworked := False;
|
||||||
|
TotalMessages := 0;
|
||||||
|
TotalBases := 0;
|
||||||
|
RepOK := 0;
|
||||||
|
RepFailed := 0;
|
||||||
|
RepBaseAdd := 0;
|
||||||
|
RepBaseDel := 0;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Procedure TQWKEngine.LONG2MSB (Index : LongInt; Var MS : BSingle);
|
||||||
|
Var
|
||||||
|
Exp : Byte;
|
||||||
|
Begin
|
||||||
|
If Index <> 0 Then Begin
|
||||||
|
Exp := 0;
|
||||||
|
|
||||||
|
While Index And $800000 = 0 Do Begin
|
||||||
|
Inc (Exp);
|
||||||
|
Index := Index SHL 1
|
||||||
|
End;
|
||||||
|
|
||||||
|
Index := Index And $7FFFFF;
|
||||||
|
End Else
|
||||||
|
Exp := 152;
|
||||||
|
|
||||||
|
MS[0] := Index AND $FF;
|
||||||
|
MS[1] := (Index SHR 8) AND $FF;
|
||||||
|
MS[2] := (Index SHR 16) AND $FF;
|
||||||
|
MS[3] := 152 - Exp;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Procedure TQWKEngine.WriteDOORID;
|
||||||
|
Var
|
||||||
|
TempFile : Text;
|
||||||
|
Begin
|
||||||
|
If IsNetworked Then Exit;
|
||||||
|
|
||||||
|
Assign (TempFile, WorkPath + 'door.id');
|
||||||
|
ReWrite (TempFile);
|
||||||
|
Write (TempFile, 'DOOR = ' + mysSoftwareID + QWK_EOL);
|
||||||
|
Write (TempFile, 'VERSION = ' + mysVersion + QWK_EOL);
|
||||||
|
Write (TempFile, 'SYSTEM = ' + mysSoftwareID + ' ' + mysVersion + QWK_EOL);
|
||||||
|
Write (TempFile, 'CONTROLNAME = MYSTICQWK' + QWK_EOL);
|
||||||
|
Write (TempFile, 'CONTROLTYPE = ADD' + QWK_EOL);
|
||||||
|
Write (TempFile, 'CONTROLTYPE = DROP' + QWK_EOL);
|
||||||
|
Close (TempFile);
|
||||||
|
End;
|
||||||
|
|
||||||
|
Procedure TQWKEngine.WriteTOREADEREXT;
|
||||||
|
Var
|
||||||
|
TempFile : Text;
|
||||||
|
BaseFile : File;
|
||||||
|
Flags : String;
|
||||||
|
Base : RecMessageBase;
|
||||||
|
Begin
|
||||||
|
If IsNetworked Or (Not IsExtended) Then Exit;
|
||||||
|
|
||||||
|
Assign (TempFile, WorkPath + 'toreader.ext');
|
||||||
|
ReWrite (TempFile);
|
||||||
|
Write (TempFile, 'ALIAS ' + UserRecord.Handle + QWK_EOL);
|
||||||
|
|
||||||
|
Assign (BaseFile, bbsCfg.DataPath + 'mbases.dat');
|
||||||
|
|
||||||
|
If ioReset (BaseFile, SizeOf(RecMessageBase), fmRWDN) Then Begin
|
||||||
|
|
||||||
|
While Not Eof(BaseFile) Do Begin
|
||||||
|
ioRead (BaseFile, Base);
|
||||||
|
|
||||||
|
If HasAccess(Base.ReadACS) Then Begin
|
||||||
|
Flags := ' ';
|
||||||
|
|
||||||
|
If Base.Flags AND MBPrivate = 0 Then
|
||||||
|
Flags := Flags + 'aO'
|
||||||
|
Else
|
||||||
|
Flags := Flags + 'pP';
|
||||||
|
|
||||||
|
If Base.Flags AND MBRealNames = 0 Then
|
||||||
|
Flags := Flags + 'H';
|
||||||
|
|
||||||
|
If Not HasAccess(Base.PostACS) Then
|
||||||
|
Flags := Flags + 'BRZ';
|
||||||
|
|
||||||
|
Case Base.NetType of
|
||||||
|
0 : Flags := Flags + 'L';
|
||||||
|
1 : Flags := Flags + 'E';
|
||||||
|
2 : Flags := Flags + 'U';
|
||||||
|
3 : Flags := Flags + 'N';
|
||||||
|
End;
|
||||||
|
|
||||||
|
If Base.DefQScan = 2 Then
|
||||||
|
Flags := Flags + 'F';
|
||||||
|
|
||||||
|
Write (TempFile, 'AREA ' + strI2S(Base.Index) + Flags, QWK_EOL);
|
||||||
|
End;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Close (BaseFile);
|
||||||
|
End;
|
||||||
|
|
||||||
|
Close (TempFile);
|
||||||
|
End;
|
||||||
|
|
||||||
|
Procedure TQWKEngine.WriteCONTROLDAT;
|
||||||
|
Var
|
||||||
|
TempFile : Text;
|
||||||
|
BaseFile : File;
|
||||||
|
Base : RecMessageBase;
|
||||||
|
Begin
|
||||||
|
If IsNetworked Then Exit;
|
||||||
|
|
||||||
|
Assign (TempFile, WorkPath + 'control.dat');
|
||||||
|
ReWrite (TempFile);
|
||||||
|
|
||||||
|
Write (TempFile, bbsCfg.BBSName + QWK_EOL);
|
||||||
|
Write (TempFile, QWK_EOL);
|
||||||
|
Write (TempFile, QWK_EOL);
|
||||||
|
Write (TempFile, bbsCfg.SysopName + QWK_EOL);
|
||||||
|
Write (TempFile, '0,' + bbsCfg.qwkBBSID + QWK_EOL);
|
||||||
|
Write (TempFile, DateDos2Str(CurDateDos, 1), ',', TimeDos2Str(CurDateDos, 0) + QWK_EOL);
|
||||||
|
Write (TempFile, strUpper(UserRecord.Handle) + QWK_EOL);
|
||||||
|
Write (TempFile, QWK_EOL);
|
||||||
|
Write (TempFile, '0' + QWK_EOL);
|
||||||
|
Write (TempFile, TotalMessages, QWK_EOL);
|
||||||
|
Write (TempFile, TotalBases - 1, QWK_EOL);
|
||||||
|
|
||||||
|
Assign (BaseFile, bbsCfg.DataPath + 'mbases.dat');
|
||||||
|
|
||||||
|
If ioReset (BaseFile, SizeOf(RecMessageBase), fmRWDN) Then Begin
|
||||||
|
|
||||||
|
While Not Eof(BaseFile) Do Begin
|
||||||
|
ioRead (BaseFile, Base);
|
||||||
|
|
||||||
|
If HasAccess(Base.ReadACS) Then Begin
|
||||||
|
Write (TempFile, Base.Index, QWK_EOL);
|
||||||
|
|
||||||
|
If IsExtended Then
|
||||||
|
Write (TempFile, strStripMCI(Base.Name) + QWK_EOL)
|
||||||
|
Else
|
||||||
|
Write (TempFile, Base.QwkName + QWK_EOL);
|
||||||
|
End;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Close (BaseFile);
|
||||||
|
End;
|
||||||
|
|
||||||
|
Write (TempFile, JustFile(bbsCfg.qwkWelcome) + QWK_EOL);
|
||||||
|
Write (TempFile, JustFile(bbsCfg.qwkNews) + QWK_EOL);
|
||||||
|
Write (TempFile, JustFile(bbsCfg.qwkGoodbye) + QWK_EOL);
|
||||||
|
|
||||||
|
Close (TempFile);
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function TQWKEngine.WriteMSGDAT : LongInt;
|
||||||
|
Var
|
||||||
|
NdxFile : File of QwkNdxHdr;
|
||||||
|
NdxHdr : QwkNdxHdr;
|
||||||
|
Header : String[128];
|
||||||
|
BufStr : String[128];
|
||||||
|
Chunks : Word;
|
||||||
|
MsgAdded : LongInt;
|
||||||
|
LastRead : LongInt;
|
||||||
|
QwkIndex : LongInt;
|
||||||
|
TooBig : Boolean;
|
||||||
|
|
||||||
|
Procedure DoString (Str: String);
|
||||||
|
Var
|
||||||
|
Count : SmallInt;
|
||||||
|
Begin
|
||||||
|
For Count := 1 to Length(Str) Do Begin
|
||||||
|
BufStr := BufStr + Str[Count];
|
||||||
|
|
||||||
|
If BufStr[0] = #128 Then Begin
|
||||||
|
DataFile.WriteBlock (BufStr[1], 128);
|
||||||
|
|
||||||
|
BufStr := '';
|
||||||
|
End;
|
||||||
|
End;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Var
|
||||||
|
TempStr : String;
|
||||||
|
Begin
|
||||||
|
MsgAdded := 0;
|
||||||
|
|
||||||
|
If Not OpenCreateBase(MsgBase, MBase) Then Exit;
|
||||||
|
|
||||||
|
LastRead := MsgBase^.GetLastRead(UserNumber) + 1;
|
||||||
|
|
||||||
|
MsgBase^.SeekFirst (LastRead);
|
||||||
|
|
||||||
|
While MsgBase^.SeekFound Do Begin
|
||||||
|
|
||||||
|
If Not IsNetworked Then
|
||||||
|
If ((bbsCfg.QwkMaxBase > 0) and (MsgAdded = bbsCfg.QwkMaxBase)) or
|
||||||
|
((bbsCfg.QwkMaxPacket > 0) and (TotalMsgs = bbsCfg.QwkMaxPacket)) Then Break;
|
||||||
|
|
||||||
|
MsgBase^.MsgStartUp;
|
||||||
|
|
||||||
|
If MsgBase^.IsPriv And Not Session.User.IsThisUser(MsgBase^.GetTo) Then Begin
|
||||||
|
MsgBase^.SeekNext;
|
||||||
|
|
||||||
|
Continue;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Inc (MsgAdded);
|
||||||
|
Inc (TotalMsgs);
|
||||||
|
|
||||||
|
LastRead := MsgBase^.GetMsgNum;
|
||||||
|
Chunks := 0;
|
||||||
|
BufStr := '';
|
||||||
|
TooBig := False;
|
||||||
|
QwkIndex := FileSize(DataFile) DIV 128 + 1;
|
||||||
|
|
||||||
|
MsgBase^.MsgTxtStartUp;
|
||||||
|
|
||||||
|
While Not MsgBase^.EOM Do Begin
|
||||||
|
TempStr := MsgBase^.GetString(79);
|
||||||
|
|
||||||
|
If TempStr[1] = #1 Then Continue;
|
||||||
|
|
||||||
|
Inc (Chunks, Length(TempStr));
|
||||||
|
End;
|
||||||
|
|
||||||
|
If Chunks MOD 128 = 0 Then
|
||||||
|
Chunks := Chunks DIV 128 + 1
|
||||||
|
Else
|
||||||
|
Chunks := Chunks DIV 128 + 2;
|
||||||
|
|
||||||
|
Header :=
|
||||||
|
' ' +
|
||||||
|
strPadR(strI2S(MsgBase^.GetMsgNum), 7, ' ') +
|
||||||
|
MsgBase^.GetDate +
|
||||||
|
MsgBase^.GetTime +
|
||||||
|
strPadR(strUpper(MsgBase^.GetTo), 25, ' ') +
|
||||||
|
strPadR(strUpper(MsgBase^.GetFrom), 25, ' ') +
|
||||||
|
strPadR(strUpper(MsgBase^.GetSubj), 25, ' ') +
|
||||||
|
strPadR('', 12, ' ') +
|
||||||
|
strPadR(strI2S(MsgBase^.GetRefer), 8, ' ') +
|
||||||
|
strPadR(strI2S(Chunks), 6, ' ') +
|
||||||
|
#255 +
|
||||||
|
' ' +
|
||||||
|
' ' +
|
||||||
|
' ';
|
||||||
|
|
||||||
|
If MsgAdded = 1 Then Begin
|
||||||
|
Assign (NdxFile, WorkPath + strPadL(strI2S(MBase.Index), 3, '0') + '.ndx');
|
||||||
|
ReWrite (NdxFile);
|
||||||
|
End;
|
||||||
|
|
||||||
|
LONG2MSB (QwkIndex, NdxHdr.MsgPos);
|
||||||
|
Write (NdxFile, NdxHdr);
|
||||||
|
|
||||||
|
DataFile.WriteBlock (Header[1], 128);
|
||||||
|
|
||||||
|
If IsExtended Then Begin
|
||||||
|
If Length(MsgBase^.GetFrom) > 25 Then Begin
|
||||||
|
DoString('From: ' + MsgBase^.GetFrom + #227);
|
||||||
|
|
||||||
|
TooBig := True;
|
||||||
|
End;
|
||||||
|
|
||||||
|
If Length(MsgBase^.GetTo) > 25 Then Begin
|
||||||
|
DoString('To: ' + MsgBase^.GetTo + #227);
|
||||||
|
|
||||||
|
TooBig := True;
|
||||||
|
End;
|
||||||
|
|
||||||
|
If Length(MsgBase^.GetSubj) > 25 Then Begin
|
||||||
|
DoString('Subject: ' + MsgBase^.GetSubj + #227);
|
||||||
|
|
||||||
|
TooBig := True;
|
||||||
|
End;
|
||||||
|
|
||||||
|
If TooBig Then DoString(#227);
|
||||||
|
End;
|
||||||
|
|
||||||
|
MsgBase^.MsgTxtStartUp;
|
||||||
|
|
||||||
|
While Not MsgBase^.EOM Do Begin
|
||||||
|
TempStr := MsgBase^.GetString(79) + #227;
|
||||||
|
|
||||||
|
If TempStr[1] = #1 Then Continue;
|
||||||
|
|
||||||
|
DoString (TempStr);
|
||||||
|
End;
|
||||||
|
|
||||||
|
If BufStr <> '' Then Begin
|
||||||
|
BufStr := strPadR (BufStr, 128, ' ');
|
||||||
|
|
||||||
|
DataFile.WriteBlock (BufStr[1], 128);
|
||||||
|
End;
|
||||||
|
|
||||||
|
MsgBase^.SeekNext;
|
||||||
|
End;
|
||||||
|
|
||||||
|
If MsgAdded > 0 Then Close (NdxFile);
|
||||||
|
|
||||||
|
MsgBase^.CloseMsgBase;
|
||||||
|
Dispose (MsgBase, Done);
|
||||||
|
|
||||||
|
Result := LastRead;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Procedure TQWKEngine.CreatePacket;
|
||||||
|
Var
|
||||||
|
Temp : String;
|
||||||
|
QwkLR : QwkLRRec;
|
||||||
|
QwkLRFile : File of QwkLRRec;
|
||||||
|
MBaseFile : File;
|
||||||
|
MBase : RecMessageBase;
|
||||||
|
MScan : MScanRec;
|
||||||
|
Begin
|
||||||
|
DataFile := TFileBuffer.Create(4 * 1024);
|
||||||
|
|
||||||
|
DataFile.OpenStream (WorkPath + 'messages.dat', 1, fmCreate, fmRWDN);
|
||||||
|
|
||||||
|
Temp := strPadR('Produced By ' + mysSoftwareID + ' v' + mysVersion + '. ' + mysCopyNotice, 128, ' ');
|
||||||
|
|
||||||
|
DataFile.WriteBlock (Temp[1], 128);
|
||||||
|
|
||||||
|
Assign (QwkLRFile, WorkPath + 'qlr.dat');
|
||||||
|
ReWrite (QwkLRFile);
|
||||||
|
|
||||||
|
Assign (MBaseFile, bbsCfg.DataPath + 'mbases.dat');
|
||||||
|
|
||||||
|
If ioReset (MBaseFile, SizeOf(RecMessageBase), fmRWDN) Then Begin
|
||||||
|
|
||||||
|
If IsNetworked Then
|
||||||
|
ioRead (MBaseFile, MBase);
|
||||||
|
|
||||||
|
While Not Eof(MBaseFile) Do Begin
|
||||||
|
ioRead (MBaseFile, MBase);
|
||||||
|
|
||||||
|
If IsNetworked And (MBase.Flags AND MBAllowQWKNet = 0) Then
|
||||||
|
Continue;
|
||||||
|
|
||||||
|
If HasAccess(MBase.ReadACS) Then Begin
|
||||||
|
|
||||||
|
GetMessageScan (UserNumber, MBase, MScan);
|
||||||
|
|
||||||
|
If MScan.QwkScan > 0 Then Begin
|
||||||
|
QwkLR.Base := FilePos(MBaseFile);
|
||||||
|
QwkLR.Pos := WriteMSGDAT;
|
||||||
|
|
||||||
|
Write (QwkLRFile, QwkLR);
|
||||||
|
End;
|
||||||
|
End;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Close (MBaseFile);
|
||||||
|
End;
|
||||||
|
|
||||||
|
Close (QwkLRFile);
|
||||||
|
|
||||||
|
DataFile.Free;
|
||||||
|
|
||||||
|
If Not IsNetworked Then Begin
|
||||||
|
WriteControlDAT;
|
||||||
|
WriteDOORID;
|
||||||
|
WriteTOREADEREXT;
|
||||||
|
End;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function TQWKEngine.ProcessReply : Boolean;
|
||||||
|
Begin
|
||||||
|
Result := False;
|
||||||
|
End;
|
||||||
|
|
||||||
|
End.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Function TMsgBase.WriteMSGDAT (Extended: Boolean) : LongInt;
|
||||||
|
Var
|
||||||
|
DataFile : File;
|
||||||
|
NdxFile : File of QwkNdxHdr;
|
||||||
|
NdxHdr : QwkNdxHdr;
|
||||||
|
Header : String[128];
|
||||||
|
Chunks : Word;
|
||||||
|
BufStr : String[128];
|
||||||
|
MsgAdded : Integer;
|
||||||
|
LastRead : LongInt;
|
||||||
|
QwkIndex : LongInt;
|
||||||
|
TooBig : Boolean;
|
||||||
|
|
||||||
|
Procedure DoString (Str: String);
|
||||||
|
Var
|
||||||
|
Count : SmallInt;
|
||||||
|
Begin
|
||||||
|
For Count := 1 to Length(Str) Do Begin
|
||||||
|
BufStr := BufStr + Str[Count];
|
||||||
|
|
||||||
|
If BufStr[0] = #128 Then Begin
|
||||||
|
BlockWrite (DataFile, BufStr[1], 128);
|
||||||
|
|
||||||
|
BufStr := '';
|
||||||
|
End;
|
||||||
|
End;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Var
|
||||||
|
TempStr : String;
|
||||||
|
Begin
|
||||||
|
MsgAdded := 0;
|
||||||
|
|
||||||
|
If Not OpenCreateBase(MsgBase, MBase) Then Exit;
|
||||||
|
|
||||||
|
Session.io.OutFull (Session.GetPrompt(231));
|
||||||
|
|
||||||
|
Assign (DataFile, Session.TempPath + 'messages.dat');
|
||||||
|
Reset (DataFile, 1);
|
||||||
|
Seek (DataFile, FileSize(DataFile));
|
||||||
|
|
||||||
|
LastRead := MsgBase^.GetLastRead(Session.User.UserNum) + 1;
|
||||||
|
|
||||||
|
MsgBase^.SeekFirst (LastRead);
|
||||||
|
|
||||||
|
While MsgBase^.SeekFound Do Begin
|
||||||
|
If ((bbsCfg.QwkMaxBase > 0) and (MsgAdded = bbsCfg.QwkMaxBase)) or
|
||||||
|
((bbsCfg.QwkMaxPacket > 0) and (TotalMsgs = bbsCfg.QwkMaxPacket)) Then Break;
|
||||||
|
|
||||||
|
MsgBase^.MsgStartUp;
|
||||||
|
|
||||||
|
If MsgBase^.IsPriv And Not Session.User.IsThisUser(MsgBase^.GetTo) Then Begin
|
||||||
|
MsgBase^.SeekNext;
|
||||||
|
|
||||||
|
Continue;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Inc (MsgAdded);
|
||||||
|
Inc (TotalMsgs);
|
||||||
|
|
||||||
|
LastRead := MsgBase^.GetMsgNum;
|
||||||
|
Chunks := 0;
|
||||||
|
BufStr := '';
|
||||||
|
TooBig := False;
|
||||||
|
QwkIndex := FileSize(DataFile) DIV 128 + 1;
|
||||||
|
|
||||||
|
MsgBase^.MsgTxtStartUp;
|
||||||
|
|
||||||
|
While Not MsgBase^.EOM Do Begin
|
||||||
|
TempStr := MsgBase^.GetString(79);
|
||||||
|
|
||||||
|
If TempStr[1] = #1 Then Continue;
|
||||||
|
|
||||||
|
Inc (Chunks, Length(TempStr));
|
||||||
|
End;
|
||||||
|
|
||||||
|
If Chunks MOD 128 = 0 Then
|
||||||
|
Chunks := Chunks DIV 128 + 1
|
||||||
|
Else
|
||||||
|
Chunks := Chunks DIV 128 + 2;
|
||||||
|
|
||||||
|
Header :=
|
||||||
|
' ' +
|
||||||
|
strPadR(strI2S(MsgBase^.GetMsgNum), 7, ' ') +
|
||||||
|
MsgBase^.GetDate +
|
||||||
|
MsgBase^.GetTime +
|
||||||
|
strPadR(strUpper(MsgBase^.GetTo), 25, ' ') +
|
||||||
|
strPadR(strUpper(MsgBase^.GetFrom), 25, ' ') +
|
||||||
|
strPadR(strUpper(MsgBase^.GetSubj), 25, ' ') +
|
||||||
|
strPadR('', 12, ' ') +
|
||||||
|
strPadR(strI2S(MsgBase^.GetRefer), 8, ' ') +
|
||||||
|
strPadR(strI2S(Chunks), 6, ' ') +
|
||||||
|
#255 +
|
||||||
|
' ' +
|
||||||
|
' ' +
|
||||||
|
' ';
|
||||||
|
|
||||||
|
If MsgAdded = 1 Then Begin
|
||||||
|
Assign (NdxFile, Session.TempPath + strPadL(strI2S(MBase.Index), 3, '0') + '.ndx');
|
||||||
|
ReWrite (NdxFile);
|
||||||
|
End;
|
||||||
|
|
||||||
|
LONG2MSB (QwkIndex, NdxHdr.MsgPos);
|
||||||
|
Write (NdxFile, NdxHdr);
|
||||||
|
BlockWrite (DataFile, Header[1], 128);
|
||||||
|
|
||||||
|
If Extended Then Begin
|
||||||
|
If Length(MsgBase^.GetFrom) > 25 Then Begin
|
||||||
|
DoString('From: ' + MsgBase^.GetFrom + #227);
|
||||||
|
|
||||||
|
TooBig := True;
|
||||||
|
End;
|
||||||
|
|
||||||
|
If Length(MsgBase^.GetTo) > 25 Then Begin
|
||||||
|
DoString('To: ' + MsgBase^.GetTo + #227);
|
||||||
|
|
||||||
|
TooBig := True;
|
||||||
|
End;
|
||||||
|
|
||||||
|
If Length(MsgBase^.GetSubj) > 25 Then Begin
|
||||||
|
DoString('Subject: ' + MsgBase^.GetSubj + #227);
|
||||||
|
|
||||||
|
TooBig := True;
|
||||||
|
End;
|
||||||
|
|
||||||
|
If TooBig Then DoString(#227);
|
||||||
|
End;
|
||||||
|
|
||||||
|
MsgBase^.MsgTxtStartUp;
|
||||||
|
|
||||||
|
While Not MsgBase^.EOM Do Begin
|
||||||
|
TempStr := MsgBase^.GetString(79) + #227;
|
||||||
|
|
||||||
|
If TempStr[1] = #1 Then Continue;
|
||||||
|
|
||||||
|
DoString (TempStr);
|
||||||
|
End;
|
||||||
|
|
||||||
|
If BufStr <> '' Then Begin
|
||||||
|
BufStr := strPadR (BufStr, 128, ' ');
|
||||||
|
|
||||||
|
BlockWrite (DataFile, BufStr[1], 128);
|
||||||
|
End;
|
||||||
|
|
||||||
|
MsgBase^.SeekNext;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Close (DataFile);
|
||||||
|
|
||||||
|
If MsgAdded > 0 Then Close (NdxFile);
|
||||||
|
|
||||||
|
Session.io.PromptInfo[1] := strI2S(MBase.Index);
|
||||||
|
Session.io.PromptInfo[2] := MBase.Name;
|
||||||
|
Session.io.PromptInfo[3] := MBase.QwkName;
|
||||||
|
Session.io.PromptInfo[4] := strI2S(MsgBase^.NumberOfMsgs);
|
||||||
|
Session.io.PromptInfo[5] := strI2S(MsgAdded);
|
||||||
|
|
||||||
|
MsgBase^.CloseMsgBase;
|
||||||
|
Dispose (MsgBase, Done);
|
||||||
|
|
||||||
|
Session.io.OutBS (Screen.CursorX, True);
|
||||||
|
Session.io.OutFullLn (Session.GetPrompt(232));
|
||||||
|
|
||||||
|
Result := LastRead;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Procedure TMsgBase.DownloadQWK (Extended: Boolean; Data: String);
|
||||||
|
Type
|
||||||
|
QwkLRRec = Record
|
||||||
|
Base : Word;
|
||||||
|
Pos : LongInt;
|
||||||
|
End;
|
||||||
|
Var
|
||||||
|
Old : RecMessageBase;
|
||||||
|
DataFile : File;
|
||||||
|
Temp : String;
|
||||||
|
QwkLR : QwkLRRec;
|
||||||
|
QwkLRFile : File of QwkLRRec;
|
||||||
|
Begin
|
||||||
|
If Session.User.ThisUser.QwkFiles Then
|
||||||
|
Session.FileBase.ExportFileList(True, True);
|
||||||
|
|
||||||
|
FileMode := 66;
|
||||||
|
Old := MBase;
|
||||||
|
Temp := strPadR('Produced By ' + mysSoftwareID + ' v' + mysVersion + '. ' + CopyID, 128, ' ');
|
||||||
|
|
||||||
|
Assign (DataFile, Session.TempPath + 'messages.dat');
|
||||||
|
ReWrite (DataFile, 1);
|
||||||
|
BlockWrite (DataFile, Temp[1], 128);
|
||||||
|
Close (DataFile);
|
||||||
|
|
||||||
|
Assign (QwkLRFile, Session.TempPath + 'qlr.dat');
|
||||||
|
ReWrite (QwkLRFile);
|
||||||
|
Reset (MBaseFile);
|
||||||
|
|
||||||
|
Session.io.OutFullLn (Session.GetPrompt(230));
|
||||||
|
|
||||||
|
TotalMsgs := 0;
|
||||||
|
TotalConf := 0;
|
||||||
|
|
||||||
|
Session.User.IgnoreGroup := Pos('/ALLGROUP', strUpper(Data)) > 0;
|
||||||
|
|
||||||
|
While Not Eof(MBaseFile) Do Begin
|
||||||
|
Read (MBaseFile, MBase);
|
||||||
|
|
||||||
|
If Session.User.Access(MBase.ReadACS) Then Begin
|
||||||
|
Inc (TotalConf);
|
||||||
|
|
||||||
|
GetMessageScan;
|
||||||
|
|
||||||
|
If MScan.QwkScan > 0 Then Begin
|
||||||
|
QwkLR.Base := FilePos(MBaseFile);
|
||||||
|
QwkLR.Pos := WriteMsgDAT(Extended);
|
||||||
|
|
||||||
|
Write (QwkLRFile, QwkLR);
|
||||||
|
End;
|
||||||
|
End;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Close (QwkLRFile);
|
||||||
|
|
||||||
|
WriteControlDAT (Extended);
|
||||||
|
WriteDOORID (Extended);
|
||||||
|
|
||||||
|
If Extended Then WriteTOREADEREXT;
|
||||||
|
|
||||||
|
If TotalMsgs > 0 Then Begin
|
||||||
|
Session.io.PromptInfo[1] := strI2S(TotalMsgs);
|
||||||
|
Session.io.PromptInfo[2] := strI2S(TotalConf);
|
||||||
|
|
||||||
|
Session.io.OutFullLn (Session.GetPrompt(233));
|
||||||
|
|
||||||
|
Temp := bbsCfg.qwkBBSID + '.qwk';
|
||||||
|
|
||||||
|
Session.io.OutFullLn (Session.GetPrompt(234));
|
||||||
|
|
||||||
|
Session.io.PromptInfo[1] := Temp;
|
||||||
|
|
||||||
|
If FileExist(bbsCfg.QwkWelcome) Then FileCopy(bbsCfg.qwkWelcome, Session.TempPath + JustFile(bbsCfg.qwkWelcome));
|
||||||
|
If FileExist(bbsCfg.QwkNews) Then FileCopy(bbsCfg.qwkNews, Session.TempPath + JustFile(bbsCfg.qwkNews));
|
||||||
|
If FileExist(bbsCfg.QwkGoodbye) Then FileCopy(bbsCfg.qwkGoodbye, Session.TempPath + JustFile(bbsCfg.qwkGoodbye));
|
||||||
|
|
||||||
|
// Session.SystemLog('DEBUG: Archiving QWK packet');
|
||||||
|
|
||||||
|
If Session.LocalMode Then Begin
|
||||||
|
FileErase (bbsCfg.QWKPath + Temp);
|
||||||
|
|
||||||
|
Session.FileBase.ExecuteArchive (bbsCfg.QWKPath + Temp, Session.User.ThisUser.Archive, Session.TempPath + '*', 1);
|
||||||
|
|
||||||
|
Session.io.OutFullLn (Session.GetPrompt(235));
|
||||||
|
End Else Begin
|
||||||
|
Session.FileBase.ExecuteArchive (Session.TempPath + Temp, Session.User.ThisUser.Archive, Session.TempPath + '*', 1);
|
||||||
|
Session.FileBase.SendFile (Session.TempPath + Temp);
|
||||||
|
End;
|
||||||
|
|
||||||
|
If Session.io.GetYN (Session.GetPrompt(236), True) Then Begin
|
||||||
|
Reset (MBaseFile);
|
||||||
|
Reset (QwkLRFile);
|
||||||
|
|
||||||
|
While Not Eof(QwkLRFile) Do Begin
|
||||||
|
Read (QwkLRFile, QwkLR);
|
||||||
|
Seek (MBaseFile, QwkLR.Base - 1);
|
||||||
|
Read (MBaseFile, MBase);
|
||||||
|
|
||||||
|
Case MBase.BaseType of
|
||||||
|
0 : MsgBase := New(PMsgBaseJAM, Init);
|
||||||
|
1 : MsgBase := New(PMsgBaseSquish, Init);
|
||||||
|
End;
|
||||||
|
|
||||||
|
MsgBase^.SetMsgPath (MBase.Path + MBase.FileName);
|
||||||
|
|
||||||
|
If MsgBase^.OpenMsgBase Then Begin
|
||||||
|
MsgBase^.SetLastRead (Session.User.UserNum, QwkLR.Pos);
|
||||||
|
MsgBase^.CloseMsgBase;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Dispose(MsgBase, Done);
|
||||||
|
End;
|
||||||
|
Close (QwkLRFile);
|
||||||
|
End;
|
||||||
|
End Else
|
||||||
|
Session.io.OutFullLn (Session.GetPrompt(228));
|
||||||
|
|
||||||
|
Session.User.IgnoreGroup := False;
|
||||||
|
|
||||||
|
Close (MBaseFile);
|
||||||
|
|
||||||
|
MBase := Old;
|
||||||
|
|
||||||
|
DirClean (Session.TempPath, '');
|
||||||
|
End;
|
||||||
|
|
||||||
|
Procedure TMsgBase.UploadREP;
|
||||||
|
Var
|
||||||
|
DataFile : File;
|
||||||
|
TempBase : RecMessageBase;
|
||||||
|
OldBase : RecMessageBase;
|
||||||
|
QwkHeader : QwkDATHdr;
|
||||||
|
QwkBlock : String[128];
|
||||||
|
Line : String;
|
||||||
|
A : SmallInt;
|
||||||
|
B : SmallInt;
|
||||||
|
Chunks : SmallInt;
|
||||||
|
LineCount : SmallInt;
|
||||||
|
IsControl : Boolean;
|
||||||
|
GotControl : Boolean;
|
||||||
|
ExtFile : Text;
|
||||||
|
StatOK : LongInt = 0;
|
||||||
|
StatFailed : LongInt = 0;
|
||||||
|
StatBaseAdd : LongInt = 0;
|
||||||
|
StatBaseDel : LongInt = 0;
|
||||||
|
|
||||||
|
Procedure QwkControl (Idx: LongInt; Mode: Byte);
|
||||||
|
Begin
|
||||||
|
OldBase := MBase;
|
||||||
|
|
||||||
|
If GetBaseByIndex(Idx, MBase) Then Begin
|
||||||
|
GetMessageScan;
|
||||||
|
|
||||||
|
MScan.QwkScan := Mode;
|
||||||
|
|
||||||
|
If Mode = 0 Then Inc (StatBaseDel);
|
||||||
|
If Mode = 1 Then Inc (StatBaseAdd);
|
||||||
|
|
||||||
|
SetMessageScan;
|
||||||
|
End;
|
||||||
|
|
||||||
|
MBase := OldBase;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Begin
|
||||||
|
If Session.LocalMode Then
|
||||||
|
Session.FileBase.ExecuteArchive (bbsCfg.QWKPath + bbsCfg.qwkBBSID + '.rep', Session.User.ThisUser.Archive, '*', 2)
|
||||||
|
Else Begin
|
||||||
|
If Session.FileBase.SelectProtocol(True, False) = 'Q' Then Exit;
|
||||||
|
|
||||||
|
Session.FileBase.ExecuteProtocol(1, Session.TempPath + bbsCfg.qwkBBSID + '.rep');
|
||||||
|
|
||||||
|
If Not Session.FileBase.DszSearch(bbsCfg.qwkBBSID + '.rep') Then Begin
|
||||||
|
Session.io.PromptInfo[1] := bbsCfg.qwkBBSID + '.rep';
|
||||||
|
|
||||||
|
Session.io.OutFullLn (Session.GetPrompt(84));
|
||||||
|
|
||||||
|
Exit;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Session.FileBase.ExecuteArchive (Session.TempPath + bbsCfg.qwkBBSID + '.rep', Session.User.ThisUser.Archive, '*', 2)
|
||||||
|
End;
|
||||||
|
|
||||||
|
Assign (DataFile, FileFind(Session.TempPath + bbsCfg.qwkBBSID + '.msg'));
|
||||||
|
|
||||||
|
If Not ioReset(DataFile, 1, fmRWDN) Then Begin
|
||||||
|
Session.io.OutFull (Session.GetPrompt(238));
|
||||||
|
DirClean (Session.TempPath, '');
|
||||||
|
Exit;
|
||||||
|
End;
|
||||||
|
|
||||||
|
BlockRead (DataFile, QwkBlock[1], 128);
|
||||||
|
QwkBlock[0] := #128;
|
||||||
|
|
||||||
|
If Pos(strUpper(bbsCfg.qwkBBSID), strUpper(QwkBlock)) = 0 Then Begin
|
||||||
|
Session.io.OutFullLn (Session.GetPrompt(239));
|
||||||
|
Close (DataFile);
|
||||||
|
DirClean(Session.TempPath, '');
|
||||||
|
Exit;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Session.io.OutFull (Session.GetPrompt(240));
|
||||||
|
|
||||||
|
While Not Eof(DataFile) Do Begin
|
||||||
|
BlockRead (DataFile, QwkHeader, SizeOf(QwkHeader));
|
||||||
|
Move (QwkHeader.MsgNum, QwkBlock[1], 7);
|
||||||
|
|
||||||
|
QwkBlock[0] := #7;
|
||||||
|
|
||||||
|
If GetBaseByIndex(strS2I(QwkBlock), TempBase) Then Begin
|
||||||
|
|
||||||
|
If OpenCreateBase(MsgBase, TempBase) Then Begin
|
||||||
|
|
||||||
|
AssignMessageData(MsgBase, TempBase);
|
||||||
|
|
||||||
|
QwkBlock[0] := #25;
|
||||||
|
Move (QwkHeader.UpTo, QwkBlock[1], 25);
|
||||||
|
MsgBase^.SetTo(strStripR(QwkBlock, ' '));
|
||||||
|
|
||||||
|
Move (QwkHeader.Subject, QwkBlock[1], 25);
|
||||||
|
MsgBase^.SetSubj(strStripR(QwkBlock, ' '));
|
||||||
|
|
||||||
|
Move (QwkHeader.ReferNum, QwkBlock[1], 6);
|
||||||
|
QwkBlock[0] := #6;
|
||||||
|
MsgBase^.SetRefer(strS2I(strStripR(QwkBlock, ' ')));
|
||||||
|
|
||||||
|
Move(QwkHeader.NumChunk, QwkBlock[1], 6);
|
||||||
|
|
||||||
|
Chunks := strS2I(QwkBlock) - 1;
|
||||||
|
Line := '';
|
||||||
|
LineCount := 0;
|
||||||
|
IsControl := MsgBase^.GetTo = qwkControlName;
|
||||||
|
GotControl := False;
|
||||||
|
|
||||||
|
If IsControl And ((MsgBase^.GetSubj = 'ADD') or (MsgBase^.GetSubj = 'DROP')) Then
|
||||||
|
QwkControl (TempBase.Index, Ord(MsgBase^.GetSubj = 'ADD'));
|
||||||
|
|
||||||
|
For A := 1 to Chunks Do Begin
|
||||||
|
BlockRead (DataFile, QwkBlock[1], 128);
|
||||||
|
|
||||||
|
QwkBlock[0] := #128;
|
||||||
|
QwkBlock := strStripR(QwkBlock, ' ');
|
||||||
|
|
||||||
|
For B := 1 to Length(QwkBlock) Do Begin
|
||||||
|
If QwkBlock[B] = #227 Then Begin
|
||||||
|
Inc (LineCount);
|
||||||
|
|
||||||
|
If (LineCount < 4) and (Copy(Line, 1, 5) = 'From:') Then
|
||||||
|
GotControl := True
|
||||||
|
// Mystic uses the username of the person who uploaded the
|
||||||
|
// reply package, based on the alias/realname setting of the
|
||||||
|
// base itself. This prevents people from spoofing "From"
|
||||||
|
// fields.
|
||||||
|
// If QWK networking will need to allow this of course
|
||||||
|
Else
|
||||||
|
If (LineCount < 4) and (Copy(Line, 1, 3) = 'To:') Then Begin
|
||||||
|
MsgBase^.SetTo(strStripB(Copy(Line, 4, Length(Line)), ' '));
|
||||||
|
GotControl := True;
|
||||||
|
End Else
|
||||||
|
If (LineCount < 4) and (Copy(Line, 1, 8) = 'Subject:') Then Begin
|
||||||
|
MsgBase^.SetSubj(strStripB(Copy(Line, 9, Length(Line)), ' '));
|
||||||
|
GotControl := True;
|
||||||
|
End Else
|
||||||
|
If GotControl And (Line = '') Then
|
||||||
|
GotControl := False
|
||||||
|
Else
|
||||||
|
MsgBase^.DoStringLn(Line);
|
||||||
|
|
||||||
|
Line := '';
|
||||||
|
End Else
|
||||||
|
Line := Line + QwkBlock[B];
|
||||||
|
End;
|
||||||
|
End;
|
||||||
|
|
||||||
|
If Line <> '' Then MsgBase^.DoStringLn(Line);
|
||||||
|
|
||||||
|
If TempBase.NetType > 0 Then Begin
|
||||||
|
MsgBase^.DoStringLn (#13 + '--- ' + mysSoftwareID + '/QWK v' + mysVersion + ' (' + OSID + ')');
|
||||||
|
MsgBase^.DoStringLn (' * Origin: ' + ResolveOrigin(TempBase) + ' (' + strAddr2Str(MsgBase^.GetOrigAddr) + ')');
|
||||||
|
End;
|
||||||
|
|
||||||
|
If Not IsControl Then Begin
|
||||||
|
MsgBase^.WriteMsg;
|
||||||
|
|
||||||
|
Inc (StatOK);
|
||||||
|
Inc (Session.User.ThisUser.Posts);
|
||||||
|
Inc (Session.HistoryPosts);
|
||||||
|
End;
|
||||||
|
|
||||||
|
MsgBase^.CloseMsgBase;
|
||||||
|
|
||||||
|
Dispose (MsgBase, Done);
|
||||||
|
End Else
|
||||||
|
Inc (StatFailed);
|
||||||
|
End Else
|
||||||
|
Inc (StatFailed);
|
||||||
|
End;
|
||||||
|
|
||||||
|
Close (DataFile);
|
||||||
|
|
||||||
|
Assign (ExtFile, FileFind(Session.TempPath + 'todoor.ext'));
|
||||||
|
{$I-} Reset (ExtFile); {$I+}
|
||||||
|
|
||||||
|
If IoResult = 0 Then Begin
|
||||||
|
While Not Eof(ExtFile) Do Begin
|
||||||
|
ReadLn (ExtFile, Line);
|
||||||
|
|
||||||
|
If strWordGet(1, Line, ' ') = 'AREA' Then Begin
|
||||||
|
QwkBlock := strWordGet(3, Line, ' ');
|
||||||
|
|
||||||
|
If Pos('a', QwkBlock) > 0 Then QwkControl(strS2I(strWordGet(2, Line, ' ')), 1);
|
||||||
|
If Pos('D', QwkBlock) > 0 Then QwkControl(strS2I(strWordGet(2, Line, ' ')), 0);
|
||||||
|
End;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Close (ExtFile);
|
||||||
|
End;
|
||||||
|
|
||||||
|
DirClean (Session.TempPath, '');
|
||||||
|
|
||||||
|
Session.io.PromptInfo[1] := strI2S(StatOK);
|
||||||
|
Session.io.PromptInfo[2] := strI2S(StatFailed);
|
||||||
|
Session.io.PromptInfo[3] := strI2S(StatBaseAdd);
|
||||||
|
Session.io.PromptInfo[4] := strI2S(StatBaseDel);
|
||||||
|
|
||||||
|
Session.io.OutFullLn(Session.GetPrompt(503));
|
||||||
|
End;
|
||||||
|
|
||||||
|
End.
|
||||||
|
|
||||||
|
// need one of these for the file list compiler now too which MAYBE can be
|
||||||
|
// used in MUTIL also. lets template and build that out first.. then...
|
||||||
|
// create and upload QWK/REP packets without relying on BBS specific stuff
|
||||||
|
|
||||||
|
Type
|
||||||
|
TMsgBaseQWK = Class
|
||||||
|
User : RecUser;
|
||||||
|
Extended : Boolean;
|
||||||
|
|
||||||
|
Constructor Create (UD: RecUser; Ext: Boolean);
|
||||||
|
Function CreatePacket : Boolean;
|
||||||
|
Function ProcessReply (bbsid, temppath, usernum, var user, forcefrom ): Boolean;
|
||||||
|
Destructor Destroy; Override;
|
||||||
|
End;
|
Loading…
Reference in New Issue