304 lines
7.1 KiB
ObjectPascal
304 lines
7.1 KiB
ObjectPascal
// ====================================================================
|
|
// Mystic BBS Software Copyright 1997-2013 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 <http://www.gnu.org/licenses/>.
|
|
//
|
|
// ====================================================================
|
|
|
|
Unit MIS_Client_Telnet;
|
|
|
|
{$I M_OPS.PAS}
|
|
|
|
Interface
|
|
|
|
{$IFDEF DARWIN}
|
|
{$DEFINE USEPROCESS}
|
|
{$ELSE}
|
|
{$IFDEF UNIX}
|
|
{$DEFINE USEFORK}
|
|
{$ENDIF}
|
|
|
|
{$IFDEF USEFORK}
|
|
{$IFDEF CPU32}
|
|
{$LinkLib libutil.a}
|
|
{$ENDIF}
|
|
{$IFDEF CPU64}
|
|
{$LinkLib libutil.a}
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
|
|
Uses
|
|
{$IFDEF USEPROCESS}
|
|
Process,
|
|
m_DateTime,
|
|
{$ENDIF}
|
|
{$IFDEF UNIX}
|
|
BaseUnix,
|
|
Unix,
|
|
{$ENDIF}
|
|
{$IFDEF WINDOWS}
|
|
Windows,
|
|
{$ENDIF}
|
|
m_io_Base,
|
|
m_io_Sockets,
|
|
m_FileIO,
|
|
m_Strings,
|
|
MIS_Common,
|
|
MIS_NodeData,
|
|
MIS_Server,
|
|
BBS_Records,
|
|
BBS_DataBase;
|
|
|
|
{$IFDEF USEFORK}
|
|
function forkpty(__amaster:Plongint; __name:Pchar; __termp:Pointer; __winp:Pointer):longint;cdecl;external 'c' name 'forkpty';
|
|
{$ENDIF}
|
|
|
|
Function CreateTelnet (Owner: TServerManager; Config: RecConfig; ND: TNodeData; CliSock: TIOSocket) : TServerClient;
|
|
|
|
Type
|
|
TTelnetServer = Class(TServerClient)
|
|
ND : TNodeData;
|
|
|
|
Constructor Create (Owner: TServerManager; NewND: TNodeData; CliSock: TIOSocket);
|
|
Procedure Execute; Override;
|
|
Destructor Destroy; Override;
|
|
End;
|
|
|
|
Implementation
|
|
|
|
Function CreateTelnet (Owner: TServerManager; Config: RecConfig; ND: TNodeData; CliSock: TIOSocket) : TServerClient;
|
|
Begin
|
|
Result := TTelnetServer.Create(Owner, ND, CliSock);
|
|
End;
|
|
|
|
Constructor TTelnetServer.Create (Owner: TServerManager; NewND: TNodeData; CliSock: TIOSocket);
|
|
Begin
|
|
Inherited Create(Owner, CliSock);
|
|
|
|
Self.ND := NewND;
|
|
End;
|
|
|
|
{$IFDEF WINDOWS}
|
|
Procedure TTelnetServer.Execute;
|
|
Var
|
|
Cmd : String;
|
|
SI : TStartupInfo;
|
|
PI : TProcessInformation;
|
|
Num : LongInt;
|
|
NI : TNodeInfoRec;
|
|
PassHandle : LongInt;
|
|
Begin
|
|
If Not DuplicateHandle (
|
|
GetCurrentProcess,
|
|
Client.FSocketHandle,
|
|
GetCurrentProcess,
|
|
@PassHandle,
|
|
0,
|
|
TRUE,
|
|
DUPLICATE_SAME_ACCESS) Then Exit;
|
|
|
|
Num := ND.GetFreeNode;
|
|
Cmd := 'mystic.exe -n' + strI2S(Num) + ' -TID' + strI2S(PassHandle) + ' -IP' + Client.FPeerIP + ' -HOST' + Client.FPeerName + #0;
|
|
|
|
FillChar(NI, SizeOf(NI), 0);
|
|
|
|
NI.Num := Num;
|
|
NI.Busy := True;
|
|
NI.IP := Client.FPeerIP;
|
|
NI.User := 'Unknown';
|
|
NI.Action := 'Logging In';
|
|
|
|
ND.SetNodeInfo(Num, NI);
|
|
|
|
FillChar(SI, SizeOf(SI), 0);
|
|
FillChar(PI, SizeOf(PI), 0);
|
|
|
|
SI.dwFlags := STARTF_USESHOWWINDOW;
|
|
|
|
If bbsCfg.inetTNHidden Then
|
|
SI.wShowWindow := SW_HIDE
|
|
Else
|
|
SI.wShowWindow := SW_SHOWMINNOACTIVE;
|
|
|
|
If CreateProcess(NIL, PChar(@Cmd[1]),
|
|
NIL, NIL, True, Create_New_Console + Normal_Priority_Class, NIL, NIL, SI, PI) Then
|
|
WaitForSingleObject (PI.hProcess, INFINITE);
|
|
|
|
NI.Busy := False;
|
|
NI.IP := '';
|
|
NI.User := '';
|
|
NI.Action := '';
|
|
|
|
ND.SetNodeInfo(Num, NI);
|
|
|
|
FileErase (bbsCfg.DataPath + 'chat' + strI2S(Num) + '.dat');
|
|
End;
|
|
{$ENDIF}
|
|
|
|
{$IFDEF USEFORK}
|
|
Procedure TTelnetServer.Execute;
|
|
Var
|
|
Num : LongInt;
|
|
NI : TNodeInfoRec;
|
|
PID : LongInt;
|
|
PTYFD : LongInt;
|
|
RDFDSET : TFDSet;
|
|
Count : LongInt;
|
|
Buffer : Array[1..8 * 1024] of Char;
|
|
MaxFD : LongInt;
|
|
WaitStat : LongInt;
|
|
Begin
|
|
Client.FTelnetServer := True;
|
|
|
|
Num := ND.GetFreeNode;
|
|
|
|
PID := ForkPTY (@PTYFD, NIL, NIL, NIL);
|
|
|
|
If PID = 0 Then Begin
|
|
fpSetSID;
|
|
//tcSetPGrp (0, fpGetPID);
|
|
|
|
fpExecLP ('./mystic', ['-n' + strI2S(Num), '-TID' + strI2S(Client.FSocketHandle), '-IP' + Client.FPeerIP, '-HOST' + Client.FPeerName]);
|
|
|
|
Exit;
|
|
End Else
|
|
If PID = -1 Then
|
|
Exit;
|
|
|
|
FillChar (NI, SizeOf(NI), 0);
|
|
|
|
NI.Num := Num;
|
|
NI.Busy := True;
|
|
NI.IP := Client.FPeerIP;
|
|
NI.User := 'Unknown';
|
|
NI.Action := 'Logging In';
|
|
|
|
ND.SetNodeInfo(Num, NI);
|
|
|
|
MaxFD := Client.FSocketHandle;
|
|
|
|
If PTYFD > Client.FSocketHandle Then MaxFD := PTYFD;
|
|
|
|
Repeat
|
|
fpFD_ZERO (RDFDSET);
|
|
fpFD_SET (PTYFD, RDFDSET);
|
|
fpFD_SET (Client.FSocketHandle, RDFDSET);
|
|
|
|
If fpSelect (MaxFD + 1, @RDFDSET, NIL, NIL, 3000) < 0 Then Break;
|
|
|
|
If fpFD_ISSET(PTYFD, RDFDSET) = 1 Then Begin
|
|
Count := fpRead (PTYFD, Buffer, SizeOf(Buffer));
|
|
|
|
If Count <= 0 Then Break;
|
|
|
|
Client.WriteBuf (Buffer, Count);
|
|
End;
|
|
|
|
If fpFD_ISSET(Client.FSocketHandle, RDFDSET) = 1 Then Begin
|
|
Count := Client.ReadBuf (Buffer, SizeOf(Buffer));
|
|
|
|
If Count < 0 Then Break;
|
|
|
|
If fpWrite (PTYFD, Buffer, Count) <> Count Then Break;
|
|
End;
|
|
Until False;
|
|
|
|
fpClose (PTYFD);
|
|
|
|
Repeat
|
|
Until fpWaitPID(PID, WaitStat, WUNTRACED) = PID;
|
|
|
|
NI.Busy := False;
|
|
NI.IP := '';
|
|
NI.User := '';
|
|
NI.Action := '';
|
|
|
|
ND.SetNodeInfo(Num, NI);
|
|
|
|
FileErase (bbsCfg.DataPath + 'chat' + strI2S(NI.Num) + '.dat');
|
|
End;
|
|
{$ENDIF}
|
|
|
|
{$IFDEF USEPROCESS}
|
|
Procedure TTelnetServer.Execute;
|
|
Var
|
|
Cmd : String;
|
|
Num : LongInt;
|
|
NI : TNodeInfoRec;
|
|
Proc : TProcess;
|
|
Buffer : TIOBuffer;
|
|
bRead : LongInt;
|
|
bWrite : LongInt;
|
|
Begin
|
|
Client.FTelnetServer := True;
|
|
|
|
Proc := TProcess.Create(Nil);
|
|
Num := ND.GetFreeNode;
|
|
|
|
Proc.CommandLine := 'mystic -n' + strI2S(Num) + ' -IP' + Client.FPeerIP + ' -HOST' + Client.FPeerName;
|
|
Proc.Options := [poUsePipes];
|
|
|
|
FillChar(NI, SizeOf(NI), 0);
|
|
|
|
NI.Num := Num;
|
|
NI.Busy := True;
|
|
NI.IP := Client.FPeerIP;
|
|
NI.User := 'Unknown';
|
|
NI.Action := 'Logging In';
|
|
|
|
ND.SetNodeInfo(Num, NI);
|
|
|
|
Proc.Execute;
|
|
|
|
While Proc.Running Or (Proc.Output.NumBytesAvailable > 0) Do Begin
|
|
If Proc.Output.NumBytesAvailable > 0 Then Begin
|
|
bRead := Proc.Output.Read(Buffer, TIOBufferSize);
|
|
Client.WriteBufEscaped (Buffer, bRead);
|
|
End Else
|
|
If Client.DataWaiting Then Begin
|
|
bWrite := Client.ReadBuf(Buffer, TIOBufferSize);
|
|
|
|
If bWrite < 0 Then Break;
|
|
|
|
If bWrite > 0 Then Begin
|
|
Proc.Input.Write(Buffer, bWrite);
|
|
End;
|
|
End Else
|
|
WaitMS(10);
|
|
End;
|
|
|
|
Proc.Free;
|
|
|
|
NI.Busy := False;
|
|
NI.IP := '';
|
|
NI.User := '';
|
|
NI.Action := '';
|
|
|
|
ND.SetNodeInfo(Num, NI);
|
|
|
|
FileErase (bbsCfg.DataPath + 'chat' + strI2S(NI.Num) + '.dat');
|
|
End;
|
|
{$ENDIF}
|
|
|
|
Destructor TTelnetServer.Destroy;
|
|
Begin
|
|
Inherited Destroy;
|
|
End;
|
|
|
|
End.
|