home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 December / Chip_2001-12_cd1.bin / zkuste / delphi / unity / d23456 / SYNAPSE.ZIP / source / lib / FTPsend.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  2001-09-17  |  22.3 KB  |  810 lines

  1. {==============================================================================|
  2. | Project : Delphree - Synapse                                   | 001.002.000 |
  3. |==============================================================================|
  4. | Content: FTP client                                                          |
  5. |==============================================================================|
  6. | The contents of this file are Subject to the Mozilla Public License Ver. 1.1 |
  7. | (the "License"); you may not use this file except in compliance with the     |
  8. | License. You may obtain a Copy of the License at http://www.mozilla.org/MPL/ |
  9. |                                                                              |
  10. | Software distributed under the License is distributed on an "AS IS" basis,   |
  11. | WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for |
  12. | the specific language governing rights and limitations under the License.    |
  13. |==============================================================================|
  14. | The Original Code is Synapse Delphi Library.                                 |
  15. |==============================================================================|
  16. | The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
  17. | Portions created by Lukas Gebauer are Copyright (c) 1999,2000,2001.          |
  18. | All Rights Reserved.                                                         |
  19. |==============================================================================|
  20. | Contributor(s):                                                              |
  21. |   Petr Esner <petr.esner@atlas.cz>                                           |
  22. |==============================================================================|
  23. | History: see HISTORY.HTM from distribution package                           |
  24. |          (Found at URL: http://www.ararat.cz/synapse/)                       |
  25. |==============================================================================}
  26.  
  27. {$WEAKPACKAGEUNIT ON}
  28.  
  29. unit FTPsend;
  30.  
  31. interface
  32.  
  33. uses
  34.   SysUtils, Classes,
  35.   blcksock, SynaUtil, SynaCode;
  36.  
  37. const
  38.   cFtpProtocol = 'ftp';
  39.   cFtpDataProtocol = 'ftp-data';
  40.  
  41.   FTP_OK = 255;
  42.   FTP_ERR = 254;
  43.  
  44. type
  45.   TLogonActions = array [0..17] of byte;
  46.  
  47.   TFTPStatus = procedure(Sender: TObject; Response: Boolean;
  48.     const Value: string) of object;
  49.  
  50.   TFTPSend = class(TObject)
  51.   private
  52.     FOnStatus: TFTPStatus;
  53.     FSock: TTCPBlockSocket;
  54.     FDSock: TTCPBlockSocket;
  55.     FTimeout: Integer;
  56.     FFTPHost: string;
  57.     FFTPPort: string;
  58.     FResultCode: Integer;
  59.     FResultString: string;
  60.     FFullResult: TStringList;
  61.     FUsername: string;
  62.     FPassword: string;
  63.     FAccount: string;
  64.     FFWHost: string;
  65.     FFWPort: string;
  66.     FFWUsername: string;
  67.     FFWPassword: string;
  68.     FFWMode: integer;
  69.     FDataStream: TMemoryStream;
  70.     FDataIP: string;
  71.     FDataPort: string;
  72.     FDirectFile: Boolean;
  73.     FDirectFileName: string;
  74.     FCanResume: Boolean;
  75.     FPassiveMode: Boolean;
  76.     FForceDefaultPort: Boolean;
  77.     function Auth(Mode: integer): Boolean;
  78.     function Connect: Boolean;
  79.     function InternalStor(const Command: string; RestoreAt: integer): Boolean;
  80.     function DataSocket: Boolean;
  81.     function AcceptDataSocket: Boolean;
  82.     function DataRead(const DestStream: TStream): Boolean;
  83.     function DataWrite(const SourceStream: TStream): Boolean;
  84.   protected
  85.     procedure DoStatus(Response: Boolean; const Value: string);
  86.   public
  87.     CustomLogon: TLogonActions;
  88.     constructor Create;
  89.     destructor Destroy; override;
  90.     function ReadResult: Integer;
  91.     procedure ParseRemote(Value: string);
  92.     function FTPCommand(const Value: string): integer;
  93.     function Login: Boolean;
  94.     procedure Logout;
  95.     function List(Directory: string; NameList: Boolean): Boolean;
  96.     function RetriveFile(const FileName: string; Restore: Boolean): Boolean;
  97.     function StoreFile(const FileName: string; Restore: Boolean): Boolean;
  98.     function StoreUniqueFile: Boolean;
  99.     function AppendFile(const FileName: string): Boolean;
  100.     function RenameFile(const OldName, NewName: string): Boolean;
  101.     function DeleteFile(const FileName: string): Boolean;
  102.     function FileSize(const FileName: string): integer;
  103.     function NoOp: Boolean;
  104.     function ChangeWorkingDir(const Directory: string): Boolean;
  105.     function ChangeToRootDir: Boolean;
  106.     function DeleteDir(const Directory: string): Boolean;
  107.     function CreateDir(const Directory: string): Boolean;
  108.     function GetCurrentDir: String;
  109.   published
  110.     property Timeout: Integer read FTimeout Write FTimeout;
  111.     property FTPHost: string read FFTPHost Write FFTPHost;
  112.     property FTPPort: string read FFTPPort Write FFTPPort;
  113.     property ResultCode: Integer read FResultCode;
  114.     property ResultString: string read FResultString;
  115.     property FullResult: TStringList read FFullResult;
  116.     property Username: string read FUsername Write FUsername;
  117.     property Password: string read FPassword Write FPassword;
  118.     property Account: string read FAccount Write FAccount;
  119.     property FWHost: string read FFWHost Write FFWHost;
  120.     property FWPort: string read FFWPort Write FFWPort;
  121.     property FWUsername: string read FFWUsername Write FFWUsername;
  122.     property FWPassword: string read FFWPassword Write FFWPassword;
  123.     property FWMode: integer read FFWMode Write FFWMode;
  124.     property Sock: TTCPBlockSocket read FSock;
  125.     property DSock: TTCPBlockSocket read FDSock;
  126.     property DataStream: TMemoryStream read FDataStream;
  127.     property DataIP: string read FDataIP;
  128.     property DataPort: string read FDataPort;
  129.     property DirectFile: Boolean read FDirectFile Write FDirectFile;
  130.     property DirectFileName: string read FDirectFileName Write FDirectFileName;
  131.     property CanResume: Boolean read FCanResume;
  132.     property PassiveMode: Boolean read FPassiveMode Write FPassiveMode;
  133.     property ForceDefaultPort: Boolean read FForceDefaultPort Write FForceDefaultPort;
  134.     property OnStatus: TFTPStatus read FOnStatus write FOnStatus;
  135.   end;
  136.  
  137. function FtpGetFile(const IP, Port, FileName, LocalFile,
  138.   User, Pass: string): Boolean;
  139. function FtpPutFile(const IP, Port, FileName, LocalFile,
  140.   User, Pass: string): Boolean;
  141. function FtpInterServerTransfer(
  142.   const FromIP, FromPort, FromFile, FromUser, FromPass: string;
  143.   const ToIP, ToPort, ToFile, ToUser, ToPass: string): Boolean;
  144.  
  145. implementation
  146.  
  147. const
  148.   CRLF = #13#10;
  149.  
  150. constructor TFTPSend.Create;
  151. begin
  152.   inherited Create;
  153.   FFullResult := TStringList.Create;
  154.   FDataStream := TMemoryStream.Create;
  155.   FSock := TTCPBlockSocket.Create;
  156.   FDSock := TTCPBlockSocket.Create;
  157.   FTimeout := 300000;
  158.   FFTPHost := cLocalhost;
  159.   FFTPPort := cFtpProtocol;
  160.   FUsername := 'anonymous';
  161.   FPassword := 'anonymous@' + FSock.LocalName;
  162.   FDirectFile := False;
  163.   FPassiveMode := True;
  164.   FForceDefaultPort := False;
  165.   FAccount := '';
  166.   FFWHost := '';
  167.   FFWPort := cFtpProtocol;
  168.   FFWUsername := '';
  169.   FFWPassword := '';
  170.   FFWMode := 0;
  171. end;
  172.  
  173. destructor TFTPSend.Destroy;
  174. begin
  175.   FDSock.Free;
  176.   FSock.Free;
  177.   FDataStream.Free;
  178.   FFullResult.Free;
  179.   inherited Destroy;
  180. end;
  181.  
  182. procedure TFTPSend.DoStatus(Response: Boolean; const Value: string);
  183. begin
  184.   if assigned(OnStatus) then
  185.     OnStatus(Self, Response, Value);
  186. end;
  187.  
  188. function TFTPSend.ReadResult: Integer;
  189. var
  190.   s,c: string;
  191. begin
  192.   Result := 0;
  193.   FFullResult.Clear;
  194.   c := '';
  195.   repeat
  196.     s := FSock.RecvString(FTimeout);
  197.     if c = '' then
  198.       c :=Copy(s, 1, 3)+' ';
  199.     FResultString := s;
  200.     FFullResult.Add(s);
  201.     if FSock.LastError <> 0 then
  202.       Break;
  203.   until Pos(c, s) = 1;
  204.   s := FFullResult[0];
  205.   if Length(s) >= 3 then
  206.     Result := StrToIntDef(Copy(s, 1, 3), 0);
  207.   FResultCode := Result;
  208. end;
  209.  
  210. function TFTPSend.FTPCommand(const Value: string): integer;
  211. begin
  212.   FSock.SendString(Value + CRLF);
  213.   DoStatus(False, Value);
  214.   Result := ReadResult;
  215.   DoStatus(True, FResultString);
  216. end;
  217.  
  218. // based on idea by Petr Esner <petr.esner@atlas.cz>
  219. function TFTPSend.Auth(Mode: integer): Boolean;
  220. const
  221.   // Direct connection USER[+PASS[+ACCT]]
  222.   Action0: TLogonActions =
  223.     (0, FTP_OK, 3, 1, FTP_OK, 6, 2, FTP_OK, FTP_ERR, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  224.   // SITE <hostname>
  225.   Action1: TLogonActions =
  226.     (3, 6, 3, 4, 6, FTP_ERR, 5, FTP_ERR, 9, 0, FTP_OK, 12, 1, FTP_OK, 15, 2,
  227.     FTP_OK, FTP_ERR);
  228.   // USER after logon
  229.   Action2: TLogonActions =
  230.     (3, 6, 3, 4, 6, FTP_ERR, 6, FTP_OK, 9, 1, FTP_OK, 12, 2, FTP_OK, FTP_ERR,
  231.      0, 0, 0);
  232.   // Transparent
  233.   Action3: TLogonActions =
  234.     (3, 6, 3, 4, 6, FTP_ERR, 0, FTP_OK, 9, 1, FTP_OK, 12, 2, FTP_OK, FTP_ERR,
  235.      0, 0, 0);
  236.   // proxy OPEN
  237.   Action4: TLogonActions =
  238.     (7, 3, 3, 0, FTP_OK, 6, 1, FTP_OK, 9, 2, FTP_OK, FTP_ERR,
  239.      0, 0, 0, 0, 0, 0);
  240.   // USER with no logon
  241.   Action5: TLogonActions =
  242.     (6, FTP_OK, 3, 1, FTP_OK, 6, 2, FTP_OK, FTP_ERR, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  243.   // USER fireID@remotehost
  244.   Action6: TLogonActions =
  245.     (8, 6, 3, 4, 6, FTP_ERR, 0, FTP_OK, 9, 1, FTP_OK, 12, 2, FTP_OK, FTP_ERR,
  246.      0, 0, 0);
  247.   // USER remoteID@remotehost fireID
  248.   Action7: TLogonActions =
  249.     (9, FTP_ERR, 3, 1, FTP_OK, 6, 2, FTP_OK, FTP_ERR, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  250.   // USER remoteID@fireID@remotehost
  251.   Action8: TLogonActions =
  252.     (10, FTP_OK, 3, 11, FTP_OK, 6, 2, FTP_OK, FTP_ERR, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  253. var
  254.   FTPServer: string;
  255.   LogonActions: TLogonActions;
  256.   i: integer;
  257.   s: string;
  258.   x: integer;
  259. begin
  260.   Result := False;
  261.   if FFWHost = '' then
  262.     Mode := 0;
  263.   if (FFTPPort = cFtpProtocol) or (FFTPPort = '21') then
  264.     FTPServer := FFTPHost
  265.   else
  266.     FTPServer := FFTPHost + ':' + FFTPPort;
  267.   case Mode of
  268.     -1:
  269.       LogonActions := CustomLogon;
  270.     1:
  271.       LogonActions := Action1;
  272.     2:
  273.       LogonActions := Action2;
  274.     3:
  275.       LogonActions := Action3;
  276.     4:
  277.       LogonActions := Action4;
  278.     5:
  279.       LogonActions := Action5;
  280.     6:
  281.       LogonActions := Action6;
  282.     7:
  283.       LogonActions := Action7;
  284.     8:
  285.       LogonActions := Action8;
  286.   else
  287.     LogonActions := Action0;
  288.   end;
  289.   i := 0;
  290.   repeat
  291.     case LogonActions[i] of
  292.       0:  s := 'USER ' + FUserName;
  293.       1:  s := 'PASS ' + FPassword;
  294.       2:  s := 'ACCT ' + FAccount;
  295.       3:  s := 'USER ' + FFWUserName;
  296.       4:  s := 'PASS ' + FFWPassword;
  297.       5:  s := 'SITE ' + FTPServer;
  298.       6:  s := 'USER ' + FUserName + '@' + FTPServer;
  299.       7:  s := 'OPEN ' + FTPServer;
  300.       8:  s := 'USER ' + FFWUserName + '@' + FTPServer;
  301.       9:  s := 'USER ' + FUserName + '@' + FTPServer + ' ' + FFWUserName;
  302.       10: s := 'USER ' + FUserName + '@' + FFWUserName + '@' + FTPServer;
  303.       11: s := 'PASS ' + FPassword + '@' + FFWPassword;
  304.     end;
  305.     x := FTPCommand(s);
  306.     x := x div 100;
  307.     if (x <> 2) and (x <> 3) then
  308.       Exit;
  309.     i := LogonActions[i + x - 1];
  310.     case i of
  311.       FTP_ERR:
  312.         Exit;
  313.       FTP_OK:
  314.         begin
  315.           Result := True;
  316.           Exit;
  317.         end;
  318.     end;
  319.   until False;
  320. end;
  321.  
  322.  
  323. function TFTPSend.Connect: Boolean;
  324. begin
  325.   FSock.CloseSocket;
  326.   FSock.CreateSocket;
  327.   if FFWHost = '' then
  328.     FSock.Connect(FFTPHost, FFTPPort)
  329.   else
  330.     FSock.Connect(FFWHost, FFWPort);
  331.   Result := FSock.LastError = 0;
  332. end;
  333.  
  334. function TFTPSend.Login: Boolean;
  335. begin
  336.   Result := False;
  337.   FCanResume := False;
  338.   if not Connect then
  339.     Exit;
  340.   if ReadResult <> 220 then
  341.     Exit;
  342.   if not Auth(FFWMode) then
  343.     Exit;
  344.   FTPCommand('TYPE I');
  345.   FTPCommand('STRU F');
  346.   FTPCommand('MODE S');
  347.   if FTPCommand('REST 1') = 350 then
  348.   begin
  349.     FTPCommand('REST 0');
  350.     FCanResume := True;
  351.   end;
  352.   Result := True;
  353. end;
  354.  
  355. procedure TFTPSend.Logout;
  356. begin
  357.   FTPCommand('QUIT');
  358.   FSock.CloseSocket;
  359. end;
  360.  
  361. procedure TFTPSend.ParseRemote(Value: string);
  362. var
  363.   n: integer;
  364.   nb, ne: integer;
  365.   s: string;
  366.   x: integer;
  367. begin
  368.   Value := trim(Value);
  369.   nb := Pos('(',Value);
  370.   ne := Pos(')',Value);
  371.   if (nb = 0) or (ne = 0) then
  372.   begin
  373.     nb:=RPos(' ',Value);
  374.     s:=Copy(Value, nb + 1, Length(Value) - nb);
  375.   end
  376.   else
  377.   begin
  378.     s:=Copy(Value,nb+1,ne-nb-1);
  379.   end;
  380.   for n := 1 to 4 do
  381.     if n = 1 then
  382.       FDataIP := Fetch(s, ',')
  383.     else
  384.       FDataIP := FDataIP + '.' + Fetch(s, ',');
  385.   x := StrToIntDef(Fetch(s, ','), 0) * 256;
  386.   x := x + StrToIntDef(Fetch(s, ','), 0);
  387.   FDataPort := IntToStr(x);
  388. end;
  389.  
  390. function TFTPSend.DataSocket: boolean;
  391. var
  392.   s: string;
  393. begin
  394.   Result := False;
  395.   if FPassiveMode then
  396.   begin
  397.     if FTPCommand('PASV') <> 227 then
  398.       Exit;
  399.     ParseRemote(FResultString);
  400.     FDSock.CloseSocket;
  401.     FDSock.CreateSocket;
  402.     FDSock.Connect(FDataIP, FDataPort);
  403.     Result := FDSock.LastError = 0;
  404.   end
  405.   else
  406.   begin
  407.     FDSock.CloseSocket;
  408.     FDSock.CreateSocket;
  409.     if FForceDefaultPort then
  410.       s := cFtpDataProtocol
  411.     else
  412.       s := '0';
  413.     FDSock.Bind(FDSock.LocalName, s);
  414.     if FDSock.LastError <> 0 then
  415.       Exit;
  416.     FDSock.Listen;
  417.     FDSock.GetSins;
  418.     FDataIP := FDSock.GetLocalSinIP;
  419.     FDataIP := FDSock.ResolveName(FDataIP);
  420.     FDataPort := IntToStr(FDSock.GetLocalSinPort);
  421.     s := StringReplace(FDataIP, '.', ',');
  422.     s := 'PORT ' + s + ',' + IntToStr(FDSock.GetLocalSinPort div 256)
  423.       + ',' + IntToStr(FDSock.GetLocalSinPort mod 256);
  424.     Result := FTPCommand(s) = 200;
  425.   end;
  426. end;
  427.  
  428. function TFTPSend.AcceptDataSocket: Boolean;
  429. var
  430.   x: integer;
  431. begin
  432.   if FPassiveMode then
  433.     Result := True
  434.   else
  435.   begin
  436.     Result := False;
  437.     if FDSock.CanRead(FTimeout) then
  438.     begin
  439.       x := FDSock.Accept;
  440.       if not FDSock.UsingSocks then
  441.         FDSock.CloseSocket;
  442.       FDSock.Socket := x;
  443.       Result := True;
  444.     end;
  445.   end;
  446. end;
  447.  
  448. function TFTPSend.DataRead(const DestStream: TStream): Boolean;
  449. var
  450.   x: integer;
  451.   buf: string;
  452. begin
  453.   Result := False;
  454.   try
  455.     if not AcceptDataSocket then
  456.       Exit;
  457.     repeat
  458.       buf := FDSock.RecvPacket(FTimeout);
  459.       if FDSock.LastError = 0 then
  460.         DestStream.Write(Pointer(buf)^, Length(buf));
  461.     until FDSock.LastError <> 0;
  462.     x := ReadResult;
  463.     if (x = 226) or (x = 250) then
  464.       Result := True;
  465.   finally
  466.     FDSock.CloseSocket;
  467.   end;
  468. end;
  469.  
  470. function TFTPSend.DataWrite(const SourceStream: TStream): Boolean;
  471. const
  472.   BufSize = 8192;
  473. var
  474.   Bytes: integer;
  475.   bc, lb: integer;
  476.   n, x: integer;
  477.   Buf: string;
  478. begin
  479.   Result := False;
  480.   try
  481.     if not AcceptDataSocket then
  482.       Exit;
  483.     Bytes := SourceStream.Size - SourceStream.Position;
  484.     bc := Bytes div BufSize;
  485.     lb := Bytes mod BufSize;
  486.     SetLength(Buf, BufSize);
  487.     for n := 1 to bc do
  488.     begin
  489.       SourceStream.read(Pointer(buf)^, BufSize);
  490.       FDSock.SendBuffer(Pchar(buf), BufSize);
  491.       if FDSock.LastError <> 0 then
  492.         Exit;
  493.     end;
  494.     SetLength(Buf, lb);
  495.     SourceStream.read(Pointer(buf)^, lb);
  496.     FDSock.SendBuffer(Pchar(buf), lb);
  497.     if FDSock.LastError <> 0 then
  498.       Exit;
  499.     FDSock.CloseSocket;
  500.     x := ReadResult;
  501.     if (x = 226) or (x = 250) then
  502.       Result := True;
  503.   finally
  504.     FDSock.CloseSocket;
  505.   end;
  506. end;
  507.  
  508. function TFTPSend.List(Directory: string; NameList: Boolean): Boolean;
  509. begin
  510.   Result := False;
  511.   FDataStream.Clear;
  512.   if Directory <> '' then
  513.     Directory := ' ' + Directory;
  514.   if not DataSocket then
  515.     Exit;
  516.   FTPCommand('TYPE A');
  517.   if NameList then
  518.     FTPCommand('NLST' + Directory)
  519.   else
  520.     FTPCommand('LIST' + Directory);
  521.   Result := DataRead(FDataStream);
  522.   FDataStream.Seek(0, soFromBeginning);
  523. end;
  524.  
  525. function TFTPSend.RetriveFile(const FileName: string; Restore: Boolean): Boolean;
  526. var
  527.   RetrStream: TStream;
  528. begin
  529.   Result := False;
  530.   if FileName = '' then
  531.     Exit;
  532.   Restore := Restore and FCanResume;
  533.   if FDirectFile then
  534.     if Restore and FileExists(FDirectFileName) then
  535.       RetrStream := TFileStream.Create(FDirectFileName,
  536.         fmOpenReadWrite     or fmShareExclusive)
  537.     else
  538.       RetrStream := TFileStream.Create(FDirectFileName,
  539.         fmCreate or fmShareDenyWrite)
  540.   else
  541.     RetrStream := FDataStream;
  542.   try
  543.     if not DataSocket then
  544.       Exit;
  545.     FTPCommand('TYPE I');
  546.     if Restore then
  547.     begin
  548.       RetrStream.Seek(0, soFromEnd);
  549.       if FTPCommand('REST ' + IntToStr(RetrStream.Size)) <> 350 then
  550.         Exit;
  551.     end
  552.     else
  553.       if RetrStream is TMemoryStream then
  554.         TMemoryStream(RetrStream).Clear;
  555.     if (FTPCommand('RETR ' + FileName) div 100) <> 1 then
  556.       Exit;
  557.     Result := DataRead(RetrStream);
  558.     if not FDirectFile then
  559.       RetrStream.Seek(0, soFromBeginning);
  560.   finally
  561.     if FDirectFile then
  562.       RetrStream.Free;
  563.   end;
  564. end;
  565.  
  566. function TFTPSend.InternalStor(const Command: string; RestoreAt: integer): Boolean;
  567. var
  568.   SendStream: TStream;
  569.   StorSize: integer;
  570. begin
  571.   Result := False;
  572.   if FDirectFile then
  573.     if not FileExists(FDirectFileName) then
  574.       Exit
  575.     else
  576.       SendStream := TFileStream.Create(FDirectFileName,
  577.         fmOpenRead or fmShareDenyWrite)
  578.   else
  579.     SendStream := FDataStream;
  580.   try
  581.     if not DataSocket then
  582.       Exit;
  583.     FTPCommand('TYPE I');
  584.     StorSize := SendStream.Size;
  585.     if not FCanResume then
  586.       RestoreAt := 0;
  587.     if RestoreAt = StorSize then
  588.     begin
  589.       Result := True;
  590.       Exit;
  591.     end;
  592.     if RestoreAt > StorSize then
  593.       RestoreAt := 0;
  594.     FTPCommand('ALLO ' + IntToStr(StorSize - RestoreAt));
  595.     if FCanResume then
  596.       if FTPCommand('REST ' + IntToStr(RestoreAt)) <> 350 then
  597.         Exit;
  598.     SendStream.Seek(RestoreAt, soFromBeginning);
  599.     if (FTPCommand(Command) div 100) <> 1 then
  600.       Exit;
  601.     Result := DataWrite(SendStream);
  602.   finally
  603.     if FDirectFile then
  604.       SendStream.Free;
  605.   end;
  606. end;
  607.  
  608. function TFTPSend.StoreFile(const FileName: string; Restore: Boolean): Boolean;
  609. var
  610.   RestoreAt: integer;
  611. begin
  612.   Result := False;
  613.   if FileName = '' then
  614.     Exit;
  615.   RestoreAt := 0;
  616.   Restore := Restore and FCanResume;
  617.   if Restore then
  618.   begin
  619.     RestoreAt := Self.FileSize(FileName);
  620.     if RestoreAt < 0 then
  621.       RestoreAt := 0;
  622.   end;
  623.   Result := InternalStor('STOR ' + FileName, RestoreAt);
  624. end;
  625.  
  626. function TFTPSend.StoreUniqueFile: Boolean;
  627. begin
  628.   Result := InternalStor('STOU', 0);
  629. end;
  630.  
  631. function TFTPSend.AppendFile(const FileName: string): Boolean;
  632. begin
  633.   Result := False;
  634.   if FileName = '' then
  635.     Exit;
  636.   Result := InternalStor('APPE '+FileName, 0);
  637. end;
  638.  
  639. function TFTPSend.NoOp: Boolean;
  640. begin
  641.   Result := FTPCommand('NOOP') = 250;
  642. end;
  643.  
  644. function TFTPSend.RenameFile(const OldName, NewName: string): Boolean;
  645. begin
  646.   Result := False;
  647.   if FTPCommand('RNFR ' + OldName) <> 350 then
  648.     Exit;
  649.   Result := FTPCommand('RNTO ' + NewName) = 250;
  650. end;
  651.  
  652. function TFTPSend.DeleteFile(const FileName: string): Boolean;
  653. begin
  654.   Result := FTPCommand('DELE ' + FileName) = 250;
  655. end;
  656.  
  657. function TFTPSend.FileSize(const FileName: string): integer;
  658. var
  659.   s: string;
  660. begin
  661.   Result := -1;
  662.   if FTPCommand('SIZE ' + FileName) = 213 then
  663.   begin
  664.     s := SeparateRight(ResultString, ' ');
  665.     s := SeparateLeft(s, ' ');
  666.     Result := StrToIntDef(s, -1);
  667.   end;
  668. end;
  669.  
  670. function TFTPSend.ChangeWorkingDir(const Directory: string): Boolean;
  671. begin
  672.   Result := FTPCommand('CWD ' + Directory) = 250;
  673. end;
  674.  
  675. function TFTPSend.ChangeToRootDir: Boolean;
  676. begin
  677.   Result := FTPCommand('CDUP') = 200;
  678. end;
  679.  
  680. function TFTPSend.DeleteDir(const Directory: string): Boolean;
  681. begin
  682.   Result := FTPCommand('RMD ' + Directory) = 250;
  683. end;
  684.  
  685. function TFTPSend.CreateDir(const Directory: string): Boolean;
  686. begin
  687.   Result := FTPCommand('MKD ' + Directory) = 257;
  688. end;
  689.  
  690. function TFTPSend.GetCurrentDir: String;
  691. begin
  692.   Result := '';
  693.   if FTPCommand('PWD') = 257 then
  694.   begin
  695.     Result := SeparateRight(FResultString, '"');
  696.     Result := Separateleft(Result, '"');
  697.   end;
  698. end;
  699.  
  700. {==============================================================================}
  701.  
  702. function FtpGetFile(const IP, Port, FileName, LocalFile,
  703.   User, Pass: string): Boolean;
  704. begin
  705.   Result := False;
  706.   with TFTPSend.Create do
  707.   try
  708.     if User <> '' then
  709.     begin
  710.       Username := User;
  711.       Password := Pass;
  712.     end;
  713.     FTPHost := IP;
  714.     FTPPort := Port;
  715.     if not Login then
  716.       Exit;
  717.     DirectFileName := LocalFile;
  718.     DirectFile:=True;
  719.     Result := RetriveFile(FileName, False);
  720.     Logout;
  721.   finally
  722.     Free;
  723.   end;
  724. end;
  725.  
  726. function FtpPutFile(const IP, Port, FileName, LocalFile,
  727.   User, Pass: string): Boolean;
  728. begin
  729.   Result := False;
  730.   with TFTPSend.Create do
  731.   try
  732.     if User <> '' then
  733.     begin
  734.       Username := User;
  735.       Password := Pass;
  736.     end;
  737.     FTPHost := IP;
  738.     FTPPort := Port;
  739.     if not Login then
  740.       Exit;
  741.     DirectFileName := LocalFile;
  742.     DirectFile:=True;
  743.     Result := StoreFile(FileName, False);
  744.     Logout;
  745.   finally
  746.     Free;
  747.   end;
  748. end;
  749.  
  750. function FtpInterServerTransfer(
  751.   const FromIP, FromPort, FromFile, FromUser, FromPass: string;
  752.   const ToIP, ToPort, ToFile, ToUser, ToPass: string): Boolean;
  753. var
  754.   FromFTP, ToFTP: TFTPSend;
  755.   s: string;
  756.   x: integer;
  757. begin
  758.   Result := False;
  759.   FromFTP := TFTPSend.Create;
  760.   toFTP := TFTPSend.Create;
  761.   try
  762.     if FromUser <> '' then
  763.     begin
  764.       FromFTP.Username := FromUser;
  765.       FromFTP.Password := FromPass;
  766.     end;
  767.     if ToUser <> '' then
  768.     begin
  769.       ToFTP.Username := ToUser;
  770.       ToFTP.Password := ToPass;
  771.     end;
  772.     FromFTP.FTPHost := FromIP;
  773.     FromFTP.FTPPort := FromPort;
  774.     ToFTP.FTPHost := ToIP;
  775.     ToFTP.FTPPort := ToPort;
  776.     if not FromFTP.Login then
  777.       Exit;
  778.     if not ToFTP.Login then
  779.       Exit;
  780.     if FromFTP.FTPCommand('PASV') <> 227 then
  781.       Exit;
  782.     FromFTP.ParseRemote(FromFTP.ResultString);
  783.     s := StringReplace(FromFTP.DataIP, '.', ',');
  784.     s := 'PORT ' + s + ',' + IntToStr(StrToIntDef(FromFTP.DataPort, 0) div 256)
  785.       + ',' + IntToStr(StrToIntDef(FromFTP.DataPort, 0) mod 256);
  786.     if ToFTP.FTPCommand(s) <> 200 then
  787.       Exit;
  788.     x := FromFTP.FTPCommand('STOR ' + FromFile);
  789.     if (x <> 125) and (x <> 150) then
  790.       Exit;
  791.     x := ToFTP.FTPCommand('RETR ' + ToFile);
  792.     if (x <> 125) and (x <> 150) then
  793.       Exit;
  794.     FromFTP.Timeout := 21600000;
  795.     x := FromFTP.ReadResult;
  796.     if (x <> 226) and (x <> 250) then
  797.       Exit;
  798.     ToFTP.Timeout := 21600000;
  799.     x := ToFTP.ReadResult;
  800.     if (x <> 226) and (x <> 250) then
  801.       Exit;
  802.     Result := True;
  803.   finally
  804.     ToFTP.Free;
  805.     FromFTP.Free;
  806.   end;
  807. end;
  808.  
  809. end.
  810.