diff --git a/mystic/bbs_cfg_archive.pas b/mystic/bbs_cfg_archive.pas index 185baad..232a37a 100644 --- a/mystic/bbs_cfg_archive.pas +++ b/mystic/bbs_cfg_archive.pas @@ -74,6 +74,7 @@ Var 1 : OS := 'Linux '; 2 : OS := 'OSX '; 3 : OS := 'All '; + 4 : OS := 'OS/2 '; End; List.Add (strPadR(YesNoStr[Arc.Active], 5, ' ') + strPadR(Arc.Ext, 7, ' ') + OS + ' ' + Arc.Desc, 0); diff --git a/mystic/bbs_cfg_echomail.pas b/mystic/bbs_cfg_echomail.pas index b083dd1..12d7b10 100644 --- a/mystic/bbs_cfg_echomail.pas +++ b/mystic/bbs_cfg_echomail.pas @@ -157,7 +157,7 @@ Begin Form.AddStr ('D', ' Description' , 6, 7, 21, 7, 13, 23, 35, @Node.Description, Topic + 'Node description'); Form.AddBol ('A', ' Active' , 11, 8, 21, 8, 8, 3, @Node.Active, Topic + 'Is node active?'); Form.AddStr ('R', ' Archive Type' , 5, 9, 21, 9, 14, 4, 4, @Node.ArcType, Topic + 'Archive type for packets'); - Form.AddTog ('E', ' Network Type' , 5, 10, 21, 10, 14, 7, 0, 1, 'FidoNet QWK', @Node.NetType, Topic); +// Form.AddTog ('E', ' Network Type' , 5, 10, 21, 10, 14, 7, 0, 1, 'FidoNet QWK', @Node.NetType, Topic); Form.AddTog ('L', ' Session Type' , 5, 11, 21, 11, 14, 5, 0, 1, 'BinkP FTP', @Node.ProtType, Topic); Form.AddTog ('Y', ' Export Type' , 6, 12, 21, 12, 13, 6, 0, 3, 'Normal Crash Direct Hold', @Node.MailType, Topic); Form.AddStr ('W', ' *Fix Password', 4, 13, 21, 13, 15, 20, 20, @Node.AreaFixPass, Topic + 'Password required for Area/FileFix'); diff --git a/mystic/bbs_cfg_filebase.pas b/mystic/bbs_cfg_filebase.pas index 96920f8..9251d17 100644 --- a/mystic/bbs_cfg_filebase.pas +++ b/mystic/bbs_cfg_filebase.pas @@ -200,6 +200,9 @@ Var Write (FBaseFile, FBase); End; +Var + KillData : Boolean; + Count : LongInt; Begin Assign (FBaseFile, bbsCfg.DataPath + 'fbases.dat'); @@ -235,7 +238,28 @@ Begin InsertRecord; MakeList; End; - 'D' : If (List.Picked < List.ListMax) Then + 'D' : If List.Marked > 0 Then Begin + If ShowMsgBox(1, 'Delete ' + strI2S(List.Marked) + ' bases?') Then Begin + KillData := ShowMsgBox(1, 'Delete data files for ' + strI2S(List.Marked) + ' bases?'); + + For Count := List.ListMax DownTo 1 Do + If List.List[Count].Tagged = 1 Then Begin + Seek (FBaseFile, Count - 1); + Read (FBaseFile, FBase); + + KillRecord (FBaseFile, Count, SizeOf(FBase)); + + If KillData Then Begin + FileErase (bbsCfg.DataPath + FBase.FileName + '.dir'); + FileErase (bbsCfg.DataPath + FBase.FileName + '.dat'); + FileErase (bbsCfg.DataPath + FBase.FileName + '.scn'); + End; + End; + + MakeList; + End; + End Else + If (List.Picked < List.ListMax) Then If ShowMsgBox(1, 'Delete this entry?') Then Begin Seek (FBaseFile, List.Picked - 1); Read (FBaseFile, FBase); diff --git a/mystic/bbs_cfg_main.pas b/mystic/bbs_cfg_main.pas index a65b2bf..19985d5 100644 --- a/mystic/bbs_cfg_main.pas +++ b/mystic/bbs_cfg_main.pas @@ -159,7 +159,7 @@ Begin End; End; 1 : Begin - BoxOpen (4, 4, 33, 17); + BoxOpen (4, 4, 33, 18); CoolBoxOpen (3, 'Configuration'); Form.AddNone ('S', ' S System Paths', 5, 5, 5, 5, 28, ''); @@ -172,8 +172,9 @@ Begin Form.AddNone ('M', ' M Message Base Settings', 5, 12, 5, 12, 28, ''); Form.AddNone ('E', ' E EchoMail Addresses', 5, 13, 5, 13, 28, ''); Form.AddNone ('N', ' N EchoMail Nodes', 5, 14, 5, 14, 28, ''); - Form.AddNone ('O', ' O Offline Mail Settings', 5, 15, 5, 15, 28, ''); - Form.AddNone ('C', ' C Console Settings', 5, 16, 5, 16, 28, ''); + Form.AddNone ('Q', ' Q QWK Networking', 5, 15, 5, 15, 28, ''); + Form.AddNone ('O', ' O Local QWK Settings', 5, 16, 5, 16, 28, ''); + Form.AddNone ('C', ' C Console Settings', 5, 17, 5, 17, 28, ''); Res := Form.Execute; MenuPos[1] := Form.ItemPos; @@ -205,7 +206,7 @@ Begin End; End; 2 : Begin - BoxOpen (25, 4, 53, 13); + BoxOpen (25, 4, 53, 12); CoolBoxOpen (24, 'Servers'); Form.AddNone ('I', ' I Internet Server Options', 26, 5, 26, 5, 27, ''); diff --git a/mystic/bbs_cfg_protocol.pas b/mystic/bbs_cfg_protocol.pas index 5407c12..1c2ec3a 100644 --- a/mystic/bbs_cfg_protocol.pas +++ b/mystic/bbs_cfg_protocol.pas @@ -74,6 +74,7 @@ Var 1 : OS := 'Linux '; 2 : OS := 'OSX'; 3 : OS := 'All'; + 4 : OS := 'OS/2'; End; //'Active OSID Batch Key Description'); diff --git a/mystic/bbs_cfg_syscfg.pas b/mystic/bbs_cfg_syscfg.pas index f6e38d3..2f9a973 100644 --- a/mystic/bbs_cfg_syscfg.pas +++ b/mystic/bbs_cfg_syscfg.pas @@ -286,7 +286,7 @@ Begin Form.AddStr ('D', ' Domain', 23, 11, 33, 11, 8, 25, 25, @bbsCfg.inetDomain, Topic + 'Internet domain name'); Form.AddStr ('I', ' Interface', 20, 12, 33, 12, 11, 23, 23, @bbsCfg.inetInterface, Topic + 'Network interface IP address'); Form.AddBol ('B', ' IP Blocking', 18, 13, 33, 13, 13, 3, @bbsCfg.inetIPBlocking, Topic + 'Enable IP blocking'); - Form.AddBol ('L', ' Logging', 22, 14, 33, 14, 12, 3, @bbsCfg.inetLogging, Topic + 'Enable server logging'); + Form.AddBol ('L', ' Logging', 22, 14, 33, 14, 9, 3, @bbsCfg.inetLogging, Topic + 'Enable server logging'); Form.Execute; diff --git a/mystic/bbs_core.pas b/mystic/bbs_core.pas index 9f6b3fb..8e1a281 100644 --- a/mystic/bbs_core.pas +++ b/mystic/bbs_core.pas @@ -313,6 +313,7 @@ Function TBBSCore.TimeLeft : Integer; Begin If Not TimerOn Then Begin TimeLeft := 0; + Exit; End; diff --git a/mystic/bbs_database.pas b/mystic/bbs_database.pas index 10b16ff..5353aee 100644 --- a/mystic/bbs_database.pas +++ b/mystic/bbs_database.pas @@ -1,10 +1,17 @@ Unit BBS_DataBase; +// for all functions... need to go through code and remove old stuff and +// replace with this new stuff one at a time. including moving everything +// to bbscfg. + {$I M_OPS.PAS} Interface Uses + m_Types, + m_Output, + m_Input, BBS_Records, BBS_MsgBase_ABS, BBS_MsgBase_JAM, @@ -14,17 +21,22 @@ Var bbsCfg : RecConfig; bbsCfgPath : String; bbsCfgStatus : Byte; + Console : TOutput = NIL; + Keyboard : TInput = NIL; Const CfgOK = 0; CfgNotFound = 1; CfgMisMatch = 2; +Type + FileDescBuffer = Array[1..99] of String[50]; + // GENERAL Function GetBaseConfiguration (UseEnv: Boolean; Var TempCfg: RecConfig) : Byte; Function PutBaseConfiguration (Var TempCfg: RecConfig) : Boolean; -Function ShellDOS (ExecPath: String; Command: String) : LongInt; +Function ExecuteProgram (ExecPath: String; Command: String) : LongInt; Function Addr2Str (Addr : RecEchoMailAddr) : String; // MESSAGE BASE @@ -40,6 +52,8 @@ Procedure MBaseAssignData (Var User: RecUser; Var Msg: PMsgBaseABS; Var Te Procedure ExecuteArchive (TempP: String; FName: String; Temp: String; Mask: String; Mode: Byte); Function GetTotalFiles (Var TempBase: RecFileBase) : LongInt; +Function IsDuplicateFile (Base: RecFileBase; FileName: String; Global: Boolean) : Boolean; +Function ImportFileDIZ (Var Desc: FileDescBuffer; Var DescLines: Byte; TempP, FN: String) : Boolean; // USER @@ -174,10 +188,14 @@ Begin End; End; -Function ShellDOS (ExecPath: String; Command: String) : LongInt; +Function ExecuteProgram (ExecPath: String; Command: String) : LongInt; Var CurDIR : String; + Image : TConsoleImageRec; Begin + If Console <> NIL Then + Console.GetScreenImage(1, 1, 80, 25, Image); + GetDIR (0, CurDIR); If ExecPath <> '' Then DirChange(ExecPath); @@ -195,6 +213,9 @@ Begin {$ENDIF} DirChange(CurDIR); + + If Console <> NIL Then + Console.PutScreenImage(Image); End; Function GetMBaseByIndex (Num: LongInt; Var TempBase: RecMessageBase) : Boolean; @@ -412,7 +433,109 @@ Begin Inc (Count); End; - ShellDOS ('', Temp); + ExecuteProgram ('', Temp); +End; + +Function IsDuplicateFile (Base: RecFileBase; FileName: String; Global: Boolean) : Boolean; + + Procedure CheckOneArea; + Var + TempFile : TFileBuffer; + Temp : RecFileList; + Begin + TempFile := TFileBuffer.Create(8 * 1024); + + If Not TempFile.OpenStream (bbsCfg.DataPath + Base.FileName + '.dir', SizeOf(RecFileList), fmOpen, fmRWDN) Then Begin + TempFile.Free; + + Exit; + End; + + While Not TempFile.EOF Do Begin + TempFile.ReadRecord(Temp); + + {$IFDEF FS_SENSITIVE} + If (Temp.FileName = FileName) And (Temp.Flags And FDirDeleted = 0) Then Begin + {$ELSE} + If (strUpper(Temp.FileName) = strUpper(FileName)) And (Temp.Flags And FDirDeleted = 0) Then Begin + {$ENDIF} + Result := True; + + Break; + End; + End; + + TempFile.Free; + End; + +Var + BaseFile : File; +Begin + Result := False; + + If Global Then Begin + Assign (BaseFile, bbsCfg.DataPath + 'fbases.dat'); + + If ioReset (BaseFile, SizeOf(RecFileBase), fmRWDN) Then Begin + While Not EOF(BaseFile) And Not Result Do Begin + ioRead (BaseFile, Base); + + CheckOneArea; + End; + + Close (BaseFile); + End; + End Else + CheckOneArea; +End; + +Function ImportFileDIZ (Var Desc: FileDescBuffer; Var DescLines: Byte; TempP, FN: String) : Boolean; + + Procedure RemoveLine (Num: Byte); + Var + Count : Byte; + Begin + For Count := Num To DescLines - 1 Do + Desc[Count] := Desc[Count + 1]; + + Desc[DescLines] := ''; + + Dec (DescLines); + End; + +Var + DizFile : Text; +Begin + Result := False; + DescLines := 0; + + ExecuteArchive (TempP, FN, '', 'file_id.diz', 2); + + Assign (DizFile, FileFind(TempP + 'file_id.diz')); + + {$I-} Reset (DizFile); {$I+} + + If IoResult = 0 Then Begin + While Not Eof(DizFile) Do Begin + Inc (DescLines); + ReadLn (DizFile, Desc[DescLines]); + + Desc[DescLines] := strStripLow(Desc[DescLines]); + + If DescLines = bbsCfg.MaxFileDesc Then Break; + End; + + Close (DizFile); + Erase (DizFile); + + While (Desc[1] = '') and (DescLines > 0) Do + RemoveLine(1); + + While (Desc[DescLines] = '') And (DescLines > 0) Do + Dec (DescLines); + + Result := True; + End; End; Initialization diff --git a/mystic/mis.pas b/mystic/mis.pas index 643122e..5e8520d 100644 --- a/mystic/mis.pas +++ b/mystic/mis.pas @@ -50,7 +50,8 @@ Uses MIS_Client_FTP, MIS_Client_NNTP, MIS_Client_BINKP, - BBS_Records; + BBS_Records, + BBS_DataBase; Const FocusTelnet = 0; diff --git a/mystic/mis_client_binkp.pas b/mystic/mis_client_binkp.pas index 56b0fab..599e923 100644 --- a/mystic/mis_client_binkp.pas +++ b/mystic/mis_client_binkp.pas @@ -823,7 +823,7 @@ End; Procedure Status (Owner: Pointer; Str: String); Begin - TServerManager(Owner).Status(Str); + TServerManager(Owner).Status(-1, Str); End; Constructor TBINKPServer.Create (Owner: TServerManager; CliSock: TIOSocket); @@ -857,7 +857,7 @@ Begin QueueByNode(Queue, False, BinkP.EchoNode); - Server.Status ('Queued ' + strI2S(Queue.QSize - Before) + ' files for ' + strAddr2Str(BinkP.EchoNode.Address)); + Server.Status (ProcessID, 'Queued ' + strI2S(Queue.QSize - Before) + ' files for ' + strAddr2Str(BinkP.EchoNode.Address)); End; End; diff --git a/mystic/mis_client_ftp.pas b/mystic/mis_client_ftp.pas index b65b0ed..c5bb2e3 100644 --- a/mystic/mis_client_ftp.pas +++ b/mystic/mis_client_ftp.pas @@ -447,7 +447,7 @@ Begin If Not OpenDataSession Then Exit; - Server.Status ('Receiving: ' + Str); + Server.Status (ProcessID, 'Receiving: ' + Str); InTransfer := True; Result := True; @@ -455,10 +455,10 @@ Begin Assign (F, Str); If FileExist(Str) And IsAppend Then Begin - Reset (F, 1); - Seek (F, FileSize(F)); + ioReset (F, 1, fmRWDW); + Seek (F, FileSize(F)); End Else Begin - ReWrite (F, 1); + ioReWrite (F, 1, fmRWDW); IsAppend := False; End; @@ -474,6 +474,8 @@ Begin Close (F); + Server.Status(ProcessID, 'Receive complete'); + If Result Then Client.WriteLine (re_XferOK); @@ -496,7 +498,7 @@ Begin OpenDataSession; - Server.Status('Sending: ' + Str); + Server.Status(ProcessID, 'Sending: ' + Str); While Not Eof(F) Do Begin BlockRead (F, Buf, SizeOf(Buf), Res); @@ -510,6 +512,8 @@ Begin Close (F); + Server.Status(ProcessID, 'Send complete'); + Client.WriteLine (re_XferOK); CloseDataSession; @@ -575,6 +579,7 @@ Begin If SearchForUser(Data, User, UserPos) Then Begin Client.WriteLine(re_UserOkay); + UserName := Data; End Else Client.WriteLine(re_UserUnknown); @@ -594,7 +599,7 @@ Begin GetSecurityLevel(User.Security, SecLevel); - Server.Status (User.Handle + ' logged in'); + Server.Status (ProcessID, User.Handle + ' logged in'); End Else Client.WriteLine(re_BadPW); End; @@ -644,7 +649,7 @@ Begin {$IFDEF FTPDEBUG} LOG('PASV on host ' + Client.HostIP + ' port ' + strI2S(DataPort)); - Server.Status(re_PassiveOK + '(' + strReplace(Client.HostIP, '.', ',') + ',' + strI2S(WordRec(DataPort).Hi) + ',' + strI2S(WordRec(DataPort).Lo) + ').'); + Server.Status(ProcessID, re_PassiveOK + '(' + strReplace(Client.HostIP, '.', ',') + ',' + strI2S(WordRec(DataPort).Hi) + ',' + strI2S(WordRec(DataPort).Lo) + ').'); {$ENDIF} Client.WriteLine(re_PassiveOK + '(' + strReplace(Client.HostIP, '.', ',') + ',' + strI2S(WordRec(DataPort).Hi) + ',' + strI2S(WordRec(DataPort).Lo) + ').'); @@ -845,6 +850,15 @@ Procedure TFTPServer.cmdSTOR (IsAppend: Boolean); Var TempPos : LongInt; TempBase : RecFileBase; + BaseFile : File; + CurDIR : String; + DizFile : Text; + Desc : FileDescBuffer; + DescSize : Byte; + Dir : RecFileList; + DirPos : LongInt = -1; + DesFile : File; + Count : Byte; Begin If Not LoggedIn Then Begin Client.WriteLine(re_BadCommand); @@ -861,30 +875,126 @@ Begin TempPos := FindDirectory(TempBase); If (TempPos = -1) Or Not ValidDirectory(TempBase) Then Begin + Client.WriteLine(re_NoAccess + ': Directory not found'); + + Exit; + End; + + If bbsCfg.UploadBase > 0 Then Begin + Assign (BaseFile, bbsCfg.DataPath + 'fbases.dat'); + ioReset (BaseFile, SizeOf(RecMessageBase), fmRWDN); + + If ioSeek (BaseFile, bbsCfg.UploadBase - 1) Then + ioRead (BaseFile, TempBase); + + Close (BaseFile); + End; + + If (Not CheckAccess (User, True, TempBase.ULACS)) or + (TempBase.Flags AND FBSlowMedia <> 0) or + (Length(FileMask) > 70) Then Begin + + Client.WriteLine(re_NoAccess); + + Exit; + End; + + If bbsCfg.FreeUL > 0 Then Begin + GetDIR (0, CurDIR); + + {$I-} ChDIR (TempBase.Path); {$I+} + + If (IoResult <> 0) or (DiskFree(0) DIV 1024 < bbsCfg.FreeUL) Then Begin + ChDIR (CurDIR); + + Client.WriteLine(re_NoAccess + ': No disk space'); + + Exit; + End; + + ChDIR (CurDIR); + End; + + If Not IsAppend And IsDuplicateFile (TempBase, FileMask, bbsCfg.FDupeScan = 2) Then Begin Client.WriteLine(re_BadFile); Exit; End; - server.status('calling recvfile'); + RecvFile (TempBase.Path + JustFile(Data), IsAppend); - RecvFile ('d:\code\mystic1\temp0\infile.tmp', IsAppend); + ImportFileDIZ(Desc, DescSize, TempPath, TempBase.Path + JustFile(Data)); -// Client.WriteLine(re_BadFile); + If DescSize = 0 Then Begin + DescSize := 1; + Desc[1] := 'No Description'; + End; + + Assign (BaseFile, BbsCfg.DataPath + TempBase.FileName + '.dir'); + + If Not ioReset (BaseFile, SizeOf(RecFileList), fmRWDW) Then + ioReWrite (BaseFile, SizeOf(RecFileList), fmRWDW); + + If IsAppend Then Begin + While Not Eof(BaseFile) Do Begin + ioRead (BaseFile, Dir); + + If JustFile(Data) = Dir.FileName Then Begin + DirPos := FilePos(BaseFile); + + Break; + End; + End; + End; + + If DirPos = -1 Then Begin + FillChar (Dir, SizeOf(Dir), 0); + + Dir.FileName := JustFile(Data); + Dir.DateTime := CurDateDOS; + Dir.Uploader := User.Handle; + End; + + Dir.DescLines := DescSize; + Dir.Size := FileByteSize(TempBase.Path + JustFile(Data)); + + Assign (DesFile, BbsCfg.DataPath + TempBase.FileName + '.des'); + + If Not ioReset (DesFile, 1, fmRWDW) Then + ioReWrite (DesFile, 1, fmRWDW); + + Dir.DescPtr := FileSize(DesFile); + + Seek (DesFile, Dir.DescPtr); + + For Count := 1 to DescSize Do + BlockWrite (DesFile, Desc[Count][0], Length(Desc[Count]) + 1); + + Close (DesFile); + + If DirPos = -1 Then + Seek (BaseFile, FileSize(BaseFile)) + Else + Seek (BaseFile, DirPos - 1); + + ioWrite (BaseFile, Dir); + Close (BaseFile); // dreadful things required to do for upload process: - // find upload base - // check diskspace - // check slowmedia - // check access - // check filename length - // duplicate file checking - // get file + // find upload base -- done + // check diskspace -- done + // check slowmedia -- done + // check access -- done + // check filename length -- done + // duplicate file checking -- done + // get file -- done // update user statistics // update history statistics // archive testing - // file_id.diz importing + // file_id.diz importing -- done? + // save file to db (or update if append) + // test all of it. // other things: add no desc and ftp test batch to configuration? End; @@ -1058,10 +1168,11 @@ Begin {$IFDEF FTPDEBUG} LOG('Cmd: ' + Cmd + ' Data: ' + Data); - Server.Status ('Cmd: ' + Cmd + ' Data: ' + Data); {$ENDIF} - //If Cmd = 'APPE' Then cmdSTOR(True) Else +// Server.Status (ProcessID, 'Cmd: ' + Cmd + ' Data: ' + Data); + + If Cmd = 'APPE' Then cmdSTOR(True) Else If Cmd = 'CDUP' Then cmdCDUP Else If Cmd = 'CWD' Then cmdCWD Else If Cmd = 'DELE' Then Client.WriteLine(re_NoAccess) Else @@ -1098,7 +1209,7 @@ Begin If GotQuit Then Begin Client.WriteLine(re_Goodbye); - Server.Status (User.Handle + ' logged out'); + Server.Status (ProcessID, User.Handle + ' logged out'); End; End; diff --git a/mystic/mis_client_nntp.pas b/mystic/mis_client_nntp.pas index 8f80684..ddcfcb9 100644 --- a/mystic/mis_client_nntp.pas +++ b/mystic/mis_client_nntp.pas @@ -88,7 +88,7 @@ End; Procedure TNNTPServer.ClientWriteLine (Str: String); Begin - Server.Status('S:' + Str); + Server.Status(ProcessID, 'S:' + Str); Client.WriteLine(Str); End; @@ -151,7 +151,7 @@ Begin ClientWriteLine(re_UnknownOption); If LoggedIn Then - Server.Status('Logged in as ' + UserName); + Server.Status(ProcessID, 'Logged in as ' + UserName); End; Procedure TNNTPServer.cmd_GROUP; @@ -535,7 +535,7 @@ Begin If HackCount >= HackThreshold Then Begin EndSession := True; // someone is being a douchebag - Server.Status('Flood attempt from ' + Client.PeerIP + '. Goodbye'); + Server.Status(ProcessID, 'Flood attempt from ' + Client.PeerIP + '. Goodbye'); MsgText.Free; @@ -848,7 +848,7 @@ Begin If Client.ReadLine(Str) = -1 Then Exit; - Server.Status('C:' + Str); + Server.Status(ProcessID, 'C:' + Str); Cmd := strUpper(strWordGet(1, Str, ' ')); diff --git a/mystic/mis_client_pop3.pas b/mystic/mis_client_pop3.pas index ba629c6..fc9a3e6 100644 --- a/mystic/mis_client_pop3.pas +++ b/mystic/mis_client_pop3.pas @@ -314,7 +314,7 @@ Begin Client.WriteLine(re_LoggedIn); - Server.Status(User.Handle + ' logged in'); + Server.Status(ProcessID, User.Handle + ' logged in'); End Else Client.WriteLine(re_BadLogin); End; @@ -491,7 +491,7 @@ Begin If GotQuit Then Begin Client.WriteLine(re_Goodbye); - Server.Status (User.Handle + ' logged out'); + Server.Status (ProcessID, User.Handle + ' logged out'); DeleteMessages; End; diff --git a/mystic/mis_client_smtp.pas b/mystic/mis_client_smtp.pas index 1ae59bc..493b261 100644 --- a/mystic/mis_client_smtp.pas +++ b/mystic/mis_client_smtp.pas @@ -87,17 +87,17 @@ Begin InDomain := Copy(Data, Pos('@', Data) + 1, Pos('>', Data) - Pos('@', Data) - 1); If IsFrom Then - Server.Status('User: ' + InName + ' Domain: ' + InDomain); + Server.Status(ProcessID, 'User: ' + InName + ' Domain: ' + InDomain); If InDomain <> bbsConfig.iNetDomain Then Begin - Server.Status('Refused by domain: ' + InName + '@' + InDomain); + Server.Status(ProcessID, 'Refused by domain: ' + InName + '@' + InDomain); Exit; End; Result := SearchForUser(InName, User, UserPos); If Not Result Then - Server.Status('Refused by name: ' + InName + '@' + InDomain); + Server.Status(ProcessID, 'Refused by name: ' + InName + '@' + InDomain); End; Procedure TSMTPServer.ResetSession; @@ -195,7 +195,7 @@ Begin If HackCount >= SMTPHackThresh Then Begin EndSession := True; // someone is being a douchebag - Server.Status('Flood attempt from ' + FromName + ' (' + Client.PeerIP + '); Goodbye'); + Server.Status(ProcessID, 'Flood attempt from ' + FromName + ' (' + Client.PeerIP + '); Goodbye'); MsgText.Free; @@ -258,7 +258,7 @@ Begin End; For MsgLoop := 0 To ToList.Count - 1 Do Begin - Server.Status('Sending mail from ' + FromName + ' to ' + ToList.Strings[MsgLoop]); + Server.Status(ProcessID, 'Sending mail from ' + FromName + ' to ' + ToList.Strings[MsgLoop]); MsgBase^.StartNewMsg; diff --git a/mystic/mis_common.pas b/mystic/mis_common.pas index 6115413..a54acc0 100644 --- a/mystic/mis_common.pas +++ b/mystic/mis_common.pas @@ -11,7 +11,7 @@ Uses Var TempPath : String; - Console : TOutput; +// Console : TOutput; Term : TTermAnsi; bbsConfig : RecConfig; diff --git a/mystic/mis_server.pas b/mystic/mis_server.pas index c8efefd..44846bc 100644 --- a/mystic/mis_server.pas +++ b/mystic/mis_server.pas @@ -42,15 +42,16 @@ Type Constructor Create (Cfg: RecConfig; PortNum: Word; CliMax: Word; ND: TNodeData; CreateProc: TServerCreateProc); Destructor Destroy; Override; Procedure Execute; Override; - Procedure Status (Str: String); + Procedure Status (ProcID: LongInt; Str: String); Function CheckIP (IP, Mask: String) : Boolean; Function IsBlockedIP (Var Client: TIOSocket) : Boolean; Function DuplicateIPs (Var Client: TIOSocket) : Byte; End; TServerClient = Class(TThread) - Client : TIOSocket; - Manager : TServerManager; + Client : TIOSocket; + Manager : TServerManager; + ProcessID : LongInt; Constructor Create (Owner: TServerManager; CliSock: TIOSocket); Destructor Destroy; Override; @@ -164,7 +165,7 @@ Begin End; End; -Procedure TServerManager.Status (Str: String); +Procedure TServerManager.Status (ProcID: LongInt; Str: String); Var Res : String; T : Text; @@ -177,7 +178,7 @@ Begin If ServerStatus.Count > MaxStatusText Then ServerStatus.Delete(0); - Res := '(' + Copy(DateDos2Str(CurDateDos, 1), 1, 5) + ' ' + TimeDos2Str(CurDateDos, 0) + ') ' + Str; + Res := FormatDate (CurDateDT, 'NNN DD HH:II') + ' ' + strI2S(ProcID + 1) + ' ' + Str; If Length(Res) > 74 Then Begin ServerStatus.Add(Copy(Res, 1, 74)); @@ -185,7 +186,7 @@ Begin If ServerStatus.Count > MaxStatusText Then ServerStatus.Delete(0); - ServerStatus.Add(strRep(' ', 14) + Copy(Res, 75, 255)); + ServerStatus.Add(strRep(' ', 15) + Copy(Res, 75, 255)); End Else ServerStatus.Add(Res); @@ -222,9 +223,9 @@ Begin If Terminated Then Exit; If ClientMax = 0 Then - Status('WARNING: At least one server is configured 0 max clients'); + Status(-1, 'WARNING: At least one server is configured 0 max clients'); - Status('Opening server socket on port ' + strI2S(Port)); + Status(-1, 'Opening server socket on port ' + strI2S(Port)); Repeat NewClient := Server.WaitConnection(0); @@ -234,7 +235,7 @@ Begin If (ClientMax > 0) And (ClientActive >= ClientMax) Then Begin Inc (ClientRefused); - Status ('BUSY: ' + NewClient.PeerIP + ' (' + NewClient.PeerName + ')'); + Status (-1, 'BUSY: ' + NewClient.PeerIP + ' (' + NewClient.PeerName + ')'); If Not NewClient.WriteFile('', TextPath + 'busy.txt') Then NewClient.WriteLine('BUSY'); @@ -246,7 +247,7 @@ Begin If IsBlockedIP(NewClient) Then Begin Inc (ClientBlocked); - Status('BLOCK: ' + NewClient.PeerIP + ' (' + NewClient.PeerName + ')'); + Status(-1, 'BLOCK: ' + NewClient.PeerIP + ' (' + NewClient.PeerName + ')'); If Not NewClient.WriteFile('', TextPath + 'blocked.txt') Then NewClient.WriteLine('BLOCKED'); @@ -258,7 +259,7 @@ Begin If (ClientMaxIPs > 0) and (DuplicateIPs(NewClient) >= ClientMaxIPs) Then Begin Inc (ClientRefused); - Status('MULTI: ' + NewClient.PeerIP + ' (' + NewClient.PeerName + ')'); + Status(-1, 'MULTI: ' + NewClient.PeerIP + ' (' + NewClient.PeerName + ')'); If Not NewClient.WriteFile('', TextPath + 'dupeip.txt') Then NewClient.WriteLine('Only ' + strI2S(ClientMaxIPs) + ' connection(s) per user'); @@ -270,13 +271,13 @@ Begin Inc (ClientTotal); Inc (ClientActive); - Status ('Connect: ' + NewClient.PeerIP + ' (' + NewClient.PeerName + ')'); + Status (-1, 'Connect: ' + NewClient.PeerIP + ' (' + NewClient.PeerName + ')'); NewClientProc(Self, Config, NodeInfo, NewClient); End; Until Terminated; - Status ('Shutting down server...'); + Status (-1, 'Shutting down server...'); End; Destructor TServerManager.Destroy; @@ -321,6 +322,7 @@ Begin For Count := 0 to Manager.ClientMax - 1 Do If Manager.ClientList[Count] = NIL Then Begin Manager.ClientList[Count] := Self; + ProcessID := Count; Break; End; diff --git a/mystic/mutil.pas b/mystic/mutil.pas index ba7c0c7..fccdd00 100644 --- a/mystic/mutil.pas +++ b/mystic/mutil.pas @@ -100,6 +100,9 @@ Begin If FileExist(ParamStr(1)) Then FN := ParamStr(1) Else + If FileExist(ParamStr(1) + '.ini') Then + FN := ParamStr(1) + '.ini' + Else If FileExist('mutil.ini') Then FN := 'mutil.ini' Else Begin diff --git a/mystic/records.pas b/mystic/records.pas index 093f3b0..7672396 100644 --- a/mystic/records.pas +++ b/mystic/records.pas @@ -106,7 +106,7 @@ Type ArcType : String[4]; MailType : Byte; binkHost : String[60]; - NetType : Byte; + UNUSED1 : Byte; ProtType : Byte; binkTimeout : Word; binkBlock : Word; diff --git a/mystic/todo.pas b/mystic/todo.pas index ee28cc0..792551b 100644 --- a/mystic/todo.pas +++ b/mystic/todo.pas @@ -7,8 +7,14 @@ design elements/issues. BUGS AND POSSIBLE ISSUES ======================== - -! Auto create of message bases is including periods in the filename? +- need to add QWK network ID to all message bases (remove QWK net flag?) +- need to add QWK networking editor (type: hub, or node) +- need to add QWK network link back to networks defined in editor for each + message base. Also need to add both to global editor? +- need to also have the ability to link a specific user account to a QWK + network from the editor. +- need function to exchange qwk with uplink (passive, login, pw, host, port) + packet type (qwke/qwk) ! Gender character is asking for ASCII number. Make new functions for areas where we don't want that. @@ -37,6 +43,8 @@ BUGS AND POSSIBLE ISSUES FUTURE / IDEAS / WORK IN PROGRESS / NOTES ========================================= +- make tiosocket buffer size dynamic. increase data sockets in ftp to 32kb +- all display files to search for .hlp before ANS? - fix END in lightbar file lists so it doesn't suck. - externalize qwk and file list compiler class. qwk for mystic/mis filelist for mystic/mutil. add compiler templates, file include, and new vs all @@ -44,16 +52,20 @@ FUTURE / IDEAS / WORK IN PROGRESS / NOTES - make embedded ANSI in file_id display correctly. - abstract ansi browser to be used for ansi archive viewer and sysop file manager (as well as the ANSI gallery). +- msg readers uses msgbase_ansi like mystic 2 - when mutil is tossing a packet and auto creates an area figure out if there can be a way to automatically create the uplink back to the originating node. +- expand max filename size for 70 to 255 chars? +- make file list use buffered IO class for reading .dir files (8k) - global user editor for user flags, def protocol, etc etc - ability to configure auto signatures (2 of them) one for handle and one - for real names + for real name bases - ability to download ANSIs while actually viewing them in the gallery - optional Menu scroller during input? - Menu type: Lightbar/Form OR just change standard lightbar to work that - way which i think is the best approach actually. + way which i think is the best approach actually but will it break existing + lightbars (shouldnt?) - ESC moves back in ANSI gallery only exits if dir = root? - Color, boxtype, and input configuration for configuration - global file editor like msg base @@ -62,8 +74,8 @@ FUTURE / IDEAS / WORK IN PROGRESS / NOTES something and also add in the "created" date to the voting question itself - Fix up new FS editor to use passed template and editor contraints. - Test with file description editor. -- ACS to allow "selecable reply base" - Strip pipe colors/ANSI from message option? +- allow ANSI option for msg bases? - AREAS.BBS import? - PGUP/DOWN moves bases in message base editor? - AreaFix diff --git a/mystic/whatsnew.txt b/mystic/whatsnew.txt index fa9a20e..3ee1c43 100644 --- a/mystic/whatsnew.txt +++ b/mystic/whatsnew.txt @@ -3613,4 +3613,16 @@ is flagged as a FTP network account, their reply packet will need to be "handle.rep". + + The file base configuration editor now allows bulk file base deletion + if a list of bases are tagged when delete is requested. + + + Mystic's FTP server now supports uploading directly to Mystic's file bases + using FTP. It will also attempt to use the archive configuration to import + FILE_ID.DIZ files. + + + MIS server status updates now use a MMM DD format date instead of MM/DD + which was confusing/annoying for people outside of North America. + + + The FTP server now allows resumed uploads via the APPE function. +