IdRemoteCMDClient.pas 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. { $HDR$}
  2. {**********************************************************************}
  3. { Unit archived using Team Coherence }
  4. { Team Coherence is Copyright 2002 by Quality Software Components }
  5. { }
  6. { For further information / comments, visit our WEB site at }
  7. { http://www.TeamCoherence.com }
  8. {**********************************************************************}
  9. {}
  10. { $Log: 10301: IdRemoteCMDClient.pas
  11. {
  12. { Rev 1.0 2002.11.12 10:50:02 PM czhower
  13. }
  14. unit IdRemoteCMDClient;
  15. {
  16. -2001.02.15 - J. Peter Mugaas
  17. Started this unit with code originally in
  18. TIdRexec
  19. }
  20. (*******************************************************}
  21. { }
  22. { Indy Rexec Client TIdRexec }
  23. { }
  24. { Copyright (C) 2001 Indy Pit Crew }
  25. { Author J. Peter Mugaas }
  26. { Based partly on code authored by Laurence LIew }
  27. { 2001-February-15 }
  28. { }
  29. {*******************************************************)
  30. interface
  31. uses
  32. Classes,
  33. IdException, IdTCPClient,
  34. SyncObjs;
  35. const
  36. IDRemoteUseStdErr = True;
  37. {for IdRSH, we set this to. IdRexec will override this}
  38. IDRemoteFixPort = True;
  39. type
  40. EIdCanNotBindRang = class(EIdException);
  41. TIdRemoteCMDClient = class(TIdTCPClient)
  42. protected
  43. FUseReservedPorts: Boolean;
  44. FUseStdError : Boolean;
  45. FErrorMessage : String;
  46. FErrorReply : Boolean;
  47. //
  48. function InternalExec(AParam1, AParam2, ACommand : String) : String; virtual;
  49. public
  50. constructor Create(AOwner: TComponent); override;
  51. destructor Destroy; override;
  52. Function Execute(ACommand: String): String; virtual;
  53. property ErrorReply : Boolean read FErrorReply;
  54. property ErrorMessage : String read FErrorMessage;
  55. published
  56. property UseStdError : Boolean read FUseStdError write FUseStdError default IDRemoteUseStdErr;
  57. end;
  58. implementation
  59. uses
  60. IdComponent, IdGlobal, IdSimpleServer, IdTCPConnection, IdThread, IdIOHandlerSocket,
  61. SysUtils;
  62. type
  63. TIdStdErrThread = class(TIdThread)
  64. protected
  65. FStdErr : TIdSimpleServer;
  66. FOutput : String;
  67. public
  68. Constructor Create(AStdErr : TIdSimpleServer; ALock : TCriticalSection); reintroduce;
  69. Procedure Run; override;
  70. property Output : String read FOutput;
  71. end;
  72. { TIdRemoteCMDClient }
  73. constructor TIdRemoteCMDClient.Create(AOwner: TComponent);
  74. begin
  75. inherited;
  76. FUseReservedPorts := IDRemoteFixPort;
  77. FUseStdError := IDRemoteUseStdErr;
  78. end;
  79. destructor TIdRemoteCMDClient.Destroy;
  80. begin
  81. inherited;
  82. end;
  83. function TIdRemoteCMDClient.Execute(ACommand: String): String;
  84. begin
  85. Result := ''; {Do not Localize}
  86. end;
  87. function TIdRemoteCMDClient.InternalExec(AParam1, AParam2, ACommand: String) : String;
  88. var
  89. stdErr : TIdSimpleServer;
  90. thr : TIdStdErrThread;
  91. procedure SendAuthentication(APort : Integer);
  92. begin
  93. // Send authentication and commands
  94. Write(IntToStr( APort )+#0); //stdErr Port Number - none for this session
  95. Write(AParam1 + #0);
  96. Write(AParam2 + #0);
  97. Write(ACommand + #0);
  98. end;
  99. begin
  100. Result := ''; {Do not Localize}
  101. if FUseReservedPorts then begin
  102. BoundPortMin := 512;
  103. BoundPortMax := 1023;
  104. end else begin
  105. BoundPortMin := 0;
  106. BoundPortMax := 0;
  107. end;
  108. {For RSH, we have to set the port the client to connect. I don't
  109. think it is required to this in Rexec.}
  110. Connect; try
  111. if FUseStdError then begin
  112. StdErr := TIdSimpleServer.Create(nil);
  113. try
  114. StdErr.BoundIP := (IOHandler as TIdIOHandlerSocket).Binding.IP;
  115. StdErr.CreateBinding;
  116. StdErr.Binding.ClientPortMin := BoundPortMin;
  117. StdErr.Binding.ClientPortMax := BoundPortMax;
  118. StdErr.BeginListen;
  119. thr := TIdStdErrThread.Create(StdErr, nil{, FLock});
  120. SendAuthentication(StdErr.Binding.Port);
  121. Thr.Start;
  122. try
  123. FErrorReply := (ReadString(1) <> #0);
  124. {Receive answers}
  125. BeginWork(wmRead);
  126. try
  127. Result := AllData;
  128. finally
  129. EndWork(wmRead);
  130. FErrorMessage := thr.Output;
  131. end;
  132. finally
  133. StdErr.Abort;
  134. thr.Terminate;
  135. thr.WaitFor;
  136. end;
  137. finally
  138. FreeAndNil(StdErr);
  139. FreeAndNil(thr);
  140. end;
  141. end
  142. else
  143. begin
  144. SendAuthentication(0);
  145. FErrorReply := (ReadString(1) <> #0);
  146. {Receive answers}
  147. BeginWork(wmRead);
  148. try
  149. if FErrorReply then
  150. begin
  151. FErrorMessage := AllData;
  152. end
  153. else
  154. Result := AllData;
  155. finally
  156. EndWork(wmRead);
  157. end;
  158. end;
  159. finally Disconnect; end;
  160. end;
  161. { TIdStdErrThread }
  162. constructor TIdStdErrThread.Create(AStdErr: TIdSimpleServer;
  163. ALock: TCriticalSection);
  164. begin
  165. inherited Create(True);
  166. FStdErr := AStdErr;
  167. FreeOnTerminate := False;
  168. StopMode := smTerminate;
  169. FStdErr.BeginListen;
  170. end;
  171. procedure TIdStdErrThread.Run;
  172. begin
  173. if FStdErr.Listen then begin
  174. FOutput := FStdErr.AllData;
  175. end;
  176. end;
  177. end.