mysticbbs/mystic/mutil_common.pas

563 lines
14 KiB
ObjectPascal
Raw Normal View History

2012-02-29 17:45:16 -08:00
Unit MUTIL_Common;
{$I M_OPS.PAS}
Interface
Uses
m_Output,
2012-08-08 10:51:41 -07:00
m_IniReader,
2013-09-04 12:02:58 -07:00
mUtil_Status,
BBS_Records,
BBS_DataBase,
2013-09-04 12:02:58 -07:00
BBS_MsgBase_ABS,
BBS_MsgBase_Squish,
BBS_MsgBase_JAM;
2012-02-29 17:45:16 -08:00
Var
2012-08-08 10:51:41 -07:00
INI : TINIReader;
2012-02-29 17:45:16 -08:00
BarOne : TStatusBar;
BarAll : TStatusBar;
ProcessTotal : Byte = 0;
ProcessPos : Byte = 0;
2012-03-01 15:21:16 -08:00
TempPath : String;
StartPath : String;
2012-09-24 20:57:45 -07:00
LogFile : String;
LogLevel : Byte = 1;
2012-02-29 17:45:16 -08:00
Const
2013-03-17 04:01:46 -07:00
Header_GENERAL = 'General';
Header_IMPORTNA = 'Import_FIDONET.NA';
Header_IMPORTMB = 'Import_MessageBase';
Header_ECHOEXPORT = 'ExportEchoMail';
2013-03-18 22:48:11 -07:00
Header_ECHOIMPORT = 'ImportEchoMail';
2013-03-17 04:01:46 -07:00
Header_FILEBONE = 'Import_FILEBONE.NA';
Header_FILESBBS = 'Import_FILES.BBS';
Header_UPLOAD = 'MassUpload';
Header_TOPLISTS = 'GenerateTopLists';
Header_ALLFILES = 'GenerateAllFiles';
Header_MSGPURGE = 'PurgeMessageBases';
Header_MSGPACK = 'PackMessageBases';
Header_MSGPOST = 'PostTextFiles';
2013-09-07 11:37:42 -07:00
Header_NODELIST = 'MergeNodeLists';
2012-02-29 17:45:16 -08:00
2012-09-24 20:57:45 -07:00
Procedure Log (Level: Byte; Code: Char; Str: String);
Function GetUserBaseSize : Cardinal;
2012-02-29 19:27:06 -08:00
Function GenerateMBaseIndex : LongInt;
2012-03-03 22:21:25 -08:00
Function GenerateFBaseIndex : LongInt;
2012-02-29 19:27:06 -08:00
Function IsDupeMBase (FN: String) : Boolean;
2012-03-03 22:21:25 -08:00
Function IsDupeFBase (FN: String) : Boolean;
2012-02-29 19:27:06 -08:00
Procedure AddMessageBase (Var MBase: RecMessageBase);
2012-03-03 22:21:25 -08:00
Procedure AddFileBase (Var FBase: RecFileBase);
2012-09-25 16:20:59 -07:00
Function GetMBaseByIndex (Num: LongInt; Var TempBase: RecMessageBase) : Boolean;
2013-03-18 22:48:11 -07:00
Function GetMBaseByTag (Tag: String; Var TempBase: RecMessageBase) : Boolean;
Function GetMBaseByNetZone (Zone: Word; Var TempBase: RecMessageBase) : Boolean;
2012-09-26 13:51:07 -07:00
Function MessageBaseOpen (Var Msg: PMsgBaseABS; Var Area: RecMessageBase) : Boolean;
Function SaveMessage (mArea: RecMessageBase; mFrom, mTo, mSubj: String; mAddr: RecEchoMailAddr; mText: RecMessageText; mLines: Integer) : Boolean;
2013-03-17 04:01:46 -07:00
Function GetFTNArchiveName (Orig, Dest: RecEchoMailAddr) : String;
Function GetFTNFlowName (Dest: RecEchoMailAddr) : String;
2013-03-31 22:08:13 -07:00
Function GetFTNOutPath (EchoNode: RecEchoMailNode) : String;
2013-04-19 23:26:51 -07:00
Function GetNodeByRoute (Dest: RecEchoMailAddr; Var TempNode: RecEchoMailNode) : Boolean;
Function IsValidAKA (Zone, Net, Node, Point: Word) : Boolean;
2012-02-29 19:27:06 -08:00
2012-02-29 17:45:16 -08:00
Implementation
Uses
2012-03-01 15:31:40 -08:00
{$IFDEF UNIX}
2012-03-01 17:23:56 -08:00
Unix,
2012-03-01 15:31:40 -08:00
{$ENDIF}
2012-03-01 15:21:16 -08:00
DOS,
m_Types,
m_Strings,
2012-09-24 20:57:45 -07:00
m_DateTime,
2012-03-01 15:21:16 -08:00
m_FileIO;
2012-02-29 17:45:16 -08:00
2012-09-24 20:57:45 -07:00
Procedure Log (Level: Byte; Code: Char; Str: String);
Var
T : Text;
Begin
2013-03-18 22:48:11 -07:00
If (LogLevel < Level) or (LogFile = '') Then Exit;
2012-09-24 20:57:45 -07:00
Assign (T, LogFile);
Append (T);
If Str = '' Then
WriteLn (T, '')
Else
2013-09-07 11:37:42 -07:00
WriteLn (T, Code + ' ' + FormatDate(CurDateDT, 'NNN DD YYYY HH:II') + ' ' + Str);
2012-09-24 20:57:45 -07:00
Close (T);
End;
Function GetUserBaseSize : Cardinal;
Begin
Result := FileByteSize(bbsCfg.DataPath + 'users.dat');
If Result > 0 Then Result := Result DIV SizeOf(RecUser);
End;
2012-02-29 19:27:06 -08:00
Function IsDupeMBase (FN: String) : Boolean;
Var
MBaseFile : File of RecMessageBase;
MBase : RecMessageBase;
Begin
Result := False;
Assign (MBaseFile, bbsCfg.DataPath + 'mbases.dat');
2012-02-29 19:27:06 -08:00
{$I-} Reset (MBaseFile); {$I+}
If IoResult <> 0 Then Exit;
While Not Eof(MBaseFile) Do Begin
Read (MBaseFile, MBase);
If strUpper(MBase.FileName) = strUpper(FN) Then Begin
Result := True;
Break;
End;
End;
Close (MBaseFile);
End;
2012-03-03 22:21:25 -08:00
Function IsDupeFBase (FN: String) : Boolean;
Var
FBaseFile : File of RecFileBase;
FBase : RecFileBase;
Begin
Result := False;
Assign (FBaseFile, bbsCfg.DataPath + 'fbases.dat');
2012-03-03 22:21:25 -08:00
{$I-} Reset (FBaseFile); {$I+}
If IoResult <> 0 Then Exit;
While Not Eof(FBaseFile) Do Begin
Read (FBaseFile, FBase);
If strUpper(FBase.FileName) = strUpper(FN) Then Begin
Result := True;
Break;
End;
End;
Close (FBaseFile);
End;
2012-02-29 19:27:06 -08:00
Function GenerateMBaseIndex : LongInt;
Var
MBaseFile : File of RecMessageBase;
MBase : RecMessageBase;
Begin
Assign (MBaseFile, bbsCfg.DataPath + 'mbases.dat');
2012-02-29 19:27:06 -08:00
Reset (MBaseFile);
Result := FileSize(MBaseFile);
While Not Eof(MBaseFile) Do Begin
Read (MBaseFile, MBase);
If MBase.Index = Result Then Begin
Inc (Result);
Reset (MBaseFile);
End;
End;
Close (MBaseFile);
End;
2012-03-03 22:21:25 -08:00
Function GenerateFBaseIndex : LongInt;
Var
FBaseFile : File of RecFileBase;
FBase : RecFileBase;
Begin
Assign (FBaseFile, bbsCfg.DataPath + 'fbases.dat');
2012-03-03 22:21:25 -08:00
Reset (FBaseFile);
Result := FileSize(FBaseFile);
While Not Eof(FBaseFile) Do Begin
Read (FBaseFile, FBase);
If FBase.Index = Result Then Begin
Inc (Result);
Reset (FBaseFile);
End;
End;
Close (FBaseFile);
End;
2012-02-29 19:27:06 -08:00
Procedure AddMessageBase (Var MBase: RecMessageBase);
Var
MBaseFile : File of RecMessageBase;
Begin
Assign (MBaseFile, bbsCfg.DataPath + 'mbases.dat');
2012-02-29 19:27:06 -08:00
Reset (MBaseFile);
Seek (MBaseFile, FileSize(MBaseFile));
Write (MBaseFile, MBase);
Close (MBaseFile);
End;
2012-03-03 22:21:25 -08:00
Procedure AddFileBase (Var FBase: RecFileBase);
Var
FBaseFile : File of RecFileBase;
Begin
Assign (FBaseFile, bbsCfg.DataPath + 'fbases.dat');
2012-03-03 22:21:25 -08:00
Reset (FBaseFile);
Seek (FBaseFile, FileSize(FBaseFile));
Write (FBaseFile, FBase);
Close (FBaseFile);
End;
2012-09-25 16:20:59 -07:00
Function GetMBaseByIndex (Num: LongInt; Var TempBase: RecMessageBase) : Boolean;
Var
F : File;
Begin
Result := False;
Assign (F, bbsCfg.DataPath + 'mbases.dat');
2012-09-25 16:20:59 -07:00
If Not ioReset(F, SizeOf(RecMessageBase), fmRWDN) Then Exit;
While Not Eof(F) Do Begin
ioRead(F, TempBase);
If TempBase.Index = Num Then Begin
Result := True;
Break;
End;
End;
Close (F);
End;
2013-03-18 22:48:11 -07:00
Function GetMBaseByTag (Tag: String; Var TempBase: RecMessageBase) : Boolean;
Var
F : File;
Begin
Result := False;
Assign (F, bbsCfg.DataPath + 'mbases.dat');
2013-03-18 22:48:11 -07:00
If Not ioReset(F, SizeOf(RecMessageBase), fmRWDN) Then Exit;
While Not Eof(F) Do Begin
ioRead(F, TempBase);
If Tag = strUpper(TempBase.EchoTag) Then Begin
Result := True;
Break;
End;
End;
Close (F);
End;
Function GetMBaseByNetZone (Zone: Word; Var TempBase: RecMessageBase) : Boolean;
2013-03-22 20:17:33 -07:00
// get netmail base with matching zone, or at least A netmail base if no match
2013-03-18 22:48:11 -07:00
Var
2013-03-22 20:17:33 -07:00
F : File;
One : RecMessageBase;
GotOne : Boolean;
2013-03-18 22:48:11 -07:00
Begin
Result := False;
Assign (F, bbsCfg.DataPath + 'mbases.dat');
2013-03-18 22:48:11 -07:00
If Not ioReset(F, SizeOf(RecMessageBase), fmRWDN) Then Exit;
While Not Eof(F) Do Begin
ioRead(F, TempBase);
2013-03-22 20:17:33 -07:00
If (TempBase.NetType = 3) Then Begin
One := TempBase;
GotOne := True;
If Zone = bbsCfg.NetAddress[TempBase.NetAddr].Zone Then Begin
2013-03-22 20:17:33 -07:00
Result := True;
Break;
End;
2013-03-18 22:48:11 -07:00
End;
End;
Close (F);
2013-03-22 20:17:33 -07:00
If Not Result And GotOne Then Begin
Result := True;
TempBase := One;
End;
2013-03-18 22:48:11 -07:00
End;
2012-09-26 13:51:07 -07:00
Function MessageBaseOpen (Var Msg: PMsgBaseABS; Var Area: RecMessageBase) : Boolean;
Begin
Result := False;
Case Area.BaseType of
0 : Msg := New(PMsgBaseJAM, Init);
1 : Msg := New(PMsgBaseSquish, Init);
End;
Msg^.SetMsgPath (Area.Path + Area.FileName);
Msg^.SetTempFile (TempPath + 'msgbuf.tmp');
If Not Msg^.OpenMsgBase Then
If Not Msg^.CreateMsgBase (Area.MaxMsgs, Area.MaxAge) Then Begin
Dispose (Msg, Done);
Exit;
End Else
If Not Msg^.OpenMsgBase Then Begin
Dispose (Msg, Done);
Exit;
End;
Result := True;
End;
Function SaveMessage (mArea: RecMessageBase; mFrom, mTo, mSubj: String; mAddr: RecEchoMailAddr; mText: RecMessageText; mLines: Integer) : Boolean;
Var
SemFile : File;
Count : SmallInt;
Msg : PMsgBaseABS;
Begin
Result := False;
If Not MessageBaseOpen(Msg, mArea) Then Exit;
Msg^.StartNewMsg;
Msg^.SetLocal (True);
If mArea.NetType > 0 Then Begin
If mArea.NetType = 2 Then Begin
Msg^.SetMailType (mmtNetMail);
Msg^.SetCrash (bbsCfg.netCrash);
Msg^.SetHold (bbsCfg.netHold);
Msg^.SetKillSent (bbsCfg.netKillSent);
2012-09-26 13:51:07 -07:00
Msg^.SetDest (mAddr);
End Else
Msg^.SetMailType (mmtEchoMail);
Msg^.SetOrig(bbsCfg.NetAddress[mArea.NetAddr]);
2012-09-26 13:51:07 -07:00
Case mArea.NetType of
2013-09-12 14:57:03 -07:00
1 : If mArea.QwkConfID = 0 Then
Assign (SemFile, bbsCfg.SemaPath + fn_SemFileEchoOut)
Else
Assign (SemFile, bbsCfg.SemaPath + fn_SemFileQwk);
2 : Assign (SemFile, bbsCfg.SemaPath + fn_SemFileNews);
3 : Assign (SemFile, bbsCfg.SemaPath + fn_SemFileNet);
2012-09-26 13:51:07 -07:00
End;
ReWrite (SemFile);
Close (SemFile);
End Else
Msg^.SetMailType (mmtNormal);
Msg^.SetPriv (mArea.Flags And MBPrivate <> 0);
Msg^.SetDate (DateDos2Str(CurDateDos, 1));
2013-03-18 22:48:11 -07:00
Msg^.SetTime (TimeDos2Str(CurDateDos, 0));
2012-09-26 13:51:07 -07:00
Msg^.SetFrom (mFrom);
Msg^.SetTo (mTo);
Msg^.SetSubj (mSubj);
2013-09-27 18:00:25 -07:00
If (mArea.NetType > 0) and (mArea.QwkNetID = 0) Then
2013-09-29 17:25:56 -07:00
Msg^.DoStringLn (#1 + 'MSGID: ' + Addr2Str(bbsCfg.NetAddress[mArea.NetAddr]) + ' ' + strI2H(CurDateDos, 8));
2013-09-06 19:14:14 -07:00
2012-09-26 13:51:07 -07:00
For Count := 1 to mLines Do
Msg^.DoStringLn(mText[Count]);
If mArea.NetType > 0 Then Begin
2013-09-29 17:25:56 -07:00
Msg^.DoStringLn (#13 + '--- ' + mysSoftwareID + ' v' + mysVersion + ' (' + OSID + ')');
Msg^.DoStringLn (' * Origin: ' + mArea.Origin + ' (' + Addr2Str(bbsCfg.NetAddress[mArea.NetAddr]) + ')');
2012-09-26 13:51:07 -07:00
End;
Msg^.WriteMsg;
Msg^.CloseMsgBase;
Dispose (Msg, Done);
Result := True;
End;
2013-03-17 04:01:46 -07:00
Function GetFTNArchiveName (Orig, Dest: RecEchoMailAddr) : String;
Var
Net : LongInt;
Node : LongInt;
Begin
2013-09-25 19:39:08 -07:00
If Dest.Point = 0 Then Begin
Net := Orig.Net - Dest.Net;
Node := Orig.Node - Dest.Node;
2013-03-17 04:01:46 -07:00
2013-09-25 19:39:08 -07:00
If Net < 0 Then Net := 65536 + Net;
If Node < 0 Then Node := 65536 + Node;
2013-03-17 04:01:46 -07:00
2013-09-25 19:39:08 -07:00
Result := strI2H((Net SHL 16) OR Node, 8);
End Else
Result := strI2H(Dest.Point, 8);
2013-03-17 04:01:46 -07:00
End;
Function GetFTNFlowName (Dest: RecEchoMailAddr) : String;
Begin
2013-05-06 17:07:39 -07:00
If Dest.Point = 0 Then
Result := strI2H((Dest.Net SHL 16) OR Dest.Node, 8)
Else
Result := strI2H(Dest.Point, 8);
2013-03-31 22:08:13 -07:00
End;
Function IsFTNPrimary (EchoNode: RecEchoMailNode) : Boolean;
Var
Count : Byte;
Begin
For Count := 1 to 30 Do
If (strUpper(EchoNode.Domain) = strUpper(bbsCfg.NetDomain[Count])) and
(EchoNode.Address.Zone = bbsCfg.NetAddress[Count].Zone) and
(bbsCfg.NetPrimary[Count]) Then Begin
2013-03-31 22:08:13 -07:00
Result := True;
Exit;
End;
Result := False;
End;
Function GetFTNOutPath (EchoNode: RecEchoMailNode) : String;
Begin;
If IsFTNPrimary(EchoNode) Then
Result := bbsCfg.OutboundPath
2013-03-31 22:08:13 -07:00
Else
Result := DirLast(bbsCfg.OutboundPath) + strLower(EchoNode.Domain + '.' + strPadL(strI2H(EchoNode.Address.Zone, 3), 3, '0')) + PathChar;
2013-05-06 17:07:39 -07:00
If EchoNode.Address.Point <> 0 Then
Result := Result + strI2H((EchoNode.Address.Net SHL 16) OR EchoNode.Address.Node, 8) + '.pnt' + PathChar;
2013-03-17 04:01:46 -07:00
End;
2013-04-19 23:26:51 -07:00
Function GetNodeByRoute (Dest: RecEchoMailAddr; Var TempNode: RecEchoMailNode) : Boolean;
Function IsMatch (Str: String) : Boolean;
2013-05-06 17:07:39 -07:00
Function IsOneMatch (Mask: String) : Boolean;
Var
Zone : String;
Net : String;
Node : String;
Point : String;
A : Byte;
B : Byte;
C : Byte;
Begin
Result := False;
Zone := '';
Net := '';
Node := '';
Point := '';
A := Pos(':', Mask);
B := Pos('/', Mask);
C := Pos('.', Mask);
If A <> 0 Then Begin
Zone := Copy(Mask, 1, A - 1);
If B = 0 Then B := 255;
If C = 0 Then C := 255;
Net := Copy(Mask, A + 1, B - 1 - A);
Node := Copy(Mask, B + 1, C - 1 - B);
Point := Copy(Mask, C + 1, 255);
End;
If Zone = '' Then Zone := '*';
If Net = '' Then Net := '*';
If Node = '' Then Node := '*';
If Point = '' Then Point := '*';
If (Zone <> '*') and (Dest.Zone <> strS2I(Zone)) Then Exit;
If (Net <> '*') and (Dest.Net <> strS2I(Net)) Then Exit;
If (Node <> '*') and (Dest.Node <> strS2I(Node)) Then Exit;
If (Point <> '*') and (Dest.Point <> strS2I(Point)) Then Exit;
Result := True;
End;
2013-04-19 23:26:51 -07:00
Var
Mask : String = '';
OneRes : Boolean;
Procedure GetNextAddress;
Begin
If Pos('!', Str) > 0 Then Begin
Mask := Copy(Str, 1, Pos('!', Str) - 1);
Delete (Str, 1, Pos('!', Str) - 1);
End Else
If Pos(' ', Str) > 0 Then Begin
Mask := Copy(Str, 1, Pos(' ', Str) - 1);
Delete (Str, 1, Pos(' ', Str));
End Else Begin
Mask := Str;
Str := '';
End;
End;
Begin
Result := False;
Str := strStripB(Str, ' ');
If Str = '' Then Exit;
Repeat
GetNextAddress;
If Mask = '' Then Break;
OneRes := IsOneMatch(Mask);
While (Str[1] = '!') and (Mask <> '') Do Begin
Delete (Str, 1, 1);
GetNextAddress;
OneRes := OneRes AND (NOT IsOneMatch(Mask));
End;
Result := Result OR OneRes;
Until Str = '';
End;
Var
F : File;
Begin
Result := False;
Assign (F, bbsCfg.DataPath + 'echonode.dat');
2013-04-19 23:26:51 -07:00
If Not ioReset(F, SizeOf(RecEchoMailNode), fmRWDN) Then Exit;
While Not Eof(F) And Not Result Do Begin
ioRead(F, TempNode);
Result := IsMatch(TempNode.RouteInfo);
End;
Close (F);
End;
Function IsValidAKA (Zone, Net, Node, Point: Word) : Boolean;
2013-04-12 21:57:02 -07:00
Var
Count : Byte;
Begin
Result := False;
For Count := 1 to 30 Do Begin
Result := (bbsCfg.NetAddress[Count].Zone = Zone) And
(bbsCfg.NetAddress[Count].Net = Net) And
(bbsCfg.NetAddress[Count].Node = Node) And
(bbsCfg.NetAddress[Count].Point = Point);
2013-04-12 21:57:02 -07:00
If Result Then Break;
End;
End;
2012-09-26 13:51:07 -07:00
End.