/ProSnooperFx_src/indy10.0.52_source/Protocols/IdFTP.pas
Pascal | 3570 lines | 2455 code | 217 blank | 898 comment | 270 complexity | 8f38ef32b852a662d62336598357674d MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- { $HDR$}
- {**********************************************************************}
- { Unit archived using Team Coherence }
- { Team Coherence is Copyright 2002 by Quality Software Components }
- { }
- { For further information / comments, visit our WEB site at }
- { http://www.TeamCoherence.com }
- {**********************************************************************}
- {}
- { $Log: 13828: IdFTP.pas
- {
- { Rev 1.102 11/5/2004 1:54:42 AM JPMugaas
- { Minor adjustment - should not detect TitanFTPD better (tested at:
- { ftp.southrivertech.com).
- {
- { If MLSD is being used, SITE ZONE will not be issued. It's not needed because
- { the MLSD spec indicates the time is based on GMT.
- }
- {
- { Rev 1.101 10/27/2004 12:58:08 AM JPMugaas
- { Improvement from Tobias Giesen http://www.superflexible.com
- { His notation is below:
- {
- { "here's a fix for TIdFTP.IndexOfFeatLine. It does not work the
- { way it is used in TIdFTP.SetModTime, because it only
- { compares the first word of the FeatLine."
- }
- {
- { Rev 1.100 10/26/2004 9:19:10 PM JPMugaas
- { Fixed references.
- }
- {
- { Rev 1.99 9/16/2004 3:24:04 AM JPMugaas
- { TIdFTP now compresses to the IOHandler and decompresses from the IOHandler.
- {
- { Noted some that the ZLib code is based was taken from ZLibEx.
- }
- {
- { Rev 1.98 9/13/2004 12:15:42 AM JPMugaas
- { Now should be able to handle some values better as suggested by Michael J.
- { Leave.
- }
- {
- { Rev 1.97 9/11/2004 10:58:06 AM JPMugaas
- { FTP now decompresses output directly to the IOHandler.
- }
- {
- { Rev 1.96 9/10/2004 7:37:42 PM JPMugaas
- { Fixed a bug. We needed to set Passthrough instead of calling StartSSL. This
- { was causing a SSL problem with upload.
- }
- {
- { Rev 1.95 8/2/04 5:56:16 PM RLebeau
- { Tweaks to TIdFTP.InitDataChannel()
- }
- {
- Rev 1.94 7/30/2004 1:55:04 AM DSiders
- Corrected DoOnRetrievedDir naming.
- }
- {
- Rev 1.93 7/30/2004 12:36:32 AM DSiders
- Corrected spelling in OnRetrievedDir, DoOnRetrievedDir declarations.
- }
- {
- { Rev 1.92 7/29/2004 2:15:28 AM JPMugaas
- { New property for controlling what AUTH command is sent. Fixed some minor
- { issues with FTP properties. Some were not set to defaults causing
- { unpredictable results -- OOPS!!!
- }
- {
- { Rev 1.91 7/29/2004 12:04:40 AM JPMugaas
- { New events for Get and Put as suggested by Don Sides and to complement an
- { event done by APR.
- }
- {
- { Rev 1.90 7/28/2004 10:16:14 AM JPMugaas
- { New events for determining when a listing is finished and when the dir
- { parsing begins and ends. Dir parsing is done sometimes when DirectoryListing
- { is referenced.
- }
- {
- { Rev 1.89 7/27/2004 2:03:54 AM JPMugaas
- { New property:
- {
- { ExternalIP - used to specify an IP address for the PORT and EPRT commands.
- { This should be blank unless you are behind a NAT and you need to use PORT
- { transfers with SSL. You would set ExternalIP to the NAT's IP address on the
- { Internet.
- {
- { The idea is this:
- {
- { 1) You set up your NAT to forward a range ports ports to your computer behind
- { the NAT.
- { 2) You specify that a port range with the DataPortMin and DataPortMin
- { properties.
- { 3) You set ExternalIP to the NAT's Internet IP address.
- {
- { I have verified this with Indy and WS FTP Pro behind a NAT router.
- }
- {
- { Rev 1.88 7/23/04 7:09:50 PM RLebeau
- { Bug fix for TFileStream access rights in Get()
- }
- {
- Rev 1.87 7/18/2004 3:00:12 PM DSiders
- Added localization comments.
- }
- {
- { Rev 1.86 7/16/2004 4:28:40 AM JPMugaas
- { CCC Support in TIdFTP to complement that capability in TIdFTPServer.
- }
- {
- { Rev 1.85 7/13/04 6:48:14 PM RLebeau
- { Added support for new DataPort and DataPortMin/Max properties
- }
- {
- Rev 1.84 7/6/2004 4:51:46 PM DSiders
- Corrected spelling of Challenge in properties, methods, types.
- }
- {
- { Rev 1.83 7/3/2004 3:15:50 AM JPMugaas
- { Checked in so everyone else can work on stuff while I'm away.
- }
- {
- { Rev 1.82 6/27/2004 1:45:38 AM JPMugaas
- { Can now optionally support LastAccessTime like Smartftp's FTP Server could.
- { I also made the MLST listing object and parser support this as well.
- }
- {
- { Rev 1.81 6/20/2004 8:31:58 PM JPMugaas
- { New events for reporting greeting and after login banners during the login
- { sequence.
- }
- {
- { Rev 1.80 6/20/2004 6:56:42 PM JPMugaas
- { Start oin attempt to support FXP with Deflate compression. More work will
- { need to be done.
- }
- {
- { Rev 1.79 6/17/2004 3:42:32 PM JPMugaas
- { Adjusted code for removal of dmBlock and dmCompressed. Made TransferMode a
- { property. Note that the Set method is odd because I am trying to keep
- { compatibility with older Indy versions.
- }
- {
- { Rev 1.78 6/14/2004 6:19:02 PM JPMugaas
- { This now refers to TIdStreamVCL when downloading isntead of directly to a
- { memory stream when compressing data.
- }
- {
- { Rev 1.77 6/14/2004 8:34:52 AM JPMugaas
- { Fix for AV on Put with Passive := True.
- }
- {
- Rev 1.76 6/11/2004 9:34:12 AM DSiders
- Added "Do not Localize" comments.
- }
- {
- { Rev 1.75 2004.05.20 11:37:16 AM czhower
- { IdStreamVCL
- }
- {
- { Rev 1.74 5/6/2004 6:54:26 PM JPMugaas
- { FTP Port transfers with TransparentProxies is enabled. This only works if
- { the TransparentProxy supports a "bind" request.
- }
- {
- { Rev 1.73 5/4/2004 11:16:28 AM JPMugaas
- { TransferTimeout property added and enabled (Bug 96).
- }
- {
- { Rev 1.72 5/4/2004 11:07:12 AM JPMugaas
- { Timeouts should now be reenabled in TIdFTP.
- }
- {
- { Rev 1.71 4/19/2004 5:05:02 PM JPMugaas
- { Class rework Kudzu wanted.
- }
- {
- { Rev 1.70 2004.04.16 9:31:42 PM czhower
- { Remove unnecessary duplicate string parsing and replaced with .assign.
- }
- {
- { Rev 1.69 2004.04.15 7:09:04 PM czhower
- { .NET overloads
- }
- {
- { Rev 1.68 4/15/2004 9:46:48 AM JPMugaas
- { List no longer requires a TStrings. It turns out that it was an optional
- { parameter.
- }
- {
- { Rev 1.67 2004.04.15 2:03:28 PM czhower
- { Removed login param from connect and made it a prop like POP3.
- }
- {
- { Rev 1.66 3/3/2004 5:57:40 AM JPMugaas
- { Some IFDEF excluses were removed because the functionality is now in DotNET.
- }
- {
- { Rev 1.65 2004.03.03 11:54:26 AM czhower
- { IdStream change
- }
- {
- { Rev 1.64 2/20/2004 1:01:06 PM JPMugaas
- { Preliminary FTP PRET command support for using PASV with a distributed FTP
- { server (Distributed PASV -
- { http://drftpd.org/wiki/wiki.phtml?title=Distributed_PASV).
- }
- {
- { Rev 1.63 2/17/2004 12:25:52 PM JPMugaas
- { The client now supports MODE Z (deflate) uploads and downloads as specified
- { by http://www.ietf.org/internet-drafts/draft-preston-ftpext-deflate-00.txt
- }
- {
- { Rev 1.62 2004.02.03 5:45:10 PM czhower
- { Name changes
- }
- {
- { Rev 1.61 2004.02.03 2:12:06 PM czhower
- { $I path change
- }
- {
- { Rev 1.60 1/27/2004 10:17:10 PM JPMugaas
- { Fix from Steve Loft for a server that sends something like this:
- { "227 Passive mode OK (195,92,195,164,4,99 )"
- }
- {
- { Rev 1.59 1/27/2004 3:59:28 PM SPerry
- { StringStream ->IdStringStream
- }
- {
- { Rev 1.58 24/01/2004 19:13:58 CCostelloe
- { Cleaned up warnings
- }
- {
- { Rev 1.57 1/21/2004 2:27:50 PM JPMugaas
- { Bullete Proof FTPD and Titan FTP support SITE ZONE. Saw this in a command
- { database in StaffFTP.
- { InitComponent.
- }
- {
- { Rev 1.56 1/19/2004 9:05:38 PM JPMugaas
- { Fixes to FTP Set Date functionality.
- { Introduced properties for Time Zone information from the server. The way it
- { works is this, if TIdFTP detects you are using "Serv-U" or SITE ZONE is
- { listed in the FEAT reply, Indy obtains the time zone information with the
- { SITE ZONE command and makes the appropriate calculation. Indy then uses this
- { information to calculate a timestamp to send to the server with the MDTM
- { command. You can also use the Time Zone information yourself to convert the
- { FTP directory listing item timestamps into GMT and than convert that to your
- { local time.
- { FTP Voyager uses SITE ZONE as I've described.
- }
- {
- { Rev 1.55 1/19/2004 4:39:08 AM JPMugaas
- { You can now set the time for a file on the server. Note that these methods
- { try to treat the time as relative to GMT.
- }
- {
- { Rev 1.54 1/17/2004 9:09:30 PM JPMugaas
- { Should now compile.
- }
- {
- { Rev 1.53 1/17/2004 7:48:02 PM JPMugaas
- { FXP site to site transfer code was redone for improvements with FXP with TLS.
- { It actually works and I verified with RaidenFTPD
- { (http://www.raidenftpd.com/) and the Indy FTP server components. I also
- { lowered the requirements for TLS FXP transfers. The requirements now are:
- { 1) Only server (either the recipient or the sendor) has to support SSCN
- {
- { or
- {
- { 2) The server receiving a PASV must support CPSV and the transfer is done
- { with IPv4.
- }
- {
- { Rev 1.52 1/9/2004 2:51:26 PM JPMugaas
- { Started IPv6 support.
- }
- {
- { Rev 1.51 11/27/2003 4:55:28 AM JPMugaas
- { Made STOU functionality separate from PUT functionality. Put now requires a
- { destination filename except where a source-file name is given. In that case,
- { the default is the filename from the source string.
- }
- {
- { Rev 1.50 10/26/2003 04:28:50 PM JPMugaas
- { Reworked Status.
- {
- { The old one was problematic because it assumed that STAT was a request to
- { send a directory listing through the control channel. This assumption is not
- { correct. It provides a way to get a freeform status report from a server.
- { With a Path parameter, it should work like a LIST command except that the
- { control connection is used. We don't support that feature and you should use
- { our LIst method to get the directory listing anyway, IMAO.
- }
- {
- { Rev 1.49 10/26/2003 9:17:46 PM BGooijen
- { Compiles in DotNet, and partially works there
- }
- {
- { Rev 1.48 10/24/2003 12:43:48 PM JPMugaas
- { Should work again.
- }
- {
- { Rev 1.47 2003.10.24 10:43:04 AM czhower
- { TIdSTream to dos
- }
- {
- { Rev 1.46 10/20/2003 03:06:10 PM JPMugaas
- { SHould now work.
- }
- {
- { Rev 1.45 10/20/2003 01:00:38 PM JPMugaas
- { EIdException no longer raised. Some things were being gutted needlessly.
- }
- {
- Rev 1.44 10/19/2003 12:58:20 PM DSiders
- Added localization comments.
- }
- {
- { Rev 1.43 2003.10.14 9:56:50 PM czhower
- { Compile todos
- }
- {
- { Rev 1.42 2003.10.12 3:50:40 PM czhower
- { Compile todos
- }
- {
- { Rev 1.41 10/10/2003 11:32:26 PM SPerry
- { -
- }
- {
- { Rev 1.40 10/9/2003 10:17:02 AM JPMugaas
- { Added overload for GetLoginPassword for providing a challanage string which
- { doesn't have to the last command reply.
- { Added CLNT support.
- }
- {
- { Rev 1.39 10/7/2003 05:46:20 AM JPMugaas
- { SSCN Support added.
- }
- {
- { Rev 1.38 10/6/2003 08:56:44 PM JPMugaas
- { Reworked the FTP list parsing framework so that the user can obtain the list
- { of capabilities from a parser class with TIdFTP. This should permit the user
- { to present a directory listing differently for each parser (some FTP list
- { parsers do have different capabilities).
- }
- {
- { Rev 1.37 10/1/2003 12:51:18 AM JPMugaas
- { SSL with active (PORT) transfers now should work again.
- }
- {
- { Rev 1.36 9/30/2003 09:50:38 PM JPMugaas
- { FTP with TLS should work better. It turned out that we were negotiating it
- { several times causing a hang. I also made sure that we send PBSZ 0 and PROT
- { P for both implicit and explicit TLS. Data ports should work in PASV again.
- }
- {
- { Rev 1.35 9/28/2003 11:41:06 PM JPMugaas
- { Reworked Eldos's proposed FTP fix as suggested by Henrick Hellström by moving
- { all of the IOHandler creation code to InitDataChannel. This should reduce
- { the likelihood of error.
- }
- {
- { Rev 1.33 9/18/2003 11:22:40 AM JPMugaas
- { Removed a temporary workaround for an OnWork bug that was in the Indy Core.
- { That bug was fixed so there's no sense in keeping a workaround here.
- }
- {
- { Rev 1.32 9/12/2003 08:05:30 PM JPMugaas
- { A temporary fix for OnWork events not firing. The bug is that OnWork events
- { aren't used in IOHandler where ReadStream really is located.
- }
- {
- { Rev 1.31 9/8/2003 02:33:00 AM JPMugaas
- { OnCustomFTPProxy added to allow Indy to support custom FTP proxies. When
- { using this event, you are responsible for programming the FTP Proxy and FTP
- { Server login sequence.
- { GetLoginPassword method function for returning the password used when logging
- { into a FTP server which handles OTP calculation. This way, custom firewall
- { support can handle One-Time-Password system transparently. You do have to
- { send the User ID before calling this function because the OTP challenge is
- { part of the reply.
- }
- {
- { Rev 1.30 6/10/2003 11:10:00 PM JPMugaas
- { Made comments about our loop that tries several AUTH command variations.
- { Some servers may only accept AUTH SSL while other servers only accept AUTH
- { TLS.
- }
- {
- { Rev 1.29 5/26/2003 12:21:54 PM JPMugaas
- }
- {
- { Rev 1.28 5/25/2003 03:54:20 AM JPMugaas
- }
- {
- { Rev 1.27 5/19/2003 08:11:32 PM JPMugaas
- { Now should compile properly with new code in Core.
- }
- {
- { Rev 1.26 5/8/2003 11:27:42 AM JPMugaas
- { Moved feature negoation properties down to the ExplicitTLSClient level as
- { feature negotiation goes hand in hand with explicit TLS support.
- }
- {
- { Rev 1.25 4/5/2003 02:06:34 PM JPMugaas
- { TLS handshake itself can now be handled.
- }
- {
- Rev 1.24 4/4/2003 8:01:32 PM BGooijen
- now creates iohandler for dataconnection
- }
- {
- { Rev 1.23 3/31/2003 08:40:18 AM JPMugaas
- { Fixed problem with QUIT command.
- }
- {
- Rev 1.22 3/27/2003 3:41:28 PM BGooijen
- Changed because some properties are moved to IOHandler
- }
- {
- { Rev 1.21 3/27/2003 05:46:24 AM JPMugaas
- { Updated framework with an event if the TLS negotiation command fails.
- { Cleaned up some duplicate code in the clients.
- }
- {
- { Rev 1.20 3/26/2003 04:19:20 PM JPMugaas
- { Cleaned-up some code and illiminated some duplicate things.
- }
- {
- { Rev 1.19 3/24/2003 04:56:10 AM JPMugaas
- { A typecast was incorrect and could cause a potential source of instability if
- { a TIdIOHandlerStack was not used.
- }
- {
- { Rev 1.18 3/16/2003 06:09:58 PM JPMugaas
- { Fixed port setting bug.
- }
- {
- { Rev 1.17 3/16/2003 02:40:16 PM JPMugaas
- { FTP client with new design.
- }
- {
- Rev 1.16 3/16/2003 1:02:44 AM BGooijen
- Added 2 events to give the user more control to the dataconnection, moved
- SendTransferType, enabled ssl
- }
- {
- { Rev 1.15 3/13/2003 09:48:58 AM JPMugaas
- { Now uses an abstract SSL base class instead of OpenSSL so 3rd-party vendors
- { can plug-in their products.
- }
- {
- { Rev 1.14 3/7/2003 11:51:52 AM JPMugaas
- { Fixed a writeln bug and an IOError issue.
- }
- {
- { Rev 1.13 3/3/2003 07:06:26 PM JPMugaas
- { FFreeIOHandlerOnDisconnect to FreeIOHandlerOnDisconnect at Bas's instruction
- }
- {
- { Rev 1.12 2/21/2003 06:54:36 PM JPMugaas
- { The FTP list processing has been restructured so that Directory output is not
- { done by IdFTPList. This now also uses the IdFTPListParserBase for parsing so
- { that the code is more scalable.
- }
- {
- { Rev 1.11 2/17/2003 04:45:36 PM JPMugaas
- { Now temporarily change the transfer mode to ASCII when requesting a DIR.
- { TOPS20 does not like transfering dirs in binary mode and it might be a good
- { idea to do it anyway.
- }
- {
- { Rev 1.10 2/16/2003 03:22:20 PM JPMugaas
- { Removed the Data Connection assurance stuff. We figure things out from the
- { draft specificaiton, the only servers we found would not send any data after
- { the new commands were sent, and there were only 2 server types that supported
- { it anyway.
- }
- {
- { Rev 1.9 2/16/2003 10:51:08 AM JPMugaas
- { Attempt to implement:
- {
- { http://www.ietf.org/internet-drafts/draft-ietf-ftpext-data-connection-assuranc
- { e-00.txt
- {
- { Currently commented out because it does not work.
- }
- {
- { Rev 1.8 2/14/2003 11:40:16 AM JPMugaas
- { Fixed compile error.
- }
- {
- { Rev 1.7 2/14/2003 10:38:32 AM JPMugaas
- { Removed a problematic override for GetInternelResponse. It was messing up
- { processing of the FEAT.
- }
- {
- { Rev 1.6 12-16-2002 20:48:10 BGooijen
- { now uses TIdIOHandler.ConstructIOHandler to construct iohandlers
- { IPv6 works again
- { Independant of TIdIOHandlerStack again
- }
- {
- { Rev 1.5 12-15-2002 23:27:26 BGooijen
- { now compiles on Indy 10, but some things like IPVersion still need to be
- { changed
- }
- {
- { Rev 1.4 12/15/2002 04:07:02 PM JPMugaas
- { Started port to Indy 10. Still can not complete it though.
- }
- {
- { Rev 1.3 12/6/2002 05:29:38 PM JPMugaas
- { Now decend from TIdTCPClientCustom instead of TIdTCPClient.
- }
- {
- { Rev 1.2 12/1/2002 04:18:02 PM JPMugaas
- { Moved all dir parsing code to one place. Reworked to use more than one line
- { for determining dir format type along with flfNextLine dir format type.
- }
- {
- { Rev 1.1 11/14/2002 04:02:58 PM JPMugaas
- { Removed cludgy code that was a workaround for the RFC Reply limitation. That
- { is no longer limited.
- }
- {
- { Rev 1.0 11/14/2002 02:20:00 PM JPMugaas
- }
- unit IdFTP;
- {
- Change Log:
- 2002-10-25 - J. Peter Mugaas
- - added XCRC support - specified by "GlobalSCAPE Secure FTP Server User’s Guide"
- which is available at http://www.globalscape.com
- and also explained at http://www.southrivertech.com/support/titanftp/webhelp/titanftp.htm
- - added COMB support - specified by "GlobalSCAPE Secure FTP Server User’s Guide"
- which is available at http://www.globalscape.com
- and also explained at http://www.southrivertech.com/support/titanftp/webhelp/titanftp.htm
- 2002-10-24 - J. Peter Mugaas
- - now supports RFC 2640 - FTP Internalization
- 2002-09-18
- _ added AFromBeginning parameter to InternalPut to correctly honor the AAppend parameter of Put
- 2002-09-05 - J. Peter Mugaas
- - now complies with RFC 2389 - Feature negotiation mechanism for the File Transfer Protocol
- - now complies with RFC 2428 - FTP Extensions for IPv6 and NATs
- 2002-08-27 - Andrew P.Rybin
- - proxy support fix (non-standard ftp port's)
- 2002-01-xx - Andrew P.Rybin
- - Proxy support, OnAfterGet (ex:decrypt, set srv timestamp)
- - J.Peter Mugaas: not readonly ProxySettings
- A Neillans - 10/17/2001
- Merged changes submitted by Andrew P.Rybin
- Correct command case problems - some servers expect commands in Uppercase only.
- SP - 06/08/2001
- Added a few more functions
- Doychin - 02/18/2001
- OnAfterLogin event handler and Login method
- OnAfterLogin is executed after successfull login but before setting up the
- connection properties. This event can be used to provide FTP proxy support
- from the user application. Look at the FTP demo program for more information
- on how to provide such support.
- Doychin - 02/17/2001
- New onFTPStatus event
- New Quote method for executing commands not implemented by the compoent
- -CleanDir contributed by Amedeo Lanza
- TODO: Chage the FTP demo to demonstrate the use of the new events and add proxy support
- }
- interface
- uses
- Classes,
- IdAssignedNumbers, IdGlobal, IdCustomTransparentProxy, IdExceptionCore,
- IdExplicitTLSClientServerBase, IdFTPCommon, IdFTPList, IdFTPListParseBase, IdException,
- IdIOHandler, IdIOHandlerSocket,
- IdReplyFTP,
- IdReplyRFC,
- IdReply,
- IdSocketHandle, IdStreamVCL,
- IdTCPConnection, IdTCPClient, IdThread, IdTStrings, IdZLibCompressorBase;
- type
- //Added by SP
- TIdCreateFTPList = procedure(ASender: TObject; Var VFTPList: TIdFTPListItems) of object;
- // TIdCheckListFormat = procedure(ASender: TObject; const ALine: String; Var VListFormat: TIdFTPListFormat) of object;
- TOnAfterClientLogin = TNotifyEvent;
- TIdFtpAfterGet = procedure (ASender: TObject; VStream: TStream) of object; //APR
- TIdOnDataChannelCreate = procedure (ASender: TObject; ADataChannel: TIdTCPConnection) of object;
- TIdOnDataChannelDestroy = procedure (ASender: TObject; ADataChannel: TIdTCPConnection) of object;
- const
- Id_TIdFTP_TransferType = ftBinary;
- Id_TIdFTP_Passive = False;
- Id_TIdFTP_UseNATFastTrack = False;
- Id_TIdFTP_HostPortDelimiter = ':';
- Id_TIdFTP_DataConAssurance = False;
- type
- //APR 011216:
- TIdFtpProxyType = (fpcmNone,//Connect method:
- fpcmUserSite, //Send command USER user@hostname
- fpcmSite, //Send command SITE (with logon)
- fpcmOpen, //Send command OPEN
- fpcmUserPass,//USER user@firewalluser@hostname / PASS pass@firewallpass
- fpcmTransparent, //First use the USER and PASS command with the firewall username and password, and then with the target host username and password.
- fpcmHttpProxyWithFtp, //HTTP Proxy with FTP support. Will be supported in Indy 10
- fpcmCustomProxy // use OnCustomFTPProxy to customize the proxy login
- ); //TIdFtpProxyType
- //This has to be in the same order as TLS_AUTH_NAMES
- TAuthCmd = (tAuto, tAuthTLS, tAuthSSL, tAuthTLSC, tAuthTLSP);
- const
- Id_TIdFTP_DataPortProtection = ftpdpsClear;
- DEF_Id_TIdFTP_Implicit = False;
- DEF_Id_FTP_UseExtendedDataPort = False;
- DEF_Id_TIdFTP_UseExtendedData = False;
- DEF_Id_TIdFTP_UseMIS = False;
- DEF_Id_FTP_UseCCC = False;
- DEF_Id_FTP_AUTH_CMD = tAuto;
- type
- TIdFTPBannerEvent = procedure (ASender: TObject; const AMsg : String) of object;
- TIdFTPClientIdentifier = class (TPersistent)
- protected
- FClientName : String;
- FClientVersion : String;
- FPlatformDescription : String;
- procedure SetClientName(const AValue: String);
- procedure SetClientVersion(const AValue: String);
- procedure SetPlatformDescription(const AValue: String);
- function GetClntOutput: String;
- public
- procedure Assign(Source: TPersistent); override;
- property ClntOutput : String read GetClntOutput;
- published
- property ClientName : String read FClientName write SetClientName;
- property ClientVersion : String read FClientVersion write SetClientVersion;
- property PlatformDescription : String read FPlatformDescription write SetPlatformDescription;
- end;
- TIdFtpProxySettings = class (TPersistent)
- protected
- FHost, FUserName, FPassword: String;
- FProxyType: TIdFtpProxyType;
- FPort: Integer;
- public
- procedure Assign(Source: TPersistent); override;
- published
- property ProxyType: TIdFtpProxyType read FProxyType write FProxyType;
- property Host: String read FHost write FHost;
- property UserName: String read FUserName write FUserName;
- property Password: String read FPassword write FPassword;
- property Port: Integer read FPort write FPort;
- End;//TIdFtpProxySettings
- TIdFTPTZInfo = class(TPersistent)
- protected
- FGMTOffset : TDateTime;
- FGMTOffsetAvailable : Boolean;
- public
- procedure Assign(Source: TPersistent); override;
- published
- property GMTOffset : TDateTime read FGMTOffset write FGMTOffset;
- property GMTOffsetAvailable : Boolean read FGMTOffsetAvailable write FGMTOffsetAvailable;
- end;
- TIdFTP = class(TIdExplicitTLSClient)
- protected
- FAutoLogin: Boolean;
- FCurrentTransferMode : TIdFTPTransferMode;
- FClientInfo : TIdFTPClientIdentifier;
- FUsingSFTP : Boolean; //enable SFTP internel flag
- FUsingCCC : Boolean; //are we using FTP with SSL on a clear control channel?
- FCanUseMLS : Boolean; //can we use MLISx instead of LIST
- FUsedMLS : Boolean; //Did the developer use MLSx commands for the last list command
- FUsingExtDataPort : Boolean; //are NAT Extensions (RFC 2428 available) flag
- FUsingNATFastTrack : Boolean;//are we using NAT fastrack feature
- FCanResume: Boolean;
- FListResult: TIdStrings;
- FLoginMsg: TIdReplyFTP;
- FPassive: boolean;
- FDataPortProtection : TIdFTPDataPortSecurity;
- FAUTHCmd : TAuthCmd;
- FDataPort: Integer;
- FDataPortMin: Integer;
- FDataPortMax: Integer;
- FExternalIP : String;
- FResumeTested: Boolean;
- FSystemDesc: string;
- FTransferType: TIdFTPTransferType;
- FTransferTimeout : Integer;
- FDataChannel: TIdTCPConnection;
- FDirectoryListing: TIdFTPListItems;
- FDirFormat : String;
- FListParserClass : TIdFTPListParseClass;
- FOnAfterClientLogin: TNotifyEvent;
- FOnCreateFTPList: TIdCreateFTPList;
- FOnBeforeGet: TNotifyEvent;
- FOnBeforePut: TIdFtpAfterGet;
- //in case someone needs to do something special with the data being uploaded
- FOnAfterGet: TIdFtpAfterGet; //APR
- FOnAfterPut: TNotifyEvent; //JPM at Don Sider's suggestion
- FOnCustomFTPProxy : TNotifyEvent;
- FOnDataChannelCreate:TIdOnDataChannelCreate;
- FOnDataChannelDestroy:TIdOnDataChannelDestroy;
- FProxySettings: TIdFtpProxySettings;
- FUseExtensionDataPort : Boolean;
- FTryNATFastTrack : Boolean;
- FUseMLIS : Boolean;
- FLangsSupported : TIdStrings;
- FUseCCC: Boolean;
- //is the SSCN Client method on for this connection?
- FSSCNOn : Boolean;
- FOnBannerBeforeLogin : TIdFTPBannerEvent;
- FOnBannerAfterLogin : TIdFTPBannerEvent;
- FTZInfo : TIdFTPTZInfo;
- FCompressor : TIdZLibCompressorBase;
- //ZLib settings
- FZLibCompressionLevel : Integer; //7
- FZLibWindowBits : Integer; //-15
- FZLibMemLevel : Integer; //8
- FZLibStratagy : Integer; //0 - default
- //dir events for some GUI programs.
- //The directory was Retrieved from the FTP server.
- FOnRetrievedDir : TNotifyEvent;
- //parsing is done only when DirectoryListing is referenced
- FOnDirParseStart : TNotifyEvent;
- FOnDirParseEnd : TNotifyEvent;
- procedure DoOnRetrievedDir;
- procedure DoOnDirParseStart;
- procedure DoOnDirParseEnd;
- procedure SetTZInfo(const Value: TIdFTPTZInfo);
- function IsSiteZONESupported : Boolean;
- function IndexOfFeatLine(const AFeatLine : String):Integer;
- procedure ClearSSCN;
- function SetSSCNToOn : Boolean;
- procedure SendInternalPassive(const ACmd : String; var VIP: string; var VPort: integer);
- procedure SendCPassive(var VIP: string; var VPort: integer);
- function FindAuthCmd : String;
- function GetReplyClass:TIdReplyClass; override;
- //
- function EPRTParams(const AIP : String; const APort : Integer; const AIPVersion : TIdIPVersion): String;
- procedure ParseFTPList(AData : TIdStrings);
- procedure SetPassive(const AValue : Boolean);
- procedure SetTryNATFastTrack(const AValue: Boolean);
- procedure DoTryNATFastTrack;
- procedure SetUseExtensionDataPort(const AValue: Boolean);
- procedure SetIPVersion(const AValue: TIdIPVersion); override;
- procedure SetIOHandler(AValue: TIdIOHandler); override;
- function GetSupportsTLS: Boolean; override;
- procedure ConstructDirListing;
- procedure DoAfterLogin;
- procedure DoFTPList;
- procedure DoCustomFTPProxy;
- procedure DoOnBannerAfterLogin(AText : TIdStrings);
- procedure DoOnBannerBeforeLogin(AText : TIdStrings);
- procedure SendPBSZ; //protection buffer size
- procedure SendPROT; //data port protection
- procedure SendDataSettings; //this is for the extensions only;
- // procedure DoCheckListFormat(const ALine: String);
- function GetDirectoryListing: TIdFTPListItems;
- // function GetOnParseCustomListFormat: TIdOnParseCustomListFormat;
- procedure InitDataChannel;
- //PRET is to help distributed FTP systems by letting them know what you will do
- //before issuing a PASV. See: http://drftpd.mog.se/wiki/wiki.phtml?title=Distributed_PASV#PRE_Transfer_Command_for_Distributed_PASV_Transfers
- //for a discussion.
- procedure SendPret(const ACommand : String);
- procedure InternalGet(const ACommand: string; ADest: TIdStreamVCL; AResume: Boolean = false);
- procedure InternalPut(const ACommand: string; ASource: TIdStreamVCL; AFromBeginning: Boolean = true);
- // procedure SetOnParseCustomListFormat(const AValue: TIdOnParseCustomListFormat);
- procedure SendPassive(var VIP: string; var VPort: integer);
- procedure SendPort(AHandle: TIdSocketHandle); overload;
- procedure SendPort(const AIP : String; const APort : Integer); overload;
- procedure ParseEPSV(const AReply : String; var VIP : String; VPort : Integer);
- //These two are for RFC 2428.txt
- procedure SendEPort(AHandle: TIdSocketHandle); overload;
- procedure SendEPort(const AIP : String; const APort : Integer; const AIPVersion : TIdIPVersion); overload;
- procedure SendEPassive(var VIP: string; var VPort: integer);
- procedure SetProxySettings(const Value: TIdFtpProxySettings);
- procedure SetClientInfo(const AValue: TIdFTPClientIdentifier);
- procedure SendTransferType;
- procedure SetTransferType(AValue: TIdFTPTransferType);
- procedure DoBeforeGet; virtual;
- procedure DoBeforePut (AStream: TStream); virtual;
- procedure DoAfterGet (AStream: TStream); virtual; //APR
- procedure DoAfterPut; virtual;
- function IsValidOTPString(const AResponse:string):boolean;
- function GenerateOTP(const AResponse:string; const APassword:string):string;
- procedure FXPSetTransferPorts(AFromSite, AToSite: TIdFTP;
- const ATargetUsesPasv : Boolean);
- procedure FXPSendFile(AFromSite, AToSite: TIdFTP;
- const ASourceFile, ADestFile: String);
- function InternalEncryptedTLSFXP(AFromSite, AToSite: TIdFTP; const ASourceFile,
- ADestFile: String; const ATargetUsesPasv : Boolean) : Boolean;
- function InternalUnencryptedFXP(AFromSite, AToSite: TIdFTP; const ASourceFile,
- ADestFile: String; const ATargetUsesPasv : Boolean): Boolean;
- function ValidateInternalIsTLSFXP(AFromSite, AToSite: TIdFTP; const ATargetUsesPasv : Boolean): Boolean;
- procedure InitComponent; override;
- procedure SetUseTLS(AValue : TIdUseTLS); override;
- procedure Notification(AComponent: TComponent; Operation: TOperation); override;
- procedure SetDataPortProtection(AValue : TIdFTPDataPortSecurity);
- procedure SetAUTHCmd(const AValue : TAuthCmd);
- procedure SetUseCCC(const AValue: Boolean);
- public
- function IsExtSupported(const ACmd : String):Boolean;
- procedure ExtractFeatFacts(const ACmd : String; AResults : TIdStrings);
- //this function transparantly handles OTP based on the Last command response
- //so it needs to be called only after the USER command or equivilent.
- function GetLoginPassword : String; overload;
- function GetLoginPassword(const APrompt : String) : String; overload;
- procedure Abort; virtual;
- procedure Account(AInfo: String);
- procedure Allocate(AAllocateBytes: Integer);
- procedure ChangeDir(const ADirName: string);
- procedure ChangeDirUp;
- procedure Connect; override;
- destructor Destroy; override;
- procedure Delete(const AFilename: string);
- procedure FileStructure(AStructure: TIdFTPDataStructure);
- procedure Get(const ASourceFile: string; ADest: TIdStreamVCL; AResume: Boolean = false); overload;
- procedure Get(const ASourceFile: string; ADest: TStream; AResume: Boolean = false); overload;
- procedure Get(const ASourceFile, ADestFile: string; const ACanOverwrite: boolean = false; AResume: Boolean = false); overload;
- procedure Help(var AHelpContents: TIdStringList; ACommand: String = '');
- procedure KillDataChannel; virtual;
- procedure List; overload; //.NET Overload
- procedure List( //.NET Overload
- const ASpecifier: string;
- ADetails: Boolean = True); overload;
- procedure List(
- ADest: TIdStrings;
- const ASpecifier: string = '';
- ADetails: Boolean = True); overload;
- procedure ExtListDir(const ADest: TIdStrings=nil; const ADirectory: string = '');
- procedure ExtListItem(ADest: TIdStrings; AFList : TIdFTPListItems; const AItem: string=''); overload;
- procedure ExtListItem(ADest: TIdStrings; const AItem: string = ''); overload;
- procedure ExtListItem(AFList : TIdFTPListItems; const AItem : String= ''); overload;
- function FileDate(const AFileName : String; const AsGMT : Boolean = False): TDateTime;
- procedure Login;
- procedure MakeDir(const ADirName: string);
- procedure Noop;
- procedure SetCMDOpt(const ACMD, AOptions : String);
- procedure Put(const ASource: TIdStreamVCL; const ADestFile: string;
- const AAppend: boolean = false); overload;
- procedure Put(const ASource: TStream; const ADestFile: string;
- const AAppend: boolean = false); overload;
- procedure Put(const ASourceFile: string; const ADestFile: string = '';
- const AAppend: boolean = false); overload;
- procedure StoreUnique(const ASource: TIdStreamVCL); overload;
- procedure StoreUnique(const ASource: TStream); overload;
- procedure StoreUnique(const ASourceFile: string); overload;
- procedure SiteToSiteUpload(const AToSite : TIdFTP; const ASourceFile : String; const ADestFile : String = '');
- procedure SiteToSiteDownload(const AFromSite: TIdFTP; const ASourceFile : String; const ADestFile : String = '');
- procedure Quit;
- function Quote(const ACommand: String): SmallInt;
- procedure RemoveDir(const ADirName: string);
- procedure Rename(const ASourceFile, ADestFile: string);
- function ResumeSupported: Boolean;
- function RetrieveCurrentDir: string;
- procedure Site(const ACommand: string);
- function Size(const AFileName: String): Integer;
- procedure Status(AStatusList: TIdStrings);
- procedure StructureMount(APath: String);
- procedure TransferMode(ATransferMode: TIdFTPTransferMode);
- procedure ReInitialize(ADelay: Cardinal = 10);
- procedure SetLang(const ALangTag : String);
- function CRC(const AFIleName : String; const AStartPoint : Cardinal = 0; const AEndPoint : Cardinal=0) : Int64;
- //file parts must be in order in TIdStrings parameter
- //GlobalScape FTP Pro uses this for multipart simultanious file uploading
- procedure CombineFiles(const ATargetFile : String; AFileParts : TIdStrings);
- //Set modified file time.
- procedure SetModTime(const AFileName: String; const ALocalTime: TDateTime);
- procedure SetModTimeGMT(const AFileName : String; const AGMTTime: TDateTime);
- // servers that support MDTM yyyymmddhhmmss[+-xxx] and also support LIST -T
- //This is true for servers that are known to support these even if they aren't
- //listed in the FEAT reply.
- function IsServerMDTZAndListTForm : Boolean;
- //
- property CanResume: Boolean read ResumeSupported;
- property DirectoryListing: TIdFTPListItems read GetDirectoryListing;
- property DirFormat : String read FDirFormat;
- property LangsSupported : TIdStrings read FLangsSupported;
- property ListParserClass : TIdFTPListParseClass read FListParserClass write FListParserClass;
- property LoginMsg: TIdReplyFTP read FLoginMsg;
- property ListResult: TIdStrings read FListResult;
- property SystemDesc: string read FSystemDesc;
- property TZInfo : TIdFTPTZInfo read FTZInfo write SetTZInfo;
- property UsingExtDataPort : Boolean read FUsingExtDataPort;
- property UsingNATFastTrack : Boolean read FUsingNATFastTrack;
- property UsingSFTP : Boolean read FUsingSFTP;
- property CurrentTransferMode : TIdFTPTransferMode read FCurrentTransferMode write TransferMode;
- published
- property AutoLogin: Boolean read FAutoLogin write FAutoLogin;
- // This is an object that can compress and decompress HTTP Deflate encoding
- property Compressor : TIdZLibCompressorBase read FCompressor write FCompressor;
- property Host;
- property UseCCC : Boolean read FUseCCC write SetUseCCC default DEF_Id_FTP_UseCCC;
- property Passive: boolean read FPassive write SetPassive default Id_TIdFTP_Passive;
- property DataPortProtection : TIdFTPDataPortSecurity read FDataPortProtection write SetDataPortProtection default Id_TIdFTP_DataPortProtection;
- property AUTHCmd : TAuthCmd read FAUTHCmd write SetAUTHCmd default DEF_Id_FTP_AUTH_CMD;
- property DataPort: Integer read FDataPort write FDataPort default 0;
- property DataPortMin: Integer read FDataPortMin write FDataPortMin default 0;
- property DataPortMax: Integer read FDataPortMax write FDataPortMax default 0;
- property ExternalIP : String read FExternalIP write FExternalIP;
- property Password;
- property TransferType: TIdFTPTransferType read FTransferType write SetTransferType default Id_TIdFTP_TransferType;
- property TransferTimeout: Integer read FTransferTimeout write FTransferTimeout default IdDefTimeout;
- property Username;
- property Port default IDPORT_FTP;
- property UseExtensionDataPort : Boolean read FUseExtensionDataPort write SetUseExtensionDataPort default DEF_Id_TIdFTP_UseExtendedData;
- property UseMLIS : Boolean read FUseMLIS write FUseMLIS default DEF_Id_TIdFTP_UseMIS;
- property TryNATFastTrack : Boolean read FTryNATFastTrack write SetTryNATFastTrack default Id_TIdFTP_UseNATFastTrack;
- property ProxySettings: TIdFtpProxySettings read FProxySettings write SetProxySettings;
- property ClientInfo : TIdFTPClientIdentifier read FClientInfo write SetClientInfo;
- property UseTLS;
- property OnTLSNotAvailable;
- property OnBannerBeforeLogin : TIdFTPBannerEvent read FOnBannerBeforeLogin write FOnBannerBeforeLogin;
- property OnBannerAfterLogin : TIdFTPBannerEvent read FOnBannerAfterLogin write FOnBannerAfterLogin;
- property OnAfterClientLogin: TOnAfterClientLogin read FOnAfterClientLogin write FOnAfterClientLogin;
- property OnCreateFTPList: TIdCreateFTPList read FOnCreateFTPList write FOnCreateFTPList;
- property OnAfterGet: TIdFtpAfterGet read FOnAfterGet write FOnAfterGet; //APR
- property OnCustomFTPProxy : TNotifyEvent read FOnCustomFTPProxy write FOnCustomFTPProxy;
- property OnDataChannelCreate:TIdOnDataChannelCreate read FOnDataChannelCreate write FOnDataChannelCreate;
- property OnDataChannelDestroy:TIdOnDataChannelDestroy read FOnDataChannelDestroy write FOnDataChannelDestroy;
- //The directory was Retrieved from the FTP server.
- property OnRetrievedDir : TNotifyEvent read FOnRetrievedDir write FOnRetrievedDir;
- //parsing is done only when DirectoryLiusting is referenced
- property OnDirParseStart : TNotifyEvent read FOnDirParseStart write FOnDirParseStart;
- property OnDirParseEnd : TNotifyEvent read FOnDirParseEnd write FOnDirParseEnd;
- end;
- EIdFTPException = class(EIdException);
- EIdFTPFileAlreadyExists = class(EIdFTPException);
- EIdFTPMustUseExtWithIPv6 = class(EIdFTPException);
- EIdFTPMustUseExtWithNATFastTrack = class(EIdFTPException);
- EIdFTPPassiveMustBeTrueWithNATFT = class(EIdFTPException);
- EIdFTPServerSentInvalidPort = class(EIdFTPException);
- EIdFTPSiteToSiteTransfer = class(EIdFTPException);
- EIdFTPSToSNATFastTrack = class(EIdFTPSiteToSiteTransfer);
- EIdFTPSToSNoDataProtection = class(EIdFTPSiteToSiteTransfer);
- EIdFTPSToSIPProtoMustBeSame = class(EIdFTPSiteToSiteTransfer);
- EIdFTPSToSBothMostSupportSSCN = class(EIdFTPSiteToSiteTransfer);
- EIdFTPSToSTransModesMustBeSame = class(EIdFTPSiteToSiteTransfer);
- EIdFTPUnknownOTPMethodException = class(EIdFTPException);
- EIdFTPOnCustomFTPProxyRequired = class(EIdFTPException);
- EIdFTPConnAssuranceFailure = class(EIdFTPException);
- EIdFTPWrongIOHandler = class(EIdFTPException);
- EIdFTPUploadFileNameCanNotBeEmpty = class(EIdFTPException);
- EIdFTPDataPortProtection = class(EIdFTPException);
- EIdFTPNoDataPortProtectionAfterCCC = class(EIdFTPDataPortProtection);
- EIdFTPNoDataPortProtectionWOEncryption = class(EIdFTPDataPortProtection);
- EIdFTPNoCCCWOEncryption = class(EIdFTPException);
- EIdFTPAUTHException = class(EIdFTPException);
- EIdFTPNoAUTHWOSSL = class(EIdFTPAUTHException);
- EIdFTPCanNotSetAUTHCon = class(EIdFTPAUTHException);
- implementation
- uses
- IdComponent, IdResourceStringsCore, IdIOHandlerStack, IdResourceStringsProtocols,
- IdSSL, IdGlobalProtocols,
- IdStack, IdSimpleServer,
- SysUtils, IdOTPCalculator;
- function CleanDirName(const APWDReply: string): string;
- begin
- Result := APWDReply;
- Delete(result, 1, IndyPos('"', result)); // Remove first doublequote {do not localize}
- Result := Copy(result, 1, IndyPos('"', result) - 1); // Remove anything from second doublequote {do not localize} // to end of line
- end;
- function TIdFTP.IsValidOTPString(const AResponse:string):boolean;
- var LChallenge:string;
- LChallengeStartPos:integer;
- LMethod:string;
- begin
- LChallengeStartPos := pos('otp-',AResponse); {do not localize}
- if LChallengeStartPos>0 then begin
- inc(LChallengeStartPos,4); // to remove "otp-"
- LChallenge:=copy(AResponse,LChallengeStartPos,$FFFF);
- LMethod:=Fetch(LChallenge);
- result := (LMethod='md4') or (LMethod='md5') or (LMethod='sha1'); // methods are case sensitive {do not localize}
- end else result:=false;
- end;
- function TIdFTP.GenerateOTP(const AResponse:string; const APassword:string):string;
- var LChallenge:string;
- LChallengeStartPos:integer;
- LMethod:string;
- LSeed:string;
- LCount:integer;
- begin
- LChallengeStartPos := pos('otp-', AResponse); {do not localize}
- if LChallengeStartPos > 0 then begin
- inc(LChallengeStartPos, 4); // to remove "otp-"
- LChallenge := copy(AResponse,LChallengeStartPos, $FFFF);
- LMethod := Fetch(LChallenge);
- LCount := StrToInt(Fetch(LChallenge));
- LSeed := Fetch(LChallenge);
- if LMethod = 'md5' then // methods are case sensitive {do not localize}
- begin
- Result := TIdOTPCalculator.ToSixWordFormat(TIdOTPCalculator.GenerateKeyMD5(lseed,APassword,LCount))
- end
- else
- begin
- if LMethod = 'md4' then {do not localize}
- begin
- Result := TIdOTPCalculator.ToSixWordFormat(TIdOTPCalculator.GenerateKeyMD4(lseed,APassword,LCount))
- end
- else
- begin
- if LMethod = 'sha1' then {do not localize}
- begin
- Result := TIdOTPCalculator.ToSixWordFormat(TIdOTPCalculator.GenerateKeySHA1(lseed,APassword,LCount))
- end
- else
- begin
- Raise EIdFTPUnknownOTPMethodException.Create(RSFTPOTPMethod);
- end;
- end;
- end;
- end;
- end;
- procedure TIdFTP.InitComponent;
- begin
- inherited;
- //
- FAutoLogin := True;
- FRegularProtPort := IdPORT_FTP;
- FImplicitTLSProtPort := IdPORT_ftps;
- //
- Port := IDPORT_FTP;
- Passive := Id_TIdFTP_Passive;
- FDataPortProtection := Id_TIdFTP_DataPortProtection;
- FUseCCC := DEF_Id_FTP_UseCCC;
- FAUTHCmd := DEF_Id_FTP_AUTH_CMD;
- FDataPort := 0;
- FDataPortMin := 0;
- FDataPortMax := 0;
- FUseExtensionDataPort := DEF_Id_TIdFTP_UseExtendedData;
- FTryNATFastTrack := Id_TIdFTP_UseNATFastTrack;
- FTransferType := Id_TIdFTP_TransferType;
- FTransferTimeout := IdDefTimeout;
- FLoginMsg := TIdReplyFTP.Create(NIL);
- FListResult := TIdStringList.Create;
- FLangsSupported := TIdStringList.Create;
- FCanResume := false;
- FResumeTested := false;
- FProxySettings:= TIdFtpProxySettings.Create; //APR
- FClientInfo := TIdFTPClientIdentifier.Create;
- FTZInfo := TIdFTPTZInfo.Create;
- FTZInfo.FGMTOffsetAvailable := False;
- FUseMLIS := DEF_Id_TIdFTP_UseMIS;
- FUsedMLS := False;
- FCanUseMLS := False; //initialize MLIS flags
- //Settings specified by
- // http://www.ietf.org/internet-drafts/draft-preston-ftpext-deflate-00.txt
- FZLibCompressionLevel := DEF_ZLIB_COMP_LEVEL;
- FZLibWindowBits := DEF_ZLIB_WINDOW_BITS; //-15 - no extra headers
- FZLibMemLevel := DEF_ZLIB_MEM_LEVEL;
- FZLibStratagy := DEF_ZLIB_STRATAGY; // - default
- end;
- procedure TIdFTP.Connect;
- var
- LHost: String;
- LPort: Integer;
- LBuf : String;
- begin
- FCurrentTransferMode := dmStream;
- FTZInfo.FGMTOffsetAvailable := False;
- //FSSCNOn should be set to false to prevent problems.
- FSSCNOn := False;
- FUsingSFTP := False;
- FUsingCCC := False;
- if FUseExtensionDataPort then begin
- FUsingExtDataPort := True;
- end;
- FUsingNATFastTrack := False;
- try
- //APR 011216: proxy support
- LHost := FHost;
- LPort := FPort;
- try
- if (ProxySettings.ProxyType > fpcmNone) and (Length(ProxySettings.Host) > 0) then begin
- FHost := ProxySettings.Host;
- FPort := ProxySettings.Port;
- end;
- if (FUseTLS=utUseImplicitTLS) then
- begin
- //at this point, we treat implicit FTP as if it were explicit FTP with TLS
- FUsingSFTP := True;
- end;
- inherited Connect;
- finally
- FHost := LHost;
- FPort := LPort;
- end;//tryf
- GetResponse([220]);
- FGreeting.Assign(LastCmdResult);
- DoOnBannerBeforeLogin (FGreeting.FormattedReply);
- if AutoLogin then begin
- Login;
- DoAfterLogin;
- //Fast track is set only one time per connection and no more, even
- //with REINIT
- if TryNATFastTrack then begin
- DoTryNATFastTrack;
- end;
- if (FUseTLS=utUseImplicitTLS) then begin
- //at this point, we treat implicit FTP as if it were explicit FTP with TLS
- FUsingSFTP := True;
- end;
- // OpenVMS 7.1 replies with 200 instead of 215 - What does the RFC say about this?
- // if SendCmd('SYST', [200, 215, 500]) = 500 then begin {do not localize}
- //Do not fault if SYST was not understood by the server. Novel Netware FTP
- //may not understand SYST.
- if SendCmd('SYST') = 500 then begin {do not localize}
- FSystemDesc := RSFTPUnknownHost;
- end else begin
- FSystemDesc := LastCmdResult.Text[0];
- end;
- if IsSiteZONESupported then
- begin
- if not FCanUseMLS then
- begin
- if SendCmd('SITE ZONE') = 210 then {do not localize}
- begin
- if LastCmdResult.Text.Count > 0 then
- begin
- LBuf := LastCmdResult.Text[0];
- //remove UTC from reply string "UTC-300"
- IdDelete(LBuf,1,3);
- FTZInfo.GMTOffset := MDTMOffset(LBuf);
- FTZInfo.FGMTOffsetAvailable := True;
- end;
- end;
- end;
- end;
- DoStatus(ftpReady, [RSFTPStatusReady]);
- end;
- except
- Disconnect;
- raise;
- end;
- end;
- procedure TIdFTP.SetTransferType(AValue: TIdFTPTransferType);
- begin
- if AValue <> FTransferType then begin
- if not Assigned(FDataChannel) then begin
- FTransferType := AValue;
- if Connected then begin
- SendTransferType;
- end;
- end
- end;
- end;
- procedure TIdFTP.SendTransferType;
- var
- s: string;
- begin
- case TransferType of
- ftAscii: s := 'A'; {do not localize}
- ftBinary: s := 'I'; {do not localize}
- end;
- SendCmd('TYPE ' + s, 200); {do not localize}
- end;
- function TIdFTP.ResumeSupported: Boolean;
- begin
- if FResumeTested then result := FCanResume
- else begin
- FResumeTested := true;
- FCanResume := Quote('REST 1') = 350; {do not localize}
- result := FCanResume;
- Quote('REST 0'); {do not localize}
- end;
- end;
- procedure TIdFTP.Get(const ASourceFile: string; ADest: TIdStreamVCL; AResume: Boolean = false);
- begin
- //for SSL FXP, we have to do it here because InternalGet is used by the LIST command
- //where SSCN is ignored.
- ClearSSCN;
- AResume := AResume and CanResume;
- DoBeforeGet; //APR
- InternalGet('RETR ' + ASourceFile, ADest, AResume); {do not localize}
- DoAfterGet(ADest.VCLStream ); //APR
- end;
- procedure TIdFTP.Get(const ASourceFile: string; ADest: TStream; AResume: Boolean = false);
- var LStream : TIdStreamVCL;
- begin
- //for SSL FXP, we have to do it here because InternalGet is used by the LIST command
- //where SSCN is ignored.
- ClearSSCN;
- AResume := AResume and CanResume;
- LStream := TIdStreamVCL.Create(ADest);
- try
- Get(ASourceFile,LStream,AResume);
- finally
- FreeAndNil(LStream);
- end;
- end;
- procedure TIdFTP.Get(const ASourceFile, ADestFile: string; const ACanOverwrite: boolean = false;
- AResume: Boolean = false);
- var
- LDestStream: TFileStream;
- begin
- if FileExists(ADestFile) then begin
- AResume := AResume and CanResume;
- if ACanOverwrite and (not AResume) then begin
- DeleteFile(ADestFile);
- LDestStream := TFileStream.Create(ADestFile, fmCreate);
- end
- else begin
- if (not ACanOverwrite) and AResume then begin
- LDestStream := TFileStream.Create(ADestFile, fmOpenReadWrite or fmShareDenyWrite);
- LDestStream.Position := LDestStream.Size;
- end
- else begin
- raise EIdFTPFileAlreadyExists.Create(RSDestinationFileAlreadyExists);
- end;
- end;
- end
- else begin
- LDestStream := TFileStream.Create(ADestFile, fmCreate);
- end;
- try
- Get(ASourceFile, LDestStream, AResume);
- finally
- FreeAndNil(LDestStream);
- end;
- end;
- procedure TIdFTP.DoBeforeGet;
- begin
- if Assigned(FOnBeforeGet) then
- begin
- FOnBeforeGet(Self);
- end;
- end;
- procedure TIdFTP.DoBeforePut (AStream: TStream);
- begin
- if Assigned(FOnBeforePut) then
- begin
- FOnBeforePut(SELF,AStream);
- end;
- end;
- procedure TIdFTP.DoAfterGet (AStream: TStream);//APR
- Begin
- if Assigned(FOnAfterGet) then
- begin
- FOnAfterGet(SELF,AStream);
- end;
- End;//TIdFTP.AtAfterFileGet
- procedure TIdFTP.DoAfterPut;
- begin
- if Assigned(FOnAfterPut) then
- begin
- FOnAfterPut(Self);
- end;
- end;
- procedure TIdFTP.ConstructDirListing;
- begin
- if not Assigned(FDirectoryListing) then begin
- if not (csDesigning in ComponentState) then begin
- DoFTPList;
- end;
- if not Assigned(FDirectoryListing) then begin
- FDirectoryListing := TIdFTPListItems.Create;
- end;
- end else begin
- FDirectoryListing.Clear;
- end;
- end;
- procedure TIdFTP.List(
- ADest: TIdStrings;
- const ASpecifier: string = ''; {do not localize}
- ADetails: Boolean = True);
- var
- LDest: TIdStringStream;
- LTrans : TIdFTPTransferType;
- LStream : TIdStreamVCL;
- begin
- if FCanUseMLS then begin
- ExtListDir(ADest);
- Exit;
- end;
- //Note that for LIST, it might be best to put the connection in ASCII
- //mode because some old servers such as TOPS20 might require this. We restore it
- //if the original mode was not ASCII. It's a good idea to do this anyway
- //because some clients still do this such as WS_FTP Pro and Microsoft's FTP Client.
- LTrans := Self.TransferType;
- if LTrans <> ftASCII then begin
- Self.TransferType := ftASCII;
- end;
- try
- LDest := TIdStringStream.Create(''); try
- LStream := TIdStreamVCL.Create(LDest); try
- InternalGet(Trim(iif(ADetails, 'LIST', 'NLST') + ' ' + ASpecifier), LStream); {do not localize}
- finally FreeAndNil(LStream); end;
- FreeAndNil(FDirectoryListing);
- FListResult.Text := LDest.DataString;
- if ADest <> nil then begin
- ADest.Assign(FListResult);
- end;
- FUsedMLS := False;
- finally FreeAndNil(LDest); end;
- DoOnRetrievedDir;
- finally
- if LTrans…
Large files files are truncated, but you can click here to view the full file