IdRemoteCMDClient.pas 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. {
  2. $Project$
  3. $Workfile$
  4. $Revision$
  5. $DateUTC$
  6. $Id$
  7. This file is part of the Indy (Internet Direct) project, and is offered
  8. under the dual-licensing agreement described on the Indy website.
  9. (http://www.indyproject.org/)
  10. Copyright:
  11. (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
  12. }
  13. {
  14. $Log$
  15. }
  16. {
  17. Rev 1.7 2004.02.03 5:44:16 PM czhower
  18. Name changes
  19. Rev 1.6 2004.01.22 6:09:04 PM czhower
  20. IdCriticalSection
  21. Rev 1.5 1/21/2004 3:27:18 PM JPMugaas
  22. InitComponent
  23. Rev 1.4 4/4/2003 8:03:40 PM BGooijen
  24. fixed
  25. Rev 1.3 2/24/2003 09:32:56 PM JPMugaas
  26. Rev 1.2 1/31/2003 02:32:04 PM JPMugaas
  27. Should now compile.
  28. Rev 1.1 12/6/2002 05:30:32 PM JPMugaas
  29. Now decend from TIdTCPClientCustom instead of TIdTCPClient.
  30. Rev 1.0 11/13/2002 07:59:26 AM JPMugaas
  31. -2001.02.15 - J. Peter Mugaas
  32. Started this unit with code originally in TIdRexec
  33. }
  34. unit IdRemoteCMDClient;
  35. {
  36. Indy Rexec Client TIdRexec
  37. Copyright (C) 2001 Indy Pit Crew
  38. Author J. Peter Mugaas
  39. Based partly on code authored by Laurence LIew
  40. 2001-February-15
  41. }
  42. interface
  43. {$i IdCompilerDefines.inc}
  44. uses
  45. Classes, IdException, IdTCPClient;
  46. const
  47. IDRemoteUseStdErr = True;
  48. {for IdRSH, we set this to. IdRexec will override this}
  49. IDRemoteFixPort = True;
  50. type
  51. EIdCanNotBindRang = class(EIdException);
  52. TIdRemoteCMDClient = class(TIdTCPClientCustom)
  53. protected
  54. FUseReservedPorts: Boolean;
  55. FUseStdError : Boolean;
  56. FErrorMessage : String;
  57. FErrorReply : Boolean;
  58. //
  59. function InternalExec(AParam1, AParam2, ACommand : String) : String; virtual;
  60. public
  61. constructor Create(AOwner: TComponent); override;
  62. Function Execute(ACommand: String): String; virtual;
  63. property ErrorReply : Boolean read FErrorReply;
  64. property ErrorMessage : String read FErrorMessage;
  65. published
  66. property UseStdError : Boolean read FUseStdError write FUseStdError default IDRemoteUseStdErr;
  67. end;
  68. implementation
  69. uses
  70. IdComponent, IdGlobal, IdIOHandlerStack, IdIOHandlerSocket,IdSimpleServer, IdTCPConnection, IdThread, SysUtils;
  71. type
  72. TIdStdErrThread = class(TIdThread)
  73. protected
  74. FStdErr : TIdSimpleServer;
  75. FOutput : String;
  76. public
  77. Constructor Create(AStdErr : TIdSimpleServer; ALock : TIdCriticalSection); reintroduce;
  78. Procedure Run; override;
  79. property Output : String read FOutput;
  80. end;
  81. { TIdRemoteCMDClient }
  82. constructor TIdRemoteCMDClient.Create(AOwner: TComponent);
  83. begin
  84. inherited Create(AOwner);
  85. FUseReservedPorts := IDRemoteFixPort;
  86. FUseStdError := IDRemoteUseStdErr;
  87. end;
  88. function TIdRemoteCMDClient.Execute(ACommand: String): String;
  89. begin
  90. Result := ''; {Do not Localize}
  91. end;
  92. function TIdRemoteCMDClient.InternalExec(AParam1, AParam2, ACommand: String) : String;
  93. var
  94. stdErr : TIdSimpleServer;
  95. thr : TIdStdErrThread;
  96. procedure SendAuthentication(APort : TIdPort);
  97. begin
  98. // Send authentication and commands
  99. IOHandler.Write(IntToStr(APort)+#0); //stdErr Port Number - none for this session
  100. IOHandler.Write(AParam1 + #0);
  101. IOHandler.Write(AParam2 + #0);
  102. IOHandler.Write(ACommand + #0);
  103. end;
  104. begin
  105. Result := ''; {Do not Localize}
  106. if FUseReservedPorts then begin
  107. BoundPortMin := 512;
  108. BoundPortMax := 1023;
  109. end else begin
  110. BoundPortMin := 0;
  111. BoundPortMax := 0;
  112. end;
  113. if Socket = nil then begin
  114. IOHandler := TIdIOHandlerStack.Create(Self);
  115. end;
  116. {For RSH, we have to set the port the client to connect. I don't
  117. think it is required to this in Rexec.}
  118. Connect;
  119. try
  120. if FUseStdError then begin
  121. StdErr := TIdSimpleServer.Create(nil);
  122. try
  123. StdErr.BoundIP := Socket.Binding.IP;
  124. StdErr.BoundPortMin := BoundPortMin;
  125. StdErr.BoundPortMax := BoundPortMax;
  126. StdErr.BeginListen;
  127. thr := TIdStdErrThread.Create(StdErr, nil{, FLock});
  128. try
  129. SendAuthentication(StdErr.Binding.Port);
  130. Thr.Start;
  131. try
  132. FErrorReply := (IOHandler.ReadString(1) <> #0);
  133. {Receive answers}
  134. BeginWork(wmRead);
  135. try
  136. Result := IOHandler.AllData;
  137. finally
  138. EndWork(wmRead);
  139. FErrorMessage := thr.Output;
  140. end;
  141. finally
  142. StdErr.Abort;
  143. thr.Terminate;
  144. thr.WaitFor;
  145. end;
  146. finally
  147. thr.Free;
  148. end;
  149. finally
  150. StdErr.Free;
  151. end;
  152. end else
  153. begin
  154. SendAuthentication(0);
  155. FErrorReply := (IOHandler.ReadString(1) <> #0);
  156. {Receive answers}
  157. BeginWork(wmRead);
  158. try
  159. if FErrorReply then begin
  160. FErrorMessage := IOHandler.AllData;
  161. end else begin
  162. Result := IOHandler.AllData;
  163. end;
  164. finally
  165. EndWork(wmRead);
  166. end;
  167. end;
  168. finally
  169. Disconnect;
  170. end;
  171. end;
  172. { TIdStdErrThread }
  173. constructor TIdStdErrThread.Create(AStdErr: TIdSimpleServer;
  174. ALock: TIdCriticalSection);
  175. begin
  176. inherited Create(True);
  177. FStdErr := AStdErr;
  178. StopMode := smTerminate;
  179. FStdErr.BeginListen;
  180. end;
  181. procedure TIdStdErrThread.Run;
  182. begin
  183. FStdErr.Listen;
  184. FOutput := FStdErr.IOHandler.AllData;
  185. end;
  186. end.