00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #pragma once
00023
00024 #include "Handshakes.h"
00025
00026
00027
00028 class CDownloadTransferFTP : public CDownloadTransfer
00029 {
00030 public:
00031 CDownloadTransferFTP(CDownloadSource* pSource);
00032 virtual ~CDownloadTransferFTP() {}
00033 virtual BOOL Initiate();
00034 virtual void Close(TRISTATE bKeepSource);
00035 virtual void Boost();
00036 virtual DWORD GetAverageSpeed();
00037 virtual DWORD GetMeasuredSpeed();
00038 virtual BOOL SubtractRequested(FF::SimpleFragmentList& ppFragments);
00039 virtual BOOL OnRun();
00040 virtual BOOL OnRead();
00041 virtual BOOL OnConnected();
00042 virtual void OnDropped(BOOL bError);
00043 virtual BOOL OnHeaderLine(CString& strHeader, CString& strValue);
00044
00045 protected:
00046
00047 class CFTPLIST : public CTransfer
00048 {
00049 public:
00050 CFTPLIST() {}
00051 virtual ~CFTPLIST() {}
00052
00053
00054
00055
00056
00057
00058
00059 virtual BOOL ConnectTo(SOCKADDR_IN* pHost)
00060 {
00061 m_sData.Empty ();
00062 return CConnection::ConnectTo( pHost );
00063 }
00064
00065
00066
00067
00068
00069
00070
00071 virtual BOOL OnRead()
00072 {
00073 if ( CTransfer::OnRead() )
00074 {
00075 if ( m_pInput->m_nLength > 0 )
00076 {
00077 m_sData.Append( CA2CT( (char*) m_pInput->m_pBuffer ),
00078 m_pInput->m_nLength );
00079 m_pInput->Clear();
00080 }
00081 return TRUE;
00082 }
00083 Close();
00084 return FALSE;
00085 }
00086
00087 virtual QWORD ExtractFileSize() const
00088 {
00089 TRACE( _T("Extracting file size from:\n%ls\n"), m_sData );
00090 CString in( m_sData ), out;
00091 for( int n = 0; Split( in, _T(' '), out ); ++n )
00092 {
00093 int i = 0;
00094 for( ; i < out.GetLength(); ++i )
00095 if ( !isdigit( out [i] ) )
00096 break;
00097 if( i == out.GetLength() && out [0] != _T('0') && n != 2 )
00098 {
00099 QWORD size = _tstoi64( out );
00100 TRACE( _T("File size: %ld bytes\n"), size );
00101 return size;
00102 }
00103 }
00104 TRACE( _T("Unknown file size.\n") );
00105 return SIZE_UNKNOWN;
00106 }
00107
00108 protected:
00109 CString m_sData;
00110
00111 inline bool Split(CString& in, TCHAR token, CString& out) const
00112 {
00113 in = in.Trim( _T(" \t\r\n") );
00114 if ( !in.GetLength() )
00115 {
00116 out.Empty();
00117 return false;
00118 }
00119 int p = in.ReverseFind( token );
00120 if ( p != -1)
00121 {
00122 out = in.Mid( p + 1 );
00123 in = in.Mid( 0, p );
00124 } else
00125 {
00126 out = in;
00127 in.Empty();
00128 }
00129 return true;
00130 }
00131 };
00132
00133
00134 class CFTPRETR : public CTransfer
00135 {
00136 public:
00137 CFTPRETR() : m_pOwner( NULL ), m_tContent( 0 ), m_nTotal( 0 ) {}
00138 virtual ~CFTPRETR() {}
00139
00140 inline void SetOwner(CDownloadTransferFTP* pOwner)
00141 {
00142 m_pOwner = pOwner;
00143 }
00144
00145
00146
00147
00148
00149
00150
00151 virtual BOOL ConnectTo(SOCKADDR_IN* pHost)
00152 {
00153 m_tContent = GetTickCount();
00154 m_nTotal = 0;
00155 return CConnection::ConnectTo( pHost );
00156 }
00157
00158
00159
00160
00161
00162
00163
00164
00165 virtual BOOL OnRead()
00166 {
00167 if ( CTransfer::OnRead() )
00168 {
00169 if ( m_pOwner && m_pInput->m_nLength > 0 )
00170 {
00171 DWORD nLength = (DWORD) min( (QWORD) m_pInput->m_nLength,
00172 m_pOwner->m_nLength - m_pOwner->m_nPosition );
00173 m_pOwner->m_pDownload->SubmitData(
00174 m_pOwner->m_nOffset + m_pOwner->m_nPosition,
00175 m_pInput->m_pBuffer, nLength );
00176 m_pOwner->m_nPosition += nLength;
00177 m_pOwner->m_nDownloaded += nLength;
00178
00179 DWORD nCurrent = GetTickCount();
00180 if ( nCurrent - m_tContent != 0) {
00181 m_pOwner->m_pSource->m_nSpeed =
00182 (DWORD) ( ( ( m_pInput->m_nLength + m_nTotal ) /
00183 ( nCurrent - m_tContent ) ) * 1000 );
00184 m_tContent = nCurrent;
00185 m_nTotal = 0;
00186 } else
00187 m_nTotal += m_pInput->m_nLength;
00188 m_pInput->Clear();
00189 if ( m_pOwner->m_nPosition >= m_pOwner->m_nLength )
00190 {
00191 m_pOwner->m_pSource->AddFragment( m_pOwner->m_nOffset,
00192 m_pOwner->m_nLength );
00193 Close();
00194 }
00195 }
00196 return TRUE;
00197 }
00198 Close();
00199 return FALSE;
00200 }
00201
00202 protected:
00203 CDownloadTransferFTP* m_pOwner;
00204 DWORD m_tContent;
00205 QWORD m_nTotal;
00206 };
00207
00208 enum FTP_STATES {
00209
00210 ftpConnecting,
00211
00212 ftpUSER, ftpPASS,
00213
00214 ftpSIZE_TYPE, ftpSIZE,
00215
00216 ftpLIST_TYPE, ftpLIST_PASVPORT, ftpLIST,
00217
00218 ftpDownloading,
00219
00220 ftpRETR_TYPE, ftpRETR_PASVPORT, ftpRETR_REST, ftpRETR,
00221
00222 ftpABOR
00223 };
00224
00225 FTP_STATES m_FtpState;
00226 DWORD m_tRequest;
00227 CFTPLIST m_LIST;
00228 CFTPRETR m_RETR;
00229 BOOL m_bPassive;
00230 BOOL m_bSizeChecked;
00231
00232
00233 BOOL StartNextFragment();
00234
00235 BOOL SendCommand(LPCTSTR args = NULL);
00236 };