IdRemoteCMDServer.pas 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  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.5 12/2/2004 4:23:58 PM JPMugaas
  18. Adjusted for changes in Core.
  19. Rev 1.4 2004.02.03 5:44:16 PM czhower
  20. Name changes
  21. Rev 1.3 4/4/2003 8:03:40 PM BGooijen
  22. fixed
  23. Rev 1.2 2/24/2003 09:33:00 PM JPMugaas
  24. Rev 1.1 1/31/2003 02:32:08 PM JPMugaas
  25. Should now compile.
  26. Rev 1.0 11/13/2002 07:59:32 AM JPMugaas
  27. 2001, Feb 17
  28. started this unit with code from TIdRexecServer
  29. }
  30. unit IdRemoteCMDServer;
  31. interface
  32. {$i IdCompilerDefines.inc}
  33. uses
  34. IdContext,IdTCPClient, IdCustomTCPServer;
  35. type
  36. TIdRemoteCMDServer = class(TIdCustomTCPServer)
  37. protected
  38. FForcePortsInRange : Boolean;
  39. FStdErrorPortsInRange : Boolean;
  40. function DoExecute(AThread: TIdContext): boolean; override;
  41. procedure DoCMD(AThread: TIdContext; AStdError : TIdTCPClient;
  42. AParam1, AParam2, ACommand : String); virtual; abstract;
  43. public
  44. procedure SendError(AThread : TIdContext;AStdErr : TIdTCPClient; AMsg : String);
  45. procedure SendResults(AThread : TIdContext; AStdErr : TIdTCPClient; AMsg : String);
  46. end;
  47. implementation
  48. uses
  49. IdSocketHandle, IdGlobal, IdIOHandlerStack, IdIOHandlerSocket, IdStack, SysUtils;
  50. { TIdRemoteCMDServer }
  51. function TIdRemoteCMDServer.DoExecute(AThread: TIdContext): boolean;
  52. var
  53. StdError : TIdTCPClient;
  54. ErrorPort : TIdPort;
  55. Param1, Param2, Command : String;
  56. procedure ExecuteCMD;
  57. begin
  58. Result := True;
  59. StdError := nil;
  60. try
  61. ErrorPort := IndyStrToInt(AThread.Connection.IOHandler.ReadLn(#0), 0);
  62. if ErrorPort <> 0 then
  63. begin
  64. StdError := TIdTCPClient.Create(nil);
  65. if FStdErrorPortsInRange then
  66. begin
  67. StdError.BoundPortMin := 512;
  68. StdError.BoundPortMax := 1023;
  69. end;
  70. StdError.BoundIP := AThread.Connection.Socket.Binding.IP;
  71. StdError.Host := AThread.Connection.Socket.Binding.PeerIP;
  72. StdError.Port := ErrorPort;
  73. repeat
  74. try
  75. StdError.Connect;
  76. Break;
  77. except
  78. on E: EIdSocketError do begin
  79. // This will be uncommented after we have the fix into TIdTCPClient.Connect method
  80. // There is one extra line that has to be added in order to run this code
  81. //
  82. // except
  83. // // This will free IOHandler
  84. // BoundPort := TIdIOHandlerSocket(IOHandler).Binding.Port; // The extra line
  85. // DisconnectSocket;
  86. // raise;
  87. // end;
  88. //
  89. // After we have this code we will know the exact Port on wich the exception has occured
  90. {if E.LastError = 10048 then begin
  91. StdError.BoundPortMax := StdError.BoundPort - 1;
  92. StdError.BoundPort := 0;
  93. StdError.Disconnect;
  94. end
  95. else}
  96. raise;
  97. end;
  98. end;
  99. until False;
  100. end;
  101. Param1 := AThread.Connection.IOHandler.ReadLn(#0);
  102. Param2 := AThread.Connection.IOHandler.ReadLn(#0);
  103. Command := AThread.Connection.IOHandler.ReadLn(#0);
  104. DoCMD(AThread, StdError, Param1, Param2, Command);
  105. if Assigned(StdError) then
  106. begin
  107. StdError.Disconnect;
  108. end;
  109. finally
  110. StdError.Free;
  111. end;
  112. end;
  113. begin
  114. if FForcePortsInRange then begin
  115. if (AThread.Connection.Socket.Binding.Port >= 512) or
  116. (AThread.Connection.Socket.Binding.Port <= 1023) then
  117. begin
  118. ExecuteCMD;
  119. end;
  120. end
  121. else begin
  122. ExecuteCMD;
  123. end;
  124. AThread.Connection.Disconnect;
  125. Result := False;// DoExecute does not have to be called again
  126. end;
  127. procedure TIdRemoteCMDServer.SendError(AThread: TIdContext;
  128. AStdErr: TIdTCPClient; AMsg: String);
  129. begin
  130. AThread.Connection.IOHandler.Write(#1);
  131. if Assigned(AStdErr) then begin
  132. AStdErr.IOHandler.Write(AMsg);
  133. end else begin
  134. AThread.Connection.IOHandler.Write(AMsg);
  135. end;
  136. end;
  137. procedure TIdRemoteCMDServer.SendResults(AThread: TIdContext;
  138. AStdErr: TIdTCPClient; AMsg: String);
  139. begin
  140. AThread.Connection.IOHandler.Write(#0 + AMsg)
  141. end;
  142. end.