diff --git a/mystic/mis.pas b/mystic/mis.pas new file mode 100644 index 0000000..0241436 --- /dev/null +++ b/mystic/mis.pas @@ -0,0 +1,521 @@ +// ==================================================================== +// Mystic BBS Software Copyright 1997-2012 By James Coyle +// ==================================================================== +// +// This file is part of Mystic BBS. +// +// Mystic BBS is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Mystic BBS is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Mystic BBS. If not, see . +// +// ==================================================================== + +{$I M_OPS.PAS} + +Program MIS; + +Uses + {$IFDEF DEBUG} + HeapTrc, + {$ENDIF} + {$IFDEF UNIX} + cThreads, + {$ENDIF} + m_Output, + m_Input, + m_DateTime, + m_Socket_Class, + m_FileIO, + m_Strings, + m_Term_Ansi, + MIS_Common, + MIS_NodeData, + MIS_Server, + MIS_Client_Telnet, + MIS_Client_SMTP, + MIS_Client_POP3, + MIS_Client_FTP, + MIS_Client_NNTP; + +Const + FocusTelnet = 0; + FocusSMTP = 1; + FocusPOP3 = 2; + FocusFTP = 3; + FocusNNTP = 4; + FocusMax = 4; + +Var + Console : TOutput; + Input : TInput; + TelnetServer : TServerManager; + FTPServer : TServerManager; + POP3Server : TServerManager; + SMTPServer : TServerManager; + NNTPServer : TServerManager; + FocusPTR : TServerManager; + FocusCurrent : Byte; + TopPage : Integer; + BarPos : Integer; + NodeData : TNodeData; + +{$I MIS_ANSIWFC.PAS} + +Procedure ReadConfiguration; +Var + FileConfig : TBufFile; +Begin + FileConfig := TBufFile.Create(SizeOf(RecConfig)); + + If Not FileConfig.Open('mystic.dat', fmOpen, fmReadWrite + fmDenyNone, SizeOf(RecConfig)) Then Begin + WriteLn; + WriteLn ('ERROR: Unable to read MYSTIC.DAT. This file must exist in the same'); + WriteLn ('directory as MIS'); + Halt (1); + End; + + FileConfig.Read(bbsConfig); + FileConfig.Free; + + If bbsConfig.DataChanged <> mysDataChanged Then Begin + WriteLn('ERROR: Data files are not current and must be upgraded.'); + Halt(1); + End; +End; + +Procedure ReadChatData; +Var + ChatFile : File of ChatRec; + Chat : ChatRec; + Nodes : LongInt; + Count : LongInt; + NI : TNodeInfoRec; +Begin + Nodes := NodeData.GetNodeTotal; + + For Count := 1 to Nodes Do + If NodeData.GetNodeInfo(Count, NI) Then Begin + Assign (ChatFile, bbsConfig.DataPath + 'chat' + strI2S(NI.Num) + '.dat'); + + If ioReset(ChatFile, SizeOf(ChatRec), fmReadWrite + fmDenyNone) Then Begin + If ioRead(ChatFile, Chat) Then Begin + If Chat.Active Then Begin + NI.User := Chat.Name; + NI.Action := Chat.Action; + + NodeData.SetNodeInfo(NI.Num, NI); + End; + End; + Close (ChatFile); + End; + End; +End; + +Function GetFocusPtr : TServerManager; +Begin + Result := NIL; + + Case FocusCurrent of + FocusTelnet : GetFocusPtr := TelnetServer; + FocusSMTP : GetFocusPtr := SMTPServer; + FocusPOP3 : GetFocusPtr := POP3Server; + FocusFTP : GetFocusPtr := FTPServer; + FocusNNTP : GetFocusPtr := NNTPServer; + End; +End; + +Procedure UpdateConnectionList; +Var + Count : Byte; + Attr : Byte; + PosY : Byte; + NI : TNodeInfoRec; +Begin + If FocusPtr = NIL Then Exit; + + ReadChatData; + + PosY := 0; + + For Count := TopPage to TopPage + 7 Do Begin + NodeData.GetNodeInfo(Count, NI); + + Inc (PosY); + + If Count = BarPos Then Attr := 31 Else Attr := 7; + + Case FocusCurrent of + 0 : If (Count <= FocusPtr.ClientList.Count) And (FocusPtr.ClientList[Count - 1] <> NIL) Then Begin + Console.WriteXY (3, 3 + PosY, Attr, + strPadL(strI2S(NI.Num), 3, '0') + ' ' + + strPadR(NI.User, 12, ' ') + ' ' + + strPadR(NI.Action, 18, ' ') + ' ' + + strPadL(NI.IP, 15, ' ')); + End Else + If Count <= FocusPtr.ClientMax Then + Console.WriteXY (3, 3 + PosY, Attr, strPadL(strI2S(NI.Num), 3, '0') + strPadR(' Waiting', 48, ' ')) + Else + Console.WriteXY (3, 3 + PosY, Attr, strRep(' ', 51)); + 1, + 2, + 3, + 4: If (Count <= FocusPtr.ClientList.Count) And (FocusPtr.ClientList[Count - 1] <> NIL) Then Begin + Console.WriteXY (3, 3 + PosY, Attr, + strPadL(strI2S(Count), 3, '0') + ' ' + + strPadR(TFTPServer(FocusPtr.ClientList[Count - 1]).User.Handle, 31, ' ') + ' ' + + strPadL(TFTPServer(FocusPtr.ClientList[Count - 1]).Client.PeerIP, 15, ' ')); + End Else + If Count <= FocusPtr.ClientMax Then + Console.WriteXY (3, 3 + PosY, Attr, strPadL(strI2S(Count), 3, '0') + strPadR(' Waiting', 48, ' ')) + Else + Console.WriteXY (3, 3 + PosY, Attr, strRep(' ', 51)); + End; + End; +End; + +Procedure UpdateStatus; +Var + Offset : Integer; + Count : Integer; +Begin + If FocusPtr = NIL Then Exit; + + FocusPtr.Server.StatusUpdated := False; + + // UPDATE CONNECTION STATS + + Console.WriteXY (69, 7, 7, strPadR(strI2S(FocusPtr.ClientActive), 5, ' ')); + Console.WriteXY (69, 8, 7, strPadR(strI2S(FocusPtr.ClientBlocked), 5, ' ')); + Console.WriteXY (69, 9, 7, strPadR(strI2S(FocusPtr.ClientRefused), 5, ' ')); + Console.WriteXY (69, 10, 7, strPadR(strI2S(FocusPtr.ClientTotal), 5, ' ')); + + // UPDATE STATUS MESSAGES + + Offset := FocusPtr.Server.SocketStatus.Count; + + For Count := 22 DownTo 15 Do Begin + If Offset > 0 Then Begin + Dec(Offset); + Console.WriteXY (4, Count, 7, strPadR(FocusPtr.Server.SocketStatus.Strings[Offset], 74, ' ')); + End Else + Console.WriteXY (4, Count, 7, strPadR(' ', 74, ' ')); + End; + + UpdateConnectionList; +End; + +Procedure SwitchFocus; +Begin + BarPos := 1; + TopPage := 1; + + Repeat + If FocusCurrent = FocusMax Then FocusCurrent := 0 Else Inc(FocusCurrent); + + Case FocusCurrent of + FocusTelnet : If TelnetServer <> NIL Then Break; + FocusSMTP : If SmtpServer <> NIL Then Break; + FocusPOP3 : If Pop3Server <> NIL Then Break; + FocusFTP : If FtpServer <> NIL Then Break; + FocusNNTP : If NNTPServer <> NIL Then Break; + End; + Until False; + + Console.WriteXY (50, 1, 112, 'telnet/smtp/pop3/ftp/nntp/http'); + + Case FocusCurrent of + FocusTelnet : Console.WriteXY (50, 1, 113, 'TELNET'); + FocusSMTP : Console.WriteXY (57, 1, 113, 'SMTP'); + FocusPOP3 : Console.WriteXY (62, 1, 113, 'POP3'); + FocusFTP : Console.WriteXY (67, 1, 113, 'FTP'); + FocusNNTP : Console.WriteXY (71, 1, 113, 'NNTP'); + End; + + FocusPtr := GetFocusPtr; + + If FocusPtr <> NIL Then Begin + Console.WriteXY (69, 5, 7, strPadR(strI2S(FocusPtr.Port), 5, ' ')); + Console.WriteXY (69, 6, 7, strPadR(strI2S(FocusPtr.ClientMax), 5, ' ')); + + UpdateStatus; + End; +End; + +Procedure LocalLogin; +Const + BufferSize = 1024 * 4; +Var + Term : TTermAnsi; + Client : TSocketClass; + Res : LongInt; + Buffer : Array[1..BufferSize] of Char; + Done : Boolean; + Ch : Char; +Begin + Console.ClearScreen; + Console.WriteStr ('Connecting to 127.0.0.1... '); + + Client := TSocketClass.Create; + + If Not Client.Connect('127.0.0.1', bbsConfig.InetTNPort) Then + Console.WriteLine('Unable to connect') + Else Begin + Done := False; + Term := TTermAnsi.Create(Console); + + Console.SetWindow (1, 1, 80, 24, True); + Console.WriteXY (1, 25, 112, strPadC('Local TELNET: ALT-X to Quit', 80, ' ')); + + Term.SetReplyClient(Client); + + Repeat + If Client.WaitForData(0) > 0 Then Begin + Repeat + Res := Client.ReadBuf (Buffer, BufferSize); + + If Res < 0 Then Begin + Done := True; + Break; + End; + + Term.ProcessBuf(Buffer, Res); + Until Res <> BufferSize; + End Else + If Input.KeyPressed Then Begin + Ch := Input.ReadKey; + Case Ch of + #00 : Case Input.ReadKey of + #45 : Break; + #71 : Client.WriteStr(#27 + '[H'); + #72 : Client.WriteStr(#27 + '[A'); + #73 : Client.WriteStr(#27 + '[V'); + #75 : Client.WriteStr(#27 + '[D'); + #77 : Client.WriteStr(#27 + '[C'); + #79 : Client.WriteStr(#27 + '[K'); + #80 : Client.WriteStr(#27 + '[B'); + #81 : Client.WriteStr(#27 + '[U'); + #83 : Client.WriteStr(#127); + End; + Else + Client.WriteBuf(Ch, 1); + If Client.FTelnetEcho Then Term.Process(Ch); + End; + End Else + WaitMS(5); + Until Done; + + Term.Free; + End; + + Client.Free; + + Console.TextAttr := 7; + Console.SetWindow (1, 1, 80, 25, True); + + FocusCurrent := FocusMax; + DrawStatusScreen; + SwitchFocus; +End; + +Const + WinTitle = 'Mystic Internet Server'; + +Var + Count : Integer; + Started : Boolean; +Begin + Randomize; + + {$IFDEF DEBUG} + SetHeapTraceOutput('mis.mem'); + {$ENDIF} + + ReadConfiguration; + + TelnetServer := NIL; + FTPServer := NIL; + POP3Server := NIL; + Started := False; + + Console := TOutput.Create(True); + Input := TInput.Create; + NodeData := TNodeData.Create(bbsConfig.INetTNMax); + + Console.SetWindowTitle(WinTitle); + + {$IFDEF WINDOWS} + If bbsConfig.InetTNUse Then Begin + TelnetServer := TServerManager.Create(bbsConfig, bbsConfig.InetTNPort, bbsConfig.INetTNMax, NodeData, @CreateTelnet); + + TelnetServer.Server.FTelnetServer := True; +// TelnetServer.TextPath := bbsConfig.DataPath; + TelnetServer.ClientMaxIPs := 1 {bbsConfig.InetTNIPs}; + + Started := True; + End; + {$ENDIF} + + If bbsConfig.InetSMTPUse Then Begin + SMTPServer := TServerManager.Create(bbsConfig, bbsConfig.INetSMTPPort, bbsConfig.inetSMTPMax, NodeData, @CreateSMTP); + + SMTPServer.Server.FTelnetServer := False; + SMTPServer.ClientMaxIPs := 1; +// SMTPServer.TextPath := bbsConfig.DataPath; + + Started := True; + End; + + If bbsConfig.InetPOP3Use Then Begin + POP3Server := TServerManager.Create(bbsConfig, bbsConfig.INetPOP3Port, bbsConfig.inetPOP3Max, NodeData, @CreatePOP3); + + POP3Server.Server.FTelnetServer := False; + POP3Server.ClientMaxIPs := 2; +// POP3Server.TextPath := bbsConfig.DataPath; + + Started := True; + End; + + If bbsConfig.InetFTPUse Then Begin + FTPServer := TServerManager.Create(bbsConfig, bbsConfig.InetFTPPort, bbsConfig.inetFTPMax, NodeData, @CreateFTP); + + FTPServer.Server.FTelnetServer := False; + FTPServer.ClientMaxIPs := 2; +// FTPServer.TextPath := bbsConfig.DataPath; + + Started := True; + End; + + If bbsConfig.InetNNTPUse Then Begin + NNTPServer := TServerManager.Create(bbsConfig, bbsConfig.InetNNTPPort, bbsConfig.inetNNTPMax, NodeData, @CreateNNTP); + + NNTPServer.Server.FTelnetServer := False; + NNTPServer.ClientMaxIPs := 1; + + Started := True; + End; + + If Not Started Then Begin + Console.ClearScreen; + + Console.WriteLine('ERROR: No servers are configured as active. Run MYSTIC -CFG to configure'); + Console.WriteLine('Internet server options.'); + + NodeData.Free; + Input.Free; + Console.Free; + + Halt(10); + End; + +// BarPos := 1; +// TopPage := 1; + Count := 0; + + DrawStatusScreen; + + FocusCurrent := FocusMax; + SwitchFocus; + + Repeat + If Input.KeyWait(1000) Then + Case Input.ReadKey of + #00 : Case Input.ReadKey of +// #37 : If (FocusPtr <> NIL) And (FocusPtr.ClientList[BarPos - 1] <> NIL) Then Begin +// TServerClient(FocusPtr.ClientList[BarPos - 1]).Client.Disconnect; +// UpdateConnectionList; +// End; + #72 : If BarPos > TopPage Then Begin + Dec(BarPos); + UpdateConnectionList; + End Else + If TopPage > 1 Then Begin + Dec(TopPage); + Dec(BarPos); + + UpdateConnectionList; + End; + #75 : Begin + Dec (TopPage, 8); + Dec (BarPos, 8); + + If TopPage < 1 Then TopPage := 1; + If BarPos < 1 Then BarPos := TopPage; + + UpdateConnectionList; + End; + #77 : Begin + Inc (TopPage, 8); + Inc (BarPos, 8); + + If TopPage + 7 > FocusPtr.ClientList.Count Then TopPage := FocusPtr.ClientList.Count - 7; + If BarPos > FocusPtr.ClientList.Count Then BarPos := FocusPtr.ClientList.Count; + If TopPage < 1 Then TopPage := 1; + UpdateConnectionList; + End; + + #80 : If (BarPos < FocusPtr.ClientMax) and (BarPos < TopPage + 7) Then Begin + Inc(BarPos); + UpdateConnectionList; + End Else + If (TopPage + 7 < FocusPtr.ClientMax) Then Begin + Inc(TopPage); + Inc(BarPos); + UpdateConnectionList; + End; + End; + #09 : SwitchFocus; + #27 : Break; + #32 : LocalLogin; + End; + + If (FocusPtr <> NIL) Then + If FocusPtr.Server.StatusUpdated Then Begin + UpdateStatus; + Count := 1; + End Else + If Count = 10 Then Begin // force update every 10 seconds since mystic + UpdateStatus; // cannot yet talk to MIS directly + Count := 1; + End Else + Inc (Count); + Until False; + + Console.TextAttr := 7; + + Console.ClearScreen; + + Console.WriteLine ('Mystic Internet Server Version ' + mysVersion); + Console.WriteLine (''); + Console.WriteStr ('Shutting down servers: TELNET'); + + TelnetServer.Free; + + Console.WriteStr (' SMTP'); + SMTPServer.Free; + + Console.WriteStr (' POP3'); + POP3Server.Free; + + Console.WriteStr (' FTP'); + FTPServer.Free; + + Console.WriteStr (' NNTP'); + NNTPServer.Free; + + Console.WriteLine (' (DONE)'); + + NodeData.Free; + Input.Free; + Console.Free; + + Halt(255); +End. \ No newline at end of file