169 lines
4.6 KiB
Plaintext
169 lines
4.6 KiB
Plaintext
|
{
|
||
|
$Project$
|
||
|
$Workfile$
|
||
|
$Revision$
|
||
|
$DateUTC$
|
||
|
$Id$
|
||
|
|
||
|
This file is part of the Indy (Internet Direct) project, and is offered
|
||
|
under the dual-licensing agreement described on the Indy website.
|
||
|
(http://www.indyproject.org/)
|
||
|
|
||
|
Copyright:
|
||
|
(c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
|
||
|
}
|
||
|
{
|
||
|
$Log$
|
||
|
}
|
||
|
{
|
||
|
Rev 1.5 12/2/2004 4:23:58 PM JPMugaas
|
||
|
Adjusted for changes in Core.
|
||
|
|
||
|
Rev 1.4 2004.02.03 5:44:16 PM czhower
|
||
|
Name changes
|
||
|
|
||
|
Rev 1.3 4/4/2003 8:03:40 PM BGooijen
|
||
|
fixed
|
||
|
|
||
|
Rev 1.2 2/24/2003 09:33:00 PM JPMugaas
|
||
|
|
||
|
Rev 1.1 1/31/2003 02:32:08 PM JPMugaas
|
||
|
Should now compile.
|
||
|
|
||
|
Rev 1.0 11/13/2002 07:59:32 AM JPMugaas
|
||
|
|
||
|
2001, Feb 17
|
||
|
started this unit with code from TIdRexecServer
|
||
|
}
|
||
|
|
||
|
unit IdRemoteCMDServer;
|
||
|
|
||
|
interface
|
||
|
|
||
|
{$i IdCompilerDefines.inc}
|
||
|
|
||
|
uses
|
||
|
IdAssignedNumbers, IdContext,IdTCPClient, IdCustomTCPServer;
|
||
|
|
||
|
type
|
||
|
TIdRemoteCMDServer = class(TIdCustomTCPServer)
|
||
|
protected
|
||
|
FForcePortsInRange : Boolean;
|
||
|
FStdErrorPortsInRange : Boolean;
|
||
|
function DoExecute(AThread: TIdContext): boolean; override;
|
||
|
procedure DoCMD(AThread: TIdContext; AStdError : TIdTCPClient;
|
||
|
AParam1, AParam2, ACommand : String); virtual; abstract;
|
||
|
public
|
||
|
procedure SendError(AThread : TIdContext;AStdErr : TIdTCPClient; AMsg : String);
|
||
|
procedure SendResults(AThread : TIdContext; AStdErr : TIdTCPClient; AMsg : String);
|
||
|
end;
|
||
|
|
||
|
implementation
|
||
|
|
||
|
uses
|
||
|
IdSocketHandle, IdException, IdGlobal, IdIOHandlerStack, IdIOHandlerSocket, IdStack, SysUtils;
|
||
|
|
||
|
{ TIdRemoteCMDServer }
|
||
|
|
||
|
function TIdRemoteCMDServer.DoExecute(AThread: TIdContext): boolean;
|
||
|
var
|
||
|
StdError : TIdTCPClient;
|
||
|
ErrorPort : TIdPort;
|
||
|
Param1, Param2, Command : String;
|
||
|
|
||
|
procedure ExecuteCMD;
|
||
|
begin
|
||
|
try
|
||
|
Result := True;
|
||
|
StdError := nil;
|
||
|
ErrorPort := IndyStrToInt(AThread.Connection.IOHandler.ReadLn(#0), 0);
|
||
|
|
||
|
if ErrorPort <> 0 then
|
||
|
begin
|
||
|
StdError := TIdTCPClient.Create(nil);
|
||
|
if FStdErrorPortsInRange then
|
||
|
begin
|
||
|
StdError.BoundPortMin := 512;
|
||
|
StdError.BoundPortMax := 1023;
|
||
|
end;
|
||
|
StdError.BoundIP := AThread.Connection.Socket.Binding.IP;
|
||
|
StdError.Host := AThread.Connection.Socket.Binding.PeerIP;
|
||
|
StdError.Port := ErrorPort;
|
||
|
|
||
|
repeat
|
||
|
try
|
||
|
StdError.Connect;
|
||
|
Break;
|
||
|
except
|
||
|
on E: EIdSocketError do begin
|
||
|
// This will be uncommented after we have the fix into TIdTCPClient.Connect method
|
||
|
// There is one extra line that has to be added in order to run this code
|
||
|
//
|
||
|
// except
|
||
|
// // This will free IOHandler
|
||
|
// BoundPort := TIdIOHandlerSocket(IOHandler).Binding.Port; // The extra line
|
||
|
// DisconnectSocket;
|
||
|
// raise;
|
||
|
// end;
|
||
|
//
|
||
|
// After we have this code we will know the exact Port on wich the exception has occured
|
||
|
|
||
|
{if E.LastError = 10048 then begin
|
||
|
StdError.BoundPortMax := StdError.BoundPort - 1;
|
||
|
StdError.BoundPort := 0;
|
||
|
StdError.Disconnect;
|
||
|
end
|
||
|
else}
|
||
|
raise;
|
||
|
end;
|
||
|
end;
|
||
|
until False;
|
||
|
end;
|
||
|
|
||
|
Param1 := AThread.Connection.IOHandler.ReadLn(#0);
|
||
|
Param2 := AThread.Connection.IOHandler.ReadLn(#0);
|
||
|
Command := AThread.Connection.IOHandler.ReadLn(#0);
|
||
|
|
||
|
DoCMD(AThread, StdError, Param1, Param2, Command);
|
||
|
if Assigned(StdError) then
|
||
|
begin
|
||
|
StdError.Disconnect;
|
||
|
end;
|
||
|
finally
|
||
|
FreeAndNil(StdError);
|
||
|
end;
|
||
|
end;
|
||
|
begin
|
||
|
if FForcePortsInRange then begin
|
||
|
if ((AThread.Connection.IOHandler as TIdIOHandlerSocket).Binding.Port >= 512) or
|
||
|
((AThread.Connection.IOHandler as TIdIOHandlerSocket).Binding.Port <= 1023) then
|
||
|
begin
|
||
|
ExecuteCMD;
|
||
|
end;
|
||
|
end
|
||
|
else begin
|
||
|
ExecuteCMD;
|
||
|
end;
|
||
|
AThread.Connection.Disconnect;
|
||
|
Result := False;// DoExecute does not have to be called again
|
||
|
end;
|
||
|
|
||
|
procedure TIdRemoteCMDServer.SendError(AThread: TIdContext;
|
||
|
AStdErr: TIdTCPClient; AMsg: String);
|
||
|
begin
|
||
|
AThread.Connection.IOHandler.Write(#1);
|
||
|
if Assigned(AStdErr) then begin
|
||
|
AStdErr.IOHandler.Write(AMsg);
|
||
|
end else begin
|
||
|
AThread.Connection.IOHandler.Write(AMsg);
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TIdRemoteCMDServer.SendResults(AThread: TIdContext;
|
||
|
AStdErr: TIdTCPClient; AMsg: String);
|
||
|
begin
|
||
|
AThread.Connection.IOHandler.Write(#0 + AMsg)
|
||
|
end;
|
||
|
|
||
|
end.
|