Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

DownloadTransferFTP.h

Go to the documentation of this file.
00001 //
00002 // DownloadTransferFTP.h
00003 //
00004 // Copyright (c) Nikolay Raspopov, 2004-2005.
00005 // This file is part of SHAREAZA (www.shareaza.com)
00006 //
00007 // Shareaza is free software; you can redistribute it
00008 // and/or modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2 of
00010 // the License, or (at your option) any later version.
00011 //
00012 // Shareaza is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU General Public License
00018 // along with Shareaza; if not, write to the Free Software
00019 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 //
00021 
00022 #pragma once
00023 
00024 #include "Handshakes.h"
00025 
00026 // Note: ftp active mode code was commented out
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         // FTP "LIST" helper class
00047         class CFTPLIST : public CTransfer
00048         {
00049         public:
00050                 CFTPLIST() {}
00051                 virtual ~CFTPLIST() {}
00052 
00053 /*              virtual void Close()
00054                 {
00055                         Handshakes.Remove( this );
00056                         CTransfer::Close();
00057                 }*/
00058 
00059                 virtual BOOL ConnectTo(SOCKADDR_IN* pHost)
00060                 {
00061                         m_sData.Empty ();
00062                         return CConnection::ConnectTo( pHost );
00063                 }
00064 
00065 /*              virtual void AttachTo(CConnection* pConnection)
00066                 {
00067                         m_sData.Empty ();
00068                         CTransfer::AttachTo( pConnection );
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;        // Received file listing data
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         // FTP "RETR" helper class
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 /*              virtual void Close()
00146                 {
00147                         Handshakes.Remove( this );
00148                         CTransfer::Close();
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 /*              virtual void AttachTo(CConnection* pConnection)
00159                 {
00160                         m_tContent = GetTickCount();
00161                         m_nTotal = 0;
00162                         CTransfer::AttachTo( pConnection );
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                                         // Measuring speed
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; // Owner object
00204                 DWORD m_tContent;                               // Last Receive time
00205                 QWORD                                   m_nTotal;       // Received bytes by m_tContent time
00206         };
00207 
00208         enum FTP_STATES {
00209                 // Initial state
00210                 ftpConnecting,
00211                 // Authenticating
00212                 ftpUSER, ftpPASS,
00213                 // File size getting via SIZE: TYPE I -> SIZE
00214                 ftpSIZE_TYPE, ftpSIZE,
00215                 // File size getting via LIST: TYPE A -> PASV or PORT -> LIST
00216                 ftpLIST_TYPE, ftpLIST_PASVPORT, ftpLIST,
00217                 // Intermediate state
00218                 ftpDownloading,
00219                 // Downloading: TYPE I -> PASV or PORT -> REST -> RETR
00220                 ftpRETR_TYPE, ftpRETR_PASVPORT, ftpRETR_REST, ftpRETR,
00221                 // Aborting after each transfer (for some strange FTP servers)
00222                 ftpABOR
00223         };
00224 
00225         FTP_STATES              m_FtpState;             // FTP Control chanell state
00226         DWORD                   m_tRequest;             // Last request time
00227         CFTPLIST                m_LIST;                 // FTP "LIST" helper object
00228         CFTPRETR                m_RETR;                 // FTP "RETR" helper object
00229         BOOL                    m_bPassive;             // Passive or Active FTP mode
00230         BOOL                    m_bSizeChecked; // File size flag
00231 
00232         // Connecting or file size getting or download starting
00233         BOOL                    StartNextFragment();
00234         // Sending command to FTP server
00235         BOOL                    SendCommand(LPCTSTR args = NULL);
00236 };

Generated on Thu Dec 15 10:39:41 2005 for Shareaza 2.2.1.0 by  doxygen 1.4.2