From d1ac7f592a1ab035d6066dccc9814231fd337b8a Mon Sep 17 00:00:00 2001 From: mysticbbs Date: Wed, 18 Sep 2013 16:41:07 -0400 Subject: [PATCH] Code restructure and some bug fixes --- mystic/bbs_database.pas | 23 ++++++++ mystic/mis.pas | 91 ++++++++++++------------------- mystic/mis_client_binkp.pas | 102 ++++++++++++++++++++++------------- mystic/mis_client_ftp.pas | 48 ++++++++--------- mystic/mis_client_nntp.pas | 14 ++--- mystic/mis_client_pop3.pas | 19 +++---- mystic/mis_client_smtp.pas | 13 ++--- mystic/mis_client_telnet.pas | 7 +-- mystic/mis_common.pas | 20 +++---- mystic/mis_nodedata.pas | 3 +- mystic/mutil_echoexport.pas | 22 ++++---- mystic/whatsnew.txt | 17 +++++- 12 files changed, 213 insertions(+), 166 deletions(-) diff --git a/mystic/bbs_database.pas b/mystic/bbs_database.pas index 9133ea8..ddab8ed 100644 --- a/mystic/bbs_database.pas +++ b/mystic/bbs_database.pas @@ -64,6 +64,10 @@ Function ImportFileDIZ (Var Desc: FileDescBuffer; Var DescLines: Byte; Function IsThisUser (U: RecUser; Str: String) : Boolean; +// ECHOMAIL + +Function GetNodeByAddress (Addr: String; Var TempNode: RecEchoMailNode) : Boolean; + Implementation Uses @@ -627,6 +631,25 @@ Begin End; End; +Function GetNodeByAddress (Addr: String; Var TempNode: RecEchoMailNode) : Boolean; +Var + F : File; +Begin + Result := False; + + Assign (F, bbsCfg.DataPath + 'echonode.dat'); + + If Not ioReset(F, SizeOf(RecEchoMailNode), fmRWDN) Then Exit; + + While Not Eof(F) And Not Result Do Begin + ioRead(F, TempNode); + + Result := Addr2Str(TempNode.Address) = Addr; + End; + + Close (F); +End; + Initialization bbsCfgStatus := GetBaseConfiguration(True, bbsCfg); diff --git a/mystic/mis.pas b/mystic/mis.pas index fe532c5..e2c13ab 100644 --- a/mystic/mis.pas +++ b/mystic/mis.pas @@ -80,41 +80,21 @@ Var {$I MIS_ANSIWFC.PAS} Procedure ReadConfiguration; -Var - FileConfig : TFileBuffer; - DatLoc : String; Begin - FileConfig := TFileBuffer.Create(SizeOf(RecConfig)); + Case bbsCfgStatus of + cfgNotFound : If Not DaemonMode Then Begin + Console.WriteLine (#13#10 + 'ERROR: Unable to read MYSTIC.DAT. This file must exist in the same'); + Console.WriteLine ('directory as MIS or MYSTICBBS environment location'); - If Not FileConfig.OpenStream ('mystic.dat', 1, fmOpen, fmRWDN) Then Begin - DatLoc := GetEnv('mysticbbs'); - - If DatLoc <> '' Then DatLoc := DirSlash(DatLoc); - - If Not FileConfig.OpenStream (DatLoc + 'mystic.dat', 1, fmOpen, fmRWDN) Then Begin - If Not DaemonMode Then Begin - Console.WriteLine (#13#10 + 'ERROR: Unable to read MYSTIC.DAT. This file must exist in the same'); - Console.WriteLine ('directory as MIS'); - - Keyboard.Free; - Console.Free; - End; - - FileConfig.Free; - - Halt (1); - End; + Halt(1); + End; + cfgMisMatch : Begin + WriteLn('ERROR: Data files are not current and must be upgraded.'); + Halt(1); + End; End; - FileConfig.ReadBlock (bbsConfig, SizeOf(bbsConfig)); - FileConfig.Free; - - If bbsConfig.DataChanged <> mysDataChanged Then Begin - WriteLn('ERROR: Data files are not current and must be upgraded.'); - Halt(1); - End; - - DirChange(bbsConfig.SystemPath); + DirChange(bbsCfg.SystemPath); End; Function GetFocusPtr : TServerManager; @@ -253,6 +233,7 @@ Begin End; End; +(* Procedure LocalLogin; Const BufferSize = 1024 * 4; @@ -271,7 +252,7 @@ Begin Client.FTelnetClient := True; - If Not Client.Connect(bbsConfig.inetInterface{'127.0.0.1'}, bbsConfig.InetTNPort) Then + If Not Client.Connect(bbsCfg.inetInterface{'127.0.0.1'}, bbsCfg.InetTNPort) Then Console.WriteLine('Unable to connect') Else Begin Done := False; @@ -332,7 +313,7 @@ Begin SwitchFocus; End; - +*) {$IFDEF UNIX} Procedure SetUserOwner; Var @@ -362,63 +343,63 @@ Begin SMTPServer := NIL; NNTPServer := NIL; BINKPServer := NIL; - NodeData := TNodeData.Create(bbsConfig.INetTNNodes); + NodeData := TNodeData.Create(bbsCfg.INetTNNodes); - If bbsConfig.InetTNUse Then Begin - TelnetServer := TServerManager.Create(bbsConfig, bbsConfig.InetTNPort, bbsConfig.INetTNNodes, NodeData, @CreateTelnet); + If bbsCfg.InetTNUse Then Begin + TelnetServer := TServerManager.Create(bbsCfg, bbsCfg.InetTNPort, bbsCfg.INetTNNodes, NodeData, @CreateTelnet); TelnetServer.Server.FTelnetServer := True; - TelnetServer.ClientMaxIPs := bbsConfig.InetTNDupes; + TelnetServer.ClientMaxIPs := bbsCfg.InetTNDupes; TelnetServer.LogFile := 'telnet'; Result := True; End; - If bbsConfig.InetSMTPUse Then Begin - SMTPServer := TServerManager.Create(bbsConfig, bbsConfig.INetSMTPPort, bbsConfig.inetSMTPMax, NodeData, @CreateSMTP); + If bbsCfg.InetSMTPUse Then Begin + SMTPServer := TServerManager.Create(bbsCfg, bbsCfg.INetSMTPPort, bbsCfg.inetSMTPMax, NodeData, @CreateSMTP); SMTPServer.Server.FTelnetServer := False; - SMTPServer.ClientMaxIPs := bbsConfig.INetSMTPDupes; + SMTPServer.ClientMaxIPs := bbsCfg.INetSMTPDupes; SMTPServer.LogFile := 'smtp'; Result := True; End; - If bbsConfig.InetPOP3Use Then Begin - POP3Server := TServerManager.Create(bbsConfig, bbsConfig.INetPOP3Port, bbsConfig.inetPOP3Max, NodeData, @CreatePOP3); + If bbsCfg.InetPOP3Use Then Begin + POP3Server := TServerManager.Create(bbsCfg, bbsCfg.INetPOP3Port, bbsCfg.inetPOP3Max, NodeData, @CreatePOP3); POP3Server.Server.FTelnetServer := False; - POP3Server.ClientMaxIPs := bbsConfig.inetPOP3Dupes; + POP3Server.ClientMaxIPs := bbsCfg.inetPOP3Dupes; POP3Server.LogFile := 'pop3'; Result := True; End; - If bbsConfig.InetFTPUse Then Begin - FTPServer := TServerManager.Create(bbsConfig, bbsConfig.InetFTPPort, bbsConfig.inetFTPMax, NodeData, @CreateFTP); + If bbsCfg.InetFTPUse Then Begin + FTPServer := TServerManager.Create(bbsCfg, bbsCfg.InetFTPPort, bbsCfg.inetFTPMax, NodeData, @CreateFTP); FTPServer.Server.FTelnetServer := False; - FTPServer.ClientMaxIPs := bbsConfig.inetFTPDupes; + FTPServer.ClientMaxIPs := bbsCfg.inetFTPDupes; FTPServer.LogFile := 'ftp'; Result := True; End; - If bbsConfig.InetNNTPUse Then Begin - NNTPServer := TServerManager.Create(bbsConfig, bbsConfig.InetNNTPPort, bbsConfig.inetNNTPMax, NodeData, @CreateNNTP); + If bbsCfg.InetNNTPUse Then Begin + NNTPServer := TServerManager.Create(bbsCfg, bbsCfg.InetNNTPPort, bbsCfg.inetNNTPMax, NodeData, @CreateNNTP); NNTPServer.Server.FTelnetServer := False; - NNTPServer.ClientMaxIPs := bbsConfig.inetNNTPDupes; + NNTPServer.ClientMaxIPs := bbsCfg.inetNNTPDupes; NNTPServer.LogFile := 'nntp'; Result := True; End; - If bbsConfig.InetBINKPUse Then Begin - BINKPServer := TServerManager.Create(bbsConfig, bbsConfig.InetBINKPPort, bbsConfig.inetBINKPMax, NodeData, @CreateBINKP); + If bbsCfg.InetBINKPUse Then Begin + BINKPServer := TServerManager.Create(bbsCfg, bbsCfg.InetBINKPPort, bbsCfg.inetBINKPMax, NodeData, @CreateBINKP); BINKPServer.Server.FTelnetServer := False; - BINKPServer.ClientMaxIPs := bbsConfig.inetBINKPDupes; + BINKPServer.ClientMaxIPs := bbsCfg.inetBINKPDupes; BINKPServer.LogFile := 'binkp'; Result := True; @@ -428,7 +409,7 @@ Begin SetUserOwner; {$ENDIF} - TempPath := bbsConfig.SystemPath + 'temp0' + PathChar; + TempPath := bbsCfg.SystemPath + 'temp0' + PathChar; DirCreate(TempPath); End; @@ -613,7 +594,7 @@ Begin #09 : SwitchFocus; // #13 : {$IFDEF UNIX}Snoop{$ENDIF}; #27 : Break; - #32 : LocalLogin; +// #32 : LocalLogin; End; If (FocusPtr <> NIL) Then @@ -656,8 +637,6 @@ Begin Console.WriteLine (' (DONE)'); NodeData.Free; - Keyboard.Free; - Console.Free; Halt(255); End. diff --git a/mystic/mis_client_binkp.pas b/mystic/mis_client_binkp.pas index 03e7f13..37e3e81 100644 --- a/mystic/mis_client_binkp.pas +++ b/mystic/mis_client_binkp.pas @@ -16,7 +16,8 @@ Uses MIS_Server, MIS_NodeData, MIS_Common, - BBS_Records; + BBS_Records, + BBS_DataBase; Const M_NUL = 0; @@ -85,7 +86,7 @@ Type Data ); - TBinkPStatusUpdate = Procedure (Owner: Pointer; Str: String); + TBinkPStatusUpdate = Procedure (Owner: Pointer; Level: Byte; Str: String); TBinkP = Class Owner : Pointer; @@ -116,6 +117,8 @@ Type PasswordMD5 : Boolean; FileList : TProtocolQueue; RcvdFiles : LongInt; + SentFiles : LongInt; + SkipFiles : LongInt; Constructor Create (O: Pointer; Var C: TIOSocket; Var FL: TProtocolQueue; IsCli: Boolean; TOV: Word); Destructor Destroy; Override; @@ -182,6 +185,8 @@ Begin HaveNode := False; AuthState := SendWelcome; RcvdFiles := 0; + SentFiles := 0; + SkipFiles := 0; If Not IsClient and UseMD5 Then AuthState := SendChallenge; @@ -230,7 +235,7 @@ Var Begin Result := False; - Assign (EchoFile, bbsConfig.DataPath + 'echonode.dat'); + Assign (EchoFile, bbsCfg.DataPath + 'echonode.dat'); If Not ioReset(EchoFile, SizeOf(RecEchoMailNode), fmRWDN) Then Exit; @@ -239,7 +244,7 @@ Begin For Count := 1 to strWordCount(AddrList, ' ') Do Begin Addr1 := strWordGet(Count, AddrList, ' '); - Addr2 := strAddr2Str(EchoNode.Address); + Addr2 := Addr2Str(EchoNode.Address); UseDomain := Pos('@', Addr1) > 0; If UseDomain Then @@ -346,12 +351,12 @@ Procedure TBinkP.SendFrame (CmdType: Byte; CmdData: String); Var DataSize : Word; Begin - DataSize := (Length(CmdData) + 2) OR $8000; + DataSize := (Length(CmdData) + 1) OR $8000; - Client.BufWriteStr(Char(Hi(DataSize)) + Char(Lo(DataSize)) + Char(CmdType) + CmdData + #0); + Client.BufWriteStr(Char(Hi(DataSize)) + Char(Lo(DataSize)) + Char(CmdType) + CmdData); Client.BufFlush; - StatusUpdate (Owner, 'S ' + BinkCmdStr[CmdType] + ' ' + CmdData); + StatusUpdate (Owner, 2, 'S ' + BinkCmdStr[CmdType] + ' ' + CmdData); // WriteLn (' S ' + BinkCmdStr[CmdType] + ' ' + CmdData); // waitms(1000); @@ -411,7 +416,7 @@ Begin End; If RxFrameType = Command Then - StatusUpdate (Owner, 'R ' + BinkCmdStr[RxCommand] + ' ' + GetDataStr); + StatusUpdate (Owner, 2, 'R ' + BinkCmdStr[RxCommand] + ' ' + GetDataStr); // Case RxFrameType of @@ -450,8 +455,8 @@ Begin If Count > 0 Then MD5Challenge := Copy(Str, Count + 4, 255); - If Not IsClient Then - StatusUpdate (Owner, Str); +// If Not IsClient Then + StatusUpdate (Owner, 1, Str); End; // WriteLn ('AuthState: ', GetStateStr(AuthState), ', HasHeader: ', HaveHeader, ' Data: ', GetDataStr); @@ -469,20 +474,20 @@ Begin AuthState := SendWelcome; End; SendWelcome : Begin - SendFrame (M_NUL, 'SYS ' + bbsConfig.BBSName); - SendFrame (M_NUL, 'ZYZ ' + bbsConfig.SysopName); + SendFrame (M_NUL, 'SYS ' + bbsCfg.BBSName); + SendFrame (M_NUL, 'ZYZ ' + bbsCfg.SysopName); SendFrame (M_NUL, 'VER Mystic/' + Copy(mysVersion, 1, 4) + ' binkp/1.0'); Str := ''; For Count := 1 to 30 Do - If strAddr2Str(bbsConfig.NetAddress[Count]) <> '0:0/0' Then Begin + If Addr2Str(bbsCfg.NetAddress[Count]) <> '0:0/0' Then Begin If Str <> '' Then Str := Str + ' '; - Str := Str + strAddr2Str(bbsConfig.NetAddress[Count]); + Str := Str + Addr2Str(bbsCfg.NetAddress[Count]); - If bbsConfig.NetDomain[Count] <> '' Then - Str := Str + '@' + bbsConfig.NetDomain[Count]; + If bbsCfg.NetDomain[Count] <> '' Then + Str := Str + '@' + bbsCfg.NetDomain[Count]; End; SendFrame (M_ADR, Str); @@ -526,7 +531,7 @@ Begin NeedHeader := True; HaveHeader := False; - StatusUpdate (Owner, 'ADR ' + AddressList); + StatusUpdate (Owner, 1, 'ADR ' + AddressList); End; End; WaitPassword : If HaveHeader Then Begin @@ -561,7 +566,7 @@ Begin End; If AuthState <> AuthOK Then - StatusUpdate(Owner, 'Authorization failed'); + StatusUpdate(Owner, 1, 'Authorization failed'); End; WaitPwdOK : If HaveHeader Then Begin If RxCommand <> M_OK Then @@ -587,6 +592,10 @@ Var InPos : Cardinal; InTime : Cardinal; FSize : Cardinal; +// LastRx : TBinkRxState = RxNone; +// LastTx : TBinkTxState = TxNone; +// LastHH : Boolean = False; +// LastNH : Boolean = False; Begin //WriteLn ('Begin File Transfers'); @@ -601,10 +610,16 @@ Begin // need to update states to handle getting FILE during an xfer // and what to do if the file frame goes past file size (fail/quit), etc +(* + If (RxState <> LastRx) or (TxState <> LastTx) or (HaveHeader <> LastHH) or (NeedHeader <> LastNH) Then Begin + lastrx := rxstate; + lasttx := txstate; + lasthh := haveheader; + lastnh := needheader; -// waitms(100); -// writeln ('rxstate=', ord(rxstate), ' txstate=', ord(txstate), ' have header ', haveheader, ' need header ', needheader); - + WriteLn ('rxstate=', ord(rxstate), ' txstate=', ord(txstate), ' have header ', haveheader, ' need header ', needheader); + End; +*) Case RxState of RxWaitFile : If HaveHeader Then Begin If RxFrameType = Data Then Begin @@ -626,25 +641,27 @@ Begin InTime := strS2I(strWordGet(3, Str, ' ')); InPos := strS2I(strWordGet(4, Str, ' ')); - If FileExist(bbsConfig.InBoundPath + InFN) Then Begin - FSize := FileByteSize(bbsConfig.InBoundPath + InFN); + If FileExist(bbsCfg.InBoundPath + InFN) Then Begin + FSize := FileByteSize(bbsCfg.InBoundPath + InFN); // fix timestamp and escape filen If FSize >= InSize Then Begin - SendFrame (M_SKIP, EscapeFileName(InFN) + ' ' + strI2S(FSize) + ' ' + strI2S(InTime)); + SendFrame (M_SKIP, EscapeFileName(InFN) + ' ' + strI2S(InSize) + ' ' + strI2S(InTime)); + + Inc (SkipFiles); Continue; End Else Begin SendFrame (M_GET, EscapeFileName(InFN) + ' ' + strI2S(FSize) + ' ' + strI2S(InTime)); - StatusUpdate(Owner, 'Receiving: ' + InFN); - InPos := FSize; End; End; - Assign (InFile, bbsConfig.InBoundPath + InFN); + StatusUpdate(Owner, 1, 'Receiving: ' + InFN); + + Assign (InFile, bbsCfg.InBoundPath + InFN); Reset (InFile, 1); If IoResult <> 0 Then ReWrite (InFile, 1); @@ -657,6 +674,10 @@ Begin NeedHeader := True; HaveHeader := False; RxState := RxDone; + // It seems BINKP never sends this IF the last file + // was skipped? Odd. Do we add a "LastWasSkipped" + // and do something after a small wait time? or + // just wait for it to timeout like it does now End; End; RxGetData : If HaveHeader And (RxFrameType = Data) Then Begin @@ -693,6 +714,8 @@ Begin HaveHeader := False; NeedHeader := True; TxState := TxNextFile; + + Inc (SkipFiles); End Else If RxCommand = M_GOT Then Begin FileList.QData[FileList.QPos].Status := QueueSuccess; @@ -703,6 +726,8 @@ Begin HaveHeader := False; NeedHeader := True; TxState := TxNextFile; + + Inc (SentFiles); End; End; TxNextFile : If FileList.Next Then Begin @@ -714,7 +739,7 @@ Begin // use real filetime instead of tempfiletime SendFrame (M_FILE, EscapeFileName(FileList.QData[FileList.QPos].FileNew) + ' ' + strI2S(FileList.QData[FileList.QPos].FileSize) + ' ' + strI2S(TempFileTime) + ' 0'); - StatusUpdate (Owner, 'Sending ' + FileList.QData[FileList.QPos].FileNew); + StatusUpdate (Owner, 1, 'Sending ' + FileList.QData[FileList.QPos].FileNew); TxState := TxSendData; End Else Begin @@ -729,6 +754,8 @@ Begin TxState := TxNextFile; HaveHeader := False; NeedHeader := True; + + Inc (SkipFiles); End Else If HaveHeader And (RxCommand = M_GET) Then Begin Str := strWordGet(4, GetDataStr, ' '); @@ -759,8 +786,7 @@ Begin End; Until ((RxState = RxDone) and (TxState = TxDone)) or (Not Client.Connected) or (TimerUp(TimeOut)); - If Not IsClient Then - StatusUpdate(Owner, 'Session complete'); + StatusUpdate(Owner, 1, 'Session complete (' + strI2S(SentFiles) + ' sent, ' + strI2S(RcvdFiles) + ' rcvd, ' + strI2S(SkipFiles) + ' skip)'); If Client.Connected Then Client.BufFlush; End; @@ -772,9 +798,9 @@ Var Count : Byte; Begin For Count := 1 to 30 Do - If (strUpper(EchoNode.Domain) = strUpper(bbsConfig.NetDomain[Count])) and - (EchoNode.Address.Zone = bbsConfig.NetAddress[Count].Zone) and - (bbsConfig.NetPrimary[Count]) Then Begin + If (strUpper(EchoNode.Domain) = strUpper(bbsCfg.NetDomain[Count])) and + (EchoNode.Address.Zone = bbsCfg.NetAddress[Count].Zone) and + (bbsCfg.NetPrimary[Count]) Then Begin Result := True; Exit; @@ -794,9 +820,9 @@ End; Function GetFTNOutPath (EchoNode: RecEchoMailNode) : String; Begin; If IsFTNPrimary(EchoNode) Then - Result := bbsConfig.OutboundPath + Result := bbsCfg.OutboundPath Else - Result := DirLast(bbsConfig.OutboundPath) + strLower(EchoNode.Domain + '.' + strPadL(strI2H(EchoNode.Address.Zone, 3), 3, '0')) + PathChar; + Result := DirLast(bbsCfg.OutboundPath) + strLower(EchoNode.Domain + '.' + strPadL(strI2H(EchoNode.Address.Zone, 3), 3, '0')) + PathChar; If EchoNode.Address.Point <> 0 Then Result := Result + strI2H((EchoNode.Address.Net SHL 16) OR EchoNode.Address.Node, 8) + '.pnt' + PathChar; @@ -909,7 +935,7 @@ Var F : File; Begin Queue := TProtocolQueue.Create; - BinkP := TBinkP.Create (Server, Client, Queue, False, bbsConfig.inetBINKPTimeOut); + BinkP := TBinkP.Create (Server, Client, Queue, False, bbsCfg.inetBINKPTimeOut); BinkP.StatusUpdate := @Status; @@ -923,7 +949,7 @@ Begin QueueByNode(Queue, False, BinkP.EchoNode); - Server.Status (ProcessID, 'Queued ' + strI2S(Queue.QSize - Before) + ' files for ' + strAddr2Str(BinkP.EchoNode.Address)); + Server.Status (ProcessID, 'Queued ' + strI2S(Queue.QSize - Before) + ' files for ' + Addr2Str(BinkP.EchoNode.Address)); End; End; @@ -931,7 +957,7 @@ Begin BinkP.DoTransfers; If BinkP.RcvdFiles > 0 Then Begin - Assign (F, bbsConfig.SemaPath + 'echomail.in'); + Assign (F, bbsCfg.SemaPath + fn_SemFileEchoIn); ReWrite (F, 1); Close (F); End; diff --git a/mystic/mis_client_ftp.pas b/mystic/mis_client_ftp.pas index 32ed8b1..8c138ee 100644 --- a/mystic/mis_client_ftp.pas +++ b/mystic/mis_client_ftp.pas @@ -151,7 +151,7 @@ Begin Password := ''; UserPos := -1; DataIP := ''; - DataPort := Random(bbsConfig.inetFTPPortMax - bbsConfig.inetFTPPortMin) + bbsConfig.inetFTPPortMin; + DataPort := Random(bbsCfg.inetFTPPortMax - bbsCfg.inetFTPPortMin) + bbsCfg.inetFTPPortMin; DataSocket := NIL; IsPassive := False; FBasePos := -1; @@ -166,7 +166,7 @@ Var UserFile : File of RecUser; Begin // change to getuserbypos - Assign (UserFile, bbsConfig.DataPath + 'users.dat'); + Assign (UserFile, bbsCfg.DataPath + 'users.dat'); ioReset (UserFile, SizeOf(RecUser), fmRWDW); ioSeek (UserFile, UserPos - 1); ioRead (UserFile, User); @@ -189,7 +189,7 @@ Begin Inc (User.DLk, FDir.Size DIV 1024); Inc (User.DLkToday, FDir.Size DIV 1024); - Assign (FDirFile, bbsConfig.DataPath + TFBase.FileName + '.dir'); + Assign (FDirFile, bbsCfg.DataPath + TFBase.FileName + '.dir'); ioReset (FDirFile, SizeOf(RecFileList), fmRWDW); ioSeek (FDirFile, DirPos - 1); ioWrite (FDirFile, FDir); @@ -200,7 +200,7 @@ Begin ioWrite (UserFile, User); Close (UserFile); - Assign (HistFile, bbsConfig.DataPath + 'history.dat'); + Assign (HistFile, bbsCfg.DataPath + 'history.dat'); ioReset (HistFile, SizeOf(RecHistory), fmRWDW); If IoResult <> 0 Then ReWrite(HistFile); @@ -248,8 +248,8 @@ Begin If FDir.Flags And FDirOffline <> 0 Then Exit; - If (FDir.Flags And FDirInvalid <> 0) And Not CheckAccess(User, True, bbsConfig.AcsDLUnvalid) Then Exit; - If (FDir.Flags And FDirFailed <> 0) And Not CheckAccess(User, True, bbsConfig.AcsDLFailed) Then Exit; + If (FDir.Flags And FDirInvalid <> 0) And Not CheckAccess(User, True, bbsCfg.AcsDLUnvalid) Then Exit; + If (FDir.Flags And FDirFailed <> 0) And Not CheckAccess(User, True, bbsCfg.AcsDLFailed) Then Exit; If (FDir.Flags And FDirFree <> 0) or (User.Flags and UserNoRatio <> 0) or (TempFBase.Flags and FBFreeFiles <> 0) Then Begin Result := 0; @@ -302,7 +302,7 @@ Begin WaitSock.FTelnetServer := False; WaitSock.FTelnetClient := False; - WaitSock.WaitInit(bbsConfig.inetInterface, DataPort); + WaitSock.WaitInit(bbsCfg.inetInterface, DataPort); DataSocket := WaitSock.WaitConnection(10000); @@ -372,7 +372,7 @@ Begin FBaseFile := TFileBuffer.Create(FileBufSize); - If FBaseFile.OpenStream (bbsConfig.DataPath + 'fbases.dat', SizeOf(TempBase), fmOpen, fmRWDN) Then Begin + If FBaseFile.OpenStream (bbsCfg.DataPath + 'fbases.dat', SizeOf(TempBase), fmOpen, fmRWDN) Then Begin Found := False; While Not FBaseFile.EOF Do Begin @@ -605,7 +605,7 @@ Procedure TFTPServer.cmdREIN; Begin ResetSession; - If Not Client.WriteFile('220', bbsConfig.DataPath + 'ftpbanner.txt') Then + If Not Client.WriteFile('220', bbsCfg.DataPath + 'ftpbanner.txt') Then Client.WriteLine (re_Greeting); End; @@ -636,12 +636,12 @@ Procedure TFTPServer.cmdPASV; // WaitSock : TIOSocket; Begin If LoggedIn Then Begin - If Not bbsConfig.inetFTPPassive Then Begin + If Not bbsCfg.inetFTPPassive Then Begin Client.WriteLine(re_BadCommand); Exit; End; - DataPort := Random(bbsConfig.inetFTPPortMax - bbsConfig.inetFTPPortMin) + bbsConfig.inetFTPPortMin; + DataPort := Random(bbsCfg.inetFTPPortMax - bbsCfg.inetFTPPortMin) + bbsCfg.inetFTPPortMin; {$IFDEF FTPDEBUG} LOG('PASV on host ' + Client.HostIP + ' port ' + strI2S(DataPort)); @@ -660,7 +660,7 @@ Begin {$IFDEF FTPDEBUG} LOG('PASV Init'); {$ENDIF} - WaitSock.WaitInit(bbsConfig.inetInterface, DataPort); + WaitSock.WaitInit(bbsCfg.inetInterface, DataPort); {$IFDEF FTPDEBUG} LOG('PASV Wait'); {$ENDIF} @@ -738,13 +738,13 @@ Begin DirFile := TFileBuffer.Create(FileBufSize); - If DirFile.OpenStream (bbsConfig.DataPath + TempBase.FileName + '.dir', SizeOf(RecFileList), fmOpenCreate, fmRWDN) Then Begin + If DirFile.OpenStream (bbsCfg.DataPath + TempBase.FileName + '.dir', SizeOf(RecFileList), fmOpenCreate, fmRWDN) Then Begin While Not DirFile.EOF Do Begin DirFile.ReadRecord (Dir); If (Dir.Flags And FDirDeleted <> 0) Then Continue; - If (Dir.Flags And FDirInvalid <> 0) And (Not CheckAccess(User, True, bbsConfig.AcsSeeUnvalid)) Then Continue; - If (Dir.Flags And FDirFailed <> 0) And (Not CheckAccess(User, True, bbsConfig.AcsSeeFailed)) Then Continue; + If (Dir.Flags And FDirInvalid <> 0) And (Not CheckAccess(User, True, bbsCfg.AcsSeeUnvalid)) Then Continue; + If (Dir.Flags And FDirFailed <> 0) And (Not CheckAccess(User, True, bbsCfg.AcsSeeFailed)) Then Continue; If WildMatch(FileMask, Dir.FileName, False) Then DataSocket.WriteLine(Dir.FileName); @@ -796,7 +796,7 @@ Begin FBaseFile := TFileBuffer.Create(FileBufSize); - If FBaseFile.OpenStream (bbsConfig.DataPath + 'fbases.dat', SizeOf(RecFileBase), fmOpen, fmRWDN) Then Begin + If FBaseFile.OpenStream (bbsCfg.DataPath + 'fbases.dat', SizeOf(RecFileBase), fmOpen, fmRWDN) Then Begin While Not FBaseFile.EOF Do Begin FBaseFile.ReadRecord (TempBase); @@ -822,14 +822,14 @@ Begin DirFile := TFileBuffer.Create(FileBufSize); - If DirFile.OpenStream (bbsConfig.DataPath + TempBase.FileName + '.dir', SizeOf(RecFileList), fmOpenCreate, fmRWDN) Then Begin + If DirFile.OpenStream (bbsCfg.DataPath + TempBase.FileName + '.dir', SizeOf(RecFileList), fmOpenCreate, fmRWDN) Then Begin While Not DirFile.EOF Do Begin DirFile.ReadRecord (Dir); If (Dir.Flags And FDirDeleted <> 0) Then Continue; - If (Dir.Flags and FDirOffline <> 0) And (Not CheckAccess(User, True, bbsConfig.AcsSeeOffline)) Then Continue; - If (Dir.Flags And FDirInvalid <> 0) And (Not CheckAccess(User, True, bbsConfig.AcsSeeUnvalid)) Then Continue; - If (Dir.Flags And FDirFailed <> 0) And (Not CheckAccess(User, True, bbsConfig.AcsSeeFailed)) Then Continue; + If (Dir.Flags and FDirOffline <> 0) And (Not CheckAccess(User, True, bbsCfg.AcsSeeOffline)) Then Continue; + If (Dir.Flags And FDirInvalid <> 0) And (Not CheckAccess(User, True, bbsCfg.AcsSeeUnvalid)) Then Continue; + If (Dir.Flags And FDirFailed <> 0) And (Not CheckAccess(User, True, bbsCfg.AcsSeeFailed)) Then Continue; If WildMatch(FileMask, Dir.FileName, False) Then DataSocket.WriteLine('-rw-r--r-- 1 ftp ftp ' + strPadL(strI2S(Dir.Size), 13, ' ') + ' ' + GetFTPDate(Dir.DateTime) + ' ' + Dir.FileName) @@ -1024,7 +1024,7 @@ Begin DirFile := TFileBuffer.Create(FileBufSize); Found := -1; - If DirFile.OpenStream (bbsConfig.DataPath + TempBase.FileName + '.dir', SizeOf(RecFileList), fmOpenCreate, fmRWDN) Then Begin + If DirFile.OpenStream (bbsCfg.DataPath + TempBase.FileName + '.dir', SizeOf(RecFileList), fmOpenCreate, fmRWDN) Then Begin While Not DirFile.EOF Do Begin DirFile.ReadRecord (Dir); @@ -1109,14 +1109,14 @@ Var Begin If LoggedIn Then Begin If Data = '' Then Begin - DataPort := Random(bbsConfig.inetFTPPortMax - bbsConfig.inetFTPPortMin) + bbsConfig.inetFTPPortMin; + DataPort := Random(bbsCfg.inetFTPPortMax - bbsCfg.inetFTPPortMin) + bbsCfg.inetFTPPortMin; IsPassive := True; Client.WriteLine('229 Entering Extended Passive Mode (|||' + strI2S(DataPort) + '|)'); WaitSock := TIOSocket.Create; - WaitSock.WaitInit(bbsConfig.inetInterface, DataPort); + WaitSock.WaitInit(bbsCfg.inetInterface, DataPort); DataSocket := WaitSock.WaitConnection(10000); @@ -1151,7 +1151,7 @@ Begin Repeat {$IFDEF FTPDEBUG} LOG('Execute loop'); {$ENDIF} - If Client.WaitForData(bbsConfig.inetFTPTimeout * 1000) = 0 Then Break; + If Client.WaitForData(bbsCfg.inetFTPTimeout * 1000) = 0 Then Break; If Terminated Then Exit; diff --git a/mystic/mis_client_nntp.pas b/mystic/mis_client_nntp.pas index bd5f7c8..85165ad 100644 --- a/mystic/mis_client_nntp.pas +++ b/mystic/mis_client_nntp.pas @@ -172,7 +172,7 @@ Begin MBaseFile := TFileBuffer.Create(FileReadBuffer); - If MBaseFile.OpenStream (bbsConfig.DataPath + 'mbases.dat', SizeOf(TempBase), fmOpen, fmRWDN) Then Begin + If MBaseFile.OpenStream (bbsCfg.DataPath + 'mbases.dat', SizeOf(TempBase), fmOpen, fmRWDN) Then Begin MBaseFile.ReadRecord (TempBase); While Not MBaseFile.EOF Do Begin @@ -237,7 +237,7 @@ Begin MBaseFile := TFileBuffer.Create(FileReadBuffer); - If MBaseFile.OpenStream (bbsConfig.DataPath + 'mbases.dat', SizeOf(TempBase), fmOpen, fmRWDN) Then Begin + If MBaseFile.OpenStream (bbsCfg.DataPath + 'mbases.dat', SizeOf(TempBase), fmOpen, fmRWDN) Then Begin MBaseFile.ReadRecord (TempBase); While Not MBaseFile.EOF Do Begin @@ -359,7 +359,7 @@ Begin Found := False; MBaseFile := TBufFile.Create(FileReadBuffer); - If MBaseFile.Open(bbsConfig.DataPath + 'mbases.dat', fmOpen, fmRWDN, SizeOf(RecMessageBase)) Then Begin + If MBaseFile.Open(bbsCfg.DataPath + 'mbases.dat', fmOpen, fmRWDN, SizeOf(RecMessageBase)) Then Begin MBaseFile.Read(TempBase); While Not MBaseFile.EOF Do Begin @@ -430,8 +430,8 @@ Begin MsgBase^.SetMailType(mmtEchoMail); Case TempBase.NetType of - 1 : Assign (SemFile, bbsConfig.SemaPath + fn_SemFileEcho); - 2 : Assign (SemFile, bbsConfig.SemaPath + fn_SemFileNews); + 1 : Assign (SemFile, bbsCfg.SemaPath + fn_SemFileEcho); + 2 : Assign (SemFile, bbsCfg.SemaPath + fn_SemFileNews); End; ReWrite (SemFile); @@ -547,7 +547,7 @@ Begin // ignore groups and check postacs in loop instead of below? - Assign (MBaseFile, bbsConfig.DataPath + 'mbases.dat'); + Assign (MBaseFile, bbsCfg.DataPath + 'mbases.dat'); If ioReset(MBaseFile, SizeOf(RecMessageBase), fmRWDN) Then Begin ioRead (MBaseFile, TempBase); @@ -785,7 +785,7 @@ Begin ClientWriteLine(re_Greeting); Repeat - If Client.WaitForData(bbsConfig.inetNNTPTimeout * 1000) = 0 Then Break; + If Client.WaitForData(bbsCfg.inetNNTPTimeout * 1000) = 0 Then Break; If Terminated Then Exit; diff --git a/mystic/mis_client_pop3.pas b/mystic/mis_client_pop3.pas index fc9a3e6..8ba977d 100644 --- a/mystic/mis_client_pop3.pas +++ b/mystic/mis_client_pop3.pas @@ -1,7 +1,7 @@ -{$I M_OPS.PAS} - Unit MIS_Client_POP3; +{$I M_OPS.PAS} + // RFC 1939 // optional TOP and APOP not implemented // needs to reformat long messages > 79 chars? @@ -23,7 +23,8 @@ Uses BBS_MsgBase_ABS, BBS_MsgBase_JAM, BBS_MsgBase_Squish, - BBS_Records; + BBS_Records, + BBS_DataBase; Function CreatePOP3 (Owner: TServerManager; Config: RecConfig; ND: TNodeData; CliSock: TIOSocket) : TServerClient; @@ -181,7 +182,7 @@ Var End; Begin - Assign (MBaseFile, bbsConfig.DataPath + 'mbases.dat'); + Assign (MBaseFile, bbsCfg.DataPath + 'mbases.dat'); If Not ioReset(MBaseFile, SizeOf(RecMessageBase), fmRWDN) Then Exit; @@ -216,9 +217,9 @@ Begin MailInfo[MailSize].Text := TStringList.Create; AddLine ('Date: ' + ParseDateTime(MsgBase^.GetDate, MsgBase^.GetTime)); - AddLine ('From: ' + MsgBase^.GetFrom + ' <' + strReplace(MsgBase^.GetFrom, ' ', '_') + '@' + bbsConfig.inetDomain + '>'); + AddLine ('From: ' + MsgBase^.GetFrom + ' <' + strReplace(MsgBase^.GetFrom, ' ', '_') + '@' + bbsCfg.inetDomain + '>'); AddLine ('X-Mailer: Mystic BBS ' + mysVersion); - AddLine ('To: ' + MsgBase^.GetTo + ' <' + strReplace(MsgBase^.GetTo, ' ', '_') + '@' + bbsConfig.inetDomain + '>'); + AddLine ('To: ' + MsgBase^.GetTo + ' <' + strReplace(MsgBase^.GetTo, ' ', '_') + '@' + bbsCfg.inetDomain + '>'); AddLine ('Subject: ' + MsgBase^.GetSubj); AddLine ('Content-Type: text/plain; charset=us-ascii'); AddLine (''); @@ -246,7 +247,7 @@ Var MBase : RecMessageBase; MsgBase : PMsgBaseABS; Begin - Assign (MBaseFile, bbsConfig.DataPath + 'mbases.dat'); + Assign (MBaseFile, bbsCfg.DataPath + 'mbases.dat'); If Not ioReset(MBaseFile, SizeOf(RecMessageBase), fmRWDN) Then Exit; @@ -267,7 +268,7 @@ Begin End; For Count := 1 to MailSize Do Begin - If MailInfo[Count].Deleted or (MailInfo[Count].GotRETR and bbsConfig.inetPOP3Delete) Then Begin + If MailInfo[Count].Deleted or (MailInfo[Count].GotRETR and bbsCfg.inetPOP3Delete) Then Begin MsgBase^.SeekFirst(1); While MsgBase^.SeekFound Do Begin @@ -457,7 +458,7 @@ Begin Client.WriteLine(re_Greeting); Repeat - If Client.WaitForData(bbsConfig.inetPOP3TimeOut * 1000) = 0 Then Break; + If Client.WaitForData(bbsCfg.inetPOP3TimeOut * 1000) = 0 Then Break; If Terminated Then Exit; diff --git a/mystic/mis_client_smtp.pas b/mystic/mis_client_smtp.pas index 493b261..da98413 100644 --- a/mystic/mis_client_smtp.pas +++ b/mystic/mis_client_smtp.pas @@ -21,7 +21,8 @@ Uses MIS_Server, MIS_NodeData, MIS_Common, - BBS_Records; + BBS_Records, + BBS_DataBase; Function CreateSMTP (Owner: TServerManager; Config: RecConfig; ND: TNodeData; CliSock: TIOSocket) : TServerClient; @@ -89,7 +90,7 @@ Begin If IsFrom Then Server.Status(ProcessID, 'User: ' + InName + ' Domain: ' + InDomain); - If InDomain <> bbsConfig.iNetDomain Then Begin + If InDomain <> bbsCfg.iNetDomain Then Begin Server.Status(ProcessID, 'Refused by domain: ' + InName + '@' + InDomain); Exit; End; @@ -114,7 +115,7 @@ End; Procedure TSMTPServer.cmdHELO; Begin - Client.WriteLine('250 ' + bbsConfig.inetDomain); + Client.WriteLine('250 ' + bbsCfg.inetDomain); End; Procedure TSMTPServer.cmdRSET; @@ -209,7 +210,7 @@ Begin MsgText.Add(InData); Until False; - Assign (MBaseFile, bbsConfig.DataPath + 'mbases.dat'); + Assign (MBaseFile, bbsCfg.DataPath + 'mbases.dat'); ioReset (MBaseFile, SizeOf(RecMessageBase), fmRWDN); ioRead (MBaseFile, MBase); Close (MBaseFile); @@ -295,10 +296,10 @@ Var Begin ResetSession; - Client.WriteLine('220 ' + bbsConfig.iNetDomain + ' Mystic SMTP Ready'); + Client.WriteLine('220 ' + bbsCfg.iNetDomain + ' Mystic SMTP Ready'); Repeat - If Client.WaitForData(bbsConfig.inetSMTPTimeout * 1000) = 0 Then Break; + If Client.WaitForData(bbsCfg.inetSMTPTimeout * 1000) = 0 Then Break; If Terminated Then Exit; diff --git a/mystic/mis_client_telnet.pas b/mystic/mis_client_telnet.pas index cbe494c..a8786cb 100644 --- a/mystic/mis_client_telnet.pas +++ b/mystic/mis_client_telnet.pas @@ -40,7 +40,8 @@ Uses MIS_Common, MIS_NodeData, MIS_Server, - BBS_Records; + BBS_Records, + BBS_DataBase; {$IFDEF USEFORK} function forkpty(__amaster:Plongint; __name:Pchar; __termp:Pointer; __winp:Pointer):longint;cdecl;external 'c' name 'forkpty'; @@ -108,7 +109,7 @@ Begin SI.dwFlags := STARTF_USESHOWWINDOW; - If bbsConfig.inetTNHidden Then + If bbsCfg.inetTNHidden Then SI.wShowWindow := SW_HIDE Else SI.wShowWindow := SW_SHOWMINNOACTIVE; @@ -124,7 +125,7 @@ Begin ND.SetNodeInfo(Num, NI); - FileErase (bbsConfig.DataPath + 'chat' + strI2S(Num) + '.dat'); + FileErase (bbsCfg.DataPath + 'chat' + strI2S(Num) + '.dat'); End; {$ENDIF} diff --git a/mystic/mis_common.pas b/mystic/mis_common.pas index a54acc0..f7d53b4 100644 --- a/mystic/mis_common.pas +++ b/mystic/mis_common.pas @@ -6,19 +6,18 @@ Interface Uses m_Output, - m_Term_Ansi, - BBS_Records; +// m_Term_Ansi, + BBS_Records, + BBS_DataBase; Var - TempPath : String; -// Console : TOutput; - Term : TTermAnsi; - bbsConfig : RecConfig; + TempPath : String; +// Term : TTermAnsi; Function SearchForUser (UN: String; Var Rec: RecUser; Var RecPos: LongInt) : Boolean; Function CheckAccess (User: RecUser; IgnoreGroup: Boolean; Str: String) : Boolean; Function GetSecurityLevel (Level: Byte; SecLevel: RecSecurity) : Boolean; -Function strAddr2Str (Addr : RecEchoMailAddr) : String; +//Function strAddr2Str (Addr : RecEchoMailAddr) : String; Implementation @@ -38,7 +37,7 @@ Begin UserFile := TFileBuffer.Create (8 * 1024); - If UserFile.OpenStream (bbsConfig.DataPath + 'users.dat', SizeOf(RecUser), fmOpen, fmRWDN) Then + If UserFile.OpenStream (bbsCfg.DataPath + 'users.dat', SizeOf(RecUser), fmOpen, fmRWDN) Then While Not UserFile.EOF Do Begin UserFile.ReadRecord (Rec); @@ -203,7 +202,7 @@ Var Begin Result := False; - Assign (SecLevelFile, bbsConfig.DataPath + 'security.dat'); + Assign (SecLevelFile, bbsCfg.DataPath + 'security.dat'); If Not ioReset (SecLevelFile, SizeOf(SecLevel), fmRWDN) Then Exit; @@ -214,6 +213,7 @@ Begin Result := True; End; +(* Function strAddr2Str (Addr : RecEchoMailAddr) : String; Var Temp : String[20]; @@ -225,5 +225,5 @@ Begin Result := Temp; End; - +*) End. diff --git a/mystic/mis_nodedata.pas b/mystic/mis_nodedata.pas index 8b6b471..f8210a2 100644 --- a/mystic/mis_nodedata.pas +++ b/mystic/mis_nodedata.pas @@ -7,6 +7,7 @@ Unit MIS_NodeData; Interface Uses + BBS_DataBase, MIS_Common; Type @@ -50,7 +51,7 @@ Begin For Count := 1 to NodeTotal Do Begin GetNodeInfo (Count, NI); - Assign (ChatFile, bbsConfig.DataPath + 'chat' + strI2S(NI.Num) + '.dat'); + Assign (ChatFile, bbsCfg.DataPath + 'chat' + strI2S(NI.Num) + '.dat'); If ioReset(ChatFile, SizeOf(ChatRec), fmRWDN) Then Begin ioRead (ChatFile, Chat); diff --git a/mystic/mutil_echoexport.pas b/mystic/mutil_echoexport.pas index a553f3c..f2e3108 100644 --- a/mystic/mutil_echoexport.pas +++ b/mystic/mutil_echoexport.pas @@ -271,19 +271,21 @@ Var While Not MsgBase^.EOM Do WriteStr (MsgBase^.GetString(79), #13); - // SEEN-BY needs to include yourself and ANYTHING it is sent to (downlinks) - // so we need to cycle through nodes for this mbase and add ALL of them + If MBase.NetType <> 3 Then Begin + // SEEN-BY needs to include yourself and ANYTHING it is sent to (downlinks) + // so we need to cycle through nodes for this mbase and add ALL of them - TempStr1 := 'SEEN-BY: ' + strI2S(MsgBase^.GetOrigAddr.Net) + '/' + strI2S(MsgBase^.GetOrigAddr.Node) + ' '; + TempStr1 := 'SEEN-BY: ' + strI2S(MsgBase^.GetOrigAddr.Net) + '/' + strI2S(MsgBase^.GetOrigAddr.Node) + ' '; - If MsgBase^.GetOrigAddr.Net <> EchoNode.Address.Net Then - TempStr1 := TempStr1 + strI2S(EchoNode.Address.Net) + '/'; + If MsgBase^.GetOrigAddr.Net <> EchoNode.Address.Net Then + TempStr1 := TempStr1 + strI2S(EchoNode.Address.Net) + '/'; - TempStr1 := TempStr1 + strI2S(EchoNode.Address.Node); + TempStr1 := TempStr1 + strI2S(EchoNode.Address.Node); - WriteStr (TempStr1, #13); - WriteStr (#1 + 'PATH: ' + strI2S(MsgBase^.GetOrigAddr.Net) + '/' + strI2S(MsgBase^.GetOrigAddr.Node), #13); - WriteStr (#0#0, #0); + WriteStr (TempStr1, #13); + WriteStr (#1 + 'PATH: ' + strI2S(MsgBase^.GetOrigAddr.Net) + '/' + strI2S(MsgBase^.GetOrigAddr.Node), #13); + WriteStr (#0#0, #0); + End; Close (F); End; @@ -381,4 +383,4 @@ Begin FileErase (bbsCfg.SemaPath + fn_SemFileEchoOut); End; -End. \ No newline at end of file +End. diff --git a/mystic/whatsnew.txt b/mystic/whatsnew.txt index 6c71b4a..e760c39 100644 --- a/mystic/whatsnew.txt +++ b/mystic/whatsnew.txt @@ -3770,8 +3770,8 @@ process each PKT or bundle in order. + When tossing an ECHOMAIL bundle, Mystic will now extract the bundle and - then sort the contents of the bundle by filedate and secondly by filename - and process each PKT in the sorted order. + then sort the contents of the bundle by filedate and secondly by filename, + then process each PKT in the sorted order. + The message base editor now has a new function /R (Reset messages). This will take a single base or a selection of tagged bases and remove ALL @@ -3787,4 +3787,17 @@ the header and INTL kludge. This could cause tossers to not correctly reroute netmail to the correct destination. + ! Fixed a bug in BINKP protocol on the client side where the client was not + sending the proper SKIP filesize back to the server. With BINKD this + could cause the BINKD server to just wait until the session times out + instead of sending EOB. + + + FIDOPOLL can now poll a single node by the address. IE: + fidopoll 46:1/100 + + + FIDOPOLL now logs to "fidopoll.log" in the logs directory. + + ! SEEN-BY and PATH kludge lines are no longer added to exported netmail + messages. +