/indy/IdRemoteCMDClient.pas
Pascal | 223 lines | 142 code | 21 blank | 60 comment | 6 complexity | e340d020551396c04bc788ad5454d020 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception
- {
- $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;
- FreeOnTerminate := False;
- StopMode := smTerminate;
- FStdErr.BeginListen;
- end;
-
- procedure TIdStdErrThread.Run;
- begin
- FStdErr.Listen;
- FOutput := FStdErr.IOHandler.AllData;
- end;
-
- end.