Definition at line 145 of file q3ftp.cpp.
Signals | |
void | connectState (int) |
void | finished (const QString &) |
void | error (int, const QString &) |
void | rawFtpReply (int, const QString &) |
Public Member Functions | |
Q3FtpPI (QObject *parent=0) | |
void | connectToHost (const QString &host, Q_UINT16 port) |
bool | sendCommands (const QStringList &cmds) |
bool | sendCommand (const QString &cmd) |
void | clearPendingCommands () |
void | abort () |
QString | currentCommand () const |
Public Attributes | |
bool | rawCommand |
Q3FtpDTP | dtp |
Private Types | |
enum | State |
enum | AbortState |
Private Slots | |
void | hostFound () |
void | connected () |
void | connectionClosed () |
void | delayedCloseFinished () |
void | readyRead () |
void | error (int) |
void | dtpConnectState (int) |
Private Member Functions | |
bool | processReply () |
bool | startNextCmd () |
Private Attributes | |
Q3Socket | commandSocket |
QString | replyText |
signed char | replyCode [3] |
State | state |
AbortState | abortState |
QStringList | pendingCommands |
QString | currentCmd |
bool | waitForDtpToConnect |
bool | waitForDtpToClose |
enum Q3FtpPI::State [private] |
enum Q3FtpPI::AbortState [private] |
Definition at line 195 of file q3ftp.cpp.
00195 { 00196 None, 00197 AbortStarted, 00198 WaitForAbortToFinish 00199 };
Q3FtpPI::Q3FtpPI | ( | QObject * | parent = 0 |
) |
Definition at line 616 of file q3ftp.cpp.
References commandSocket, QObject::connect(), connected(), connectionClosed(), connectState(), delayedCloseFinished(), dtp, dtpConnectState(), error(), hostFound(), readyRead(), SIGNAL, and SLOT.
00616 : 00617 QObject( parent ), 00618 rawCommand(false), 00619 dtp( this ), 00620 commandSocket( 0, "Q3FtpPI_socket" ), 00621 state( Begin ), abortState( None ), 00622 currentCmd( QString() ), 00623 waitForDtpToConnect( false ), 00624 waitForDtpToClose( false ) 00625 { 00626 connect( &commandSocket, SIGNAL(hostFound()), 00627 SLOT(hostFound()) ); 00628 connect( &commandSocket, SIGNAL(connected()), 00629 SLOT(connected()) ); 00630 connect( &commandSocket, SIGNAL(connectionClosed()), 00631 SLOT(connectionClosed()) ); 00632 connect( &commandSocket, SIGNAL(delayedCloseFinished()), 00633 SLOT(delayedCloseFinished()) ); 00634 connect( &commandSocket, SIGNAL(readyRead()), 00635 SLOT(readyRead()) ); 00636 connect( &commandSocket, SIGNAL(error(int)), 00637 SLOT(error(int)) ); 00638 00639 connect( &dtp, SIGNAL(connectState(int)), 00640 SLOT(dtpConnectState(int)) ); 00641 }
Here is the call graph for this function:
void Q3FtpPI::connectToHost | ( | const QString & | host, | |
Q_UINT16 | port | |||
) |
Definition at line 643 of file q3ftp.cpp.
References commandSocket, connectState(), Q3Socket::connectToHost(), emit, and Q3Ftp::HostLookup.
00644 { 00645 emit connectState( Q3Ftp::HostLookup ); 00646 commandSocket.connectToHost( host, port ); 00647 }
Here is the call graph for this function:
bool Q3FtpPI::sendCommands | ( | const QStringList & | cmds | ) |
Definition at line 657 of file q3ftp.cpp.
References commandSocket, Q3Socket::Connected, emit, error(), Idle, QList< T >::isEmpty(), Q3Ftp::NotConnected, pendingCommands, startNextCmd(), state, and Q3Socket::state().
Referenced by sendCommand().
00658 { 00659 if ( !pendingCommands.isEmpty() ) 00660 return false; 00661 00662 if ( commandSocket.state()!=Q3Socket::Connected || state!=Idle ) { 00663 emit error( Q3Ftp::NotConnected, QFtp::tr( "Not connected" ) ); 00664 return true; // there are no pending commands 00665 } 00666 00667 pendingCommands = cmds; 00668 startNextCmd(); 00669 return true; 00670 }
Here is the call graph for this function:
bool Q3FtpPI::sendCommand | ( | const QString & | cmd | ) | [inline] |
Definition at line 155 of file q3ftp.cpp.
References sendCommands().
00156 { return sendCommands( QStringList( cmd ) ); }
Here is the call graph for this function:
void Q3FtpPI::clearPendingCommands | ( | ) |
Definition at line 672 of file q3ftp.cpp.
References Q3FtpDTP::abortConnection(), QString::clear(), QList< T >::clear(), currentCmd, dtp, Idle, pendingCommands, and state.
00673 { 00674 pendingCommands.clear(); 00675 dtp.abortConnection(); 00676 currentCmd.clear(); 00677 state = Idle; 00678 }
Here is the call graph for this function:
void Q3FtpPI::abort | ( | ) |
Definition at line 680 of file q3ftp.cpp.
References Q3FtpDTP::abortConnection(), AbortStarted, abortState, QList< T >::clear(), commandSocket, currentCmd, dtp, None, pendingCommands, qDebug(), and QString::startsWith().
00681 { 00682 pendingCommands.clear(); 00683 00684 if ( abortState != None ) 00685 // ABOR already sent 00686 return; 00687 00688 abortState = AbortStarted; 00689 #if defined(Q3FTPPI_DEBUG) 00690 qDebug( "Q3FtpPI send: ABOR" ); 00691 #endif 00692 commandSocket.writeBlock( "ABOR\r\n", 6 ); 00693 00694 if ( currentCmd.startsWith("STOR ") ) 00695 dtp.abortConnection(); 00696 }
Here is the call graph for this function:
QString Q3FtpPI::currentCommand | ( | ) | const [inline] |
Definition at line 161 of file q3ftp.cpp.
References currentCmd.
Referenced by Q3FtpDTP::socketReadyRead().
00162 { return currentCmd; }
void Q3FtpPI::connectState | ( | int | ) | [signal] |
Referenced by connected(), connectionClosed(), connectToHost(), delayedCloseFinished(), error(), hostFound(), processReply(), and Q3FtpPI().
void Q3FtpPI::finished | ( | const QString & | ) | [signal] |
Referenced by processReply(), and startNextCmd().
void Q3FtpPI::error | ( | int | , | |
const QString & | ||||
) | [signal] |
Referenced by dtpConnectState(), error(), processReply(), Q3FtpPI(), and sendCommands().
void Q3FtpPI::rawFtpReply | ( | int | , | |
const QString & | ||||
) | [signal] |
Referenced by processReply().
void Q3FtpPI::hostFound | ( | ) | [private, slot] |
Definition at line 698 of file q3ftp.cpp.
References Q3Ftp::Connecting, connectState(), and emit.
Referenced by Q3FtpPI().
00699 { 00700 emit connectState( Q3Ftp::Connecting ); 00701 }
void Q3FtpPI::connected | ( | ) | [private, slot] |
Definition at line 703 of file q3ftp.cpp.
References Begin, Q3Ftp::Connected, connectState(), emit, and state.
Referenced by Q3FtpPI().
00704 { 00705 state = Begin; 00706 #if defined(Q3FTPPI_DEBUG) 00707 // qDebug( "Q3FtpPI state: %d [connected()]", state ); 00708 #endif 00709 emit connectState( Q3Ftp::Connected ); 00710 }
void Q3FtpPI::connectionClosed | ( | ) | [private, slot] |
Definition at line 712 of file q3ftp.cpp.
References Q3Socket::close(), commandSocket, connectState(), emit, and Q3Ftp::Unconnected.
Referenced by Q3FtpPI().
00713 { 00714 commandSocket.close(); 00715 emit connectState( Q3Ftp::Unconnected ); 00716 }
void Q3FtpPI::delayedCloseFinished | ( | ) | [private, slot] |
Definition at line 718 of file q3ftp.cpp.
References connectState(), emit, and Q3Ftp::Unconnected.
Referenced by Q3FtpPI().
00719 { 00720 emit connectState( Q3Ftp::Unconnected ); 00721 }
void Q3FtpPI::readyRead | ( | ) | [private, slot] |
Definition at line 736 of file q3ftp.cpp.
References Q3Socket::canReadLine(), commandSocket, QUnicodeTables::digitValue(), QString::endsWith(), i, QString::isEmpty(), QString::left(), QString::length(), QString::mid(), processReply(), QIODevice::readLine(), replyCode, replyText, QString::truncate(), and waitForDtpToClose.
Referenced by dtpConnectState(), and Q3FtpPI().
00737 { 00738 if ( waitForDtpToClose ) 00739 return; 00740 00741 while ( commandSocket.canReadLine() ) { 00742 // read line with respect to line continuation 00743 QString line = commandSocket.readLine(); 00744 if ( replyText.isEmpty() ) { 00745 if ( line.length() < 3 ) { 00746 // ### protocol error 00747 return; 00748 } 00749 const int lowerLimit[3] = {1,0,0}; 00750 const int upperLimit[3] = {5,5,9}; 00751 for ( int i=0; i<3; i++ ) { 00752 replyCode[i] = line[i].digitValue(); 00753 if ( replyCode[i]<lowerLimit[i] || replyCode[i]>upperLimit[i] ) { 00754 // ### protocol error 00755 return; 00756 } 00757 } 00758 } 00759 QString endOfMultiLine; 00760 endOfMultiLine[0] = '0' + replyCode[0]; 00761 endOfMultiLine[1] = '0' + replyCode[1]; 00762 endOfMultiLine[2] = '0' + replyCode[2]; 00763 endOfMultiLine[3] = ' '; 00764 QString lineCont( endOfMultiLine ); 00765 lineCont[3] = '-'; 00766 QString lineLeft4 = line.left(4); 00767 00768 while ( lineLeft4 != endOfMultiLine ) { 00769 if ( lineLeft4 == lineCont ) 00770 replyText += line.mid( 4 ); // strip 'xyz-' 00771 else 00772 replyText += line; 00773 if ( !commandSocket.canReadLine() ) 00774 return; 00775 line = commandSocket.readLine(); 00776 lineLeft4 = line.left(4); 00777 } 00778 replyText += line.mid( 4 ); // strip reply code 'xyz ' 00779 if ( replyText.endsWith("\r\n") ) 00780 replyText.truncate( replyText.length()-2 ); 00781 00782 if ( processReply() ) 00783 replyText = ""; 00784 } 00785 }
void Q3FtpPI::error | ( | int | ) | [private, slot] |
Definition at line 723 of file q3ftp.cpp.
References commandSocket, Q3Ftp::ConnectionRefused, connectState(), emit, Q3Socket::ErrConnectionRefused, Q3Socket::ErrHostNotFound, error(), Q3Ftp::HostNotFound, Q3Socket::peerName(), and Q3Ftp::Unconnected.
00724 { 00725 if ( e == Q3Socket::ErrHostNotFound ) { 00726 emit connectState( Q3Ftp::Unconnected ); 00727 emit error( Q3Ftp::HostNotFound, 00728 QFtp::tr( "Host %1 not found" ).arg( commandSocket.peerName() ) ); 00729 } else if ( e == Q3Socket::ErrConnectionRefused ) { 00730 emit connectState( Q3Ftp::Unconnected ); 00731 emit error( Q3Ftp::ConnectionRefused, 00732 QFtp::tr( "Connection refused to host %1" ).arg( commandSocket.peerName() ) ); 00733 } 00734 }
void Q3FtpPI::dtpConnectState | ( | int | ) | [private, slot] |
Definition at line 974 of file q3ftp.cpp.
References Q3Ftp::ConnectionRefused, Q3FtpDTP::CsClosed, Q3FtpDTP::CsConnected, Q3FtpDTP::CsConnectionRefused, Q3FtpDTP::CsHostNotFound, emit, error(), processReply(), readyRead(), replyText, startNextCmd(), waitForDtpToClose, and waitForDtpToConnect.
Referenced by Q3FtpPI().
00975 { 00976 switch ( s ) { 00977 case Q3FtpDTP::CsClosed: 00978 if ( waitForDtpToClose ) { 00979 // there is an unprocessed reply 00980 if ( processReply() ) 00981 replyText = ""; 00982 else 00983 return; 00984 } 00985 waitForDtpToClose = false; 00986 readyRead(); 00987 return; 00988 case Q3FtpDTP::CsConnected: 00989 waitForDtpToConnect = false; 00990 startNextCmd(); 00991 return; 00992 case Q3FtpDTP::CsHostNotFound: 00993 case Q3FtpDTP::CsConnectionRefused: 00994 emit error( Q3Ftp::ConnectionRefused, 00995 QFtp::tr( "Connection refused for data connection" ) ); 00996 startNextCmd(); 00997 return; 00998 default: 00999 return; 01000 } 01001 }
bool Q3FtpPI::processReply | ( | ) | [private] |
Definition at line 793 of file q3ftp.cpp.
References AbortStarted, abortState, Begin, QRegExp::capturedTexts(), Q3FtpDTP::clearError(), commandSocket, connectState(), Q3FtpDTP::connectToHost(), QList< T >::count(), currentCmd, dtp, emit, error(), Q3FtpDTP::errorMessage(), Failure, finished(), QList< T >::first(), Q3FtpDTP::hasError(), Idle, Q3Socket::Idle, QString::length(), Q3Ftp::LoggedIn, None, Q3Socket::peerName(), pendingCommands, QList< T >::pop_front(), qDebug(), rawCommand, rawFtpReply(), replyCode, replyText, Q3FtpDTP::setBytesTotal(), Q3FtpDTP::socketState(), startNextCmd(), QString::startsWith(), state, Success, t, QString::toInt(), Q3Ftp::UnknownError, WaitForAbortToFinish, waitForDtpToClose, waitForDtpToConnect, Waiting, and Q3FtpDTP::writeData().
Referenced by dtpConnectState(), and readyRead().
00794 { 00795 #if defined(Q3FTPPI_DEBUG) 00796 // qDebug( "Q3FtpPI state: %d [processReply() begin]", state ); 00797 if ( replyText.length() < 400 ) 00798 qDebug( "Q3FtpPI recv: %d %s", 100*replyCode[0]+10*replyCode[1]+replyCode[2], replyText.latin1() ); 00799 else 00800 qDebug( "Q3FtpPI recv: %d (text skipped)", 100*replyCode[0]+10*replyCode[1]+replyCode[2] ); 00801 #endif 00802 00803 // process 226 replies ("Closing Data Connection") only when the data 00804 // connection is really closed to avoid short reads of the DTP 00805 if ( 100*replyCode[0]+10*replyCode[1]+replyCode[2] == 226 ) { 00806 if ( dtp.socketState() != Q3Socket::Idle ) { 00807 waitForDtpToClose = true; 00808 return false; 00809 } 00810 } 00811 00812 switch ( abortState ) { 00813 case AbortStarted: 00814 abortState = WaitForAbortToFinish; 00815 break; 00816 case WaitForAbortToFinish: 00817 abortState = None; 00818 return true; 00819 default: 00820 break; 00821 } 00822 00823 // get new state 00824 static const State table[5] = { 00825 /* 1yz 2yz 3yz 4yz 5yz */ 00826 Waiting, Success, Idle, Failure, Failure 00827 }; 00828 switch ( state ) { 00829 case Begin: 00830 if ( replyCode[0] == 1 ) { 00831 return true; 00832 } else if ( replyCode[0] == 2 ) { 00833 state = Idle; 00834 emit finished( QFtp::tr( "Connected to host %1" ).arg( commandSocket.peerName() ) ); 00835 break; 00836 } 00837 // ### error handling 00838 return true; 00839 case Waiting: 00840 if ( replyCode[0]<0 || replyCode[0]>5 ) 00841 state = Failure; 00842 else 00843 #if defined(Q_OS_IRIX) && defined(Q_CC_GNU) 00844 { 00845 // work around a crash on 64 bit gcc IRIX 00846 State *t = (State *) table; 00847 state = t[replyCode[0] - 1]; 00848 } 00849 #else 00850 state = table[replyCode[0] - 1]; 00851 #endif 00852 break; 00853 default: 00854 // ### spontaneous message 00855 return true; 00856 } 00857 #if defined(Q3FTPPI_DEBUG) 00858 // qDebug( "Q3FtpPI state: %d [processReply() intermediate]", state ); 00859 #endif 00860 00861 // special actions on certain replies 00862 int replyCodeInt = 100*replyCode[0] + 10*replyCode[1] + replyCode[2]; 00863 emit rawFtpReply( replyCodeInt, replyText ); 00864 if ( rawCommand ) { 00865 rawCommand = false; 00866 } else if ( replyCodeInt == 227 ) { 00867 // 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2) 00868 // rfc959 does not define this response precisely, and gives 00869 // both examples where the parenthesis are used, and where 00870 // they are missing. We need to scan for the address and host 00871 // info. 00872 QRegExp addrPortPattern("(\\d+),(\\d+),(\\d+),(\\d+),(\\d+),(\\d+)"); 00873 if (addrPortPattern.search(replyText) == -1) { 00874 #if defined(Q3FTPPI_DEBUG) 00875 qDebug( "Q3Ftp: bad 227 response -- address and port information missing" ); 00876 #endif 00877 // ### error handling 00878 } else { 00879 QStringList lst = addrPortPattern.capturedTexts(); 00880 QString host = lst[1] + "." + lst[2] + "." + lst[3] + "." + lst[4]; 00881 Q_UINT16 port = ( lst[5].toUInt() << 8 ) + lst[6].toUInt(); 00882 waitForDtpToConnect = true; 00883 dtp.connectToHost( host, port ); 00884 } 00885 } else if ( replyCodeInt == 230 ) { 00886 if ( currentCmd.startsWith("USER ") && pendingCommands.count()>0 && 00887 pendingCommands.first().startsWith("PASS ") ) { 00888 // no need to send the PASS -- we are already logged in 00889 pendingCommands.pop_front(); 00890 } 00891 // 230 User logged in, proceed. 00892 emit connectState( Q3Ftp::LoggedIn ); 00893 } else if ( replyCodeInt == 213 ) { 00894 // 213 File status. 00895 if ( currentCmd.startsWith("SIZE ") ) 00896 dtp.setBytesTotal( replyText.simplifyWhiteSpace().toInt() ); 00897 } else if ( replyCode[0]==1 && currentCmd.startsWith("STOR ") ) { 00898 dtp.writeData(); 00899 } 00900 00901 // react on new state 00902 switch ( state ) { 00903 case Begin: 00904 // ### should never happen 00905 break; 00906 case Success: 00907 // ### success handling 00908 state = Idle; 00909 // no break! 00910 case Idle: 00911 if ( dtp.hasError() ) { 00912 emit error( Q3Ftp::UnknownError, dtp.errorMessage() ); 00913 dtp.clearError(); 00914 } 00915 startNextCmd(); 00916 break; 00917 case Waiting: 00918 // ### do nothing 00919 break; 00920 case Failure: 00921 emit error( Q3Ftp::UnknownError, replyText ); 00922 state = Idle; 00923 startNextCmd(); 00924 break; 00925 } 00926 #if defined(Q3FTPPI_DEBUG) 00927 // qDebug( "Q3FtpPI state: %d [processReply() end]", state ); 00928 #endif 00929 return true; 00930 }
Here is the call graph for this function:
bool Q3FtpPI::startNextCmd | ( | ) | [private] |
Definition at line 940 of file q3ftp.cpp.
References QString::clear(), commandSocket, currentCmd, QByteArray::data(), emit, finished(), QList< T >::first(), QTextCodec::fromUnicode(), Idle, QList< T >::isEmpty(), QString::left(), len, QString::length(), pendingCommands, QList< T >::pop_front(), qDebug(), qt_ftp_filename_codec, replyText, state, waitForDtpToConnect, and Waiting.
Referenced by dtpConnectState(), processReply(), and sendCommands().
00941 { 00942 if ( waitForDtpToConnect ) 00943 // don't process any new commands until we are connected 00944 return true; 00945 00946 #if defined(Q3FTPPI_DEBUG) 00947 if ( state != Idle ) 00948 qDebug( "Q3FtpPI startNextCmd: Internal error! Q3FtpPI called in non-Idle state %d", state ); 00949 #endif 00950 if ( pendingCommands.isEmpty() ) { 00951 currentCmd.clear(); 00952 emit finished( replyText ); 00953 return false; 00954 } 00955 currentCmd = pendingCommands.first(); 00956 pendingCommands.pop_front(); 00957 #if defined(Q3FTPPI_DEBUG) 00958 qDebug( "Q3FtpPI send: %s", currentCmd.left( currentCmd.length()-2 ).latin1() ); 00959 #endif 00960 state = Waiting; 00961 #ifndef QT_NO_TEXTCODEC 00962 if ( qt_ftp_filename_codec ) { 00963 int len; 00964 Q3CString enc = qt_ftp_filename_codec->fromUnicode(currentCmd,len); 00965 commandSocket.writeBlock( enc.data(), len ); 00966 } else 00967 #endif 00968 { 00969 commandSocket.writeBlock( currentCmd.latin1(), currentCmd.length() ); 00970 } 00971 return true; 00972 }
Here is the call graph for this function:
bool Q3FtpPI::rawCommand |
Definition at line 166 of file q3ftp.cpp.
Referenced by abort(), clearPendingCommands(), processReply(), and Q3FtpPI().
Q3Socket Q3FtpPI::commandSocket [private] |
Definition at line 204 of file q3ftp.cpp.
Referenced by abort(), connectionClosed(), connectToHost(), error(), processReply(), Q3FtpPI(), readyRead(), sendCommands(), and startNextCmd().
QString Q3FtpPI::replyText [private] |
Definition at line 205 of file q3ftp.cpp.
Referenced by dtpConnectState(), processReply(), readyRead(), and startNextCmd().
signed char Q3FtpPI::replyCode[3] [private] |
State Q3FtpPI::state [private] |
Definition at line 207 of file q3ftp.cpp.
Referenced by clearPendingCommands(), connected(), processReply(), sendCommands(), and startNextCmd().
AbortState Q3FtpPI::abortState [private] |
QStringList Q3FtpPI::pendingCommands [private] |
Definition at line 209 of file q3ftp.cpp.
Referenced by abort(), clearPendingCommands(), processReply(), sendCommands(), and startNextCmd().
QString Q3FtpPI::currentCmd [private] |
Definition at line 210 of file q3ftp.cpp.
Referenced by abort(), clearPendingCommands(), currentCommand(), processReply(), and startNextCmd().
bool Q3FtpPI::waitForDtpToConnect [private] |
Definition at line 212 of file q3ftp.cpp.
Referenced by dtpConnectState(), processReply(), and startNextCmd().
bool Q3FtpPI::waitForDtpToClose [private] |
Definition at line 213 of file q3ftp.cpp.
Referenced by dtpConnectState(), processReply(), and readyRead().