223 lines
5.4 KiB
Plaintext
223 lines
5.4 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.7 2004.02.03 5:44:16 PM czhower
|
|
Name changes
|
|
|
|
Rev 1.6 2004.01.22 6:09:04 PM czhower
|
|
IdCriticalSection
|
|
|
|
Rev 1.5 1/21/2004 3:27:18 PM JPMugaas
|
|
InitComponent
|
|
|
|
Rev 1.4 4/4/2003 8:03:40 PM BGooijen
|
|
fixed
|
|
|
|
Rev 1.3 2/24/2003 09:32:56 PM JPMugaas
|
|
|
|
Rev 1.2 1/31/2003 02:32:04 PM JPMugaas
|
|
Should now compile.
|
|
|
|
Rev 1.1 12/6/2002 05:30:32 PM JPMugaas
|
|
Now decend from TIdTCPClientCustom instead of TIdTCPClient.
|
|
|
|
Rev 1.0 11/13/2002 07:59:26 AM JPMugaas
|
|
|
|
-2001.02.15 - J. Peter Mugaas
|
|
Started this unit with code originally in TIdRexec
|
|
}
|
|
|
|
unit IdRemoteCMDClient;
|
|
|
|
{
|
|
Indy Rexec Client TIdRexec
|
|
Copyright (C) 2001 Indy Pit Crew
|
|
Author J. Peter Mugaas
|
|
Based partly on code authored by Laurence LIew
|
|
2001-February-15
|
|
}
|
|
|
|
interface
|
|
{$i IdCompilerDefines.inc}
|
|
|
|
uses
|
|
IdException, IdTCPClient;
|
|
|
|
const
|
|
IDRemoteUseStdErr = True;
|
|
{for IdRSH, we set this to. IdRexec will override this}
|
|
IDRemoteFixPort = True;
|
|
|
|
type
|
|
EIdCanNotBindRang = class(EIdException);
|
|
|
|
TIdRemoteCMDClient = class(TIdTCPClientCustom)
|
|
protected
|
|
FUseReservedPorts: Boolean;
|
|
FUseStdError : Boolean;
|
|
FErrorMessage : String;
|
|
FErrorReply : Boolean;
|
|
//
|
|
function InternalExec(AParam1, AParam2, ACommand : String) : String; virtual;
|
|
procedure InitComponent; override;
|
|
public
|
|
destructor Destroy; override;
|
|
Function Execute(ACommand: String): String; virtual;
|
|
property ErrorReply : Boolean read FErrorReply;
|
|
property ErrorMessage : String read FErrorMessage;
|
|
published
|
|
property UseStdError : Boolean read FUseStdError write FUseStdError default IDRemoteUseStdErr;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
IdComponent, IdGlobal, IdIOHandlerStack, IdIOHandlerSocket,IdSimpleServer, IdTCPConnection, IdThread, SysUtils;
|
|
|
|
type
|
|
TIdStdErrThread = class(TIdThread)
|
|
protected
|
|
FStdErr : TIdSimpleServer;
|
|
FOutput : String;
|
|
public
|
|
Constructor Create(AStdErr : TIdSimpleServer; ALock : TIdCriticalSection); reintroduce;
|
|
Procedure Run; override;
|
|
property Output : String read FOutput;
|
|
end;
|
|
|
|
{ TIdRemoteCMDClient }
|
|
|
|
procedure TIdRemoteCMDClient.InitComponent;
|
|
begin
|
|
inherited;
|
|
FUseReservedPorts := IDRemoteFixPort;
|
|
FUseStdError := IDRemoteUseStdErr;
|
|
end;
|
|
|
|
destructor TIdRemoteCMDClient.Destroy;
|
|
begin
|
|
inherited;
|
|
end;
|
|
|
|
function TIdRemoteCMDClient.Execute(ACommand: String): String;
|
|
begin
|
|
Result := ''; {Do not Localize}
|
|
end;
|
|
|
|
function TIdRemoteCMDClient.InternalExec(AParam1, AParam2, ACommand: String) : String;
|
|
var
|
|
stdErr : TIdSimpleServer;
|
|
thr : TIdStdErrThread;
|
|
|
|
procedure SendAuthentication(APort : TIdPort);
|
|
begin
|
|
// Send authentication and commands
|
|
IOHandler.Write(IntToStr(APort)+#0); //stdErr Port Number - none for this session
|
|
IOHandler.Write(AParam1 + #0);
|
|
IOHandler.Write(AParam2 + #0);
|
|
IOHandler.Write(ACommand + #0);
|
|
end;
|
|
|
|
begin
|
|
Result := ''; {Do not Localize}
|
|
if FUseReservedPorts then begin
|
|
BoundPortMin := 512;
|
|
BoundPortMax := 1023;
|
|
end else begin
|
|
BoundPortMin := 0;
|
|
BoundPortMax := 0;
|
|
end;
|
|
if Socket = nil then begin
|
|
IOHandler := TIdIOHandlerStack.Create(Self);
|
|
end;
|
|
{For RSH, we have to set the port the client to connect. I don't
|
|
think it is required to this in Rexec.}
|
|
Connect;
|
|
try
|
|
if FUseStdError then begin
|
|
StdErr := TIdSimpleServer.Create(nil);
|
|
try
|
|
StdErr.BoundIP := Socket.Binding.IP;
|
|
StdErr.BoundPortMin := BoundPortMin;
|
|
StdErr.BoundPortMax := BoundPortMax;
|
|
StdErr.BeginListen;
|
|
thr := TIdStdErrThread.Create(StdErr, nil{, FLock});
|
|
try
|
|
SendAuthentication(StdErr.Binding.Port);
|
|
Thr.Start;
|
|
try
|
|
FErrorReply := (IOHandler.ReadString(1) <> #0);
|
|
{Receive answers}
|
|
BeginWork(wmRead);
|
|
try
|
|
Result := IOHandler.AllData;
|
|
finally
|
|
EndWork(wmRead);
|
|
FErrorMessage := thr.Output;
|
|
end;
|
|
finally
|
|
StdErr.Abort;
|
|
thr.Terminate;
|
|
thr.WaitFor;
|
|
end;
|
|
finally
|
|
FreeAndNil(thr);
|
|
end;
|
|
finally
|
|
FreeAndNil(StdErr);
|
|
end;
|
|
end else
|
|
begin
|
|
SendAuthentication(0);
|
|
FErrorReply := (IOHandler.ReadString(1) <> #0);
|
|
{Receive answers}
|
|
BeginWork(wmRead);
|
|
try
|
|
if FErrorReply then begin
|
|
FErrorMessage := IOHandler.AllData;
|
|
end else begin
|
|
Result := IOHandler.AllData;
|
|
end;
|
|
finally
|
|
EndWork(wmRead);
|
|
end;
|
|
end;
|
|
finally
|
|
Disconnect;
|
|
end;
|
|
end;
|
|
|
|
{ TIdStdErrThread }
|
|
|
|
constructor TIdStdErrThread.Create(AStdErr: TIdSimpleServer;
|
|
ALock: TIdCriticalSection);
|
|
begin
|
|
inherited Create(True);
|
|
FStdErr := AStdErr;
|
|
StopMode := smTerminate;
|
|
FStdErr.BeginListen;
|
|
end;
|
|
|
|
procedure TIdStdErrThread.Run;
|
|
begin
|
|
FStdErr.Listen;
|
|
FOutput := FStdErr.IOHandler.AllData;
|
|
end;
|
|
|
|
end.
|